Commit d9b9463fa7a33957fc092dfdbfcc1cbde74797f1

Authored by lichao
1 parent fbca9085

提交12-12

garbage-removal/src/components/liu-delivery-time/liu-delivery-time.vue
@@ -96,34 +96,33 @@ const init = () => { @@ -96,34 +96,33 @@ const init = () => {
96 96
97 } 97 }
98 const getFutureDays = () => { 98 const getFutureDays = () => {
99 - const days = [];  
100 - for (let i = 0; i < props.day; i++) {  
101 - const date = new Date();  
102 - date.setDate(date.getDate() + i);  
103 - const year = date.getFullYear();  
104 - const month = (date.getMonth() + 1).toString().padStart(2, '0');  
105 - const day = date.getDate().toString().padStart(2, '0');  
106 - if (i === 0) {  
107 - let hours = date.getHours();  
108 - console.log(hours);  
109 - // if (hours >= 13) {  
110 - // continue;  
111 - // }  
112 - days.push({  
113 - day: `${year}-${month}-${day}`,  
114 - timeList: getCurrentDayTimeList(0, hours, 1)  
115 - });  
116 - } else {  
117 - days.push({  
118 - day: `${year}-${month}-${day}`,  
119 - timeList: getTimeList()  
120 - });  
121 - }  
122 - }  
123 - return days; 99 + const days = [];
  100 + for (let i = 0; i < props.day; i++) {
  101 + const date = new Date();
  102 + date.setDate(date.getDate() + i);
  103 + const year = date.getFullYear();
  104 + const month = (date.getMonth() + 1).toString().padStart(2, '0');
  105 + const day = date.getDate().toString().padStart(2, '0');
  106 + if (i === 0) {
  107 + let hours = date.getHours();
  108 + let minutes = date.getMinutes();
  109 + console.log(hours, minutes);
  110 + days.push({
  111 + day: `${year}-${month}-${day}`,
  112 + timeList: getCurrentDayTimeList(0, hours, minutes, 1)
  113 + });
  114 + } else {
  115 + days.push({
  116 + day: `${year}-${month}-${day}`,
  117 + timeList: getTimeList()
  118 + });
  119 + }
  120 + }
  121 + return days;
124 } 122 }
125 123
126 124
  125 +
