wanggang 2 years ago
parent
commit
e78ba0fc95
  1. 16
      fe/PDA/.hbuilderx/launch.json
  2. 29
      fe/PDA/App.vue
  3. 21
      fe/PDA/LICENSE
  4. 129
      fe/PDA/README.md
  5. 1223
      fe/PDA/api/index.js
  6. 22
      fe/PDA/api/test.js
  7. 22
      fe/PDA/api/test_2.js
  8. 171
      fe/PDA/changelog.md
  9. 221
      fe/PDA/common/PDA_style.css
  10. 262
      fe/PDA/common/airport.js
  11. 134
      fe/PDA/common/array.js
  12. 328
      fe/PDA/common/basic.js
  13. 33
      fe/PDA/common/common.js
  14. 26
      fe/PDA/common/config.js
  15. 97
      fe/PDA/common/graceChecker.js
  16. 352
      fe/PDA/common/html-parser.js
  17. 112
      fe/PDA/common/message.js
  18. 5
      fe/PDA/common/modelConfig.js
  19. 1863
      fe/PDA/common/new_style.css
  20. 697
      fe/PDA/common/pdabasic.css
  21. 245
      fe/PDA/common/permission.js
  22. 191
      fe/PDA/common/print.js
  23. 26
      fe/PDA/common/promise.js
  24. 124
      fe/PDA/common/request.js
  25. 103
      fe/PDA/common/request_test.js
  26. 308
      fe/PDA/common/scan.js
  27. 15
      fe/PDA/common/text.js
  28. 136
      fe/PDA/common/uni-nvue.css
  29. 2897
      fe/PDA/common/uni.css
  30. 53
      fe/PDA/common/util.js
  31. 6
      fe/PDA/common/utils.js
  32. 181
      fe/PDA/components/amap-wx/js/util.js
  33. 1
      fe/PDA/components/amap-wx/lib/amap-wx.js
  34. 156
      fe/PDA/components/api-set-tabbar.nvue
  35. 1
      fe/PDA/components/marked/index.js
  36. 1573
      fe/PDA/components/marked/lib/marked.js
  37. 12542
      fe/PDA/components/mpvue-citypicker/city-data/area.js
  38. 1503
      fe/PDA/components/mpvue-citypicker/city-data/city.js
  39. 139
      fe/PDA/components/mpvue-citypicker/city-data/province.js
  40. 230
      fe/PDA/components/mpvue-citypicker/mpvueCityPicker.vue
  41. 123
      fe/PDA/components/mpvue-echarts/src/echarts.vue
  42. 73
      fe/PDA/components/mpvue-echarts/src/wx-canvas.js
  43. 484
      fe/PDA/components/mpvue-picker/mpvuePicker.vue
  44. 175
      fe/PDA/components/mpvueGestureLock/gestureLock.js
  45. 138
      fe/PDA/components/mpvueGestureLock/index.vue
  46. 38
      fe/PDA/components/page-foot/page-foot.vue
  47. 16
      fe/PDA/components/page-head/page-head.vue
  48. 66
      fe/PDA/components/product.vue
  49. 175
      fe/PDA/components/tab-nvue/mediaList.vue
  50. 5046
      fe/PDA/components/u-charts/u-charts.js
  51. 59
      fe/PDA/components/u-link/u-link.vue
  52. 88
      fe/PDA/hybrid/html/local.html
  53. 20
      fe/PDA/index.html
  54. 23
      fe/PDA/libs/versionUpdate.js
  55. 90
      fe/PDA/main.js
  56. 187
      fe/PDA/manifest.json
  57. 53
      fe/PDA/mycomponents/comItem/comBalanceItem.vue
  58. 50
      fe/PDA/mycomponents/comItem/comBaseItem.vue
  59. 95
      fe/PDA/mycomponents/comItem/comBottomItem.vue
  60. 39
      fe/PDA/mycomponents/comItem/comErpLocation.vue
  61. 73
      fe/PDA/mycomponents/comItem/comItemBottom.vue
  62. 62
      fe/PDA/mycomponents/comItem/comItemErpCenter.vue
  63. 47
      fe/PDA/mycomponents/comItem/comItemLocationCenter.vue
  64. 58
      fe/PDA/mycomponents/comItem/comItemTop.vue
  65. 493
      fe/PDA/mycomponents/comItem/comJobScanDetail.vue
  66. 95
      fe/PDA/mycomponents/comItem/comTopItem.vue
  67. 75
      fe/PDA/mycomponents/comjob/comJobScanDetail.vue
  68. 53
      fe/PDA/mycomponents/comjob/comJobTopInfo.vue
  69. 399
      fe/PDA/mycomponents/common/SemiCollapseItem.vue
  70. 60
      fe/PDA/mycomponents/common/comBalance.vue
  71. 31
      fe/PDA/mycomponents/common/comBlankView.vue
  72. 399
      fe/PDA/mycomponents/common/comCollapseItem.vue
  73. 28
      fe/PDA/mycomponents/common/comDyItemInfo.vue
  74. 98
      fe/PDA/mycomponents/common/comEasyInput.vue
  75. 194
      fe/PDA/mycomponents/common/comMessage.vue
  76. 232
      fe/PDA/mycomponents/common/comNumberBox.vue
  77. 277
      fe/PDA/mycomponents/common/comStepsCustom.vue
  78. 54
      fe/PDA/mycomponents/comreceipt.vue
  79. 71
      fe/PDA/mycomponents/coms/comProductItem.vue
  80. 72
      fe/PDA/mycomponents/coms/comTjDeliver.vue
  81. 44
      fe/PDA/mycomponents/coms/comTjProduct.vue
  82. 122
      fe/PDA/mycomponents/coms/inventory/comHold.vue
  83. 116
      fe/PDA/mycomponents/coms/inventory/comUnissue.vue
  84. 65
      fe/PDA/mycomponents/coms/query/comDetail.vue
  85. 52
      fe/PDA/mycomponents/coms/query/comItem.vue
  86. 58
      fe/PDA/mycomponents/coms/query/comLocation.vue
  87. 70
      fe/PDA/mycomponents/coms/query/comOccupied.vue
  88. 74
      fe/PDA/mycomponents/coms/query/comSummary.vue
  89. 63
      fe/PDA/mycomponents/coms/return/comProductionReturn.vue
  90. 64
      fe/PDA/mycomponents/coms/return/comReturn.vue
  91. 130
      fe/PDA/mycomponents/coms/return/comReturnDetail.vue
  92. 80
      fe/PDA/mycomponents/coms/return/comScanReturn.vue
  93. 111
      fe/PDA/mycomponents/coms/store/comDeliverFg.vue
  94. 109
      fe/PDA/mycomponents/coms/store/comDeliverTf.vue
  95. 57
      fe/PDA/mycomponents/coms/store/comReceipt.vue
  96. 70
      fe/PDA/mycomponents/coms/store/comTjRecycle.vue
  97. 65
      fe/PDA/mycomponents/coms/task/comCalc.vue
  98. 77
      fe/PDA/mycomponents/coms/task/comCount.vue
  99. 45
      fe/PDA/mycomponents/coms/task/comCountItems.vue
  100. 90
      fe/PDA/mycomponents/coms/task/comCountScanDetail.vue

16
fe/PDA/.hbuilderx/launch.json

@ -0,0 +1,16 @@
{ // 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"
}
]
}

29
fe/PDA/App.vue

@ -0,0 +1,29 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
// setInterval(function(){
// uni.hideKeyboard()
// },60)
// console.log('App Show')
},
onHide: function() {
// console.log('App Hide')
}
}
</script>
<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
/*每个页面公共css */
// @import './common/PDA_style.css';
@import './common/new_style.css';
@import "./static/icon/iconfont.css";
@import './common/uni.css';
@import './common/pdabasic.css';
body{
background-color: #EBEEF0;
}
</style>

21
fe/PDA/LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 DCloud
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.

129
fe/PDA/README.md

@ -0,0 +1,129 @@
# hello-uniapp
`uni-app`框架示例,一套代码,同时发行到iOS、Android、H5、小程序等多个平台,请使用手机在下方扫码快速体验`uni-app`的强大功能。[官方文档](https://uniapp.dcloud.net.cn/)
## 快速上手
hello-uniapp 示例工程可以通过两种方式创建, 一种是 HBuilderX, 配套 IDE,集成开发;另一种是 CLI 创建;推荐前者。
### 通过 HBuilderX 可视化界面创建(推荐)
可视化的方式比较简单,HBuilderX内置相关环境,开箱即用,无需配置nodejs。
开始之前,开发者需先下载安装如下工具:
- HBuilderX:[官方IDE下载地址](https://www.dcloud.io/hbuilderx.html)
HBuilderX是通用的前端开发工具,但为`uni-app`做了特别强化,请下载App开发版。
由于截图在 github 不便浏览,参见官方文档 [HBuilderX 可视化界面创建](https://uniapp.dcloud.net.cn/quickstart?id=_1-%e9%80%9a%e8%bf%87-hbuilderx-%e5%8f%af%e8%a7%86%e5%8c%96%e7%95%8c%e9%9d%a2)
### 通过 vue-cli 创建
```
npm install -g @vue/cli
```
#### 创建uni-app
**使用正式版**(对应HBuilderX最新正式版)
```
vue create -p dcloudio/uni-preset-vue my-project
```
**使用alpha版**(对应HBuilderX最新alpha版)
```
vue create -p dcloudio/uni-preset-vue#alpha my-alpha-project
```
此时,会提示选择项目模板,选择 `hello uni-app` 项目模板,如下所示:
<div>
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/h5-cli-01.png" width="300">
</div>
创建好后,进入项目目录
```
cd my-project
```
执行该命令运行到 h5 端
```
npm run dev:h5
```
欢迎提 issues,推荐到[官方社区](https://ask.dcloud.net.cn/explore/)提问。
## 扫码体验
<div class="quick">
<p>一套代码编到10个平台,这不是梦想。眼见为实,扫描10个二维码,亲自体验最全面的跨平台效果!</p>
<div style="display: flex;">
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/ba7d0750-517d-11eb-bdc1-8bd33eb6adaa.png" width="160" />
</div>
<b>Android版</b>
</a>
<a href="https://itunes.apple.com/cn/app/hello-uni-app/id1417078253?mt=8" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/bb3ef7c0-517d-11eb-bdc1-8bd33eb6adaa.png" width="160" />
</div>
<b>iOS版</b>
</a>
<a href="https://hellouniapp.dcloud.net.cn/" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/bb3ef7c0-517d-11eb-bdc1-8bd33eb6adaa.png" width="160" />
</div>
<b>H5版</b>
</a>
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box"><img src="//img.cdn.aliyun.dcloud.net.cn/guide/uniapp/gh_33446d7f7a26_430.jpg" width="160" /></div>
<b>微信小程序版</b>
</a>
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box"><img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b131e0d0-517d-11eb-a16f-5b3e54966275.png" width="160" /></div>
<b>支付宝小程序版</b>
</a>
</div>
<div class="flex-img-group-view" style="margin-top: 20px;">
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box"><img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b204e840-517d-11eb-8ff1-d5dcf8779628.png" width="160" /></div>
<b>百度小程序版</b>
</a>
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/mp-toutiao.png" width="160" />
</div>
<b>字节跳动小程序版</b>
</a>
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/hello-uni-qq.png" width="160" />
</div>
<b>QQ小程序版</b>
</a>
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/hello-uni-qa-union.png" width="160" />
</div>
<b>快应用</b>
</a>
<a href="https://so.mp.360.cn/mp.html?appid=qh4j181qqtru354st6" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/hello-uni-mp-360-qr.png" width="160" />
</div>
<b>360小程序</b>
</a>
</div>
<p>
<em>注:某些平台不能提交简单demo,故补充了一些其他功能;hello uni-app示例代码可从[github](https://github.com/dcloudio/hello-uniapp)获取</em></br>
<em>快应用仅支持 vivo 、oppo、华为</em></br>
<em>360小程序仅 windows平台支持,需要在360浏览器中打开</em></br>
</p>
</div>
`uni-app`官网文档详见[https://uniapp.dcloud.io](https://uniapp.dcloud.io)
更多uni-app的模板、示例详见[插件市场](https://ext.dcloud.net.cn/)

1223
fe/PDA/api/index.js

File diff suppressed because it is too large

22
fe/PDA/api/test.js

@ -0,0 +1,22 @@
// import request from '@/common/request.js'
// import promise from '@/common/promise.js'
import request from '@/common/request_test.js'
// let devUrl = this.$dev_url;
let devUrl = "http://dev.ccwin-in.com:59096"
export function getlogin(params) {
return request({
url: devUrl + "/api/pda/account/login",
method: "post",
data: params,
});
}
//修改用户密码
export function changePassword(params) { //
return request({
url:devUrl + "/api/pda/account/change-password",//
data: params,
method: "post"
})
}

22
fe/PDA/api/test_2.js

@ -0,0 +1,22 @@
// // import request from '@/common/request.js'
// // import promise from '@/common/promise.js'
// import request from '@/common/request_test.js'
// // let devUrl = this.$dev_url;
// let devUrl = "http://dev.ccwin-in.com:59096"
// export function getlogin(params) {
// return request({
// url: devUrl + "/api/pda/account/login",
// method: "post",
// data: params,
// });
// }
// //修改用户密码
// export function changePassword(params) { //
// return request({
// url:devUrl + "/api/pda/account/change-password",//
// data: params,
// method: "post"
// })
// }

171
fe/PDA/changelog.md

@ -0,0 +1,171 @@
## 3.4.4(2022-07-25)
- 新增 同步 uni-ui@1.4.20
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
- uni-section 新增组件
## 3.4.3(2022-07-14)
- 修复 HBuilderX 拉取 hello uni-app 项目直接运行提示无服务空间关联的bug
## 3.4.2(2022-07-06)
- 新增 同步 uni-ui@1.4.18
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
- uni-forms 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
- uni-forms 新增 更多表单示例
- uni-forms 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
- uni-forms 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
- uni-forms 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
- uni-forms 新增 子表单的 setRules 方法,配合自定义校验函数使用
- uni-forms 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
- uni-forms 修复 由 1.4.0 引发的 label 插槽不生效的bug
- uni-forms 修复 子组件找不到 setValue 报错的bug
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中报错的bug
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
- uni-forms 修复 表单校验顺序无序问题
- uni-forms 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
- uni-forms 优化 动态表单校验方式,废弃拼接name的方式
- uni-breadcrumb 修复 微信小程序 separator 不显示问题
- uni-data-checkbox 优化 在 uni-forms 中的依赖注入方式
- uni-data-picker 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
- uni-data-picker 优化 显示样式
- uni-data-select 优化 显示样式
- uni-datetime-picker 修复 日历顶部年月及底部确认未国际化 bug
- uni-datetime-picker 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
- uni-easyinput 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
- uni-easyinput 新增 clear 事件,点击右侧叉号图标触发
- uni-easyinput 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
- uni-easyinput 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
- uni-easyinput 优化 clearable 显示策略
- uni-file-picker 修复 在uni-forms下样式不生效的bug
- uni-nav-bar 修复 组件示例中插槽用法无法显示内容的bug
- uni-swipe-action 修复 vue3 下使用组件不能正常运行的Bug
- uni-swipe-action 修复 h5端点击click触发两次的Bug
- uni-table 修复 微信小程序存在无使用组件的问题
## 3.4.1(2022-06-30)
- 新增 支持 ios 安全区
## 3.3.8(2022-05-08)
- 新增 同步 uni-ui@1.4.15
- uni-data-picker 修复 字节小程序 本地数据无法选择下一级的Bug
- uni-data-select 新增 记住上次的选项(仅 collection 存在时有效)
- uni-search-bar 修复 vue3 input 事件不生效的bug
- uni-search-bar 修复 多余代码导致的bug
- uni-tooltip 更新 text 属性变更为 content
- uni-tooltip 更新 移除 width 属性
- uni-tooltip 修复 组件根 text 嵌套组件 warning
## 3.3.7(2022-04-06)
- 新增 更新扩展组件 uni-nav-bar、uni-list 的展示页面
## 3.3.6(2022-03-31)
- 更新 uni-ui 组件及示例
## 3.3.5(2022-03-30)
- 修复 插槽兼容 vue3, slot -> v-slot
- 新增 更新 uni-ui
## 3.3.4(2022-02-25)
- 修复 编译到 App 平台的控制台报错
## 3.3.3(2022-02-23)
- 修复 模板城市选择 vue3 报错的bug
- 修复 删除 map.nvue 中多余的 enableOverlooking 变量
- 修复 swipe-dot.nvue 中条件编译媒体查询
## 3.3.2(2022-01-26)
- 修复 默认运行到 vue2
## 3.3.1(2022-01-26)
- 新增 同步 uni-ui@1.4.11
- uni-collapse 修复 微信小程序resize后组件收起的bug
- uni-countdown 修复 在微信小程序中样式不生效的bug
- uni-countdown 新增 update 方法 ,在动态更新时间后,刷新组件
- uni-load-more 新增 showText属性 ,是否显示文本
- uni-load-more 修复 nvue 平台下不显示文本的bug
- uni-load-more 修复 微信小程序平台样式选择器报警告的问题
- uni-nav-bar 修复 在vue下,标题不垂直居中的bug
- uni-nav-bar 修复 height 属性类型错误
- uni-nav-bar 新增 height 属性,可修改组件高度
- uni-nav-bar 新增 dark 属性可可开启暗黑模式
- uni-nav-bar 优化 标题字数过多显示省略号
- uni-nav-bar 优化 插槽,插入内容可完全覆盖
- uni-popup 修复 isMaskClick 失效的bug
- uni-popup 新增 cancelText \ confirmText 属性 ,可自定义文本
- uni-popup 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
- uni-popup 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
## 3.3.0(2022-01-04)
- 修复 开发时在 vue3 下由 pc 端切换到手机端,不能返回上一级页面的 bug
- 优化 去掉 pc 端 topwindow 右上角用于演示的 url 导航
## 3.2.12(2021-12-20)
- 新增 适配京东小程序
## 3.2.11(2021-12-07)
- 修复 uni-ui 在 hello-uniapp 中丢失图标、ui 受到公共样式影响等问题
- 修复 微信登录取值报错的问题
## 3.2.10(2021-11-30)
- 修复 map 组件示例不显示的 bug
## 3.2.9(2021-11-19)
- 新增 uni-ui 以 uni_modules 方式引入,方便开发者从 hello-uniapp 中 copy 组件及示例
- 优化 uni-ui 示例页面,完善组件示例
## 3.2.8(2021-11-10)
- 新增 适配飞书平台(lark)
## 3.2.7(2021-10-26)
- 修复 uni-popup 示例的 button 文字在 iPhone 5 上换行的 bug
- 修复 uni-table 示例,页面顶部距离不对的 bug
- 修复 GlobalData示例,在vue3是无效的 bug
- 优化 删除无用的 project.swan.json 文件
## 3.2.6(2021-10-08)
- 由于体验问题,暂时撤销 uni-ui 以 uni_modules 方式引入的修改
## 3.2.4(2021-09-07)
- 修复 vue3 在 H5 编译报错的 bug
- 新增 同步 uni-ui
- 新增 uni-ui 组件支持国际化 i18n
- uni-data-checkbox 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
- uni-datetime-picker 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
- uni-datetime-picker 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
- uni-datetime-picker 优化 调整字号大小,美化日历界面
- uni-datetime-picker 修复 因国际化导致的 placeholder 失效的 bug
- uni-file-picker 修复 return-type="object" 时且存在v-model时,无法删除文件的Bug
- uni-file-picker 新增 参数中返回 fileID 字段
- uni-file-picker 修复 腾讯云传入fileID 不能回显的bug
- uni-file-picker 修复 选择图片后,不能放大的问题
- uni-link 修复 在 nvue 下不显示的 bug
- uni-list 修复 在vue3中to属性在发行应用的时候报错的bug
- uni-search-bar 修复 value 属性与 modelValue 属性不兼容的Bug
- uni-swipe-action 优化 close-all 方法
- uni-collapse 优化 show-arrow 属性默认为true
- uni-collapse 新增 show-arrow 属性,控制是否显示右侧箭头
- uni-data-checkbox 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
- uni-easyinput 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
- uni-file-picker 修复 由于 0.2.11 版本引起的不能回显图片的Bug
- uni-file-picker 新增 clearFiles(index) 方法,可以手动删除指定文件
- uni-file-picker 修复 v-model 值设为 null 报错的Bug
- uni-swipe-action 新增 close-all 方法,关闭所有已打开的组件
- uni-swipe-action 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件
- uni-swipe-action 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题
- uni-swipe-action 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
## 3.2.3(2021-08-27)
- 优化 tabbar 页面移除 vuex 相关代码
- 新增 适配 vue3 (app)
## 3.2.2(2021-08-10)
- 新增 适配快手小程序
- 新增 同步 uni-ui
- uni-datetime-picker 新增 return-type 属性支持返回 date 日期对象
- uni-file-picker 修复 fileExtname属性不指定值报错的Bug
- uni-file-picker 修复 在某种场景下图片不回显的Bug
- uni-link 支持自定义插槽
- uni-calendar 修复 弹出层被 tabbar 遮盖 bug
- uni-dateformat 调整 默认时间不再是当前时间,而是显示'-'字符
- uni-datetime-picker 新增 适配 vue3
- uni-datetime-picker 新增 支持作为 uni-forms 子组件相关功能
- uni-datetime-picker 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
- uni-datetime-picker 修复 type 属性动态赋值无效的 bug
- uni-datetime-picker 修复 ‘确认’按钮被 tabbar 遮盖 bug
- uni-datetime-picker 修复 组件未赋值时范围选左、右日历相同的 bug
- uni-datetime-picker 修复 范围选未正确显示当前值的 bug
- uni-datetime-picker 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
- uni-file-picker 修复 auto-upload 属性失效的Bug
## 3.2.1(2021-07-31)
- 新增 同步 uni-ui@1.3.8
## 3.2.0(2021-07-30)
- 新增 同时兼容 vue2 & vue3
## 3.1.20(2021-07-30)
- 新增 同时兼容 vue2 & vue3
## 3.1.17(2021-05-26)
- 修复 3.1.16 依赖 sass 的问题
- 条件编译 nuve 不支持 css 属性
## 3.1.16(2021-05-26)
- 修复 uni-data-checkbox 不关联服务空间的情况下组件报错的 Bug
## 3.1.12(2021-05-07)
- hello-uniapp 发布插件市场

221
fe/PDA/common/PDA_style.css

@ -0,0 +1,221 @@
@media screen and (min-width:400px) {
uni-app, uni-page-head{
height: 60px;
}
uni-page-head .uni-page-head{
height: 60px !important;
}
uni-page-head[uni-page-head-type=default]~uni-page-wrapper{
height: calc(100% - 70px) !important;
}
uni-page-head .uni-page-head__title{
font-size: 1.125rem !important;
line-height: 40px !important;
font-weight: normal !important;
}
uni-page-head .uni-btn-icon{
font-size: 1.725rem !important;
}
.font_xs{
font-size: 0.825rem !important;
}
.font_xl{
font-size: 1.325rem !important;
}
.mini-type-style{
font-size: 0.8rem !important;
}
.cen_card .label_box .label_info uni-text{
line-height: 1.725 !important;
/* font-size: 1rem !important; */
color: #333;
}
.cen_card .label_box .label_info{
background-color: #eee !important;
}
.popup_box .detail-list{
box-shadow: none !important;
}
.detail-list,.device-detail{
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15) !important;
}
.list_form .uni-table-tr{
background-color: #f0f0f0 !important;
}
.list_form .uni-table-th{
border-bottom: 1px solid #cfcfcf !important;
}
/* yuanswitch
.require_wrap{
padding-top: 0 !important;
}
.require_wrap .require_cell{
line-height: 1.75 !important;
}
.ljh_box .tit_ljh{
font-size: 1.25rem !important;
}
.cen_card .label_box .label_info {
background-color: #eee !important;
}
.cen_card .label_box .label_info uni-image{
width: 48rpx !important;
height: 48rpx !important;
}
.cen_card .label_box .label_info uni-text{
line-height: 1.5 !important;
font-size: 1rem !important;
color: #333;
}
.ljh_box .tit_ljh .state-style, .top_card .state-style{
font-size: 0.8rem !important;
}
.card_task .ljh_box{
margin-bottom: 0 !important;
}
.task_num uni-image{
width: 56rpx !important;
height: 56rpx !important;
}
.task_num uni-text{
font-size: 1rem !important;
}
.pda_receipt_label .label_order uni-text{
font-size: 1rem;
color: #434556;
}
.pda_receipt_label .icon_normal{
width: 56rpx;
height: 56rpx;
}
.pda_receipt_bot .icon_normal{
width: 56rpx;
height: 56rpx;
float: left;
}
.pda_receipt_bot .text_darkblue{
float: left;
font-size: 1rem;
margin-top: 8rpx;
display: inline-block;
}*/
.top_card .text_lightblue{
font-size: 1rem !important;
}
.top_card .cell_box .cell_info{
margin-bottom: 0;
}
.uni-tab-item-title{
font-size: 1.125rem !important;
}
.cell_box .cell_info uni-view{
font-size: 1rem !important;
color: #101010 !important;
}
.cell_box .cell_info .text_lightblue{
font-size: 0.875rem !important;
color: #6A6E7A !important;
}
.cell_box .cell_info .text_black{
font-size: 1.125rem !important;
}
.scan_float uni-image{
margin-top: 18rpx !important;
}
.scan_float uni-view{
font-size: 0.875rem !important;
letter-spacing: 1px;
}
.new_btn_bot .new_save_btn,.popup_box .pop_title uni-text{
font-size: 1rem !important;
}
.bot_card{
background-color: #eee !important;
}
.bot_card_item uni-text{
font-size: 0.8rem !important;
font-weight: 600;
}
.summary_state .state_point{
font-size: 1rem !important;
}
.summary_item label{
float: left;
}
.summary_item uni-text{
font-size: 1.125rem !important;
font-weight: normal !important;
float: left;
}
/* popup */
.popup_box{
box-sizing: border-box;
}
.popup_box .uni-steps{
width:100%;
overflow-x: hidden;
}
.popup_box .uni-steps__row-line-item{
height: 60rpx !important;
}
.popup_box .uni-steps__row-text-container{
margin-top: 0 !important;
}
.popup_box,.uni-popup .uni-scroll-view-content{
border-top-left-radius:30rpx !important;
border-top-right-radius:30rpx !important;
}
.popup_box .pop_title{
font-size: 1.125rem !important;
letter-spacing: 1px;
}
.popup_box .pop_tab .tab_tit{
font-size: 0.875rem !important;
}
.popup_box .pop_tab .tab_tit_active{
font-size: 1rem !important;
}
.popup_box .pop_tab .tab_info{
min-height: 200rpx !important;
}
.popup_box .pop_tab .tab_info uni-textarea{
height: 200rpx;
}
.popup_box .pop_tab .tab_info uni-button{
font-size: 0.875rem !important;
letter-spacing: 1px;
}
/*底部按钮*/
.new_btn_bot .new_save_btn{
background-color: #E4EAFF !important;
height: 50px;
line-height: 50px;
}
.new_btn_bot .new_clear_btn{
font-size: 1rem !important;
line-height: 50px;
}
.scroll-detail{
padding-bottom: 70px !important;
}
.count_shadow,.device-detail{
box-shadow: 0 0 20rpx rgba(0,0,0,0.2);
}
.list_info {
padding: 0 20rpx 20rpx;
margin-top: 0;
}
.uni-scroll-view-content .creattp_list{
width: 100% !important;
}
.creattp_list .uni-list .list_cell uni-text{
font-weight: bold;
}
.popup_box .scan_scroll{
max-height: 44vh !important;
}
}

262
fe/PDA/common/airport.js

@ -0,0 +1,262 @@
export default {
"list": [{
"letter": "A",
"data": [
"阿克苏机场",
"阿拉山口机场",
"阿勒泰机场",
"阿里昆莎机场",
"安庆天柱山机场",
"澳门国际机场"
]
}, {
"letter": "B",
"data": [
"保山机场",
"包头机场",
"北海福成机场",
"北京南苑机场",
"北京首都国际机场"
]
}, {
"letter": "C",
"data": [
"长白山机场",
"长春龙嘉国际机场",
"常德桃花源机场",
"昌都邦达机场",
"长沙黄花国际机场",
"长治王村机场",
"常州奔牛机场",
"成都双流国际机场",
"赤峰机场"
]
}, {
"letter": "D",
"data": [
"大理机场",
"大连周水子国际机场",
"大庆萨尔图机场",
"大同东王庄机场",
"达州河市机场",
"丹东浪头机场",
"德宏芒市机场",
"迪庆香格里拉机场",
"东营机场",
"敦煌机场"
]
}, {
"letter": "E",
"data": [
"鄂尔多斯机场",
"恩施许家坪机场",
"二连浩特赛乌苏国际机场"
]
}, {
"letter": "F",
"data": [
"阜阳西关机场",
"福州长乐国际机场"
]
}, {
"letter": "G",
"data": [
"赣州黄金机场",
"格尔木机场",
"固原六盘山机场",
"广元盘龙机场",
"广州白云国际机场",
"桂林两江国际机场",
"贵阳龙洞堡国际机场"
]
}, {
"letter": "H",
"data": [
"哈尔滨太平国际机场",
"哈密机场",
"海口美兰国际机场",
"海拉尔东山国际机场",
"邯郸机场",
"汉中机场",
"杭州萧山国际机场",
"合肥骆岗国际机场",
"和田机场",
"黑河机场",
"呼和浩特白塔国际机场",
"淮安涟水机场",
"黄山屯溪国际机场"
]
}, {
"letter": "I",
"data": []
}, {
"letter": "J",
"data": [
"济南遥墙国际机场",
"济宁曲阜机场",
"鸡西兴凯湖机场",
"佳木斯东郊机场",
"嘉峪关机场",
"锦州小岭子机场",
"景德镇机场",
"井冈山机场",
"九江庐山机场",
"九寨黄龙机场"
]
}, {
"letter": "K",
"data": [
"喀什机场",
"克拉玛依机场",
"库车龟兹机场",
"库尔勒机场",
"昆明巫家坝国际机场"
]
}, {
"letter": "L",
"data": [
"拉萨贡嘎机场",
"兰州中川机场",
"丽江三义机场",
"黎平机场",
"连云港白塔埠机场",
"临沧机场",
"临沂机场",
"林芝米林机场",
"柳州白莲机场",
"龙岩冠豸山机场",
"泸州蓝田机场",
"洛阳北郊机场"
]
}, {
"letter": "M",
"data": [
"满洲里西郊机场",
"绵阳南郊机场",
"漠河古莲机场",
"牡丹江海浪机场"
]
}, {
"letter": "N",
"data": [
"南昌昌北国际机场",
"南充高坪机场",
"南京禄口国际机场",
"南宁吴圩机场",
"南通兴东机场",
"南阳姜营机场",
"宁波栎社国际机场"
]
}, {
"letter": "O",
"data": []
}, {
"letter": "P",
"data": [
"普洱思茅机场"
]
}, {
"letter": "Q",
"data": [
"齐齐哈尔三家子机场",
"秦皇岛山海关机场",
"青岛流亭国际机场",
"衢州机场",
"泉州晋江机场"
]
}, {
"letter": "R",
"data": [
"日喀则和平机场"
]
}, {
"letter": "S",
"data": [
"三亚凤凰国际机场",
"汕头外砂机场",
"上海虹桥国际机场",
"上海浦东国际机场",
"深圳宝安国际机场",
"沈阳桃仙国际机场",
"石家庄正定国际机场",
"苏南硕放国际机场"
]
}, {
"letter": "T",
"data": [
"塔城机场",
"太原武宿国际机场",
"台州路桥机场 (黄岩机场)",
"唐山三女河机场",
"腾冲驼峰机场",
"天津滨海国际机场",
"通辽机场",
"铜仁凤凰机场"
]
}, {
"letter": "U",
"data": []
}, {
"letter": "V",
"data": []
}, {
"letter": "W",
"data": [
"万州五桥机场",
"潍坊机场",
"威海大水泊机场",
"文山普者黑机场",
"温州永强国际机场",
"乌海机场",
"武汉天河国际机场",
"乌兰浩特机场",
"乌鲁木齐地窝堡国际机场",
"武夷山机场",
"梧州长洲岛机场"
]
}, {
"letter": "X",
"data": [
"西安咸阳国际机场",
"西昌青山机场",
"锡林浩特机场",
"西宁曹家堡机场",
"西双版纳嘎洒机场",
"厦门高崎国际机场",
"香港国际机场",
"襄阳刘集机场",
"兴义机场",
"徐州观音机场"
]
}, {
"letter": "Y",
"data": [
"延安二十里堡机场",
"盐城机场",
"延吉朝阳川机场",
"烟台莱山国际机场",
"宜宾菜坝机场",
"宜昌三峡机场",
"伊春林都机场",
"伊宁机场",
"义乌机场",
"银川河东机场",
"永州零陵机场",
"榆林榆阳机场",
"玉树巴塘机场",
"运城张孝机场"
]
}, {
"letter": "Z",
"data": [
"湛江机场",
"昭通机场",
"郑州新郑国际机场",
"芷江机场",
"重庆江北国际机场",
"中卫香山机场",
"舟山朱家尖机场",
"珠海三灶机场"
]
}]
}

134
fe/PDA/common/array.js

@ -0,0 +1,134 @@
//出库原因
export function getIssueReasonArray() {
let array = [{
text: '原因1',
value: '1'
}, {
text: '原因2',
value: '2'
}, {
text: '原因3',
value: '3'
}];
return array;
}
//入库原因
export function getReceiptReasonArray() {
let array = [{
text: '原因1',
value: '1'
}, {
text: '原因2',
value: '2'
}, {
text: '原因3',
value: '3'
}];
return array;
}
// 检验任务,不合格原因
export function getFailedReasonArray() {
let array = [{
text: '外观不良',
value: '外观不良'
}, {
text: '尺寸超差',
value: '尺寸超差'
}, {
text: '功能失效',
value: '功能失效'
}, {
text: '标签不符',
value: '标签不符'
}, {
text: '检验报告异常',
value: '检验报告异常'
}, {
text: '其他',
value: '其他'
}]
return array;
}
// 检验任务,下一步动作
export function getNextStepArray() {
let array = [{
text: '整批不合格',
value: 1
}, {
text: '挑选',
value: 2
}, {
text: '部分合格',
value: 3
}]
return array;
}
// 库存状态字典项
export function getInventoryStatusArray() {
let array = [{
text: '待检',
value: 1
}, {
text: '合格',
value: 2
}, {
text: '不合格',
value: 3
}, {
text: '隔离',
value: 4
}, {
text: '报废',
value: 5
}, {
text: '冻结',
value: 6
}]
return array;
}
//隔离库存处理操作
export function getHoldStatusArray() {
let array = [{
text: '隔离转合格',
value: 1
}, {
text: '隔离出库',
value: 2
}, {
text: '合格转隔离',
value: 3
}]
return array;
}
// 检验任务,不合格原因
export function getReturnReasonArray() {
let array = [{
text: '外观不良',
value: '外观不良'
}, {
text: '尺寸超差',
value: '尺寸超差'
}, {
text: '功能失效',
value: '功能失效'
}, {
text: '标签不符',
value: '标签不符'
}, {
text: '检验报告异常',
value: '检验报告异常'
}, {
text: '其他',
value: '其他'
}]
return array;
}

328
fe/PDA/common/basic.js

@ -0,0 +1,328 @@
let maxPageSize = 1000;
export { maxPageSize }
//任务状态
export function getJobStatuStyle(val) {
if (val == 0) return 'unk'
else if (val == 1) return 'open'
else if (val == 2) return 'pending'
else if (val == 3) return 'completed'
else if (val == 4) return 'close'
}
//任务状态
//open pending completed close
export function getJobStatuDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '待处理'
else if (val == 2) return '进行中'
else if (val == 3) return '完成'
else if (val == 4) return '关闭'
else return '其他'
}
//检验任务状态
export function getInspectTypeStyle(val) {
if (val == 0) return 'unk'
else if (val == 1) return 'exempt'
else if (val == 2) return 'full'
else if (val == 3) return 'sampling'
else if (val == 4) return 'pick'
else return 'other'
}
//open pending completed close
export function getInspectTypeDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '免检'
else if (val == 2) return '全检'
else if (val == 3) return '抽检'
else if (val == 4) return '挑选'
else return '其他'
}
//库存状态
export function getInventoryTypeStyle(val) {
if (val == 0) return 'unk'
else if (val == 1) return 'insp'
else if (val == 2) return 'ok'
else if (val == 3) return 'nok'
else if (val == 4) return 'hold'
else if (val == 5) return 'scarp'
else if (val == 6) return 'frozen'
else if (val == 31) return 'nok'
else return 'other'
}
//库存状态
export function getInventoryStatusDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '待检'
else if (val == 2) return '合格'
else if (val == 3) return '不合格'
else if (val == 4) return '隔离'
else if (val == 5) return '报废'
else if (val == 6) return '冻结'
else if (val == 31) return '不合格'
// else if (val == 31) return '目检不合格'
else return '其他'
}
//零件状态
export function getItemTypeStyle(val) {
if (val == 0) return 'unk'
else if (val == 1) return 'active'
else if (val == 2) return 'hold'
else if (val == 3) return 'new'
else if (val == 4) return 'plan'
else if (val == 5) return 'disable'
else return 'other'
}
//零件状态
export function getItemStatusDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '可用'
else if (val == 2) return '隔离'
else if (val == 3) return '新增'
else if (val == 4) return '规划'
else if (val == 5) return '禁用'
else return '其他'
}
//盘点状态
export function getCountStageTypeStyle(val) {
if (val == 0) return 'unk'
else if (val == 1) return 'initial'
else if (val == 2) return 'afresh'
else if (val == 3) return 'supervision'
else return 'other'
}
//盘点状态
export function getCountStageDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '初盘'
else if (val == 2) return '重盘'
else if (val == 3) return '监盘'
else return '其他'
}
//盘点计划类型
export function getCheckTypeDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '周期盘点'
else if (val == 2) return '物理盘点'
else return '其他'
}
//盘点方式
export function getCountMethodDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '库位盘点'
else if (val == 2) return '物品盘点'
else if (val == 3) return '库位零件盘点'
else return '其他'
}
//获取库位类型
export function getLocationType(val) {
if (val == 0) return 'unk'
else if (val == 1) return 'inspect'
else if (val == 2) return 'raw'
else if (val == 3) return 'semi'
else if (val == 4) return 'fg'
else if (val == 5) return 'wip'
else if (val == 6) return 'hold'
else if (val == 7) return 'scrap'
else if (val == 8) return 'noc'
else if (val == 9) return 'overflow'
else if (val == 10) return 'customer'
else return 'other'
}
//获取库位类型描述
export function getLocationTypeDesc(val) {
if (val == 0) return '未知'
else if (val == 1) return '待检库'
else if (val == 2) return '原料库'
else if (val == 3) return '半成品库'
else if (val == 4) return '成品库'
else if (val == 5) return '线边库'
else if (val == 6) return '隔离库'
else if (val == 7) return '报废库'
else if (val == 8) return '不合格品库'
else if (val == 9) return '溢出库'
else if (val == 10) return '客户库'
else return '其他'
}
//获取库位类型描述
export function getJobType(val) {
if (val == 0) return 'uno'
else if (val == 1) return 'PurchaseReceiptJob' //采购收货
else if (val == 2) return 'PurchaseReturnJob' //采购退货任务
else if (val == 3) return 'InspectJob' //检验任务
else if (val == 4) return 'PutawayJob' //上架任务
else if (val == 5) return 'ProductReceiveJob' //完工收货任务
else if (val == 6) return 'IssueJob' //发料任务
else if (val == 7) return 'DeliverJob' //发货任务
else if (val == 8) return 'CheckJob' //校验任务
else if (val == 9) return 'CountJob' //盘点任务
else return 'Other'
}
//提示是否消息
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 compare(key) {
return function(a, b) {
var val1 = a[key];
var val2 = b[key];
return val2 - val1;
}
}
export function compareDesc(key) {
return function(a, b) {
var val1 = a[key];
var val2 = b[key];
return val1 - val2;
}
}
export function goHome() {
uni.reLaunch({
url: '../index/index'
})
}
export function getCurrDate() {
var date = new Date();
return getDate(date);
}
export function getCurrDateTime() {
var date = new Date();
return getDate(date) + " " + getTime(date);
}
export function getISODateTime() {
var date = new Date();
return getDate(date) + "T" + getTime(date) + "Z";
}
//格式化处理
export function dateFormat(time) {
let date = new Date(time);
return getDate(date) + " " + getTime(date);
}
//获取日期部分
export function getDate(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;
}
//获取时间部分
export function getTime(date) {
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
// 拼接
return hours + ":" + minutes + ":" + seconds;
}
//将20220713转成2022-07-13
export function toYYYY_MM_DD(value) {
return value.substring(0, 4) + "-" + value.substring(4, 6) + "-" + value.substring(6, 8)
}
export function getRootFontSize() {
const self = this;
var fontSize = getApp().globalData.rootFontSize;
if (fontSize) {
return fontSize;
} else {
fontSize = uni.getStorageSync('root_font_size');
if (fontSize) {
getApp().globalData.rootFontSize = fontSize;
} else {
fontSize = '20px'; //默认字体大小
self.setRootFontSize(fontSize);
}
return fontSize;
}
}
export function getRemoveOption() {
let options = [{
text: '移除',
style: {
backgroundColor: '#F56C6C'
}
}]
return options;
}
export function setRootFontSize(fontSize) {
uni.setStorageSync('root_font_size', fontSize);
getApp().globalData.rootFontSize = fontSize;
}
export function scanErrorAudio() {
var music = null;
music = uni.createInnerAudioContext(); //创建播放器对象
music.src ="../../static/video/error.wav";
music.volume=1;
music.play(); //执行播放
music.onEnded(() => {
//播放结束
music = null;
});
}
export function newMessageAudio() {
var music = null;
music = uni.createInnerAudioContext(); //创建播放器对象
music.src ="../../static/video/error.wav";
music.volume=1;
music.play(); //执行播放
music.onEnded(() => {
//播放结束
music = null;
});
}
export function vibrate() {
uni.vibrateLong({
success:function(){
}
})
}

