index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. <template>
  2. <view class="p-content">
  3. <view class="p-head">
  4. <view v-if="baseData">
  5. <view>
  6. <text>散件单号:</text>
  7. <text style="color: crimson;">{{baseData.sparePartsPurchaseNo}}</text>
  8. </view>
  9. <view>
  10. <button size="mini" :disabled="loading" type="warn" @click="submitInStock"> 入库 <text class="iconfont icon-icon-test43"></text></button>
  11. </view>
  12. </view>
  13. <view>
  14. <view>
  15. <text>产品条码:</text>
  16. <view style="flex-grow: 1;display: flex;align-items: center;">
  17. <input
  18. :focus="true"
  19. style="width: 150px;text-align: left;font-size: 32rpx;padding: 6rpx 0 6rpx 7rpx;"
  20. class="uni-input"
  21. placeholder="扫描或输入条码"
  22. border="surround"
  23. v-model="code">
  24. <button size="mini" @click="queryProduct" :style="{padding:'2px 10px',color:'#00aaff'}">查询</button>
  25. </view>
  26. </view>
  27. <view></view>
  28. </view>
  29. <view v-if="curProduct">
  30. <view>
  31. <text style="width:180rpx">产品名称:</text>
  32. <view>
  33. {{curProduct.productName}}
  34. </view>
  35. </view>
  36. </view>
  37. <view v-if="curProduct">
  38. <view>数量:<input class="uni-input" v-model="curProduct.putQty" :min="0" @blur="updateCurr" type="digit"/></view>
  39. <view>成本:<input class="uni-input" v-model="curProduct.putCost" :min="0" @blur="updateCurr" type="digit"/></view>
  40. </view>
  41. <view v-if="countData" style="justify-content: flex-start;flex-wrap: wrap;">
  42. <view>总款数:{{countData.productTotalCategory||0}}</view>
  43. <view>总数量:{{countData.productTotalQty||0}}</view>
  44. <view>
  45. 总成本:<u-text type="error" mode="price" :text="countData.productTotalCost" />
  46. </view>
  47. </view>
  48. </view>
  49. <view class="p-body">
  50. <uni-table border emptyText="暂无数据" :loading="loading" >
  51. <!-- 表头行 -->
  52. <uni-tr>
  53. <uni-td align="center">产品编码</uni-td>
  54. <uni-td align="center">数量</uni-td>
  55. <uni-td align="center">总成本</uni-td>
  56. </uni-tr>
  57. <!-- 表格数据行 -->
  58. <uni-tr v-for="item in detailList" :key="item.id" :checkedRow="curProduct&&curProduct.qrCode == item.qrCode" @click="toDetail(item)">
  59. <uni-td width="40%" align="center">{{item.productCode}}</uni-td>
  60. <uni-td width="30%" align="center">{{item.putQty}}</uni-td>
  61. <uni-td width="30%" align="center">
  62. <span :style="{ color: 'red' }">¥{{Number(item.putCost*item.putQty).toFixed(2)}}</span>
  63. </uni-td>
  64. </uni-tr>
  65. </uni-table>
  66. </view>
  67. <view class="p-footer">
  68. <button size="mini" type="warn" @click="addQty(false)"> <text class="iconfont icon-reduce-btn"> 减 </text></button>
  69. <button size="mini" type="primary" @click="addQty(true)"> <text class="iconfont icon-add-btn"> 加 </text></button>
  70. </view>
  71. <scanCode></scanCode>
  72. <uni-popup ref="popup" :mask-click="false" type="dialog">
  73. <view style="background-color: #fff;padding: 30rpx 50rpx;border-radius: 30rpx;width: 75%;margin: 0 auto;">
  74. <view v-if="tempProduct">
  75. <view>
  76. 产品编码:{{tempProduct.code}}
  77. </view>
  78. <view>
  79. 产品名称:{{tempProduct.name}}
  80. </view>
  81. <view style="display: flex;align-items: center;">
  82. 成本价:
  83. <u--input
  84. placeholder="请输入成本价"
  85. border="surround"
  86. v-model="tempProduct.putCost"
  87. :min="0"
  88. type="digit"
  89. ></u--input>
  90. </view>
  91. </view>
  92. <view style="display: flex;padding: 30rpx 15rpx;justify-content: space-between;">
  93. <button @click="closePop">取消</button>
  94. <button type="primary" @click="okPop">确定</button>
  95. </view>
  96. </view>
  97. </uni-popup>
  98. </view>
  99. </template>
  100. <script>
  101. import {
  102. sparePartsPurDetail,
  103. dealerProductQueryForSparePartsPur,
  104. sparePartsPurDetailList,
  105. sparePartsQueryCount,
  106. sparePartsPurDetailSave,
  107. sparePartsPurDetailDel,
  108. sparePartsPurDetailDelAll,
  109. sparePartsPurSubmitPut,
  110. } from '@/config/api.js'
  111. import scanCode from '@/libs/scan-code.vue';
  112. import { playAudio } from '@/libs/tools.js'
  113. export default {
  114. components: { scanCode },
  115. data() {
  116. return {
  117. loading: false,
  118. baseData: null,
  119. detailList:[],
  120. countData:null,
  121. code:'',
  122. sparePartsPurchaseSn: '',
  123. sparePartsPurchaseId: '',
  124. curProduct: null,
  125. defaultWarehouseCascade: [] ,// 默认仓库仓位
  126. tempProduct: null
  127. };
  128. },
  129. onLoad(opts) {
  130. var _this = this
  131. this.sparePartsPurchaseSn = opts.sn
  132. this.sparePartsPurchaseId = opts.id
  133. this.getWarehouseCascade()
  134. this.getDetail()
  135. this.pageInit()
  136. uni.$on('scancodedate', function(content) {
  137. console.log("扫描到的内容为:", content)
  138. _this.code = content||''
  139. _this.queryProduct()
  140. })
  141. },
  142. onShow() {
  143. this.pageInit()
  144. this.hideKeyborder()
  145. },
  146. onUnload() {
  147. uni.$off('scancodedate')
  148. },
  149. methods: {
  150. closePop(){
  151. this.$refs.popup.close()
  152. },
  153. okPop(){
  154. if(this.tempProduct.putCost || this.tempProduct.putCost === 0){
  155. this.closePop()
  156. this.addDetailProduct(this.tempProduct, false)
  157. }else{
  158. uni.$u.toast("请输入成本价!")
  159. }
  160. },
  161. pageInit(){
  162. this.getTotal()
  163. this.getDetailList()
  164. },
  165. // 仓库仓位 级联 列表
  166. getWarehouseCascade () {
  167. const _this = this
  168. const warehouseList = this.$store.state.vuex_warehouseList
  169. warehouseList.filter(item => {
  170. // 过滤默认仓库
  171. if (item.defaultFlag == 1 && item.wasteFlag == 0) { // defaultFlag为1,且不是废品仓
  172. _this.defaultWarehouseCascade[0] = item.warehouseSn
  173. // 过滤默认仓位
  174. item.warehouseLocationList.filter(subItem => {
  175. if (subItem.defaultFlag == 1 && subItem.wasteFlag == 0) {
  176. _this.defaultWarehouseCascade[1] = subItem.warehouseLocationSn
  177. }
  178. })
  179. }
  180. })
  181. },
  182. hideKeyborder(){
  183. uni.hideKeyboard()
  184. },
  185. // 修改数量和成本
  186. updateCurr(){
  187. if(this.curProduct.putQty>0){
  188. if(this.curProduct.putCost>0){
  189. this.addDetailProduct(this.curProduct, true)
  190. }else{
  191. uni.$u.toast("成本必须大于0!")
  192. this.curProduct.putCost = this.curProduct.putCostBackups
  193. }
  194. }else{
  195. // 删除
  196. this.delDetailProduct(this.curProduct)
  197. }
  198. },
  199. // 加减数量
  200. addQty(type){
  201. playAudio('info')
  202. const hasProduct = this.detailList.find(item => item.qrCode == this.code)
  203. if(hasProduct){
  204. hasProduct.putQty = hasProduct.putQty + (type ? 1 : -1)
  205. if(hasProduct.putQty>0){
  206. this.addDetailProduct(hasProduct, true)
  207. }else{
  208. // 删除
  209. this.delDetailProduct(hasProduct)
  210. }
  211. }
  212. },
  213. // 删除
  214. delDetailProduct(item) {
  215. sparePartsPurDetailDel({ sn: item.id }).then(res => {
  216. if (res.status == 200) {
  217. uni.$u.toast(res.message)
  218. this.pageInit()
  219. }
  220. })
  221. },
  222. // 查询产品
  223. queryProduct(){
  224. if(!this.code){
  225. uni.$u.toast("请扫码或输入条形码!")
  226. return
  227. }
  228. // 如果已添加产品,则累加数量
  229. const hasProduct = this.detailList.find(item => item.qrCode == this.code)
  230. console.log(hasProduct)
  231. if(!!hasProduct){
  232. this.addQty(true)
  233. return
  234. }
  235. if(this.code==''){
  236. uni.$u.toast("未识别到条形码!")
  237. playAudio('error')
  238. return
  239. }
  240. const params = {
  241. supplierSn: this.baseData.supplierSn,
  242. qrCode: this.code,
  243. pageNo:1,
  244. pageSize:1 ,
  245. }
  246. console.log(params)
  247. dealerProductQueryForSparePartsPur(params).then(res => {
  248. console.log(res)
  249. if(res.status == 200){
  250. const curProduct = res.data && res.data.list[0] || null
  251. console.log(curProduct)
  252. if(curProduct){
  253. curProduct.putCost = curProduct.purchasePrice
  254. curProduct.putQty = curProduct.putQty || 1
  255. if (this.defaultWarehouseCascade.length > 0) {
  256. curProduct.warehouseSn = this.defaultWarehouseCascade[0]
  257. curProduct.warehouseLocationSn = this.defaultWarehouseCascade[1]
  258. } else {
  259. curProduct.warehouseSn = undefined
  260. curProduct.warehouseLocationSn = undefined
  261. }
  262. // 添加产品
  263. this.addDetailProduct(curProduct, false)
  264. }else{
  265. uni.$u.toast("此商品不存在!")
  266. playAudio('error')
  267. }
  268. }
  269. })
  270. },
  271. // 添加明细
  272. addDetailProduct(row, isEdit){
  273. const params = {
  274. id: isEdit ? row.id : undefined,
  275. sparePartsPurchaseSn: this.sparePartsPurchaseSn,
  276. putCost: row.putCost,
  277. putQty: row.putQty,
  278. productCode: isEdit ? row.productCode : row.code,
  279. productOrigCode: (isEdit ? row.productOrigCode : row.origCode) || undefined,
  280. productSn: row.productSn,
  281. productTypeSn1: row.productTypeSn1,
  282. productTypeSn2: row.productTypeSn2,
  283. productTypeSn3: row.productTypeSn3,
  284. brandSn: isEdit ? row.brandSn : row.productBrandSn,
  285. warehouseLocationSn: row.warehouseLocationSn,
  286. warehouseSn: row.warehouseSn
  287. }
  288. if (isEdit) { // 编辑
  289. // 清空成本价或数量时,值应保持未清空前的值,因成本价和数量都不可为空
  290. if (!(row.putCost || row.putCost == 0)) {
  291. row.putCost = row.putCostBackups
  292. return
  293. }
  294. if (!row.putQty) {
  295. row.putQty = row.putQtyBackups
  296. return
  297. }
  298. }
  299. console.log(params)
  300. this.loading = true
  301. sparePartsPurDetailSave(params).then(res => {
  302. console.log(res,'添加')
  303. if (res.status == 200) {
  304. this.loading = false
  305. this.pageInit()
  306. } else {
  307. this.loading = false
  308. if(res.message == '采购成本价不能为空;'){
  309. this.$refs.popup.open()
  310. this.tempProduct = row
  311. }
  312. }
  313. })
  314. },
  315. // 详情
  316. getDetail(){
  317. sparePartsPurDetail({sn: this.sparePartsPurchaseSn}).then(res => {
  318. if(res.status == 200){
  319. this.baseData = res.data
  320. }
  321. })
  322. },
  323. // 已添加产品列表
  324. getDetailList(){
  325. sparePartsPurDetailList({pageNo:1,pageSize:1000,sparePartsPurchaseSn:this.sparePartsPurchaseSn}).then(res => {
  326. console.log(res,'已添加产品列表')
  327. if(res.status == 200){
  328. this.detailList = res.data.list
  329. this.detailList.map(item => {
  330. item.putCostBackups = item.putCost
  331. item.putQtyBackups = item.putQty
  332. })
  333. const curProduct = this.detailList.find(item => item.qrCode == this.code)
  334. this.curProduct = curProduct || null
  335. }
  336. })
  337. },
  338. getTotal(){
  339. sparePartsQueryCount({sparePartsPurchaseSn:this.sparePartsPurchaseSn}).then(res => {
  340. console.log(res,'getTotal')
  341. this.countData = res.data
  342. })
  343. },
  344. toDetail(item) {
  345. this.$store.state.vuex_tempData = item
  346. uni.navigateTo({
  347. url:"/pages/stockIn/detail?state="+this.baseData.state
  348. })
  349. },
  350. submitInStock(){
  351. sparePartsPurSubmitPut({id: this.sparePartsPurchaseId}).then(res => {
  352. if(res.status == 200){
  353. uni.$emit("refashList")
  354. uni.navigateBack()
  355. }
  356. })
  357. }
  358. },
  359. }
  360. </script>
  361. <style lang="scss">
  362. .p-content{
  363. button{
  364. line-height: 1.7;
  365. }
  366. .p-head{
  367. font-size: 32upx;
  368. color: $uni-text-color;
  369. >view{
  370. display: flex;
  371. align-items: center;
  372. padding: 15upx 20upx;
  373. border-bottom: 1px solid #eee;
  374. justify-content: space-between;
  375. > view{
  376. display: flex;
  377. padding: 0 10upx;
  378. align-items: center;
  379. }
  380. }
  381. .uni-input{
  382. border: 1px solid #eee;
  383. width: 150upx;
  384. text-align: center;
  385. }
  386. }
  387. .p-body{
  388. overflow: auto;
  389. flex-grow: 1;
  390. height: 50%;
  391. }
  392. .p-footer{
  393. padding:20upx 30upx;
  394. display: flex;
  395. > button{
  396. width: 30%;
  397. }
  398. }
  399. }
  400. </style>