NewWorkplaceBacklog.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. <template>
  2. <div>
  3. <div class="gutter-example">
  4. <a-row :gutter="20">
  5. <a-col class="gutter-row" :span="8">
  6. <div class="gutter-box">
  7. <a-row type="flex" justify="space-between" style="flex:1; font-size:22px;font-weight: 500;color: #373737;">
  8. <a-col>维修数据</a-col>
  9. <a-col><a href="/repair/form?type=1&searchType=6" style="color:#3066EC ;" target="_block">{{ topData.repairTotalNum }}</a></a-col>
  10. </a-row>
  11. <a-row type="flex" justify="space-between" :gutter="[0,16]" style="flex:1;font-size:18px;font-weight: 500;">
  12. <a-col style="width:110px;">
  13. <a-badge color="#3066EC "/>
  14. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/wait?type=1">待接单 &nbsp; {{ topData.completedRepairNum }}</a></span>
  15. </a-col>
  16. <a-col style="width:110px;">
  17. <a-badge color="#3066EC "/>
  18. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/form/mine?type=1">维修中 &nbsp; {{ topData.waitForRepairNum }}</a></span>
  19. </a-col>
  20. </a-row>
  21. <a-row type="flex" justify="space-between" :gutter="[0,16]" style="flex:1;font-size:18px;font-weight: 500;">
  22. <a-col style="width:110px;">
  23. <a-badge color="#3066EC "/>
  24. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/form?type=1&searchType=3">待审核 &nbsp; {{ topData.verifyRepairNum }}</a></span>
  25. </a-col>
  26. <a-col style="width:110px;">
  27. <a-badge color="#3066EC "/>
  28. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/form?type=1&searchType=5">已驳回 &nbsp; {{ topData.refusedRepairNum }}</a></span>
  29. </a-col>
  30. </a-row>
  31. </div>
  32. </a-col>
  33. <a-col class="gutter-row" :span="8">
  34. <div class="gutter-box">
  35. <a-row type="flex" justify="space-between" style="flex:1; font-size:22px;font-weight: 500;color: #373737;">
  36. <a-col>委外数据</a-col>
  37. <a-col><a target="_block" style="color:#3066EC ;" href="/repair/form?type=2&searchType=6">{{ topData.outRepairTotalNum }}</a></a-col>
  38. </a-row>
  39. <a-row type="flex" justify="space-between" :gutter="[0,16]" style="flex:1;font-size:18px;font-weight: 500;">
  40. <a-col style="width:110px;">
  41. <a-badge color="#3066EC "/>
  42. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/wait?type=2">待接单 &nbsp; {{ topData.outCompletedRepairNum }}</a></span>
  43. </a-col>
  44. <a-col style="width:110px;">
  45. <a-badge color="#3066EC "/>
  46. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/form/mine?type=2">待维修 &nbsp; {{ topData.outWaitForRepairNum }}</a></span>
  47. </a-col>
  48. </a-row>
  49. <a-row type="flex" justify="space-between" :gutter="[0,16]" style="flex:1;font-size:18px;font-weight: 500;">
  50. <a-col style="width:110px;">
  51. <a-badge color="#3066EC "/>
  52. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/form?type=2&searchType=3">待审核 &nbsp; {{ topData.outVerifyRepairNum }}</a></span>
  53. </a-col>
  54. <a-col style="width:110px;">
  55. <a-badge color="#3066EC "/>
  56. <span style="color:#3066EC ;"><a style="color:#3066EC ;" target="_block" href="/repair/form?type=2&searchType=5">已驳回 &nbsp; {{ topData.outRefusedRepairNum }}</a></span>
  57. </a-col>
  58. </a-row>
  59. </div>
  60. </a-col>
  61. <a-col class="gutter-row" :span="8">
  62. <div style="display:flex;text-align:center;background:#fff;height: 170px;">
  63. <div style="width:48%;margin:auto;font-size:26px; line-height: 60px;">
  64. <div>本月维修总计</div>
  65. <div style="font-size:24px;"><a style="color:#3066EC ;" target="_block" :href="`/repair/form?repairStartTimeStart=${date.repairStartTimeStart}&repairStartTimeEnd=${date.repairStartTimeEnd}`">{{ topData.totalNum }}</a></div>
  66. </div>
  67. <div style="width: 1px;height: 70px;background: #999999;margin:auto;"></div>
  68. <div style="width:48%;margin:auto; font-size:26px;line-height: 60px;">
  69. <div>本月维修费用</div>
  70. <div style="font-size:24px;"><a style="color:#3066EC ;" target="_block" :href="`/repair/fee?feeDateStart=${date.searchStartTime}&feeDateEnd=${date.searchEndTime}`">{{ topData.totalFee }}</a></div>
  71. </div>
  72. </div>
  73. </a-col>
  74. </a-row>
  75. </div>
  76. <div class="gutter-example">
  77. <a-row :gutter="[20,40]">
  78. <a-col class="gutter-row" :span="8">
  79. <div style="height: 471px;background: #FFFFFF;padding:24px">
  80. <div style="display:flex;justify-content: space-between;width:160px;height: 18px; font-size:16px;color: #555555; ">
  81. <div>维修费用类别统计</div>
  82. </div>
  83. <div id="container-pie"></div>
  84. </div>
  85. </a-col>
  86. <a-col class="gutter-row" :span="12">
  87. <div style="height: 471px;background: #FFFFFF; padding:24px;">
  88. <div style="display:flex;justify-content: space-between;width:190px;height: 18px; font-size:16px;color: #555555; margin-bottom:80px;">
  89. <div style="width: 7px;background: #4D86ED;"></div>
  90. <div>近一周每日产生维修单数</div>
  91. </div>
  92. <div id="container-line"></div>
  93. </div>
  94. </a-col>
  95. <a-col class="gutter-row" :span="4">
  96. <div style="height: 471px;display:flex;flex-direction:column;justify-content: space-between">
  97. <a style="color:#fff;" target="_block" href="/repair/form/mine?type=1">
  98. <div class="btn" style="background:linear-gradient(to right,#36B5FA,#3066EC);" >
  99. <my-icon type="icon-weixiu" style="font-size:58px;"/>
  100. <span>维修</span>
  101. </div>
  102. </a>
  103. <div class="btn" style="background:linear-gradient(to right,#36B5FA,#3066EC);" @click="$refs.repairForm.base({},{filter: -1})">
  104. <my-icon type="icon-baoxiu-xuanzhong-copy" style="font-size:58px;color:#fff;"/>
  105. <span>报修</span>
  106. </div>
  107. <div class="btn" style="background:linear-gradient(to right,#36B5FA,#3066EC);" @click="$refs.sparePickForm.base()">
  108. <my-icon type="icon-tubiaozhizuomoban-copy" style="font-size:58px;color:#fff;"/>
  109. <span>领用</span>
  110. </div>
  111. <div class="btn" style="background:linear-gradient(to right,#36B5FA,#3066EC);" @click="$refs.sparebackform.base()">
  112. <!-- <my-icon type="icon-tuiku" style="font-size:58px; color:#fff;"/> -->
  113. <img src="@/assets/tuiku.png" width="60px" alt="">
  114. <span>退库</span>
  115. </div>
  116. </div>
  117. </a-col>
  118. </a-row>
  119. </div>
  120. <div class="gutter-example">
  121. <a-row :gutter="20">
  122. <a-col class="gutter-row" :span="6">
  123. <div class="information">
  124. <div style="display:flex;justify-content: space-between;align-items: center; padding-bottom:20px;">
  125. <div style="display:flex; width:65px;height:17px;justify-content: space-between;align-items: center;">
  126. <div style=" width: 17px;height: 17px;background: #3462FD;border-radius: 50%;"></div>
  127. <div style="font-size: 18px;font-weight: 800;color: #333333;">资料</div>
  128. </div>
  129. <div>
  130. <a href="/operate/article/Article" target="_block"> 查看全部
  131. <my-icon type="icon-xiangyou-copy" style="font-size:13px;"/></a>
  132. </div>
  133. </div>
  134. <div
  135. class="demo-infinite-container"
  136. >
  137. <a-list size="small" bordered :data-source="information">
  138. <a-list-item slot="renderItem" slot-scope="item,index" :class="{discolor: index%2}">
  139. <a-list-item-meta @click="handleView(item)" >
  140. <div slot="title" style="cursor:pointer">{{ item.title }}</div>
  141. </a-list-item-meta>
  142. <div>{{ item.updateTime }}</div>
  143. </a-list-item>
  144. </a-list>
  145. </div>
  146. </div>
  147. </a-col>
  148. <a-col class="gutter-row" :span="18">
  149. <div class="information">
  150. <div style="display:flex;justify-content: space-between;align-items: center; padding-bottom:20px;">
  151. <div style="display:flex; width:65px;height:17px;justify-content: space-between;align-items: center;">
  152. <div style=" width: 17px;height: 17px;background: #3462FD;border-radius: 50%;"></div>
  153. <div style="font-size: 18px;font-weight: 800;color: #333333;">通知</div>
  154. </div>
  155. <a href="WorkplaceBacklog" target="_block">
  156. 查看全部
  157. <my-icon type="icon-xiangyou-copy" style="font-size:13px;"/>
  158. </a>
  159. </div>
  160. <s-table
  161. ref="table"
  162. size="small"
  163. bordered
  164. rowKey="id"
  165. :columns="columns"
  166. :data="loadData"
  167. :pageSize="10"
  168. :scroll="{ y: 400 }"
  169. >
  170. <span slot="action" slot-scope="record">
  171. <template>
  172. <a @click="handle(record)">详情</a>
  173. <a-divider v-if="record.status === 1" type="vertical" />
  174. <a v-if="record.status === 1" @click="dealJumpDetail(record)">跳转</a>
  175. </template>
  176. </span>
  177. <span slot="content" slot-scope="text" v-html="text">
  178. </span>
  179. </s-table>
  180. </div>
  181. </a-col>
  182. </a-row>
  183. </div>
  184. <detail ref="detailModal"></detail>
  185. <repair-form ref="repairForm"></repair-form>
  186. <SparePickForm ref="sparePickForm"></SparePickForm>
  187. <SpareBackForm ref="sparebackform"></SpareBackForm>
  188. </div>
  189. </template>
  190. <script>
  191. import { STable } from '@/components'
  192. import Detail from '@/views/operate/article/modules/Detail.vue'
  193. import RepairForm from '@/views/repair/application-form/modules/BaseForm.vue'
  194. import SpareBackForm from '@/views/store/sparebackform/modules/BaseForm'
  195. import SparePickForm from '@/views/store/sparepickform/modules/BaseForm'
  196. import { getArticlePage, fetchArticle } from '@/api/operate/article'
  197. import { getWorkplaceBacklogUserPage, getWorkplaceBacklogTopData, getWorkplaceBacklogWeekData, getWorkplaceBacklogPie } from '@/api/workplace/backlog'
  198. import { getCalendarNotice } from '@/api/repair/application-form'
  199. import { Chart } from '@antv/g2'
  200. import cookie from 'vue-cookie'
  201. export default {
  202. name: 'NewWorkplaceBacklog',
  203. components: {
  204. STable,
  205. Detail,
  206. SparePickForm,
  207. SpareBackForm,
  208. RepairForm,
  209. Chart
  210. },
  211. data () {
  212. return {
  213. equipmentData: [],
  214. lineData: [],
  215. allCount: 100,
  216. chartPie: null,
  217. chartLine: null,
  218. topData: null,
  219. type: this.$route.query.type,
  220. date: {
  221. repairStartTimeStart: '',
  222. repairStartTimeEnd: '',
  223. searchStartTime: '',
  224. searchEndTime: ''
  225. },
  226. queryParam: {
  227. status: 1
  228. },
  229. information: [
  230. ],
  231. columns: [
  232. {
  233. title: '序号',
  234. dataIndex: 'index',
  235. align: 'center',
  236. width: 50,
  237. customRender: (text, record, index) => {
  238. return `${(this.$refs.table.localPagination.current - 1) * this.$refs.table.localPagination.pageSize + index + 1}`
  239. }
  240. },
  241. {
  242. title: '类型',
  243. dataIndex: 'type',
  244. align: 'center',
  245. width: 100,
  246. customRender: (text, record, index) => {
  247. return this.typeDict[text]
  248. }
  249. },
  250. {
  251. title: '详细类型',
  252. dataIndex: 'detailType',
  253. align: 'center',
  254. width: 140,
  255. customRender: (text, record, index) => {
  256. return this.typeDetailDict[text]
  257. }
  258. },
  259. {
  260. title: '内容',
  261. dataIndex: 'content',
  262. align: 'center',
  263. width: 460,
  264. ellipsis: true,
  265. scopedSlots: { customRender: 'content' }
  266. },
  267. {
  268. title: '时间',
  269. align: 'center',
  270. width: 160,
  271. dataIndex: 'createdTime'
  272. },
  273. {
  274. title: '状态',
  275. align: 'center',
  276. dataIndex: 'status',
  277. width: 100,
  278. customRender: (text, record, index) => {
  279. return (text === 1 ? '未读' : '已读')
  280. }
  281. },
  282. {
  283. title: '操作',
  284. key: 'action',
  285. width: 150,
  286. align: 'center',
  287. scopedSlots: { customRender: 'action' }
  288. }
  289. ],
  290. // 加载数据方法 必须为 Promise 对象
  291. loadData: parameter => {
  292. parameter = {
  293. ...parameter,
  294. ...this.queryParam
  295. }
  296. return getWorkplaceBacklogUserPage(parameter)
  297. .then(res => {
  298. return res.data
  299. })
  300. }
  301. }
  302. },
  303. computed: {
  304. role () {
  305. if (this.$store.state.user.roles.join().includes('workplace-repair-manage')) {
  306. return 'workplace-repair-manage'
  307. } else if (this.$store.state.user.roles.join().includes('workplace-repair-normal')) {
  308. return 'workplace-repair-normal'
  309. } else {
  310. return 'undifined'
  311. }
  312. }
  313. },
  314. created () {
  315. this.getdate()
  316. console.log(this.date)
  317. this.getDict()
  318. this.getInfo()
  319. this.toCalendar()
  320. },
  321. mounted () {
  322. },
  323. updated () {
  324. console.log(11)
  325. if (this.lineData.length > 0 && this.equipmentData.length > 0) {
  326. this.$nextTick(function () {
  327. console.log(1111)
  328. this.getPieCharts('container-pie')
  329. this.getLineCharts('container-line')
  330. })
  331. }
  332. },
  333. methods: {
  334. getdate () {
  335. const date = new Date()
  336. const year = date.getFullYear()
  337. const month = date.getMonth()
  338. this.date = {
  339. repairStartTimeStart: `${year}-0${month + 1}-01 00:00:00`,
  340. repairStartTimeEnd: this.BaseTool.Date.formatter(date, this.BaseTool.Date.PICKER_NORM_DATETIME_PATTERN),
  341. searchStartTime: `${year}-0${month + 1}-01`,
  342. searchEndTime: this.BaseTool.Date.formatter(date, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN)
  343. }
  344. },
  345. getDict () {
  346. this.typeDict = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.WORKPLACE_BACKLOG_TYPE)
  347. this.typeDetailDict = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.WORKPLACE_BACKLOG_DETAIL_TYPE)
  348. },
  349. getInfo () {
  350. if (this.role === 'undifined') {
  351. // this.$error('您的角色未赋予该权限')
  352. alert('您的角色未赋予该权限')
  353. this.$router.push({ path: '/WorkplaceBacklog' })
  354. }
  355. getWorkplaceBacklogWeekData(this.role).then(res => {
  356. const data = res.data.reduce((pre, item) => {
  357. pre.push({
  358. week: item.weekDayName,
  359. value: item.tempTotalNum
  360. })
  361. return pre
  362. }, [])
  363. this.lineData = data
  364. })
  365. getWorkplaceBacklogPie(this.role).then(res => {
  366. const data = res.data.reduce((pre, item) => {
  367. pre.push({
  368. item: item.typeName,
  369. count: item.fee,
  370. percent: item.fee
  371. })
  372. return pre
  373. }, [])
  374. this.equipmentData = data
  375. })
  376. getWorkplaceBacklogTopData(this.role).then(res => {
  377. this.topData = res.data
  378. })
  379. getArticlePage({
  380. pageNum: 1,
  381. pageSize: 10,
  382. dataScope: {
  383. sortBy: 'desc',
  384. sortName: 'update_time'
  385. }
  386. }).then(res => {
  387. this.information = res.data.rows
  388. })
  389. },
  390. handleView (record) {
  391. fetchArticle({ id: record.id }).then(res => {
  392. const modal = this.$refs.detailModal
  393. modal.base(res.data)
  394. })
  395. },
  396. getPieCharts (id) {
  397. this.chartPie && this.chartPie.destroy()// 防止点击搜索按钮新增一个
  398. this.chartPie = new Chart({
  399. container: id,
  400. autoFit: true,
  401. height: 400
  402. })
  403. this.chartPie.data(this.equipmentData)
  404. this.chartPie.scale('count', {
  405. nice: true
  406. })
  407. this.chartPie.coordinate('theta', {
  408. radius: 0.6,
  409. innerRadius: 0.5
  410. })
  411. this.chartPie.tooltip({
  412. showTitle: false,
  413. showMarkers: false,
  414. itemTpl: `<li class="g2-tooltip-list-item">
  415. <span style="background-color:{color};" class="g2-tooltip-marker"></span>
  416. {name}: {value}
  417. </li>`
  418. })
  419. // 辅助文本
  420. this.chartPie
  421. .annotation()
  422. this.chartPie
  423. .interval()
  424. .adjust('stack')
  425. .position('percent')
  426. .color('item')
  427. .label('percent', (percent) => {
  428. return {
  429. content: (data) => {
  430. return `${data.item}: ${percent}`
  431. }
  432. }
  433. })
  434. .tooltip('item*count', (item, count) => {
  435. return {
  436. name: item,
  437. value: count
  438. }
  439. })
  440. // this.chartPie.interaction('element-active')
  441. this.chartPie.interaction('active-region')
  442. this.chartPie.render()
  443. },
  444. getLineCharts (id) {
  445. this.chartLine = new Chart({
  446. container: id,
  447. autoFit: true,
  448. height: 300
  449. })
  450. this.chartLine.data(this.lineData)
  451. this.chartLine.scale({
  452. value: {
  453. min: 0,
  454. nice: true
  455. }
  456. })
  457. this.chartLine.tooltip({
  458. showCrosshairs: true, // 展示 Tooltip 辅助线
  459. shared: true
  460. })
  461. this.chartLine.axis('value', {
  462. label: {
  463. formatter: (val) => {
  464. return val
  465. }
  466. }
  467. })
  468. this.chartLine.interval().position('week*value').color('week')
  469. this.chartLine.interaction('active-region')
  470. this.chartLine.render()
  471. },
  472. toCalendar () {
  473. const repairTips = cookie.get('repairTips')
  474. if (repairTips === '1') {
  475. getCalendarNotice().then(res => {
  476. const router = this.$router
  477. cookie.set('repairTips', 2, 7)
  478. if (res.data !== null && res.data.length > 0) {
  479. this.$confirm({
  480. title: '提示',
  481. content: () => {
  482. return (<div>
  483. 近一周工单任务如下: <br />
  484. {
  485. res.data.map(item => {
  486. return <div>{item.calendarDate + ' : ' + item.num }</div>
  487. })
  488. }
  489. </div>)
  490. },
  491. okText: '去查看',
  492. icon: 'info-circle',
  493. onOk () {
  494. return new Promise((resolve, reject) => {
  495. router.push({ path: '/repaire/calendar' })
  496. resolve()
  497. }).catch(err => {
  498. this.$message.error({
  499. title: '错误',
  500. description: err.message
  501. })
  502. })
  503. },
  504. onCancel () {}
  505. })
  506. }
  507. })
  508. }
  509. }
  510. }
  511. }
  512. </script>
  513. <style scoped>
  514. .gutter-example >>> .ant-row > div {
  515. background: transparent;
  516. border: 0;
  517. font-family: PingFang SC;
  518. }
  519. .gutter-box {
  520. display:flex;
  521. flex-direction:column;
  522. justify-content: space-between;
  523. background: #fff;
  524. padding: 18px 41px;
  525. height: 170px;
  526. }
  527. .btn{
  528. height: 113px;
  529. width: 100%;
  530. color: #fff!important;
  531. font-size:28px;
  532. border-radius: 20px;
  533. display:flex;
  534. align-items: center;
  535. justify-content: space-around;
  536. }
  537. .btn:hover{
  538. cursor:pointer;
  539. }
  540. .information{
  541. background: #fff;
  542. padding: 30px 12px;
  543. height: 500px;
  544. color:#666;
  545. }
  546. .discolor{
  547. background: #EFEFFB;
  548. }
  549. .demo-infinite-container {
  550. overflow: auto;
  551. height: 400px;
  552. }
  553. /deep/ .ant-table-placeholder{
  554. height:360px;
  555. display: flex;
  556. flex-direction: column;
  557. align-items: center;
  558. justify-content: center;
  559. }
  560. ::-webkit-scrollbar { width: 0; height: 0; color: transparent; }
  561. </style>