33
fe/PDA/common/common.js

@ -0,0 +1,33 @@
export default {
created() {
const self = this;
},
mounted() {
const self = this;
},
methods: {
//设置字体
getRootFontSize(){
const self = this;
var fontSize = getApp().globalData.rootFontSize;
if(fontSize){
return fontSize;
}else{
fontSize = uni.getStorageSync('root_font_size');
if(fontSize){
getApp().globalData.rootFontSize=fontSize;
}else{
fontSize='20px';//默认字体大小
self.setRootFontSize(fontSize);
}
return fontSize;
}
},
setRootFontSize(fontSize){
uni.setStorageSync('root_font_size',fontSize);
getApp().globalData.rootFontSize=fontSize;
},
}
}

26
fe/PDA/common/config.js

@ -0,0 +1,26 @@
let url_config = ""
let jsApiList = [
'biz.cspace.saveFile', //钉盘保存文件
'biz.map.search', //位置搜索
'device.geolocation.get', //定位
'biz.ding.create', //创建ding消息
'device.base.getUUID', //uuid
'biz.contact.choose', //联系人
'biz.contact.complexPicker', //选人和部门
'biz.contact.departmentsPicker', //选部门
'biz.chat.chooseConversationByCorpId', //会话选择
"biz.contact.chooseMobileContacts", //手机联系人
];
let option = {
corpId: '', //企业ID
agentId: '', //微应用ID
serverPath: url_config, //接口基础地址
jsApiList: jsApiList, //鉴权列表
isDebug: false //判断是否alert
};
export default {
url_config,
option
}

97
fe/PDA/common/graceChecker.js

@ -0,0 +1,97 @@
/**
数据验证表单验证
来自 grace.hcoder.net
作者 hcoder 深海
*/
export default {
error:'',
check : function (data, rule){
for(var i = 0; i < rule.length; i++){
if (!rule[i].checkType){return true;}
if (!rule[i].name) {return true;}
if (!rule[i].errorMsg) {return true;}
if (!data[rule[i].name]) {this.error = rule[i].errorMsg; return false;}
switch (rule[i].checkType){
case 'string':
var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
break;
case 'int':
var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
break;
break;
case 'between':
if (!this.isNumber(data[rule[i].name])){
this.error = rule[i].errorMsg;
return false;
}
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'betweenD':
var reg = /^-?[1-9][0-9]?$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'betweenF':
var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
if (!reg.test(data[rule[i].name])){this.error = rule[i].errorMsg; return false;}
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'same':
if (data[rule[i].name] != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;}
break;
case 'notsame':
if (data[rule[i].name] == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; }
break;
case 'email':
var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'phoneno':
var reg = /^1[0-9]{10,10}$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'zipcode':
var reg = /^[0-9]{6}$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'reg':
var reg = new RegExp(rule[i].checkRule);
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'in':
if(rule[i].checkRule.indexOf(data[rule[i].name]) == -1){
this.error = rule[i].errorMsg; return false;
}
break;
case 'notnull':
if(data[rule[i].name] == null || data[rule[i].name].length < 1){this.error = rule[i].errorMsg; return false;}
break;
}
}
return true;
},
isNumber : function (checkVal){
var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
return reg.test(checkVal);
}
}

352
fe/PDA/common/html-parser.js

@ -0,0 +1,352 @@
/*
* HTML5 Parser By Sam Blowes
*
* Designed for HTML5 documents
*
* Original code by John Resig (ejohn.org)
* http://ejohn.org/blog/pure-javascript-html-parser/
* Original code by Erik Arvidsson, Mozilla Public License
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
*
* ----------------------------------------------------------------------------
* License
* ----------------------------------------------------------------------------
*
* This code is triple licensed using Apache Software License 2.0,
* Mozilla Public License or GNU Public License
*
* ////////////////////////////////////////////////////////////////////////////
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* ////////////////////////////////////////////////////////////////////////////
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Simple HTML Parser.
*
* The Initial Developer of the Original Code is Erik Arvidsson.
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
* Reserved.
*
* ////////////////////////////////////////////////////////////////////////////
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ----------------------------------------------------------------------------
* Usage
* ----------------------------------------------------------------------------
*
* // Use like so:
* HTMLParser(htmlString, {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* });
*
* // or to get an XML string:
* HTMLtoXML(htmlString);
*
* // or to get an XML DOM Document
* HTMLtoDOM(htmlString);
*
* // or to inject into an existing document/DOM node
* HTMLtoDOM(htmlString, document);
* HTMLtoDOM(htmlString, document.body);
*
*/
// Regular Expressions for parsing tags and attributes
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
// fixed by xxx 将 ins 标签从块级名单中移除
var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
// (and which close themselves)
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
var special = makeMap('script,style');
function HTMLParser(html, handler) {
var index;
var chars;
var match;
var stack = [];
var last = html;
stack.last = function () {
return this[this.length - 1];
};
while (html) {
chars = true; // Make sure we're not in a script or style element
if (!stack.last() || !special[stack.last()]) {
// Comment
if (html.indexOf('<!--') == 0) {
index = html.indexOf('-->');
if (index >= 0) {
if (handler.comment) {
handler.comment(html.substring(4, index));
}
html = html.substring(index + 3);
chars = false;
} // end tag
} else if (html.indexOf('</') == 0) {
match = html.match(endTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(endTag, parseEndTag);
chars = false;
} // start tag
} else if (html.indexOf('<') == 0) {
match = html.match(startTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(startTag, parseStartTag);
chars = false;
}
}
if (chars) {
index = html.indexOf('<');
var text = index < 0 ? html : html.substring(0, index);
html = index < 0 ? '' : html.substring(index);
if (handler.chars) {
handler.chars(text);
}
}
} else {
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
if (handler.chars) {
handler.chars(text);
}
return '';
});
parseEndTag('', stack.last());
}
if (html == last) {
throw 'Parse Error: ' + html;
}
last = html;
} // Clean up any remaining tags
parseEndTag();
function parseStartTag(tag, tagName, rest, unary) {
tagName = tagName.toLowerCase();
if (block[tagName]) {
while (stack.last() && inline[stack.last()]) {
parseEndTag('', stack.last());
}
}
if (closeSelf[tagName] && stack.last() == tagName) {
parseEndTag('', tagName);
}
unary = empty[tagName] || !!unary;
if (!unary) {
stack.push(tagName);
}
if (handler.start) {
var attrs = [];
rest.replace(attr, function (match, name) {
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
attrs.push({
name: name,
value: value,
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
});
});
if (handler.start) {
handler.start(tagName, attrs, unary);
}
}
}
function parseEndTag(tag, tagName) {
// If no tag name is provided, clean shop
if (!tagName) {
var pos = 0;
} // Find the closest opened tag of the same type
else {
for (var pos = stack.length - 1; pos >= 0; pos--) {
if (stack[pos] == tagName) {
break;
}
}
}
if (pos >= 0) {
// Close all the open elements, up the stack
for (var i = stack.length - 1; i >= pos; i--) {
if (handler.end) {
handler.end(stack[i]);
}
} // Remove the open elements from the stack
stack.length = pos;
}
}
}
function makeMap(str) {
var obj = {};
var items = str.split(',');
for (var i = 0; i < items.length; i++) {
obj[items[i]] = true;
}
return obj;
}
function removeDOCTYPE(html) {
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
}
function parseAttrs(attrs) {
return attrs.reduce(function (pre, attr) {
var value = attr.value;
var name = attr.name;
if (pre[name]) {
pre[name] = pre[name] + " " + value;
} else {
pre[name] = value;
}
return pre;
}, {});
}
function parseHtml(html) {
html = removeDOCTYPE(html);
var stacks = [];
var results = {
node: 'root',
children: []
};
HTMLParser(html, {
start: function start(tag, attrs, unary) {
var node = {
name: tag
};
if (attrs.length !== 0) {
node.attrs = parseAttrs(attrs);
}
if (unary) {
var parent = stacks[0] || results;
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
} else {
stacks.unshift(node);
}
},
end: function end(tag) {
var node = stacks.shift();
if (node.name !== tag) console.error('invalid state: mismatch end tag');
if (stacks.length === 0) {
results.children.push(node);
} else {
var parent = stacks[0];
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
}
},
chars: function chars(text) {
var node = {
type: 'text',
text: text
};
if (stacks.length === 0) {
results.children.push(node);
} else {
var parent = stacks[0];
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
}
},
comment: function comment(text) {
var node = {
node: 'comment',
text: text
};
var parent = stacks[0];
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
}
});
return results.children;
}
export default parseHtml;

112
fe/PDA/common/message.js

@ -0,0 +1,112 @@
import * as dd from 'dingtalk-jsapi';
import store from '@/store/index'
let showAlert=true
let message = {
error: function (msg) { //进入项目初始化配置
uni.showToast({
title: msg,
icon: "none"
});
},
alert:function (message) {
return new Promise((resolve, reject) => {
if (showAlert){
dd.device.notification.alert({
message: message,
title: "提示",
buttonName: "收到",
onSuccess : function(res) {
// 调用成功时回调
console.log(res)
},
onFail : function(err) {
// 调用失败时回调
console.log(err)
}
});
}
})
}
}
let selectD = {
selectPeo: function (option) {
return new Promise((resolve, reject) => {
dd.biz.contact.complexPicker({
title: option.title ? option.title : "选择人员", //标题
corpId: store.state.corpId, //企业的corpId
multiple: option.multiple ? option.multiple : true, //是否多选
limitTips: option.limitTips ? option.limitTips : "超出了", //超过限定人数返回提示
maxUsers: option.maxUsers ? option.maxUsers : 100, //最大可选人数
pickedUsers: option.pickedUsers ? option.pickedUsers : [], //已选用户
pickedDepartments: option.pickedDepartments ? option.pickedDepartments :[], //已选部门
disabledUsers: option.disabledUsers ? option.disabledUsers :[], //不可选用户
disabledDepartments: option.disabledDepartments ? option.disabledDepartments :[], //不可选部门
requiredUsers: option.requiredUsers ? option.requiredUsers :[], //必选用户(不可取消选中状态)
requiredDepartments: option.requiredDepartments ? option.requiredDepartments :[], //必选部门(不可取消选中状态)
appId: store.state.agentId, //微应用Id,企业内部应用查看AgentId
permissionType: "GLOBAL", //可添加权限校验,选人权限,目前只有GLOBAL这个参数
responseUserOnly: true, //返回人,或者返回人和部门
startWithDepartmentId: 0, //仅支持0和-1
onSuccess: function (result) {
// alert(JSON.stringify(result))
resolve(result);
/**
{
selectedCount:1, //选择人数
users:[{"name":"","avatar":"","emplId ":""}]//返回选人的列表,列表中的对象包含name(用户名),avatar(用户头像),emplId(用户工号)三个字段
departments:[{"id":,"name":"","number":}]//返回已选部门列表,列表中每个对象包含id(部门id)、name(部门名称)、number(部门人数)
}
*/
},
onFail: function (err) {
alert("唤起联系人失败");
reject(err)
}
});
})
},
selectDept: function (option) {
return new Promise((resolve, reject) => {
dd.biz.contact.departmentsPicker({
title: option.title ? option.title : "选择部门", //标题
corpId: store.state.corpId, //企业的corpId
multiple: option.multiple ? option.multiple : true, //是否多选
limitTips: option.limitTips ? option.limitTips : "超出了", //超过限定人数返回提示
maxDepartments: option.maxDepartments ? option.maxDepartments : 100, //最大可选部门
pickedDepartments: option.pickedDepartments ? option.pickedDepartments :[], //已选部门
disabledDepartments: option.disabledDepartments ? option.disabledDepartments :[], //不可选部门
requiredDepartments: option.requiredDepartments ? option.requiredDepartments :[], //必选部门(不可取消选中状态)
appId: store.state.agentId, //微应用Id,企业内部应用查看AgentId
permissionType: "GLOBAL", //可添加权限校验,选人权限,目前只有GLOBAL这个参数
onSuccess: function (result) {
resolve(result);
/**
{
"userCount":10, //选择人数。
"departments":[
{
"number":10,
"name":"班车2",
"id":405921063
}
], //返回已选部门列表,列表中每个对象包含id (部门id)、name (部门名称)、number (部门人数)。
"departmentsCount":1 //选择的部门数。
}
*/
},
onFail: function (err) {
alert("唤起部门失败");
reject(err)
}
});
})
},
}
export default {
message,
selectD
}

5
fe/PDA/common/modelConfig.js

@ -0,0 +1,5 @@
let maxPageSize = 10;
export default{
maxPageSize
}

1863
fe/PDA/common/new_style.css

File diff suppressed because it is too large

697
fe/PDA/common/pdabasic.css

@ -0,0 +1,697 @@
/*
.pda-list {
padding: 10rpx 10rpx;
box-sizing: border-box;
display: flex;
width: 100%;
flex-direction: row;
}
*/
/* 列表 */
.pda-list {
padding: 0 20rpx;
box-sizing: border-box;
background-color: #FFFFFF;
position: relative;
width: 100%;
display: flex;
flex-direction: column;
border-radius: 16rpx;
margin-bottom: 120rpx;
}
.pda-list:after {
position: absolute;
z-index: 10;
/* right: 0; */
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.pda-list-cell {
position: relative;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #eee;
padding: 10rpx 0;
}
.pda-list-cell:last-child {
border-bottom: 0;
}
.pda-list-cell-left {
white-space: nowrap;
/* padding: 0 10rpx; */
}
.pda-list-cell-db,
.pda-list-cell-right {
flex: 1;
}
.pda-list-cell .pda-list-cell-db .uni-input-input {
font-size: .875rem;
}
.pda-list-cell .uni-easyinput__content-input,
.pda-list-cell .uni-input-placeholder {
height: 2rem;
line-height: 2rem;
}
.pda-list-cell .placeholder {
color: #999 !important;
font-size: 0.875rem;
padding-left: 10rpx;
}
.pda-list-cell .uni-label {
color: #434556;
}
.list_locode .uni-collapse-item__title-box {
font-weight: bold !important;
}
.display-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.list-body {
/* height: 84rpx; */
display: flex;
flex: 1;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
overflow: hidden;
}
.list-text-top {
width: 100%;
color: #000;
font-weight: bolder;
/* line-height: 36rpx; */
/* font-size: 30rpx; */
}
.list-text-bottom {
/* line-height: 30rpx; */
/* font-size: 26rpx; */
color: #8f8f94;
}
/* 改为detail-content */
/* margin-bottom: 20rpx; */
.device-detail {
padding: 20rpx !important;
margin: 20rpx;
border-radius: 16rpx;
background-color: #fff;
color: #666666;
line-height: 1.5;
overflow: hidden;
}
.list-style {
margin-bottom: 0rpx;
border-radius: 16rpx;
background-color: #FFFFFF;
color: #666666;
line-height: 1.5;
}
.border-font {
color: #000;
font-weight: bolder;
}
.space-between {
-webkit-justify-content: space-between;
justify-content: space-between;
}
.accept-button {
width: 30%;
font-size: 16px;
background-color: #7ac756;
color: #ffffff;
}
.bigsave-button {
width: 80%;
font-size: 16px;
background-color: #007AFF;
color: #ffffff;
}
.save-button {
width: 30%;
font-size: 16px;
background-color: #007AFF;
color: #ffffff;
}
.scroll-detail {
overflow: hidden;
padding-bottom: 60px;
height: 480px;
/* 没有高度不可以回到顶部 */
/* background-color: #ffffff; */
}
.scrollView {
overflow: hidden;
padding-bottom: 50px
}
.scroll-Y {
/* height: 70ux; */
padding-bottom: 50px
}
.bottom1 {
position: fixed;
width: 100%;
/* padding: 10rpx 10rpx; */
left: 0;
/* right: 0; */
bottom: 0;
background-color: #ffffff;
}
.bottom {
position: fixed;
display: flex;
width: 100%;
padding: 10rpx 10rpx;
left: 0;
/* right: 0; */
bottom: 0;
background-color: #ffffff;
}
.pars-num {
/* font-size: 26rpx; */
}
.right-width {
text-align: center;
width: 100rpx;
}
.state-style {
float: left;
margin-top: 10rpx;
/* border-radius: 16rpx;
padding: 0rpx 10rpx; */
/* line-height: 50rpx;
height: 50rpx; */
/* width: 120rpx;
display: flex;
flex-direction: column;
align-items: center; */
/* 垂直居中 */
}
.uni-popup-view {
background-color: #fff;
border-radius: 10px;
}
.uni-popup-button-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 10px 15px;
}
.uni-popup-button {
flex: 1;
/* // border-radius: 50px;
// color: #666; */
/* font-size: 16px; */
}
/* 任务状态 */
/* 打开 */
.open {
background-color: #409EFF;
color: #FFFFFF;
}
/* 进行中 */
.pending {
background-color: #5FCB94;
color: #FFFFFF;
}
/* 完成 */
.completed {
background-color: #E6A23C;
color: #FFFFFF;
}
/* 关闭 */
.close {
background-color: #F56C6C;
color: #FFFFFF;
}
/* 关闭 */
.other {
background-color: #808080;
color: #FFFFFF;
}
/* 其他 */
.unk {
background-color: #ececec;
color: #666;
}
/* 检验任务状态 */
/* 免检 */
.exempt {
background-color: #409EFF;
color: #FFFFFF;
}
/* 全检 */
.full {
background-color: #67C23A;
color: #FFFFFF;
}
/* 抽检 */
.sampling {
background-color: #E6A23C;
color: #FFFFFF;
}
/* 挑检 */
.pick {
background-color: #F56C6C;
color: #FFFFFF;
}
/* 库存状态 */
.uni-link {
background-color: #BD2C00;
color: #BD2C00 !important;
}
.insp {
background-color: #409EFF;
color: #409EFF !important;
}
.ok {
color: #67C23A !important;
background-color: #67C23A;
}
.nok {
background-color: #FF2424;
color: #FF2424 !important;
}
.hold {
background-color: #EC9C00;
color: #EC9C00 !important;
}
.scarp {
background-color: #999;
color: #999 !important;
}
.frozen {
background-color: #FF581D;
color: #FF581D !important;
}
.pass {
color: #67C23A !important;
}
.unPass {
color: #FF2424 !important;
}
.inspect {
background-color: #F6CB61;
color: #FFFFFF;
}
.raw {
background-color: #2DA8D8;
color: #FFFFFF;
}
.semi {
background-color: #EDAE50;
color: #FFFFFF;
}
.fg {
background-color: #078343;
color: #FFFFFF;
}
.wip {
background-color: #FC85FE;
color: #FFFFFF;
}
/* .hold{
} */
.scrap {
background-color: #E30016;
color: #FFFFFF;
}
.noc {
background-color: #C31223;
color: #FFFFFF;
}
.overflow {
background-color: #7D1EDC;
color: #FFFFFF;
}
.customer {
background-color: #5A7CF3;
color: #FFFFFF;
}
/* //零件状态
export function getItemTypeStyle(val) {
if (val == 0) return 'active'
else if (val == 1) return 'hold'
else if (val == 2) return 'new'
else if (val == 3) return 'plan'
else if (val == 4) return 'disable'
else return 'other'
}
*/
/* 零件状态 */
.active {
background-color: #5FCB94;
color: #FFFFFF;
}
.hold {
background-color: #FF4206;
color: #FFFFFF;
}
.new {
background-color: #E6A23C;
color: #FFFFFF;
}
.plan {
background-color: #2677F9;
color: #FFFFFF;
}
.disable {
background-color: #666;
color: #FFFFFF;
}
/* 任务编号字体 */
.text-number {
color: #000;
font-weight: bolder;
}
/* 零件编号字体 */
.text-itemcode {
/* font-size: 26rpx; */
color: #000;
font-weight: bolder;
}
.text-desc {
color: #8f8f91;
/* font-size: 22rpx; */
}
/* 零件编号字体 */
.text-bolder {
color: #000;
font-weight: bolder;
}
.detail-list {
background-color: #fff;
padding: 0;
margin: 20rpx;
border-radius: 16rpx;
overflow: hidden;
}
.detail-content {
position: relative;
flex: 1;
/* font-size: 26rpx; */
color: #101010;
}
.example-body {
background-color: #FFFFFF;
}
.result-box {
text-align: center;
padding: 20px 0px;
/* font-size: 16px; */
}
.toptext {
padding-left: 20upx;
line-height: 80upx;
}
.numberstyle {
display: flex;
/* flex-direction: row-reverse; */
border-bottom: 10upx solid #EEEEEE;
width: 200upx;
padding-bottom: 20upx;
}
.input {
height: 20rpx;
padding: 0rpx 8rpx;
line-height: 50rpx;
/* font-size: 25rpx; */
background: #FFF;
border-radius: 4rpx;
flex: 1;
}
.mini-type-style {
vertical-align: middle;
font-size: 0.725rem;
margin-right: 6rpx;
border-radius: 4rpx;
padding: 4rpx 8rpx;
/* width: 80rpx; */
/* height: 46rpx;
min-width: 80rpx;
display: flex;
flex-direction: column; */
}
.text-color {
color: #000;
font-weight: bolder;
}
.tabs {
flex: 1;
flex-direction: column;
overflow: hidden;
/* background-color: #ffffff; */
}
/* .scroll-h {
touch-action: none;
width: 100%;
height: 100rpx;
flex-direction: row;
white-space: nowrap;
justify-content: center;
} */
.line-h {
height: 1rpx;
background-color: #cccccc;
}
.uni-tab-item {
/* #ifndef APP-PLUS */
display: inline-block;
/* #endif */
flex-wrap: nowrap;
padding: 0 30rpx;
}
.uni-tab-item-title {
position: relative;
color: #555;
/* font-size: 24rpx; */
height: 100rpx;
line-height: 100rpx;
flex-wrap: nowrap;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
}
.uni-tab-item-title-active {
color: #101010;
font-weight: bold;
}
.uni-tab-item-title-active:after {
left: 50%;
transform: translateX(-50%);
position: absolute;
bottom: -20rpx;
display: inline-block;
content: "";
width: 40rpx;
height: 8rpx;
background-color: #5a7cf3;
border-radius: 5px;
}
/* .blece {
padding: 10upx;
color: #111111;
border-bottom: 2px solid #f5f5f5;
display: flex;
flex-wrap: wrap;
} */
.conbox {
padding: 10rpx 0;
}
.myinput {
display: flex;
box-sizing: border-box;
overflow: hidden;
position: relative;
flex: 1;
justify-content: center;
flex-direction: row;
align-items: center;
height: 88rpx;
padding: 20rpx 0;
/* border-width: 0.5px;
border-style: solid;
border-color: #e5e5e5;
border-radius: 5px;
background-color: rgb(248, 248, 248);
font-size: 18px;*/
font-size: .825rem;
}
.qtyinput {
height: 50px;
padding: 10px 0px;
font-size: 20px;
}
.count-input {
padding: 5rpx 3rpx;
width: 95%;
font-size: 18px;
}
.pda-data-picker {
padding: 5rpx 3rpx;
width: 95%;
font-size: 18px;
}
.inputPlaceholderStyle {
font-size: 16px;
}
.inputfocus {
border-color: #007AFF;
}
.txt-16 {
font-size: 16px;
}
.txt-18 {
font-size: 18px;
}
.txt-20 {
font-size: 20px;
}
.pda-label {
width: 210rpx;
word-wrap: break-word;
word-break: break-all;
text-indent: 20rpx;
font-size: 16px;
}
.fontsize-16 {
font-size: 16px;
}
.fontsize-18 {
font-size: 18px;
}
.fontsize-20 {
font-size: 20px;
}
/deep/ .uni-collapse-item__title-text {
font-size: 16px;
}
/deep/ .input-value {
font-size: 16px;
}
/deep/ .uni-input-input {
font-size: 18px;
}

