Compare commits

...

456 Commits

Author SHA1 Message Date
张立 e17df7b0d8 fix: scan组件 7 months ago
张立 25daf96696 fix: 11月14号到12月9号的修改 7 months ago
test 37058e5c01 login修改 无验证码登录 文件迁移 Vue2升级Vue3 10/25-11/8 8 months ago
test 30e0ca53c5 issue文件迁移 Vue2升级Vue3 10/25-11/8 8 months ago
test 0ec30d4e53 issue文件迁移 Vue2升级Vue3 10/25-11/8 8 months ago
test 2c810f50ec inventoryMove文件迁移 Vue2升级Vue3 10/25-11/8 8 months ago
test 40b32f5456 inventoryMove文件迁移,action:betweeen改成between Vue2升级Vue3 10/25-11/8 8 months ago
test cd6cf24520 index 文件迁移Vue2升级Vue3 10/25-11/8 8 months ago
test d072b12309 新文件修改 文件迁移Vue2升级Vue3 10/25-11/8 8 months ago
test a57256000c deliver/job 文件迁移Vue2升级Vue3 10/25-11/8 8 months ago
test a263602deb 新文件修改 文件迁移Vue2升级Vue3 10/25-11/8 8 months ago
test a1faee9aac 文件修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 31b19c23e4 文件修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test ce11ed696e 文件修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 864430cdc4 样式修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test f0d3f18ddd import BalanceSelect 改成大写 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test f1bdb1cfa8 import BalanceSelect 改成大写 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test ffa29b802b uni-load-more改写u-loadmore u-popup弹出框异步问题,添加到setTimeout方法内 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 1952d7b7e8 文件修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 0b268ed2e2 main.ts pages.json修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 9190adbdd7 uni_modules\vk-uview-ui\components ref修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test e3618f70a9 comMessage ref修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test a574a49984 页面报错修改 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 53c44b1aa5 pages/customerReturn/coms 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test cee85c60ff store引用 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test eba5273896 mycomponents/page/container/record 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test be04eb258d mycomponents/scan 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 0be5334006 mycomponents/recommend 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test bbc67e3d70 mycomponents/receive 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 96f6b6ecaa mycomponents/query 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test fc15060dc3 mycomponents/job mycomponents/item mycomponents/qty 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 2ec44be25d mycomponents/balance 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 042ebdecde mycomponents/detail 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test ea6f46aafe mycomponents/scan 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 694688ab65 pages/package/record 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test c1e7fcd245 pages mycomponents 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 3a75b774ab pages/issue/coms 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 55af9befa2 pages/pointPutawayJob 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 51b53d3e60 pages/fg 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 8f66e72844 pages/fg 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 316099aa54 pages/deliver 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test f1738c952f 文件迁移Vue2升级Vue3 8/2-10/25 8 months ago
test 38e1fc2f36 page/unPlanned 文件迁移 8/8-10/25 8 months ago
test da792b67bd page/unPlanned 文件迁移 8/8-10/25 8 months ago
test 9ac369b992 page/transfer 文件迁移 8/8-10/25 8 months ago
test b8bdbac627 page/stockUp 文件迁移 8/8-10/25 8 months ago
test 91140e285a page/setter 文件迁移 8/8-10/25 8 months ago
test 11304e965d page/scrap 文件迁移 8/8-10/25 8 months ago
test 834c19b9fb page/repleinsh/record 文件迁移 8/8-10/25 8 months ago
test 1ad14f5a3e page/repleinsh/job 文件迁移 8/8-10/25 8 months ago
test e15df659f0 page/repleinsh/coms 文件迁移 8/8-10/25 8 months ago
test 302b6fca1c page/query 文件迁移 8/8-10/25 8 months ago
test 445dff443a page/query/coms 文件迁移 8/8-10/25 8 months ago
test 827799f186 page/putaway/request 文件迁移 8/8-10/25 8 months ago
test 3db82d1364 page/putaway/record 文件迁移 8/8-10/25 8 months ago
test 5df309e342 page/putaway/job 文件迁移 8/8-10/25 8 months ago
test b0f22c3b28 page/purchaseReturn/job 文件迁移 8/8-10/25 8 months ago
test 21a6f3a18a page/purchaseReturn 文件迁移 8/8-10/25 8 months ago
test 5ef62fb37b page/purchaseReceipt 文件迁移 8/8-10/25 8 months ago
test cb439eddf6 page/productRecycle 文件迁移 8/8-10/25 8 months ago
test 410d81dc87 page/productReceipt/record 文件迁移 8/8-10/25 8 months ago
test 03dc9caab4 page/productReceipt/record 文件迁移 8/8-10/25 8 months ago
test 04890c1922 page/productReceipt/job 文件迁移 8/8-10/25 8 months ago
test 4ae564d47e page/productReceipt/coms 文件迁移 8/8-10/25 8 months ago
test 96d26ac908 page/productPutaway 文件迁移 8/8-10/25 8 months ago
test 254b563563 page/productionReturn/request 文件迁移 8/8-10/25 8 months ago
test 7c12adc9f1 page/productionReturn/record 文件迁移 8/8-10/25 8 months ago
test ee8d706cb0 page/productionReturn/job 文件迁移 8/8-10/25 8 months ago
test b7647bb2f8 page/productionReturn/coms 文件迁移 8/8-10/25 8 months ago
test 8be7a296ac page/productionReturn/coms 文件迁移 8/8-10/25 8 months ago
test 4a10ab1e6e page/productionReceipt 文件迁移 8/8-10/25 8 months ago
test 54ddb6bef0 page/productDismantle 文件迁移 8/8-10/25 8 months ago
test 212472f628 page/pointPutawayJob 文件迁移 8/8-10/25 8 months ago
test 1b4c4f21d5 page/point 文件迁移 8/8-10/25 8 months ago
test cb34c0e8a0 page/package/record 文件迁移 8/8-10/25 8 months ago
test cd3690cf4d page/package/job 文件迁移 8/8-10/25 8 months ago
test 5d17be69be page/package/coms 文件迁移 8/8-10/25 8 months ago
test 8fdb2017d3 page/material 文件迁移 8/8-10/25 8 months ago
test 7beaec532f page/itemHold 文件迁移 8/8-10/25 8 months ago
test 164f9595d6 page/issue/request 文件迁移 8/8-10/25 8 months ago
test f2e6ce3838 page/issue/record 文件迁移 8/8-10/25 8 months ago
test 47c6716e47 page/issue/job 文件迁移 8/8-10/25 8 months ago
test 3cb5df117e page/issue/coms 文件迁移 8/8-10/25 8 months ago
test 6ceb4108a8 page/inventoryMove/job 文件迁移 8/8-10/25 8 months ago
test 0589b23409 page/inventoryMove/coms 文件迁移 8/8-10/25 8 months ago
test 5d9c296c5a page/inspect/job 文件迁移 8/8-10/25 8 months ago
test 7adcef4d12 page/index 文件迁移 8/8-10/25 8 months ago
test b3d5a0aae1 page/fg 文件迁移 8/8-10/25 8 months ago
test a916ae924b page/deliver/request 文件迁移 8/8-10/25 8 months ago
test 49f63a9d8c page/deliver/record 文件迁移 8/8-10/25 8 months ago
test 7eece6e49d page/deliver/job 文件迁移 8/8-10/25 8 months ago
test 004f472040 page/deliver/coms 文件迁移 8/8-10/25 8 months ago
test 021a678e4d mycomponents/page/customerReturn/request 文件迁移 8/8-10/25 8 months ago
test 74555ce7ad mycomponents/page/customerReturn/record 文件迁移 8/8-10/25 8 months ago
test 668899df83 mycomponents/page/customerReturn/job 文件迁移 8/8-10/25 8 months ago
test f02b5a87a6 mycomponents/page/customerReturn/coms 文件迁移 8/8-10/25 8 months ago
test c2ced0d734 mycomponents/page/customerReturn/coms 文件迁移 8/8-10/25 8 months ago
test ab9058e744 mycomponents/page/count/record 文件迁移 8/8-10/25 8 months ago
test 05c24a6a4c mycomponents/page/count/job 文件迁移 8/8-10/25 8 months ago
test 4e55a8dcf6 mycomponents/page/count 文件迁移 8/8-10/25 8 months ago
test a6c14baa6c mycomponents/page/container/record 文件迁移 8/8-10/25 8 months ago
test e65e75151a mycomponents/scan 文件迁移 8/8-10/25 8 months ago
test 4920e82c6d mycomponents/record 文件迁移 8/8-10/25 8 months ago
test ac0efd189d mycomponents/recommend 文件迁移 8/8-10/25 8 months ago
test d2aa7e2f89 mycomponents/query mycomponents/receive 文件迁移 8/8-10/25 8 months ago
test 5f53730dec mycomponents/qty 文件迁移 8/8-10/25 8 months ago
test cc3a2d8878 mycomponents/package 文件迁移 8/8-10/25 8 months ago
test 6106c5630b mycomponents/job 文件迁移 8/8-10/25 8 months ago
test 82f202f5a3 mycomponents/item 文件迁移 8/8-10/25 8 months ago
test 97c69365d7 mycomponents/detail 文件迁移 8/8-10/25 8 months ago
test 61ecba7dc9 mycomponents/common 文件迁移 8/8-10/25 8 months ago
test e08be65e79 mycomponents/button 文件迁移 8/8-10/25 8 months ago
test 9e3e4b8fe4 mycomponents/balance下 文件迁移 8/8-10/25 8 months ago
test dbac1e67da common下文件修改 hybrid\html修改 8/8-10/25 8 months ago
test 1f88f83fe1 提示bug 2024/8/9 8 months ago
test 559cf97eef 提示bug 2024/8/9 8 months ago
test ce51bd898a 修改发料任务查询已经有库存 2024/8/9 8 months ago
test eb9685ff6a 修改翻包焦点消失 2024/8/9 8 months ago
test cfc15c1f53 PDA部分任务增加扫描数量与任务数量不一致的提醒 2024/8/9 8 months ago
test 3f7a11fbf2 修改补料已经有库存余额提示 2024/8/9 8 months ago
test d83f7fd700 优化显示 2024/8/9 8 months ago
test df2c6f785c 修改补料任务筛选没有记住 2024/8/9 8 months ago
test 2c3c3c4079 采购收货打印添加字段,修改页面样式 2024/8/9 8 months ago
test fe40054d40 关闭弹窗的时候失去焦点,隐藏软件盘 2024/8/9 8 months ago
test 6edd503bcd 修改发货扫描标签 2024/8/8 8 months ago
test 97fded5ac0 翻包任务没有扫描,数量为0时校验 2024/8/8 8 months ago
test 2572452cb1 直接翻包打印bug 2024/8/8 8 months ago
test 3ba05343e1 修改翻包,拆包库存查询 2024/8/8 8 months ago
test 0c8ffb7dd1 修改制品回收提示 2024/8/8 8 months ago
test ac3e5f0b15 修改任务列表下拉不刷新和返回列表不刷新 2024/8/8 8 months ago
test 686d24393e 上拉加载更多 2024/8/8 8 months ago
test 9d97501d95 修改直接补料查询条件 2024/8/8 8 months ago
test b82074dcd1 直接发料不扫描来源库位 2024/8/8 8 months ago
test ac5f44c92c 直接发料不扫描来源库位 2024/8/8 8 months ago
test f002e441d9 剩余未满箱自动提交+返回首页 2024/8/8 8 months ago
test d3517108ba 修改直接发料和直接补料 2024/8/8 8 months ago
test 8f6548874b 扫描数量 2024/8/8 8 months ago
test 0c1650388e 重新计算数量 2024/8/8 8 months ago
test 43a8310ed5 按计划完工 2024/8/8 8 months ago
test 9e78826694 拆包打印标签和二维码不一致问题 2024/8/8 8 months ago
test fa45e596da 开关问题 2024/8/8 8 months ago
test e7d8e04fb9 按计划完工打印标签后不清空列表 2024/8/8 8 months ago
test 10d14adeaa 库位 2024/8/7 8 months ago
test d8bcc17a31 修改发料和补料 2024/8/7 8 months ago
test 438d3861b9 修改发料和补料 2024/8/7 8 months ago
test 461c4a2c48 装配收货任务-默认库位 2024/8/7 8 months ago
test bae3f57070 装配收货任务提交校验,关闭提交报错 2024/8/7 8 months ago
test 265f698119 打印 2024/8/7 8 months ago
test 87440a1b8c 装配收货任务提交校验,关闭提交报错 2024/8/7 8 months ago
test 505f232192 补料任务代码提交bug 2024/8/7 8 months ago
test dc45abe72e 拆包打印 2024/8/7 8 months ago
test f1bf3e34de 修改发料任务的扫描 2024/8/7 8 months ago
test 9fd445780a 代码维护 2024/8/7 8 months ago
test 944073e0aa 修改补料任务的推荐 2024/8/7 8 months ago
test c1a8c7a336 HL-4896 2024/8/7 8 months ago
test f3a7deb83e 检验单打印页面不显示问题 2024/8/7 8 months ago
test c83b393163 成品发货 2024/8/7 8 months ago
test fa9dcc68bb 提交代码 2024/8/7 8 months ago
test bfc14865fa 修改按包装号过滤功能 2024/8/7 8 months ago
test af8d109dee 添加备注 2024/8/7 8 months ago
test 0d4d745829 成品发货任务--同一物料,可以扫描提交不在任务中的库位 2024/8/7 8 months ago
test 62f956ab1c 发料,补料任务,查询,重置功能 2024/8/7 8 months ago
test f50a44b1d9 修改发料筛选 2024/8/7 8 months ago
test ab8028619b 修改采购退货的校验 2024/8/7 8 months ago
test 376a5d1276 上拉加载更多数据 2024/8/7 8 months ago
test 4f503a5380 修改生产线查询条件 2024/8/6 8 months ago
test d5d225702d 增加补料任务模糊查询功能 2024/8/6 8 months ago
test 024d5920e7 修改发料任务筛选 2024/8/6 8 months ago
test 177277872b 修改提交 2024/8/6 8 months ago
test c695154058 修改发料任务 2024/8/6 8 months ago
test 5d0d83aa2d 修改发料明细的赋值 2024/8/6 8 months ago
test 8137a35465 修改发料任务执行功能 2024/8/6 8 months ago
test 11051c9dc0 是否继续 2024/8/6 8 months ago
test 4b558ba646 先进先出发料加提示 2024/8/6 8 months ago
test fd6c6b4c10 判断物料代码 2024/8/6 8 months ago
test 3fabf36d7c 隐藏掉包装名称 2024/8/6 8 months ago
test 213bc7d37b 修改发料任务的扫描 2024/8/6 8 months ago
test 094cf0bfee 检验指引单显示问题 2024/8/6 8 months ago
test 550638a5d0 检验指引单显示问题 2024/8/6 8 months ago
test dfceaf0fa1 Merge remote-tracking branch 'origin/hella_vue3' into hella_vue3 8 months ago
test 43c8627cae 检验指引单按钮显示问题 2024/8/6 8 months ago
test b847d241e5 容错 2024/8/6 8 months ago
test 64b42e0e71 容错 2024/8/6 8 months ago
test 868b356a37 增加CreateProductputawayRequestAfterProductreceiptRecordCreated开关校验 2024/8/6 8 months ago
test 63202ac8eb title问题 2024/8/6 8 months ago
test 7263bc3161 显示ui问题 2024/8/5 8 months ago
test ad6b121a96 修改库存转移批量提交 2024/8/5 8 months ago
test 30c6f6c4be 修改补料任务 2024/8/5 8 months ago
test 03bb07e415 修改补料任务 2024/8/5 8 months ago
test 3c7760b8a7 喜婷--关:不用扫描目标库位 2024/8/5 8 months ago
test 4a68d7201a 现场数量只展示20 2024/8/5 8 months ago
test 84cc39bcc9 数据为空去掉打印按钮 2024/8/5 8 months ago
test ff9a9f009e 邱晨提:现场的人不懂这个啥意思,并且这个也没啥影响。 2024/8/5 8 months ago
test 8f429b6630 扫描样式 2024/8/5 8 months ago
test 3b54cba6d7 现场bug:长春海拉PDA线边发料任务筛选功能有问题,最多能显示10条数据 2024/8/4 8 months ago
test ad777dca57 修改打印的跳转方式 2024/8/4 8 months ago
test d63b25e478 PC打印 2024/8/4 8 months ago
test b4a7995882 修改装配收货明细样式 2024/8/4 8 months ago
test c54583182d 添加包名 2024/8/4 8 months ago
test d181863e03 修改版本号 2024/8/3 8 months ago
test 1c5e3ad92c 打印 2024/8/3 8 months ago
test 6f0995ad7a 修改直接上架 2024/8/3 8 months ago
test 5b5637ce20 打印采购收货 2024/8/3 8 months ago
test 2b6bd254f7 UI样式 2024/8/3 8 months ago
test 248212a279 修改无计划完工 2024/8/3 8 months ago
test 31a4cc5bf4 修改样式 2024/8/3 8 months ago
test 24f67a1282 修改按计划完工 2024/8/3 8 months ago
test 7d7505a21e 修改样式 2024/8/3 8 months ago
test 054900db97 修改直接上架 2024/8/3 8 months ago
test 24e9ab2fff 区分制品直接上架和装配直接上架 2024/8/3 8 months ago
test 5ba9676fcc 修改直接上架 2024/8/3 8 months ago
test 9e6c5635e7 修改制品直接上架 2024/8/2 8 months ago
test 9614bd465e 修改预生产上架 2024/8/2 8 months ago
test 129b933893 样式 2024/8/2 8 months ago
test a26e5dd64b 修改批次的赋值 2024/8/2 8 months ago
test 3ed1a278b7 样式 2024/8/2 8 months ago
test b0e7fe5312 修改无计划完工 2024/8/2 8 months ago
test 31db3d40ab 样式 2024/8/2 8 months ago
test 6553b2d0ee 样式+默认选择物料 2024/8/2 8 months ago
test 5bdeabd63d 默认选择物料 2024/8/2 8 months ago
test c0ee72332a 整理预生产上架功能 2024/8/2 8 months ago
test 64b3fe6db4 生产线没传值 2024/8/2 8 months ago
test 8f22527b8f 物料变更 2024/8/2 8 months ago
test 5d104109b1 物料变更 2024/8/2 8 months ago
test c832238124 修改制品直接上架功能 2024/8/2 8 months ago
test d01008daef PDA线边发料任务详情中进行中状态压到了原料库位,且原料库位不应该为空 2024/8/2 8 months ago
test 2f3e13c12f PDA预生产报工和装配报工扫描箱码编辑页面包装个数不正确 2024/8/2 8 months ago
test 0ca8be2cc4 打印还原 2024/08/02 8 months ago
张立 d275bbf7f4 修改制品直接上架及物料变更 2024/8/1 17:29:13 10 months ago
张立 5328d2119f 整理样式2024/8/1 01:18:59 10 months ago
张立 9fb38ff589 增加样式2024/8/1 00:17:33 10 months ago
张立 38fe15dd4a 完善物料变更功能及按计划完工2024/7/31 22:58:41 10 months ago
张立 22760b8409 打印接口 2024/7/31 16:58:31 10 months ago
张立 ccaad1ca3c 打印 2024/7/31 08:28:45 10 months ago
张立 1b5df5fded 修改翻包打印功能2024/7/30 17:28:22 10 months ago
张立 0eb9eee7d8 添加组件 2024/7/29 15:13:04 10 months ago
张立 d0cd063493 增加先进先出发料功能2024/7/29 13:55:39 10 months ago
张立 d716fe237e 增加先进先出直接补料2024/7/29 11:41:24 10 months ago
张立 64ea8ebeca 发料申请添加优先级 2024/7/29 10:37:01 10 months ago
张立 323b67c8ad 修改发料和发料接收任务筛选2024/7/23 16:52:17 10 months ago
张立 ebdcfa896c 修改计划完工2024/7/22 16:27:47 10 months ago
张立 becd817108 添加按包装号查询库存2024/7/22 15:24:24 10 months ago
张立 d02c823304 添加按包装号查询库存 2024/7/22 15:24:24 10 months ago
张立 7453288b2e 修改扫描2024/7/20 13:52:36 10 months ago
张立 a5e1e583a6 修改盘点功能2024/7/20 15:27:09 10 months ago
张立 f328e61e08 修改跳转任务自动扫描2024/7/20 13:04:24 10 months ago
张立 63ee947b31 增加盲盘时的校验 2024/7/19 22:30:25 10 months ago
张立 bf7b78223c 增加盘点相关组件2024/7/19 19:59:14 10 months ago
张立 4ec6b3e2cd 修改发料补料、备货2024/7/19 19:20:40 10 months ago
张立 f4097fede8 修改按计划完工 2024/7/19 11:25:56 10 months ago
张立 5a00aaf5c8 修改直接完工功能2024/7/18 17:24:08 10 months ago
张立 ec66fc3df6 修改标题显示2024/7/18 10:33:31 10 months ago
张立 feb4d0d534 增加长春的完工功能2024/7/17 17:19:34ccProductReceiptDetail,pages.json沒写 10 months ago
张立 c578b157ef 修改任务提示和任务筛选添加承接人 2024/7/15 17:15:05 10 months ago
张立 116a5598ce 直接发料清除物料2024/7/15 15:45:50 10 months ago
张立 305a135735 修改重复扫描没有提示 2024/7/12 13:56:17 10 months ago
张立 88613d0eb2 直接补料扫描数量2024/7/11 19:27:31uni_modules组件没写 10 months ago
张立 1335f3861c 库存管理--标题 2024/7/11 18:25:17 10 months ago
张立 d7b9b77c7e 库存管理--标题2024/7/11 18:25:17src/pages/inventoryMove/record/moveFreeRecord.vue没写 10 months ago
张立 edf39d9f04 生产管理标题 2024/7/11 17:32:01 10 months ago
张立 c56c4bc515 发料管理动态标题 2024/7/11 15:27:05 10 months ago
张立 973f959f3b 原料管理--标题2024/7/11 14:46:56 10 months ago
张立 a3b06a49b1 采购拒绝 2024/7/11 14:30:33 10 months ago
张立 accc0e1eb0 单据查询模块--标题动态取 2024/7/11 14:16:52 10 months ago
张立 541253d6c5 修改样式2024/7/10 15:14:58 10 months ago
张立 cc68fcbff0 修改直接补料查询库存2024/7/10 15:14:14 10 months ago
张立 e859de7dd4 修改查询物料号添加库位和状态,修改扫描后清空2024/7/9 18:33:31 10 months ago
张立 42fb46c61e 修改拆包组件的显示 2024/7/9 16:28:29 10 months ago
张立 0d9f96fbe6 打印loading2024/7/9 13:35:39 10 months ago
张立 5e3a333c90 优化扫描框 2024/7/8 19:59:20 10 months ago
张立 a148be3127 修改盘点 2024/7/8 16:58:41 10 months ago
张立 48e2bd6cbc 采购上架弹出扫描页面2024/7/8 14:26:20 10 months ago
张立 ad4adbc25a 修改按库位查询库存 2024/7/5 17:17:56src/pages/query/location.vue 10 months ago
张立 e634cd5cdd 修改直接发料和发料任务扫描小包装2024/7/5 13:43:09 10 months ago
张立 9dbe73d0b5 修改备货任务扫描其他批次选不中 2024/7/4 19:18:30 10 months ago
张立 7ec6a5ffb2 增加组件2024/7/3 16:35:31 10 months ago
张立 adff8617c9 重新封装一个扫描组件2024/7/2 15:59:00 10 months ago
张立 1cdec1142b 修改盘点2024/7/1 16:09:10 10 months ago
张立 6ec83002d5 修改盘点2024/7/1 14:34:50没有修改vue3 10 months ago
张立 4a414161a8 打印:制造件标签2024/7/1 14:18:25 10 months ago
张立 6659954fbe 盘点库位 2024/7/1 13:35:17 10 months ago
张立 584377da42 目标库位 2024/6/27 17:03:11 10 months ago
张立 a99f65dfeb 字段2024/6/26 16:15:32 10 months ago
张立 82eaf91bbb 修改库位必须校验大小写 2024/6/26 15:04:54 10 months ago
张立 0e0e0323e4 itemcode 2024/6/26 14:43:15 10 months ago
张立 eff81553fe 修改拒收功能2024/6/26 10:33:28 10 months ago
张立 1cfb4b8579 PDA所有任务都加承接人校验 2024/6/25 15:40:59 10 months ago
张立 a9d0069afe PDA所有任务都加承接人校验2024/6/25 15:40:59src/api/request2.js 10 months ago
张立 cf7d600add 增加头部信息 后端添加过滤承接人条件2024/6/25 09:43:11 10 months ago
张立 937c7574be 修改直接补料2024/6/21 16:36:24 10 months ago
张立 f609957e14 bug 修复 2024/6/21 10:05:16 10 months ago
张立 804cde655f 打印 10 months ago
张立 bc919bf89e 修改发料不使用在途库 10 months ago
张立 cb5964dbc2 打印样式修改 10 months ago
张立 9458c72085 PDA采购收货任务执行,是否打印的开关 10 months ago
张立 394d381373 任务列表直接扫描2024/6/18 19:52:55 10 months ago
张立 33a59d5e26 组件扫码 10 months ago
张立 3aa0d74ab5 打印数据bug 2024/6/18 13:48:02 10 months ago
张立 e497412681 前一个提交备注修改:直接翻包 2024/6/17 14:07:02 10 months ago
张立 c7d93b865c 报错代码2024/6/12 18:26:48 10 months ago
张立 b5c618d7d6 翻包打印 2024/6/15 14:17:06没改完 10 months ago
张立 59a863a9e6 上架模块fromInventoryStatus2024/6/14 19:01:24 10 months ago
张立 922a6ca3ea 修改预生产收货任务 提交报错 2024/6/14 18:54:02 10 months ago
张立 a129f7420c 6-14 15:09 查询库存余额 10 months ago
张立 4c26aa814c 6-12 16:30采购收货打印 10 months ago
张立 72f8f62986 6月13号15:53之前的提交 10 months ago
张立 ff0649af5e 8月13号1点12之前git提交记录的修改 10 months ago
张立 2e62d67844 6月11号上拉加载更多还没改 10 months ago
张立 1c12bb1a47 修改6月6号到8号的问题 修改装配收货 弹出软键盘 预生产收货任务列表--上拉加载 10 months ago
张立 ac0f8cb931 测试 1 year ago
张立 f017805d76 改成vue3 1 year ago
张立 3e278ce6e2 登录页面和消息提示组件 1 year ago
张立 18a518be06 基础框架 1 year ago
张立 61084b90ca 多条打印 1 year ago
聂喜婷 2f61b30b4b 修改成品发货 1 year ago
聂喜婷 6cb5b7840a 修改地址 1 year ago
聂喜婷 143e95c540 修改上加任务问题 1 year ago
聂喜婷 fbe96a097b 修改制品上架任务 1 year ago
聂喜婷 95de5ee2b3 修改装配收货任务的提交 1 year ago
聂喜婷 11a0986d6b Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 965f7e81cc 修改样式 1 year ago
李俊城 b023fad1f0 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 dfd3742667 修改配置 1 year ago
张立 f6f44c02bb 打印 1 year ago
张立 e19c63b2d3 app判断 1 year ago
李俊城 2fcc173aad Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 25eb91a677 添加打印功能 1 year ago
张立 813738ef39 翻包任务,发货单,采购收货,采购拒绝 1 year ago
张立 191a9ca271 采购收货管理合格转隔离,隔离转合格,隔离转报废,合格转报废,报废转隔离,库存移动 主子合并 1 year ago
刘忱 0dbb038e57 修改bug 1 year ago
张立 11609288fb 调拨出库 计划外出库 计划外入库 报废出库 主子合并 1 year ago
张立 9b0818564b 成品发货申请 成品发货任务 客户退货申请 客户退货任务 1 year ago
聂喜婷 c7ef460c8a Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 aac9333bc9 修改合格转隔离功能 1 year ago
张立 becd39f135 预生产收货 装配收回 制品回收 报废收货 制品上架主子合并 1 year ago
聂喜婷 9725bd4a7a Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 ab46faec0a 上架增加库存状态的显示 1 year ago
张立 0ba1a3439d 生产退料 生产合格退料申请 生产隔离退料申请 主子合并 1 year ago
张立 e092299817 采购上架任务主子合并,删掉注释 1 year ago
张立 4109a37d70 采购退货申请,采购退货任务主子合并,补料申请 1 year ago
张立 3945e8c62c 采购退货申请主子合并 1 year ago
聂喜婷 0459a9b101 修改样式 1 year ago
聂喜婷 501062b03b 修改翻包样式 1 year ago
聂喜婷 06c418c66c 整理PDA样式 1 year ago
聂喜婷 96978e396a Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 832778a318 修改发货记录查询 1 year ago
李俊城 77d6dc77d6 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 ddb00b8e8c 配置开关 1 year ago
聂喜婷 3100ee0625 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 f3ad067992 修改样式 1 year ago
张立 00e5d71199 打印功能 1 year ago
聂喜婷 2d2b0928a2 修改供应商发货记录扫码功能 1 year ago
聂喜婷 0ad4051cbc 修改菜单样式 1 year ago
聂喜婷 2a61a76747 增加拒收功能 1 year ago
聂喜婷 b2996bc205 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 a16bdb3639 修改样式及翻包功能 1 year ago
李俊城 1f35ccc894 修改库位校验 1 year ago
张立 6f09def9de 判断修改 1 year ago
张立 11598d0fe9 采购上架任务详情组件 1 year ago
聂喜婷 4f628eef9f 修改状态 1 year ago
聂喜婷 7eb925f20d Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 de241ef8f6 修改上架任务请求 1 year ago
刘忱 26981d77e1 修改端口和命令 1 year ago
张立 64831c1f73 分环境 1 year ago
张立 19a677fcc1 地址分环境 1 year ago
刘忱 4da7dcc15f 统一文件名 1 year ago
刘忱 e209873949 修改海拉环境 1 year ago
刘忱 2981c09a62 更改nginx配置 1 year ago
聂喜婷 97fb039d25 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 ebe3e03872 修改上架任务卡片 1 year ago
李俊城 77d44406e0 修改更新 1 year ago
聂喜婷 033dbb39d0 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 29284fb824 修改升级 1 year ago
李俊城 13039715d5 修改库位扫描标签 1 year ago
李俊城 a197bf484f 修改采购上架 1 year ago
李俊城 725adb6a5c 修改采购收货显示 1 year ago
聂喜婷 558b3b400e Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 a8d2d7e890 修改发货 1 year ago
李俊城 fff686d287 修改计划外出库校验 1 year ago
李俊城 9525533074 修改默认库位提示。预生产收货任务提示 1 year ago
李俊城 1ec30743b1 装配收货任务 1 year ago
李俊城 dfb9194b13 修改补料参数赋值 1 year ago
李俊城 5c9165bc75 装配任务扫码校验 1 year ago
聂喜婷 49959e3862 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 9bda5815a0 修改组件的显示 1 year ago
李俊城 b2bb54b6c7 修改提示 1 year ago
李俊城 0ba5894242 报废收货任务 1 year ago
李俊城 e07512faf6 删除无用文件 1 year ago
李俊城 2a2509e2d4 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 0a1235c223 修改功能 1 year ago
李俊城 677a9f7d10 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 d9fb5fecc5 修改提示 1 year ago
聂喜婷 837339efb0 修改备货申请 1 year ago
聂喜婷 44a8f369d5 修改备货任务 1 year ago
聂喜婷 e2f9b05134 修改备货任务 1 year ago
李俊城 9582c1d183 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 95c6594fa3 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 4fc1029961 修改库存转移功能 1 year ago
聂喜婷 e50e73f3e0 修改制品收货 1 year ago
聂喜婷 6241e913ae 修改补料功能 1 year ago
李俊城 8d354069eb 制品回收 1 year ago
聂喜婷 244c2042c9 修改补料任务 1 year ago
聂喜婷 07082655da 修改发料功能 1 year ago
聂喜婷 351ae12524 增加组件 1 year ago
聂喜婷 9a7677546f 移除组件 1 year ago
聂喜婷 f5d1e37384 增加组件 1 year ago
聂喜婷 3462f73287 移除文件 1 year ago
聂喜婷 ab69394079 修改装配收货 1 year ago
聂喜婷 7cd4df004d 修改制品完工收货 1 year ago
聂喜婷 cf3e1311fd Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 c0c637388a 增加新页面 1 year ago
李俊城 4f173f179d 修改推荐库位 1 year ago
李俊城 e83e6a4512 修改采购收货 1 year ago
李俊城 d27bcf2313 添加备货任务,修改标题更新 1 year ago
李俊城 e31d10e346 修改数据权限错误 1 year ago
李俊城 f796ccac69 直接备货任务 1 year ago
李俊城 b8ff5958ad 修改来源库区校验 1 year ago
李俊城 c4450633fb 修改翻包记录 1 year ago
李俊城 8c54221efa 翻包任务 1 year ago
李俊城 eb44fa07b8 翻包任务 1 year ago
李俊城 04997d2d1e 修改注释 1 year ago
李俊城 ac9d1b0458 修改采购收货扫描数量 1 year ago
李俊城 086fc126d9 采购上架编辑修改 1 year ago
李俊城 061f57a2f5 采购上架任务 1 year ago
李俊城 3b1fcc747d 修改采购收货编辑 1 year ago
李俊城 db2b76947e 修改单位名称 1 year ago
李俊城 3cffde3b2f 采购收货,提交没收货的赋值为0 1 year ago
李俊城 98f6a409bd 修改配置文件 1 year ago
聂喜婷 8e4ce6de11 修改列表样式 1 year ago
聂喜婷 f6b5639e6d 修改复制按钮样式 1 year ago
李俊城 f5d2e2ace1 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 fe91a3f283 采购收货扫描数据逻辑验证 1 year ago
刘忱 5ca1cc49e7 修改nginx版本 1 year ago
聂喜婷 3167e9e482 增加包装组件 1 year ago
陈薪名 32c46f219c 修改大小 1 year ago
陈薪名 3c19692f8e 修改大小 1 year ago
陈薪名 c8519dfc3d 修改大小 1 year ago
陈薪名 2fd174658e 修改大小写 1 year ago
陈薪名 1fa968c4ae 修改大小写 1 year ago
陈薪名 a8353597d4 修改大小写 1 year ago
陈薪名 cae517392c 修改文件 1 year ago
李俊城 4467f0a6b1 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 67a30941d2 修改文件 1 year ago
陈薪名 927b162255 配置文件修改 1 year ago
李俊城 3851d362da Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
李俊城 c342722ca9 修改打包命令 1 year ago
聂喜婷 c1bb7601b0 Merge branch 'master_hella' of http://dev.ccwin-in.com:3000/sfms3.0/sfms3.0-uniapp into master_hella 1 year ago
聂喜婷 29c71637f5 修改采购收货任务列表 1 year ago
李俊城 6b63aaf4d4 修改编译大小写问题 1 year ago
李俊城 9610965086 添加主页面搜索菜单功能 1 year ago
聂喜婷 6d3fdb8c57 修改样式 1 year ago
聂喜婷 1df31bb8bc 修改推荐数量和实际数量的对比 1 year ago
聂喜婷 bd9e6a0afb 修改采购收货、修改包装规格 1 year ago
李俊城 068bd7c003 隐藏软件盘 1 year ago
李俊城 da4c5c11e2 修改任务库位,推荐库位,采购收货整单收货按钮 1 year ago
李俊城 be9985d925 删除无用代码 1 year ago
  1. 71
      .commitlintrc.js
  2. 15
      .env.development
  3. 11
      .env.hella13
  4. 11
      .env.hella14
  5. 11
      .env.hella15
  6. 11
      .env.hella16
  7. 12
      .env.hella8
  8. 11
      .env.hella9
  9. 7
      .env.production
  10. 12
      .env.test
  11. 2
      .eslintignore
  12. 49
      .eslintrc.json
  13. 32
      .gitignore
  14. 4
      .hbuilderx/debug.config.json
  15. 20
      .hbuilderx/launch.json
  16. 9
      .prettierrc.js
  17. 7
      Dockerfile
  18. 21
      LICENSE
  19. 260
      README.md
  20. 43
      index.html
  21. 53
      nginx.conf
  22. 12051
      package-lock.json
  23. 110
      package.json
  24. 2
      password.txt
  25. 6260
      pnpm-lock.yaml
  26. 10
      shims-uni.d.ts
  27. 102
      src/App.vue
  28. 132
      src/api/http.ts
  29. 67
      src/api/httpRequest3.js
  30. 41
      src/api/login.js
  31. 2698
      src/api/request2.js
  32. 117
      src/common/appUpdate.js
  33. 50
      src/common/array.js
  34. 139
      src/common/balance.js
  35. 177
      src/common/basic.js
  36. 10
      src/common/calc.js
  37. 9
      src/common/config.js
  38. 281
      src/common/detail.js
  39. 181
      src/common/directory.js
  40. 107
      src/common/label.js
  41. 44
      src/common/noclick.js
  42. 101
      src/common/record.js
  43. 236
      src/common/style/new_style.css
  44. 31
      src/common/style/pdabasic.css
  45. 16
      src/common/utils/storage.js
  46. BIN
      src/components/kk-printer/empty-icon.png
  47. 416
      src/components/kk-printer/index.vue
  48. 402
      src/components/kk-printer/utils/barcode.js
  49. 723
      src/components/kk-printer/utils/bluetoolth.js
  50. 23
      src/components/kk-printer/utils/index.js
  51. 14633
      src/components/kk-printer/utils/mqtt.js
  52. 1
      src/components/kk-printer/utils/mqtt.min.js
  53. 285
      src/components/kk-printer/utils/printUtil-GBK.js
  54. 778
      src/components/kk-printer/utils/qrcode.js
  55. 171
      src/components/kk-printer/utils/util.js
  56. 299
      src/components/my-paging/my-paging.vue
  57. 885
      src/components/show-modal/show-modal.vue
  58. 13
      src/env.d.ts
  59. 95
      src/hybrid/html/point.html
  60. 67
      src/hybrid/html/pointPutawayJob.html
  61. 67
      src/hybrid/html/purchaseReceiptJob.html
  62. 74
      src/main.js
  63. 48
      src/main.ts
  64. 64
      src/manifest.json
  65. 239
      src/mycomponents/balance/balance.vue
  66. 2
      src/mycomponents/balance/balanceDetailPopup.vue
  67. 2
      src/mycomponents/balance/balanceMove.vue
  68. 85
      src/mycomponents/balance/balanceSelect.vue
  69. 29
      src/mycomponents/balance/batch.vue
  70. 51
      src/mycomponents/balance/bussinessType.vue
  71. 125
      src/mycomponents/balance/handleBalance.vue
  72. 64
      src/mycomponents/balance/handleBalanceBatch.vue
  73. 27
      src/mycomponents/balance/level.vue
  74. 21
      src/mycomponents/balance/light.vue
  75. 42
      src/mycomponents/balance/location.vue
  76. 55
      src/mycomponents/balance/pack.vue
  77. 87
      src/mycomponents/balance/productionLabel.vue
  78. 126
      src/mycomponents/balance/recommendBalance.vue
  79. 55
      src/mycomponents/balance/recommendBalanceBatch.vue
  80. 42
      src/mycomponents/balance/toLocation.vue
  81. 0
      src/mycomponents/batch/batch.vue
  82. 40
      src/mycomponents/button/comCheckAll.vue
  83. 74
      src/mycomponents/button/requestButton.vue
  84. 46
      src/mycomponents/common/comBlankView.vue
  85. 29
      src/mycomponents/common/comEmptyView.vue
  86. 4
      src/mycomponents/common/comListHint.vue
  87. 124
      src/mycomponents/common/comListItem.vue
  88. 1026
      src/mycomponents/common/comMessage.vue
  89. 25
      src/mycomponents/common/comPopup.vue
  90. 111
      src/mycomponents/container/targetContainer.vue
  91. 315
      src/mycomponents/detail/comDetailCard.vue
  92. 173
      src/mycomponents/detail/comDetailCardBatch.vue
  93. 138
      src/mycomponents/detail/comJobDetailCard.vue
  94. 151
      src/mycomponents/detail/comJobDetailCardBatch.vue
  95. 178
      src/mycomponents/detail/comLableDetailCard.vue
  96. 185
      src/mycomponents/detail/comRecommendDetailCard.vue
  97. 229
      src/mycomponents/detail/comRecommendDetailCardBatch.vue
  98. 270
      src/mycomponents/detail/comRequestDetailCard.vue
  99. 44
      src/mycomponents/detail/detailBalanceInfo.vue
  100. 103
      src/mycomponents/detail/detailCommonInfo.vue

