index.vue 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365
  1. <template>
  2. <div v-if="showReportData" style="width: 100%; height: calc(100% - 70px);">
  3. <div class="cy-report-content">
  4. <div class="cy-div0">
  5. <div class="cy-report-ruler-unit">mm</div>
  6. </div>
  7. <div class="cy-div1">
  8. <div class="cy-ruler-top">
  9. <ruler-view ruler-position="horizontal"></ruler-view>
  10. </div>
  11. <div class="cy-box">
  12. <div class="cy-ruler-left">
  13. <ruler-view ruler-position="vertical"></ruler-view>
  14. </div>
  15. <div class="cy-box-main">
  16. <el-input type="text" placeholder="请输入报表模板标题" v-model="templateName" maxlength="20" size="mini" show-word-limit></el-input>
  17. <div id="luckysheet"
  18. style="margin:0px;padding:0px;position:relative;height:100%;width:100%;left: 0px;top: 0px;bottom:0px;">
  19. </div>
  20. </div>
  21. </div>
  22. </div>
  23. <div class="cy-div2">
  24. <div class="cy-chart-div" @click="newReportTemplate" v-if="templateId">
  25. <svg-icon icon-class="report_new" style="width: 35px; height: 35px; margin-bottom: 6px;"/>
  26. <span>新建</span>
  27. </div>
  28. <div class="cy-chart-div" @click="saveReportTemplate">
  29. <svg-icon icon-class="report_save" style="width: 35px; height: 35px; margin-bottom: 6px;"/>
  30. <span>保存</span>
  31. </div>
  32. <div class="cy-chart-div" @click="clearReportTemplate">
  33. <svg-icon icon-class="report_cancel" style="width: 30px; height: 30px; margin-bottom: 8px;"/>
  34. <span>重置</span>
  35. </div>
  36. <el-divider></el-divider>
  37. <div class="cy-chart-div" @click="templateEvent()">
  38. <svg-icon icon-class="report_template" style="width: 35px;"/>
  39. <span>模板库</span>
  40. </div>
  41. <div class="cy-chart-div" @click="dataEvent(1)">
  42. <svg-icon icon-class="report_basedata" style="width: 35px;"/>
  43. <span>基础数据项</span>
  44. </div>
  45. <div class="cy-chart-div" @click="dataEvent()">
  46. <svg-icon icon-class="report_data" style="width: 35px;"/>
  47. <span>数据项</span>
  48. </div>
  49. <div class="cy-chart-div" @click="barEvent('bar')">
  50. <svg-icon icon-class="bar_chart"/>
  51. <span>柱状图</span>
  52. </div>
  53. <div class="cy-chart-div" @click="barEvent('line')">
  54. <svg-icon icon-class="line_chart"/>
  55. <span>折线图</span>
  56. </div>
  57. <div class="cy-chart-div" @click="barEvent('pie')">
  58. <svg-icon icon-class="pie_chart"/>
  59. <span>饼状图</span>
  60. </div>
  61. </div>
  62. </div>
  63. <!-- 图表右键操作 -->
  64. <ul v-show="visibleChartMenu"
  65. :style="{ left: menuLeft + 'px', top: menuTop + 'px' }"
  66. class="contextmenu contextmenu-black">
  67. <li @click="updateChartItem">修改</li>
  68. <li @click="delChartItem">删除</li>
  69. </ul>
  70. <!-- 弹出层:图配置 -->
  71. <el-drawer
  72. :title="chartConfigTitle"
  73. :visible.sync="dialogBarChartVisible"
  74. :show-close="false"
  75. :close-on-press-escape="false"
  76. :wrapperClosable="false"
  77. :before-close="dialogClose">
  78. <el-form ref="barChartForm" :model="barChartForm" label-position="top" size="mini" style="margin: 0 20px;">
  79. <el-form-item label="图表标题:" prop="title" class="label-title1">
  80. <el-input type="text" placeholder="请输入标题" v-model="barChartForm.title" maxlength="80" show-word-limit>
  81. </el-input>
  82. </el-form-item>
  83. <el-form-item label="图表副标题:" prop="subtitle" class="label-title1">
  84. <el-input type="text" placeholder="请输入副标题" v-model="barChartForm.subtitle" maxlength="60" show-word-limit>
  85. </el-input>
  86. </el-form-item>
  87. <el-form-item label="是否显示图表标题:" prop="showTitle">
  88. <el-radio v-model="barChartForm.showTitle" label="1">是</el-radio>
  89. <el-radio v-model="barChartForm.showTitle" label="0">否</el-radio>
  90. </el-form-item>
  91. <el-form-item label="是否显示图例:" prop="showLegend">
  92. <el-radio v-model="barChartForm.showLegend" label="1">是</el-radio>
  93. <el-radio v-model="barChartForm.showLegend" label="0">否</el-radio>
  94. </el-form-item>
  95. <!-- <el-form-item label="图例:" prop="legendType" v-if="barChartForm.type != 'pie'">-->
  96. <!-- <el-radio v-model="barChartForm.legendType" label="1">数据项</el-radio>-->
  97. <!-- <el-radio v-model="barChartForm.legendType" label="0">值</el-radio>-->
  98. <!-- </el-form-item>-->
  99. <el-form-item label="数据组:">
  100. <el-select filterable
  101. v-model="chooseDataGroup"
  102. placeholder="请选择数据组"
  103. @change="dataSourceChange"
  104. style="width: calc(100% - 110px);">
  105. <el-option
  106. v-for="dict in dataGroupList"
  107. :key="dict.id"
  108. :label="dict.groupName"
  109. :value="dict.id"
  110. ></el-option>
  111. </el-select>
  112. <el-button size="mini" @click="addDataItem" style="float: right;width: 100px;">选择数据项</el-button>
  113. <el-tag size="mini" v-if="chooseItemData.length > 0"
  114. style="margin-top: 10px;"
  115. class="cy-item-tag">已选择({{ chooseItemData.length }})项</el-tag>
  116. </el-form-item>
  117. <el-button type="primary" size="mini" @click="insertBarChartForm">保存</el-button>
  118. <el-button size="mini" @click="cancelBarChartForm">取消</el-button>
  119. </el-form>
  120. </el-drawer>
  121. <!-- 数据项列表信息 -->
  122. <el-dialog
  123. title="数据表配置"
  124. width="80%"
  125. top="10vh"
  126. center
  127. :before-close="dialogClose"
  128. :visible.sync="dialogDataVisible"
  129. :close-on-click-modal="false"
  130. :append-to-body="true">
  131. <div style="text-align: center">
  132. <el-transfer v-model="transferValue"
  133. style="text-align: left; display: inline-block"
  134. :titles="['数据字段列表', '已选择数据字段']"
  135. target-order="push"
  136. :data="transferData"></el-transfer>
  137. <el-divider content-position="left">请选择数据组</el-divider>
  138. <div class="cy-line" style="height: 100px;">
  139. <div>
  140. <el-select filterable
  141. v-model="chooseDataGroup"
  142. placeholder="请选择数据组"
  143. @change="dataSourceChange"
  144. style="width: calc(100% - 110px);">
  145. <el-option
  146. v-for="dict in dataGroupList"
  147. :key="dict.id"
  148. :label="dict.groupName"
  149. :value="dict.id"
  150. ></el-option>
  151. </el-select>
  152. <el-button size="mini" @click="addDataItem" style="float: right;width: 100px;margin-top: 4px;">选择数据项</el-button>
  153. </div>
  154. <el-tag size="mini" v-if="chooseItemData.length > 0"
  155. style="margin-top: 10px;"
  156. class="cy-item-tag">已选择({{ chooseItemData.length }})项</el-tag>
  157. </div>
  158. <el-button type="primary" @click="transferEvent" style="margin-top: 20px;">确定</el-button>
  159. </div>
  160. </el-dialog>
  161. <!-- 数据组选择 -->
  162. <el-dialog
  163. title="选择数据项"
  164. width="80%"
  165. top="10vh"
  166. center
  167. :before-close="dialogClose"
  168. :visible.sync="dialogDataItemVisible"
  169. :close-on-click-modal="false"
  170. :append-to-body="true">
  171. <div>
  172. <el-input placeholder="请输入关键字进行过滤" v-model="filterItemData"></el-input>
  173. <div style="height: 50vh; margin-top: 10px; overflow: auto;">
  174. <el-tree class="cy-item-tree"
  175. ref="itemTree"
  176. :data="itemDataListByTree"
  177. :indent="10"
  178. node-key="id"
  179. show-checkbox
  180. :check-on-click-node="true"
  181. :filter-node-method="filterItemDataNode"
  182. :highlight-current="true"
  183. :default-expand-all="true">
  184. <span class="custom-tree-node" slot-scope="{ node, data }">
  185. <svg-icon v-if="!data.children || data.children.length == 0" icon-class="file"/>
  186. <svg-icon v-else-if="node.expanded" icon-class="folder-open"/>
  187. <svg-icon v-else icon-class="folder"/>
  188. <span :title='data.itemName || "-"' style="margin-left: 2px;">
  189. {{ data.describe
  190. ? ((data.itemName ? data.itemName : '') + '【' + data.describe + '】')
  191. : data.itemName ? data.itemName : '' }}
  192. </span>
  193. </span>
  194. </el-tree>
  195. </div>
  196. </div>
  197. <div style="width: 100%;text-align: center;">
  198. <el-button type="primary"
  199. @click="chooseItemTreeEvent"
  200. style="margin-top: 20px;">确定</el-button>
  201. </div>
  202. </el-dialog>
  203. <!-- 选择基础数据项 -->
  204. <el-dialog
  205. title="选择基础数据项"
  206. width="500px"
  207. center
  208. :before-close="dialogBaseDataClose"
  209. :visible.sync="dialogBaseDataVisible"
  210. :close-on-click-modal="false"
  211. :append-to-body="true">
  212. <el-select v-model="chooseBaseData" filterable placeholder="请选择数据项" style="width: 100%;">
  213. <el-option
  214. v-for="item in this.baseDataList"
  215. :key="item.id"
  216. :label="item.dictKey"
  217. :value="item.dictValue">
  218. </el-option>
  219. </el-select>
  220. <div style="width: 100%; text-align: center; margin-top: 20px;">
  221. <el-button type="primary" @click="baseItemEvent">确定</el-button>
  222. <el-button @click="dialogBaseDataClose">取消</el-button>
  223. </div>
  224. </el-dialog>
  225. <el-dialog
  226. title="选择四则运算表达式"
  227. width="500px"
  228. top="10vh"
  229. center
  230. :before-close="dialogDataModelClose"
  231. :visible.sync="dialogDataModelVisible"
  232. :close-on-click-modal="false"
  233. :append-to-body="true">
  234. <el-select v-model="chooseDataModel" filterable placeholder="请选择表达式" style="width: 100%;">
  235. <el-option
  236. v-for="item in this.dataModelList"
  237. :key="item.id"
  238. :label="item.operationRule"
  239. :value="item.id">
  240. </el-option>
  241. </el-select>
  242. <div style="width: 100%; text-align: center; margin-top: 20px;">
  243. <el-button type="primary" @click="saveDataModelEvent">确定</el-button>
  244. <el-button @click="dialogDataModelClose">取消</el-button>
  245. </div>
  246. </el-dialog>
  247. <!-- 公共模板报表类型选择 -->
  248. <el-dialog
  249. title="选择模板报表"
  250. width="500px"
  251. center
  252. :before-close="dialogClose"
  253. :visible.sync="dialogCommReportVisible"
  254. :close-on-click-modal="false"
  255. :append-to-body="true">
  256. <div style="height: 220px; overflow: auto;">
  257. <div v-for="item in commTemplateList"
  258. style="float: left;width: 50%;display: flex;flex-direction: column;align-items: center;margin-top: 10px;">
  259. <el-image :src="require('@/assets/images/muban.png')" fit="contain" style="height: 80px;"></el-image>
  260. <el-radio v-model="commTemplate" :label="item"
  261. style="margin-top: 5px;width: 100%;text-overflow: ellipsis;white-space: nowrap;overflow: hidden;text-align: center;">
  262. {{ item.templateName }}
  263. </el-radio>
  264. </div>
  265. </div>
  266. <div style="text-align: center; margin-top: 40px;">
  267. <el-button type="primary" @click="commReportEvent">确定</el-button>
  268. <el-button @click="dialogClose">取消</el-button>
  269. </div>
  270. </el-dialog>
  271. <!-- 选择数据组数据 -->
  272. <el-dialog
  273. title="选择数据项"
  274. width="80%"
  275. top="10vh"
  276. center
  277. :before-close="dialogClose"
  278. :visible.sync="dialogGroupItemVisible"
  279. :close-on-click-modal="false"
  280. :append-to-body="true">
  281. <div>
  282. <div>
  283. <el-select filterable
  284. v-model="chooseDataGroup"
  285. placeholder="请选择数据组"
  286. style="width: calc(100% - 110px);">
  287. <el-option
  288. v-for="dict in dataGroupList"
  289. :key="dict.id"
  290. :label="dict.groupName"
  291. :value="dict.id"
  292. ></el-option>
  293. </el-select>
  294. <el-button size="mini" @click="addDataItem" style="float: right;width: 100px;margin-top: 4px;">选择数据项</el-button>
  295. </div>
  296. <div style="height: 50vh; margin-top: 10px; overflow: auto;">
  297. <el-tree class="cy-item-tree"
  298. ref="itemTree"
  299. :data="chooseGroupItemList"
  300. :indent="10"
  301. node-key="id"
  302. show-checkbox
  303. :check-on-click-node="true"
  304. :filter-node-method="filterItemDataNode"
  305. :highlight-current="true"
  306. :default-expand-all="true">
  307. <span class="custom-tree-node" slot-scope="{ node, data }">
  308. <svg-icon v-if="!data.children || data.children.length == 0" icon-class="file"/>
  309. <svg-icon v-else-if="node.expanded" icon-class="folder-open"/>
  310. <svg-icon v-else icon-class="folder"/>
  311. <span v-if="!data.children || data.children.length == 0" :title='data.itemName || "-"' style="margin-left: 2px;">
  312. <!-- {{ data.describe-->
  313. <!-- ? ((data.itemName ? data.itemName : '') + '【' + data.describe + '】')-->
  314. <!-- : data.itemName ? data.itemName : '' }}-->
  315. {{ '【' + data.groupName + '】' + data.itemName + (data.describe ? ('(' + data.describe + ')') : '') }}
  316. </span>
  317. <span v-else :title='data.groupName || "-"' style="margin-left: 2px;">
  318. {{ data.groupName }}
  319. </span>
  320. </span>
  321. </el-tree>
  322. </div>
  323. </div>
  324. <div style="width: 100%;text-align: center;">
  325. <el-button type="primary" style="margin-top: 20px;" @click="itemEvent">确定</el-button>
  326. <el-button style="margin-top: 20px;" @click="dialogClose">取消</el-button>
  327. </div>
  328. </el-dialog>
  329. </div>
  330. <div v-else></div>
  331. </template>
  332. <script>
  333. import RulerView from '@/components/RulerView'
  334. import { insertEChart } from 'luckytool'
  335. import {
  336. getAllDataModel,
  337. getAllItemGroup, getAllTableTemplate, getItemGroupById,
  338. getTableItemGroupById,
  339. getTableTemplateById,
  340. saveReportTemplate,
  341. updateReportTemplate
  342. } from "@/api/datasource";
  343. import {showLoading} from "@/utils/cqcy";
  344. import {getDictByKey} from "@/api/basic";
  345. export default {
  346. name: 'index',
  347. components: {
  348. RulerView
  349. },
  350. data() {
  351. return {
  352. showReportData: true,
  353. dialogBarChartVisible: false,
  354. dialogDataVisible: false,
  355. dialogDataItemVisible: false,
  356. dialogDataModelVisible: false,
  357. dialogCommReportVisible: false,
  358. dialogGroupItemVisible: false,
  359. dialogBaseDataVisible: false,
  360. menuLeft: 0,
  361. menuTop: 0,
  362. visibleChartMenu: false,
  363. chooseChartClz: '',
  364. chartConfigTitle: '',
  365. barChartForm: {
  366. title: '',
  367. type: '',
  368. subtitle: '',
  369. showTitle: '1',
  370. showLegend: '1',
  371. legendType: '1',
  372. legendData: ['模板数据1', '模板数据2'],
  373. xAxisData: ['数据1', '数据2', '数据3']
  374. },
  375. barChartOption: {
  376. },
  377. baseDataList: [],
  378. chooseBaseData: null,
  379. dataGroupList: [],
  380. itemDataListByTree: [],
  381. itemDataListByCalc: [],
  382. chooseGroupItemList: [],
  383. dataModelList: [],
  384. chooseDataModel: null,
  385. chooseDataItemIndex: null,
  386. bomCheckKey: 0,
  387. chooseDataGroup: null,
  388. chooseItemData: [],
  389. filterItemData: '',
  390. transferSingleData: [
  391. { key: 'groupName', label: 'groupName(组名称)', sort: 1 },
  392. { key: 'groupDescribe', label: 'groupDescribe(组描述)', sort: 11 },
  393. { key: 'dataSourceName', label: 'dataSourceName(数据源名称)', sort: 21 }
  394. ],
  395. transferData: [
  396. { key: 'itemName', label: 'itemName(数据项名称)', sort: 31 },
  397. { key: 'describe', label: 'describe(数据标签/描述)', sort: 41 },
  398. { key: 'dataType', label: 'dataType(数据类型)', sort: 51 },
  399. { key: 'dataValue', label: 'dataValue(数据值)', sort: 61 },
  400. { key: 'calcDataValue', label: 'calcDataValue(数据计算值)', sort: 71 }
  401. ],
  402. transferValue: [],
  403. commTemplate: null,
  404. commTemplateList: [],
  405. templateName: '',
  406. templateId: '',
  407. reportTemplateItem: 'REPORT_TEMPLATE_ITEM',
  408. reportInterval: null,
  409. toolChart: [],
  410. toolTable: [],
  411. luckysheetOption: {
  412. container: 'luckysheet', // 设定 DOM 容器的 id
  413. title: '报表模版', // 设定表格名称
  414. lang: 'zh', // 设定表格语言
  415. showinfobar: false, // 是否显示顶部信息栏
  416. showtoolbar: false, // 是否显示工具栏
  417. showtoolbarConfig: {
  418. paintFormat: true, //格式刷
  419. moreFormats: true, // 单元格格式
  420. font: true, // 字体
  421. fontSize: true, // 字号大小
  422. bold: true, // 粗体 (Ctrl+B)
  423. italic: true, // 斜体 (Ctrl+I)
  424. strikethrough: true, // 删除线 (Alt+Shift+5)
  425. underline: true, // 下划线 (Alt+Shift+6)
  426. textColor: true, // 文本颜色
  427. fillColor: true, // 单元格颜色
  428. border: true, // 边框
  429. mergeCell: true, // 合并单元格
  430. horizontalAlignMode: true, // 水平对齐方式
  431. verticalAlignMode: true, // 垂直对齐方式
  432. function: true, // 公式
  433. // image: true
  434. // chart: true
  435. },
  436. showsheetbar: false, // 是否显示底部 sheet 页按钮
  437. sheetFormulaBar: false, // 是否显示公式
  438. row: 50, // 是否显示底部 sheet 页按钮
  439. data: [{
  440. "name": "统计报表", //工作表名称
  441. }],
  442. cellRightClickConfig: { // 自定义配置单元格右击菜单
  443. copy: false, // 复制
  444. copyAs: false, // 复制为
  445. paste: false, // 粘贴
  446. insertRow: true, // 插入行
  447. insertColumn: true, // 插入列
  448. deleteRow: true, // 删除选中行
  449. deleteColumn: true, // 删除选中列
  450. deleteCell: false, // 删除单元格
  451. hideRow: false, // 隐藏选中行和显示选中行
  452. hideColumn: false, // 隐藏选中列和显示选中列
  453. rowHeight: true, // 行高
  454. columnWidth: true, // 列宽
  455. clear: false, // 清除内容
  456. matrix: false, // 矩阵操作选区
  457. sort: false, // 排序选区
  458. filter: false, // 筛选选区
  459. chart: true, // 图表生成
  460. image: false, // 插入图片
  461. link: false, // 插入链接
  462. data: false, // 数据验证
  463. cellFormat: false // 设置单元格格式
  464. },
  465. plugins: ['chart']
  466. }
  467. }
  468. },
  469. watch: {
  470. '$route.query.id': {
  471. handler(now, old) {
  472. this.getTableTemplate(now)
  473. }
  474. },
  475. filterItemData(val) {
  476. this.$refs.itemTree.filter(val)
  477. },
  478. visibleChartMenu(value) {
  479. if (value) {
  480. document.body.addEventListener('click', this.closeMenu)
  481. } else {
  482. document.body.removeEventListener('click', this.closeMenu)
  483. }
  484. }
  485. },
  486. mounted() {
  487. let _this = this
  488. $(function () {
  489. if (_this.showReportData) {
  490. let tempId = _this.$route.query.id
  491. if (tempId) {
  492. _this.getTableTemplate(tempId)
  493. return
  494. }
  495. luckysheet.destroy()
  496. let locItem = localStorage.getItem(_this.reportTemplateItem)
  497. if (locItem && JSON.parse(locItem).data && Array.isArray(JSON.parse(locItem).data)) {
  498. let option = JSON.parse(JSON.stringify(_this.luckysheetOption))
  499. option.data = JSON.parse(locItem).data
  500. _this.toolChart = JSON.parse(locItem).charts
  501. luckysheet.create(option)
  502. for (let i in _this.toolChart) {
  503. _this.insertEChartTool(_this.toolChart[i].info, false)
  504. }
  505. } else {
  506. luckysheet.create(_this.luckysheetOption)
  507. }
  508. _this.autoSaveReportInfo()
  509. }
  510. })
  511. },
  512. created() {
  513. this.transferData = this.transferData.concat(this.transferSingleData)
  514. let compare = (obj1, obj2) => {
  515. if (obj1.sort > obj2.sort) return 1
  516. else if (obj1.sort < obj2.sort) return -1
  517. else return 0
  518. }
  519. this.transferData.sort(compare)
  520. },
  521. destroyed() {
  522. luckysheet.destroy()
  523. if (this.reportInterval) {
  524. clearInterval(this.reportInterval)
  525. }
  526. },
  527. methods: {
  528. /** 保存模版信息 */
  529. saveReportTemplate() {
  530. this.$prompt('请输入/确认报表模版名称', '保存', {
  531. confirmButtonText: '确定',
  532. cancelButtonText: '取消',
  533. inputValue: this.templateName,
  534. inputValidator: (val) => {
  535. if (!val) {
  536. return '模版名称不能为空'
  537. }
  538. if (val.length > 20) {
  539. return '模版名称必须在20字以内'
  540. }
  541. }
  542. }).then(({ value }) => {
  543. const loading = showLoading(this, '保存中,请稍候···')
  544. let result = {
  545. 'charts': this.toolChart,
  546. 'tables': this.toolTable,
  547. 'option': this.luckysheetOption,
  548. 'data': JSON.parse(this.getLuckysheetConfig())
  549. }
  550. let data = {
  551. 'templateName': value,
  552. 'templateData': JSON.stringify(result)
  553. }
  554. if (this.templateId) {
  555. data.id = this.templateId
  556. updateReportTemplate(data).then(res => {
  557. loading.close()
  558. let msg = res.data ? '修改成功!' : '修改失败!'
  559. let msgType = res.data ? 'success' : 'error'
  560. this.$message({
  561. message: msg,
  562. type: msgType
  563. })
  564. this.clearReportTemplate()
  565. this.$emit('refreshReportTemplateData', true)
  566. }).catch((e) => {
  567. loading.close()
  568. })
  569. } else {
  570. saveReportTemplate(data).then(res => {
  571. loading.close()
  572. let msg = res.data ? '保存成功!' : '保存失败!'
  573. let msgType = res.data ? 'success' : 'error'
  574. this.$message({
  575. message: msg,
  576. type: msgType
  577. })
  578. this.clearReportTemplate()
  579. this.$emit('refreshReportTemplateData', true)
  580. }).catch((e) => {
  581. loading.close()
  582. })
  583. }
  584. }).catch(() => {
  585. })
  586. },
  587. /** 新建报表内容 */
  588. newReportTemplate() {
  589. this.templateId = null
  590. this.templateName = ''
  591. this.clearReportTemplate()
  592. },
  593. /** 取消报表内容 */
  594. clearReportTemplate() {
  595. localStorage.removeItem(this.reportTemplateItem)
  596. this.toolChart = []
  597. luckysheet.destroy()
  598. luckysheet.create(this.luckysheetOption)
  599. },
  600. /** 保存数据格式转换 */
  601. getLuckysheetConfig() {
  602. let ls = luckysheet.getLuckysheetfile()
  603. ls.forEach((item, index) => {
  604. if(item.chart) {
  605. item.chart.forEach((chart, i) => {
  606. ls[index].chart[i] = {
  607. ...ls[index].chart[i],
  608. chartOptions: {...chartmix.default.getChartJson(chart.chart_id)}
  609. }
  610. let div = document.getElementById(chart.chart_id + '_c');
  611. if(div.style) {
  612. ls[index].chart[i].left = parseInt(div.style.left)
  613. ls[index].chart[i].top = parseInt(div.style.top)
  614. ls[index].chart[i].width = parseInt(div.style.width)
  615. ls[index].chart[i].height = parseInt(div.style.height)
  616. }
  617. })
  618. }
  619. })
  620. return JSON.stringify(ls)
  621. },
  622. /** 生成唯一 ID 字符串 */
  623. generateRandomKey(prefix) {
  624. if (prefix == null) {
  625. prefix = 'chart'
  626. }
  627. let userAgent = window.navigator.userAgent
  628. .replace(/[^a-zA-Z0-9]/g, '')
  629. .split('')
  630. let mid = ''
  631. for (let i = 0; i < 12; i++) {
  632. mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))]
  633. }
  634. let time = new Date().getTime()
  635. return prefix + '_' + mid + '_' + time
  636. },
  637. /** 向 Excel 插入图表 */
  638. insertEChartTool(info, flag, item, legendType) {
  639. let _this = this
  640. setTimeout(() => {
  641. const sheet = luckysheet.getLuckysheetfile()[0]
  642. let optionData = sheet.data
  643. try {
  644. insertEChart({
  645. selector: '#luckysheet',
  646. info,
  647. sheet,
  648. optionData,
  649. echarts,
  650. luckysheet,
  651. $
  652. })
  653. } catch (e) {
  654. console.error(e)
  655. }
  656. // 保存图表信息
  657. if (flag) {
  658. let chart = {
  659. 'info': info,
  660. 'legendType': legendType,
  661. 'item': item
  662. }
  663. _this.toolChart.push(chart)
  664. }
  665. // 图表事件监听
  666. $('.' + info.className).mousedown(function(e) {
  667. if (3 == e.which) {
  668. _this.closeMenu()
  669. _this.menuTop = e.pageY
  670. _this.menuLeft = e.pageX / 2
  671. _this.visibleChartMenu = true
  672. _this.chooseChartClz = info.className
  673. }
  674. })
  675. }, 200)
  676. },
  677. /** 获取右侧数据组列表 */
  678. getDataGroupList() {
  679. getAllItemGroup().then(res => {
  680. this.dataGroupList = res.data
  681. }).catch((e) => {
  682. this.$message({
  683. message: '数据组查询失败!',
  684. type: 'error'
  685. })
  686. })
  687. },
  688. /** 选择数据源值改变事件 */
  689. dataSourceChange(val) {
  690. this.chooseDataGroup = val
  691. this.chooseItemData = []
  692. },
  693. /** 数据项搜索过滤 */
  694. filterItemDataNode(value, data) {
  695. if (!value) return true
  696. return data.itemName.indexOf(value) !== -1
  697. },
  698. /** 添加数据项 */
  699. addDataItem() {
  700. let id = this.chooseDataGroup
  701. if (!id) {
  702. this.$message({
  703. message: '请选择数据组!',
  704. type: 'warning'
  705. })
  706. return
  707. }
  708. const loading = showLoading(this, '加载中,请稍候···')
  709. getTableItemGroupById(id).then(res => {
  710. loading.close()
  711. this.itemDataListByTree = res.data.itemList
  712. if (this.chooseItemData.length > 0) {
  713. let idList = []
  714. for (let i in this.chooseItemData) {
  715. idList.push(this.chooseItemData[i].id)
  716. }
  717. this.$refs.itemTree.setCheckedKeys(idList)
  718. }
  719. this.dialogDataItemVisible = true
  720. }).catch((e) => {
  721. console.error(e)
  722. loading.close()
  723. this.$message({
  724. message: '连接失败!',
  725. type: 'error'
  726. })
  727. })
  728. },
  729. /** 选择的数据项:第一步 */
  730. chooseItemTreeEvent() {
  731. let checkedNodes = this.$refs.itemTree.getCheckedNodes(false, true)
  732. if (checkedNodes.length == 0) {
  733. this.$message({
  734. message: '请选择数据项!',
  735. type: 'warning'
  736. })
  737. return
  738. }
  739. let chooseList = []
  740. for (let i in checkedNodes) {
  741. let checkedNode = checkedNodes[i]
  742. if (checkedNode.children && checkedNode.children.length > 0) {
  743. continue
  744. }
  745. chooseList.push(checkedNode)
  746. }
  747. this.chooseItemData = chooseList
  748. this.dialogDataItemVisible = false
  749. if (this.dialogGroupItemVisible) {
  750. this.initGroupItem()
  751. }
  752. // this.getAllDataModel(chooseList)
  753. },
  754. initGroupItem() {
  755. let group = null
  756. for (let i = 0; i < this.dataGroupList.length; i ++) {
  757. if (this.dataGroupList[i].id == this.chooseDataGroup) {
  758. group = this.dataGroupList[i]
  759. break
  760. }
  761. }
  762. this.chooseGroupItemList = this.chooseGroupItemList.filter(function (item, index) {
  763. return item.itemGroupId != group.id;
  764. })
  765. for (let j = 0; j < this.chooseItemData.length; j ++) {
  766. this.chooseItemData[j].groupName = group.groupName
  767. this.chooseGroupItemList.push(this.chooseItemData[j])
  768. }
  769. let obj = {};
  770. this.chooseGroupItemList = this.chooseGroupItemList.reduce(function(item, next) {
  771. obj[next.id] ? '' : obj[next.id] = true && item.push(next)
  772. return item;
  773. }, [])
  774. },
  775. /** 查询所有数据模型 */
  776. getAllDataModel(itemList) {
  777. let loading = showLoading(this, '数据加载中,请稍候···')
  778. let params = {
  779. 'page': 1,
  780. 'limit': 1000
  781. }
  782. getAllDataModel(params).then(res => {
  783. loading.close()
  784. if (!res.data) {
  785. this.chooseItemData = itemList
  786. return
  787. }
  788. this.dataModelList = res.data.dataModelList
  789. this.itemDataListByCalc = JSON.parse(JSON.stringify(itemList))
  790. for (let i in this.itemDataListByCalc) {
  791. let temp = this.itemDataListByCalc[i]
  792. temp.rule = {
  793. 'operationRule': '默认值'
  794. }
  795. }
  796. }).catch((e) => {
  797. loading.close()
  798. })
  799. },
  800. /** 选择数据模型 */
  801. handleChoose(index, row) {
  802. this.chooseDataItemIndex = index
  803. this.chooseDataModel = null
  804. this.dialogDataModelVisible = true
  805. },
  806. /** 保存数据模型事件 */
  807. saveDataModelEvent() {
  808. let item = {}
  809. for (let i in this.dataModelList) {
  810. if (this.chooseDataModel == this.dataModelList[i].id) {
  811. item = this.dataModelList[i]
  812. }
  813. }
  814. this.$nextTick(() => {
  815. this.itemDataListByCalc[this.chooseDataItemIndex].rule = item
  816. this.bomCheckKey ++
  817. })
  818. this.dialogDataModelVisible = false
  819. },
  820. /** 报表模板库 */
  821. templateEvent() {
  822. let params = {
  823. 'page': 1,
  824. 'limit': 1000,
  825. 'userId': 'comm'
  826. }
  827. getAllTableTemplate(params).then(res => {
  828. if (!res.data) {
  829. return
  830. }
  831. this.dialogCommReportVisible = true
  832. this.commTemplateList = res.data.tableTemplateList
  833. }).catch((e) => {
  834. })
  835. },
  836. /** 选择模板报表 */
  837. commReportEvent() {
  838. if (!this.commTemplate) {
  839. this.$message({
  840. message: '请选择模板!',
  841. type: 'warning'
  842. })
  843. return
  844. }
  845. let locItem = this.commTemplate.templateData
  846. luckysheet.destroy()
  847. let option = JSON.parse(JSON.stringify(this.luckysheetOption))
  848. option.data = JSON.parse(locItem).data
  849. this.toolChart = JSON.parse(locItem).charts
  850. luckysheet.create(option)
  851. this.dialogClose()
  852. },
  853. /** 数据项 */
  854. dataEvent(type) {
  855. let rangeWithFlatten = luckysheet.getRangeWithFlatten()
  856. if (!rangeWithFlatten || rangeWithFlatten.length != 1) {
  857. this.$message({
  858. message: '请在 Excel 中选择图表需要存放的位置!',
  859. type: 'warning'
  860. })
  861. return
  862. }
  863. // 基础数据项
  864. if (type == 1) {
  865. this.getBaseDataItem()
  866. return
  867. }
  868. this.chooseDataGroup = null
  869. this.getDataGroupList()
  870. this.dialogGroupItemVisible = true
  871. },
  872. /** 查询字典表:基础数据项 */
  873. getBaseDataItem() {
  874. getDictByKey({
  875. 'keyType': 'base_data_item'
  876. }).then(res => {
  877. this.dialogBaseDataVisible = true
  878. this.baseDataList = res.data
  879. }).catch((e) => {
  880. console.error(e)
  881. })
  882. },
  883. /** 基础数据项插入 */
  884. baseItemEvent() {
  885. console.log(this.chooseBaseData)
  886. if (!this.chooseBaseData) {
  887. this.$message({
  888. message: '请选择基础数据项!',
  889. type: 'warning'
  890. })
  891. return
  892. }
  893. let rangeWithFlatten = luckysheet.getRangeWithFlatten()
  894. let c = rangeWithFlatten[0].c
  895. let r = rangeWithFlatten[0].r
  896. luckysheet.setCellValue(r, c, this.chooseBaseData)
  897. this.dialogBaseDataClose()
  898. },
  899. /** 动态数据项插入 */
  900. itemEvent() {
  901. if (this.chooseGroupItemList.length == 0) {
  902. this.$message({
  903. message: '请选择数据组项!',
  904. type: 'warning'
  905. })
  906. return
  907. }
  908. let rangeWithFlatten = luckysheet.getRangeWithFlatten()
  909. let c = rangeWithFlatten[0].c
  910. let r = rangeWithFlatten[0].r
  911. let fieldList = []
  912. for (let i in this.chooseGroupItemList) {
  913. let groupId = this.chooseGroupItemList[i].itemGroupId
  914. let name = this.chooseGroupItemList[i].itemName
  915. name = name.substring(name.lastIndexOf('.') + 1)
  916. let v = '${' + groupId + '.' + name + '}'
  917. let p_c = parseInt(c) + parseInt(i)
  918. fieldList.push({
  919. 'name': v,
  920. 'r': r,
  921. 'c': p_c
  922. })
  923. luckysheet.setCellValue(r, p_c, v)
  924. }
  925. let tableTem = {
  926. 'item': this.chooseGroupItemList,
  927. 'field': fieldList
  928. }
  929. this.toolTable.push(tableTem)
  930. this.chooseGroupItemList = []
  931. this.chooseDataGroup = null
  932. this.chooseItemData = []
  933. this.dialogGroupItemVisible = false
  934. },
  935. /** 数据字段添加 */
  936. transferEvent() {
  937. if (this.transferValue.length == 0) {
  938. this.$message({
  939. message: '请选择数据字段!',
  940. type: 'warning'
  941. })
  942. return
  943. }
  944. if (!this.chooseDataGroup) {
  945. this.$message({
  946. message: '请选择数据组!',
  947. type: 'warning'
  948. })
  949. return
  950. }
  951. if (this.chooseItemData.length == 0) {
  952. this.$message({
  953. message: '请选择数据组项!',
  954. type: 'warning'
  955. })
  956. return
  957. }
  958. let rangeWithFlatten = luckysheet.getRangeWithFlatten()
  959. let c = rangeWithFlatten[0].c
  960. let r = rangeWithFlatten[0].r
  961. let fieldList = []
  962. for (let i in this.transferValue) {
  963. let v = '#{' + this.transferValue[i] + '}'
  964. let p_c = parseInt(c) + parseInt(i)
  965. fieldList.push({
  966. 'name': v,
  967. 'r': r,
  968. 'c': p_c
  969. })
  970. luckysheet.setCellValue(r, p_c, v)
  971. }
  972. let tableTem = {
  973. 'item': this.chooseItemData,
  974. 'field': fieldList
  975. }
  976. this.toolTable.push(tableTem)
  977. this.transferValue = []
  978. this.chooseDataGroup = null
  979. this.chooseItemData = []
  980. this.dialogDataVisible = false
  981. },
  982. /** 柱状图 */
  983. barEvent(type) {
  984. let _this = this
  985. // 当前选择范围
  986. let rangeWithFlatten = luckysheet.getRangeWithFlatten()
  987. if (!rangeWithFlatten || rangeWithFlatten.length <= 1) {
  988. _this.$message({
  989. message: '请在 Excel 中选择图表需要存放的位置范围!',
  990. type: 'warning'
  991. })
  992. return
  993. }
  994. this.chooseDataGroup = null
  995. this.getDataGroupList()
  996. if (!type) {
  997. type = 'bar'
  998. }
  999. if (type == 'bar') {
  1000. this.chartConfigTitle = '柱状图配置'
  1001. } else if (type == 'line') {
  1002. this.chartConfigTitle = '折线图配置'
  1003. } else if (type == 'pie') {
  1004. this.chartConfigTitle = '饼状图配置'
  1005. }
  1006. this.barChartForm.type = type
  1007. // 显示柱状图配置信息
  1008. this.dialogBarChartVisible = true
  1009. },
  1010. /** 柱状图图表插入 */
  1011. insertBarChartForm() {
  1012. if (this.barChartForm.showTitle == '1' && !this.barChartForm.title) {
  1013. this.$message({
  1014. message: '标题不能为空!',
  1015. type: 'warning'
  1016. })
  1017. return
  1018. }
  1019. if (!this.chooseDataGroup) {
  1020. this.$message({
  1021. message: '请选择数据组!',
  1022. type: 'warning'
  1023. })
  1024. return
  1025. }
  1026. if (this.chooseItemData.length == 0) {
  1027. this.$message({
  1028. message: '请选择数据组项!',
  1029. type: 'warning'
  1030. })
  1031. return
  1032. }
  1033. if ((this.barChartForm.legendType == '0' && this.chooseItemData.length > 1)
  1034. || (this.barChartForm.type == 'pie' && this.chooseItemData.length > 1)) {
  1035. this.$message({
  1036. message: '请选择一项数据项!',
  1037. type: 'warning'
  1038. })
  1039. return
  1040. }
  1041. // 图表参数
  1042. this.barChartOption = {
  1043. title: {
  1044. show: this.barChartForm.showTitle == '1',
  1045. text: this.barChartForm.title,
  1046. subtext: this.barChartForm.subtitle,
  1047. left: 'center'
  1048. },
  1049. tooltip: {},
  1050. legend: {
  1051. show: this.barChartForm.showLegend == '1',
  1052. orient: 'vertical',
  1053. left: 'left',
  1054. data: []
  1055. },
  1056. series: []
  1057. }
  1058. if (this.barChartForm.type != 'pie') {
  1059. this.barChartOption.xAxis = {
  1060. data: this.barChartForm.xAxisData
  1061. }
  1062. this.barChartOption.yAxis = {
  1063. }
  1064. // 图表图例类型:1 数据项 0 值
  1065. if (this.barChartForm.legendType == '1') {
  1066. let legendNameList = []
  1067. for (let i in this.chooseItemData) {
  1068. let name = this.chooseItemData[i].describe
  1069. name = name ? name : this.chooseItemData[i].itemName
  1070. legendNameList.push(name)
  1071. }
  1072. this.barChartOption.legend.data = legendNameList
  1073. } else {
  1074. this.barChartOption.legend.data = ['值', '运算值']
  1075. }
  1076. // this.barChartOption.legend.data = this.barChartForm.legendData
  1077. for (let i in this.barChartOption.legend.data) {
  1078. let seriesName = this.barChartOption.legend.data[i]
  1079. let dataList = []
  1080. for (let j in this.barChartForm.xAxisData) {
  1081. dataList.push(Math.ceil(Math.random() * 10))
  1082. }
  1083. let series = {
  1084. name: seriesName,
  1085. type: this.barChartForm.type,
  1086. data: dataList
  1087. }
  1088. this.barChartOption.series.push(series)
  1089. }
  1090. } else {
  1091. this.barChartOption.legend.data = null
  1092. let seriesName = this.barChartForm.legendData[0]
  1093. let dataList = []
  1094. for (let i in this.barChartForm.xAxisData) {
  1095. dataList.push({
  1096. value: Math.ceil(Math.random() * 10),
  1097. name: this.barChartForm.xAxisData[i]
  1098. })
  1099. }
  1100. let series = {
  1101. name: seriesName,
  1102. type: this.barChartForm.type,
  1103. radius: '50%',
  1104. data: dataList
  1105. }
  1106. this.barChartOption.series.push(series)
  1107. }
  1108. if (this.barChartForm.uid) {
  1109. this.delChartItem()
  1110. }
  1111. // 合并当前选择范围
  1112. luckysheet.setRangeMerge('all')
  1113. // 图表插入的 x、y 轴坐标获取
  1114. let range = luckysheet.getRange()
  1115. let x = range[0].column[0]
  1116. let y = range[0].row[0]
  1117. // 随机类名称
  1118. let clz = this.generateRandomKey('chart_clz')
  1119. let info = {
  1120. id: this.generateRandomKey('chart'), // 唯一 id
  1121. pos: [y, x], // eCharts 插入的单元格横、纵坐标
  1122. className: clz, // 给定eCharts容器的 className,自定义
  1123. chart: null, // 创建的 eCharts 实例
  1124. option: this.barChartOption // eCharts 图形配置选项
  1125. }
  1126. this.insertEChartTool(info, true, this.chooseItemData, this.barChartForm.legendType)
  1127. this.$refs.barChartForm.resetFields()
  1128. this.chooseDataGroup = null
  1129. this.chooseItemData = []
  1130. this.dialogBarChartVisible = false
  1131. },
  1132. /** 取消图表插入 */
  1133. cancelBarChartForm() {
  1134. this.$refs.barChartForm.resetFields()
  1135. this.chooseDataGroup = null
  1136. this.chooseItemData = []
  1137. this.dialogBarChartVisible = false
  1138. },
  1139. /** 图表修改 */
  1140. updateChartItem() {
  1141. this.getDataGroupList()
  1142. let chartInfo = {}
  1143. for (let i in this.toolChart) {
  1144. if (this.toolChart[i].info.className == this.chooseChartClz) {
  1145. chartInfo = this.toolChart[i]
  1146. }
  1147. }
  1148. let temp = chartInfo.info.option
  1149. this.barChartForm.uid = new Date().getTime()
  1150. this.barChartForm.title = temp.title.text
  1151. this.barChartForm.subtitle = temp.title.subtext
  1152. this.barChartForm.showTitle = temp.title.show ? '1' : '0'
  1153. this.barChartForm.showLegend = temp.legend.show ? '1' : '0'
  1154. this.barChartForm.type = temp.series[0].type
  1155. this.barChartForm.legendType = chartInfo.legendType
  1156. this.chooseItemData = chartInfo.item
  1157. this.chooseDataGroup = chartInfo.item[0].itemGroupId
  1158. this.dialogBarChartVisible = true
  1159. },
  1160. /** 图表删除 */
  1161. delChartItem() {
  1162. $('.' + this.chooseChartClz).remove()
  1163. luckysheet.cancelRangeMerge()
  1164. for (let i in this.toolChart) {
  1165. if (this.toolChart[i].info.className == this.chooseChartClz) {
  1166. this.toolChart.splice(i, 1)
  1167. }
  1168. }
  1169. },
  1170. /** 自动存储报表信息 */
  1171. autoSaveReportInfo() {
  1172. let _this = this
  1173. let time = setInterval(() => {
  1174. if (!this.templateId) {
  1175. let result = {
  1176. 'charts': _this.toolChart,
  1177. 'tables': _this.toolTable,
  1178. 'data': JSON.parse(_this.getLuckysheetConfig())
  1179. }
  1180. localStorage.setItem(_this.reportTemplateItem, JSON.stringify(result))
  1181. console.log(new Date().getTime(), 'auto save report template success.')
  1182. }
  1183. }, 30 * 1000)
  1184. this.reportInterval = time
  1185. },
  1186. /** 获取模板报表信息 */
  1187. getTableTemplate(id) {
  1188. if (!id) {
  1189. this.$message({
  1190. message: '获取模板失败!',
  1191. type: 'error'
  1192. })
  1193. return
  1194. }
  1195. getTableTemplateById(id).then(res => {
  1196. if (!res.data) {
  1197. return
  1198. }
  1199. luckysheet.destroy()
  1200. this.templateName = res.data.templateName
  1201. this.templateId = res.data.id
  1202. let templateData = res.data.templateData
  1203. let option = JSON.parse(JSON.stringify(this.luckysheetOption))
  1204. option.data = JSON.parse(templateData).data
  1205. this.toolChart = JSON.parse(templateData).charts
  1206. luckysheet.create(option)
  1207. for (let i in this.toolChart) {
  1208. this.insertEChartTool(this.toolChart[i].info, false)
  1209. }
  1210. }).catch((e) => {
  1211. })
  1212. },
  1213. /** 弹出层关闭事件 */
  1214. dialogClose(done) {
  1215. this.commTemplate = null
  1216. if (typeof(done) === 'function') {
  1217. done()
  1218. } else {
  1219. this.dialogBarChartVisible = false
  1220. this.dialogDataVisible = false
  1221. this.dialogDataItemVisible = false
  1222. this.dialogDataModelVisible = false
  1223. this.dialogCommReportVisible = false
  1224. this.dialogGroupItemVisible = false
  1225. }
  1226. },
  1227. /** 弹出层关闭事件 */
  1228. dialogDataModelClose() {
  1229. if (typeof(done) === 'function') {
  1230. done()
  1231. } else {
  1232. this.dialogDataModelVisible = false
  1233. }
  1234. },
  1235. /** 弹出层关闭事件 */
  1236. dialogBaseDataClose() {
  1237. this.chooseBaseData = null
  1238. if (typeof(done) === 'function') {
  1239. done()
  1240. } else {
  1241. this.dialogBaseDataVisible = false
  1242. }
  1243. },
  1244. /** 关闭右键弹出层 */
  1245. closeMenu() {
  1246. this.visibleChartMenu = false
  1247. }
  1248. }
  1249. }
  1250. </script>
  1251. <style rel="stylesheet/scss" lang="scss">
  1252. .cy-report-content {
  1253. width: 100%;
  1254. height: 100%;
  1255. padding-left: 6px;
  1256. color: #FFFFFF;
  1257. font-size: 14px;
  1258. background-color: #2c3e50;
  1259. display: flex;
  1260. flex-direction: row;
  1261. flex-wrap: nowrap;
  1262. }
  1263. .cy-div0 {
  1264. width: 30px;
  1265. height: 30px;
  1266. background: #767676;
  1267. }
  1268. .cy-div1 {
  1269. width: calc(100% - 90px);
  1270. height: 100%;
  1271. }
  1272. .cy-div2 {
  1273. width: 60px;
  1274. height: 100%;
  1275. overflow: auto;
  1276. }
  1277. .cy-report-ruler-unit {
  1278. width: 30px;
  1279. height: 30px;
  1280. display: flex;
  1281. justify-content: center;
  1282. align-items: center;
  1283. float: left;
  1284. border-right: 1px solid #2c3e50;
  1285. border-bottom: 1px solid #2c3e50;
  1286. }
  1287. .cy-ruler-top {
  1288. background: #767676;
  1289. width: 100%;
  1290. height: 30px;
  1291. }
  1292. .cy-box {
  1293. height: calc(100% - 50px);
  1294. width: calc(100% + 30px);
  1295. display: flex;
  1296. margin-left: -30px;
  1297. overflow: auto;
  1298. .cy-ruler-left {
  1299. background: #767676;
  1300. width: 30px;
  1301. height: calc(297mm + 20px);
  1302. }
  1303. .cy-box-main {
  1304. width: 100%;
  1305. height: 297mm;
  1306. margin: 10px;
  1307. background: #FFFFFF;
  1308. }
  1309. }
  1310. .cy-chart-div {
  1311. display: flex;
  1312. flex-direction: column;
  1313. align-items: center;
  1314. cursor: pointer;
  1315. margin-bottom: 15px;
  1316. .svg-icon {
  1317. width: 50px;
  1318. height: 50px;
  1319. }
  1320. span {
  1321. font-size: 12px;
  1322. margin-top: -5px;
  1323. }
  1324. }
  1325. .label-title {
  1326. display: block !important;
  1327. .el-form-item__content {
  1328. width: calc(100% - 100px);
  1329. }
  1330. }
  1331. .el-transfer-panel {
  1332. width: 300px !important;
  1333. }
  1334. </style>