245
fe/PDA/common/permission.js

@ -0,0 +1,245 @@
/// null = 未请求,1 = 已允许,0 = 拒绝|受限, 2 = 系统未开启
var isIOS
function album() {
var result = 0;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
if (authStatus === 0) {
result = null;
} else if (authStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
function camera() {
var result = 0;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
if (authStatus === 0) {
result = null;
} else if (authStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
function location() {
var result = 0;
var cllocationManger = plus.ios.import("CLLocationManager");
var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
if (!enable) {
result = 2;
} else if (status === 0) {
result = null;
} else if (status === 3 || status === 4) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(cllocationManger);
return result;
}
function push() {
var result = 0;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
if (enabledTypes == 0) {
result = 0;
console.log("推送权限没有开启");
} else {
result = 1;
console.log("已经开启推送功能!")
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
result = 3;
console.log("推送权限没有开启!");
} else {
result = 4;
console.log("已经开启推送功能!")
}
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
function contact() {
var result = 0;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus === 0) {
result = null;
} else if (cnAuthStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(CNContactStore);
return result;
}
function record() {
var result = null;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var status = avaudio.recordPermission();
console.log("permissionStatus:" + status);
if (status === 1970168948) {
result = null;
} else if (status === 1735552628) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(avaudiosession);
return result;
}
function calendar() {
var result = null;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = 1;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
function memo() {
var result = null;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = 1;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
function requestIOS(permissionID) {
return new Promise((resolve, reject) => {
switch (permissionID) {
case "push":
resolve(push());
break;
case "location":
resolve(location());
break;
case "record":
resolve(record());
break;
case "camera":
resolve(camera());
break;
case "album":
resolve(album());
break;
case "contact":
resolve(contact());
break;
case "calendar":
resolve(calendar());
break;
case "memo":
resolve(memo());
break;
default:
resolve(0);
break;
}
});
}
function requestAndroid(permissionID) {
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
[permissionID],
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
resolve(result);
},
function(error) {
console.log('result error: ' + error.message)
resolve({
code: error.code,
message: error.message
});
}
);
});
}
function gotoAppPermissionSetting() {
if (permission.isIOS) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
const permission = {
get isIOS(){
return typeof isIOS === 'boolean' ? isIOS : (isIOS = uni.getSystemInfoSync().platform === 'ios')
},
requestIOS: requestIOS,
requestAndroid: requestAndroid,
gotoAppSetting: gotoAppPermissionSetting
}
export default permission

191
fe/PDA/common/print.js

@ -0,0 +1,191 @@
import {
PrintServices
} from '@/api/index.js';
import VUE from 'vue'
let printUrl = VUE.prototype.$print_url; //打印
export function getTBQPrintData(details) {
let params = {
Palletlabel: []
}
details.forEach(item => {
let detail = {
asnNumber: item.asnNumber,
number: item.number,
supplierCode: item.supplierCode,
supplierName: item.supplierName,
arriveTime: item.arriveTime,
packingCode: item.packingCode,
containerCode: item.containerCode,
itemCode: item.itemCode,
qty: item.qty.qty,
totalQty: item.qty.qty,
}
let detailjson = JSON.parse(JSON.stringify(detail))
params.Palletlabel.push(detailjson)
})
let jsonData = JSON.stringify(params)
let data = {
reportName: 'tuopan.rdlx',
dataUrl: 'ccc',
jsonData: jsonData
};
return data
}
export function getXBQPrintData(item) {
let params = {
boxlabel: []
}
let newParams = {
asnNumber: item.asnNumber,
supplierCode: item.supplierCode,
supplierName: item.supplierName,
timeWindow: item.timeWindow,
arriveTime: item.arriveTime,
details: []
};
item.details.forEach(row => {
let detail = {
poNumber: row.poNumber,
poLine: row.poLine,
qty: row.qty,
packingCode: row.packingCode,
containerCode: row.containerCode,
lot: row.lot,
batch: row.batch,
itemCode: row.itemCode,
item: row.item
}
newParams.details.push(detail)
})
params.boxlabel.push(newParams)
let jsonData = JSON.stringify(params)
let data = {
reportName: 'xiangbq.rdlx',
dataUrl: 'ccc',
jsonData: jsonData
};
return data
}
export function getPutawayData(item) {
let params = {
putawaylabel: []
}
let newParams = {
creationTime: item.creationTime,
number: item.number,
jobType: item.jobType,
jobStatus: item.jobStatus,
priority: item.priority,
workGroupCode: item.workGroupCode,
supplierCode: item.supplierCode,
inspectNumber: item.inspectNumber,
receiptNumber: item.receiptNumber,
arriveNoticeNumber: item.arriveNoticeNumber,
asnNumber: item.asnNumber,
rpNumber: item.rpNumber,
poNumber: item.poNumber,
productReceiptNumber: item.productReceiptNumber,
details: []
};
item.details.forEach(row => {
let detail = {
item: row.item,
itemCode: row.itemCode,
stdPack: row.stdPack,
status: row.status,
recommendContainerCode: row.recommendContainerCode,
recommendPackingCode: row.recommendPackingCode,
recommendLocationCode: row.recommendLocationCode,
recommendQty: row.recommendQty,
fromLocationCode: row.fromLocationCode
}
newParams.details.push(detail)
})
params.putawaylabel.push(newParams)
let jsonData = JSON.stringify(params)
let data = {
reportName: 'putawaylabel.rdlx',
dataUrl: 'ccc',
jsonData: jsonData
};
return data
}
//打印托标签
export function printTBQLabel(details) {
let data = getTBQPrintData(details);
// let params =
// '{"Palletlabel":[{
//"asnNumber":"AVN202205250002",
//"number":"AVN202205250002",
//"supplierCode":"02053835",
//"supplierName":"埃驰汽车零部件(常熟)有限公司",
//"arriveTime":"2022/05/25",
//"packingCode":"undefined",
//"containerCode":"T0000591",
//"itemCode":"1765049LAA",
//"qty":"200",
//"totalQty":1},
//{"asnNumber":"AVN202205250002","number":"AVN202205250002","supplierCode":"02053835","supplierName":"埃驰汽车零部件(常熟)有限公司","arriveTime":"2022/05/25","packingCode":"undefined","containerCode":"T0000592","itemCode":"1765049LAA","qty":"200","totalQty":1},{"asnNumber":"AVN202205250002","number":"AVN202205250002","supplierCode":"02053835","supplierName":"埃驰汽车零部件(常熟)有限公司","arriveTime":"2022/05/25","packingCode":"undefined/B0001513/B0001511","containerCode":"T0000591","itemCode":"1765049LAA","qty":"200/200/200","totalQty":3}]}'
// let data = {
// reportName: 'tuopan.rdlx',
// dataUrl: 'ccc',
// jsonData: params
// };
console.log('data', data);
if (data != null && data.jsonData != "") {
PrintServices(data)
.then(res => {
window.open(printUrl + '/' + res)
})
.catch(err => {
});
}
}
//打印箱标签
export function printXBQLabel(details) {
let data = getXBQPrintData(details);
// let params =
// '{"boxlabel":[{"asnNumber":"AVN202205250003","supplierCode":"02053835","supplierName":"埃驰汽车零部件(常熟)有限公司","timeWindow":"09-11","arriveTime":"2022/05/25","details":[{"poNumber":"","poLine":"","qty":{"uom":"EA","qty":300},"packingCode":"B0001516","containerCode":"T0000596","lot":"220525","batch":{"supplierBatch":"220525","produceDate":"2022-05-25T00:00:00"},"itemCode":"2254149RAA","item":{"id":"fd231dd8-ed13-e4cb-9972-3a035cd3e176","name":"FA1B 78266A64 AJD6 PIA22","desc1":"PULL HANDLE CLOSEOUT","desc2":"右后门把手盖表皮-裁片2-PVC-JD6"}}]}]}';
// let data = {
// reportName: 'xiangbq.rdlx',
// dataUrl: 'ccc',
// jsonData: params
// };
console.log('data', data);
if (data != null && data.jsonData != "") {
PrintServices(data)
.then(res => {
window.open(printUrl + '/' + res)
})
.catch(err => {});
}
}
//打印上架任务标签
export function printPutawayLabel(item) {
let data = getPutawayData(item);
console.log('data', data);
if (data != null && data.jsonData != "") {
PrintServices(data)
.then(res => {
window.open(printUrl + '/' + res)
})
.catch(err => {});
}
}

26
fe/PDA/common/promise.js

@ -0,0 +1,26 @@
import urlConfig from './config.js'
const promise = {}
promise.asyncRequest = (url, options = {}, power) => {
return new Promise((resolve, reject) => {
uni.request({
url: url,
...options, //data,method...
header: {
"content-type": "application/json",
'withCredentials': true,
'Authorization': localStorage.token_type,
// 'Authorization': localStorage.token_type,
...options.header,
},
success: (res) => {
resolve(res.data);
},
fail: (err) => {
reject(err)
}
});
})
}
export default promise.asyncRequest

124
fe/PDA/common/request.js

@ -0,0 +1,124 @@
import urlConfig from './config.js'
// import store from '@/store/index'
const request = {}
request.globalRequest = (url, options = {}, power) => {
/*
1 == 不通过access_token校验的接口
2 == 文件下载接口列表
3 == 验证码登录 */
let contentType = localStorage.token_type ? "application/json" : "application/x-www-form-urlencoded";
return new Promise((resolve, reject) => {
uni.request({
url: url,
...options, //data,method...
header: {
"content-type": contentType,
"Authorization": localStorage.token_type,
'withCredentials': true,
// 'Blade-Auth':'bearer '+store.state.token,
'token_type': localStorage.token_type,
...options.header,
},
success: (res) => {
if (res != null) {
if (res.statusCode != null) {
let statusCode = res.statusCode.toString();
// 状态码类型 2开头的全是成功
let code = statusCode.substring(0, 1);
if (statusCode == '200') {
resolve(res.data);
} else if (statusCode == '204') {
if (options.method == 'get') {
reject(options.data+"没查到")
} else {
reject(res.data)
}
} else if (statusCode == '400') {
if (res.data.error) {
if (res.data.error.message) {
reject(res.data.error.message);
}
} else if (res.data.errors) {
let errors = res.data.errors;
let errorMsg = '请求参数错误:\n';
let keys = Object.keys(errors);
for (var i = 0; i < keys.length; i++) {
let key = keys[i];
let value = errors[key];
errorMsg += i + 1 + ':' + value + '\n';
}
reject(errorMsg);
}
} else if (statusCode == '404') {
if (res.data === '') {
reject('未找到接口');
} else {
reject(res.data);
}
} else if (statusCode == '403') {
let message = res.data.error.message;
if (message) {
let temp;
try {
temp = JSON.parse(message)
} catch (err) {
reject(message);
}
if (temp) {
var hintError = temp.error;
var hintErrorDes = temp.error_description;
if (hintError == 'invalid_grant') {
if (hintErrorDes.includes(
'Invalid username or password!')) {
reject('用户名或密码错误');
} else if (hintErrorDes.includes(
'The user account has been locked out due to invalid login attempts'
)) {
reject("账号已被锁定,请稍后再试");
}
} else {
reject(message)
}
}
} else {
reject(res.statusCode + "错误")
}
} else {
let message = res.data.error.message;
if (message != undefined) {
reject(res.data.error.message)
} else {
reject(res.statusCode + "错误")
}
}
} else {
reject('options.url' + "返回的状态码类型为空")
}
} else {
reject('options.url' + "返回的res为空")
}
},
fail: (eror) => {
reject(eror)
}
})
})
// .catch(params => {
// reject(params);
// })
}
export default request.globalRequest
// 最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String。转换规则如下:
// 对于 GET 方法,会将数据转换为 query string。例如 { name: 'name', age: 18 } 转换后的结果是 name=name&age=18。
// 对于 POST 方法且 header['content-type'] 为 application/json 的数据,会进行 JSON 序列化。
// 对于 POST 方法且 header['content-type'] 为 application/x-www-form-urlencoded 的数据,会将数据转换为 query string。

103
fe/PDA/common/request_test.js

@ -0,0 +1,103 @@
import urlConfig from './config.js'
// import store from '@/store/index'
function service(options = {}) {
let contentType = localStorage.token_type ? "application/json" : "application/x-www-form-urlencoded";
options.header = {
"content-type": contentType,
"Authorization": localStorage.token_type,
'withCredentials': true,
// 'Blade-Auth':'bearer '+store.state.token,
'token_type': localStorage.token_type
};
return new Promise((resolve, reject) => {
options.success = (res) => {
console.log("请求成功", res);
// 如果请求回来的状态码不是200则执行以下操作
if (res != null ) {
if (res.statusCode != null) {
let statusCode = res.statusCode.toString();
// 状态码类型 2开头的全是成功
let code = statusCode.substring(0, 1);
if (statusCode == '200') {
resolve(res.data);
} else if (statusCode == '204') {
if (options.method == 'get') {
return null;
} else {
reject(res.data)
}
} else if (statusCode == '400') {
if (res.data.error) {
if (res.data.error.message) {
reject(res.data.error.message);
}
} else if (res.data.errors) {
let errors = res.data.errors;
let errorMsg = '请求参数错误:\n';
let keys = Object.keys(errors);
for (var i = 0; i < keys.length; i++) {
let key = keys[i];
let value = errors[key];
errorMsg += i + 1 + ':' + value + '\n';
}
reject(errorMsg);
}
} else if (statusCode == '404') {
if (res.data === '') {
reject('未找到接口');
} else {
reject(res.data);
}
}
else if (statusCode == '403') {
let message = res.data.error.message;
if (message) {
let temp;
try {
temp = JSON.parse(message)
} catch (err) {
reject(message) ;
}
if (temp) {
var hintError = temp.error;
var hintErrorDes = temp.error_description;
if (hintError == 'invalid_grant') {
if (hintErrorDes.includes('Invalid username or password!')) {
reject('用户名或密码错误');
} else if (hintErrorDes.includes(
'The user account has been locked out due to invalid login attempts'
)) {
reject("账号已被锁定,请稍后再试");
}
} else {
reject(message)
}
}
} else {
reject(res.statusCode + "错误")
}
}
else {
let message = res.data.error.message;
if (message != undefined) {
reject(res.data.error.message)
} else {
reject(res.statusCode + "错误")
}
}
} else {
reject('options.url' + "返回的状态码类型为空")
}
} else {
reject('options.url' + "返回的res为空")
}
};
options.fail = (err) => {
reject(err);
};
uni.request(options);
});
}
export default service;

308
fe/PDA/common/scan.js

@ -0,0 +1,308 @@
//解析扫描信息
//P2251076NAA;L220325;Q2000;N0205183222000006;SS0000066;V02051832;OPO1072;C15;
//解析规则
//P:itemCode 物料号
//L:lot批次
//Q:qty 数量
//N:asn 供应商商发货单 ASN
//S:packingCode 箱码
//T:containerCode托盘
//V:supplierCode 供应商代码
//O: order订单号
//C: poLine订单行
//B:supplierBatch 供应商批次
//返回结果
//sucess true:成功 false:失败
//scanType barcode:条码 qrcode:二维码
//isPack true:箱码 false:托码
export function analyseScanInfo(scanMsg) {
let scanResult = {
sucess: false,
message: "",
data: {
isPack: null,
scanType: null,
itemCode: null,
lot: null,
qty: null,
asn: null,
packingCode: null,
supplierBatch: null,
order: null,
poLine: null,
code: null,
}
};
if (scanMsg === "") {
scanResult.message = "扫描到的内容为空";
} else {
try {
console.log('1.扫描到的内容:', scanMsg);
//条码
if (scanMsg.indexOf(';') < 0) {
scanResult.sucess = true;
scanResult.data.code = scanMsg;
scanResult.data.scanType = 'barcode'; //条码
} else {
let arrayItems = scanMsg.split(';');
if (arrayItems.length > 0) {
scanResult.data.scanType = 'qrcode'; //二维码
arrayItems.forEach((item, index) => {
if (item != "") {
let type = item.substring(0, 1);
let value = item.substring(1, item.length);
if (type != "") {
scanResult.data.scanType = 'qrcode';
switch (type) {
case "P": //物料号
case "p":
scanResult.data.itemCode = value;
break;
case "L": //批次
case "l":
scanResult.data.lot = value;
break;
case "Q": //数量
case "q":
scanResult.data.qty = value;
break;
case "N": //供应商商发货单 ASN
case "n":
scanResult.data.asn = value;
break;
case "S": //箱码
case "s":
scanResult.data.packingCode = value;
scanResult.data.isPack = true;
break;
case "T": //托盘
case "t":
scanResult.data.containerCode = value;
scanResult.data.isPack = false;
break;
case "V": //供应商批次
case "v":
scanResult.data.supplierCode = value;
break;
case "O": //订单号
case "o":
scanResult.data.order = value;
break;
case "C": //订单行
case "c":
scanResult.data.poLine = value;
break;
case "B": //供应商批次
case "b":
scanResult.data.supplierBatch = value;
break;
// default: //条码
// scanResult.data.code = item;
// scanResult.data.scanType = 'barcode';
// break;
}
}
}
})
scanResult.sucess = true;
} else { //扫描的是条码,直接返回接收到的内容
scanResult.sucess = true;
scanResult.data.code = scanMsg;
scanResult.data.scanType = 'barcode';
}
}
} catch (ex) {
scanResult.sucess = false;
scanResult.message = "解析遇到异常" + ex.message;
}
}
return scanResult;
}
//解析完工收货标签
//P2250229RAA;L220408;Q100;N62840610;SB0000107;UEA;DU571LS;FA;E2022-4-8
//P零件号,L批次,Q数量,N生产计划号,S箱码,U计量单位,D生产线,F班次,E日期,M零件名称(待添加)
//解析规则
//P:itemCode 物料号
//L:lot批次
//Q:qty 数量
//N:pnumber productionPlanNumber生产计划号
//S:packingCode 箱码
//U:uom 计量单位
//D:prodLine 生产线
//F:shift 班次
//E:produceDate日期
//返回结果
//sucess true:成功 false:失败
//scanType barcode:条码 qrcode:二维码
//isPack true:箱码 false:托码
export function analyseProductLabelInfo(scanMsg) {
let scanResult = {
sucess: false,
message: "",
data: {
itemCode: null,
lot: null,
qty: null,
pnumber: null,
packingCode: null,
uom: null,
prodLine: null,
shift: null,
produceDate: null
}
};
if (scanMsg == "") {
scanResult.message = "扫描到的内容为空";
} else {
try {
//条码
if (scanMsg.indexOf(';') < 0) {
scanResult.sucess = false;
scanResult.message = "标签格式不正确";
} else {
let arrayItems = scanMsg.split(';');
if (arrayItems.length > 0) {
arrayItems.forEach((item, index) => {
if (item != "") {
let type = item.substring(0, 1);
let value = item.substring(1, item.length);
if (type != "") {
switch (type) {
case "P": //物料号
case "p":
scanResult.data.itemCode = value;
break;
case "L": //批次
case "l":
scanResult.data.lot = value;
break;
case "Q": //数量
case "q":
scanResult.data.qty = value;
break;
case "N": //生产计划号 ASN
case "n":
scanResult.data.pnumber = value;
break;
case "S": //箱码
case "s":
scanResult.data.packingCode = value;
break;
case "U": //计量单位
case "u":
scanResult.data.uom = value;
break;
case "D": //生产线
case "d":
scanResult.data.prodLine = value;
break;
case "F": //班次
case "f":
scanResult.data.shift = value;
break;
case "E": //日期
case "e":
scanResult.data.produceDate = value;
break;
default:
scanResult.sucess = false;
scanResult.message = "无法识别的前缀" + type;
break;
}
scanResult.sucess = true;
} else {
scanResult.sucess = false;
scanResult.message = "标签信息不能为空" + type;
}
}
})
} else { //扫描的是条码,直接返回接收到的内容
scanResult.sucess = false;
scanResult.message = "标签分隔符错误";
}
}
} catch (ex) {
scanResult.sucess = false;
scanResult.message = "解析遇到异常" + ex.message;
}
}
return scanResult;
}
//解析天津mes标签
//1#2546319FL#254FL003#202207110009:
//1.序号1,2.生产号2546311FL,3.零件号254FL004,4.批序号202207110009
export function analyseTJMesQRCode(scanMsg) {
let scanResult = {
sucess: false,
message: "",
items: []
};
if (scanMsg == "") {
scanResult.message = "扫描到的内容为空";
} else {
try {
if (scanMsg.indexOf(':') < 0) {
scanResult.sucess = false;
scanResult.message = "标签格式不正确";
} else {
let arrayItems = scanMsg.split(':');
if (arrayItems.length > 0) {
arrayItems.forEach((item, index) => {
if (item != "") {
if (item.includes('#')) {
let datas = item.split('#');
//为空时是:2N
if (datas.length > 1) {
let itemCode = datas[2];
let location = itemCode.substring(3, 5);
let data = {
seq: datas[0], //序号
produceNo: datas[1], //生产号
// projectNo: datas[2], //项目号
itemCode: itemCode, //配置码(零件号)
lot: datas[3], //批次
position: location //上层、下层
}
scanResult.items.push(data)
}
} else {
if (item.includes('N')) {
let seq = item.substring(0, item.length - 1);
let data = {
seq: seq, //序号
produceNo: 'N', //生产号
projectNo: 'N', //项目号
itemCode: 'N', //配置码(零件号)
lot: 'N', //批次
position: ''
}
scanResult.items.push(data)
}
}
} else {
scanResult.sucess = false;
scanResult.message = "标签信息不能为空";
}
})
scanResult.sucess = true;
} else { //扫描的是条码,直接返回接收到的内容
scanResult.sucess = false;
scanResult.message = "标签分隔符错误";
}
}
} catch (ex) {
scanResult.sucess = false;
scanResult.message = "解析遇到异常" + ex.message;
}
}
return scanResult;
}

15
fe/PDA/common/text.js

@ -0,0 +1,15 @@
// //等待一会再执行
// this.timer = setInterval(() => {
// //TODO
// that.hideLoading();
// }, 2000);
// //拦截返回按钮事件
// onBackPress(e) {
// uni.reLaunch({
// url: 'Inspect'
// })
// // 此处一定要return为true,否则页面不会返回到指定路径
// return true;
// },

136
fe/PDA/common/uni-nvue.css

@ -0,0 +1,136 @@
/* #ifndef APP-PLUS-NVUE */
page {
min-height: 100%;
height: auto;
}
/* #endif */
/* 解决头条小程序字体图标不显示问题,因为头条运行时自动插入了span标签,且有全局字体 */
/* #ifdef MP-TOUTIAO */
/* text :not(view) {
font-family: uniicons;
} */
/* #endif */
.uni-icon {
font-family: uniicons;
font-weight: normal;
}
.uni-container {
padding: 15px;
background-color: #f8f8f8;
}
.uni-header-logo {
/* #ifdef H5 */
display: flex;
/* #endif */
padding: 15px 15px;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 10rpx;
}
.uni-header-image {
width: 80px;
height: 80px;
}
.uni-hello-text {
margin-bottom: 20px;
}
.hello-text {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
.hello-link {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
.uni-panel {
margin-bottom: 12px;
}
.uni-panel-h {
/* #ifdef H5 */
display: flex;
/* #endif */
background-color: #ffffff;
flex-direction: row !important;
/* justify-content: space-between !important; */
align-items: center !important;
padding: 12px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
/*
.uni-panel-h:active {
background-color: #f8f8f8;
}
*/
.uni-panel-h-on {
background-color: #f0f0f0;
}
.uni-panel-text {
flex: 1;
color: #000000;
font-size: 14px;
font-weight: normal;
}
.uni-panel-icon {
margin-left: 15px;
color: #999999;
font-size: 14px;
font-weight: normal;
transform: rotate(0deg);
transition-duration: 0s;
transition-property: transform;
}
.uni-panel-icon-on {
transform: rotate(180deg);
}
.uni-navigate-item {
/* #ifdef H5 */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
background-color: #FFFFFF;
border-top-style: solid;
border-top-color: #f0f0f0;
border-top-width: 1px;
padding: 12px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-navigate-item:active {
background-color: #f8f8f8;
}
.uni-navigate-text {
flex: 1;
color: #000000;
font-size: 14px;
font-weight: normal;
}
.uni-navigate-icon {
margin-left: 15px;
color: #999999;
font-size: 14px;
font-weight: normal;
}

2897
fe/PDA/common/uni.css

File diff suppressed because it is too large

53
fe/PDA/common/util.js

@ -0,0 +1,53 @@
export default {
goHome() {
uni.reLaunch({
url: '../index/index'
})
},
getRemoveOption() {
let options = [{
text: '移除',
style: {
backgroundColor: '#F56C6C'
}
}]
return options;
},
//提示是否消息
showConfirmMsg(content, callback) {
uni.showModal({
title: '提示',
cancelText: '否',
confirmText: '是',
content: content,
success: function(res) {
if (res.confirm) {
callback(true);
} else {
callback(false);
}
}
})
},
compare(key) {
return function(a, b) {
var val1 = a[key];
var val2 = b[key];
return val2 - val1;
}
},
compareDesc(key) {
return function(a, b) {
var val1 = a[key];
var val2 = b[key];
return val1 - val2;
}
}
}

6
fe/PDA/common/utils.js

@ -0,0 +1,6 @@
export default {
// 判断 " " / null / undefined的方法
isEmpty(text){
return (!text || 0 === text.length);
}
}

181
fe/PDA/components/amap-wx/js/util.js

@ -0,0 +1,181 @@
import amap from '@/components/amap-wx/lib/amap-wx.js';
// 地铁颜色图
const line = {
'1号线': '#C43B33',
'2号线': '#016299',
'4号线/大兴线': '#008E9C',
'5号线': '#A42380',
'6号线': '#D09900',
'7号线': '#F2C172',
'8号线': '#009D6A',
'9号线': '#8FC41E',
'10号线': '#009DBE',
'13号线': '#F9E701',
'14号线东段': '#D4A7A2',
'14号线西段': '#D4A7A2',
'15号线': '#5D2D69',
'八通线': '#C33A32',
'昌平线': '#DE82B1',
'亦庄线': '#E40177',
'房山线': '#E66021',
'机场线': '#A29BBC',
}
// 150500:地铁站 ,150700:公交站 , 190700:地名地址
const typecode = [{
id: '150500',
icon: 'icon-ditie'
}, {
id: '150700',
icon: 'icon-gongjiao'
}, {
id: '190700',
icon: 'icon-gonglu'
}];
const util = {
key:'b526b09b86cd2996e7732be8ab8c4430',
/**
* 初始化高德地图api
*/
mapInit() {
return new amap.AMapWX({
key: this.key
});
},
// 服务状态吗
typecode,
/**
* 获取地图颜色
*/
lineColor(name) {
if (line[name]) {
return line[name];
} else {
return '#ccc';
}
},
/**
* 关键字颜色变化
*/
serachNmme(val, name) {
let namestr = new RegExp(val);
let nameresult =
`<div style="font-size: 14px;color: #333;line-height: 1.5;">
${name.replace(namestr, "<span style='color:#66ccff;'>" + val + '</span>')}
</div>`
.trim();
return nameresult;
},
/**
* 地址转地铁线路
*/
addressToLine(address, type) {
let addr = address.split(';');
let dt = '';
addr.forEach(elm => {
let color = '#cccccc';
if (type === typecode[0].id) {
color = this.lineColor(elm)
} else if (type === typecode[1].id) {
color = '#4075cb'
}
let style = 'margin:5px 0;margin-right:5px;padding:0 5px;background:' + color +
';font-size:12px;color:#fff;border-radius:3px;';
dt += `<div style=\'${style}\'>${elm}</div>`;
});
return `<div style="display:flex;flex-wrap: wrap;">${dt}</div>`;
},
/**
* 数据处理
*/
dataHandle(item, val) {
// 改变字体颜色
if (val) {
item.nameNodes = util.serachNmme(val, item.name);
} else {
item.nameNodes = `<div style="font-size: 14px;color: #333;line-height: 1.5;">${item.name}</div>`;
}
// 地址解析 地铁
if (
item.typecode === util.typecode[0].id ||
item.typecode === util.typecode[1].id
) {
item.addressNodes = util.addressToLine(item.address, item.typecode);
if (item.typecode === util.typecode[0].id) {
item.icon = util.typecode[0].icon;
} else if (item.typecode === util.typecode[1].id) {
item.icon = util.typecode[1].icon;
}
} else {
item.addressNodes = `<span>${item.district}${
item.address.length > 0 ? '·' + item.address : ''
}</span>`.trim();
item.icon = 'icon-weizhi';
}
if (item.location && item.location.length === 0) {
item.icon = 'icon-sousuo';
}
return item;
},
/**
* 存储历史数据
* val [string | object]需要存储的内容
*/
setHistory(val) {
let searchHistory = uni.getStorageSync('search:history');
if (!searchHistory) searchHistory = [];
let serachData = {};
if (typeof(val) === 'string') {
serachData = {
adcode: [],
address: [],
city: [],
district: [],
id: [],
location: [],
name: val,
typecode: []
};
} else {
serachData = val
}
// 判断数组是否存在,如果存在,那么将放到最前面
for (var i = 0; i < searchHistory.length; i++) {
if (searchHistory[i].name === serachData.name) {
searchHistory.splice(i, 1);
break;
}
}
searchHistory.unshift(util.dataHandle(serachData));
uni.setStorage({
key: 'search:history',
data: searchHistory,
success: function() {
// console.log('success');
}
});
},
getHistory() {
},
removeHistory() {
uni.removeStorage({
key: 'search:history',
success: function(res) {
console.log('success');
}
});
return []
}
}
export default util;

1
fe/PDA/components/amap-wx/lib/amap-wx.js

File diff suppressed because one or more lines are too long

156
fe/PDA/components/api-set-tabbar.nvue

@ -0,0 +1,156 @@
<template>
<view class="uni-padding-wrap">
<page-head :title="title"></page-head>
<button class="button" @click="setTabBarBadge">{{ !hasSetTabBarBadge ? '设置tab徽标' : '移除tab徽标' }}</button>
<button class="button" @click="showTabBarRedDot">{{ !hasShownTabBarRedDot ? '显示红点' : '移除红点'}}</button>
<button class="button" @click="customStyle">{{ !hasCustomedStyle ? '自定义Tab样式' : '移除自定义样式'}}</button>
<button class="button" @click="customItem">{{ !hasCustomedItem ? '自定义Tab信息' : '移除自定义信息' }}</button>
<button class="button" @click="hideTabBar">{{ !hasHiddenTabBar ? '隐藏TabBar' : '显示TabBar' }}</button>
<view class="btn-area">
<button class="button" type="primary" @click="navigateBack">返回上一级</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'tababr',
hasSetTabBarBadge: false,
hasShownTabBarRedDot: false,
hasCustomedStyle: false,
hasCustomedItem: false,
hasHiddenTabBar: false
}
},
destroyed() {
if (this.hasSetTabBarBadge) {
uni.removeTabBarBadge({
index: 1
})
}
if (this.hasShownTabBarRedDot) {
uni.hideTabBarRedDot({
index: 1
})
}
if (this.hasHiddenTabBar) {
uni.showTabBar()
}
if (this.hasCustomedStyle) {
uni.setTabBarStyle({
color: '#7A7E83',
selectedColor: '#007AFF',
backgroundColor: '#F8F8F8',
borderStyle: 'black'
})
}
if (this.hasCustomedItem) {
let tabBarOptions = {
index: 1,
text: '接口',
iconPath: '/static/api.png',
selectedIconPath: '/static/apiHL.png'
}
uni.setTabBarItem(tabBarOptions)
}
},
methods: {
navigateBack() {
this.$emit('unmount')
},
setTabBarBadge() {
if(this.hasShownTabBarRedDot){
uni.hideTabBarRedDot({
index: 1
})
this.hasShownTabBarRedDot = !this.hasShownTabBarRedDot
}
if (!this.hasSetTabBarBadge) {
uni.setTabBarBadge({
index: 1,
text: '1'
})
} else {
uni.removeTabBarBadge({
index: 1
})
}
this.hasSetTabBarBadge = !this.hasSetTabBarBadge
},
showTabBarRedDot() {
if(this.hasSetTabBarBadge) {
uni.removeTabBarBadge({
index: 1
})
this.hasSetTabBarBadge = !this.hasSetTabBarBadge
}
if (!this.hasShownTabBarRedDot) {
uni.showTabBarRedDot({
index: 1
})
} else {
uni.hideTabBarRedDot({
index: 1
})
}
this.hasShownTabBarRedDot = !this.hasShownTabBarRedDot
},
hideTabBar() {
if (!this.hasHiddenTabBar) {
uni.hideTabBar()
} else {
uni.showTabBar()
}
this.hasHiddenTabBar = !this.hasHiddenTabBar
},
customStyle() {
if (this.hasCustomedStyle) {
uni.setTabBarStyle({
color: '#7A7E83',
selectedColor: '#007AFF',
backgroundColor: '#F8F8F8',
borderStyle: 'black'
})
} else {
uni.setTabBarStyle({
color: '#FFF',
selectedColor: '#007AFF',
backgroundColor: '#000000',
borderStyle: 'black'
})
}
this.hasCustomedStyle = !this.hasCustomedStyle
},
customItem() {
let tabBarOptions = {
index: 1,
text: '接口',
iconPath: '/static/api.png',
selectedIconPath: '/static/apiHL.png'
}
if (this.hasCustomedItem) {
uni.setTabBarItem(tabBarOptions)
} else {
tabBarOptions.text = 'API'
uni.setTabBarItem(tabBarOptions)
}
this.hasCustomedItem = !this.hasCustomedItem
}
}
}
</script>
<style>
.button {
margin-top: 30rpx;
margin-left: 0;
margin-right: 0;
}
.btn-area {
padding-top: 30rpx;
}
</style>

1
fe/PDA/components/marked/index.js

@ -0,0 +1 @@
export default './lib/marked'

1573
fe/PDA/components/marked/lib/marked.js

File diff suppressed because it is too large

12542
fe/PDA/components/mpvue-citypicker/city-data/area.js

File diff suppressed because it is too large

1503
fe/PDA/components/mpvue-citypicker/city-data/city.js

File diff suppressed because it is too large

139
fe/PDA/components/mpvue-citypicker/city-data/province.js

@ -0,0 +1,139 @@
/* eslint-disable */
var provinceData = [{
"label": "北京市",
"value": "11"
},
{
"label": "天津市",
"value": "12"
},
{
"label": "河北省",
"value": "13"
},
{
"label": "山西省",
"value": "14"
},
{
"label": "内蒙古自治区",
"value": "15"
},
{
"label": "辽宁省",
"value": "21"
},
{
"label": "吉林省",
"value": "22"
},
{
"label": "黑龙江省",
"value": "23"
},
{
"label": "上海市",
"value": "31"
},
{
"label": "江苏省",
"value": "32"
},
{
"label": "浙江省",
"value": "33"
},
{
"label": "安徽省",
"value": "34"
},
{
"label": "福建省",
"value": "35"
},
{
"label": "江西省",
"value": "36"
},
{
"label": "山东省",
"value": "37"
},
{
"label": "河南省",
"value": "41"
},
{
"label": "湖北省",
"value": "42"
},
{
"label": "湖南省",
"value": "43"
},
{
"label": "广东省",
"value": "44"
},
{
"label": "广西壮族自治区",
"value": "45"
},
{
"label": "海南省",
"value": "46"
},
{
"label": "重庆市",
"value": "50"
},
{
"label": "四川省",
"value": "51"
},
{
"label": "贵州省",
"value": "52"
},
{
"label": "云南省",
"value": "53"
},
{
"label": "西藏自治区",
"value": "54"
},
{
"label": "陕西省",
"value": "61"
},
{
"label": "甘肃省",
"value": "62"
},
{
"label": "青海省",
"value": "63"
},
{
"label": "宁夏回族自治区",
"value": "64"
},
{
"label": "新疆维吾尔自治区",
"value": "65"
},
{
"label": "台湾",
"value": "66"
},
{
"label": "香港",
"value": "67"
},
{
"label": "澳门",
"value": "68"
}
]
export default provinceData;

230
fe/PDA/components/mpvue-citypicker/mpvueCityPicker.vue

@ -0,0 +1,230 @@
<template>
<div class="mpvue-picker">
<div :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></div>
<div class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
<div class="mpvue-picker__hd" catchtouchmove="true">
<div class="mpvue-picker__action" @click="pickerCancel">取消</div>
<div class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</div>
</div>
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange">
<block>
<picker-view-column>
<div class="picker-item" v-for="(item,index) in provinceDataList" :key="index">{{item.label}}</div>
</picker-view-column>
<picker-view-column>
<div class="picker-item" v-for="(item,index) in cityDataList" :key="index">{{item.label}}</div>
</picker-view-column>
<picker-view-column>
<div class="picker-item" v-for="(item,index) in areaDataList" :key="index">{{item.label}}</div>
</picker-view-column>
</block>
</picker-view>
</div>
</div>
</template>
<script>
import provinceData from './city-data/province.js';
import cityData from './city-data/city.js';
import areaData from './city-data/area.js';
export default {
data() {
return {
pickerValue: [0, 0, 0],
provinceDataList: provinceData,
cityDataList: cityData[0],
areaDataList: areaData[0][0],
/* 是否显示控件 */
showPicker: false,
};
},
created() {
this.init()
},
props: {
/* 默认值 */
pickerValueDefault: {
type: Array,
default () {
return [0, 0, 0]
}
},
/* 主题色 */
themeColor: String
},
watch: {
pickerValueDefault() {
this.init();
}
},
methods: {
init() {
this.handPickValueDefault(); // pickerValueDefault
const pickerValueDefault = this.pickerValueDefault
this.cityDataList = cityData[pickerValueDefault[0]];
this.areaDataList = areaData[pickerValueDefault[0]][pickerValueDefault[1]];
this.pickerValue = pickerValueDefault;
},
show() {
setTimeout(() => {
this.showPicker = true;
}, 0);
},
maskClick() {
this.pickerCancel();
},
pickerCancel() {
this.showPicker = false;
this._$emit('onCancel');
},
pickerConfirm(e) {
this.showPicker = false;
this._$emit('onConfirm');
},
showPickerView() {
this.showPicker = true;
},
handPickValueDefault() {
const pickerValueDefault = this.pickerValueDefault
let provinceIndex = pickerValueDefault[0]
let cityIndex = pickerValueDefault[1]
const areaIndex = pickerValueDefault[2]
if (
provinceIndex !== 0 ||
cityIndex !== 0 ||
areaIndex !== 0
) {
if (provinceIndex > provinceData.length - 1) {
this.pickerValueDefault[0] = provinceIndex = provinceData.length - 1;
}
if (cityIndex > cityData[provinceIndex].length - 1) {
this.pickerValueDefault[1] = cityIndex = cityData[provinceIndex].length - 1;
}
if (areaIndex > areaData[provinceIndex][cityIndex].length - 1) {
this.pickerValueDefault[2] = areaData[provinceIndex][cityIndex].length - 1;
}
}
},
pickerChange(e) {
let changePickerValue = e.mp.detail.value;
if (this.pickerValue[0] !== changePickerValue[0]) {
//
this.cityDataList = cityData[changePickerValue[0]];
this.areaDataList = areaData[changePickerValue[0]][0];
changePickerValue[1] = 0;
changePickerValue[2] = 0;
} else if (this.pickerValue[1] !== changePickerValue[1]) {
//
this.areaDataList =
areaData[changePickerValue[0]][changePickerValue[1]];
changePickerValue[2] = 0;
}
this.pickerValue = changePickerValue;
this._$emit('onChange');
},
_$emit(emitName) {
let pickObj = {
label: this._getLabel(),
value: this.pickerValue,
cityCode: this._getCityCode()
};
this.$emit(emitName, pickObj);
},
_getLabel() {
let pcikerLabel =
this.provinceDataList[this.pickerValue[0]].label +
'-' +
this.cityDataList[this.pickerValue[1]].label +
'-' +
this.areaDataList[this.pickerValue[2]].label;
return pcikerLabel;
},
_getCityCode() {
return this.areaDataList[this.pickerValue[2]].value;
}
}
};
</script>
<style>
.pickerMask {
position: fixed;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
}
.mpvue-picker-content {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
transition: all 0.3s ease;
transform: translateY(100%);
z-index: 3000;
}
.mpvue-picker-view-show {
transform: translateY(0);
}
.mpvue-picker__hd {
display: flex;
padding: 9px 15px;
background-color: #fff;
position: relative;
text-align: center;
font-size: 17px;
}
.mpvue-picker__hd:after {
content: ' ';
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid #e5e5e5;
color: #e5e5e5;
transform-origin: 0 100%;
transform: scaleY(0.5);
}
.mpvue-picker__action {
display: block;
flex: 1;
color: #1aad19;
}
.mpvue-picker__action:first-child {
text-align: left;
color: #888;
}
.mpvue-picker__action:last-child {
text-align: right;
}
.picker-item {
text-align: center;
line-height: 40px;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 16px;
}
.mpvue-picker-view {
position: relative;
bottom: 0;
left: 0;
width: 100%;
height: 238px;
background-color: rgba(255, 255, 255, 1);
}
</style>

123
fe/PDA/components/mpvue-echarts/src/echarts.vue

@ -0,0 +1,123 @@
<template>
<canvas v-if="canvasId" class="ec-canvas" :id="canvasId" :canvasId="canvasId" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error"></canvas>
</template>
<script>
import WxCanvas from './wx-canvas';
export default {
props: {
canvasId: {
type: String,
default: 'ec-canvas'
},
lazyLoad: {
type: Boolean,
default: false
},
disableTouch: {
type: Boolean,
default: false
},
throttleTouch: {
type: Boolean,
default: false
}
},
// #ifdef H5
mounted() {
if (!this.lazyLoad) this.init();
},
// #endif
// #ifndef H5
onReady() {
if (!this.lazyLoad) this.init();
},
// #endif
methods: {
setChart(chart){
this.chart = chart
},
init() {
const { canvasId } = this;
this.ctx = wx.createCanvasContext(canvasId, this);
this.canvas = new WxCanvas(this.ctx, canvasId);
const query = wx.createSelectorQuery().in(this);
query
.select(`#${canvasId}`)
.boundingClientRect(res => {
if (!res) {
setTimeout(() => this.init(), 50);
return;
}
this.$emit('onInit', {
width: res.width,
height: res.height
});
})
.exec();
},
canvasToTempFilePath(opt) {
const { canvasId } = this;
this.ctx.draw(true, () => {
wx.canvasToTempFilePath({
canvasId,
...opt
});
});
},
touchStart(e) {
const { disableTouch, chart } = this;
if (disableTouch || !chart || !e.mp.touches.length) return;
const touch = e.mp.touches[0];
chart._zr.handler.dispatch('mousedown', {
zrX: touch.x,
zrY: touch.y
});
chart._zr.handler.dispatch('mousemove', {
zrX: touch.x,
zrY: touch.y
});
},
touchMove(e) {
const { disableTouch, throttleTouch, chart, lastMoveTime } = this;
if (disableTouch || !chart || !e.mp.touches.length) return;
if (throttleTouch) {
const currMoveTime = Date.now();
if (currMoveTime - lastMoveTime < 240) return;
this.lastMoveTime = currMoveTime;
}
const touch = e.mp.touches[0];
chart._zr.handler.dispatch('mousemove', {
zrX: touch.x,
zrY: touch.y
});
},
touchEnd(e) {
const { disableTouch, chart } = this;
if (disableTouch || !chart) return;
const touch = e.mp.changedTouches ? e.mp.changedTouches[0] : {};
chart._zr.handler.dispatch('mouseup', {
zrX: touch.x,
zrY: touch.y
});
chart._zr.handler.dispatch('click', {
zrX: touch.x,
zrY: touch.y
});
}
}
};
</script>
<style scoped>
.ec-canvas {
width: 100%;
height: 100%;
flex: 1;
}
</style>

73
fe/PDA/components/mpvue-echarts/src/wx-canvas.js

@ -0,0 +1,73 @@
export default class WxCanvas {
constructor(ctx, canvasId) {
this.ctx = ctx;
this.canvasId = canvasId;
this.chart = null;
WxCanvas.initStyle(ctx);
this.initEvent();
}
getContext(contextType) {
return contextType === '2d' ? this.ctx : null;
}
setChart(chart) {
this.chart = chart;
}
attachEvent() {
// noop
}
detachEvent() {
// noop
}
static initStyle(ctx) {
const styles = ['fillStyle', 'strokeStyle', 'globalAlpha',
'textAlign', 'textBaseAlign', 'shadow', 'lineWidth',
'lineCap', 'lineJoin', 'lineDash', 'miterLimit', 'fontSize'];
styles.forEach((style) => {
Object.defineProperty(ctx, style, {
set: (value) => {
if ((style !== 'fillStyle' && style !== 'strokeStyle')
|| (value !== 'none' && value !== null)
) {
ctx[`set${style.charAt(0).toUpperCase()}${style.slice(1)}`](value);
}
},
});
});
ctx.createRadialGradient = () => ctx.createCircularGradient(arguments);
}
initEvent() {
this.event = {};
const eventNames = [{
wxName: 'touchStart',
ecName: 'mousedown',
}, {
wxName: 'touchMove',
ecName: 'mousemove',
}, {
wxName: 'touchEnd',
ecName: 'mouseup',
}, {
wxName: 'touchEnd',
ecName: 'click',
}];
eventNames.forEach((name) => {
this.event[name.wxName] = (e) => {
const touch = e.mp.touches[0];
this.chart._zr.handler.dispatch(name.ecName, {
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
zrY: name.wxName === 'tap' ? touch.clientY : touch.y,
});
};
});
}
}

484
fe/PDA/components/mpvue-picker/mpvuePicker.vue

@ -0,0 +1,484 @@
<template>
<view class="mpvue-picker">
<view :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></view>
<view class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
<view class="mpvue-picker__hd" catchtouchmove="true">
<view class="mpvue-picker__action" @click="pickerCancel">取消</view>
<view class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</view>
</view>
<!-- 单列 -->
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
@change="pickerChange" v-if="mode==='selector' && pickerValueSingleArray.length > 0">
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueSingleArray" :key="index">{{item.label}}
</view>
</picker-view-column>
</picker-view>
<!-- 时间选择器 -->
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
@change="pickerChange" v-if="mode==='timeSelector'">
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueHour" :key="index">{{item.label}}</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueMinute" :key="index">{{item.label}}
</view>
</picker-view-column>
</picker-view>
<!-- 多列选择 -->
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
@change="pickerChange" v-if="mode==='multiSelector'">
<!-- #ifdef VUE3 -->
<template v-for="(n,index) in pickerValueMulArray.length" :key="index">
<picker-view-column>
<view class="picker-item" v-for="(item,index1) in pickerValueMulArray[n]" :key="index1">
{{item.label}}
</view>
</picker-view-column>
</template>
<!-- #endif -->
<!-- #ifndef VUE3 -->
<block v-for="(n,index) in pickerValueMulArray.length" :key="index">
<picker-view-column>
<view class="picker-item" v-for="(item,index1) in pickerValueMulArray[n]" :key="index1">
{{item.label}}
</view>
</picker-view-column>
</block>
<!-- #endif -->
</picker-view>
<!-- 二级联动 -->
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
@change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===2">
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueMulTwoOne" :key="index">{{item.label}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueMulTwoTwo" :key="index">{{item.label}}
</view>
</picker-view-column>
</picker-view>
<!-- 三级联动 -->
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
@change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===3">
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeOne" :key="index">{{item.label}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeTwo" :key="index">{{item.label}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeThree" :key="index">
{{item.label}}
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
pickerChangeValue: [],
pickerValue: [],
pickerValueArrayChange: true,
modeChange: false,
pickerValueSingleArray: [],
pickerValueHour: [],
pickerValueMinute: [],
pickerValueMulArray: [],
pickerValueMulTwoOne: [],
pickerValueMulTwoTwo: [],
pickerValueMulThreeOne: [],
pickerValueMulThreeTwo: [],
pickerValueMulThreeThree: [],
/* 是否显示控件 */
showPicker: false,
};
},
props: {
/* mode */
mode: {
type: String,
default: 'selector'
},
/* picker 数值 */
pickerValueArray: {
type: Array,
default () {
return []
}
},
/* 默认值 */
pickerValueDefault: {
type: Array,
default () {
return []
}
},
/* 几级联动 */
deepLength: {
type: Number,
default: 2
},
/* 主题色 */
themeColor: String
},
watch: {
pickerValueArray(oldVal, newVal) {
this.pickerValueArrayChange = true;
},
mode(oldVal, newVal) {
this.modeChange = true;
},
pickerValueArray(val) {
this.initPicker(val);
}
},
methods: {
initPicker(valueArray) {
let pickerValueArray = valueArray;
this.pickerValue = this.pickerValueDefault;
//
if (this.mode === 'selector') {
this.pickerValueSingleArray = valueArray;
} else if (this.mode === 'timeSelector') {
this.modeChange = false;
let hourArray = [];
let minuteArray = [];
for (let i = 0; i < 24; i++) {
hourArray.push({
value: i,
label: i > 9 ? `${i}` : `0${i}`
});
}
for (let i = 0; i < 60; i++) {
minuteArray.push({
value: i,
label: i > 9 ? `${i}` : `0${i}`
});
}
this.pickerValueHour = hourArray;
this.pickerValueMinute = minuteArray;
} else if (this.mode === 'multiSelector') {
this.pickerValueMulArray = valueArray;
} else if (this.mode === 'multiLinkageSelector' && this.deepLength === 2) {
//
let pickerValueMulTwoOne = [];
let pickerValueMulTwoTwo = [];
//
for (let i = 0, length = pickerValueArray.length; i < length; i++) {
pickerValueMulTwoOne.push(pickerValueArray[i]);
}
//
//
if (this.pickerValueDefault.length === 2) {
let num = this.pickerValueDefault[0];
for (
let i = 0, length = pickerValueArray[num].children.length; i < length; i++
) {
pickerValueMulTwoTwo.push(pickerValueArray[num].children[i]);
}
} else {
for (
let i = 0, length = pickerValueArray[0].children.length; i < length; i++
) {
pickerValueMulTwoTwo.push(pickerValueArray[0].children[i]);
}
}
this.pickerValueMulTwoOne = pickerValueMulTwoOne;
this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
} else if (
this.mode === 'multiLinkageSelector' &&
this.deepLength === 3
) {
let pickerValueMulThreeOne = [];
let pickerValueMulThreeTwo = [];
let pickerValueMulThreeThree = [];
//
for (let i = 0, length = pickerValueArray.length; i < length; i++) {
pickerValueMulThreeOne.push(pickerValueArray[i]);
}
//
this.pickerValueDefault =
this.pickerValueDefault.length === 3 ?
this.pickerValueDefault : [0, 0, 0];
if (this.pickerValueDefault.length === 3) {
let num = this.pickerValueDefault[0];
for (
let i = 0, length = pickerValueArray[num].children.length; i < length; i++
) {
pickerValueMulThreeTwo.push(pickerValueArray[num].children[i]);
}
//
let numSecond = this.pickerValueDefault[1];
for (let i = 0, length = pickerValueArray[num].children[numSecond].children.length; i <
length; i++) {
pickerValueMulThreeThree.push(
pickerValueArray[num].children[numSecond].children[i]
);
}
}
this.pickerValueMulThreeOne = pickerValueMulThreeOne;
this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
}
},
show() {
setTimeout(() => {
if (this.pickerValueArrayChange || this.modeChange) {
this.initPicker(this.pickerValueArray);
this.showPicker = true;
this.pickerValueArrayChange = false;
this.modeChange = false;
} else {
this.showPicker = true;
}
}, 0);
},
maskClick() {
this.pickerCancel();
},
pickerCancel() {
this.showPicker = false;
this._initPickerVale();
let pickObj = {
index: this.pickerValue,
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
};
this.$emit('onCancel', pickObj);
},
pickerConfirm(e) {
this.showPicker = false;
this._initPickerVale();
let pickObj = {
index: this.pickerValue,
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
};
this.$emit('onConfirm', pickObj);
},
showPickerView() {
this.showPicker = true;
},
pickerChange(e) {
console.log(11111111, e);
this.pickerValue = e.detail.value;
let pickObj = {
index: this.pickerValue,
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
};
this.$emit('onChange', pickObj);
},
pickerChangeMul(e) {
if (this.deepLength === 2) {
let pickerValueArray = this.pickerValueArray;
let changeValue = e.detail.value;
//
if (changeValue[0] !== this.pickerValue[0]) {
let pickerValueMulTwoTwo = [];
//
for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
pickerValueMulTwoTwo.push(pickerValueArray[changeValue[0]].children[i]);
}
this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
// 0
changeValue[1] = 0;
}
this.pickerValue = changeValue;
} else if (this.deepLength === 3) {
let pickerValueArray = this.pickerValueArray;
let changeValue = e.detail.value;
let pickerValueMulThreeTwo = [];
let pickerValueMulThreeThree = [];
//
//
if (changeValue[0] !== this.pickerValue[0]) {
this.pickerValueMulThreeTwo = [];
for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
pickerValueMulThreeTwo.push(pickerValueArray[changeValue[0]].children[i]);
}
//
for (let i = 0, length = pickerValueArray[changeValue[0]].children[0].children.length; i <
length; i++) {
pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[0].children[i]);
}
changeValue[1] = 0;
changeValue[2] = 0;
this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
} else if (changeValue[1] !== this.pickerValue[1]) {
//
//
this.pickerValueMulThreeThree = [];
pickerValueMulThreeTwo = this.pickerValueMulThreeTwo;
for (let i = 0, length = pickerValueArray[changeValue[0]].children[changeValue[1]].children
.length; i <
length; i++) {
pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[changeValue[1]]
.children[
i]);
}
changeValue[2] = 0;
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
}
this.pickerValue = changeValue;
}
let pickObj = {
index: this.pickerValue,
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
};
this.$emit('onChange', pickObj);
},
// pxikerLabel
_getPickerLabelAndValue(value, mode) {
let pickerLable;
let pickerGetValue = [];
// selector
if (mode === 'selector') {
pickerLable = this.pickerValueSingleArray[value].label;
pickerGetValue.push(this.pickerValueSingleArray[value].value);
} else if (mode === 'timeSelector') {
pickerLable = `${this.pickerValueHour[value[0]].label}-${this.pickerValueMinute[value[1]].label}`;
pickerGetValue.push(this.pickerValueHour[value[0]].value);
pickerGetValue.push(this.pickerValueHour[value[1]].value);
} else if (mode === 'multiSelector') {
for (let i = 0; i < value.length; i++) {
if (i > 0) {
pickerLable += this.pickerValueMulArray[i][value[i]].label + (i === value.length - 1 ? '' :
'-');
} else {
pickerLable = this.pickerValueMulArray[i][value[i]].label + '-';
}
pickerGetValue.push(this.pickerValueMulArray[i][value[i]].value);
}
} else if (mode === 'multiLinkageSelector') {
/* eslint-disable indent */
pickerLable =
this.deepLength === 2 ?
`${this.pickerValueMulTwoOne[value[0]].label}-${this.pickerValueMulTwoTwo[value[1]].label}` :
`${this.pickerValueMulThreeOne[value[0]].label}-${this.pickerValueMulThreeTwo[value[1]].label}-${this.pickerValueMulThreeThree[value[2]].label}`;
if (this.deepLength === 2) {
pickerGetValue.push(this.pickerValueMulTwoOne[value[0]].value);
pickerGetValue.push(this.pickerValueMulTwoTwo[value[1]].value);
} else {
pickerGetValue.push(this.pickerValueMulThreeOne[value[0]].value);
pickerGetValue.push(this.pickerValueMulThreeTwo[value[1]].value);
pickerGetValue.push(this.pickerValueMulThreeThree[value[2]].value);
}
/* eslint-enable indent */
}
return {
label: pickerLable,
value: pickerGetValue
};
},
// pickerValue
_initPickerVale() {
if (this.pickerValue.length === 0) {
if (this.mode === 'selector') {
this.pickerValue = [0];
} else if (this.mode === 'multiSelector') {
this.pickerValue = new Int8Array(this.pickerValueArray.length);
} else if (
this.mode === 'multiLinkageSelector' &&
this.deepLength === 2
) {
this.pickerValue = [0, 0];
} else if (
this.mode === 'multiLinkageSelector' &&
this.deepLength === 3
) {
this.pickerValue = [0, 0, 0];
}
}
}
}
};
</script>
<style>
.pickerMask {
position: fixed;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
}
.mpvue-picker-content {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
transition: all 0.3s ease;
transform: translateY(100%);
z-index: 3000;
}
.mpvue-picker-view-show {
transform: translateY(0);
}
.mpvue-picker__hd {
display: flex;
padding: 9px 15px;
background-color: #fff;
position: relative;
text-align: center;
font-size: 17px;
}
.mpvue-picker__hd:after {
content: ' ';
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid #e5e5e5;
color: #e5e5e5;
transform-origin: 0 100%;
transform: scaleY(0.5);
}
.mpvue-picker__action {
display: block;
flex: 1;
color: #1aad19;
}
.mpvue-picker__action:first-child {
text-align: left;
color: #888;
}
.mpvue-picker__action:last-child {
text-align: right;
}
.picker-item {
text-align: center;
line-height: 40px;
font-size: 16px;
}
.mpvue-picker-view {
position: relative;
bottom: 0;
left: 0;
width: 100%;
height: 238px;
background-color: rgba(255, 255, 255, 1);
}
</style>

