approve_approve_allot.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. <template>
  2. <!-- 报损报溢 -->
  3. <view class="plan-approval-container">
  4. <uni-nav-bar
  5. fixed="true"
  6. statusBar="true"
  7. left-icon="back"
  8. title="报损报溢审批详情"
  9. @clickLeft="back"
  10. ></uni-nav-bar>
  11. <template>
  12. <view class="tab-title">
  13. <view
  14. class="tab-item"
  15. :class="0 === pickTabIndex ? 'active' : ''"
  16. @click="changeChartsTab(0)"
  17. >基本信息
  18. </view>
  19. <view
  20. class="tab-item"
  21. :class="1 === pickTabIndex ? 'active' : ''"
  22. @click="changeChartsTab(1)"
  23. >
  24. 报损报溢明细
  25. </view>
  26. </view>
  27. </template>
  28. <view class="content">
  29. <!-- 基本信息 -->
  30. <view class="baseinfo" v-if="pickTabIndex === 0">
  31. <view class="col">
  32. <text class="label">报损报溢单号</text>
  33. <text class="desc">{{ baseInfo.code }}</text>
  34. </view>
  35. <view class="col">
  36. <text class="label">名称</text>
  37. <text class="desc">{{ baseInfo.name }}</text>
  38. </view>
  39. <view class="col">
  40. <text class="label">仓库</text>
  41. <text class="desc">{{ baseInfo.warehouseName }}</text>
  42. </view>
  43. <view class="col">
  44. <text class="label">报损报溢人</text>
  45. <text class="desc">{{ baseInfo.reportName }}</text>
  46. </view>
  47. <view class="col">
  48. <text class="label">报损报溢部门</text>
  49. <text class="desc">{{ baseInfo.reportDeptName }}</text>
  50. </view>
  51. <view class="col">
  52. <text class="label">创建时间</text>
  53. <text class="desc">{{ baseInfo.createTime }}</text>
  54. </view>
  55. <view class="col">
  56. <text class="label">备注</text>
  57. <text class="desc">{{ baseInfo.remark }}</text>
  58. </view>
  59. </view>
  60. <view class="equipment" v-if="pickTabIndex === 1">
  61. <uni-collapse accordion v-model="accordionVal">
  62. <uni-collapse-item :show-animation="true" :open="false" :typeOpen="1">
  63. <template v-slot:title>
  64. <view class="collapse-title">
  65. 报损明细
  66. <text> 数量 {{ bsList.length }} </text>
  67. </view>
  68. </template>
  69. <view class="collapse-item-wrapper">
  70. <view
  71. class="info-container"
  72. v-for="(item, index) in bsList"
  73. :key="index"
  74. >
  75. <view class="col">
  76. <text class="label">编码</text>
  77. <text class="desc">{{ item.code }}</text>
  78. </view>
  79. <view class="col">
  80. <text class="label">名称</text>
  81. <text class="desc">{{ item.name }}</text>
  82. </view>
  83. <view class="col">
  84. <text class="label">类型</text>
  85. <text class="desc">{{
  86. getDictValue('物品类型', item.productType)
  87. }}</text>
  88. </view>
  89. <view class="col">
  90. <text class="label">批次号</text>
  91. <text class="desc">{{ item.batch }}</text>
  92. </view>
  93. <view
  94. class="col"
  95. v-for="(itm, index) in tableHeader"
  96. :key="index"
  97. >
  98. <text class="label">{{ itm.label }}</text>
  99. <text class="desc">
  100. <template v-if="itm.formatter">
  101. {{ itm.formatter(item) }}
  102. </template>
  103. <template v-else>
  104. {{ item[itm.prop] }}
  105. </template></text
  106. >
  107. </view>
  108. <!-- <view class="col">
  109. <text class="label">包装编码</text>
  110. <text class="desc">{{ item.num }}</text>
  111. </view> -->
  112. <view class="col">
  113. <text class="label">最小单元</text>
  114. <text class="desc"
  115. >{{ item.measurementUnit }} {{ item.unit }}/{{
  116. item.minPackUnit || item.minimumUnit
  117. }}</text
  118. >
  119. </view>
  120. </view>
  121. </view>
  122. </uni-collapse-item>
  123. </uni-collapse>
  124. <uni-collapse accordion v-model="accordionVal2">
  125. <uni-collapse-item :show-animation="true" :open="false" :typeOpen="1">
  126. <template v-slot:title>
  127. <view class="collapse-title">
  128. 报溢明细
  129. <text> 数量 {{ byList.length }} </text>
  130. </view>
  131. </template>
  132. <view class="collapse-item-wrapper">
  133. <view
  134. class="info-container"
  135. v-for="(item, index) in byList"
  136. :key="index"
  137. >
  138. <view class="col">
  139. <text class="label">编码</text>
  140. <text class="desc">{{ item.code }}</text>
  141. </view>
  142. <view class="col">
  143. <text class="label">名称</text>
  144. <text class="desc">{{ item.name }}</text>
  145. </view>
  146. <view class="col">
  147. <text class="label">类型</text>
  148. <text class="desc">{{
  149. getDictValue('物品类型', item.productType)
  150. }}</text>
  151. </view>
  152. <view class="col">
  153. <text class="label">批次号</text>
  154. <text class="desc">{{ item.batch }}</text>
  155. </view>
  156. <view
  157. class="col"
  158. v-for="(itm, index) in tableHeader"
  159. :key="index"
  160. >
  161. <text class="label">{{ itm.label }}</text>
  162. <text class="desc">
  163. <template v-if="itm.formatter">
  164. {{ itm.formatter(item) }}
  165. </template>
  166. <template v-else>
  167. {{ item[itm.prop] }}
  168. </template></text
  169. >
  170. </view>
  171. <!-- <view class="col">
  172. <text class="label">包装编码</text>
  173. <text class="desc">{{ item.num }}</text>
  174. </view> -->
  175. <view class="col">
  176. <text class="label">最小单元</text>
  177. <text class="desc"
  178. >{{ item.measurementUnit }} {{ item.unit }}/{{
  179. item.minPackUnit || item.minimumUnit
  180. }}</text
  181. >
  182. </view>
  183. </view>
  184. </view>
  185. </uni-collapse-item>
  186. </uni-collapse>
  187. </view>
  188. </view>
  189. <view class="approval-container" v-if="isApproval && baseInfo.status == 1">
  190. <view class="approval_btn-wrapper">
  191. <text class="approval-btn refuse" @click="handleRefuse">驳回</text>
  192. <text class="approval-btn primary" @click="handlePass(true)">通过</text>
  193. </view>
  194. <uni-popup ref="inputDialog" type="dialog">
  195. <uni-popup-dialog
  196. ref="inputClose"
  197. mode="input"
  198. title="驳回原因"
  199. placeholder="请输入内容"
  200. :before-close="true"
  201. @close="handleClose"
  202. @confirm="timeoutCauseConfirm"
  203. ></uni-popup-dialog>
  204. </uni-popup>
  205. </view>
  206. </view>
  207. </template>
  208. <script>
  209. import { post, get, postJ } from '@/utils/api.js'
  210. import Approval from '@/components/Approval.vue'
  211. import Info from './components/Info'
  212. import Content from './components/Content'
  213. import dictMixns from '@/mixins/dictMixins'
  214. export default {
  215. components: {
  216. Approval,
  217. Content,
  218. Info
  219. },
  220. mixins: [dictMixns],
  221. data () {
  222. return {
  223. pickTabIndex: 0,
  224. accordionVal: '',
  225. accordionVal2: '',
  226. options: {
  227. id: '',
  228. workOrderId: '',
  229. planType: '',
  230. devOpsType: ''
  231. },
  232. baseInfo: {},
  233. // 报损
  234. bsList: [],
  235. // 报溢
  236. byList: [],
  237. isApproval: false,
  238. dictOpt: {
  239. bizScene: {
  240. 1: '生产调拨',
  241. 2: '采购调拨',
  242. 3: '赠送调拨',
  243. 4: '借用调拨',
  244. 5: '退还调拨',
  245. 6: '其他调拨'
  246. },
  247. urgent: {
  248. 1: '普通',
  249. 2: '重要',
  250. 3: '紧急'
  251. }
  252. }
  253. }
  254. },
  255. onLoad (options) {
  256. this.options = options
  257. this.isApproval = options.type === 'approval'
  258. // this.requestDict('物品类型')
  259. },
  260. onShow () {
  261. this.bsList = []
  262. this.byList = []
  263. this.getInfo()
  264. },
  265. computed: {
  266. tableHeader () {
  267. return this.getTableHeader(
  268. this.baseInfo.list && this.baseInfo.list[0]?.productType
  269. )
  270. }
  271. },
  272. methods: {
  273. getTableHeader (selectEquiType) {
  274. switch (+selectEquiType) {
  275. case 3:
  276. return [{ label: '牌号', prop: 'brandNum' }]
  277. case 8:
  278. return [
  279. { label: '型号', prop: 'modelType' },
  280. { label: '规格', prop: 'specification' }
  281. ]
  282. case 4:
  283. return [
  284. { label: '牌号', prop: 'brandNum' },
  285. { label: '型号', prop: 'modelType' }
  286. ]
  287. case 5: //'周转车'
  288. return [
  289. { label: '规格', prop: 'specification' },
  290. {
  291. label: '材质',
  292. prop: 'texture',
  293. formatter (row) {
  294. if (!row?.extendField) return ''
  295. const extendField = JSON.parse(row.extendField)
  296. return extendField.texture
  297. }
  298. },
  299. {
  300. label: '长宽高',
  301. prop: '',
  302. formatter (row) {
  303. if (!row?.extendField) return ''
  304. const extendField = JSON.parse(row.extendField)
  305. return `${extendField.length || '-'}*${
  306. extendField.width || '-'
  307. }*${extendField.high || '-'}`
  308. }
  309. }
  310. ]
  311. case 2: //'舟皿'
  312. return [
  313. { label: '规格', prop: 'specification' },
  314. { label: '型号', prop: 'modelType' },
  315. {
  316. label: '长宽高',
  317. prop: '',
  318. formatter (row) {
  319. if (!row?.extendField) return ''
  320. const extendField = JSON.parse(row.extendField)
  321. return `${extendField.length || '-'}*${
  322. extendField.width || '-'
  323. }*${extendField.high || '-'}`
  324. }
  325. }
  326. ]
  327. case 1: //'设备'
  328. return [
  329. { label: '型号', prop: 'modelType' },
  330. { label: '规格', prop: 'specification' }
  331. ]
  332. case 6: //'模具'
  333. return [
  334. { label: '牌号', prop: 'brandNum' },
  335. { label: '型号', prop: 'modelType' },
  336. {
  337. label: '收缩系数',
  338. prop: '',
  339. formatter (row) {
  340. if (!row?.extendField) return ''
  341. const extendField = JSON.parse(row.extendField)
  342. return extendField.shrinkageCoefficient
  343. }
  344. }
  345. ]
  346. case 7: //'备品备件'
  347. return [
  348. { label: '规格', prop: 'specification' },
  349. { label: '型号', prop: 'modelType' }
  350. ]
  351. }
  352. return []
  353. },
  354. //切换选项卡
  355. changeChartsTab (index) {
  356. this.pickTabIndex = index
  357. },
  358. getInfo () {
  359. get(this.apiUrl + `/breakag/info/${this.options.workOrderId}`).then(
  360. res => {
  361. if (res?.success) {
  362. this.baseInfo = res.data
  363. for (let s of res.data.list) {
  364. console.log(s.status)
  365. if (s.status == 1 || s.status == 2) {
  366. this.bsList.push(s)
  367. } else if (s.status == 3) {
  368. this.byList.push(s)
  369. }
  370. }
  371. }
  372. }
  373. )
  374. },
  375. // 审批
  376. handleRefuse () {
  377. this.$refs.inputDialog.open()
  378. },
  379. handleClose () {
  380. this.$refs.inputDialog.close()
  381. },
  382. handlePass (checked, cause) {
  383. const params = {
  384. checked,
  385. handleType: this.options.handleType,
  386. myHandleId: this.options.id,
  387. id: this.options.workOrderId,
  388. type: this.options.planType,
  389. cause
  390. }
  391. postJ(this.apiUrl + '/plan/info/audit', params).then(res => {
  392. if (res?.success) {
  393. uni.navigateTo({
  394. url: `/pages/home/backlog/result?type=${
  395. checked ? 'approve' : 'refuse'
  396. }&status=${this.devOpsType}`
  397. })
  398. }
  399. })
  400. },
  401. timeoutCauseConfirm (value) {
  402. if (!value) {
  403. uni.showToast({
  404. title: '请输入驳回原因',
  405. icon: 'none'
  406. })
  407. return
  408. }
  409. this.handlePass(false, value)
  410. this.$refs.inputDialog.close()
  411. }
  412. // 审批end
  413. }
  414. }
  415. </script>
  416. <style lang="scss" scoped>
  417. .tab-title {
  418. width: 100%;
  419. padding: 0 30rpx;
  420. margin-bottom: 12rpx;
  421. display: flex;
  422. height: $tab-height;
  423. line-height: $tab-height;
  424. background-color: #ffffff;
  425. border-bottom: 1px solid #f2f2f2;
  426. box-sizing: border-box;
  427. .tab-item {
  428. width: 30%;
  429. text-align: center;
  430. font-size: 32rpx;
  431. color: $uni-text-color-grey;
  432. }
  433. .tab-item.active {
  434. color: $j-primary-border-green;
  435. border-bottom: 1px solid $j-primary-border-green;
  436. }
  437. }
  438. .plan-approval-container {
  439. display: flex;
  440. flex-direction: column;
  441. padding-bottom: 80rpx;
  442. /deep/.uni-collapse-item {
  443. background-color: rgba(21, 122, 44, 0.372549019607843);
  444. }
  445. .content {
  446. flex: 1;
  447. overflow: auto;
  448. .baseinfo {
  449. padding: 0 22rpx;
  450. font-size: 28rpx;
  451. .col {
  452. display: flex;
  453. padding: 10rpx 0;
  454. border-bottom: 1rpx dashed #d7d7d7;
  455. .label {
  456. display: inline-block;
  457. width: 250rpx;
  458. text-align: right;
  459. margin-right: 20rpx;
  460. font-weight: bold;
  461. }
  462. .desc {
  463. flex: 1;
  464. word-break: break-all;
  465. }
  466. }
  467. }
  468. }
  469. .collapse-title {
  470. display: flex;
  471. justify-content: space-between;
  472. align-items: center;
  473. font-size: 28rpx;
  474. height: 80rpx;
  475. padding: 8rpx;
  476. box-sizing: border-box;
  477. }
  478. .collapse-item-wrapper {
  479. padding: 12rpx;
  480. .info-container {
  481. margin-bottom: 20rpx;
  482. display: flex;
  483. flex-wrap: wrap;
  484. border: 1px solid #f2f2f2;
  485. padding: 30rpx;
  486. .col {
  487. width: 50%;
  488. &.row {
  489. width: 100%;
  490. }
  491. }
  492. }
  493. }
  494. }
  495. .pd-list-item {
  496. padding: 10rpx;
  497. border-bottom: 1px solid #d7d7d7;
  498. .item {
  499. display: flex;
  500. font-size: 28rpx;
  501. justify-content: space-between;
  502. padding: 10rpx;
  503. }
  504. }
  505. .info-container {
  506. padding: 0 20rpx;
  507. .col {
  508. border-bottom: 1rpx dashed #7d7d7d;
  509. padding: 10rpx 0;
  510. display: flex;
  511. .label {
  512. width: 120rpx;
  513. text-align: right;
  514. margin-right: 28rpx;
  515. color: #333;
  516. font-weight: bold;
  517. }
  518. .desc {
  519. word-break: break-all;
  520. flex: 1;
  521. }
  522. }
  523. }
  524. .approval-container {
  525. width: 100vw;
  526. height: 80rpx;
  527. .approval_btn-wrapper {
  528. display: flex;
  529. position: fixed;
  530. bottom: 0;
  531. width: 100vw;
  532. height: 80rpx;
  533. background-color: #fff;
  534. }
  535. .approval-btn {
  536. flex: 1;
  537. line-height: 78rpx;
  538. text-align: center;
  539. border: 1rpx solid $j-primary-border-green;
  540. &.refuse {
  541. color: red;
  542. }
  543. &.primary {
  544. background-color: $j-primary-border-green;
  545. color: #fff;
  546. }
  547. }
  548. }
  549. </style>