sureCombine.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <div class="container">
  3. <div v-show="isPhotoOrsize == '0'">
  4. <div style="padding: 20px 0;">合并签收以下快件:</div>
  5. <van-form @submit="onSubmit">
  6. <van-field name="checkboxGroup">
  7. <template #input>
  8. <van-checkbox-group v-model="checkboxGroup">
  9. <van-checkbox disabled style="margin-bottom: 10px;" :name="item.id" shape="square"
  10. v-for="item in goodsList" :key="item.id"> {{ item.expressNo }} & {{ item.expressType
  11. }} & {{ item.expressQuantity }}件 &{{ item.isPayOnDelivery == '否' ? '非到付' : '到付' }}
  12. </van-checkbox>
  13. </van-checkbox-group>
  14. </template>
  15. </van-field>
  16. <van-field readonly clickable name="shelfInformation" label="上传照片或签字板" lable-width="1000px" :value="currentSelect"
  17. placeholder="请选择货架" @click="isShelf = true" :rules="[{ required: true }]" />
  18. <van-popup v-model="isShelf" position="bottom">
  19. <van-picker title="标题" show-toolbar :columns="shelfs" @confirm="onConfirm" @cancel="onCancel" />
  20. </van-popup>
  21. <div style="display: flex;justify-content: flex-start;">
  22. <span style="margin-left: 0.4rem; margin-right: 1rem;">图片显示:</span>
  23. <van-image width="2rem" height="2rem" fit="contain" :src="canvasPhotoIMG"/>
  24. </div>
  25. <div>
  26. <van-button style="height: 40px; width: 150px; border-radius: 8px; margin-right: 20px;" type="info"
  27. native-type="submit">确定签收</van-button>
  28. <van-button style="height: 40px; width: 150px; border-radius: 8px;" type="default"
  29. @click="back">返回上一级</van-button>
  30. </div>
  31. <!-- <van-image class="batch-middel-text-style" width="100" height="100" :src="aaa" /> -->
  32. </van-form>
  33. </div>
  34. <div v-show="isPhotoOrsize == '图片'">
  35. <van-field name="uploader" label="上传照片" >
  36. <template #input>
  37. <van-uploader multiple :deletable="true"
  38. @delete="onDelete" v-model="uploader" :after-read="afterRead" :before-read="beforeRead" :max-count="1" />
  39. </template>
  40. </van-field>
  41. <van-button type="default" native-type="button" @click="photoClose">取消</van-button>
  42. <van-button type="default" native-type="button" @click="phoneSubmit">确定</van-button>
  43. </div>
  44. <div v-show="isPhotoOrsize == '签字板'">
  45. <canvas ref="canvas"
  46. :width="width"
  47. :height="height"
  48. @mousedown="startDrawing"
  49. @mouseup="stopDrawing"
  50. @mousemove="draw"
  51. @mouseout="stopDrawing"
  52. @touchstart="startDrawing"
  53. @touchend="stopDrawing"
  54. @touchmove="drawTouch" style="border: 1px solid;" ></canvas>
  55. <van-button type="default" native-type="button" @click="canvasClose">取消</van-button>
  56. <van-button type="default" native-type="button" @click="clearCanvas">重写</van-button>
  57. <van-button type="default" native-type="button" @click="saveSignature" >确定</van-button>
  58. </div>
  59. </div>
  60. </template>
  61. <script>
  62. import { appDelivery, appUploadTheSignature } from '@/api/index'
  63. import axios from 'axios';
  64. export default {
  65. name: 'sureCombine',
  66. props: ['isCombine', 'goodsList'],
  67. data() {
  68. return {
  69. checkbox: false,
  70. checkboxGroup: [],
  71. uploader: [],//图片
  72. isShelf:false,
  73. isPhotoOrsize:'0',//控制展示
  74. currentSelect:'',
  75. shelfs:['图片', '签字板'],
  76. isDrawing: false,
  77. hasContent: false,
  78. context: null,
  79. lastX: 0,
  80. lastY: 0,
  81. width: window.innerWidth - 24,
  82. height: window.innerHeight - 100,
  83. photoIMG:'',//储存展示图片
  84. canvasPhotoIMG:'',//展示图片
  85. hasUploadedImage: false, // 标记是否已上传图片
  86. };
  87. },
  88. mounted() {
  89. document.addEventListener('touchmove', function(e) {
  90. e.preventDefault();
  91. }, { passive: false })
  92. this.initCanvas();
  93. // 在组件挂载后,设置默认选中的值
  94. this.checkboxGroup = this.goodsList.map(item => item.id);
  95. },
  96. methods: {
  97. initCanvas() {
  98. const canvas = this.$refs.canvas;
  99. this.context = canvas.getContext('2d');
  100. this.context.strokeStyle = '#000000';
  101. this.context.lineWidth = 2;
  102. },
  103. startDrawing(event) {
  104. this.isDrawing = true;
  105. const rect = this.$refs.canvas.getBoundingClientRect();
  106. this.lastX = event.clientX - rect.left;
  107. this.lastY = event.clientY - rect.top;
  108. // this.lastX = event.offsetX || event.touches[0].clientX;
  109. // this.lastY = event.offsetY || event.touches[0].clientY;
  110. },
  111. stopDrawing() {
  112. this.isDrawing = false;
  113. this.lastX = null;
  114. this.lastY = null;
  115. },
  116. draw(event) {
  117. if (!this.isDrawing || !this.lastX || !this.lastY) return;
  118. const rect = this.$refs.canvas.getBoundingClientRect();
  119. const x = event.clientX - rect.left;
  120. const y = event.clientY - rect.top;
  121. this.drawLine(this.lastX, this.lastY, x, y);
  122. this.lastX = x;
  123. this.lastY = y;
  124. },
  125. drawTouch(event) {
  126. this.hasContent = true;
  127. if (!this.isDrawing) return;
  128. const rect = this.$refs.canvas.getBoundingClientRect();
  129. const touch = event.touches[0];
  130. const x = touch.clientX - rect.left;
  131. const y = touch.clientY - rect.top;
  132. this.drawLine(this.lastX, this.lastY, x, y);
  133. this.lastX = x;
  134. this.lastY = y;
  135. },
  136. drawLine(x1, y1, x2, y2) {
  137. this.context.beginPath();
  138. this.context.moveTo(x1, y1);
  139. this.context.lineTo(x2, y2);
  140. this.context.stroke();
  141. },
  142. canvasClose() {
  143. this.isPhotoOrsize = 0
  144. },
  145. clearCanvas() {
  146. this.context.clearRect(0, 0, this.width, this.height);
  147. this.hasContent = false;
  148. },
  149. saveSignature() {
  150. if(this.hasContent == false) {
  151. return this.$toast('请签名')
  152. }
  153. this.canvasPhotoIMG = this.$refs.canvas.toDataURL('image/png');
  154. const canvas = this.$refs.canvas;
  155. canvas.toBlob(async (blob) => {
  156. const file = new File([blob], 'my_image.png', { type: 'image/png' });
  157. console.log(file,'file')
  158. const formData = new FormData();
  159. formData.append('file', file);
  160. const res = await appUploadTheSignature(formData)
  161. this.getFileUrl = res.data
  162. console.log(this.getFileUrl,'=addresse')
  163. });
  164. this.currentSelect = "签字板"
  165. this.isPhotoOrsize = 0
  166. },
  167. onConfirm(value, index) {
  168. if(value == '签字板') {
  169. this.show =true
  170. }
  171. this.isPhotoOrsize = value
  172. this.isShelf = false
  173. },
  174. onCancel() {
  175. this.isShelf = false
  176. },
  177. beforeRead(file) {
  178. // 在这里可以添加对文件的校验逻辑
  179. // 如果返回 true, 则继续读取文件
  180. return true;
  181. },
  182. // 文件读取完成后的钩子
  183. async afterRead(file) {
  184. console.log(file)
  185. this.photoIMG = file.content
  186. this.hasUploadedImage = true;
  187. console.log(file.content,'--',this.photoIMG)
  188. const formData = new FormData();
  189. formData.append('file', file.file); // 这里的 'file' 是后端接收文件的字段名
  190. const res = await appUploadTheSignature(formData)
  191. this.getFileUrl = res.data
  192. },
  193. async onSubmit(values) {
  194. let data = []
  195. this.goodsList.forEach((item) => {
  196. if (values.checkboxGroup.find((itemA) => itemA === item.id)) {
  197. data.push(item.expressNo)
  198. }
  199. })
  200. console.log(this.getFileUrl,'传的对不对,是哪一个')
  201. const params = {
  202. signEnclosureImg: this.getFileUrl,//签署图片
  203. deliveryId: data.join(','),//快递单号逗号隔开
  204. deliveryPeopleId: localStorage.getItem('courierId'),// 派件员id
  205. }
  206. const res = await appDelivery({ ...params }, { emulateJSON: true, loading: true, message: '签收中' })
  207. if (res.code == 0) {
  208. this.$toast('签收成功')
  209. this.$router.push('/')
  210. } else {
  211. this.$toast('签收失败')
  212. }
  213. },
  214. back() {
  215. this.$emit('isCombine', true)
  216. },
  217. phoneSubmit() {
  218. if (this.hasUploadedImage) {
  219. this.isPhotoOrsize = 0
  220. this.currentSelect = '图片'
  221. this.canvasPhotoIMG = this.photoIMG
  222. console.log(this.photoIMG,'--123图片')
  223. } else {
  224. this.$toast('请先上传图片');
  225. }
  226. },
  227. photoClose() {
  228. this.isPhotoOrsize = 0
  229. },
  230. // 删除图片时的处理
  231. onDelete(file) {
  232. // 标记为未上传图片
  233. this.hasUploadedImage = false;
  234. console.log('已删除图片', file);
  235. },
  236. }
  237. };
  238. </script>
  239. <style lang="less" scoped>
  240. .ckickChange {
  241. padding: 20px 20px;
  242. }
  243. * {
  244. font-size: 16px;
  245. }
  246. .van-field__label {
  247. width: 4rem;
  248. }
  249. .container {
  250. padding: 2px 10px 0 10px;
  251. background-color: #fff;
  252. }
  253. </style>