ReportV2.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <div class="app-container">
  3. <div
  4. class="filter-container"
  5. v-loading="loading.filter">
  6. <div class="filter-row">
  7. <label class="el-form-item__label">Report Type:</label>
  8. <el-select
  9. v-model="filter.pageVo.reportType"
  10. @change="changeReportType"
  11. class="filter-input"
  12. placeholder="Filter Report Type"
  13. clearable>
  14. <el-option
  15. v-for="reportType in options.reportType"
  16. :label="reportType.name"
  17. :value="reportType.value"
  18. :key="reportType.value"/>
  19. </el-select>
  20. </div>
  21. <div class="filter-row">
  22. <label class="el-form-item__label">Filters:</label>
  23. <el-date-picker
  24. v-model="dateRange"
  25. type="daterange"
  26. format="yyyy-MM-dd"
  27. value-format="yyyy-MM-dd"
  28. start-placeholder="Start Date"
  29. end-placeholder="End Date"
  30. :picker-options="pickerOptions"
  31. clearable
  32. @change="changeDateRange"
  33. class="filter-input"
  34. v-if="filter.pageVo.reportType === 'APENDIXF'"/>
  35. <el-date-picker
  36. v-model="dateRange"
  37. type="daterange"
  38. value-format="yyyy-MM"
  39. format="yyyy-MM"
  40. start-placeholder="Start Month"
  41. end-placeholder="End Month"
  42. :picker-options="pickerOptions"
  43. clearable
  44. @change="changeDateRange"
  45. class="filter-input"
  46. v-if="filter.pageVo.reportType == 'MNTHADHOC'"/>
  47. <el-date-picker
  48. v-model="filter.pageVo.year"
  49. type="year"
  50. format="yyyy"
  51. value-format="yyyy"
  52. :clearable="false"
  53. class="filter-input half"
  54. placeholder="Filter Year"
  55. v-show="filter.pageVo.reportType != 'APENDIXF' && filter.pageVo.reportType != 'MNTHADHOC'"/>
  56. <el-select
  57. v-show="filter.pageVo.reportType != 'APENDIXF' && filter.pageVo.reportType != 'MNTHADHOC'"
  58. v-model="filter.pageVo.month"
  59. class="filter-input half"
  60. placeholder="Filter Month"
  61. clearable>
  62. <el-option
  63. v-for="month in options.monthOptions"
  64. :label="month.name"
  65. :value="month.value"
  66. :key="month.value"/>
  67. </el-select>
  68. <el-select
  69. v-show="filter.pageVo.reportType == 'MNTHTRAN' || filter.pageVo.reportType == 'MNTHSEPR'"
  70. v-model="filter.pageVo.providerPks"
  71. class="filter-input"
  72. placeholder="Service Provider"
  73. clearable
  74. multiple>
  75. <el-option
  76. v-for="(item,index) in options.serviceProvider"
  77. :label="item.providerName"
  78. :value="item.providerPk"
  79. :key="index"/>
  80. </el-select>
  81. <!--:remote-method="(s) => getSiteOptions(s)"-->
  82. <el-select
  83. clearable
  84. filterable multiple
  85. v-show="isAppendixSite"
  86. v-model="filter.pageVo.sitePks"
  87. class="filter-input"
  88. placeholder="Sites">
  89. <el-option
  90. v-for="(item, index) in options.siteOptions"
  91. :key="index"
  92. :label="item.siteName"
  93. :value="item.sitePk"/>
  94. </el-select>
  95. <el-select
  96. clearable
  97. multiple
  98. v-show="filter.pageVo.reportType == 'MNTHFLET'"
  99. v-model="filter.pageVo.groupPks"
  100. class="filter-input"
  101. placeholder="Fleet">
  102. <el-option
  103. v-for="(item, index) in options.groupOptions"
  104. :key="index"
  105. :label="item.name"
  106. :value="item.value"/>
  107. </el-select>
  108. <el-select
  109. clearable
  110. multiple
  111. v-show="filter.pageVo.reportType == 'MNTHMEMB'"
  112. v-model="filter.pageVo.groupPks"
  113. class="filter-input"
  114. placeholder="Member">
  115. <el-option
  116. v-for="(item, index) in options.groupOptions"
  117. :key="index"
  118. :label="item.name"
  119. :value="item.value"/>
  120. </el-select>
  121. <el-select
  122. clearable
  123. multiple
  124. v-show="filter.pageVo.reportType == 'MNTHPART'"
  125. v-model="filter.pageVo.groupPks"
  126. class="filter-input"
  127. placeholder="Partner">
  128. <el-option
  129. v-for="(item, index) in options.groupOptions"
  130. :key="index"
  131. :label="item.name"
  132. :value="item.value"/>
  133. </el-select>
  134. <el-button
  135. class="generate-button"
  136. type="primary"
  137. @click="onSearch"
  138. :disabled="loading.table">
  139. Search
  140. </el-button>
  141. <el-button
  142. class="generate-button"
  143. v-waves
  144. type="primary"
  145. :loading="loading.generate"
  146. @click="reGenerateReport">
  147. Generate
  148. </el-button>
  149. </div>
  150. </div>
  151. <el-table
  152. :data="table.data"
  153. class="no-border"
  154. v-loading="loading.table">
  155. <el-table-column
  156. label="Report Type"
  157. prop="reportType"
  158. align="center"
  159. min-width="180"/>
  160. <el-table-column
  161. label="Year"
  162. prop="year"
  163. align="center"
  164. min-width="80"/>
  165. <el-table-column
  166. label="Month"
  167. prop="month"
  168. align="center"
  169. min-width="80"/>
  170. <el-table-column
  171. label="Creation Date/Time"
  172. prop="createTime"
  173. align="center"
  174. min-width="150"/>
  175. <el-table-column
  176. label="Created By"
  177. prop="createBy"
  178. align="center"
  179. min-width="150"/>
  180. <el-table-column
  181. label="Role"
  182. prop="role"
  183. align="center"
  184. min-width="100"/>
  185. <el-table-column
  186. label="Status"
  187. prop="generateStatus"
  188. align="center"
  189. min-width="120"/>
  190. <el-table-column
  191. label="File"
  192. prop="reportName"
  193. align="center"
  194. min-width="220">
  195. <template slot-scope="{row}">
  196. <a :href="row.filePath"
  197. v-if="row.filePath"
  198. class="link-detail">
  199. {{row.reportName}}
  200. </a>
  201. <span v-else>{{row.reportName}}</span>
  202. </template>
  203. </el-table-column>
  204. <!-- <el-table-column
  205. v-if="!$route.meta.onlyView"
  206. label="Action"
  207. align="center"
  208. width="130">
  209. <template slot-scope="{row}">
  210. <el-button
  211. :loading="row.loading"
  212. icon="el-icon-download"
  213. class="export-button"
  214. @click="handleExportExcel(row)">
  215. Export
  216. </el-button>
  217. </template>
  218. </el-table-column> -->
  219. </el-table>
  220. <div class="right">
  221. <pagination
  222. v-show="table.total > 0"
  223. :total="table.total"
  224. :page.sync="filter.pageNo"
  225. :limit.sync="filter.pageSize"
  226. @pagination="getReportsPages" />
  227. </div>
  228. </div>
  229. </template>
  230. <script>
  231. import site from '@/http/api/site'
  232. import api from '@/http/api/apiReport'
  233. import provider from '@/http/api/provider'
  234. import Pagination from '@/components/Pagination'
  235. import TableAction from '@/components/TableAction.vue'
  236. export default {
  237. components: { Pagination, TableAction },
  238. data() {
  239. return {
  240. loading: {
  241. filter: false,
  242. table: false,
  243. generate: false
  244. },
  245. dateRange: [],
  246. filter: {
  247. pageNo: 1,
  248. pageSize: 10,
  249. pageVo: {
  250. year: ''+new Date().getFullYear(),
  251. month: '',
  252. startDate: "",
  253. endDate: "",
  254. reportType: '',
  255. sitePks: [],
  256. groupPks: [],
  257. providerPks: []
  258. }
  259. },
  260. options: {
  261. reportType: [],
  262. siteOptions: [],
  263. monthOptions: [],
  264. groupOptions: [],
  265. serviceProvider: []
  266. },
  267. table: {
  268. data: [],
  269. total: 0
  270. },
  271. pickerOptions: {
  272. shortcuts: [{
  273. text: 'Nearest Week',
  274. onClick(picker) {
  275. const end = new Date();
  276. const start = new Date();
  277. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
  278. picker.$emit('pick', [start, end]);
  279. }
  280. }]
  281. },
  282. hasGrouptype: ["MNTHFLET", "MNTHMEMB", "MNTHPART"]
  283. }
  284. },
  285. computed: {
  286. isAppendixSite() {
  287. return this.filter.pageVo.reportType == 'MNTHSITE'
  288. || this.filter.pageVo.reportType == 'MNTHEBS'
  289. || this.filter.pageVo.reportType == 'MNTHECS'
  290. || this.filter.pageVo.reportType == 'APENDIXF'
  291. || this.filter.pageVo.reportType === 'APENDIXH'
  292. || this.filter.pageVo.reportType === 'APENDIXH1'
  293. || this.filter.pageVo.reportType === 'APENDIXF1'
  294. || this.filter.pageVo.reportType === 'APENDIXF2'
  295. }
  296. },
  297. created() {
  298. this.getFilterOptions();
  299. },
  300. methods: {
  301. getFilterOptions() {
  302. this.loading.filter = true
  303. Promise.all([
  304. this.getMonthOptions(),
  305. this.getReportTypeOptions(),
  306. this.getSiteOptions(),
  307. this.getServiceProviderList()
  308. ]).then(() => {
  309. this.loading.filter = false;
  310. this.getReportsPages();
  311. }).catch(err => {
  312. this.loading.filter = false;
  313. this.$message({
  314. type: 'error',
  315. message: err
  316. })
  317. })
  318. },
  319. changeReportType() {
  320. if (this.hasGrouptype.indexOf(this.filter.pageVo.reportType) >= 0) {
  321. this.getGroupOptions();
  322. }
  323. this.filter.pageVo.sitePks = [];
  324. this.filter.pageVo.groupPks = [];
  325. this.filter.pageVo.providerPks = [];
  326. this.filter.pageVo.startDate = "";
  327. this.filter.pageVo.endDate = "";
  328. this.filter.pageVo.month = "";
  329. this.dateRange = [];
  330. this.$forceUpdate();
  331. },
  332. changeDateRange(range) {
  333. if (this.dateRange.length == 2) {
  334. this.filter.pageVo.startDate = this.dateRange[0]
  335. this.filter.pageVo.endDate = this.dateRange[1]
  336. }
  337. },
  338. onSearch() {
  339. this.filter.pageNo = 1;
  340. this.loading.table = true;
  341. setTimeout(() => {
  342. this.getReportsPages()
  343. }, 500);
  344. },
  345. reGenerateReport() {
  346. this.loading.generate = true;
  347. api.generateReport(this.filter.pageVo).then(res => {
  348. this.loading.generate = false;
  349. this.$message({
  350. type: res.success?'success':'error',
  351. message: res.msg
  352. })
  353. }).catch(err => {
  354. this.loading.generate = false;
  355. this.$message({
  356. type: 'error',
  357. message: err
  358. })
  359. })
  360. },
  361. getServiceProviderList() {
  362. return provider.getAllServiceProvider().then(res => {
  363. if (res.data) {
  364. this.options.serviceProvider = res.data;
  365. }
  366. })
  367. },
  368. getMonthOptions() {
  369. return api.getMonthList().then(res => {
  370. if (res.data) {
  371. this.options.monthOptions = res.data
  372. this.filter.pageVo.month = res.data[0].value
  373. }
  374. })
  375. },
  376. getReportTypeOptions() {
  377. return api.getReportTypeList().then(res => {
  378. if (res.data) {
  379. this.options.reportType = res.data
  380. this.filter.pageVo.reportType = res.data[0].value
  381. }
  382. })
  383. },
  384. getSiteOptions() {
  385. site.getAllSiteList({siteName: ""}).then(res => {
  386. if (res.data && res.data.length > 0) {
  387. this.options.siteOptions = res.data
  388. } else {
  389. this.options.siteOptions = []
  390. }
  391. }).catch(err => {
  392. this.$message({
  393. message: err,
  394. type: 'error'
  395. })
  396. this.options.siteOptions = []
  397. });
  398. },
  399. getGroupOptions() {
  400. api.getGroupList({
  401. reportType: this.filter.pageVo.reportType
  402. }).then(res => {
  403. if (res.data) {
  404. this.options.groupOptions = res.data
  405. }
  406. })
  407. },
  408. getReportsPages() {
  409. this.loading.table = true;
  410. api.getReportsPages(this.filter).then(res => {
  411. if (res.data) {
  412. this.table.data = res.data.map((report) => {
  413. report.loading = false
  414. return report
  415. })
  416. this.table.total = res.total
  417. } else {
  418. this.table.total = 0;
  419. this.table.data = [];
  420. }
  421. }).catch(err => {
  422. this.$message({
  423. message: err,
  424. type: 'error'
  425. })
  426. this.table.total = 0;
  427. this.table.data = [];
  428. }).finally(() => {
  429. this.loading.table = false
  430. })
  431. },
  432. handleExportExcel(row) {
  433. row.loading = true
  434. api.exportReports({ filePk: row.filePk }).then((res) => {
  435. this.downloadExcel(res, row.reportName)
  436. }).catch(err => {
  437. this.$message({
  438. message: err,
  439. type: 'error'
  440. })
  441. }).finally(() => {
  442. row.loading = false
  443. })
  444. },
  445. downloadExcel(res, fileName) {
  446. const blob = new Blob([res], {
  447. type: 'application/vnd.ms-excel;charset=utf-8'
  448. })
  449. if ('download' in document.createElement('a')) {
  450. // 非IE下载
  451. const elink = document.createElement('a')
  452. elink.download = fileName
  453. elink.style.display = 'none'
  454. elink.href = URL.createObjectURL(blob)
  455. document.body.appendChild(elink)
  456. elink.click()
  457. URL.revokeObjectURL(elink.href) // 释放URL 对象
  458. document.body.removeChild(elink)
  459. } else {
  460. // IE10+下载
  461. navigator.msSaveBlob(blob, fileName)
  462. }
  463. this.excelLoad = false
  464. }
  465. },
  466. }
  467. </script>
  468. <style lang="scss" scoped>
  469. .filter-row {
  470. display: flex;
  471. flex-wrap: wrap;
  472. align-items: center;
  473. margin-bottom: 15px;
  474. .el-form-item__label {
  475. color: #333;
  476. width: 100px;
  477. text-align: right;
  478. }
  479. .filter-input {
  480. flex: 1;
  481. min-width: 180px;
  482. max-width: 260px;
  483. &.half {
  484. min-width: 85px;
  485. max-width: 125px;
  486. }
  487. & + .filter-input {
  488. margin-left: 10px;
  489. }
  490. }
  491. }
  492. .generate-button {
  493. width: 100px;
  494. height: 40px;
  495. margin-left: 10px;
  496. }
  497. .export-button {
  498. background-color: #fff;
  499. }
  500. </style>