|
@@ -0,0 +1,502 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div class="sy-content">
|
|
|
+ <el-row>
|
|
|
+ <split-pane
|
|
|
+ :min-percent='15'
|
|
|
+ :default-percent='15'
|
|
|
+ split="vertical">
|
|
|
+ <template slot="paneL">
|
|
|
+
|
|
|
+ </template>
|
|
|
+ <template slot="paneR">
|
|
|
+
|
|
|
+
|
|
|
+ </template>
|
|
|
+ </split-pane>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-tree :data="treeData"
|
|
|
+ :props="defaultProps"
|
|
|
+ node-key="id"
|
|
|
+ default-expand-all
|
|
|
+ :expand-on-click-node="false"
|
|
|
+ @node-contextmenu="rightReportNodeEvent"
|
|
|
+ @node-click="templateNameClick" class="lefttree1">
|
|
|
+ <!-- <span class="custom-tree-node" slot-scope="{ node, data }">
|
|
|
+ <i class="el-icon-folder" style="color: #DFBA49; margin-right: 5px;"></i>
|
|
|
+ <span style="font-size: 15px;">{{ node.label }}</span>
|
|
|
+ </span> -->
|
|
|
+ <span class="custom-tree-node" slot-scope="{ node, data }">
|
|
|
+ <!-- <span style="font-size: 15px;">{{ node.label }}</span> -->
|
|
|
+ <svg-icon v-if="data.id == -1" icon-class="reports" />
|
|
|
+ <template v-else>
|
|
|
+ <svg-icon v-if="data.templateType == 0" icon-class="report_m" />
|
|
|
+ <svg-icon v-else-if="data.templateType == 1 || data.templateType == 3" icon-class="report_a" />
|
|
|
+ <svg-icon v-else-if="data.templateType == 2 || data.templateType == 4" icon-class="report_e" />
|
|
|
+ <svg-icon v-else-if="data.templateType == 5 || data.templateType == 6" icon-class="report_d" />
|
|
|
+ <svg-icon v-else icon-class="report_m" />
|
|
|
+ </template>
|
|
|
+ <span :title="data.templateName" style="margin-left: 2px;font-size: 14px;">{{
|
|
|
+ data.templateName
|
|
|
+ }}</span>
|
|
|
+ <span v-if="data.id == -1" style="position: absolute; right: 0;">
|
|
|
+ <el-button type="text" size="mini" title="新建报表" @click="addReportEvent"
|
|
|
+ icon="el-icon-document-add"></el-button>
|
|
|
+ <el-button type="text" size="mini" style="margin-left: 5px" title="导入报表"
|
|
|
+ @click="importReportEvent" icon="el-icon-upload2"></el-button>
|
|
|
+ <input ref="importFileNode" class="import-file-node" type="file" @change="loadExcel"
|
|
|
+ accept=".xlsx" style="display: none;"></input>
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ </el-tree>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="20">
|
|
|
+ <iframe @load="load" id="myIframe" :src="iframeSrc"
|
|
|
+ :style="{ 'height': '90vh', 'width': '100%', 'border': 'none', 'display': 'block' }"></iframe>
|
|
|
+ </el-col>
|
|
|
+ <!-- 报表模板列表右键操作 -->
|
|
|
+ <ul v-show="visibleReportChildMenu" :style="{ left: menuLeft + 'px', top: menuTop + 'px' }"
|
|
|
+ class="contextmenu contextmenu-black">
|
|
|
+ <li @click="updateReportName">修改名称</li>
|
|
|
+ <li @click="exportReport">导出</li>
|
|
|
+ <li @click="delReport">删除</li>
|
|
|
+ </ul>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import CommonTable from '@/components/CommonTable/index.vue'
|
|
|
+
|
|
|
+import { getAllTableTemplate,updateTableTemplateNameById,delTableTemplateById } from '@/api/report/tableTemplate'
|
|
|
+import {
|
|
|
+ showConfirmWin,
|
|
|
+ showAlertMsgWin,
|
|
|
+ showPromptWin,
|
|
|
+ showAlertWin,
|
|
|
+ showLoading,
|
|
|
+ goPage,
|
|
|
+ checkReportChangeStatus
|
|
|
+} from "@/utils/cqcy"
|
|
|
+import LuckyExcel from 'luckyexcel'
|
|
|
+import { getToken } from '@/utils/auth'
|
|
|
+import ExcelJS from 'exceljs';
|
|
|
+
|
|
|
+export default {
|
|
|
+ created() {
|
|
|
+ this.getAllTableTemplate()
|
|
|
+ const loading = showLoading(this, '加载中,请稍候···')
|
|
|
+ const task = setInterval(() => {
|
|
|
+ loading.close()
|
|
|
+ }, 200)
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ CommonTable
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ '$route.query.t': {
|
|
|
+ handler(now, old) {
|
|
|
+ this.sendMsg({
|
|
|
+ cmd: 'show',
|
|
|
+ data: {
|
|
|
+ reportId: this.$route.query.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ visibleReportChildMenu(value) {
|
|
|
+ if (value) {
|
|
|
+ document.body.addEventListener("click", this.closeMenu);
|
|
|
+ } else {
|
|
|
+ document.body.removeEventListener("click", this.closeMenu);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ isLoadingStatus: false,
|
|
|
+ //reportId: null,
|
|
|
+ reportId: 0,
|
|
|
+ type: '',
|
|
|
+ iframeSrc: process.env.VUE_APP_BASE_API + '/reportSheet/index.html',
|
|
|
+ // iframeSrc: 'http://localhost:83/#/tableTemplate/templateDetail?id=18',
|
|
|
+ visibleReportChildMenu: false,
|
|
|
+ visibleReportMenu:false,
|
|
|
+ chooseReportData: null,
|
|
|
+ // 右键布局显示位置
|
|
|
+ menuLeft: 0,
|
|
|
+ // 右键布局显示位置
|
|
|
+ menuTop: 0,
|
|
|
+ treeData:[
|
|
|
+ {
|
|
|
+ id:-1,
|
|
|
+ templateName: '报表列表',
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ defaultProps: {
|
|
|
+ children: 'children',
|
|
|
+ label: 'templateName'
|
|
|
+ },
|
|
|
+ queryParams: {
|
|
|
+ page: 1,
|
|
|
+ limit: 10,
|
|
|
+ templateName: null,
|
|
|
+ templateType: null
|
|
|
+ },
|
|
|
+ tableTotal: 0,
|
|
|
+ //报表类型
|
|
|
+ reportTableTypeList: [
|
|
|
+ {
|
|
|
+ value: 0,
|
|
|
+ label: '手动报表'
|
|
|
+ }, {
|
|
|
+ value: 1,
|
|
|
+ label: '周期报表'
|
|
|
+ }, {
|
|
|
+ value: 2,
|
|
|
+ label: '事件驱动报表'
|
|
|
+ }, {
|
|
|
+ value: 3,
|
|
|
+ label: '设备报表'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ load() {
|
|
|
+
|
|
|
+ const _this = this
|
|
|
+ const files = localStorage.getItem('IMPORT_FILES_JSON')
|
|
|
+ _this.sendMsg({
|
|
|
+ cmd: 'init',
|
|
|
+ data: {
|
|
|
+ token: getToken(),
|
|
|
+ url: process.env.VUE_APP_BASE_API,
|
|
|
+ reportId: this.reportId,
|
|
|
+ type: this.type,
|
|
|
+ files
|
|
|
+ }
|
|
|
+ })
|
|
|
+ localStorage.setItem('IMPORT_FILES_JSON', '')
|
|
|
+ window.addEventListener('message', function (event) {
|
|
|
+ const json = event.data
|
|
|
+ if (json.cmd === 'close') {
|
|
|
+ //_this.$router.go(-1)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ sendMsg(msg) {
|
|
|
+ document.getElementById('myIframe').contentWindow.postMessage(msg, '*')
|
|
|
+ },
|
|
|
+ /** 如果userId为空,则获取当前登录人的所有报表模板;不为空,则查询对应的参数的报表模板 */
|
|
|
+ getAllTableTemplate() {
|
|
|
+ getAllTableTemplate(this.queryParams).then(res => {
|
|
|
+ if (!res || !res.data) {
|
|
|
+ this.$message({
|
|
|
+ message: '数据查询失败!',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.tableTotal = res.data.count
|
|
|
+ this.tableData = res.data.tableTemplateList
|
|
|
+ //this.treeData = res.data.tableTemplateList
|
|
|
+ this.treeData[0].children = res.data.tableTemplateList
|
|
|
+ if(res.data.count>0){
|
|
|
+ this.reportId = res.data.tableTemplateList[0].id
|
|
|
+ this.type = ''
|
|
|
+ }
|
|
|
+ this.load()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 报表名称点击事件 */
|
|
|
+ templateNameClick(data) {
|
|
|
+ this.closeMenu()
|
|
|
+ if(data.id==-1){
|
|
|
+ return;
|
|
|
+ };
|
|
|
+ //checkReportChangeStatus()
|
|
|
+ this.reportId=data.id
|
|
|
+ this.type = ''
|
|
|
+ this.load()
|
|
|
+ },
|
|
|
+ addReportEvent(){
|
|
|
+ this.reportId=0
|
|
|
+ this.type = ''
|
|
|
+ this.load()
|
|
|
+ },
|
|
|
+ importReportEvent(){
|
|
|
+ this.$refs.importFileNode.dispatchEvent(new MouseEvent('click'))
|
|
|
+ },
|
|
|
+ /** 关闭右键弹出层 */
|
|
|
+ closeMenu() {
|
|
|
+ this.visibleReportMenu = false;
|
|
|
+ this.visibleReportChildMenu = false;
|
|
|
+ },
|
|
|
+ /** 报表配置右键菜单事件 */
|
|
|
+ rightReportNodeEvent(event, data, node, target) {
|
|
|
+ this.closeMenu();
|
|
|
+ this.menuLeft = 80;
|
|
|
+ if (data.id == -1) {
|
|
|
+ this.menuTop = 30;
|
|
|
+ this.visibleReportMenu = true;
|
|
|
+ this.chooseReportParentNode = node;
|
|
|
+ } else if (!data.itemName) {
|
|
|
+ // this.menuTop = 30 + event.layerY
|
|
|
+ this.menuTop = 30 + event.y - 100;
|
|
|
+ this.visibleReportChildMenu = true;
|
|
|
+ this.chooseReportData = data;
|
|
|
+ this.reportId = data.id;
|
|
|
+ this.chooseReportParentNode = node.parent;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ updateReportName(){
|
|
|
+ this.closeMenu();
|
|
|
+ if (!this.chooseReportData || !this.chooseReportData.id) {
|
|
|
+ showAlertMsgWin(this, null, cqcyCode[201]);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ showPromptWin(
|
|
|
+ this,
|
|
|
+ "修改报表名称",
|
|
|
+ "请输入报表名称",
|
|
|
+ this.chooseReportData.templateName,
|
|
|
+ (val) => {
|
|
|
+ if (!val || !val.trim()) {
|
|
|
+ return "报表名称不能为空";
|
|
|
+ }
|
|
|
+ if (val.length > 20) {
|
|
|
+ return "报表名称必须在20字以内";
|
|
|
+ }
|
|
|
+ },
|
|
|
+ (value) => {
|
|
|
+ const loading = showLoading(this, "修改中,请稍候···");
|
|
|
+ let params = {
|
|
|
+ id: this.chooseReportData.id,
|
|
|
+ templateName: encodeURIComponent(value),
|
|
|
+ };
|
|
|
+ updateTableTemplateNameById(params)
|
|
|
+ .then((res) => {
|
|
|
+ loading.close();
|
|
|
+ let msg = res.data ? "修改成功!" : "修改失败!";
|
|
|
+ showAlertMsgWin(this, null, msg, () => {
|
|
|
+ this.getAllTableTemplate();
|
|
|
+ // goPage(this, "/reportTemplate", {
|
|
|
+ // id: this.chooseReportData.id,
|
|
|
+ // });
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ loading.close();
|
|
|
+ showAlertWin(this, null, e);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+ delReport(){
|
|
|
+ this.closeMenu();
|
|
|
+ if (!this.chooseReportData || !this.chooseReportData.id) {
|
|
|
+ showAlertMsgWin(this, null, cqcyCode[201]);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ showConfirmWin(this, null, '您确定要删除该报表设计吗?', () => {
|
|
|
+ // delReportDataPolicyById(this.chooseReportData.id).then(res => {
|
|
|
+ // this.$message({
|
|
|
+ // message: '删除报表设计成功!',
|
|
|
+ // type: 'success'
|
|
|
+ // })
|
|
|
+ // this.getAllTableTemplate()
|
|
|
+ // })
|
|
|
+ delTableTemplateById(this.chooseReportData.id, 0).then((res) => {
|
|
|
+ if (res.msg == "fail") {
|
|
|
+ this.delById(res.data, this.chooseReportData.id)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (res.data) {
|
|
|
+ this.$message({
|
|
|
+ message: '删除成功!',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: '删除失败!',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.getAllTableTemplate()
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ exportReport(){
|
|
|
+ this.closeMenu();
|
|
|
+ this.reportId = this.chooseReportData.id;
|
|
|
+ this.type = 'export';
|
|
|
+ this.load();
|
|
|
+ // this.$router.push({
|
|
|
+ // path: '/tableTemplate/templateDetail'
|
|
|
+ // , query: {
|
|
|
+ // id: this.chooseReportData.id,
|
|
|
+ // type: 'export'
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ },
|
|
|
+ /** 新增报表设计 */
|
|
|
+ addTableTemplateEvent() {
|
|
|
+ this.$router.push({
|
|
|
+ path: '/tableTemplate/templateDetail'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 导入报表设计 */
|
|
|
+ importTableTemplateEvent() {
|
|
|
+ this.$refs.importFileNode.dispatchEvent(new MouseEvent('click'))
|
|
|
+ },
|
|
|
+ /** 删除报表模板 */
|
|
|
+ delById(tips, id) {
|
|
|
+ showConfirmWin(this, null, tips, () => {
|
|
|
+ delTableTemplateById(id, 1).then((res) => {
|
|
|
+ if (res.data) {
|
|
|
+ this.$message({
|
|
|
+ message: '删除成功!',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: '删除失败!',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.getAllTableTemplate()
|
|
|
+ })
|
|
|
+ });
|
|
|
+ },
|
|
|
+ loadExcel(evt) {
|
|
|
+ let _this = this
|
|
|
+ const files = evt.target.files
|
|
|
+ if (files == null || files.length == 0) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!files[0].name.endsWith('.xlsx')) {
|
|
|
+ showAlertMsgWin(_this, null, '只能导入xlsx格式文件!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const loading = showLoading(this, '文件导入中,请稍候···')
|
|
|
+ let status = true
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = function (event) {
|
|
|
+ const data = new Uint8Array(event.target.result);
|
|
|
+ const workbook = new ExcelJS.Workbook();
|
|
|
+ workbook.xlsx.load(data).then(function (workbook) {
|
|
|
+ workbook.eachSheet(function (worksheet, sheetId) {
|
|
|
+ if (status) {
|
|
|
+ status = false
|
|
|
+ let hyperlink = {}
|
|
|
+ worksheet.eachRow(function (row, rowNumber) {
|
|
|
+ row.eachCell(function (cell, colNumber) {
|
|
|
+ if (cell.type === ExcelJS.ValueType.Hyperlink) {
|
|
|
+ hyperlink[(parseInt(rowNumber) - 1) + '_' + (parseInt(colNumber) - 1)] = {
|
|
|
+ linkAddress: cell.value.hyperlink,
|
|
|
+ linkTooltip: cell.value.text,
|
|
|
+ linkType: 'external'
|
|
|
+ }
|
|
|
+ } else if (cell.type === ExcelJS.ValueType.String) {
|
|
|
+ if (/![A-Z]+\d+/g.test(cell.value) && cell.value.startsWith(worksheet.name + '!')) {
|
|
|
+ hyperlink[(parseInt(rowNumber) - 1) + '_' + (parseInt(colNumber) - 1)] = {
|
|
|
+ linkAddress: cell.value,
|
|
|
+ linkTooltip: cell.value,
|
|
|
+ linkType: 'internal'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ LuckyExcel.transformExcelToLucky(files[0], function (exportJson, luckysheetfile) {
|
|
|
+ loading.close()
|
|
|
+ localStorage.setItem('IMPORT_FILES_JSON', JSON.stringify({
|
|
|
+ luckysheetfile,
|
|
|
+ hyperlink
|
|
|
+ }))
|
|
|
+ // _this.$router.push({
|
|
|
+ // path: '/tableTemplate/templateDetail'
|
|
|
+ // , query: {
|
|
|
+ // id: -999,
|
|
|
+ // type: 'import',
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ _this.reportId = 0
|
|
|
+ _this.type = 'import'
|
|
|
+ _this.load()
|
|
|
+ document.getElementsByClassName('import-file-node')[0].value = ''
|
|
|
+ })
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+ reader.onerror = function (event) {
|
|
|
+ document.getElementsByClassName('import-file-node')[0].value = ''
|
|
|
+ showAlertMsgWin(_this, null, '读取文件失败,请稍后再试!')
|
|
|
+ return
|
|
|
+ };
|
|
|
+ reader.readAsArrayBuffer(files[0]);
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style rel="stylesheet/scss" lang="scss">
|
|
|
+.el-tree{
|
|
|
+ //background: #646464 !important;
|
|
|
+ //color: #fff;
|
|
|
+ //font-size:14px;
|
|
|
+}
|
|
|
+.sy-content{
|
|
|
+ //background: #646464 !important;
|
|
|
+}
|
|
|
+.contextmenu {
|
|
|
+ margin: 0;
|
|
|
+ background: #fff;
|
|
|
+ z-index: 3000;
|
|
|
+ position: absolute;
|
|
|
+ list-style-type: none;
|
|
|
+ padding: 5px 0;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #333;
|
|
|
+ box-shadow: 2px 2px 3px 0 rgb(0 0 0 / 30%);
|
|
|
+}
|
|
|
+.contextmenu-black {
|
|
|
+ background: #000;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+.contextmenu-black li {
|
|
|
+ border-bottom: 1px solid;
|
|
|
+ margin: 0 5px;
|
|
|
+}
|
|
|
+.contextmenu li {
|
|
|
+ margin: 0;
|
|
|
+ padding: 7px 16px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.contextmenu-black li:last-child {
|
|
|
+ border-bottom: 0;
|
|
|
+}
|
|
|
+.splitter-paneL {
|
|
|
+ background-color: #2c3e50;
|
|
|
+ padding-right: 0 !important;
|
|
|
+}
|
|
|
+
|
|
|
+.splitter-paneR {
|
|
|
+ padding-left: 0 !important;
|
|
|
+}
|
|
|
+
|
|
|
+.splitter-pane-resizer {
|
|
|
+ opacity: unset !important;
|
|
|
+ background: #2c3e50 !important;
|
|
|
+}
|
|
|
+</style>
|