StoreWorkplaceBacklog.vue 19 KB

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