index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <!--
  2. * @Author: lide1202@hotmail.com
  3. * @Date: 2021-3-13 11:04:24
  4. * @Last Modified by: lide1202@hotmail.com
  5. * @Last Modified time: 2021-3-13 11:04:24
  6. !-->
  7. <template>
  8. <div class="layout">
  9. <div class="layout-left">
  10. <div class="add-collection">
  11. 数据集管理
  12. <el-button
  13. type="text"
  14. icon="el-icon-circle-plus-outline"
  15. @click="queryAllDataSet()"
  16. />
  17. </div>
  18. <div>
  19. <el-collapse
  20. v-for="(item, indexs) in dataSet"
  21. :key="indexs"
  22. v-model="activeNames"
  23. @change="handleChange"
  24. >
  25. <el-collapse-item :title="item.setName" :name="item.id">
  26. <el-popconfirm
  27. :title="'确定删除' + item.setName + '吗?'"
  28. @onConfirm="del(item)"
  29. >
  30. <el-button
  31. slot="reference"
  32. type="text"
  33. icon="el-icon-close"
  34. class="delect-all"
  35. />
  36. </el-popconfirm>
  37. <draggable
  38. v-model="item.setParamList"
  39. :sort="false"
  40. group="people"
  41. style="margin-left: 10px"
  42. @start="onStart(item.setCode, $event)"
  43. >
  44. <!-- <transition-group> -->
  45. <div
  46. v-for="(i, index) in item.setParamList"
  47. :key="index"
  48. class="field-container"
  49. >
  50. <div class="aRow">
  51. <span>{{ i }}</span>
  52. </div>
  53. </div>
  54. <!-- </transition-group> -->
  55. </draggable>
  56. </el-collapse-item>
  57. </el-collapse>
  58. </div>
  59. </div>
  60. <div class="layout-middle">
  61. <div class="push_btn">
  62. <el-tooltip
  63. class="item"
  64. effect="dark"
  65. content="预览"
  66. placement="bottom-start"
  67. >
  68. <el-button type="text" @click="preview()">
  69. <i class="iconfont iconfuzhi"></i>
  70. </el-button>
  71. </el-tooltip>
  72. <el-tooltip
  73. class="item"
  74. effect="dark"
  75. content="保存"
  76. placement="bottom-start"
  77. >
  78. <el-button type="text" @click="save()">
  79. <i class="iconfont iconsave"></i>
  80. </el-button>
  81. </el-tooltip>
  82. </div>
  83. <div
  84. id="luckysheet"
  85. style="margin:0px;padding:0px;position:absolute;width:100%;height:95vh;left: 0px;top: 30px;bottom:0px;"
  86. />
  87. <div id="qrCode" ref="qrCodeDiv" />
  88. <img id="barCode" />
  89. </div>
  90. <div class="layout-right">
  91. <el-tabs v-model="activeName" @tab-click="handleClick">
  92. <el-tab-pane label="基础配置" name="first">
  93. <el-form ref="rightForm" :model="rightForm" label-width="60px">
  94. <el-form-item label="坐标">
  95. <el-input v-model="rightForm.coordinate" />
  96. </el-form-item>
  97. <el-form-item label="值">
  98. <el-input v-model="rightForm.value" />
  99. </el-form-item>
  100. </el-form>
  101. </el-tab-pane>
  102. </el-tabs>
  103. </div>
  104. <el-dialog title="数据集管理" :visible.sync="outerVisible">
  105. <el-table
  106. ref="multipleTable"
  107. :data="dataSetData"
  108. tooltip-effect="dark"
  109. style="width: 100%;height: 60vh;overflow-y: scroll;"
  110. @selection-change="handleSelectionChange"
  111. >
  112. <el-table-column type="selection" width="55" />
  113. <el-table-column label="数据集名称" width="120" prop="setName" />
  114. <el-table-column prop="setDesc" label="数据集描述" width="180" />
  115. <el-table-column
  116. prop="setCode"
  117. label="数据集编码"
  118. show-overflow-tooltip
  119. />
  120. </el-table>
  121. <div slot="footer" class="dialog-footer">
  122. <el-button @click="outerVisible = false">取 消</el-button>
  123. <el-button type="primary" @click="checkDataSet()">确定 </el-button>
  124. </div>
  125. </el-dialog>
  126. </div>
  127. </template>
  128. <script>
  129. import draggable from "vuedraggable";
  130. import { queryAllDataSet, detail, detailByReportCode } from "@/api/GaeaReport";
  131. import { addReportExcel, editReportExcel } from "@/api/report";
  132. import ColorPicker from "../components/colorPicker.vue";
  133. // import QRCode from 'qrcodejs2'
  134. // import JsBarcode from 'jsbarcode'
  135. export default {
  136. name: "Excels",
  137. components: {
  138. draggable,
  139. ColorPicker
  140. },
  141. data() {
  142. return {
  143. activeName: "first",
  144. activeNames: ["1"],
  145. reportId: null,
  146. accessKey: null,
  147. reportCode: "",
  148. options: [],
  149. sheet: {},
  150. sheetData: [],
  151. dataSetData: [],
  152. reportExcelDto: {
  153. id: null,
  154. jsonStr: "",
  155. setCodes: "",
  156. setParam: "",
  157. reportCode: ""
  158. },
  159. multipleSelection: [],
  160. rightForm: {
  161. coordinate: "",
  162. value: ""
  163. },
  164. qrCodeForm: {
  165. type: "QRCode",
  166. content: "https://www.baidu.com",
  167. width: 125,
  168. height: 125,
  169. colorDark: "#333333", // 二维码颜色
  170. colorLight: "#ffffff", // 二维码背景色
  171. // correctLevel: QRCode.CorrectLevel.L, // 容错率,L/M/H
  172. ri: 0,
  173. ci: 0,
  174. currentSrc: ""
  175. },
  176. barCodeForm: {
  177. type: "BarCode",
  178. format: "CODE39",
  179. displayValue: true,
  180. content: "99999999999",
  181. lineColor: "#000",
  182. background: "#fff",
  183. width: 100,
  184. height: 40,
  185. ri: 0,
  186. ci: 0,
  187. currentSrc: ""
  188. },
  189. formPrintSetting: {
  190. size: "",
  191. pixel1: "",
  192. pixel2: ""
  193. },
  194. pixelList: [
  195. { paper: "A4", width: 210, height: 297 },
  196. { paper: "A3", width: 297, height: 420 },
  197. { paper: "Letter", width: 216, height: 279 },
  198. { paper: "Legal", width: 216, height: 355 },
  199. { paper: "Executive", width: 184, height: 266 }
  200. ],
  201. dataSet: [],
  202. outerVisible: false,
  203. printVisible: false,
  204. pop: false,
  205. setCode: null,
  206. draggableFieldLabel: null,
  207. dialogVisible: false,
  208. dialogBarCode: false,
  209. paperList: [],
  210. // 纸张标识
  211. paper: "",
  212. // 纸张宽高
  213. width: "",
  214. height: "",
  215. // 清晰度
  216. definition: "",
  217. // 是否套打
  218. isBackend: "",
  219. dpi: "",
  220. pxWidth: "",
  221. pxHeight: "",
  222. show: false,
  223. config: "",
  224. settings: {},
  225. qrCodeList: [],
  226. moveDataelse: {
  227. x: null,
  228. y: null
  229. }
  230. };
  231. },
  232. mounted() {},
  233. created() {
  234. this.reportCode = this.$route.query.reportCode;
  235. this.accessKey = this.$route.query.accessKey;
  236. this.loadDataSet();
  237. this.design();
  238. },
  239. methods: {
  240. handleClose() {
  241. this.printVisible = false;
  242. },
  243. handleChange(val) {},
  244. // 右侧信息配置tabs
  245. handleClick(tab, event) {},
  246. async design() {
  247. // 根据reportCode获取单条报表
  248. const { code, data } = await detailByReportCode(this.reportCode);
  249. if (data != null) {
  250. this.reportId = data.id;
  251. }
  252. this.sheetData = data == null ? [{}] : JSON.parse(data.jsonStr);
  253. console.log(this.sheetData);
  254. this.createSheet();
  255. if (data != null) {
  256. if (data.setCodes != null && data.setCodes !== "") {
  257. let dataSetList = data.setCodes.split("|");
  258. dataSetList.forEach(code => {
  259. this.dataSetData.forEach(setData => {
  260. if (code === setData.setCode) {
  261. this.detail(setData.id);
  262. }
  263. });
  264. });
  265. }
  266. }
  267. },
  268. //初始化表格
  269. createSheet() {
  270. //将vue对象传入
  271. const that = this;
  272. const options = {
  273. container: "luckysheet", // 设定DOM容器的id
  274. title: "Luckysheet Demo", // 设定表格名称
  275. lang: "zh", // 设定表格语言
  276. plugins: ["chart"],
  277. hook: {
  278. cellDragStop: function(cell, postion, sheetFile, ctx, event) {
  279. // console.info("cellDragStop-cell",cell);
  280. // console.info("cellDragStop-postion", postion);
  281. // console.info("cellDragStop-sheetFile", sheetFile);
  282. // console.info("cellDragStop-ctx",ctx);
  283. // console.info("cellDragStop-event", event);
  284. // console.log("cellDragStop-draggableFieldLabel", that);
  285. luckysheet.setCellValue(
  286. postion.r,
  287. postion.c,
  288. that.draggableFieldLabel
  289. );
  290. },
  291. cellMousedown: function(cell, postion, sheetFile, ctx) {
  292. that.rightForm.coordinate = postion.r + "," + postion.c;
  293. that.rightForm.value = cell == null ? "" : cell.v;
  294. }
  295. },
  296. data: [
  297. {
  298. name: "report", //工作表名称
  299. color: "", //工作表颜色
  300. index: 0, //工作表索引
  301. status: 1, //激活状态
  302. order: 0, //工作表的下标
  303. hide: 0, //是否隐藏
  304. row: 36, //行数
  305. column: 18, //列数
  306. defaultRowHeight: 19, //自定义行高
  307. defaultColWidth: 73, //自定义列宽
  308. celldata: [], //初始化使用的单元格数据
  309. config: {
  310. merge: {}, //合并单元格
  311. rowlen: {}, //表格行高
  312. columnlen: {}, //表格列宽
  313. rowhidden: {}, //隐藏行
  314. colhidden: {}, //隐藏列
  315. borderInfo: {}, //边框
  316. authority: {} //工作表保护
  317. },
  318. scrollLeft: 0, //左右滚动条位置
  319. scrollTop: 315, //上下滚动条位置
  320. luckysheet_select_save: [], //选中的区域
  321. calcChain: [], //公式链
  322. isPivotTable: false, //是否数据透视表
  323. pivotTable: {}, //数据透视表设置
  324. filter_select: {}, //筛选范围
  325. filter: null, //筛选配置
  326. luckysheet_alternateformat_save: [], //交替颜色
  327. luckysheet_alternateformat_save_modelCustom: [], //自定义交替颜色
  328. luckysheet_conditionformat_save: {}, //条件格式
  329. frozen: {}, //冻结行列配置
  330. chart: [], //图表配置
  331. zoomRatio: 1, // 缩放比例
  332. image: [], //图片
  333. showGridLines: 1, //是否显示网格线
  334. dataVerification: {} //数据验证配置
  335. }
  336. ]
  337. };
  338. options.data = this.sheetData;
  339. $(function() {
  340. luckysheet.create(options);
  341. });
  342. },
  343. onStart(setCode, evt) {
  344. this.setCode = setCode;
  345. let fieldLabel = evt.item.innerText; // 列名称
  346. this.draggableFieldLabel = "#{" + this.setCode + "." + fieldLabel + "}";
  347. console.log("evt", evt);
  348. console.log("draggableFieldLabel", this.draggableFieldLabel);
  349. },
  350. async loadDataSet() {
  351. const { code, data } = await queryAllDataSet();
  352. this.dataSetData = data;
  353. if (code != "200") return;
  354. },
  355. doCancel() {
  356. this.pop = false;
  357. },
  358. async save() {
  359. // console.log(luckysheet.toJson())
  360. // console.log(luckysheet.getAllSheets())
  361. // console.log(luckysheet.getSheetData(0))
  362. const jsonData = luckysheet.getAllSheets();
  363. for (let i = 0; i < jsonData.length; i++) {
  364. //清空data数据,以celldata数据为主
  365. jsonData[i]["data"] = [];
  366. }
  367. this.reportExcelDto.jsonStr = JSON.stringify(luckysheet.getAllSheets());
  368. let setCodeList = [];
  369. let setParams = {};
  370. this.dataSet.forEach(code => {
  371. setCodeList.push(code.setCode);
  372. if (
  373. code.dataSetParamDtoList != null &&
  374. code.dataSetParamDtoList.length > 0
  375. ) {
  376. let dataSetParam = {};
  377. code.dataSetParamDtoList.forEach(value => {
  378. dataSetParam[value.paramName] = value.sampleItem;
  379. });
  380. setParams[code.setCode] = dataSetParam;
  381. }
  382. });
  383. this.reportExcelDto.setParam = JSON.stringify(setParams);
  384. this.reportExcelDto.setCodes = setCodeList.join("|");
  385. this.reportExcelDto.reportCode = this.reportCode;
  386. if (this.reportId == null) {
  387. const { code } = await addReportExcel(this.reportExcelDto);
  388. if (code != "200") return;
  389. this.$message.success("保存成功");
  390. } else {
  391. this.reportExcelDto.id = this.reportId;
  392. const { code } = await editReportExcel(this.reportExcelDto);
  393. if (code != "200") return;
  394. this.$message.success("更新成功");
  395. }
  396. },
  397. async detailByReportCode(reportCode) {
  398. const { code, data } = await detailByReportCode(reportCode);
  399. if (data != null) {
  400. this.reportId = data.id;
  401. }
  402. },
  403. async preview() {
  404. let routeUrl = this.$router.resolve({
  405. path: "/excelreport/viewer",
  406. query: { reportCode: this.reportCode }
  407. });
  408. window.open(routeUrl.href, "_blank");
  409. },
  410. async queryAllDataSet() {
  411. this.outerVisible = true;
  412. },
  413. handleSelectionChange(val) {
  414. this.multipleSelection = val;
  415. },
  416. checkDataSet() {
  417. this.outerVisible = false;
  418. if (this.multipleSelection.length > 1) {
  419. this.$message({
  420. message: "一次最多勾选一个数据集",
  421. type: "warning"
  422. });
  423. this.outerVisible = true;
  424. } else {
  425. this.detail(this.multipleSelection[0].id);
  426. }
  427. },
  428. async detail(id) {
  429. const { code, data } = await detail(id);
  430. if (code != 200) return;
  431. let flag = true;
  432. this.dataSet.forEach(value => {
  433. if (value.setCode === data.setCode) {
  434. flag = false;
  435. }
  436. });
  437. if (flag) {
  438. this.dataSet.push(data);
  439. }
  440. },
  441. del(val) {
  442. for (let i = 0; i < this.dataSet.length; i++) {
  443. if (this.dataSet[i].setCode === val.setCode) {
  444. this.dataSet.splice(i, 1);
  445. }
  446. }
  447. }
  448. }
  449. };
  450. </script>
  451. <style src="../../../../static/luckysheet/assets/iconfont/iconfont.css" />
  452. <style scoped lang="scss">
  453. .position {
  454. position: absolute;
  455. z-index: 100;
  456. }
  457. #qrCode,
  458. #barCode {
  459. display: none;
  460. }
  461. .yulancopy {
  462. font-size: 16px;
  463. }
  464. .baocun {
  465. font-size: 17px;
  466. }
  467. .el-collapse {
  468. position: relative;
  469. border-top: 0 solid #e6ebf5;
  470. border-bottom: 0 solid #e6ebf5;
  471. }
  472. .el-collapse-item__header {
  473. border-bottom: 0 solid #e6ebf5 !important;
  474. }
  475. .delect-all {
  476. position: absolute;
  477. top: 10px;
  478. right: 30px;
  479. color: #333;
  480. }
  481. .push_btn {
  482. position: absolute;
  483. z-index: 100;
  484. top: 5px;
  485. left: 3px;
  486. .iconfont {
  487. color: black;
  488. }
  489. }
  490. .add-collection {
  491. line-height: 30px;
  492. .el-button {
  493. font-size: 16px !important;
  494. vertical-align: middle;
  495. margin-left: 20px;
  496. }
  497. }
  498. .layout {
  499. display: block;
  500. position: relative;
  501. margin: 0;
  502. padding: 0;
  503. border: 1px solid #d7dde4;
  504. }
  505. .layout-left {
  506. display: block;
  507. position: absolute;
  508. padding: 20px;
  509. width: 230px;
  510. min-height: 99.98vh;
  511. border-right: 1px solid #eee;
  512. border-color: #e8eaec;
  513. background: #fff;
  514. border-radius: 4px;
  515. font-size: 14px;
  516. -webkit-transition: all 0.2s ease-in-out;
  517. transition: all 0.2s ease-in-out;
  518. top: 0;
  519. left: 0;
  520. .field-container {
  521. display: block;
  522. position: relative;
  523. width: 100%;
  524. margin: 0;
  525. cursor: pointer;
  526. line-height: 30px;
  527. .aRow {
  528. padding: 0 10px;
  529. .operation {
  530. float: right;
  531. display: none;
  532. .el-button--text {
  533. color: #333 !important;
  534. }
  535. }
  536. &:hover {
  537. .operation {
  538. display: block;
  539. }
  540. background: #f7fafd;
  541. }
  542. }
  543. }
  544. }
  545. .layout-middle {
  546. display: block;
  547. position: absolute;
  548. left: 230px;
  549. right: 230px;
  550. width: calc(100% - 460px);
  551. margin: 0;
  552. padding: 0;
  553. .excel-designer {
  554. display: block;
  555. position: relative;
  556. margin: 0;
  557. padding: 0;
  558. }
  559. }
  560. .layout-right {
  561. display: block;
  562. position: absolute;
  563. top: 0;
  564. right: 0;
  565. padding: 20px;
  566. width: 230px;
  567. min-height: 99.98vh;
  568. border-left: 1px solid #dcdee2;
  569. border-color: #e8eaec;
  570. background: #fff;
  571. border-radius: 4px;
  572. font-size: 14px;
  573. -webkit-transition: all 0.2s ease-in-out;
  574. transition: all 0.2s ease-in-out;
  575. }
  576. </style>