175
fe/PDA/components/mpvueGestureLock/gestureLock.js

@ -0,0 +1,175 @@
class GestureLock {
constructor(containerWidth, cycleRadius) {
this.containerWidth = containerWidth; // 容器宽度
this.cycleRadius = cycleRadius; // 圆的半径
this.circleArray = []; // 全部圆的对象数组
this.checkPoints = []; // 选中的圆的对象数组
this.lineArray = []; // 已激活锁之间的线段数组
this.lastCheckPoint = 0; // 最后一个激活的锁
this.offsetX = 0; // 容器的 X 偏移
this.offsetY = 0; // 容器的 Y 偏移
this.activeLine = {}; // 最后一个激活的锁与当前位置之间的线段
this.windowWidth = wx.getSystemInfoSync().windowWidth; // 窗口大小(用于rpx 和 px 转换)
this.initCircleArray();
}
// 初始化 画布上的 9个圆
initCircleArray() {
const cycleMargin = (this.containerWidth - 6 * this.cycleRadius) / 6;
let count = 0;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
count++;
this.circleArray.push({
count: count,
x: this.rpxTopx((cycleMargin + this.cycleRadius) * (j * 2 + 1)),
y: this.rpxTopx((cycleMargin + this.cycleRadius) * (i * 2 + 1)),
radius: this.rpxTopx(this.cycleRadius),
check: false,
style: {
left: (cycleMargin + this.cycleRadius) * (j * 2 + 1) - this.cycleRadius + 'rpx',
top: (cycleMargin + this.cycleRadius) * (i * 2 + 1) - this.cycleRadius + 'rpx',
width: this.cycleRadius * 2 + 'rpx',
}
});
}
}
}
onTouchStart(e) {
this.setOffset(e);
this.checkTouch({
x: e.touches[0].pageX - this.offsetX,
y: e.touches[0].pageY - this.offsetY
});
}
onTouchMove(e) {
this.moveDraw(e)
}
onTouchEnd(e) {
const checkPoints = this.checkPoints;
this.reset();
return checkPoints;
}
// 初始化 偏移量
setOffset(e) {
this.offsetX = e.currentTarget.offsetLeft;
this.offsetY = e.currentTarget.offsetTop;
}
// 检测当时 触摸位置是否位于 锁上
checkTouch({
x,
y
}) {
for (let i = 0; i < this.circleArray.length; i++) {
let point = this.circleArray[i];
if (this.isPointInCycle(x, y, point.x, point.y, point.radius)) {
if (!point.check) {
this.checkPoints.push(point.count);
if (this.lastCheckPoint != 0) {
// 已激活锁之间的线段
const line = this.drawLine(this.lastCheckPoint, point);
this.lineArray.push(line);
}
this.lastCheckPoint = point;
}
point.check = true;
return;
}
}
}
// 画线 - 返回 样式 对象
drawLine(start, end) {
const width = this.getPointDis(start.x, start.y, end.x, end.y);
const rotate = this.getAngle(start, end);
return {
activeLeft: start.x + 'px',
activeTop: start.y + 'px',
activeWidth: width + 'px',
activeRotate: rotate + 'deg'
}
}
// 获取 画线的 角度
getAngle(start, end) {
var diff_x = end.x - start.x,
diff_y = end.y - start.y;
if (diff_x >= 0) {
return 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI);
} else {
return 180 + 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI);
}
}
// 判断 当前点是否位于 锁内
isPointInCycle(x, y, circleX, circleY, radius) {
return (this.getPointDis(x, y, circleX, circleY) < radius) ? true : false;
}
// 获取两点之间距离
getPointDis(ax, ay, bx, by) {
return Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2));
}
// 移动 绘制
moveDraw(e) {
// 画经过的圆
const x = e.touches[0].pageX - this.offsetX;
const y = e.touches[0].pageY - this.offsetY;
this.checkTouch({
x,
y
});
// 画 最后一个激活的锁与当前位置之间的线段
this.activeLine = this.drawLine(this.lastCheckPoint, {
x,
y
});
}
// 使 画布 恢复初始状态
reset() {
this.circleArray.forEach((item) => {
item.check = false;
});
this.checkPoints = [];
this.lineArray = [];
this.activeLine = {};
this.lastCheckPoint = 0;
}
// 获取 最后一个激活的锁与当前位置之间的线段
getActiveLine() {
return this.activeLine;
}
// 获取 圆对象数组
getCycleArray() {
return this.circleArray;
}
// 获取 已激活锁之间的线段
getLineArray() {
return this.lineArray;
}
// 将 RPX 转换成 PX
rpxTopx(rpx) {
return rpx / 750 * this.windowWidth;
}
}
export default GestureLock;

