index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <template>
  2. <view class="container">
  3. <uni-forms ref="valiForm" label-align="right" :label-width="80" :rules="rules" :modelValue="valiFormData">
  4. <uni-forms-item label="单据编号" required name="order_code">
  5. <uni-easyinput v-model="valiFormData.order_code" placeholder="请输入单据编号" suffixIcon="scan"
  6. :focus="focusType" @iconClick="scanInput" @blur="setfocus" @confirm="onsubmit" />
  7. </uni-forms-item>
  8. </uni-forms>
  9. <view class="button-group">
  10. <button type="info" @click="reset">重置</button>
  11. <button type="primary" @click="onsubmit" :loading="loading">
  12. <uni-icons v-if="!loading" type="checkmarkempty" size="18" color="white"></uni-icons>
  13. 提交
  14. </button>
  15. </view>
  16. <view v-if="warehouseLogHistory.length > 0" class="history">
  17. <text class="title">记录(最近5条)</text>
  18. </view>
  19. <view class="history">
  20. <view class="item" v-for="(item, i) in warehouseLogHistory.slice(0, 5)" :key="i">
  21. <text class="code" :style="{ color: item.status ? 'green' : '#666' }">{{ item.order_code }}</text>
  22. <uni-icons v-if="item.status" type="checkmarkempty" class="status" size="16" color="green"></uni-icons>
  23. <text class="status fail" v-else>F</text>
  24. <text style="margin-left: 10rpx; font-weight: 300">
  25. {{ '\r\n' + item.createTime }}
  26. </text>
  27. </view>
  28. </view>
  29. <uni-popup ref="messageRef" type="message">
  30. <uni-popup-message :type="messageType" :message="messageText" :duration="2000"></uni-popup-message>
  31. </uni-popup>
  32. </view>
  33. </template>
  34. <script setup lang="ts">
  35. import { reactive, ref, nextTick } from 'vue';
  36. import permision from '@/common/permission.js';
  37. import {
  38. onShow,
  39. onLoad,
  40. onUnload,
  41. onHide,
  42. onBackPress,
  43. onNavigationBarButtonTap
  44. } from '@dcloudio/uni-app';
  45. import { warehouseScanURL } from '@/utils/api.js';
  46. const token = ref();
  47. const loading = ref(false);
  48. const hidePage = ref(false);
  49. const focusType = ref(true);
  50. const warehouseLogHistory = ref([]);
  51. const messageRef = ref();
  52. const messageType = ref();
  53. const messageText = ref();
  54. let st : NodeJS.Timeout;
  55. const valiFormData = ref({
  56. order_code: ''
  57. });
  58. const rules = reactive({
  59. order_code: {
  60. rules: [
  61. {
  62. required: true,
  63. errorMessage: '单据编号不能为空'
  64. }
  65. ]
  66. }
  67. });
  68. const checkPermission = async () => {
  69. let status = permision.isIOS ? await permision.requestIOS('camera') : await permision.requestAndroid('android.permission.CAMERA');
  70. if (status === null || status === 1) {
  71. status = 1;
  72. } else {
  73. uni.showModal({
  74. content: 'Camera permission required',
  75. confirmText: 'Setting',
  76. success: function (res) {
  77. if (res.confirm) {
  78. permision.gotoAppSetting();
  79. }
  80. }
  81. });
  82. }
  83. return status;
  84. }
  85. const scanInput = async () => {
  86. // #ifdef APP-PLUS
  87. let status = await checkPermission();
  88. if (status !== 1) {
  89. return;
  90. }
  91. // #endif
  92. uni.scanCode({
  93. success: (res : any) => {
  94. valiFormData.value.order_code = res.result;
  95. onsubmit();
  96. },
  97. fail: (err) => {
  98. // 需要注意的是小程序扫码不需要申请相机权限
  99. }
  100. });
  101. };
  102. const reset = () => {
  103. loading.value = false;
  104. valiFormData.value.order_code = '';
  105. };
  106. const setfocus = () => {
  107. if (hidePage.value) {
  108. return;
  109. }
  110. focusType.value = false;
  111. nextTick(() => {
  112. focusType.value = true;
  113. });
  114. }
  115. const onsubmit = () => {
  116. st && clearTimeout(st);
  117. loading.value = true;
  118. uni.request({
  119. url: warehouseScanURL,
  120. method: 'POST',
  121. header: {
  122. batoken: token.value
  123. },
  124. data: {
  125. order_code: valiFormData.value.order_code
  126. },
  127. success: (res : any) => {
  128. loading.value = false;
  129. if (res.data.code == 1) {
  130. messageType.value = 'success';
  131. messageText.value = res.data.msg;
  132. messageRef.value.open();
  133. const historyItem = {
  134. order_code: valiFormData.value.order_code,
  135. createTime: new Date(),
  136. type: '单据扫描',
  137. status: true
  138. };
  139. warehouseLogHistory.value.unshift(historyItem);
  140. uni.setStorageSync('warehouseLogHistory', warehouseLogHistory.value);
  141. getHistory();
  142. } else {
  143. messageType.value = 'error';
  144. messageText.value = res.data.msg;
  145. messageRef.value.open();
  146. const historyItem = {
  147. order_code: valiFormData.value.order_code,
  148. createTime: new Date(),
  149. type: '单据扫描',
  150. status: false
  151. };
  152. warehouseLogHistory.value.unshift(historyItem);
  153. uni.setStorageSync('warehouseLogHistory', warehouseLogHistory.value);
  154. getHistory();
  155. }
  156. st = setTimeout(() => {
  157. reset();
  158. st && clearTimeout(st);
  159. }, 1000);
  160. }
  161. });
  162. };
  163. const getHistory = () => {
  164. warehouseLogHistory.value = uni.getStorageSync('warehouseLogHistory') || [];
  165. };
  166. const keypress = (e : any) => {
  167. console.log(e, '按键码');
  168. // 102 左侧 103 右侧 104 中间按键
  169. if (e.keyCode === 102 || e.keyCode === 103 || e.keyCode === 104) {
  170. //这里按键成功
  171. }
  172. if (e.keyCode == 66) {
  173. //enter按键
  174. //这里input已经拿到数据了,在这里把拿到的数据,通过接口数据联调起来
  175. onsubmit();
  176. }
  177. }
  178. onLoad(() => {
  179. // #ifdef APP-PLUS
  180. plus.key.addEventListener('keyup', keypress);
  181. // #endif
  182. // #ifdef H5
  183. document.addEventListener('keyup', keypress);
  184. // #endif
  185. })
  186. onUnload(() => {
  187. // #ifdef APP-PLUS
  188. plus.key.removeEventListener('keyup', keypress);
  189. // #endif
  190. // #ifdef H5
  191. document.removeEventListener('keyup', keypress);
  192. // #endif
  193. })
  194. onHide(() => {
  195. hidePage.value = true;
  196. // #ifdef APP-PLUS
  197. plus.key.removeEventListener('keyup', keypress);
  198. // #endif
  199. // #ifdef H5
  200. document.removeEventListener('keyup', keypress);
  201. // #endif
  202. })
  203. onBackPress(() => {
  204. // #ifdef APP-PLUS
  205. plus.key.removeEventListener('keyup', keypress);
  206. // #endif
  207. // #ifdef H5
  208. document.removeEventListener('keyup', keypress);
  209. // #endif
  210. })
  211. onShow(() => {
  212. token.value = uni.getStorageSync('token');
  213. hidePage.value = false;
  214. getHistory();
  215. });
  216. onNavigationBarButtonTap((event) => {
  217. if (event.index === 0) {
  218. uni.navigateTo({
  219. url: '/pages/warehouseScan/warehouseLog'
  220. });
  221. }
  222. });
  223. </script>
  224. <style lang="scss" scoped>
  225. .container {
  226. padding: 15px;
  227. background-color: #fff;
  228. }
  229. .button-group {
  230. margin-top: 15px;
  231. display: flex;
  232. flex-direction: row;
  233. justify-content: space-around;
  234. button {
  235. display: flex;
  236. align-items: center;
  237. justify-content: center;
  238. height: 35px;
  239. width: 50%;
  240. margin-left: 10px;
  241. font-size: 16rpx;
  242. }
  243. .uni-icons {
  244. margin-right: 10px;
  245. }
  246. }
  247. .history {
  248. display: flex;
  249. width: 100%;
  250. flex-direction: column;
  251. justify-items: start;
  252. .title {
  253. padding: 20rpx;
  254. font-size: 24rpx;
  255. font-weight: 600;
  256. }
  257. .type {
  258. padding-right: 20rpx;
  259. font-size: 24rpx;
  260. }
  261. .code {
  262. font-weight: 600;
  263. }
  264. .item {
  265. padding: 20rpx;
  266. font-size: 20rpx;
  267. color: #666;
  268. .status {
  269. padding-left: 20rpx;
  270. }
  271. .fail {
  272. font-weight: 600;
  273. color: #f00;
  274. }
  275. }
  276. .is-empty {
  277. text-align: center;
  278. margin: 40px 0;
  279. color: #999;
  280. }
  281. }
  282. </style>