8
0

wbs-tree.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. <template>
  2. <hc-drawer v-model="isShow" is-close to-id="hc-project-list">
  3. <div class="hc-project-wbs-tree flex">
  4. <div class="header hc-flex">
  5. <div class="name flex-1">{{ typeLable }} - {{ projectInfo.projectName }}</div>
  6. <div class="hc-flex">
  7. <el-dropdown trigger="click">
  8. <el-button hc-btn type="success">
  9. <span>数据同步</span>
  10. <hc-icon name="arrow-down-s" />
  11. </el-button>
  12. <template #dropdown>
  13. <el-dropdown-menu>
  14. <template v-for="item in dataSyncMenu" :key="item.key">
  15. <el-dropdown-item @click="dataSyncMenuClick(item)">{{ item.name }}</el-dropdown-item>
  16. </template>
  17. </el-dropdown-menu>
  18. </template>
  19. </el-dropdown>
  20. <el-button v-if="isFormSet" class="ml-3" hc-btn type="primary" @click="setIsFormSetValue">表单设置</el-button>
  21. <el-button v-else class="ml-3" hc-btn type="primary" @click="setIsFormSetValue">元素设置</el-button>
  22. <el-button hc-btn type="danger">节点参数</el-button>
  23. <el-button hc-btn color="#626aef">独立表单库</el-button>
  24. <el-button hc-btn type="warning">归档文件时间</el-button>
  25. </div>
  26. </div>
  27. <div class="body">
  28. <hc-body split padding="8px">
  29. <template #left>
  30. <hc-card v-loading="isTreeLoading" title="工程节点信息" scrollbar class="is-tree">
  31. <template #search>
  32. <hc-search-input v-model="searchTree.queryValue" @search="searchTreeClick">
  33. <template #prepend>
  34. <el-select v-model="searchTree.type" placeholder="类型" style="width: 75px">
  35. <el-option label="节点" value="1" />
  36. <el-option label="表名" value="2" />
  37. </el-select>
  38. </template>
  39. </hc-search-input>
  40. </template>
  41. <hc-data-tree
  42. v-if="isSearchTree" :h-props="treeProps" :datas="treeLoadData" tree-key="id" :auto-expand-keys="treeExpandKeys"
  43. :menus="treeMenus" @menu-tap="treeMenuClick" @node-tap="treeNodeClick"
  44. />
  45. <hc-lazy-tree
  46. v-else :h-props="treeProps" tree-key="id" :auto-expand-keys="treeExpandKeys"
  47. :menus="treeMenus" @load="treeLoadNode" @menu-tap="treeMenuClick" @node-tap="treeNodeClick"
  48. />
  49. </hc-card>
  50. </template>
  51. <template v-if="isFormSet">
  52. <div class="body-top">
  53. <hc-card title="节点信息">
  54. <hc-table :is-index="false" :column="nodeTableColumn" :datas="nodeTableData">
  55. <template #nodeType="{ row }">{{ getDictionaryName(nodeTypelist, row.nodeType, true) }}</template>
  56. </hc-table>
  57. </hc-card>
  58. </div>
  59. <div class="body-content">
  60. <hc-card title="当前项目信息表">
  61. <template #extra>
  62. <el-button hc-btn type="primary" :disabled="infoTableData.length <= 0">编辑</el-button>
  63. <el-button hc-btn type="success" :disabled="infoTableData.length <= 0">排序</el-button>
  64. </template>
  65. <hc-table v-loading="infoTableLoading" :is-index="false" :column="infoTableColumn" :datas="infoTableData">
  66. <template #tableType="{ row }">{{ getDictionaryName(tableTypelist, row.tableType, true) }}</template>
  67. <template #tableOwner="{ row }">{{ getDictionaryName(ownerTypeList, row.tableOwner, true) }}</template>
  68. <template #action="{ row }">
  69. <el-link type="primary">预览</el-link>
  70. <el-link v-if="row.status === 1" type="warning">隐藏表单</el-link>
  71. <el-link v-if="row.status === 0" type="success">取消隐藏</el-link>
  72. <el-link v-del-com:[delInfoTableRow]="row" type="danger">删除</el-link>
  73. </template>
  74. </hc-table>
  75. </hc-card>
  76. </div>
  77. </template>
  78. <template v-else>
  79. <hc-card>
  80. <hc-table v-loading="infoTableLoading" :is-index="false" :column="infoTableColumn1" :datas="infoTableData">
  81. <template #tableType="{ row }">{{ getDictionaryName(tableTypelist, row.tableType, true) }}</template>
  82. <template #isLinkTable="{ row }">{{ row.isLinkTable === 2 ? '是' : '否' }}</template>
  83. <template #tableOwner="{ row }">{{ getDictionaryName(ownerTypeList, row.tableOwner, true) }}</template>
  84. <template #action="{ row }">
  85. <el-link type="success" @click="associationList(row)">关联清表</el-link>
  86. <el-link v-loading="editElementLoading" type="primary" :disabled="row.excelId === -1 || isNullES(row.excelId)" @click="editElement(row)">编辑元素</el-link>
  87. <el-link v-loading="adjustExcelLoading" type="warning" :disabled="row.excelId === -1 || isNullES(row.excelId)" @click="adjustExcelClick(row)">调整表单</el-link>
  88. <el-link type="primary" @click="elementFormulasClick(row)">编辑元素公式</el-link>
  89. <el-link type="warning">表单同步</el-link>
  90. <el-link type="primary">关联节点</el-link>
  91. <el-link v-del-com:[delInfoTableRow]="row" type="danger">删除表单</el-link>
  92. </template>
  93. </hc-table>
  94. </hc-card>
  95. </template>
  96. </hc-body>
  97. </div>
  98. </div>
  99. <!-- 编辑节点 -->
  100. <TreeNodeEditDialog
  101. v-model="isTreeNodeEditShow" :node="treeInfo" :type="Number(isType)" :wid="wbsId" :pid="projectInfo.id" :tree-props="treeProps"
  102. :node-type="nodeTypelist" :major-type="majorDataTypeList" @close="treeNodeEditClose" @change="treeNodeEditChange"
  103. />
  104. <!-- 节点排序 -->
  105. <hc-new-dialog v-model="nodeSortModalShow" is-table widths="1100px" title="调整排序" @save="nodeSortModalSave">
  106. <hc-table
  107. ui="hc-table-row-drop" :column="nodeSortTableColumn" :datas="nodeSortTableData"
  108. :loading="nodeSortNodeLoading" is-row-drop quick-sort :index-style="{ width: 80 }"
  109. @row-drop="nodeSortTableRowDrop" @row-sort="nodeSortTableRowDrop"
  110. >
  111. <template #action="{ row, index }">
  112. <span class="text-xl" :class="index === 0 ? 'text-gray' : 'text-link'" @click="upNodeSortClick(row, index)">
  113. <hc-icon name="arrow-up" fill />
  114. </span>
  115. <span class="ml-2 text-xl" :class="index === (nodeSortTableData.length - 1) ? 'text-gray' : 'text-link'" @click="downNodeSortClick(row, index)">
  116. <hc-icon name="arrow-down" fill />
  117. </span>
  118. </template>
  119. </hc-table>
  120. </hc-new-dialog>
  121. <!-- 关联清表 -->
  122. <HcAssociationList v-model="isAssociationShow" :info="associationInfo" @change="getInfoTableData" />
  123. <!-- 编辑元素 -->
  124. <HcEditElement v-model="isEditElementShow" :info="editElementInfo" :data="editElementData" @to-page="editElementToPage" />
  125. <!-- 调整表单 -->
  126. <HcAdjustExcel v-model="isAdjustExcelShow" :info="adjustExcelInfo" />
  127. <!-- 编辑元素公式 -->
  128. <hc-dialog v-model="elementFormulasShow" is-table widths="600px" :title="elementFormulasName" :footer="false" @close="elementFormulasClose">
  129. <template #search>
  130. <hc-search-input v-model="formulaInput" @search="searchFormulaClick" />
  131. </template>
  132. <hc-table v-loading="formulaTableLoading" :is-index="false" :is-current-row="false" :column="formulaTableColumn" :datas="formulaTableData">
  133. <template #action="{ row }">
  134. <el-link :type="row.globalFormula === 1 ? 'warning' : 'primary'" @click="toFormulaGlobal(row)">全局公式</el-link>
  135. <el-link v-show="row.hasPartFormula" :type="row.isSaveFormula === 1 ? 'warning' : 'primary'" @click="toFormulaNodes(row)">节点公式</el-link>
  136. </template>
  137. </hc-table>
  138. </hc-dialog>
  139. <!-- 编辑公式 -->
  140. <HcEditFormula v-model="isEditFormulaShow" :data="editFormulaData" @finish="editFormulaFinish" />
  141. </hc-drawer>
  142. </template>
  143. <script setup>
  144. import { nextTick, onDeactivated, ref, watch } from 'vue'
  145. import { useAppStore } from '~src/store'
  146. import { HcFirmMsg, getStore, setStore } from 'hc-vue3-ui'
  147. import { deepClone, getArrValue, getObjValue, isNullES } from 'js-fast-way'
  148. import { getDictionaryData, reloadPage } from '~uti/tools'
  149. import TreeNodeEditDialog from './tree-node-edit.vue'
  150. import HcAdjustExcel from './adjust-excel.vue'
  151. import HcAssociationList from './association-list.vue'
  152. import HcEditElement from './edit-element.vue'
  153. import HcEditFormula from './edit-formula.vue'
  154. import excelApi from '~api/exctab/exceltab'
  155. import wbsTreeApi from '~api/wbs/tree'
  156. import mainApi from '~api/wbs/private'
  157. const props = defineProps({
  158. type: {
  159. type: [String, Number],
  160. default: '1',
  161. },
  162. info: {
  163. type: Object,
  164. default: () => ({}),
  165. },
  166. })
  167. //事件
  168. const emit = defineEmits(['change', 'close'])
  169. //双向绑定
  170. // eslint-disable-next-line no-undef
  171. const isShow = defineModel('modelValue', {
  172. default: false,
  173. })
  174. const store = useAppStore()
  175. //监听数据
  176. const isType = ref(props.type)
  177. const projectInfo = ref(props.info)
  178. watch(() => [props.type, props.info], ([type, info]) => {
  179. isType.value = type
  180. projectInfo.value = info
  181. }, { deep: true })
  182. //监听显示
  183. watch(isShow, (val) => {
  184. if (val) {
  185. getProjectData()
  186. } else {
  187. //projectInfo.value = {}
  188. //isType.value = ''
  189. emit('close')
  190. }
  191. })
  192. //获取项目信息
  193. const typeLable = ref('')
  194. const wbsId = ref('')
  195. const getProjectData = () => {
  196. const type = isType.value ?? 1
  197. const wbsArr = ['WBS树管理', '实验划分', '计量管理', '日志树管理', '征拆划分']
  198. typeLable.value = wbsArr[Number(type) - 1]
  199. const wbsIds = [
  200. 'referenceWbsTemplateId', 'referenceWbsTemplateIdTrial',
  201. 'referenceWbsTemplateIdMeter', 'referenceLogWbsTemplateId',
  202. 'referenceWbsTemplateIdLar',
  203. ]
  204. wbsId.value = projectInfo.value[wbsIds[Number(type) - 1]]
  205. console.log('info: ', projectInfo.value)
  206. getNodeTypelist(Number(type) - 1)
  207. getTableTypelist(Number(type) - 1)
  208. getDataTypelist()
  209. getOwnerTypelist()
  210. getMajorDataTypeList()
  211. }
  212. //获取节点类型
  213. const nodeTypelist = ref([])
  214. const getNodeTypelist = async (type) => {
  215. //计量管理,征拆划分,实验划分,WBS树管理,日志树管理
  216. const types = ['wbs_node_type', 'trial_node_type', 'meter_node_type', 'wbs_node_type', 'lar_node_type']
  217. const data = await getDictionaryData(types[type])
  218. nodeTypelist.value = getArrValue(data)
  219. }
  220. //获取表单类型
  221. const tableTypelist = ref([])
  222. const getTableTypelist = async (type) => {
  223. //计量管理,征拆划分,实验划分,WBS树管理,日志树管理
  224. const types = ['table_type', 'trial_table_type', 'table_type', 'table_type', 'table_type']
  225. const data = await getDictionaryData(types[type])
  226. tableTypelist.value = getArrValue(data)
  227. }
  228. //获取数据类型
  229. const dataTypeList = ref([])
  230. const getDataTypelist = async () => {
  231. const data = await getDictionaryData('data_type')
  232. dataTypeList.value = getArrValue(data)
  233. }
  234. //获取业主类型
  235. const ownerTypeList = ref([])
  236. const getOwnerTypelist = async () => {
  237. const data = await getDictionaryData('owner_type')
  238. ownerTypeList.value = getArrValue(data)
  239. }
  240. //获取类型字典
  241. const majorDataTypeList = ref([])
  242. const getMajorDataTypeList = async () => {
  243. const data = await getDictionaryData('major_data_type')
  244. majorDataTypeList.value = getArrValue(data)
  245. }
  246. //获取字典里的数据
  247. const getDictionaryName = (arr, id, name) => {
  248. if (isNullES(id)) return name ? '' : {}
  249. const item = arr.find((item) => item.value === Number(id))
  250. return name ? item?.label : getObjValue(item)
  251. }
  252. //树节点搜索
  253. const isSearchTree = ref(false)
  254. const isTreeLoading = ref(false)
  255. const searchTree = ref({ queryValue: '', type: '1' })
  256. const searchTreeClick = () => {
  257. const { queryValue } = searchTree.value
  258. isSearchTree.value = !isNullES(queryValue)
  259. getTreeLoadData()
  260. }
  261. //获取搜索树的数据
  262. const treeLoadData = ref([])
  263. const getTreeLoadData = async () => {
  264. isTreeLoading.value = true
  265. const { data } = await wbsTreeApi.getQueryValueByType({
  266. ...searchTree.value,
  267. wbsId: wbsId.value,
  268. projectId: projectInfo.value.id,
  269. })
  270. treeLoadData.value = getArrValue(data)
  271. isTreeLoading.value = false
  272. }
  273. //树属性
  274. const treeExpandKeys = ref(getStore('project-wbs-tree-expand-keys') || [])
  275. const treeProps = {
  276. children: 'children',
  277. label: 'title',
  278. isLeaf: ({ hasChildren, isExistForm, majorDataType, nodeType }) => {
  279. let tag = false
  280. if (!hasChildren) {
  281. tag = true
  282. }
  283. if (isExistForm === 1) {
  284. tag = true
  285. }
  286. if (nodeType >= 6 && nodeType <= 13) {
  287. tag = true
  288. }
  289. //中间交工。开工报告、质量评定)
  290. if (majorDataType >= 1 && majorDataType <= 3) {
  291. tag = true
  292. }
  293. return tag
  294. },
  295. }
  296. //树的右键菜单
  297. const treeMenus = [
  298. { icon: 'draft', label: '编辑节点', key: 'edit' },
  299. { icon: 'refresh', label: '同步新增元素表单', key: 'sync1' },
  300. { icon: 'loop-left', label: '同步元素表单排序到合同段', key: 'sync3' },
  301. { icon: 'loop-right', label: '同步节点基础信息及表单URL', key: 'sync2' },
  302. { icon: 'arrow-up-down', label: '调整排序', key: 'rank' },
  303. { icon: 'delete-bin', label: '删除节点', key: 'del' },
  304. ]
  305. //菜单被点击
  306. const treeMenuItem = ref({})
  307. const treeMenuClick = async ({ key, node, data }) => {
  308. if (key === 'edit') { //编辑节点
  309. data.parentName = node?.parent?.data?.title ?? '' //获取父节点名称
  310. treeItem.value = data
  311. await getTreeDetail()
  312. await nextTick()
  313. isTreeNodeEditShow.value = true
  314. } else if (key === 'sync1') {
  315. const { primaryKeyId, pKeyId } = data
  316. const pid = primaryKeyId ? primaryKeyId : pKeyId
  317. if (isNullES(pid)) {
  318. window.$message.warning('参数异常,请稍后重试')
  319. return
  320. }
  321. //同步新增元素表单
  322. await HcFirmMsg({
  323. text: `是否同步节点【${data.title}】?`,
  324. loadingText: '数据同步中...',
  325. }, (resolve) => {
  326. const { isRes } = mainApi.syncNodeTable(pid)
  327. resolve() //关闭弹窗
  328. if (!isRes) return
  329. window.$message.success('同步成功')
  330. getInfoTableData()
  331. })
  332. } else if (key === 'sync3') {
  333. const { id } = projectInfo.value
  334. if (isNullES(id)) {
  335. window.$message.warning('参数异常,请稍后重试')
  336. return
  337. }
  338. //同步元素表单排序到合同段
  339. await HcFirmMsg({
  340. text: '同步元素表单排序到合同段?',
  341. loadingText: '数据同步中...',
  342. }, (resolve) => {
  343. const { isRes } = mainApi.syncContractTabSort(id)
  344. resolve() //关闭弹窗
  345. if (!isRes) return
  346. window.$message.success('同步成功')
  347. getInfoTableData()
  348. })
  349. } else if (key === 'sync2') {
  350. const { primaryKeyId, pKeyId } = data
  351. const pid = primaryKeyId ? primaryKeyId : pKeyId
  352. if (isNullES(pid)) {
  353. window.$message.warning('参数异常,请稍后重试')
  354. return
  355. }
  356. //同步节点基础信息及表单URL
  357. await HcFirmMsg({
  358. text: `是否同步节点【${data.title}】到合同段?`,
  359. loadingText: '数据同步中...',
  360. }, (resolve) => {
  361. const { isRes } = mainApi.syncNodeinfo(pid)
  362. resolve() //关闭弹窗
  363. if (!isRes) return
  364. window.$message.success('同步成功')
  365. getInfoTableData()
  366. })
  367. } else if (key === 'rank') {
  368. const { parentId } = data
  369. const { id } = projectInfo.value
  370. if (isNullES(id) || isNullES(wbsId.value)) {
  371. window.$message.warning('参数异常,请稍后重试')
  372. return
  373. }
  374. //调整排序
  375. nodeSortModalShow.value = true
  376. nodeSortNodeLoading.value = true
  377. const { data: apiData } = await wbsTreeApi.findWbsTreePrivateSameLevel({
  378. parentId: parentId,
  379. projectId: id,
  380. wbsId: wbsId.value,
  381. })
  382. nodeSortNodeLoading.value = false
  383. nodeSortTableData.value = getArrValue(apiData)
  384. } else if (key === 'del') {
  385. if (node.level <= 1) {
  386. window.$message.warning('当前节点无法删除')
  387. return
  388. }
  389. const { primaryKeyId, pKeyId } = data
  390. const pid = primaryKeyId ? primaryKeyId : pKeyId
  391. if (isNullES(pid)) {
  392. window.$message.warning('参数异常,请稍后重试')
  393. return
  394. }
  395. //删除节点
  396. await HcFirmMsg({
  397. text: `此操作将删除节点【${data.title}】,是否继续?`,
  398. loadingText: '删除节点中...',
  399. }, (resolve) => {
  400. const { isRes } = mainApi.del(pid)
  401. resolve() //关闭弹窗
  402. if (!isRes) return
  403. window.$message.success('删除成功')
  404. reloadPage()
  405. })
  406. }
  407. }
  408. //节点排序
  409. const nodeSortModalShow = ref(false)
  410. const nodeSortTableColumn = ref([
  411. { key:'tableName', name: '节点名称' },
  412. { key:'action', name: '排序', width: 90 },
  413. ])
  414. const nodeSortTableData = ref([])
  415. const nodeSortNodeLoading = ref(false)
  416. //拖动完成
  417. const nodeSortTableRowDrop = (rows) => {
  418. nodeSortTableData.value = [] // 先清空,否则排序会异常
  419. nextTick(() => {
  420. nodeSortTableData.value = rows
  421. })
  422. }
  423. //向上
  424. const upNodeSortClick = (row, index) => {
  425. const data = nodeSortTableData.value || []
  426. if (index !== 0) {
  427. const tmp = data.splice(index - 1, 1)
  428. nodeSortTableData.value.splice(index, 0, tmp[0])
  429. } else {
  430. window?.$message?.warning('已经处于置顶,无法上移')
  431. }
  432. }
  433. //向下
  434. const downNodeSortClick = (row, index) => {
  435. const indexs = index + 1
  436. const data = nodeSortTableData.value
  437. if (indexs !== data.length) {
  438. const tmp = data.splice(indexs, 1)
  439. nodeSortTableData.value.splice(index, 0, tmp[0])
  440. } else {
  441. window?.$message?.warning('已经处于置底,无法下移')
  442. }
  443. }
  444. //节点排序完成
  445. const nodeSortModalSave = async () => {
  446. const arr = deepClone(nodeSortTableData.value)
  447. if (arr.length <= 0) {
  448. window.$message.warning('数据异常,请稍后重试')
  449. nodeSortModalShow.value = false
  450. return
  451. }
  452. //处理顺序
  453. for (let i = 0; i < arr.length; i++) {
  454. arr[i].sort = i + 1
  455. }
  456. //发起请求
  457. const { isRes } = await wbsTreeApi.wbsTreePrivateSort(arr)
  458. if (!isRes) return
  459. window.$message.success('排序完成')
  460. nodeSortModalShow.value = false
  461. reloadPage()
  462. }
  463. //编辑节点
  464. const isTreeNodeEditShow = ref(false)
  465. //编辑节点被关闭
  466. const treeNodeEditClose = () => {
  467. isTreeNodeEditShow.value = false
  468. treeMenuItem.value = {}
  469. }
  470. //编辑节点被修改
  471. const treeNodeEditChange = () => {
  472. isTreeNodeEditShow.value = false
  473. treeMenuItem.value = {}
  474. console.log('编辑节点被修改')
  475. }
  476. //懒加载树
  477. const treeLoadNode = async ({ item, level }, resolve) => {
  478. let pid = level !== 0 ? item.id : 0
  479. const { data } = await mainApi.getLazytree({
  480. wbsId: wbsId.value,
  481. parentId: pid,
  482. tenantId: store.tenantId,
  483. projectId: projectInfo.value.id,
  484. wbsType: isType.value,
  485. })
  486. resolve(getArrValue(data))
  487. }
  488. //节点信息
  489. const nodeTableColumn = ref([
  490. { key: 'nodeName', name: '当前节点', align: 'center' },
  491. { key: 'nodeType', name: '节点类型', align: 'center' },
  492. { key: 'parentName', name: '上级节点', align: 'center' },
  493. ])
  494. const nodeTableData = ref([])
  495. //节点被点击
  496. const treeItem = ref({})
  497. const treeNodeClick = ({ node, data, keys }) => {
  498. //获取父节点名称
  499. let parentName = ''
  500. if (node?.parent?.data) {
  501. parentName = node.parent.data.title ?? ''
  502. }
  503. data.parentName = parentName
  504. //设置相关数据
  505. treeItem.value = getObjValue(data)
  506. setStore('project-wbs-tree-expand-keys', keys)
  507. treeExpandKeys.value = getArrValue(keys)
  508. //获取节点详情
  509. getTreeDetail()
  510. getInfoTableData()
  511. }
  512. //获取节点详情
  513. const treeInfo = ref({})
  514. const getTreeDetail = async () => {
  515. const { id, parentName } = treeItem.value
  516. const { data } = await mainApi.detail({
  517. id,
  518. wbsId: wbsId.value,
  519. projectId: projectInfo.value.id,
  520. })
  521. const res = getObjValue(data)
  522. res.parentName = parentName
  523. treeInfo.value = res
  524. nodeTableData.value = [res]
  525. }
  526. //当前项目信息表
  527. const infoTableLoading = ref(false)
  528. const infoTableColumn = ref([
  529. { key: 'tableName', name: '表单名称' },
  530. { key: 'elementTotal', name: '字段总量', align: 'center', width: 80 },
  531. { key: 'fillRate', name: '填报率', align: 'center', width: 80 },
  532. { key: 'tableType', name: '表单类型', align: 'center', width: 100 },
  533. { key: 'tableOwner', name: '所属方', align: 'center', width: 100 },
  534. { key: 'action', name: '操作', align: 'center', width: 160 },
  535. ])
  536. const infoTableData = ref([])
  537. const getInfoTableData = async () => {
  538. const { id } = treeItem.value
  539. infoTableLoading.value = true
  540. const { data } = await mainApi.findNodeTableByCondition({
  541. parentId: id,
  542. wbsId: wbsId.value,
  543. projectId: projectInfo.value.id,
  544. })
  545. infoTableData.value = getArrValue(data)
  546. infoTableLoading.value = false
  547. }
  548. //当前项目信息表删除
  549. const delInfoTableRow = async ({ item }, resolve) => {
  550. const { isRes } = await mainApi.removeTableByCondition({
  551. id: item.id,
  552. wbsId: wbsId.value,
  553. projectId: projectInfo.value.id,
  554. })
  555. resolve() //关闭弹窗
  556. if (!isRes) return
  557. window.$message.success('删除成功')
  558. getInfoTableData().then()
  559. }
  560. //表单设置
  561. const isFormSet = ref(true)
  562. const infoTableColumn1 = ref([
  563. { key: 'tableName', name: '表单名称' },
  564. { key: 'tableType', name: '表单类型', align: 'center', width: 80 },
  565. { key: 'fillRate', name: '填报率', align: 'center', width: 80 },
  566. { key: 'isLinkTable', name: '关联清表', align: 'center', width: 80 },
  567. { key: 'tableOwner', name: '所属方', align: 'center', width: 100 },
  568. { key: 'action', name: '操作', width: 490, align: 'center', fixed: 'right' },
  569. ])
  570. const setIsFormSetValue = () => {
  571. isFormSet.value = !isFormSet.value
  572. if (isFormSet.value) {
  573. getTreeDetail()
  574. }
  575. getInfoTableData()
  576. }
  577. //数据同步按钮菜单
  578. const dataSyncMenu = [
  579. { key: 'jdSync', name: '节点参数同步', load:false },
  580. { key: 'dqSync', name: '电签同步', load:false },
  581. { key: 'gsSync', name: '公式同步', load:false },
  582. ]
  583. const dataSyncMenuClick = (item) => {
  584. console.log( item)
  585. }
  586. // 关联清表
  587. const isAssociationShow = ref(false)
  588. const associationInfo = ref({})
  589. const associationList = async (item) => {
  590. associationInfo.value = item
  591. await nextTick()
  592. isAssociationShow.value = true
  593. }
  594. //编辑元素
  595. const isEditElementShow = ref(false)
  596. const editElementInfo = ref({})
  597. const editElementData = ref({})
  598. const editElementLoading = ref(false)
  599. const editElement = async (row) => {
  600. editElementLoading.value = true
  601. const { code, data } = await excelApi.getExcelHtml({ pkeyId: row.pkeyId })
  602. if (code !== 200 || isNullES(data)) {
  603. editElementLoading.value = false
  604. window?.$message.warning('表单异常,请联系管理员')
  605. return
  606. }
  607. editElementLoading.value = false
  608. editElementInfo.value = row
  609. editElementData.value = {
  610. pid: projectInfo.value.id,
  611. wbsid: wbsId.value,
  612. nodeid: treeItem.value.id,
  613. }
  614. await nextTick()
  615. isEditElementShow.value = true
  616. }
  617. //调整表单
  618. const isAdjustExcelShow = ref(false)
  619. const adjustExcelLoading = ref(false)
  620. const adjustExcelInfo = ref({})
  621. const adjustExcelClick = async (row) => {
  622. const { pkeyId, excelId } = row
  623. if (isNullES(pkeyId) || isNullES(excelId)) {
  624. window?.$message.warning('表单值异常,请联系管理员')
  625. return
  626. }
  627. adjustExcelLoading.value = true
  628. const { code, data } = await excelApi.getExcelHtml({ pkeyId })
  629. if (code !== 200 || isNullES(data)) {
  630. adjustExcelLoading.value = false
  631. window?.$message.warning('表单异常,请联系管理员')
  632. return
  633. }
  634. adjustExcelInfo.value = deepClone(row)
  635. adjustExcelLoading.value = false
  636. isAdjustExcelShow.value = true
  637. }
  638. //编辑元素里的跳转页面
  639. const editElementToPage = async (name) => {
  640. const row = deepClone(editElementInfo.value)
  641. //表单调整
  642. if (name === 'adjustment') {
  643. adjustExcelInfo.value = deepClone(row)
  644. await nextTick()
  645. isAdjustExcelShow.value = true
  646. }
  647. //公式配置
  648. if (name === 'formula') {
  649. console.log('还没做')
  650. }
  651. }
  652. //编辑元素公式
  653. const elementFormulasName = ref('')
  654. const elementFormulasObj = ref({})
  655. const elementFormulasShow = ref(false)
  656. const elementFormulasClick = async (row) => {
  657. elementFormulasObj.value = row
  658. elementFormulasName.value = row.tableName + ' 元素公式'
  659. elementFormulasShow.value = true
  660. formulaTableLoading.value = true
  661. const { data } = await wbsTreeApi.selectFormElements({
  662. id: row.pkeyId,
  663. type: 0,
  664. })
  665. const arr = getArrValue(data)
  666. formulaTableData.value = arr
  667. formulaTableList.value = deepClone(arr)
  668. formulaTableLoading.value = false
  669. }
  670. //元素公式列表
  671. const formulaTableLoading = ref(false)
  672. const formulaTableColumn = [
  673. { key: 'eName', name: '字段信息' },
  674. { key: 'action', name: '操作', width: 160, align: 'center' },
  675. ]
  676. const formulaTableData = ref([])
  677. const formulaTableList = ref([])
  678. // 搜索元素公式
  679. const formulaInput = ref('')
  680. const searchFormulaClick = () => {
  681. const arr = formulaTableList.value
  682. formulaTableData.value = arr.filter(({ eName }) => {
  683. return eName.indexOf(formulaInput.value) > -1
  684. })
  685. }
  686. //编辑元素公式关闭
  687. const elementFormulasClose = () => {
  688. elementFormulasShow.value = false
  689. formulaTableLoading.value = false
  690. elementFormulasName.value = ''
  691. formulaTableData.value = []
  692. formulaTableList.value = []
  693. }
  694. //编辑公式
  695. const isEditFormulaShow = ref(false)
  696. const editFormulaData = ref({})
  697. //全局公式,10
  698. const toFormulaGlobal = async (row) => {
  699. elementFormulasClose()
  700. const formulasObj = elementFormulasObj.value
  701. formulasObj.hasPartFormula = row.hasPartFormula
  702. editFormulaData.value = {
  703. node: formulasObj,
  704. pid: projectInfo.value.id,
  705. wbsId: wbsId.value,
  706. nodeId: treeItem.value.id,
  707. eleId: row.id,
  708. eleType: false,
  709. tableType: true,
  710. globalType: 10,
  711. }
  712. await nextTick()
  713. isEditFormulaShow.value = true
  714. }
  715. //节点公式,20
  716. const toFormulaNodes = async (row) => {
  717. elementFormulasClose()
  718. editFormulaData.value = {
  719. node: treeItem.value,
  720. pid: projectInfo.value.id,
  721. wbsId: wbsId.value,
  722. nodeId: treeItem.value.id,
  723. eleId: row.id,
  724. tableType: false,
  725. globalType: 20,
  726. }
  727. await nextTick()
  728. isEditFormulaShow.value = true
  729. }
  730. //公式操作完成
  731. const editFormulaFinish = () => {
  732. isEditFormulaShow.value = false
  733. editFormulaData.value = {}
  734. }
  735. //离开了当前页面
  736. onDeactivated(() => {
  737. isAdjustExcelShow.value = false
  738. })
  739. </script>
  740. <style scoped lang="scss">
  741. .hc-project-wbs-tree {
  742. position: relative;
  743. background: #ececec;
  744. border-radius: 4px;
  745. height: 100%;
  746. flex-direction: column;
  747. overflow: hidden;
  748. .header {
  749. color: white;
  750. background: #54565A;
  751. padding: 10px 14px;
  752. flex-shrink: 0;
  753. .name {
  754. white-space:nowrap;
  755. overflow:hidden;
  756. text-overflow:ellipsis;
  757. }
  758. }
  759. .body {
  760. flex: 1;
  761. flex-basis: auto;
  762. position: relative;
  763. }
  764. }
  765. </style>
  766. <style lang="scss">
  767. .hc-project-wbs-tree .body {
  768. .el-card.hc-card-box {
  769. --el-card-padding: 12px;
  770. --el-card-border-radius: 5px;
  771. }
  772. .hc-page-split-content {
  773. position: relative;
  774. .body-top {
  775. position: relative;
  776. height: 119.5px;
  777. }
  778. .body-content {
  779. position: relative;
  780. margin-top: 10px;
  781. height: calc(100% - 129.5px);
  782. }
  783. }
  784. }
  785. </style>