138
fe/PDA/components/mpvueGestureLock/index.vue

@ -0,0 +1,138 @@
<template>
<view class="gesture-lock" :class="{error:error}" :style="{width: containerWidth +'rpx', height:containerWidth +'rpx'}"
@touchstart.stop="onTouchStart" @touchmove.stop="onTouchMove" @touchend.stop="onTouchEnd">
<!-- 同级 v-for key 重复会有问题需要套一层 -->
<!-- 9 个圆 -->
<view>
<view v-for="(item,i) in circleArray" :key="i" class="cycle" :class="{check:item.check}" :style="{left:item.style.left,top:item.style.top,width:item.style.width,height:item.style.width}">
</view>
</view>
<view>
<!-- 已激活锁之间的线段 -->
<view v-for="(item,i) in lineArray" :key="i" class="line" :style="{left:item.activeLeft,top:item.activeTop,width:item.activeWidth,'-webkit-transform':'rotate('+item.activeRotate+')',transform:'rotate('+item.activeRotate+')'}">
</view>
</view>
<!-- 最后一个激活的锁与当前位置之间的线段 -->
<view class="line" :style="{left:activeLine.activeLeft,top:activeLine.activeTop,width:activeLine.activeWidth,'-webkit-transform':'rotate('+activeLine.activeRotate+')',transform:'rotate('+activeLine.activeRotate+')'}">
</view>
</view>
</template>
<script>
import GestureLock from './gestureLock';
export default {
name: 'index',
props: {
/**
* 容器宽度
*/
containerWidth: {
type: [Number, String],
default: 0
},
/**
* 圆的半径
*/
cycleRadius: {
type: [Number, String],
default: 0
},
/**
* 已设定的密码
*/
password: {
type: Array,
default () {
return []
}
},
},
data() {
return {
gestureLock: {}, //
circleArray: [], //
lineArray: [], // 线
activeLine: {}, // 线
error: false
}
},
methods: {
onTouchStart(e) {
this.gestureLock.onTouchStart(e);
this.refesh();
},
onTouchMove(e) {
this.gestureLock.onTouchMove(e);
this.refesh();
},
onTouchEnd(e) {
const checkPoints = this.gestureLock.onTouchEnd(e);
if (!this.password.length || checkPoints.join('') == this.password.join('')) {
this.refesh();
this.$emit('end', checkPoints);
} else {
this.error = true;
setTimeout(() => {
this.refesh();
this.$emit('end', checkPoints);
}, 800);
}
},
refesh() {
this.error = false;
this.circleArray = this.gestureLock.getCycleArray();
this.lineArray = this.gestureLock.getLineArray();
this.activeLine = this.gestureLock.getActiveLine();
}
},
mounted() {
this.gestureLock = new GestureLock(this.containerWidth, this.cycleRadius);
this.refesh();
}
}
</script>
<style scoped>
.gesture-lock {
margin: 0 auto;
position: relative;
box-sizing: border-box;
overflow: auto;
}
.gesture-lock .cycle {
box-sizing: border-box;
position: absolute;
border: 2px solid #66aaff;
border-radius: 50%;
}
.gesture-lock .cycle.check:after {
content: "";
display: block;
position: absolute;
width: 32%;
height: 32%;
border: 2px solid #66aaff;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.gesture-lock .line {
height: 0;
border-top: 2px solid #66aaff;
position: absolute;
transform-origin: left center;
}
.gesture-lock.error .cycle.check,
.gesture-lock.error .cycle.check:after,
.gesture-lock.error .line {
border-color: #ffa197;
}
</style>

38
fe/PDA/components/page-foot/page-foot.vue

@ -0,0 +1,38 @@
<template name="page-foot">
<view class="page-share-title">
<text>感谢{{name}}提供本示例</text>
<text class="submit" @click="submit">我也提交</text>
</view>
</template>
<script>
export default {
name: "page-foot",
props: {
name: {
type: String,
default: ""
}
},
methods: {
submit() {
uni.showModal({
content:"hello uni-app开源地址为https://github.com/dcloudio/uni-app/tree/master/examples,请在这个开源项目上贡献你的代码",
showCancel:false
})
}
}
}
</script>
<style>
.page-share-title {
text-align: center;
font-size: 30rpx;
color: #BEBEBE;
padding: 20rpx 0;
}
.submit {
border-bottom: 1rpx solid #BEBEBE;
}
</style>

16
fe/PDA/components/page-head/page-head.vue

@ -0,0 +1,16 @@
<template name="page-head">
<view class="common-page-head">
<view class="common-page-head-title">{{title}}</view>
</view>
</template>
<script>
export default {
name: "page-head",
props: {
title: {
type: String,
default: ""
}
}
}
</script>

66
fe/PDA/components/product.vue

@ -0,0 +1,66 @@
<template>
<view class="product">
<image class="product-image" :src="image ? image : 'https://via.placeholder.com/150x200'"></image>
<view class="product-title">{{title}}</view>
<view class="product-price">
<text class="product-price-favour">{{originalPrice}}</text>
<text class="product-price-original">{{favourPrice}}</text>
<text class="product-tip">{{tip}}</text>
</view>
</view>
</template>
<script>
export default {
name: 'product',
props: ['image', 'title', 'originalPrice', 'favourPrice', 'tip']
}
</script>
<style>
.product {
padding: 10rpx 20rpx;
display: flex;
flex-direction: column;
}
.product-image {
height: 330rpx;
width: 330rpx;
}
.product-title {
width: 300rpx;
font-size: 32rpx;
word-break: break-all;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.product-price {
font-size: 28rpx;
position: relative;
}
.product-price-original {
color: #E80080;
}
.product-price-favour {
color: #888888;
text-decoration: line-through;
margin-left: 10rpx;
}
.product-tip {
position: absolute;
right: 10rpx;
background-color: #FF3333;
color: #FFFFFF;
padding: 0 10rpx;
border-radius: 5rpx;
}
</style>

175
fe/PDA/components/tab-nvue/mediaList.vue

@ -0,0 +1,175 @@
<template>
<view class="view">
<view class="list-cell view" hover-class="uni-list-cell-hover" @click="bindClick">
<view class="media-list view" v-if="options.title">
<view class="view" :class="{'media-image-right': options.article_type === 2, 'media-image-left': options.article_type === 1}">
<text class="media-title" :class="{'media-title2': options.article_type === 1 || options.article_type === 2}">{{options.title}}</text>
<view v-if="options.image_list || options.image_url" class="image-section view" :class="{'image-section-right': options.article_type === 2, 'image-section-left': options.article_type === 1}">
<image class="image-list1" :class="{'image-list2': options.article_type === 1 || options.article_type === 2}"
v-if="options.image_url" :src="options.image_url"></image>
<image class="image-list3" v-if="options.image_list" :src="source.url" v-for="(source, i) in options.image_list"
:key="i" />
</view>
</view>
<view class="media-foot view">
<view class="media-info view">
<text class="info-text">{{options.source}}</text>
<text class="info-text">{{options.comment_count}}条评论</text>
<text class="info-text">{{options.datetime}}</text>
</view>
<view class="max-close-view view" @click.stop="close">
<view class="close-view view"><text class="close">×</text></view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
options: {
type: Object,
default: function(e) {
return {}
}
}
},
methods: {
close(e) {
this.$emit('close');
},
bindClick() {
this.$emit('click');
}
}
}
</script>
<style>
.view {
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.list-cell {
width: 750rpx;
padding: 0 30rpx;
}
.uni-list-cell-hover {
background-color: #eeeeee;
}
.media-list {
flex: 1;
flex-direction: column;
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #c8c7cc;
padding: 20rpx 0;
}
.media-image-right {
flex-direction: row;
}
.media-image-left {
flex-direction: row-reverse;
}
.media-title {
flex: 1;
}
.media-title {
lines: 3;
text-overflow: ellipsis;
font-size: 32rpx;
color: #555555;
}
.media-title2 {
flex: 1;
margin-top: 6rpx;
line-height: 40rpx;
}
.image-section {
margin-top: 20rpx;
flex-direction: row;
justify-content: space-between;
}
.image-section-right {
margin-top: 0rpx;
margin-left: 10rpx;
width: 225rpx;
height: 146rpx;
}
.image-section-left {
margin-top: 0rpx;
margin-right: 10rpx;
width: 225rpx;
height: 146rpx;
}
.image-list1 {
width: 690rpx;
height: 481rpx;
}
.image-list2 {
width: 225rpx;
height: 146rpx;
}
.image-list3 {
width: 225rpx;
height: 146rpx;
}
.media-info {
flex-direction: row;
}
.info-text {
margin-right: 20rpx;
color: #999999;
font-size: 24rpx;
}
.media-foot {
margin-top: 20rpx;
flex-direction: row;
justify-content: space-between;
}
.max-close-view {
align-items: center;
justify-content: flex-end;
flex-direction: row;
height: 40rpx;
width: 80rpx;
}
.close-view {
border-style: solid;
border-width: 1px;
border-color: #999999;
border-radius: 10rpx;
justify-content: center;
height: 30rpx;
width: 40rpx;
line-height: 30rpx;
}
.close {
text-align: center;
color: #999999;
font-size: 28rpx;
}
</style>

5046
fe/PDA/components/u-charts/u-charts.js

File diff suppressed because it is too large

59
fe/PDA/components/u-link/u-link.vue

@ -0,0 +1,59 @@
<template>
<text style="text-decoration:underline" :href="href" @click="openURL" :inWhiteList="inWhiteList">{{text}}</text>
</template>
<script>
/**
* @description u-link是一个外部网页超链接组件在小程序内打开内部web-view组件或复制url在app内打开外部浏览器在h5端打开新网页
* @property {String} href 点击后打开的外部网页url小程序中必须以https://
* @property {String} text 显示的文字
* @property {Boolean} inWhiteList 是否在小程序白名单中如果在的话在小程序端会直接打开内置web-view否则会只会复制url提示在外部打开
* @example * <u-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn" :inWhiteList="true"></u-link>
*/
export default {
name: 'u-link',
props: {
href: {
type: String,
default: ''
},
text: {
type: String,
default: ''
},
inWhiteList: {
type: Boolean,
default: false
}
},
methods: {
openURL() {
// #ifdef APP-PLUS
plus.runtime.openURL(this.href) //使web-view
// #endif
// #ifdef H5
window.open(this.href)
// #endif
// #ifdef MP
if (this.inWhiteList) { //webview
uni.navigateTo({
url: '/pages/component/web-view/web-view?url=' + this.href
});
} else {
uni.setClipboardData({
data: this.href
});
uni.showModal({
content: '本网址无法直接在小程序内打开。已自动复制网址,请在手机浏览器里粘贴该网址',
showCancel: false
});
}
// #endif
}
}
}
</script>
<style>
</style>

88
fe/PDA/hybrid/html/local.html

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>本地网页</title>
<style type="text/css">
.btn {
display: block;
margin: 20px auto;
padding: 5px;
background-color: #007aff;
border: 0;
color: #ffffff;
height: 40px;
width: 200px;
}
.btn-red {
background-color: #dd524d;
}
.btn-yellow {
background-color: #f0ad4e;
}
.desc {
padding: 10px;
color: #999999;
}
</style>
</head>
<body>
<p class="desc">web-view 组件加载本地 html 示例,仅在 App 环境下生效。点击下列按钮,跳转至其它页面。</p>
<div class="btn-list">
<button class="btn" type="button" data-action="navigateTo">navigateTo</button>
<button class="btn" type="button" data-action="redirectTo">redirectTo</button>
<button class="btn" type="button" data-action="navigateBack">navigateBack</button>
<button class="btn" type="button" data-action="reLaunch">reLaunch</button>
<button class="btn" type="button" data-action="switchTab">switchTab</button>
</div>
<p class="desc">网页向应用发送消息。注意:小程序端应用会在此页面后退时接收到消息。</p>
<div class="btn-list">
<button class="btn btn-red" type="button" id="postMessage">postMessage</button>
</div>
<!-- uni 的 SDK -->
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.1/index.js"></script>
<script type="text/javascript">
document.addEventListener('UniAppJSBridgeReady', function() {
document.querySelector('.btn-list').addEventListener('click', function(evt) {
var target = evt.target;
if (target.tagName === 'BUTTON') {
var action = target.getAttribute('data-action');
switch (action) {
case 'switchTab':
uni.switchTab({
url: '/pages/tabBar/API/API'
});
break;
case 'reLaunch':
uni.reLaunch({
url: '/pages/tabBar/API/API'
});
break;
case 'navigateBack':
uni.navigateBack({
delta: 1
});
break;
default:
uni[action]({
url: '/pages/component/button/button'
});
break;
}
}
});
document.querySelector("#postMessage").addEventListener('click', function() {
uni.postMessage({
data: {
action: 'message'
}
});
})
});
</script>
</body>
</html>

20
fe/PDA/index.html

@ -0,0 +1,20 @@
<!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-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

23
fe/PDA/libs/versionUpdate.js

@ -0,0 +1,23 @@
import axios from 'axios'
const isNewVersion = () => {
let updae_url = getApp().globalData.text;
let url = updae_url+ `/static/version.json?t=${new Date().getTime()}`
axios.get(url).then(res => {
if (res.status === 200) {
let vueVersion = res.data.version;
let localVueVersion = localStorage.getItem('vueVersion');
if (localVueVersion && localVueVersion != vueVersion) {
localStorage.setItem('vueVersion', vueVersion);
window.location.reload();
return;
} else {
localStorage.setItem('vueVersion', vueVersion);
}
}
})
}
export default {
isNewVersion
}

90
fe/PDA/main.js

@ -0,0 +1,90 @@
import App from './App'
import store from './store'
import './router/my_router.js';//引入拦截
// #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
// #ifdef VUE3
import {
createSSRApp
} from 'vue'
export function createApp() {
const app = createSSRApp(App)
// 使用 uView UI
app.use(store)
app.config.globalProperties.$adpid = "1111111111"
app.config.globalProperties.$pageSize = 10
app.config.globalProperties.$backgroundAudioData = {
playing: false,
playTime: 0,
formatedPlayTime: '00:00:00'
}
startApp(app);
return {
app
}
}
export function startApp(app) {
uni.request({
url:'/static/config.json',
method: 'GET',
data:{},
success: (res) => {
console.log("请求",res)
if(res.data!=""){
//在配置中读url,company等信息
app.config.globalProperties.$dev_url = res.data.params.dev;
app.config.globalProperties.$companyCode = res.data.params.companyCode;
app.config.globalProperties.$warehouseCode = res.data.params.warehouseCode;
app.config.globalProperties.$putawayLocationTypes = res.data.params.putawayLocationTypes; //创建上架任务的库存类型
app.config.globalProperties.$putawayInventoryStatus = res.data.params.putawayInventoryStatus; //创建上架任务的库存状态
app.config.globalProperties.$print_url = res.data.params.print_url; //打印的服务地址
app.config.globalProperties.$isScrapScanToLocation = res.data.params.isScrapScanToLocation; //原料报废是否显示库位
app.config.globalProperties.$isReceiptToday = res.data.params.isReceiptToday; //采购收货是否只看今天的采购任务
app.config.globalProperties.$scrapReason = res.data.params.scrapReason; //原料报废原因字典项
app.config.globalProperties.$purchaseReturnReason = res.data.params.purchaseReturnReason; //采购退货原因字典项
app.config.globalProperties.$returnBeforPutawayReason = res.data.params.returnBeforPutawayReason; //上架前退货原因字典项
app.config.globalProperties.$receiptCheckReason = res.data.params.receiptCheckReason; //采购收货不合格原因字典项
app.config.globalProperties.$configList = res.data.configList;
app.config.globalProperties.$isShowQty_receipt = res.data.params.isShowQty_receipt;
app.config.globalProperties.$isEditShowQty_receipt = res.data.params.isEditShowQty_receipt;
getApp().globalData.text = res.data.params.version_update_url;
getApp().globalData.dev_url = res.data.params.dev;
getApp().globalData.print_url = res.data.params.print_url;
// console.log("地址",app.config.globalProperties.$dev_url)
}
},
fail: (error) => {
}
})
return {startApp};
}
// #endif

187
fe/PDA/manifest.json

@ -0,0 +1,187 @@
{
"name" : "pda_vue_3.0",
"appid" : "__UNI__43932FE",
"description" : "应用描述",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"nvueLaunchMode" : "fast",
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {
"OAuth" : {},
"Payment" : {},
"Push" : {},
"Share" : {},
"Speech" : {},
"VideoPlayer" : {}
},
"distribute" : {
"android" : {
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
]
},
"ios" : {
"UIBackgroundModes" : [ "audio" ],
"urlschemewhitelist" : [ "baidumap", "iosamap" ]
},
"sdkConfigs" : {
"speech" : {
"ifly" : {}
}
},
"orientation" : [ "portrait-primary" ]
},
"uniStatistics" : {
"enable" : true
}
},
"quickapp" : {},
"quickapp-native" : {
"icon" : "/static/logo.png",
"package" : "com.example.demo",
"features" : [
{
"name" : "system.clipboard"
}
]
},
"quickapp-webview" : {
"icon" : "/static/logo.png",
"package" : "com.example.demo",
"minPlatformVersion" : 1070,
"versionName" : "1.0.0",
"versionCode" : 100
},
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "演示定位能力"
}
},
"uniStatistics" : {
"enable" : true
}
},
"mp-alipay" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
}
},
"mp-baidu" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
}
},
"mp-toutiao" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
}
},
"mp-jd" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
}
},
"h5" : {
"template" : "template.h5.html",
"router" : {
"mode" : "history",
"base" : ""
},
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "TKUBZ-D24AF-GJ4JY-JDVM2-IBYKK-KEBCU"
}
}
},
"async" : {
"timeout" : 20000
},
"uniStatistics" : {
"enable" : true
}
},
"vueVersion" : "3",
"mp-kuaishou" : {
"uniStatistics" : {
"enable" : true
}
},
"mp-lark" : {
"uniStatistics" : {
"enable" : true
}
},
"mp-qq" : {
"uniStatistics" : {
"enable" : true
}
},
"quickapp-webview-huawei" : {
"uniStatistics" : {
"enable" : true
}
},
"quickapp-webview-union" : {
"uniStatistics" : {
"enable" : true
}
},
"uniStatistics" : {
"version" : "2",
"enable" : true
}
}

53
fe/PDA/mycomponents/comItem/comBalanceItem.vue