127 const getTimeList = () => { 126 const getTimeList = () => {
128 const timeList = [{ 127 const timeList = [{
129 time: '00:00-02:00', 128 time: '00:00-02:00',
@@ -196,17 +195,65 @@ const getTimeList = () =&gt; { @@ -196,17 +195,65 @@ const getTimeList = () =&gt; {
196 * @param {*} hours 当前几点 195 * @param {*} hours 当前几点
197 * @param {*} skip 跳过几个 196 * @param {*} skip 跳过几个
198 */ 197 */
199 -const getCurrentDayTimeList = (startTime, hours, skip) => {  
200 - const timeList = getTimeList();  
201 - // 计算当前小时所属的时间段索引  
202 - // 每个时间段是2小时,从00:00-02:00开始  
203 - let index = Math.floor(hours / 2) + 1; // 加1是为了跳过已过期的时间段  
204 - // 确保不会超出数组范围  
205 - if (index >= timeList.length) {  
206 - return []; // 如果没有可选时间段,返回空数组 198 +const getCurrentDayTimeList = (startTime, hours, minutes, skip) => {
  199 + const dynamicTimeList = [];
  200 +
  201 + // 根据当前时间计算最早可预约的开始时间
  202 + let startHour = hours;
  203 + let startMinute = 0;
  204 +
  205 + if (minutes < 30) {
  206 + // 如果当前分钟小于30,则最早可预约时间是当前小时+30分钟开始
  207 + startMinute = 30;
  208 + } else {
  209 + // 如果当前分钟大于等于30,则最早可预约时间是下一个小时开始
  210 + startHour += 1;
  211 + startMinute = 0;
207 } 212 }
208 - return timeList.slice(index, timeList.length) 213 +
  214 + // 生成未来的时间段,每个时间段跨度2小时
  215 + for (let i = 0; i < 10; i++) { // 生成10个时间段足够使用
  216 + let endHour = startHour + 2;
  217 + const endMinute = startMinute;
  218 +
  219 + // 处理时间超过24小时的情况
  220 + const formattedEndHour = endHour > 24 ? endHour - 24 : endHour;
  221 + const formattedEndMinute = endMinute;
  222 +
  223 + // 格式化时间字符串
  224 + const startStr = `${startHour.toString().padStart(2, '0')}:${startMinute.toString().padStart(2, '0')}`;
  225 + const endStr = endHour >= 24 ? `24:00` : `${formattedEndHour.toString().padStart(2, '0')}:${formattedEndMinute.toString().padStart(2, '0')}`;
  226 + const timeStr = `${startStr}-${endStr}`;
  227 +
  228 + // 确定timeStr(根据原代码推测可能是时间段的标签)
  229 + let periodTimeStr = '';
  230 + if (startHour >= 7 && startHour < 22) {
  231 + periodTimeStr = `${startHour.toString().padStart(2, '0')}-${(startHour + 1).toString().padStart(2, '0')}`;
  232 + } else {
  233 + periodTimeStr = '22-07';
  234 + }
  235 +
  236 + // 添加到时间列表
  237 + dynamicTimeList.push({
  238 + time: timeStr,
  239 + start: startStr,
  240 + end: endStr,
  241 + timeStr: periodTimeStr
  242 + });
  243 +
  244 + // 更新下一个时间段的开始时间为当前时间段的结束时间(跨度2小时)
  245 + startHour += 2;
  246 + // 这里不需要改变分钟,因为我们是按2小时递增的
  247 +
  248 + // 如果开始时间超过24小时,停止生成(当天不再生成新的时间段)
  249 + if (startHour >= 24) {
  250 + break;
  251 + }
  252 + }
  253 +
  254 + return dynamicTimeList;
209 } 255 }
  256 +
210 const open = () => { 257 const open = () => {
211 isShow.value = true; 258 isShow.value = true;
212 init(); 259 init();
garbage-removal/src/pages/home-info/address/addSite.vue
@@ -165,94 +165,21 @@ const submit = () =&gt; { @@ -165,94 +165,21 @@ const submit = () =&gt; {
165 * 打开地图选择地址(自动定位到当前位置,修复 startCompass:fail 问题) 165 * 打开地图选择地址(自动定位到当前位置,修复 startCompass:fail 问题)
166 */ 166 */
167 const chooseAddressDetail = () => { 167 const chooseAddressDetail = () => {
168 - console.log('打开地图选择地址(自动定位)');  
169 -  
170 - // 1. 先获取当前位置的经纬度(关键:统一坐标系为 gcj02,关闭 altitude 避免额外权限)  
171 - uni.getLocation({  
172 - type: 'gcj02', // 必须使用 gcj02(腾讯/高德地图标准,避免坐标系不匹配)  
173 - altitude: false, // 关闭海拔获取,减少权限要求  
174 - isHighAccuracy: false, // 关闭高精度定位(降低硬件依赖)  
175 - success: (locationRes) => {  
176 - console.log('当前位置经纬度:', locationRes);  
177 - const { latitude, longitude } = locationRes;  
178 -  
179 - // 2. 打开地图选择器(移除可能触发指南针的参数)  
180 - uni.chooseLocation({  
181 - latitude: latitude,  
182 - longitude: longitude,  
183 - scale: 16,  
184 - name: addressInfo.addressDetail || '',  
185 - address: addressInfo.addressArea || '',  
186 - success: (res) => {  
187 - addressInfo.addressDetail = res.name;  
188 - addressInfo.garLongitude = res.longitude;  
189 - addressInfo.garLatitude = res.latitude;  
190 - },  
191 - fail: (err) => {  
192 - console.error('地图选择失败:', err);  
193 - handleLocationError(err);  
194 - }  
195 - }); 168 + console.log('打开地图选择地址');
  169 +
  170 + // 直接打开地图选择器,不进行定位
  171 + uni.chooseLocation({
  172 + success: (res) => {
  173 + addressInfo.addressDetail = res.name;
  174 + addressInfo.garLongitude = res.longitude;
  175 + addressInfo.garLatitude = res.latitude;
196 }, 176 },
197 fail: (err) => { 177 fail: (err) => {
198 - console.error('获取当前位置失败:', err);  
199 - handleLocationError(err); 178 + console.error('地图选择失败:', err);
200 } 179 }
201 }); 180 });
202 }; 181 };
203 182
204 -/**  
205 - * 统一处理定位/地图错误  
206 - */  
207 -const handleLocationError = (err) => {  
208 - const errMsg = err.errMsg || '';  
209 -  
210 - // 1. 处理权限拒绝  
211 - if (errMsg.includes('auth deny') || errMsg.includes('permission denied')) {  
212 - uni.showModal({  
213 - title: '授权提示',  
214 - content: '需要获取您的位置权限才能自动定位,请在设置中开启',  
215 - confirmText: '去设置',  
216 - cancelText: '手动输入',  
217 - success: (modalRes) => {  
218 - if (modalRes.confirm) {  
219 - uni.openSetting(); // 打开系统设置  
220 - } else {  
221 - // 手动输入地址(隐藏地图选择,直接让用户输入)  
222 - uni.showToast({ title: '请手动输入详细地址', icon: 'none' });  
223 - }  
224 - }  
225 - });  
226 - }  
227 -  
228 - // 2. 处理指南针失败(startCompass:fail)  
229 - else if (errMsg.includes('startCompass:fail')) {  
230 - uni.showModal({  
231 - title: '提示',  
232 - content: '当前设备不支持指南针功能,将为您打开地图手动选择地址',  
233 - showCancel: false,  
234 - success: () => {  
235 - // 降级方案:不传递初始经纬度,直接打开地图  
236 - uni.chooseLocation({  
237 - success: (res) => {  
238 - addressInfo.addressDetail = res.name;  
239 - addressInfo.garLongitude = res.longitude;  
240 - addressInfo.garLatitude = res.latitude;  
241 - },  
242 - fail: () => {  
243 - uni.showToast({ title: '地图选择失败,请手动输入地址', icon: 'none' });  
244 - }  
245 - });  
246 - }  
247 - });  
248 - }  
249 -  
250 - // 3. 其他错误(网络/设备问题)  
251 - else {  
252 - uni.showToast({ title: '定位失败,请手动输入地址', icon: 'none' });  
253 - }  
254 -};  
255 -  
256 onMounted(() => { 183 onMounted(() => {
257 proxy.$refs.addressFrom.setRules(rules) 184 proxy.$refs.addressFrom.setRules(rules)
258 }) 185 })
garbage-removal/src/pages/home-info/clean/index.vue
@@ -630,30 +630,31 @@ @@ -630,30 +630,31 @@
630 uni.$u.toast("请勿频繁操作") 630 uni.$u.toast("请勿频繁操作")
631 } 631 }
632 } 632 }
633 - const handlerSaveOrder = async (params) => {  
634 - await saveOrder(params).then(res => {  
635 - if (res.data.success) { 633 + const handlerSaveOrder = async (params) => {
  634 + await saveOrder(params).then(res => {
  635 + if (res.data.success) {
636 store.updateUnreadOrderCount(); 636 store.updateUnreadOrderCount();
637 - if (userType.value != "用户") {  
638 - uni.$u.toast("下单成功,请切换成且角色查看订单详情")  
639 - uni.$u.route({  
640 - type: 'navigateBack',  
641 - url: `pages/home/index`,  
642 - })  
643 - } else {  
644 - uni.$u.toast('下单成功')  
645 - uni.$u.route({  
646 - type: "redirect",  
647 - url: `pages/order-info/order-other/detail/index`,  
648 - params: {  
649 - orderId: res.data.data  
650 - }  
651 - })  
652 - }  
653 - }  
654 - })  
655 -  
656 - } 637 + // 发送自定义事件通知订单列表更新
  638 + uni.$emit('orderCreated', { type: 'newOrder' });
  639 + if (userType.value !== "用户") {
  640 + uni.$u.toast("下单成功,请切换成且角色查看订单详情")
  641 + uni.$u.route({
  642 + type: 'navigateBack',
  643 + url: `pages/home/index`,
  644 + })
  645 + } else {
  646 + uni.$u.toast('下单成功')
  647 + uni.$u.route({
  648 + type: "redirect",
  649 + url: `pages/order-info/order-other/detail/index`,
  650 + params: {
  651 + orderId: res.data.data
  652 + }
  653 + })
  654 + }
  655 + }
  656 + })
  657 + }
657 658
658 const handlerChooseAddress = () => { 659 const handlerChooseAddress = () => {
659 addressPopupRef.value.open(userAddress.value) 660 addressPopupRef.value.open(userAddress.value)
garbage-removal/src/pages/home/index.vue
@@ -163,6 +163,10 @@ const dropdownOptions = ref([ @@ -163,6 +163,10 @@ const dropdownOptions = ref([
163 label: '湘江新区', 163 label: '湘江新区',
164 value: '湘江新区' 164 value: '湘江新区'
165 }, 165 },
  166 + {
  167 + label: '芙蓉区',
  168 + value: '芙蓉区'
  169 + },
166 { 170 {
167 label: '天心区', 171 label: '天心区',
168 value: '天心区' 172 value: '天心区'
@@ -190,10 +194,6 @@ const dropdownOptions = ref([ @@ -190,10 +194,6 @@ const dropdownOptions = ref([
190 { 194 {
191 label: '宁乡市', 195 label: '宁乡市',
192 value: '宁乡市' 196 value: '宁乡市'
193 - },  
194 - {  
195 - label: '芙蓉区',  
196 - value: '芙蓉区'  
197 } 197 }
198 ], [{ 198 ], [{
199 label: '暂未开放', 199 label: '暂未开放',
garbage-removal/src/pages/order-info/order-driver/detail/index.vue
@@ -45,14 +45,14 @@ @@ -45,14 +45,14 @@
45 </view> 45 </view>
46 </view> 46 </view>
47 47
48 - 48 +
49 <view class="order-detail-container-header-item" v-for="(disposal,index) in dataGram.disposalSites"> 49 <view class="order-detail-container-header-item" v-for="(disposal,index) in dataGram.disposalSites">
50 <view> 50 <view>
51 <text class="order-detail-container-header-title" v-if="index == 0" >处置场地:</text> 51 <text class="order-detail-container-header-title" v-if="index == 0" >处置场地:</text>
52 <text class="order-detail-container-header-title" v-else >&emsp;&emsp;&emsp;&emsp;&emsp;</text> 52 <text class="order-detail-container-header-title" v-else >&emsp;&emsp;&emsp;&emsp;&emsp;</text>
53 </view> 53 </view>
54 <view class="order-detail-container-header-content" style="text-decoration: underline" @click.stop="handlerJumpOtherApp(disposal.latitude, disposal.longitude, dataGram.garCoordinate)"> 54 <view class="order-detail-container-header-content" style="text-decoration: underline" @click.stop="handlerJumpOtherApp(disposal.latitude, disposal.longitude, dataGram.garCoordinate)">
55 - <text>{{ disposal.addrStr }}</text> 55 + <text>{{ disposal.addrStr }}</text>
56 </view> 56 </view>
57 </view> 57 </view>
58 58
@@ -90,7 +90,7 @@ @@ -90,7 +90,7 @@
90 <view class="order-detail-container-box-card"> 90 <view class="order-detail-container-box-card">
91 <view class="order-detail-container-header-card-title"> 91 <view class="order-detail-container-header-card-title">
92 <view class="order-detail-container-header-card-uicon"></view> 92 <view class="order-detail-container-header-card-uicon"></view>
93 - 订单人员 93 + 订单信息
94 </view> 94 </view>
95 <!-- <view class="order-detail-container-header-item"> 95 <!-- <view class="order-detail-container-header-item">
96 <text class="order-detail-container-header-title">订单时间:</text> 96 <text class="order-detail-container-header-title">订单时间:</text>
@@ -152,12 +152,12 @@ @@ -152,12 +152,12 @@
152 <view v-for="group in putOnImagesGrouped" :key="group.index" class="image-group"> 152 <view v-for="group in putOnImagesGrouped" :key="group.index" class="image-group">
153 <view class="image-group-header"> 153 <view class="image-group-header">
154 <view class="image-group-title">{{ group.carName}}第 {{ group.index }} 趟</view> 154 <view class="image-group-title">{{ group.carName}}第 {{ group.index }} 趟</view>
155 - <!-- 根据group.index与真实发车数比较显示状态 --> 155 + <!-- 根据group.carStatus显示状态 -->
156 <view class="car-status" :class="{ 156 <view class="car-status" :class="{
157 - 'in-transit': isInTransit(group.index),  
158 - 'completed': isCompleted(group.index)  
159 - }">  
160 - {{ getStatusText(group.index) }} 157 + 'in-transit': group.carStatus === '0',
  158 + 'completed': group.carStatus === '1' || group.carStatus === '2'
  159 + }">
  160 + {{ (group.carStatus === '1'||group.carStatus === '2') ? '已运完' : '正在清运' }}
161 </view> 161 </view>
162 </view> 162 </view>
163 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20" 163 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20"
@@ -352,32 +352,40 @@ const handleEvaluateDetail = (orderId, userType) =&gt; { @@ -352,32 +352,40 @@ const handleEvaluateDetail = (orderId, userType) =&gt; {
352 const selectClick = (index) => { 352 const selectClick = (index) => {
353 currentCancelName.value = index.name; 353 currentCancelName.value = index.name;
354 } 354 }
  355 +
355 const handleOrderDetail = (orderId) => { 356 const handleOrderDetail = (orderId) => {
356 queryOrderDetail(orderId).then(res => { 357 queryOrderDetail(orderId).then(res => {
357 dataGram.value = res.data.data; 358 dataGram.value = res.data.data;
358 currentImages.value = res.data.data.currentImages.map(item => { 359 currentImages.value = res.data.data.currentImages.map(item => {
359 return { url: import.meta.env.VITE_BASE_URL + item}; 360 return { url: import.meta.env.VITE_BASE_URL + item};
360 }); 361 });
361 - 362 +
362 putOnImages.value = res.data.data.putOnImages.map(item => { 363 putOnImages.value = res.data.data.putOnImages.map(item => {
363 let processedItem = item; 364 let processedItem = item;
364 let carName = ''; 365 let carName = '';
365 - 366 + let carStatus = '';
  367 +
366 // 提取name后面的字符串作为carName并从item中移除 368 // 提取name后面的字符串作为carName并从item中移除
367 if (item.includes('name')) { 369 if (item.includes('name')) {
368 const nameIndex = item.indexOf('name'); 370 const nameIndex = item.indexOf('name');
369 carName = item.substring(nameIndex + 4); 371 carName = item.substring(nameIndex + 4);
370 372
  373 + // 检查carName末尾是否包含状态值(0或1)
  374 + if (carName.endsWith('0') || carName.endsWith('1') || carName.endsWith('2')) {
  375 + carStatus = carName.slice(-1);
  376 + carName = carName.slice(0, -1);
  377 + }
  378 +
371 processedItem = item.substring(0, nameIndex); 379 processedItem = item.substring(0, nameIndex);
372 } 380 }
373 -  
374 - // 保持原有逻辑不变,但添加carName到返回对象 381 +
  382 + // 保持原有逻辑不变,但添加carName和carStatus到返回对象
375 const newItem = processedItem.substring(0, processedItem.length - 6); 383 const newItem = processedItem.substring(0, processedItem.length - 6);
376 const newIndex = processedItem.substring(processedItem.length - 6); 384 const newIndex = processedItem.substring(processedItem.length - 6);
377 - return { url: import.meta.env.VITE_BASE_URL + newItem, newIndex, carName }; 385 + return { url: import.meta.env.VITE_BASE_URL + newItem, newIndex, carName, carStatus };
378 }); 386 });
379 387
380 - 388 +
381 // 按照newIndex升序排序 389 // 按照newIndex升序排序
382 putOnImages.value.sort((a, b) => { 390 putOnImages.value.sort((a, b) => {
383 return parseInt(a.newIndex) - parseInt(b.newIndex); 391 return parseInt(a.newIndex) - parseInt(b.newIndex);
@@ -403,7 +411,8 @@ const handleOrderDetail = (orderId) =&gt; { @@ -403,7 +411,8 @@ const handleOrderDetail = (orderId) =&gt; {
403 putOnImagesGrouped.value = Object.keys(newGroupedImages).map(key => ({ 411 putOnImagesGrouped.value = Object.keys(newGroupedImages).map(key => ({
404 index: key, 412 index: key,
405 images: newGroupedImages[key], 413 images: newGroupedImages[key],
406 - carName: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carName : '' 414 + carName: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carName : '',
  415 + carStatus: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carStatus : ''
407 })); 416 }));
408 putDownImages.value = res.data.data.putDownImages.map(item => { 417 putDownImages.value = res.data.data.putDownImages.map(item => {
409 return { url: import.meta.env.VITE_BASE_URL + item }; 418 return { url: import.meta.env.VITE_BASE_URL + item };
garbage-removal/src/pages/order-info/order-other/detail/index.vue
@@ -136,7 +136,7 @@ @@ -136,7 +136,7 @@
136 </view> 136 </view>
137 <!-- 车辆信息 --> 137 <!-- 车辆信息 -->
138 138
139 - <view class="order-detail-container-box-card vehicle-section" v-if="userType !== '用户'"> 139 + <view class="order-detail-container-box-card vehicle-section" v-if="dataGram.garOrderHandlerStatus !== 3">
140 <view class="section-header"> 140 <view class="section-header">
141 <view class="header-icon-bar"></view> 141 <view class="header-icon-bar"></view>
142 <u-icon name="car" size="22" color="#fff" style="margin-right: 10rpx;"></u-icon> 142 <u-icon name="car" size="22" color="#fff" style="margin-right: 10rpx;"></u-icon>
@@ -150,9 +150,31 @@ @@ -150,9 +150,31 @@
150 <text class="summary-value">{{ realCarCount }}</text> 150 <text class="summary-value">{{ realCarCount }}</text>
151 <text class="summary-unit">次</text> 151 <text class="summary-unit">次</text>
152 </view> 152 </view>
  153 + <view v-if="userType === '用户'" class="reduce-trip-section">
  154 + <text class="reduce-label">减少发车次数:</text>
  155 + <view class="right-controls">
  156 + <u-number-box
  157 + v-model="reduceTripCount"
  158 + :min="1"
  159 + :max="realCarCount - 1"
  160 + integer
  161 + buttonSize="30"
  162 + inputWidth="50"
  163 + style="margin: 0 20rpx;">
  164 + </u-number-box>
  165 + <u-button
  166 + type="primary"
  167 + size="mini"
  168 + @click="handleReduceTrips"
  169 + :disabled="reduceTripCount <= 0 || realCarCount <= 1"
  170 + style="background-color: #19a97c; max-width: 120rpx; font-size: 20rpx; padding: 0 10rpx;">
  171 + 确认减少
  172 + </u-button>
  173 + </view>
  174 + </view>
153 </view> 175 </view>
154 176
155 - <view class="vehicle-info-card" v-if="dataGram.garCarInfoList && dataGram.garCarInfoList.length > 0"> 177 + <view class="vehicle-info-card" v-if="dataGram.garCarInfoList && dataGram.garCarInfoList.length > 0 &&userType !== '用户'">
156 <view class="card-header"> 178 <view class="card-header">
157 <u-icon name="file-text" size="18" color="#19a97c"></u-icon> 179 <u-icon name="file-text" size="18" color="#19a97c"></u-icon>
158 <text class="card-title">车辆类型详情</text> 180 <text class="card-title">车辆类型详情</text>
@@ -173,7 +195,7 @@ @@ -173,7 +195,7 @@
173 </view> 195 </view>
174 </view> 196 </view>
175 197
176 - <view class="handler-list-card" > 198 + <view class="handler-list-card" v-if=" userType !== '用户'">
177 <view class="card-header"> 199 <view class="card-header">
178 <u-icon name="list" size="18" color="#19a97c"></u-icon> 200 <u-icon name="list" size="18" color="#19a97c"></u-icon>
179 <text class="card-title">处理人员信息</text> 201 <text class="card-title">处理人员信息</text>
@@ -219,9 +241,10 @@ @@ -219,9 +241,10 @@
219 <view class="section-header"> 241 <view class="section-header">
220 <view class="header-icon-bar"></view> 242 <view class="header-icon-bar"></view>
221 <u-icon name="account" size="22" color="#fff" style="margin-right: 8rpx;"></u-icon> 243 <u-icon name="account" size="22" color="#fff" style="margin-right: 8rpx;"></u-icon>
222 - <text class="header-title">订单人员</text> 244 + <text class="header-title">订单信息</text>
223 </view> 245 </view>
224 246
  247 +
225 <view class="info-item"> 248 <view class="info-item">
226 <view class="info-label"> 249 <view class="info-label">
227 <u-icon name="clock" size="16" color="#19a97c" style="margin-right: 8rpx;"></u-icon> 250 <u-icon name="clock" size="16" color="#19a97c" style="margin-right: 8rpx;"></u-icon>
@@ -257,6 +280,29 @@ @@ -257,6 +280,29 @@
257 280
258 <view class="info-item"> 281 <view class="info-item">
259 <view class="info-label"> 282 <view class="info-label">
  283 + <u-icon name="map" size="16" color="#19a97c" style="margin-right: 8rpx;"></u-icon>
  284 + <text>处理场所:</text>
  285 + </view>
  286 + <!-- 修改后 -->
  287 + <view class="info-content" v-if="selectedDisposalSites.length > 0" style="flex-direction: column; align-items: flex-start;">
  288 + <view v-for="(site, index) in selectedDisposalSites" :key="index" style="margin-bottom: 15rpx; width: 100%;">
  289 + <text class="content-text">{{ site.companyName }}</text>
  290 + <view v-if="site.contactName" style="margin-top: 5rpx;">
  291 + <text class="content-text">联系人: {{ site.contactName }}</text>
  292 + </view>
  293 + <!-- 修改后 -->
  294 + <view v-if="site.contactPhone" style="margin-top: 5rpx; display: flex; align-items: center;">
  295 + <text style="flex: 1;">联系电话: {{ site.contactPhone }}</text>
  296 + <view style="margin-left: 10rpx;" v-if="dataGram.handleFlag" @click="handleContactClick(site.contactPhone)">
  297 + <u-icon name="phone-fill" size="20" color="#19a97c"></u-icon>
  298 + </view>
  299 + </view>
  300 + </view>
  301 + </view>
  302 + </view>
  303 +
  304 + <view class="info-item">
  305 + <view class="info-label">
260 <u-icon name="file-text" size="16" color="#19a97c" style="margin-right: 8rpx;"></u-icon> 306 <u-icon name="file-text" size="16" color="#19a97c" style="margin-right: 8rpx;"></u-icon>
261 <text>备注:</text> 307 <text>备注:</text>
262 </view> 308 </view>
@@ -287,10 +333,10 @@ @@ -287,10 +333,10 @@
287 <view class="image-group-header"> 333 <view class="image-group-header">
288 <view class="image-group-title">{{ group.carName}}第 {{ group.index }} 趟</view> 334 <view class="image-group-title">{{ group.carName}}第 {{ group.index }} 趟</view>
289 <view class="car-status" :class="{ 335 <view class="car-status" :class="{
290 - 'in-transit': isInTransit(group.index),  
291 - 'completed': isCompleted(group.index)  
292 - }">  
293 - {{ getStatusText(group.index) }} 336 + 'in-transit': group.carStatus === '0',
  337 + 'completed': group.carStatus === '1' || group.carStatus === '2'
  338 + }">
  339 + {{ (group.carStatus === '1'||group.carStatus === '2') ? '已运完' : '正在清运' }}
294 </view> 340 </view>
295 </view> 341 </view>
296 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20" 342 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20"
@@ -453,6 +499,7 @@ const carCount = ref(null) @@ -453,6 +499,7 @@ const carCount = ref(null)
453 const tel = ref(null) 499 const tel = ref(null)
454 const selectedHandlerTel = ref("") 500 const selectedHandlerTel = ref("")
455 const realCarCount = ref(null) 501 const realCarCount = ref(null)
  502 +const reduceTripCount = ref(1) // 要减少的发车次数
456 const store = useMainStore(); 503 const store = useMainStore();
457 const userType = computed(() => store.userType) 504 const userType = computed(() => store.userType)
458 const dataGram = ref(); 505 const dataGram = ref();
@@ -475,6 +522,7 @@ const selectedHandlerTels = ref(&quot;&quot;) @@ -475,6 +522,7 @@ const selectedHandlerTels = ref(&quot;&quot;)
475 const garCarTypeList = ref([]) 522 const garCarTypeList = ref([])
476 const driverAssigned = ref(false); // 添加这行,跟踪驾驶员是否已分配 523 const driverAssigned = ref(false); // 添加这行,跟踪驾驶员是否已分配
477 const disposalAssigned = ref(false); // 添加这行,跟踪处置场所是否已分配 524 const disposalAssigned = ref(false); // 添加这行,跟踪处置场所是否已分配
  525 +const selectedDisposalSites = ref([]);
478 // 新增:用于存储待分配的驾驶员列表 526 // 新增:用于存储待分配的驾驶员列表
479 const pendingDriverAssignments = ref({}) 527 const pendingDriverAssignments = ref({})
480 528
@@ -547,6 +595,37 @@ const list = computed(() =&gt; { @@ -547,6 +595,37 @@ const list = computed(() =&gt; {
547 return reason 595 return reason
548 }) 596 })
549 597
  598 +const handleReduceTrips = () => {
  599 + if (!reduceTripCount.value || reduceTripCount.value <= 0) {
  600 + uni.$u.toast('请输入有效的减少次数');
  601 + return;
  602 + }
  603 +
  604 + if (realCarCount.value <= reduceTripCount.value) {
  605 + uni.$u.toast('减少次数不能超过当前总次数');
  606 + return;
  607 + }
  608 +
  609 + // 调用接口,传递负数表示减少
  610 + updateGarRealCarCount(orderId.value, -reduceTripCount.value)
  611 + .then(res => {
  612 + if (res.data.success) {
  613 + uni.$u.toast(`减少${reduceTripCount.value}次成功!`);
  614 + // 刷新订单详情
  615 + handleOrderDetail(orderId.value);
  616 + refreshOrderData();
  617 + // 重置减少次数
  618 + reduceTripCount.value = 1;
  619 + } else {
  620 + uni.$u.toast(`减少次数失败!`);
  621 + }
  622 + })
  623 + .catch(err => {
  624 + uni.$u.toast('减少次数请求失败');
  625 + console.error('减少次数失败:', err);
  626 + });
  627 +}
  628 +
550 const isDriverAssigned = computed(() => { 629 const isDriverAssigned = computed(() => {
551 // 检查是否有分配的驾驶员 630 // 检查是否有分配的驾驶员
552 return handlerList.value && handlerList.value.length > 0; 631 return handlerList.value && handlerList.value.length > 0;
@@ -914,22 +993,57 @@ const handleOrderDetail = (orderId) =&gt; { @@ -914,22 +993,57 @@ const handleOrderDetail = (orderId) =&gt; {
914 }; 993 };
915 }); 994 });
916 995
  996 + // 同时调用queryDisposalDispatch接口获取处理场所信息
  997 + queryDisposalDispatch(orderId).then(disposalRes => {
  998 + if (disposalRes.data.success && disposalRes.data.data && disposalRes.data.data.length > 0) {
  999 + // 根据实际返回数据结构提取处理场所信息,只显示选中的联系人
  1000 + selectedDisposalSites.value = disposalRes.data.data
  1001 + .map(site => {
  1002 + // 筛选出personnelInfo中checked为true的联系人
  1003 + const selectedPerson = site.personnelInfo && site.personnelInfo.length > 0 ?
  1004 + site.personnelInfo.find(person => person.checked) : null;
  1005 +
  1006 + return {
  1007 + companyName: site.garOrderDisposalCompanyName,
  1008 + contactName: selectedPerson ? selectedPerson.personName : '',
  1009 + contactPhone: selectedPerson ? selectedPerson.tel : ''
  1010 + };
  1011 + })
  1012 + // 过滤掉没有选中联系人的处理场所
  1013 + .filter(site => site.contactName && site.contactPhone);
  1014 +
  1015 + // 设置已分配状态
  1016 + disposalAssigned.value = selectedDisposalSites.value.length > 0;
  1017 + console.log('从queryDisposalDispatch获取的处理场所信息:', selectedDisposalSites.value);
  1018 + } else {
  1019 + selectedDisposalSites.value = [];
  1020 + disposalAssigned.value = false;
  1021 + }
  1022 + });
  1023 +
917 putOnImages.value = res.data.data.putOnImages.map(item => { 1024 putOnImages.value = res.data.data.putOnImages.map(item => {
918 let processedItem = item; 1025 let processedItem = item;
919 let carName = ''; 1026 let carName = '';
  1027 + let carStatus = '';
920 1028
921 // 提取name后面的字符串作为carName并从item中移除 1029 // 提取name后面的字符串作为carName并从item中移除
922 if (item.includes('name')) { 1030 if (item.includes('name')) {
923 const nameIndex = item.indexOf('name'); 1031 const nameIndex = item.indexOf('name');
924 carName = item.substring(nameIndex + 4); 1032 carName = item.substring(nameIndex + 4);
925 1033
  1034 + // 检查carName末尾是否包含状态值(0或1)
  1035 + if (carName.endsWith('0') || carName.endsWith('1') || carName.endsWith('2')) {
  1036 + carStatus = carName.slice(-1);
  1037 + carName = carName.slice(0, -1);
  1038 + }
  1039 +
926 processedItem = item.substring(0, nameIndex); 1040 processedItem = item.substring(0, nameIndex);
927 } 1041 }
928 1042
929 - // 保持原有逻辑不变,但添加carName到返回对象 1043 + // 保持原有逻辑不变,但添加carName和carStatus到返回对象
930 const newItem = processedItem.substring(0, processedItem.length - 6); 1044 const newItem = processedItem.substring(0, processedItem.length - 6);
931 const newIndex = processedItem.substring(processedItem.length - 6); 1045 const newIndex = processedItem.substring(processedItem.length - 6);
932 - return { url: import.meta.env.VITE_BASE_URL + newItem, newIndex, carName }; 1046 + return { url: import.meta.env.VITE_BASE_URL + newItem, newIndex, carName, carStatus };
933 }); 1047 });
934 1048
935 // 按照newIndex升序排序 1049 // 按照newIndex升序排序
@@ -957,7 +1071,8 @@ const handleOrderDetail = (orderId) =&gt; { @@ -957,7 +1071,8 @@ const handleOrderDetail = (orderId) =&gt; {
957 putOnImagesGrouped.value = Object.keys(newGroupedImages).map(key => ({ 1071 putOnImagesGrouped.value = Object.keys(newGroupedImages).map(key => ({
958 index: key, 1072 index: key,
959 images: newGroupedImages[key], 1073 images: newGroupedImages[key],
960 - carName: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carName : '' 1074 + carName: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carName : '',
  1075 + carStatus: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carStatus : ''
961 })); 1076 }));
962 console.log('putOnImagesGrouped.value:', putOnImagesGrouped.value); 1077 console.log('putOnImagesGrouped.value:', putOnImagesGrouped.value);
963 putDownImages.value = res.data.data.putDownImages.map(item => { 1078 putDownImages.value = res.data.data.putDownImages.map(item => {
@@ -1157,10 +1272,21 @@ const handleDisposalDispatchConfirm = (val) =&gt; { @@ -1157,10 +1272,21 @@ const handleDisposalDispatchConfirm = (val) =&gt; {
1157 garOrderId: orderId.value, 1272 garOrderId: orderId.value,
1158 dispatchList: [] 1273 dispatchList: []
1159 } 1274 }
  1275 +
  1276 + // 新增:存储选中的处理场所信息
  1277 + selectedDisposalSites.value = [];
  1278 +
1160 for (const key in val) { 1279 for (const key in val) {
1161 data.dispatchList.push({ 1280 data.dispatchList.push({
1162 ...val[key] 1281 ...val[key]
1163 }); 1282 });
  1283 +
  1284 + // 新增:提取处理场所信息
  1285 + selectedDisposalSites.value.push({
  1286 + companyName: val[key].companyName,
  1287 + contactName: val[key].personName,
  1288 + contactPhone: val[key].tel
  1289 + });
1164 } 1290 }
1165 console.log(data); 1291 console.log(data);
1166 dispatchDisposalOrders(data).then(res => { 1292 dispatchDisposalOrders(data).then(res => {
@@ -1169,6 +1295,8 @@ const handleDisposalDispatchConfirm = (val) =&gt; { @@ -1169,6 +1295,8 @@ const handleDisposalDispatchConfirm = (val) =&gt; {
1169 // 标记处置场所已分配 1295 // 标记处置场所已分配
1170 disposalAssigned.value = true; 1296 disposalAssigned.value = true;
1171 // 检查是否两个任务都已完成 1297 // 检查是否两个任务都已完成
  1298 + // 立即刷新订单详情以确保分配信息得到保存
  1299 + handleOrderDetail(orderId.value);
1172 } else { 1300 } else {
1173 uni.$u.toast("指定人员失败,请重试") 1301 uni.$u.toast("指定人员失败,请重试")
1174 } 1302 }
@@ -1176,6 +1304,7 @@ const handleDisposalDispatchConfirm = (val) =&gt; { @@ -1176,6 +1304,7 @@ const handleDisposalDispatchConfirm = (val) =&gt; {
1176 }) 1304 })
1177 } 1305 }
1178 1306
  1307 +
1179 const handlerUpdateOrderClick = () => { 1308 const handlerUpdateOrderClick = () => {
1180 carPopupShowFlag.value = true; 1309 carPopupShowFlag.value = true;
1181 // TODO 照搬一键清运得弹窗 1310 // TODO 照搬一键清运得弹窗
@@ -1648,28 +1777,59 @@ $custom-bottom-height: 200rpx; @@ -1648,28 +1777,59 @@ $custom-bottom-height: 200rpx;
1648 1777
1649 /* 发车次数摘要 */ 1778 /* 发车次数摘要 */
1650 .trip-summary-card { 1779 .trip-summary-card {
  1780 + /* 现有的 summary-content 样式保持不变 */
1651 .summary-content { 1781 .summary-content {
1652 display: flex; 1782 display: flex;
1653 align-items: center; 1783 align-items: center;
1654 - padding: 20rpx 15rpx; /* 减小内边距 */ 1784 + padding: 20rpx 15rpx;
1655 background: linear-gradient(90deg, #e8f4f0, #fff); 1785 background: linear-gradient(90deg, #e8f4f0, #fff);
1656 1786
1657 .summary-label { 1787 .summary-label {
1658 color: #666; 1788 color: #666;
1659 - margin-right: 8rpx; /* 减小右边距 */  
1660 - font-size: 24rpx; /* 减小字体大小 */ 1789 + margin-right: 8rpx;
  1790 + font-size: 24rpx;
1661 } 1791 }
1662 1792
1663 .summary-value { 1793 .summary-value {
1664 color: #19a97c; 1794 color: #19a97c;
1665 font-weight: bold; 1795 font-weight: bold;
1666 - font-size: 28rpx; /* 减小字体大小 */  
1667 - margin: 0 4rpx; /* 减小边距 */ 1796 + font-size: 28rpx;
  1797 + margin: 0 4rpx;
1668 } 1798 }
1669 1799
1670 .summary-unit { 1800 .summary-unit {
1671 color: #666; 1801 color: #666;
1672 - font-size: 24rpx; /* 减小字体大小 */ 1802 + font-size: 24rpx;
  1803 + }
  1804 + }
  1805 +
  1806 + /* 添加 reduce-trip-section 的样式 */
  1807 + /* 添加 reduce-trip-section 的样式 */
  1808 + .reduce-trip-section {
  1809 + display: flex;
  1810 + flex-wrap: wrap; /* 允许内容换行 */
  1811 + justify-content: space-between; /* 两端对齐,使右侧控件靠右 */
  1812 + align-items: center;
  1813 + padding: 20rpx 15rpx;
  1814 + border-top: 1rpx solid #e8f4f0;
  1815 +
  1816 + .reduce-label {
  1817 + color: #666;
  1818 + font-size: 24rpx;
  1819 + min-width: 120rpx; /* 固定标签宽度,防止换行 */
  1820 + }
  1821 +
  1822 + /* 右侧控件容器 */
  1823 + .right-controls {
  1824 + display: flex;
  1825 + align-items: center;
  1826 + }
  1827 +
  1828 + /* 为按钮添加样式 */
  1829 + .u-button {
  1830 + max-width: 120rpx; /* 限制按钮最大宽度 */
  1831 + font-size: 20rpx; /* 减小字体大小 */
  1832 + padding: 0 10rpx; /* 调整内边距 */
1673 } 1833 }
1674 } 1834 }
1675 } 1835 }
garbage-removal/src/pages/order/index.vue
@@ -33,12 +33,20 @@ const getOrderCountByType = async (type) =&gt; { @@ -33,12 +33,20 @@ const getOrderCountByType = async (type) =&gt; {
33 } 33 }
34 34
35 onShow(() => { 35 onShow(() => {
36 - // 调用获取订单数量的接口  
37 - getOrderCountByType(0).then(res => {  
38 - // 设置角标显示为实际的订单总数 36 + // 同时获取待清运和清运中订单数量
  37 + Promise.all([
  38 + getOrderCountByType(0), // 待清运
  39 + getOrderCountByType(1) // 清运中
  40 + ]).then(results => {
  41 + // 计算待清运和清运中订单数量之和
  42 + const totalCount = results.reduce((sum, res) => {
  43 + return sum + (res.data.data.total || 0);
  44 + }, 0);
  45 +
  46 + // 设置角标显示为待清运和清运中订单数量之和
39 uni.setTabBarBadge({ 47 uni.setTabBarBadge({
40 index: 1, // 订单tab在tabBar中的索引 48 index: 1, // 订单tab在tabBar中的索引
41 - text: String(res.data.data.total) // 使用实际的订单总数 49 + text: String(totalCount) // 使用实际的订单总数
42 }); 50 });
43 }).catch(error => { 51 }).catch(error => {
44 console.error('获取订单数量失败:', error); 52 console.error('获取订单数量失败:', error);
garbage-removal/src/pages/order/order-disposal/swiper-list-item/index.vue
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 载运量 {{ item.garNowCarCount }} /{{ item.garRealCarCount }} 20 载运量 {{ item.garNowCarCount }} /{{ item.garRealCarCount }}
21 </view> 21 </view>
22 <view v-if="item.garNowCarCount === item.garRealCarCount" class="completion-tip"> 22 <view v-if="item.garNowCarCount === item.garRealCarCount" class="completion-tip">
23 - 全部完成 23 + {{ props.tabIndex === 0 ? '清运完成待确认' : '已完成' }}
24 </view> 24 </view>
25 </view> 25 </view>
26 </view> 26 </view>
garbage-removal/src/pages/order/order-other/index.vue
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 <script setup> 39 <script setup>
40 import { queryOrderMessageCount, queryOrderList } from '@/apis/order.js'; 40 import { queryOrderMessageCount, queryOrderList } from '@/apis/order.js';
41 import { useMainStore } from '@/stores/index.js'; 41 import { useMainStore } from '@/stores/index.js';
42 -import { computed, nextTick, onMounted, ref } from 'vue'; 42 +import { computed, nextTick, onMounted, ref ,onUnmounted} from 'vue';
43 import swiperListItem from './swiper-list-item/index.vue'; 43 import swiperListItem from './swiper-list-item/index.vue';
44 const store = useMainStore(); 44 const store = useMainStore();
45 // 初始化订单类型列表,添加count属性 45 // 初始化订单类型列表,添加count属性
@@ -128,7 +128,18 @@ onMounted(() =&gt; { @@ -128,7 +128,18 @@ onMounted(() =&gt; {
128 // 页面加载后获取所有订单总数 128 // 页面加载后获取所有订单总数
129 getAllOrderCounts(); 129 getAllOrderCounts();
130 }) 130 })
  131 + uni.$on('orderCreated', handleOrderCreated);
131 }) 132 })
  133 +
  134 +const handleOrderCreated = () => {
  135 + // 重新获取所有订单数量
  136 + getAllOrderCounts();
  137 +};
  138 +
  139 +onUnmounted(() => {
  140 + // 移除事件监听
  141 + uni.$off('orderCreated', handleOrderCreated);
  142 +});
132 </script> 143 </script>
133 <style lang="scss" scoped> 144 <style lang="scss" scoped>
134 .order-container { 145 .order-container {
garbage-removal/src/pages/order/order-other/swiper-list-item/index.vue
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 <view style="display: flex;align-items: center;"> 13 <view style="display: flex;align-items: center;">
14 <view v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0" class="right">待清运 </view> 14 <view v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0" class="right">待清运 </view>
15 <view v-if="item.garCancelFlag === 1" class="right">已取消 </view> 15 <view v-if="item.garCancelFlag === 1" class="right">已取消 </view>
16 - <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0" class="right">清运中 </view> 16 + <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0 && item.garNowCarCount !== item.garRealCarCount" class="right">清运中 </view>
17 <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0 && item.garNowCarCount === item.garRealCarCount" class="right">已完成 </view> 17 <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0 && item.garNowCarCount === item.garRealCarCount" class="right">已完成 </view>
18 </view> 18 </view>
19 <view v-if="item.garEvaluateFlag === 0 && userType === '用户'" class="right">待评价 19 <view v-if="item.garEvaluateFlag === 0 && userType === '用户'" class="right">待评价