processList.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. <template>
  2. <gui-page :custom-header="true" :header-class="['gui-theme-background-color']">
  3. <template #gHeader>
  4. <view style="height:44px;" class="gui-flex gui-nowrap gui-rows gui-align-items-center">
  5. <!-- 使用组件实现返回按钮及返回首页按钮 -->
  6. <text style="font-size:44rpx;" class="gui-header-leader-btns gui-color-white font-icons"
  7. @tap="goHome">&#xe6c5;</text>
  8. <!-- 导航文本此处也可以是其他自定义内容 -->
  9. <text
  10. class="gui-h4 gui-blod gui-flex1 gui-text-center gui-ellipsis gui-color-white gui-primary-text">生产工单</text>
  11. <!-- 此处加一个右侧展位元素与左侧同宽,实现标题居中 -->
  12. <!-- 实际宽度请根据自己情况设置 -->
  13. <view style="width:40px;" />
  14. <!-- 如果右侧有其他内容可以利用条件编译和定位来实现-->
  15. </view>
  16. </template>
  17. <template #gBody>
  18. <view class="list-content">
  19. <view class="search">
  20. <view class="search-card">
  21. <text>生产工序</text>
  22. <view class="custom-select">
  23. <uni-data-select v-model="queryParams.processNo" :localdata="selectList"
  24. @change="handleSelected" />
  25. </view>
  26. </view>
  27. </view>
  28. <view class="scan">
  29. <view class="scan-card">
  30. <uni-easyinput ref="easyinput" v-model="scanBatchNumber" class="easyinput" :input-border="false"
  31. :clearable="false" type="text" focus @focus="handleInputFocus" placeholder="请扫描工单二维码"
  32. @confirm="confirmWork" />
  33. <text class="font-icons" style="font-size: 20px;" @click="handleMapass">&#xe6b7;</text>
  34. </view>
  35. </view>
  36. <view v-if="cardList.length > 0" class="list-panel">
  37. <view v-for="item in cardList" :key="item.id" class="panel" @click="handleToScanMaterials(item)">
  38. <view class="panel-row">
  39. <text>{{ item.erpWorkOrderNo }}</text>
  40. <text class="text-2 font-icons">{{ item.processName }}&#xe66b;</text>
  41. </view>
  42. <view class="panel-row">
  43. <text>生产订单号</text>
  44. <text>{{ item.materialNo }}</text>
  45. </view>
  46. <view class="panel-row">
  47. <text>计划数量</text>
  48. <text>{{ item.planningQty }}</text>
  49. </view>
  50. </view>
  51. </view>
  52. <view v-else>
  53. <view class="bg-image">
  54. <image src="@/static/empty.png" mode="heightFix" />
  55. <text>这里什么都没有...</text>
  56. </view>
  57. </view>
  58. </view>
  59. <uni-popup ref="popupProcess" background-color="#fff">
  60. <view class="popup-process-content">
  61. <view class="list-title" style="margin-bottom: 8px;">
  62. <span class="font-icons"
  63. style="font-size: 20px;color: #00a0e9;width: 40px;text-align: center;">&#xe6a3;</span>
  64. <span>工序列表</span>
  65. </view>
  66. <view>
  67. <view class="grid-box">
  68. <view v-for="(item, index) in processList" :key="index" class="box"
  69. @click="handleClickProcessItem(item)">{{ item.processName }}</view>
  70. </view>
  71. </view>
  72. </view>
  73. </uni-popup>
  74. <uni-popup ref="errorTip" type="dialog">
  75. <uni-popup-dialog type="error" cancel-text="关闭" confirm-text="确认" title="提示" :content="errorTipMessage"
  76. @confirm="handleCloseErrorTipsModal" @close="handleCloseErrorTipsModal" />
  77. </uni-popup>
  78. </template>
  79. </gui-page>
  80. </template>
  81. <script>
  82. import {
  83. onReachBottom
  84. } from '@dcloudio/uni-app'
  85. import {
  86. ref,
  87. onMounted,
  88. defineComponent
  89. } from 'vue'
  90. export default defineComponent({
  91. setup() {
  92. const selectList = ref([])
  93. const scanBatchNumber = ref('')
  94. const queryParams = ref({
  95. pageSize: 10,
  96. pageNo: 1,
  97. deviceStatus: 1,
  98. processNo: '',
  99. ipqcFlag: 1
  100. })
  101. const cardList = ref([])
  102. const processList = ref([])
  103. const easyinput = ref()
  104. const popupProcess = ref()
  105. const errorState = ref(0)
  106. const errorTip = ref('')
  107. const errorTipMessage = ref('')
  108. const search = function() {
  109. uni.$reqGet('getHotPressList', queryParams.value)
  110. .then(({
  111. data,
  112. msg
  113. }) => {
  114. cardList.value = data?.list ?? []
  115. })
  116. }
  117. onMounted(() => {
  118. // 待检区列表数据
  119. uni.$reqGet('getProcessBaseList', {
  120. pageSize: 100,
  121. pageNo: 1
  122. })
  123. .then(({
  124. data
  125. }) => {
  126. if (data?.list.length > 0) {
  127. data?.list.forEach(item => {
  128. selectList.value.push({
  129. text: item.processName,
  130. value: item.processNo
  131. })
  132. })
  133. }
  134. })
  135. search()
  136. })
  137. const goHome = function() {
  138. uni.removeStorageSync('HotPressInfo')
  139. uni.$goHome()
  140. }
  141. const handleSelected = function(data) {
  142. queryParams.value.pageNo = 1
  143. if (![NaN, null, undefined].includes(data)) {
  144. queryParams.value.processNo = data
  145. }
  146. search()
  147. }
  148. // 获取工单明细并跳转工单明细页面
  149. const handleGetHotPressInfo = function(id) {
  150. uni.$reqGet('getHotPressDetails', {
  151. id
  152. })
  153. .then(({
  154. code,
  155. data,
  156. msg
  157. }) => {
  158. if (code === 0 && Object.keys(data).length > 0) {
  159. uni.setStorageSync('HotPressInfo', JSON.stringify(data))
  160. uni.navigateTo({
  161. url: `/pages/workbranch/production/processExecution/processDetails`
  162. })
  163. } else {
  164. // #ifdef APP-PLUS
  165. plus.device.beep(2)
  166. // #endif
  167. errorTipMessage.value = msg
  168. errorTip.value.open()
  169. errorState.value = 0
  170. }
  171. })
  172. }
  173. const handleToScanMaterials = function(params) {
  174. handleGetHotPressInfo(params?.id)
  175. }
  176. const handleValidataHotPressId = function(hotPressId) {
  177. uni.$reqGet('getUpperMaterialFlatKnife', {
  178. hotPressId
  179. })
  180. .then(({
  181. code,
  182. data,
  183. msg
  184. }) => {
  185. if (code === 0) {
  186. handleGetHotPressInfo(hotPressId)
  187. } else {
  188. // #ifdef APP-PLUS
  189. plus.device.beep(2)
  190. // #endif
  191. errorTipMessage.value = msg
  192. errorTip.value.open()
  193. errorState.value = 0
  194. }
  195. })
  196. }
  197. const handleMapass = function() {
  198. // #ifdef APP-PLUS
  199. const mpaasScanModule = uni.requireNativePlugin('Mpaas-Scan-Module')
  200. mpaasScanModule.mpaasScan({
  201. // 扫码识别类型,参数可多选,qrCode、barCode,不设置,默认识别所有
  202. 'scanType': ['qrCode', 'barCode'],
  203. // 是否隐藏相册,默认false不隐藏
  204. 'hideAlbum': false
  205. },
  206. (ret) => {
  207. if (ret.resp_code === 1000) {
  208. uni.$reqGet('getHotPressIdByQrCode', {
  209. qrCode: ret.resp_result
  210. })
  211. .then(({
  212. code,
  213. data,
  214. msg
  215. }) => {
  216. if (code === 0) {
  217. if (data?.length === 1) {
  218. handleValidataHotPressId(data[0].hotPressId)
  219. } else if (data?.length > 1) {
  220. processList.value = data
  221. popupProcess.value.open('bottom')
  222. }
  223. } else {
  224. // #ifdef APP-PLUS
  225. plus.device.beep(2)
  226. // #endif
  227. errorTipMessage.value = msg
  228. errorTip.value.open()
  229. errorState.value = 0
  230. }
  231. })
  232. }
  233. })
  234. // #endif
  235. }
  236. const confirmWork = async function(e) {
  237. uni.$reqGet('getHotPressIdByQrCode', {
  238. qrCode: e
  239. })
  240. .then(({
  241. code,
  242. data,
  243. msg
  244. }) => {
  245. if (code === 0) {
  246. if (data?.length === 1) {
  247. handleValidataHotPressId(data[0].hotPressId)
  248. } else if (data?.length > 1) {
  249. processList.value = data
  250. popupProcess.value.open('bottom')
  251. }
  252. } else {
  253. // #ifdef APP-PLUS
  254. plus.device.beep(2)
  255. // #endif
  256. errorTipMessage.value = msg
  257. errorTip.value.open()
  258. errorState.value = 0
  259. }
  260. })
  261. }
  262. // 工序列表点击事件
  263. const handleClickProcessItem = function(ret) {
  264. handleValidataHotPressId(ret.hotPressId)
  265. }
  266. const setInputFocus = function() {
  267. scanBatchNumber.value = ''
  268. easyinput.value.onBlur()
  269. easyinput.value.onFocus()
  270. }
  271. // 关闭错误信息弹窗
  272. const handleCloseErrorTipsModal = async function() {
  273. errorTip.value.close()
  274. if (errorState.value === 0) {
  275. await setInputFocus()
  276. }
  277. }
  278. // 禁用软键盘
  279. const handleInputFocus = function() {
  280. // #ifdef APP-PLUS
  281. setTimeout(() => {
  282. uni.hideKeyboard()
  283. }, 100)
  284. // #endif
  285. }
  286. // uniapp移动端触底事件
  287. onReachBottom(() => {
  288. queryParams.value.pageNo += 1
  289. uni.$reqGet('getHotPressList', queryParams.value)
  290. .then(({
  291. data
  292. }) => {
  293. Array.prototype.push.call(cardList.value, ...data?.list ?? [])
  294. })
  295. })
  296. return {
  297. search,
  298. goHome,
  299. cardList,
  300. selectList,
  301. popupProcess,
  302. processList,
  303. easyinput,
  304. errorTip,
  305. errorState,
  306. errorTipMessage,
  307. handleInputFocus,
  308. queryParams,
  309. confirmWork,
  310. handleSelected,
  311. scanBatchNumber,
  312. handleMapass,
  313. handleToScanMaterials,
  314. handleClickProcessItem,
  315. handleCloseErrorTipsModal
  316. }
  317. }
  318. })
  319. </script>
  320. <style lang="scss" scoped>
  321. .gui-header-leader-btns {
  322. color: black;
  323. font-size: 24px !important;
  324. margin-left: 24rpx;
  325. }
  326. .list-content {
  327. margin-top: 80px;
  328. background-color: #edeeee;
  329. }
  330. .list-panel {
  331. padding: 5px 8px;
  332. margin-top: 102px;
  333. overflow-y: scroll;
  334. }
  335. .scan {
  336. position: fixed;
  337. top: 124px;
  338. left: 0;
  339. height: 45px;
  340. width: 100%;
  341. padding: 0 12px;
  342. z-index: 1;
  343. display: flex;
  344. justify-content: space-between;
  345. align-items: center;
  346. box-sizing: border-box;
  347. background-color: white;
  348. .scan-card {
  349. width: 100%;
  350. display: grid;
  351. grid-template-rows: 1fr;
  352. grid-template-columns: 7fr 2fr;
  353. align-items: center;
  354. input {
  355. height: 35px;
  356. line-height: 35px;
  357. }
  358. text {
  359. width: 100%;
  360. text-align: right;
  361. }
  362. }
  363. }
  364. .search {
  365. position: fixed;
  366. top: 79px;
  367. left: 0;
  368. height: 45px;
  369. width: 100%;
  370. padding: 0 12px 0 24px;
  371. z-index: 9;
  372. display: flex;
  373. justify-content: space-between;
  374. align-items: center;
  375. box-sizing: border-box;
  376. border-bottom: 1px solid #edeeee;
  377. background-color: white;
  378. .search-card {
  379. width: 100%;
  380. display: grid;
  381. grid-template-rows: 1fr;
  382. grid-template-columns: 3fr 7fr;
  383. align-items: center;
  384. }
  385. }
  386. .custom-select {
  387. width: 100%;
  388. }
  389. .popup-process-content {
  390. width: 100vw;
  391. height: 85vh;
  392. overflow-y: scroll;
  393. .list-title {
  394. position: fixed;
  395. top: 0;
  396. left: 0;
  397. z-index: 99999;
  398. display: flex;
  399. align-items: center;
  400. width: 100%;
  401. height: 45px;
  402. line-height: 45px;
  403. font-size: 16px;
  404. font-weight: bold;
  405. border-bottom: 1px solid rgba(237, 238, 238, 1);
  406. border-top-left-radius: 16px;
  407. border-top-right-radius: 16px;
  408. .block {
  409. width: 6px;
  410. height: 60%;
  411. margin: 0 4px;
  412. background-color: rgb(0, 160, 233);
  413. }
  414. }
  415. .grid-box {
  416. margin-top: 45px;
  417. display: grid;
  418. grid-template-columns: 1fr 1fr 1fr;
  419. .box {
  420. position: relative;
  421. height: 40px;
  422. padding: 10px 6px;
  423. border: 1px solid rgb(250, 250, 251);
  424. box-sizing: border-box;
  425. margin: 12px;
  426. display: flex;
  427. justify-content: center;
  428. align-items: center;
  429. font-size: 14px;
  430. font-weight: bold;
  431. border-radius: 4px;
  432. color: white;
  433. box-shadow: 0 3px 6px 0 rgba(121, 118, 118, 0.34);
  434. background-color: rgb(0, 160, 233);
  435. }
  436. .box::before {
  437. content: '';
  438. position: absolute;
  439. top: 20px;
  440. left: 0;
  441. bottom: 0;
  442. transform: translate(-50%, -50%);
  443. width: 12px;
  444. height: 12px;
  445. border-radius: 50%;
  446. z-index: 1;
  447. background-color: #ffffff;
  448. }
  449. }
  450. }
  451. </style>