index.vue 100 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779
  1. <template>
  2. <div class="cqcy-content" style="margin: 0;height: calc(100% - 70px);">
  3. <breadcrumb-view :breadcrumbList="breadcrumbList" :show-index="false"></breadcrumb-view>
  4. <div v-if="btnType === ''" class="cy-nav-sx">
  5. <el-select v-model="searchValue"
  6. style="width: 180px;"
  7. placeholder="请选择报表类型"
  8. @change="changeReportTypeEvent">
  9. <el-option v-for="item in reportOptions"
  10. style="margin-left: 5px; width: 180px;"
  11. :key="item.value"
  12. :label="item.label"
  13. :value="item.value">
  14. </el-option>
  15. </el-select>
  16. <el-input placeholder="请输入报表名称"
  17. v-model="searchTxt"
  18. style="margin-left: 5px; width: 180px;"
  19. prefix-icon="el-icon-search">
  20. </el-input>
  21. <el-button style="margin-left: 5px;" @click="searchReportEvent">查询</el-button>
  22. </div>
  23. <!-- <el-button v-if="btnType === ''" type="primary" class="cy-nav-btn" icon="el-icon-circle-plus-outline"-->
  24. <!-- size="mini" @click="addReportEvent">新增-->
  25. <!-- </el-button>-->
  26. <!-- <el-button v-if="btnType === ''" type="success" class="cy-nav-btn" icon="el-icon-refresh"-->
  27. <!-- size="mini" @click="refreshReportEvent">刷新</el-button>-->
  28. <el-divider></el-divider>
  29. <div class="cy-main">
  30. <div class="cy-main-left" v-if="!showMainView">
  31. <div class="cy-list">
  32. <el-table v-if="reportDataList.length > 0"
  33. :data="reportDataList"
  34. border
  35. :stripe="true"
  36. :header-cell-style="{background: '#E8E8E8'}"
  37. @sort-change="sortChange"
  38. style="width: 100%;">
  39. <el-table-column
  40. align="center"
  41. sortable="custom"
  42. label="报表名称"
  43. prop="reportTableName">
  44. <template slot-scope="scope">
  45. <span style="color: #409EFF; cursor: pointer;"
  46. @click="handleReportNodeClick(scope.row, scope.row.userId != uid ? 'deny' : '')"
  47. :title="scope.row.reportTableName">{{ scope.row.reportTableName }}</span>
  48. </template>
  49. </el-table-column>
  50. <el-table-column
  51. align="center"
  52. label="报表类型"
  53. prop="reportTableType"
  54. width="350">
  55. <template slot-scope="scope">
  56. <el-tag v-if="scope.row.userId != uid" type="success" style="margin-right: 5px;">被分享</el-tag>
  57. <el-tag v-if="uid == scope.row.userId && scope.row.userGroupList && scope.row.userGroupList.length > 0"
  58. type="warning" style="margin-right: 5px;">已分享
  59. </el-tag>
  60. <el-tag v-if="scope.row.reportTableType == 0" style="margin-right: 5px;">手动报表</el-tag>
  61. <el-tag v-if="scope.row.reportTableType == 1" style="margin-right: 5px;">自动报表</el-tag>
  62. <el-tag v-if="scope.row.reportTableType == 2" style="margin-right: 5px;">事件驱动报表</el-tag>
  63. <el-tag v-if="scope.row.reportTableType == 5" style="margin-right: 5px;">设备报表</el-tag>
  64. </template>
  65. </el-table-column>
  66. <el-table-column
  67. align="center"
  68. label="创建时间"
  69. sortable
  70. prop="createTime"
  71. width="200">
  72. </el-table-column>
  73. <el-table-column label="操作" align="center" width="380">
  74. <template slot-scope="scope">
  75. <el-button type="text"
  76. v-if="uid == scope.row.userId"
  77. size="small"
  78. icon="el-icon-setting"
  79. @click="editReportItem(scope.row)">配置
  80. </el-button>
  81. <!-- <el-button type="text"-->
  82. <!-- v-if="uid == scope.row.userId"-->
  83. <!-- size="small"-->
  84. <!-- icon="el-icon-edit"-->
  85. <!-- @click="editReportItem(scope.row)">修改-->
  86. <!-- </el-button>-->
  87. <el-button type="text"
  88. v-if="uid == scope.row.userId && scope.row.reportTableType == 1 && scope.row.runState == 0"
  89. size="small"
  90. icon="el-icon-video-play"
  91. @click="setReportStatus(scope.row)">启动
  92. </el-button>
  93. <el-button type="text"
  94. v-if="uid == scope.row.userId && scope.row.reportTableType == 1 && scope.row.runState == 1"
  95. size="small"
  96. icon="el-icon-video-pause"
  97. @click="setReportStatus(scope.row)">停止
  98. </el-button>
  99. <el-button type="text"
  100. v-if="uid == scope.row.userId"
  101. size="small"
  102. icon="el-icon-printer"
  103. @click="setAutoPrint(scope.row)">打印配置
  104. </el-button>
  105. <el-button type="text"
  106. v-if="uid == scope.row.userId"
  107. size="small"
  108. icon="el-icon-user"
  109. @click="setUserGroupEvent(scope.row)">授权
  110. </el-button>
  111. <el-button type="text"
  112. v-if="uid == scope.row.userId"
  113. size="small"
  114. icon="el-icon-document"
  115. @click="getUserGroupEvent(scope.row)">授权详情
  116. </el-button>
  117. <el-button type="text"
  118. v-if="uid == scope.row.userId"
  119. size="small"
  120. icon="el-icon-delete"
  121. style="color: red;"
  122. @click="removeReportItem(scope.row)">删除
  123. </el-button>
  124. </template>
  125. </el-table-column>
  126. </el-table>
  127. <el-empty v-else description="暂无数据"></el-empty>
  128. </div>
  129. <el-pagination
  130. background
  131. @size-change="handleSizeChange"
  132. @current-change="handleCurrentChange"
  133. :current-page="reportPage"
  134. :page-size="reportLimit"
  135. layout="sizes, prev, pager, next, total"
  136. :total="reportTotal">
  137. </el-pagination>
  138. </div>
  139. <div class="cy-main-right" :style="showMainView ? '' : 'display: none;'">
  140. <el-row v-if="btnType == 'add'" style="margin: 10px 20px;">
  141. <el-button type="primary" size="mini" icon="el-icon-document" @click="saveReportInfo">保存报表</el-button>
  142. <el-button type="danger" size="mini" icon="el-icon-circle-close" @click="cancelSaveReport">取消</el-button>
  143. </el-row>
  144. <el-row v-if="btnType == 'show'" style="margin: 10px 20px;">
  145. <el-button type="success" size="mini" icon="el-icon-document-checked" @click="updateReport">保存</el-button>
  146. <el-button type="primary" size="mini" icon="el-icon-download" @click="downloadReport">下载</el-button>
  147. <el-button type="warning" size="mini" icon="el-icon-printer" @click="printExcel">打印</el-button>
  148. <el-button type="info" size="mini" icon="el-icon-document" @click="historyReport">运行记录</el-button>
  149. <el-button type="danger" size="mini" icon="el-icon-circle-close" @click="cancelSaveReport">关闭</el-button>
  150. </el-row>
  151. <el-row v-if="btnType == 'showShared'" style="margin: 10px 20px;">
  152. <el-button type="primary" size="mini" icon="el-icon-download" @click="downloadReport">下载</el-button>
  153. <el-button type="warning" size="mini" icon="el-icon-printer" @click="printExcel">打印</el-button>
  154. <el-button v-if="chooseMyReport && chooseMyReport.reportTableType != 0" type="info" size="mini"
  155. icon="el-icon-document" @click="historyReport">运行记录
  156. </el-button>
  157. <el-button type="danger" size="mini" icon="el-icon-circle-close" @click="cancelSaveReport">关闭</el-button>
  158. <div style="float: right;" v-if="this.showReportTableType == 1 || this.showReportTableType == 0 || this.showReportTableType == 5">
  159. <label>频率:</label>
  160. <el-select style="width: 90px;" size="mini" placeholder="请选择频率"
  161. v-model="reportInterval" @change="reportIntervalChange">
  162. <el-option
  163. v-for="item in reportIntervalOptions"
  164. :key="item"
  165. :label="item + '秒'"
  166. :value="item">
  167. </el-option>
  168. </el-select>
  169. </div>
  170. </el-row>
  171. <el-row v-if="btnType == 'showChild'" style="margin: 10px 20px;">
  172. <el-button type="primary" size="mini" icon="el-icon-download" @click="downloadReport">下载</el-button>
  173. <el-button type="warning" size="mini" icon="el-icon-printer" @click="printExcel">打印</el-button>
  174. <el-button type="danger" size="mini" icon="el-icon-circle-close" @click="cancelSaveReport2">关闭</el-button>
  175. </el-row>
  176. <div id="luckysheet"
  177. style="margin:0px;padding:0px;position:relative;height:calc(100% - 50px);width:100%;left: 20px;top: 0px;bottom:0px;">
  178. </div>
  179. </div>
  180. </div>
  181. <!-- 新增报表 -->
  182. <el-dialog
  183. :title="reportDialogTitle"
  184. width="600px"
  185. top="10vh"
  186. center
  187. v-dialog-drag
  188. v-if="dialogReportTemplateVisible"
  189. :before-close="dialogClose"
  190. :visible.sync="dialogReportTemplateVisible"
  191. :close-on-click-modal="false"
  192. :append-to-body="true">
  193. <el-form ref="reportForm" :model="reportForm" :rules="reportRules" label-width="80px">
  194. <el-form-item label='报表名称' prop="reportTableName">
  195. <el-input placeholder="请输入报表名称" v-model="reportForm.reportTableName" maxlength="20"></el-input>
  196. </el-form-item>
  197. <el-form-item label="报表类型" prop="reportTableType" v-if="!reportForm.id">
  198. <el-radio-group v-model="reportForm.reportTableType" @input="changeReportType">
  199. <el-radio label="0">手动报表</el-radio>
  200. <el-radio label="1">自动报表</el-radio>
  201. <el-radio label="2">事件驱动报表</el-radio>
  202. <el-radio label="5">设备报表</el-radio>
  203. </el-radio-group>
  204. </el-form-item>
  205. <el-form-item label="报表模板" prop="tableTemplateId" v-if="!reportForm.id">
  206. <el-select v-model="reportForm.tableTemplateId" filterable placeholder="请选择报表模板" style="width: 100%;">
  207. <el-option
  208. v-for="item in reportTemplateList"
  209. :key="item.id"
  210. :label="item.templateName"
  211. :value="item.id">
  212. </el-option>
  213. </el-select>
  214. </el-form-item>
  215. <el-form-item label="开始时间" prop="dateRange" v-if="reportForm.reportTableType == 1">
  216. <el-date-picker
  217. v-model="reportForm.startTime"
  218. style="width: 100%;"
  219. type="datetime"
  220. :clearable="false"
  221. placeholder="请选择开始时间"
  222. prefix-icon=""
  223. :picker-options="{
  224. format: 'yyyy-MM-dd HH:mm:ss'
  225. }"
  226. value-format="yyyy-MM-dd HH:mm:ss">
  227. </el-date-picker>
  228. </el-form-item>
  229. <el-form-item label="运行时间" prop="cronLabel" v-if="reportForm.reportTableType == 1">
  230. <el-input placeholder="请设置运行时间" v-model="reportForm.cronLabel" style="width: calc(100% - 105px);"
  231. readonly></el-input>
  232. <el-button size="mini" @click="settingAutoReportTime" style="float: right;width: 100px;line-height: 20px;">
  233. 设置运行时间
  234. </el-button>
  235. </el-form-item>
  236. </el-form>
  237. <span slot='footer'>
  238. <el-button type="primary" @click="chooseReportEvent" style="margin-top: 20px;">确定</el-button>
  239. <el-button @click="dialogClose" style="margin-top: 20px;">取消</el-button>
  240. </span>
  241. </el-dialog>
  242. <!-- 配置打印定时任务 -->
  243. <el-dialog
  244. :title="printDialogTitle"
  245. width="700px"
  246. top="10vh"
  247. center
  248. v-dialog-drag
  249. v-if="dialogAutoPrintVisible"
  250. :before-close="dialogClose"
  251. :visible.sync="dialogAutoPrintVisible"
  252. :close-on-click-modal="false"
  253. :append-to-body="true">
  254. <el-form ref="reportForm" :model="reportForm" :rules="reportRules" label-width="80px">
  255. <el-radio-group v-model="radioByCron">
  256. <el-form-item label="秒">
  257. <el-radio :label="1">
  258. <span style="margin-right: 10px;">每</span>
  259. <el-input-number size="mini" v-model="radioByCronValS" :min="1" :max="59"
  260. :precision="0"></el-input-number>
  261. <span style="margin-left: 10px;">秒执行一次</span>
  262. </el-radio>
  263. </el-form-item>
  264. <el-form-item label="分钟">
  265. <el-radio :label="2">
  266. <span style="margin-right: 10px;">每</span>
  267. <el-input-number size="mini" v-model="radioByCronValM" :min="1" :max="59"
  268. :precision="0"></el-input-number>
  269. <span style="margin-left: 10px;">分钟执行一次</span>
  270. </el-radio>
  271. </el-form-item>
  272. <el-form-item label="小时">
  273. <el-radio :label="3">
  274. <span style="margin-right: 10px;">每</span>
  275. <el-input-number size="mini" v-model="radioByCronValH" :min="1" :max="2" :precision="0"></el-input-number>
  276. <span style="margin-left: 10px;">小时执行一次</span>
  277. </el-radio>
  278. </el-form-item>
  279. <el-form-item label="指定时间">
  280. <el-radio :label="4">
  281. <span style="margin-right: 10px;">在每天的</span>
  282. <el-time-picker v-model="radioByCronValD"
  283. size="mini"
  284. placeholder="请选择时间"
  285. :clearable="false"
  286. :editable="false"
  287. value-format="HH:mm:ss"
  288. :picker-options="{
  289. format: 'HH:mm:ss'
  290. }">
  291. </el-time-picker>
  292. <span style="margin-left: 10px;">执行一次</span>
  293. </el-radio>
  294. </el-form-item>
  295. <el-form-item label="">
  296. <el-radio :label="5">
  297. <span style="margin-right: 10px;">在每月</span>
  298. <el-input-number size="mini" v-model="radioByCronValMo" :min="1" :max="31"
  299. :precision="0"></el-input-number>
  300. <span style="margin-right: 10px; margin-left: 10px;">号的</span>
  301. <el-time-picker v-model="radioByCronValMoD"
  302. size="mini"
  303. placeholder="请选择时间"
  304. :clearable="false"
  305. :editable="false"
  306. value-format="HH:mm:ss"
  307. :picker-options="{
  308. format: 'HH:mm:ss'
  309. }">
  310. </el-time-picker>
  311. <span style="margin-left: 10px;">执行一次</span>
  312. </el-radio>
  313. </el-form-item>
  314. </el-radio-group>
  315. </el-form>
  316. <span slot='footer'>
  317. <el-button type="primary" @click="chooseCronPrint" style="margin-top: 20px;">确定</el-button>
  318. <el-button type="warning" v-if="printForm.runState==1" @click="stopAutoPrint"
  319. style="margin-top: 20px;">停止</el-button>
  320. <el-button type="warning" disabled v-if="printForm.runState!=1" @click="stopAutoPrint"
  321. style="margin-top: 20px;">停止</el-button>
  322. <el-button @click="dialogClose" style="margin-top: 20px;">取消</el-button>
  323. </span>
  324. </el-dialog>
  325. <!-- 用户组选择 -->
  326. <el-dialog
  327. title="选择用户组"
  328. width="840px"
  329. top="10vh"
  330. center
  331. v-dialog-drag
  332. v-if="dialogUserGroupVisible"
  333. :before-close="dialogClose"
  334. :visible.sync="dialogUserGroupVisible"
  335. :close-on-click-modal="false"
  336. :append-to-body="true">
  337. <!-- <el-form label-width="80px">-->
  338. <!-- <el-form-item label="用户组">-->
  339. <!-- <el-select v-model="userGroupInfo" filterable clearable multiple placeholder="请选择用户组" style="width: 100%;">-->
  340. <!-- <el-option-->
  341. <!-- v-for="item in userGroupList"-->
  342. <!-- :key="item.id"-->
  343. <!-- :label="item.userGroupName"-->
  344. <!-- :value="item.id">-->
  345. <!-- </el-option>-->
  346. <!-- </el-select>-->
  347. <!-- </el-form-item>-->
  348. <!-- </el-form>-->
  349. <div class="ug-div">
  350. <el-transfer
  351. v-model="userGroupInfo"
  352. :titles="['用户组列表', '已选择用户组']"
  353. :data="userGroupList"
  354. :props="{
  355. key: 'id',
  356. label: 'userGroupName'
  357. }">
  358. </el-transfer>
  359. </div>
  360. <span slot='footer'>
  361. <el-button type="primary" @click="chooseUserGroupEvent" style="margin-top: 20px;">确定</el-button>
  362. <el-button @click="dialogClose" style="margin-top: 20px;">取消</el-button>
  363. </span>
  364. </el-dialog>
  365. <!-- 自动报表CRON定时表达式 -->
  366. <el-dialog
  367. title="配置定时任务"
  368. width="700px"
  369. top="10vh"
  370. center
  371. v-dialog-drag
  372. v-if="dialogAutoReportVisible"
  373. :before-close="dialogClose"
  374. :visible.sync="dialogAutoReportVisible"
  375. :close-on-click-modal="false"
  376. :append-to-body="true">
  377. <el-form label-width="80px">
  378. <el-radio-group v-model="radioByCron">
  379. <el-form-item label="秒">
  380. <el-radio :label="1">
  381. <span style="margin-right: 10px;">每</span>
  382. <el-input-number size="mini" v-model="radioByCronValS" :min="1" :max="59"
  383. :precision="0"></el-input-number>
  384. <span style="margin-left: 10px;">秒执行一次</span>
  385. </el-radio>
  386. </el-form-item>
  387. <el-form-item label="分钟">
  388. <el-radio :label="2">
  389. <span style="margin-right: 10px;">每</span>
  390. <el-input-number size="mini" v-model="radioByCronValM" :min="1" :max="59"
  391. :precision="0"></el-input-number>
  392. <span style="margin-left: 10px;">分钟执行一次</span>
  393. </el-radio>
  394. </el-form-item>
  395. <el-form-item label="小时">
  396. <el-radio :label="3">
  397. <span style="margin-right: 10px;">每</span>
  398. <el-input-number size="mini" v-model="radioByCronValH" :min="1" :max="2" :precision="0"></el-input-number>
  399. <span style="margin-left: 10px;">小时执行一次</span>
  400. </el-radio>
  401. </el-form-item>
  402. <el-form-item label="指定时间">
  403. <el-radio :label="4">
  404. <span style="margin-right: 10px;">在每天的</span>
  405. <el-time-picker v-model="radioByCronValD"
  406. size="mini"
  407. placeholder="请选择时间"
  408. :clearable="false"
  409. :editable="false"
  410. value-format="HH:mm:ss"
  411. :picker-options="{
  412. format: 'HH:mm:ss'
  413. }">
  414. </el-time-picker>
  415. <span style="margin-left: 10px;">执行一次</span>
  416. </el-radio>
  417. </el-form-item>
  418. <el-form-item label="">
  419. <el-radio :label="5">
  420. <span style="margin-right: 10px;">在每月</span>
  421. <el-input-number size="mini" v-model="radioByCronValMo" :min="1" :max="31"
  422. :precision="0"></el-input-number>
  423. <span style="margin-right: 10px; margin-left: 10px;">号的</span>
  424. <el-time-picker v-model="radioByCronValMoD"
  425. size="mini"
  426. placeholder="请选择时间"
  427. :clearable="false"
  428. :editable="false"
  429. value-format="HH:mm:ss"
  430. :picker-options="{
  431. format: 'HH:mm:ss'
  432. }">
  433. </el-time-picker>
  434. <span style="margin-left: 10px;">执行一次</span>
  435. </el-radio>
  436. </el-form-item>
  437. </el-radio-group>
  438. <!-- <el-form-item label="表达式">-->
  439. <!-- <el-input type="text" placeholder="请输入定时任务表达式" v-model="cronVal" maxlength="50"></el-input>-->
  440. <!-- </el-form-item>-->
  441. <!-- <div>-->
  442. <!-- <label>常用定时任务表达式例子</label>-->
  443. <!-- <ul>-->
  444. <!-- <li v-for="(item, i) in cronList" style="margin-bottom: 5px;">-->
  445. <!-- <span class="cron-txt" @click="cronNodeEvent(item)">{{ item.value }}</span>-->
  446. <!-- <span class="cron-txt-desc">{{ item.label }}</span>-->
  447. <!-- </li>-->
  448. <!-- </ul>-->
  449. <!-- </div>-->
  450. </el-form>
  451. <span slot='footer'>
  452. <el-button type="primary" @click="chooseCronEvent">确定</el-button>
  453. <!-- <el-button @click="dialogClose">取消</el-button>-->
  454. </span>
  455. </el-dialog>
  456. <!-- 报表类型 -->
  457. <el-dialog
  458. title="报表类型选择"
  459. width="50%"
  460. top="10vh"
  461. center
  462. v-dialog-drag
  463. v-if="dialogReportTypeVisible"
  464. :before-close="dialogClose"
  465. :visible.sync="dialogReportTypeVisible"
  466. :close-on-click-modal="false"
  467. :append-to-body="true">
  468. <div style="text-align: center;">
  469. <el-radio v-model="reportType" label="0">手动报表</el-radio>
  470. <el-radio v-model="reportType" label="1">自动报表</el-radio>
  471. <el-radio v-model="reportType" label="2">事件驱动报表</el-radio>
  472. <el-radio v-model="reportType" label="5">设备报表</el-radio>
  473. </div>
  474. <span slot='footer'>
  475. <el-button type="primary" @click="chooseReportTypeEvent">确定</el-button>
  476. <el-button @click="dialogClose">取消</el-button>
  477. </span>
  478. </el-dialog>
  479. <!-- 报表下载类型选择 -->
  480. <el-dialog
  481. title="选择下载类型"
  482. width="500px"
  483. center
  484. v-dialog-drag
  485. v-if="dialogDownloadReportTypeVisible"
  486. :before-close="dialogClose"
  487. :visible.sync="dialogDownloadReportTypeVisible"
  488. :close-on-click-modal="false"
  489. :append-to-body="true">
  490. <div style="text-align: center;">
  491. <el-radio v-model="downloadType" label="1">Excel</el-radio>
  492. <!-- <el-radio v-model="downloadType" label="2" disabled>PDF</el-radio>-->
  493. </div>
  494. <div style="text-align: center; margin-top: 40px;">
  495. <el-button type="primary" @click="downloadReportEvent">确定</el-button>
  496. </div>
  497. </el-dialog>
  498. <!-- 历史报表查看 -->
  499. <el-dialog
  500. title="运行报表记录"
  501. width="80%"
  502. top="10vh"
  503. center
  504. v-dialog-drag-and-zoom
  505. v-if="dialogHistoryReportVisible"
  506. :before-close="dialogClose"
  507. :visible.sync="dialogHistoryReportVisible"
  508. :close-on-click-modal="false"
  509. :append-to-body="true">
  510. <div style="height: 60vh;">
  511. <div style="margin-bottom: 10px; float: right;">
  512. <el-input placeholder="请输入报表名称"
  513. v-model="searchHistoryTxt"
  514. style="margin-left: 5px; width: 300px;"
  515. prefix-icon="el-icon-search">
  516. </el-input>
  517. <el-button type="primary" style="margin-left: 5px;" @click="searchHistoryReportEvent">查询</el-button>
  518. </div>
  519. <el-table
  520. :data="reportHistoryData" border :stripe="true"
  521. :header-cell-style="{background: '#E8E8E8'}"
  522. @sort-change="sortChange1"
  523. style="width: 100%; height: calc(100% - 100px); overflow: auto;">
  524. <el-table-column
  525. align="center"
  526. sortable="custom"
  527. label="报表名称"
  528. prop="reportTableName">
  529. <template slot-scope="scope">
  530. <span style="color: #409EFF; cursor: pointer;"
  531. @click="handleReportNodeClick(scope.row, 'history')"
  532. :title="scope.row.reportTableName">{{ scope.row.reportTableName }}</span>
  533. </template>
  534. </el-table-column>
  535. <!-- <el-table-column-->
  536. <!-- align="center"-->
  537. <!-- label="报表状态"-->
  538. <!-- prop="isAutoReport"-->
  539. <!-- width="180">-->
  540. <!-- <template slot-scope="scope">-->
  541. <!-- <el-tag v-if="scope.row.userId != uid" type="success" style="margin-right: 5px;">被分享</el-tag>-->
  542. <!-- <el-tag v-if="uid == scope.row.userId && scope.row.userGroupList && scope.row.userGroupList.length > 0"-->
  543. <!-- type="warning" style="margin-right: 5px;">已分享</el-tag>-->
  544. <!-- </template>-->
  545. <!-- </el-table-column>-->
  546. <!-- <el-table-column-->
  547. <!-- align="center"-->
  548. <!-- label="当前版本"-->
  549. <!-- sortable="custom"-->
  550. <!-- prop="version"-->
  551. <!-- width="120">-->
  552. <!-- </el-table-column>-->
  553. <el-table-column
  554. align="center"
  555. label="运行时间"
  556. sortable
  557. prop="createTime"
  558. width="200">
  559. </el-table-column>
  560. <el-table-column label="操作" align="center" width="300">
  561. <template slot-scope="scope">
  562. <el-button type="text"
  563. v-if="uid == scope.row.userId"
  564. size="small"
  565. icon="el-icon-delete"
  566. style="color: red;"
  567. @click="removeReportItem(scope.row, 'record')">删除
  568. </el-button>
  569. </template>
  570. </el-table-column>
  571. </el-table>
  572. <el-pagination
  573. style="margin-top: 20px;"
  574. background
  575. layout="sizes, prev, pager, next, total"
  576. :current-page="reportHistoryPage"
  577. :page-size="reportHistoryLimit"
  578. @size-change="sizeHistoryChangeEvent"
  579. @current-change="currentHistoryChangeEvent"
  580. :total="reportHistoryTotal">
  581. </el-pagination>
  582. </div>
  583. </el-dialog>
  584. <!-- 用户组用户人员查看 -->
  585. <el-dialog
  586. title="授权详情"
  587. width="600px"
  588. top="10vh"
  589. center
  590. v-dialog-drag
  591. v-if="dialogGroupUserVisible"
  592. :before-close="dialogGroupUserClose"
  593. :visible.sync="dialogGroupUserVisible"
  594. :close-on-click-modal="false"
  595. :append-to-body="true">
  596. <div style="height: 60vh;">
  597. <el-table
  598. :data="groupUserData" border :stripe="true"
  599. :header-cell-style="{background: '#E8E8E8'}"
  600. style="width: 100%; height: calc(100% - 50px); overflow: auto;">
  601. <el-table-column
  602. align="center"
  603. label="用户组名称"
  604. prop="userGroupName">
  605. </el-table-column>
  606. <el-table-column
  607. align="center"
  608. label="姓名"
  609. prop="userName">
  610. </el-table-column>
  611. </el-table>
  612. </div>
  613. </el-dialog>
  614. <div id="print-area"
  615. style="display: none;position: absolute;z-index: 0;top: 0;width: 100%;height: 100vh;overflow: hidden;">
  616. <div id="print-html" ref="printPayFeeNew"></div>
  617. </div>
  618. </div>
  619. </template>
  620. <script>
  621. import BreadcrumbView from '@/components/BreadcrumbView'
  622. import {
  623. customCompare,
  624. getLuckysheetConfig,
  625. getNowFormatDate, showAlertMsgWin,
  626. showAlertWin, showConfirmWin,
  627. showLoading, showPromptWin, withDateFormatLength
  628. } from '@/utils/cqcy'
  629. import {
  630. delReportTableById,
  631. getAllDataModel,
  632. getAllOkReportTable,
  633. getAllTableTemplate,
  634. getAutoChReportTable,
  635. getChartData,
  636. getDataModelById,
  637. getReportTableById,
  638. getTableData,
  639. getTableTemplateById,
  640. getUserByGroupId, runAutoTableById,
  641. saveReport, setAutoTableTime,
  642. tableAssignUserById,
  643. tableExchangeTypeById,
  644. updateReportTable,
  645. updateTableNameById,
  646. getPrintByReportId,
  647. addPrint,
  648. stopAutoPrintById
  649. } from '@/api/datasource'
  650. import Print from 'print-js'
  651. import {getUsername} from '@/utils/auth'
  652. import {exportExcel} from '@/utils/export'
  653. import {getAllUserGroup} from "@/api/user";
  654. import {mapGetters} from "vuex";
  655. import {insertLuckysheetEChart} from "@/utils/luckysheettool";
  656. import cqcyCode from "@/utils/cqcyCode";
  657. export default {
  658. name: "index",
  659. components: {
  660. BreadcrumbView
  661. },
  662. computed: {
  663. ...mapGetters([
  664. 'name',
  665. 'uid'
  666. ])
  667. },
  668. data() {
  669. return {
  670. breadcrumbList: ['运行配置'],
  671. groupProps: {
  672. isLeaf: 'leaf'
  673. },
  674. reportDialogTitle: '新增报表',
  675. showMainView: false,
  676. chooseMyReport: null,
  677. chooseCurrMyReport: null,
  678. dialogReportTemplateVisible: false,
  679. dialogDownloadReportTypeVisible: false,
  680. dialogAutoReportVisible: false,
  681. dialogReportTypeVisible: false,
  682. dialogUserGroupVisible: false,
  683. dialogHistoryReportVisible: false,
  684. dialogGroupUserVisible: false,
  685. dialogAutoPrintVisible: false,
  686. reportType: '0',
  687. downloadType: '1',
  688. btnType: '',
  689. hasUserGroup: false,
  690. userGroupInfo: null,
  691. userGroupList: [],
  692. radioByCron: null,
  693. radioByCronValS: '',
  694. radioByCronValM: '',
  695. radioByCronValH: '',
  696. radioByCronValD: null,
  697. radioByCronValMo: '',
  698. radioByCronValMoD: null,
  699. cronVal: '',
  700. cronList: [],
  701. reportId: null,
  702. reportTemplateList: [],
  703. dataModelList: [],
  704. chooseReportTemplate: null,
  705. chooseReportTemplateId: null,
  706. chooseIsAutoReport: null,
  707. delFlag: 0,
  708. dateByRange: null,
  709. reportForm: {
  710. id: null,
  711. reportTableName: '',
  712. reportTableType: null,
  713. tableTemplateId: null,
  714. reportTableData: '',
  715. cronLabel: '',
  716. startTime: '',
  717. cron: ''
  718. },
  719. printDialogTitle: '打印任务配置',
  720. printForm: {
  721. id: null,
  722. reportTableId: null,
  723. cronId: '',
  724. cron: '',
  725. runState: null
  726. },
  727. searchValue: null,
  728. searchTxt: '',
  729. searchHistoryTxt: '',
  730. sessionName: 'device_report_index',
  731. reportOptions: [{
  732. label: '所有报表',
  733. value: -1
  734. }, {
  735. label: '手动报表',
  736. value: 0
  737. }, {
  738. label: '自动报表',
  739. value: 1
  740. }, {
  741. label: '事件驱动报表',
  742. value: 2
  743. }, {
  744. label: '设备报表',
  745. value: 5
  746. }],
  747. groupUserData: [],
  748. reportHistoryData: [],
  749. reportHistoryTotal: 0,
  750. reportHistoryPage: 1,
  751. reportHistoryLimit: 10,
  752. reportTotal: 0,
  753. reportPage: 1,
  754. reportLimit: 10,
  755. reportDataList: [],
  756. reportIntervalOptions: [5, 10, 15, 20, 25, 30],
  757. reportInterval: 30, // 手动报表更新数据频率
  758. reportIntervalTag: null,
  759. showReportTableType: null,
  760. reportRules: {
  761. reportTableName: [
  762. {required: true, message: '请输入报表名称', trigger: 'blur'}
  763. ],
  764. reportTableType: [
  765. {required: true, message: '请选择报表类型', trigger: 'change'}
  766. ],
  767. tableTemplateId: [
  768. {required: true, message: '请选择报表模板', trigger: 'change'}
  769. ]
  770. },
  771. luckysheetOption: {
  772. container: 'luckysheet', // 设定 DOM 容器的 id
  773. title: '报表模板', // 设定表格名称
  774. lang: 'zh', // 设定表格语言
  775. showinfobar: false, // 是否显示顶部信息栏
  776. showtoolbar: false, // 是否显示工具栏
  777. showtoolbarConfig: {
  778. paintFormat: true, //格式刷
  779. moreFormats: true, // 单元格格式
  780. font: true, // 字体
  781. fontSize: true, // 字号大小
  782. bold: true, // 粗体 (Ctrl+B)
  783. italic: true, // 斜体 (Ctrl+I)
  784. strikethrough: true, // 删除线 (Alt+Shift+5)
  785. underline: true, // 下划线 (Alt+Shift+6)
  786. textColor: true, // 文本颜色
  787. fillColor: true, // 单元格颜色
  788. border: true, // 边框
  789. mergeCell: true, // 合并单元格
  790. horizontalAlignMode: true, // 水平对齐方式
  791. verticalAlignMode: true, // 垂直对齐方式
  792. function: true, // 公式
  793. // image: true
  794. // chart: true
  795. },
  796. showsheetbar: false, // 是否显示底部 sheet 页按钮
  797. sheetFormulaBar: false, // 是否显示公式
  798. row: 120, // 是否显示底部 sheet 页按钮
  799. data: [{
  800. "name": "统计报表", //工作表名称
  801. }],
  802. cellRightClickConfig: { // 自定义配置单元格右击菜单
  803. copy: true, // 复制
  804. copyAs: false, // 复制为
  805. paste: true, // 粘贴
  806. insertRow: true, // 插入行
  807. insertColumn: true, // 插入列
  808. deleteRow: true, // 删除选中行
  809. deleteColumn: true, // 删除选中列
  810. deleteCell: false, // 删除单元格
  811. hideRow: false, // 隐藏选中行和显示选中行
  812. hideColumn: false, // 隐藏选中列和显示选中列
  813. rowHeight: true, // 行高
  814. columnWidth: true, // 列宽
  815. clear: false, // 清除内容
  816. matrix: false, // 矩阵操作选区
  817. sort: false, // 排序选区
  818. filter: false, // 筛选选区
  819. chart: true, // 图表生成
  820. image: false, // 插入图片
  821. link: false, // 插入链接
  822. data: false, // 数据验证
  823. cellFormat: false // 设置单元格格式
  824. },
  825. plugins: ['chart']
  826. }
  827. }
  828. },
  829. watch: {},
  830. beforeDestroy() {
  831. this.chooseMyReport = null
  832. this.chooseCurrMyReport = null
  833. },
  834. mounted() {
  835. let _this = this
  836. document.onkeyup = function (event) {
  837. let e = event || window.event || arguments.callee.caller.arguments[0]
  838. if (!e) return
  839. const {key, keyCode} = e
  840. if (keyCode === 46 || keyCode === 8) {
  841. _this.forceRefreshLuckysheet()
  842. }
  843. }
  844. },
  845. created() {
  846. luckysheet.destroy()
  847. this.loadReport()
  848. this.initCronList()
  849. },
  850. destroyed() {
  851. if (this.reportIntervalTag) {
  852. clearInterval(this.reportIntervalTag)
  853. sessionStorage.removeItem(this.sessionName)
  854. }
  855. luckysheet.destroy()
  856. },
  857. methods: {
  858. reportIntervalChange(val) {
  859. this.reportInterval = val
  860. this.pollingReportData()
  861. },
  862. /** 实现类似刷新效果 */
  863. forceRefreshLuckysheet() {
  864. if (luckysheet) {
  865. luckysheet.setCellValue(49, 0, luckysheet.getCellValue(49, 0))
  866. }
  867. },
  868. sortChange({prop, order}) {
  869. this.reportDataList.sort(customCompare(prop, order))
  870. },
  871. sortChange1({prop, order}) {
  872. this.reportHistoryData.sort(customCompare(prop, order))
  873. },
  874. handleSizeChange(val) {
  875. this.reportPage = 1
  876. this.reportLimit = val
  877. this.loadReport()
  878. },
  879. handleCurrentChange(val) {
  880. this.reportPage = val
  881. this.loadReport()
  882. },
  883. sizeHistoryChangeEvent(val) {
  884. this.reportHistoryPage = 1
  885. this.reportHistoryLimit = val
  886. this.historyReport()
  887. },
  888. currentHistoryChangeEvent(val) {
  889. this.reportHistoryPage = val
  890. this.historyReport()
  891. },
  892. searchHistoryReportEvent() {
  893. this.reportHistoryPage = 1
  894. this.historyReport()
  895. },
  896. changeReportTypeEvent(val) {
  897. this.reportPage = 1
  898. this.searchValue = val
  899. this.loadReport()
  900. },
  901. searchReportEvent() {
  902. this.reportPage = 1
  903. this.loadReport()
  904. },
  905. /** 验证CRON是否正确 */
  906. validCron(value) {
  907. const cronParse = require('cron-parser')
  908. try {
  909. const interval = cronParse.parseExpression(value)
  910. console.log('cronDate:', interval.next().toDate())
  911. return true
  912. } catch (e) {
  913. }
  914. return false
  915. },
  916. /** 解析数据运行表达式 */
  917. analysisCron(val) {
  918. if (!val) return
  919. let s = val.split(' ')
  920. if (s[0].indexOf('/') > -1) {
  921. this.radioByCron = 1
  922. this.radioByCronValS = parseInt(s[0].split('/')[1])
  923. } else if (s[1].indexOf('/') > -1) {
  924. this.radioByCron = 2
  925. this.radioByCronValM = parseInt(s[1].split('/')[1])
  926. } else if (s[2].indexOf('/') > -1) {
  927. this.radioByCron = 3
  928. this.radioByCronValH = parseInt(s[2].split('/')[1])
  929. } else if (s[3] === '*') {
  930. this.radioByCron = 4
  931. this.radioByCronValD = s[2] + ':' + s[1] + ':' + s[0]
  932. } else {
  933. this.radioByCron = 5
  934. this.radioByCronValMo = parseInt(s[3])
  935. this.radioByCronValMoD = s[2] + ':' + s[1] + ':' + s[0]
  936. }
  937. },
  938. /** 获取自动报表运行表达式 */
  939. getCron() {
  940. let result = null
  941. switch (this.radioByCron) {
  942. // 按每秒执行:0/2 * * * * ?
  943. case 1:
  944. if (Number.isInteger(this.radioByCronValS)) {
  945. result = '0/#{cron} * * * * ?'
  946. result = result.replace('#{cron}', this.radioByCronValS)
  947. }
  948. break
  949. // 按每分钟执行:0 0/2 * * * ?
  950. case 2:
  951. if (Number.isInteger(this.radioByCronValM)) {
  952. result = '0 0/#{cron} * * * ?'
  953. result = result.replace('#{cron}', this.radioByCronValM)
  954. }
  955. break
  956. // 按每小时执行:0 0 0/2 * * ?
  957. case 3:
  958. if (Number.isInteger(this.radioByCronValH)) {
  959. result = '0 0 0/#{cron} * * ?'
  960. result = result.replace('#{cron}', this.radioByCronValH)
  961. }
  962. break
  963. // 每天定时执行:0 15 10 * * ?
  964. case 4:
  965. if (this.radioByCronValD) {
  966. let times = this.radioByCronValD.split(':')
  967. result = '#{cron1} #{cron2} #{cron3} * * ?'
  968. result = result.replace('#{cron1}', times[2])
  969. result = result.replace('#{cron2}', times[1])
  970. result = result.replace('#{cron3}', times[0])
  971. result = result.replace(/00/g, '0')
  972. }
  973. break
  974. // 每月定时执行:0 0 2 1 * ?
  975. case 5:
  976. if (Number.isInteger(this.radioByCronValMo) && this.radioByCronValMoD) {
  977. let times = this.radioByCronValMoD.split(':')
  978. result = '#{cron1} #{cron2} #{cron3} #{cron4} * ?'
  979. result = result.replace('#{cron1}', times[2])
  980. result = result.replace('#{cron2}', times[1])
  981. result = result.replace('#{cron3}', times[0])
  982. result = result.replace('#{cron4}', this.radioByCronValMo)
  983. result = result.replace(/00/g, '0')
  984. }
  985. break
  986. default:
  987. break
  988. }
  989. return result
  990. },
  991. /** 获取自动报表运行表达式名称 */
  992. getCronLabel() {
  993. let result = null
  994. switch (this.radioByCron) {
  995. // 按每秒执行:0/2 * * * * ?
  996. case 1:
  997. if (Number.isInteger(this.radioByCronValS)) {
  998. result = '每#{cron}秒执行一次'
  999. result = result.replace('#{cron}', this.radioByCronValS)
  1000. }
  1001. break
  1002. // 按每分钟执行:0 0/2 * * * ?
  1003. case 2:
  1004. if (Number.isInteger(this.radioByCronValM)) {
  1005. result = '每#{cron}分钟执行一次'
  1006. result = result.replace('#{cron}', this.radioByCronValM)
  1007. }
  1008. break
  1009. // 按每小时执行:0 0 0/2 * * ?
  1010. case 3:
  1011. if (Number.isInteger(this.radioByCronValH)) {
  1012. result = '每#{cron}小时执行一次'
  1013. result = result.replace('#{cron}', this.radioByCronValH)
  1014. }
  1015. break
  1016. // 每天定时执行:0 15 10 * * ?
  1017. case 4:
  1018. if (this.radioByCronValD) {
  1019. let times = this.radioByCronValD.split(':')
  1020. result = '每天#{cron3}:#{cron2}:#{cron1}执行一次'
  1021. result = result.replace('#{cron1}',
  1022. (times[2].length < 2 && parseInt(times[2]) < 10) ? ('0' + times[2]) : times[2])
  1023. result = result.replace('#{cron2}',
  1024. (times[1].length < 2 && parseInt(times[1]) < 10) ? ('0' + times[1]) : times[1])
  1025. result = result.replace('#{cron3}',
  1026. (times[0].length < 2 && parseInt(times[0]) < 10) ? ('0' + times[0]) : times[0])
  1027. // result = result.replace(/00/g, '0')
  1028. }
  1029. break
  1030. // 每月定时执行:0 0 2 1 * ?
  1031. case 5:
  1032. if (Number.isInteger(this.radioByCronValMo) && this.radioByCronValMoD) {
  1033. let times = this.radioByCronValMoD.split(':')
  1034. result = '每月#{cron4}号的#{cron3}:#{cron2}:#{cron1}执行一次'
  1035. result = result.replace('#{cron1}',
  1036. (times[2].length < 2 && parseInt(times[2]) < 10) ? ('0' + times[2]) : times[2])
  1037. result = result.replace('#{cron2}',
  1038. (times[1].length < 2 && parseInt(times[1]) < 10) ? ('0' + times[1]) : times[1])
  1039. result = result.replace('#{cron3}',
  1040. (times[0].length < 2 && parseInt(times[0]) < 10) ? ('0' + times[0]) : times[0])
  1041. result = result.replace('#{cron4}', this.radioByCronValMo)
  1042. // result = result.replace(/00/g, '0')
  1043. }
  1044. break
  1045. default:
  1046. break
  1047. }
  1048. return result
  1049. },
  1050. /** 选择定时任务表达式 */
  1051. chooseCronEvent() {
  1052. if (!this.getCron()) {
  1053. showAlertMsgWin(this, null, '请指定定时任务类型或运行时间!')
  1054. return
  1055. }
  1056. this.reportForm.cron = this.getCron()
  1057. this.reportForm.cronLabel = this.getCronLabel()
  1058. if (!this.validCron(this.reportForm.cron)) {
  1059. showAlertMsgWin(this, null, '定时任务表达式格式不正确!')
  1060. return
  1061. }
  1062. this.dialogAutoReportVisible = false
  1063. },
  1064. resetRadioVal() {
  1065. this.radioByCron = null
  1066. this.radioByCronValS = ''
  1067. this.radioByCronValM = ''
  1068. this.radioByCronValH = ''
  1069. this.radioByCronValD = null
  1070. this.radioByCronValMo = ''
  1071. this.radioByCronValMoD = null
  1072. this.cronVal = ''
  1073. },
  1074. chooseReportTypeEvent() {
  1075. if (!this.reportType) {
  1076. showAlertMsgWin(this, null, '请选择报表类型!')
  1077. return
  1078. }
  1079. // 自动报表
  1080. if (this.reportType == '1') {
  1081. this.resetRadioVal()
  1082. getReportTableById(this.reportId).then(res => {
  1083. this.dialogAutoReportVisible = true
  1084. this.cronVal = res.data.cron
  1085. this.analysisCron(this.cronVal)
  1086. }).catch((e) => {
  1087. showAlertWin(this, null, e)
  1088. })
  1089. return
  1090. }
  1091. const loading = showLoading(this, '请稍候···')
  1092. let params = {
  1093. 'id': this.reportId,
  1094. 'isAutoReport': this.reportType
  1095. }
  1096. tableExchangeTypeById(params).then(res => {
  1097. loading.close()
  1098. this.dialogClose()
  1099. this.loadReport()
  1100. }).catch((e) => {
  1101. loading.close()
  1102. showAlertWin(this, null, e)
  1103. })
  1104. },
  1105. switchChangeEvent(val, data) {
  1106. this.reportId = data.id
  1107. if (val) {
  1108. this.resetRadioVal()
  1109. this.dialogAutoReportVisible = true
  1110. getReportTableById(data.id).then(res => {
  1111. this.cronVal = res.data.cron
  1112. this.analysisCron(this.cronVal)
  1113. }).catch((e) => {
  1114. showAlertWin(this, null, e)
  1115. })
  1116. return
  1117. }
  1118. this.dialogReportTypeVisible = true
  1119. },
  1120. /** 修改自动报表运行状态 */
  1121. setReportStatus(data) {
  1122. let status = data.runState == 0 ? '启动' : '停止'
  1123. let tips = '您确定要' + status + '该报表吗?'
  1124. showConfirmWin(this, null, tips, () => {
  1125. const loading = showLoading(this, status + '中,请稍候···')
  1126. let params = {
  1127. 'id': data.id,
  1128. 'runState': data.runState == 0 ? 1 : 0
  1129. }
  1130. runAutoTableById(params).then(res => {
  1131. loading.close()
  1132. let msg = res.data ? status + '成功!' : status + '失败!'
  1133. showAlertMsgWin(this, null, msg)
  1134. this.reportPage = 1
  1135. this.loadReport()
  1136. }).catch((e) => {
  1137. loading.close()
  1138. showAlertWin(this, null, e)
  1139. })
  1140. })
  1141. },
  1142. /** 初始化报表信息 */
  1143. resetReportFormVal() {
  1144. this.reportForm = {
  1145. id: null,
  1146. reportTableName: '',
  1147. reportTableType: null,
  1148. tableTemplateId: null,
  1149. reportTableData: '',
  1150. cronLabel: '',
  1151. startTime: '',
  1152. cron: ''
  1153. }
  1154. this.dateByRange = null
  1155. },
  1156. /** 报表类型更改事件 */
  1157. changeReportType() {
  1158. this.reportForm.tableTemplateId = null
  1159. this.getAllReportTemplate(this.reportForm.reportTableType)
  1160. },
  1161. /** 新增报表 */
  1162. addReportEvent() {
  1163. this.resetReportFormVal()
  1164. this.reportDialogTitle = '新增报表'
  1165. this.dialogReportTemplateVisible = true
  1166. },
  1167. /** 刷新报表 */
  1168. refreshReportEvent() {
  1169. this.reportPage = 1
  1170. this.loadReport()
  1171. },
  1172. /** 设置自动报表运行时间 */
  1173. settingAutoReportTime() {
  1174. if (this.reportForm.cron) {
  1175. this.analysisCron(this.reportForm.cron)
  1176. } else {
  1177. this.resetRadioVal()
  1178. }
  1179. this.dialogAutoReportVisible = true
  1180. },
  1181. /** 模版报表选择 */
  1182. chooseReportEvent() {
  1183. // 判断是否自动报表
  1184. // if (this.reportForm.reportTableType == 1 && this.dateByRange.length == 0) {
  1185. // showAlertMsgWin(this, null, '请选择时间范围!')
  1186. // return
  1187. // }
  1188. if (this.reportForm.reportTableType == 1 && !this.reportForm.startTime) {
  1189. showAlertMsgWin(this, null, '请选择开始时间!')
  1190. return
  1191. }
  1192. if (this.reportForm.reportTableType == 1 && !this.reportForm.cron) {
  1193. showAlertMsgWin(this, null, '请设置自动报表运行时间!')
  1194. return
  1195. }
  1196. this.$refs['reportForm'].validate((valid) => {
  1197. if (valid) {
  1198. const loading = showLoading(this, '数据加载中,请稍候···')
  1199. getTableTemplateById(this.reportForm.tableTemplateId).then(res => {
  1200. if (!res.data) {
  1201. loading.close()
  1202. showAlertMsgWin(this, null, '选择的报表模板不存在!')
  1203. return
  1204. }
  1205. let luckyData = JSON.parse(res.data.templateData)
  1206. if (this.reportForm.id) {
  1207. this.updateReportInfo(loading, luckyData)
  1208. } else {
  1209. this.saveReportInfo(loading, luckyData)
  1210. }
  1211. }).catch((e) => {
  1212. loading.close()
  1213. showAlertWin(this, null, e)
  1214. })
  1215. }
  1216. })
  1217. },
  1218. /** 根据 ID 查询数据模型 */
  1219. getDataModelById(loading, reportData) {
  1220. if (!loading) {
  1221. loading = showLoading(this, '数据加载中,请稍候···')
  1222. }
  1223. getDataModelById(this.reportForm.operationRule).then(res => {
  1224. loading.close()
  1225. if (!res.data) {
  1226. showAlertMsgWin(this, null, '选择的四则运算表达式不存在!')
  1227. return
  1228. }
  1229. let luckyData = JSON.parse(reportData.templateData)
  1230. this.drawLuckyExcel(luckyData)
  1231. this.btnType = 'add'
  1232. this.dialogReportTemplateVisible = false
  1233. }).catch((e) => {
  1234. loading.close()
  1235. showAlertWin(this, null, e)
  1236. })
  1237. },
  1238. /** 绘制 Excel 表 */
  1239. drawLuckyExcel(luckyData, callback) {
  1240. let _this = this
  1241. luckysheet.destroy()
  1242. let option = luckyData.option
  1243. option.data = luckyData.data
  1244. let charts = luckyData.charts
  1245. let tables = luckyData.tables
  1246. option.hook = {
  1247. workbookCreateAfter() {
  1248. console.log(luckyData)
  1249. for (let i in charts) {
  1250. _this.insertEChartInfo(charts[i])
  1251. }
  1252. for (let i in tables) {
  1253. _this.insertTableInfo(tables[i])
  1254. }
  1255. _this.drawBaseInfo()
  1256. if (callback) {
  1257. callback()
  1258. }
  1259. },
  1260. cellUpdated(r, c, newV, oldV) {
  1261. if (!(r === 49 && c === 0)) {
  1262. _this.forceRefreshLuckysheet()
  1263. }
  1264. }
  1265. }
  1266. luckysheet.create(option)
  1267. },
  1268. /** 获取图表数据 */
  1269. getChartData(data, callback) {
  1270. getChartData(data).then(res => {
  1271. if (!res.data) {
  1272. if (callback) callback([])
  1273. return
  1274. }
  1275. if (callback) callback(res.data)
  1276. }).catch((e) => {
  1277. if (callback) callback([])
  1278. showAlertWin(this, null, e)
  1279. })
  1280. },
  1281. /** 获取表格数据 */
  1282. getTableData(data, callback) {
  1283. getTableData(data).then(res => {
  1284. if (!res.data) {
  1285. if (callback) callback([])
  1286. return
  1287. }
  1288. if (callback) callback(res.data)
  1289. }).catch((e) => {
  1290. if (callback) callback([])
  1291. showAlertWin(this, null, e)
  1292. })
  1293. },
  1294. /** 向 Excel 插入表格 */
  1295. insertTableInfo(tableData) {
  1296. let params = []
  1297. let itemList = tableData.item
  1298. for (let i in itemList) {
  1299. let temp = itemList[i]
  1300. params.push({
  1301. 'itemGroupId': temp.itemGroupId,
  1302. 'itemName': temp.itemName
  1303. })
  1304. }
  1305. let p = {
  1306. 'reportValueFormat': this.reportForm.reportValueFormat,
  1307. 'valueCondition': this.reportForm.valueCondition,
  1308. 'tableDataDtoChList': params,
  1309. 'showType': tableData.showType
  1310. }
  1311. if (this.reportForm.reportDate && this.reportForm.reportDate.length > 0) {
  1312. p.startBelongTime = this.reportForm.reportDate[0]
  1313. p.endBelongTime = this.reportForm.reportDate[1]
  1314. } else {
  1315. p.startBelongTime = getNowFormatDate('yyyy-MM-dd') + ' 08:00:00'
  1316. p.endBelongTime = getNowFormatDate('yyyy-MM-dd') + ' 18:00:00'
  1317. }
  1318. this.getTableData(p, (res) => {
  1319. // console.log('option==>', luckysheet.getAllSheets()[0])
  1320. // console.log('table1==>', res)
  1321. // const optionData = packtable(res, luckysheet.getAllSheets()[0])
  1322. // console.log('table2==>', optionData)
  1323. setTimeout(() => {
  1324. // this.drawTableData(res, p.showType, luckysheet.getAllSheets()[0])
  1325. }, 500)
  1326. })
  1327. },
  1328. /** 初始化表格基础数据项值 */
  1329. initBaseInfoData(data) {
  1330. let currDate = getNowFormatDate('yyyy-MM-dd')
  1331. let currDateTime = getNowFormatDate('yyyy-MM-dd HH:mm:ss')
  1332. data.baseItem = {
  1333. 'currDate': currDate,
  1334. 'currDateTime': currDateTime,
  1335. 'userName': getUsername(),
  1336. 'winUserName': process.env.VUE_APP_WINNAME
  1337. }
  1338. return data
  1339. },
  1340. /** 绘制基础数据项布局信息 */
  1341. drawBaseInfo(baseData) {
  1342. if (!baseData) {
  1343. baseData = {
  1344. 'currDate': getNowFormatDate('yyyy-MM-dd'),
  1345. 'currDateTime': getNowFormatDate('yyyy-MM-dd HH:mm:ss'),
  1346. 'userName': getUsername(),
  1347. 'winUserName': process.env.VUE_APP_WINNAME
  1348. }
  1349. }
  1350. let option = luckysheet.getAllSheets()[0]
  1351. option.celldata.map(item => {
  1352. if (item.v.v) {
  1353. item.v.v = String(item.v.v).trim()
  1354. if (item.v.v.match(/\${([^}]+)}/g)) { // 替换${xxx}内部数据
  1355. if (item.v.v.indexOf('${currDate}') > -1) {
  1356. let val = item.v.v
  1357. val = val.replace('${currDate}', baseData.currDate)
  1358. luckysheet.setCellValue(item.r, item.c, val)
  1359. }
  1360. if (item.v.v.indexOf('${currDateTime}') > -1) {
  1361. let val = item.v.v
  1362. val = val.replace('${currDateTime}', baseData.currDateTime)
  1363. luckysheet.setCellValue(item.r, item.c, val)
  1364. }
  1365. if (item.v.v.indexOf('${userName}') > -1) {
  1366. let val = item.v.v
  1367. val = val.replace('${userName}', baseData.userName)
  1368. luckysheet.setCellValue(item.r, item.c, val)
  1369. }
  1370. if (item.v.v.indexOf('${winUserName}') > -1) {
  1371. let val = item.v.v
  1372. val = val.replace('${winUserName}', baseData.winUserName)
  1373. luckysheet.setCellValue(item.r, item.c, val)
  1374. }
  1375. }
  1376. }
  1377. })
  1378. },
  1379. /** 删除不合理数据值 */
  1380. updateLocalExcelContent() {
  1381. let option = luckysheet.getAllSheets()[0]
  1382. option.celldata.map(item => {
  1383. if (item.v.v) {
  1384. item.v.v = String(item.v.v).trim()
  1385. // 替换${xxx}内部数据
  1386. if (item.v.v.match(/\${([^}]+)}/g)) {
  1387. luckysheet.setCellValue(item.r, item.c, '')
  1388. }
  1389. }
  1390. })
  1391. },
  1392. /** 绘制表格数据 */
  1393. drawTableData(tableItemList, type, tableInfo) {
  1394. if (!tableItemList || tableItemList.length == 0) {
  1395. this.updateLocalExcelContent()
  1396. return
  1397. }
  1398. // 事件驱动报表
  1399. if (type == 2 || type == 4) {
  1400. tableItemList.forEach((tableItem, i) => {
  1401. if (i == 0) {
  1402. let valueTimeList = tableItem.valueTimeList ? tableItem.valueTimeList.split(',') : []
  1403. valueTimeList = withDateFormatLength(valueTimeList)
  1404. let xAxis = tableItem.xaxis
  1405. let yAxis = tableItem.yaxis - 1
  1406. if (valueTimeList.length == 0) {
  1407. luckysheet.setCellValue(xAxis, yAxis, '')
  1408. } else {
  1409. valueTimeList.forEach((v, j) => {
  1410. luckysheet.setCellValue(xAxis + j, yAxis, v)
  1411. })
  1412. }
  1413. }
  1414. let valueList = tableItem.valueList ? tableItem.valueList.split(',') : []
  1415. let xAxis = tableItem.xaxis
  1416. let yAxis = tableItem.yaxis
  1417. if (valueList.length == 0) {
  1418. luckysheet.setCellValue(xAxis, yAxis, '')
  1419. } else {
  1420. valueList.forEach((v, j) => {
  1421. luckysheet.setCellValue(xAxis + j, yAxis, v)
  1422. })
  1423. }
  1424. })
  1425. this.updateLocalExcelContent()
  1426. return
  1427. }
  1428. // 设备报表
  1429. if (type == 5 || type == 6) {
  1430. tableItemList.forEach((tableItem, i) => {
  1431. let standby = tableItem.standby ? JSON.parse(tableItem.standby) : {}
  1432. let dataIndex = standby.index != null ? standby.index : -1
  1433. let valueList = tableItem.valueList ? tableItem.valueList.split(',') : []
  1434. let xAxis = tableItem.xaxis
  1435. let yAxis = tableItem.yaxis
  1436. // 序号、时间处理
  1437. if (tableItem.timeItemType == 0) { // 序号、开始时间
  1438. let valueIndexList = tableItem.valueIndexList ? tableItem.valueIndexList.split(',') : []
  1439. this.deviceReportUpdateData('${index}', valueIndexList, false)
  1440. let valueTimeList = tableItem.valueTimeList ? tableItem.valueTimeList.split(',') : []
  1441. valueTimeList = withDateFormatLength(valueTimeList)
  1442. this.deviceReportUpdateData('${startTime}', valueTimeList, false)
  1443. }
  1444. if (tableItem.timeItemType == 1) { // 结束时间
  1445. let valueTimeList = tableItem.valueTimeList ? tableItem.valueTimeList.split(',') : []
  1446. valueTimeList = withDateFormatLength(valueTimeList)
  1447. this.deviceReportUpdateData('${stopTime}', valueTimeList, tableInfo.isGenCountTime == 1)
  1448. }
  1449. if (valueList.length == 0) {
  1450. luckysheet.setCellValue(xAxis, yAxis, '')
  1451. } else {
  1452. valueList.forEach((v, j) => {
  1453. luckysheet.setCellValue(xAxis + j, yAxis, v)
  1454. })
  1455. }
  1456. })
  1457. this.updateLocalExcelContent()
  1458. return
  1459. }
  1460. // 其余报表信息
  1461. tableItemList.forEach((tableItem, i) => {
  1462. // let standby = tableItem.standby ? JSON.parse(tableItem.standby) : {}
  1463. // let dataIndex = standby.index != null ? standby.index : -1
  1464. let valueList = tableItem.valueList ? tableItem.valueList.split(',') : []
  1465. // let val = (dataIndex == -1 || (dataIndex + 1) > valueList.length)
  1466. // ? cqcyCode['invalidData'] : valueList[dataIndex]
  1467. let xAxis = tableItem.xaxis
  1468. let yAxis = tableItem.yaxis
  1469. if (valueList.length == 0) {
  1470. luckysheet.setCellValue(xAxis, yAxis, '')
  1471. } else {
  1472. valueList.forEach((v, j) => {
  1473. luckysheet.setCellValue(xAxis + j, yAxis, v)
  1474. })
  1475. }
  1476. })
  1477. this.updateLocalExcelContent()
  1478. },
  1479. /** 设备报表时间特殊处理 */
  1480. deviceReportUpdateData(field, dataList, hasCalc) {
  1481. let indexPos = sessionStorage.getItem(this.sessionName)
  1482. if (indexPos) {
  1483. let pos = indexPos.split(',')
  1484. if (field == '${index}') {
  1485. let yAxis = parseInt(pos[0])
  1486. let xAxis = parseInt(pos[1])
  1487. dataList.forEach((v, j) => {
  1488. luckysheet.setCellValue(yAxis + j, xAxis, j + 1)
  1489. })
  1490. } else if (field == '${startTime}') {
  1491. let yAxis = parseInt(pos[0])
  1492. let xAxis = parseInt(pos[1]) + 1
  1493. dataList.forEach((v, j) => {
  1494. luckysheet.setCellValue(yAxis + j, xAxis, v)
  1495. })
  1496. } else if (field == '${stopTime}') {
  1497. let yAxis = parseInt(pos[0])
  1498. let xAxis = parseInt(pos[1]) + 2
  1499. dataList.forEach((v, j) => {
  1500. luckysheet.setCellValue(yAxis + j, xAxis, v)
  1501. if (hasCalc) {
  1502. let startDate = luckysheet.getCellValue(yAxis + j, xAxis - 1)
  1503. let minutes = this.calculateMinutes(startDate, v)
  1504. luckysheet.setCellValue(yAxis + j, xAxis + 1, minutes)
  1505. }
  1506. })
  1507. }
  1508. return
  1509. }
  1510. let option = luckysheet.getAllSheets()[0]
  1511. option.celldata.map(item => {
  1512. if (item.v.v) {
  1513. item.v.v = String(item.v.v).trim()
  1514. // 替换${xxx}内部数据
  1515. if (item.v.v.match(/\${([^}]+)}/g)) {
  1516. if (item.v.v.indexOf(field) > -1) {
  1517. let yAxis = item.r
  1518. let xAxis = item.c
  1519. if (field == '${index}') {
  1520. sessionStorage.setItem(this.sessionName, yAxis + ',' + xAxis)
  1521. dataList.forEach((v, j) => {
  1522. luckysheet.setCellValue(yAxis + j, xAxis, j + 1)
  1523. })
  1524. } else {
  1525. dataList.forEach((v, j) => {
  1526. luckysheet.setCellValue(yAxis + j, xAxis, v)
  1527. if (hasCalc) {
  1528. let startDate = luckysheet.getCellValue(yAxis + j, xAxis - 1)
  1529. let minutes = this.calculateMinutes(startDate, v)
  1530. luckysheet.setCellValue(yAxis + j, xAxis + 1, minutes)
  1531. }
  1532. })
  1533. }
  1534. }
  1535. }
  1536. }
  1537. })
  1538. },
  1539. /** 计算分钟数 */
  1540. calculateMinutes(time1, time2) {
  1541. // 将时间字符串转换为Date对象
  1542. let date1 = new Date(time1);
  1543. let date2 = new Date(time2);
  1544. // 计算时间差(以毫秒为单位)
  1545. let diffInMilliseconds = Math.abs(date2.getTime() - date1.getTime());
  1546. // 将时间差转换为分钟
  1547. let minutes = Math.floor(diffInMilliseconds / 1000 / 60);
  1548. return minutes;
  1549. },
  1550. /** 向 Excel 插入图表 */
  1551. insertEChartInfo(chart) {
  1552. let _self = this
  1553. let info = JSON.parse(chart.standby)
  1554. let reportChartItemList = chart.reportChartItemList
  1555. let chartType = chart.chartType
  1556. // 系列
  1557. let series = info.option.series
  1558. for (let i in series) {
  1559. let temp = series[i]
  1560. temp.data = []
  1561. for (let j in reportChartItemList) {
  1562. let _name = reportChartItemList[j].describe ? reportChartItemList[j].describe : reportChartItemList[j].itemName
  1563. if (chartType == 'pie') {
  1564. info.option.legend = null
  1565. info.option.tooltip = {
  1566. trigger: 'item',
  1567. formatter: '{b0}<br /> <b>{c0}</b>'
  1568. }
  1569. temp.name = _name
  1570. let names = reportChartItemList[i].valueTimeList ? reportChartItemList[i].valueTimeList.split(',') : [];
  1571. names = withDateFormatLength(names)
  1572. let vals = reportChartItemList[i].valueList ? reportChartItemList[i].valueList.split(',') : [];
  1573. names.forEach((name, j) => {
  1574. temp.data.push({
  1575. 'name': name,
  1576. 'value': vals[j]
  1577. })
  1578. })
  1579. } else {
  1580. let _t = []
  1581. let t = reportChartItemList[i].valueList ? reportChartItemList[i].valueList.split(',') : []
  1582. t.forEach((temp) => {
  1583. _t.push(parseFloat(temp))
  1584. })
  1585. temp.data = _t
  1586. }
  1587. }
  1588. }
  1589. if (chartType != 'pie') {
  1590. // x 轴
  1591. let xAxis = info.option.xAxis
  1592. let legend = info.option.legend
  1593. // xAxis.data = []
  1594. legend.data = []
  1595. let axisLabel = {};
  1596. axisLabel.rotate = 20;
  1597. xAxis.axisLabel = axisLabel
  1598. let times = (reportChartItemList[0].valueTimeList) ? reportChartItemList[0].valueTimeList.split(",") : []
  1599. xAxis.data = (reportChartItemList && reportChartItemList.length > 0) ?
  1600. withDateFormatLength(times) : []
  1601. // xAxis.data = xAxis.data.slice(0, 7)
  1602. for (let i in reportChartItemList) {
  1603. let name = reportChartItemList[i].describe ? reportChartItemList[i].describe : reportChartItemList[i].itemName
  1604. // xAxis.data.push(name)
  1605. legend.data.push(name)
  1606. }
  1607. }
  1608. console.log(chartType, info)
  1609. setTimeout(() => {
  1610. const sheet = luckysheet.getLuckysheetfile()[0]
  1611. let optionData = sheet.data
  1612. let elements = document.getElementsByClassName(info.className);
  1613. for (let i = 0; i < elements.length; i++) {
  1614. elements[i].parentNode.removeChild(elements[i]);
  1615. }
  1616. try {
  1617. let flag = true
  1618. insertLuckysheetEChart({
  1619. selector: '#luckysheet',
  1620. info,
  1621. sheet,
  1622. optionData,
  1623. echarts,
  1624. luckysheet,
  1625. $,
  1626. _self,
  1627. flag
  1628. })
  1629. } catch (e) {
  1630. console.log(999, e == 'echarts is not defined')
  1631. console.error(e)
  1632. }
  1633. }, 200)
  1634. },
  1635. /** 查询所有报表模板信息 */
  1636. getAllReportTemplate(templateType) {
  1637. const loading = showLoading(this, '数据加载中,请稍候···')
  1638. let params = {
  1639. 'page': 1,
  1640. 'limit': 1000
  1641. }
  1642. if (templateType != null) {
  1643. params.templateType = templateType
  1644. }
  1645. getAllTableTemplate(params).then(res => {
  1646. loading.close()
  1647. if (!res.data) {
  1648. return
  1649. }
  1650. this.reportTemplateList = res.data.tableTemplateList
  1651. }).catch((e) => {
  1652. loading.close()
  1653. showAlertWin(this, null, e)
  1654. })
  1655. },
  1656. /** 查询所有数据模型 */
  1657. getAllDataModel() {
  1658. let params = {
  1659. 'page': 1,
  1660. 'limit': 1000
  1661. }
  1662. getAllDataModel(params).then(res => {
  1663. if (!res.data) {
  1664. return
  1665. }
  1666. this.dataModelList = res.data.dataModelList
  1667. }).catch((e) => {
  1668. showAlertWin(this, null, e)
  1669. })
  1670. },
  1671. /** 查询我的报表列表 */
  1672. loadReport() {
  1673. const loading = showLoading(this, '加载中,请稍候···')
  1674. let params = {
  1675. 'page': this.reportPage,
  1676. 'limit': this.reportLimit
  1677. }
  1678. if (this.searchValue != '-1') {
  1679. params.isAutoReport = this.searchValue
  1680. }
  1681. if (this.searchTxt && this.searchTxt.trim()) {
  1682. params.reportTableName = this.searchTxt
  1683. }
  1684. params.isDelete = 0
  1685. getAllOkReportTable(params).then(res => {
  1686. loading.close()
  1687. if (!res || !res.data) {
  1688. return
  1689. }
  1690. this.reportTotal = res.data.count
  1691. this.reportDataList = res.data.reportTableList
  1692. }).catch((e) => {
  1693. loading.close()
  1694. showAlertWin(this, null, e)
  1695. })
  1696. },
  1697. /** 设置自动打印 */
  1698. setAutoPrint(data) {
  1699. this.resetPrint();
  1700. const loading = showLoading(this, '设置中,请稍候···')
  1701. this.printForm.reportTableId = data.id;
  1702. getPrintByReportId(data.id).then(res => {
  1703. loading.close()
  1704. if (res.data) {
  1705. this.printForm.id = res.data.id;
  1706. this.printForm.cronId = res.data.cronId;
  1707. this.printForm.cron = res.data.cron;
  1708. this.printForm.runState = res.data.runState;
  1709. this.analysisCron(res.data.cron)
  1710. }
  1711. this.dialogAutoPrintVisible = true
  1712. }).catch((e) => {
  1713. loading.close()
  1714. })
  1715. },
  1716. resetPrint() {
  1717. this.printForm.id = null;
  1718. this.printForm.reportTableId = null;
  1719. this.printForm.cronId = '';
  1720. this.printForm.cron = '';
  1721. this.printForm.runState = null;
  1722. },
  1723. /** 选择定时打印 */
  1724. chooseCronPrint() {
  1725. if (!this.getCron()) {
  1726. showAlertMsgWin(this, null, '请指定定时任务类型或运行时间!')
  1727. return
  1728. }
  1729. this.printForm.cron = this.getCron();
  1730. if (!this.validCron(this.printForm.cron)) {
  1731. showAlertMsgWin(this, null, '定时任务表达式格式不正确!')
  1732. return
  1733. }
  1734. addPrint(this.printForm).then(res => {
  1735. let msg = res.data ? '配置成功!' : '配置失败!'
  1736. showAlertMsgWin(this, null, msg)
  1737. this.showMainView = false
  1738. this.dialogAutoPrintVisible = false;
  1739. }).catch(e => {
  1740. showAlertWin(this, null, e)
  1741. })
  1742. },
  1743. /** 停止打印 */
  1744. stopAutoPrint() {
  1745. console.log(this.printForm.reportTableId)
  1746. stopAutoPrintById(this.printForm.reportTableId).then(res => {
  1747. showAlertWin(this, null, res.data)
  1748. if (res.code == 200) {
  1749. this.dialogAutoPrintVisible = false;
  1750. }
  1751. }).catch(e => {
  1752. showAlertWin(this, null, e)
  1753. })
  1754. },
  1755. /** 设置用户组信息 */
  1756. setUserGroupEvent(data) {
  1757. if (data.userId != this.uid) {
  1758. showAlertMsgWin(this, null, '您没有权限进行设置!')
  1759. return
  1760. }
  1761. this.reportId = data.id
  1762. this.dialogUserGroupVisible = true
  1763. getAllUserGroup().then(res => {
  1764. this.$nextTick(() => {
  1765. this.userGroupList = res.data
  1766. // this.userGroupInfo = data.userGroupList
  1767. this.userGroupInfo = []
  1768. for (let i = 0; i < data.userGroupList.length; i++) {
  1769. this.userGroupInfo.push(data.userGroupList[i].id)
  1770. }
  1771. if (data.userGroupList && data.userGroupList.length > 0) {
  1772. this.hasUserGroup = true
  1773. }
  1774. })
  1775. }).catch((e) => {
  1776. showAlertWin(this, null, e)
  1777. })
  1778. },
  1779. getUserGroupEvent(data) {
  1780. this.groupUserData = []
  1781. if (!data.userGroupList || data.userGroupList.length == 0) {
  1782. showAlertMsgWin(this, null, '该报表还未进行授权操作!')
  1783. return
  1784. }
  1785. let _this = this
  1786. data.userGroupList.forEach((group) => {
  1787. getUserByGroupId(group.id).then(res => {
  1788. let users = res.data
  1789. users.forEach((u) => {
  1790. _this.groupUserData.push({
  1791. 'userGroupName': group.userGroupName,
  1792. 'userName': u.userName
  1793. })
  1794. })
  1795. }).catch((e) => {
  1796. showAlertWin(_this, null, e)
  1797. })
  1798. })
  1799. this.dialogGroupUserVisible = true
  1800. },
  1801. chooseUserGroupEvent() {
  1802. // if (!this.userGroupInfo) {
  1803. // this.$message({
  1804. // message: '请选择用户组!',
  1805. // type: 'warning'
  1806. // })
  1807. // return
  1808. // }
  1809. let params = {
  1810. 'id': this.reportId,
  1811. 'userGroupList': []
  1812. }
  1813. for (let i = 0; i < this.userGroupInfo.length; i++) {
  1814. params.userGroupList.push({
  1815. 'id': this.userGroupInfo[i]
  1816. })
  1817. }
  1818. tableAssignUserById(params).then(res => {
  1819. if (this.hasUserGroup || this.userGroupInfo) {
  1820. showAlertMsgWin(this, null, '保存成功!')
  1821. this.hasUserGroup = false
  1822. }
  1823. this.dialogClose()
  1824. this.loadReport()
  1825. }).catch((e) => {
  1826. showAlertWin(this, null, e)
  1827. })
  1828. },
  1829. /** 处理自动报表数据信息 */
  1830. drawAutoReportData(datas) {
  1831. if (!datas || datas.length == 0) {
  1832. return
  1833. }
  1834. datas.forEach((data) => {
  1835. if (!data || !data.item) {
  1836. return
  1837. }
  1838. let showInfo = data.showType
  1839. let fieldList = data.field
  1840. data.item.forEach((item, i) => {
  1841. if (!item || !item.dataList) {
  1842. return
  1843. }
  1844. let itemName = item.itemName
  1845. itemName = itemName.substring(itemName.lastIndexOf('.') + 1)
  1846. let tempName = '${' + item.itemGroupId + '.' + itemName + '.' + showInfo.dataId + '}'
  1847. let p_r, p_c
  1848. if (fieldList[i] && tempName == fieldList[i].name) {
  1849. p_r = parseInt(fieldList[i].r)
  1850. p_c = parseInt(fieldList[i].c)
  1851. } else {
  1852. for (let n = 0; n < fieldList.length; n++) {
  1853. if (fieldList[n].name == tempName) {
  1854. p_r = parseInt(fieldList[n].r)
  1855. p_c = parseInt(fieldList[n].c)
  1856. break
  1857. }
  1858. }
  1859. }
  1860. // 数据信息
  1861. let dataList = item.dataList
  1862. for (let j = 0; j < showInfo.valLine; j++) {
  1863. let c = p_c
  1864. let r = p_r
  1865. if (showInfo.valType == '2') r += j
  1866. else c += j
  1867. luckysheet.setCellValue(r, c, (dataList[j] != null && dataList[j] != undefined) ? (dataList[j] + '') : cqcyCode['invalidData'])
  1868. }
  1869. })
  1870. })
  1871. },
  1872. /** 报表点击事件 */
  1873. handleReportNodeClick(data, type) {
  1874. if (data.id == -1 || this.delFlag == 1) {
  1875. return
  1876. }
  1877. const loading = showLoading(this, '加载中,请稍候···')
  1878. getReportTableById(data.id).then(res => {
  1879. let _data = res.data
  1880. if (!_data) {
  1881. loading.close()
  1882. showAlertMsgWin(this, null, '选择的报表不存在!')
  1883. return
  1884. }
  1885. this.showMainView = true
  1886. this.breadcrumbList = [_data.reportTableName]
  1887. this.chooseCurrMyReport = _data
  1888. // 判断是否运行记录
  1889. if (type === 'history') {
  1890. this.dialogHistoryReportVisible = false
  1891. this.btnType = 'showChild'
  1892. } else {
  1893. this.chooseMyReport = res.data
  1894. this.btnType = 'showShared'
  1895. }
  1896. this.setLuckysheetStatus(_data, true, type, loading)
  1897. // 手动报表,循环查询数据
  1898. this.showReportTableType = _data.reportTableType
  1899. this.pollingReportData()
  1900. }).catch((e) => {
  1901. loading.close()
  1902. showAlertWin(this, null, e)
  1903. })
  1904. },
  1905. /** 轮询更新报表数据 */
  1906. pollingReportData() {
  1907. if (this.reportIntervalTag) {
  1908. clearInterval(this.reportIntervalTag)
  1909. sessionStorage.removeItem(this.sessionName)
  1910. }
  1911. if (this.showReportTableType == 0 || this.showReportTableType == 1 || this.showReportTableType == 5) {
  1912. this.reportIntervalTag = setInterval(() => {
  1913. this.reloadReportNode()
  1914. }, this.reportInterval * 1000)
  1915. }
  1916. },
  1917. /** 报表reload事件 */
  1918. reloadReportNode() {
  1919. if (!this.chooseMyReport || !this.chooseMyReport.id) {
  1920. if (this.reportIntervalTag) {
  1921. clearInterval(this.reportIntervalTag)
  1922. sessionStorage.removeItem(this.sessionName)
  1923. }
  1924. return
  1925. }
  1926. const loading = showLoading(this, '加载中,请稍候···')
  1927. getReportTableById(this.chooseMyReport.id).then(res => {
  1928. let _data = res.data
  1929. if (!_data) {
  1930. loading.close()
  1931. // if (this.reportIntervalTag) clearInterval(this.reportIntervalTag)
  1932. return
  1933. }
  1934. this.chooseCurrMyReport = _data
  1935. this.chooseMyReport = res.data
  1936. // this.setLuckysheetStatus(_data, true, '', loading)
  1937. // 报表数据
  1938. let reportTableData = _data.reportTableData
  1939. let luckyData = JSON.parse(reportTableData)
  1940. // 基础数据项值
  1941. let baseItem = luckyData.baseItem
  1942. // 数据项
  1943. let reportTableItemList = _data.reportTableItemList
  1944. let reportChartList = _data.reportChartList
  1945. // 报表类型
  1946. let reportTableType = _data.reportTableType
  1947. for (let i in reportChartList) {
  1948. this.insertEChartInfo(reportChartList[i])
  1949. }
  1950. // 绘制基础数据项
  1951. this.drawBaseInfo(baseItem)
  1952. // 绘制数据值
  1953. this.drawTableData(reportTableItemList, reportTableType, _data)
  1954. luckysheet.setRangeShow('BH1')
  1955. loading.close()
  1956. }).catch((e) => {
  1957. if (this.reportIntervalTag) {
  1958. clearInterval(this.reportIntervalTag)
  1959. sessionStorage.removeItem(this.sessionName)
  1960. }
  1961. loading.close()
  1962. showAlertWin(this, null, e)
  1963. })
  1964. },
  1965. /** 设置工作表状态 */
  1966. setLuckysheetStatus(dataInfo, isReadOnly, type, loading) {
  1967. let _this = this
  1968. // 报表数据
  1969. let reportTableData = dataInfo.reportTableData
  1970. let luckyData = JSON.parse(reportTableData)
  1971. // 基础数据项值
  1972. let baseItem = luckyData.baseItem
  1973. // 数据项
  1974. let reportTableItemList = dataInfo.reportTableItemList
  1975. let reportChartList = dataInfo.reportChartList
  1976. // 报表类型
  1977. let reportTableType = dataInfo.reportTableType
  1978. luckysheet.destroy()
  1979. let option = luckyData.option
  1980. if (!option) option = JSON.parse(JSON.stringify(this.luckysheetOption))
  1981. option.data = luckyData.data
  1982. if (isReadOnly) {
  1983. // 设置工作表保护
  1984. option.data[0].config.authority = {
  1985. sheet: 1, // 如果为 1 或 true,则该工作表受到保护;如果为 0 或 false,则该工作表不受保护。
  1986. hintText: '该工作表受到保护,无法操作', // 弹窗提示的文字
  1987. }
  1988. // 关闭右键菜单
  1989. option.cellRightClickConfig.chart = false
  1990. option.cellRightClickConfig.columnWidth = false
  1991. option.cellRightClickConfig.rowHeight = false
  1992. option.cellRightClickConfig.deleteColumn = false
  1993. option.cellRightClickConfig.deleteRow = false
  1994. option.cellRightClickConfig.insertColumn = false
  1995. option.cellRightClickConfig.insertRow = false
  1996. // 关闭工具栏
  1997. option.showtoolbar = false
  1998. option.enableAddRow = false
  1999. option.showtoolbarConfig = {
  2000. bold: false,
  2001. border: false,
  2002. fillColor: false,
  2003. font: false,
  2004. fontSize: false,
  2005. function: false,
  2006. horizontalAlignMode: false,
  2007. italic: false,
  2008. mergeCell: false,
  2009. moreFormats: false,
  2010. paintFormat: false,
  2011. strikethrough: false,
  2012. textColor: false,
  2013. underline: false,
  2014. verticalAlignMode: false
  2015. }
  2016. // 钩子函数
  2017. option.hook = {
  2018. workbookCreateAfter() {
  2019. for (let i in reportChartList) {
  2020. _this.insertEChartInfo(reportChartList[i])
  2021. }
  2022. // 绘制基础数据项
  2023. _this.drawBaseInfo(baseItem)
  2024. // 绘制数据值
  2025. _this.drawTableData(reportTableItemList, reportTableType, dataInfo)
  2026. luckysheet.setRangeShow('BH1')
  2027. if (loading) loading.close()
  2028. }
  2029. }
  2030. } else {
  2031. let charts = luckyData.charts
  2032. // 钩子函数
  2033. option.hook = {
  2034. workbookCreateAfter() {
  2035. for (let i in charts) {
  2036. _this.insertEChartInfo(charts[i])
  2037. }
  2038. // 绘制基础数据项
  2039. _this.drawBaseInfo(baseItem)
  2040. // 绘制数据值
  2041. _this.drawTableData(reportTableItemList, reportTableType, dataInfo)
  2042. luckysheet.setRangeShow('BH1')
  2043. if (loading) loading.close()
  2044. },
  2045. cellUpdated(r, c, newV, oldV) {
  2046. if (!(r === 49 && c === 0)) {
  2047. _this.forceRefreshLuckysheet()
  2048. }
  2049. }
  2050. }
  2051. }
  2052. luckysheet.create(option)
  2053. },
  2054. /** 绘制事件驱动报表信息 */
  2055. drawEventReportData(eventTables) {
  2056. if (!eventTables || eventTables.length == 0) {
  2057. return
  2058. }
  2059. let x = 0, y = 0
  2060. eventTables.forEach((data, i) => {
  2061. x += 1
  2062. y = 0
  2063. let {dataList, dataTimeList, itemName} = data
  2064. itemName = (itemName != null && itemName != undefined) ? itemName : cqcyCode['invalidData']
  2065. luckysheet.setCellValue(x, y, itemName)
  2066. dataList.forEach((val, j) => {
  2067. y = j + 1
  2068. let _date = luckysheet.getCellValue(0, y)
  2069. if (!_date) {
  2070. let text = (dataTimeList[j] != null && dataTimeList[j] != undefined) ? dataTimeList[j] : cqcyCode['invalidData']
  2071. if (text.length > 19) text = text.substring(0, 19)
  2072. luckysheet.setCellValue(0, y, text)
  2073. }
  2074. val = (val != null && val != undefined) ? val : cqcyCode['invalidData']
  2075. luckysheet.setCellValue(x, y, val)
  2076. })
  2077. })
  2078. },
  2079. /** 修改报表信息 */
  2080. editReportItem(data) {
  2081. let _data = JSON.parse(JSON.stringify(data))
  2082. this.$nextTick(() => {
  2083. this.resetRadioVal()
  2084. this.cronVal = _data.cron
  2085. this.analysisCron(this.cronVal)
  2086. this.reportForm = _data
  2087. // if (_data.startTime && _data.endTime) {
  2088. // this.dateByRange = [_data.startTime, _data.endTime]
  2089. // } else {
  2090. // this.dateByRange = ''
  2091. // }
  2092. this.reportForm.startTime = _data.startTime
  2093. this.reportForm.cronLabel = this.getCronLabel()
  2094. })
  2095. this.reportDialogTitle = '配置报表'
  2096. this.dialogReportTemplateVisible = true
  2097. // const loading = showLoading(this, '修改中,请稍候···')
  2098. // getReportTableById(data.id).then(res => {
  2099. // loading.close()
  2100. // this.cronVal = res.data.cron
  2101. // this.analysisCron(this.cronVal)
  2102. // this.reportForm = res.data
  2103. // this.reportForm.cronLabel = this.getCronLabel()
  2104. // this.reportDialogTitle = '配置报表'
  2105. // this.dialogReportTemplateVisible = true
  2106. // }).catch((e) => {
  2107. // loading.close()
  2108. // showAlertWin(this, null, e)
  2109. // })
  2110. },
  2111. /** 报表移除 */
  2112. removeReportItem(data, type) {
  2113. showConfirmWin(this, null, '您确定要删除该报表吗?', () => {
  2114. const loading = showLoading(this, '删除中,请稍候···')
  2115. delReportTableById(data.id).then(res => {
  2116. loading.close()
  2117. let msg = res.data ? '删除成功!' : '删除失败!'
  2118. showAlertMsgWin(this, null, msg)
  2119. if (type == 'record') {
  2120. this.reportHistoryPage = 1
  2121. this.historyReport()
  2122. return
  2123. }
  2124. this.reportPage = 1
  2125. this.loadReport()
  2126. this.cancelSaveReport()
  2127. }).catch((e) => {
  2128. loading.close()
  2129. showAlertWin(this, null, e)
  2130. })
  2131. })
  2132. },
  2133. /** 获取单元格大小 */
  2134. getCellSize(celldata, r, c, luckysheet) {
  2135. const {cs, rs} = celldata.data[r][c].mc
  2136. const rowhidden = celldata.config.rowhidden && Object.keys(celldata.config.rowhidden) || ''
  2137. const rowArr = []
  2138. for (let i = 0; i < rs; i++) {
  2139. let rowIndex = r + i
  2140. if (rowhidden.indexOf(String(rowIndex)) < 0) {
  2141. rowArr.push(rowIndex)
  2142. }
  2143. }
  2144. const colArr = []
  2145. for (let j = 0; j < cs; j++) {
  2146. colArr.push(c + j)
  2147. }
  2148. const totalHeight = Object.values(
  2149. luckysheet.getRowHeight(rowArr)
  2150. ).reduce((a, b) => a + b)
  2151. const totalWidth = Object.values(
  2152. luckysheet.getColumnWidth(colArr)
  2153. ).reduce((a, b) => a + b)
  2154. return {
  2155. w: totalWidth,
  2156. h: totalHeight
  2157. }
  2158. },
  2159. /** 获取图片位置 */
  2160. getImagePosition(num, arr) {
  2161. let index = 0
  2162. let minIndex
  2163. let maxIndex
  2164. for (let i = 0; i < arr.length; i++) {
  2165. if (num < arr[i]) {
  2166. index = i
  2167. break
  2168. }
  2169. }
  2170. if (index == 0) {
  2171. minIndex = 0
  2172. maxIndex = 1
  2173. } else if (index == arr.length - 1) {
  2174. minIndex = arr.length - 2
  2175. maxIndex = arr.length - 1
  2176. } else {
  2177. minIndex = index - 1
  2178. maxIndex = index
  2179. }
  2180. let min = arr[minIndex]
  2181. let max = arr[maxIndex]
  2182. let radio = Math.abs((num - min) / (max - min)) + index
  2183. return radio
  2184. },
  2185. /** 图表转换为图片 */
  2186. convertChart(luckyData) {
  2187. const optionData = luckysheet.getLuckysheetfile()[0]
  2188. let {
  2189. visibledatacolumn, // 所有行的位置
  2190. visibledatarow // 所有列的位置
  2191. } = optionData
  2192. // 动态图表
  2193. if (luckyData.charts && luckyData.charts.length > 0) {
  2194. luckyData.charts.forEach((chart, i) => {
  2195. let myChart = echarts.init(
  2196. document.getElementsByClassName(chart.info.className)[0]
  2197. )
  2198. let baseData = myChart.getConnectedDataURL({
  2199. type: 'png',
  2200. pixelRatio: 2,
  2201. backgroundColor: '#ffffff'
  2202. })
  2203. // luckysheet.cancelRangeMerge(chart.info.pos)
  2204. luckysheet.insertImage(baseData, {
  2205. rowIndex: chart.info.pos[0],
  2206. colIndex: chart.info.pos[1],
  2207. cellSize: this.getCellSize(optionData, chart.info.pos[0], chart.info.pos[1], luckysheet),
  2208. success: function () {
  2209. console.log("插入成功")
  2210. }
  2211. })
  2212. })
  2213. }
  2214. // 静态图表
  2215. if (luckyData.data && luckyData.data.length > 0) {
  2216. luckyData.data.forEach((data, i) => {
  2217. if (data.chart && data.chart.length > 0) {
  2218. data.chart.forEach((chart, j) => {
  2219. let myChart = echarts.init(
  2220. document.getElementById(chart.chart_id)
  2221. )
  2222. myChart.setOption(chart.chartOptions);
  2223. let baseData = myChart.getConnectedDataURL({
  2224. type: 'png',
  2225. pixelRatio: 2,
  2226. backgroundColor: '#ffffff'
  2227. })
  2228. let col_st = this.getImagePosition(chart.left, visibledatacolumn)
  2229. let row_st = this.getImagePosition(chart.top, visibledatarow)
  2230. luckysheet.insertImage(baseData, {
  2231. rowIndex: parseInt(row_st),
  2232. colIndex: parseInt(col_st),
  2233. cellSize: {
  2234. w: chart.width,
  2235. h: chart.height,
  2236. },
  2237. success: function () {
  2238. console.log("插入成功")
  2239. }
  2240. })
  2241. })
  2242. }
  2243. })
  2244. }
  2245. },
  2246. /** 处理日期显示数字问题 */
  2247. withDateData(excelData) {
  2248. if (!excelData) {
  2249. return
  2250. }
  2251. try {
  2252. excelData.map((item) => {
  2253. if (item) {
  2254. item.map((ll) => {
  2255. if (ll && ll.ct && ll.ct.t && ll.ct.t === 'd') {
  2256. ll.m = ll.m,
  2257. ll.v = ll.m,
  2258. ll.ct = {
  2259. fa: "@",
  2260. t: "s",
  2261. }
  2262. }
  2263. })
  2264. }
  2265. })
  2266. } catch (error) {
  2267. console.log(error)
  2268. }
  2269. },
  2270. /** 保存报表信息 */
  2271. saveReportInfo(loading, dataInfo) {
  2272. if (!loading) loading = showLoading(this, '保存中,请稍候···')
  2273. let _excelData = this.initBaseInfoData(dataInfo)
  2274. let params = JSON.parse(JSON.stringify(this.reportForm))
  2275. params.reportTableData = JSON.stringify(_excelData)
  2276. // if (this.dateByRange && this.dateByRange.length > 0) {
  2277. // params.startTime = this.dateByRange[0]
  2278. // params.endTime = this.dateByRange[1]
  2279. // }
  2280. saveReport(params).then(res => {
  2281. loading.close()
  2282. let msg = res.data ? '保存成功!' : '保存失败!'
  2283. showAlertMsgWin(this, null, msg)
  2284. this.showMainView = false
  2285. this.dialogReportTemplateVisible = false
  2286. this.loadReport()
  2287. this.cancelSaveReport()
  2288. }).catch((e) => {
  2289. loading.close()
  2290. showAlertWin(this, null, e)
  2291. })
  2292. },
  2293. /** 修改报表信息 */
  2294. updateReportInfo(loading, dataInfo) {
  2295. let _content = '修改'
  2296. if (this.reportForm.reportTableType == 1) _content = '配置'
  2297. if (!loading) loading = showLoading(this, _content + '中,请稍候···')
  2298. let params = JSON.parse(JSON.stringify(this.reportForm))
  2299. // if (this.dateByRange && this.dateByRange.length > 0) {
  2300. // params.startTime = this.dateByRange[0]
  2301. // params.endTime = this.dateByRange[1]
  2302. // }
  2303. setAutoTableTime(params).then(res => {
  2304. loading.close()
  2305. let msg = res.data ? (_content + '成功!') : (_content + '失败!')
  2306. showAlertMsgWin(this, null, msg)
  2307. this.showMainView = false
  2308. this.dialogReportTemplateVisible = false
  2309. this.loadReport()
  2310. this.cancelSaveReport()
  2311. }).catch((e) => {
  2312. loading.close()
  2313. showAlertWin(this, null, e)
  2314. })
  2315. },
  2316. /** 更新报表信息 */
  2317. updateReport() {
  2318. if (!this.chooseMyReport || !this.chooseMyReport.id) {
  2319. showAlertMsgWin(this, null, '保存失败,请刷新后重试!')
  2320. return
  2321. }
  2322. showPromptWin(this, '保存', '请输入报表名称', this.chooseMyReport.reportTableName, (val) => {
  2323. if (!val) {
  2324. return '报表名称不能为空'
  2325. }
  2326. if (val.length > 20) {
  2327. return '报表名称必须在20字以内'
  2328. }
  2329. }, (value) => {
  2330. const loading = showLoading(this, '保存中,请稍候···')
  2331. let _data2 = JSON.parse(this.chooseMyReport.reportTableData)
  2332. let excelTable = _data2.tables
  2333. excelTable.forEach(table => {
  2334. table.field.forEach(field => {
  2335. luckysheet.setCellValue(field.r, field.c, field.name)
  2336. })
  2337. })
  2338. let _data = JSON.parse(getLuckysheetConfig())
  2339. let excelData = _data[0].data
  2340. this.withDateData(excelData)
  2341. _data2.data = _data
  2342. // this.convertChart(_data2)
  2343. let data = this.chooseMyReport
  2344. data.reportTableName = value
  2345. data.reportTableData = JSON.stringify(_data2)
  2346. updateReportTable(data).then(res => {
  2347. loading.close()
  2348. let msg = res.data ? '保存成功!' : '保存失败!'
  2349. showAlertMsgWin(this, null, msg)
  2350. this.showMainView = false
  2351. this.loadReport()
  2352. this.cancelSaveReport()
  2353. }).catch((e) => {
  2354. loading.close()
  2355. showAlertWin(this, null, e)
  2356. })
  2357. })
  2358. },
  2359. /** 报表下载 */
  2360. downloadReport() {
  2361. this.dialogDownloadReportTypeVisible = true
  2362. },
  2363. /** 报表下载事件 */
  2364. downloadReportEvent() {
  2365. if (!this.chooseCurrMyReport) {
  2366. showAlertMsgWin(this, null, '请选择报表!')
  2367. return
  2368. }
  2369. let reportName = this.chooseCurrMyReport.reportTableName ? this.chooseCurrMyReport.reportTableName : '统计报表'
  2370. if (this.downloadType == '1') {
  2371. // exportExcel(luckysheet, reportName, ExcelJS).then((res) => {
  2372. // console.log("result==>", res)
  2373. // // this.$message({
  2374. // // message: res,
  2375. // // type: 'success'
  2376. // // })
  2377. // this.dialogDownloadReportTypeVisible = false
  2378. // }).catch((err) => {
  2379. // })
  2380. exportExcel(luckysheet.getAllSheets(), reportName)
  2381. setTimeout(() => {
  2382. this.dialogDownloadReportTypeVisible = false
  2383. }, 500)
  2384. }
  2385. },
  2386. /** 报表记录 */
  2387. historyReport() {
  2388. const loading = showLoading(this, '加载中,请稍候···')
  2389. let params = {
  2390. 'page': this.reportHistoryPage,
  2391. 'limit': this.reportHistoryLimit,
  2392. 'reportTableName': this.searchHistoryTxt,
  2393. 'autoTableId': this.chooseMyReport.id
  2394. }
  2395. getAutoChReportTable(params).then(res => {
  2396. loading.close()
  2397. this.dialogHistoryReportVisible = true
  2398. if (!res.data) return
  2399. this.reportHistoryData = res.data.reportTableList
  2400. this.reportHistoryTotal = res.data.count
  2401. }).catch((e) => {
  2402. loading.close()
  2403. showAlertWin(this, null, e)
  2404. })
  2405. },
  2406. getPrintSheetArea() {
  2407. const sheetData = luckysheet.getSheetData();
  2408. let objRowColumn = {
  2409. row: [0, 0], //行
  2410. column: [0, 0], //列
  2411. };
  2412. // * item是行、index是行索引、it是一行里的一格、itemIndex是这一格在这一行里的列索引
  2413. sheetData.forEach((item, index) => {
  2414. //行数
  2415. item.forEach((it, itemIndex) => {
  2416. if (it !== null && it.v) {
  2417. // console.log(index, it)
  2418. if (objRowColumn.row[1] < index) {
  2419. objRowColumn.row[1] = index; //row第二位
  2420. }
  2421. if (objRowColumn.column[1] < itemIndex) {
  2422. objRowColumn.column[1] = itemIndex; //column第二位
  2423. }
  2424. }
  2425. });
  2426. });
  2427. return objRowColumn;
  2428. },
  2429. /** 打印操作 */
  2430. printExcel() {
  2431. const loading = showLoading(this, '请稍候···')
  2432. document.querySelector('#print-area').style = "display:block;margin:20px;";
  2433. window.luckysheet.hideGridLines();
  2434. //获取当前选中区域
  2435. let currentSelected = luckysheet.getRange()
  2436. //如果当前选中区只是一个单元格,则认为选取无效。
  2437. if (currentSelected[0] != null && (currentSelected[0].row[1] - currentSelected[0].row[0] >= 1 || currentSelected[0].column[1] - currentSelected[0].column[0] >= 1)) {
  2438. // 将打印区域生成base64图片(*将生成的base64编码复制粘贴到浏览器地址框,是可以预览图片样式的),生成后执行的后续打印操作,取用匿名委托函数做为参数传入
  2439. luckysheet.getScreenshotNew((imgSrc) => {
  2440. window.luckysheet.showGridLines();
  2441. // * Lodop中的ADD_PRINT_IMAGE,也可以直接输出base64码图片,不用加img标签(如果加了img标签,会被当做超文本对待,受浏览器引擎解析的影响)
  2442. let $img = `<img src=${imgSrc} />`
  2443. this.$nextTick(() => {
  2444. console.log(imgSrc)
  2445. document.querySelector('#print-html').innerHTML = $img;
  2446. setTimeout(() => {
  2447. Print({
  2448. printable: 'print-html',
  2449. type: 'html',
  2450. documentTitle: '文档标题',
  2451. maxWidth: 1150, // 最大宽度
  2452. header: '',
  2453. headerStyle: 'font-weight:400;text-align:center;',
  2454. style: '', // 不打印页眉和页脚
  2455. honorColor: true, // 是否打印彩色文本
  2456. targetStyles: ['*'] // 允许打印所有样式属性
  2457. }) // Print.js插件
  2458. if (document.querySelector('#print-area'))
  2459. document.querySelector('#print-area').style = "display:none";
  2460. loading.close()
  2461. }, 1000);
  2462. })
  2463. });
  2464. } else {
  2465. // 获取打印区域的行列
  2466. let RowColumn = this.getPrintSheetArea();
  2467. // 因需要打印左边的边框,需重新设置第一列
  2468. //RowColumn.column[0] = 0;
  2469. // 进行选区操作
  2470. luckysheet.setRangeShow(RowColumn);
  2471. // 将打印区域生成base64图片(*将生成的base64编码复制粘贴到浏览器地址框,是可以预览图片样式的),生成后执行的后续打印操作,取用匿名委托函数做为参数传入
  2472. luckysheet.getScreenshotNew((imgSrc) => {
  2473. window.luckysheet.showGridLines();
  2474. // * Lodop中的ADD_PRINT_IMAGE,也可以直接输出base64码图片,不用加img标签(如果加了img标签,会被当做超文本对待,受浏览器引擎解析的影响)
  2475. let $img = `<img src=${imgSrc} />`
  2476. this.$nextTick(() => {
  2477. document.querySelector('#print-html').innerHTML = $img;
  2478. setTimeout(() => {
  2479. Print({
  2480. printable: 'print-html',
  2481. type: 'html',
  2482. documentTitle: '文档标题',
  2483. maxWidth: 1150, // 最大宽度
  2484. header: '',
  2485. headerStyle: 'font-weight:400;text-align:center;',
  2486. style: '', // 不打印页眉和页脚
  2487. honorColor: true, // 是否打印彩色文本
  2488. targetStyles: ['*'] // 允许打印所有样式属性
  2489. }) // Print.js插件
  2490. if (document.querySelector('#print-area'))
  2491. document.querySelector('#print-area').style = "display:none";
  2492. loading.close()
  2493. }, 1000);
  2494. })
  2495. });
  2496. }
  2497. },
  2498. printSheet() {
  2499. const loading = showLoading(this, '请稍候···')
  2500. document.querySelector('#print-area').style = "display:block";
  2501. window.luckysheet.hideGridLines();
  2502. // 获取当前选中区域
  2503. let currentSelected = luckysheet.getRange()
  2504. // 如果当前选中区只是一个单元格,则认为选取无效。
  2505. if (currentSelected[0] != null
  2506. && (currentSelected[0].row[1] - currentSelected[0].row[0] >= 1
  2507. || currentSelected[0].column[1] - currentSelected[0].column[0] >= 1)) {
  2508. // 生成base64图片
  2509. let imgSrc = luckysheet.getScreenshot();
  2510. window.luckysheet.showGridLines();
  2511. // * Lodop中的ADD_PRINT_IMAGE,也可以直接输出base64码图片,不用加img标签(如果加了img标签,会被当做超文本对待,受浏览器引擎解析的影响)
  2512. let $img = `<img src=${imgSrc} style="" />`
  2513. this.$nextTick(() => {
  2514. document.querySelector('#print-html').innerHTML = $img;
  2515. setTimeout(() => {
  2516. Print({
  2517. printable: 'print-html',
  2518. type: 'html',
  2519. documentTitle: '文档标题',
  2520. maxWidth: 1150, // 最大宽度
  2521. header: '',
  2522. headerStyle: 'font-weight:400;text-align:center;',
  2523. style: '', // 不打印页眉和页脚
  2524. honorColor: true, // 是否打印彩色文本
  2525. targetStyles: ['*'] // 允许打印所有样式属性
  2526. }) // Print.js插件
  2527. document.querySelector("#print-area").style.display = "none";
  2528. loading.close()
  2529. }, 1000)
  2530. })
  2531. } else {
  2532. // 获取打印区域的行列
  2533. let RowColumn = this.getPrintSheetArea();
  2534. // 因需要打印左边的边框,需重新设置第一列
  2535. RowColumn.column[0] = 0;
  2536. // 进行选区操作
  2537. luckysheet.setRangeShow(RowColumn);
  2538. let imgSrc = luckysheet.getScreenshot(); // 生成base64图片
  2539. window.luckysheet.showGridLines();
  2540. // * Lodop中的ADD_PRINT_IMAGE,也可以直接输出base64码图片,不用加img标签(如果加了img标签,会被当做超文本对待,受浏览器引擎解析的影响)
  2541. let $img = `<img src=${imgSrc} style="" />`
  2542. this.$nextTick(() => {
  2543. document.querySelector('#print-html').innerHTML = $img;
  2544. setTimeout(() => {
  2545. Print({
  2546. printable: 'print-html',
  2547. type: 'html',
  2548. documentTitle: '文档标题',
  2549. maxWidth: 1150, // 最大宽度
  2550. header: '',
  2551. headerStyle: 'font-weight:400;text-align:center;',
  2552. style: '', // 不打印页眉和页脚
  2553. honorColor: true, // 是否打印彩色文本
  2554. targetStyles: ['*'] // 允许打印所有样式属性
  2555. }) // Print.js插件
  2556. document.querySelector("#print-area").style.display = "none";
  2557. loading.close()
  2558. }, 1000)
  2559. })
  2560. }
  2561. },
  2562. /** 自定义选中区域 */
  2563. getExcelRowColumn() {
  2564. const sheetData = luckysheet.getSheetData();
  2565. let objRowColumn = {
  2566. row: [null, null], //行
  2567. column: [null, null], //列
  2568. };
  2569. sheetData.forEach((item, index) => {
  2570. //行数
  2571. item.forEach((it, itemIndex) => {
  2572. console.log(it)
  2573. if (it !== null) {
  2574. if (objRowColumn.row[0] == null) objRowColumn.row[0] = index; // row第一位
  2575. objRowColumn.row[1] = index; //row第二位
  2576. if (objRowColumn.column[0] == null)
  2577. objRowColumn.column[0] = itemIndex; //column第一位
  2578. objRowColumn.column[1] = itemIndex; //column第二位
  2579. }
  2580. });
  2581. });
  2582. return objRowColumn;
  2583. },
  2584. cronNodeEvent(obj) {
  2585. this.cronVal = obj.value
  2586. },
  2587. initCronList() {
  2588. this.cronList = []
  2589. this.cronList.push({value: '0/2 * * * * ?', label: '表示每2秒钟执行一次任务'})
  2590. this.cronList.push({value: '0 0/2 * * * ?', label: '表示每2分钟执行一次任务'})
  2591. this.cronList.push({value: '0 0 0/2 * * ?', label: '表示每2小时执行一次任务'})
  2592. this.cronList.push({value: '0 15 10 * * ?', label: '表示在每天上午10点15分执行一次任务'})
  2593. this.cronList.push({value: '0 0 10,14,16 * * ?', label: '表示在每天的上午10点、下午2点、下午4点分别执行一次任务'})
  2594. this.cronList.push({
  2595. value: '0 0/30 9-17 * * ?',
  2596. label: '表示在每天的上午9点到下午5点的范围内每30分钟执行一次任务'
  2597. })
  2598. this.cronList.push({value: '0 0 12 ? * WED', label: '表示在每周星期三中午12点执行一次任务'})
  2599. this.cronList.push({value: '0 0 2 1 * ?', label: '表示在每月的1日的凌晨2点执行一次任务'})
  2600. },
  2601. /** 取消保存报表 */
  2602. cancelSaveReport2() {
  2603. this.handleReportNodeClick(this.chooseMyReport, this.chooseMyReport.userId !== this.uid ? 'deny' : '')
  2604. },
  2605. /** 取消保存报表 */
  2606. cancelSaveReport() {
  2607. if (this.reportIntervalTag) {
  2608. clearInterval(this.reportIntervalTag)
  2609. sessionStorage.removeItem(this.sessionName)
  2610. }
  2611. luckysheet.destroy()
  2612. this.breadcrumbList = ['运行配置']
  2613. this.showMainView = false
  2614. this.btnType = ''
  2615. this.chooseMyReport = null
  2616. if (this.$refs['reportForm']) this.$refs['reportForm'].resetFields()
  2617. },
  2618. /** 弹出层关闭事件 */
  2619. dialogClose(done) {
  2620. this.cronVal = ''
  2621. this.searchHistoryTxt = ''
  2622. this.reportId = null
  2623. // this.userGroupInfo = null
  2624. if (typeof (done) === 'function') {
  2625. done()
  2626. } else {
  2627. this.dialogReportTemplateVisible = false
  2628. this.dialogDownloadReportTypeVisible = false
  2629. this.dialogAutoReportVisible = false
  2630. this.dialogReportTypeVisible = false
  2631. this.dialogUserGroupVisible = false
  2632. this.dialogAutoPrintVisible = false
  2633. }
  2634. },
  2635. /** 弹出层关闭事件 */
  2636. dialogGroupUserClose(done) {
  2637. if (typeof (done) === 'function') {
  2638. done()
  2639. } else {
  2640. this.dialogGroupUserVisible = false
  2641. }
  2642. }
  2643. }
  2644. }
  2645. </script>
  2646. <style rel="stylesheet/scss" lang="scss">
  2647. .breadcrumb-content {
  2648. padding-bottom: 0;
  2649. }
  2650. .cy-nav-sx {
  2651. float: left !important;
  2652. margin-top: -23px !important;
  2653. margin-left: 120px !important;
  2654. display: flex;
  2655. }
  2656. .cy-nav-btn {
  2657. float: right !important;
  2658. margin-right: 20px !important;
  2659. margin-top: -20px !important;
  2660. }
  2661. .cy-main {
  2662. margin: 10px 20px;
  2663. width: calc(100% - 40px);
  2664. height: calc(100% - 100px);
  2665. .cy-btn {
  2666. margin-bottom: 10px;
  2667. }
  2668. .cy-btn .el-link {
  2669. margin-right: 15px;
  2670. }
  2671. .cy-main-left {
  2672. width: 100%;
  2673. height: 100%;
  2674. overflow: auto;
  2675. //float: left;
  2676. padding: 5px 10px;
  2677. //border-right: 1px solid #d4d4d4;
  2678. .cy-list {
  2679. overflow: auto;
  2680. height: 100%;
  2681. height: calc(100% - 40px);
  2682. ul {
  2683. display: flex;
  2684. flex-wrap: wrap;
  2685. padding: 0;
  2686. margin-top: 0;
  2687. li {
  2688. list-style-type: none;
  2689. background: #41aed7;
  2690. width: 23%;
  2691. margin: 10px 1%;
  2692. border-radius: 8px;
  2693. height: 110px;
  2694. padding: 15px;
  2695. color: #ffffff;
  2696. .cy-item-name {
  2697. font-size: 14px;
  2698. text-overflow: ellipsis;
  2699. white-space: nowrap;
  2700. overflow: hidden;
  2701. margin-bottom: 15px;
  2702. cursor: pointer;
  2703. }
  2704. .cy-item-val {
  2705. font-size: 12px;
  2706. }
  2707. .cy-list-item {
  2708. font-size: 12px;
  2709. color: #f6f6f6;
  2710. width: 100%;
  2711. //display: flex;
  2712. margin-top: 40px;
  2713. }
  2714. }
  2715. }
  2716. }
  2717. }
  2718. .cy-main-right {
  2719. width: 100%;
  2720. height: 100%;
  2721. float: left;
  2722. overflow: hidden;
  2723. }
  2724. }
  2725. .cy-group-tree1 {
  2726. font-size: 14px;
  2727. .custom-tree-node1 {
  2728. height: 28px;
  2729. line-height: 28px;
  2730. }
  2731. }
  2732. .cron-txt {
  2733. color: blue;
  2734. margin-right: 20px;
  2735. cursor: pointer;
  2736. font-weight: bold;
  2737. font-size: 16px;
  2738. }
  2739. .cron-txt-desc {
  2740. }
  2741. .ug-div {
  2742. .el-transfer-panel {
  2743. width: 300px;
  2744. }
  2745. }
  2746. </style>