packingBom.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. <template>
  2. <view>
  3. <view class="title_box rx-bc">
  4. <view class="name">最小包装单元</view>
  5. <view class="btn_box rx-bc" @click="handCancelPacking">
  6. 重置打包
  7. </view>
  8. </view>
  9. <view class="material ">
  10. <view class="content_table">
  11. <view class="item">
  12. <view class="lable rx-cc">包装总数 </view>
  13. <view class="content content_num">
  14. <input class="uni-input" v-model="formedNumLast" type='digit'></input>
  15. <view class="unit">{{ objData.unit }}</view>
  16. </view>
  17. </view>
  18. <view class="item rx-sc">
  19. <view class="rx ww55 ">
  20. <view class="lable lable150 rx-cc ">最小包装单元</view>
  21. <view class="content content_num">
  22. <input class="uni-input" v-model="quantity"></input>
  23. </view>
  24. </view>
  25. <view class="rx ww45">
  26. <view class="rx-cc ww80">
  27. <view style="max-width: 100rpx; font-size: 24rpx;">{{ objData.unit }}</view>/
  28. </view>
  29. <view class="content rx-sc">
  30. <zxz-uni-data-select :localdata="unitList" v-model="unit" dataValue='Key' format='{Value}'
  31. dataKey="Key" filterable :clear='false'></zxz-uni-data-select>
  32. <view class="penalize" @click="handleSplit">确认</view>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. <view class="content_table2" v-if='splitList.length'>
  38. <view class="head row rx-sc">
  39. <view class="item ww10">序号</view>
  40. <view class="item ww30">数量</view>
  41. <view class="item ww50">条码</view>
  42. <view class="item ww10 jsColor" @click="calculation()" v-if="clientEnvironmentId != 3">计算</view>
  43. <view class="item ww10" v-if="clientEnvironmentId == 3"></view>
  44. </view>
  45. <view class="table">
  46. <u-list @scrolltolower="scrolltolower" class="z_list" style="height: 100% !important;">
  47. <view class="tr row rx-sc" v-for="(it, idx) in splitList" :key='idx'>
  48. <view class="item ww10 rx-cc ">{{ it.computeSize }}</view>
  49. <view class="item ww30 content_num rx-sc">
  50. <input class="uni-input" v-model="it.quantity" type="digit"></input>
  51. <view style="width: 260rpx; font-size: 22rpx;"> {{ objData.unit }}/ {{ it.unit }}</view>
  52. </view>
  53. <view class="item ww50">
  54. {{ it.code }}
  55. </view>
  56. <view class="item ww10 rx-cc" v-if="!it.parentId" @click="handleCheck(idx, it)">
  57. <image class="check" v-if='it.check == 1' src='@/static/check.png'>
  58. </image>
  59. <image class="check" v-if='it.check == 0 || it.check == null'
  60. src='@/static/check_no.png'>
  61. </image>
  62. </view>
  63. </view>
  64. </u-list>
  65. </view>
  66. </view>
  67. </view>
  68. <view class="title_box rx-bc">
  69. <view class="name">内包装</view>
  70. <view class="btn_box rx-bc" @click="handCancelPacking">
  71. 重置打包
  72. </view>
  73. </view>
  74. <view class="material ">
  75. <view class="content_table">
  76. <view class="item">
  77. <view class="lable rx-cc">包装总数 </view>
  78. <view class="content content_num">
  79. <input class="uni-input" v-model="formedNumLast" type='digit'></input>
  80. <view class="unit">{{ objData.unit }}</view>
  81. </view>
  82. </view>
  83. <view class="item rx-sc">
  84. <view class="rx ww55 ">
  85. <view class="lable lable150 rx-cc ">内包装单元</view>
  86. <view class="content content_num">
  87. <input class="uni-input" v-model="quantity"></input>
  88. </view>
  89. </view>
  90. <view class="rx ww45">
  91. <view class="rx-cc ww80">
  92. <view style="max-width: 100rpx; font-size: 24rpx;">{{ objData.unit }}</view>/
  93. </view>
  94. <view class="content rx-sc">
  95. <zxz-uni-data-select :localdata="unitList" v-model="unit" dataValue='Key' format='{Value}'
  96. dataKey="Key" filterable :clear='false'></zxz-uni-data-select>
  97. <view class="penalize" @click="handleSplit">确认</view>
  98. </view>
  99. </view>
  100. </view>
  101. </view>
  102. <view class="content_table2" v-if='splitList.length'>
  103. <view class="head row rx-sc">
  104. <view class="item ww10">序号</view>
  105. <view class="item ww30">数量</view>
  106. <view class="item ww50">条码</view>
  107. <view class="item ww10 jsColor" @click="calculation()" v-if="clientEnvironmentId != 3">计算</view>
  108. <view class="item ww10" v-if="clientEnvironmentId == 3"></view>
  109. </view>
  110. <view class="table">
  111. <u-list @scrolltolower="scrolltolower" class="z_list" style="height: 100% !important;">
  112. <view class="tr row rx-sc" v-for="(it, idx) in splitList" :key='idx'>
  113. <view class="item ww10 rx-cc ">{{ it.computeSize }}</view>
  114. <view class="item ww30 content_num rx-sc">
  115. <input class="uni-input" v-model="it.quantity" type="digit"></input>
  116. <view style="width: 260rpx; font-size: 22rpx;"> {{ objData.unit }}/ {{ it.unit }}</view>
  117. </view>
  118. <view class="item ww50">
  119. {{ it.code }}
  120. </view>
  121. <view class="item ww10 rx-cc" v-if="!it.parentId" @click="handleCheck(idx, it)">
  122. <image class="check" v-if='it.check == 1' src='@/static/check.png'>
  123. </image>
  124. <image class="check" v-if='it.check == 0 || it.check == null'
  125. src='@/static/check_no.png'>
  126. </image>
  127. </view>
  128. </view>
  129. </u-list>
  130. </view>
  131. </view>
  132. </view>
  133. <view class="material ">
  134. <view class="title_box rx-bc">
  135. <view class="name">外包装</view>
  136. </view>
  137. <view class="content_table2" v-if='temporaryList.length'>
  138. <view class="head row rx-sc">
  139. <view class="item ww10">序号</view>
  140. <view class="item ww30">数量</view>
  141. <view class="item ww50">条码</view>
  142. <view class="item ww10"></view>
  143. </view>
  144. <view class="table">
  145. <view class="tr row rx-sc" v-for="(it, idx) in temporaryList" :key='idx'>
  146. <view class="item ww10 rx-cc ">{{ idx + 1 }}</view>
  147. <view class="item ww30 content_num rx-sc">
  148. <input class="uni-input" v-model="it.quantity" disabled type="digit"></input>
  149. <view style="width: 260rpx; font-size: 22rpx;"> {{ objData.unit }}/ {{ it.unit }}</view>
  150. </view>
  151. <view class="item ww50">
  152. {{ it.code }}
  153. </view>
  154. <view class="item ww10 rx-cc">
  155. <uni-icons custom-prefix="iconfont" type="icon-shanchu" size="20" color="#fa3534"
  156. @click="handclose(it)"></uni-icons>
  157. </view>
  158. </view>
  159. <view class="tr row rx-sc">
  160. <view class="item ww10 rx-cc ">合并</view>
  161. <view class="item ww90 rx-sc">
  162. 总共{{ temporaryCount }} {{ objData.unit }} / {{ this.temporaryNum }} {{ unit }}
  163. --打包成 1
  164. <zxz-uni-data-select :localdata="unitList" v-model="packUnit" dataValue='Key'
  165. format='{Value}' dataKey="Key" :clear='false'></zxz-uni-data-select>
  166. <view class="penalize" @click="handlePack">打包</view>
  167. </view>
  168. </view>
  169. </view>
  170. </view>
  171. <!-- 外包装 列表-->
  172. <view class="content_table2" v-if='packTwoList.length > 0'>
  173. <view class="head row rx-sc">
  174. <view class="item ww10">序号</view>
  175. <view class="item ww30">数量</view>
  176. <view class="item ww50">条码</view>
  177. <view class="item ww10"></view>
  178. </view>
  179. <view class="table">
  180. <view class="tr row rx-sc " v-for="(it, idx) in packTwoList" :key='idx'>
  181. <view class="item ww10 rx-cc ">{{ idx + 1 }}</view>
  182. <view class="item ww30 content_num rx-sc">
  183. {{ it.quantity }} {{ objData.unit }} / {{ it.unit }}
  184. </view>
  185. <view class="item ww50">
  186. {{ it.code }}
  187. </view>
  188. <view class="item ww10 rx-cc">
  189. </view>
  190. </view>
  191. </view>
  192. </view>
  193. </view>
  194. <SearchPopup mode="center" v-if='show'>
  195. <template v-slot:list>
  196. <view class="search_list">
  197. <u-form labelPosition="left" :model="formData" labelWidth="180" labelAlign="left" class="baseForm">
  198. <u-form-item label="外包装数:" class="required-form" borderBottom prop="assetType">
  199. <input class="uni-input" v-model="formData.wPackNum" style="width: 280rpx;"
  200. placeholder="外包装数"></input> / {{ splitList[0].unit }}
  201. </u-form-item>
  202. </u-form>
  203. </view>
  204. </template>
  205. <template v-slot:operate>
  206. <view class="operate_box rx-bc">
  207. <u-button size="small" class="u-reset-button" @click="calculationClose()">
  208. 取消
  209. </u-button>
  210. <u-button type="success" size="small" class="u-reset-button" @click="calculationReset()">
  211. 重置
  212. </u-button>
  213. <u-button type="success" size="small" class="u-reset-button" @click="calculationSave()">
  214. 确定
  215. </u-button>
  216. </view>
  217. </template>
  218. </SearchPopup>
  219. </view>
  220. </template>
  221. <script>
  222. import {
  223. getByCode
  224. } from '@/api/pda/common.js'
  225. import {
  226. cancelPacking,
  227. packingReport,
  228. getPackingReport,
  229. packingReportRepeat,
  230. packageDisposition,
  231. getPackingReportRepeat
  232. } from '@/api/pda/workOrder.js'
  233. import SearchPopup from '../../components/searchPopup.vue'
  234. export default {
  235. components: {
  236. SearchPopup
  237. },
  238. props: {
  239. categoryId: {
  240. type: String,
  241. default: ''
  242. },
  243. objData: {
  244. type: Object,
  245. default: () => { }
  246. },
  247. taskId: {
  248. type: String,
  249. default: ''
  250. },
  251. workOrderId: {
  252. type: String,
  253. default: ''
  254. }
  255. },
  256. data() {
  257. return {
  258. formedNumLast: 0,
  259. quantity: '',
  260. unit: '',
  261. unitList: [],
  262. splitList: [],
  263. packUnit: null,
  264. temporaryNum: 0,
  265. temporaryCount: 0,
  266. temporaryList: [],
  267. packTwoList: [],
  268. newCategoryId:'',
  269. show: false,
  270. formData: {
  271. wPackNum: null,
  272. },
  273. clientEnvironmentId: uni.getStorageSync("userInfo") && uni.getStorageSync("userInfo").clientEnvironmentId,
  274. }
  275. },
  276. watch:{
  277. categoryId:{
  278. handler(newVal){
  279. console.log(newVal,'newVal');
  280. this.newCategoryId = newVal;
  281. },
  282. deep:true,
  283. immediate:true
  284. },
  285. },
  286. created() {
  287. this.formedNumLast = this.objData.formedNumLast
  288. this.byCode(),
  289. this.packageDispositionFn();
  290. this.getPackingDetails()
  291. this.getPackingDetailsTwo()
  292. },
  293. methods: {
  294. async packageDispositionFn() {
  295. const res = await packageDisposition(this.newCategoryId)
  296. console.log(res, '1111111');
  297. },
  298. byCode() {
  299. getByCode('packing_unit').then(res => {
  300. this.unitList = []
  301. res.forEach((obj, index) => {
  302. for (let key in obj) {
  303. if (obj.hasOwnProperty(key)) { // 确保key是对象自身的属性
  304. this.unitList.push({
  305. Key: `${key}`,
  306. Value: ` ${obj[key]}`
  307. })
  308. }
  309. }
  310. });
  311. })
  312. },
  313. getPackingDetails() {
  314. let param = {
  315. workOrderId: this.workOrderId,
  316. taskId: this.taskId,
  317. tier: 1
  318. }
  319. getPackingReport(param).then(res => {
  320. this.splitList = res.detailList
  321. this.formedNumLast = res.totalQuantity
  322. this.quantity = res.quantity
  323. this.unit = res.unit
  324. })
  325. },
  326. handCancelPacking() {
  327. uni.showModal({
  328. title: `是否清空包装?`,
  329. content: "",
  330. confirmText: "确认",
  331. success: () => {
  332. let param = {
  333. workOrderId: this.workOrderId,
  334. taskId: this.taskId,
  335. }
  336. cancelPacking(param).then(res => {
  337. this.getPackingDetails()
  338. this.getPackingDetailsTwo()
  339. })
  340. },
  341. })
  342. },
  343. handleSplit() {
  344. if (this.splitList.length) {
  345. uni.showToast({
  346. title: '产品已分包',
  347. icon: 'none'
  348. })
  349. return false
  350. }
  351. if (!this.formedNumLast) {
  352. uni.showToast({
  353. title: '包装总数数量不能为空',
  354. icon: 'none'
  355. })
  356. return false
  357. }
  358. if (!this.quantity) {
  359. uni.showToast({
  360. title: '内包装单元数量不能为空',
  361. icon: 'none'
  362. })
  363. return false
  364. }
  365. if (!this.unit) {
  366. uni.showToast({
  367. title: '请选择包装单位',
  368. icon: 'none'
  369. })
  370. return false
  371. }
  372. let param = {
  373. totalQuantity: this.formedNumLast,
  374. quantity: this.quantity,
  375. unit: this.unit,
  376. workOrderId: this.workOrderId,
  377. taskId: this.taskId,
  378. tier: 1
  379. }
  380. packingReport(param).then(res => {
  381. this.splitList = res.map(m => {
  382. return {
  383. check: false,
  384. ...m
  385. }
  386. })
  387. this.getPackingDetails()
  388. })
  389. },
  390. handleCheck(idx, it) {
  391. if (it.quantity <= 0) {
  392. uni.showToast({
  393. icon: 'none',
  394. title: '数量为空不能勾选'
  395. })
  396. return false
  397. }
  398. this.$set(this.splitList[idx], 'check', it.check ? 0 : 1)
  399. this.temporaryList = []
  400. this.temporaryList = this.splitList.filter(e => {
  401. return e.check == 1
  402. })
  403. this.temporaryNum = 0
  404. this.temporaryCount = 0
  405. if (this.temporaryList.length > 0) {
  406. this.temporaryList.forEach(e => {
  407. this.temporaryNum = this.temporaryNum + 1
  408. this.temporaryCount = this.temporaryCount + Number(e.quantity)
  409. })
  410. }
  411. },
  412. handclose(it) {
  413. this.splitList.forEach(f => {
  414. if (f.computeSize == it.computeSize) {
  415. f.check = 0
  416. }
  417. })
  418. this.temporaryList = []
  419. this.temporaryList = this.splitList.filter(e => {
  420. return e.check == 1
  421. })
  422. },
  423. getPackingDetailsTwo() {
  424. let param = {
  425. totalQuantity: this.formedNumLast,
  426. quantity: this.quantity,
  427. unit: this.unit,
  428. workOrderId: this.workOrderId,
  429. taskId: this.taskId,
  430. tier: 2,
  431. }
  432. getPackingReportRepeat(param).then(res => {
  433. this.packTwoList = res.detailList
  434. })
  435. },
  436. handlePack() {
  437. let _arr = []
  438. _arr = this.temporaryList.map(m => {
  439. return {
  440. ...m,
  441. isChecked: 1
  442. }
  443. })
  444. let param = {
  445. detailList: _arr,
  446. quantity: this.temporaryCount,
  447. totalQuantity: this.formedNumLast,
  448. unit: this.packUnit,
  449. taskId: this.taskId,
  450. workOrderId: this.workOrderId,
  451. tier: 2
  452. }
  453. packingReportRepeat(param).then(res => {
  454. this.temporaryList = []
  455. this.getPackingDetails()
  456. this.getPackingDetailsTwo()
  457. })
  458. },
  459. scrolltolower() {
  460. },
  461. getData() {
  462. let _packingReportMarginList = []
  463. _packingReportMarginList = this.splitList.filter(e => {
  464. return !e.parentId
  465. })
  466. let packInfo = {
  467. packingReportList: this.packTwoList,
  468. packingReportMarginList: _packingReportMarginList,
  469. formedNumLast: this.formedNumLast
  470. }
  471. return packInfo
  472. },
  473. calculation() {
  474. this.show = true
  475. },
  476. calculationSave() {
  477. let count = this.splitList.filter(item => item.isChecked != 1).length;
  478. if (this.formData.wPackNum <= count && count != 0) {
  479. for (let i = 0; i < this.formData.wPackNum; i++) {
  480. this.splitList[i].check = 1
  481. }
  482. this.handleCheck(0, 0)
  483. this.calculationClose()
  484. } else {
  485. if (count != 0) {
  486. for (let i = 0; i < count; i++) {
  487. this.splitList[i].check = 1
  488. }
  489. this.handleCheck(0, 0)
  490. this.calculationClose()
  491. }
  492. uni.showToast({
  493. icon: 'none',
  494. title: '外包装数超出内包装条数'
  495. })
  496. }
  497. },
  498. calculationClose() {
  499. this.show = false
  500. },
  501. calculationReset() {
  502. this.formData.wPackNum = null
  503. this.splitList.forEach(f => {
  504. f.check = null
  505. })
  506. this.temporaryList = []
  507. this.show = false
  508. }
  509. },
  510. }
  511. </script>
  512. <style lang="scss" scoped>
  513. .title_box {
  514. margin-top: 20rpx;
  515. .name {
  516. font-size: 28rpx;
  517. font-style: normal;
  518. font-weight: 400;
  519. color: $theme-color;
  520. padding-left: 20rpx;
  521. position: relative;
  522. &:before {
  523. position: absolute;
  524. content: '';
  525. left: 0rpx;
  526. top: 0rpx;
  527. bottom: 0rpx;
  528. width: 4rpx;
  529. height: 28rpx;
  530. background: $theme-color;
  531. margin: auto;
  532. }
  533. }
  534. .btn_box {
  535. color: $theme-color;
  536. }
  537. }
  538. .material {
  539. margin-top: 10rpx;
  540. .content_table {
  541. width: 100%;
  542. border: 2rpx solid $border-color;
  543. .item {
  544. display: flex;
  545. border-bottom: 2rpx solid $border-color;
  546. .lable {
  547. width: 132rpx;
  548. text-align: center;
  549. background-color: #F7F9FA;
  550. font-size: 26rpx;
  551. border-right: 2rpx solid $border-color;
  552. flex-shrink: 0;
  553. }
  554. .lable220 {
  555. width: 220rpx !important;
  556. font-size: 24rpx;
  557. }
  558. .lable150 {
  559. width: 156rpx !important;
  560. font-size: 24rpx;
  561. }
  562. .ww80 {
  563. width: 80rpx;
  564. }
  565. .content {
  566. width: 518rpx;
  567. min-height: 64rpx;
  568. font-size: 28rpx;
  569. line-height: 28rpx;
  570. font-style: normal;
  571. font-weight: 400;
  572. // padding: 18rpx 8rpx;
  573. box-sizing: border-box;
  574. word-wrap: break-word;
  575. flex-grow: 1 !important;
  576. .unit {
  577. padding: 0 4rpx;
  578. font-size: 24rpx;
  579. color: #404446;
  580. }
  581. }
  582. &:last-child {
  583. border-bottom: none;
  584. }
  585. }
  586. .ww55 {
  587. width: 55%;
  588. }
  589. .ww45 {
  590. width: 45%;
  591. }
  592. }
  593. }
  594. .content_table2 {
  595. width: 100%;
  596. margin-top: 16rpx;
  597. .row {
  598. width: 100%;
  599. .item {
  600. color: #404446;
  601. font-size: 28rpx;
  602. padding-left: 12rpx;
  603. }
  604. .color157 {
  605. color: $theme-color;
  606. }
  607. .ww30 {
  608. width: 30%;
  609. }
  610. .ww50 {
  611. width: 50%;
  612. }
  613. .ww90 {
  614. width: 90%;
  615. }
  616. .ww15 {
  617. width: 15%;
  618. }
  619. .ww10 {
  620. width: 10%;
  621. }
  622. .ww30 {
  623. width: 30%;
  624. }
  625. .jsColor {
  626. color: $theme-color;
  627. font-size: 20rpx;
  628. }
  629. }
  630. .head {
  631. height: 64rpx;
  632. background: #F7F9FA;
  633. border-top: 2rpx solid #E3E5E5;
  634. border-left: 2rpx solid #E3E5E5;
  635. .item {
  636. height: 64rpx;
  637. line-height: 64rpx;
  638. border-right: 2rpx solid #E3E5E5;
  639. box-sizing: border-box;
  640. }
  641. }
  642. .tr {
  643. border-top: 2rpx solid #E3E5E5;
  644. border-left: 2rpx solid #E3E5E5;
  645. .item {
  646. font-size: 24rpx;
  647. min-height: 64rpx;
  648. display: flex;
  649. align-items: center;
  650. border-right: 2rpx solid #E3E5E5;
  651. box-sizing: border-box;
  652. white-space: normal;
  653. word-break: break-all;
  654. }
  655. &:last-child {
  656. border-bottom: 2rpx solid #E3E5E5;
  657. }
  658. }
  659. }
  660. .content_num {
  661. display: flex;
  662. align-items: center;
  663. padding: 0 4rpx;
  664. /deep/ .uni-input-input {
  665. border: 2rpx solid #F0F8F2;
  666. background: #F0F8F2;
  667. color: $theme-color;
  668. }
  669. }
  670. .penalize {
  671. width: 86rpx;
  672. line-height: 60rpx;
  673. background: $theme-color;
  674. font-size: 24rpx;
  675. text-align: center;
  676. color: #fff;
  677. }
  678. .check {
  679. width: 30rpx;
  680. height: 30rpx;
  681. }
  682. .z_list {
  683. max-height: 500rpx;
  684. }
  685. .search_list {
  686. min-height: 100rpx;
  687. width: 80vw;
  688. /deep/ .baseForm {
  689. padding: 0 20rpx;
  690. }
  691. }
  692. .operate_box {
  693. padding: 10rpx 32rpx;
  694. /deep/ .u-button {
  695. width: 30%;
  696. }
  697. }
  698. </style>