index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. <template>
  2. <div class="boxswai">
  3. <div class="boxnei">
  4. <el-row
  5. :gutter="20"
  6. style="height:100%;"
  7. >
  8. <el-col
  9. :span="5"
  10. style="height:99%;"
  11. >
  12. <div
  13. style="fontSize:18px; font-weight: 900;"
  14. class="marbottom5"
  15. >元素识别</div>
  16. <div style="height:98%;overflow: auto;width:auto;">
  17. <el-tree
  18. :data="treeData"
  19. :props="treeProps"
  20. @node-click="handleNodeClick"
  21. :load="loadNode"
  22. :expand-on-click-node="false"
  23. lazy
  24. ></el-tree>
  25. </div>
  26. </el-col>
  27. <el-col
  28. :span="19"
  29. style="height:98%;"
  30. >
  31. <div v-if="addElementForm.deptName==''">表名称</div>
  32. <div v-else>{{addElementForm.deptName}}</div>
  33. <el-row
  34. class="martop20"
  35. :gutter="20"
  36. style="height:96%;"
  37. >
  38. <el-col
  39. :span="16"
  40. style="overflow:auto;height:100%;border:1px solid black; border-radius: 4px;box-sizing: border-box;padding: 10px 10px;"
  41. >
  42. <div
  43. class="parent"
  44. id='parent'
  45. >
  46. </div>
  47. </el-col>
  48. <el-col
  49. :span="8"
  50. style="overflow:auto;height:100%;"
  51. >
  52. <div class="flexBetween flexItemsC">
  53. <el-button
  54. type="info"
  55. size="mini"
  56. :disabled="from.id==''"
  57. @click="automaticRecognition"
  58. >自动识别</el-button>
  59. <div
  60. class="el-icon-plus"
  61. @click="pushTableData"
  62. style="width:16px;height:16px;backgroundColor:#1DD81D;color:#fff;cursor: pointer;"
  63. ></div>
  64. </div>
  65. <el-table
  66. class="martop20"
  67. :data="tableData"
  68. border
  69. style="width: 100%"
  70. >
  71. <el-table-column
  72. type="index"
  73. label="坐标"
  74. >
  75. </el-table-column>
  76. <el-table-column
  77. prop="eName"
  78. label="元素名称"
  79. >
  80. <template slot-scope="scope">
  81. <el-input
  82. v-model="scope.row.eName"
  83. placeholder="请输入内容"
  84. ></el-input>
  85. </template>
  86. </el-table-column>
  87. <el-table-column
  88. prop="eType"
  89. label="数据类型"
  90. >
  91. <template slot-scope="scope">
  92. <el-select
  93. v-model="scope.row.eType"
  94. placeholder="请选择"
  95. >
  96. <el-option
  97. v-for="item in dataType"
  98. :key="item.dictKey"
  99. :label="item.dictValue"
  100. :value="item.dictKey"
  101. >
  102. </el-option>
  103. </el-select>
  104. </template>
  105. </el-table-column>
  106. <el-table-column
  107. prop="eAllowDeviation"
  108. label="允许偏差值"
  109. >
  110. <template slot-scope="scope">
  111. <el-input
  112. v-model="scope.row.eAllowDeviation"
  113. placeholder="请输入内容"
  114. ></el-input>
  115. </template>
  116. </el-table-column>
  117. <el-table-column label="操作">
  118. <template slot-scope="scope">
  119. <el-link
  120. type="danger"
  121. @click="deleteTableData(scope.$index)"
  122. >删除</el-link>
  123. </template>
  124. </el-table-column>
  125. </el-table>
  126. <el-button
  127. type="success"
  128. class="martop20 dingwei"
  129. @click="establish()"
  130. :disabled="from.id==''"
  131. >关联WBS并创建元素</el-button>
  132. </el-col>
  133. </el-row>
  134. </el-col>
  135. </el-row>
  136. <!-- 关联公共WBS模板 -->
  137. <el-dialog
  138. title="关联公共WBS模板"
  139. class="excelBox"
  140. :visible.sync="AssociatedPublicTap"
  141. modal-append-to-body
  142. append-to-body
  143. :before-close="AssociatedPublicClose"
  144. >
  145. <el-row :gutter="20">
  146. <el-col :span="12">
  147. <el-select
  148. style="width:100%;"
  149. v-model="GLExcelFrom.name"
  150. placeholder="请选择"
  151. @change="changetherr()"
  152. >
  153. <el-option
  154. v-for="(item,key) in GLExcelData"
  155. :key="key"
  156. :label="item.wbsName"
  157. :value="item.id"
  158. >
  159. </el-option>
  160. </el-select>
  161. <el-scrollbar style="height:50vh;">
  162. <el-tree
  163. v-if="GLExcelFromtag"
  164. @node-click="handleNodeClickExcel"
  165. ref="tree"
  166. class="filter-tree"
  167. style="margin-top:10px;"
  168. :props="GLExcelProps"
  169. :data="exceldata"
  170. :load="loadNodeTan"
  171. lazy
  172. node-key="id"
  173. accordion
  174. >
  175. </el-tree>
  176. </el-scrollbar>
  177. </el-col>
  178. <el-col
  179. :span="12"
  180. v-if="addElementForm.wbsId"
  181. >
  182. <el-button
  183. type="primary"
  184. style="float:right;"
  185. class="marbottom20"
  186. @click="addElementMD"
  187. :disabled="addElement"
  188. >新增元素信息表</el-button>
  189. <el-table
  190. :data="addTableData"
  191. border
  192. style="width: 100%"
  193. >
  194. <el-table-column
  195. prop="tableName"
  196. label="已有元素表名称"
  197. align="center"
  198. >
  199. </el-table-column>
  200. <el-table-column
  201. prop="name"
  202. label="操作"
  203. align="center"
  204. >
  205. <template slot-scope="scope">
  206. <el-button
  207. type="primary"
  208. size="mini"
  209. @click="relationMD(scope.$index,'关联')"
  210. v-show="!scope.row.checknd"
  211. >选择关联</el-button>
  212. <el-button
  213. type="danger"
  214. size="mini"
  215. @click="relationMD(scope.$index,'取消关联')"
  216. v-show="scope.row.checknd"
  217. >取消关联</el-button>
  218. </template>
  219. </el-table-column>
  220. </el-table>
  221. <div v-if="addElement">
  222. <div class="flexBetween martop40">
  223. <el-input
  224. v-model="addElementForm.deptName"
  225. placeholder="请输入表名"
  226. ></el-input>
  227. <el-select
  228. class="marleft10"
  229. v-model="addElementForm.tableType"
  230. placeholder="请选择表类型"
  231. >
  232. <el-option
  233. v-for="(item,index) in exceltypeData"
  234. :key="index"
  235. :label="item.dictValue"
  236. :value="item.dictKey"
  237. ></el-option>
  238. </el-select>
  239. </div>
  240. <el-select
  241. style="width:100%;"
  242. class="martop20 "
  243. v-model="addElementForm.tableOwner"
  244. placeholder="请选择所属方"
  245. >
  246. <el-option
  247. v-for="(item,index) in dataType"
  248. :key="index"
  249. :label="item.dictValue"
  250. :value="item.dictKey"
  251. ></el-option>
  252. </el-select>
  253. </div>
  254. </el-col>
  255. </el-row>
  256. <span
  257. slot="footer"
  258. class="dialog-footer"
  259. style="display: flex;justify-content: center;align-items: center;"
  260. >
  261. <el-button @click="AssociatedPublicClose()">取 消</el-button>
  262. <el-button
  263. style="margin-left:30px;"
  264. type="primary"
  265. @click="saveElementMD()"
  266. >确 定</el-button>
  267. </span>
  268. </el-dialog>
  269. </div>
  270. </div>
  271. </template>
  272. <script>
  273. import { tabLazytree, getExcelHtmlCol, excelType, submitExcelRelationWbsTreeAndElement, getWbsTypeList, getLazytree, } from "@/api/exctab/excelmodel";
  274. import { dictionarydataType } from "@/api/exctab/editelement";
  275. import { getColByTabId } from "@/api/manager/AdjustForm";
  276. import { selectByNodeTable } from "@/api/manager/wbstree";
  277. import Vue from 'vue'
  278. export default {
  279. data () {
  280. return {
  281. //#region 左侧树节点
  282. treeData: [],
  283. treeProps: {
  284. label: 'name',
  285. children: 'children',
  286. isLeaf: 'hasChildren'
  287. },
  288. //#endregion
  289. excelSrc: '',
  290. from: {
  291. id: '',
  292. },
  293. tableData: [],//外层table
  294. dataType: [],
  295. AssociatedPublicTap: false,
  296. //#region 弹框属性
  297. GLExcelFrom: {
  298. id: "",
  299. name: '',
  300. search: '',//搜素框舒服的值
  301. },
  302. GLExcelData: [],//
  303. GLExcelProps: {
  304. label: 'title',
  305. children: 'children',
  306. isLeaf: 'isExistForm',
  307. },
  308. exceldata: [],//清表模板树数据
  309. addTableData: [],//新增元素信息表
  310. exceltypeData: [],//清表类型
  311. addElement: false,
  312. GLExcelFromtag: false,
  313. addElementForm: {
  314. id: "",
  315. initTableName: "",
  316. deptName: '',
  317. tableType: '',
  318. tableOwner: '',
  319. wbsId: '',
  320. parentId: '',
  321. }
  322. //#endregion
  323. }
  324. },
  325. methods: {
  326. //#region
  327. handleNodeClick (data) {//树节点点击事件
  328. console.log(data);
  329. if (data.fileType == 3) {
  330. this.getExcelHtmlCol(data.id)//获取excel模板
  331. if (this.dataType.length == 0) {
  332. this.dictionarydataType() //数据类型字典
  333. }
  334. this.addElement = false
  335. this.addElementForm.deptName = data.name
  336. this.from.id = data.id
  337. }
  338. },
  339. async loadNode (node, resolve) {//懒加载获取节点
  340. if (node.level === 0) {
  341. return resolve(await this.tabLazytree(this.$route.params.id, 0))
  342. }
  343. if (node.level > 0) {
  344. return resolve(await this.tabLazytree(this.$route.params.id, node.data.id))
  345. }
  346. },
  347. automaticRecognition () {//自动识别按钮
  348. this.getColByTabId()
  349. },
  350. pushTableData () {//
  351. if (this.from.id) {
  352. this.tableData.push({
  353. eName: '',
  354. eType: '',
  355. eAllowDeviation: ''
  356. })
  357. }
  358. },
  359. deleteTableData (key) {//删除
  360. this.tableData.splice(key, 1)
  361. },
  362. async getColByTabId () {//获取字段信息
  363. const { data: res } = await getColByTabId({ tabId: this.from.id })
  364. console.log(res);
  365. if (res.code === 200) {
  366. this.tableData = res.data
  367. }
  368. },
  369. async getExcelHtmlCol (id) {//获取excel模板
  370. const { data: res } = await getExcelHtmlCol({ id })
  371. console.log(res);
  372. if (res.code == 200) {
  373. // let _that = this
  374. var MyComponent = await Vue.extend({
  375. data () {
  376. return {
  377. formData: {}
  378. }
  379. },
  380. template: res.data,
  381. })
  382. var component = new MyComponent().$mount()
  383. let na = document.getElementById('parent')
  384. na.innerHTML = `<div
  385. class='parent'
  386. id='parent'"
  387. ></div>`
  388. document.getElementById('parent').appendChild(component.$el);
  389. }
  390. },
  391. //#endregion
  392. //#region 关联公共WBS模板弹框
  393. establish () {//关联WBS并创建元素
  394. this.getWbsTypeList()
  395. this.AssociatedPublicTap = true
  396. },
  397. AssociatedPublicClose () {//关联公共WBS模板关闭事件
  398. this.addElementForm = {
  399. id: "",
  400. initTableName: "",
  401. deptName: '',
  402. tableType: '',
  403. tableOwner: '',
  404. wbsId: '',
  405. parentId: '',
  406. }
  407. this.GLExcelFrom = {
  408. name: '',
  409. search: ''
  410. }
  411. this.exceldata = []
  412. this.addElement = false
  413. this.AssociatedPublicTap = false
  414. },
  415. async loadNodeTan (node, resolve) {//懒加载
  416. console.log(node);
  417. if (node.level === 0) {
  418. return resolve(await this.getLazytree(0));
  419. } else {
  420. return resolve(await this.getLazytree(node.data.id));
  421. }
  422. },
  423. changetherr () {//下拉框change事件
  424. this.GLExcelFromtag = false
  425. if (this.GLExcelFrom.name != "") {
  426. this.GLExcelFrom.search = ''
  427. this.exceldata = []
  428. this.addTableData = []
  429. this.addElementForm.wbsId = ''
  430. this.$nextTick(() => {
  431. this.GLExcelFromtag = true
  432. })
  433. }
  434. },
  435. addElementMD () {//新增元素信息表按钮
  436. this.excelType()
  437. this.addElement = true
  438. },
  439. async getWbsTypeList () {//获取清表模板信息
  440. const { data: res } = await getWbsTypeList({ wbsType: 1 })
  441. console.log(res);
  442. if (res.code === 200 && res.msg === '操作成功') {
  443. this.GLExcelData = res.data
  444. }
  445. },
  446. async getLazytree (parentId) {//清表树信息
  447. const { data: res } = await getLazytree({
  448. parentId: parentId,
  449. wbsId: this.GLExcelFrom.name,
  450. wbsType: '1'
  451. })
  452. console.log(res);
  453. if (res.code === 200 && res.msg === '操作成功') {
  454. res.data.forEach(val => {
  455. val.isExistForm = !!val.isExistForm
  456. })
  457. return res.data
  458. } else {
  459. return []
  460. }
  461. },
  462. handleNodeClickExcel (data) {//点击节点事件
  463. console.log(data);
  464. if (data.hasChildren) {
  465. this.addElementForm.wbsId = data.id
  466. this.addElementForm.parentId = data.parentId
  467. this.selectByNodeTable(data.id)
  468. }
  469. },
  470. async selectByNodeTable (id) {//获取清表信息
  471. const { data: res } = await selectByNodeTable(id)
  472. console.log(res);
  473. if (res.code == 200) {
  474. if (res.data.length > 0) {
  475. res.data.forEach(val => {
  476. if (val.isLinkTable == 2) {
  477. val.checknd = true
  478. } else {
  479. val.checknd = false
  480. }
  481. })
  482. }
  483. this.addTableData = res.data
  484. }
  485. },
  486. async excelType () {//清表类型
  487. const { data: res } = await excelType({ code: 'sys_excltab_type' })
  488. console.log(res);
  489. if (res.code === 200) {
  490. this.exceltypeData = res.data
  491. }
  492. },
  493. relationMD (index, type) {//关联取消关联
  494. console.log(this.addTableData[index]);
  495. if (this.addTableData.length > 0) {
  496. if (type == '关联') {
  497. this.addTableData.forEach((val, k) => {
  498. if (index == k) {
  499. val.checknd = !val.checknd
  500. } else {
  501. val.checknd = false
  502. }
  503. })
  504. this.addElementForm.id = this.addTableData[index].id
  505. this.addElementForm.initTableName = this.addTableData[index].initTableName
  506. } else {
  507. this.addTableData.forEach((val, k) => {
  508. val.checknd = false
  509. })
  510. this.addElementForm.id = ''
  511. this.addElementForm.initTableName = ''
  512. }
  513. }
  514. },
  515. saveElementMD () {//保存按钮
  516. if (this.addElementForm.wbsId) {
  517. if (this.addTableData.length > 0) {
  518. let tag = false
  519. this.addTableData.forEach(val => {
  520. if ((val.checknd == true && val.isLinkTable != 2) || (val.checknd == false && val.isLinkTable == 2)) {
  521. tag = true
  522. }
  523. })
  524. if (tag) {
  525. this.submitExcelRelationWbsTreeAndElement({
  526. id: this.addElementForm.id,
  527. initTableName: this.addElementForm.initTableName,
  528. elementList: this.tableData
  529. })
  530. } else {
  531. if (this.addElementForm.deptName && this.addElementForm.tableType && this.addElementForm.tableOwner) {
  532. this.submitExcelRelationWbsTreeAndElement({
  533. deptName: this.addElementForm.deptName,
  534. tableType: this.addElementForm.tableType,
  535. tableOwner: this.addElementForm.tableOwner,
  536. wbsId: this.addElementForm.wbsId,
  537. parentId: this.addElementForm.parentId,
  538. elementList: this.tableData
  539. })
  540. }
  541. }
  542. }
  543. } else {
  544. this.$message({
  545. type: 'error',
  546. message: '请先选择WBS树节点表单'
  547. })
  548. }
  549. },
  550. async submitExcelRelationWbsTreeAndElement (da) {//保存接口
  551. const { data: res } = await submitExcelRelationWbsTreeAndElement(da)
  552. console.log(res);
  553. if (res.code == 200) {
  554. this.$message({
  555. type: 'success',
  556. message: '设置成功'
  557. })
  558. this.AssociatedPublicTap = false
  559. }
  560. },
  561. //#endregion
  562. //#region 接口
  563. async tabLazytree (modeId, parentId) {
  564. const { data: res } = await tabLazytree({ modeId, parentId })
  565. console.log(res);
  566. if (res.code == 200) {
  567. if (res.data.length > 0) {
  568. res.data.forEach(val => {
  569. val.hasChildren = !val.hasChildren
  570. });
  571. }
  572. return res.data
  573. }
  574. },
  575. async dictionarydataType () {//数据类型字典
  576. const { data: res } = await dictionarydataType()
  577. console.log(res);
  578. if (res.code == 200) {
  579. this.dataType = res.data
  580. }
  581. },
  582. //#endregion
  583. },
  584. created () {
  585. }
  586. }
  587. </script>
  588. <style lang="scss" scoped>
  589. .boxswai {
  590. padding: 0px 14px 10px 14px !important;
  591. }
  592. .dingwei {
  593. position: fixed;
  594. bottom: 40px;
  595. right: 40px;
  596. }
  597. </style>