index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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.checkWarehouseNo}}</text>
  8. </view>
  9. <view>
  10. <button size="mini" :disabled="loading" type="warn" @click="submitIn"> 提交 <text class="iconfont icon-icon-test43"></text></button>
  11. </view>
  12. </view>
  13. <view style="border: 0;">
  14. <view>
  15. <text>产品条码:</text>
  16. <view style="flex-grow: 1;display: flex;align-items: center;">
  17. <input
  18. style="width: 190px;text-align: left;font-size: 32rpx;padding: 6rpx 0 6rpx 7rpx;"
  19. class="uni-input"
  20. placeholder="扫描或输入条码"
  21. border="surround"
  22. v-model="code">
  23. </view>
  24. </view>
  25. <view>
  26. <button size="mini" @click="resetForm" :style="{padding:'2px 3px',color:'#aa0000'}">重置</button>
  27. </view>
  28. </view>
  29. <view>
  30. <view>
  31. <text>产品编码:</text>
  32. <view style="flex-grow: 1;display: flex;align-items: center;">
  33. <input
  34. style="width: 190px;text-align: left;font-size: 32rpx;padding: 6rpx 0 6rpx 7rpx;"
  35. class="uni-input"
  36. placeholder="请输入产品编码"
  37. border="surround"
  38. v-model="productCode">
  39. </view>
  40. </view>
  41. <view>
  42. <button size="mini" @click="queryProduct" :style="{padding:'2px 3px',color:'#00aaff'}">查询</button>
  43. </view>
  44. </view>
  45. <view v-if="curProduct">
  46. <view>
  47. <text style="width:180rpx">产品名称:</text>
  48. <view>
  49. {{curProduct.productName}}
  50. </view>
  51. </view>
  52. </view>
  53. <view v-if="curProduct">
  54. <view>盘点数量:<input class="uni-input" v-model="curProduct.checkQty" :min="0" @blur="updateCurr" type="digit"/></view>
  55. <view v-if="curProduct.checkProfitLossQty<0||(curProduct.stockQty==curProduct.checkQty)">成本:{{curProduct.cost||'--'}}</view>
  56. <view v-else>成本:<input class="uni-input" v-model="curProduct.cost" :min="0" @blur="updateCost" type="digit"/></view>
  57. <view>库存:{{curProduct.stockQty}}</view>
  58. </view>
  59. <view v-if="countData" style="justify-content: flex-start;flex-wrap: wrap;">
  60. <view>共{{countData.totalCategory||0}}款</view>
  61. <view>总数量:{{countData.stockQty||0}}</view>
  62. <view>盈亏数量:<span :style="{ color: countData.totalCheckProfitLossQty>0?'red':countData.totalCheckProfitLossQty<0?'green':'' }">{{ (countData.totalCheckProfitLossQty || countData.totalCheckProfitLossQty==0) ? Math.abs(countData.totalCheckProfitLossQty) : '--' }}</span></view>
  63. </view>
  64. </view>
  65. <view class="p-body" :style="{height: curProduct ? 'calc(100vh - 290px)':'calc(100vh - 220px)'}">
  66. <scroll-view :scroll-top="scrollTop" :scroll-y="true" class="scrollView">
  67. <uni-table style="width: 100%;" border emptyText="暂无数据" :loading="loading" >
  68. <!-- 表头行 -->
  69. <uni-tr>
  70. <uni-td align="center">产品编码</uni-td>
  71. <uni-td align="center">库存</uni-td>
  72. <uni-td align="center">盘点数量</uni-td>
  73. <uni-td align="center">盈亏数量</uni-td>
  74. </uni-tr>
  75. <!-- 表格数据行 -->
  76. <uni-tr v-for="item in detailList" :key="item.id" :checkedRow="hasCheck(item)" @click="selRow(item)">
  77. <uni-td width="30%" align="center">{{item.productCode}}</uni-td>
  78. <uni-td width="20%" align="center">{{item.stockQty}}</uni-td>
  79. <uni-td width="25%" align="center">{{item.checkQty}}</uni-td>
  80. <uni-td width="25%" align="center">
  81. <view @click="toDetail(item)">
  82. <span :style="{ color: item.checkProfitLossQty>0?'red':item.checkProfitLossQty<0?'green':'' }">{{ (item.checkProfitLossQty || item.checkProfitLossQty==0) ? Math.abs(item.checkProfitLossQty) : '--' }}</span>
  83. </view>
  84. </uni-td>
  85. </uni-tr>
  86. </uni-table>
  87. </scroll-view>
  88. </view>
  89. <view class="p-footer">
  90. <button size="mini" type="warn" @click="addQty(false)"> <text class="iconfont icon-reduce-btn"> 减 </text></button>
  91. <button size="mini" type="primary" @click="addQty(true)"> <text class="iconfont icon-add-btn"> 加 </text></button>
  92. </view>
  93. <scanCode @onKeyDown="keyDown"></scanCode>
  94. </view>
  95. </template>
  96. <script>
  97. import scanCode from '@/libs/scan-code.vue';
  98. import { playAudio } from '@/libs/tools.js'
  99. import {
  100. checkWarehouseDetailStockList,
  101. checkWarehouseDetailBySn,
  102. checkWarehouseDetailList,
  103. checkWarehouseDetailCount,
  104. checkWarehouseDetailSave,
  105. checkWarehouseModifyCost,
  106. checkWarehouseDetailDel,
  107. checkWarehouseSubmit} from '@/config/api.js'
  108. export default {
  109. components: { scanCode },
  110. data() {
  111. return {
  112. checkWarehouseSn: '',
  113. checkWarehouseId: null,
  114. loading: false,
  115. detailList:[],
  116. countData: null,
  117. code:'',
  118. productCode: '',
  119. baseData: null,
  120. curProduct: null,
  121. scrollTop: 0
  122. };
  123. },
  124. onLoad(opts) {
  125. var _this = this
  126. this.checkWarehouseSn = opts.checkWarehouseSn
  127. this.checkWarehouseId = opts.id
  128. uni.$on('scancodedate', function(content) {
  129. console.log("扫描到的内容为:", content)
  130. _this.code = content||''
  131. _this.queryProduct()
  132. })
  133. this.getDetail()
  134. this.pageInit()
  135. },
  136. onShow() {
  137. this.pageInit()
  138. this.hideKeyborder()
  139. },
  140. onUnload() {
  141. uni.$off('scancodedate')
  142. },
  143. onNavigationBarButtonTap(e){
  144. if(e.index == 0){
  145. uni.navigateTo({
  146. url: "/pages/stockPan/list"
  147. })
  148. }
  149. },
  150. methods: {
  151. pageInit(){
  152. this.getTotal()
  153. this.getDetailList()
  154. },
  155. hideKeyborder(){
  156. uni.hideKeyboard()
  157. },
  158. // 物理按键
  159. keyDown(key,e){
  160. console.log(key,e)
  161. },
  162. // 修改数量
  163. updateCurr(){
  164. if(this.curProduct.checkQty>0){
  165. this.addDetailProduct(this.curProduct, true)
  166. }else{
  167. // 删除
  168. this.delDetailProduct(this.curProduct)
  169. }
  170. },
  171. // 修改成本
  172. updateCost(){
  173. checkWarehouseModifyCost({
  174. id: this.curProduct.id,
  175. checkWarehouseSn: this.checkWarehouseSn,
  176. cost: this.curProduct.cost
  177. }).then(res => {
  178. if(res.status == 200){
  179. uni.$u.toast(res.message)
  180. this.pageInit()
  181. }
  182. })
  183. },
  184. // 加减数量
  185. addQty(type){
  186. playAudio('info')
  187. const hasProduct = this.detailList.find(item => item.qrCode == this.code || item.productCode == this.productCode)
  188. if(hasProduct){
  189. hasProduct.checkQty = hasProduct.checkQty + (type ? 1 : -1)
  190. if(hasProduct.checkQty>0){
  191. this.addDetailProduct(hasProduct, true)
  192. }else{
  193. // 删除
  194. this.delDetailProduct(hasProduct)
  195. }
  196. }
  197. },
  198. // 删除
  199. delDetailProduct(item) {
  200. checkWarehouseDetailDel({ id: item.id, checkWarehouseSn: this.checkWarehouseSn }).then(res => {
  201. if (res.status == 200) {
  202. uni.$u.toast(res.message)
  203. this.pageInit()
  204. }
  205. })
  206. },
  207. hasCheck(item){
  208. if(this.curProduct){
  209. return(this.curProduct.productCode == item.productCode)
  210. if(this.curProduct.qrCode || item.qrCode){
  211. return(this.curProduct.qrCode == item.qrCode)
  212. }
  213. }
  214. return false
  215. },
  216. selRow(item){
  217. this.curProduct = item
  218. this.code = item.qrCode||''
  219. this.productCode = item.productCode||''
  220. },
  221. resetForm(){
  222. this.curProduct = null
  223. this.code = ''
  224. this.productCode = ''
  225. this.scrollTop = 0
  226. },
  227. // 查询产品
  228. queryProduct(){
  229. if(!this.code&&!this.productCode){
  230. uni.$u.toast("请输入条形码或编码!")
  231. playAudio('error')
  232. return
  233. }
  234. // 如果已添加产品,则累加数量
  235. const hasProduct = this.detailList.find(item => item.qrCode == this.code || item.productCode == this.productCode)
  236. console.log(hasProduct)
  237. if(!!hasProduct){
  238. this.addQty(true)
  239. return
  240. }
  241. const params = {
  242. checkWarehouseId: this.checkWarehouseId,
  243. qrCode: this.code,
  244. productCode: this.productCode,
  245. pageNo:1,
  246. pageSize:1 ,
  247. }
  248. console.log(params)
  249. checkWarehouseDetailStockList(params).then(res => {
  250. if(res.status == 200){
  251. const curProduct = res.data && res.data.list[0] || null
  252. console.log(curProduct,'curProduct')
  253. if(curProduct){
  254. // 添加产品
  255. this.addDetailProduct(curProduct, false)
  256. }else{
  257. uni.$u.toast("此商品不存在!")
  258. playAudio('error')
  259. }
  260. }
  261. })
  262. },
  263. // 添加明细
  264. addDetailProduct(row, isEdit){
  265. const params = isEdit ? row : {
  266. checkWarehouseSn: this.checkWarehouseSn,
  267. checkCost: row.putCost,
  268. cost: row.lastStockCost,
  269. productSn: row.productSn,
  270. productCode: row.productCode,
  271. productOrigCode: row.productOrigCode || undefined,
  272. productTypeSn1: row.productTypeSn1,
  273. productTypeSn2: row.productTypeSn2,
  274. productTypeSn3: row.productTypeSn3,
  275. brandSn: row.brandSn,
  276. stockQty: row.currentQty,
  277. lastStockTime: row.lastStockTime,
  278. checkProfitLossCost: row.lastStockCost,
  279. stockBatchNo: row.stockBatchNo || undefined,
  280. productProduceDate: row.productProduceDate || undefined,
  281. productExpiryDate: row.productExpiryDate || undefined,
  282. warehouseSn: row.warehouseSn || undefined,
  283. warehouseLocationSn: row.warehouseLocationSn || undefined
  284. };
  285. console.log(params)
  286. this.loading = true
  287. checkWarehouseDetailSave(params).then(res => {
  288. console.log(res,'添加')
  289. if (res.status == 200) {
  290. this.pageInit()
  291. } else {
  292. this.loading = false
  293. }
  294. })
  295. },
  296. // 详情
  297. getDetail(){
  298. checkWarehouseDetailBySn({sn: this.checkWarehouseSn}).then(res => {
  299. console.log(res,'详情')
  300. if(res.status == 200){
  301. this.baseData = res.data
  302. }
  303. })
  304. },
  305. // 已添加产品列表
  306. getDetailList(){
  307. checkWarehouseDetailList({pageNo:1,pageSize:1000,checkWarehouseSn:this.checkWarehouseSn}).then(res => {
  308. console.log(res,'已添加产品列表')
  309. if(res.status == 200){
  310. this.detailList = res.data.list
  311. const curProduct = this.detailList.find(item => item.qrCode == this.code || item.productCode == this.productCode)
  312. this.curProduct = curProduct || null
  313. this.scrollToRow(this.curProduct)
  314. }
  315. this.loading = false
  316. })
  317. },
  318. // 滚动到指定行
  319. scrollToRow(cur){
  320. const idx = this.detailList.findIndex(item => item.id == cur.id)
  321. this.scrollTop = idx * 30
  322. },
  323. getTotal(){
  324. checkWarehouseDetailCount({checkWarehouseSn:this.checkWarehouseSn}).then(res => {
  325. console.log(res,'getTotal')
  326. this.countData = res.data
  327. })
  328. },
  329. // 商品详情
  330. toDetail(item) {
  331. this.$store.state.vuex_tempData = item
  332. uni.navigateTo({
  333. url:"/pages/stockPan/detail?state="+this.baseData.state
  334. })
  335. },
  336. // 提交盘点
  337. submitIn(){
  338. checkWarehouseSubmit({id: this.checkWarehouseId, auditFlag: true}).then(res => {
  339. if(res.status == 200){
  340. uni.$emit("refashList")
  341. uni.navigateBack()
  342. }
  343. })
  344. }
  345. },
  346. }
  347. </script>
  348. <style lang="scss">
  349. .p-content{
  350. button{
  351. line-height: 1.7;
  352. }
  353. .p-head{
  354. font-size: 32upx;
  355. color: $uni-text-color;
  356. >view{
  357. display: flex;
  358. align-items: center;
  359. padding: 15upx 20upx;
  360. border-bottom: 1px solid #eee;
  361. justify-content: space-between;
  362. > view{
  363. display: flex;
  364. padding: 0 10upx;
  365. align-items: center;
  366. }
  367. }
  368. .uni-input{
  369. border: 1px solid #eee;
  370. width: 150upx;
  371. text-align: center;
  372. }
  373. }
  374. .p-body{
  375. flex-grow: 1;
  376. height: calc(100vh - 220px);
  377. .scrollView{
  378. height: 100%;
  379. }
  380. }
  381. .p-footer{
  382. padding: 20upx;
  383. display: flex;
  384. > button{
  385. width: 40%;
  386. padding: 3px 0;
  387. }
  388. }
  389. }
  390. </style>