index.vue 93 KB

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