Waitsent.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <template>
  2. <div class="container">
  3. <div class="container-searchNumber">
  4. <van-search style="width: 100%;" v-model="params.search" placeholder="请输入批次号" />
  5. <van-icon class="container-searchNumber-icon" @click="onSearch" size="20" name="search" />
  6. </div>
  7. <ScrollRefresh style="background-color: #f0eff4;" height="calc(100vh - 99px)" ref="scrollRefresh"
  8. :request="request">
  9. <template v-slot="slotProps">
  10. <div class="batch" v-for="(item, index) in slotProps.list" :key="index">
  11. <div class="batch-top">
  12. <div class="batch-top-dispatchBatchNo">批次号:{{ item.dispatchBatchNo
  13. }}
  14. </div>
  15. <div class="jindu">派送进度 {{ item.signed }}/{{ item.sumAnd }}</div>
  16. </div>
  17. <!-- 各个运单 -->
  18. <div class="batchss"
  19. :style="{ overflow: item.openCard ? 'auto' : 'hidden', height: item.openCard ? 'auto' : '140px', }">
  20. <div class="batch-middel" v-for="(unfold, index) in item.list" :key="index">
  21. <div class="batch-middel-text">
  22. <div class="batch-middel-text-style"
  23. style="text-align: left; width: 100%; margin-left: -6px;">【{{
  24. unfold.expressCompany }}】运单号:{{
  25. unfold.expressNo }}</div>
  26. <div style="display: flex; justify-content: space-between; flex-wrap: wrap;">
  27. <div class="batch-middel-text-style">收件人:{{ unfold.recipient }}</div>
  28. <div class="batch-middel-text-style">部门:{{ unfold.departmentId }}</div>
  29. <div class="batch-middel-text-style">楼层:{{ unfold.floor }}</div>
  30. <div class="batch-middel-text-style">座位号:{{ unfold.sendSeat }}</div>
  31. <div style="display: flex;" class="batch-middel-text-style">联系方式:{{ unfold.phone }}
  32. <a :href="'tel:' + unfold.phone" style="padding-left: 6px;" type="info" plain
  33. size="mini">拨打</a>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="batch-middel-bottom">
  38. <van-button class="batch-middel-bottom-buttom" size="small" plain type="info"
  39. @click="onReceiving(unfold)">签收
  40. </van-button>
  41. <van-button class="batch-middel-bottom-buttom" size="small" plain type="danger"
  42. @click="onSureRetention(unfold)">设为滞留</van-button>
  43. </div>
  44. </div>
  45. </div>
  46. <div @click="onUnfold(item)" class="batch-bottom">
  47. {{ item.openCard ? "收起....." : "展开....." }}
  48. </div>
  49. </div>
  50. </template>
  51. </ScrollRefresh>
  52. <!-- 签收 -->
  53. <van-popup v-model="receiving" style="width: 100%; height: 84%;">
  54. <div style="font-size: 20px; text-align: center; margin-top: 12px;">派件签收</div>
  55. <van-form @submit="onReceipt">
  56. <van-field name="expressNo" label="运单号" :value="onReceivingVlaue.expressNo" readonly />
  57. <van-field label="快件类型" :value="onReceivingVlaue.expressType" readonly />
  58. <van-field label="快递公司" :value="onReceivingVlaue.expressCompany" readonly />
  59. <van-field label="部门" :value="onReceivingVlaue.departmentId" readonly />
  60. <van-field label="座位号" :value="onReceivingVlaue.sendSeat" readonly />
  61. <van-field label="收件人" :value="onReceivingVlaue.recipient" readonly />
  62. <van-field label="楼层" :value="onReceivingVlaue.floor" readonly />
  63. <van-field label="联系方式" :value="onReceivingVlaue.phone" readonly />
  64. <van-field readonly clickable name="picker" :value="selectedOption" label="签收类型" placeholder="点击签收类型"
  65. @click="showPicker = true" />
  66. <van-popup v-model="showPicker" position="bottom">
  67. <van-picker show-toolbar :columns="options" @confirm="onConfirm" @cancel="showPicker = false" />
  68. </van-popup>
  69. <van-field v-if="wer == '他人签收'" v-model="getOtherPhone" :rules="[{ required: true }]" label="代取手机号"
  70. placeholder="请输入代取手机号" />
  71. <van-field name="uploader" :rules="[{ required: true }]" label="签收照片">
  72. <template #input>
  73. <van-uploader v-model="uploader" :after-read="afterRead" :before-read="beforeRead"
  74. :max-count="1" />
  75. </template>
  76. </van-field>
  77. <div style="margin: 16px;">
  78. <van-button round block type="info" native-type="submit">签收完成</van-button>
  79. </div>
  80. </van-form>
  81. </van-popup>
  82. <!-- 设为滞留 -->
  83. <van-popup v-model="retention" style="width: 100%; height: 75%;">
  84. <div style="font-size: 20px; text-align: center; ">派件滞留</div>
  85. <van-form @submit="onSetRetention">
  86. <van-field name="expressNo" label="运单号" :value="onSureRetentionVlaue.expressNo" readonly />
  87. <van-field label="快件类型" :value="onSureRetentionVlaue.expressType" readonly />
  88. <van-field label="快递公司" :value="onSureRetentionVlaue.expressCompany" readonly />
  89. <van-field label="部门" :value="onSureRetentionVlaue.departmentId" readonly />
  90. <van-field label="座位号" :value="onSureRetentionVlaue.sendSeat" readonly />
  91. <van-field label="收件人" :value="onSureRetentionVlaue.recipient" readonly />
  92. <van-field label="楼层" :value="onSureRetentionVlaue.floor" readonly />
  93. <van-field label="联系方式" :value="onSureRetentionVlaue.phone" readonly />
  94. <van-field readonly clickable name="picker" :value="selectedRetention" label="滞留原因" placeholder="点击签收类型"
  95. @click="showRetention = true" />
  96. <van-popup v-model="showRetention" position="bottom">
  97. <van-picker show-toolbar :columns="Retention" @confirm="onRetention"
  98. @cancel="showRetention = false" />
  99. </van-popup>
  100. <van-field v-if="ert == '其他原因'" v-model="otherCause" label="其他原因" :rules="[{ required: true }]"
  101. placeholder="请输入其他原因" />
  102. <div style="margin: 16px;">
  103. <van-button round block native-type="submit" type="danger">设为滞留</van-button>
  104. </div>
  105. </van-form>
  106. </van-popup>
  107. </div>
  108. </template>
  109. <script>
  110. import ScrollRefresh from './ScrollRefresh.vue';
  111. import { appOutboundInquiry, appGetTheDetails, appSetStrands, appDelivery, appUploadTheSignature } from '@/api/index'
  112. export default {
  113. name: 'waitsent',
  114. components: {
  115. ScrollRefresh
  116. },
  117. data() {
  118. return {
  119. getOtherPhone: '',//他人签收
  120. otherCause: '',//滞留原因
  121. receiving: false,//签收
  122. retention: false,//滞留
  123. selectedOption: '本人签收', // 设置为空字符串,等待选择
  124. selectedRetention: '',
  125. value: '',
  126. options: ['本人签收', '他人签收'],
  127. Retention: ['无法联系收件人', '其他原因'],
  128. showPicker: false,
  129. showRetention: false,
  130. wer: '',
  131. ert: '',
  132. uploader: [],
  133. params: {
  134. search: '', //'SF202303221917',
  135. },
  136. onReceivingVlaue: {},//点击签收存放的数据
  137. onSureRetentionVlaue: {},//点击签收滞留的数据
  138. Agent: '',//是否待签(后续判断)
  139. getFileUrl: '',//返回的图片地址
  140. };
  141. },
  142. mounted() {
  143. // 获取数据
  144. // this.getData();
  145. },
  146. methods: {
  147. // 搜索批次号
  148. async onSearch() {
  149. this.$refs.scrollRefresh.onRefresh()
  150. },
  151. async request(_params) {
  152. let parmas = {
  153. dispatchBatchNo: this.params.search, // 批次号
  154. deliveryPeopleId: localStorage.getItem('courierId'), //派送员id
  155. isFinish: '2',//完成 1已完成 2未完成
  156. ..._params
  157. }
  158. const res = await appOutboundInquiry({ ...parmas }, { emulateJSON: true })
  159. res.data = res.data.map((item) => {
  160. item.list = [item.list]
  161. return item
  162. })
  163. return res
  164. }
  165. ,
  166. // 签收控制显示
  167. onReceiving(value) {
  168. this.onReceivingVlaue = value
  169. this.receiving = true;
  170. this.selectedOption = this.options[0];
  171. },
  172. // 签收选择确认弹框
  173. onConfirm(value) {
  174. this.selectedOption = value;
  175. this.showPicker = false;
  176. this.wer = value
  177. },
  178. // 滞留控制显示
  179. onSureRetention(value) {
  180. this.onSureRetentionVlaue = value
  181. this.retention = true;
  182. },
  183. // 确定滞留
  184. async onSetRetention(value) {
  185. console.log(value)
  186. let params = {
  187. expressNo: value.expressNo,
  188. sendRemark: value.picker
  189. }
  190. if (value.picker == '其他原因') {
  191. params.sendRemark = this.otherCause
  192. }
  193. const res = await appSetStrands({ ...params })
  194. if (res.code == 0) {
  195. this.$toast('滞留完成')
  196. this.retention = false
  197. // this.request()
  198. this.$router.push('/DeliveryInquiry')
  199. }
  200. },
  201. // 原因
  202. onRetention(value) {
  203. this.selectedRetention = value;
  204. this.showRetention = false;
  205. this.ert = value
  206. },
  207. // 文件读取完成后的钩子
  208. async afterRead(file) {
  209. console.log(file)
  210. const formData = new FormData();
  211. formData.append('file', file.file); // 这里的 'file' 是后端接收文件的字段名
  212. const res = await appUploadTheSignature(formData)
  213. this.getFileUrl = res.data
  214. },
  215. beforeRead(file) {
  216. // 在这里可以添加对文件的校验逻辑
  217. // 如果返回 true, 则继续读取文件
  218. return true;
  219. },
  220. // 签收完成
  221. async onReceipt(value) {
  222. console.log('123')
  223. console.log(value)
  224. if (value.picker == '他人签收') {
  225. this.Agent = 2
  226. } else {
  227. this.Agent = 1
  228. }
  229. let params = {
  230. signEnclosureImg: this.getFileUrl,//签署图片
  231. deliveryId: value.expressNo, //快递单号
  232. deliveryPeopleId: localStorage.getItem('courierId'), //派件员id
  233. isCollectAgent: this.Agent,//是否代签
  234. collectAgentNumber: value.picker // 原因
  235. // expressNo: value.expressNo,
  236. }
  237. if (value.picker == '他人签收') {
  238. params.collectAgentNumber = this.getOtherPhone
  239. }
  240. const res = await appDelivery({ ...params })
  241. if (res.code == 0) {
  242. this.$toast('签收完成')
  243. this.receiving = false
  244. this.$refs.scrollRefresh.onRefresh()
  245. }
  246. },
  247. // 展开
  248. async onUnfold(waite) {
  249. const data = await appGetTheDetails({ dispatchBatchNo: waite.dispatchBatchNo })
  250. waite.list = data.data
  251. this.$set(waite, "openCard", !waite.openCard)
  252. }
  253. },
  254. }
  255. </script>
  256. <style lang="less" scoped>
  257. * {
  258. font-size: 12px;
  259. }
  260. .container {
  261. height: 100%;
  262. &-searchNumber {
  263. display: flex;
  264. justify-content: space-between;
  265. background-color: #fff;
  266. &-icon {
  267. margin: 19px 8px 0 0px;
  268. }
  269. }
  270. .batch {
  271. background-color: #fff;
  272. margin: 10px;
  273. &-top {
  274. display: flex;
  275. justify-content: space-between;
  276. align-items: center;
  277. padding: 10px 6px 6px 6px;
  278. &-dispatchBatchNo {
  279. font-size: 12px;
  280. }
  281. .jindu {
  282. color: #169bd5
  283. }
  284. }
  285. &-middel {
  286. // height: 120px;
  287. background-color: #f7f8fa;
  288. border-radius: 12px;
  289. margin: 10px 6px;
  290. &-text {
  291. padding: 0px 10px;
  292. &-style {
  293. width: 50%;
  294. font-size: 12px;
  295. padding-top: 8px;
  296. }
  297. }
  298. &-bottom {
  299. display: flex;
  300. justify-content: flex-end;
  301. padding-top: 5px;
  302. &-buttom {
  303. width: 70px;
  304. height: 25px;
  305. border-radius: 6px;
  306. margin-right: 12px
  307. }
  308. }
  309. }
  310. &-bottom {
  311. padding: 10px 4px;
  312. color: #169bd5;
  313. }
  314. }
  315. }
  316. </style>