ReportV2.vue 14 KB

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