index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <route lang="yaml">
  2. meta:
  3. enabled: false
  4. </route>
  5. <script lang="ts" setup>
  6. import { ElMessage, ElMessageBox } from 'element-plus'
  7. import DSModel from './components/model.vue'
  8. import DSEntity from './components/entity.vue'
  9. import { deleteModelById, getModelByList } from '@/api/model/modelApi'
  10. import { deleteEntityById, getEntityByList } from '@/api/model/entityApi'
  11. interface TreeNode {
  12. label: string
  13. isLeaf: boolean
  14. modelId: number
  15. children?: TreeNode[]
  16. }
  17. interface Entity {
  18. modelId: number
  19. entityId: number
  20. entityTitle: string
  21. entityCode: string
  22. entityComment: string
  23. }
  24. const state = reactive({
  25. loading: false,
  26. keywords: '',
  27. models: [] as TreeNode[],
  28. curModelId: 0,
  29. entityList: [] as Entity[],
  30. dialogState: 1,
  31. search: {
  32. keywords: '',
  33. },
  34. })
  35. const leftTreeRef = ref()
  36. const modelRef = ref()
  37. const entityTableRef = ref()
  38. const entityRef = ref()
  39. const getModelList = async () => {
  40. const { data } = await getModelByList('')
  41. const children: TreeNode[] = []
  42. data.forEach((item: any) => {
  43. return children.push({
  44. label: item.modelTitle,
  45. modelId: item.modelId,
  46. isLeaf: true,
  47. })
  48. })
  49. state.models = [
  50. {
  51. label: '模型库',
  52. isLeaf: false,
  53. modelId: -1,
  54. children,
  55. },
  56. ]
  57. if (data && data.length > 0) {
  58. state.curModelId = data[0].modelId
  59. window.console.log(`curModelId:${data[0].modelId}`)
  60. const res = await getEntityByList({ modelId: state.curModelId })
  61. state.entityList = res.data
  62. }
  63. }
  64. const getEntityList = async () => {
  65. const curModelId = state.curModelId
  66. if (curModelId > 0) {
  67. state.loading = true
  68. const { data } = await getEntityByList({ modelId: curModelId })
  69. state.entityList = data
  70. state.loading = false
  71. }
  72. }
  73. onMounted(() => {
  74. getModelList()
  75. })
  76. const onModelAdd = () => {
  77. modelRef.value.showAddModel()
  78. }
  79. const onModelEdit = (data: { modelId: number }) => {
  80. const modelId = data.modelId
  81. modelRef.value.showEditModel(modelId)
  82. }
  83. const onModelDelete = (data: any) => {
  84. ElMessageBox.confirm(`确认删除「${data.modelTitle}」吗?`, '确认信息').then(async () => {
  85. await deleteModelById(data.modelId)
  86. await getModelList()
  87. ElMessage.success({
  88. message: '删除成功',
  89. center: true,
  90. })
  91. })
  92. }
  93. const onTreeNodeClick = (node: TreeNode) => {
  94. if (node.isLeaf) {
  95. state.curModelId = node.modelId
  96. getEntityList()
  97. }
  98. }
  99. const onSearch = () => {
  100. getEntityList()
  101. }
  102. const onEntityAdd = () => {
  103. if (state.curModelId > 0) {
  104. entityRef.value.showAddModel(state.curModelId)
  105. }
  106. }
  107. const onEntityEdit = (row: any) => {
  108. const { modelId, entityId } = row
  109. entityRef.value.showEditModel(modelId, entityId)
  110. }
  111. const onEntityDelete = (row: any) => {
  112. const { modelId, entityId, entityTitle } = row
  113. ElMessageBox.confirm(`确认删除「${entityTitle}」吗?`, '确认信息').then(async () => {
  114. await deleteEntityById(modelId, entityId)
  115. await getEntityList()
  116. ElMessage.success({
  117. message: '删除成功',
  118. center: true,
  119. })
  120. })
  121. }
  122. </script>
  123. <template>
  124. <div class="absolute-container">
  125. <tool-header title="数据模型">
  126. <template #right>
  127. <el-button plain @click="onModelAdd">
  128. <template #icon>
  129. <el-icon>
  130. <svg-icon name="i-ep:plus" />
  131. </el-icon>
  132. </template>
  133. 新增模型
  134. </el-button>
  135. </template>
  136. </tool-header>
  137. <div class="page-main">
  138. <LayoutContainer left-side-width="300px" hide-left-side-toggle>
  139. <template #leftSide>
  140. <el-scrollbar class="tree">
  141. <ElTree ref="leftTreeRef" :data="state.models" default-expand-all @node-click="onTreeNodeClick">
  142. <template #default="{ node, data }">
  143. <div class="custom-tree-node">
  144. <div class="label" :title="node.label">
  145. <el-icon v-if="data.isLeaf" size="16px" style="margin-right: 5px;">
  146. <svg-icon name="uim:box" />
  147. </el-icon>
  148. <div class="text">
  149. {{ data.label }}
  150. </div>
  151. </div>
  152. <div v-if="data.isLeaf" class="actions">
  153. <el-button-group>
  154. <el-button type="info" plain size="small" @click.stop="onModelEdit(data)">
  155. <template #icon>
  156. <el-icon>
  157. <svg-icon name="i-ep:edit" />
  158. </el-icon>
  159. </template>
  160. </el-button>
  161. <el-button type="danger" plain size="small" @click.stop="onModelDelete(data)">
  162. <template #icon>
  163. <el-icon>
  164. <svg-icon name="i-ep:delete" />
  165. </el-icon>
  166. </template>
  167. </el-button>
  168. </el-button-group>
  169. </div>
  170. </div>
  171. </template>
  172. </ElTree>
  173. </el-scrollbar>
  174. </template>
  175. <div class="container">
  176. <tool-bar>
  177. <template #right>
  178. <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
  179. <el-button type="primary" @click="onSearch">
  180. <template #icon>
  181. <el-icon>
  182. <svg-icon name="i-ep:search" />
  183. </el-icon>
  184. </template>
  185. </el-button>
  186. <el-button plain size="default" @click.stop="onEntityAdd">
  187. <template #icon>
  188. <el-icon>
  189. <svg-icon name="i-ep:plus" />
  190. </el-icon>
  191. </template>
  192. 新增实体
  193. </el-button>
  194. </template>
  195. </tool-bar>
  196. <el-table ref="entityTableRef" v-loading="state.loading" class="list-table" :data="state.entityList" border stripe highlight-current-row height="100%">
  197. <el-table-column type="index" label="序号" header-align="center" align="center" width="70" />
  198. <el-table-column prop="entityTitle" label="名称" header-align="center" align="center" width="200" />
  199. <el-table-column prop="entityCode" label="编码" header-align="center" align="center" width="150" />
  200. <el-table-column prop="entityComment" label="说明" header-align="center" align="left" />
  201. <el-table-column label="操作" header-align="center" align="center" width="200">
  202. <template #default="scope">
  203. <el-button type="primary" size="small" plain @click="onEntityEdit(scope.row)">
  204. 编辑
  205. </el-button>
  206. <el-button type="danger" size="small" plain @click="onEntityDelete(scope.row)">
  207. 删除
  208. </el-button>
  209. </template>
  210. </el-table-column>
  211. </el-table>
  212. </div>
  213. </LayoutContainer>
  214. </div>
  215. <DSEntity ref="entityRef" @success="getEntityList" />
  216. <DSModel ref="modelRef" @success="getModelList" />
  217. </div>
  218. </template>
  219. <style lang="scss" scoped>
  220. .container {
  221. height: 100%;
  222. display: flex;
  223. flex-direction: column;
  224. }
  225. .absolute-container {
  226. :deep(.left-side) {
  227. display: flex;
  228. flex-direction: column;
  229. height: 100%;
  230. .btns {
  231. display: inline-flex;
  232. width: 100%;
  233. margin-bottom: var(--container-padding);
  234. .add {
  235. width: 100%;
  236. }
  237. }
  238. .tree {
  239. flex: 1;
  240. overflow-y: auto;
  241. .el-tree {
  242. .el-tree-node__content {
  243. height: 40px;
  244. }
  245. .is-current > .el-tree-node__content {
  246. background-color: var(--el-color-primary-light-9);
  247. }
  248. .custom-tree-node {
  249. flex: 1;
  250. position: relative;
  251. width: 0;
  252. height: 100%;
  253. display: flex;
  254. flex-direction: column;
  255. justify-content: center;
  256. .label {
  257. display: inline-flex;
  258. align-items: center;
  259. width: calc(100% - 10px);
  260. color: var(--el-text-color-primary);
  261. .text {
  262. @include text-overflow;
  263. }
  264. }
  265. &:hover {
  266. .actions {
  267. display: block;
  268. }
  269. }
  270. .actions {
  271. display: none;
  272. position: absolute;
  273. right: 10px;
  274. top: 50%;
  275. transform: translateY(-50%);
  276. .el-button {
  277. padding: 5px 8px;
  278. }
  279. }
  280. }
  281. }
  282. }
  283. }
  284. }
  285. </style>