excelmodel.vue 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  1. <template>
  2. <div style="height:100%;" class="flexStar">
  3. <div class="boxswai" style="width:26%;padding-left:0px;">
  4. <div class="boxnei" style="display: flex;flex-direction: column;">
  5. <div class="flex">
  6. <el-input size="small" placeholder="输入关键字搜索" clearable @clear="allTreeShow = false" v-model="filterText">
  7. </el-input>
  8. <el-button size="small" class="mg-l-10" @click="treeFilter">搜索</el-button>
  9. </div>
  10. <!-- 树结构 -->
  11. <div style="overflow: auto;flex:1" v-if="isShowTree">
  12. <el-tree style="display: inline-block;min-width: 100%;" ref="trees" :loading="loading" :load="treeLoad" lazy
  13. :data="data" :props="defaultProps" @node-click="nodeClick" node-key="id" :expand-on-click-node="false"
  14. v-show="!allTreeShow" :default-expanded-keys="expandedKeys" auto-expand-parent>
  15. <span class="custom-tree-node" slot-scope="{ data ,node }" @mouseover.stop="mouseOver(data)"
  16. @mouseleave.stop="mouseLeave(data)" style="box-sizing: border-box;padding-right:70px!important;;">
  17. <div style="width:100%;">
  18. <span style="text-overflow: ellipsis;"> {{ data.name }} </span>
  19. <!-- <span> {{ node}} </span> -->
  20. <!-- 添加 -->
  21. <span v-show="data.moreShow">
  22. <el-link :underline="false">
  23. <i class="el-icon-circle-plus-outline" @click.stop="addExcel(data)" v-if="data.fileType != 3"
  24. title="新增"></i>
  25. </el-link>
  26. <!-- 编辑 -->
  27. <el-link :underline="false">
  28. <i class="el-icon-edit marleft10 " @click.stop="editExcel(data)" v-if="data.fileType != 1"
  29. title="编辑"></i>
  30. </el-link>
  31. <el-link :underline="false">
  32. <i class="el-icon-sort marleft10" @click.stop="sortpai(data, node)" v-if="node.level != 1"
  33. title="调整排序"></i>
  34. </el-link>
  35. <el-link :underline="false">
  36. <i class="el-icon-upload marleft10" @click.stop="uploadMoudle(data, node)" v-if="data.fileType != 3"
  37. title="上传"></i>
  38. </el-link>
  39. <!-- 删除 -->
  40. <i class="el-icon-delete marleft10" @click.stop="deleteExcelM(data, node)" title="删除"></i>
  41. </span>
  42. </div>
  43. </span>
  44. </el-tree>
  45. <el-tree style="display: inline-block;min-width: 100%;" ref="treeall" v-loading="treeloading"
  46. :data="allTreeData" :props="defaultProps" @node-click="nodeClick" node-key="id" :expand-on-click-node="false"
  47. :filter-node-method="filterNode" v-show="allTreeShow">
  48. <span class="custom-tree-node" slot-scope="{ data ,node }" @mouseover.stop="mouseOver(data)"
  49. @mouseleave.stop="mouseLeave(data)" style="box-sizing: border-box;padding-right:70px!important;;">
  50. <div style="width:100%;">
  51. <span style="text-overflow: ellipsis;"> {{ data.name }} </span>
  52. <!-- <span> {{ node}} </span> -->
  53. <!-- 添加 -->
  54. <span v-show="data.moreShow">
  55. <i class="el-icon-circle-plus-outline marleft10" @click.stop="addExcel(data)"
  56. v-if="data.fileType != 3"></i>
  57. <!-- 编辑 -->
  58. <i class="el-icon-edit marleft10" @click.stop="editExcel(data)" v-if="data.fileType != 1"></i>
  59. <el-link :underline="false">
  60. <i class="el-icon-sort" @click.stop="sortpai(data, node)" v-if="node.level == 3" title="调整排序"></i>
  61. </el-link>
  62. <el-link :underline="false">
  63. <i class="el-icon-upload marleft10" @click.stop="uploadMoudle(data, node)" v-if="node.level != 1"
  64. title="上传"></i>
  65. </el-link>
  66. <!-- 删除 -->
  67. <i class="el-icon-delete marleft10" @click.stop="deleteExcelM(data, node)" title="删除"></i>
  68. </span>
  69. </div>
  70. </span>
  71. </el-tree>
  72. </div>
  73. </div>
  74. </div>
  75. <div class="boxswai" style="width:74%;padding-left:0px;padding-right:0px;">
  76. <div class="boxnei">
  77. <div class="marleft10" style="height:100%;
  78. display: flex;flex-direction: column;">
  79. <!-- 上传、删除、下载操作栏 -->
  80. <div class="rightHeader" v-show="from.checkd">
  81. <template v-if="from.fileUrl">
  82. <div class="excelname">
  83. <div>{{ from.extension }}</div>
  84. <i class="el-icon-success marleft10" style="color: rgb(0, 168, 112);"></i>
  85. </div>
  86. <el-upload class="marleft10" :auto-upload="false" :show-file-list="false" action="#" :limit="1"
  87. :file-list='fileList' accept=".xls,.xlsx" :on-change="uploadChange" ref="file1">
  88. <el-button type="primary" size="mini">重新上传</el-button>
  89. </el-upload>
  90. <el-link class="marleft10 colorblue" @click="delectExcelMS">删除</el-link>
  91. <el-link underline class="marleft10 colorblue" style="text-decoration:underline;"
  92. @click="downloadExcel()">下载EXCEL</el-link>
  93. </template>
  94. <template v-else>
  95. <el-upload :auto-upload="false" :show-file-list="false" action="#" :limit="1" :file-list='fileList'
  96. accept=".xls,.xlsx" :on-change="uploadChange" ref="file2">
  97. <el-button type="primary" size="mini">上传 excel</el-button>
  98. </el-upload>
  99. </template>
  100. <div style="margin-left:50px;position: relative;" class="flex">
  101. <div class="excelname mg-r-10" v-if="from.templateExtension">
  102. <div>{{ from.templateExtension }}</div>
  103. <i class="el-icon-success marleft10" style="color: rgb(0, 168, 112);"></i>
  104. </div>
  105. <!-- <el-upload :auto-upload="false" :show-file-list="false" action="#" :limit="1" accept=".xls,.xlsx"
  106. :on-change="uploadcoverfileExcel" ref="file3">
  107. <el-button type="primary" size="mini">{{ from.templateExtension ? '重新上传导入模板' : '上传导入模板' }}</el-button>
  108. </el-upload> -->
  109. <div>
  110. <el-link v-if="from.templateExtension" class="marleft10 colorblue" @click="delectExcelMSModel">删除</el-link>
  111. <el-link v-if="from.templateExtension" underline class="marleft10 colorblue"
  112. style="text-decoration:underline;" @click="downloadExcelModel()">下载模板</el-link>
  113. <el-button type="success" size="mini" @click="saveExcelInfo" :loading="saveExcelJsonLoad" style="margin-left: 5px;">保存数据</el-button>
  114. </div>
  115. </div>
  116. <div style="position: absolute;right:30px;top:65px;">
  117. <el-button type="primary" size="mini" @click="fullPage">全屏显示</el-button>
  118. </div>
  119. </div>
  120. <el-empty style="height:80%;" v-show="!from.checkd" description="该目录为根目录没有EXCEL文件"></el-empty>
  121. <div class="martop10" v-if="from.fileUrl" style="flex:1;">
  122. <!-- <iframe
  123. :src="excelSrc"
  124. style="width:100%;height:100%;"
  125. ></iframe> -->
  126. <div v-if='excelshow' style="width:100%;height:100%;" id="fullscreen_content">
  127. <!-- <vab-only-office :option='exceloption' /> -->
  128. <lucky-sheet
  129. ref="luckySheet"
  130. @data-change="handleDataChange"
  131. :initialData="initialData"
  132. :url="from.fileUrl"
  133. ></lucky-sheet>
  134. </div>
  135. </div>
  136. </div>
  137. </div>
  138. </div>
  139. <!-- 弹出框 -->
  140. <el-dialog :title="dialogTapType" class="dialogModel" :visible.sync="dialogTap" width="800px" modal-append-to-body
  141. append-to-body @close="handleClose">
  142. <div class="dialogBox">
  143. <el-form ref="excelForm" :model="excelForm" label-width="80px" :rules="rules">
  144. <div style="display: flex;justify-content: space-between;">
  145. <el-form-item label="清表名称" style="width: 370px;" size="small" prop="nodeName">
  146. <el-input v-model="excelForm.nodeName"></el-input>
  147. </el-form-item>
  148. <el-form-item label="清表类型" style="width: 370px;" size="small" prop="tabType">
  149. <el-select v-model="excelForm.tabType" style="width:100%;" placeholder="请选择清表类型">
  150. <el-option v-for="(val, index) in exceltypeData" :key="index" :label="val.dictValue"
  151. :value="val.dictKey"></el-option>
  152. </el-select>
  153. </el-form-item>
  154. </div>
  155. </el-form>
  156. <div class="middle" v-if="wbsmiddle">
  157. <div class="left">
  158. <div class="select">
  159. <el-select placeholder="请选择WBS模板" style="width: 96%;" size="small" @change="wbsmodelchange"
  160. v-model="excelForm.wbsId">
  161. <el-option v-for="(val, index) in wbsmodel" :key="index" :label="val.wbsName" :value="val.id"></el-option>
  162. </el-select>
  163. </div>
  164. <div class="treecontent" v-loading="loading">
  165. <avue-tree :option="option2" :data="wbsdata" @node-click="nodeClickExcel" style="height:450px">
  166. <span class="el-tree-node__label" slot-scope="{ data }">
  167. <div>
  168. <span> {{ data.nodeName }} </span>
  169. </div>
  170. </span>
  171. </avue-tree>
  172. </div>
  173. </div>
  174. <!-- 右侧关联 -->
  175. <template>
  176. <el-table :data="tableData" border height="502px" style="width: 100%;margin-left:20px">
  177. <el-table-column prop="tableName" label="表名">
  178. </el-table-column>
  179. <el-table-column label="操作" align="center" width="120">
  180. <template slot-scope="scope">
  181. <el-button v-if="scope.row.isLinkTable != 2" type="info" size="small"
  182. @click="relation(scope.$index)">关联</el-button>
  183. <el-button v-if="scope.row.isLinkTable == 2" type="warning" size="small"
  184. @click="Disassociate(scope.$index)">取消关联</el-button>
  185. </template>
  186. </el-table-column>
  187. </el-table>
  188. </template>
  189. </div>
  190. </div>
  191. <div class="btbox">
  192. <el-button size="mini" @click="handleClose()">取消</el-button>
  193. <el-button type="info" style="margin-left: 50px;" size="mini" :loading="saveExcelLoad"
  194. @click="saveExcel()">确定</el-button>
  195. </div>
  196. </el-dialog>
  197. <!-- 私有wbs树排序弹框 -->
  198. <el-dialog title="调整排序" :visible.sync="sortTag" width="50%" append-to-body>
  199. <ManualSorting v-if="sortTag2" @bianhua="bianhua()" :sort="sort" />
  200. <span slot="footer" class="dialog-footer">
  201. <el-button @click="(sortTag = false), (sortTag2 = false)">取 消</el-button>
  202. <el-button type="primary" @click="editSort()">确 定</el-button>
  203. </span>
  204. </el-dialog>
  205. <!-- 上传Excel表格 -->
  206. <el-dialog title="上传Excel表格" :visible.sync="exceldialogVisible" width="40%" append-to-body
  207. :before-close="cancleexceldialog">
  208. <span>
  209. <el-upload accept=".xls, .xlsx" class="upload-demo" action="#" :auto-upload="false" :on-change="excelhandleChange"
  210. :show-file-list="false" multiple :on-exceed="excelhandleExceed" :file-list="excelfileList"
  211. ref="excelmoudelupload">
  212. <el-button size="small" type="primary">选择文件</el-button>
  213. <!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> -->
  214. </el-upload>
  215. <el-table class="down" :data="dataList" border stripe style="width: 100%;margin-top: 20px;">
  216. <el-table-column label="序号" width="150">
  217. <template slot-scope="scope">
  218. <i class="el-icon-sort-up marleft10 text-hover" @click="upSortFile(scope.row,scope.$index)"></i>
  219. <i class="el-icon-sort-down marleft10 text-hover" @click="downSortFile(scope.row,scope.$index)"></i>
  220. {{ scope.$index + 1 }}
  221. </template>
  222. </el-table-column>
  223. <el-table-column prop="name" label="文件名称">
  224. <template slot-scope="scope">
  225. <el-input v-model="scope.row.name" placeholder="请输入内容"></el-input>
  226. </template>
  227. </el-table-column>
  228. <el-table-column width="80" label="操作">
  229. <template slot-scope="scope">
  230. <el-button size="small" type="text" @click="deleteHandle(scope.row.uid)">删除</el-button>
  231. </template>
  232. </el-table-column>
  233. </el-table>
  234. </span>
  235. <span slot="footer" class="dialog-footer">
  236. <el-button @click="cancleexceldialog">取 消</el-button>
  237. <el-button type="primary" @click="aumbitexcelmoudel">确 定上传</el-button>
  238. </span>
  239. </el-dialog>
  240. </div>
  241. </template>
  242. <script>
  243. import { mapGetters } from "vuex";
  244. import {
  245. detailExcel, excelType, tabLazytree, getWbsTypeList, wbstree, selectByNodeTable, Excelmodify, uploadExcel, deleteExcelshu, deleteExcel, deleteExcelmodel, tabLazytreeAll,
  246. uploadcoverfileExcel, downExcelFile, downExcelFileModel, exctabSort,batchUploadExcelTab
  247. } from '@/api/exctab/excelmodel';
  248. import ManualSorting from '@/components/WbsTree/ManualSorting'
  249. import VabOnlyOffice from '@/components/online-office/index'
  250. import { log } from '@antv/g2plot/lib/utils';
  251. import screenfull from "screenfull";
  252. import LuckySheet from '@/components/lucky-sheet-editor/LuckySheet.vue'
  253. import {getExcelJson,saveExcelJson} from '@/api/exctab/exceltab';
  254. export default {
  255. components: {
  256. ManualSorting, VabOnlyOffice,LuckySheet
  257. },
  258. data() {
  259. return {
  260. //参考vabOnlyOffice组件参数配置
  261. excelshow: false,
  262. expandedKeys: [],//默认展开的节点
  263. excelId: '',
  264. treeNode: {},
  265. //#region 鼠标
  266. leftTRee: '',//左侧树ID
  267. threessW: 400,
  268. //#endregion
  269. heightss: '',//
  270. loading: false,//懒加载
  271. data: [],//清表模板
  272. filterText: "",//搜索关键字
  273. allTreeShow: false,//是否显示整棵树
  274. treeloading: false,
  275. allTreeData: [],
  276. defaultProps: {
  277. children: "children",
  278. isLeaf: function (data) {
  279. return !data.hasChildren || (data.isExistForm == 1);
  280. },
  281. },
  282. wbsdata: [],//wbs模板
  283. //#region 右侧数据
  284. from: {
  285. checkd: false,//判断是否可以进行上传、重新上传excel
  286. id: '',//清表树ID
  287. extension: '', //文件名称
  288. fileUrl: '',//文件路径
  289. import: null,
  290. },
  291. fileList: [],//选中的文件
  292. excelSrc: '',//
  293. //#endregion
  294. //#region 弹框
  295. dialogTapType: '',
  296. dialogTap: false,
  297. option2: {
  298. filter: false,
  299. lazy: true,
  300. menu: false,
  301. treeLoad: (async (node, resolve) => {
  302. if (node.data.hasChildren) {
  303. const { data: res } = await wbstree({ parentId: node.data.id, wbsId: this.excelForm.wbsId, wbsType: this.excelForm.wbsType })
  304. console.log(res);
  305. if (res.code === 200) {
  306. if (Array.isArray(res.data)) {
  307. res.data.forEach((val) => {
  308. if (!val.hasChildren) {
  309. val.leaf = true
  310. }
  311. })
  312. }
  313. return resolve(res.data)
  314. }
  315. } else {
  316. return resolve([])
  317. }
  318. }),
  319. },//弹框里面的wbs树
  320. excelForm: {
  321. nodeName: '',//清表名称
  322. tabType: '',//清表类型
  323. id: '',//清表Id,编辑时用
  324. parentId: '',//清表Id,添加时用
  325. wbsId: '',//WBS模板Id
  326. wbsType: '',//WBS模板类型
  327. },
  328. rules: {
  329. nodeName: [
  330. { required: true, message: '请输入清表名称', trigger: 'blur' },
  331. ],
  332. tabType: [
  333. { required: true, message: '请选择清表类型', trigger: 'blur' },
  334. ],
  335. },
  336. wbsform: {
  337. id: '',
  338. wbsType: '',
  339. wbsName: '',
  340. },//wbs树选中的值
  341. tableData: [],//右侧表数据
  342. wbsmiddle: false,//选择wbs模板那块是否有
  343. tableList: [],//进行处理的wbs关联表
  344. exceltypeData: [],//清表类型枚举
  345. wbsmodel: [],//wbs模板名称枚举
  346. //#endregion
  347. saveExcelLoad: false,
  348. sortTag: false,
  349. sortTag2: false,
  350. sort: [],
  351. curTreeData: {},
  352. defaultExpandKey: [],
  353. exceldialogVisible: false,
  354. isShowTree:true,
  355. uploadId:'',
  356. excelfileList: [],
  357. dataList: [],
  358. fileobj: [],
  359. initialData: [],
  360. saveExcelJsonLoad: false,
  361. }
  362. },
  363. computed: {
  364. ...mapGetters(["userInfo"]),
  365. },
  366. methods: {
  367. fullPage(){
  368. console.log('全屏显示');
  369. // 判断是否支持
  370. if (!screenfull.isEnabled) {
  371. this.$message({
  372. message: "浏览器不支持全屏",
  373. type: "warning"
  374. });
  375. return false;
  376. }
  377. const element = document.getElementById('fullscreen_content');//指定全屏区域元素
  378. screenfull.request(element);
  379. // screenfull.toggle();
  380. s
  381. },
  382. getFile() {
  383. this.excelshow = true
  384. this.getInitialData()
  385. },
  386. //刷新左边树形数据
  387. refreshTree() {
  388. console.log(this.curTreeData, 'this.curTreeData111111111');
  389. //刷新左边树形数据
  390. if (this.curTreeData.level === 1) {
  391. const parentId = 0
  392. tabLazytree({
  393. parentId: this.curTreeData.parentId,
  394. modeId: this.$route.params.id
  395. }).then(res => {
  396. this.data = res.data.data.data;
  397. this.$nextTick(() => {
  398. this.defaultExpandKey.push(this.curTreeData.id);
  399. this.$refs.trees.setCurrentKey(this.curTreeData.id);
  400. })
  401. });
  402. } else {
  403. this.updateTreeNewNode()
  404. }
  405. },
  406. updateTreeNewNode() {
  407. tabLazytree({
  408. parentId: this.curTreeData.parentId,
  409. modeId: this.$route.params.id
  410. }).then((res) => {
  411. let node = this.$refs.trees.getNode(this.curTreeData.parentId.parentId);
  412. this.$refs.trees.updateKeyChildren(this.curTreeData.parentId, res.data.data)
  413. this.$refs.trees.setCurrentKey(this.curTreeData.id);
  414. })
  415. },
  416. //#region 调整排序排序
  417. async sortpai(data, node) {
  418. console.log(data, node);
  419. await this.findWbsTreePrivateSameLevel(node, data)
  420. this.sortTag = true;
  421. this.sortTag2 = true;
  422. this.curTreeData = data
  423. },
  424. editSort() {
  425. this.exctabSort();
  426. },
  427. bianhua() {
  428. this.sortTag2 = false;
  429. this.$nextTick(() => {
  430. this.sortTag2 = true;
  431. });
  432. },
  433. async exctabSort() {
  434. console.log(this.sort, 'this.sort');
  435. var newArr = this.sort.map((v) => { return v.id })
  436. newArr = newArr.join(',')
  437. //清表树手动排序
  438. const { data: res } = await exctabSort(newArr);
  439. console.log(res);
  440. if (res.code == 200) {
  441. this.sortTag = false;
  442. this.sortTag2 = false;
  443. this.updateTreeNewNode();
  444. }
  445. },
  446. async findWbsTreePrivateSameLevel(node, data) {
  447. const { data: res } = await tabLazytree(
  448. {
  449. parentId: data.parentId,
  450. modeId: this.$route.params.id
  451. })
  452. if (res.code == 200) {
  453. res.data.forEach((item) => {
  454. item.tableName = item.name
  455. })
  456. this.sort = res.data
  457. }
  458. },
  459. async getLazytreessss() {
  460. const { data: res } = await tabLazytree(
  461. {
  462. parentId: 0,
  463. modeId: this.$route.params.id
  464. }
  465. );
  466. console.log(res);
  467. if (res.code == 200) {
  468. this.data = res.data;
  469. this.allTreeData = res.data
  470. }
  471. },
  472. //#region 接口
  473. async tabLazytree(parentId, modeId) {//清表树
  474. const { data: res } = await tabLazytree({ parentId, modeId })
  475. console.log(res);
  476. if (res.code === 200) {
  477. return res.data
  478. }
  479. },
  480. async detailExcel(id) {//获取列表信息
  481. const { data: res } = await detailExcel({ id })
  482. console.log(res);
  483. if (res.code === 200) {
  484. this.from.id = res.data.id
  485. this.from.extension = res.data.extension //文件名称
  486. this.from.templateExtension = res.data.templateExtension
  487. this.from.name = res.data.name
  488. this.from.fileUrl = res.data.fileUrl //文件路径
  489. let routeUrl = res.data.fileUrl
  490. let pSrc = routeUrl + '?r=' + new Date()
  491. this.excelSrc = 'http://view.officeapps.live.com/op/view.aspx?src=' + encodeURIComponent(pSrc);
  492. // //导入模板名称
  493. // this.from.import={}
  494. this.getFile()
  495. }
  496. },
  497. async getWbsTypeList() {//清表编辑 wbs 下拉框选择
  498. const { data: res } = await getWbsTypeList({ wbstype: 2 })
  499. console.log(res);
  500. if (res.code === 200) {
  501. this.wbsmodel = res.data
  502. }
  503. },
  504. async excelType() {//清表类型
  505. const { data: res } = await excelType({ code: 'sys_excltab_type' })
  506. console.log(res);
  507. if (res.code === 200) {
  508. res.data.forEach(element => {
  509. element.dictKey = Number(element.dictKey)
  510. });
  511. this.exceltypeData = res.data
  512. }
  513. },
  514. async wbstree() {//wbs树懒加载
  515. this.loading = true;
  516. const { data: res } = await wbstree({ parentId: 0, wbsId: this.excelForm.wbsId, wbsType: this.excelForm.wbsType })
  517. console.log(res);
  518. this.loading = false
  519. if (res.code === 200) {
  520. res.data.forEach((val) => {
  521. if (!val.hasChildren) {
  522. val.leaf = true
  523. }
  524. })
  525. this.wbsdata = res.data
  526. }
  527. },
  528. async selectByNodeTable(id, wbsType, liunxId, projectid) {//wbs树获取表
  529. const { data: res } = await selectByNodeTable({ id, wbsType, liunxId, projectid })
  530. console.log(res);
  531. if (res.code === 200) {
  532. console.log(Array.isArray(res.data));
  533. if (Array.isArray(res.data)) {
  534. this.tableData = res.data
  535. this.tableData.forEach(val => {
  536. val.changeTable = val.isLinkTable
  537. })
  538. } else {
  539. this.tableData = []
  540. }
  541. }
  542. },
  543. async deleteExcelshu(ids) {//删除清表
  544. // console.log(ids);
  545. const { data: res } = await deleteExcelshu(ids)
  546. console.log(res);
  547. if (res.code === 200) {
  548. this.$message({
  549. message: '删除清表树成功',
  550. type: 'success'
  551. });
  552. this.tabLazytree(0, this.$route.params.id)//获取清表树
  553. this.from = {
  554. checkd: false,//判断是否可以进行上传、重新上传excel
  555. id: '',//清表树ID
  556. extension: '', //文件名称
  557. fileUrl: '',//文件路径
  558. }
  559. }
  560. },
  561. async Excelmodify(wbsExclTabParmVO) {//编辑添加清表
  562. console.log(wbsExclTabParmVO, this.treeNode);
  563. const { data: res } = await Excelmodify(wbsExclTabParmVO)
  564. console.log(res);
  565. if (res.code === 200) {
  566. this.$message({
  567. type: 'success',
  568. message: '保存成功'
  569. })
  570. let ids = ''
  571. if (wbsExclTabParmVO.id) {
  572. ids = this.treeNode.parentId
  573. } else {
  574. ids = wbsExclTabParmVO.parentId
  575. }
  576. let das = await this.tabLazytree(ids, this.$route.params.id)//获取清表树
  577. if (wbsExclTabParmVO.id) {
  578. this.treeNode.name = wbsExclTabParmVO.nodeName
  579. } else {
  580. this.$refs.trees.updateKeyChildren(this.treeNode.id, das)
  581. }
  582. let node = this.$refs.trees.getNode(ids);
  583. node.isLeaf = false;
  584. node.isLeafByUser = false;
  585. this.dialogTap = false
  586. }
  587. },
  588. async uploadExcel(data) {//上传清表
  589. console.log('上传');
  590. const { data: res } = await uploadExcel(data)
  591. console.log(res);
  592. if (res.code === 200) {
  593. this.$message({
  594. message: '上传文件成功',
  595. type: 'success'
  596. })
  597. this.detailExcel(this.from.id)
  598. this.from.checkd = true
  599. }
  600. this.fileList = [];
  601. this.refreshTree()
  602. },
  603. async deleteExcel(data) {//删除excel表
  604. const { data: res } = await deleteExcel(data)
  605. if (res.code === 200) {
  606. this.$message({
  607. message: '删除excel表成功',
  608. type: 'success'
  609. })
  610. this.detailExcel(this.from.id)
  611. this.refreshTree()
  612. }
  613. },
  614. //#endregion
  615. //#region 右侧
  616. async uploadChange(file, fileList) {//选中表后触发
  617. this.fileList = [file.raw]
  618. let formData = new FormData()
  619. formData.append('file', ...this.fileList)
  620. formData.append('nodeId', this.from.id)
  621. if (this.from.fileUrl && this.from.fileUrl.length >= 2) {
  622. formData.append('type', 2)
  623. } else {
  624. formData.append('type', 1)
  625. }
  626. const loading = this.$loading({
  627. lock: true,
  628. text: 'Loading',
  629. spinner: 'el-icon-loading',
  630. background: 'rgba(0, 0, 0, 0.7)'
  631. });
  632. try {
  633. await this.uploadExcel(formData)
  634. loading.close();
  635. } catch (error) {
  636. loading.close();
  637. }
  638. if (this.$refs.file1) {
  639. this.$refs.file1.clearFiles();
  640. }
  641. if (this.$refs.file2) {
  642. this.$refs.file2.clearFiles();
  643. }
  644. },
  645. delectExcelMS() {//删除excel表点击事件、
  646. let _that = this
  647. this.$confirm('确认删除该文件?', '', {
  648. confirmButtonText: '确定',
  649. cancelButtonText: '取消',
  650. type: 'warning'
  651. }).then(() => {
  652. _that.deleteExcel({ id: _that.from.id, fileUrl: '' })
  653. }).catch(() => {
  654. })
  655. },
  656. downloadExcel() {//下载excel表
  657. //this.downFile(this.from.fileUrl,"123456.xlsx");
  658. //window.open(this.from.fileUrl,'namexxx')
  659. const link = document.createElement('a')
  660. downExcelFile(this.from.id).then((res) => {
  661. // 创建Blob对象,设置文件类型
  662. let blob = new Blob([res.data], { type: "application/vnd.ms-excel" })
  663. let objectUrl = URL.createObjectURL(blob) // 创建URL
  664. link.href = objectUrl
  665. link.download = this.from.extension // 自定义文件名
  666. link.click() // 下载文件
  667. URL.revokeObjectURL(objectUrl); // 释放内存
  668. })
  669. },
  670. delectExcelMSModel() {//删除excel表点击事件、
  671. let _that = this
  672. this.$confirm('确认删除该文件?', '', {
  673. confirmButtonText: '确定',
  674. cancelButtonText: '取消',
  675. type: 'warning'
  676. }).then(() => {
  677. deleteExcelmodel({ id: _that.from.id, fileUrl: '' }).then((res) => {
  678. if (res.data.code == 200) {
  679. _that.from.templateExtension = ''
  680. this.$forceUpdate()
  681. }
  682. })
  683. }).catch(() => {
  684. })
  685. },
  686. downloadExcelModel() {//下载excel表
  687. //this.downFile(this.from.fileUrl,"123456.xlsx");
  688. //window.open(this.from.fileUrl,'namexxx')
  689. const link = document.createElement('a')
  690. downExcelFileModel(this.from.id).then((res) => {
  691. // 创建Blob对象,设置文件类型
  692. let blob = new Blob([res.data], { type: "application/vnd.ms-excel" })
  693. let objectUrl = URL.createObjectURL(blob) // 创建URL
  694. link.href = objectUrl
  695. link.download = this.from.extension // 自定义文件名
  696. link.click() // 下载文件
  697. URL.revokeObjectURL(objectUrl); // 释放内存
  698. })
  699. },
  700. //#endregion
  701. //#region 外层左侧事件
  702. mouseLeave(data) {
  703. if (data.moreShow) {
  704. this.$set(data, 'moreShow', false)
  705. }
  706. },
  707. mouseOver(data) {
  708. if (!data.moreShow) {
  709. this.$set(data, 'moreShow', true)
  710. }
  711. },
  712. async treeLoad(node, resolve) {
  713. let id = node.data.id
  714. if (node.level == 0) {
  715. id = 0
  716. }
  717. let das = await this.tabLazytree(id, this.$route.params.id)
  718. return resolve(das)
  719. },
  720. nodeClick(data) {//外层树结构
  721. this.curTreeData = data;
  722. this.from.import = ""
  723. if (data.hasChildren == false) {
  724. this.from.checkd = true
  725. } else if (data.fileType == 3) {
  726. this.from.checkd = true
  727. } else {
  728. this.from.checkd = false
  729. }
  730. if (this.from.checkd) {
  731. this.detailExcel(data.id)
  732. } else {
  733. this.from = {
  734. checkd: false,//判断是否可以进行上传、重新上传excel
  735. id: '',//清表树ID
  736. extension: '', //文件名称
  737. fileUrl: '',//文件路径
  738. }
  739. }
  740. },
  741. async editExcel(data) {//编辑
  742. this.dialogTapType = '编辑'
  743. if (data.fileType != 3 && data.hasChildren) {
  744. this.wbsmiddle = false
  745. } else {
  746. this.wbsmiddle = true
  747. this.getWbsTypeList()//wbs模板名称
  748. }
  749. const { data: res } = await detailExcel({ id: data.id })
  750. console.log(res);
  751. if (res.code === 200) {
  752. this.excelForm.id = res.data.id
  753. this.excelForm.nodeName = res.data.name //清表名称
  754. this.excelForm.tabType = res.data.tabType //清表类型
  755. this.treeNode = data
  756. this.dialogTap = true
  757. }
  758. },
  759. async addExcel(data) {//添加
  760. this.dialogTapType = '新增'
  761. console.log(data);
  762. if (data.fileType == 3) {
  763. this.wbsmiddle = false
  764. } else {
  765. this.wbsmiddle = true
  766. this.getWbsTypeList()//wbs模板名称
  767. }
  768. this.excelForm.parentId = data.id
  769. this.treeNode = data
  770. this.dialogTap = true
  771. },
  772. deleteExcelM(data, node) {//删除
  773. console.log(node);
  774. if (data.hasChildren) {
  775. this.$message({
  776. type: 'warning',
  777. message: '该节点下有子节点,无法删除'
  778. })
  779. return;
  780. }
  781. const _that = this
  782. this.$confirm('确定将选择数据删除?', '', {
  783. confirmButtonText: '确定',
  784. cancelButtonText: '取消',
  785. type: 'error'
  786. }).then(async () => {
  787. await _that.deleteExcelshu(data.id)
  788. _that.$refs.trees.remove(node) //删除界面上的节点
  789. }).catch(() => {
  790. });
  791. },
  792. //#endregion
  793. //#region 弹框属性
  794. handleClose() {//关闭弹框触发事件
  795. this.excelForm = {
  796. nodeName: '',//清表名称
  797. tabType: '',//清表类型
  798. id: '',//清表Id,编辑时用
  799. parentId: '',//清表Id,添加时用
  800. wbsId: '',//WBS模板Id
  801. wbsType: '',//WBS模板类型
  802. }
  803. this.wbsform = {
  804. id: '',
  805. wbsType: '',
  806. wbsName: '',
  807. }//wbs树选中的值
  808. this.wbsdata = [] //wbs树数据
  809. this.tableData = []//弹框table数据
  810. this.tableList = []//关联取消关联的数据
  811. this.dialogTap = false
  812. },
  813. wbsmodelchange(val) {//wbs模板change事件
  814. if (val) {
  815. this.wbsmodel.forEach((da) => {
  816. if (da.id == val) {
  817. this.excelForm.wbsType = da.wbsType
  818. }
  819. })
  820. }
  821. window.setTimeout(() => {
  822. this.wbstree();
  823. }, 100)
  824. this.tableData = [];
  825. this.tableList = [];
  826. },
  827. nodeClickExcel(data) {//wbs树点击事件
  828. console.log(this.excelId, "xxxxxxxxx");
  829. console.log(this.excelForm.id, "yyyyyyyy");
  830. this.wbsform.id = data.id
  831. this.wbsform.wbsType = data.type
  832. this.wbsform.wbsName = data.nodeName
  833. if (this.tableList == '') {
  834. this.selectByNodeTable(data.id, data.type, this.excelForm.id, this.excelForm.wbsId)
  835. } else {
  836. let tag = true
  837. this.tableList.forEach((val) => {
  838. if (val.id == data.id) {
  839. this.tableData = val.arrs
  840. tag = false
  841. }
  842. })
  843. if (tag) {
  844. this.selectByNodeTable(data.id, data.type, this.excelForm.id, this.excelForm.wbsId)
  845. }
  846. }
  847. },
  848. relation(key) {//关联
  849. this.tableData[key].isLinkTable = 2
  850. let tap = this.tableList.find((val) => {
  851. return val.id == this.wbsform.id
  852. })
  853. if (!tap) {
  854. this.tableList.push({
  855. id: this.wbsform.id,
  856. wbsType: this.wbsform.wbsType,
  857. wbsName: this.wbsform.wbsName,
  858. arrs: this.tableData
  859. })
  860. }
  861. },
  862. Disassociate(key) {//取消关联
  863. this.tableData[key].isLinkTable = 1
  864. const tap = this.tableList.find((val) => {
  865. return val.id == this.wbsform.id
  866. })
  867. if (!tap) {
  868. this.tableList.push({
  869. id: this.wbsform.id,
  870. wbsType: this.wbsform.wbsType,
  871. wbsName: this.wbsform.wbsName,
  872. arrs: this.tableData
  873. })
  874. }
  875. },
  876. saveExcel() {//保存按钮
  877. this.$refs.excelForm.validate(async (valid) => {
  878. if (valid) {
  879. let linkDataInfo = []
  880. if (this.tableList.length > 0) {
  881. this.tableList.forEach(val => {
  882. let linkIds = ''
  883. val.arrs.forEach(da => {
  884. if (da.isLinkTable != da.changeTable) {
  885. linkIds = `${linkIds}${linkIds != '' ? ',' : ''}${da.pkeyId}_${da.isLinkTable}`
  886. }
  887. })
  888. if (linkIds != '') {
  889. linkDataInfo.push({
  890. id: val.id,
  891. linkIds: linkIds,
  892. wbsName: val.wbsName,
  893. wbsType: val.wbsType
  894. })
  895. }
  896. })
  897. }
  898. this.saveExcelLoad = true;
  899. try {
  900. if (this.excelForm.parentId && !this.excelForm.id) {
  901. await this.Excelmodify({
  902. nodeName: this.excelForm.nodeName,
  903. tabType: this.excelForm.tabType,
  904. parentId: this.excelForm.parentId,
  905. linkDataInfo: linkDataInfo
  906. })
  907. } else {
  908. await this.Excelmodify({
  909. nodeName: this.excelForm.nodeName,
  910. tabType: this.excelForm.tabType,
  911. id: this.excelForm.id,
  912. linkDataInfo: linkDataInfo
  913. })
  914. }
  915. this.dialogTap = false
  916. } catch (error) {
  917. console.log(error)
  918. }
  919. this.saveExcelLoad = false;
  920. }
  921. });
  922. },
  923. //#endregion
  924. //搜索树
  925. treeFilter() {
  926. if (this.filterText) {
  927. this.allTreeShow = true;
  928. if (!this.allTreeData.length) {
  929. this.treeloading = true;
  930. tabLazytreeAll({
  931. modeId: this.$route.params.id,
  932. name: '',
  933. }).then((res) => {
  934. this.treeloading = false;
  935. this.allTreeData = res.data.data;
  936. this.$nextTick(() => {
  937. this.$refs.treeall.filter(this.filterText);
  938. })
  939. })
  940. } else {
  941. this.$refs.treeall.filter(this.filterText);
  942. }
  943. } else {
  944. this.allTreeShow = false;
  945. }
  946. },
  947. filterNode(value, data) {
  948. if (!value) return true;
  949. return data.name.indexOf(value) !== -1;
  950. },
  951. uploadcoverfileExcel(file) {
  952. console.log('上传导入模板');
  953. this.from.templateExtension = false
  954. let formData = new FormData()
  955. formData.append('file', file.raw)
  956. formData.append('nodeId', this.from.id)
  957. this.from.templateExtension = file.raw.name
  958. // console.log(file.raw)
  959. const loading = this.$loading({
  960. lock: true,
  961. text: 'Loading',
  962. spinner: 'el-icon-loading',
  963. background: 'rgba(0, 0, 0, 0.7)'
  964. });
  965. uploadcoverfileExcel(formData).then(() => {
  966. this.$message({
  967. message: '上传文件成功',
  968. type: 'success'
  969. })
  970. // this.detailExcel(this.from.id)
  971. loading.close();
  972. }).catch(() => {
  973. loading.close();
  974. });
  975. this.$refs.file3.clearFiles();
  976. this.$forceUpdate()
  977. },
  978. //上传
  979. uploadMoudle(data) {
  980. console.log('上传');
  981. this.uploadId=data.id
  982. this.curTreeData = data;
  983. this.exceldialogVisible = true
  984. },
  985. excelhandleChange(file, fileList) {
  986. this.dataList = fileList
  987. },
  988. deleteHandle(uid) {
  989. let arr = this.dataList.filter((item) => {
  990. return item.uid !== uid
  991. })
  992. this.$nextTick(() => {
  993. this.dataList = arr
  994. })
  995. },
  996. aumbitexcelmoudel() {
  997. let formData = new FormData()
  998. this.dataList.forEach((item) => {
  999. formData.append('file', item.raw,item.name)
  1000. })
  1001. formData.append('id',this.uploadId)
  1002. const loading = this.$loading({
  1003. lock: true,
  1004. text: 'Loading',
  1005. spinner: 'el-icon-loading',
  1006. background: 'rgba(0, 0, 0, 0.7)'
  1007. });
  1008. batchUploadExcelTab(formData).then(() => {
  1009. this.$message({
  1010. message: '上传文件成功',
  1011. type: 'success'
  1012. })
  1013. this.exceldialogVisible=false
  1014. this.refreshTree()
  1015. loading.close();
  1016. }).catch(() => {
  1017. loading.close();
  1018. });
  1019. this.$refs.excelmoudelupload.clearFiles();
  1020. this.cancleexceldialog()
  1021. },
  1022. //更改上传文件顺序
  1023. upSortFile(row,index){
  1024. const data= this.dataList
  1025. if(index!==0){
  1026. const tmp = data.splice(index - 1, 1);
  1027. this.dataList.splice(index, 0, tmp[0]);
  1028. }else{
  1029. this.$message.warning('已经处于置顶,无法上移')
  1030. }
  1031. },
  1032. downSortFile(row,index){
  1033. const indexs = index + 1
  1034. const data = this.dataList
  1035. if (indexs !== data.length) {
  1036. const tmp = data.splice(indexs, 1);
  1037. this.dataList.splice(index, 0, tmp[0]);
  1038. } else {
  1039. this.$message.warning('已经处于置底,无法下移')
  1040. }
  1041. },
  1042. cancleexceldialog(){
  1043. this.exceldialogVisible=false
  1044. this.dataList=[]
  1045. this.excelfileList=[]
  1046. },
  1047. handleDataChange(data) {
  1048. // 处理数据变化
  1049. console.log('表格数据已更新:', data)
  1050. // 可以在这里将数据发送到后端保存
  1051. },
  1052. async getInitialData(){
  1053. const { data: res } = await getExcelJson(
  1054. {
  1055. url: this.from.fileUrl,
  1056. })
  1057. if (res.code == 200) {
  1058. this.initialData = JSON.parse(res.data)
  1059. }else{
  1060. this.$message.error(res.msg)
  1061. this.initialData=[]
  1062. }
  1063. },
  1064. //保存表格数据
  1065. async saveExcelInfo() {
  1066. this.saveExcelJsonLoad = true; // 开始加载
  1067. try {
  1068. const saveData = await this.$refs.luckySheet.getData();
  1069. const { data: res } = await saveExcelJson({
  1070. key: this.from.id,
  1071. jsonExcel: JSON.stringify(saveData)
  1072. });
  1073. if (res.code === 200) {
  1074. this.$message({
  1075. message: '保存成功',
  1076. type: 'success'
  1077. });
  1078. } else {
  1079. this.$message.error(res.msg);
  1080. this.getInitialData();
  1081. }
  1082. } catch (error) {
  1083. } finally {
  1084. // 无论成功还是失败,最终都会执行这里
  1085. this.saveExcelJsonLoad = false;
  1086. }
  1087. }
  1088. },
  1089. created() {
  1090. this.excelType()//清表类型
  1091. },
  1092. mounted() {
  1093. // this.heightss = this.$refs.rulesss.clientHeight
  1094. }
  1095. }
  1096. </script>
  1097. <style scoped lang="scss">
  1098. .marleft10 {
  1099. margin-left: 10px;
  1100. }
  1101. ::v-deep.el-tree-node__expand-icon {
  1102. font-size: 16px;
  1103. }
  1104. .colorblue {
  1105. color: rgb(0, 82, 217);
  1106. }
  1107. .treecontent ::v-deep.el-scrollbar {
  1108. height: 100%;
  1109. }
  1110. .el-scrollbar {
  1111. height: 100%;
  1112. }
  1113. .rightHeader {
  1114. display: flex;
  1115. justify-content: flex-start;
  1116. align-items: top;
  1117. font-size: 14px;
  1118. background-color: #fff;
  1119. .excelname {
  1120. box-sizing: border-box;
  1121. min-width: 200px;
  1122. height: 28px;
  1123. border: 1px solid rgb(220, 220, 220);
  1124. padding: 0 10px;
  1125. border-radius: 3px;
  1126. display: flex;
  1127. justify-content: space-between;
  1128. align-items: center;
  1129. }
  1130. }
  1131. .dialogModel {
  1132. .dialogBox {
  1133. .middle {
  1134. display: flex;
  1135. .left {
  1136. border: 1px solid rgb(220, 220, 220);
  1137. border-radius: 3px;
  1138. height: 500px;
  1139. width: 49%;
  1140. .select {
  1141. box-sizing: border-box;
  1142. display: flex;
  1143. justify-content: center;
  1144. padding: 5px 0;
  1145. border-bottom: 1px solid #e0e0e0;
  1146. }
  1147. .leftscroll {
  1148. height: 450px;
  1149. overflow-y: scroll;
  1150. }
  1151. }
  1152. .right {
  1153. height: auto;
  1154. height: 60px;
  1155. max-height: 500px;
  1156. margin-left: 2%;
  1157. // height: 500px;
  1158. border-radius: 3px;
  1159. td {
  1160. box-sizing: border-box;
  1161. padding: 5px 10px;
  1162. height: 30px;
  1163. line-height: 30px;
  1164. }
  1165. }
  1166. }
  1167. }
  1168. .btbox {
  1169. margin-top: 20px;
  1170. display: flex;
  1171. justify-content: center;
  1172. }
  1173. }
  1174. .rightBox {
  1175. flex: 1;
  1176. }
  1177. .boxswai {
  1178. height: 100%;
  1179. box-sizing: border-box;
  1180. padding-bottom: 10px;
  1181. }
  1182. .text-hover{
  1183. cursor: pointer;
  1184. color: #409EFF;
  1185. }
  1186. </style>