@ -0,0 +1,53 @@
<template>
<view class="choose_main common_card">
<com-item-top :dataContent="dataContent"></com-item-top>
<com-erp-location :erpLocationCode="dataContent.locationErpCode"></com-erp-location>
<com-item-bottom :dataContent="dataContent"></com-item-bottom>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
} from '@/common/basic.js';
import comItemTop from '@/mycomponents/comItem/comItemTop.vue'
import comErpLocation from '@/mycomponents/comItem/comErpLocation.vue'
import comItemBottom from '@/mycomponents/comItem/comItemBottom.vue'
export default {
name: 'comTransfer',
components: {
comItemTop,
comErpLocation,
comItemBottom
},
props: {
dataContent: {
type: Object,
default: {}
},
},
data() {
return {
}
},
created() {
},
methods: {
qtyInput(value, item) {
this.$emit('qtyInput', value, item)
},
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

50
fe/PDA/mycomponents/comItem/comBaseItem.vue

@ -0,0 +1,50 @@
<!-- 零件基础信息卡片包括:
零件号名称描述数量和单位
箱码批次库位状态
可以通过属性控制库位和状态是否显示 -->
<template>
<view class="common_card">
<com-item-top :dataContent="dataContent"></com-item-top>
<com-item-bottom :dataContent="dataContent" v-if="displayBottomInfo"></com-item-bottom>
</view>
</template>
<script>
import comItemTop from '@/mycomponents/comItem/comItemTop.vue'
import comItemBottom from '@/mycomponents/comItem/comItemBottom.vue'
export default {
name: 'comBaseItem',
components: {
comItemTop,
comItemBottom
},
props: {
dataContent: {
type: Object,
default: {}
},
displayStatus: {
type: Boolean,
default: true
},
displayBottomInfo: {
type: Boolean,
default: true
},
},
data() {
return {}
},
created() {
},
methods: {
}
}
</script>
<style>
</style>

95
fe/PDA/mycomponents/comItem/comBottomItem.vue

@ -0,0 +1,95 @@
<!-- 零件基础信息卡片包括:
零件号名称描述数量和单位
箱码批次库位状态
可以通过属性控制库位和状态是否显示 -->
<template>
<view class="common_card">
<view class="ljh_box">
<view class="ljh_info">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="label_xm font_xs fr">{{ dataContent.packingCode }}</view>
</view>
<view class="uni-flex space-between desc_card">
<view class="ljh_left">
<view class="text_lightblue font_xs">{{dataContent.itemName }}</view>
</view>
<view class="ljh_right">
<text class="tnum">{{dataContent.qty}}</text>
<text class="tunit">{{dataContent.uom}}</text>
</view>
</view>
</view>
<view class="uni-flex uni-row bot_card" v-if="displayBottomInfo">
<!-- 库位 -->
<view class="bot_card_item" v-if="displayLocation">
<label class="icon_bg icon_bg_kw">
<image class="icon_normal" src="@/static/icons_ui/icon_kw.svg">
</image>
</label>
<text>{{ dataContent.locationCode }}</text>
</view>
<!-- 批次 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg">
</image>
</label>
<text>{{dataContent.lot}}</text>
</view>
<!-- 状态 -->
<view class="bot_card_item item_short" v-if="displayStatus">
<!-- <label class="icon_state" :class="dataContent.status | statusStyle"></label> -->
<text class="state_point" :class="statusStyle(dataContent.status)">
{{ statusColor(dataContent.status) }}
</text>
</view>
</view>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
} from '@/common/basic.js';
export default {
name: 'comBaseItem',
components: {},
props: {
dataContent: {
type: Object,
default: {}
},
displayLocation: {
type: Boolean,
default: true
},
displayStatus: {
type: Boolean,
default: true
},
displayBottomInfo: {
type: Boolean,
default: true
},
},
data() {
return {}
},
created() {
},
methods: {
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

39
fe/PDA/mycomponents/comItem/comErpLocation.vue

@ -0,0 +1,39 @@
<template>
<view class="cen_card">
<view class="label_box uni-flex uni-row">
<view class="label_info">
<label class="">
<image class="icon_normal" src="@/static/icons_ui/icon_erp.svg"></image>
</label>
<text >{{erpLocationCode }}</text>
<!-- style="margin-top:4rpx ;margin-bottom: 4px;" -->
</view>
</view>
</view>
</template>
<script>
export default {
name: 'comErpLocation',
components: {},
props: {
erpLocationCode: {
type: String,
default: ""
}
},
data() {
return {}
},
created() {
},
methods: {
}
}
</script>
<style>
</style>

73
fe/PDA/mycomponents/comItem/comItemBottom.vue

@ -0,0 +1,73 @@
<template>
<view class="uni-flex uni-row bot_card">
<!-- 库位 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_kw">
<image class="icon_normal" src="@/static/icons_ui/icon_kw.svg">
</image>
</label>
<text>{{ dataContent.locationCode }}</text>
</view>
<!-- 批次 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg">
</image>
</label>
<text >{{dataContent.lot}}</text>
</view>
<!-- 状态 -->
<view class="bot_card_item item_short">
<!-- <label class="icon_state" :class="dataContent.status | statusStyle"></label> -->
<text class="state_point" :class="statusStyle(dataContent.status) ">
{{ statusColor(dataContent.status)}}
</text>
</view>
<!-- <view class="summary_state">
<label class="icon_state" :class="item.status | statusStyle"
style="margin-right: 10rpx;"></label>
<text class="state_point" :class="item.status | statusStyle"
style="background-color: transparent;">
{{ item.status | statusColor}}
</text>
</view> -->
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
} from '@/common/basic.js';
export default {
name: 'comItemBottom',
components: {},
props: {
dataContent: {
type: Object,
default: {}
}
},
data() {
return {}
},
created() {
},
methods: {
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

62
fe/PDA/mycomponents/comItem/comItemErpCenter.vue

@ -0,0 +1,62 @@
<template>
<view class="uni-flex uni-row bot_card">
<!-- 库位 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_kw">
<image class="icon_normal" src="@/static/icons_ui/icon_kw.svg">
</image>
</label>
<text>{{ dataContent.locationCode }}</text>
</view>
<!-- 批次 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg">
</image>
</label>
<text>{{dataContent.lot}}</text>
</view>
<!-- 状态 -->
<view class="bot_card_item item_short">
<!-- <label class="icon_state" :class="dataContent.status | statusStyle"></label> -->
<text class="state_point" :class="statusStyle(dataContent.status)">
{{ statusColor(dataContent.status)}}
</text>
</view>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
} from '@/common/basic.js';
export default {
name: 'comItemBottom',
components: {},
props: {
dataContent: {
type: Object,
default: {}
}
},
data() {
return {}
},
created() {
},
methods: {
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

47
fe/PDA/mycomponents/comItem/comItemLocationCenter.vue

@ -0,0 +1,47 @@
<template>
<view class="cen_card">
<view class="cell_box uni-flex uni-row">
<view class="cell_info">
<view class="text_lightblue">仓库</view>
<view>{{dataContent.warehouseCode}}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">库区</view>
<view>{{dataContent.locationArea }}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">库位组</view>
<view>{{ dataContent.locationGroup }}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">ERP储位</view>
<view>{{ dataContent.locationErpCode }}</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'comItemLocationCenter',
components: {},
props: {
dataContent: {
type: Object,
default: {}
}
},
data() {
return {}
},
created() {
},
methods: {
}
}
</script>
<style>
</style>

58
fe/PDA/mycomponents/comItem/comItemTop.vue

@ -0,0 +1,58 @@
<!-- 零件基础信息卡片包括:
零件号名称描述数量和单位
箱码批次库位状态
可以通过属性控制库位和状态是否显示 -->
<template>
<view class="ljh_box">
<view class="ljh_info">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="label_xm font_xs fr">{{ dataContent.packingCode }}</view>
</view>
<view class="uni-flex space-between desc_card">
<view class="ljh_left">
<view class="text_lightblue font_xs">{{dataContent.itemName }}</view>
<view class="text_lightblue font_xs">{{dataContent.itemDesc1}}</view>
</view>
<view class="ljh_right">
<text class="tnum">{{dataContent.qty}}</text>
<text class="tunit">{{dataContent.uom}}</text>
</view>
</view>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
} from '@/common/basic.js';
export default {
name: 'comItemTop',
components: {},
props: {
dataContent: {
type: Object,
default: {}
},
},
data() {
return {}
},
created() {
},
methods: {
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

493
fe/PDA/mycomponents/comItem/comJobScanDetail.vue

@ -0,0 +1,493 @@
<!-- 收货任务详情 -->
<template>
<page-meta root-font-size="18px"></page-meta>
<view class="">
<view class="top_card">
<view class="device-detail" style="padding-bottom: 0 !important;">
<view class="ljh_box nopad">
<text class="state-style fl margin_xs_top" :class="statusStyle(receiptJob.jobStatus)">
{{ statusColor(receiptJob.jobStatus) }}
</text>
<text class="tit_ljh">{{ receiptJob.number }}</text>
</view>
<view class="cell_box uni-flex uni-row margin_top">
<view class="cell_info">
<view class="text_lightblue">总数量</view>
<view class="text_black text_bold">{{ allCount}}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">已扫描</view>
<view class="text_black text_bold">{{ scanCount}}</view>
</view>
</view>
</view>
</view>
<scroll-view scroll-y="true" class="scroll-detail" style="margin-top: 20rpx;">
<view class="detail-list" v-for="(item, index) in receiptJob.details" :key="item.id"
style="margin-top: 4rpx;">
<view class="detail-content common_card">
<view class="choose_main">
<view class="ljh_box">
<view class="ljh_info">
<view class="tit_ljh">{{ item.itemCode }}</view>
<view class="label_xm font_sm fr">{{ item.recommendPackingCode }}</view>
</view>
<view class="desc_card uni-flex space-between">
<view class="ljh_left desc_ljh">
<view class="font_xs text_lightblue">{{ item.itemName }}</view>
<view class="font_xs text_lightblue">{{ item.itemDesc1 }}</view>
</view>
</view>
</view>
<view class="list_form">
<view class="uni-container">
<uni-table style="overflow-x: hidden;">
<uni-tr>
<uni-th width="100"></uni-th>
<uni-th width="100" align="center">整包</uni-th>
<uni-th width="100" align="center">实际</uni-th>
</uni-tr>
<uni-tr>
<uni-th width="100">数量({{item.recommendUom}})</uni-th>
<uni-th width="100" align="center">
<text class="text_black"
style="font-size: 1rem;">{{item.recommendQty}}</text>
</uni-th>
<uni-th width="100" align="center">
<text class="text_black" style="font-size: 1rem;">{{item.handledQty}}</text>
</uni-th>
</uni-tr>
</uni-table>
</view>
</view>
<view class="photo_btn fr" style="margin:0 20rpx 20rpx;"
v-if="item.purchaseReceiptInspectStatus>1" @click="takePhoto(item)">
<image class="icon_normal fl" src="@/static/icons_ui/icon_take_photo.svg"></image>
<text class="fl">拍照</text>
</view>
</view>
<view v-if="item.purchaseReceiptInspectStatus>1"
:class="item.purchaseReceiptInspectStatus==2?'choose_marked':'choose_marked_faild'">
<image v-if='item.purchaseReceiptInspectStatus==2' src="@/static/icons_ui/icon_passed.svg">
</image>
<image v-else-if="item.purchaseReceiptInspectStatus==3"
src="@/static/icons_ui/icon_notpass.svg"></image>
</view>
</view>
</view>
</scroll-view>
<view class="pop_btn ">
<view class="new_btn_bot uni-flex uni-row space-between btn_unusual">
<button class="new_clear_btn btn_triple" @click="clear()">清空</button>
<button class="new_save_btn btn_triple" @click="unInspectToQualified()">待检合格</button>
<button class="new_save_btn btn_triple" @click="inspectResult()">检验结果</button>
</view>
</view>
<com-message ref="comMessage"></com-message>
<win-scan-button @goScan='openScanPopup'></win-scan-button>
<win-scan-by-pack ref="scanPopup" @getScanResult='getScanResult'></win-scan-pack>
<receipt-check ref='receiptCheck' :dataContent='selectedItem' :disabled='false'
@getReceiptResult='getPhotoResult'>
</receipt-check>
</view>
</template>
<script>
import {
purchaseReceipts,
takeReceiptJob,
cancelTakeReceiptJob,
finishReceiptJob,
unInspectToQualified,
saveReceiptResult,
resetReceiptResult
} from '@/api/index.js';
import {
getJobStatuStyle,
getJobStatuDesc,
showConfirmMsg,
compare,
goHome
} from '@/common/basic.js';
import comMessage from '@/mycomponents/common/comMessage.vue'
import winScanButton from '@/mycomponents/wincom/scanCom/winScanButton.vue'
import winScanPack from '@/mycomponents/wincom/scanCom/winScanPack.vue'
import receiptCheck from '@/pages/task/receipt_check.vue'
export default {
name: 'receipt_detail',
components: {
comMessage,
winScanButton,
winScanPack,
receiptCheck
},
data() {
return {
scrollTop: 0,
old: {
scrollTop: 0
},
currentItem: {},
id: '',
receiptJob: {},
ispending: false,
inputQty: "",
listfocus: false,
finshed: false,
received: false,
allCount: 0,
scanCount: 0,
isCheckAll: false,
selectedItem: {}
};
},
onLoad(option) {
if (option.id != undefined) {
this.id = option.id;
//
if (option.jobStatus == 1) {
this.receive((callback => {
this.received = true;
this.getDetail();
}));
} else {
this.getDetail();
}
}
},
//
onNavigationBarButtonTap(e) {
if (e.index === 0) {
goHome();
}
},
//
onBackPress(e) {
//
if (this.received) {
//
cancelTakeReceiptJob(this.id)
.then(res => {})
.catch(err => {
this.showMessage(err.message);
});
}
},
mounted() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: "#5A7CF3 !important"
})
},
methods: {
openScanPopup() {
this.$refs.scanPopup.openScanPopup();
},
//
receive(callback) {
if (this.id != null) {
takeReceiptJob(this.id)
.then(res => {
callback();
})
.catch(err => {
this.showMessage(err.message);
});
}
},
getDetail() {
let that = this;
that.getJoDetail(callBack => {
that.ispending = that.receiptJob.jobStatus === 2;
if (that.receiptJob.details != null) {
that.allCount = that.receiptJob.details.length;
let items = that.receiptJob.details.filter(r => {
return r.purchaseReceiptInspectStatus > 1
})
that.scanCount = items != null ? items.length : 0;
that.initDetails();
this.$nextTick();
}
});
},
getJoDetail(callBack) {
let that = this;
purchaseReceipts(that.id)
.then(res => {
that.receiptJob = res;
callBack();
})
.catch(err => {
this.showMessage(err.message);
});
},
initDetails() {
setTimeout(() => {
this.receiptJob.details.forEach(v => {});
}, 100);
},
afterPurchase() {
let that = this;
//
that.getJoDetail(() => {
let items = that.receiptJob.details.filter(r => {
return r.purchaseReceiptInspectStatus > 1
})
that.scanCount = items != null ? items.length : 0;
})
},
//
getScanResult(result) {
if (result.data.code == '')
return;
let code = result.data.code;
let datas = this.receiptJob.details.filter(function(r) {
if (
r.recommendPackingCode === code) {
return r;
}
});
if (datas.length === 0) {
this.showMessage('在收货任务详情中,未找到[' + code + ']');
} else {
if (datas.length === 1) {
let data = datas[0];
if (data.purchaseReceiptInspectStatus > 1) {
this.showMessage('箱码[' + data.recommendPackingCode + ']已经扫描,请扫描下一箱');
} else {
this.toQualified(data);
}
} else {
datas.forEach(r => {
this.toQualified(r);
});
}
}
},
//
toQualified(detail) {
uni.showLoading({
title: '扫描中...',
mask: true
})
let item = {
id: this.id,
detailId: detail.id,
failedReason: '',
massDefect: '',
purchaseReceiptInspectStatus: 2,
fileList: []
};
let param = JSON.stringify(item);
//
saveReceiptResult(this.id, param).then(res => {
if (res != null) {
this.afterPurchase();
}
uni.hideLoading();
}).catch(err => {
this.showMessage(err.message)
uni.hideLoading();
})
},
takePhoto(item) {
let that = this;
that.selectedItem = item;
that.$refs.receiptCheck.openReceiptCheckPopup(item.inspectPhotoJson);
},
getPhotoResult(files) {
this.afterPurchase();
},
getFileBlob(file, callBack) {
// let fileParam = [];
let filePath = file.path;
let fileName = file.name;
let rd = new FileReader(); //
this.objectURLToBlob((filePath), (blob) => {
const file = new window.File([blob], fileName, {
type: blob.type
});
rd.readAsDataURL(file)
rd.onloadend = function() {
var arrayBuffer = rd.result
let file = {
fileName: fileName,
bytes: arrayBuffer.substring(arrayBuffer.indexOf(',') + 1, arrayBuffer
.length)
}
// fileParam.push(file);
callBack(file);
}
})
},
//
inspectResult() {
let that = this;
let uncheckitems = that.receiptJob.details.filter(r => {
return (r.purchaseReceiptInspectStatus <= 1)
});
if (uncheckitems.length > 0) {
let msg = '还有未扫描的零件,是否要生成检验结果?';
showConfirmMsg(msg, confirm => {
if (confirm) {
that.gotoInspectResult();
}
})
} else {
that.gotoInspectResult();
}
},
gotoInspectResult() {
let param = JSON.stringify(this.receiptJob);
uni.navigateTo({
url: './receipt_result?id=' + this.id + '&item=' + param
});
},
//
unInspectToQualified() {
let items = this.receiptJob.details.filter(r => {
return (r.purchaseReceiptInspectStatus <= 1)
})
if (items.length == 0) {
this.showMessage('没有需要待检转合格的零件')
return;
}
uni.showLoading({
title: '处理中...',
mask: true
})
unInspectToQualified(this.id).then(r => {
if (r != null) {
items.forEach(r => {
r.purchaseReceiptInspectStatus = 2; //
r.handledQty = r.recommendQty;
})
}
uni.hideLoading();
}).catch(err => {
this.showMessage(err.message);
uni.hideLoading();
});
},
clear() {
showConfirmMsg('是否要清空已扫描及已目检的零件?', confirm => {
if (confirm) {
uni.showLoading({
title: '清空中...',
mask: true
})
let that = this;
let details = [];
this.receiptJob.details.forEach(r => {
details.push(r.id);
})
let param = JSON.stringify(details);
resetReceiptResult(that.id, param).then(res => {
if (res != null) {
that.getJoDetail(() => {
that.scanCount = 0;
});
}
uni.hideLoading();
}).catch(err => {
uni.hideLoading();
that.showMessage(err.message)
});
}
});
},
showMessage(message) {
this.$refs.comMessage.showMessage(message);
},
upper: function(e) {
// console.log(e)
},
lower: function(e) {
// console.log(e)
},
scroll: function(e) {
// console.log(e)
this.old.scrollTop = e.receiptJob.scrollTop;
},
readImageBuffer(files) {
let fileParam = [];
let rd = new FileReader(); //
for (var i = 0; i < files.length; i++) {
let filePath = files[i].path;
let fileName = files[i].name;
this.objectURLToBlob((filePath), (blob) => {
const file = new window.File([blob], fileName, {
type: blob.type
});
rd.readAsDataURL(file)
rd.onloadend = function() {
var arrayBuffer = rd.result
let params = {
fileName: fileName,
bytes: arrayBuffer.substring(arrayBuffer.indexOf(',') + 1, arrayBuffer
.length)
}
fileParam.push(params);
}
})
}
},
/**
* BlobUrl转blob数据
* @param {Object} url blob URL
* @param {Object} callback 回调函数
*/
objectURLToBlob(url, callback) {
const http = new XMLHttpRequest();
http.open("GET", url, true);
http.responseType = "blob";
http.onload = function(e) {
if (this.status == 200 || this.status === 0) {
callback(this.response);
}
};
http.send();
},
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
}
}
</script>
<style scoped lang="scss">
@import '../../common/pdabasic.css';
</style>

95
fe/PDA/mycomponents/comItem/comTopItem.vue

@ -0,0 +1,95 @@
<!-- 零件基础信息卡片包括:
零件号名称描述数量和单位
箱码批次库位状态
可以通过属性控制库位和状态是否显示 -->
<template>
<view class="common_card">
<view class="ljh_box">
<view class="ljh_info">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="label_xm font_xs fr">{{ dataContent.packingCode }}</view>
</view>
<view class="uni-flex space-between desc_card">
<view class="ljh_left">
<view class="text_lightblue font_xs">{{dataContent.itemName }}</view>
</view>
<view class="ljh_right">
<text class="tnum">{{dataContent.qty}}</text>
<text class="tunit">{{dataContent.uom}}</text>
</view>
</view>
</view>
<view class="uni-flex uni-row bot_card" v-if="displayBottomInfo">
<!-- 库位 -->
<view class="bot_card_item" v-if="displayLocation">
<label class="icon_bg icon_bg_kw">
<image class="icon_normal" src="@/static/icons_ui/icon_kw.svg">
</image>
</label>
<text>{{ dataContent.locationCode }}</text>
</view>
<!-- 批次 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg">
</image>
</label>
<text>{{dataContent.lot}}</text>
</view>
<!-- 状态 -->
<view class="bot_card_item item_short" v-if="displayStatus">
<!-- <label class="icon_state" :class="dataContent.status | statusStyle"></label> -->
<text class="state_point" :class="statusStyle(dataContent.status)">
{{ statusColor(dataContent.status)}}
</text>
</view>
</view>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
} from '@/common/basic.js';
export default {
name: 'comBaseItem',
components: {},
props: {
dataContent: {
type: Object,
default: {}
},
displayLocation: {
type: Boolean,
default: true
},
displayStatus: {
type: Boolean,
default: true
},
displayBottomInfo: {
type: Boolean,
default: true
},
},
data() {
return {}
},
created() {
},
methods: {
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

75
fe/PDA/mycomponents/comjob/comJobScanDetail.vue

@ -0,0 +1,75 @@
<!-- 收货任务详情 -->
<template>
<view class="device-detail" style="padding-bottom: 0 !important;">
<com-job-top-info :jobContent="jobContent"></com-job-top-info>
<!-- <view class="ljh_box nopad">
<text class="state-style fl margin_xs_top" :class="jobContent.jobStatus | statusStyle">
{{ jobContent.jobStatus | statusColor }}
</text>
<text class="tit_ljh">{{ jobContent.number }}</text>
</view> -->
<view class="cell_box uni-flex uni-row margin_top">
<view class="cell_info">
<view class="text_lightblue">总数量</view>
<view class="text_black text_bold">{{ allCount}}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">{{scanHint}}</view>
<view class="text_black text_bold">{{ scanCount}}</view>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
} from '@/common/basic.js';
import comJobTopInfo from '@/mycomponents/comjob/comJobTopInfo.vue'
export default {
name: 'comJobScanDetail',
components: {
comJobTopInfo
},
props: {
jobContent: {
type: Object,
default: {}
},
allCount: {
type: Number,
default: 0
},
scanCount: {
type: Number,
default: 0
},
scanHint: {
type: String,
default: "已扫描"
},
},
data() {
return {
};
},
mounted() {
},
methods: {
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
}
}
</script>
<style scoped lang="scss">
</style>

53
fe/PDA/mycomponents/comjob/comJobTopInfo.vue

@ -0,0 +1,53 @@
<!-- 收货任务详情 -->
<template>
<view class="task_num">
<view class="ljh_box nopad">
<view class="tit_ljh">
<text class="state-style" :class="jobStatusStyle(jobContent.jobStatus)">
{{ jobStatusColor(jobContent.jobStatus)}}
</text>
<text class="text_bold" style="padding:4rpx 2rpx;">{{jobContent.number}}</text>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
} from '@/common/basic.js';
export default {
name: 'comJobScanDetail',
components: {
},
props: {
jobContent: {
type: Object,
default: {}
}
},
data() {
return {
};
},
mounted() {
},
methods: {
jobStatusStyle: function(val) {
return getJobStatuStyle(val);
},
jobStatusColor: function(val) {
return getJobStatuDesc(val);
},
}
}
</script>
<style scoped lang="scss">
</style>

399
fe/PDA/mycomponents/common/SemiCollapseItem.vue

@ -0,0 +1,399 @@
<template>
<view class="uni-collapse-item">
<!-- onClick(!isOpen) -->
<view @click="onClick(!isOpen)" class="uni-collapse-item__title"
:class="{'is-open':isOpen &&titleBorder === 'auto' ,'uni-collapse-item-border':titleBorder !== 'none'}">
<view class="uni-collapse-item__title-wrap">
<slot name="title">
<view class="uni-collapse-item__title-box" :class="{'is-disabled':disabled}">
<image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
<text class="uni-collapse-item__title-text">{{ title }}</text>
<view>
<text class="num_color">{{scanCount}}</text>/<text>{{item.totalQty}}{{item.uom}}</text>
</view>
<!-- <text >{{ subTitle }}</text> -->
</view>
</slot>
</view>
<view
:class="{ 'uni-collapse-item__title-arrow-active': isOpen, 'uni-collapse-item--animation': showAnimation === true }"
class="uni-collapse-item__title-arrow">
<uni-icons :color="disabled?'#ddd':'#bbb'" size="14" type="arrowdown" />
</view>
</view>
<view class="uni-collapse-item__wrap" :class="{'is--transition':showAnimation}"
:style="{height: (isOpen?height:0) +'px'}">
<view :id="elId" ref="collapse--hook" class="uni-collapse-item__wrap-content"
:class="{open:isheight,'uni-collapse-item--border':border&&isOpen}">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom')
// #endif
/**
* CollapseItem 折叠面板子组件
* @description 折叠面板子组件
* @property {String} title 标题文字
* @property {String} thumb 标题左侧缩略图
* @property {String} name 唯一标志符
* @property {Boolean} disabled = [true|false] 是否展开面板
* @property {Boolean} showAnimation = [true|false] 开启动画
*/
export default {
name: 'semiCollapseItem',
props: {
//
title: {
type: String,
default: ''
},
name: {
type: [Number, String],
default: ''
},
//
disabled: {
type: Boolean,
default: false
},
// #ifdef APP-PLUS
// ,app
showAnimation: {
type: Boolean,
default: false
},
// #endif
// #ifndef APP-PLUS
//
showAnimation: {
type: Boolean,
default: true
},
// #endif
//
open: {
type: Boolean,
default: false
},
//
thumb: {
type: String,
default: ''
},
// 线
titleBorder: {
type: String,
default: 'auto'
},
// 线
border: {
type: Boolean,
default: true
},
allCount: {
type: Number,
default: 0
},
scanCount: {
type: Number,
default: 0
},
item: {
type: Object,
default: null
}
},
data() {
// TODO IDbug
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
isOpen: false,
isheight: null,
height: 0,
elId,
nameSync: 0
}
},
watch: {
open(val) {
this.isOpen = val
this.onClick(val, 'init')
}
},
updated(e) {
this.$nextTick(() => {
this.init(true)
})
},
created() {
this.collapse = this.getCollapse()
this.oldHeight = 0
},
// #ifndef VUE3
// TODO vue2
destroyed() {
if (this.__isUnmounted) return
this.uninstall()
},
// #endif
// #ifdef VUE3
// TODO vue3
unmounted() {
this.__isUnmounted = true
this.uninstall()
},
// #endif
mounted() {
if (!this.collapse) return
if (this.name !== '') {
this.nameSync = this.name
} else {
this.nameSync = this.collapse.childrens.length + ''
}
if (this.collapse.names.indexOf(this.nameSync) === -1) {
this.collapse.names.push(this.nameSync)
} else {
console.warn(`name 值 ${this.nameSync} 重复`);
}
if (this.collapse.childrens.indexOf(this) === -1) {
this.collapse.childrens.push(this)
}
this.init()
},
methods: {
init(type) {
// #ifndef APP-NVUE
this.getCollapseHeight(type)
// #endif
// #ifdef APP-NVUE
this.getNvueHwight(type)
// #endif
},
uninstall() {
if (this.collapse) {
this.collapse.childrens.forEach((item, index) => {
if (item === this) {
this.collapse.childrens.splice(index, 1)
}
})
this.collapse.names.forEach((item, index) => {
if (item === this.nameSync) {
this.collapse.names.splice(index, 1)
}
})
}
},
onClick(isOpen, type) {
if (this.disabled) return
this.isOpen = isOpen
if (this.isOpen && this.collapse) {
this.collapse.setAccordion(this)
}
if (type !== 'init') {
this.collapse.onChange(isOpen, this)
}
},
getCollapseHeight(type, index = 0) {
const views = uni.createSelectorQuery().in(this)
views
.select(`#${this.elId}`)
.fields({
size: true
}, data => {
// TODO
if (index >= 10) return
if (!data) {
index++
this.getCollapseHeight(false, index)
return
}
// #ifdef APP-NVUE
this.height = data.height + 1
// #endif
// #ifndef APP-NVUE
this.height = data.height
// #endif
this.isheight = true
if (type) return
this.onClick(this.open, 'init')
})
.exec()
},
getNvueHwight(type) {
const result = dom.getComponentRect(this.$refs['collapse--hook'], option => {
if (option && option.result && option.size) {
// #ifdef APP-NVUE
this.height = option.size.height + 1
// #endif
// #ifndef APP-NVUE
this.height = option.size.height
// #endif
this.isheight = true
if (type) return
this.onClick(this.open, 'init')
}
})
},
/**
* 获取父元素实例
*/
getCollapse(name = 'uniCollapse') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false;
parentName = parent.$options.name;
}
return parent;
}
}
}
</script>
<style scoped>
.uni-collapse-item {
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
}
.uni-collapse-item__title {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
transition: border-bottom-color 0.3s;
}
.uni-collapse-item__title-wrap {
width: 100%;
flex: 1;
}
.uni-collapse-item__title-box {
padding: 0 15px;
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 48px;
line-height: 48px;
background-color: #fff;
color: #303133;
font-size: 13px;
font-weight: 500;
/* #ifdef H5 */
cursor: pointer;
outline: none;
/* #endif */
}
.uni-collapse-item__title-box.is-disabled .uni-collapse-item__title-text {
color: #c0c0c0;
}
.uni-collapse-item__title.uni-collapse-item-border {
border-bottom: 1px solid #ebeef5;
}
.uni-collapse-item__title.is-open {
border-bottom-color: transparent;
}
.uni-collapse-item__title-img {
height: 26px;
width: 26px;
margin-right: 10px;
}
.uni-collapse-item__title-text {
flex: 1;
font-size: 14px;
/* #ifndef APP-NVUE */
white-space: nowrap;
color: inherit;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
overflow: hidden;
text-overflow: ellipsis;
}
.uni-collapse-item__title-arrow {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin-right: 10px;
transform: rotate(0deg);
}
.uni-collapse-item__title-arrow-active {
transform: rotate(180deg);
}
.uni-collapse-item__wrap {
/* #ifndef APP-NVUE */
will-change: height;
box-sizing: border-box;
/* #endif */
background-color: #fff;
overflow: hidden;
position: relative;
height: 0;
}
.uni-collapse-item__wrap.is--transition {
transition-property: height, border-bottom-width;
transition-duration: 0.3s;
/* #ifndef APP-NVUE */
will-change: height;
/* #endif */
}
.uni-collapse-item__wrap-content {
position: absolute;
font-size: 13px;
color: #303133;
border-bottom-color: transparent;
border-bottom-style: solid;
border-bottom-width: 0;
}
.uni-collapse-item__wrap-content.uni-collapse-item--border {
border-bottom-width: 1px;
border-bottom-color: red;
border-bottom-color: #ebeef5;
}
.uni-collapse-item__wrap-content.open {
position: relative;
}
.uni-collapse-item--animation {
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease;
}
</style>

60
fe/PDA/mycomponents/common/comBalance.vue

@ -0,0 +1,60 @@
<!--发料任务卡片-->
<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;">
<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)">
<com-balance-item :dataContent="item"></com-balance-item>
</view>
</scroll-view>
</uni-popup>
</template>
<script>
import {
getJobStatuStyle,
getInventoryStatusDesc
} from '@/common/basic.js';
import comBalanceItem from '@/mycomponents/comItem/comBalanceItem.vue'
export default {
name: "combalance",
emits:['selectedItem'],
components: {
comBalanceItem
},
data() {
return {
balanceItems: [],
};
},
//
props: {
// datacontent: {
// type: Object,
// value: null
// }
},
methods: {
openPopup(items) {
this.balanceItems = items;
this.$refs['popupItems'].open("center");
},
callback(item) {
this.$emit("selectedItem", item);
this.$refs['popupItems'].close();
},
statusStyle: function(val) {
return getJobStatuStyle(val);
},
inventoryStatus: function(val) {
return getInventoryStatusDesc(val);
}
}
}
</script>
<style scoped lang="scss">
</style>

31
fe/PDA/mycomponents/common/comBlankView.vue

@ -0,0 +1,31 @@
<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>
</template>
<script>
export default {
data() {
return {
}
},
created() {
},
methods: {
goScan(content) {
this.$emit("goScan");
}
}
}
</script>
<style>
</style>

399
fe/PDA/mycomponents/common/comCollapseItem.vue