71
.commitlintrc.js

@ -0,0 +1,71 @@
// @ts-check
/** @type {import('cz-git').UserConfig} */
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'body-leading-blank': [2, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'subject-case': [0],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release'
]
]
},
prompt: {
// 中英文对照版
// messages: {
// type: '选择你要提交的类型 :',
// scope: '选择一个提交范围 (可选):',
// customScope: '请输入自定义的提交范围 :',
// subject: '填写简短精炼的变更描述 :\n',
// body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n',
// breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n',
// footerPrefixsSelect: '选择关联issue前缀 (可选):',
// customFooterPrefixs: '输入自定义issue前缀 :',
// footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
// confirmCommit: '是否提交或修改commit ?'
// },
// types: [
// { value: 'feat', name: 'feat: 新增功能' },
// { value: 'fix', name: 'fix: 修复缺陷' },
// { value: 'docs', name: 'docs: 文档变更' },
// { value: 'style', name: 'style: 代码格式' },
// { value: 'refactor', name: 'refactor: 代码重构' },
// { value: 'perf', name: 'perf: 性能优化' },
// { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' },
// {
// value: 'build',
// name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)'
// },
// { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
// { value: 'revert', name: 'revert: 回滚 commit' },
// {
// value: 'chore',
// name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)'
// },
// { value: 'wip', name: 'wip: 正在开发中' },
// { value: 'workflow', name: 'workflow: 工作流程改进' },
// { value: 'types', name: 'types: 类型定义文件修改' }
// ]
}
}

15
.env.development

@ -0,0 +1,15 @@
VITE_BASE_URL=http://localhost:12080/admin-api
#VITE_BASE_URL=http://dev.ccwin-in.com:28051/api/admin-api
# VITE_BASE_URL_IMAGE=http://172.22.32.9:81/admin-api
# 租户配置
VITE_TENANT='[{"text":"英泰","value":1}]'
# 是否是测试环境
VITE_isDevelopment=true
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='http://172.22.32.9:90'
# 项目管理模式 批次货/包装
VITE_MANAGE_MODEL="BY_BATCH"

11
.env.hella13

@ -0,0 +1,11 @@
VITE_BASE_URL=http://172.21.32.13:81/api/admin-api
VITE_BASE_URL_IMAGE=http://172.21.32.13:81/admin-api
# 租户配置
VITE_TENANT='[{"text":"长春","value":1}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='http://172.21.32.13:90'

11
.env.hella14

@ -0,0 +1,11 @@
VITE_BASE_URL=http://172.21.32.14:81/api/admin-api
VITE_BASE_URL_IMAGE=http://172.21.32.14:81/admin-api
# 租户配置
VITE_TENANT='[{"text":"长春","value":1}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='http://172.21.32.14:90'

11
.env.hella15

@ -0,0 +1,11 @@
VITE_BASE_URL=https://scp.faway-hella.com:81/api/admin-api
VITE_BASE_URL_IMAGE=https://scp.faway-hella.com:81/admin-api
# 租户配置
VITE_TENANT='[{"text":"长春","value":1}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='https://scp.faway-hella.com'

11
.env.hella16

@ -0,0 +1,11 @@
VITE_BASE_URL=https://scptest.faway-hella.com:81/api/admin-api
VITE_BASE_URL_IMAGE=https://scptest.faway-hella.com:81/admin-api
# 租户配置
VITE_TENANT='[{"text":"长春","value":1},{"text":"成都","value":2}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='https://scptest.faway-hella.com'

12
.env.hella8

@ -0,0 +1,12 @@
VITE_BASE_URL=http://172.22.32.8:81/api/admin-api
VITE_BASE_URL_IMAGE=http://172.22.32.8:81/admin-api
# 租户配置
VITE_TENANT='[{"text":"成都","value":2}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='http://172.22.32.8:90'

11
.env.hella9

@ -0,0 +1,11 @@
VITE_BASE_URL=http://172.22.32.9:81/api/admin-api
VITE_BASE_URL_IMAGE=http://172.22.32.9:81/admin-api
# 租户配置
VITE_TENANT='[{"text":"成都","value":2}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='http://172.22.32.9:90'

7
.env.production

@ -0,0 +1,7 @@
VITE_BASE_URL=http://172.21.32.14:81/api/admin-api VITE_BASE_URL_IMAGE=http://172.21.32.14:81/admin-api # 租户配置 VITE_TENANT='[{"text":"长春","value":1},{"text":"成都","value":2}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='http://172.21.32.14:90'

12
.env.test

@ -0,0 +1,12 @@
VITE_BASE_URL=http://dev.ccwin-in.com:25300/api/admin-api
VITE_BASE_URL_IMAGE=http://dev.ccwin-in.com:25300/admin-api
# 租户配置
VITE_TENANT='[{"text":"长春","value":1},{"text":"成都","value":2}]'
# 是否是测试环境
VITE_isDevelopment=false
# 积木报表请求路径
VITE_JMREPORT_BASE_URL='http://dev.ccwin-in.com:25310'

2
.eslintignore

@ -0,0 +1,2 @@
dist
*.nvue

49
.eslintrc.json

