editElement.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. <template>
  2. <div
  3. style="height:100%;"
  4. ref="heights"
  5. >
  6. <basic-container class="editElement">
  7. <div
  8. class="header"
  9. style="padding-bottom:20px;"
  10. >
  11. 提示:鼠标右键功能:更换匹配元素字段、新增元素字段、删除匹配元素字段、公式配置&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 红色:代表匹配不成功、蓝色代表推荐匹配元素字段、绿色代表匹配成功
  12. </div>
  13. <el-row
  14. :gutter="20"
  15. :style="{height:heights-150+'px',}"
  16. >
  17. <el-col :span="16">
  18. <div
  19. class='parent'
  20. id='parent'
  21. >
  22. </div>
  23. </el-col>
  24. <el-col
  25. :span="7"
  26. style="position: fixed;right: 13px;"
  27. >
  28. <div v-show="AddNewElementField == '替换元素'">
  29. <el-select
  30. style="width:300px;"
  31. v-model="value"
  32. filterable
  33. placeholder="请选择"
  34. >
  35. <el-option
  36. v-for="item in options"
  37. :key="item.id"
  38. :label="item.eName"
  39. :value="item.id"
  40. >
  41. </el-option>
  42. </el-select>
  43. <div class="tihuan">替换为:</div>
  44. <el-input
  45. style="width:95%;"
  46. :disabled="true"
  47. type="textarea"
  48. :rows="4"
  49. placeholder="请输入内容"
  50. v-model="names"
  51. >
  52. </el-input>
  53. <div class="martop20">
  54. <el-button
  55. type="info"
  56. @click="cancelReplace()"
  57. >取消</el-button>
  58. <el-button
  59. type="primary"
  60. :disabled="tag"
  61. @click="saveReplace()"
  62. >保存</el-button>
  63. </div>
  64. </div>
  65. <div
  66. v-show="AddNewElementField ==''"
  67. style="width:160px;position: fixed;bottom: 20px; right:20px;"
  68. >
  69. <el-button type="info">取消</el-button>
  70. <el-button type="primary">保存</el-button>
  71. </div>
  72. </el-col>
  73. </el-row>
  74. <!-- 弹框 -->
  75. <div
  76. @mouseout="mouseout22"
  77. @mousemove="mousemove22"
  78. v-if="cascaderPanel"
  79. >
  80. <el-cascader-panel
  81. :style="{width:'360px',position: 'absolute',top:top+'px',left:left+'px','background-color':'#fff',margin:'40px',}"
  82. :props="{ expandTrigger: 'hover' }"
  83. :options="options2"
  84. @change="takuangchangge"
  85. ></el-cascader-panel>
  86. </div>
  87. <el-dialog
  88. title="添加新元素字段"
  89. :visible="AddNewElementField=='新增元素'"
  90. width="60%"
  91. :before-close="handleClose"
  92. :modal-append-to-body="false"
  93. style="z-index: 999999;"
  94. >
  95. <div>
  96. <i
  97. @click="addyuansu"
  98. class="el-icon-circle-plus marbottom10"
  99. style="color:red; font-size:24px; float: right;cursor: pointer;"
  100. ></i>
  101. <el-table
  102. :data="tableData"
  103. height="250"
  104. border
  105. style="width: 100%"
  106. >
  107. <el-table-column
  108. prop="date"
  109. label="清表元素名称"
  110. >
  111. <template slot-scope="scope">
  112. <el-input
  113. v-model="scope.row.eName"
  114. placeholder="请输入内容"
  115. ></el-input>
  116. </template>
  117. </el-table-column>
  118. <el-table-column
  119. prop="date"
  120. label="元素数据类型"
  121. >
  122. <template slot-scope="scope">
  123. <el-select
  124. style="width:100%;"
  125. v-model="scope.row.eType"
  126. placeholder="请选择"
  127. >
  128. <el-option
  129. v-for="item in dataType"
  130. :key="item.dictKey"
  131. :label="item.dictValue"
  132. :value="item.dictKey"
  133. >
  134. </el-option>
  135. </el-select>
  136. </template>
  137. </el-table-column>
  138. <!-- <el-table-column
  139. prop="date"
  140. label="长度"
  141. align="center"
  142. >
  143. <template slot-scope="scope">
  144. <el-input
  145. v-model="scope.row.date"
  146. placeholder="请输入内容"
  147. ></el-input>
  148. </template>
  149. </el-table-column> -->
  150. <el-table-column
  151. prop="date"
  152. align="center"
  153. width="120"
  154. label="操作"
  155. >
  156. <template slot-scope="scope">
  157. <el-button
  158. type="danger"
  159. size="mini"
  160. @click="deleteziduan(scope.$index)"
  161. >删除</el-button>
  162. </template>
  163. </el-table-column>
  164. </el-table>
  165. </div>
  166. <span
  167. slot="footer"
  168. class="dialog-footer"
  169. >
  170. <el-button @click="handleClose()">取 消</el-button>
  171. <el-button
  172. type="primary"
  173. v-throttle='2000'
  174. :disabled="tableData.length===0"
  175. @click="pushNewElementField()"
  176. >确 定</el-button>
  177. </span>
  178. </el-dialog>
  179. </basic-container>
  180. </div>
  181. </template>
  182. <script>
  183. import { getExcelHtml } from '@/api/exctab/excelmodel'
  184. import { getElementInfoByTabId, submit, dictionarydataType, submitBatch } from '@/api/exctab/editelement'
  185. import Vue from 'vue'
  186. export default {
  187. data () {
  188. return {
  189. heights: '',
  190. dataType: [],//数据类型
  191. tag: false,
  192. table: {
  193. },//table表鼠标右键事件
  194. AddNewElementField: '',
  195. setTimeout: '',
  196. top: 0,
  197. left: 0,
  198. cascaderPanel: false,
  199. options: [],
  200. value: '',
  201. names: '',//替换元素得值
  202. tableData: [],//table表
  203. options2: [{
  204. value: '编辑元素字段',
  205. label: '编辑元素字段',
  206. children: [{
  207. value: '替换元素',
  208. label: '替换元素'
  209. }, {
  210. value: '新增元素',
  211. label: '新增元素'
  212. }, {
  213. value: '删除文本信息',
  214. label: '删除文本信息'
  215. }]
  216. }, {
  217. value: '公式配置',
  218. label: '公式配置',
  219. }],
  220. ekeyReg:/(key_\d+)/,
  221. }
  222. },
  223. mounted () {
  224. this.cop()
  225. this.heights = this.$refs.heights.clientHeight
  226. },
  227. created () {
  228. this.getElementInfoByTabId()
  229. },
  230. methods: {
  231. takuangchangge (value) {//切换事件
  232. if (value[value.length - 1] == '替换元素') {
  233. this.AddNewElementField = '替换元素'
  234. this.cascaderPanel = false
  235. clearTimeout(this.setTimeout)
  236. } else if (value[value.length - 1] == '新增元素') {
  237. if (this.dataType.length == 0) {
  238. this.dictionarydataType()
  239. }
  240. this.tableData = []
  241. this.AddNewElementField = '新增元素'//打开新增元素弹框
  242. this.cascaderPanel = false
  243. clearTimeout(this.setTimeout)
  244. } else if (value[value.length - 1] == '删除文本信息') {
  245. this.deleteelement()
  246. this.cascaderPanel = false
  247. clearTimeout(this.setTimeout)
  248. } else if (value[value.length - 1] == '公式配置') {
  249. this.cascaderPanel = false
  250. clearTimeout(this.setTimeout)
  251. this.toFormulaEdit();
  252. }
  253. },
  254. mouseout22 () {//鼠标移出事件
  255. clearTimeout(this.setTimeout)
  256. this.setTimeout = setTimeout(() => {
  257. this.cascaderPanel = false
  258. }, 500)
  259. },
  260. mousemove22 () {//鼠标移入事件
  261. clearTimeout(this.setTimeout)
  262. this.setTimeout = setTimeout(() => {
  263. this.cascaderPanel = true
  264. }, 500)
  265. },
  266. RightClick2 (tr, td, x1, x2, y1, y2) {
  267. //console.log(event.target.getAttribute("keyname"))
  268. let targetkeyname = event.target.getAttribute("keyname");
  269. let ekey = null;
  270. if(this.ekeyReg.test(targetkeyname)){
  271. ekey = targetkeyname.match(this.ekeyReg)[1]
  272. }
  273. this.table = {
  274. tr,
  275. td,
  276. ekey
  277. }
  278. this.left = window.event.clientX - 300
  279. let Y = window.event.clientY
  280. if (window.outerHeight - Y > 200) {
  281. this.top = window.event.clientY - 80
  282. } else {
  283. this.top = window.event.clientY - 270
  284. }
  285. this.cascaderPanel = true
  286. clearTimeout(this.setTimeout)
  287. this.setTimeout = setTimeout(() => {
  288. this.cascaderPanel = false
  289. }, 3000)
  290. },
  291. deleteelement () {//删除元素提示
  292. let _that = this
  293. this.$confirm('确认删除该元素?', '提示', {
  294. confirmButtonText: '确定',
  295. cancelButtonText: '取消',
  296. type: 'warning'
  297. }).then(() => {
  298. _that.submit({
  299. colName: '/',
  300. tabId: this.$route.query.pkeyId,
  301. tdIndex: this.table.td,
  302. trIndex: this.table.tr,
  303. })
  304. }).catch(() => {
  305. _that.$message({
  306. type: 'info',
  307. message: '已取消删除'
  308. });
  309. });
  310. },
  311. getInformation2 (a, b, c) {
  312. if (this.AddNewElementField) {
  313. this.table = {
  314. tr: b,
  315. td: c
  316. }
  317. }
  318. },
  319. async cop () {
  320. let _that = this
  321. var MyComponent = await Vue.extend({
  322. template: localStorage.getItem('editElement'),
  323. data () {
  324. return {
  325. formData: {}
  326. }
  327. },
  328. methods: {
  329. RightClick (tr, td, x1, x2, y1, y2) {//鼠标右键事件
  330. _that.RightClick2(tr, td, x1, x2, y1, y2)
  331. },
  332. getInformation (a, b, c) {
  333. _that.getInformation2(a, b, c)
  334. }
  335. }
  336. })
  337. var component = new MyComponent().$mount()
  338. document.getElementById('parent').appendChild(component.$el);
  339. },
  340. async copss () {
  341. let _that = this
  342. var MyComponent = await Vue.extend({
  343. template: localStorage.getItem('editElement'),
  344. data () {
  345. return {
  346. formData: {}
  347. }
  348. },
  349. methods: {
  350. RightClick (tr, td, x1, x2, y1, y2) {//鼠标右键事件
  351. _that.RightClick2(tr, td, x1, x2, y1, y2)
  352. },
  353. getInformation (a, b, c) {
  354. _that.getInformation2(a, b, c)
  355. }
  356. }
  357. })
  358. var component = new MyComponent().$mount()
  359. let na = document.getElementById('parent')
  360. na.innerHTML = `<div
  361. class='parent'
  362. id='parent'
  363. ></div>`
  364. document.getElementById('parent').appendChild(component.$el);
  365. },
  366. async dictionarydataType () {
  367. const { data: res } = await dictionarydataType()
  368. console.log(res);
  369. if (res.code == 200) {
  370. this.dataType = res.data
  371. }
  372. },
  373. returns () {
  374. this.$router.push({
  375. path: '/project/tree',
  376. query: {
  377. pid: this.$route.query.pid,
  378. wbsid: this.$route.query.wbsid,
  379. }
  380. })
  381. },
  382. //#region 左侧替换元素
  383. cancelReplace () {//替换元素取消按钮
  384. this.AddNewElementField = ''
  385. },
  386. saveReplace () {//保存按钮
  387. if (this.value) {
  388. this.tag = true
  389. console.log({
  390. tabId: this.$route.query.pkeyId,
  391. tdIndex: this.table.td,
  392. trIndex: this.table.tr,
  393. colName: "",
  394. htmlType: this.value
  395. });
  396. this.submit({
  397. tabId: this.$route.query.pkeyId,
  398. tdIndex: this.table.td,
  399. trIndex: this.table.tr,
  400. colName: "",
  401. htmlType: this.value
  402. })
  403. } else {
  404. this.$message({
  405. type: "error",
  406. message: "请选择要替换的元素"
  407. })
  408. }
  409. },
  410. async getElementInfoByTabId () {//获取字段信息
  411. const { data: res } = await getElementInfoByTabId({ tabId: this.$route.query.id })
  412. console.log(res);
  413. if (res.code === 200) {
  414. this.options = res.data
  415. }
  416. },
  417. async submit (da) {//保存替换元素
  418. const { data: res } = await submit(da)
  419. console.log(res);
  420. if (res.code == 200) {
  421. const { data: res } = await getExcelHtml({ pkeyId: this.$route.query.pkeyId })
  422. console.log(res);
  423. if (res.code === 200) {
  424. this.tag = false
  425. this.value = ''
  426. this.options = []
  427. localStorage.setItem('editElement', res.data)
  428. this.getElementInfoByTabId()
  429. this.copss()
  430. }
  431. }
  432. },
  433. //#endregion
  434. //#region 弹框事件
  435. handleClose () {
  436. this.tableData = []
  437. this.AddNewElementField = ''
  438. },
  439. addyuansu () {//新增元素
  440. this.tableData.unshift({ eName: '', eType: '' })
  441. },
  442. deleteziduan (key) {//删除新增元素弹框字段
  443. this.tableData.splice(key, 1)
  444. },
  445. pushNewElementField () {//确定添加按钮
  446. if (this.tableData.length > 0) {
  447. let tag = true
  448. this.tableData.forEach(val => {
  449. if (!(val.eName && val.eType)) {
  450. tag = false
  451. }
  452. })
  453. if (tag) {
  454. this.submitBatch({
  455. initTableName: this.$route.query.initTableName,
  456. id: this.$route.query.id,
  457. listData: this.tableData,
  458. })
  459. } else {
  460. this.$message({
  461. type: 'error',
  462. message: '请填写所有字段'
  463. });
  464. }
  465. }
  466. },
  467. async submitBatch (da) {
  468. const { data: res } = await submitBatch(da)
  469. console.log(res);
  470. if (res.code == 200) {
  471. this.$message({
  472. type: 'success',
  473. message: '添加成功'
  474. })
  475. this.AddNewElementField = ''
  476. }
  477. },
  478. //#endregion
  479. //跳转到公式配置页面
  480. toFormulaEdit () {
  481. let eleid = null;
  482. if(this.table.ekey){
  483. for (let i = 0; i < this.options.length; i++) {
  484. if(this.options[i].ekey == this.table.ekey){
  485. eleid = this.options[i].id;
  486. break;
  487. }
  488. }
  489. }
  490. if(eleid == null){
  491. this.$message({
  492. type: "warning",
  493. message: "找不到元素id"
  494. })
  495. return;
  496. }
  497. this.$router.push({
  498. path: '/formula/edit',
  499. query: {
  500. wbsid: this.$route.query.wbsid,
  501. eleid: eleid,
  502. nodeid:this.$route.query.nodeid,
  503. projectid:this.$route.query.pid
  504. }
  505. });
  506. },
  507. },
  508. watch: {
  509. 'options' () {
  510. if (this.options) {
  511. this.options2 = [{
  512. value: '编辑元素字段',
  513. label: '编辑元素字段',
  514. children: [{
  515. value: '替换元素',
  516. label: '替换元素'
  517. }, {
  518. value: '新增元素',
  519. label: '新增元素'
  520. }, {
  521. value: '删除文本信息',
  522. label: '删除文本信息'
  523. }]
  524. }, {
  525. value: '公式配置',
  526. label: '公式配置',
  527. }]
  528. } else {
  529. this.options2 = [{
  530. value: '编辑元素字段',
  531. label: '编辑元素字段',
  532. children: [{
  533. value: '新增元素',
  534. label: '新增元素'
  535. }, {
  536. value: '删除文本信息',
  537. label: '删除文本信息'
  538. }]
  539. }, {
  540. value: '公式配置',
  541. label: '公式配置',
  542. }]
  543. }
  544. },
  545. 'value' (values) {
  546. if (values) {
  547. this.options.forEach(val => {
  548. if (val.id == values) {
  549. this.names = val.eName
  550. }
  551. })
  552. }
  553. },
  554. }
  555. }
  556. </script>
  557. <style lang="scss" scoped>
  558. .editElement {
  559. padding-bottom: 40px !important;
  560. .header {
  561. color: rgb(240, 114, 10);
  562. }
  563. .tihuan {
  564. margin-top: 15px;
  565. margin-bottom: 10px;
  566. font-family: SourceHanSansSC;
  567. font-weight: 400;
  568. font-size: 14px;
  569. color: rgb(16, 16, 16);
  570. font-style: normal;
  571. letter-spacing: 0px;
  572. line-height: 20px;
  573. text-decoration: none;
  574. }
  575. }
  576. </style>