approve_out.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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.bizNum }}</text>
  34. </view>
  35. <!-- <view class="col">
  36. <text class="label">来源类型</text>
  37. <text class="desc">{{ baseInfo.planName }}</text>
  38. </view> -->
  39. <view class="col">
  40. <text class="label">来源单号</text>
  41. <text class="desc">{{ baseInfo.documentSource }}</text>
  42. </view>
  43. <view class="col">
  44. <text class="label">出库场景</text>
  45. <text class="desc">{{ dictOpt.bizScene[baseInfo.bizScene] }}</text>
  46. </view>
  47. <view class="col">
  48. <text class="label">出库登记人</text>
  49. <text class="desc">{{ baseInfo.createUserName }}</text>
  50. </view>
  51. <!-- <view class="col">
  52. <text class="label">领用部门</text>
  53. <text class="desc">{{ baseInfo.supplierName }}</text>
  54. </view> -->
  55. <view class="col">
  56. <text class="label">领用人</text>
  57. <text class="desc">{{ baseInfo.deliveryName }}</text>
  58. </view>
  59. <view class="col">
  60. <text class="label">审核人</text>
  61. <text class="desc">{{ baseInfo.verifyName }}</text>
  62. </view>
  63. <view class="col">
  64. <text class="label">紧急状态</text>
  65. <text class="desc">{{ dictOpt.urgent[baseInfo.urgent] }}</text>
  66. </view>
  67. <view class="col">
  68. <text class="label">出库时间</text>
  69. <text class="desc">{{ baseInfo.verifyTime }}</text>
  70. </view>
  71. <view class="col">
  72. <text class="label">备注</text>
  73. <text class="desc">{{ baseInfo.remark }}</text>
  74. </view>
  75. </view>
  76. <view class="equipment" v-if="pickTabIndex === 1">
  77. <uni-collapse accordion v-model="accordionVal">
  78. <uni-collapse-item
  79. v-for="(item, index) in planEquiList"
  80. :show-animation="true"
  81. :key="index"
  82. :open="false"
  83. :typeOpen="1"
  84. >
  85. <template v-slot:title>
  86. <view class="collapse-title">
  87. {{ item.assetName }}({{ item.assetCode }})
  88. <text style="white-space: nowrap">
  89. {{ item.warehouseLedgerDetails.length
  90. }}{{ item.isUnpack ? item.unit : item.minPackUnit }}
  91. </text>
  92. </view>
  93. </template>
  94. <view class="collapse-item-wrapper">
  95. <view class="info-container">
  96. <view class="col">
  97. <text class="before">类型</text>
  98. <text class="desc">{{
  99. getDictValue('物品类型', item.assetType)
  100. }}</text>
  101. </view>
  102. <view class="col">
  103. <text class="label">出库数量</text>
  104. <view class="desc">
  105. <!-- <text
  106. >{{ item.outInNum
  107. }}{{ item.isUnpack ? item.unit : item.minPackUnit }}
  108. </text> -->
  109. <text style="margin-right: 20rpx"
  110. >{{ item.selfSum }} {{ item.unit }}</text
  111. >
  112. <template v-if="!item.isUnpack"
  113. >{{ item.outInNum }}{{ item.minPackUnit }}</template
  114. >
  115. <!-- <text style="margin-left: 20rpx;">{{item.outInNum*item.measurementUnit}} {{item.unit}}</text> -->
  116. </view>
  117. </view>
  118. <view
  119. class="col"
  120. v-for="(itm, index) in tableHeader"
  121. :key="index"
  122. >
  123. <text class="label">{{ itm.label }}</text>
  124. <text class="desc">{{ item[itm.prop] }}</text>
  125. </view>
  126. </view>
  127. <uni-table
  128. border
  129. stripe
  130. emptyText="暂无更多数据"
  131. style="margin-top: 30rpx"
  132. >
  133. <!-- 表头行 -->
  134. <uni-tr>
  135. <uni-th align="left" width="240rpx"
  136. >{{ getDictValue('物品类型', item.assetType) }}编码</uni-th
  137. >
  138. <uni-th align="left" width="240rpx">批次号</uni-th>
  139. <uni-th align="left" width="170rpx" v-if="!item.isUnpack"
  140. >最小单元</uni-th
  141. >
  142. <uni-th align="left" width="170rpx">生产日期</uni-th>
  143. <uni-th align="left" width="170rpx">货位</uni-th>
  144. <uni-th align="left" width="170rpx">包装编号</uni-th>
  145. </uni-tr>
  146. <!-- 表格数据行 -->
  147. <uni-tr
  148. v-for="(el, index) in item.warehouseLedgerDetails"
  149. :key="index"
  150. >
  151. <uni-td>
  152. {{ el.onlyCode }}
  153. </uni-td>
  154. <uni-td>
  155. {{ el.batchNum }}
  156. </uni-td>
  157. <uni-td v-if="!item.isUnpack"
  158. >{{ el.measurementUnit }} {{ el.unit }} /{{
  159. el.minPackUnit
  160. }}</uni-td
  161. >
  162. <uni-td>{{
  163. el.manufactureTime || el.procurementTime
  164. }}</uni-td>
  165. <uni-td
  166. >{{ el.warehouseName }}-{{ el.areaName }}-{{
  167. el.shelfCode
  168. }}-{{ el.cargoSpaceCode }}</uni-td
  169. >
  170. <uni-td>{{ el.num }}</uni-td>
  171. </uni-tr>
  172. </uni-table>
  173. </view>
  174. </uni-collapse-item>
  175. </uni-collapse>
  176. </view>
  177. </view>
  178. <view
  179. class="approval-container"
  180. v-if="isApproval && baseInfo.verifyStatus === 1"
  181. >
  182. <view class="approval_btn-wrapper">
  183. <text class="approval-btn refuse" @click="handleRefuse">驳回</text>
  184. <text class="approval-btn primary" @click="handlePass(true)">通过</text>
  185. </view>
  186. <uni-popup ref="inputDialog" type="dialog">
  187. <uni-popup-dialog
  188. ref="inputClose"
  189. mode="input"
  190. title="驳回原因"
  191. placeholder="请输入内容"
  192. :before-close="true"
  193. @close="handleClose"
  194. @confirm="timeoutCauseConfirm"
  195. ></uni-popup-dialog>
  196. </uni-popup>
  197. </view>
  198. </view>
  199. </template>
  200. <script>
  201. import { post, get, postJ } from '@/utils/api.js'
  202. import Approval from '@/components/Approval.vue'
  203. import Info from './components/Info'
  204. import { tableHeader } from '@/pages/warehouse/common.js'
  205. import dictMixin from '@/mixins/dictMixins'
  206. import Content from './components/Content'
  207. export default {
  208. components: {
  209. Approval,
  210. Content,
  211. Info
  212. },
  213. mixins: [dictMixin],
  214. data () {
  215. return {
  216. pickTabIndex: 0,
  217. accordionVal: '',
  218. options: {
  219. id: '',
  220. workOrderId: '',
  221. planType: '',
  222. devOpsType: ''
  223. },
  224. baseInfo: {},
  225. planEquiList: [],
  226. isApproval: false,
  227. dictOpt: {
  228. bizScene: {
  229. 1: '生产出库',
  230. 2: '采购出库',
  231. 3: '赠送出库',
  232. 4: '借用出库',
  233. 5: '退还出库',
  234. 6: '其他出库'
  235. },
  236. urgent: {
  237. 1: '普通',
  238. 2: '重要',
  239. 3: '紧急'
  240. }
  241. }
  242. }
  243. },
  244. onLoad (options) {
  245. this.options = options
  246. this.isApproval = options.type === 'approval'
  247. // this.requestDict('物品类型')
  248. },
  249. onShow () {
  250. this.getInfo()
  251. },
  252. computed: {
  253. tableHeader () {
  254. return tableHeader(this.baseInfo.assetType)
  255. }
  256. },
  257. methods: {
  258. //切换选项卡
  259. changeChartsTab (index) {
  260. this.pickTabIndex = index
  261. },
  262. getInfo () {
  263. get(
  264. this.apiUrl +
  265. `/outInWarehouse/select/detail/${this.options.workOrderId}`
  266. ).then(res => {
  267. if (res?.success) {
  268. this.baseInfo = res.data.outInWarehouse
  269. this.planEquiList = res.data.warehouseLedgerInfos.map(item => {
  270. item.selfSum = (item.warehouseLedgerDetails || []).reduce(
  271. (sum, pre) => {
  272. if (item.isUnpack) {
  273. return ++sum
  274. }
  275. return sum + pre.measurementUnit
  276. },
  277. 0
  278. )
  279. return item
  280. })
  281. }
  282. })
  283. },
  284. // 审批
  285. handleRefuse () {
  286. this.$refs.inputDialog.open()
  287. },
  288. handleClose () {
  289. this.$refs.inputDialog.close()
  290. },
  291. handlePass (checked, cause) {
  292. const params = {
  293. approlId: this.options.id,
  294. handleResult: checked ? 2 : 0,
  295. bizId: this.options.workOrderId,
  296. handleCause: cause,
  297. handleStatus: 1
  298. }
  299. postJ(this.apiUrl + '/outInWarehouse/changeStatus', params).then(res => {
  300. if (res?.success) {
  301. uni.navigateTo({
  302. url: `/pages/home/backlog/result?type=${
  303. checked ? 'approve' : 'refuse'
  304. }&status=${this.devOpsType}`
  305. })
  306. }
  307. })
  308. },
  309. timeoutCauseConfirm (value) {
  310. if (!value) {
  311. uni.showToast({
  312. title: '请输入驳回原因',
  313. icon: 'none'
  314. })
  315. return
  316. }
  317. this.handlePass(false, value)
  318. this.$refs.inputDialog.close()
  319. }
  320. // 审批end
  321. }
  322. }
  323. </script>
  324. <style lang="scss" scoped>
  325. .tab-title {
  326. width: 100%;
  327. padding: 0 30rpx;
  328. margin-bottom: 12rpx;
  329. display: flex;
  330. height: $tab-height;
  331. line-height: $tab-height;
  332. background-color: #ffffff;
  333. border-bottom: 1px solid #f2f2f2;
  334. box-sizing: border-box;
  335. .tab-item {
  336. width: 30%;
  337. text-align: center;
  338. font-size: 32rpx;
  339. color: $uni-text-color-grey;
  340. }
  341. .tab-item.active {
  342. color: $j-primary-border-green;
  343. border-bottom: 1px solid $j-primary-border-green;
  344. }
  345. }
  346. .plan-approval-container {
  347. display: flex;
  348. flex-direction: column;
  349. padding-bottom: 80rpx;
  350. /deep/.uni-collapse-item {
  351. background-color: rgba(21, 122, 44, 0.372549019607843);
  352. }
  353. .content {
  354. flex: 1;
  355. overflow: auto;
  356. .baseinfo {
  357. padding: 0 22rpx;
  358. font-size: 28rpx;
  359. .col {
  360. display: flex;
  361. padding: 10rpx 0;
  362. border-bottom: 1rpx dashed #d7d7d7;
  363. .label {
  364. display: inline-block;
  365. width: 200rpx;
  366. text-align: right;
  367. margin-right: 20rpx;
  368. font-weight: bold;
  369. }
  370. .desc {
  371. flex: 1;
  372. word-break: break-all;
  373. }
  374. }
  375. }
  376. }
  377. .collapse-title {
  378. display: flex;
  379. justify-content: space-between;
  380. align-items: center;
  381. font-size: 28rpx;
  382. height: 80rpx;
  383. padding: 8rpx;
  384. box-sizing: border-box;
  385. }
  386. .collapse-item-wrapper {
  387. padding: 12rpx;
  388. .info-container {
  389. margin-bottom: 20rpx;
  390. display: flex;
  391. flex-wrap: wrap;
  392. .col {
  393. width: 50%;
  394. &.row {
  395. width: 100%;
  396. }
  397. }
  398. }
  399. }
  400. }
  401. .pd-list-item {
  402. padding: 10rpx;
  403. border-bottom: 1px solid #d7d7d7;
  404. .item {
  405. display: flex;
  406. font-size: 28rpx;
  407. justify-content: space-between;
  408. padding: 10rpx;
  409. }
  410. }
  411. .info-container {
  412. .col {
  413. border-bottom: 1rpx dashed #7d7d7d;
  414. padding: 10rpx 0;
  415. display: flex;
  416. .before {
  417. width: 90rpx;
  418. text-align: right;
  419. margin-right: 28rpx;
  420. color: #333;
  421. font-weight: bold;
  422. }
  423. .label {
  424. width: 130rpx;
  425. text-align: right;
  426. margin-right: 28rpx;
  427. color: #333;
  428. font-weight: bold;
  429. }
  430. .desc {
  431. flex: 1;
  432. }
  433. }
  434. }
  435. .approval-container {
  436. width: 100vw;
  437. height: 80rpx;
  438. .approval_btn-wrapper {
  439. display: flex;
  440. position: fixed;
  441. bottom: 0;
  442. width: 100vw;
  443. height: 80rpx;
  444. background-color: #fff;
  445. }
  446. .approval-btn {
  447. flex: 1;
  448. line-height: 78rpx;
  449. text-align: center;
  450. border: 1rpx solid $j-primary-border-green;
  451. &.refuse {
  452. color: red;
  453. }
  454. &.primary {
  455. background-color: $j-primary-border-green;
  456. color: #fff;
  457. }
  458. }
  459. }
  460. </style>