mixins.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. import {
  2. BARCODE_CAIGOU,
  3. BARCODE_CAIGOU_KEY,
  4. BARCODE_FINISHEDGOOD,
  5. BARCODE_FINISHEDGOOD_KEY,
  6. BARCODE_PRODUCE,
  7. BARCODE_PRODUCE_KEY,
  8. BARCODE_PROCESS,
  9. BARCODE_PROCESS_KEY,
  10. BARCODE_JOBCENTER,
  11. BARCODE_JOBCENTER_KEY,
  12. BARCODE_TARE,
  13. BARCODE_TARE_KEY,
  14. BARCODE_OUTSOURCE
  15. } from "@/common/utils/barCode.js"
  16. import {MSG_MAX_SCAN_NUM,MAX_SCAN_NUM} from "@/common/utils/tipMessage.js"
  17. import {formateScanData,onErrorBarCodeType} from "@/common/utils/common.js"
  18. import {mapGetters} from "vuex"
  19. //获取module
  20. const barcodeModel = uni.requireNativePlugin("iData-BarcodePlugin-BarcodeModule")
  21. const globalEvent = uni.requireNativePlugin('globalEvent');
  22. const BRAND_PRO = "iData" // pda品牌
  23. const BigNumber = require('bignumber.js');
  24. // 扫描物品的逻辑
  25. export const scanProductMixin={
  26. data () {
  27. return {
  28. list:[], // 显示数据列表
  29. // itemnoClassList:[], // 每一类物品号所拥有的物品列表
  30. barCodeTypeList:[BARCODE_CAIGOU_KEY,BARCODE_FINISHEDGOOD_KEY], // 扫描的二维码类型
  31. uniqueType:{}, // 不允许重复的类型
  32. barcode:null, // 扫到的条形码
  33. }
  34. },
  35. computed:{
  36. // 已扫描的物品列表
  37. itemcheckedList () {
  38. let arr=this.list.map(item=>{
  39. return item.itemid
  40. })
  41. return arr
  42. },
  43. // 计算去重物品号的数据
  44. itemnoClassList () {
  45. let arr=[]
  46. const arr2=this.list.slice(0)
  47. this.list.forEach(v=>{
  48. const i=arr.findIndex(v2=>{
  49. return v.itemno===v2.itemno
  50. })
  51. if (i<0){
  52. const obj={...v} // 避免污染this.list
  53. arr.push(obj)
  54. }else{
  55. arr[i].itemnum+=v.itemnum
  56. }
  57. })
  58. return arr
  59. }
  60. },
  61. onLoad (e) {
  62. uni.$on('onSubmitIventory',(e)=>{
  63. this.clearList()
  64. })
  65. },
  66. onUnload () {
  67. uni.$off('onSubmitIventory',()=>{})
  68. },
  69. onBackPress (e) {
  70. if (this.list.length>0 && e.from ==='backbutton') {
  71. this.confirmLeave()
  72. return true
  73. }
  74. },
  75. methods:{
  76. // 离开提示
  77. confirmLeave () {
  78. uni.showModal({
  79. title:"重要提示",
  80. content:"扫描的物品未确认,系统将不会保存数据,离开将清空,确认离开?",
  81. success:(res)=>{
  82. if (res.confirm) {
  83. this.clearList()
  84. uni.navigateBack({
  85. delta:1
  86. })
  87. }
  88. }
  89. })
  90. },
  91. // 清空数据
  92. clearList () {
  93. this.list=[]
  94. },
  95. // 找索引
  96. _findIndex (array,key,item) {
  97. const index=array.findIndex((v)=>{
  98. return v[key]===item
  99. })
  100. return index
  101. },
  102. // 删除物品
  103. onDelete (index) {
  104. uni.showModal({
  105. title:"确定删除该条物品吗?",
  106. success:res=>{
  107. if (res.confirm) {
  108. this.list.splice(index,1) // 删除列表
  109. }
  110. }
  111. })
  112. },
  113. // 扫描入库,value:条形码,obj :其他数据
  114. /* 物品不能重复有两种情况
  115. */
  116. onScan ({value},obj={}) {
  117. // 如果数组长度过长,进行阻断提示
  118. if (this.list.length===MAX_SCAN_NUM) {
  119. uni.showToast({
  120. title:MSG_MAX_SCAN_NUM,
  121. icon:"none"
  122. })
  123. throw new Error('mixins.js:scanProductMixin{}:onScan():扫码的物品数量过多')
  124. return false;
  125. }
  126. this.barcode=value
  127. let {barCodeType,itemno,itemnum,itemcode,itemid}=formateScanData(value)
  128. itemnum=Number(itemnum)
  129. const other=this.scanCustomer()
  130. let otherData=[]
  131. if (typeof other ==="boolean") {
  132. if (!other) {
  133. throw new Error ('mixins.js:scanCustomer():return false')
  134. return false
  135. }
  136. }
  137. if (typeof other==="object") {
  138. if (!other.ok) {
  139. throw new Error ('mixins.js:scanCustomer():return false')
  140. return false
  141. };
  142. if (typeof other.data !="undefined") {
  143. otherData=other.data
  144. }
  145. }
  146. /* 情况一:通过扫码得到数量,需要(条形码类型+物品号+识别码)这三样组成的物品身份 不能重复
  147. */
  148. if (obj.uniqueItemid) {
  149. this.uniqueType={
  150. uniqueItemid:true
  151. }
  152. if (this.itemcheckedList.indexOf(itemid) >=0) {
  153. return uni.showToast({
  154. title:"该物品已扫描,不可重复扫描",
  155. icon:"none",
  156. duration:2000
  157. })
  158. }else{
  159. // 没有重复进行数据录入,判断是否需要进行数据合并
  160. const obj={
  161. WPH:itemno,
  162. itemno,
  163. itemnum,
  164. itemid,
  165. itemcode,
  166. }
  167. const objitem= other.ok ? Object.assign({},obj,otherData[0]) : obj
  168. this.list.push(objitem)
  169. }
  170. }
  171. /* 手动录入数量
  172. */
  173. if (obj.uniqueItemno) {
  174. this.uniqueType={
  175. uniqueItemno:true
  176. }
  177. const itemNoIndex=this._findIndex(this.list,'itemno',itemno)
  178. if (itemNoIndex>=0) {
  179. return uni.showToast({
  180. title:"该物品已扫描,请不要重复扫描",
  181. icon:"none",
  182. duration:2000
  183. })
  184. }else{
  185. this.list.push({
  186. itemno,
  187. WPH:itemno
  188. })
  189. }
  190. }
  191. },
  192. // 自定义一个扫码回调,方便在页面里面进行一些替换覆盖
  193. scanCustomer () {
  194. return true
  195. },
  196. // 自定义一个提交前确认
  197. beforeSubmitConfirmCustomer () {
  198. return true
  199. },
  200. onSubmit (urlkey,params='&') {
  201. const other=this.beforeSubmitConfirmCustomer()
  202. let customerList=[]
  203. let isCustomer=false
  204. if (typeof other ==="boolean") {
  205. if (!other) {
  206. throw new Error ('mixins.js:beforeSubmitConfirmCustomer():return false')
  207. return false
  208. }
  209. }
  210. if (typeof other==="object") {
  211. if (!other.ok) {
  212. throw new Error ('mixins.js:beforeSubmitConfirmCustomer():return false')
  213. return false
  214. };
  215. if (typeof other.data !="undefined") {
  216. customerList=other.data
  217. isCustomer=true
  218. }
  219. }
  220. if (!isCustomer) {
  221. if(this.list.length===0){
  222. return uni.showToast({
  223. title:"请至少扫描添加一条物品",
  224. icon:"none"
  225. })
  226. }
  227. }
  228. uni.showModal({
  229. title:"确认保存吗?",
  230. success:(res)=>{
  231. if (res.confirm) {
  232. uni.showToast({
  233. title:"保存成功"
  234. })
  235. let list=[]
  236. // 如果用户自定义格式话的数组,传递到下一张页面得数据自己定义
  237. if (isCustomer) {
  238. list=JSON.stringify(customerList)
  239. }else{
  240. // 扫描输入数量,需要传递物品类列表,物品类是我们经过合并之后的数据
  241. if (this.uniqueType.uniqueItemid) {
  242. list= JSON.stringify(this.itemnoClassList)
  243. }
  244. // 手动输入数量,直接把列表传递过去,因为已经控制了物品号不能重复
  245. if (this.uniqueType.uniqueItemno) {
  246. list=JSON.stringify(this.list)
  247. }
  248. }
  249. const url=`/pages/${urlkey}/${urlkey}?list=${list}${params}`
  250. uni.navigateTo({
  251. url:url
  252. })
  253. }
  254. }
  255. })
  256. },
  257. }
  258. }
  259. // 清点单合并数据
  260. export const inventoryEditMixin={
  261. methods:{
  262. checkList () {
  263. let arr=[]
  264. this.realList.forEach((item,index,array)=>{
  265. this.scanList.forEach((item2,index2,array2)=>{
  266. // 两个数据源都有的项
  267. if (item.itemno===item2.itemno) {
  268. const obj={...item,...item2}
  269. obj.difAmount=item.amount-item2.itemnum
  270. obj.highlight=obj.difAmount == 0 ? false : true
  271. array[index]=obj
  272. }else {
  273. // 扫码里有,后台没有
  274. let i=array.findIndex(v=>{
  275. return v.itemno===item2.itemno
  276. })
  277. if (i<0) {
  278. const obj=item2
  279. obj.amount="--"
  280. obj.difAmount=0-obj.itemnum
  281. obj.highlight=obj.difAmount == 0 ? false : true
  282. array.push(obj)
  283. }
  284. // 后台有,扫码里没有找到,修改后台数据
  285. let i2=array2.findIndex(v=>{
  286. return v.itemno===item.itemno
  287. })
  288. if (i2<0) {
  289. const obj=item
  290. obj.itemnum="--"
  291. obj.difAmount=obj.amount-0
  292. obj.highlight=obj.difAmount == 0 ? false : true
  293. array[index]=obj
  294. }
  295. }
  296. })
  297. })
  298. this.list.body=this.realList.slice(0)
  299. },
  300. }
  301. }
  302. export const onScanMixin={
  303. data () {
  304. return {
  305. sourcename:"", // 数据集合名称
  306. tapIndex:-1, // 点击的索引
  307. tapKeyname:"", // 点击的键名
  308. barcodekey:"", // 条形码关键字
  309. scaning:false, //扫码中
  310. barcode:null, // 条形码
  311. }
  312. },
  313. computed:{
  314. ...mapGetters(['deviceBrand']),
  315. },
  316. methods:{
  317. // 关闭扫码
  318. onCloseScanPage () {
  319. this.scaning=false
  320. },
  321. // 开启监听
  322. addListenerFn () {
  323. const _this=this
  324. globalEvent.addEventListener('iDataBarcodeEvent', function(e) {
  325. if (e.barcode) {
  326. /*扫完码就关闭扫码,下次需要扫码,再次点击初始化扫码,
  327. 给数据赋值
  328. */
  329. _this.barcode=e.barcode
  330. _this.scaning=false
  331. _this.onFormatCode()
  332. barcodeModel.closeScan();
  333. }
  334. });
  335. },
  336. // 卸载监听
  337. removeListenerFn () {
  338. // 去除监听,关闭扫码
  339. globalEvent.removeEventListener('iDataBarcodeEvent', () => {})
  340. barcodeModel.closeScan();
  341. },
  342. // 格式化点击事件数据
  343. formatTapEvent (e) {
  344. const dataset=e.currentTarget.dataset
  345. const index=this.tapIndex=dataset.index
  346. const keyname=this.tapKeyname=dataset.keyname
  347. const barcodekey=this.barcodekey=dataset.barcodekey
  348. const sourcename=this.sourcename=dataset.sourcename
  349. return {
  350. index,
  351. keyname,
  352. barcodekey,
  353. sourcename
  354. }
  355. },
  356. //扫码
  357. onScan(e) {
  358. this.formatTapEvent(e)
  359. if (this.deviceBrand === BRAND_PRO) {
  360. // iData
  361. /** 初始化扫码
  362. */
  363. barcodeModel.initScan();
  364. this.scaning=true
  365. } else {
  366. // uni-app
  367. uni.scanCode({
  368. scanType:['barCode'],
  369. success:(res)=>{
  370. // console.log(res)
  371. this.barcode=res.result
  372. this.onFormatCode()
  373. },
  374. fail:err=>{
  375. console.log(err)
  376. uni.showToast({
  377. title:err,
  378. icon:"none"
  379. })
  380. }
  381. })
  382. }
  383. },
  384. // 清空input数据
  385. onClearValue(e) {
  386. this.formatTapEvent(e)
  387. this.myClearValue()
  388. },
  389. // 清除数据的回调
  390. myClearValue () {
  391. this.setBarcode()
  392. this.barcode=null
  393. },
  394. // 处理扫到的码,value:条形码
  395. onFormatCode () {
  396. const value=this.barcode
  397. let info=formateScanData(value)
  398. info.value=value
  399. let str='' //显示的值
  400. // 如果有条码类型再进入程序
  401. let {ok,msg}=onErrorBarCodeType(this.barcodekey,value)
  402. if (!ok) {
  403. uni.showToast({
  404. title:msg,
  405. icon:"none",
  406. duration:1500
  407. })
  408. info={}
  409. }else{
  410. uni.showToast({
  411. title:"扫码成功"
  412. })
  413. // 根据不同的条形码类型赋值
  414. switch (info.barCodeType) {
  415. case BARCODE_CAIGOU:
  416. case BARCODE_FINISHEDGOOD:
  417. str=info.itemno
  418. break;
  419. case BARCODE_PRODUCE:
  420. case BARCODE_PROCESS:
  421. case BARCODE_JOBCENTER:
  422. str=info.value
  423. break;
  424. case BARCODE_TARE:
  425. str=info.tare
  426. break;
  427. case BARCODE_OUTSOURCE:
  428. str=info.value
  429. break;
  430. }
  431. this.setBarcode(str)
  432. }
  433. },
  434. // 设置数据
  435. setBarcode (value=null) {
  436. const ok=this.myScanCallback()
  437. if(!ok)return
  438. const index=this.tapIndex
  439. const keyname=this.tapKeyname
  440. const sourcename=this.sourcename
  441. if (sourcename) {
  442. if (index >=0) {
  443. this.$set(this[sourcename][index],keyname,value)
  444. }else{
  445. this.$set(this[sourcename],keyname,value)
  446. }
  447. }else{
  448. this[keyname]=value
  449. }
  450. },
  451. myScanCallback () {
  452. return true
  453. }
  454. }
  455. }