index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. <template>
  2. <view class="p-content">
  3. <view class="p-head" v-if="baseData">
  4. <view>
  5. <view>
  6. <text>采购单号:</text>
  7. <text style="color: crimson;">{{baseData.purchaseBillNo}}</text>
  8. </view>
  9. <view>
  10. <button :disabled="loading" size="mini" type="primary" @click="toOut"> 入库 <text class="iconfont icon-icon-test43"></text></button>
  11. </view>
  12. </view>
  13. <view>
  14. <view>
  15. <text>发货单号:</text>
  16. <text style="color: crimson;">{{baseData.sendBillNo}}</text>
  17. </view>
  18. </view>
  19. <view>
  20. <view>
  21. <text>条码:</text>
  22. <view>
  23. <input
  24. @blur="pickFun(true)"
  25. style="width: 100%;text-align: left;"
  26. class="uni-input"
  27. placeholder="扫描或输入条码"
  28. border="surround"
  29. v-model="code">
  30. </view>
  31. </view>
  32. </view>
  33. <view style="justify-content: flex-start;flex-wrap: wrap;" v-if="baseData">
  34. <view>总款数:{{ baseData.totalPutCategory }}</view>
  35. <view>发货数量: {{ baseData.totalPutQty }}</view>
  36. <view>发货金额: {{ baseData.totalPutAmount?toThousands(baseData.totalPutAmount,2):'0.00' }}</view>
  37. <view>入库数量: {{ baseData && (baseData.totalRealPutQty || baseData.totalRealPutQty==0) ? baseData.totalRealPutQty : '--' }}</view>
  38. <view>入库金额: {{ baseData && (baseData.totalRealPutAmount || baseData.totalRealPutAmount==0) ? toThousands(baseData.totalRealPutAmount, 2) : '--' }}</view>
  39. </view>
  40. </view>
  41. <view class="p-body">
  42. <uni-table style="width: 100%;" border emptyText="暂无数据" :loading="loading" >
  43. <!-- 表头行 -->
  44. <uni-tr>
  45. <uni-td align="center">产品编码</uni-td>
  46. <uni-td align="center">仓库仓位</uni-td>
  47. <uni-td align="center">入库/发货数量</uni-td>
  48. </uni-tr>
  49. <!-- 表格数据行 -->
  50. <uni-tr
  51. v-for="item in detailList"
  52. :key="item.id"
  53. :checkedRow="hasCheck(item)"
  54. @click="editRow(item)"
  55. >
  56. <uni-td width="30%" align="center">
  57. <view>{{item.dealerProductEntity&&item.dealerProductEntity.code||'--'}}</view>
  58. </uni-td>
  59. <uni-td width="30%" align="center">
  60. <view>
  61. <view>{{item.warehouseEntity&&item.warehouseEntity.name||defWarehouseName[0]}}/</view>
  62. <view>{{item.warehouseLocationEntity&&item.warehouseLocationEntity.name||defWarehouseName[1]}}</view>
  63. </view>
  64. </uni-td>
  65. <uni-td width="40%" align="center"><text style="color: red;">{{item.realPutQty||'0'}}</text>/{{item.putQty}}</uni-td>
  66. </uni-tr>
  67. </uni-table>
  68. </view>
  69. <view class="p-footer">
  70. <button size="mini" type="warn" @click="pickFun(false)"> <text class="iconfont icon-reduce-btn"> 减 </text></button>
  71. <button size="mini" type="primary" @click="pickFun(true)"> <text class="iconfont icon-add-btn"> 加 </text></button>
  72. </view>
  73. <scanCode @onKeyDown="keyDown"></scanCode>
  74. <!-- 选择仓库 -->
  75. <chooseWarehouse ref="chooseWarehouse" :openPick="showPick" :value="warehouseVal" @close="showPick=false" @change="confirmWarehouse"></chooseWarehouse>
  76. <!-- 左键扫描,修改包装数 -->
  77. <uni-popup ref="popup" :mask-click="false" type="dialog">
  78. <view style="background-color: #fff;padding: 30rpx 50rpx;border-radius: 30rpx;width: 75%;margin: 0 auto;">
  79. <view v-if="tempProduct">
  80. <view style="padding: 30rpx 0;">
  81. 产品编码:{{tempProduct.dealerProductEntity.code}}
  82. </view>
  83. <view style="display: flex;align-items: center;">
  84. 数量:
  85. <u--input
  86. placeholder="请输入数量"
  87. border="surround"
  88. v-model="tempProduct.packQty"
  89. :min="0"
  90. type="digit"
  91. ></u--input>
  92. {{tempProduct.dealerProductEntity.unit}}
  93. {{tempProduct.dealerProductEntity.packQtyUnit?("/"+tempProduct.dealerProductEntity.packQtyUnit):''}}
  94. </view>
  95. </view>
  96. <view style="display: flex;padding: 60rpx 15rpx 10rpx;justify-content: space-between;">
  97. <button size="mini" @click="closePop">取消</button>
  98. <button size="mini" type="primary" @click="okPop">确定</button>
  99. </view>
  100. </view>
  101. </uni-popup>
  102. <u-modal :show="showModal" :title="msg.title" :confirmText="msg.confirmText" showCancelButton :content='msg.content' @cancel="showModal=false" @confirm="confirmModal"></u-modal>
  103. </view>
  104. </template>
  105. <script>
  106. import scanCode from '@/libs/scan-code.vue';
  107. import { purchaseWriteStockIn, receivingQuery, receivingDetail, purchaseUpdateWarehouse, updateRealPutQty, receivingStockInVerify } from '@/config/api.js'
  108. import { playAudio, toThousands } from '@/libs/tools.js'
  109. import clipboard from "@/js_sdk/dc-clipboard/clipboard.js"
  110. import chooseWarehouse from './chooseWarehouse.vue'
  111. export default {
  112. components: { scanCode, chooseWarehouse },
  113. data() {
  114. return {
  115. loading: false,
  116. showModal: false,
  117. msg:{title:'提示',content:''},
  118. showPick: false,
  119. baseData: null,
  120. detailList:[],
  121. code:'',
  122. receivingBillSn: null,
  123. salesId: null,
  124. curProductIndex: 0,
  125. curProductArr: [],
  126. tempProduct:null,
  127. toThousands,
  128. defWarehouse: [],
  129. defWarehouseName:[],
  130. keyName: '',
  131. warehouseVal: []
  132. };
  133. },
  134. onLoad(opts) {
  135. var _this = this
  136. this.receivingBillSn = opts.receivingBillSn
  137. this.salesId = opts.id
  138. // 默认仓库仓位
  139. this.defWarehouse = this.$store.state.vuex_tempData
  140. // 调用数据
  141. this.getDetail()
  142. this.getDetailList()
  143. uni.$on('scancodedate', function(content) {
  144. console.log("扫描到的内容为:", content, _this.keyName)
  145. _this.code = content||''
  146. _this.curProductIndex = 0
  147. if(_this.keyName == 'rightKey' || _this.keyName == 'midKey'){
  148. _this.pickFun(true)
  149. }
  150. if(_this.keyName == 'leftKey'){
  151. _this.openPack()
  152. }
  153. })
  154. },
  155. onShow() {
  156. this.hideKeyborder()
  157. const list = this.$store.state.vuex_warehouseList
  158. const an =list.find(item => item.warehouseSn==this.defWarehouse[0])
  159. const cn = an&&an.warehouseLocationList&&an.warehouseLocationList.find(item => item.warehouseLocationSn == this.defWarehouse[1])
  160. this.defWarehouseName = [an&&an.name,cn&&cn.name]
  161. console.log(this.defWarehouseName)
  162. },
  163. onUnload() {
  164. uni.$off('scancodedate')
  165. },
  166. methods: {
  167. hideKeyborder(){
  168. uni.hideKeyboard()
  169. },
  170. // 复制
  171. copyText(text){
  172. clipboard.setText(text);
  173. uni.showToast({
  174. icon: 'none',
  175. title: '编码已复制成功'
  176. })
  177. },
  178. hasCheck(item){
  179. const curProduct = this.curProductArr[this.curProductIndex]
  180. return curProduct&&curProduct.id == item.id
  181. },
  182. // 获取所有可操作商品
  183. getCurProduct(){
  184. const curProduct = this.detailList.filter(item => item.dealerProductEntity&&item.dealerProductEntity.qrCode == this.code)
  185. this.curProductArr = curProduct || []
  186. },
  187. // 获取当前操作行
  188. getCurRow(){
  189. console.log(this.curProductArr, this.curProductIndex)
  190. const curProduct = this.curProductArr[this.curProductIndex]
  191. if(curProduct){
  192. curProduct.packQty = curProduct.dealerProductEntity&&curProduct.dealerProductEntity.packQty || 0
  193. }
  194. return curProduct
  195. },
  196. pickFun(flag){
  197. playAudio('info')
  198. this.getCurProduct()
  199. this.addQty(flag)
  200. },
  201. addQty(flag){
  202. const curProduct = this.getCurRow()
  203. // console.log(curProduct)
  204. if(curProduct){
  205. this.loading = true
  206. // 加
  207. if(flag){
  208. // 如果入库数量与发货数量不相等
  209. if(curProduct.realPutQty < curProduct.putQty){
  210. this.changePutQty(curProduct,(curProduct.realPutQty||0) + 1)
  211. }else{
  212. // 当前入库数量与发货数量相等时
  213. // 切换到下一个商品
  214. if(this.curProductIndex<this.curProductArr.length-1){
  215. this.curProductIndex = this.curProductIndex + 1
  216. this.pickFun(flag)
  217. }else{
  218. // 直到最后一条数据,扫描数量无上线增加
  219. this.changePutQty(curProduct,(curProduct.realPutQty||0) + 1)
  220. }
  221. }
  222. }else{
  223. // 减
  224. // 如果入库数量不是0
  225. if(curProduct.realPutQty != 0){
  226. this.changePutQty(curProduct,(curProduct.realPutQty||0) - 1)
  227. }else{
  228. // 入库数量等于0
  229. // 切换到上一个商品
  230. if(this.curProductIndex){
  231. this.curProductIndex = this.curProductIndex - 1
  232. this.pickFun(flag)
  233. }else{
  234. this.loading = false
  235. playAudio('warn')
  236. }
  237. }
  238. }
  239. }else{
  240. this.curProductIndex = 0
  241. if(this.code == ''){
  242. uni.$u.toast("请扫描条形码")
  243. playAudio('warn')
  244. }else{
  245. uni.$u.toast("此商品不存在")
  246. playAudio('error')
  247. }
  248. }
  249. },
  250. // 关闭弹框
  251. closePop(){
  252. this.$refs.popup.close()
  253. },
  254. okPop(){
  255. const curProduct = this.tempProduct
  256. if(curProduct.packQty){
  257. this.changePutQty(curProduct,Number(curProduct.realPutQty||0) + Number(curProduct.packQty))
  258. this.closePop()
  259. }else{
  260. uni.$u.toast("请输入数量!")
  261. playAudio('warn')
  262. }
  263. },
  264. // 修改入库数量
  265. changePutQty(record, realPutQty){
  266. if(realPutQty>=0){
  267. this.loading = true
  268. updateRealPutQty({id:record.id,realPutQty:realPutQty}).then(res => {
  269. if(res.status == 200){
  270. uni.$u.toast(res.message)
  271. this.getDetail()
  272. this.getDetailList()
  273. }
  274. this.loading = false
  275. })
  276. }else{
  277. uni.$u.toast("入库数量不能小于0")
  278. playAudio('warn')
  279. }
  280. },
  281. keyDown(e){
  282. this.keyName = e
  283. },
  284. // 确定选择仓库
  285. confirmWarehouse(data){
  286. console.log(data)
  287. const curProduct = this.tempProduct
  288. this.updateWarehouse({id:curProduct.id,warehouseSn:data[0],warehouseLocationSn:data[1]})
  289. },
  290. // 修改仓库
  291. editRow(item){
  292. this.warehouseVal = item.warehouseSn ? [item.warehouseSn,item.warehouseLocationSn] : this.defWarehouse
  293. this.showPick = true
  294. this.tempProduct = item
  295. },
  296. // 修改仓库
  297. updateWarehouse (row) {
  298. console.log(row)
  299. this.loading = true
  300. purchaseUpdateWarehouse({
  301. id: row.id,
  302. warehouseSn: row.warehouseSn,
  303. warehouseLocationSn: row.warehouseLocationSn
  304. }).then(res => {
  305. if (res.status == 200) {
  306. this.showPick = false
  307. this.getDetailList()
  308. }
  309. this.loading = false
  310. })
  311. },
  312. // 详情
  313. getDetail(){
  314. receivingQuery({receivingBillSn: this.receivingBillSn, source : "PDA"}).then(res => {
  315. console.log(res,'详情')
  316. if(res.status == 200){
  317. this.baseData = res.data
  318. }
  319. })
  320. },
  321. // 产品明细列表
  322. getDetailList(){
  323. receivingDetail({pageNo:1,pageSize:1000,receivingBillSn:this.receivingBillSn}).then(res => {
  324. console.log(res,'明细列表')
  325. if(res.status == 200){
  326. this.detailList = res.data.list
  327. this.getCurRow()
  328. }
  329. })
  330. },
  331. // 打开包装数弹框
  332. openPack(){
  333. this.getCurProduct()
  334. const curProduct = this.getCurRow()
  335. this.tempProduct = curProduct
  336. if(curProduct.realPutQty < curProduct.putQty){
  337. this.$refs.popup.open()
  338. }else{
  339. // 切换到下一个商品
  340. if(this.curProductIndex<this.curProductArr.length-1){
  341. this.curProductIndex = this.curProductIndex + 1
  342. this.openPack()
  343. }else{
  344. // 直到最后一条数据,扫描数量无上线增加
  345. this.$refs.popup.open()
  346. }
  347. }
  348. },
  349. // 入库
  350. async toOut(){
  351. const isOk = await receivingStockInVerify({receivingBillSn:this.receivingBillSn})
  352. if(!isOk.data){
  353. this.submitForm()
  354. }else{
  355. this.showModal = true
  356. this.msg = {
  357. title: '提示',
  358. content: '有产品入库数量与发货数量不一致,确定入库?',
  359. confirmText: '确定'
  360. }
  361. }
  362. },
  363. confirmModal(e){
  364. this.submitForm()
  365. },
  366. async submitForm(){
  367. const a = this.defWarehouse
  368. const ret = await purchaseWriteStockIn({id: this.baseData.id,warehouseSn:a[0], warehouseLocationSn:a[1]})
  369. if(ret.status == 200){
  370. this.$store.state.vuex_isRefash = true
  371. uni.navigateBack()
  372. }
  373. this.showModal = false
  374. }
  375. },
  376. }
  377. </script>
  378. <style lang="scss">
  379. .p-content{
  380. .p-head{
  381. font-size: 32upx;
  382. color: $uni-text-color;
  383. >view{
  384. display: flex;
  385. align-items: center;
  386. padding: 10upx 20upx;
  387. border-bottom: 1px solid #eee;
  388. justify-content: space-between;
  389. > view{
  390. display: flex;
  391. padding: 0 10upx;
  392. align-items: center;
  393. }
  394. }
  395. .uni-input{
  396. border: 1px solid #eee;
  397. width: 150upx;
  398. text-align: center;
  399. padding: 8upx;
  400. }
  401. }
  402. .p-body{
  403. overflow: auto;
  404. flex-grow: 1;
  405. height: 50%;
  406. }
  407. .p-footer{
  408. padding:30upx;
  409. display: flex;
  410. > button{
  411. width: 40%;
  412. }
  413. }
  414. }
  415. </style>