@ -0,0 +1,49 @@
{
"parser": "vue-eslint-parser",
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"parserOptions": {
"ecmaVersion": 2021,
"parser": "@typescript-eslint/parser",
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"extends": [
"airbnb-base",
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:vue/vue3-essential",
"plugin:@typescript-eslint/recommended"
],
"plugins": ["vue", "@typescript-eslint", "todo-ddl"],
"rules": {
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"import/extensions": "off",
"quotes": ["warn", "single"],
"semi": ["warn", "never"],
"import/no-unresolved": "off",
"todo-ddl/diy": "warn",
"import/prefer-default-export": "off",
"no-param-reassign": "warn",
"import/no-extraneous-dependencies": "off",
"max-len": "warn",
"no-restricted-syntax": "off",
"no-bitwise": "off",
"camelcase": "off",
"no-case-declarations": "off",
"@typescript-eslint/no-namespace": "off",
"no-undef": "off",
"no-promise-executor-return": "off",
"vue/multi-word-component-names": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-ts-comment": "off",
"linebreak-style": "off"
}
}

32
.gitignore

@ -1,21 +1,31 @@
# Logs
logs
*.log
.DS_Store
node_modules/
unpackage/
dist/
wxcomponents
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
*.local
# Editor directories and files
.project
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.sw*
.hbuilderx
.gitee
.github
package-lock.json
yarn.lock

4
.hbuilderx/debug.config.json

@ -1,4 +0,0 @@
{
"rootPathIndex": 1,
"webRoot": "${projectDir}"
}

20
.hbuilderx/launch.json

@ -1,20 +0,0 @@
{
// launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version" : "0.0",
"configurations" : [
{
"app-plus" : {
"launchtype" : "local"
},
"default" : {
"launchtype" : "local"
},
"type" : "uniCloud"
},
{
"openVueDevtools" : true,
"type" : "uni-app:h5"
}
]
}

9
.prettierrc.js

@ -0,0 +1,9 @@
module.exports = {
printWidth: 700, // 一行的字符数,如果超过会进行换行,默认为80
tabWidth: 2, // 一个 tab 代表几个空格数,默认为 2 个
useTabs: false, //是否使用 tab 进行缩进,默认为false,表示用空格进行缩减
singleQuote: true, // 字符串是否使用单引号,默认为 false,使用双引号
semi: false, // 行尾是否使用分号,默认为true
trailingComma: 'none', // 是否使用尾逗号
bracketSpacing: true // 对象大括号直接是否有空格,默认为 true,效果:{ a: 1 }
}

7
Dockerfile

@ -0,0 +1,7 @@
# 设置基础镜像
FROM win-nginx
WORKDIR /opt/eam-pda
COPY nginx.conf /usr/local/nginx/conf/nginx.conf
# 将dist/build/h5/文件中的内容复制到 /opt/eam-pda 这个目录下面
COPY dist/build/h5/ /opt/eam-pda

21
LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 sugar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

260
README.md

@ -0,0 +1,260 @@
# uni-vue3-ts-template
uni-app Vue3 + TypeScript + Vite + Pinia + Unocss 模板项目
支持小程序,H5,App
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxODc4OTk1OQ==653218789959)
![Unocss](https://fastly.jsdelivr.net/gh/MellowCo/image-host/2022/202211121156442.png)
| H5 | 微信小程序 | App(iOS) | App(Android) |
| :-------------------------------------------------------------------------: | :-------------------------------------------------------------------------: | :-------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------: |
| ![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzE5Mzc4MzUyMQ==653193783521) | ![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzE5Mzc1Mzk1MQ==653193753951) | ![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMDc2NTcwNg==653210765706) | <img src="https://img.cdn.sugarat.top/mdImg/MTY1MzIxMzkyOTQxNg==653213929416" width="360"/> |
其它模板
* Vue3的uni-app 纯js模板:[uni-app-template](https://github.com/ATQQ/uni-app-template)
* Vue3的Web应用模板:[vite-vue3-template](https://github.com/ATQQ/vite-vue3-template)
## Env Suggest
**Node >= 14.19**
**pnpm 7**
**Registry taobao - https://registry.npmmirror.com/**
## Use This Template
```sh
npx degit atqq/uni-vue3-ts-template#main my-uni-vue3-ts-vite-project
```
## Feature
### Prod
* [x] [Vue3](https://vuejs.org/)
* [x] [Pinia](https://pinia.vuejs.org/) - replace vuex
* [x] [Axios](https://github.com/axios/axios)
* UI/组件库
* [x] [uView](https://vkuviewdoc.fsq.pub/) - vk-uview-ui
* [ ] [uni-ui](https://github.com/dcloudio/uni-ui) - 待接入
### Dev
* [x] [Vite](https://github.com/vitejs/vite)
* [x] [TypeScript](https://github.com/microsoft/TypeScript/#readme)
* [x] [Sass](https://github.com/sass/sass)
* [x] [Less](https://github.com/less/less.js)
* [x] [Eslint](https://eslint.org/)
* [x] [Prettier](https://prettier.io/)
* [x] [Vitest](https://vitest.dev/) - replace jest
* [x] [unocss](https://github.com/unocss/unocss) - 即时按需原子 css 引擎
* [x] GitHooks [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks#readme)
* ~~LintStaged~~
* ~~StyleLint~~
## 使用
### 安装依赖
**建议使用pnpm,依赖安装速度更快**
```sh
npm i -g pnpm
```
```sh
pnpm install
```
**MAC M1(ARM芯片),其它操作系统无需关注**,正常运行需要手动安装 `esbuild-darwin-64`即可
```sh
pnpm add esbuild-darwin-64@0.15.13 -D
```
## 本地启动
### 微信小程序
```sh
# 构建出产物
pnpm dev:mp-weixin
```
> **Q1:** 如果dev的时候发现报错,可以尝试删除`node_modules`之后再在命令行中运行`pnpm install --shamefully-hoist`重新安装依赖再`pnpm dev:mp-weixin`
>
> [详细参考文档](https://pnpm.io/zh/faq#%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%883)
> **Q2:** 如果运行白屏,有报错信息 “app.js错误ReferenceError: regeneratorRuntime is not defined”
>
> 参考[解决方案](https://blog.csdn.net/FUFCY/article/details/125160828) 给微信小程序IDE开启**增强编译选项**
然后将编译结果`dist/dev/mp-weixin`导入微信开发者工具即可运行
<details>
<summary>点击查看 导入详细步骤</summary>
![图片](https://img.cdn.sugarat.top/mdImg/MTYzNzQxNjc3MjA4Mw==637416772083)
![图片](https://img.cdn.sugarat.top/mdImg/MTYzNzQxNjg4MTUwNA==637416881504)
![图片](https://img.cdn.sugarat.top/mdImg/MTYzNzQxNjY3OTY0NQ==637416679645)
</details>
### H5
```sh
# CSR
pnpm dev:h5
# SSR
pnpm dev:h5:ssr
```
根据提示,打开对应地址即可访问
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMTE0MDEzMg==653211140132)
### App
>**Q1:** 如启动到App侧有报错?
>请更新至最新的HBuilderX-Alpha客户端
#### 安装一些必要工具
需要使用 `uni-app` 官方提供的 [HBuilderX](https://www.dcloud.io/hbuilderx.html) 启动项目
**Android模拟器在MacOSX、Windows上都可以安装;iOS模拟器只能在MacOSX上安装。**
先安装相关模拟器,[详细参考文档](https://hx.dcloud.net.cn/Tutorial/App/installSimulator)
* 安卓:[夜神模拟器](https://www.yeshen.com/blog/)
* iOS:Mac上安装Xcode
准备就绪后,使用 HBuilderX 打开项目
#### iOS模拟器运行
通过顶部菜单栏,找到运行入口
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMjk1MTgzNw==653212951837)
选择一个目标设备,点击启动即可
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMjk3NDM0NQ==653212974345)
#### Android模拟器运行
这里以[夜神模拟器](https://www.yeshen.com/blog/)为例
<details>
<summary>点击查看 详细步骤</summary>
先通过 HBuilderX 修改模拟器端口为 `62001`
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDAzMjIwNg==653214032206)
打开夜神模拟器
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDA5OTYxNg==653214099616)
选择运行到 Android 基座
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDEzMzI0OA==653214133248)
选择已经打开的模拟器,点击运行即可
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDIxNjczNw==653214216737)
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMzkyOTQxNg==653213929416)
</details>
## 打包构建
### 微信小程序
```
pnpm build:mp-weixin
```
### H5
```sh
# CSR
pnpm build:h5
# SSR
pnpm build:h5:ssr
```
### App
基于 `HBuilderX` 参考[官方文档](https://hx.dcloud.net.cn/Tutorial/App/SafePack)进行进一步的操作
其它更多运行脚本 查看 [package.json](./package.json)中的scripts
## css预处理
### 已配置`scss`和`less`全局变量
```typescript
// vite.config.ts
export default defineConfig({
// ......
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "@/static/styles/variables.scss";'
},
less: {
additionalData: '@import "@/static/styles/variables.less";'
}
}
}
})
```
`additionalData`的值是文件的路径,可以按照自己业务需求去修改,**如果项目样式变量分的比较细,可以使用一个样式文件引入多个变量样式文件,然后在这里引入入口文件**
## 别名配置
如果我们想要在`import`的时候 src 的路径简写成`@`,下面的就是配置 vite 的别名,[属性类型请查看vite文档](https://vitejs.cn/config/#resolve-alias)
- `@` 代替 `./src`
- `@components`代替`./src/components`
```typescript
// vite.config.ts
export default defineConfig({
// ......
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components')
}
}
})
```
例子:
```diff
// pages/index/index.vue
- import Hello from '../../components/hello/index.vue'
+ import Hello from '@/components/hello/index.vue'
// 或者
+ import Hello from '@components/hello/index.vue'
```
### ts
如果是使用ts开发,这样还不够,ts不会识别路径的别名,显示找不到模块的报错,这个时候需要修改 `tsconfig.json` 文件,纠正下路径才可以。
```diff
// tsconfig.json
{
// ......
"compilerOptions": {
// ......
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"],
+ "@components/*": ["src/components/*"]
}
},
}
```
添加 `baseUrl``paths` 参数,就可以完美解决编辑器的报错提示了!
## 原子化css
* [unocss](https://github.com/unocss/unocss) - 即时按需原子 css 引擎
* [unocss-preset-weapp](https://github.com/MellowCo/unocss-preset-weapp) - 兼容小程序 unocss 预设
> 支持小程序,h5,app
![](https://fastly.jsdelivr.net/gh/MellowCo/image-host/2022/202211121156442.png)

43
index.html

@ -1,22 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
<!-- 配置H5的 web图标static/logo.png -->
<link rel="icon" href="../../static/logo.png" />
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app">
<!--app-html-->
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

53
nginx.conf

@ -0,0 +1,53 @@
user root;
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
charset utf-8,gbk;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$request_time $upstream_response_time"';
proxy_cache_path /opt/nginx_cache/ levels=1:2 keys_zone=my_zone:10m inactive=300s max_size=5g;
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 600s;
client_max_body_size 200m;
gzip on;
gzip_min_length 10k;
gzip_comp_level 9;
gzip_buffers 4 16k;
gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
upstream eam {
server localhost:25210 weight=10 max_fails=3 fail_timeout=10s;
}
server {
listen 25203;
server_name_in_redirect off;
server_name dev.ccwin-in.com;
location /api/ {
proxy_pass http://eam/;
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
}
location / {
proxy_cache my_zone;
proxy_cache_valid 200 304 12h;
proxy_cache_key $host$uri$is_args$args;
try_files $uri $uri/ /index.html;
root /opt/eam-pda;
index index.html index.htm;
}
}
}

12051
package-lock.json

File diff suppressed because it is too large

110
package.json

@ -1,46 +1,86 @@
{
"name": "uni-preset-vue",
"version": "0.0.0",
"name": "闻荫APP",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "uni",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:app": "uni -p app",
"dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios",
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-weixin": "uni -p mp-weixin",
"build:app": "uni build -p app",
"build:app-android": "uni build -p app-android",
"build:app-ios": "uni build -p app-ios",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-weixin": "uni build -p mp-weixin"
"test": "uni build --mode test",
"test:mp-weixin": "uni build -p mp-weixin",
"test:app": "uni build -p app",
"test:custom": "uni build -p",
"prod:mp-weixin": "uni build -p mp-weixin --mode production",
"prod:app": "uni build -p app --mode production",
"prod:custom": "uni build -p --mode production",
"prod": "uni build --mode production",
"hella8": "uni build --mode hella8",
"hella9": "uni build --mode hella9",
"hella13": "uni build --mode hella13",
"hella14": "uni build --mode hella14",
"hella15": "uni build --mode hella15",
"hella16": "uni build --mode hella16"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-3090920231225001",
"@dcloudio/uni-app-plus": "3.0.0-3090920231225001",
"@dcloudio/uni-components": "3.0.0-3090920231225001",
"@dcloudio/uni-h5": "3.0.0-3090920231225001",
"@dcloudio/uni-mp-weixin": "3.0.0-3090920231225001",
"less": "^4.2.0",
"vue": "^3.2.45",
"@dcloudio/uni-app": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-app-plus": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-components": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-h5": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-mp-alipay": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-mp-baidu": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-mp-lark": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-mp-qq": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3060920221114001",
"axios": "^0.27.2",
"cz-git": "^1.4.1",
"decimal.js": "^10.4.3",
"or": "^0.2.0",
"pinia": "^2.0.35",
"vk-uview-ui": "^1.3.7",
"vue": "^3.2.41",
"vue-demi": "latest",
"vue-i18n": "^9.1.9",
"vuex": "^4.1.0"
"vuex": "^4.0.2"
},
"devDependencies": {
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "3.0.0-3090920231225001",
"@dcloudio/uni-cli-shared": "3.0.0-3090920231225001",
"@dcloudio/uni-stacktracey": "3.0.0-3090920231225001",
"@dcloudio/vite-plugin-uni": "3.0.0-3090920231225001",
"@vue/runtime-core": "^3.2.45",
"axios": "^1.3.4",
"decimal.js": "^10.4.3",
"jwt-decode": "^3.1.2",
"sass": "^1.70.0",
"sass-loader": "^14.1.0",
"vite": "4.0.3",
"vue-clipboard2": "^0.3.3"
"@commitlint/cli": "^17.4.2",
"@commitlint/config-conventional": "^17.4.2",
"@dcloudio/types": "^3.0.16",
"@dcloudio/uni-automator": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-cli-shared": "3.0.0-alpha-3060920221114001",
"@dcloudio/uni-stacktracey": "3.0.0-alpha-3060920221114001",
"@dcloudio/vite-plugin-uni": "3.0.0-alpha-3060920221114001",
"@types/node": "^17.0.45",
"@typescript-eslint/eslint-plugin": "^5.30.3",
"@typescript-eslint/parser": "^5.30.3",
"@vitejs/plugin-vue": "^2.3.3",
"@vitest/ui": "^0.10.5",
"c8": "^7.11.3",
"czg": "^1.4.1",
"eslint": "^8.19.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-todo-ddl": "^1.1.1",
"eslint-plugin-vue": "^9.1.1",
"jsdom": "^24.0.0",
"less": "^4.1.3",
"prettier": "^2.7.1",
"sass": "^1.53.0",
"simple-git-hooks": "^2.8.1",
"typescript": "^4.7.4",
"unocss": "^0.46.4",
"unocss-preset-weapp": "^0.2.1",
"vite": "^3.1.8",
"vite-plugin-eslint": "^1.6.1",
"vitest": "^0.16.0"
},
"simple-git-hooks": {
"commit-msg": "npx --no-install commitlint --edit \"$1\""
}
}

2
password.txt

@ -1,2 +0,0 @@
别名:testalias
密码: wms3.0

6260
pnpm-lock.yaml

File diff suppressed because it is too large

10
shims-uni.d.ts

@ -1,10 +0,0 @@
/// <reference types='@dcloudio/types' />
import 'vue'
declare module '@vue/runtime-core' {
type Hooks = App.AppInstance & Page.PageInstance;
interface ComponentCustomOptions extends Hooks {
}
}

102
src/App.vue

@ -1,60 +1,94 @@
<script>
// #ifdef APP-PLUS
<script setup lang="ts">
import {
appUpdate
} from "@/common/appUpdate.js"
// #endif
onLaunch,
onShow,
onHide
} from '@dcloudio/uni-app'
import {
getCurrentInstance
} from 'vue'
import {
getAccessToken
} from '@/utils/auth'
const { proxy } = getCurrentInstance()
export default {
onLaunch: function() {
import { storeToRefs } from 'pinia'
import { useCountStore } from '@/store'
console.log('App Launch')
// ,
// #ifdef APP-PLUS
// ,
uni.setStorageSync('hasLogin', false)
// plus.navigator.setFullscreen(true);
// // app
// plus.screen.lockOrientation('landscape-primary');
// // app
// plus.screen.lockOrientation('portrait-primary');
appUpdate();
// #endif
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
// store
const store = useCountStore()
}
onLaunch(async () => {
// #ifdef MP-WEIXIN
if (uni.canIUse('getUpdateManager')) {
const updateManager = uni.getUpdateManager()
updateManager.onCheckForUpdate(function (res) {
if (res.hasUpdate) {
updateManager.onUpdateReady(function () {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function (res) {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function () {
uni.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~'
})
})
}
})
} else {
uni.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
// #endif
if (getAccessToken()) {
await store.GetPermissionInfo().then(res => {
}).catch(() => { })
await store.GetInfo().then(res => {
}).catch(() => { })
}
// onLaunchonLoad
proxy.$isResolve();
})
onShow(() => {
})
onHide(() => {
})
</script>
<style lang="scss">
@import "./uni_modules/vk-uview-ui/index.scss";
@import 'vk-uview-ui/index.scss';
// @import "./uni_modules/vk-uview-ui/index.scss";
@import './common/style/new_style.css';
@import './common/style/uni.css';
@import './common/style/pdabasic.css';
@import './uni.scss';
@import './static/scss/index.scss';
@import './static/ali_icon/iconfont.css';
body {
background-color: #EBEEF0;
}
.content {
background-color: #fff
}
page {
// #ifdef APP-PLUS
height: 100vh;
// #endif
// #ifdef H5
// height: calc(100vh-94px);
// #endif

132
src/api/http.ts

@ -0,0 +1,132 @@
import axios from 'axios'
import { getFullURL } from '@/utils/http'
import { getAccessToken, removeToken } from '@/utils/auth'
const instance = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
adapter(config) {
const { url, method, data, params, headers, baseURL, paramsSerializer } =
config
config.timeout = 300000
return new Promise((resolve, reject) => {
uni.request({
method: method!.toUpperCase() as any,
url: getFullURL(baseURL || '', url!, params, paramsSerializer),
header: headers,
data,
dataType: 'json',
responseType: config.responseType,
success: (res : any) => {
resolve(res)
},
fail: (error : any) => {
// var message = error.errMsg
// if (message === 'Network Error') {
// message = '接口连接异常'
// } else if (message.includes('timeout')) {
// message = '接口请求超时'
// } else if (message.includes('Request failed with status code')) {
// message = '接口' + message.substr(message.length - 3) + '异常'
// }
// reject("系统异常:"+message);
// console.log("系统异常",message)
}
})
})
}
})
/**
*
*/
instance.interceptors.request.use((config) => {
const { method, params, url } = config
// 附带鉴权的token
// const tenantId = 1
var tenantId = uni.getStorageSync('tenantId')
const headers : any = {
token: getAccessToken(),
"tenant-id": tenantId,
"dataSource":"PDA",
'Authorization': 'Bearer ' + getAccessToken()
}
if (uni.getStorageSync('openId')) {
headers['openId'] = uni.getStorageSync('openId')
}
// 不缓存get请求
if (method === 'get') {
headers['Cache-Control'] = 'no-cache'
}
// delete请求参数放入body中
if (method === 'delete') {
headers['Content-type'] = 'application/json;'
Object.assign(config, {
data: params,
params: {}
})
}
return {
...config,
headers
}
})
/**
*
*/
instance.interceptors.response.use((v) => {
if (v) {
if (v.statusCode == 200) {
if (v.data.code == 0) {
// return v.data
return Promise.resolve(v.data)
}else if(v.data.code == 404){
uni.showModal({
title: '系统提示',
content: '登录状态已过期,您可以继续留在该页面,或者重新登录',
cancelText: '关闭',
confirmText: '重新登录',
success: function (res) {
if (res.confirm) {
uni.reLaunch({ url: '/pages/login/index' })
}
}
})
} else if(v.data.code == 401){
uni.clearStorageSync()
uni.removeStorageSync('overPackageRecord')
uni.showModal({
title: '系统提示',
content: '账号未登录,请重新登录',
cancelText: '关闭',
confirmText: '重新登录',
success: function (res) {
if (res.confirm) {
uni.reLaunch({ url: '/pages/login/index' })
}
}
})
} else {
// return v.data
return Promise.reject("系统异常:" + v.data.msg)
}
} else {
return Promise.reject("系统异常:" + v.data.msg)
}
} else {
return Promise.reject("系统异常:" + v.data.msg)
}
}, error => {
console.log(error)
uni.showToast({
title: '网络错误',
icon: 'none'
})
})
export default instance

67
src/api/httpRequest3.js

@ -1,67 +0,0 @@
import storage from '../common/utils/storage'
import config from '../static/config.js'
function service(options = {}) {
var token = storage.getStorage(storage.constant.token)
var tenantId = 1
// if(getApp()!=undefined){
// tenantId = getApp().globalData.tenantId
// }
// if(getApp()!=undefined){
// requestUrl = getApp().globalData.request_url
// }
var requestUrl = ""
requestUrl =config.request_url
options.header = {
"content-type": "application/json",
"Authorization": "Bearer "+token,
"dataType":"json",
"tenant-id":tenantId
};
options.timeout = 10000
options.url = requestUrl+options.url
return new Promise((resolve, reject) => {
options.success = (res) => {
if (res ) {
if(res.statusCode == 200){
if(res.data.code==0){
resolve(res.data);
}else {
reject("系统异常:"+res.data.msg)
console.log("系统异常",res.data.msg)
}
}else {
reject("系统异常:"+ res.data.msg)
console.log("系统异常",res.data.msg)
}
} else {
reject("系统异常:"+res.data.msg)
console.log("系统异常",res.data.msg)
}
};
options.fail = (error) => {
var message = error.errMsg
if (message === 'Network Error') {
message = '接口连接异常'
} else if (message.includes('timeout')) {
message = '接口请求超时'
} else if (message.includes('Request failed with status code')) {
message = '接口' + message.substr(message.length - 3) + '异常'
}
reject("系统异常:"+message);
console.log("系统异常",message)
};
uni.request(options);
});
}
export default service;

41
src/api/login.js

@ -0,0 +1,41 @@
import http from './http'
// 登录方法
export function login(username, password, captchaVerification, tenantName, rememberMe, code, uuid) {
const data = {
username,
password,
captchaVerification,
tenantName,
rememberMe,
code,
uuid,
}
return http.post('/system/auth/loginNoCode', data)
}
// 获取用户详细信息
export function getInfo() {
return http.get('/system/user/profile/get')
}
// 获取权限
export function getPermissionInfo() {
return http.get('/system/auth/get-permission-info')
}
// 退出方法
export function logout() {
return http.post('/system/auth/logout')
}

2698
src/api/request2.js

File diff suppressed because it is too large

117
src/common/appUpdate.js

@ -1,7 +1,7 @@
import {
appCheckUpdate
} from '../api/request2.js';
export function appUpdate() {
export function appUpdate(isShowHint) {
let curversion = 0;
plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {
const data = {
@ -11,44 +11,77 @@ export function appUpdate() {
wgtVersion: widgetInfo.version,
versionCode: widgetInfo.versionCode
}
curversion=data.versionCode
appCheckUpdate().then(res => {
console.log("当前版本提示",curversion)
if (res.data) {
if (res.data.versionCode > Number(curversion)) {
var downUrl = res.data.downUrl;
var content = res.data.content;
var version =res.data.version
console.log("新版本提示")
uni.showModal({
title: "发现新版本:("+version+")",
content: content,
confirmText: "更新",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
confirm(downUrl);
console.log('comfirm') //点击确定之后执行的代码
} else {
console.log('cancel') //点击取消之后执行的代码
}
curversion = data.versionCode
appCheckUpdate().then(res => {
console.log("当前版本提示", curversion)
var json = JSON.stringify(res)
console.log("获取更新数据", json)
if (res.data) {
if (res.data.installPackageVersion > Number(curversion)) {
var downUrl = res.data.installPackageUrl;
var content = res.data.updateContent;
var version = res.data.installPackageVersion;
var isForcedUpdate = res.data.isForcedUpdate
var versionName = res.data.installPackageName
console.log("新版本提示")
showDialog(versionName, content, isForcedUpdate, downUrl)
// uni.showModal({
// title: "发现新版本:(" + version + ")",
// content: content,
// confirmText: "更新",
// showCancel: isForcedUpdate == "TRUE" ? false : true,
// cancelText: "取消",
// success: (res) => {
// if (res.confirm) {
// confirm(downUrl);
// console.log('comfirm') //点击确定之后执行的代码
// } else {
// console.log('cancel') //点击取消之后执行的代码
// if (isForcedUpdate == "TRUE") {
// }
// }
// }
// })
} else {
if (isShowHint) {
uni.showToast({
title: "当前是最新版本"
})
}
})
console.log("没有新版本")
}
}
}).catch(error => {
console.log("版本错误", error)
})
})
}
export function showDialog(versionName, content, isForcedUpdate, downUrl) {
uni.showModal({
title: "发现新版本:(" + versionName + ")",
content: content,
confirmText: "更新",
showCancel: isForcedUpdate == "TRUE" ? false : true,
cancelText: "取消",
success: (res) => {
if (res.confirm) {
confirm(downUrl);
console.log(
'comfirm') //点击确定之后执行的代码
} else {
uni.showToast({
title:"当前是最新版本"
})
console.log("没有新版本")
console.log(
'cancel') //点击取消之后执行的代码
if (isForcedUpdate == "TRUE") {
showDialog(versionName, content, isForcedUpdate, downUrl)
}
}
}
}).catch(error => {
console.log("版本错误", error)
})
})
}
export function confirm(downUrl) {
@ -91,12 +124,16 @@ export function confirm(downUrl) {
showLoading.setTitle("已连接到服务器");
break;
case 3:
prg = parseInt(
(parseFloat(task.downloadedSize) /
parseFloat(task.totalSize)) *
100
);
showLoading.setTitle(" 正在下载" + prg + "% ");
if (task.totalSize && task.totalSize > 0) {
prg = parseInt(
(parseFloat(task.downloadedSize) /
parseFloat(task.totalSize)) *
100
);
showLoading.setTitle("正在下载" + prg + "% ");
}else {
showLoading.setTitle("正在下载");
}
break;
case 4:
plus.nativeUI.closeWaiting();

50
src/common/array.js

@ -110,6 +110,18 @@ export function getPurchaseReceiptOption(allowModifyQty, allowModifyLocation) {
return option;
}
export function getRecordOption(allowModifyQty, allowModifyLocation) {
var option = []
option.push(...getDetailOption())
if (allowModifyQty) {
option.push(...getEditOption())
}
if (allowModifyLocation) {
option.push(...getLocationOption())
}
option.push(...getRemoveOption())
return option;
}
//详情
export function getDetailOption() {
let option_detail = [{
@ -223,7 +235,7 @@ export function getDetailEditRemoveOption() {
}
//详情编辑放弃
//详情编辑关闭
export function getDetailGiveupOption() {
let option_detail_giveup = [{
text: '详情',
@ -241,7 +253,23 @@ export function getDetailGiveupOption() {
return option_detail_giveup;
}
//详情放弃
export function getDetailCloseOption() {
let option_detail_giveup = [{
text: '详情',
style: {
backgroundColor: '#3C9CFF'
}
},
{
text: '关闭',
style: {
backgroundColor: '#F56C6C'
}
}
];
return option_detail_giveup;
}
//详情编辑移除
export function getEditRemoveOption() {
@ -261,7 +289,23 @@ export function getEditRemoveOption() {
return option_edit_remove;
}
//详情编辑移除
export function getEditLocationRemoveOption() {
let option_edit_remove = [{
text: '修改\n库位',
style: {
backgroundColor: '#F1A532'
}
},
{
text: '移除',
style: {
backgroundColor: '#F56C6C'
}
}
];
return option_edit_remove;
}
// 库存状态字典项
export function getInventoryStatusArray() {
let array = [{

139
src/common/balance.js

@ -84,16 +84,19 @@ export function getPrecisionStrategyList(itemList, callback) {
};
getPrecisionStrategy(itemList).then(res => {
console.log(111, res.data)
if (res.data == null) {
result.success = false
result.message = '未查询到管理精度信息'
} else {
result.list = res.data;
}
console.log('haha', result)
callback(result);
}).catch(error => {
result.success = false;
result.message = error;
console.log('hehe', result)
callback(result);
})
}
@ -105,7 +108,7 @@ export function getPrecisionStrategyList(itemList, callback) {
* @param {*}
*
*/
export function getManagementPrecisions(itemCodes, locationCode, callback) {
export async function getManagementPrecisions(itemCodes, locationCode, callback) {
// let jsonParem = JSON.stringify(param)
let result = {
list: [],
@ -113,11 +116,11 @@ export function getManagementPrecisions(itemCodes, locationCode, callback) {
message: ''
};
var params = {
const params = {
itemCodes: itemCodes,
locationCode: locationCode
}
getManagementPrecision(params).then(res => {
await getManagementPrecision(params).then(res => {
if (res.data == null) {
result.success = false
result.message = '未查询到管理精度信息'
@ -131,23 +134,75 @@ export function getManagementPrecisions(itemCodes, locationCode, callback) {
callback(result);
})
}
//通过父包装查询
export function getBalanceByManagementPrecisionByPacking(label, packageInfo,locationCode, fromInventoryStatuses, callback) {
let result = {
list: [],
success: true,
message: ''
};
let params = {
itemCodes: [label.itemCode],
locationCode: locationCode
};
// let jsonParem = JSON.stringify(param)
getManagementPrecision(params).then(res => {
let managementPrecision = res.data[0].ManagementPrecision;
switch (managementPrecision) {
case 'BY_PACKAGING':
byPacking(label, packageInfo,locationCode, fromInventoryStatuses, res => {
res.managementPrecision = managementPrecision;
callback(res);
});
break;
case 'BY_BATCH':
byBatch(label, locationCode, fromInventoryStatuses, res => {
res.managementPrecision = managementPrecision;
callback(res);
});
break;
case 'BY_QUANTITY':
byQuantity(label, locationCode, fromInventoryStatuses, res => {
res.managementPrecision = managementPrecision;
callback(res);
});
break;
case 'BY_UNIQUEID':
byUniqueId(label, fromInventoryStatuses, res => {
res.managementPrecision = managementPrecision;
callback(res);
});
break;
}
}).catch(error => {
let result = {
success: false,
message: error
};
callback(result);
})
}
export function getBalanceByManagementPrecision(label, locationCode, fromInventoryStatuses, callback) {
let result = {
list: [],
success: true,
message: ''
};
let params = {
itemCodes: [label.itemCode],
locationCode: locationCode
};
// let jsonParem = JSON.stringify(param)
getManagementPrecision(params).then(res => {
console.log("成功" + res)
let managementPrecision = res.data[0].ManagementPrecision;
switch (managementPrecision) {
case 'BY_PACKAGING':
byPacking(label, locationCode, fromInventoryStatuses, res => {
byPacking(label, "", locationCode, fromInventoryStatuses, res => {
res.managementPrecision = managementPrecision;
callback(res);
});
@ -172,6 +227,7 @@ export function getBalanceByManagementPrecision(label, locationCode, fromInvento
break;
}
}).catch(error => {
console.log("失败" + error)
let result = {
success: false,
message: error
@ -191,6 +247,20 @@ export function byPacking(label, locationCode, fromInventoryStatuses, callback)
data: {}
};
var filters = []
if (packageInfo&&packageInfo.parentNumber) {
var packingNumber = packageInfo.parentNumber + "," + label.packingNumber;
filters.push({
column: "packingNumber",
action: "in",
value: packingNumber
})
} else {
filters.push({
column: "packingNumber",
action: "==",
value: label.packingNumber
})
}
filters.push({
column: "packingNumber",
action: "==",
@ -211,11 +281,12 @@ export function byPacking(label, locationCode, fromInventoryStatuses, callback)
action: "==",
value: locationCode
})
if (fromInventoryStatuses != null && fromInventoryStatuses != "") {
if (fromInventoryStatuses) {
var status = fromInventoryStatuses.join(',');
filters.push({
column: "inventoryStatus",
action: "in",
value: fromInventoryStatuses
value: status
})
}
@ -266,7 +337,7 @@ export function byBatch(label, locationCode, fromInventoryStatuses, callback) {
filters.push({
column: "packingNumber",
action: "==",
value: null
value: ''
})
filters.push({
column: "locationCode",
@ -274,12 +345,13 @@ export function byBatch(label, locationCode, fromInventoryStatuses, callback) {
value: locationCode
})
if (fromInventoryStatuses != null && fromInventoryStatuses != "") {
filters.push({
column: "inventoryStatus",
action: "in",
value: fromInventoryStatuses
})
if (fromInventoryStatuses) {
var status = fromInventoryStatuses.join(',');
filters.push({
column: "inventoryStatus",
action: "in",
value: status
})
}
var params = {
@ -324,7 +396,7 @@ export function byQuantity(label, locationCode, fromInventoryStatuses, callback)
data: {}
};
var filters = []
let filters = []
filters.push({
column: "itemCode",
action: "==",
@ -332,13 +404,13 @@ export function byQuantity(label, locationCode, fromInventoryStatuses, callback)
})
filters.push({
column: "packingNumber",
action: "==",
value: null
action: "isStr",
value: ''
})
filters.push({
column: "batch",
action: "==",
value: null
action: "isStr",
value: ''
})
filters.push({
column: "locationCode",
@ -346,12 +418,13 @@ export function byQuantity(label, locationCode, fromInventoryStatuses, callback)
value: locationCode
})
if (fromInventoryStatuses != null && fromInventoryStatuses != "") {
filters.push({
column: "inventoryStatus",
action: "in",
value: fromInventoryStatuses
})
if (fromInventoryStatuses) {
var status = fromInventoryStatuses.join(',');
filters.push({
column: "inventoryStatus",
action: "in",
value: status
})
}
var params = {
@ -393,19 +466,21 @@ export function byUniqueId(label, locationCode, fromInventoryStatuses, callback)
data: {}
};
var filters = []
let filters = []
filters.push({
column: "packingNumber",
action: "==",
value: label.packingNumber
})
if (fromInventoryStatuses != null && fromInventoryStatuses != "") {
filters.push({
column: "inventoryStatus",
action: "in",
value: fromInventoryStatuses
})
if (fromInventoryStatuses) {
var status = fromInventoryStatuses.join(',');
filters.push({
column: "inventoryStatus",
action: "in",
value: status
})
}
var params = {
@ -474,4 +549,4 @@ export function balanceByLocation(locationCode, callback) {
result.message = err.message;
callback(result)
})
}
}

177
src/common/basic.js

@ -7,7 +7,7 @@ import { calc } from '@/common/calc'
let jobStatusList = [];
let itemStatusList = [];
let locationTypeList = [];
let locationAreaTypeList = [];
let uomList = [];
let inventoryStatusList = [];
let containerTypeList = [];
@ -17,6 +17,8 @@ let unplannedReceiptReasonList = [];
let unplannedIissueReason = [];
let scrapReasonList = [];
let inspectFailedReasonList = [];
let switchList=[]
let businessList=[]
@ -24,7 +26,7 @@ let inspectFailedReasonList = [];
export function clearCacheData() {
jobStatusList = [];
itemStatusList = [];
locationTypeList = [];
locationAreaTypeList = [];
uomList = [];
inventoryStatusList = [];
containerTypeList = [];
@ -34,6 +36,8 @@ export function clearCacheData() {
unplannedIissueReason = [];
scrapReasonList = [];
inspectFailedReasonList = [];
switchList=[]
businessList = []
}
@ -152,11 +156,11 @@ export function getItemStateInfo(value) {
//获取库位类型
export function getLocationTypeInfo(value) {
var resultInfo = "";
if (locationTypeList.length == 0) {
locationTypeList = getDirectoryInfo("location_type")
if (locationAreaTypeList.length == 0) {
locationAreaTypeList = getDirectoryInfo("location_type")
}
if (locationTypeList.length > 0) {
for (let item of locationTypeList) {
if (locationAreaTypeList.length > 0) {
for (let item of locationAreaTypeList) {
if (item.value == value) {
resultInfo = item
break;
@ -174,7 +178,7 @@ export function getLocationTypeName(value) {
}
//获取计量单位
export function getUnitInfo(value) {
export function getUomInfo(value) {
var resultInfo = "";
if (uomList.length == 0) {
uomList = getDirectoryInfo("uom")
@ -191,7 +195,7 @@ export function getUnitInfo(value) {
}
//获取包装单位
export function getStdPackUnitInfo(value) {
export function getPackUnitInfo(value) {
var resultInfo = "";
if (packUnitList.length == 0) {
packUnitList = getDirectoryInfo("pack_unit")
@ -335,6 +339,39 @@ export function getInspectReasonList(value) {
return inspectFailedReasonList
}
//获取单据开关
export function getSwitchInfoByCode(code) {
var isCheck = false
var resultInfo = ""
switchList = uni.getStorageSync("switch")
for (let item of switchList) {
if (item.code == code) {
resultInfo = item
break;
}
}
isCheck = resultInfo.effectiveSetValue == "TRUE" ? true : false
return isCheck;
}
//获取业务类型名称
export function getBusinessTypeName(code) {
var resultInfo = null
if (businessList.length == 0) {
businessList = uni.getStorageSync("businessType")
}
for (let item of businessList) {
if (item.code == code) {
resultInfo = item
break;
}
}
return resultInfo.name;
}
// //数量状态
// export function getCoutJobStatuStyle(val) {
@ -688,23 +725,29 @@ export function getPackingNumberAndBatch(managementList, itemCode, packingNumber
return itemInfo;
}
// //提示是否消息
// export function showConfirmMsg(content, callback) {
// uni.showModal({
// title: '提示',
// cancelText: '否',
// confirmText: '是',
// content: content,
// success: function(res) {
// if (res.confirm) {
// callback(true);
// } else {
// callback(false);
// }
// },
// })
// scanErrorAudio();
// }
// 提示是否消息
export function showConfirmMsg(content, callback) {
uni.showModal({
title: '提示',
cancelText: '否',
confirmText: '是',
content: content,
success: function(res) {
if (res.confirm) {
callback(true);
} else {
callback(false);
}
},
})
}
export function compare(key) {
return function(a, b) {
var val1 = a[key];
var val2 = b[key];
return val2 - val1;
}
}
export function compareTime() {
return function(a, b) {
@ -813,7 +856,74 @@ export function getBatch() {
var batch = year.toString() + month.toString() + day.toString()
return batch;
}
//20270717
export function getBatch8() {
var date = new Date();
//获取日期部分
var year = date.getFullYear(); //年
var month = date.getMonth() + 1; //月
var day = date.getDate(); //日
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
return year + month + day;
}
/**
* 获取前几天和后几天的日期 2024-07-07
*/
export function lastThreeDays(grapDay) {
let dates = [];
for (let i = grapDay; i >= 0; i--) {
// 创建新的Date对象,并减去i天
let date = new Date();
date.setDate(date.getDate() - i);
// 将格式化的日期字符串添加到数组中
dates.push(formatDate(date));
}
for (let i = 0; i <grapDay; i++) {
// 创建新的Date对象,并减去i天
let date = new Date();
date.setDate(date.getDate() + (i+1));
// 将格式化的日期字符串添加到数组中
dates.push(formatDate(date));
}
return dates;
}
//20240702
export function formatDate(date) {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
}
export function getBeforeDayDate(grapDay) {
const today = new Date();
var resultList = []
//获取前几天
var beforeList = []
var afterList = []
for (var i = 0; i < grapDay; i++) {
beforeList.push(today.getDate() - (i + 1))
}
//获取后几天
var afterList = []
for (var i = 0; i < grapDay; i++) {
afterList.push(today.getDate() + (i + 1))
}
resultList.concat(beforeList)
resultList.push(today)
resultList.concat(afterList)
return resultList;
}
export function getCurrDate() {
var date = new Date();
return getDate(date);
@ -839,6 +949,15 @@ export function dateFormat(time) {
return result;
}
export function dateFormatData(time) {
var result = ""
if (time != null) {
let date = new Date(time);
result = getDate(date);
}
return result;
}
//获取日期部分
export function getDate(date) {
@ -957,8 +1076,8 @@ export function createItemInfo(res) {
let item = {
itemCode: res.itemCode,
itemName: res.itemName,
stdPackQty: Number(res.stdPackQty),
stdPackUnit: res.stdPackUnit,
packQty: Number(res.packQty),
packUnit: res.packUnit,
qty: Number(res.qty),
handleQty: 0,
uom: res.uom,
@ -1012,3 +1131,7 @@ export function deepCopyData(target) {
return cloneTarget;
}
//数组去重重复数据
export function uniqueArray(arr) {
return arr.filter((item, index, self) => self.indexOf(item) === index);
}

10
src/common/calc.js

@ -1,16 +1,24 @@
/* 解决js计算精度问题 */
import { Decimal } from 'decimal.js';//引入
import Decimal from 'decimal.js'
class Calc {
add(num1,num2) {
num1 = num1 || 0
num2 = num2 || 0
return new Decimal(num1).add(new Decimal(num2)).toNumber()
}
sub(num1,num2) {
num1 = num1 || 0
num2 = num2 || 0
return new Decimal(num1).sub(new Decimal(num2)).toNumber()
}
mul(num1,num2) {
num1 = num1 || 0
num2 = num2 || 0
return new Decimal(num1).mul(new Decimal(num2)).toNumber()
}
div(num1,num2) {
num1 = num1 || 0
num2 = num2 || 0
return new Decimal(num1).div(new Decimal(num2)).toNumber()
}
}

9
src/common/config.js

@ -0,0 +1,9 @@
export const overPagePrint="overPage_print"
export const overPageTemplate="overPage_Template"
//3分钟刷新
export const planRefreshTime=3*60*1000
export const issueJobFilter="issue_job_filter"
export const repleinshJobFilter="repleinsh_job_filter"
export const overPackageJobFilter="over_package_job_filter"
export const productionReceiptJobFilter="production_receipt_job_filter"

281
src/common/detail.js

@ -1,83 +1,232 @@
import {
calc
} from '@/common/calc'
import { Decimal } from 'decimal.js';//引入
export function getDataSource(subList) {
let items = [];
subList.forEach(detail => {
var item = items.find(r =>
r.itemCode == detail.itemCode)
if (item == undefined) {
item = createItemInfo(detail);
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
items.push(item)
} else {
item.qty = calc.add(item.qty, detail.qty)
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
}
})
return items;
}
calc
} from '@/common/calc'
import {
Decimal
} from 'decimal.js'; //引入
export function getTreeDataSource(dataList) {
let items = [];
let parentList = dataList.filter(r => r.parentPackingNumber == null || r
.parentPackingNumber == '');
let childList = dataList.filter(r => r.parentPackingNumber != '' && r.parentPackingNumber != null);
export function createItemInfo(detail) {
let item = {
itemCode: detail.itemCode,
itemName: detail.itemName,
stdPackQty: Number(detail.stdPackQty) || undefined,
stdPackUnit: detail.stdPackUnit,
qty: Number(detail.qty),
handleQty: 0,
uom: detail.uom,
subList: []
parentList.forEach(detail => {
var item = items.find(r =>
r.itemCode == detail.itemCode)
if (item == undefined) {
item = createItemInfo(detail);
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
items.push(item)
} else {
item.qty = calc.add(item.qty, detail.qty)
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
}
return item;
})
if (childList.length > 0) {
items.forEach(r =>
r.subList.forEach(s => {
s.packList = childList.filter(c => c.parentPackingNumber == s.packingNumber)
s.packList.forEach(pac => {
pac.scaned = false;
pac.scanDate = new Date();
})
})
)
}
export function createDetailInfo(data) {
data.scaned = false;
// data.record = {};
let detail = data;
return detail;
return items;
}
export function getThreeDataSource(data) {
let items = []
let obj ={
...data.subList[0]
}
console.log(12)
data.subList.forEach((item)=>{
item.threeList = [{
fromLocationCode:item.fromLocationCode,
batch:item.batch,
handleQty:0,
qty:item.qty,
inventoryStatus:item.inventoryStatus,
toLocationCode:item.toLocationCode,
}]
item.packList=[{
scaned : false,
scanDate: new Date()
}]
})
obj.subList = data.subList
items.push(obj)
return items;
}
export function getDataSourceBatch(subList) {
let items = [];
subList.forEach(detail => {
var item = items.find(r =>
r.itemCode == detail.itemCode )
if (item == undefined) {
item = createItemInfo(detail);
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
items.push(item)
} else {
item.qty = calc.add(item.qty, detail.qty)
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
}
})
return items;
}
export function getDataSource(subList) {
let items = [];
subList.forEach(detail => {
var item = items.find(r =>
r.itemCode == detail.itemCode)
if (item == undefined) {
item = createItemInfo(detail);
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
items.push(item)
} else {
item.qty = calc.add(item.qty, detail.qty)
let newDetail = createDetailInfo(detail); //
item.subList.push(newDetail);
}
})
return items;
}
//根据明细创建记录
export function createRecordInfo(detail, balance) {
var record = {}
// let record = JSON.parse(JSON.stringify(detail));
//克隆对象,深度克隆,防止双向绑定同一个变量
Object.assign(record, detail)
detail.scaned = true;
detail.balance = balance;
detail.recommendInventoryStatus = detail.inventoryStatus;
detail.inventoryStatus = balance.inventoryStatus;
record.qty = Number(balance.qty);
return record;
export function createItemInfo(detail) {
let item = {
itemCode: detail.itemCode,
itemName: detail.itemName,
packQty: Number(detail.packQty) || undefined,
packUnit: detail.packUnit,
qty: Number(detail.qty),
handleQty: 0,
uom: detail.uom,
subList: []
}
return item;
}
export function createDetailInfo(data) {
data.scaned = false;
data.scanDate = new Date();
let detail = data;
detail.packList = [];
return detail;
}
//计算实际数量
export function calcHandleQty(detailSource) {
for (let item of detailSource) {
item.handleQty = new Decimal(0).toNumber();
item.qty = new Decimal(0).toNumber();
for (let detail of item.subList) {
if (detail != undefined && detail.scaned) {
item.handleQty = calc.add(item.handleQty,detail.handleQty);
item.qty = calc.add(item.qty,detail.qty);
//根据明细创建记录
export function createRecordInfo(detail, balance) {
var record = {}
// let record = JSON.parse(JSON.stringify(detail));
//克隆对象,深度克隆,防止双向绑定同一个变量
Object.assign(record, detail)
detail.scaned = true;
detail.balance = balance;
detail.recommendInventoryStatus = detail.inventoryStatus;
detail.inventoryStatus = balance.inventoryStatus;
record.qty = Number(balance.qty);
return record;
}
//计算实际数量
export function calcHandleQty(detailSource) {
for (let item of detailSource) {
item.handleQty = new Decimal(0).toNumber();
item.qty = new Decimal(0).toNumber();
for (let detail of item.subList) {
if (detail != undefined) {
if (detail.scaned) {
item.handleQty = calc.add(item.handleQty, detail.handleQty);
}
item.qty = calc.add(item.qty, detail.qty);
}
}
}
}
//计算计划外入库实际数量和任务数量
export function calcHandleQtyPlanOut(detailSource) {
for (let item of detailSource) {
item.handleQty = new Decimal(0).toNumber();
item.qty = new Decimal(0).toNumber();
for (let detail of item.subList) {
if (detail != undefined) {
if (detail.scaned) {
item.handleQty = calc.add(item.handleQty, detail.handleQty);
}
console.log(detail.isRecommend)
if(detail.isRecommend){
item.qty = calc.add(item.qty, detail.qty);
}
}
}
}
}
//计算推荐和扫描的不是用一个的数量
export function calcHandleNewQty(detailSource) {
for (let item of detailSource) {
item.handleQty = new Decimal(0).toNumber();
// item.qty = new Decimal(0).toNumber();
for (let detail of item.subList) {
if (detail ) {
if (!detail.isRecommend && detail.scaned) {
item.handleQty = calc.add(item.handleQty, detail.handleQty);
}
// if (!detail.isRecommend ) {
// item.qty = calc.add(item.qty, detail.qty);
// }
}
}
}
}
export function calcTreeHandleQty(detailSource) {
for (let item of detailSource) {
item.handleQty = new Decimal(0).toNumber();
export function getScanCount(subList) {
let items = subList.filter(r => {
if (r.scaned) {
return r;
for (let detail of item.subList) {
if (detail) {
if (detail.packList && detail.packList.length > 0) {
detail.handleQty = new Decimal(0).toNumber();
for (let pack of detail.packList) {
if (pack && pack.scaned) {
detail.handleQty = calc.add(detail.handleQty, pack.handleQty);
}
}
}else{
detail.handleQty = new Decimal(0).toNumber();
}
if(detail.handleQty){
item.handleQty = calc.add(item.handleQty, detail.handleQty);
}
}
})
let scanCount = items != null ? items.length : 0;
return scanCount;
}
}
}
export function getScanCount(subList) {
let items = subList.filter(r => {
if (r.scaned) {
return r;
}
})
let scanCount = items != null ? items.length : 0;
return scanCount;
}

181
src/common/directory.js

@ -1,4 +1,5 @@
let jobStatusList = [];
let receiveStatusList = [];
let itemStatusList = [];
let itemTypeList =[];
let locationTypeList = [];
@ -6,6 +7,7 @@ let uomList = [];
let inventoryStatusList = [];
let containerTypeList = [];
let packUnitList = [];
let packUnitInfoList = [];
let requestStatusList = [];
let unplannedReceiptReasonList = [];
let unplannedIssueReasonList = [];
@ -18,8 +20,10 @@ let inspectTypeList = [];
let sampleMethodList = [];
let transferModeList = [];
let countStageList = [];
let locationAreaTypeList = [];
let businessList=[];
let countScopeTypeList = [];
let priorityList = []
@ -39,6 +43,7 @@ export function getBusinessTypeDesc(type) {
//获取字典信息
export function clearCacheData() {
jobStatusList = [];
receiveStatusList=[];
itemStatusList = [];
itemTypeList =[];
locationTypeList = [];
@ -46,6 +51,7 @@ export function clearCacheData() {
inventoryStatusList = [];
containerTypeList = [];
packUnitList = [];
packUnitInfoList = [];
requestStatusList = [];
unplannedReceiptReasonList = [];
unplannedIssueReasonList = [];
@ -58,6 +64,10 @@ export function clearCacheData() {
sampleMethodList = [];
transferModeList = [];
countStageList = [];
locationAreaTypeList=[];
businessList=[];
countScopeTypeList = []
priorityList = []
}
//获取字典信息
@ -131,6 +141,22 @@ export function getJobStateInfo(value) {
return resultInfo
}
export function getReceiveStateInfo(value) {
var resultInfo = "";
if (receiveStatusList.length == 0) {
receiveStatusList = getDirectoryInfo("receive_status")
}
if (receiveStatusList.length > 0) {
for (let item of receiveStatusList) {
if (item.value == value) {
resultInfo = item
break;
}
}
}
return resultInfo
}
//获取任务状态样式
export function getJobStateStyle(value) {
let item = getJobStateInfo(value);
@ -145,6 +171,16 @@ export function getJobStateStyle(value) {
}
}
//获取库区描述(多个库区)
export function getListLocationAreaTypeDesc(list) {
let desc = '';
list.forEach(res => {
desc += getLocationAreaTypeInfo(res).label + ","
})
desc = desc.slice(0, -1);
return desc;
}
//获取库位描述(多个库位)
export function getListLocationTypeDesc(list) {
let desc = '';
@ -175,7 +211,15 @@ export function getListItemTypeDesc(list) {
desc = desc.slice(0, -1);
return desc;
}
//获取物品状态(多个)
export function getListItemStatusDesc(list) {
let desc = '';
list.forEach(res => {
desc += getItemStateInfo(res).label + ","
})
desc = desc.slice(0, -1);
return desc;
}
//获取物品类型
export function getItemTypeInfo(value) {
var resultInfo = "";
@ -213,6 +257,38 @@ export function getItemStateInfo(value) {
return resultInfo
}
//获取业务类型名称
export function getBusinessTypeName(code) {
var resultInfo = null
if (businessList.length == 0) {
businessList = uni.getStorageSync("businessType")
}
for (let item of businessList) {
if (item.code == code) {
resultInfo = item
break;
}
}
return resultInfo.name;
}
//获取库区类型
export function getLocationAreaTypeInfo(value) {
var resultInfo = "";
if (locationAreaTypeList.length == 0) {
locationAreaTypeList = getDirectoryInfo("area_type")
}
if (locationAreaTypeList.length > 0) {
for (let item of locationAreaTypeList) {
if (item.value == value) {
resultInfo = item
break;
}
}
}
return resultInfo
}
//获取库位类型
export function getLocationTypeInfo(value) {
var resultInfo = "";
@ -229,6 +305,26 @@ export function getLocationTypeInfo(value) {
}
return resultInfo
}
//获取库区类型名称
export function getLocationAreaTypeName(value) {
let location = getLocationAreaTypeInfo(value);
return location == '' ? value : location.label;
}
//获取物品类型名称
export function getItemTypeName(value) {
let location = getItemTypeInfo(value);
return location == '' ? value : location.label;
}
//获取物品状态名称
export function getItemStatusName(value) {
let location = getItemStateInfo(value);
return location == '' ? value : location.label;
}
//获取库位类型名称
export function getLocationTypeName(value) {
@ -249,7 +345,7 @@ export function getLocationTypeNameList(lst) {
}
//获取计量单位
export function getUnitInfo(value) {
export function getUomInfo(value) {
var resultInfo = "";
if (uomList.length == 0) {
uomList = getDirectoryInfo("uom")
@ -264,9 +360,25 @@ export function getUnitInfo(value) {
}
return resultInfo
}
//获取盘点范围类型
export function getCountScopeType(value) {
var resultInfo = "";
if (countStageList.length == 0) {
countStageList = getDirectoryInfo("count_scope_type")
}
if (countStageList.length > 0) {
for (let item of countStageList) {
if (item.value == value) {
resultInfo = item
break;
}
}
}
return resultInfo
}
//获取包装单位
export function getStdPackUnitInfo(value) {
export function getPackUnitInfo(value) {
var resultInfo = "";
if (packUnitList.length == 0) {
packUnitList = getDirectoryInfo("pack_unit")
@ -298,7 +410,13 @@ export function getRequestStateInfo(value) {
}
return resultInfo
}
//获取库存状态集合
export function getInventoryStatusList() {
if (inventoryStatusList.length == 0) {
inventoryStatusList = getDirectoryInfo("inventory_status")
}
return inventoryStatusList
}
//获取库存状态
export function getInventoryStatusInfo(value) {
@ -514,3 +632,54 @@ export function getCountStageName(value) {
}
return resultInfo
}
//获取包装规格
export function getPackUnitName(value) {
var resultInfo = "";
if (packUnitInfoList.length == 0) {
packUnitInfoList = uni.getStorageSync('packunit');
}
if (packUnitInfoList.length > 0) {
for (let item of packUnitInfoList) {
if (item.code == value) {
resultInfo = item.name
break;
}
}
}
return resultInfo
}
//获取优先级
export function getPriorityName(value) {
// console.log(344,value)
var resultInfo = "";
if (priorityList.length == 0) {
priorityList = getDirectoryInfo("priority")
}
// console.log(455,priorityList)
if (priorityList.length > 0) {
for (let item of priorityList) {
if (item.value == value) {
resultInfo = item.label
break;
}
}
}
return resultInfo
}
//获取优先级
export function getDeliverMethod(value) {
var resultInfo = "";
if (priorityList.length == 0) {
priorityList = getDirectoryInfo("deliver_method")
}
if (priorityList.length > 0) {
for (let item of priorityList) {
if (item.value == value) {
resultInfo = item.label
break;
}
}
}
return resultInfo
}

107
src/common/label.js

@ -2,18 +2,19 @@ let labelDic = [];
import {
getLabelByHeader,
getPackageByNumber
} from '../api/request2.js';
getPackageListByNumber
} from '@/api/request2.js';
import {
checkDirectoryItemExist,
getDirectoryItemArray
} from '../common/directory.js';
} from '@/common/directory.js';
import {
getManagementPrecisions
} from '@/common/balance.js';
export function getLabelInfo(scanMsg,headerType, callBack) {
console.log('扫描信息:', scanMsg);
export function getLabelInfo(scanMsg,headerType, callBack,locationCode,isHavePackNumber) {
if (scanMsg.length == 0) {
return null
}
@ -41,29 +42,32 @@ export function getLabelInfo(scanMsg,headerType, callBack) {
let type = header.substring(header.length - 1, header.length);
if (type == 'Q') //qrcode
{
getQRCodeInfo(header, version, scanMsg, callBack);
} else if (type == 'B') //barcode
{
getBarCodeInfo(header, version, items[2], callBack);
} else { //直接输入文本
getBarCodeInfo('text', 'V1.0', scanMsg, callBack);
getQRCodeInfo(header, version, scanMsg, callBack,locationCode,isHavePackNumber);
}
// else if (type == 'B') //barcode
// {
// getBarCodeInfo(header, version, items[2], callBack);
// }
else { //直接输入文本
getBarCodeInfo('text', 'V1.0', scanMsg, callBack,locationCode,isHavePackNumber);
}
}else {
let labelResult = {
label: {
labelType: "",
barType: '',
code:""
},
package: null,
success: false,
message: '标签格式不正确',
}
callBack(labelResult);
getBarCodeInfo('text', 'V1.0', scanMsg, callBack,locationCode,isHavePackNumber);
// let labelResult = {
// label: {
// labelType: "",
// barType: '',
// code:""
// },
// package: null,
// success: false,
// message: '标签格式不正确',
// }
// callBack(labelResult);
}
}
export function getQRCodeInfo(header, version, scanMsg, callBack) {
export function getQRCodeInfo(header, version, scanMsg, callBack,locationCode,isHavePackNumber) {
//获取包装信息
let labelItem = labelDic.find(r => r.header == header && r.version == version);
if (labelItem == undefined) {
@ -88,7 +92,7 @@ export function getQRCodeInfo(header, version, scanMsg, callBack) {
};
labelDic.push(newItem);
getLabelItems(newItem, scanMsg, callBack);
getLabelItems(newItem, scanMsg, callBack,locationCode,isHavePackNumber);
}
}).catch(err => {
labelResult.success = false;
@ -96,24 +100,40 @@ export function getQRCodeInfo(header, version, scanMsg, callBack) {
callBack(err);
})
} else {
getLabelItems(labelItem, scanMsg, callBack);
getLabelItems(labelItem, scanMsg, callBack,locationCode,isHavePackNumber);
}
}
export function getLabelItems(labelItem, scanMsg, callBack) {
export async function getLabelItems(labelItem, scanMsg, callBack,locationCode) {
let managementType = ""
let labelResult = analysisQRCodeLabel(labelItem, scanMsg);
if (labelResult.label.labelType == 'PurchaseLabel' || labelResult.label.labelType == 'MakeLabel') {
//查询包装信息
let packingNumber = labelResult.label.packingNumber
if (packingNumber != undefined) {
getPackageByNumber(packingNumber).then(pack => {
if (pack.data.list.length == 0) {
let packingNumber1 = labelResult.label.packingNumber//记录单号
if(locationCode){
await getManagementPrecisions([labelResult.label.itemCode], locationCode, res => {
if (res.success) {
const managementList = res.list;
managementType = managementList&&managementList[0]&&managementList[0].ManagementPrecision ? managementList[0].ManagementPrecision :'BY_PACKAGING'
if(managementType == 'BY_BATCH' || managementType == 'BY_QUANTITY'){
if(!isHavePackNumber){
packingNumber = ''
}
}
}
})
}
if (packingNumber != undefined && packingNumber != '') {
await getPackageListByNumber(packingNumber).then(pack => {
if (pack.data.reqPackage) {
labelResult.package = pack.data.reqPackage;
labelResult.package.subList = pack.data.subList;
} else {
labelResult.success = false;
labelResult.message = '包装号[' + packingNumber + ']没有包装信息';
} else {
labelResult.package = pack.data.list[0];
console.log('包装信息', JSON.stringify(labelResult.package))
}
labelResult.managementType = managementType
callBack(labelResult);
}).catch(err => {
labelResult.success = false;
@ -121,9 +141,14 @@ export function getLabelItems(labelItem, scanMsg, callBack) {
callBack(labelResult);
})
} else {
labelResult.success = false;
labelResult.message = '在条码中未解析到箱码';
labelResult.package = labelResult.label;
labelResult.package.number = packingNumber1 ? packingNumber1 : ''
labelResult.package.packingNumber=''
labelResult.managementType = managementType
callBack(labelResult);
// labelResult.success = false;
// labelResult.message = '在条码中未解析到箱码';
// callBack(labelResult);
}
} else {
callBack(labelResult);
@ -153,8 +178,15 @@ export function analysisQRCodeLabel(labelItem, scanMsg) {
let scanItems = scanMsg.split(separators);
if (scanItems.length > 0) {
scanItems.forEach((item, index) => {
let type = item.substring(0, 1);
let value = item.substring(1, item.length);
let type = ''
let value = ''
if(item.includes('PU')||item.includes('PQ')){
type = item.substring(0, 2);
value = item.substring(2, item.length);
}else{
type = item.substring(0, 1);
value = item.substring(1, item.length);
}
if (type == 'H') {
labelResult.label.header = item;
} else if (type == 'V') {
@ -175,7 +207,6 @@ export function analysisQRCodeLabel(labelItem, scanMsg) {
}
}
// console.log('标签', labelResult.label)
return labelResult;
}

44
src/common/noclick.js

@ -0,0 +1,44 @@
// 防止处理多次点击
function noMultipleClicks(methods, info) {
// methods是需要点击后需要执行的函数, info是点击需要传的参数
let that = this;
if (that.noClick) {
// 第一次点击
that.noClick= false;
if(info && info !== '') {
// info是执行函数需要传的参数
methods(info);
} else {
methods();
}
let timer = setTimeout(()=> {
that.noClick= true;
clearTimeout(timer)
}, 2000)
} else {
// 这里是重复点击的判断
}
}
// 节流函数
const throttle = (fn, t,_this) => {
console.log('throttle')
return ()=> {
if (!_this.timer) {
_this.timer = setTimeout(()=>{
console.log('fn')
//·清空定时器
_this.timer = null
}, t)
fn()
}
}
}
//导出
export default {
noMultipleClicks,//禁止多次点击
throttle
}

101
src/common/record.js

@ -7,21 +7,22 @@ import {
} from '@/common/directory.js';
import { calc } from '@/common/calc'
import { Decimal } from 'decimal.js';//引入
import {
deepCopyData
} from '@/common/basic.js';
import {
deepCopyData
} from '@/common/basic.js';
export function createItemInfo(balance, pack) {
let item = {
itemCode: pack.itemCode,
itemName: pack.itemName,
stdPackQty: pack.stdPackQty,
stdPackUnit: pack.stdPackUnit,
packQty: pack.packQty,
packUnit: pack.packUnit,
qty: new Decimal(balance.qty).toNumber(),
handleQty:new Decimal(0).toNumber(),
handleQty: new Decimal(0).toNumber(),
uom: pack.uom,
subList: []
}
item.containerNumber = pack.parentNumber ? pack.parentNumber : pack.number;
return item;
}
@ -32,21 +33,56 @@ export function createDetailInfo(balance, pack) {
let detail = deepCopyData(balance);
detail.balanceQty = new Decimal(detail.qty).toNumber()
detail.qty = new Decimal(detail.qty).toNumber();
detail.stdPackQty = new Decimal(pack.stdPackQty).toNumber()
detail.stdPackUnit = pack.stdPackUnit
detail.handleQty = new Decimal(detail.qty).toNumber() ;
detail.packQty = pack.packQty ? new Decimal(pack.packQty).toNumber() : 0
detail.packUnit = pack.packUnit
detail.handleQty = new Decimal(detail.qty).toNumber() ;
detail.package = pack;
detail.productionlineCode = pack.productionLineCode; // 制品回收记录需要加的
detail.toInventoryStatus = balance.inventoryStatus; // 制品回收记录需要加的
return detail;
}
export function createDetailInfoForLabel(balance, pack,label) {
balance.scaned = true;
// data.toInventoryStatus = this.toInventoryStatus == "" ? data.inventoryStatus : this.toInventoryStatus;
// data.inventoryStatus = data.inventoryStatus;
let detail = deepCopyData(balance);
detail.balanceQty = new Decimal(detail.qty).toNumber()
detail.qty = new Decimal(detail.qty).toNumber();
detail.packQty = pack.packQty ? new Decimal(pack.packQty).toNumber() : 0
detail.packUnit = pack.packUnit
console.log(988,label.qty)
detail.handleQty = new Decimal(label.qty).toNumber();
detail.package = pack;
detail.productionlineCode = pack.productionLineCode; // 制品回收记录需要加的
detail.toInventoryStatus = balance.inventoryStatus; // 制品回收记录需要加的
return detail;
}
export function createDetailByPackInfo(pack) {
// data.toInventoryStatus = this.toInventoryStatus == "" ? data.inventoryStatus : this.toInventoryStatus;
// data.inventoryStatus = data.inventoryStatus;
let detail = deepCopyData(pack); detail.scaned = true;
detail.balanceQty = new Decimal(detail.qty).toNumber()
detail.qty = new Decimal(detail.qty).toNumber();
detail.packQty = pack.packQty ? new Decimal(pack.packQty).toNumber() : 0
detail.packUnit = pack.packUnit
detail.handleQty = new Decimal(detail.qty).toNumber();
detail.package = pack;
return detail;
}
//计算实际数量
export function calcHandleQty(detailSource) {
for (let item of detailSource) {
console.log('qqqqqqqqq')
item.handleQty = new Decimal(0).toNumber();
item.qty = new Decimal(0).toNumber();
console.log('bbbbbb')
for (let detail of item.subList) {
if(detail!=undefined){
console.log(detail)
if(detail.scaned){
item.handleQty = calc.add(item.handleQty,detail.handleQty);
}
@ -55,14 +91,48 @@ export function calcHandleQty(detailSource) {
}
}
}
//添加数量
export function calcHandleQtyAdd(detailSource,label) {
for (let item of detailSource) {
item.handleQty = item.handleQty || new Decimal(0).toNumber();
item.qty = item.qty|| new Decimal(0).toNumber();
item.handleQty = calc.add(item.handleQty, label.qty);
for (let detail of item.subList) {
if (detail != undefined) {
if (detail.scaned) {
detail.handleQty = calc.add(detail.handleQty, label.qty);
}
// item.qty = calc.add(item.qty, detail.qty);
}
}
}
}
export function calcTreeHandleQty(detailSource) {
for (let item of detailSource) {
item.handleQty = new Decimal(0).toNumber();
for (let detail of item.subList) {
if (detail != undefined && detail.scaned) {
detail.handleQty = new Decimal(0).toNumber();
for (let pack of detail.packList){
if(pack!=undefined&&pack.scaned){
detail.handleQty = calc.add(detail.handleQty, pack.handleQty);
}
}
item.handleQty = calc.add(item.handleQty, detail.handleQty);
}
}
}
}
export function getBusinessType(typeCode, callback) {
let result = {
success: true,
businessType: '',
fromlocationTypeList: '',
tolocationTypeList: '',
itemCodeTypeList:"",
fromLocationAreaTypeList:'',
toLocationAreaTypeList:'',
itemTypeList: "",
itemStatusList:"",
useOnTheWay:"FALSE",
fromInventoryStatuses: '',
toInventoryStatuses: '',
@ -71,9 +141,10 @@ export function getBusinessType(typeCode, callback) {
getBusinesstypeByCode(typeCode).then(res => {
if (res.data.total > 0) {
result.businessType = res.data.list[0];
result.fromlocationTypeList = getDirectoryItemArray(res.data.list[0].outLocationTypes)
result.tolocationTypeList = getDirectoryItemArray(res.data.list[0].inLocationTypes)
result.itemCodeTypeList = getDirectoryItemArray(res.data.list[0].itemTypes)
result.fromLocationAreaTypeList = getDirectoryItemArray(res.data.list[0].outAreaTypes) ;
result.toLocationAreaTypeList = getDirectoryItemArray(res.data.list[0].inAreaTypes) ;
result.itemTypeList = getDirectoryItemArray(res.data.list[0].itemTypes)
result.itemStatusList =getDirectoryItemArray(res.data.list[0].itemStatuses)
result.fromInventoryStatuses = res.data.list[0].outInventoryStatuses;
result.toInventoryStatuses = res.data.list[0].inInventoryStatuses;
result.useOnTheWay =res.data.list[0].useOnTheWay

236
src/common/style/new_style.css

@ -62,6 +62,10 @@ uni-page-head .uni-page-head__title {
font-size: 1.125rem;
}
.font_default {
font-size: 1rem;
}
.margin_top {
margin-top: 20rpx;
}
@ -180,18 +184,20 @@ uni-page-head .uni-page-head__title {
text-align: center;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
opacity: 0.8;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.scan_float image {
width: 40rpx;
height: 40rpx;
margin-top: 10rpx;
}
.scan_float view {
color: #fff;
font-size: .725rem;
margin-top: -8rpx;
}
.top_card {
@ -212,9 +218,10 @@ uni-page-head .uni-page-head__title {
.cen_card {
padding: 0 0rpx;
width: 100%;
box-sizing: border-box;
float: left;
background:#EEF4FA;
padding:20rpx;
border-radius: 10rpx;
}
.cell_box {
@ -227,6 +234,7 @@ uni-page-head .uni-page-head__title {
padding: 0 20rpx;
/* margin: 0 0 20rpx; */
text-align: center;
flex:1
}
.cell_box .cell_long {
@ -236,7 +244,8 @@ uni-page-head .uni-page-head__title {
.cell_box .cell_info view {
font-size: 0.9375rem;
margin-bottom: 10rpx;
color: #7B8195;
color: #515562;
word-wrap:break-word
}
.cell_box .cell_info .text_black {
@ -306,7 +315,7 @@ uni-page-head .uni-page-head__title {
}
.cen_card .cell_box .cell_info .text_lightblue {
font-size: 0.925rem;
font-size:26rpx;
}
.bot_card {
@ -1390,13 +1399,13 @@ uni-page-head .uni-page-head__title {
}
.msg_list {
padding-top: 20rpx;
}
.msg_list .uni-list-chat__header {
.msg_list ::v-deep .u-card__head--left__thumb{
width: 60rpx !important;
height: 60rpx !important;
background-color: #3d7eff;
padding:12rpx;
background-color: #3d7eff!important;
border-color: transparent !important;
border-radius: 6rpx !important;
}
@ -1422,9 +1431,8 @@ uni-page-head .uni-page-head__title {
.msg_list .uni-list-chat__content-title {
font-size: .9rem !important;
}
.msg_list .hasread .uni-list-chat__header {
background-color: #ccc;
::v-deep .msg_list .hasread .u-card__head--left__thumb {
background-color: #ccc!important;
}
/* index */
@ -1850,7 +1858,7 @@ uni-modal .uni-modal__hd {
border-radius: 8rpx;
max-width: 300rpx;
font-size: 0.7rem;
overflow: visble;
overflow: visible;
word-break: break-all;
/* overflow: hidden;
white-space: nowrap;
@ -2027,15 +2035,21 @@ button::after {
}
.card_itemCode {
font-size: 36rpx;
/* font-weight: 500; */
padding: 5rpx 10rpx;
font-size: 32rpx;
font-weight: bold;
/* padding: 5rpx 10rpx; */
/* width: 210rpx; */
word-wrap: break-word;
word-break: break-all;
}
.card_itemName {
color: #909399;
font-size: 30rpx;
padding: 5rpx 20rpx;
font-size: 26rpx;
/* padding: 5rpx 10rpx; */
/* width: 210rpx; */
word-wrap: break-word;
word-break: break-all;
}
.card_ProdLine {
@ -2058,43 +2072,50 @@ button::after {
.card_content {
font-size: 32rpx;
font-size: 40rpx;
color:#2E3A63;
margin-left:20rpx;
font-weight: 600;
}
.card_big_content {
font-size: 40rpx;
font-weight: bold;
padding: 5px;
}
.card_icon_normal {
width: 45rpx;
height: 45rpx;
vertical-align: middle
width: 30rpx;
height: 30rpx;
vertical-align: middle;
margin-right:12rpx
}
.card_packing_code {
color: #3315EB;
.card_item_code {
color: #329362;
padding: 5px;
font-size: 30rpx;
}
.card_packing_code_content {
font-size: 32rpx;
.card_packing_code {
color: #3315EB;
padding: 5px;
font-size: 26rpx;
font-style: italic;
}
.card_batch {
color: #9747FF;
padding: 5px;
}
.card_batch_content {
font-size: 32rpx;
padding: 5px;
font-size: 26rpx;
font-style: italic;
}
.card_container {
color: #0076F6;
padding: 5px;
font-size: 30rpx;
}
.card_container_content {
font-size: 32rpx;
padding: 5px;
@ -2102,45 +2123,72 @@ button::after {
.card_business {
color: #F1A532;
padding: 5px;
font-size: 26rpx;
font-style: italic;
}
.card_business_content {
font-size: 32rpx;
padding: 5px;
color:#2E3A63;
margin-left:20rpx
}
.card_location {
color: #DA8910;
padding: 5px;
font-size: 26rpx;
font-style: italic;
}
.card_to_location {
color: #329362;
padding: 5px;
font-size: 26rpx;
font-style: italic;
}
.card_location_content {
font-size: 32rpx;
padding: 5px;
}
.card_level {
color: #0689da;
padding: 5px;
font-size: 30rpx;
}
.card_supportCode {
color: #DA8910;
padding: 5px;
}
.card_supportCode_content {
font-size: 32rpx;
}
/* .card_item_code {
color: #F1A532;
padding: 5px;
} */
.card_product_date {
color: #329362;
padding: 5px;
}
.card_order {
color: #0076F6;
padding: 5px;
}
.scan_view {
/* #0CC2B6 20% */
background: linear-gradient(90deg, rgba(12, 194, 182, 0.2) 0%, rgba(12, 194, 182, 0) 100%)
background: linear-gradient(90deg, rgba(12, 194, 182, 0.2) 0%, rgba(12, 194, 182, 0.05) 100%);
border-radius:14rpx;
padding:10rpx 20rpx 16rpx
}
.card_view {
font-size: 32rpx;
padding: 5rpx;
margin-top:14rpx;
margin-left: 10rpx;
}
/*
@ -2183,29 +2231,28 @@ button::after {
.task_top {
margin: 0rpx 10rpx;
background-color: #fff;
vertical-align: middle;
}
.task_item {
margin: 0rpx 10rpx;
background-color: #fff;
padding:20rpx 0px
}
.task_card {
padding: 12rpx;
padding:0px 20rpx;
background-color: #fff;
border-radius: 10rpx;
margin: 12rpx;
}
.task_number {
font-size: 35rpx;
font-size: 36rpx;
font-weight: 600;
/* bold */
}
.task_text {
font-size: 30rpx;
margin: 5rpx 0rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@ -2260,25 +2307,50 @@ button::after {
border-radius: 10rpx;
}
.receive_state_no_ok {
font-size: 28rpx;
background: rgba(236, 156, 0, 0.2);
color: #EC9C00;
padding: 10rpx 20rpx 10rpx 20rpx;
border-radius: 10rpx;
}
.receive_state_ok {
font-size: 28rpx;
background: rgba(95, 203, 148, 0.2);
color: #22AF68;
padding: 10rpx 20rpx 10rpx 20rpx;
border-radius: 10rpx;
}
.receive_state_reject {
font-size: 28rpx;
background: rgba(95, 203, 148, 0.2);
color: #22AF68;
padding: 10rpx 20rpx 10rpx 20rpx;
border-radius: 10rpx;
}
.pop_detail {
background-color: #fff;
width: 100%;
border-radius: 8rpx 8rpx 0rpx 0rpx;
padding: 15rpx;
padding:0px 30rpx;
}
.pop_detail .item {
padding-top: 5rpx;
padding-bottom: 5rpx;
margin-left: 10rpx;
margin-right: 10rpx;
/* margin-left: 10rpx; */
/* margin-right: 10rpx; */
display: flex;
flex-direction: row;
-webkit-justify-content: space-between;
justify-content: space-between;
align-items:center
}
.pop_detail .item_title {
@ -2423,7 +2495,24 @@ button[disabled] {
padding-right: 20rpx;
z-index: 10;
}
.btn_single_clear{
background-color: #fff;
font-size: 30rpx;
color: #000;
text-align: center;
width: 180rpx;
}
.btn_single_clear{
background-color: #fff;
font-size: 30rpx;
color: #000;
text-align: center;
width: 180rpx;
}
.btn_clear_after {
opacity: 0.7;
}
.btn_single_commit {
background-color: #3C9CFF;
font-size: 30rpx;
@ -2431,11 +2520,27 @@ button[disabled] {
text-align: center;
width: 180rpx;
}
.btn_single_clear {
background-color: #EBEEF0;
font-size: 30rpx;
color: #000;
text-align: center;
width: 180rpx;
}
.btn_single_reject {
background-color: #F56C6C;
font-size: 30rpx;
color: #fff;
text-align: center;
width: 180rpx;
}
.center {
display: flex;
flex-direction: row;
justify-content: center;
justify-content: flex-end;
align-items: center;
}
@ -2447,9 +2552,17 @@ button[disabled] {
.text_recommend {
color: #0A84FF;
font-size: 38rpx;
font-size: 34rpx;
font-weight: bold;
}
.text_packQty {
color: #3315EB;
font-size: 40rpx;
font-weight: bold;
}
.text_balance {
font-size: 36rpx;
}
@ -2481,7 +2594,7 @@ button[disabled] {
align-items: center;
padding: 0px;
color: #909399;
font-size: 30rpx;
font-size:26rpx;
}
.std_uom {
@ -2493,7 +2606,7 @@ button[disabled] {
.uom {
color: #909399;
font-size: 30rpx;
font-size: 26rpx;
margin-left: 5rpx;
margin-right: 5rpx;
display: flex;
@ -2587,7 +2700,14 @@ button[disabled] {
border: 1px solid rgb(220, 211, 211);
padding: 5rpx;
}
.desc_input {
height: 100rpx;
font-size: 10rpx;
color: #000000;
text-align: left;
border: 1px solid rgb(220, 211, 211);
padding: 5rpx;
}
.qty_inspect_input {
width: 150rpx;
height: 60rpx;
@ -2642,8 +2762,9 @@ button[disabled] {
align-self: stretch;
/* 颜色/白色 */
background: #FFFFFF;
background:rgba(60, 156, 255, 1);
box-sizing: border-box;
color:white;
/* 颜色/边框 */
border: 1px solid #E7E6E4;
z-index: 3;
@ -2747,3 +2868,8 @@ button[disabled] {
padding: 10rpx 20rpx 10rpx 20rpx;
border-radius: 10rpx;
}
.split_line {
background-color: rgba(230,230,230,0.5);
height: 1px;
}

31
src/common/style/pdabasic.css

@ -480,7 +480,7 @@ export function getItemTypeStyle(val) {
.detail-list {
background-color: #fff;
padding:5rpx 10rpx;
padding: 5rpx 10rpx;
/* margin: 20rpx; */
/* border-radius: 16rpx; */
/* overflow: hidden; */
@ -631,7 +631,7 @@ export function getItemTypeStyle(val) {
/* border-width: 0.5px;
border-style: solid;
border-color: #e5e5e5;
border-radius: 5px;
border-radius: 5px;
background-color: rgb(248, 248, 248);
font-size: 18px;*/
font-size: .825rem;
@ -725,20 +725,29 @@ page {
}
.page-header {
background-color: #3c9cff;
font-size: 35rpx;
padding: 10rpx 20rpx;
}
.page-header .header-view {
display: flex;
flex-direction: column;
background-color: #fff;
font-size: 35rpx;
padding: 10rpx 20rpx;
border-radius: 4px;
}
.page-header .header_item {
.page-header .header-view .header_item {
/* padding-left: 10rpx; */
padding: 5rpx 10rpx;
font-size:32rpx ;
font-size: 32rpx;
}
.page-header .header_job_top {
padding:5rpx 0rpx;
.page-header .header-view .header_job_top {
padding: 5rpx 0rpx;
}
.page-main {
flex: 1;
position: relative;
@ -760,3 +769,11 @@ page {
background: #e0e0e0;
}
.page-footer {
/* color: #fff; */
/* line-height: 100rpx; */
/* 不放大不缩小固定100rpx */
flex: 0 0 100rpx;
/* background-color: #00AAFF; */
}

16
src/common/utils/storage.js

@ -10,7 +10,21 @@ const setStorage = (key,value)=>{
// 清除全部本地存储
const clearStorage = ()=>{
uni.clearStorageSync();
let overPackageRecordPointParams = ''
if( uni.getStorageSync('overPackageRecordPointParams')){
overPackageRecordPointParams = uni.getStorageSync('overPackageRecordPointParams')
}
let overPackageJobDetailPointParams = ''
if( uni.getStorageSync('overPackageJobDetailPointParams')){
overPackageJobDetailPointParams = uni.getStorageSync('overPackageJobDetailPointParams')
}
uni.clearStorageSync();
if(overPackageRecordPointParams){
uni.setStorageSync('overPackageRecordPointParams',overPackageRecordPointParams)
}
if(overPackageJobDetailPointParams){
uni.setStorageSync('overPackageJobDetailPointParams',overPackageJobDetailPointParams)
}
}
// 清除指定key本地存储

BIN
src/components/kk-printer/empty-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

416
src/components/kk-printer/index.vue

@ -0,0 +1,416 @@
<template>
<view class="kk-printer">
<view class="kk-printer-btn" @tap="handlePrintTap">
{{isPrinting?printingText:defaultText}}
</view>
<view class="kk-shadow" :class="isShowSearch?'show':''" @tap="handleSearchClose">
<view class="kk-modal" @tap.stop="doNothing">
<view class="kk-search-device">
<view class="kk-filter-wrap">
<view class="filter-title">根据SRRI过滤设备</view>
<slider @change="handleSRRIChange" max='-20' min='-100' value="-95" show-value/>
</view>
<view class="kk-filter-wrap">
<view class="filter-title">根据蓝牙名过滤</view>
<input type="text" placeholder-class="kk-placeholder-class" placeholder="请输入蓝牙名字或设备ID搜索" v-model="filterName" />
</view>
<view class="kk-btn-wrap">
<view class="kk-btn-item confirm-btn" @tap="searchBtnTap" v-if="!isSearching">
搜索设备
</view>
<view class="kk-btn-item confirm-btn" v-else>
搜索中...
</view>
<view class="kk-btn-item" @tap="stopSearchBtnTap">
停止搜索
</view>
</view>
<view class="kk-devices-wrap">
<view class="empty-wrap" v-if="filterDeviceList.length <= 0">
<view class="empty-icon"></view>
<view class="empty-text">~ 无可搜索到的设备 ~</view>
</view>
<view class="" v-else>
<view class="kk-devices-item" v-for="(item,index) in filterDeviceList" :key="index" @tap="handleConnectDevice(item)">
<view class="name">
<text>设备名称</text>
<text>{{item.name?item.name:'未命名'}}</text>
</view>
<view class="rssi">
<text>信号强度</text>
<text>({{Math.max(0, item.RSSI + 100)}}%)</text>
</view>
<view class="deviceid">
<text>设备ID</text>
<text>{{item.deviceId}}</text>
</view>
<view class="advmac" v-if="item.advMac">
<text>advMac</text>
<text>{{item.advMac}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import * as gbk from '@/components/kk-printer/utils/printUtil-GBK.js';
import * as blesdk from './utils/bluetoolth';
import * as util from './utils/util.js';
export default {
data(){
return{
//
isPrinting:false,
//
isSearching:false,
//
isShowSearch:false,
//
filterName:'',
//
filterRSSI:-95,
//
devicesList:[],
//ID
deviceId:'',
//ID
services:'',
//
serviceId: '',
writeId: '',
readId: ''
}
},
props:{
//
defaultText:{
type:String,
default:'打印'
},
//
printingText:{
type:String,
default:'打印中...'
},
bufferData:{
type:String,
require:true
}
},
computed:{
mapFilterRSSI(){
return (0 - this.filterRSSI)
},
filterDeviceList(){
let devices = this.devicesList;
let name = this.filterName;
let rssi = this.filterRSSI;
console.log(devices,name,rssi)
//RSSI
let filterDevices1 = devices.filter((item)=>{
return item.RSSI > rssi
})
console.log(filterDevices1)
//
let filterDevices2
if(name!=''){
filterDevices2 = filterDevices1.filter((item)=>{
return (item.name.indexOf(name) >= 0 || item.deviceId.indexOf(name) >= 0)
})
}else{
filterDevices2 = filterDevices1
}
// 广MAC
for (let i = 0; i < filterDevices2.length;i++) {
if (filterDevices2[i].hasOwnProperty('advertisData')){
if (filterDevices2[i].advertisData.byteLength == 8) {
filterDevices2[i].advMac = util.buf2hex(filterDevices2[i].advertisData.slice(2, 7));
}
}
}
return filterDevices2
}
},
mounted() {
},
beforeDestroy(){
this.stopSearchBtnTap();
},
methods:{
doNothing(){
return;
},
//
handlePrintTap(){
console.log(11)
//
blesdk.openBlue().then((res)=>{
console.log(99,res)
//
blesdk.getConnectedBluetoothDevices().then((res)=>{
//
console.log(66,res,this.deviceId,this.serviceId,this.writeId,this.bufferData,this.onPrintSuccess)
if(res.devices.length == 0){
this.isShowSearch = true
}else{
let datalen=20;
if (plus.os.name != 'Android')
{
datalen=180;
}
this.isPrinting = true;
this.$emit('onPrint');
this.$nextTick(()=>{
console.log(1,this.bufferData)
if(this.bufferData!=''){
let buffer = gbk.strToGBKByte(this.bufferData)
console.log(2,buffer)
let opt = {
deviceId: this.deviceId,
serviceId: this.serviceId,
characteristicId: this.writeId,
value:buffer,
lasterSuccess: this.onPrintSuccess,
onceLength:datalen
}
console.log(3,opt)
blesdk.sendDataToDevice(opt);
this.isPrinting = false;
}
})
}
}).catch((err)=>{
console.log(88,err)
blesdk.catchToast(err);
})
}).catch((err)=>{
console.log(77,err)
blesdk.catchToast(err);
})
},
onGetDevice(res){
this.devicesList = res;
},
handleSearchClose(){
this.isShowSearch = false
},
handleSRRIChange(e){
this.filterRSSI = e.detail.value
},
//
searchBtnTap(){
blesdk.startBluetoothDevicesDiscovery();
this.isSearching = true;
blesdk.onfindBlueDevices(this.onGetDevice)
},
//
stopSearchBtnTap(){
blesdk.stopBlueDevicesDiscovery();
this.isSearching = false;
},
//
handleConnectDevice(device){
let deviceId = device.deviceId;
let name = device.name;
this.deviceId = deviceId;
console.log('deviceId',this.deviceId)
// uni.setStorageSync('k_curDeviceID',deviceId);
// uni.setStorageSync('k_curDeviceName',name);
uni.onBLEConnectionStateChange((res)=>{
console.log('连接',res)
if(res.connected){
plus.nativeUI.toast('设备'+ res.deviceId + '已连接',{
verticalAlign:'center'
})
}else{
plus.nativeUI.toast('设备'+ res.deviceId + '已断开连接',{
verticalAlign:'center'
})
}
})
blesdk.createBLEConnection(deviceId, this.onConnectSuccess, this.onConnectFail);
},
onConnectSuccess(res){
this.stopSearchBtnTap()
blesdk.getBLEDeviceServices(this.deviceId, this.onGetServicesSuccess, this.onGetServicesFail);
},
onConnectFail(err){
console.log('链接失败',err)
},
onGetServicesSuccess(res){
console.log('获取服务',res)
this.services = res.serviceId;
blesdk.getDeviceCharacteristics(this.deviceId, this.services, this.onGetCharacterSuccess, this.onGetCharacterFail);
},
onGetServicesFail(err){
console.log('获取服务失败')
},
onGetCharacterSuccess(res){
console.log('获取特征值成功',res)
this.serviceId = res.serviceId;
this.writeId = res.writeId;
this.readId = res.readId;
this.isShowSearch = false;
},
onGetCharacterFail(err){
console.log('特征值获取失败')
},
onPrintSuccess(){
this.isPrinting = false;
console.log('打印成功')
this.$emit('onPrintSuccess')
},
onPrintFail(){
console.log('打印失败')
this.isPrinting = false;
}
}
}
</script>
<style lang="scss" scoped>
.kk-printer{
width:100%;
height:100%;
&-btn{
width:100%;
height:100%;
text-align: center;
line-height: 50px;
}
.kk-shadow{
display: none;
&.show{
display: block;
width:100vw;
height:100vh;
background: rgba(0,0,0,0.4);
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
.kk-modal{
width:680upx;
height: 80%;
padding:24upx;
box-sizing: border-box;
overflow-y: auto;
border-radius: 20upx;
background: #ffffff;
display: flex;
justify-content: center;
align-items: center;
.kk-search-device{
width:100%;
height: 100%;
.kk-filter-wrap{
width:100%;
height: 160upx;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
.filter-title{
line-height: 70upx;
font-size: 30upx;
color: #999999;
}
&>slider{
width:90%;
height: 90upx;
}
&>input{
padding:0 20upx;
box-sizing: border-box;
border-radius: 10upx;
height: 90upx;
width:100%;
border: 1upx solid #ebebeb;
}
}
.kk-btn-wrap{
width:100%;
height: 140upx;
display: flex;
justify-content: space-between;
align-items: center;
&>view{
flex:1 1 auto;
height: 100upx;
line-height: 100upx;
border-radius: 16upx;
text-align: center;
color:#ffffff;
&.confirm-btn{
background: #007AFF;
margin-right:30upx;
}
&:nth-last-child(1){
background: #DD524D;
}
}
}
.kk-devices-wrap{
height: calc(100% - 460upx);
overflow-y:auto;
padding:10upx 20upx;
box-sizing: border-box;
border: 1upx solid #ebebeb;
box-sizing: border-box;
border-radius: 20upx;
.empty-wrap{
width:100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.empty-icon{
width:268upx;
height: 240upx;
background: url('./empty-icon.png') no-repeat;
background-size:100% 100%;
margin-bottom: 26upx;
}
.empty-text{
width: 100%;
line-height: 50upx;
font-size: 30upx;
text-align: center;
color: #999999;
}
}
.kk-devices-item{
width:100%;
border-bottom: 1upx solid #ebebeb;
padding:10upx 0;
box-sizing: border-box;
&:nth-last-child(1){
border-bottom: none;
}
&>view{
width:100%;
font-size: 30upx;
}
}
}
}
}
}
}
}
.kk-placeholder-class{
font-size: 30upx;
color:#999999;
}
</style>

402
src/components/kk-printer/utils/barcode.js

@ -0,0 +1,402 @@
var CHAR_TILDE = 126;
var CODE_FNC1 = 102;
var SET_STARTA = 103;
var SET_STARTB = 104;
var SET_STARTC = 105;
var SET_SHIFT = 98;
var SET_CODEA = 101;
var SET_CODEB = 100;
var SET_STOP = 106;
var REPLACE_CODES = {
CHAR_TILDE: CODE_FNC1 //~ corresponds to FNC1 in GS1-128 standard
}
var CODESET = {
ANY: 1,
AB: 2,
A: 3,
B: 4,
C: 5
};
function getBytes(str) {
var bytes = [];
for (var i = 0; i < str.length; i++) {
bytes.push(str.charCodeAt(i));
}
return bytes;
}
exports.code128 = function (ctx, text, width, height) {
width = parseInt(width);
height = parseInt(height);
var codes = stringToCode128(text);
var g = new Graphics(ctx, width, height);
var barWeight = g.area.width / ((codes.length - 3) * 11 + 35);
var x = g.area.left;
var y = g.area.top;
for (var i = 0; i < codes.length; i++) {
var c = codes[i];
//two bars at a time: 1 black and 1 white
for (var bar = 0; bar < 8; bar += 2) {
var barW = PATTERNS[c][bar] * barWeight;
// var barH = height - y - this.border;
var barH = height - y;
var spcW = PATTERNS[c][bar + 1] * barWeight;
//no need to draw if 0 width
if (barW > 0) {
g.fillFgRect(x, y, barW, barH);
}
x += barW + spcW;
}
}
ctx.draw();
}
function stringToCode128(text) {
var barc = {
currcs: CODESET.C
};
var bytes = getBytes(text);
//decide starting codeset
var index = bytes[0] == CHAR_TILDE ? 1 : 0;
var csa1 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;
var csa2 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;
barc.currcs = getBestStartSet(csa1, csa2);
barc.currcs = perhapsCodeC(bytes, barc.currcs);
//if no codeset changes this will end up with bytes.length+3
//start, checksum and stop
var codes = new Array();
switch (barc.currcs) {
case CODESET.A:
codes.push(SET_STARTA);
break;
case CODESET.B:
codes.push(SET_STARTB);
break;
default:
codes.push(SET_STARTC);
break;
}
for (var i = 0; i < bytes.length; i++) {
var b1 = bytes[i]; //get the first of a pair
//should we translate/replace
if (b1 in REPLACE_CODES) {
codes.push(REPLACE_CODES[b1]);
i++ //jump to next
b1 = bytes[i];
}
//get the next in the pair if possible
var b2 = bytes.length > (i + 1) ? bytes[i + 1] : -1;
codes = codes.concat(codesForChar(b1, b2, barc.currcs));
//code C takes 2 chars each time
if (barc.currcs == CODESET.C) i++;
}
//calculate checksum according to Code 128 standards
var checksum = codes[0];
for (var weight = 1; weight < codes.length; weight++) {
checksum += (weight * codes[weight]);
}
codes.push(checksum % 103);
codes.push(SET_STOP);
//encoding should now be complete
return codes;
function getBestStartSet(csa1, csa2) {
//tries to figure out the best codeset
//to start with to get the most compact code
var vote = 0;
vote += csa1 == CODESET.A ? 1 : 0;
vote += csa1 == CODESET.B ? -1 : 0;
vote += csa2 == CODESET.A ? 1 : 0;
vote += csa2 == CODESET.B ? -1 : 0;
//tie goes to B due to my own predudices
return vote > 0 ? CODESET.A : CODESET.B;
}
function perhapsCodeC(bytes, codeset) {
for (var i = 0; i < bytes.length; i++) {
var b = bytes[i]
if ((b < 48 || b > 57) && b != CHAR_TILDE)
return codeset;
}
return CODESET.C;
}
//chr1 is current byte
//chr2 is the next byte to process. looks ahead.
function codesForChar(chr1, chr2, currcs) {
var result = [];
var shifter = -1;
if (charCompatible(chr1, currcs)) {
if (currcs == CODESET.C) {
if (chr2 == -1) {
shifter = SET_CODEB;
currcs = CODESET.B;
}
else if ((chr2 != -1) && !charCompatible(chr2, currcs)) {
//need to check ahead as well
if (charCompatible(chr2, CODESET.A)) {
shifter = SET_CODEA;
currcs = CODESET.A;
}
else {
shifter = SET_CODEB;
currcs = CODESET.B;
}
}
}
}
else {
//if there is a next char AND that next char is also not compatible
if ((chr2 != -1) && !charCompatible(chr2, currcs)) {
//need to switch code sets
switch (currcs) {
case CODESET.A:
shifter = SET_CODEB;
currcs = CODESET.B;
break;
case CODESET.B:
shifter = SET_CODEA;
currcs = CODESET.A;
break;
}
}
else {
//no need to shift code sets, a temporary SHIFT will suffice
shifter = SET_SHIFT;
}
}
//ok some type of shift is nessecary
if (shifter != -1) {
result.push(shifter);
result.push(codeValue(chr2));
}
else {
if (currcs == CODESET.C) {
//include next as well
result.push(codeValue(chr1, chr2));
}
else {
result.push(codeValue(chr1));
}
}
barc.currcs = currcs;
return result;
}
}
//reduce the ascii code to fit into the Code128 char table
function codeValue(chr1, chr2) {
if (typeof chr2 == "undefined") {
return chr1 >= 32 ? chr1 - 32 : chr1 + 64;
}
else {
return parseInt(String.fromCharCode(chr1) + String.fromCharCode(chr2));
}
}
function charCompatible(chr, codeset) {
var csa = codeSetAllowedFor(chr);
if (csa == CODESET.ANY) return true;
//if we need to change from current
if (csa == CODESET.AB) return true;
if (csa == CODESET.A && codeset == CODESET.A) return true;
if (csa == CODESET.B && codeset == CODESET.B) return true;
return false;
}
function codeSetAllowedFor(chr) {
if (chr >= 48 && chr <= 57) {
//0-9
return CODESET.ANY;
}
else if (chr >= 32 && chr <= 95) {
//0-9 A-Z
return CODESET.AB;
}
else {
//if non printable
return chr < 32 ? CODESET.A : CODESET.B;
}
}
var Graphics = function(ctx, width, height) {
this.width = width;
this.height = height;
this.quiet = Math.round(this.width / 40);
this.border_size = 0;
this.padding_width = 0;
this.area = {
width : width - this.padding_width * 2 - this.quiet * 2,
height: height - this.border_size * 2,
top : this.border_size - 4,
left : this.padding_width + this.quiet
};
this.ctx = ctx;
this.fg = "#000000";
this.bg = "#ffffff";
// fill background
this.fillBgRect(0,0, width, height);
// fill center to create border
this.fillBgRect(0, this.border_size, width, height - this.border_size * 2);
}
//use native color
Graphics.prototype._fillRect = function(x, y, width, height, color) {
this.ctx.setFillStyle(color)
this.ctx.fillRect(x, y, width, height)
}
Graphics.prototype.fillFgRect = function(x,y, width, height) {
this._fillRect(x, y, width, height, this.fg);
}
Graphics.prototype.fillBgRect = function(x,y, width, height) {
this._fillRect(x, y, width, height, this.bg);
}
var PATTERNS = [
[2, 1, 2, 2, 2, 2, 0, 0], // 0
[2, 2, 2, 1, 2, 2, 0, 0], // 1
[2, 2, 2, 2, 2, 1, 0, 0], // 2
[1, 2, 1, 2, 2, 3, 0, 0], // 3
[1, 2, 1, 3, 2, 2, 0, 0], // 4
[1, 3, 1, 2, 2, 2, 0, 0], // 5
[1, 2, 2, 2, 1, 3, 0, 0], // 6
[1, 2, 2, 3, 1, 2, 0, 0], // 7
[1, 3, 2, 2, 1, 2, 0, 0], // 8
[2, 2, 1, 2, 1, 3, 0, 0], // 9
[2, 2, 1, 3, 1, 2, 0, 0], // 10
[2, 3, 1, 2, 1, 2, 0, 0], // 11
[1, 1, 2, 2, 3, 2, 0, 0], // 12
[1, 2, 2, 1, 3, 2, 0, 0], // 13
[1, 2, 2, 2, 3, 1, 0, 0], // 14
[1, 1, 3, 2, 2, 2, 0, 0], // 15
[1, 2, 3, 1, 2, 2, 0, 0], // 16
[1, 2, 3, 2, 2, 1, 0, 0], // 17
[2, 2, 3, 2, 1, 1, 0, 0], // 18
[2, 2, 1, 1, 3, 2, 0, 0], // 19
[2, 2, 1, 2, 3, 1, 0, 0], // 20
[2, 1, 3, 2, 1, 2, 0, 0], // 21
[2, 2, 3, 1, 1, 2, 0, 0], // 22
[3, 1, 2, 1, 3, 1, 0, 0], // 23
[3, 1, 1, 2, 2, 2, 0, 0], // 24
[3, 2, 1, 1, 2, 2, 0, 0], // 25
[3, 2, 1, 2, 2, 1, 0, 0], // 26
[3, 1, 2, 2, 1, 2, 0, 0], // 27
[3, 2, 2, 1, 1, 2, 0, 0], // 28
[3, 2, 2, 2, 1, 1, 0, 0], // 29
[2, 1, 2, 1, 2, 3, 0, 0], // 30
[2, 1, 2, 3, 2, 1, 0, 0], // 31
[2, 3, 2, 1, 2, 1, 0, 0], // 32
[1, 1, 1, 3, 2, 3, 0, 0], // 33
[1, 3, 1, 1, 2, 3, 0, 0], // 34
[1, 3, 1, 3, 2, 1, 0, 0], // 35
[1, 1, 2, 3, 1, 3, 0, 0], // 36
[1, 3, 2, 1, 1, 3, 0, 0], // 37
[1, 3, 2, 3, 1, 1, 0, 0], // 38
[2, 1, 1, 3, 1, 3, 0, 0], // 39
[2, 3, 1, 1, 1, 3, 0, 0], // 40
[2, 3, 1, 3, 1, 1, 0, 0], // 41
[1, 1, 2, 1, 3, 3, 0, 0], // 42
[1, 1, 2, 3, 3, 1, 0, 0], // 43
[1, 3, 2, 1, 3, 1, 0, 0], // 44
[1, 1, 3, 1, 2, 3, 0, 0], // 45
[1, 1, 3, 3, 2, 1, 0, 0], // 46
[1, 3, 3, 1, 2, 1, 0, 0], // 47
[3, 1, 3, 1, 2, 1, 0, 0], // 48
[2, 1, 1, 3, 3, 1, 0, 0], // 49
[2, 3, 1, 1, 3, 1, 0, 0], // 50
[2, 1, 3, 1, 1, 3, 0, 0], // 51
[2, 1, 3, 3, 1, 1, 0, 0], // 52
[2, 1, 3, 1, 3, 1, 0, 0], // 53
[3, 1, 1, 1, 2, 3, 0, 0], // 54
[3, 1, 1, 3, 2, 1, 0, 0], // 55
[3, 3, 1, 1, 2, 1, 0, 0], // 56
[3, 1, 2, 1, 1, 3, 0, 0], // 57
[3, 1, 2, 3, 1, 1, 0, 0], // 58
[3, 3, 2, 1, 1, 1, 0, 0], // 59
[3, 1, 4, 1, 1, 1, 0, 0], // 60
[2, 2, 1, 4, 1, 1, 0, 0], // 61
[4, 3, 1, 1, 1, 1, 0, 0], // 62
[1, 1, 1, 2, 2, 4, 0, 0], // 63
[1, 1, 1, 4, 2, 2, 0, 0], // 64
[1, 2, 1, 1, 2, 4, 0, 0], // 65
[1, 2, 1, 4, 2, 1, 0, 0], // 66
[1, 4, 1, 1, 2, 2, 0, 0], // 67
[1, 4, 1, 2, 2, 1, 0, 0], // 68
[1, 1, 2, 2, 1, 4, 0, 0], // 69
[1, 1, 2, 4, 1, 2, 0, 0], // 70
[1, 2, 2, 1, 1, 4, 0, 0], // 71
[1, 2, 2, 4, 1, 1, 0, 0], // 72
[1, 4, 2, 1, 1, 2, 0, 0], // 73
[1, 4, 2, 2, 1, 1, 0, 0], // 74
[2, 4, 1, 2, 1, 1, 0, 0], // 75
[2, 2, 1, 1, 1, 4, 0, 0], // 76
[4, 1, 3, 1, 1, 1, 0, 0], // 77
[2, 4, 1, 1, 1, 2, 0, 0], // 78
[1, 3, 4, 1, 1, 1, 0, 0], // 79
[1, 1, 1, 2, 4, 2, 0, 0], // 80
[1, 2, 1, 1, 4, 2, 0, 0], // 81
[1, 2, 1, 2, 4, 1, 0, 0], // 82
[1, 1, 4, 2, 1, 2, 0, 0], // 83
[1, 2, 4, 1, 1, 2, 0, 0], // 84
[1, 2, 4, 2, 1, 1, 0, 0], // 85
[4, 1, 1, 2, 1, 2, 0, 0], // 86
[4, 2, 1, 1, 1, 2, 0, 0], // 87
[4, 2, 1, 2, 1, 1, 0, 0], // 88
[2, 1, 2, 1, 4, 1, 0, 0], // 89
[2, 1, 4, 1, 2, 1, 0, 0], // 90
[4, 1, 2, 1, 2, 1, 0, 0], // 91
[1, 1, 1, 1, 4, 3, 0, 0], // 92
[1, 1, 1, 3, 4, 1, 0, 0], // 93
[1, 3, 1, 1, 4, 1, 0, 0], // 94
[1, 1, 4, 1, 1, 3, 0, 0], // 95
[1, 1, 4, 3, 1, 1, 0, 0], // 96
[4, 1, 1, 1, 1, 3, 0, 0], // 97
[4, 1, 1, 3, 1, 1, 0, 0], // 98
[1, 1, 3, 1, 4, 1, 0, 0], // 99
[1, 1, 4, 1, 3, 1, 0, 0], // 100
[3, 1, 1, 1, 4, 1, 0, 0], // 101
[4, 1, 1, 1, 3, 1, 0, 0], // 102
[2, 1, 1, 4, 1, 2, 0, 0], // 103
[2, 1, 1, 2, 1, 4, 0, 0], // 104
[2, 1, 1, 2, 3, 2, 0, 0], // 105
[2, 3, 3, 1, 1, 1, 2, 0] // 106
]

723
src/components/kk-printer/utils/bluetoolth.js

@ -0,0 +1,723 @@
/**
* @export
* @param {string} name 微信api的名称 uniAsyncPromise("getSystemInfo",options)
* @param {object} options 除了success fail 的其他参数
* @returns
*/
export function uniAsyncPromise(name, options) {
return new Promise((resolve, reject) => {
uni[name]({
...(options || {}),
// ...options,
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
}
});
});
}
//微信小程序向蓝牙打印机发送数据进行打印的坑:
//小程序api向蓝牙打印机发送数据打印,发送的任何内容都应该要转成二进制数据,而且蓝牙打印的文本编码是GBK的,发送中文需转成GBK编码再转成二进制数据发送
//发送打印机指令也要转成二进制数据发送
//蓝牙打印机一次接收的二级制数据有限制,不同的系统不同的蓝牙设备限制可能不同,微信建议一次20个字节,需做递归分包发送
//发送完要打印的内容后,一定要发送一个打印的指令才能顺利打印 (有些指令就不需要)
//一、初始化蓝牙、开始检索蓝牙设备
// { allowDuplicatesKey: true, interval: 500}
export function openBlue() {
return uniAsyncPromise('openBluetoothAdapter')
}
export function startBluetoothDevicesDiscovery(option) {
console.log('开始蓝牙扫描');
uniAsyncPromise('startBluetoothDevicesDiscovery', option).then((res) => {
console.log('正在搜寻蓝牙设备', res);
});
}
export function getConnectedBluetoothDevices(option) {
console.log('开始获取已连接设备');
return uniAsyncPromise('getConnectedBluetoothDevices', option)
}
//二、
/**
*
*
* @export
* @param {function} getDevices uni.getBluetoothDevices的监听回调函数
*/
export function onfindBlueDevices(getDevices) {
//监听寻找到新设备的事件
uni.onBluetoothDeviceFound((devices)=>{
//获取在蓝牙模块生效期间所有已发现的蓝牙设备
uniAsyncPromise('getBluetoothDevices').then((res) => {
getDevices && getDevices(res.devices);
});
});
}
/**
* @export
* @param {function} stopBlueDevicesDiscovery 关闭蓝牙扫描
*/
export function stopBlueDevicesDiscovery() {
//监听寻找到新设备的事件
console.log('停止蓝牙扫描');
return uniAsyncPromise('stopBluetoothDevicesDiscovery').then((res) => {
console.log('停止搜寻蓝牙设备', res);
});
}
//三、连接蓝牙设备
/**
* @export
* @param {function} createBLEConnection
* @param {number} deviceId 蓝牙设备id
*/
export function createBLEConnection(deviceId, sucess, fail) {
//连接蓝牙设备
console.log('连接蓝牙设备', deviceId);
uniAsyncPromise("createBLEConnection", {
deviceId
})
.then(res => {
//连接成功可选择停止搜索蓝牙
//stopBlueDevicesDiscovery();
console.log('连接成功');
sucess && sucess({
res: res,
});
})
.catch(res => {
console.log('连接设备异常' + res);
fail && fail({
res: res,
});
})
/*.finally(res=>{
console.log('连接成功');
sucess && sucess({
res: res,
});
});*/
}
export function closeBLEConnection(deviceId) {
console.log('断开蓝牙设备', deviceId);
uniAsyncPromise("closeBLEConnection", {
deviceId
})
.then(res => {
console.log('BLEDisconnect complete', res);
})
.catch(res => {
console.log('断开设备异常' + res);
})
/*.finally(res=>{
console.log('BLEDisconnect complete', res);
}); */
}
//四、连接成功后, 获取蓝牙设备的service服务
// uniAsyncPromise("getBLEDeviceServices",{deviceId:""}).then(res=>{})
export function getBLEDeviceServices(deviceId, success, fail) {
console.log('获取ServiceId', deviceId);
//加延迟避免取不到service
setTimeout(()=>{
uniAsyncPromise("getBLEDeviceServices", {
deviceId:deviceId
})
.then(res => {
console.log('服务', res);
success && success({
serviceId: res.services,
});
})
.catch((res) => {
//getBLEDeviceServices(deviceId, success, fail);
console.log('获取ServiceId异常' + res);
fail && fail({
res: res,
});
});
},1000)
}
//五、获取的service服务可能有多个,递归获取特征值(最后要用的是能读,能写,能监听的那个值的uuid作为特征值id)
/**
*
*
* @export
* @param {number} deviceId 蓝牙设备id
* @param {array} services uniAsyncPromise("getBLEDeviceServices",{deviceId:""}).then(res=>{})获取的res.services
* @param {function} success 成功取得有用特征值uuid的回调函数
*/
export function getDeviceCharacteristics(deviceId, services, success, fail) {
//services = services.slice(0);
console.log('获取Characteristics', deviceId, services);
if (services.length) {
const serviceId = services.shift().uuid;
console.log('ServceID ', serviceId);
uniAsyncPromise('getBLEDeviceCharacteristics', {
deviceId,
serviceId,
})
.then((res) => {
console.log('getBLEDeviceCharacteristics', deviceId, serviceId, res);
let finished = false;
let write = false;
let notify = false;
let indicate = false;
var readId;
var writeId;
//有斑马品牌的一款打印机中res.characteristics的所有uuid都是相同的,找所有的properties存在(notify || indicate) && write这种情况就说明这个uuid是可用的(不确保所有的打印机都能用这种方式取得uuid,在主要测试得凯盛诺打印机res.characteristic只有一个uuid,所以也能用这个方式)
for (var i = 0; i < res.characteristics.length; i++) {
if (!notify) {
notify = res.characteristics[i].properties.notify;
if (notify) readId = res.characteristics[i].uuid;
}
if (!indicate) {
indicate = res.characteristics[i].properties.indicate;
if (indicate) readId = res.characteristics[i].uuid;
}
if (!write) {
write = res.characteristics[i].properties.write;
writeId = res.characteristics[i].uuid;
}
if ((notify || indicate) && write) {
/* 获取蓝牙特征值uuid */
success &&
success({
serviceId,
writeId: writeId,
readId: readId,
});
finished = true;
break;
}
}
if (!finished) {
getDeviceCharacteristics(deviceId, services, success, fail);
}
})
.catch((res) => {
getDeviceCharacteristics(deviceId, services, success, fail);
});
} else {
fail && fail();
}
}
//六、启动notify 蓝牙监听功能 然后使用 uni.onBLECharacteristicValueChange用来监听蓝牙设备传递数据
/**
* @export
* @param {object} options
* {
deviceId,//蓝牙设备id
serviceId,//服务id
characteristicId,//可用特征值uuid
}
* @param {function} onChange 监听蓝牙设备传递数据回调函数
*/
export function onGetBLECharacteristicValueChange(options, onChange = function() {}) {
console.log('deviceId ', options.deviceId);
console.log('serviceId ', options.serviceId);
console.log('characteristicId ', options.characteristicId);
uniAsyncPromise('notifyBLECharacteristicValueChange', {
state: true,
...options,
}).then((res) => {
console.log('onBLECharacteristicValueChange ');
uni.onBLECharacteristicValueChange(onChange);
});
}
//七、发送数据(递归分包发送)
/**
* @export
* @param {object} options
* {
deviceId,
serviceId,
characteristicId,
value [ArrayBuffer],
lasterSuccess,
onceLength
}
*/
export function sendDataToDevice(options) {
let byteLength = options.value.byteLength;
//这里默认一次20个字节发送
const speed = options.onceLength; //20;
console.log("send data 20");
console.log(options);
if (byteLength > 0) {
uniAsyncPromise('writeBLECharacteristicValue', {
...options,
value: options.value.slice(0, byteLength > speed ? speed : byteLength),
})
.then((res) => {
if (byteLength > speed) {
sendDataToDevice({
...options,
value: options.value.slice(speed, byteLength),
});
} else {
options.lasterSuccess && options.lasterSuccess();
}
})
.catch((res) => {
console.log(res);
});
}
}
export function charToArrayBuffer(str) {
var out = new ArrayBuffer(str.length);
var uint8 = new Uint8Array(out);
var strs = str.split('');
for (var i = 0; i < strs.length; i++) {
uint8[i] = strs[i].charCodeAt();
}
return uint8;
}
export function charToArray(str) {
var arr = [];
var strs = str.split('');
for (var i = 0; i < strs.length; i++) {
arr[i] = strs[i].charCodeAt();
}
return arr;
}
//打印二维码
/**
* @export
* @param {object} options
* {
deviceId,
serviceId,
characteristicId,
value,//ArrayBuffer:二维码的数据
}
*/
export function printQR(options) {
//打印二维码的十进制指令data:
let data = [29, 107, 97, 7, 4, options.value.byteLength, 0];
sendDataToDevice({
...options,
value: new Uint8Array(data).buffer,
lasterSuccess: () => {
//指令发送成功后,发送二维码的数据
sendDataToDevice(options);
},
});
}
function grayPixle(pix) {
return pix[0] * 0.299 + pix[1] * 0.587 + pix[2] * 0.114;
}
export function overwriteImageData(data) {
let sendWidth = data.width,
sendHeight = data.height;
const threshold = data.threshold || 180;
let sendImageData = new ArrayBuffer((sendWidth * sendHeight) / 8);
sendImageData = new Uint8Array(sendImageData);
let pix = data.imageData;
const part = [];
let index = 0;
for (let i = 0; i < pix.length; i += 32) {
//横向每8个像素点组成一个字节(8位二进制数)。
for (let k = 0; k < 8; k++) {
const grayPixle1 = grayPixle(pix.slice(i + k * 4, i + k * 4 + (4 - 1)));
//阈值调整
if (grayPixle1 > threshold) {
//灰度值大于threshold位 白色 为第k位0不打印
part[k] = 0;
} else {
part[k] = 1;
}
}
let temp = 0;
for (let a = 0; a < part.length; a++) {
temp += part[a] * Math.pow(2, part.length - 1 - a);
}
//开始不明白以下算法什么意思,了解了字节才知道,一个字节是8位的二进制数,part这个数组存的0和1就是二进制的0和1,传输到打印的位图数据的一个字节是0-255之间的十进制数,以下是用权相加法转十进制数,理解了这个就用上面的for循环替代了
// const temp =
// part[0] * 128 +
// part[1] * 64 +
// part[2] * 32 +
// part[3] * 16 +
// part[4] * 8 +
// part[5] * 4 +
// part[6] * 2 +
// part[7] * 1;
sendImageData[index++] = temp;
}
return {
array: Array.from(sendImageData),
width: sendWidth / 8,
height: sendHeight,
};
}
/**
* printImage
* @param {object} opt
* {
deviceId,//蓝牙设备id
serviceId,//服务id
characteristicId,//可用特征值uuid
lasterSuccess , //最后完成的回调
}
*/
export function printImage(opt = {}, imageInfo = {}) {
let arr = imageInfo.array,
width = imageInfo.width;
const writeArray = [];
const xl = width % 256;
const xh = width / 256;
//分行发送图片数据,用的十进制指令
const command = [29, 118, 48, 0, xl, xh, 1, 0]; //1D 76 30 00 w h
const enter = [13, 10];
for (let i = 0; i < arr.length / width; i++) {
const subArr = arr.slice(i * width, i * width + width);
const tempArr = command.concat(subArr);
writeArray.push(new Uint8Array(tempArr));
}
writeArray.push(new Uint8Array(enter));
//console.log(writeArray);
const print = (options, writeArray) => {
if (writeArray.length) {
console.log("send");
sendDataToDevice({
...options,
value: writeArray.shift().buffer,
lasterSuccess: () => {
if (writeArray.length) {
print(options, writeArray);
} else {
options.lasterSuccess && options.lasterSuccess();
}
},
});
}
};
console.log("start print");
print(opt, writeArray);
}
/* 16hex insert 0 */
function Hex2Str(num) {
if (num.toString(16).length < 2) return "0" + num.toString(16);
else
return num.toString(16);
}
/*****CPCL指令接口****/
/**
* 配置项如下
*
* width: 标签纸的宽度单位像素點
* height: 标签纸的高度单位像素點
* 8像素=1mm
* printNum: 打印张数默认为1
* rotation页面整体旋转 1-90 2-180 3-270 其他-不旋转
*/
export function CreatCPCLPage(width, height, printNum, rotation = 0, offset = 0) {
var strCmd = '! ' + offset + ' 200 200 ' + height + ' ' + printNum + '\n';
strCmd += "PAGE-WIDTH " + width + '\n';
if (rotation == 1)
strCmd += "ZPROTATE90\n";
else if (rotation == 2)
strCmd += "ZPROTATE180\n";
else if (rotation == 3)
strCmd += "ZPROTATE270\n";
else
strCmd += "ZPROTATE0\n";
return strCmd;
}
/**
* 打印文字
* x: 文字方块左上角X座标单位dot
* y: 文字方块左上角Y座标单位dot
* fontName,fontSize: 字体取值 參考文檔
* rotation: 旋转 1-90 2-180 3-270 其他-不旋转
* content: 文字内容
*/
export function addCPCLText(x, y, fontName, fontSize, rotation, content) {
//console.log(fontName,fontSize,rotation, content);
var strCmd = '';
if (rotation == 1) {
strCmd += 'T90 ';
}
if (rotation == 2) {
strCmd += 'T180 ';
}
if (rotation == 3) {
strCmd += 'T270 ';
} else {
strCmd += 'T ';
}
strCmd += fontName + ' ' + fontSize + ' ' + x + ' ' + y + ' ' + content + '\n';
return strCmd;
};
/**
* 打印一维码
*
* x: 文字方块左上角X座标单位dot
* y: 文字方块左上角Y座标单位dot
* codeType: 条码类型取值为128UPCAUPCA2UPCA5UPCEUPCE2UPC5EAN13EAN13+2EAN13+5
* EAN8EAN8+2EAN8+53939CF39F39C93CODABARCODABAR16ITFI2OF5
* h: 条码高度单位dot
* rotation: 顺时针旋转角度取值如下
* - 0 不旋转
* - 1 顺时针旋转90度
*
* narrow: 窄条码比例因子(dot) 取值 參考文檔
* wide: 宽条码比例因子(dot) 取值 參考文檔
* content: 文字内容
*
*/
export function addCPCLBarCode(x, y, codeType, h, rotation, narrow, wide, content) {
var strCmd = '';
if (rotation == 0)
strCmd += 'B ';
else
strCmd += 'VB ';
strCmd += codeType + ' ' + narrow + ' ' + wide + ' ' + h + ' ' + x + ' ' + y + ' ' + content + '\n'
return strCmd;
};
/**
* 打印二维码
*
* x: 文字方块左上角X座标单位dot
* y: 文字方块左上角Y座标单位dot
* level: 错误纠正能力等级取值为L(7%)M(15%)Q(25%)H(30%)
* ver: 1-10 版本根据内容调整以获取合适容量
* scale: 1-10 放大倍数
* content: 文字内容
*
*/
export function addCPCLQRCode(x, y, level, ver, scale, content) {
var strCmd = 'B QR ' + x + ' ' + y + ' M ' + ver + ' U ' + scale + '\n' + level + 'A,' + content + '\n';
strCmd += 'ENDQR\n';
return strCmd;
};
/**
* 放大指令
* scaleX: 横向放大倍数 123等整数
* scaleY: 纵向放大倍数 123等整数
*/
export function addCPCLSETMAG(scaleX, scaleY) {
var strCmd = 'SETMAG ' + scaleX + ' ' + scaleY + '\n';
return strCmd;
};
/**
* 对齐指令 0-左对齐 1-右对齐 2-居中
*/
export function addCPCLLocation(set) {
var strCmd = '';
if (set == 1) {
strCmd += 'RIGHT\n';
} else if (set == 2) {
strCmd += 'CENTER\n';
} else {
strCmd += 'LEFT\n';
}
return strCmd;
};
/**
* 反白线 x0,y0,x1,y1,width
*/
export function addCPCLInverseLine(x0, y0, x1, y1, width) {
var strCmd = 'IL ' + x0 + ' ' + y0 + ' ' + x1 + ' ' + y1 + ' ' + width + '\n';
return strCmd;
};
/**
* 画线 x0,y0,x1,y1,width
*/
export function addCPCLLine(x0, y0, x1, y1, width) {
var strCmd = 'L ' + x0 + ' ' + y0 + ' ' + x1 + ' ' + y1 + ' ' + width + '\n';
return strCmd;
};
/**
* 画框 x0,y0,x1,y1,width
*/
export function addCPCLBox(x0, y0, x1, y1, width) {
var strCmd = 'BOX ' + x0 + ' ' + y0 + ' ' + x1 + ' ' + y1 + ' ' + width + '\n';
return strCmd;
};
/**
* 字体加粗
*/
export function addCPCLSETBOLD(bold) {
var strCmd = 'SETBOLD ' + bold + '\n';
return strCmd;
};
/**
* 字体下划线
*/
export function addCPCLUNDERLINE(c) {
var strCmd = 'UNDERLINE ';
if (c) strCmd += 'ON\n';
else if (c) strCmd += 'OFF\n';
return strCmd;
};
/**
* 水印打印灰度等级 0-255
*/
export function addCPCLBACKGROUND(level) {
var strCmd = 'BACKGROUND ';
if (level > 255 || level < 0) level = 255;
strCmd += level + '\n';
return strCmd;
};
/**
* 打印水印文字
* x: 文字方块左上角X座标单位dot
* y: 文字方块左上角Y座标单位dot
* fontName,fontSize: 字体取值 參考文檔
* rotation: 旋转 1-90 2-180 3-270 其他-不旋转
* content: 文字内容
*/
export function addCPCLBKVText(x, y, fontName, fontSize, rotation, content) {
//console.log(fontName,fontSize,rotation, content);
var strCmd = '';
if (rotation == 1) {
strCmd += 'BKT90 ';
}
if (rotation == 2) {
strCmd += 'BKT180 ';
}
if (rotation == 3) {
strCmd += 'BKT270 ';
} else {
strCmd += 'BKT ';
}
strCmd += fontName + ' ' + fontSize + ' ' + x + ' ' + y + ' ' + content + '\n';
return strCmd;
};
/**
* 标签缝隙定位指令
*/
export function addCPCLGAP() {
var strCmd = 'GAP-SENSE\nFORM\n';
return strCmd;
};
/**
* 标签右黑标检测指令
*/
export function addCPCLSENSE() {
var strCmd = 'BAR-SENSE\nFORM\n';
return strCmd;
};
/**
* 标签左黑标检测指令
*/
export function addCPCLSENSELEFT() {
var strCmd = 'BAR-SENSE LEFT\nFORM\n';
return strCmd;
};
/**
* 打印指令
*/
export function addCPCLPrint() {
var strCmd = 'PRINT\n';
return strCmd;
};
/**
* 图片打印指令
* x: 文字方块左上角X座标单位dot
* y: 文字方块左上角Y座标单位dot
* data{
threshold,//0/1提取的灰度级
width,//图像宽度
height,//图像高度
imageData , //图像数据
}
*/
export function addCPCLImageCmd(x, y, data) {
var strImgCmd = '';
const threshold = data.threshold || 180;
let myBitmapWidth = data.width,
myBitmapHeight = data.height;
let len = parseInt((myBitmapWidth + 7) / 8); //一行的数据长度
//console.log('len=',len);
//console.log('myBitmapWidth=',myBitmapWidth);
//console.log('myBitmapHeight=',myBitmapHeight);
let ndata = 0;
let i = 0;
let j = 0;
let sendImageData = new ArrayBuffer(len * myBitmapHeight);
sendImageData = new Uint8Array(sendImageData);
let pix = data.imageData;
console.log('pix=', pix);
for (i = 0; i < myBitmapHeight; i++) {
for (j = 0; j < len; j++) {
sendImageData[ndata + j] = 0;
}
for (j = 0; j < myBitmapWidth; j++) {
const grayPixle1 = grayPixle(pix.slice((i * myBitmapWidth + j) * 4, (i * myBitmapWidth + j) * 4 + 3));
if (grayPixle1 < threshold)
sendImageData[ndata + parseInt(j / 8)] |= (0x80 >> (j % 8));
}
ndata += len;
}
//console.log('sendImageData=',sendImageData);
//CPCL指令图片数据
strImgCmd += 'EG ' + len + ' ' + myBitmapHeight + ' ' + x + ' ' + y + ' ';
for (i = 0; i < sendImageData.length; i++) {
strImgCmd += Hex2Str(sendImageData[i]);
}
strImgCmd += '\n';
//console.log(strImgCmd);
return strImgCmd;
}
/**
* toast显示捕获的蓝牙异常
*/
export function catchToast(err) {
const errMsg = {
10000: '未初始化蓝牙模块',
10001: '蓝牙未打开',
10002: '没有找到指定设备',
10003: '连接失败',
10004: '没有找到指定服务',
10005: '没有找到指定特征值',
10006: '当前连接已断开',
10007: '当前特征值不支持此操作',
10008: '系统上报异常',
10009: '系统版本低于 4.3 不支持BLE'
};
let coode = err.errCode ? err.errCode.toString() : '';
let msg = errMsg[coode];
plus.nativeUI.toast(msg || coode, {
align: 'center',
verticalAlign: 'center'
});
}

23
src/components/kk-printer/utils/index.js

@ -0,0 +1,23 @@
var barcode = require('./barcode');
var qrcode = require('./qrcode');
function convert_length(length) {
return Math.round(wx.getSystemInfoSync().windowWidth * length / 750);
}
function barc(id, code, width, height) {
barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height))
}
function qrc(id, code, width, height) {
qrcode.api.draw(code, {
ctx: wx.createCanvasContext(id),
width: convert_length(width),
height: convert_length(height)
})
}
module.exports = {
barcode: barc,
qrcode: qrc
}

14633
src/components/kk-printer/utils/mqtt.js

File diff suppressed because it is too large

1
src/components/kk-printer/utils/mqtt.min.js

File diff suppressed because one or more lines are too long

285
src/components/kk-printer/utils/printUtil-GBK.js

File diff suppressed because one or more lines are too long

778
src/components/kk-printer/utils/qrcode.js

@ -0,0 +1,778 @@
var QR = (function () {
// alignment pattern
var adelta = [
0, 11, 15, 19, 23, 27, 31, // force 1 pat
16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28
];
// version block
var vpat = [
0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d,
0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9,
0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75,
0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64,
0x541, 0xc69
];
// final format bits with mask: level << 3 | mask
var fmtword = [
0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M
0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q
0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b //H
];
// 4 per version: number of blocks 1,2; data width; ecc width
var eccblocks = [
1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17,
1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28,
1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22,
1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16,
1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22,
2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28,
2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26,
2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26,
2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24,
2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28,
4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24,
2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28,
4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22,
3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24,
5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24,
5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28,
5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28,
3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26,
3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28,
4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24,
4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30,
6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30,
8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30,
10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30,
3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30,
7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30,
5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30,
13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30,
17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30,
17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30,
12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30,
6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30,
17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30,
4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30,
19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30
];
// Galois field log table
var glog = [
0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
];
// Galios field exponent table
var gexp = [
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00
];
// Working buffers:
// data input and ecc append, image working buffer, fixed part of image, run lengths for badness
var strinbuf=[], eccbuf=[], qrframe=[], framask=[], rlens=[];
// Control values - width is based on version, last 4 are from table.
var version, width, neccblk1, neccblk2, datablkw, eccblkwid;
var ecclevel = 2;
// set bit to indicate cell in qrframe is immutable. symmetric around diagonal
function setmask(x, y)
{
var bt;
if (x > y) {
bt = x;
x = y;
y = bt;
}
// y*y = 1+3+5...
bt = y;
bt *= y;
bt += y;
bt >>= 1;
bt += x;
framask[bt] = 1;
}
// enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask)
function putalign(x, y)
{
var j;
qrframe[x + width * y] = 1;
for (j = -2; j < 2; j++) {
qrframe[(x + j) + width * (y - 2)] = 1;
qrframe[(x - 2) + width * (y + j + 1)] = 1;
qrframe[(x + 2) + width * (y + j)] = 1;
qrframe[(x + j + 1) + width * (y + 2)] = 1;
}
for (j = 0; j < 2; j++) {
setmask(x - 1, y + j);
setmask(x + 1, y - j);
setmask(x - j, y - 1);
setmask(x + j, y + 1);
}
}
//========================================================================
// Reed Solomon error correction
// exponentiation mod N
function modnn(x)
{
while (x >= 255) {
x -= 255;
x = (x >> 8) + (x & 255);
}
return x;
}
var genpoly = [];
// Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given.
function appendrs(data, dlen, ecbuf, eclen)
{
var i, j, fb;
for (i = 0; i < eclen; i++)
strinbuf[ecbuf + i] = 0;
for (i = 0; i < dlen; i++) {
fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]];
if (fb != 255) /* fb term is non-zero */
for (j = 1; j < eclen; j++)
strinbuf[ecbuf + j - 1] = strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])];
else
for( j = ecbuf ; j < ecbuf + eclen; j++ )
strinbuf[j] = strinbuf[j + 1];
strinbuf[ ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])];
}
}
//========================================================================
// Frame data insert following the path rules
// check mask - since symmetrical use half.
function ismasked(x, y)
{
var bt;
if (x > y) {
bt = x;
x = y;
y = bt;
}
bt = y;
bt += y * y;
bt >>= 1;
bt += x;
return framask[bt];
}
//========================================================================
// Apply the selected mask out of the 8.
function applymask(m)
{
var x, y, r3x, r3y;
switch (m) {
case 0:
for (y = 0; y < width; y++)
for (x = 0; x < width; x++)
if (!((x + y) & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
break;
case 1:
for (y = 0; y < width; y++)
for (x = 0; x < width; x++)
if (!(y & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
break;
case 2:
for (y = 0; y < width; y++)
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!r3x && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
break;
case 3:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = r3y, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!r3x && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
case 4:
for (y = 0; y < width; y++)
for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++, r3x++) {
if (r3x == 3) {
r3x = 0;
r3y = !r3y;
}
if (!r3y && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
break;
case 5:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
case 6:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
case 7:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
}
return;
}
// Badness coefficients.
var N1 = 3, N2 = 3, N3 = 40, N4 = 10;
// Using the table of the length of each run, calculate the amount of bad image
// - long runs or those that look like finders; called twice, once each for X and Y
function badruns(length)
{
var i;
var runsbad = 0;
for (i = 0; i <= length; i++)
if (rlens[i] >= 5)
runsbad += N1 + rlens[i] - 5;
// BwBBBwB as in finder
for (i = 3; i < length - 1; i += 2)
if (rlens[i - 2] == rlens[i + 2]
&& rlens[i + 2] == rlens[i - 1]
&& rlens[i - 1] == rlens[i + 1]
&& rlens[i - 1] * 3 == rlens[i]
// white around the black pattern? Not part of spec
&& (rlens[i - 3] == 0 // beginning
|| i + 3 > length // end
|| rlens[i - 3] * 3 >= rlens[i] * 4 || rlens[i + 3] * 3 >= rlens[i] * 4)
)
runsbad += N3;
return runsbad;
}
// Calculate how bad the masked image is - blocks, imbalance, runs, or finders.
function badcheck()
{
var x, y, h, b, b1;
var thisbad = 0;
var bw = 0;
// blocks of same color.
for (y = 0; y < width - 1; y++)
for (x = 0; x < width - 1; x++)
if ((qrframe[x + width * y] && qrframe[(x + 1) + width * y]
&& qrframe[x + width * (y + 1)] && qrframe[(x + 1) + width * (y + 1)]) // all black
|| !(qrframe[x + width * y] || qrframe[(x + 1) + width * y]
|| qrframe[x + width * (y + 1)] || qrframe[(x + 1) + width * (y + 1)])) // all white
thisbad += N2;
// X runs
for (y = 0; y < width; y++) {
rlens[0] = 0;
for (h = b = x = 0; x < width; x++) {
if ((b1 = qrframe[x + width * y]) == b)
rlens[h]++;
else
rlens[++h] = 1;
b = b1;
bw += b ? 1 : -1;
}
thisbad += badruns(h);
}
// black/white imbalance
if (bw < 0)
bw = -bw;
var big = bw;
var count = 0;
big += big << 2;
big <<= 1;
while (big > width * width)
big -= width * width, count++;
thisbad += count * N4;
// Y runs
for (x = 0; x < width; x++) {
rlens[0] = 0;
for (h = b = y = 0; y < width; y++) {
if ((b1 = qrframe[x + width * y]) == b)
rlens[h]++;
else
rlens[++h] = 1;
b = b1;
}
thisbad += badruns(h);
}
return thisbad;
}
function genframe(instring)
{
var x, y, k, t, v, i, j, m;
// find the smallest version that fits the string
t = instring.length;
version = 0;
do {
version++;
k = (ecclevel - 1) * 4 + (version - 1) * 16;
neccblk1 = eccblocks[k++];
neccblk2 = eccblocks[k++];
datablkw = eccblocks[k++];
eccblkwid = eccblocks[k];
k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9);
if (t <= k)
break;
} while (version < 40);
// FIXME - insure that it fits insted of being truncated
width = 17 + 4 * version;
// allocate, clear and setup data structures
v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
for( t = 0; t < v; t++ )
eccbuf[t] = 0;
strinbuf = instring.slice(0);
for( t = 0; t < width * width; t++ )
qrframe[t] = 0;
for( t = 0 ; t < (width * (width + 1) + 1) / 2; t++)
framask[t] = 0;
// insert finders - black to frame, white to mask
for (t = 0; t < 3; t++) {
k = 0;
y = 0;
if (t == 1)
k = (width - 7);
if (t == 2)
y = (width - 7);
qrframe[(y + 3) + width * (k + 3)] = 1;
for (x = 0; x < 6; x++) {
qrframe[(y + x) + width * k] = 1;
qrframe[y + width * (k + x + 1)] = 1;
qrframe[(y + 6) + width * (k + x)] = 1;
qrframe[(y + x + 1) + width * (k + 6)] = 1;
}
for (x = 1; x < 5; x++) {
setmask(y + x, k + 1);
setmask(y + 1, k + x + 1);
setmask(y + 5, k + x);
setmask(y + x + 1, k + 5);
}
for (x = 2; x < 4; x++) {
qrframe[(y + x) + width * (k + 2)] = 1;
qrframe[(y + 2) + width * (k + x + 1)] = 1;
qrframe[(y + 4) + width * (k + x)] = 1;
qrframe[(y + x + 1) + width * (k + 4)] = 1;
}
}
// alignment blocks
if (version > 1) {
t = adelta[version];
y = width - 7;
for (;;) {
x = width - 7;
while (x > t - 3) {
putalign(x, y);
if (x < t)
break;
x -= t;
}
if (y <= t + 9)
break;
y -= t;
putalign(6, y);
putalign(y, 6);
}
}
// single black
qrframe[8 + width * (width - 8)] = 1;
// timing gap - mask only
for (y = 0; y < 7; y++) {
setmask(7, y);
setmask(width - 8, y);
setmask(7, y + width - 7);
}
for (x = 0; x < 8; x++) {
setmask(x, 7);
setmask(x + width - 8, 7);
setmask(x, width - 8);
}
// reserve mask-format area
for (x = 0; x < 9; x++)
setmask(x, 8);
for (x = 0; x < 8; x++) {
setmask(x + width - 8, 8);
setmask(8, x);
}
for (y = 0; y < 7; y++)
setmask(8, y + width - 7);
// timing row/col
for (x = 0; x < width - 14; x++)
if (x & 1) {
setmask(8 + x, 6);
setmask(6, 8 + x);
}
else {
qrframe[(8 + x) + width * 6] = 1;
qrframe[6 + width * (8 + x)] = 1;
}
// version block
if (version > 6) {
t = vpat[version - 7];
k = 17;
for (x = 0; x < 6; x++)
for (y = 0; y < 3; y++, k--)
if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
qrframe[(5 - x) + width * (2 - y + width - 11)] = 1;
qrframe[(2 - y + width - 11) + width * (5 - x)] = 1;
}
else {
setmask(5 - x, 2 - y + width - 11);
setmask(2 - y + width - 11, 5 - x);
}
}
// sync mask bits - only set above for white spaces, so add in black bits
for (y = 0; y < width; y++)
for (x = 0; x <= y; x++)
if (qrframe[x + width * y])
setmask(x, y);
// convert string to bitstream
// 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported)
v = strinbuf.length;
// string to array
for( i = 0 ; i < v; i++ )
eccbuf[i] = strinbuf.charCodeAt(i);
strinbuf = eccbuf.slice(0);
// calculate max string length
x = datablkw * (neccblk1 + neccblk2) + neccblk2;
if (v >= x - 2) {
v = x - 2;
if (version > 9)
v--;
}
// shift and repack to insert length prefix
i = v;
if (version > 9) {
strinbuf[i + 2] = 0;
strinbuf[i + 3] = 0;
while (i--) {
t = strinbuf[i];
strinbuf[i + 3] |= 255 & (t << 4);
strinbuf[i + 2] = t >> 4;
}
strinbuf[2] |= 255 & (v << 4);
strinbuf[1] = v >> 4;
strinbuf[0] = 0x40 | (v >> 12);
}
else {
strinbuf[i + 1] = 0;
strinbuf[i + 2] = 0;
while (i--) {
t = strinbuf[i];
strinbuf[i + 2] |= 255 & (t << 4);
strinbuf[i + 1] = t >> 4;
}
strinbuf[1] |= 255 & (v << 4);
strinbuf[0] = 0x40 | (v >> 4);
}
// fill to end with pad pattern
i = v + 3 - (version < 10);
while (i < x) {
strinbuf[i++] = 0xec;
// buffer has room if (i == x) break;
strinbuf[i++] = 0x11;
}
// calculate and append ECC
// calculate generator polynomial
genpoly[0] = 1;
for (i = 0; i < eccblkwid; i++) {
genpoly[i + 1] = 1;
for (j = i; j > 0; j--)
genpoly[j] = genpoly[j]
? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)] : genpoly[j - 1];
genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)];
}
for (i = 0; i <= eccblkwid; i++)
genpoly[i] = glog[genpoly[i]]; // use logs for genpoly[] to save calc step
// append ecc to data buffer
k = x;
y = 0;
for (i = 0; i < neccblk1; i++) {
appendrs(y, datablkw, k, eccblkwid);
y += datablkw;
k += eccblkwid;
}
for (i = 0; i < neccblk2; i++) {
appendrs(y, datablkw + 1, k, eccblkwid);
y += datablkw + 1;
k += eccblkwid;
}
// interleave blocks
y = 0;
for (i = 0; i < datablkw; i++) {
for (j = 0; j < neccblk1; j++)
eccbuf[y++] = strinbuf[i + j * datablkw];
for (j = 0; j < neccblk2; j++)
eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
}
for (j = 0; j < neccblk2; j++)
eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
for (i = 0; i < eccblkwid; i++)
for (j = 0; j < neccblk1 + neccblk2; j++)
eccbuf[y++] = strinbuf[x + i + j * eccblkwid];
strinbuf = eccbuf;
// pack bits into frame avoiding masked area.
x = y = width - 1;
k = v = 1; // up, minus
/* inteleaved data and ecc codes */
m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
for (i = 0; i < m; i++) {
t = strinbuf[i];
for (j = 0; j < 8; j++, t <<= 1) {
if (0x80 & t)
qrframe[x + width * y] = 1;
do { // find next fill position
if (v)
x--;
else {
x++;
if (k) {
if (y != 0)
y--;
else {
x -= 2;
k = !k;
if (x == 6) {
x--;
y = 9;
}
}
}
else {
if (y != width - 1)
y++;
else {
x -= 2;
k = !k;
if (x == 6) {
x--;
y -= 8;
}
}
}
}
v = !v;
} while (ismasked(x, y));
}
}
// save pre-mask copy of frame
strinbuf = qrframe.slice(0);
t = 0; // best
y = 30000; // demerit
// for instead of while since in original arduino code
// if an early mask was "good enough" it wouldn't try for a better one
// since they get more complex and take longer.
for (k = 0; k < 8; k++) {
applymask(k); // returns black-white imbalance
x = badcheck();
if (x < y) { // current mask better than previous best?
y = x;
t = k;
}
if (t == 7)
break; // don't increment i to a void redoing mask
qrframe = strinbuf.slice(0); // reset for next pass
}
if (t != k) // redo best mask - none good enough, last wasn't t
applymask(t);
// add in final mask/ecclevel bytes
y = fmtword[t + ((ecclevel - 1) << 3)];
// low byte
for (k = 0; k < 8; k++, y >>= 1)
if (y & 1) {
qrframe[(width - 1 - k) + width * 8] = 1;
if (k < 6)
qrframe[8 + width * k] = 1;
else
qrframe[8 + width * (k + 1)] = 1;
}
// high byte
for (k = 0; k < 7; k++, y >>= 1)
if (y & 1) {
qrframe[8 + width * (width - 7 + k)] = 1;
if (k)
qrframe[(6 - k) + width * 8] = 1;
else
qrframe[7 + width * 8] = 1;
}
// return image
return qrframe;
}
var _canvas = null,
_size = null;
var api = {
get ecclevel () {
return ecclevel;
},
set ecclevel (val) {
ecclevel = val;
},
get size () {
return _size;
},
set size (val) {
_size = val
},
get canvas () {
return _canvas;
},
set canvas (el) {
_canvas = el;
},
getFrame: function (string) {
return genframe(string);
},
draw: function (string, canvas, size, ecc) {
ecclevel = ecc || ecclevel;
canvas = canvas || _canvas;
if (!canvas) {
console.warn('No canvas provided to draw QR code in!')
return;
}
size = size || _size || Math.min(canvas.width, canvas.height);
var frame = genframe(string),
ctx = canvas.ctx,
px = Math.round(size / (width + 8));
var roundedSize = px * (width + 8),
offset = Math.floor((size - roundedSize) / 2);
size = roundedSize;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.setFillStyle('#000000');
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) {
ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
}
}
}
ctx.draw();
}
}
module.exports = {
api: api
}
})()

171
src/components/kk-printer/utils/util.js

@ -0,0 +1,171 @@
//const gbk = require('./gbk.js');
//console.log("sasas" + gbk);
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
/*
const hexStringToBuff = str => { //str='中国:WXHSH'
const buffer = new ArrayBuffer((sumStrLength(str)) * 4)
const dataView = new DataView(buffer)
var data = str.toString();
var p = 0; //ArrayBuffer 偏移量
for (var i = 0; i < data.length; i++) {
if (isCN(data[i])) { //是中文
//调用GBK 转码
var t = gbk.encode(data[i]);
for (var j = 0; j < 2; j++) {
//var code = t[j * 2] + t[j * 2 + 1];
var code = t[j * 3 + 1] + t[j * 3 + 2];
var temp = parseInt(code, 16)
//var temp = strToHexCharCode(code);
dataView.setUint8(p++, temp)
}
} else {
var temp = data.charCodeAt(i);
dataView.setUint8(p++, temp)
}
}
return buffer;
}
*/
function toUnicode(s) {
var str = "";
for (var i = 0; i < s.length; i++) {
str += "\\u" + s.charCodeAt(i).toString(16) + "\t";
}
return str;
}
function strToHexCharCode(str) {
if (str === "")
return "";
var hexCharCode = [];
hexCharCode.push("0x");
for (var i = 0; i < str.length; i++) {
hexCharCode.push((str.charCodeAt(i)).toString(16));
}
return hexCharCode.join("");
}
function sumStrLength(str) {
var length = 0;
var data = str.toString();
for (var i = 0; i < data.length; i++) {
if (isCN(data[i])) { //是中文
length += 2;
} else {
length += 1;
}
}
return length;
}
function isCN(str) {
if (/^[\u3220-\uFA29]+$/.test(str)) {
return true;
} else {
return false;
}
}
//汉字转码
export function hexStringToArrayBuffer(str) {
const buffer = new ArrayBuffer((str.length / 2) + 1)
const dataView = new DataView(buffer)
for (var i = 0; i < str.length / 2; i++) {
var temp = parseInt(str[i * 2] + str[i * 2 + 1], 16)
dataView.setUint8(i, temp)
}
dataView.setUint8((str.length / 2), 0x0a)
return buffer;
}
//返回八位数组
function subString(str) {
var arr = [];
if (str.length > 8) { //大于8
for (var i = 0;
(i * 8) < str.length; i++) {
var temp = str.substring(i * 8, 8 * i + 8);
arr.push(temp)
}
return arr;
} else {
return str
}
}
//不带有汉字
function hexStringToArrayBufferstr(str) {
let val = ""
for (let i = 0; i < str.length; i++) {
if (val === '') {
val = str.charCodeAt(i).toString(16)
} else {
val += ',' + str.charCodeAt(i).toString(16)
}
}
val += "," + "0x0a";
console.log(val)
// 将16进制转化为ArrayBuffer
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
return parseInt(h, 16)
})).buffer
}
export function ab2hex(buffer) {
let hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
})
return hexArr.join('');
}
// ArrayBuffer转为字符串,参数为ArrayBuffer对象
export function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf));
}
// 字符串转为ArrayBuffer对象,参数为字符串
export function str2ab(str) {
var buf = new ArrayBuffer(str.length+1); // 补充/0
var bufView = new Uint8Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
export function send0X0A() {
const buffer = new ArrayBuffer(1)
const dataView = new DataView(buffer)
dataView.setUint8(0, 0x0a)
return buffer;
}
export function buf2hex(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
// module.exports = {
// hexStringToArrayBuffer: hexStringToArrayBuffer,
// send0X0A: send0X0A,
// ab2hex: ab2hex,
// str2ab: str2ab,
// ab2str: ab2str,
// buf2hex: buf2hex
// }

299
src/components/my-paging/my-paging.vue

@ -1,157 +1,160 @@
<!-- 基于z-paging封装个性化分页组件演示可减少大量重复代码 -->
<template>
<!-- 这边统一设置z-paging在页面中使用时就不用重复写 -->
<!-- 如果要在这里设置极简写法这里的ref不能设置为paging设置为其他名即可因为极简写法会修改/调用第一个包含了ref="paging"的付view中的list和query -->
<!-- 极简写法在下方设置autowire-list-name="xxx" autowire-query-name="xxx"即可与minimalism-demo.vue中的一致并且不用再从这个组件转发到页面只要遵循上一行的规则即可 -->
<z-paging ref="paging" v-model="list" fixed auto-show-back-to-top refresher-threshold="160rpx" @query="queryList"
:useVirtualList="useVirtualList" :useInnerList="useInnerList" :cellKeyName="cellKeyName" :innerListStyle="innerListStyle" :preloadPage="preloadPage" :cellHeightMode="cellHeightMode" :virtualScrollFps="virtualScrollFps"
:loading-more-loading-text="{'en':'英文的加载中','zh-cn':'中文的加载中','zh-hant-cn':'繁体的加载中'}">
<!-- 这里插入一个view到z-paging中并且这个view会被z-paging标记为top固定在顶部 -->
<template #top>
<!-- 这里接收页面传进来的slot这样相当于将页面传进来的slot传给z-paging的slot="top" -->
<slot name="top" />
</template>
<!-- 这里插入一个view到z-paging中并且这个view会被z-paging标记为bottom固定在顶部 -->
<!-- vue3中用v-slot:bottom -->
<template #bottom>
<!-- 这里接收页面传进来的slot这样相当于将页面传进来的slot传给z-paging的slot="bottom" -->
<slot name="bottom" />
</template>
<template #empty v-if="$slots.empty" >
<!-- 这里接收页面传进来的slot这样相当于将页面传进来的slot传给z-paging的slot="empty" -->
<slot name="empty" />
</template>
<!-- 这个是插入虚拟列表/内置列表的cell -->
<template #cell="{item,index}">
<slot name="cell" :item="item" :index="index"/>
</template>
<!-- 这边统一设置z-paging在页面中使用时就不用重复写 -->
<!-- 如果要在这里设置极简写法这里的ref不能设置为paging设置为其他名即可因为极简写法会修改/调用第一个包含了ref="paging"的付view中的list和query -->
<!-- 极简写法在下方设置autowire-list-name="xxx" autowire-query-name="xxx"即可与minimalism-demo.vue中的一致并且不用再从这个组件转发到页面只要遵循上一行的规则即可 -->
<z-paging ref="paging" v-model="list" fixed auto-show-back-to-top refresher-threshold="160rpx" @query="queryList" :useVirtualList="useVirtualList" :useInnerList="useInnerList" :cellKeyName="cellKeyName" :innerListStyle="innerListStyle" :preloadPage="preloadPage" :cellHeightMode="cellHeightMode" :virtualScrollFps="virtualScrollFps" :loading-more-loading-text="{ en: '英文的加载中', 'zh-cn': '中文的加载中', 'zh-hant-cn': '繁体的加载中' }">
<!-- 这里插入一个view到z-paging中并且这个view会被z-paging标记为top固定在顶部 -->
<template #top>
<!-- 这里接收页面传进来的slot这样相当于将页面传进来的slot传给z-paging的slot="top" -->
<slot name="top" />
</template>
<!-- 这里通过slot统一自定义了下拉刷新view和没有更多数据view页面那边就不用再写下面两行了 -->
<!-- 自定义下拉刷新view(如果use-custom-refresher为true且不设置下面的slot="refresher"此时不用获取refresherStatus会自动使用z-paging自带的下拉刷新view) -->
<template #refresher="{refresherStatus}">
<!-- <custom-refresher :status="refresherStatus" /> -->
</template>
<!-- 自定义没有更多数据view -->
<template #loadingMoreNoMore>
<!-- <custom-nomore></custom-nomore> -->
<uni-load-more status="normore" />
</template>
<!-- 这里插入一个view到z-paging中并且这个view会被z-paging标记为bottom固定在顶部 -->
<!-- vue3中用v-slot:bottom -->
<template #bottom>
<!-- 这里接收页面传进来的slot这样相当于将页面传进来的slot传给z-paging的slot="bottom" -->
<slot name="bottom" />
</template>
<!-- 这里接收页面传进来的普通slot如列表数据等 -->
<slot />
</z-paging>
<template #empty v-if="$slots.empty">
<!-- 这里接收页面传进来的slot这样相当于将页面传进来的slot传给z-paging的slot="empty" -->
<slot name="empty" />
</template>
<!-- 这个是插入虚拟列表/内置列表的cell -->
<template #cell="{ item, index }">
<slot name="cell" :item="item" :index="index" />
</template>
<!-- 这里通过slot统一自定义了下拉刷新view和没有更多数据view页面那边就不用再写下面两行了 -->
<!-- 自定义下拉刷新view(如果use-custom-refresher为true且不设置下面的slot="refresher"此时不用获取refresherStatus会自动使用z-paging自带的下拉刷新view) -->
<template #refresher="{ refresherStatus }">
<!-- <custom-refresher :status="refresherStatus" /> -->
</template>
<!-- 自定义没有更多数据view -->
<template #loadingMoreNoMore>
<!-- <custom-nomore></custom-nomore> -->
<u-loadmore status="normore" />
</template>
<!-- 这里接收页面传进来的普通slot如列表数据等 -->
<slot />
</z-paging>
</template>
<script>
export default {
name: "my-paging",
data() {
return {
list: []
};
},
props: {
//v-modellist
value: {
type: Array,
default: function() {
return [];
}
},
//使
useVirtualList: {
type: Boolean,
default: false
},
//z-paging()use-virtual-listtruetrue
useInnerList: {
type: Boolean,
default: false
},
//cellkeynvuenvueuse-inner-list
cellKeyName: {
type: String,
default: ''
},
//innerList
innerListStyle: {
type: Object,
default: function() {
return {};
}
},
//()127celldom()
preloadPage: {
type: [Number, String],
default: 12
},
//cellfixedcellcelldynamicdynamicfixed
cellHeightMode: {
type: String,
default: 'fixed'
},
//scroll60
virtualScrollFps: {
type: [Number, String],
default: 60
},
},
watch: {
//v-modez-paging
value(newVal) {
this.list = newVal;
},
// #ifdef VUE3
modelValue(newVal) {
this.list = newVal;
},
// #endif
//z-paging
list(newVal) {
//emit inputv-model
this.$emit('input', newVal);
// #ifdef VUE3
this.$emit('update:modelValue', newVal);
// #endif
}
},
methods: {
//z-paging@queryemit
queryList(pageNo, pageSize) {
console.log("queryList",pageNo)
// this.$emit('query', pageNo, pageSize);
},
//reloadz-paging
reload(data) {
this.$refs.paging.reload(data);
},
//completez-paging
complete(data) {
this.$refs.paging.complete(data);
},
/*
//使mixins使
//updatePageScrollTopz-paging
updatePageScrollTop(data){
this.$refs.paging.updatePageScrollTop(data);
},
//pageReachBottomz-paging
pageReachBottom(){
this.$refs.paging.pageReachBottom();
},
//doChatRecordLoadMorez-paging
doChatRecordLoadMore() {
this.$refs.paging.doChatRecordLoadMore();
}
*/
}
<script setup lang="ts">
import { ref, getCurrentInstance, nextTick, onMounted, watch } from 'vue'
import { onLoad, onShow, onNavigationBarButtonTap, onReady, onBackPress, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
const props = defineProps({
value: {
type: Array,
default() {
return []
}
},
// 使
useVirtualList: {
type: Boolean,
default: false
},
// z-paging()use-virtual-listtruetrue
useInnerList: {
type: Boolean,
default: false
},
// cellkeynvuenvueuse-inner-list
cellKeyName: {
type: String,
default: ''
},
// innerList
innerListStyle: {
type: Object,
default() {
return {}
}
},
// ()127celldom()
preloadPage: {
type: [Number, String],
default: 12
},
// cellfixedcellcelldynamicdynamicfixed
cellHeightMode: {
type: String,
default: 'fixed'
},
// scroll60
virtualScrollFps: {
type: [Number, String],
default: 60
}
})
const list = ref([])
const paging = ref()
// v-modez-paging
watch(
() => props.value,
(newVal) => {
list.value = newVal
}
)
// #ifdef VUE3
watch(
() => props.modelValue,
(newVal) => {
list.value = newVal
}
)
// #endif
watch(
() => list.value,
(newVal) => {
// emit inputv-model
emit('input', newVal)
// #ifdef VUE3
emit('update:modelValue', newVal)
// #endif
}
)
// z-paging@queryemit
const queryList = (pageNo, pageSize) => {
console.log('queryList', pageNo)
// this.$emit('query', pageNo, pageSize);
}
// reloadz-paging
const reload = (data) => {
paging.value.reload(data)
}
// completez-paging
const complete = (data) => {
console.log(data)
paging.value.complete(data)
}
/*
//使mixins使
//updatePageScrollTopz-paging
updatePageScrollTop(data){
this.$refs.paging.updatePageScrollTop(data);
},
//pageReachBottomz-paging
pageReachBottom(){
this.$refs.paging.pageReachBottom();
},
//doChatRecordLoadMorez-paging
doChatRecordLoadMore() {
this.$refs.paging.doChatRecordLoadMore();
}
*/
//
const emit = defineEmits(['input', 'update:modelValue'])
defineExpose({
reload,
complete
})
</script>
<style>
</style>
<style></style>

885
src/components/show-modal/show-modal.vue

@ -1,456 +1,443 @@
<template name="show-modal">
<view>
<u-modal v-model="show" :title-style="{color: 'red'}" :title="title" :showTitle="false"
:showConfirmButton="false" ref="modal">
<view class="slot-content">
<slot name="icon">
<image class="icon" :src="icon" />
</slot>
<scroll-view scroll-y="true" style="max-height: 200px;">
<rich-text class="content" :nodes="content">
</rich-text>
</scroll-view>
<u-line></u-line>
<slot name="button">
<view class="uni-flex uni-row u-col-center space-between" style="width: 100%;height: 48px;">
<view v-if="showCancelButton" class="cance_button" @tap="$u.throttle(cancelClose, 500)">
<text :style="{'color':cancelColor}">{{ cancelText }}</text>
</view>
<u-line direction="col" length="100%"></u-line>
<view v-if="showConfirmButton" class="confirm_button" @tap="$u.throttle(confirmClose, 500)">
<text :style="{'color':confirmColor}">{{confirmText}}</text>
<text v-if="showConfirmCountdown">({{seconds}}s关闭)</text>
</view>
</view>
</slot>
</view>
</u-modal>
</view>
<view>
<u-modal v-model="show" :title-style="{ color: 'red' }" :title="title" :showTitle="false" :showConfirmButton="false" ref="modal">
<view class="slot-content">
<slot name="icon">
<image class="icon" :src="icon" />
</slot>
<scroll-view scroll-y="true" style="max-height: 200px">
<rich-text class="content" :nodes="content"> </rich-text>
</scroll-view>
<view class="split_line"></view>
<slot name="button">
<view class="uni-flex uni-row u-col-center space-between" style="width: 100%; height: 48px">
<view v-if="showCancelButton" class="cance_button" @tap="$u.throttle(cancelClose, 500)">
<text :style="{ color: cancelColor }">{{ cancelText }}</text>
</view>
<u-line direction="col" length="100%"></u-line>
<view v-if="showConfirmButton" class="confirm_button" @tap="$u.throttle(confirmClose, 500)">
<text :style="{ color: confirmColor }">{{ confirmText }}</text>
<text v-if="showConfirmCountdown">({{ seconds }}s关闭)</text>
</view>
</view>
</slot>
</view>
</u-modal>
</view>
</template>
<script>
/**
* modal 模态框
* @description 弹出模态框常用于消息提示消息确认在当前页面内完成特定的交互操作
* */
export default {
data() {
return {
timer: null,
show: false, //
iconType: '消息',
icon: '../../static/icons/error-circle.svg',
title: '', //
content: '', //
cancelText: '取消', //
confirmText: '确定', //
showCancel: true, // true
confirmColor: '#007aff', //
cancelColor: null, //
showConfirmButton: true, //
showConfirmCountdown: true, //
showCancelButton: true, //
showClose: false,
confirm: false, // true
cancel: false, // true
seconds: 0,
success: () => {} //
}
},
methods: {
open() {
this.show = true;
},
close() {
this.$.refs.modal.popupClose();
},
confirmClose() {
if (this.show) {
this.show = false;
clearInterval(this.timer) //timer
this.$.refs.modal.popupClose();
this.success({
// cancel: false,
confirm: true,
});
}
},
cancelClose() {
clearInterval(this.timer) //timer
this.$.refs.modal.popupClose();
this.success({
// cancel: true,
confirm: false,
});
},
// (
showConfirmMessageModal(mContent, callback) {
this.showConfirmModal("消息", mContent, callback);
},
// (
showConfirmSuccessModal(mContent, callback) {
this.showConfirmModal("成功", mContent, callback);
},
// (
showConfirmFailModal(mContent, callback) {
this.showConfirmModal("失败", mContent, callback);
},
// (
showConfirmWarningModal(mContent, callback) {
this.showConfirmModal("警告", mContent, callback);
},
// (
showConfirmQuestionModal(mContent, callback) {
this.showConfirmModal("疑问", mContent, callback);
},
// (
showConfirmModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
showCancelButton: false,
success: function(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true);
console.log('用户点击确定')
} else {
callback(false);
console.log('用户点击取消')
}
}
}
});
},
// (+
showSelectMessageModal(mContent, callback) {
this.showSelectModal("消息", mContent, callback);
},
// (+
showSelectSuccessModal(mContent, callback) {
this.showSelectModal("成功", mContent, callback);
},
// (+
showSelectFailModal(mContent, callback) {
this.showSelectModal("失败", mContent, callback);
},
// (+
showSelectWarningModal(mContent, callback) {
this.showSelectModal("警告", mContent, callback);
},
// (+
showSelectQuestionModal(mContent, callback) {
this.showSelectModal("疑问", mContent, callback);
},
// (+
showSelectModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
success: function(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true);
console.log('用户点击确定')
} else {
callback(false);
console.log('用户点击取消')
}
}
}
});
},
// (+)
showConfirmCountdownMessageModal(mContent, callback) {
this.showConfirmCountdownModal("消息", mContent, callback);
},
// (+)
showConfirmCountdownSuccessModal(mContent, callback) {
this.showConfirmCountdownModal("成功", mContent, callback);
},
// (+)
showConfirmCountdownFailModal(mContent, callback) {
this.showConfirmCountdownModal("失败", mContent, callback);
},
// (+)
showConfirmCountdownWarningModal(mContent, callback) {
this.showConfirmCountdownModal("警告", mContent, callback);
},
// (+)
showConfirmCountdownQuestionModal(mContent, callback) {
this.showConfirmCountdownModal("疑问", mContent, callback);
},
// (+)
showConfirmCountdownModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
showCancelButton: false,
showConfirmCountdown: true,
success: function(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true);
console.log('用户点击确定')
} else {
callback(false);
console.log('用户点击取消')
}
}
}
});
},
// (++)
showSelectCountdownMessageModal(mContent, callback) {
this.showSelectCountdownModal("消息", mContent, callback);
},
// (++)
showSelectCountdownSuccessModal(mContent, callback) {
this.showSelectCountdownModal("成功", mContent, callback);
},
// (++)
showSelectCountdownFailModal(mContent, callback) {
this.showSelectCountdownModal("失败", mContent, callback);
},
// (++)
showSelectCountdownWarningModal(mContent, callback) {
this.showSelectCountdownModal("警告", mContent, callback);
},
// (++)
showSelectCountdownQuestionModal(mContent, callback) {
this.showSelectCountdownModal("疑问", mContent, callback);
},
// (++)
showSelectCountdownModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
showConfirmCountdown: true,
success: function(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true);
console.log('用户点击确定')
} else {
callback(false);
console.log('用户点击取消')
}
}
}
});
},
//
showModal(data) {
if (data.iconType) {
this.iconType = data.iconType
switch (data.iconType) {
case '消息':
this.icon = '/static/icons/error-circle.svg';
break;
case '成功':
this.icon = '/static/icons/checkmark-circle.svg';
break;
case '失败':
this.icon = '/static/icons/close-circle.svg';
break;
case '警告':
this.icon = '/static/icons/warning.svg';
break;
case '疑问':
this.icon = '/static/icons/question-circle.svg';
break;
default:
break;
}
}
// image
if (data.title) {
this.title = data.title
}
if (data.content) {
console.log(data.content);
this.content = data.content;
} else {
this.content = ''
}
if (data.cancelText) {
this.cancelText = data.cancelText
} else {
this.cancelText = '取消'
}
if (data.confirmText) {
this.confirmText = data.confirmText
} else {
this.confirmText = '确定'
}
if (data.showCancel === false || data.showCancel === true) {
this.showCancel = data.showCancel
} else {
this.showCancel = true
}
if (data.confirmColor) {
this.confirmColor = data.confirmColor
} else {
this.confirmColor = '#007aff'
}
if (data.cancelColor) {
this.cancelColor = data.cancelColor
} else {
this.cancelColor = '#666F83'
}
if (data.showConfirmButton === false || data.showConfirmButton === true) {
this.showConfirmButton = data.showConfirmButton
} else {
this.showConfirmButton = true
}
if (data.showConfirmCountdown === false || data.showConfirmCountdown === true) {
this.showConfirmCountdown = data.showConfirmCountdown
} else {
this.showConfirmCountdown = false
}
if (data.showCancelButton === false || data.showCancelButton === true) {
this.showCancelButton = data.showCancelButton
} else {
this.showCancelButton = true
}
if (data.success) {
this.success = data.success
} else {
this.success = () => {}
}
setTimeout(res => {
this.show = true;
}, 500)
if (this.showConfirmCountdown) {
this.startTimer();
}
},
startTimer() {
this.seconds = 3;
clearInterval(this.timer)
this.timer = setInterval(() => {
this.seconds--
// console.log("", this.seconds);
if (this.seconds <= 0) {
this.timeUp()
return
}
}, 1000)
},
timeUp() {
// clearInterval(this.timer)
console.log('时间到')
this.confirmClose();
},
},
}
/**
* modal 模态框
* @description 弹出模态框常用于消息提示消息确认在当前页面内完成特定的交互操作
* */
export default {
data() {
return {
timer: null,
show: false, //
iconType: '消息',
icon: '../../static/icons/error-circle.svg',
title: '', //
content: '', //
cancelText: '取消', //
confirmText: '确定', //
showCancel: true, // true
confirmColor: '#007aff', //
cancelColor: null, //
showConfirmButton: true, //
showConfirmCountdown: true, //
showCancelButton: true, //
showClose: false,
confirm: false, // true
cancel: false, // true
seconds: 0,
success: () => {} //
}
},
methods: {
open() {
this.show = true
},
close() {
this.$.refs.modal.popupClose()
},
confirmClose() {
if (this.show) {
this.show = false
clearInterval(this.timer) // timer
this.success({
// cancel: false,
confirm: true
})
}
},
cancelClose() {
clearInterval(this.timer) // timer
if(this.$refs.modal){
this.$refs.modal.popupClose();
}
this.success({
// cancel: true,
confirm: false
})
},
// (
showConfirmMessageModal(mContent, callback) {
this.showConfirmModal('消息', mContent, callback)
},
// (
showConfirmSuccessModal(mContent, callback) {
this.showConfirmModal('成功', mContent, callback)
},
// (
showConfirmFailModal(mContent, callback) {
this.showConfirmModal('失败', mContent, callback)
},
// (
showConfirmWarningModal(mContent, callback) {
this.showConfirmModal('警告', mContent, callback)
},
// (
showConfirmQuestionModal(mContent, callback) {
this.showConfirmModal('疑问', mContent, callback)
},
// (
showConfirmModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
showCancelButton: false,
success(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true)
console.log('用户点击确定')
} else {
callback(false)
console.log('用户点击取消')
}
}
}
})
},
// (+
showSelectMessageModal(mContent, callback) {
this.showSelectModal('消息', mContent, callback)
},
// (+
showSelectSuccessModal(mContent, callback) {
this.showSelectModal('成功', mContent, callback)
},
// (+
showSelectFailModal(mContent, callback) {
this.showSelectModal('失败', mContent, callback)
},
// (+
showSelectWarningModal(mContent, callback) {
this.showSelectModal('警告', mContent, callback)
},
// (+
showSelectQuestionModal(mContent, callback) {
this.showSelectModal('疑问', mContent, callback)
},
// (+
showSelectModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
success(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true)
console.log('用户点击确定')
} else {
callback(false)
console.log('用户点击取消')
}
}
}
})
},
// (+)
showConfirmCountdownMessageModal(mContent, callback) {
this.showConfirmCountdownModal('消息', mContent, callback)
},
// (+)
showConfirmCountdownSuccessModal(mContent, callback) {
this.showConfirmCountdownModal('成功', mContent, callback)
},
// (+)
showConfirmCountdownFailModal(mContent, callback) {
this.showConfirmCountdownModal('失败', mContent, callback)
},
// (+)
showConfirmCountdownWarningModal(mContent, callback) {
this.showConfirmCountdownModal('警告', mContent, callback)
},
// (+)
showConfirmCountdownQuestionModal(mContent, callback) {
this.showConfirmCountdownModal('疑问', mContent, callback)
},
// (+)
showConfirmCountdownModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
showCancelButton: false,
showConfirmCountdown: true,
success(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true)
console.log('用户点击确定')
} else {
callback(false)
console.log('用户点击取消')
}
}
}
})
},
// (++)
showSelectCountdownMessageModal(mContent, callback) {
this.showSelectCountdownModal('消息', mContent, callback)
},
// (++)
showSelectCountdownSuccessModal(mContent, callback) {
this.showSelectCountdownModal('成功', mContent, callback)
},
// (++)
showSelectCountdownFailModal(mContent, callback) {
this.showSelectCountdownModal('失败', mContent, callback)
},
// (++)
showSelectCountdownWarningModal(mContent, callback) {
this.showSelectCountdownModal('警告', mContent, callback)
},
// (++)
showSelectCountdownQuestionModal(mContent, callback) {
this.showSelectCountdownModal('疑问', mContent, callback)
},
// (++)
showSelectCountdownModal(mIconType, mContent, callback) {
this.showModal({
iconType: mIconType,
content: mContent,
showConfirmCountdown: true,
success(res) {
if (callback != undefined) {
if (res.confirm == true) {
callback(true)
console.log('用户点击确定')
} else {
callback(false)
console.log('用户点击取消')
}
}
}
})
},
//
showModal(data) {
if (data.iconType) {
this.iconType = data.iconType
switch (data.iconType) {
case '消息':
this.icon = '/static/icons/error-circle.svg'
break
case '成功':
this.icon = '/static/icons/checkmark-circle.svg'
break
case '失败':
this.icon = '/static/icons/close-circle.svg'
break
case '警告':
this.icon = '/static/icons/warning.svg'
break
case '疑问':
this.icon = '/static/icons/question-circle.svg'
break
default:
break
}
}
// image
if (data.title) {
this.title = data.title
}
if (data.content) {
console.log(data.content)
this.content = data.content
} else {
this.content = ''
}
if (data.cancelText) {
this.cancelText = data.cancelText
} else {
this.cancelText = '取消'
}
if (data.confirmText) {
this.confirmText = data.confirmText
} else {
this.confirmText = '确定'
}
if (data.showCancel === false || data.showCancel === true) {
this.showCancel = data.showCancel
} else {
this.showCancel = true
}
if (data.confirmColor) {
this.confirmColor = data.confirmColor
} else {
this.confirmColor = '#007aff'
}
if (data.cancelColor) {
this.cancelColor = data.cancelColor
} else {
this.cancelColor = '#666F83'
}
if (data.showConfirmButton === false || data.showConfirmButton === true) {
this.showConfirmButton = data.showConfirmButton
} else {
this.showConfirmButton = true
}
if (data.showConfirmCountdown === false || data.showConfirmCountdown === true) {
this.showConfirmCountdown = data.showConfirmCountdown
} else {
this.showConfirmCountdown = false
}
if (data.showCancelButton === false || data.showCancelButton === true) {
this.showCancelButton = data.showCancelButton
} else {
this.showCancelButton = true
}
if (data.success) {
this.success = data.success
} else {
this.success = () => {}
}
setTimeout((res) => {
this.show = true
}, 500)
if (this.showConfirmCountdown) {
this.startTimer()
}
},
startTimer() {
this.seconds = 3
clearInterval(this.timer)
this.timer = setInterval(() => {
this.seconds--
// console.log("", this.seconds);
if (this.seconds <= 0) {
this.timeUp()
}
}, 1000)
},
timeUp() {
// clearInterval(this.timer)
console.log('时间到')
this.confirmClose()
}
}
}
</script>
<style lang="scss" scoped>
.slot-content {
font-size: 36rpx;
display: flex; //
flex-direction: column; //
align-items: center; //
// background-image: url()
}
.icon {
width: 70rpx;
height: 70rpx;
opacity: 1; //
margin-top: 16px;
}
.title {
font-size: 35rpx;
}
.content {
margin-top: 16px;
margin-bottom: 16px;
margin-left: 8px;
margin-right: 8px;
font-size: 32rpx;
text-align: center;
word-wrap: break-word;
word-break: break-all;
white-space: pre-line;
}
.cance_button {
width: 100%;
margin-top: 10px;
margin-bottom: 10px;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
.confirm_button {
width: 100%;
margin-top: 10px;
margin-bottom: 10px;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
.confirm_text {
// color: $uni-color-primary;
}
.def_text {
color: $uni-color-primary;
}
.slot-content {
font-size: 36rpx;
display: flex; //
flex-direction: column; //
align-items: center; //
// background-image: url()
}
.icon {
width: 70rpx;
height: 70rpx;
opacity: 1; //
margin-top: 16px;
}
.title {
font-size: 35rpx;
}
.content {
margin-top: 16px;
margin-bottom: 16px;
margin-left: 8px;
margin-right: 8px;
font-size: 32rpx;
text-align: center;
word-wrap: break-word;
word-break: break-all;
white-space: pre-line;
}
.cance_button {
width: 100%;
margin-top: 10px;
margin-bottom: 10px;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
.confirm_button {
width: 100%;
margin-top: 10px;
margin-bottom: 10px;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
.confirm_text {
// color: $uni-color-primary;
}
.def_text {
color: $uni-color-primary;
}
</style>

13
src/env.d.ts

@ -0,0 +1,13 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
interface ImportMetaEnv {
VITE_TITLE: string
VITE_BASE_URL: string
}

95
src/hybrid/html/point.html

@ -0,0 +1,95 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title></title>
<script src="../../api/img-to-base64.js"></script>
<script type="text/javascript">
document.addEventListener('plusready', function() {
//console.log("所有plus api都应该在此事件发生后调用,否则会出现plus is undefined。")
});
</script>
<style>
.box {
font-size: 14px;
display: flex;
margin-top: 60px;
}
.left {
border-top: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
flex: 1;
}
.left-item {
display: flex;
}
.bold-font {
font-weight: bold;
}
.font-30 {
font-size: 30px;
}
.font-20 {
font-size: 20px;
}
.bold-label {
font-weight: bold;
font-size: 15px;
}
.label {
border-bottom: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
width: 60px;
padding: 0px 5px;
height: 49px;
line-height: 49px;
}
.value {
border-bottom: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
padding: 0px 5px;
height: 49px;
flex: 1;
width: 0px;
display: flex;
align-items: center;
word-break: break-all;
justify-content: center;
}
.right {
width: 300px;
}
.image {
width: calc(100% - 1px);
height: 149px;
border-bottom: 1px solid #b1b1b1;
border-top: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
.image img {
width: 147px;
height: 147px;
border: 1px solid #b1b1b1;
/* width: calc(100% - 4px);
height: calc(100% - 4px); */
margin: 1px;
}
</style>
</head>
<body>
mainBody
</body>
</html>

67
src/hybrid/html/pointPutawayJob.html

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title></title>
<script src="../../api/img-to-base64.js"></script>
<script type="text/javascript">
document.addEventListener('plusready', function() {
//console.log("所有plus api都应该在此事件发生后调用,否则会出现plus is undefined。")
});
</script>
<style>
.box {
font-size: 13px;
/* padding: 10px; */
/* border: 1px solid #dedede; */
}
.left {
flex: 1;
border-bottom: 1px solid #b1b1b1;
}
.left-item {
display: flex;
border-top: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
.left-item div{
padding: 10px 10px;
font-size: 16px;
}
.left-item .label{
width: 100px;
padding: 10px 10px;
border-right: 1px solid #b1b1b1;
}
.relative {
margin-bottom: 10px;
position: relative;
}
.q {
position: absolute;
font-size: 15rem;
color: rgba(0, 0, 0, 0.1);
width: calc(100% - 100px);
right: 0px;
top: 0px;
text-align: center;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
mainBody
</body>
</html>

67
src/hybrid/html/purchaseReceiptJob.html

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title></title>
<script src="../../api/img-to-base64.js"></script>
<script type="text/javascript">
document.addEventListener('plusready', function() {
//console.log("所有plus api都应该在此事件发生后调用,否则会出现plus is undefined。")
});
</script>
<style>
.box {
font-size: 13px;
/* padding: 10px; */
/* border: 1px solid #dedede; */
}
.left {
flex: 1;
border-bottom: 1px solid #b1b1b1;
}
.left-item {
display: flex;
border-top: 1px solid #b1b1b1;
border-left: 1px solid #b1b1b1;
border-right: 1px solid #b1b1b1;
}
.left-item div{
padding: 10px 10px;
font-size: 16px;
}
.left-item .label{
width: 100px;
padding: 10px 10px;
border-right: 1px solid #b1b1b1;
}
.relative {
margin-bottom: 10px;
position: relative;
}
.q {
position: absolute;
font-size: 15rem;
color: rgba(0, 0, 0, 0.1);
width: calc(100% - 100px);
right: 0px;
top: 0px;
text-align: center;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
mainBody
</body>
</html>

74
src/main.js

@ -1,74 +0,0 @@
import App from './App'
import store from './store'
import './router/my_router.js'; //引入拦截
import VueClipboard from 'vue-clipboard2' //复制粘贴
import uView from './uni_modules/vk-uview-ui';// 引入 uView UI
import comMessage from './mycomponents/common/comMessage.vue'
// #ifndef VUE3
import Vue from 'vue'
console.log("Vuew2222");
Vue.config.productionTip = false
Vue.prototype.$store = store
Vue.prototype.$adpid = "1111111111"
Vue.prototype.$backgroundAudioData = {
playing: false,
playTime: 0,
formatedPlayTime: '00:00:00'
}
App.mpType = 'app'
const app = new Vue({
store,
...App
})
app.$mount()
// #endif
import {
createSSRApp
} from "vue";
export function createApp() {
const app = createSSRApp(App);
app.use(store)
app.use(VueClipboard)
app.use(uView)
app.component('comMessage', comMessage)
console.log("网络22请求")
// startApp(app);
return {
app,
};
}
export function startApp(app) {
uni.request({
url: `./static/config.json?t=${new Date().getTime()}`,
method: 'get',
data: {},
success: (res) => {
if (res.data != "") {
//在配置中读url,company等信息
// app.config.globalProperties.$baseInfo = res.data.baseInfo;
// getApp().globalData.dev_url = res.data.baseInfo.dev.value;
// getApp().globalData.request_url = res.data.baseInfo.request_url.value;
// getApp().globalData.tenantId = res.data.baseInfo.tenantId.value;
// app.config.globalProperties.$recepit_configList = res.data.recepit_configList;
// getApp().globalData.recepit_configList = res.data.recepit_configList;
// getApp().globalData.feed_configList = res.data.feed_configList;
// getApp().globalData.isDevelopment = res.data.baseInfo.isDevelopment.value
// Vue.prototype.$dev_url = res.data.baseInfo.dev.value;
// console.log("网络",res.data.baseInfo.request_url.value)
// console.log("开发环境12",res.data.baseInfo.isDevelopment.value)
// uni.setStorageSync("request_url",res.data.baseInfo.request_url.value)
// uni.setStorageSync("isDevelopment",res.data.baseInfo.isDevelopment.value)
}
},
fail: (error) => {
}
})
return {
startApp
};
}

48
src/main.ts

@ -0,0 +1,48 @@
import { createSSRApp } from 'vue'
import * as Pinia from 'pinia'
// @ts-ignore
import uView from 'vk-uview-ui'
import App from './App.vue'
import comMessage from '@/mycomponents/common/comMessage.vue'
import noclick from './common/noclick.js'
import tab from './plugins/tab'
import modal from './plugins/modal'
import time from './plugins/time'
import storage from './plugins/storage'
// unocss
import 'uno.css'
import { accessTimeInAnHour, getNowFormatDate } from "./utils/dateTime";
export function createApp() {
const app = createSSRApp(App)
app.use(Pinia.createPinia())
app.use(uView)
// 解决onLaunch和onLoad异步问题
app.config.globalProperties.$onLaunched = new Promise(resolve => {
app.config.globalProperties.$isResolve = resolve
})
// 页签操作
app.config.globalProperties.$tab = tab
// 模态框对象
app.config.globalProperties.$modal = modal
// 时间对象
app.config.globalProperties.$time = time
// 节流
app.config.globalProperties.$throttle = noclick.throttle;
// 缓存
app.config.globalProperties.$storage = storage
app.component('ComMessage', comMessage)
return {
app,
// uni-app 官方文档示例 https://zh.uniapp.dcloud.io/tutorial/vue3-pinia.html#%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86-pinia
Pinia // 此处必须将 Pinia 返回
}
}

64
src/manifest.json

@ -1,18 +1,16 @@
{
"name" : "wms",
"appid" : "__UNI__43932FE",
"name" : "富维汽车镜",
"package" : "uni.UNI43932FE",
"appid" : "__UNI__DA78BC9",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : 1,
"versionName" : "1.0.44",
"versionCode" : 44,
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"compatible" : {
"ignoreVersion" : true //trueHBuilderX1.9.0
},
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
@ -20,11 +18,7 @@
"delay" : 0
},
/* */
"modules" : {
"Bluetooth" : {},
"Barcode" : {},
"Camera" : {}
},
"modules" : {},
/* */
"distribute" : {
/* android */
@ -45,9 +39,7 @@
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
"minSdkVersion" : 23
]
},
/* ios */
"ios" : {
@ -56,6 +48,38 @@
/* SDK */
"sdkConfigs" : {
"ad" : {}
},
"nativePlugins" : {
"TestModule" : {
"__plugin_info__" : {
"name" : "TestModule",
"description" : "打印",
"platforms" : "Android",
"url" : "",
"android_package_name" : "",
"ios_bundle_id" : "",
"isCloud" : false,
"bought" : -1,
"pid" : "",
"parameters" : {}
}
}
}
},
"nativePlugins" : {
"TestModule" : {
"__plugin_info__" : {
"name" : "TestModule",
"description" : "打印",
"platforms" : "Android",
"url" : "",
"android_package_name" : "",
"ios_bundle_id" : "",
"isCloud" : false,
"bought" : -1,
"pid" : "",
"parameters" : {}
}
}
}
},
@ -63,7 +87,7 @@
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"appid" : "wx6176535b0b0153f0",
"setting" : {
"urlCheck" : false
},
@ -81,5 +105,11 @@
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
"vueVersion" : "3",
"h5" : {
"template" : "index.html",
"devServer" : {
"port" : 9020
}
}
}

239
src/mycomponents/balance/balance.vue

@ -1,147 +1,110 @@
<template>
<view :class="dataContent.scaned?'scan_view':''" style="background-color: #ffffff;margin-bottom: 1px; ">
<view class="uni-flex uni-row space-between" style="align-items: center">
<view>
<pack v-if="isShowPack && dataContent.packingNumber" :packingCode="dataContent.packingNumber"></pack>
<batch v-if="isShowBatch && dataContent.batch" :batch="dataContent.batch"></batch>
<location title="来源库位" v-if="isShowFromLocation" :locationCode="dataContent.locationCode"></location>
<to-location title="目标库位" v-if="isShowToLocation" :locationCode="dataContent.toLocationCode">
</to-location>
</view>
<view>
<!-- <qty v-if="dataContent.record==null ||dataContent.record==undefined " :dataContent="dataContent"
<view :class="dataContent.scaned ? 'scan_view' : ''">
<view class="uni-flex uni-row space-between" style="align-items: center; padding: 20rpx">
<view>
<pack v-if="isShowParentPack && dataContent.parentNumber" title="父包装" :packingCode="dataContent.parentNumber"></pack>
<pack v-if="isShowPack && dataContent.packingNumber" :isShowPackingNumberProps="isShowPackingNumberProps" :packingCode="dataContent.packingNumber"></pack>
<batch v-if="isShowBatch && dataContent.batch" :batch="dataContent.batch"></batch>
<location title="来源库位" v-if="isShowFromLocation" :locationCode="dataContent.locationCode"></location>
<to-location title="目标库位" v-if="isShowToLocation" :locationCode="dataContent.toLocationCode"> </to-location>
</view>
<view class="uni-flex" style="flex-direction: column">
<view class="uni-flex uni-row u-align-start">
<!-- <qty v-if="dataContent.record==null ||dataContent.record==undefined " :dataContent="dataContent"
:isShowStdPack="isShowStdPack" :isShowStatus="isShowStatus"></qty> -->
<qty v-if="dataContent.handleQty==0 || dataContent.handleQty==undefined" :dataContent="dataContent"
:isShowStdPack="isShowStdPack" :isShowStatus="isShowStatus"></qty>
<compare-qty v-else :dataContent="dataContent" :recommendQty="Number( dataContent.qty)"
:handleQty="Number (dataContent.handleQty)" :isShowStdPack="isShowStdPack">
</compare-qty>
<view class="uni-flex uni-row" style="vertical-align:center" v-if="isDevlement()">
<text style="font-size: 30rpx;color: #2979ff; " @click="copy">复制采购</text>
<text style="font-size: 30rpx;color: #2979ff;" @click="copyPro">|制品</text>
</view>
</view>
</view>
<!-- <u-line></u-line> -->
</view>
</template>
<qty v-if="dataContent.handleQty == 0 || dataContent.handleQty == undefined" :dataContent="dataContent" :isShowStdPack="isShowStdPack" :isShowStatus="isShowStatus"></qty>
<compare-qty v-else :dataContent="dataContent" :recommendQty="Number(dataContent.qty)" :handleQty="Number(dataContent.handleQty)" :isShowStdPack="isShowStdPack" :isShowStatus="isShowStatus"> </compare-qty>
<script>
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import toLocation from '@/mycomponents/balance/toLocation.vue'
import batch from '@/mycomponents/balance/batch.vue'
import qty from '@/mycomponents/qty/qty.vue'
import recommendQty from '@/mycomponents/qty/recommendQty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
import config from '@/static/config.js'
<!-- <view class="uni-flex uni-row" style="vertical-align: center" v-if="isDevlement()">
<image style="width: 26rpx; height: 26rpx; margin-top: 40rpx" src="/static/icons/icon_copy.svg" alt="" @click="copy" />
</view> -->
</view>
<!-- <view class="" v-if="dataContent.inventoryStatus">
<move-status :fromInventoryStatus="dataContent.inventoryStatus"> </move-status>
</view> -->
</view>
</view>
<!-- <u-line></u-line> -->
</view>
</template>
export default {
components: {
pack,
location,
toLocation,
batch,
qty,
recommendQty,
compareQty,
},
<script setup lang="ts">
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import toLocation from '@/mycomponents/balance/toLocation.vue'
import batch from '@/mycomponents/balance/batch.vue'
import qty from '@/mycomponents/qty/qty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
import config from '@/static/config.js'
import moveStatus from '@/mycomponents/balance/moveStatus.vue'
data() {
return {
const props = defineProps({
dataContent: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowFromLocation: {
type: Boolean,
default: true
},
isShowStdPack: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
},
isShowToLocation: {
type: Boolean,
default: false
},
isShowParentPack: {
type: Boolean,
default: true
},
isShowPackingNumberProps: {
type: Boolean,
default: false
}
})
const copy = () => {
// HPQ;V1.0;ICE115F11161AG;PP20230427000026;B20230427002;Q100
const content = `HPQ;V1.0;I${props.dataContent.itemCode};P${props.dataContent.packingNumber};B${props.dataContent.batch};Q${props.dataContent.qty}`
}
},
props: {
dataContent: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowFromLocation: {
type: Boolean,
default: true
},
isShowStdPack: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
},
isShowToLocation: {
type: Boolean,
default: false
},
},
watch: {
uni.setClipboardData({
data: content,
success: () => {
uni.showToast({
title: '复制采购标签成功'
})
}
})
}
const copyPro = () => {
// HPQ;V1.0;ICE115F11161AG;PP20230427000026;B20230427002;Q100
const content = `HMQ;V1.0;I${props.dataContent.itemCode};P${props.dataContent.packingNumber};B${props.dataContent.batch};Q${props.dataContent.qty}`
},
methods: {
copy() {
// HPQ;V1.0;ICE115F11161AG;PP20230427000026;B20230427002;Q100
var content = "HPQ;V1.0;I" + this.dataContent.itemCode + ";P" + this.dataContent.packingNumber + ";B" +
this.dataContent.batch + ";Q" + this.dataContent.qty
// #ifdef H5
this.$copyText(content).then(
res => {
uni.showToast({
title: '复制成功',
icon: 'none'
})
}
)
// #endif
// #ifndef H5
uni.setClipboardData({
data: content,
success: () => {
uni.showToast({
title: '复制采购标签成功'
})
}
})
// #endif
},
copyPro() {
// HPQ;V1.0;ICE115F11161AG;PP20230427000026;B20230427002;Q100
var content = "HMQ;V1.0;I" + this.dataContent.itemCode + ";P" + this.dataContent.packingNumber + ";B" +
this.dataContent.batch + ";Q" + this.dataContent.qty
// #ifdef H5
this.$copyText(content).then(
res => {
uni.showToast({
title: '复制成功',
icon: 'none'
})
}
)
// #endif
// #ifndef H5
uni.setClipboardData({
data: content,
success: () => {
uni.showToast({
title: '复制制品标签成功'
})
}
})
// #endif
},
isDevlement() {
return config.isDevelopment;
}
}
}
uni.setClipboardData({
data: content,
success: () => {
uni.showToast({
title: '复制制品标签成功'
})
}
})
}
const isDevlement = () => {
return config.isDevelopment
}
</script>
<style>
</style>
<style></style>

2
src/mycomponents/balance/balanceDetailPopup.vue

@ -4,7 +4,7 @@
<!-- <com-item :dataContent="dataContent.package"></com-item>
<u-line></u-line>
<view class='split_line'></view>
<scroll-view style="height:320px ">
<view v-for="(item, index) in dataList" style="width: 100%;">
<view class="item">

2
src/mycomponents/balance/balanceMove.vue

@ -18,7 +18,7 @@
</view>
</view>
<u-line></u-line>
<view class='split_line'></view>
</view>
</template>

85
src/mycomponents/balance/balanceSelect.vue

@ -1,54 +1,49 @@
<!--发料任务卡片-->
<template>
<!-- <page-meta root-font-size="18px"></page-meta> -->
<uni-popup ref="popupItems" type="center">
<scroll-view scroll-y="true" style="background-color: #EEEEEE;height: 90vh;">
<item :dataContent="balanceItems[0]"></item>
<view class="popinpop count_shadow" style="width: 90vw;margin: 20rpx 20rpx 30rpx 20rpx;"
v-for="(item, index) in balanceItems" :key="item.id" @click="callback(item)">
<balance :dataContent="item"></balance>
</view>
</scroll-view>
</uni-popup>
<!-- <page-meta root-font-size="18px"></page-meta> -->
<u-popup v-model="show" mode="center">
<scroll-view scroll-y="true" style="background-color: #eeeeee; height: 90vh">
<item style="margin: 10rpx" :dataContent="balanceItems[0]"></item>
<view class="popinpop count_shadow" style="width: 90vw; margin: 20rpx 20rpx 30rpx 20rpx" v-for="(item, index) in balanceItems" :key="item.id" @click="callback(item)">
<balance :dataContent="item" :isShowStatus="false"></balance>
</view>
<view class="page-footer">
<view class="uni-flex space-between" style="width: 100%">
<!-- <view class=" uni-flex uni-row"> -->
<button class="btn_single_reject" hover-class="btn_commit_after" @click="close">关闭</button>
<!-- </view> -->
</view>
</view>
</scroll-view>
</u-popup>
</template>
<script>
import item from '@/mycomponents/item/item.vue'
import balance from '@/mycomponents/balance/balance.vue'
<script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'
import item from '@/mycomponents/item/item.vue'
import balance from '@/mycomponents/balance/balance.vue'
export default {
name: "balanceSelect",
emits: ['onSelectItem'],
components: {
item,
balance
},
data() {
return {
balanceItems: [],
};
},
//
props: {
// datacontent: {
// type: Object,
// value: null
// }
},
methods: {
openPopup(items) {
this.balanceItems = items;
this.$refs['popupItems'].open("center");
},
const balanceItems = ref([])
const show = ref(false)
const openPopup = (items) => {
if (Array.isArray(items)) {
balanceItems.value = items
} else {
balanceItems.value = [items]
}
show.value = true
}
callback(item) {
this.$emit("onSelectItem", item);
this.$refs['popupItems'].close();
},
const callback = (item) => {
emit('onSelectItem', item)
show.value = false
}
}
}
const close = () => {
show.value = false
}
const emit = defineEmits(['onSelectItem'])
defineExpose({ openPopup })
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>

29
src/mycomponents/balance/batch.vue

@ -1,24 +1,19 @@
<template>
<view class="card_view ">
<text class="card_batch card_content ">批次</text>
<text class="card_content ">{{batch}}</text>
<view class="card_view">
<text class="card_batch">批次</text>
<text class="card_content">{{batch}}</text>
</view>
</template>
<script>
export default {
data() {
return {}
},
props: {
batch: {
type: String,
default: ""
}
},
}
<script setup lang="ts">
const props = defineProps({
batch: {
type: String,
default: ""
}
})
</script>
<style>
<style scoped>
</style>

51
src/mycomponents/balance/bussinessType.vue

@ -1,37 +1,26 @@
<template>
<view class="business_view">
<text class="card_business">{{businessTypeDesc(bussinessType)}}</text>
<text class="card_business_content">{{number}}</text>
</view>
<view class="card_view">
<text class="card_business">业务类型</text>
<text class="card_business_content">{{ businessTypeDesc(bussinessType) }}</text>
</view>
</template>
<script>
import {
getBusinessTypeDesc
} from '@/common/directory.js';
export default {
data() {
return {}
},
props: {
bussinessType: {
type: String,
default: ""
},
number: {
type: String,
default: ""
}
},
methods:{
businessTypeDesc(type){
return getBusinessTypeDesc(type)
}
}
<script setup lang="ts">
import { getBusinessTypeName } from '@/common/directory.js'
}
const props = defineProps({
bussinessType: {
type: String,
default: ''
},
number: {
type: String,
default: ''
}
})
const businessTypeDesc = (type) => {
return getBusinessTypeName(type)
}
</script>
<style>
</style>
<style></style>

125
src/mycomponents/balance/handleBalance.vue

@ -1,80 +1,59 @@
<template>
<view :class="detail.scaned?'scan_view':''" style="background-color: #ffffff;">
<view class="space_between center" >
<view style="word-break: break-all;width: 60%;">
<pack v-if="isShowPack" :packingCode="detail.packingNumber"></pack>
<batch v-if="isShowBatch" :batch="detail.batch"></batch>
<location v-if="isShowLocation" :locationCode="detail.fromLocationCode"></location>
</view>
<view style="word-break: break-all;">
<recommend-qty v-if="detail.record==null || detail.record==undefined" :dataContent="detail"
:isShowStdPack="false"></recommend-qty>
<compare-qty v-else :dataContent="detail" :recommendQty="detail.qty" :handleQty="detail.record.qty"
:isShowStdPack="false">
</compare-qty>
</view>
</view>
</view>
<view :class="detail.scaned ? 'scan_view' : ''" style="background-color: #ffffff">
<view class="space_between center">
<view style="word-break: break-all; width: 60%">
<pack title="外包装" v-if="detail.parentPackingNumber" :packingCode="detail.parentPackingNumber"></pack>
<pack v-if="isShowPack" :packingCode="detail.packingNumber"></pack>
<batch v-if="isShowBatch" :batch="detail.batch"></batch>
<location v-if="isShowLocation" :locationCode="detail.fromLocationCode"></location>
</view>
<view style="word-break: break-all">
<recommend-qty v-if="detail.record == null || detail.record == undefined" :dataContent="detail" :isShowStatus="isShowStatus" :isShowStdPack="true"></recommend-qty>
<compare-qty v-else :dataContent="detail" :recommendQty="detail.qty" :handleQty="detail.record.qty" :isShowStatus="isShowStatus" :isShowStdPack="true"> </compare-qty>
</view>
</view>
</view>
</template>
<script>
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import batch from '@/mycomponents/balance/batch.vue'
import recommendQty from '@/mycomponents/qty/recommendQty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
export default {
components: {
pack,
location,
batch,
recommendQty,
compareQty
},
data() {
return {
}
},
props: {
detail: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
},
watch: {
},
methods: {
}
}
<script setup lang="ts">
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import batch from '@/mycomponents/balance/batch.vue'
import recommendQty from '@/mycomponents/qty/recommendQty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
const props = defineProps({
detail: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
}
})
</script>
<style>
.recommend {
position: absolute;
left: 25px;
top: 70px;
width: 10px;
height: 30px;
opacity: 1;
}
.recommend {
position: absolute;
left: 25px;
top: 70px;
width: 10px;
height: 30px;
opacity: 1;
}
</style>

64
src/mycomponents/balance/handleBalanceBatch.vue

@ -0,0 +1,64 @@
<template>
<view :class="detail.scaned?'scan_view':''" style="background-color: #ffffff;">
<view class="space_between center">
<view style="word-break: break-all;width: 60%;">
<pack title='外包装' v-if="detail.parentPackingNumber"
:packingCode="detail.parentPackingNumber"></pack>
<pack v-if="isShowPack" :packingCode="detail.packingNumber"></pack>
<batch v-if="isShowBatch" :batch="detail.batch"></batch>
<location v-if="isShowLocation" :locationCode="detail.fromLocationCode"></location>
</view>
<view style="word-break: break-all;">
<recommend-qty v-if="detail.record==null || detail.record==undefined" :dataContent="detail"
:isShowStatus='isShowStatus' :isShowStdPack="true" :isShowCount='false'></recommend-qty>
<compare-qty v-else :dataContent="detail" :recommendQty="detail.qty" :handleQty="detail.record.qty"
:isShowStatus='isShowStatus' :isShowStdPack="true">
</compare-qty>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import batch from '@/mycomponents/balance/batch.vue'
import recommendQty from '@/mycomponents/qty/recommendQty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
const props = defineProps({
detail: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
},
})
</script>
<style>
.recommend {
position: absolute;
left: 25px;
top: 70px;
width: 10px;
height: 30px;
opacity: 1;
}
</style>

27
src/mycomponents/balance/level.vue

@ -0,0 +1,27 @@
<template>
<view class="card_view">
<text class="card_level">{{ title }}</text>
<text class="card_big_content" style="font-size: 40rpx">{{ getPriorityName1() }}</text>
</view>
</template>
<script setup lang="ts">
import { getPriorityName } from '@/common/directory.js'
const props = defineProps({
priority: {
type: Number,
default: 2
},
title: {
type: String,
default: '优先级'
}
})
const getPriorityName1 = () => {
return getPriorityName(props.priority)
}
</script>
<style></style>

21
src/mycomponents/balance/light.vue

@ -0,0 +1,21 @@
<template>
<view class="card_view">
<text class="card_light">{{ title }}</text>
<text class="card_content">{{ lightCode }}</text>
</view>
</template>
<script setup lang="ts">
const props = defineProps({
lightCode: {
type: String,
default: ''
},
title: {
type: String,
default: '灯码'
}
})
</script>
<style></style>

42
src/mycomponents/balance/location.vue

@ -1,31 +1,23 @@
<template>
<view class="card_view ">
<text class="card_location card_content ">{{title}}</text>
<text class="card_content ">{{locationCode}}</text>
</view>
<view class="card_view">
<text class="card_location">{{ title }}</text>
<text class="card_big_content" style="font-size: 40rpx">{{ locationCode }}</text>
</view>
</template>
<script>
export default {
components: {
},
data() {
return {}
},
props: {
locationCode: {
type: String,
default: ''
},
title: {
type: String,
default: '库位'
},
},
}
<script setup lang="ts">
const props = defineProps({
locationCode: {
type: String,
default: ''
},
title: {
type: String,
default: '库位'
}
})
</script>
<style>
<style scoped>
</style>

55
src/mycomponents/balance/pack.vue

@ -1,34 +1,33 @@
<template>
<view class="card_view">
<text class="card_packing_code card_content ">箱码</text>
<text class="card_content ">{{packingCode}}</text>
</view>
<view class="card_view" v-if="ShowPackingNumber">
<text class="card_packing_code">{{ title }}</text>
<text class="card_content">{{ packingCode }}</text>
</view>
</template>
<script>
export default {
components: {
},
data() {
return {
}
},
props: {
packingCode: {
type: String,
default: ''
},
},
watch: {
},
methods: {
}
}
<script setup lang="ts">
import {getSwitchInfoByCode} from '@/common/basic.js';
import {onMounted} from "vue";
import {ref} from "vue";
const props = defineProps({
packingCode: {
type: String,
default: ''
},
title: {
type: String,
default: '包装'
}
})
const ShowPackingNumber = ref(true)
onMounted(()=>{
ShowPackingNumber.value = getSwitchInfoByCode('ShowPackingNumber')
})
</script>
<style>
<style lang="scss" scoped>
.card_packing_code {
padding: 0;
}
</style>

87
src/mycomponents/balance/productionLabel.vue

@ -1,59 +1,40 @@
<template>
<view :class="dataContent.scaned?'scan_view':''">
<balance :dataContent="dataContent" :isShowStdPack="false" :isShowPack="isShowPack"
:isShowFromLocation="isShowLocation"></balance>
<production-info :dataContent="packageContent"></production-info>
</view>
<view :class="dataContent.scaned ? 'scan_view' : ''">
<balance :dataContent="dataContent" :isShowStdPack="false" :isShowPack="isShowPack" :isShowFromLocation="isShowLocation"></balance>
<production-info :dataContent="packageContent"></production-info>
</view>
</template>
<script>
import balance from '@/mycomponents/balance/balance.vue'
import productionInfo from '@/mycomponents/production/productionInfo.vue'
export default {
components: {
balance,
productionInfo
},
data() {
return {
<script setup lang="ts">
import balance from '@/mycomponents/balance/balance.vue'
import productionInfo from '@/mycomponents/production/productionInfo.vue'
}
},
props: {
dataContent: {
type: Object,
default: {}
},
packageContent: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
isShowStdPack: {
type: Boolean,
default: true
}
},
watch: {
},
methods: {
}
}
const props = defineProps({
dataContent: {
type: Object,
default: {}
},
packageContent: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
isShowStdPack: {
type: Boolean,
default: true
}
})
</script>
<style>
</style>
<style></style>

126
src/mycomponents/balance/recommendBalance.vue

@ -1,84 +1,56 @@
<template>
<view :class="detail.scaned?'scan_view':''" style="background-color: #fff;">
<view class="uni-flex uni-row space-between center ">
<view class="uni-flex uni-row " style="width: 60%;margin-left: 30rpx;" >
<view style=" width: 25rpx;color: #32C1E8;">
推荐
</view>
<view style="word-break: break-all">
<pack v-if="isShowPack" :packingCode="detail.packingNumber"></pack>
<batch v-if="isShowBatch" :batch="detail.batch"></batch>
<location v-if="isShowLocation" :locationCode="detail.fromLocationCode"></location>
</view>
</view>
<view style="word-break: break-all">
<recommend-qty v-if="detail.Records==null || detail.Records.length==0" :dataContent="detail"
:isShowStdPack="false" :isShowStatus="false"></recommend-qty>
<compare-qty v-else :dataContent="detail" :recommendQty="Number( detail.qty)"
:handleQty="Number(detail.handleQty)" :isShowStdPack="false" :isShowStatus="false">
</compare-qty>
</view>
</view>
</view>
<view :class="detail.scaned ? 'scan_view' : ''" style="background-color: #fff">
<view class="uni-flex uni-row space-between center">
<view class="uni-flex uni-row" style="width: 60%">
<view style="width: 20rpx; color: #1677ff; margin-right: 20rpx; font-size: 24rpx"> 推荐 </view>
<view style="word-break: break-all">
<pack v-if="isShowPack" :packingCode="detail.packingNumber"></pack>
<batch v-if="isShowBatch" :batch="detail.batch"></batch>
<location v-if="isShowLocation" :locationCode="detail.fromLocationCode"></location>
</view>
</view>
<view style="word-break: break-all">
<recommend-qty v-if="detail.Records == null || detail.Records.length == 0" :dataContent="detail" :isShowStdPack="false" :isShowStatus="false"></recommend-qty>
<compare-qty v-else :dataContent="detail" :recommendQty="Number(detail.qty)" :handleQty="Number(detail.handleQty)" :isShowStdPack="false" :isShowStatus="false"> </compare-qty>
</view>
</view>
</view>
</template>
<script>
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import batch from '@/mycomponents/balance/batch.vue'
import recommendQty from '@/mycomponents/qty/recommendQty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
export default {
components: {
pack,
location,
batch,
recommendQty,
compareQty
},
data() {
return {
}
},
props: {
detail: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
},
watch: {
},
methods: {
}
}
<script setup lang="ts">
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import batch from '@/mycomponents/balance/batch.vue'
import recommendQty from '@/mycomponents/qty/recommendQty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
const props = defineProps({
detail: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
}
})
</script>
<style>
.recommend {
position: absolute;
left: 25px;
top: 70px;
width: 10px;
height: 30px;
opacity: 1;
}
.recommend {
position: absolute;
left: 25px;
top: 70px;
width: 10px;
height: 30px;
opacity: 1;
}
</style>

55
src/mycomponents/balance/recommendBalanceBatch.vue

@ -0,0 +1,55 @@
<template>
<view>
<view class="uni-flex uni-row space-between center ">
<view class="uni-flex uni-row " style="width: 60%;" >
<view style=" width: 25rpx;color: #32C1E8;">
推荐
</view>
<view style="word-break: break-all">
<pack v-if="isShowPack&&detail.packingNumber" :packingCode="detail.packingNumber"></pack>
<batch v-if="isShowBatch&&detail.batch" :batch="detail.batch"></batch>
<location v-if="isShowLocation" :locationCode="detail.fromLocationCode"></location>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import pack from '@/mycomponents/balance/pack.vue'
import location from '@/mycomponents/balance/location.vue'
import batch from '@/mycomponents/balance/batch.vue'
import recommendQty from '@/mycomponents/qty/recommendQty.vue'
import compareQty from '@/mycomponents/qty/compareQty.vue'
const props = defineProps({
detail: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
})
</script>
<style>
.recommend {
position: absolute;
left: 25px;
top: 70px;
width: 10px;
height: 30px;
opacity: 1;
}
</style>

42
src/mycomponents/balance/toLocation.vue

@ -1,31 +1,19 @@
<template>
<view class="card_view ">
<text class="card_to_location card_content ">{{title}}</text>
<text class="card_content ">{{locationCode}}</text>
</view>
<view class="card_view">
<text class="card_to_location">{{ title }}</text>
<text class="card_big_content">{{ locationCode }}</text>
</view>
</template>
<script>
export default {
components: {
},
data() {
return {}
},
props: {
locationCode: {
type: String,
default: ''
},
title: {
type: String,
default: '库位'
},
},
}
<script setup lang="ts">
const props = defineProps({
locationCode: {
type: String
},
title: {
type: String,
default: '库位'
}
})
</script>
<style>
</style>
<style></style>

0
src/mycomponents/Batch/Batch.vue → src/mycomponents/batch/batch.vue

40
src/mycomponents/button/comCheckAll.vue

@ -0,0 +1,40 @@
<template>
<view class="flex uni-row">
<view class="" >
<u-checkbox size="50" v-model="checkAll" @change="checkAllItems" >
</u-checkbox>
</view>
<view>
<text style="margin-left: 10rpx; font-size: 35rpx;font-weight: bold;">全选({{checkCount}}/{{allCount}})</text>
</view>
</view>
</template>
<script lang="ts" setup>
import {nextTick, ref} from 'vue'
const props = defineProps({
checkCount: {
type: Number,
default: 0
},
allCount: {
type: Number,
default: 0
},
})
const emit = defineEmits(['checkAllItems'])
const checkAll = ref(false)
const checkAllItems = ()=>{
checkAll.value = !checkAll.value
emit('checkAllItems', checkAll.value)
}
const changeCheckAllState = ()=>{
nextTick(()=>{
checkAll.value = props.checkCount == props.allCount
})
}
</script>
<style>
</style>

74
src/mycomponents/button/requestButton.vue

@ -4,53 +4,43 @@
<image src="@/static/icons_ui/icon_add.svg"></image>
<view>{{btnName}}</view>
</view>
<!-- <movable-area>
<movable-view class="max" direction="all">扫描</movable-view>
</movable-area> -->
</view>
</template>
<script>
export default {
data() {
return {
x: 0,
y: 0,
old: {
x: 0,
y: 0
}
}
},
props: {
btnName: {
type: String,
default: '创建'
},
},
created() {
},
methods: {
goScan(content) {
this.$emit("goScan", '');
},
tap: function(e) {
this.x = this.old.x
this.y = this.old.y
this.$nextTick(function() {
this.x = 30
this.y = 30
})
},
onChange: function(e) {
this.old.x = e.detail.x
this.old.y = e.detail.y
}
<script setup lang="ts">
import {
ref,
nextTick
} from 'vue'
const props = defineProps({
btnName: {
type: String,
default: '创建'
},
})
const x = ref(0)
const y = ref(0)
const old= ref({
x: 0,
y: 0
})
const goScan=(content)=> {
emit("goScan", '');
}
const tap=(e) =>{
x.value = old.value.x
y.value = old.value.y
nextTick(function() {
x.value = 30
y.value = 30
})
}
const onChange=(e) =>{
old.value.x = e.detail.x
old.value.y = e.detail.y
}
//
const emit = defineEmits(['goScan'])
</script>
<style>

46
src/mycomponents/common/comBlankView.vue

@ -1,31 +1,25 @@
<template>
<view class="default_goscan">
<image class="img_goscan" src="@/static/icons_ui/default_blank.png"></image>
<button @click="goScan">
<image src="@/static/icons_ui/icon_add.svg"></image>
去扫描
</button>
</view>
<view class="default_goscan">
<image class="img_goscan" src="@/static/icons_ui/default_blank.png"></image>
<button @click="goScan">
<image src="@/static/icons_ui/icon_add.svg"></image>
{{ title }}
</button>
</view>
</template>
<script>
export default {
data() {
return {
}
},
created() {
},
methods: {
goScan(content) {
this.$emit("goScan", '');
}
}
}
<script setup lang="ts">
const props = defineProps({
title: {
type: String,
default: '去扫描'
}
})
const goScan = (content) => {
emit('goScan', '')
}
//
const emit = defineEmits(['goScan'])
</script>
<style>
</style>
<style></style>

29
src/mycomponents/common/comEmptyView.vue

@ -4,36 +4,11 @@
<view class="">
<image class="default_nodata" src="@/static/icons_ui/default_data.png"></image>
</view>
<!--
<view class="" style="display: flex;flex-direction: column;
align-items: center;">
<view class="" >
<image class="nodata" src="/static/icons_ui/default_data.png"></image>
</view>
<view style="font-size: 40rpx;color: #909193;">
暂无数据
</view>
</view> -->
</view>
</template>
<script>
export default {
data() {
return {
}
},
created() {
},
methods: {
}
}
<script setup lang="ts">
</script>

4
src/mycomponents/common/comListHint.vue

@ -39,14 +39,14 @@
</view> -->
</view>
<u-line></u-line>
<view class='split_line'></view>
<view class="" v-for="(item, index) in dataList">
<view class="item" v-if="(item.title!='worker')" v-show="(item.title!='date')">
<text class="item_title">{{item.title}} : </text>
<text class="text_wrap">{{item.content}} </text>
</view>
</view>
<u-line></u-line>
<view class='split_line'></view>
<view v-if="isShowbottom" style="margin-top: 10rpx;margin-bottom: 10rpx;width: 100%;display: flex;"
class="uni-flex uni-row space-between u-col-center">
<view class="uni-flex uni-row u-col-center " style="flex: 1; overflow: hidden;">

124
src/mycomponents/common/comListItem.vue

@ -1,27 +1,25 @@
<template>
<view class="">
<view class="uni-flex uni-column">
<view class="item" v-for="(item,index) in dataList">
<text class="item_title">{{item.title}} : </text>
<text v-if="(item.type=='')||(item.type==undefined)" class="text_wrap">{{item.content}} </text>
<text v-else-if="item.type=='dateTime'" class="text_wrap">{{formatDate(item.content)}} </text>
<text v-else-if="item.type=='boolean'" class="text_wrap">{{boolean(item.content)}} </text>
<text v-else-if="item.type=='transferMode'" class="text_wrap">{{getTransferModeName(item.content)}} </text>
<text v-else-if="item.type=='locationType'" class="text_wrap">{{getLocationTypeNameList(getDirectoryItemArray(item.content))}} </text>
<text v-else-if="item.type=='uom'" class="text_wrap">{{getUnitInfo(item.content)}} </text>
<text v-else-if="item.type=='inspectType'" class="text_wrap">{{getInspectType(item.content)}} </text>
<text v-else-if="item.type=='sampleMethod'" class="text_wrap">{{getSampleMethod(item.content)}} </text>
<text v-else-if="item.type=='requestState'" class="text_wrap">{{getRequestStateInfo(item.content)}} </text>
<text v-else-if="item.type=='inventoryStatus'" class="text_wrap">{{getInventoryStatusName(item.content)}} </text>
<text v-else-if="item.type=='locationCode'" class="text_wrap">{{getLocationTypeName(item.content)}} </text>
<text v-else-if="item.type=='transferMode'" class="text_wrap">{{handleGetTransferModeName(item.content)}} </text>
<text v-else-if="item.type=='locationType'" class="text_wrap">{{handleGetLocationTypeNameList(handleGetDirectoryItemArray(item.content))}} </text>
<text v-else-if="item.type=='uom'" class="text_wrap">{{handleGetUomInfo(item.content)}} </text>
<text v-else-if="item.type=='inspectType'" class="text_wrap">{{handleGetInspectType(item.content)}} </text>
<text v-else-if="item.type=='sampleMethod'" class="text_wrap">{{handleGetSampleMethod(item.content)}} </text>
<text v-else-if="item.type=='requestState'" class="text_wrap">{{handleGetRequestStateInfo(item.content)}} </text>
<text v-else-if="item.type=='inventoryStatus'" class="text_wrap">{{handleGetInventoryStatusName(item.content)}} </text>
<text v-else-if="item.type=='locationCode'" class="text_wrap">{{handleGetLocationTypeName(item.content)}} </text>
</view>
</view>
</view>
</template>
<script>
<script setup lang="ts">
import {
dateFormat
} from '@/common/basic.js';
@ -30,7 +28,7 @@
getTransferModeName,
getLocationTypeNameList,
getDirectoryItemArray,
getUnitInfo,
getUomInfo,
getInspectType,
getSampleMethod,
getRequestStateInfo,
@ -38,69 +36,49 @@
getLocationTypeName
} from '@/common/directory.js';
export default {
components: {},
data() {
return {
}
},
mounted() {},
watch: {
// dataContent: {
// handler(newName, oldName) {
// },
// immediate: true,
// deep: true
// }
},
props: {
dataList: {
type: Array,
default: []
}
},
methods: {
avaliable(value) {
return value == "TRUE" ? "可用" : "不可用"
},
boolean(value) {
return value == "TRUE" ? "是" : "否"
},
formatDate(val) {
return dateFormat(val)
},
getTransferModeName(value){
return getTransferModeName(value)
},
getLocationTypeNameList(value){
return getLocationTypeNameList(value)
},
getDirectoryItemArray(value){
return getDirectoryItemArray(value)
},
getUnitInfo(value){
return getUnitInfo(value).label
},
getInspectType(value){
return getInspectType(value)
},
getSampleMethod(value){
return getSampleMethod(value)
},
getRequestStateInfo(value){
return getRequestStateInfo(value).label
},
getInventoryStatusName(value){
return getInventoryStatusName(value)
},
getLocationTypeName(value){
return getLocationTypeName(value)
}
const props = defineProps({
dataList: {
type: Array,
default: []
}
})
const avaliable=(value)=> {
return value == "TRUE" ? "可用" : "不可用"
}
const boolean=(value)=> {
return value == "TRUE" ? "是" : "否"
}
const formatDate=(val)=> {
return dateFormat(val)
}
const handleGetTransferModeName=(value)=>{
return getTransferModeName(value)
}
const handleGetLocationTypeNameList=(value)=>{
return getLocationTypeNameList(value)
}
const handleGetDirectoryItemArray=(value)=>{
return getDirectoryItemArray(value)
}
const handleGetUomInfo=(value)=>{
return getUomInfo(value).label
}
const handleGetInspectType=(value)=>{
return getInspectType(value)
}
const handleGetSampleMethod=(value)=>{
return getSampleMethod(value)
}
const handleGetRequestStateInfo=(value)=>{
return getRequestStateInfo(value).label
}
const handleGetInventoryStatusName=(value)=>{
return getInventoryStatusName(value)
}
const handleGetLocationTypeName=(value)=>{
return getLocationTypeName(value)
}
</script>
<style>

1026
src/mycomponents/common/comMessage.vue

File diff suppressed because it is too large

25
src/mycomponents/common/comPopup.vue

@ -10,26 +10,13 @@
</view>
</template>
<script>
export default {
emits: ["onClose"],
components: {
},
props: {
},
data() {
return {
}
},
methods: {
closeScanPopup() {
this.$emit("onClose", );
}
}
<script setup lang="ts">
const closeScanPopup = () => {
emit("onClose", );
}
//
const emit = defineEmits(['onClose'])
</script>
<style>

111
src/mycomponents/container/targetContainer.vue

@ -1,68 +1,57 @@
<template>
<view class="uni-flex u-col-center" style="padding-top: 15rpx;
padding-bottom: 15rpx;
padding-left: 10rpx;
padding-right: 10rpx;
font-size:32rpx;">
<text style="font-size: 35rpx;">{{title}} </text>
<view class="uni-flex u-col-center" @click="showLocation">
<text style="color:#3FBAFF;font-size: 35rpx;" v-if="containerCode==''&&isShowEdit==true">&nbsp 请扫描</text>
<text style="color:#3FBAFF; font-size: 35rpx;">&nbsp {{containerCode}}</text>
<image v-if="isShowEdit" style="width: 45rpx;height: 45rpx;" src="/static/icons/icons_edit.svg"></image>
</view>
<winScanContainer ref="scanContainer" :title="title" @getContainer='getContainer'></winScanContainer>
</view>
<view class="uni-flex u-col-center" style="padding-top: 15rpx; padding-bottom: 15rpx; padding-left: 10rpx; padding-right: 10rpx; font-size: 32rpx">
<text style="font-size: 35rpx">{{ title }} </text>
<view class="uni-flex u-col-center" @click="showLocation">
<text style="color: #3fbaff; font-size: 35rpx" v-if="containerCode == '' && isShowEdit == true">&nbsp 请扫描</text>
<text style="color: #3fbaff; font-size: 35rpx">&nbsp {{ containerCode }}</text>
<image v-if="isShowEdit" style="width: 45rpx; height: 45rpx" src="/static/icons/icons_edit.svg"></image>
</view>
<winScanContainer ref="scanContainer" :title="title" @getContainer="getContainer"></winScanContainer>
</view>
</template>
<script>
import winScanContainer from "@/mycomponents/scan/winScanContainer.vue"
<script setup lang="ts">
import { ref, getCurrentInstance, onMounted, nextTick, watch } from 'vue'
import winScanContainer from '@/mycomponents/scan/winScanContainer.vue'
export default {
components: {
winScanContainer
},
data() {
return {
defaultContainerCode: ""
}
},
props: {
title: {
type: String,
default: "需求库位"
},
containerCode: {
type: String,
default: ""
},
isShowEdit: {
type: Boolean,
default: true
},
},
const defaultContainerCode = ref('')
const props = defineProps({
title: {
type: String,
default: '需求库位'
},
containerCode: {
type: String,
default: ''
},
isShowEdit: {
type: Boolean,
default: true
}
})
watch(
() => props.containerCode,
(val) => {
if (val != '') {
defaultContainerCode.value = val
}
},
{
immediate: true,
deep: true
}
)
watch: {
containerCode: {
handler(newName, oldName) {
if (this.containerCode != "") {
this.defaultContainerCode = this.containerCode;
}
},
immediate: true,
deep: true
}
},
methods: {
showLocation() {
this.$refs.scanContainer.openScanPopup();
},
//
getContainer(containerInfo) {
this.$emit("getContainer", containerInfo)
}
}
}
const showLocation = () => {
scanContainer.value.openScanPopup()
}
//
const getContainer = (containerInfo) => {
emit('getContainer', containerInfo)
}
//
const emit = defineEmits(['getContainer'])
</script>
<style>
</style>
<style></style>

315
src/mycomponents/detail/comDetailCard.vue

@ -1,162 +1,165 @@
<template>
<view class="" style="background-color: #fff;">
<uni-collapse ref="collapse1" @change="">
<uni-collapse-item :open="true">
<template v-slot:title>
<item-compare-qty :dataContent="dataContent" :handleQty="dataContent.handleQty" :isShowStdPack="false">
</item-compare-qty>
</template>
<u-line></u-line>
<view class="" v-for="(item,index) in dataContent.subList">
<uni-swipe-action ref="swipeAction">
<uni-swipe-action-item @click="swipeClick($event,item)"
:right-options="item.scaned?scanOptions:detailOptions"
style='padding:0px 0px 5px 0px;align-items: center;'>
<recommend :detail="item" :isShowToLocation="false">
</recommend>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
</uni-collapse-item>
</uni-collapse>
<balance-qty-edit ref="qtyEdit" :settingParam="settingParam" @confirm="confirm"></balance-qty-edit>
<win-scan-location ref="scanLocationCode" title="目标库位" @getLocation='getLocation'
:locationTypeList="locationTypeList"></win-scan-location>
<comMessage ref="message"></comMessage>
</view>
<view class="" style="background-color: #fff">
<u-collapse ref="collapse">
<u-collapse-item :open="true">
<template v-slot:title>
<item-compare-qty :dataContent="dataContent" :handleQty="dataContent.handleQty" :isShowStdPack="false" style="width: 100%"> </item-compare-qty>
</template>
<u-swipe-action :show="item.show" :index="index" v-for="(item, index) in dataContent.subList" :key="index" :options="item.scaned ? scanOptions : detailOptions" bg-color="rgba(255,255,255,0)" @click="(...event) => swipeClick(event, item)">
<recommend :detail="item" :isShowFromLocation="isShowFromLocation" :isShowStatus="isShowStatus" :isShowToLocation="isShowToLocation"></recommend>
</u-swipe-action>
</u-collapse-item>
</u-collapse>
<balance-qty-edit ref="qtyEdit" :settingParam="settingParam" :queryBalance="queryBalance" @confirm="confirm"></balance-qty-edit>
<win-scan-location ref="scanLocationCode" title="目标库位" @getLocation="getLocation" :locationAreaTypeList="locationAreaTypeList"></win-scan-location>
<com-message ref="comMessageRef" />
</view>
</template>
<script>
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import balanceQtyEdit from '@/mycomponents/qty/balanceQtyEdit.vue'
import winScanLocation from "@/mycomponents/scan/winScanLocation.vue"
import {
getDetailOption,
getPurchaseReceiptOption
} from '@/common/array.js';
<script setup lang="ts">
import { ref, getCurrentInstance, onMounted, nextTick, watch } from 'vue'
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import balanceQtyEdit from '@/mycomponents/qty/balanceQtyEdit.vue'
import winScanLocation from '@/mycomponents/scan/winScanLocation.vue'
import { getDetailOption, getPurchaseReceiptOption } from '@/common/array.js'
export default {
emits: ['openDetail', "updateData"],
components: {
itemCompareQty,
recommend,
balanceQtyEdit,
winScanLocation
},
props: {
dataContent: {
type: Object,
default: {}
},
settingParam: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
locationTypeList: {
type: Array,
default: []
},
},
watch: {
dataContent: {
handler(newName, oldName) {
if (this.dataContent.subList.length > 0) {
if (this.$refs.collapse1 != undefined && this.$refs.collapse1 != null) {
this.$nextTick(res => {
this.$refs.collapse1.resize()
})
}
}
},
immediate: true,
deep: true
}
},
data() {
return {
option: [],
showItem: {},
locatonItem: {},
editItem: {},
detailOptions: [],
scanOptions: []
}
},
mounted() {
if (this.detailOptions.length == 0) {
this.detailOptions = getDetailOption();
}
if (this.scanOptions.length == 0) {
this.scanOptions = getPurchaseReceiptOption(this.settingParam.allowModifyQty, this.settingParam
.allowModifyLocation)
}
},
methods: {
swipeClick(e, item) {
if (e.content.text == "详情") {
this.detail(item)
} else if (e.content.text == "编辑") {
this.edit(item)
} else if (e.content.text == "库位") {
this.showLocation(item)
} else if (e.content.text == "移除") {
this.remove(item)
}
},
edit(item) {
this.editItem = item;
this.$refs.qtyEdit.openEditPopup(item.balance, item.handleQty);
},
detail(item) {
this.$emit('openDetail', item);
// this.showItem = item;
// this.$refs.jobDetailPopup.openPopup(item)
},
remove(item) {
this.$refs.message.showQuestionMessage("确定移除扫描信息?",
res => {
if (res) {
item.scaned = false
item.balance = {}
item.handleQty = null;
this.$forceUpdate()
this.$emit('remove', item)
}
});
},
confirm(qty) {
this.editItem.handleQty = qty;
this.$emit('updateData')
},
showLocation(item) {
this.locatonItem = item;
this.$refs.scanLocationCode.openScanPopup();
},
//
getLocation(location, code) {
this.locatonItem.toLocationCode = code;
this.$emit('updateData')
},
}
}
const props = defineProps({
dataContent: {
type: Object,
default: null
},
settingParam: {
type: Object,
default: null
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
isShowFromLocation: {
type: Boolean,
default: true
},
isShowToLocation: {
type: Boolean,
default: false
},
locationAreaTypeList: {
type: Array,
default: null
},
queryBalance: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
}
})
const option = ref([])
const showItem = ref({})
const editItem = ref({})
const locatonItem = ref({})
const detailOptions = ref([])
const scanOptions = ref([])
const comMessageRef = ref()
const collapse = ref()
const qtyEdit = ref()
const scanLocationCode = ref()
const dataContent = ref(props.dataContent)
dataContent.value.subList.forEach((item) => {
item.show = false
})
//
watch(
() => props.dataContent,
(val) => {
if (val.subList.length > 0) {
if (collapse.value != undefined && collapse.value != null) {
nextTick((res) => {
setTimeout(()=>{
collapse.value.init()
},500)
})
}
}
},
{
immediate: true,
deep: true
}
)
onMounted(() => {
if (detailOptions.value.length == 0) {
detailOptions.value = getDetailOption()
}
if (scanOptions.value.length == 0) {
scanOptions.value = getPurchaseReceiptOption(props.settingParam.allowModifyQty, false)
}
nextTick((res) => {
collapse.value.init()
})
showLocation()
})
const swipeClick = (params, item) => {
let text = ''
if (item.scaned) {
text = scanOptions.value[params[1]].text
} else {
text = detailOptions.value[params[1]].text
}
if (text == '详情') {
detail(item)
} else if (text == '编辑') {
edit(item)
} else if (text == '库位') {
showLocation(item)
} else if (text == '移除') {
remove(item)
}
}
const edit = (item) => {
editItem.value = item
qtyEdit.value.openEditPopup(item, item.handleQty)
}
const detail = (item) => {
emit('openDetail', item)
}
const remove = (item) => {
comMessageRef.value.showQuestionMessage('确定移除扫描信息?', (res) => {
if (res) {
item.scaned = false
item.balance = {}
item.handleQty = null
emit('remove', item)
}
})
}
const confirm = (qty) => {
editItem.value.handleQty = qty
emit('updateData')
}
const showLocation = (item) => {
locatonItem.value = item
scanLocationCode.value.openScanPopup()
}
//
const getLocation = () => {
locatonItem.value.LocationCode = code
emit('updateData')
}
//
const emit = defineEmits(['openDetail', 'remove', 'updateData'])
</script>
<style>
</style>
<style></style>

173
src/mycomponents/detail/comDetailCardBatch.vue

@ -0,0 +1,173 @@
<template>
<view style="background-color: #fff;">
<u-collapse ref="collapse1Ref" @change="">
<u-collapse-item :open="true">
<template #title>
<item-compare-qty :dataContent="dataContent"
:handleQty="dataContent.handleQty" :isShowStdPack="false">
</item-compare-qty>
</template>
<view class="" v-for="(item,index) in dataContent.subList" :key="index">
<u-swipe-action ref="swipeAction"
:options="item.scaned?scanOptions:detailOptions"
@click="(...event)=>swipeClick(event,item,'parent')"
v-if='index==0'>
<recommend :detail="item" :isShowFromLocation="isShowFromLocation"
:isShowStatus="isShowStatus" :isShowToLocation="isShowToLocation">
</recommend>
</u-swipe-action>
</view>
</u-collapse-item>
</u-collapse>
<balance-qty-edit ref="qtyEdit" :settingParam="settingParam" :queryBalance="queryBalance"
@confirm="confirm"></balance-qty-edit>
<win-scan-location ref="scanLocationCode" title="目标库位" @getLocation='getLocation'
:locationAreaTypeList="locationAreaTypeList"></win-scan-location>
<comMessage ref="message"></comMessage>
</view>
</template>
<script setup>
import config from '@/static/config.js'
import ItemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import Recommend from '@/mycomponents/recommend/recommend.vue'
import BalanceQtyEdit from '@/mycomponents/qty/balanceQtyEdit.vue'
import WinScanLocation from "@/mycomponents/scan/winScanLocation.vue"
import {
getDetailOption,
getPurchaseReceiptOption,
} from '@/common/array.js';
import { ref, watch, onMounted, nextTick } from 'vue';
const props = defineProps({
dataContent: {
type: Object,
default: null
},
settingParam: {
type: Object,
default: null
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
isShowFromLocation: {
type: Boolean,
default: true
},
isShowToLocation: {
type: Boolean,
default: false
},
locationAreaTypeList: {
type: Array,
default: null
},
queryBalance: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
},
});
const emit = defineEmits(['openDetail', 'remove', 'updateData']);
const showItem = ref({});
const locatonItem = ref({});
const editItem = ref({});
const detailOptions = ref([]);
const scanOptions = ref([]);
const options = ref([]);
const collapse1Ref = ref(null);
const qtyEditRef = ref(null);
const messageRef = ref(null);
const scanLocationCodeRef = ref(null);
watch(() => props.dataContent, (newDataContent, oldDataContent) => {
if (newDataContent?.subList?.length > 0) {
nextTick(() => {
setTimeout(() => {
if (collapse1Ref.value) {
collapse1Ref.value.resize();
}
}, 500);
});
}
}, { immediate: true, deep: true });
onMounted(() => {
if (detailOptions.value.length === 0) {
detailOptions.value = getDetailOption();
}
if (scanOptions.value.length === 0) {
scanOptions.value = getPurchaseReceiptOption(props.settingParam.allowModifyQty, false);
}
});
const swipeClick = (e, item) => {
if (e.content.text === "详情") {
detail(item);
} else if (e.content.text === "编辑") {
edit(item);
} else if (e.content.text === "库位") {
showLocation(item);
} else if (e.content.text === "移除") {
remove(item);
}
};
const edit = (item) => {
editItem.value = item;
qtyEditRef.value.openEditPopup(item.balance, item.handleQty);
};
const detail = (item) => {
emit('openDetail', item);
};
const remove = (item) => {
messageRef.value.showQuestionMessage("确定移除扫描信息?", (res) => {
if (res) {
item.scaned = false;
item.balance = {};
item.handleQty = null;
emit('remove', item);
}
});
};
const confirm = (qty) => {
editItem.value.handleQty = qty;
emit('updateData');
};
const showLocation = (item) => {
locatonItem.value = item;
scanLocationCodeRef.value.openScanPopup();
};
const getLocation = (location, code) => {
locatonItem.value.toLocationCode = code;
emit('updateData');
};
</script>
<style>
</style>

138
src/mycomponents/detail/comJobDetailCard.vue

@ -0,0 +1,138 @@
<template>
<view class="" style="background-color: #fff">
<u-collapse ref="collapse">
<u-collapse-item :open="true">
<template v-slot:title>
<itemCompareQty :dataContent="dataContent" :handleQty="dataContent.handleQty" :isShowPackUnit="true" style="flex: 1"></itemCompareQty>
</template>
<package-list :dataContent="dataContent.subList"
:isEdit="settingParam.allowModifyQty == 'TRUE'"
:settingParam="settingParam"
@collapseChange="collapseChange" @updateData="updateData"
:isShowStatus="isShowStatus" :isShowPackListStatus="isShowPackListStatus">
</package-list>
</u-collapse-item>
</u-collapse>
<recommend-qty-edit ref="receiptEdit" :dataContent="editItem" :settingParam="settingParam" @confirm="confirm"> </recommend-qty-edit>
<com-message ref="comMessageRef" />
</view>
</template>
<script setup lang="ts">
import { ref, getCurrentInstance, onMounted, nextTick, watch } from 'vue'
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import recommendQtyEdit from '@/mycomponents/qty/recommendQtyEdit.vue'
import packageList from '@/mycomponents/package/packageList.vue'
import { getDetailOption, getPurchaseReceiptOption } from '@/common/array.js'
const props = defineProps({
dataContent: {
type: Object,
default: null
},
settingParam: {
type: Object,
default: null
},
locationAreaTypeList: {
type: Object,
default: null
},
isShowStatus: {
type: Boolean,
default: true
},
isShowPackListStatus: {
type: Boolean,
default: true
}
})
const showItem = ref({})
const editItem = ref({
record: {}
})
const locatonItem = ref({})
const detailOptions = ref([])
const scanOptions = ref([])
const comMessageRef = ref()
const collapse = ref()
const receiptEdit = ref()
//
watch(
() => props.dataContent,
(val) => {
if (val.subList.length > 0) {
if (collapse.value != undefined && collapse.value != null) {
nextTick((res) => {
collapse.value.init()
})
}
}
},
{
deep: true
}
)
onMounted(() => {
if (detailOptions.value.length == 0) {
detailOptions.value = getDetailOption()
}
if (scanOptions.value.length == 0) {
scanOptions.value = getPurchaseReceiptOption(props.settingParam.allowModifyQty, props.settingParam.allowModifyLocation)
}
})
const collapseChange = () => {
setTimeout(() => {
resizeCollapse()
}, 500)
}
const resizeCollapse = (object) => {
nextTick(() => {
collapse.value.init()
})
}
const refreshCollapse = () => {
nextTick((r) => {
collapse.value.forEach((r) => {
r.childrens.forEach((i) => {
i.init()
})
r.init()
})
})
}
const swipeClick = (e, item) => {
if (e.content.text == '编辑') {
edit(item)
} else if (e.content.text == '移除') {
remove(item)
}
}
const edit = (item) => {
editItem = item
receiptEdit.value.openTaskEditPopup(item.qty, item.handleQty, item.labelQty)
}
const remove = (item) => {
comMessageRef.value.showQuestionMessage('确定移除扫描信息?', (res) => {
if (res) {
item.scaned = false
item.handleQty = null
emit('remove', item)
}
})
}
const confirm = (qty) => {
editItem.value.handleQty = qty
emit('updateData')
}
const updateData = () => {
emit('updateData')
}
//
const emit = defineEmits(['remove', 'updateData'])
</script>
<style></style>

151
src/mycomponents/detail/comJobDetailCardBatch.vue

@ -0,0 +1,151 @@
<!-- 采购上架任务详情按批次显示详情的组件 -->
<template>
<view class="" style="background-color: #fff;">
<u-collapse ref="collapseRef">
<u-collapse-item :open="true">
<template #title>
<itemCompareQty :dataContent="dataContent" :handleQty="dataContent.handleQty"
:isShowPackUnit="true"></itemCompareQty>
</template>
<package-list :dataContent="dataContent.subList"
:isEdit="settingParam.allowModifyQty=='TRUE'"
:settingParam="settingParam"
@collapseChange="collapseChange"
@updateData="updateData"
:isShowStatus="isShowStatus"
:isShowPackListStatus="isShowPackListStatus"
></package-list>
</u-collapse-item>
</u-collapse>
<recommend-qty-edit ref="receiptEditRef" :dataContent="editItem" :settingParam="settingParam" @confirm="confirm">
</recommend-qty-edit>
<comMessage ref="messageRef"></comMessage>
</view>
</template>
<script setup>
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import recommendQtyEdit from '@/mycomponents/qty/recommendQtyEdit.vue'
import jobDetailPopup from '@/mycomponents/detail/jobDetailPopup.vue'
import receiptDetailInfoPopup from '@/pages/purchaseReceipt/coms/receiptDetailInfoPopup.vue'
import pack from '@/mycomponents/balance/pack.vue'
import detailList from '@/mycomponents/detail/detailList.vue'
import packageList from '@/mycomponents/package/packageList.vue'
import {
getDetailOption,
getPurchaseReceiptOption
} from '@/common/array.js';
import { ref, onMounted, nextTick } from 'vue';
const props = defineProps({
dataContent: {
type: Object,
default: null
},
settingParam: {
type: Object,
default: null
},
locationAreaTypeList: {
type: Object,
default: null
},
isShowStatus: {
type: Boolean,
default: true
},
isShowPackListStatus: {
type: Boolean,
default: true
},
});
const showItem = ref({});
const editItem = ref({ record: {} });
const locatonItem = ref({});
const detailOptions = ref([]);
const scanOptions = ref([]);
const options = ref([]);
const collapseRef = ref(null);
const receiptEditRef = ref(null);
const messageRef = ref(null);
onMounted(() => {
if (detailOptions.value.length === 0) {
detailOptions.value = getDetailOption();
}
if (scanOptions.value.length === 0) {
scanOptions.value = getPurchaseReceiptOption(props.settingParam.allowModifyQty, props.settingParam.allowModifyLocation);
}
});
const collapseChange = () => {
setTimeout(() => {
resizeCollapse();
}, 500);
};
const resizeCollapse = () => {
nextTick(() => {
if (collapseRef.value) {
collapseRef.value.init();
}
});
};
const refreshCollapse = () => {
nextTick(() => {
if (collapseRef.value) {
collapseRef.value.forEach(r => {
r.childrens.forEach(i => {
i.init();
});
r.init();
});
}
});
};
const swipeClick = (e, item) => {
if (e.content.text === "编辑") {
edit(item);
} else if (e.content.text === "移除") {
remove(item);
}
};
const edit = (item) => {
editItem.value = item;
receiptEditRef.value.openTaskEditPopup(item.qty, item.handleQty, item.labelQty);
};
const remove = (item) => {
messageRef.value.showQuestionMessage("确定移除扫描信息?", (res) => {
if (res) {
item.scaned = false;
item.handleQty = null;
emit('remove', item);
}
});
};
const confirm = (qty) => {
editItem.value.handleQty = qty;
emit('updateData');
};
const updateData = () => {
emit('updateData');
};
const emit = defineEmits(['remove', 'updateData']);
</script>
<style>
</style>

178
src/mycomponents/detail/comLableDetailCard.vue

@ -0,0 +1,178 @@
<template>
<view class="" style="background-color: #fff;">
<u-collapse ref="collapse1" @change="">
<u-collapse-item :open="true">
<template v-slot:title>
<item-compare-qty :dataContent="dataContent" :handleQty="dataContent.handleQty"
:isShowStdPack="false">
</item-compare-qty>
</template>
<view class="" v-for="(item,index) in dataContent.subList" :key="index">
<u-swipe-action ref="swipeAction"
@click="(...event)=>swipeClick(event,item)"
style='padding:0px 0px 5px 0px;align-items: center;'
:options="item.scaned?scanOptions:detailOptions">
<recommend :detail="item" :isShowFromLocation="isShowFromLocation"
:isShowStatus="isShowStatus" :isShowToLocation="isShowToLocation">
</recommend>
</u-swipe-action>
</view>
</u-collapse-item>
</u-collapse>
<recommend-qty-edit ref="receiptEdit" :dataContent="editItem" :settingParam="settingParam" @confirm="confirm">
</recommend-qty-edit>
<win-scan-location ref="scanLocationCode" title="目标库位" @getLocation='getLocation'
:locationAreaTypeList="locationAreaTypeList"></win-scan-location>
<comMessage ref="message"></comMessage>
</view>
</template>
<script setup>
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import recommendQtyEdit from '@/mycomponents/qty/recommendQtyEdit.vue'
import winScanLocation from "@/mycomponents/scan/winScanLocation.vue"
import {
getDetailOption,
getPurchaseReceiptOption
} from '@/common/array.js';
import { ref, watch, onMounted, nextTick } from 'vue';
const props = defineProps({
dataContent: {
type: Object,
default: null
},
settingParam: {
type: Object,
default: null
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
isShowFromLocation: {
type: Boolean,
default: true
},
isShowToLocation: {
type: Boolean,
default: false
},
locationAreaTypeList: {
type: Array,
default: null
},
queryBalance: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
}
});
const collapse1 = ref(null);
const receiptEdit = ref(null);
const message = ref(null);
const scanLocationCode = ref(null);
const option = ref([]);
const showItem = ref({});
const locatonItem = ref({});
const editItem = ref({});
const detailOptions = ref([]);
const scanOptions = ref([]);
watch(() => props.dataContent, (newDataContent, oldDataContent) => {
if (newDataContent?.subList.length > 0) {
nextTick(() => {
setTimeout(() => {
if (collapse1.value) {
collapse1.value.resize();
}
}, 500);
});
}
}, { immediate: true, deep: true });
onMounted(() => {
if (detailOptions.value.length === 0) {
detailOptions.value = getDetailOption();
}
if (scanOptions.value.length === 0) {
scanOptions.value = getPurchaseReceiptOption(props.settingParam.allowModifyQty, false);
}
// showLocation();
});
const swipeClick = (e, item) => {
switch (e.content.text) {
case "详情":
detail(item);
break;
case "编辑":
edit(item);
break;
case "库位":
showLocation(item);
break;
case "移除":
remove(item);
break;
}
};
const edit = (item) => {
editItem.value = item;
receiptEdit.value.openTaskEditPopup(item.qty, item.handleQty, item.labelQty);
};
const detail = (item) => {
emit('openDetail', item);
// showItem.value = item;
// jobDetailPopup.value.openPopup(item);
};
const remove = (item) => {
message.value.showQuestionMessage("确定移除扫描信息?", (res) => {
if (res) {
item.scaned = false;
item.balance = {};
item.handleQty = null;
emit('remove', item);
}
});
};
const confirm = (qty) => {
editItem.value.handleQty = qty;
emit('updateData');
};
const showLocation = (item) => {
locatonItem.value = item;
scanLocationCode.value.openScanPopup();
};
const getLocation = (location, code) => {
locatonItem.value.toLocationCode = code;
emit('updateData');
};
const emit = defineEmits(['openDetail', 'remove', 'updateData']);
</script>
<style>
</style>

185
src/mycomponents/detail/comRecommendDetailCard.vue

@ -0,0 +1,185 @@
<template>
<view class="" style="background-color: #fff;">
<u-collapse ref="collapse1" >
<u-collapse-item :open="true">
<template v-slot:title>
<item-compare-qty :dataContent="dataContent" :handleQty="dataContent.handleQty"
:isShowStdPack="false">
</item-compare-qty>
</template>
<view class="" v-for="(item,index) in dataContent.subList" :key="index">
<u-swipe-action ref="swipeAction"
:options="item.scaned?scanOptions:detailOptions"
style='padding:0px 0px 5px 0px;align-items: center;'
@click="(...event)=>swipeClick(event,item)">
<view v-if="item.isRecommend" class="uni-flex" style="flex-direction: row; align-items: center;background-color: antiquewhite;">
<view class="" style="font-size: 32rpx; color: black; font-weight: bold; text-align: center;">
</view>
<recommend :detail="item" :isShowStatus="isShowStatus" :isShowFromLocation="isShowFromLocation" :isShowToLocation="isShowToLocation" style="flex:1" :isShowBatch='item.batch ? true:false' :isShowPack='isShowPack'>
</view>
<view v-else class="uni-flex" style="flex-direction: row; align-items: center;background-color: antiquewhite; margin-top: 5rpx;">
<view class="" style="font-size: 32rpx; color: red; font-weight: bold; text-align: center;">
</view>
<recommend :detail="item" :isShowStatus="isShowStatus" :isShowFromLocation="isShowFromLocation" :isShowToLocation="isShowToLocation" style="flex:1" :isShowBatch='item.batch? true:false' :isShowPack='isShowPack'></recommend>
</view>
</u-swipe-action>
</view>
</u-collapse-item>
</u-collapse>
<<recommend-qty-edit ref="recommendQtyEditRef" :dataContent="editItem" :handleQty="editItem.qty" @confirm="confirm" :settingParam='settingParam'
:isShowStatus="isShowStatus"></recommend-qty-edit>
<win-scan-location ref="scanLocationCode" title="目标库位" @getLocation='getLocation'
:locationAreaTypeList="locationAreaTypeList"></win-scan-location>
<comMessage ref="message"></comMessage>
</view>
</template>
<script setup>
import {ref, watch, onMounted, nextTick} from 'vue'
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import recommendQtyEdit from '@/mycomponents/qty/recommendQtyEdit.vue'
import winScanLocation from '@/mycomponents/scan/winScanLocation.vue'
import {
getDetailOption,
getPurchaseReceiptOption
} from '@/common/array.js'
const props = defineProps({
dataContent: {
type: Object,
default: null
},
settingParam: {
type: Object,
default: null
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
locationAreaTypeList: {
type: Array,
default: null
},
queryBalance: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
}
})
const emit = defineEmits(['openDetail', 'remove', 'updateData'])
const collapse1 = ref(null)
const qtyEdit = ref(null)
const message = ref(null)
const scanLocationCode = ref(null)
const option = ref([])
const showItem = ref({})
const locatonItem = ref({})
const editItem = ref({})
const detailOptions = ref([])
const scanOptions = ref([])
const recommendQtyEditRef = ref()
watch(() => props.dataContent, (newDataContent, oldDataContent) => {
if (newDataContent?.subList.length > 0) {
nextTick(() => {
setTimeout(() => {
if (collapse1.value) {
collapse1.value.init()
}
}, 500)
})
}
}, { immediate: true, deep: true })
onMounted(() => {
if (scanOptions.value.length === 0) {
scanOptions.value = getPurchaseReceiptOption(props.settingParam.allowModifyQty, false)
}
// showLocation();
if(import.meta.env.VITE_MANAGE_MODEL=='BY_PACKAGING'){
if (detailOptions.value.length == 0) {
detailOptions.value = getDetailOption()
}
}else {
scanOptions.value.splice(0,1)
}
})
const swipeClick = (e, item) => {
switch (e.content.text) {
case '详情':
detail(item)
break
case '编辑':
edit(item)
break
case '库位':
showLocation(item)
break
case '移除':
remove(item)
break
}
}
const edit = (item) => {
editItem.value = item
qtyEdit.value.openEditPopup(item.balance, item.handleQty)
recommendQtyEditRef.value.openTaskEditPopup(item.qty,item.handleQty,item.labelQty)
}
const detail = (item) => {
emit('openDetail', item)
// showItem.value = item;
// jobDetailPopup.value.openPopup(item);
}
const remove = (item) => {
message.value.showQuestionMessage('确定移除扫描信息?', (res) => {
if (res) {
item.scaned = false
item.balance = {}
item.handleQty = null
emit('remove', item)
}
})
}
const confirm = (qty) => {
editItem.value.handleQty = qty
emit('updateData')
}
const showLocation = (item) => {
locatonItem.value = item
scanLocationCode.value.openScanPopup()
}
const getLocation = (location, code) => {
locatonItem.value.toLocationCode = code
emit('updateData')
}
</script>
<style>
</style>

229
src/mycomponents/detail/comRecommendDetailCardBatch.vue

@ -0,0 +1,229 @@
<template>
<view class="" style="background-color: #fff;">
<item-compare-qty :dataContent="dataContent" :handleQty="dataContent.handleQty"
:isShowStdPack="false">
</item-compare-qty>
<view class="" v-for="(item,index) in dataContent.subList" :key="index">
<uni-swipe-action ref="swipeAction"
style='padding:0px 0px 5px 0px;align-items: center;'
:options="(item.scaned&&isEdit)?editAndRemoveOptions : item.scaned? removeOptions:options"
@click="(...event)=>swipeClick(event,item)">
<view v-if="item.isRecommend" class="uni-flex" style="flex-direction: row;">
<view class=""
style="font-size: 32rpx; color: black; font-weight: bold; text-align: center;background-color: antiquewhite;display: flex;align-items: center;justify-content: center;padding: 0px 10rpx;">
<br/>
</view>
<view class="" style="flex:1;">
<batch v-if="item.batch" :batch="item.batch"></batch>
<location v-if="item.fromLocationCode" title="来源库位"
:locationCode="item.fromLocationCode"></location>
</view>
<text style="font-size: 30rpx;color: #2979ff; " @click="copy(item)" v-if="isDevlement()">复制</text>
</view>
<view v-else class="uni-flex" style="flex-direction: row; margin-top: 5rpx;">
<view class=""
style="font-size: 32rpx; color: black; font-weight: bold; text-align: center;background-color: antiquewhite;display: flex;align-items: center;justify-content: center;padding: 0px 10rpx;">
<br/>
</view>
<view class="scan_view" style="flex:1;">
<location v-if="item.fromLocationCode" title="来源库位"
:locationCode="item.fromLocationCode"></location>
</view>
<!-- <recommend :detail="item" :isShowStatus="isShowStatus" :isShowToLocation="false">
</recommend> -->
</view>
</uni-swipe-action>
</view>
<balance-qty-edit ref="qtyEdit" :settingParam="settingParam" :queryBalance="queryBalance"
@confirm="confirm"></balance-qty-edit>
<win-scan-location ref="scanLocationCode" title="目标库位" @getLocation='getLocation'
:locationAreaTypeList="locationAreaTypeList"></win-scan-location>
<comMessage ref="message"></comMessage>
</view>
</template>
<script setup>
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import balanceQtyEdit from '@/mycomponents/qty/balanceQtyEdit.vue'
import winScanLocation from "@/mycomponents/scan/winScanLocation.vue"
import location from '@/mycomponents/balance/location.vue'
import toLocation from '@/mycomponents/balance/toLocation.vue'
import batch from '@/mycomponents/balance/batch.vue'
import config from '@/static/config.js'
import {
getRemoveOption,
getEditRemoveOption
} from '@/common/array.js';
import { ref, watch, onMounted, nextTick } from 'vue';
const props = defineProps({
dataContent: {
type: Object,
default: null
},
settingParam: {
type: Object,
default: null
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
locationAreaTypeList: {
type: Array,
default: null
},
queryBalance: {
type: Boolean,
default: true
},
isShowStatus: {
type: Boolean,
default: true
},
isEdit: {
type: Boolean,
default: true
}
});
const emit = defineEmits(['openDetail', 'remove', 'updateData']);
const collapse1 = ref(null);
const qtyEdit = ref(null);
const message = ref(null);
const scanLocationCode = ref(null);
const option = ref([]);
const showItem = ref({});
const locatonItem = ref({});
const editItem = ref({});
const detailOptions = ref([]);
const scanOptions = ref([]);
const options = ref([]);
const removeOptions = ref([]);
const editAndRemoveOptions = ref([]);
watch(() => props.dataContent, (newDataContent, oldDataContent) => {
if (newDataContent?.subList.length > 0) {
nextTick(() => {
setTimeout(() => {
if (collapse1.value) {
collapse1.value.resize();
}
}, 500);
});
}
}, { immediate: true, deep: true });
onMounted(() => {
removeOptions.value = getRemoveOption();
editAndRemoveOptions.value = getEditRemoveOption();
// showLocation();
});
const swipeClick = (e, item) => {
switch (e.content.text) {
case "详情":
detail(item);
break;
case "编辑":
edit(item);
break;
case "库位":
showLocation(item);
break;
case "移除":
remove(item);
break;
}
};
const edit = (item) => {
editItem.value = item;
qtyEdit.value.openEditPopup(item.balance, item.handleQty);
};
const detail = (item) => {
emit('openDetail', item);
// showItem.value = item;
// jobDetailPopup.value.openPopup(item);
};
const remove = (item) => {
message.value.showQuestionMessage("确定移除扫描信息?", (res) => {
if (res) {
item.scaned = false;
item.balance = {};
item.handleQty = null;
emit('remove', item);
}
});
};
const confirm = (qty) => {
editItem.value.handleQty = qty;
emit('updateData');
};
const showLocation = (item) => {
locatonItem.value = item;
scanLocationCode.value.openScanPopup();
};
const getLocation = (location, code) => {
locatonItem.value.toLocationCode = code;
emit('updateData');
};
const isDevlement = () => {
return config.isDevelopment;
};
const copy = (detail) => {
console.log(detail);
const content = `HPQ;V1.0;I${detail.itemCode};P${detail.packingNumber};B${detail.batch};Q${detail.qty}`;
// #ifdef H5
navigator.clipboard.writeText(content).then(
() => {
uni.showToast({
title: '复制采购标签成功',
icon: 'none'
});
},
() => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
);
// #endif
// #ifndef H5
uni.setClipboardData({
data: content,
success: () => {
uni.showToast({
title: '复制采购标签成功'
});
}
});
// #endif
};
</script>
<style>
</style>

270
src/mycomponents/detail/comRequestDetailCard.vue

@ -1,151 +1,135 @@
<template>
<view class="" style="background-color: #fff;">
<!-- <comReturnRequestInfo :workShopCode="dataContent.workshopCode" :dataContent="requestItem">
</comReturnRequestInfo> -->
<uni-collapse ref="collapse1" @change="">
<uni-collapse-item :open="true">
<template v-slot:title>
<item-compare-qty
:dataContent="dataContent"
:handleQty="Number(dataContent.handleQty)"
:isShowStdPack="false">
</item-compare-qty>
</template>
<u-line />
<view class="" v-for="(item,index) in dataContent.subList">
<uni-swipe-action ref="swipeAction">
<uni-swipe-action-item @click="swipeClick($event,item)"
:right-options="item.scaned?scanOptions:detailOptions">
<recommend :detail="item" :record="item.record" :isShowPack="isShowPack"
:isShowBatch="isShowBatch" :isShowFromLocation="isShowLocation"></recommend>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
</uni-collapse-item>
</uni-collapse>
<balance-qty-edit ref="qtyEdit" :settingParam="settingParam" @confirm="confirm"></balance-qty-edit>
<comMessage ref="message"></comMessage>
</view>
<view class="" style="background-color: #fff">
<u-collapse ref="collapse">
<u-collapse-item :open="true">
<template v-slot:title>
<item-compare-qty :dataContent="dataContent" :handleQty="Number(dataContent.handleQty)" :isShowStdPack="false" style="flex: 1"> </item-compare-qty>
</template>
<u-swipe-action :show="item.show" :index="index" v-for="(item, index) in dataContent.subList" :key="index" :options="item.scaned ? scanOptions : detailOptions" bg-color="rgba(255,255,255,0)" @click="(...event) => swipeClick(event, item)">
<recommend :detail="item" :record="item.record" :isShowPack="isShowPack" :isShowBatch="isShowBatch" :isShowFromLocation="isShowLocation"></recommend>
</u-swipe-action>
</u-collapse-item>
</u-collapse>
<balance-qty-edit ref="qtyEdit" :settingParam="settingParam" @confirm="confirm"></balance-qty-edit>
<com-message ref="comMessageRef" />
</view>
</template>
<script>
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import balanceQtyEdit from '@/mycomponents/qty/balanceQtyEdit.vue'
import comReturnRequestInfo from '@/pages/productionReturn/coms/comReturnRequestInfo.vue'
import {
getDetailOption,
getDetailEditRemoveOption,
getDetailRemoveOption
} from '@/common/array.js';
<script setup lang="ts">
import { ref, getCurrentInstance, onMounted, watch, nextTick } from 'vue'
import itemCompareQty from '@/mycomponents/item/itemCompareQty.vue'
import recommend from '@/mycomponents/recommend/recommend.vue'
import balanceQtyEdit from '@/mycomponents/qty/balanceQtyEdit.vue'
import comReturnRequestInfo from '@/pages/productionReturn/coms/comReturnRequestInfo.vue'
import { getDetailOption, getDetailEditRemoveOption, getDetailRemoveOption } from '@/common/array.js'
export default {
emits: ['openDetail'],
components: {
itemCompareQty,
recommend,
balanceQtyEdit,
comReturnRequestInfo
},
props: {
dataContent: {
type: Object,
default: {}
},
settingParam: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
},
},
watch: {
dataContent(newVal) {
var test =this.dataContent
this.requestItem = newVal.subList[0];
},
},
data() {
return {
option: [],
showItem: {},
editItem: {
record: {
}
},
detailOptions: [],
scanOptions: [],
requestItem:{}
}
},
mounted() {
if (this.detailOptions.length == 0) {
this.detailOptions = getDetailOption();
}
if (this.scanOptions.length == 0) {
this.scanOptions = getDetailEditRemoveOption();
// if (this.dataContent.allowModifyQty == 1) {
// this.scanOptions = getDetailEditRemoveOption();
// } else {
// this.scanOptions = getDetailRemoveOption();
// }
}
},
methods: {
swipeClick(e, item) {
if (e.content.text == "详情") {
this.detail(item)
} else if (e.content.text == "编辑") {
this.edit(item)
} else if (e.content.text == "移除") {
this.remove(item)
}
},
edit(item) {
this.editItem = item;
this.$refs.qtyEdit.openEditPopup(item.balance, item.record.qty);
},
detail(item) {
this.$emit('openDetail', item);
// this.showItem = item;
// this.$refs.jobDetailPopup.openPopup(item)
},
remove(item) {
this.$refs.message.showQuestionMessage("确定移除扫描信息?",
res => {
if (res) {
item.scaned = false
item.record = {}
item.balance = {}
item.inventoryStatus = item.RecommendInventoryStatus
// item.record.qty = 0;
this.$forceUpdate()
this.$emit('remove', item)
}
});
},
confirm(qty) {
this.editItem.record.qty = qty;
this.$emit('updateData')
}
}
}
const props = defineProps({
dataContent: {
type: Object,
default: {}
},
settingParam: {
type: Object,
default: {}
},
isShowPack: {
type: Boolean,
default: true
},
isShowBatch: {
type: Boolean,
default: true
},
isShowLocation: {
type: Boolean,
default: true
}
})
const option = ref([])
const showItem = ref({})
const editItem = ref({
record: {}
})
const detailOptions = ref([])
const scanOptions = ref([])
const requestItem = ref({})
const qtyEdit = ref()
const comMessageRef = ref()
const dataContent = ref([])
const collapse = ref()
dataContent.value = props.dataContent
dataContent.value.subList.forEach((item) => {
item.show = false
})
onMounted(() => {
if (detailOptions.value.length == 0) {
detailOptions.value = getDetailOption()
}
if (scanOptions.value.length == 0) {
scanOptions.value = getDetailEditRemoveOption()
}
})
//
watch(
() => props.dataContent,
(val) => {
requestItem.value = val.subList[0]
dataContent.value = val
dataContent.value.subList.forEach((item) => {
item.show = false
})
nextTick(() => {
collapse.value.init()
})
},
{
immediate: true,
deep: true
}
)
const swipeClick = (params, item) => {
let text = ''
if (item.scaned) {
text = scanOptions.value[params[1]].text
} else {
text = detailOptions.value[params[1]].text
}
if (text == '详情') {
detail(item)
} else if (text == '编辑') {
edit(item)
} else if (text == '移除') {
remove(item)
}
}
const edit = (item) => {
editItem.value = item
qtyEdit.value.openEditPopup(item.balance, item.record.qty)
}
const detail = (item) => {
emit('openDetail', item)
}
const remove = (item) => {
comMessageRef.value.showQuestionMessage('确定移除扫描信息?', (res) => {
if (res) {
item.scaned = false
item.record = {}
item.balance = {}
item.inventoryStatus = item.RecommendInventoryStatus
emit('remove', item)
}
})
}
const confirm = (qty) => {
editItem.value.record.qty = qty
emit('updateData')
}
//
const emit = defineEmits(['openDetail', 'remove', 'updateData'])
</script>
<style>
::v-deep .u-arrow-down-icon {
margin-right: 0px !important;
}
</style>

44
src/mycomponents/detail/detailBalanceInfo.vue

@ -15,12 +15,12 @@
<text class="item_title">数量 : </text>
<view class="text_wrap">
<text class="text_wrap">{{Number(dataContent.qty)}}</text>
<text class="text_wrap">{{getUnitInfo(dataContent.uom)}}</text>
<text class="text_wrap">{{handleGetUomInfo(dataContent.uom)}}</text>
</view>
</view>
<view class="item">
<text class="item_title">库存状态 : </text>
<text class="text_wrap">{{getInventoryStatusInfo(dataContent.inventoryStatus)}}</text>
<text class="text_wrap">{{handleGetInventoryStatusInfo(dataContent.inventoryStatus)}}</text>
</view>
<view class="item">
<text class="item_title">来源库位 : </text>
@ -29,37 +29,25 @@
</view>
</template>
<script>
<script setup lang="ts">
import {
getInventoryStatusName,
getStdPackUnitInfo,
getUnitInfo
getPackUnitInfo,
getUomInfo
} from '@/common/directory.js';
export default {
components: {},
data() {
return {
}
},
mounted() {},
props: {
dataContent: {
type: Object,
default: {}
}
},
methods: {
getInventoryStatusInfo(value) {
return getInventoryStatusName(value)
},
getUnitInfo(value){
return getUnitInfo(value).label
}
const props = defineProps({
dataContent: {
type: Object,
default: {}
}
})
const handleGetInventoryStatusInfo=(value)=> {
return getInventoryStatusName(value)
}
const handleGetUomInfo=(value)=>{
return getUomInfo(value).label
}
</script>
<style>

103
src/mycomponents/detail/detailCommonInfo.vue

@ -1,65 +1,48 @@
<template>
<view class="pop_detail" style="height:80%">
<com-item :dataContent="dataContent"></com-item>
<u-line></u-line>
<scroll-view style="height:320px ">
<detail-item-info :dataContent="dataContent"></detail-item-info>
<u-line></u-line>
<detail-recommend-info :dataContent="dataContent"></detail-recommend-info>
<u-line></u-line>
<view v-if="dataContent.record!=undefined">
<detail-handle-info :dataContent="dataContent">
</detail-handle-info>
<u-line></u-line>
</view>
<slot>
<!-- 每个任务的详情 -->
</slot>
</scroll-view>
<view class="uni-flex u-row-center ">
<view class="close_button" @click="closePopup">
关闭</view>
<!-- button 滚动不好使 -->
</view>
</view>
<view class="pop_detail" style="height: 80%">
<view class="u-p-t-20 u-p-b-20">
<com-item :dataContent="dataContent"></com-item>
</view>
<view class="split_line"></view>
<scroll-view style="height: 320px" scroll-y>
<detail-item-info :dataContent="dataContent"></detail-item-info>
<view class="split_line"></view>
<detail-recommend-info :dataContent="dataContent"></detail-recommend-info>
<view class="split_line"></view>
<view v-if="dataContent.record != undefined">
<detail-handle-info :dataContent="dataContent"> </detail-handle-info>
<view class="split_line"></view>
</view>
<slot>
<!-- 每个任务的详情 -->
</slot>
</scroll-view>
<view class="uni-flex u-row-center u-p-t-20 u-p-b-20">
<view class="close_button" @click="closePopup"> 关闭</view>
<!-- button 滚动不好使 -->
</view>
</view>
</template>
<script>
import comItem from '@/mycomponents/item/item.vue'
import detailItemInfo from '@/mycomponents/detail/detailItemInfo.vue'
import detailRecommendInfo from '@/mycomponents/detail/detailRecommendInfo.vue'
import detailHandleInfo from '@/mycomponents/detail/detailHandleInfo.vue'
export default {
emits: ['onClose'],
components: {
comItem,
detailItemInfo,
detailRecommendInfo,
detailHandleInfo
},
data() {
return {}
},
mounted() {},
props: {
dataContent: {
type: Object,
default: {}
}
},
methods: {
closePopup() {
this.$emit('onClose')
},
}
}
<script setup lang="ts">
import comItem from '@/mycomponents/item/item.vue'
import detailItemInfo from '@/mycomponents/detail/detailItemInfo.vue'
import detailRecommendInfo from '@/mycomponents/detail/detailRecommendInfo.vue'
import detailHandleInfo from '@/mycomponents/detail/detailHandleInfo.vue'
const props = defineProps({
dataContent: {
type: Object,
default: {}
}
})
const closePopup = () => {
emit('onClose')
}
//
const emit = defineEmits(['onClose'])
</script>
<style>
</style>
<style></style>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save