@ -0,0 +1,399 @@
<template>
<view class="uni-collapse-item">
<!-- onClick(!isOpen) -->
<view @click="onClick(!isOpen)" class="uni-collapse-item__title"
:class="{'is-open':isOpen &&titleBorder === 'auto' ,'uni-collapse-item-border':titleBorder !== 'none'}">
<view class="uni-collapse-item__title-wrap">
<slot name="title">
<view class="uni-collapse-item__title-box" :class="{'is-disabled':disabled}">
<image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
<text class="uni-collapse-item__title-text">{{ title }}</text>
<view class="ljh_right">
<text class="tnum" style="font-size: 1rem;">{{item.labelList.length}}</text>
<text class="tunit">()</text>
</view>
</view>
</slot>
</view>
<view
:class="{ 'uni-collapse-item__title-arrow-active': isOpen, 'uni-collapse-item--animation': showAnimation === true }"
class="uni-collapse-item__title-arrow">
<uni-icons :color="disabled?'#ddd':'#bbb'" size="14" type="arrowdown" />
</view>
</view>
<view class="uni-collapse-item__wrap" :class="{'is--transition':showAnimation}"
:style="{height: (isOpen?height:0) +'px'}">
<view :id="elId" ref="collapse--hook" class="uni-collapse-item__wrap-content"
:class="{open:isheight,'uni-collapse-item--border':border&&isOpen}">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom')
// #endif
/**
* CollapseItem 折叠面板子组件
* @description 折叠面板子组件
* @property {String} title 标题文字
* @property {String} thumb 标题左侧缩略图
* @property {String} name 唯一标志符
* @property {Boolean} disabled = [true|false] 是否展开面板
* @property {Boolean} showAnimation = [true|false] 开启动画
*/
export default {
name: 'comCollapseItem',
props: {
//
title: {
type: String,
default: ''
},
name: {
type: [Number, String],
default: ''
},
//
disabled: {
type: Boolean,
default: false
},
// #ifdef APP-PLUS
// ,app
showAnimation: {
type: Boolean,
default: false
},
// #endif
// #ifndef APP-PLUS
//
showAnimation: {
type: Boolean,
default: true
},
// #endif
//
open: {
type: Boolean,
default: false
},
//
thumb: {
type: String,
default: ''
},
// 线
titleBorder: {
type: String,
default: 'auto'
},
// 线
border: {
type: Boolean,
default: true
},
allCount: {
type: Number,
default: 0
},
scanCount: {
type: Number,
default: 0
},
item: {
type: Object,
default: null
}
},
data() {
// TODO IDbug
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
isOpen: false,
isheight: null,
height: 0,
elId,
nameSync: 0
}
},
watch: {
open(val) {
this.isOpen = val
this.onClick(val, 'init')
}
},
updated(e) {
this.$nextTick(() => {
this.init(true)
})
},
created() {
this.collapse = this.getCollapse()
this.oldHeight = 0
},
// #ifndef VUE3
// TODO vue2
destroyed() {
if (this.__isUnmounted) return
this.uninstall()
},
// #endif
// #ifdef VUE3
// TODO vue3
unmounted() {
this.__isUnmounted = true
this.uninstall()
},
// #endif
mounted() {
if (!this.collapse) return
if (this.name !== '') {
this.nameSync = this.name
} else {
this.nameSync = this.collapse.childrens.length + ''
}
if (this.collapse.names.indexOf(this.nameSync) === -1) {
this.collapse.names.push(this.nameSync)
} else {
console.warn(`name 值 ${this.nameSync} 重复`);
}
if (this.collapse.childrens.indexOf(this) === -1) {
this.collapse.childrens.push(this)
}
this.init()
},
methods: {
init(type) {
// #ifndef APP-NVUE
this.getCollapseHeight(type)
// #endif
// #ifdef APP-NVUE
this.getNvueHwight(type)
// #endif
},
uninstall() {
if (this.collapse) {
this.collapse.childrens.forEach((item, index) => {
if (item === this) {
this.collapse.childrens.splice(index, 1)
}
})
this.collapse.names.forEach((item, index) => {
if (item === this.nameSync) {
this.collapse.names.splice(index, 1)
}
})
}
},
onClick(isOpen, type) {
if (this.disabled) return
this.isOpen = isOpen
if (this.isOpen && this.collapse) {
this.collapse.setAccordion(this)
}
if (type !== 'init') {
this.collapse.onChange(isOpen, this)
}
},
getCollapseHeight(type, index = 0) {
const views = uni.createSelectorQuery().in(this)
views
.select(`#${this.elId}`)
.fields({
size: true
}, data => {
// TODO
if (index >= 10) return
if (!data) {
index++
this.getCollapseHeight(false, index)
return
}
// #ifdef APP-NVUE
this.height = data.height + 1
// #endif
// #ifndef APP-NVUE
this.height = data.height
// #endif
this.isheight = true
if (type) return
this.onClick(this.open, 'init')
})
.exec()
},
getNvueHwight(type) {
const result = dom.getComponentRect(this.$refs['collapse--hook'], option => {
if (option && option.result && option.size) {
// #ifdef APP-NVUE
this.height = option.size.height + 1
// #endif
// #ifndef APP-NVUE
this.height = option.size.height
// #endif
this.isheight = true
if (type) return
this.onClick(this.open, 'init')
}
})
},
/**
* 获取父元素实例
*/
getCollapse(name = 'uniCollapse') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false;
parentName = parent.$options.name;
}
return parent;
}
}
}
</script>
<style scoped>
.uni-collapse-item {
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
}
.uni-collapse-item__title {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
transition: border-bottom-color 0.3s;
}
.uni-collapse-item__title-wrap {
width: 100%;
flex: 1;
}
.uni-collapse-item__title-box {
padding: 0 15px;
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 48px;
line-height: 48px;
background-color: #fff;
color: #303133;
font-size: 13px;
font-weight: 500;
/* #ifdef H5 */
cursor: pointer;
outline: none;
/* #endif */
}
.uni-collapse-item__title-box.is-disabled .uni-collapse-item__title-text {
color: #c0c0c0;
}
.uni-collapse-item__title.uni-collapse-item-border {
border-bottom: 1px solid #ebeef5;
}
.uni-collapse-item__title.is-open {
border-bottom-color: transparent;
}
.uni-collapse-item__title-img {
height: 26px;
width: 26px;
margin-right: 10px;
}
.uni-collapse-item__title-text {
flex: 1;
font-size: 14px;
/* #ifndef APP-NVUE */
white-space: nowrap;
color: inherit;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
overflow: hidden;
text-overflow: ellipsis;
}
.uni-collapse-item__title-arrow {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin-right: 10px;
transform: rotate(0deg);
}
.uni-collapse-item__title-arrow-active {
transform: rotate(180deg);
}
.uni-collapse-item__wrap {
/* #ifndef APP-NVUE */
will-change: height;
box-sizing: border-box;
/* #endif */
background-color: #fff;
overflow: hidden;
position: relative;
height: 0;
}
.uni-collapse-item__wrap.is--transition {
transition-property: height, border-bottom-width;
transition-duration: 0.3s;
/* #ifndef APP-NVUE */
will-change: height;
/* #endif */
}
.uni-collapse-item__wrap-content {
position: absolute;
font-size: 13px;
color: #303133;
border-bottom-color: transparent;
border-bottom-style: solid;
border-bottom-width: 0;
}
.uni-collapse-item__wrap-content.uni-collapse-item--border {
border-bottom-width: 1px;
border-bottom-color: red;
border-bottom-color: #ebeef5;
}
.uni-collapse-item__wrap-content.open {
position: relative;
}
.uni-collapse-item--animation {
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease;
}
</style>

28
fe/PDA/mycomponents/common/comDyItemInfo.vue

@ -0,0 +1,28 @@
<!--收货任务卡片-->
<template>
<view class="device-detail">
<view class="list-style">
<view class="text-color">物料号:{{dataContent.itemCode}}</view>
<view>物料名称:{{dataContent.itemName }}</view>
<view class="uni-flex">
<view style="-webkit-flex: 1;flex: 1;">箱码: {{dataContent.packingCode}}</view>
<view style="-webkit-flex: 1;flex: 1;">数量: {{dataContent.qty}}{{dataContent.uom}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "comDyItemInfo",
data() {
return {};
},
//
props: ['dataContent'],
}
</script>
<style scoped lang="scss">
</style>

98
fe/PDA/mycomponents/common/comEasyInput.vue

@ -0,0 +1,98 @@
<template>
<view>
<uni-popup ref="popup">
<view class="popup_box">
<view class="pop_title">
描述信息
<text class="fr" @click="closeScanPopup()">关闭</text>
</view>
<view class="pop_tab">
<view class="tab_info">
<view class="conbox">
<textarea v-model="content" trim="all" style="margin-left: 5px;" :focus="true"></textarea>
<!-- <uni-easyinput v-model="content" type="textarea" ></uni-easyinput> -->
</view>
<view class="uni-flex">
<button class="clean_scan_btn" @click="clear()">清空</button>
<button class="scan_btn" @click="confirm()">确定</button>
</view>
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import {
// showErrorMsg,
} from '@/common/basic.js';
export default {
data() {
return {
content: '',
}
},
created() {
},
methods: {
openPopup(content) {
this.content = content;
this.$refs['popup'].open("bottom");
},
closeScanPopup(content) {
this.$refs.popup.close();
},
cancel() {
this.$refs['popup'].close();
},
confirm() {
this.$emit("confirm", this.content);
this.$refs['popup'].close();
},
clear() {
this.content = '';
},
maskClick() {
this.$emit("confirm", true);
}
}
}
</script>
<!-- background-color: #fff; -->
<style scoped lang="scss">
.center {
flex: auto;
display: flex;
flex-direction: column;
justify-content: center;
// align-items: center;
}
.flex-item {
width: 50%;
text-align: center;
}
.messageButton {
border-color: #F8F8F8;
}
.messagePopup {
background-color: #fff;
border-radius: 5px;
}
.uni-input-input {
font-size: 20px;
height: 46px;
}
</style>

194
fe/PDA/mycomponents/common/comMessage.vue

@ -0,0 +1,194 @@
<template>
<!-- @maskClick="afterClose()" -->
<uni-popup ref="popupMessage" style="width: 100%; height:100%;" :maskClick='false'>
<view class="messagePopup center" @touchmove.stop.prevent="clear">
<scroll-view style="" scroll-y="true" @touchmove.stop.prevent="clear">
<view class="center" @touchmove.stop.prevent="clear" style="width: 230px;min-height: 100px; ">
<view style="margin-left: 15px;margin-right: 15px; ">
{{content}}
</view>
</view>
</scroll-view>
<view v-if="type=='confirm' || type=='rescan' " class="uni-flex uni-row">
<view class="flex-item">
<button @click="cancel()" plain="true" class="messageButton">{{cancelText}}</button>
</view>
<view class="flex-item">
<button @click="confirm()" plain="true" class="messageButton"
style="color: #007AFF;">{{confirmText}}</button>
<!-- <button @click="confirm()" plain="true" class="messageButton"
style="color: #007AFF;">{{confirmText}}({{seconds}}s)</button> -->
</view>
</view>
<view v-else-if="type=='commit' || type=='autoClose'">
<button @click="closeMessage()" plain="true" class="messageButton">关闭({{seconds}}s)</button>
</view>
<view v-else>
<button @click="closeMessage()" plain="true" class="messageButton">关闭</button>
</view>
</view>
</uni-popup>
</template>
<script>
import {
// showErrorMsg,
scanErrorAudio,
vibrate
} from '@/common/basic.js';
export default {
data() {
return {
content: '',
cancelText: '否',
confirmText: '是',
type: 'basic', //basiccommitMessage:
timer: null,
seconds: 3,
confirmResult: true
}
},
created() {
},
methods: {
showMessage(content) {
this.openMessage(content, 'basic');
// this.startTimer();
vibrate();
},
//
showCommitSuccess() {
this.openMessage('提交成功', 'commit');
this.startTimer();
},
//
showScanMessage(content) {
this.openMessage(content, 'scan');
scanErrorAudio(); //
},
//
showConfirmMessage(content) {
this.openMessage(content, 'confirm');
},
//
showRescanMessage(content) {
this.openMessage(content, 'rescan');
},
//
showAutoCloseMessge(content) {
this.openMessage(content, 'autoClose');
this.startTimer();
vibrate();
},
//
showOkCanceConfirmMessage(content) {
this.cancelText = '取消';
this.confirmText = '确定';
this.openMessage(content, 'confirm');
},
openMessage(content, type) {
this.content = content;
this.type = type;
this.$refs['popupMessage'].open("center");
},
closeMessage() {
clearInterval(this.timer) //timer
this.$refs['popupMessage'].close();
this.afterClose();
},
maskClick() {
this.afterClose();
},
confirm() {
this.confirmResult = true;
this.closeMessage();
},
cancel() {
this.closeMessage();
},
//
afterClose() {
if (this.type == 'basic') {
this.$emit("afterClose");
} else if (this.type == 'commit') {
this.$emit("afterCloseCommitMessage"); //
} else if (this.type == 'scan') {
this.$emit("afterCloseScanMessage"); //
} else if (this.type == 'rescan') {
this.$emit("afterRescanMessage", this.confirmResult);
}
},
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.closeMessage();
},
clear() {
return;
},
}
}
</script>
<!-- background-color: #fff; -->
<style scoped lang="scss">
.center {
flex: auto;
display: flex;
flex-direction: column;
justify-content: center;
white-space: pre-wrap;
word-wrap: break-word;
// align-items: center;
}
.flex-item {
width: 50%;
text-align: center;
}
.messageButton {
border-color: #F8F8F8;
}
.messagePopup {
background-color: #fff;
border-radius: 5px;
}
// /deep/ .uni-input-input {
// font-size: 20px;
// height: 46px;
// }
</style>

232
fe/PDA/mycomponents/common/comNumberBox.vue

@ -0,0 +1,232 @@
<template>
<view class="uni-numbox">
<view @click="_calcValue('minus')" class="uni-numbox__minus uni-cursor-point">
<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }">-</text>
</view>
<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value" type="number"
v-model="inputValue" />
<view @click="_calcValue('plus')" class="uni-numbox__plus uni-cursor-point">
<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }">+</text>
</view>
</view>
</template>
<script>
/**
* NumberBox 数字输入框
* @description 带加减按钮的数字输入框
* @tutorial https://ext.dcloud.net.cn/plugin?id=31
* @property {Number} value 输入框当前值
* @property {Number} min 最小值
* @property {Number} max 最大值
* @property {Number} step 每次点击改变的间隔大小
* @property {Boolean} disabled = [true|false] 是否为禁用状态
* @event {Function} change 输入框值改变时触发的事件参数为输入框当前的 value
*/
export default {
name: "UniNumberBox",
emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'],
props: {
value: {
type: [Number, String],
default: 1
},
modelValue: {
type: [Number, String],
default: 1
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
step: {
type: Number,
default: 1
},
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
inputValue: 0
};
},
watch: {
value(val) {
this.inputValue = +val;
},
modelValue(val) {
this.inputValue = +val;
}
},
created() {
if (this.value === 1) {
this.inputValue = +this.modelValue;
}
if (this.modelValue === 1) {
this.inputValue = +this.value;
}
},
methods: {
_calcValue(type) {
if (this.disabled) {
return;
}
const scale = this._getDecimalScale();
let value = this.inputValue * scale;
let step = this.step * scale;
if (type === "minus") {
value -= step;
if (value < (this.min * scale)) {
return;
}
if (value > (this.max * scale)) {
value = this.max * scale
}
}
if (type === "plus") {
value += step;
if (value > (this.max * scale)) {
return;
}
if (value < (this.min * scale)) {
value = this.min * scale
}
}
this.inputValue = value;
// this.inputValue = (value / scale).toFixed(String(scale).length - 1);
this.$emit("change", +this.inputValue);
// TODO vue2
this.$emit("input", +this.inputValue);
// TODO vue3
this.$emit("update:modelValue", +this.inputValue);
},
_getDecimalScale() {
let scale = 1;
// //
// if (~~this.step !== this.step) {
// scale = Math.pow(10, String(this.step).split(".")[1].length);
// }
return scale;
},
_onBlur(event) {
this.$emit('blur', event)
let value = event.detail.value;
if (!value) {
this.inputValue = 0;
} else {
value = +value;
if (value > this.max) {
value = this.max;
} else if (value < this.min) {
value = this.min;
}
// const scale = this._getDecimalScale();
// this.inputValue = value.toFixed(String(scale).length - 1);
this.inputValue = value;
}
this.$emit("change", +this.inputValue);
this.$emit("input", +this.inputValue);
},
_onFocus(event) {
this.$emit('focus', event)
}
}
};
</script>
<style scoped>
/* #ifdef APP-NVUE */
/* #endif */
.uni-numbox {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
height: 30px;
line-height: 30px;
width: 120px;
}
.uni-cursor-point {
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-numbox__value {
background-color: #ffffff;
width: 60px;
height: 30px;
text-align: center;
font-size: 0.775rem;
color: #101010;
border-width: 1rpx;
border-style: solid;
border-color: #e5e5e5;
border-left-width: 0;
border-right-width: 0;
}
.uni-numbox__minus {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
font-size: 1rem;
color: #333;
background-color: #f8f8f8;
border-width: 1rpx;
border-style: solid;
border-color: #e5e5e5;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
border-right-width: 0;
}
.uni-numbox__plus {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
border-width: 1rpx;
border-style: solid;
border-color: #e5e5e5;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
background-color: #f8f8f8;
border-left-width: 0;
}
.uni-numbox--text {
font-size: 0.775rem;
color: #101010
}
.uni-numbox--disabled {
color: #c0c0c0;
/* #ifdef H5 */
cursor: not-allowed;
/* #endif */
}
/deep/ .uni-input-input
{
font-size: 0.775rem;
color: #101010
}
</style>

277
fe/PDA/mycomponents/common/comStepsCustom.vue

@ -0,0 +1,277 @@
<!-- 自定义步骤条 copy by uni-steps -->
<template name="unistepscustom">
<view class="uni-steps">
<view :class="[direction==='column'?'uni-steps__column':'uni-steps__row']">
<view :class="[direction==='column'?'uni-steps__column-container':'uni-steps__row-container']">
<view :class="[direction==='column'?'uni-steps__column-line-item':'uni-steps__row-line-item']" v-for="(item,index) in options" :key="index">
<view :class="[direction==='column'?'uni-steps__column-line':'uni-steps__row-line',direction==='column'?'uni-steps__column-line--before':'uni-steps__row-line--before']" :style="{backgroundColor:index<=active&&index!==0?activeColor:index===0?'transparent':deactiveColor}"></view>
<view :class="[direction==='column'?'uni-steps__column-check':'uni-steps__row-check']" v-if="index === active">
<view class="steps_text" :style="{backgroundColor:index<active?deactiveColor:activeColor}">
<text :style="{color:index<=active?numColor:numColor}">{{item.num}}</text>
</view>
<!-- <uni-icons type="checkbox-filled" size="14"></uni-icons> -->
</view>
<view :class="[direction==='column'?'uni-steps__column-circle':'uni-steps__row-circle']" v-else :style="{backgroundColor:index<active?activeColor:deactiveColor}">
<view class="steps_text" :style="{backgroundColor:index<active?activeColor:deactiveColor}">
<text style="color: #fff;">{{item.num}}</text>
</view>
</view>
<view :class="[direction==='column'?'uni-steps__column-line':'uni-steps__row-line',direction==='column'?'uni-steps__column-line--after':'uni-steps__row-line--after']" :style="{backgroundColor:index<active&&index!==options.length-1?activeColor:index===options.length-1?'transparent':deactiveColor}"></view>
</view>
</view>
<view :class="[direction==='column'?'uni-steps__column-text-container':'uni-steps__row-text-container']" style="margin-top: 20rpx;">
<view v-for="(item,index) in options" :key="index" :class="[direction==='column'?'uni-steps__column-text':'uni-steps__row-text']">
<text :style="{color:index<=active?activeColor:fontColor}" :class="[direction==='column'?'uni-steps__column-title':'uni-steps__row-title']"><strong>{{item.title}}</strong></text>
<text :style="{color:index<=active?activeColor:deactiveColor}" :class="[direction==='column'?'uni-steps__column-desc':'uni-steps__row-desc']"><strong>{{item.desc}}</strong></text>
</view>
</view>
</view>
</view>
</template>
<script>
/**
* Steps 步骤条
* @description 评分组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=34
* @property {Number} active 当前步骤
* @property {String} direction = [row|column] 当前步骤
* @value row 横向
* @value column 纵向
* @property {String} activeColor 选中状态的颜色
* @property {Array} options 数据源格式为[{title:'xxx',desc:'xxx'},{title:'xxx',desc:'xxx'}]
*/
export default {
name: 'unistepscustom',
props: {
direction: {
// row column
type: String,
default: 'row'
},
activeColor: {
//
type: String,
default: '#5A7CF3'
},
deactiveColor: {
//
type: String,
default: '#C5D1D9'
},
fontColor:{
//
type: String,
default: '#999'
},
numColor:{
//
type: String,
default: '#fff'
},
active: {
//
type: Number,
default: 0
},
options: {
type: Array,
default () {
return []
}
} //
},
data() {
return {}
}
}
</script>
<style scoped>
.uni-steps {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
/* #endif */
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
flex-direction: column;
}
.uni-steps__row {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-steps__column {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row-reverse;
}
.uni-steps__row-text-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: flex-end;
margin-bottom: 8px;
}
.uni-steps__column-text-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
}
.uni-steps__row-text {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex: 1;
flex-direction: column;
}
.uni-steps__column-text {
padding: 6px 0px;
border-bottom-style: solid;
border-bottom-width: 1px;
border-bottom-color: #e5e5e5;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-steps__row-title {
font-size: 14px;
line-height: 16px;
text-align: center;
}
.uni-steps__column-title {
font-size: 14px;
text-align: left;
line-height: 18px;
}
.uni-steps__row-desc {
font-size: 12px;
line-height: 14px;
text-align: center;
}
.uni-steps__column-desc {
font-size: 12px;
text-align: left;
line-height: 18px;
}
.uni-steps__row-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-steps__column-container {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
width: 30px;
flex-direction: column;
}
.uni-steps__row-line-item {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex-direction: row;
flex: 1;
height: 14px;
line-height: 14px;
align-items: center;
justify-content: center;
}
.uni-steps__column-line-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
align-items: center;
justify-content: center;
}
.uni-steps__row-line {
flex: 1;
height: 1px;
background-color: #999;
}
.uni-steps__column-line {
width: 1px;
background-color: #999;
}
.uni-steps__row-line--after {
transform: translateX(1px);
}
.uni-steps__column-line--after {
flex: 1;
transform: translate(0px, 1px);
}
.uni-steps__row-line--before {
transform: translateX(-1px);
}
.uni-steps__column-line--before {
height: 6px;
transform: translate(0px, -1px);
}
.uni-steps__row-circle {
width: 40rpx;
height: 40rpx;
border-radius: 100px;
/* background-color: #999; */
margin: 0px 3px;
}
.uni-steps__column-circle {
width: 5px;
height: 5px;
border-radius: 100px;
background-color: #999;
margin: 4px 0px 5px 0px;
}
.uni-steps__row-check {
margin: 0px 6px;
}
.uni-steps__row-check .steps_text,.uni-steps__row-circle .steps_text{
display: inline-block;
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
text-align: center;
border-radius: 50%;
font-size: 0.875rem;
}
.uni-steps__column-check {
height: 14px;
line-height: 14px;
margin: 2px 0px;
}
</style>

54
fe/PDA/mycomponents/comreceipt.vue

@ -0,0 +1,54 @@
<!--收货任务卡片-->
<template>
<view class="device-detail">
<view class="list-style">
<view class="display-flex">
<view class="text-color">任务编号:{{comreceipt.number}}</view>
<view class="state-style right-width" :class="statusStyle(comreceipt.jobStatus)">
{{statusColor(comreceipt.jobStatus)}}
</view>
</view>
<view>供应商:{{comreceipt.supplierName }}</view>
<view>ASN:{{comreceipt.asnNumber}}</view>
<view>到货单:{{comreceipt.arriveNoticeNumber}}</view>
<view>到货日期:
<!-- {{comreceipt.arriveTime===null?'无':comreceipt.arriveTime.slice(0,10)}} -->
{{comreceipt.planArriveDate===null?'无':formatDate (comreceipt.planArriveDate)}}
</view>
<!-- <view>时间窗口:{{comreceipt.timeWindow}}</view> -->
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
dateFormat
} from '@/common/basic.js';
export default {
name: "comreceiptsmple",
data() {
return {
};
},
//
props: ['comreceipt'],
methods :{
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
formatDate: function(val) {
return dateFormat(val)
}
}
}
</script>
<style scoped lang="scss">
</style>

71
fe/PDA/mycomponents/coms/comProductItem.vue

@ -0,0 +1,71 @@
<!-- 产品信息卡片包括:
零件号名称描述数量和单位
箱码批次库位状态
可以通过属性控制库位和状态是否显示 -->
<template>
<view class="choose_main">
<view class="ljh_box">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="uni-flex uni-row space-between">
<view class="ljh_left">
<view class="font_xs text_lightblue">{{dataContent.itemName}}</view>
<view class="font_xs text_lightblue">{{dataContent.item.desc2}}</view>
</view>
<view class="ljh_right">
<text class="tnum">{{dataContent.qty.qty}}</text>
<text class="tunit">{{dataContent.qty.uom}}</text>
</view>
</view>
</view>
<view class="cen_card margin_xs_bottom">
<view class="label_box uni-flex uni-row">
<view class="label_info" v-if="dataContent.prodLine!=undefined">
<label class="">
<image class="icon_normal" src="@/static/icons_ui/label_scx.svg">
</image>
</label>
<text>{{dataContent.prodLine}}</text>
</view>
</view>
</view>
<view class="uni-flex uni-row bot_card">
<view class="bot_card_item item_long">
<label class="icon_bg icon_bg_xm">
<image class="icon_normal" src="@/static/icons_ui/icon_xm.svg"></image>
</label>
<text>{{dataContent.packingCode}}</text>
</view>
<view class="bot_card_item" style="width:46%;">
</view>
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg"></image>
</label>
<text>{{dataContent.lot}}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: "comItemInfo",
data() {
return {};
},
//
props: {
dataContent: {
type: Object,
value: null
},
},
methods: {
}
}
</script>
<style scoped lang="scss">
</style>

72
fe/PDA/mycomponents/coms/comTjDeliver.vue

@ -0,0 +1,72 @@
<!--发料任务卡片-->
<template>
<view class="device-detail">
<view class="ljh_box nopad">
<view class="tit_ljh">
<text class="state-style" :class="statusStyle(datacontent.jobStatus) ">
{{statusColor(datacontent.jobStatus) }}
</text>
<text>{{datacontent.number}}</text>
</view>
</view>
<!-- <view class="display-flex">
<view class="border-font">任务编号:</view>
</view> -->
<view class="margin_xs_bottom margin_xs_top pda_receipt_label">
<view class="label_order font_sm">
<image class="icon_normal" src="@/static/icons_ui/icon_qiju_start.svg"></image>
<!-- 开始器具号 -->开始器具号{{datacontent.BeginContainer}}
</view>
<view class="label_order font_sm">
<image class="icon_normal" src="@/static/icons_ui/icon_qiju_end.svg"></image>
<!-- 结束器具号 -->结束器具号{{datacontent.EndContainer}}
</view>
</view>
<view class="uni-flex uni-row receipt_bot pda_receipt_bot">
<view class="label_order">
<!-- 占位 勿删 -->
</view>
<view class="label_order fr">
<image class="icon_normal" src="@/static/icons_ui/icon_time.svg"></image>
<text class="text_darkblue">{{datacontent.creationTime}}</text>
</view>
</view>
<!-- <view>开始器具号:</view>
<view>结束器具号: </view> -->
<!-- <view>创建时间: </view> -->
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc
} from '@/common/basic.js';
export default {
name: "comissue",
data() {
return {};
},
//
props: {
datacontent: {
type: Object,
value: null
}
},
methods:{
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
}
}
}
</script>
<style scoped lang="scss">
@import '../../common/pdabasic.css';
</style>

44
fe/PDA/mycomponents/coms/comTjProduct.vue

@ -0,0 +1,44 @@
<template>
<div>
<!-- :loading="loading" -->
<uni-table ref="table" border stripe type="false" emptyText="暂无更多数据" @selection-change="selectionChange">
<uni-tr>
<uni-th width="50">序号</uni-th>
<uni-th width="60">生产码</uni-th>
<uni-th width="60">配置码</uni-th>
<uni-th width="100">批次</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in tableData" :key="index">
<uni-td>{{ item.seq }}</uni-td>
<uni-td>{{ item.produceNo }}</uni-td>
<!-- <uni-td>{{ item.projectNo }}</uni-td> -->
<uni-td>{{ item.itemCode }}</uni-td>
<uni-td>{{ item.lot }}</uni-td>
</uni-tr>
</uni-table>
</div>
</template>
<script>
export default {
name: "comtjproduct",
data() {
return {
// tableData: {}
};
},
//
props: {
tableData: {}
// tableData: {
// type: [],
// value: null
// }
},
}
</script>
<style>
</style>

122
fe/PDA/mycomponents/coms/inventory/comHold.vue

@ -0,0 +1,122 @@
<!--发料任务卡片-->
<template>
<view class="choose_main">
<view class="ljh_box">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="ljh_left">
<view class="font_xs text_lightblue">{{ dataContent.itemName }}</view>
<view class="font_xs text_lightblue">{{ dataContent.item.desc2 }}</view>
</view>
</view>
<view class="cen_card margin_xs_bottom">
<view class="label_box uni-flex uni-row">
<view class="label_info">
<label class="">
<image class="icon_normal" src="@/static/icons_ui/icon_tm.svg">
</image>
</label>
<text>{{ dataContent.locationCode }}</text>
<!-- 库位 -->
</view>
</view>
</view>
<view class="list_form hold_form">
<view class="uni-container">
<uni-table style="overflow-x: hidden;">
<uni-tr>
<uni-th width="100"></uni-th>
<uni-th width="100" align="center" v-if="holdItem.holdStatus === 3">
<view>合格</view>
</uni-th>
<uni-th width="100" align="center" v-else>隔离</uni-th>
<uni-th width="100" align="center">实际</uni-th>
</uni-tr>
<uni-tr>
<uni-th width="100">
<view>数量{{ dataContent.qty.uom===null?'空': dataContent.qty.uom}}</view>
</uni-th>
<uni-th width="100" align="center" v-if="holdItem.holdStatus === 3">
<view class="text_black">
{{dataContent.fromQty.qty }}
</view>
</uni-th>
<uni-th width="100" align="center" v-else>
<view class="text_black">
{{dataContent.fromQty.qty }}
</view>
</uni-th>
<uni-th width="100" align="center">
<uni-easyinput v-if="editQty" type="digit" v-model="dataContent.qty.qty"
@input="qtyInput($event,dataContent)">
</uni-easyinput>
<view v-else class="text_black">{{dataContent.qty.qty}}</view>
</uni-th>
</uni-tr>
<uni-tr>
<uni-th width="100">
<view>批次</view>
</uni-th>
<uni-th width="100" align="center" v-if="holdItem.holdStatus === 3">
<view class="text_black">{{dataContent.fromLot }}</view>
</uni-th>
<uni-th width="100" align="center" v-else>
<view class="text_black">{{dataContent.fromLot }}</view>
</uni-th>
<uni-th width="100" align="center">
<view class="text_black">{{dataContent.toLot }}</view>
</uni-th>
</uni-tr>
<uni-tr>
<uni-th width="100">
<view>箱码</view>
</uni-th>
<uni-th width="100" align="center" v-if="holdItem.holdStatus === 3">
<view class="text_black">{{ dataContent.fromPackingCode }}</view>
</uni-th>
<uni-th width="100" align="center" v-else>
<view class="text_black">{{ dataContent.fromPackingCode }}</view>
</uni-th>
<uni-th width="100" align="center">
<view class="text_black">{{ dataContent.toPackingCode }}</view>
</uni-th>
</uni-tr>
</uni-table>
</view>
</view>
</view>
</template>
<script>
export default {
name: "comHold",
data() {
return {};
},
//
props: {
holdItem: {
type: Object,
value: null
},
dataContent: {
type: Object,
value: null
},
editQty: {
type: Boolean,
value: false
}
},
methods: {
qtyInput(value, item) {
this.$emit('qtyInput', value, item)
}
}
}
</script>
<style scoped lang="scss">
</style>

116
fe/PDA/mycomponents/coms/inventory/comUnissue.vue

