8
0

index.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <template>
  2. <hc-drawer v-model="isShow" ui="hc-element-recognition-drawer" to-id="hc-layout-box" is-close @close="drawerClose">
  3. <hc-page-split :options="{ sizes: [14, 60, 26], minSize: [50, 300, 100] }" class="hc-element-recognition">
  4. <template #left>
  5. <hc-card scrollbar>
  6. <template #header>
  7. <hc-search-input v-model="searchTreeName" placeholder="请输入关键字" @search="searchTreeNameClick" />
  8. </template>
  9. <template v-if="isTreeMode === 1">
  10. <hc-lazy-tree v-if="isShow" :h-props="treeProps" tree-key="id" @load="treeLoadNode" @node-tap="treeNodeTap">
  11. <template #name="{ data }">
  12. <span class="text-16px font-400">{{ data.name }}</span>
  13. </template>
  14. </hc-lazy-tree>
  15. </template>
  16. <template v-if="isTreeMode === 2">
  17. <hc-data-tree ref="treeRef" :h-props="treeProps" tree-key="id" :datas="treeData" @node-tap="treeNodeTap">
  18. <template #name="{ data }">
  19. <span class="text-16px font-400">{{ data.name }}</span>
  20. </template>
  21. </hc-data-tree>
  22. </template>
  23. </hc-card>
  24. </template>
  25. <hc-card :title="`【元素识别】${isNullES(nodeInfo.name) ? '表名称' : nodeInfo.name}`">
  26. <hc-table-form ref="excelRef" :html="excelHtml" @tap="excelClick" />
  27. </hc-card>
  28. <template #right>
  29. <hc-card>
  30. <template #header>
  31. <el-button color="#2550A2" size="small" class="text-white" :disabled="!isTreeNode">关联WBS并创建元素</el-button>
  32. <el-button color="#FF986A" size="small" class="text-white" :disabled="!isTreeNode" @click="elementLibClick">添加到元素库</el-button>
  33. <!-- el-button color="#567722" size="small" class="text-white">元素匹配</el-button>
  34. <el-button color="#67C23B" size="small" class="text-white">调整表单</el-button -->
  35. </template>
  36. <template #extra>
  37. <el-button type="primary" size="small" :disabled="!isTreeNode" @click="addColByTab">新增</el-button>
  38. </template>
  39. <hc-table ref="tabRef" :column="tableColumn" :datas="tableData" :index-style="{ width: 60 }" @row-click="tableRowClick">
  40. <template #textInfo="{ row }">
  41. <hc-table-input v-model="row.textInfo" />
  42. </template>
  43. <template #textElementType="{ row }">
  44. <el-select v-model="row.textElementType" filterable block>
  45. <el-option v-for="item in dataType" :key="item.value" :label="item.label" :value="item.value" />
  46. </el-select>
  47. </template>
  48. <template #textDeviation="{ row }">
  49. <hc-table-input v-model="row.textDeviation" />
  50. </template>
  51. <template #action="{ row }">
  52. <el-link type="warning" @click="saveRowClick(row)">保存</el-link>
  53. <el-link type="danger" @click="delRowClick(row)">删除</el-link>
  54. </template>
  55. </hc-table>
  56. </hc-card>
  57. </template>
  58. </hc-page-split>
  59. <!-- 添加新元素字段 -->
  60. <HcAddColTab v-model="addColTabShow" :info="addColTabInfo" @finish="getTableData" />
  61. <!-- 添加到元素库 -->
  62. <HcElementLib v-model="elementLibShow" :info="elementLibInfo" />
  63. </hc-drawer>
  64. </template>
  65. <script setup>
  66. import { HcDelMsg } from 'hc-vue3-ui'
  67. import { ref, watch } from 'vue'
  68. import { getArrValue, isNullES, isString } from 'js-fast-way'
  69. import { getDictionaryData } from '~uti/tools'
  70. import HcAddColTab from './add-col-tab.vue'
  71. import HcElementLib from './element-lib.vue'
  72. import mainApi from '~api/exctab/exceltab'
  73. const props = defineProps({
  74. data: {
  75. type: Object,
  76. default: () => ({}),
  77. },
  78. })
  79. //事件
  80. const emit = defineEmits(['close'])
  81. //双向绑定
  82. const isShow = defineModel('modelValue', {
  83. default: false,
  84. })
  85. //监听数据
  86. const dataInfo = ref(props.data)
  87. watch(() => props.data, (data) => {
  88. dataInfo.value = data
  89. }, { immediate: true, deep: true })
  90. //监听显示
  91. watch(isShow, (val) => {
  92. if (val) getDataApi()
  93. })
  94. //处理相关数据
  95. const getDataApi = () => {
  96. getDataType()
  97. }
  98. //树搜索
  99. const isTreeMode = ref(1) //1懒加载,2全加载
  100. const searchTreeName = ref('')
  101. const searchTreeNameClick = async () => {
  102. if (isNullES(searchTreeName.value)) {
  103. isTreeMode.value = 1
  104. } else {
  105. isTreeMode.value = 2
  106. await getTreeAllData()
  107. treeRef.value?.treeRef?.filter(searchTreeName.value)
  108. }
  109. }
  110. //树配置
  111. const treeRef = ref(null)
  112. const treeProps = {
  113. label: 'name',
  114. children: 'children',
  115. isLeaf: (item) => {
  116. return !item.hasChildren
  117. },
  118. }
  119. //全加载树
  120. const treeData = ref([])
  121. const getTreeAllData = async () => {
  122. const { data } = await mainApi.tabLazyTreeAll({
  123. modeId: dataInfo.value.id,
  124. name: '',
  125. })
  126. treeData.value = getArrValue(data)
  127. }
  128. //懒加载树
  129. const treeLoadNode = async ({ item, level }, resolve) => {
  130. const parentId = level === 0 ? 0 : item.id
  131. const { data } = await mainApi.tabLazyTree({
  132. parentId: parentId,
  133. modeId: dataInfo.value.id,
  134. })
  135. resolve(getArrValue(data))
  136. }
  137. //树节点被点击
  138. const isTreeNode = ref(false)
  139. const nodeInfo = ref({})
  140. const treeNodeTap = async ({ data }) => {
  141. nodeInfo.value = data
  142. if (data.fileType !== 3) {
  143. isTreeNode.value = false
  144. return
  145. }
  146. await getExcelHtmlCol(data.id)
  147. await getTableData()
  148. isTreeNode.value = true
  149. }
  150. //获取excel模板
  151. const getExcelHtmlCol = async (id) => {
  152. const { error, code, data } = await mainApi.getExcelHtmlCol({ id })
  153. const resData = isString(data) ? data || '' : ''
  154. if (!error && code === 200 && resData) {
  155. excelHtml.value = resData
  156. } else {
  157. excelHtml.value = ''
  158. }
  159. }
  160. //excel模板
  161. const excelRef = ref(null)
  162. const excelHtml = ref('')
  163. //获取元素类型
  164. const dataType = ref([])
  165. const getDataType = async () => {
  166. dataType.value = await getDictionaryData('data_type')
  167. }
  168. //元素表格
  169. const tabRef = ref(null)
  170. const tableColumn = [
  171. { key: 'textInfo', name: '元素名称' },
  172. { key: 'textElementType', name: '数据类型' },
  173. { key: 'textDeviation', name: '允许偏差值' },
  174. { key: 'action', name: '操作', width: 90, align: 'center' },
  175. ]
  176. const tableData = ref([])
  177. const getTableData = async () => {
  178. const { data } = await mainApi.getColByTabId({
  179. tabId: nodeInfo.value.id,
  180. })
  181. tableData.value = getArrValue(data)
  182. }
  183. //框框被点击
  184. const excelClick = async (item) => {
  185. const arr = tableData.value
  186. let key = item.target.getAttribute('data-index')
  187. for (let i = 0; i < arr.length; i++) {
  188. let xys = isNullES(arr[i].xys) ? [] : arr[i].xys.split(',')
  189. if (xys.indexOf(key) > -1) {
  190. tabRef.value?.tableRef?.setCurrentRow(arr[i])
  191. await tableScrollToRow(i)
  192. break
  193. }
  194. }
  195. }
  196. //滚动到表格某一行
  197. const tableScrollToRow = async (index) => {
  198. const table = tabRef.value?.tableRef.$el
  199. const row = table.querySelectorAll('.el-table__row')[index]
  200. tabRef.value?.tableRef?.setScrollTop(row.offsetTop)
  201. }
  202. //表格的某一行被点击
  203. const tableRowClick = ({ row }) => {
  204. let xys = isNullES(row.xys) ? [] : row.xys.split(',')
  205. excelRef.value?.setSelect(xys)
  206. }
  207. //保存元素表格
  208. const saveRowClick = async (row) => {
  209. if (isNullES(row.textInfo)) {
  210. window?.$message.warning('请填写元素名称')
  211. return
  212. }
  213. const { isRes } = await mainApi.saveColByTabId(row)
  214. if (!isRes) return
  215. window.$message.success('保存成功')
  216. }
  217. //删除元素表格
  218. const delRowClick = (row) => {
  219. HcDelMsg(async (resolve) => {
  220. const { isRes } = await mainApi.delColByTabId(row.id)
  221. resolve() //关闭弹窗的回调
  222. if (!isRes) return
  223. window.$message.success('删除成功')
  224. getTableData().then()
  225. })
  226. }
  227. //添加新元素字段
  228. const addColTabShow = ref(false)
  229. const addColTabInfo = ref({})
  230. const addColByTab = () => {
  231. addColTabInfo.value = nodeInfo.value
  232. addColTabShow.value = true
  233. }
  234. //添加到元素库
  235. const elementLibShow = ref(false)
  236. const elementLibInfo = ref({})
  237. const elementLibClick = () => {
  238. elementLibInfo.value = nodeInfo.value
  239. elementLibShow.value = true
  240. }
  241. //关闭抽屉
  242. const drawerClose = () => {
  243. isShow.value = false
  244. dataInfo.value = {}
  245. emit('close')
  246. }
  247. </script>
  248. <style scoped lang="scss">
  249. </style>
  250. <style lang="scss">
  251. .el-overlay .el-drawer.hc-element-recognition-drawer {
  252. background-color: #F1F5F8;
  253. .tree-line .el-tree__empty-block {
  254. min-width: unset;
  255. }
  256. }
  257. </style>