@ -0,0 +1,116 @@
<template>
<view class="choose_main">
<view class="ljh_box">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="ljh_left">
<view class="text_lightblue font_xs">{{dataContent.itemName }}</view>
<view class="text_lightblue font_xs">{{dataContent.item.desc2 }}</view>
</view>
</view>
<view class="list_form">
<view class="uni-container">
<uni-table style="overflow-x: hidden;">
<uni-tr>
<uni-th width="100"></uni-th>
<uni-th width="100" align="center">库存</uni-th>
<uni-th width="100" align="center">出库</uni-th>
</uni-tr>
<uni-tr>
<uni-th width="100">数量{{dataContent.qty.uom}}</uni-th>
<uni-th width="100" align="center">
<text class="text_black" style="font-size: 1rem;">{{dataContent.qty.qty}}</text>
</uni-th>
<uni-th width="100" align="center">
<uni-easyinput v-model="dataContent.handelQty.qty" type="digit"
@input="qtyInput($event,dataContent)"></uni-easyinput>
</uni-th>
</uni-tr>
</uni-table>
</view>
</view>
<view class="uni-flex uni-row bot_card">
<view class="bot_card_item item_long">
<label class="icon_bg icon_bg_xm">
<image class="icon_normal" src="@/static/icons_ui/icon_xm.svg"></image>
</label>
<text>{{dataContent.packingCode}}</text>
</view>
<!-- 箱码 -->
<view class="bot_card_item" style="width:46%;">
<label class="icon_bg icon_bg_kw">
<image class="icon_normal" src="@/static/icons_ui/icon_kw.svg"></image>
</label>
<text>{{ dataContent.locationCode }}</text>
</view>
<!-- 库位 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg"></image>
</label>
<text>{{dataContent.lot}}</text>
</view>
<!-- 批次 -->
<view class="bot_card_item item_short">
<label class="icon_state" :class="statusStyle(dataContent.status) "></label>
<text class="state_point" :class="statusStyle(dataContent.status) ">
{{ statusColor(dataContent.status) }}
</text>
</view>
</view>
<comMessage ref="comMessage"></comMessage>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
} from '@/common/basic.js';
import comMessage from '@/mycomponents/common/comMessage.vue'
export default {
name: 'comUnissue',
components: {
comMessage
},
props: {
dataContent: {
type: Object,
default: {}
},
},
data() {
return {}
},
created() {
},
methods: {
qtyInput(value, item) {
let that = this;
if (value == '') {
setTimeout(() => {
that.dataContent.handledQty;
}, 10)
} else {
let qty = Number(value);
this.$emit('qtyChanged',qty,item)
}
},
showMessage(message) {
this.$refs.comMessage.showMessage(message);
},
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

65
fe/PDA/mycomponents/coms/query/comDetail.vue

@ -0,0 +1,65 @@
<template>
<view>
<win-empty-view v-if="itemList.length==0"></win-empty-view>
<view class="detail-list" v-for="item in itemList">
<view class="common_card">
<view class="detail-content">
<com-item-top :dataContent="item"></com-item-top>
<com-item-center v-if="displayLocations" :dataContent="item" ></com-item-center>
<com-item-bottom :dataContent="item"></com-item-bottom>
</view>
</view>
<!-- <com-detail :item="item"></com-detail> -->
</view>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc
} from '@/common/basic.js';
import winEmptyView from '@/mycomponents/wincom/winEmptyView.vue'
import comItemTop from '@/mycomponents/comItem/comItemTop.vue'
import comItemCenter from '@/mycomponents/comItem/comItemLocationCenter.vue'
import comItemBottom from '@/mycomponents/comItem/comItemBottom.vue'
export default {
name: "comdetail",
components: {
winEmptyView,
comItemTop,
comItemCenter,
comItemBottom
},
data() {
return {};
},
//
props: {
itemList: {
type: Array,
value: null
},
displayLocations: {
type: Boolean,
default: true
}
},
methods:{
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

52
fe/PDA/mycomponents/coms/query/comItem.vue

@ -0,0 +1,52 @@
<!--包装组件-->
<template>
<view class="device-detail">
<view class="list-style">
<view class="ljh_box nopad">
<view class="tit_ljh uni-flex">
<text class="mini-type-style" :class="statusStyle(itemdetail.status) ">
{{ statusColor(itemdetail.status)}}
</text>
<text class="font_xl text_black text_bold">{{ itemdetail.code }}</text>
</view>
<view class="ljh_left">
<view class="font_xs text_lightblue">{{itemdetail.name}}</view>
<view class="font_xs text_lightblue">{{itemdetail.desc2}}</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
getItemTypeStyle,
getItemStatusDesc
} from '@/common/basic.js';
export default {
name: "comItem",
data() {
return {
};
},
//
props: {
itemdetail: {
type: Object,
value: null
}
},
methods:{
statusStyle: function(val) {
return getItemTypeStyle(val);
},
statusColor: function(val) {
return getItemStatusDesc(val);
},
}
}
</script>
<style>
</style>

58
fe/PDA/mycomponents/coms/query/comLocation.vue

@ -0,0 +1,58 @@
<!--库位组件-->
<template>
<view class="device-detail">
<view class="list-style nopad">
<view class="ljh_box nopad">
<view class="tit_ljh uni-flex">
<text class="mini-type-style" :class="typeStyle(locationDetail.type) ">
{{ typeDesc(locationDetail.type)}}
</text>
<text class="font_xl text_black text_bold">{{locationDetail.code}}</text>
</view>
<view class="ljh_left">
<view class="font_xs text_lightblue">{{locationDetail.name}}</view>
</view>
</view>
<com-item-location-center :dataContent="locationDetail"></com-item-location-center>
</view>
</view>
</template>
<script>
import {
getLocationType,
getLocationTypeDesc
} from '@/common/basic.js';
import comErpLocation from '@/mycomponents/comItem/comErpLocation.vue'
import comItemLocationCenter from '@/mycomponents/comItem/comItemLocationCenter.vue'
export default {
name: "comlocation",
components: {
comErpLocation,
comItemLocationCenter
},
data() {
return {
};
},
//
props: {
locationDetail: {
type: Object,
value: null
}
},
methods:{
typeStyle: function(val) {
return getLocationType(val);
},
typeDesc: function(val) {
return getLocationTypeDesc(val);
},
}
}
</script>
<style scoped lang="scss">
</style>

70
fe/PDA/mycomponents/coms/query/comOccupied.vue

@ -0,0 +1,70 @@
<template>
<view>
<win-empty-view v-if="itemList.length==0"></win-empty-view>
<view class="detail-list" v-for="item in itemList">
<view class="detail-content ">
<view class="ljh_box">
<view class="tit_ljh">{{ item.jobNumber }}</view>
<view class="uni-flex uni-row space-between">
<view class="ljh_left desc_ljh">
<view class="label_normal">
<view class="label_col">
<!-- <label class="">
<image class="icon_normal" src="@/static/icons_ui/icon_xm.svg"></image>
</label> -->
<text>{{ item.packingCode }}</text>
</view>
</view>
</view>
<view class="ljh_right">
<text class="tnum">{{item.qty}}</text>
<text class="tunit">{{item.uom}}</text>
</view>
</view>
</view>
<com-item-bottom :dataContent="item"></com-item-bottom>
</view>
</view>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc,
dateFormat
} from '@/common/basic.js';
import winEmptyView from '@/mycomponents/wincom/winEmptyView.vue'
import comItemBottom from '@/mycomponents/comItem/comItemBottom.vue'
export default {
name: "comoccupied",
components: {
winEmptyView,
comItemBottom
},
data() {
return {};
},
//
props: {
itemList: {
type: Array,
value: null
}
},
methods:{
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
formatDate: function(val) {
return dateFormat(val)
}
}
}
</script>
<style>
</style>

74
fe/PDA/mycomponents/coms/query/comSummary.vue

@ -0,0 +1,74 @@
<!--按零件查询-汇总 -->
<template>
<view>
<win-empty-view v-if="itemList.length==0"></win-empty-view>
<view class="detail-list" v-for="(item, index) in itemList">
<view class="detail-content">
<view class="ljh_box uni-flex uni-row space-between">
<view class="tit_ljh" v-if="summaryByLocation">{{item.itemCode}}</view>
<view class="tit_ljh" v-else>{{item.locationCode}}</view>
<view class="summary_state">
<label class="icon_state" :class="statusStyle(item.status)"
style="margin-right: 10rpx;"></label>
<text class="state_point" :class="statusStyle(item.status)"
style="background-color: transparent;">
{{ statusColor(item.status)}}
</text>
</view>
</view>
<view class="uni-flex uni-row space-between summary_wrap">
<view class="bot_card_item summary_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg"></image>
</label>
<text>{{ item.lot}}</text>
</view>
<!-- 批次 -->
<view class="ljh_right" style="margin-top: 0;">
<text class="tnum">{{ item.qty }}</text>
<text class="tunit">{{ item.uom }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
getInventoryTypeStyle,
getInventoryStatusDesc
} from '@/common/basic.js';
import winEmptyView from '@/mycomponents/wincom/winEmptyView.vue'
export default {
name: "comsummary",
components: {
winEmptyView
},
data() {
return {};
},
//
props: {
itemList: {
type: Array,
value: null
},
summaryByLocation: {
type: Boolean,
default: true
}
},
methods: {
statusStyle: function(val) {
return getInventoryTypeStyle(val);
},
statusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style>
</style>

63
fe/PDA/mycomponents/coms/return/comProductionReturn.vue

@ -0,0 +1,63 @@
<!--收货任务卡片-->
<template>
<view class="device-detail">
<view class="card_task nopad">
<view class="task_num">
<view class="ljh_box nopad">
<view class="tit_ljh">
<text class="state-style fl margin_xs_top" style="color: #fff;"
:class="statusStyle(dataContent.jobStatus) ">
{{statusColor(dataContent.jobStatus)}}
</text>
<text style="font-weight: normal; ">{{dataContent.number }}</text>
</view>
</view>
</view>
</view>
<view class="margin_xs_bottom pda_receipt_label">
<view class="label_order">
<image class="icon_normal" src="@/static/icons_ui/icon_return_num.svg"></image>
<text class="text_darkblue">退库单号:{{dataContent.productionReturnRequestNumber}}</text>
</view>
</view>
<view class="margin_xs_bottom pda_receipt_label">
<view class="label_order">
<image class="icon_normal" src="@/static/icons_ui/icon_date.svg"></image>
<text
class="text_darkblue">创建时间:{{dataContent.creationTime===null?'无':formatDate(dataContent.creationTime)}}</text>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
dateFormat
} from '@/common/basic.js';
export default {
name: "comReturn",
data() {
return {
};
},
props: ['dataContent'],
methods:{
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
formatDate: function(val) {
return dateFormat(val)
}
}
}
</script>
<style scoped lang="scss">
</style>

64
fe/PDA/mycomponents/coms/return/comReturn.vue

@ -0,0 +1,64 @@
<!--收货任务卡片-->
<template>
<view class="device-detail">
<view class="card_task nopad">
<view class="task_num">
<view class="ljh_box nopad">
<view class="tit_ljh">
<text class="state-style fl margin_xs_top" style="color: #fff;"
:class="statusStyle(returnItem.jobStatus)">
{{statusColor(returnItem.jobStatus) }}
</text>
<text>{{returnItem.number }}</text>
</view>
</view>
</view>
</view>
<view class="margin_xs_bottom pda_receipt_label">
<view class="label_order">
<image class="icon_normal" src="@/static/icons_ui/icon_supplier.svg"></image>
<text
class="text_darkblue">供应商:{{returnItem.supplierCode}}</text>
</view>
</view>
<view class="margin_xs_bottom pda_receipt_label">
<view class="label_order">
<image class="icon_normal" src="@/static/icons_ui/icon_date.svg"></image>
<text
class="text_darkblue">创建时间:{{returnItem.creationTime===null?'无':formatDate(returnItem.creationTime)}}</text>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
dateFormat
} from '@/common/basic.js';
export default {
name: "comReturn",
data() {
return {
};
},
props: ['returnItem'],
methods:{
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
formatDate: function(val) {
return dateFormat(val)
}
}
}
</script>
<style scoped lang="scss">
</style>

130
fe/PDA/mycomponents/coms/return/comReturnDetail.vue

@ -0,0 +1,130 @@
<!--收货任务卡片-->
<template>
<view class="detail-content">
<view class="choose_main">
<view class="ljh_box">
<view class="uni-flex uni-row space-between">
<view class="text-itemcode">零件号:{{ returnDetail.itemCode }}</view>
</view>
<view class="label_order">
<image class="icon_normal" src="@/static/icons_ui/icon_asn.svg"></image>
<text>名称:{{ returnDetail.itemName }}</text>
</view>
<view class="uni-flex space-between">
<view class="label_order" style="width: 50%;">
<image class="icon_normal" src="@/static/icons_ui/icon_tm.svg"></image>
<text>箱码:{{ returnDetail.recommendPackingCode }}</text>
</view>
<view class="label_order" style="width: 50%;">
<image class="icon_normal" src="@/static/icons_ui/icon_avn.svg"></image>
<text>数量:{{ returnDetail.recommendQty{ returnDetail.recommendQty.uom }}</text>
</view>
</view>
</view>
</view>
<view v-if="returnDetail.scaned" class="choose_marked">
<image src="@/static/image_marked.svg"></image>
</view>
</view>
</template>
<script>
export default {
name: "comReturnDetail",
data() {
return {
};
},
//
props: ['returnDetail'],
}
</script>
<style scoped lang="scss">
.display-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.device-detail {
padding: 8px;
.list-style {
padding: 8px;
margin-bottom: 0rpx;
border-radius: 16rpx;
background-color: #FFFFFF;
color: #666666;
line-height: 1.5;
.right-width {
text-align: center;
width: 100rpx;
}
.text-color {
color: #000;
font-weight: bolder;
}
.state-style {
border-radius: 16rpx;
font-size: 30rpx;
padding: 0 10rpx;
line-height: 50rpx;
height: 50rpx;
}
.green {
background-color: #c5ffe2;
color: #4b9762;
}
.red {
background-color: #ffc8c2;
color: #9f3f40;
}
.blue {
background-color: #c9d8ff;
color: #3167d2;
}
.grey {
background-color: #eaeaea;
color: #a5a5a5;
}
}
.wrap-flex {
flex-wrap: wrap;
align-content: space-between;
height: 100rpx;
padding-bottom: 25rpx;
.width-40,
.width-29 {
font-size: 24rpx;
box-shadow: 0rpx 0rpx 5rpx #888888;
background-color: $uni-bg-color;
view {
padding: 6rpx 8rpx;
}
}
.width-40 {
width: 39%;
}
.width-29 {
width: 29%;
text-align: center;
}
}
}
</style>

80
fe/PDA/mycomponents/coms/return/comScanReturn.vue

@ -0,0 +1,80 @@
<template>
<uni-popup ref="popup">
<view class="popup_box">
<view class="pop_title">
扫描信息
<text class="fr" @click="closeScanPopup()">关闭</text>
</view>
<view class="pop_tab">
<view class="uni-flex uni-row">
<view v-for="(tab, index) in tabBars" :key="tab.id" class="uni-tab-item" :id="tab.id"
:data-current="index" :class="tabIndex == index ? 'tab_tit tab_tit_active' : 'tab_tit'"
@click="ontabtap">
{{ tab.name }}
</view>
</view>
<view class="tab_info">
<win-com-scan @getScanResult="getScanResult" :placeholder="placeholder"></win-com-scan>
</view>
</view>
</view>
</uni-popup>
</template>
<script>
import winComScan from '@/mycomponents/wincom/winComScan.vue'
export default {
name: 'winScanReceipt',
components: {
winComScan
},
props: {
title: {
type: String,
default: ''
},
},
data() {
return {
code: '',
type: 'ASN',
tabIndex: 0,
tabBars: [{
name: '扫描退货单',
id: 1
}
],
placeholder: '扫描退货单'
}
},
created() {
},
methods: {
openScanPopup() {
this.$refs.popup.open('bottom')
},
closeScanPopup() {
this.$refs.popup.close()
},
ontabtap(e) {
let index = e.target.dataset.current || e.currentTarget.dataset.current;
this.tabIndex = index;
if (this.tabIndex === 0) this.placeholder = '退货单';
},
getScanResult(resut) {
this.code = resut.data.code;
this.callBack();
},
callBack() {
if (this.tabIndex === 0) this.type = 'return';
this.closeScanPopup();
this.$emit("getScanCode", this.type, this.code);
}
}
}
</script>
<style>
</style>

111
fe/PDA/mycomponents/coms/store/comDeliverFg.vue

@ -0,0 +1,111 @@
<!--发料任务卡片-->
<template>
<view class="choose_main">
<view class="ljh_box">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="ljh_left">
<view class="font_xs text_lightblue">{{dataContent.itemName}}</view>
<view class="font_xs text_lightblue">{{dataContent.item.desc2}}</view>
</view>
</view>
<view class="list_form">
<view class="uni-container">
<uni-table style="overflow-x: hidden;">
<uni-tr>
<uni-th width="90"></uni-th>
<uni-th width="100" align="center">库存</uni-th>
<uni-th width="100" align="center">发货</uni-th>
</uni-tr>
<uni-tr>
<uni-th width="90">数量{{dataContent.qty.uom}}</uni-th>
<uni-th width="100" align="center">
<view class="text_black">{{dataContent.balanceQty}}</view>
</uni-th>
<uni-th width="100" align="center">
<view class="text_black">
<uni-easyinput v-if='editQty' v-model="dataContent.qty.qty" type="digit"
@input="qtyInput($event,dataContent)">
</uni-easyinput>
<view v-else class="text_black">{{dataContent.qty.qty}}</view>
</view>
</uni-th>
</uni-tr>
</uni-table>
</view>
</view>
<view class="uni-flex uni-row bot_card">
<!-- 箱码 -->
<view class="bot_card_item item_long">
<label class="icon_bg icon_bg_xm">
<image class="icon_normal" src="@/static/icons_ui/icon_xm.svg">
</image>
</label>
<text>{{dataContent.packingCode}}</text>
</view>
<!-- 库位 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_kw">
<image class="icon_normal" src="@/static/icons_ui/icon_kw.svg">
</image>
</label>
<text>{{ dataContent.locationCode }}</text>
</view>
<!-- 批次 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg">
</image>
</label>
<text>{{dataContent.lot}}</text>
</view>
<!-- 状态 -->
<view class="bot_card_item item_short">
<label class="icon_state" :class="statusStyle(dataContent.status)"></label>
<text class="state_point" :class="statusStyle(dataContent.status)">
{{ statusColor(dataContent.status)}}
</text>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getInventoryStatusDesc
} from '@/common/basic.js';
export default {
name: "comDeliverFg",
data() {
return {};
},
//
props: {
dataContent: {
type: Object,
value: null
},
editQty: {
type: Boolean,
value: false
}
},
methods: {
qtyInput(value, item) {
this.$emit('qtyInput', value, item)
},
statusStyle: function(val) {
return getJobStatuStyle(val);
},
inventoryStatus: function(val) {
return getInventoryStatusDesc(val);
}
}
}
</script>
<style scoped lang="scss">
</style>

109
fe/PDA/mycomponents/coms/store/comDeliverTf.vue

@ -0,0 +1,109 @@
<!--发料任务卡片-->
<template>
<view class="choose_main">
<view class="ljh_box">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="ljh_left">
<view class="font_xs text_lightblue">{{dataContent.itemName}}</view>
<view class="font_xs text_lightblue">{{dataContent.item.desc2}}</view>
</view>
</view>
<view class="list_form">
<view class="uni-container">
<uni-table style="overflow-x: hidden;">
<uni-tr>
<uni-th width="90"></uni-th>
<uni-th width="100" align="center">库存</uni-th>
<uni-th width="100" align="center">发货</uni-th>
</uni-tr>
<uni-tr>
<uni-th width="90">数量{{dataContent.qty.uom}}</uni-th>
<uni-th width="100" align="center">
<view class="text_black">{{dataContent.balanceQty}}</view>
</uni-th>
<uni-th width="100" align="center">
<view class="text_black">
<uni-easyinput v-if="editQty" v-model="dataContent.qty.qty" type="digit"
@input="qtyInput($event,dataContent)">
</uni-easyinput>
<view v-else class="text_black">{{dataContent.qty.qty}}</view>
</view>
</uni-th>
</uni-tr>
</uni-table>
</view>
</view>
<view class="uni-flex uni-row bot_card">
<!-- 箱码 -->
<view class="bot_card_item item_long">
<label class="icon_bg icon_bg_xm">
<image class="icon_normal" src="@/static/icons_ui/icon_xm.svg">
</image>
</label>
<text>{{dataContent.packingCode}}</text>
</view>
<!-- 库位 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_kw">
<image class="icon_normal" src="@/static/icons_ui/icon_kw.svg">
</image>
</label>
<text>{{ dataContent.locationCode }}</text>
</view>
<!-- 批次 -->
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg">
</image>
</label>
<text>{{dataContent.lot}}</text>
</view>
<!-- 状态 -->
<view class="bot_card_item item_short">
<label class="icon_state" :class="statusStyle(dataContent.status )"></label>
<text class="state_point" :class="statusStyle(dataContent.status)">
{{ statusColor(dataContent.status)}}
</text>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getInventoryStatusDesc
} from '@/common/basic.js';
export default {
name: "comDeliverTf",
data() {
return {};
},
//
props: {
dataContent: {
type: Object,
value: null
},
editQty: {
type: Boolean,
value: false
}
},
methods: {
qtyInput(value, item) {
this.$emit('qtyInput', value, item)
},
statusStyle: function(val) {
return getJobStatuStyle(val);
},
inventoryStatus: function(val) {
return getInventoryStatusDesc(val);
}
}
}
</script>
<style scoped lang="scss">
</style>

57
fe/PDA/mycomponents/coms/store/comReceipt.vue

@ -0,0 +1,57 @@
<template>
<view class="choose_main">
<view class="ljh_box">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="uni-flex uni-row space-between">
<view class="ljh_left">
<view class="font_xs text_lightblue">{{dataContent.itemName}}</view>
<view class="font_xs text_lightblue">{{dataContent.item.desc2}}</view>
</view>
<view class="ljh_right">
<text class="tnum">{{dataContent.qty.qty}}</text>
<text class="tunit">{{dataContent.qty.uom}}</text>
</view>
</view>
</view>
<view class="uni-flex uni-row bot_card">
<view class="bot_card_item item_long">
<label class="icon_bg icon_bg_xm">
<image class="icon_normal" src="@/static/icons_ui/icon_xm.svg"></image>
</label>
<text>{{dataContent.packingCode}}</text>
</view>
<view class="bot_card_item" style="width:46%;">
</view>
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg"></image>
</label>
<text>{{dataContent.lot}}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: "comReceipt",
data() {
return {};
},
//
props: {
dataContent: {
type: Object,
value: null
},
},
methods: {
}
}
</script>
<style scoped lang="scss">
</style>

70
fe/PDA/mycomponents/coms/store/comTjRecycle.vue

@ -0,0 +1,70 @@
<!--发料任务卡片-->
<template>
<view class="choose_main">
<view class="ljh_box">
<view class="tit_ljh">{{ dataContent.itemCode }}</view>
<view class="uni-flex uni-row space-between">
<view class="ljh_left">
<view class="text_lightblue font_xs">{{ dataContent.itemName }}</view>
<view class="text_lightblue font_xs">{{ dataContent.item.Desc2 }}</view>
</view>
<view class="ljh_right">
<text class="tnum">{{dataContent.qty.qty}}</text>
<text class="tunit">{{dataContent.qty.uom}}</text>
</view>
</view>
</view>
<view class="cen_card margin_xs_bottom">
<view class="label_box uni-flex uni-row">
<view class="label_info" v-if="dataContent.prodLine!=undefined">
<label class="">
<image class="icon_normal" src="@/static/icons_ui/label_scx.svg">
</image>
</label>
<text>{{dataContent.prodLine}}</text>
</view>
</view>
</view>
<view class="uni-flex uni-row bot_card">
<view class="bot_card_item item_long">
<label class="icon_bg icon_bg_xm">
<image class="icon_normal" src="@/static/icons_ui/icon_xm.svg">
</image>
</label>
<text>{{dataContent.packingCode}}</text>
</view>
<view class="bot_card_item">
</view>
<view class="bot_card_item">
<label class="icon_bg icon_bg_pc">
<image class="icon_normal" src="@/static/icons_ui/icon_pc.svg">
</image>
</label>
<text>{{dataContent.lot}}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: "comTjRecycle",
data() {
return {};
},
//
props: {
dataContent: {
type: Object,
value: null
},
},
methods: {
}
}
</script>
<style scoped lang="scss">
</style>

65
fe/PDA/mycomponents/coms/task/comCalc.vue

@ -0,0 +1,65 @@
<!--盘点任务卡片-->
<template>
<view class="device-detail">
<view class="card_task nopad">
<com-job-top-info :jobContent="datacontent"></com-job-top-info>
</view>
<view class="cen_card margin_xs_bottom">
<view class="count_list">
<text>{{countStageDesc(datacontent.countStage)}}</text> |
<text>{{checkTypeDesc(datacontent.type)}}</text> |
<text>{{countMethodDesc(datacontent.countMethod) }}</text>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
getCountStageDesc,
getCheckTypeDesc,
getCountMethodDesc,
getInventoryStatusDesc,
getInventoryTypeStyle,
} from '@/common/basic.js';
import comJobTopInfo from '@/mycomponents/comjob/comJobTopInfo.vue'
export default {
name: "comcount",
data() {
return {};
},
components: {
comJobTopInfo
},
//
props: ['datacontent'],
methods:{
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
countStageDesc: function(val) {
return getCountStageDesc(val);
},
checkTypeDesc: function(val) {
return getCheckTypeDesc(val);
},
countMethodDesc: function(val) {
return getCountMethodDesc(val);
},
inventoryStatuStyle: function(val) {
return getInventoryTypeStyle(val);
},
inventoryStatusColor: function(val) {
return getInventoryStatusDesc(val);
},
}
}
</script>
<style scoped lang="scss">
</style>

77
fe/PDA/mycomponents/coms/task/comCount.vue

@ -0,0 +1,77 @@
<!--盘点任务卡片-->
<template>
<view class="device-detail">
<view class="card_task nopad">
<com-job-top-info :jobContent="datacontent"></com-job-top-info>
</view>
<view class="margin_xs_bottom">
<view class="count_list">
<text>{{countStageDesc(datacontent.countStage)}}</text> |
<!-- <text>{{datacontent.type | checkTypeDesc}}</text> | -->
<text>{{countMethodDesc(datacontent.countMethod)}}</text> |
<text>{{datacontent.locationCode }}</text>
</view>
</view>
<view class="uni-flex uni-row receipt_bot">
<view class="label_order">
<image class="icon_normal" style="vertical-align: middle;" src="@/static/icons_ui/icon_date.svg">
</image>
<text
class="text_darkblue">{{datacontent.creationTime===null?'无':formatDate(datacontent.creationTime) }}</text>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
getCountStageDesc,
getCheckTypeDesc,
getCountMethodDesc,
getInventoryStatusDesc,
getInventoryTypeStyle,
dateFormat
} from '@/common/basic.js';
import comJobTopInfo from '@/mycomponents/comjob/comJobTopInfo.vue'
export default {
name: "comcount",
data() {
return {};
},
components: {
comJobTopInfo
},
//
props: ['datacontent'],
methods:{
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
countStageDesc: function(val) {
return getCountStageDesc(val);
},
checkTypeDesc: function(val) {
return getCheckTypeDesc(val);
},
countMethodDesc: function(val) {
return getCountMethodDesc(val);
},
inventoryStatuStyle: function(val) {
return getInventoryTypeStyle(val);
},
inventoryStatusColor: function(val) {
return getInventoryStatusDesc(val);
},
formatDate: function(val) {
return dateFormat(val)
}
}
}
</script>
<style scoped lang="scss">
</style>

45
fe/PDA/mycomponents/coms/task/comCountItems.vue

@ -0,0 +1,45 @@
<template>
<page-meta root-font-size="16px"></page-meta>
<uni-popup ref="popupItems">
<scroll-view scroll-y="true" style="background-color: #EEEEEE;height: 90vh;">
<view class="popinpop count_shadow" style="width: 90vw;margin: 20rpx 20rpx 30rpx 20rpx;"
v-for="(item, index) in countList" :key="index" @click="callback(item)">
<com-count :datacontent="item"></com-count>
</view>
</scroll-view>
</uni-popup>
</template>
<script>
import comCount from '@/mycomponents/coms/task/comCount.vue';
export default {
components: {comCount}, //
emits:["selectedItem"],
data() {
return {
countList: {}
}
},
props: {
},
methods: {
openPopup(items) {
this.countList = items;
this.$refs['popupItems'].open("center");
},
callback(item) {
this.$emit("selectedItem", item);
this.$refs['popupItems'].close();
},
clear() {
return;
}
},
}
</script>
<style>
</style>

90
fe/PDA/mycomponents/coms/task/comCountScanDetail.vue

@ -0,0 +1,90 @@
<!-- 收货任务详情 -->
<template>
<view class="device-detail" style="padding-bottom: 0 !important;">
<com-job-top-info :jobContent="jobContent"></com-job-top-info>
<view class="cell_box uni-flex uni-row margin_top">
<view class="cell_info">
<view class="text_lightblue">库位</view>
<view class="text_black text_bold">{{location==null?'无':location.code}}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">ERP储位</view>
<view class="text_black text_bold">{{ location==null?'无':location.erpLocationCode}}</view>
</view>
<!-- <view class="cell_info">
<view class="text_lightblue">库位组</view>
<view class="text_black text_bold">{{ location.areaCode}}</view>
</view> -->
<view class="cell_info">
<view class="text_lightblue">总数量</view>
<view class="text_black text_bold">{{ allCount}}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">新增</view>
<view class="text_black text_bold">{{ newCount}}</view>
</view>
<view class="cell_info">
<view class="text_lightblue">盘点</view>
<view class="text_black text_bold">{{ scanCount}}</view>
</view>
</view>
</view>
</template>
<script>
import {
getJobStatuStyle,
getJobStatuDesc,
} from '@/common/basic.js';
import comJobTopInfo from '@/mycomponents/comjob/comJobTopInfo.vue'
export default {
name: 'comJobScanDetail',
components: {
comJobTopInfo
},
props: {
jobContent: {
type: Object,
default: {}
},
allCount: {
type: Number,
default: 0
},
newCount: {
type: Number,
default: 0
},
scanCount: {
type: Number,
default: 0
},
location: {
type: Object,
default: {}
}
},
data() {
return {
};
},
mounted() {
},
methods: {
statusStyle: function(val) {
return getJobStatuStyle(val);
},
statusColor: function(val) {
return getJobStatuDesc(val);
},
}
}
</script>
<style scoped lang="scss">
</style>

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

Loading…
Cancel
Save