Commit 62b28cacc9c5c549fad4a6566e31bdf171090fc9

Authored by lichao
1 parent bea22677

提交

garbage-removal/src/apis/order.js
@@ -14,6 +14,58 @@ export async function queryOrderDetail(id) { @@ -14,6 +14,58 @@ export async function queryOrderDetail(id) {
14 return await request.get(`/order/detail/${id}`); 14 return await request.get(`/order/detail/${id}`);
15 } 15 }
16 /** 16 /**
  17 + * @method 新增车辆
  18 + */
  19 +export async function updateGarRealCarCount(orderId, garRealCarCount) {
  20 + return await request.get(`/order/updateGarRealCarCount`, {
  21 + params: {
  22 + orderId,
  23 + garRealCarCount
  24 + }
  25 + });
  26 +}
  27 +
  28 +
  29 +export async function queryErrType() {
  30 + return await request.get(`/order/queryErrType`,{
  31 + });
  32 +}
  33 +
  34 +/**
  35 + * @method 获取司机列表
  36 + */
  37 +export async function getGarOrderMatchHandlers(orderId) {
  38 + return await request.get(`/order/getGarOrderMatchHandlers`, {
  39 + params: {
  40 + orderId
  41 + }
  42 + });
  43 +}
  44 +export async function queryDriverSend() {
  45 + return await request.get(`/order/queryDriverSend`,{
  46 + });
  47 +}
  48 +
  49 +export async function updateDriverSend() {
  50 + return await request.post(`/order/updateDriverSend`, {
  51 + });
  52 +}
  53 +
  54 +export async function sendToDriver(orderId) {
  55 + return await request.post(`/order/sendToDriver`, {
  56 + orderId
  57 + });
  58 +}
  59 +export async function queryCarCode(orderId) {
  60 + return await request.get(`/order/queryCarCode`, {
  61 + params: {
  62 + orderId
  63 + }
  64 + });
  65 +}
  66 +
  67 +
  68 +/**
17 * @method 订单详情 69 * @method 订单详情
18 */ 70 */
19 export async function queryOrderTransportDetail(id) { 71 export async function queryOrderTransportDetail(id) {
@@ -36,6 +88,8 @@ export async function updateOrder(params, config) { @@ -36,6 +88,8 @@ export async function updateOrder(params, config) {
36 return await request.put(`/order/update`, params, config); 88 return await request.put(`/order/update`, params, config);
37 } 89 }
38 90
  91 +
  92 +
39 /** 93 /**
40 * @method 上传图片 94 * @method 上传图片
41 */ 95 */
@@ -103,6 +157,10 @@ export async function queryGarOrderMatchAsk(orderId) { @@ -103,6 +157,10 @@ export async function queryGarOrderMatchAsk(orderId) {
103 return await request.get(`/order/queryGarOrderMatchAsk/${orderId}`); 157 return await request.get(`/order/queryGarOrderMatchAsk/${orderId}`);
104 } 158 }
105 159
  160 +export async function queryGarOrderMatchAsks(orderId) {
  161 + return await request.get(`/order/queryGarOrderMatchAsks/${orderId}`);
  162 +}
  163 +
106 export async function querySiteByTel() { 164 export async function querySiteByTel() {
107 return await request.get(`/order/querySiteByTel`); 165 return await request.get(`/order/querySiteByTel`);
108 } 166 }
@@ -126,3 +184,7 @@ export async function successOrder(data) { @@ -126,3 +184,7 @@ export async function successOrder(data) {
126 export async function queryBadgeByType(type) { 184 export async function queryBadgeByType(type) {
127 return await request.get(`/order/queryBadgeByType/${type}`); 185 return await request.get(`/order/queryBadgeByType/${type}`);
128 } 186 }
  187 +
  188 +export async function queryByCarCode(carCode) {
  189 + return await request.get(`/order/queryByCarCode/${carCode}`);
  190 +}
garbage-removal/src/components/clash-disposal-dispatch/index.vue
1 -  
2 <template> 1 <template>
3 <next-tree 2 <next-tree
4 :changeVerify="changeVerify" 3 :changeVerify="changeVerify"
@@ -8,6 +7,7 @@ @@ -8,6 +7,7 @@
8 :selectParent="selectParent" 7 :selectParent="selectParent"
9 :multiple="multiple" 8 :multiple="multiple"
10 :treeData="filteredTreeData" 9 :treeData="filteredTreeData"
  10 + :ifSearch="false"
11 @cancel="close" 11 @cancel="close"
12 @confirm="onconfirm"> 12 @confirm="onconfirm">
13 <template #topBar> 13 <template #topBar>
@@ -16,8 +16,9 @@ @@ -16,8 +16,9 @@
16 <text class="search-icon">🔍</text> 16 <text class="search-icon">🔍</text>
17 <input 17 <input
18 class="search-input" 18 class="search-input"
19 - placeholder="搜索处置场所负责人姓名"  
20 - v-model="searchText" /> 19 + placeholder="搜索处置场所"
  20 + :value="searchText"
  21 + @input="onSearchInput" />
21 <text 22 <text
22 v-if="searchText" 23 v-if="searchText"
23 class="clear-icon" 24 class="clear-icon"
@@ -28,7 +29,7 @@ @@ -28,7 +29,7 @@
28 </next-tree> 29 </next-tree>
29 </template> 30 </template>
30 31
31 -<script setup>import { nextTick, ref, unref, computed } from 'vue'; 32 +<script setup>import {nextTick, ref, unref, computed, watch} from 'vue';
32 // @ts-ignore 33 // @ts-ignore
33 import nextTree from '../next-tree/next-tree.vue'; 34 import nextTree from '../next-tree/next-tree.vue';
34 35
@@ -63,22 +64,59 @@ const treeData = ref([]) @@ -63,22 +64,59 @@ const treeData = ref([])
63 const nextTreeRef = ref() 64 const nextTreeRef = ref()
64 const searchText = ref('') 65 const searchText = ref('')
65 66
  67 +// 监听 searchText 的变化
  68 +watch(searchText, (newVal, oldVal) => {
  69 + console.log('searchText changed from', oldVal, 'to', newVal);
  70 + if (nextTreeRef.value) {
  71 + // 延迟一点执行,确保 DOM 更新完成
  72 + setTimeout(() => {
  73 + nextTreeRef.value._initTree();
  74 + }, 0);
  75 + }
  76 +});
  77 +
  78 +// 添加搜索输入处理函数
  79 +function onSearchInput(event) {
  80 + console.log('Search input event:', event);
  81 + console.log('Search input value:', event.detail.value);
  82 + searchText.value = event.detail.value
  83 + console.log('Updated searchText:', searchText.value);
  84 +}
  85 +
66 // 添加计算属性用于过滤数据 86 // 添加计算属性用于过滤数据
67 const filteredTreeData = computed(() => { 87 const filteredTreeData = computed(() => {
  88 + console.log('Computing filteredTreeData, searchText:', searchText.value);
68 if (!searchText.value) { 89 if (!searchText.value) {
  90 + console.log('No search text, returning all data');
69 return treeData.value 91 return treeData.value
70 } 92 }
71 93
  94 + const searchLower = searchText.value.toLowerCase()
  95 + console.log('Searching for:', searchLower);
  96 +
72 return treeData.value.map(item => { 97 return treeData.value.map(item => {
73 - const filteredChildren = item.children.filter(child =>  
74 - child.label.toLowerCase().includes(searchText.value.toLowerCase())  
75 - ) 98 + // 检查处置场所名称是否匹配搜索词
  99 + const companyMatch = item.label.toLowerCase().includes(searchLower)
  100 +
  101 + // 如果处置场所匹配,显示所有负责人;否则按原逻辑过滤负责人
  102 + const filteredChildren = companyMatch ?
  103 + item.children :
  104 + item.children.filter(child =>
  105 + child.label.toLowerCase().includes(searchLower)
  106 + )
76 107
77 return { 108 return {
78 ...item, 109 ...item,
79 children: filteredChildren 110 children: filteredChildren
80 } 111 }
81 - }).filter(item => item.children.length > 0) 112 + }).filter(item => {
  113 + // 只保留处置场所名称匹配或有匹配负责人的项
  114 + const companyMatch = item.label.toLowerCase().includes(searchLower)
  115 + const hasMatchingChildren = item.children.length > 0
  116 +
  117 + console.log('Item filter - companyMatch:', companyMatch, 'hasMatchingChildren:', hasMatchingChildren);
  118 + return companyMatch || hasMatchingChildren
  119 + })
82 }) 120 })
83 121
84 function getTitle(checked) { 122 function getTitle(checked) {
garbage-removal/src/components/clash-driver-dispatch/index.vue
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 </next-tree> 27 </next-tree>
28 </template> 28 </template>
29 29
30 -<script setup>import { nextTick, ref, unref, computed } from 'vue'; 30 +<script setup>import {computed, nextTick, ref, unref, watch} from 'vue';
31 // @ts-ignore 31 // @ts-ignore
32 import nextTree from '../next-tree/next-tree.vue'; 32 import nextTree from '../next-tree/next-tree.vue';
33 33
@@ -62,24 +62,49 @@ const treeData = ref([]) @@ -62,24 +62,49 @@ const treeData = ref([])
62 const nextTreeRef = ref() 62 const nextTreeRef = ref()
63 const searchText = ref('') 63 const searchText = ref('')
64 64
  65 +watch(searchText, (newVal, oldVal) => {
  66 + if (nextTreeRef.value) {
  67 + // 延迟一点执行,确保 DOM 更新完成
  68 + setTimeout(() => {
  69 + nextTreeRef.value._initTree();
  70 + }, 0);
  71 + }
  72 +});
  73 +
65 // 添加计算属性用于过滤数据 74 // 添加计算属性用于过滤数据
66 const filteredTreeData = computed(() => { 75 const filteredTreeData = computed(() => {
67 if (!searchText.value) { 76 if (!searchText.value) {
68 return treeData.value 77 return treeData.value
69 } 78 }
70 79
71 - return treeData.value.map(item => {  
72 - const filteredChildren = item.children.filter(child =>  
73 - child.label.toLowerCase().includes(searchText.value.toLowerCase())  
74 - ) 80 + const searchLower = searchText.value.trim().toLowerCase()
  81 +
  82 + // 当有搜索文本时,过滤包含搜索词的节点
  83 + const filtered = treeData.value.map(item => {
  84 + // 过滤子节点(驾驶员)
  85 + const filteredChildren = item.children.filter(child => {
  86 + const match = child.label.toLowerCase().includes(searchLower) ||
  87 + child.name.toLowerCase().includes(searchLower) ||
  88 + (child.tel && child.tel.includes(searchText.value))
  89 + return match
  90 + })
75 91
  92 + // 返回带有过滤后子节点的项
76 return { 93 return {
77 ...item, 94 ...item,
78 children: filteredChildren 95 children: filteredChildren
79 } 96 }
80 - }).filter(item => item.children.length > 0) 97 + }).filter(item => {
  98 + // 只保留有匹配子节点的项或者父节点本身匹配的项
  99 + const hasMatchingChildren = item.children.length > 0
  100 + const parentMatches = item.label.toLowerCase().includes(searchLower) ||
  101 + (item.licensePlateNumber && item.licensePlateNumber.toLowerCase().includes(searchLower))
  102 + return hasMatchingChildren || parentMatches
  103 + })
  104 + return filtered
81 }) 105 })
82 106
  107 +
83 function getTitle(checked) { 108 function getTitle(checked) {
84 return `已选:${checked.length}位驾驶员` 109 return `已选:${checked.length}位驾驶员`
85 } 110 }
garbage-removal/src/manifest.json
@@ -67,18 +67,12 @@ @@ -67,18 +67,12 @@
67 }, 67 },
68 "usingComponents" : true 68 "usingComponents" : true
69 }, 69 },
70 - "h5" : { 70 + "h5" : {
71 "router" : { 71 "router" : {
72 "mode" : "history" 72 "mode" : "history"
73 }, 73 },
74 "sdkConfigs" : { 74 "sdkConfigs" : {
75 - "maps" : {  
76 - "amap" : {  
77 - "key" : "d459b6535916a23c05ade96744cf5d31",  
78 - "securityJsCode" : "22356e0e06fbedc6667519e170f232ae",  
79 - "serviceHost" : ""  
80 - }  
81 - } 75 + "maps" : {}
82 } 76 }
83 }, 77 },
84 "mp-alipay" : { 78 "mp-alipay" : {
garbage-removal/src/pages.json
@@ -162,6 +162,15 @@ @@ -162,6 +162,15 @@
162 "navigationBarBackgroundColor": "#19a97c", 162 "navigationBarBackgroundColor": "#19a97c",
163 "enablePullDownRefresh": false 163 "enablePullDownRefresh": false
164 } 164 }
  165 + }, {
  166 + "path": "order-driver/detail/guest/index",
  167 + "style": {
  168 + "navigationBarTitleText": "订单详情",
  169 + "navigationBarTextStyle": "white",
  170 + "navigationBarBackgroundColor": "#19a97c",
  171 + "enablePullDownRefresh": false,
  172 + "navigationStyle": "custom"
  173 + }
165 },{ 174 },{
166 "path": "order-other/success/index", 175 "path": "order-other/success/index",
167 "style": { 176 "style": {
garbage-removal/src/pages/change-password/index.vue
@@ -136,9 +136,7 @@ const handleChangePassword = () =&gt; { @@ -136,9 +136,7 @@ const handleChangePassword = () =&gt; {
136 // 密码修改成功后,清除本地存储的用户信息并跳转到登录页 136 // 密码修改成功后,清除本地存储的用户信息并跳转到登录页
137 setTimeout(() => { 137 setTimeout(() => {
138 uni.clearStorageSync(); // 清除本地存储的所有信息 138 uni.clearStorageSync(); // 清除本地存储的所有信息
139 - uni.reLaunch({  
140 - url: '/pages/login/index' // 跳转到登录页  
141 - }); 139 + uni.navigateBack();
142 }, 1500); 140 }, 1500);
143 } else { 141 } else {
144 proxy.$u.toast(res.data.msg || "修改失败"); 142 proxy.$u.toast(res.data.msg || "修改失败");
garbage-removal/src/pages/home-info/address/addSite.vue
@@ -166,59 +166,654 @@ const submit = () =&gt; { @@ -166,59 +166,654 @@ const submit = () =&gt; {
166 */ 166 */
167 const chooseAddressDetail = () => { 167 const chooseAddressDetail = () => {
168 console.log('打开地图选择地址'); 168 console.log('打开地图选择地址');
169 - let coordinate = 'gcj02';  
170 - // #ifdef MP-WEIXIN  
171 - uni.chooseLocation({  
172 - type: coordinate,  
173 - success: function (res) {  
174 - if (res.address) {  
175 - addressInfo.addressDetail = res.address + res.name;  
176 - addressInfo.garLongitude = res.longitude  
177 - addressInfo.garLatitude = res.latitude  
178 - addressInfo.garCoordinate = coordinate  
179 - let SecretKey = "DsNi4Hug4POlYLJ8AaloKB6Uob5fvL8l";  
180 - let key = "HNEBZ-PWHLR-M5AWP-WMRT3-XEOHJ-Y2BHY";  
181 - let md5Param = `/ws/geocoder/v1/?key=${key}&location=${res.latitude},${res.longitude}`;  
182 - let locApi = `https://apis.map.qq.com`  
183 - let sig = uni.$u.md5(md5Param + SecretKey)  
184 - uni.request({  
185 - url: locApi + md5Param + "&sig=" + sig,  
186 - method: 'GET',  
187 - success: (res) => {  
188 - let component = res.data.result.address_component;  
189 - if (component.province == "湖南省") {  
190 - addressInfo.addressDetail = addressInfo.addressDetail.replace(component.province + component.city + component.district, "")  
191 - addressInfo.addressArea = component.province + '-' + component.city + '-' + component.district;  
192 - } 169 +
  170 + // 创建选择方式的模态框
  171 + const choiceContainer = document.createElement('div');
  172 + choiceContainer.id = 'choiceContainer';
  173 + choiceContainer.style.cssText = ` position: fixed;
  174 + top: 0;
  175 + left: 0;
  176 + width: 100%;
  177 + height: 100%;
  178 + background: rgba(0, 0, 0, 0.5);
  179 + z-index: 9999;
  180 + display: flex;
  181 + justify-content: center;
  182 + align-items: center;
  183 + `;
  184 +
  185 + const choiceBox = document.createElement('div');
  186 + choiceBox.style.cssText = ` background: white;
  187 + padding: 20px;
  188 + border-radius: 8px;
  189 + text-align: center;
  190 + width: 80%;
  191 + max-width: 300px;
  192 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  193 + `;
  194 +
  195 + const title = document.createElement('h3');
  196 + title.innerText = '请选择地址输入方式';
  197 + title.style.cssText = ` margin-top: 0;
  198 + color: #333;
  199 + font-size: 18px;
  200 + `;
  201 +
  202 + const mapBtn = document.createElement('button');
  203 + mapBtn.innerText = '地图选择';
  204 + mapBtn.style.cssText = ` display: block;
  205 + width: 100%;
  206 + padding: 12px;
  207 + margin: 10px 0;
  208 + background: #19a97c;
  209 + color: white;
  210 + border: none;
  211 + border-radius: 4px;
  212 + cursor: pointer;
  213 + font-size: 16px;
  214 + transition: background 0.3s;
  215 + `;
  216 +
  217 + mapBtn.onmouseover = function() {
  218 + mapBtn.style.background = '#13966a';
  219 + };
  220 +
  221 + mapBtn.onmouseout = function() {
  222 + mapBtn.style.background = '#19a97c';
  223 + };
  224 +
  225 + const manualBtn = document.createElement('button');
  226 + manualBtn.innerText = '手动输入';
  227 + manualBtn.style.cssText = ` display: block;
  228 + width: 100%;
  229 + padding: 12px;
  230 + margin: 10px 0;
  231 + background: #409eff;
  232 + color: white;
  233 + border: none;
  234 + border-radius: 4px;
  235 + cursor: pointer;
  236 + font-size: 16px;
  237 + transition: background 0.3s;
  238 + `;
  239 +
  240 + manualBtn.onmouseover = function() {
  241 + manualBtn.style.background = '#3388e6';
  242 + };
  243 +
  244 + manualBtn.onmouseout = function() {
  245 + manualBtn.style.background = '#409eff';
  246 + };
  247 +
  248 + const cancelBtn = document.createElement('button');
  249 + cancelBtn.innerText = '取消';
  250 + cancelBtn.style.cssText = ` display: block;
  251 + width: 100%;
  252 + padding: 12px;
  253 + margin: 10px 0;
  254 + background: #ff4d4f;
  255 + color: white;
  256 + border: none;
  257 + border-radius: 4px;
  258 + cursor: pointer;
  259 + font-size: 16px;
  260 + transition: background 0.3s;
  261 + `;
  262 +
  263 + cancelBtn.onmouseover = function() {
  264 + cancelBtn.style.background = '#e63939';
  265 + };
  266 +
  267 + cancelBtn.onmouseout = function() {
  268 + cancelBtn.style.background = '#ff4d4f';
  269 + };
  270 +
  271 + choiceBox.appendChild(title);
  272 + choiceBox.appendChild(mapBtn);
  273 + choiceBox.appendChild(manualBtn);
  274 + choiceBox.appendChild(cancelBtn);
  275 + choiceContainer.appendChild(choiceBox);
  276 + document.body.appendChild(choiceContainer);
  277 +
  278 + // 地图选择按钮事件
  279 + mapBtn.onclick = function() {
  280 + document.body.removeChild(choiceContainer);
  281 +
  282 + // 地图选择方式
  283 + let coordinate = 'gcj02';
  284 +
  285 + // 创建一个模态框来显示地图
  286 + const mapContainer = document.createElement('div');
  287 + mapContainer.id = 'mapContainerWrapper';
  288 + mapContainer.style.cssText = ` position: fixed;
  289 + top: 0;
  290 + left: 0;
  291 + width: 100%;
  292 + height: 100%;
  293 + background: white;
  294 + z-index: 9999;
  295 + `;
  296 +
  297 + // 创建顶部工具栏
  298 + const toolbar = document.createElement('div');
  299 + toolbar.style.cssText = ` position: absolute;
  300 + top: 0;
  301 + left: 0;
  302 + width: 100%;
  303 + height: 50px;
  304 + background: #fff;
  305 + box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  306 + z-index: 10000;
  307 + display: flex;
  308 + align-items: center;
  309 + padding: 0 15px;
  310 + box-sizing: border-box;
  311 + `;
  312 +
  313 + const titleText = document.createElement('div');
  314 + titleText.innerText = '请选择地址';
  315 + titleText.style.cssText = ` flex: 1;
  316 + text-align: center;
  317 + font-size: 16px;
  318 + font-weight: bold;
  319 + color: #333;
  320 + `;
  321 +
  322 + // 创建关闭按钮
  323 + const closeBtn = document.createElement('button');
  324 + closeBtn.innerText = '✕';
  325 + closeBtn.style.cssText = ` width: 30px;
  326 + height: 30px;
  327 + background: #ff4d4f;
  328 + color: white;
  329 + border: none;
  330 + border-radius: 50%;
  331 + cursor: pointer;
  332 + font-size: 16px;
  333 + display: flex;
  334 + align-items: center;
  335 + justify-content: center;
  336 + `;
  337 +
  338 + toolbar.appendChild(titleText);
  339 + toolbar.appendChild(closeBtn);
  340 +
  341 + // 创建地图容器
  342 + const mapElement = document.createElement('div');
  343 + mapElement.id = 'mapContainer';
  344 + mapElement.style.cssText = ` width: 100%;
  345 + height: 100%;
  346 + margin-top: 50px;
  347 + `;
  348 +
  349 + mapContainer.appendChild(toolbar);
  350 + mapContainer.appendChild(mapElement);
  351 + document.body.appendChild(mapContainer);
  352 +
  353 + // 加载腾讯地图API
  354 + const script = document.createElement('script');
  355 + script.src = 'https://map.qq.com/api/js?v=2.exp&key=XICBZ-ALWKT-2KPXZ-VCBL7-XMRYO-2QFS4&callback=initMap';
  356 +
  357 + // 定义全局回调函数
  358 + window.initMap = function() {
  359 + // 初始化地图,设置默认位置为长沙
  360 + const center = new qq.maps.LatLng(28.198265, 112.984353); // 长沙市坐标
  361 + const map = new qq.maps.Map(mapElement, {
  362 + center: center,
  363 + zoom: 15
  364 + });
  365 +
  366 + // 添加点击事件监听器
  367 + qq.maps.event.addListener(map, 'click', function(event) {
  368 + const lat = event.latLng.getLat();
  369 + const lng = event.latLng.getLng();
  370 +
  371 + // 使用腾讯地图逆解析API获取地址信息
  372 + const key = "XICBZ-ALWKT-2KPXZ-VCBL7-XMRYO-2QFS4";
  373 + const url = `https://apis.map.qq.com/ws/geocoder/v1/?key=${key}&location=${lat},${lng}&output=jsonp`;
  374 +
  375 + // 创建script标签实现JSONP
  376 + const jsonpScript = document.createElement('script');
  377 + const callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
  378 +
  379 + // 定义全局回调函数
  380 + window[callbackName] = function(data) {
  381 + // 清理
  382 + delete window[callbackName];
  383 + document.body.removeChild(jsonpScript);
  384 +
  385 + if (data.status === 0) {
  386 + const component = data.result.address_component;
  387 + const address = data.result.address;
  388 +
  389 + // 创建确认选择的模态框
  390 + const confirmContainer = document.createElement('div');
  391 + confirmContainer.style.cssText = ` position: fixed;
  392 + top: 0;
  393 + left: 0;
  394 + width: 100%;
  395 + height: 100%;
  396 + background: rgba(0, 0, 0, 0.5);
  397 + z-index: 10001;
  398 + display: flex;
  399 + justify-content: center;
  400 + align-items: center;
  401 + `;
  402 +
  403 + const confirmBox = document.createElement('div');
  404 + confirmBox.style.cssText = ` background: white;
  405 + padding: 20px;
  406 + border-radius: 8px;
  407 + text-align: center;
  408 + width: 80%;
  409 + max-width: 300px;
  410 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  411 + `;
  412 +
  413 + const confirmTitle = document.createElement('h3');
  414 + confirmTitle.innerText = '确认地址';
  415 + confirmTitle.style.cssText = ` margin-top: 0;
  416 + color: #333;
  417 + `;
  418 +
  419 + const confirmText = document.createElement('p');
  420 + confirmText.innerText = address;
  421 + confirmText.style.cssText = ` color: #666;
  422 + font-size: 14px;
  423 + line-height: 1.5;
  424 + margin: 10px 0;
  425 + `;
  426 +
  427 + const confirmBtn = document.createElement('button');
  428 + confirmBtn.innerText = '确认';
  429 + confirmBtn.style.cssText = ` display: inline-block;
  430 + width: 45%;
  431 + padding: 10px;
  432 + margin: 5px;
  433 + background: #19a97c;
  434 + color: white;
  435 + border: none;
  436 + border-radius: 4px;
  437 + cursor: pointer;
  438 + font-size: 14px;
  439 + `;
  440 +
  441 + const cancelConfirmBtn = document.createElement('button');
  442 + cancelConfirmBtn.innerText = '取消';
  443 + cancelConfirmBtn.style.cssText = ` display: inline-block;
  444 + width: 45%;
  445 + padding: 10px;
  446 + margin: 5px;
  447 + background: #ff4d4f;
  448 + color: white;
  449 + border: none;
  450 + border-radius: 4px;
  451 + cursor: pointer;
  452 + font-size: 14px;
  453 + `;
  454 +
  455 + confirmBox.appendChild(confirmTitle);
  456 + confirmBox.appendChild(confirmText);
  457 + confirmBox.appendChild(confirmBtn);
  458 + confirmBox.appendChild(cancelConfirmBtn);
  459 + confirmContainer.appendChild(confirmBox);
  460 + document.body.appendChild(confirmContainer);
  461 +
  462 + // 确认按钮事件
  463 + confirmBtn.onclick = function() {
  464 + addressInfo.garLongitude = lng;
  465 + addressInfo.garLatitude = lat;
  466 + addressInfo.garCoordinate = coordinate;
  467 +
  468 + if (component.province == "湖南省") {
  469 + addressInfo.addressDetail = address.replace(component.province + component.city + component.district, "");
  470 + addressInfo.addressArea = component.province + '-' + component.city + '-' + component.district;
  471 + } else {
  472 + addressInfo.addressDetail = address;
  473 + }
  474 +
  475 + // 关闭所有模态框
  476 + document.body.removeChild(confirmContainer);
  477 + document.body.removeChild(mapContainer);
  478 + // 清理全局函数
  479 + delete window.initMap;
  480 + };
  481 +
  482 + // 取消确认按钮事件
  483 + cancelConfirmBtn.onclick = function() {
  484 + document.body.removeChild(confirmContainer);
  485 + };
  486 + } else {
  487 + // 创建错误提示的模态框
  488 + const errorContainer = document.createElement('div');
  489 + errorContainer.style.cssText = ` position: fixed;
  490 + top: 0;
  491 + left: 0;
  492 + width: 100%;
  493 + height: 100%;
  494 + background: rgba(0, 0, 0, 0.5);
  495 + z-index: 10001;
  496 + display: flex;
  497 + justify-content: center;
  498 + align-items: center;
  499 + `;
  500 +
  501 + const errorBox = document.createElement('div');
  502 + errorBox.style.cssText = ` background: white;
  503 + padding: 20px;
  504 + border-radius: 8px;
  505 + text-align: center;
  506 + width: 80%;
  507 + max-width: 300px;
  508 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  509 + `;
  510 +
  511 + const errorTitle = document.createElement('h3');
  512 + errorTitle.innerText = '提示';
  513 + errorTitle.style.cssText = ` margin-top: 0;
  514 + color: #333;
  515 + `;
  516 +
  517 + const errorText = document.createElement('p');
  518 + errorText.innerText = '地址解析失败,请重新选择';
  519 + errorText.style.cssText = ` color: #666;
  520 + font-size: 14px;
  521 + margin: 10px 0;
  522 + `;
  523 +
  524 + const okBtn = document.createElement('button');
  525 + okBtn.innerText = '确定';
  526 + okBtn.style.cssText = ` display: inline-block;
  527 + width: 100%;
  528 + padding: 10px;
  529 + margin: 5px 0;
  530 + background: #409eff;
  531 + color: white;
  532 + border: none;
  533 + border-radius: 4px;
  534 + cursor: pointer;
  535 + font-size: 14px;
  536 + `;
  537 +
  538 + errorBox.appendChild(errorTitle);
  539 + errorBox.appendChild(errorText);
  540 + errorBox.appendChild(okBtn);
  541 + errorContainer.appendChild(errorBox);
  542 + document.body.appendChild(errorContainer);
  543 +
  544 + // 确定按钮事件
  545 + okBtn.onclick = function() {
  546 + document.body.removeChild(errorContainer);
  547 + };
  548 + }
  549 + };
  550 +
  551 + // 设置错误处理
  552 + jsonpScript.onerror = function() {
  553 + // 清理
  554 + delete window[callbackName];
  555 + document.body.removeChild(jsonpScript);
  556 +
  557 + // 创建错误提示的模态框
  558 + const errorContainer = document.createElement('div');
  559 + errorContainer.style.cssText = ` position: fixed;
  560 + top: 0;
  561 + left: 0;
  562 + width: 100%;
  563 + height: 100%;
  564 + background: rgba(0, 0, 0, 0.5);
  565 + z-index: 10001;
  566 + display: flex;
  567 + justify-content: center;
  568 + align-items: center;
  569 + `;
  570 +
  571 + const errorBox = document.createElement('div');
  572 + errorBox.style.cssText = ` background: white;
  573 + padding: 20px;
  574 + border-radius: 8px;
  575 + text-align: center;
  576 + width: 80%;
  577 + max-width: 300px;
  578 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  579 + `;
  580 +
  581 + const errorTitle = document.createElement('h3');
  582 + errorTitle.innerText = '提示';
  583 + errorTitle.style.cssText = ` margin-top: 0;
  584 + color: #333;
  585 + `;
  586 +
  587 + const errorText = document.createElement('p');
  588 + errorText.innerText = '地址解析失败,请重新选择';
  589 + errorText.style.cssText = ` color: #666;
  590 + font-size: 14px;
  591 + margin: 10px 0;
  592 + `;
  593 +
  594 + const okBtn = document.createElement('button');
  595 + okBtn.innerText = '确定';
  596 + okBtn.style.cssText = ` display: inline-block;
  597 + width: 100%;
  598 + padding: 10px;
  599 + margin: 5px 0;
  600 + background: #409eff;
  601 + color: white;
  602 + border: none;
  603 + border-radius: 4px;
  604 + cursor: pointer;
  605 + font-size: 14px;
  606 + `;
  607 +
  608 + errorBox.appendChild(errorTitle);
  609 + errorBox.appendChild(errorText);
  610 + errorBox.appendChild(okBtn);
  611 + errorContainer.appendChild(errorBox);
  612 + document.body.appendChild(errorContainer);
  613 +
  614 + // 确定按钮事件
  615 + okBtn.onclick = function() {
  616 + document.body.removeChild(errorContainer);
  617 + };
  618 + };
  619 +
  620 + jsonpScript.src = url + '&callback=' + callbackName;
  621 + document.body.appendChild(jsonpScript);
  622 + });
  623 +
  624 + // 添加当前位置定位功能
  625 + if (navigator.geolocation) {
  626 + navigator.geolocation.getCurrentPosition(
  627 + (position) => {
  628 + const lat = position.coords.latitude;
  629 + const lng = position.coords.longitude;
  630 + const pos = new qq.maps.LatLng(lat, lng);
  631 + map.setCenter(pos);
  632 + },
  633 + (error) => {
  634 + console.log('获取当前位置失败', error);
193 } 635 }
194 - });  
195 - 636 + );
196 } 637 }
197 - },  
198 - fail: function (res) {  
199 - console.log(res);  
200 - }  
201 - });  
202 - // #endif 638 + };
203 639
204 - // #ifdef H5  
205 - uni.chooseLocation({  
206 - type: coordinate,  
207 - latitude:113.081000,  
208 - longitude:28.246000,  
209 - success: function (res) {  
210 - if (res.address) {  
211 - addressInfo.addressDetail = res.address + res.name;  
212 - addressInfo.garLongitude = res.longitude  
213 - addressInfo.garLatitude = res.latitude  
214 - addressInfo.garCoordinate = coordinate 640 + // 关闭按钮事件
  641 + closeBtn.onclick = function() {
  642 + document.body.removeChild(mapContainer);
  643 + // 清理全局函数
  644 + delete window.initMap;
  645 + };
  646 +
  647 + document.body.appendChild(script);
  648 + };
  649 +
  650 + // 手动输入按钮事件
  651 + manualBtn.onclick = function() {
  652 + document.body.removeChild(choiceContainer);
  653 +
  654 + // 创建自定义输入框模态框
  655 + const inputContainer = document.createElement('div');
  656 + inputContainer.style.cssText = ` position: fixed;
  657 + top: 0;
  658 + left: 0;
  659 + width: 100%;
  660 + height: 100%;
  661 + background: rgba(0, 0, 0, 0.5);
  662 + z-index: 9999;
  663 + display: flex;
  664 + justify-content: center;
  665 + align-items: center;
  666 + `;
  667 +
  668 + const inputBox = document.createElement('div');
  669 + inputBox.style.cssText = ` background: white;
  670 + padding: 20px;
  671 + border-radius: 8px;
  672 + text-align: center;
  673 + width: 80%;
  674 + max-width: 300px;
  675 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  676 + `;
  677 +
  678 + const inputTitle = document.createElement('h3');
  679 + inputTitle.innerText = '请输入详细地址';
  680 + inputTitle.style.cssText = ` margin-top: 0;
  681 + color: #333;
  682 + `;
  683 +
  684 + const inputField = document.createElement('input');
  685 + inputField.type = 'text';
  686 + inputField.placeholder = '请输入详细地址';
  687 + inputField.style.cssText = ` width: 100%;
  688 + padding: 10px;
  689 + margin: 10px 0;
  690 + border: 1px solid #ddd;
  691 + border-radius: 4px;
  692 + box-sizing: border-box;
  693 + font-size: 14px;
  694 + `;
  695 +
  696 + const submitBtn = document.createElement('button');
  697 + submitBtn.innerText = '确定';
  698 + submitBtn.style.cssText = ` display: inline-block;
  699 + width: 45%;
  700 + padding: 10px;
  701 + margin: 5px;
  702 + background: #19a97c;
  703 + color: white;
  704 + border: none;
  705 + border-radius: 4px;
  706 + cursor: pointer;
  707 + font-size: 14px;
  708 + `;
  709 +
  710 + const cancelInputBtn = document.createElement('button');
  711 + cancelInputBtn.innerText = '取消';
  712 + cancelInputBtn.style.cssText = ` display: inline-block;
  713 + width: 45%;
  714 + padding: 10px;
  715 + margin: 5px;
  716 + background: #ff4d4f;
  717 + color: white;
  718 + border: none;
  719 + border-radius: 4px;
  720 + cursor: pointer;
  721 + font-size: 14px;
  722 + `;
  723 +
  724 + inputBox.appendChild(inputTitle);
  725 + inputBox.appendChild(inputField);
  726 + inputBox.appendChild(submitBtn);
  727 + inputBox.appendChild(cancelInputBtn);
  728 + inputContainer.appendChild(inputBox);
  729 + document.body.appendChild(inputContainer);
  730 +
  731 + // 确定按钮事件
  732 + submitBtn.onclick = function() {
  733 + const manualAddress = inputField.value.trim();
  734 + if (manualAddress) {
  735 + addressInfo.addressDetail = manualAddress;
  736 + document.body.removeChild(inputContainer);
  737 + } else {
  738 + // 创建提示模态框
  739 + const tipContainer = document.createElement('div');
  740 + tipContainer.style.cssText = ` position: fixed;
  741 + top: 0;
  742 + left: 0;
  743 + width: 100%;
  744 + height: 100%;
  745 + background: rgba(0, 0, 0, 0.5);
  746 + z-index: 10000;
  747 + display: flex;
  748 + justify-content: center;
  749 + align-items: center;
  750 + `;
  751 +
  752 + const tipBox = document.createElement('div');
  753 + tipBox.style.cssText = ` background: white;
  754 + padding: 20px;
  755 + border-radius: 8px;
  756 + text-align: center;
  757 + width: 80%;
  758 + max-width: 300px;
  759 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  760 + `;
  761 +
  762 + const tipText = document.createElement('p');
  763 + tipText.innerText = '请输入详细地址';
  764 + tipText.style.cssText = ` color: #666;
  765 + font-size: 14px;
  766 + margin: 10px 0;
  767 + `;
  768 +
  769 + const okBtn = document.createElement('button');
  770 + okBtn.innerText = '确定';
  771 + okBtn.style.cssText = ` display: inline-block;
  772 + width: 100%;
  773 + padding: 10px;
  774 + margin: 5px 0;
  775 + background: #409eff;
  776 + color: white;
  777 + border: none;
  778 + border-radius: 4px;
  779 + cursor: pointer;
  780 + font-size: 14px;
  781 + `;
  782 +
  783 + tipBox.appendChild(tipText);
  784 + tipBox.appendChild(okBtn);
  785 + tipContainer.appendChild(tipBox);
  786 + document.body.appendChild(tipContainer);
  787 +
  788 + // 确定按钮事件
  789 + okBtn.onclick = function() {
  790 + document.body.removeChild(tipContainer);
  791 + };
215 } 792 }
216 - },  
217 - fail: function (res) {  
218 - console.log(res);  
219 - }  
220 - });  
221 - // #endif 793 + };
  794 +
  795 + // 取消按钮事件
  796 + cancelInputBtn.onclick = function() {
  797 + document.body.removeChild(inputContainer);
  798 + };
  799 +
  800 + // 回车键确认
  801 + inputField.addEventListener('keypress', function(e) {
  802 + if (e.key === 'Enter') {
  803 + submitBtn.click();
  804 + }
  805 + });
  806 +
  807 + // 聚焦到输入框
  808 + setTimeout(() => {
  809 + inputField.focus();
  810 + }, 100);
  811 + };
  812 +
  813 + // 取消按钮事件
  814 + cancelBtn.onclick = function() {
  815 + document.body.removeChild(choiceContainer);
  816 + };
222 } 817 }
223 818
224 onMounted(() => { 819 onMounted(() => {
garbage-removal/src/pages/home-info/clean/company-detail/index.vue
@@ -45,7 +45,7 @@ @@ -45,7 +45,7 @@
45 <view class="company-content-car-info-sub-title">车牌号</view> 45 <view class="company-content-car-info-sub-title">车牌号</view>
46 <view class="company-content-car-info-car-list"> 46 <view class="company-content-car-info-car-list">
47 <view v-for="(item, index) in carList" :key="index" class="company-content-car-info-car-list-item"> 47 <view v-for="(item, index) in carList" :key="index" class="company-content-car-info-car-list-item">
48 - {{ item.carCode }} 48 +<!-- {{ item.carCode }}-->
49 </view> 49 </view>
50 </view> 50 </view>
51 <view class="company-content-remark"> 51 <view class="company-content-remark">
garbage-removal/src/pages/home-info/clean/index.vue
@@ -113,26 +113,26 @@ @@ -113,26 +113,26 @@
113 </view> 113 </view>
114 </view> 114 </view>
115 115
116 - <!-- 添加是否需要装车选项 -->  
117 - <view class="company-clean-container-car-main-content-type">  
118 - <view class="company-clean-container-car-main-content-type-price-area">  
119 - <text style="color: red;">*</text>是否需要装车:  
120 - </view>  
121 - <view  
122 - style="width:100%;display: flex;justify-content: flex-start;align-items: center; ">  
123 - <view style="display: flex; align-items: center;">  
124 - <up-radio-group shape="square" size="34" v-model="paramFrom.needFollowCar"  
125 - placement="row">  
126 - <up-radio activeColor="#19a97c" labelSize="32" iconSize="30"  
127 - :customStyle="{ marginRight: '30rpx' }" label="需要" :name="true">  
128 - </up-radio>  
129 - <up-radio activeColor="#19a97c" labelSize="32" iconSize="30"  
130 - :customStyle="{ marginRight: '30rp' }" label="不需要" :name="false">  
131 - </up-radio>  
132 - </up-radio-group>  
133 - </view>  
134 - </view>  
135 - </view> 116 +<!-- &lt;!&ndash; 添加是否需要装车选项 &ndash;&gt;-->
  117 +<!-- <view class="company-clean-container-car-main-content-type">-->
  118 +<!-- <view class="company-clean-container-car-main-content-type-price-area">-->
  119 +<!-- <text style="color: red;">*</text>是否需要装车:-->
  120 +<!-- </view>-->
  121 +<!-- <view-->
  122 +<!-- style="width:100%;display: flex;justify-content: flex-start;align-items: center; ">-->
  123 +<!-- <view style="display: flex; align-items: center;">-->
  124 +<!-- <up-radio-group shape="square" size="34" v-model="paramFrom.needFollowCar"-->
  125 +<!-- placement="row">-->
  126 +<!-- <up-radio activeColor="#19a97c" labelSize="32" iconSize="30"-->
  127 +<!-- :customStyle="{ marginRight: '30rpx' }" label="需要" :name="true">-->
  128 +<!-- </up-radio>-->
  129 +<!-- <up-radio activeColor="#19a97c" labelSize="32" iconSize="30"-->
  130 +<!-- :customStyle="{ marginRight: '30rp' }" label="不需要" :name="false">-->
  131 +<!-- </up-radio>-->
  132 +<!-- </up-radio-group>-->
  133 +<!-- </view>-->
  134 +<!-- </view>-->
  135 +<!-- </view>-->
136 136
137 137
138 <view v-if="paramFrom.garInCarStore" class="company-in-car-store-box-info"> 138 <view v-if="paramFrom.garInCarStore" class="company-in-car-store-box-info">
garbage-removal/src/pages/home/index.vue
@@ -486,6 +486,7 @@ const queryList = (pageNo, pageSize) =&gt; { @@ -486,6 +486,7 @@ const queryList = (pageNo, pageSize) =&gt; {
486 } 486 }
487 // 查询公司信息 487 // 查询公司信息
488 queryEnterpriseList(query).then(res => { 488 queryEnterpriseList(query).then(res => {
  489 + console.log('获取到的公司列表数据:', res);
489 paging.value.complete(res.data.data.list); 490 paging.value.complete(res.data.data.list);
490 }) 491 })
491 } 492 }
garbage-removal/src/pages/login/code.vue
@@ -16,14 +16,14 @@ @@ -16,14 +16,14 @@
16 :class="{ active: loginType === 'password' }" 16 :class="{ active: loginType === 'password' }"
17 @click="switchLoginType('password')" 17 @click="switchLoginType('password')"
18 > 18 >
19 - 密码登录  
20 - </text>  
21 - <text  
22 - :class="{ active: loginType === 'nickname' }"  
23 - @click="switchLoginType('nickname')"  
24 - >  
25 - 用户名登录 19 + 账号密码登录
26 </text> 20 </text>
  21 +<!-- <text-->
  22 +<!-- :class="{ active: loginType === 'nickname' }"-->
  23 +<!-- @click="switchLoginType('nickname')"-->
  24 +<!-- >-->
  25 +<!-- 账号密码登录-->
  26 +<!-- </text>-->
27 </view> 27 </view>
28 28
29 <!-- 手机号输入 --> 29 <!-- 手机号输入 -->
@@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
33 class="login-input" 33 class="login-input"
34 type="text" 34 type="text"
35 v-model="iphoneNumber" 35 v-model="iphoneNumber"
36 - placeholder="请输入手机号" 36 + placeholder="请输入号"
37 placeholder-class="placeholder-style" 37 placeholder-class="placeholder-style"
38 /> 38 />
39 </view> 39 </view>
@@ -63,7 +63,7 @@ @@ -63,7 +63,7 @@
63 class="login-input" 63 class="login-input"
64 type="text" 64 type="text"
65 v-model="nickname" 65 v-model="nickname"
66 - placeholder="请输入用户名" 66 + placeholder="请输入账号"
67 placeholder-class="placeholder-style" 67 placeholder-class="placeholder-style"
68 /> 68 />
69 </view> 69 </view>
@@ -96,7 +96,7 @@ @@ -96,7 +96,7 @@
96 </view> 96 </view>
97 97
98 <view class="alternative"> 98 <view class="alternative">
99 - <text class="link" @click="toRegister">立即注册</text> 99 +<!-- <text class="link" @click="toRegister">立即注册</text>-->
100 <text class="link" @click="toChangePassword">修改密码</text> 100 <text class="link" @click="toChangePassword">修改密码</text>
101 </view> 101 </view>
102 </view> 102 </view>
@@ -135,7 +135,7 @@ const switchLoginType = (type) =&gt; { @@ -135,7 +135,7 @@ const switchLoginType = (type) =&gt; {
135 135
136 const loginWithUsername = () => { 136 const loginWithUsername = () => {
137 if (!nickname.value) { 137 if (!nickname.value) {
138 - proxy.$u.toast("请输入用户名"); 138 + proxy.$u.toast("请输入手机号");
139 return; 139 return;
140 } 140 }
141 141
@@ -166,7 +166,11 @@ const getCaptcha = () =&gt; { @@ -166,7 +166,11 @@ const getCaptcha = () =&gt; {
166 show.value = false; 166 show.value = false;
167 167
168 sendCode(iphoneNumber.value).then(res => { 168 sendCode(iphoneNumber.value).then(res => {
169 - proxy.$u.toast(res.data.data); 169 + if(res.data.success){
  170 + proxy.$u.toast("验证码已发送!");
  171 + }else {
  172 + proxy.$u.toast(res.data.message);
  173 + }
170 }); 174 });
171 175
172 let interval = setInterval(() => { 176 let interval = setInterval(() => {
@@ -206,10 +210,10 @@ const checkVerifyNum = (code) =&gt; { @@ -206,10 +210,10 @@ const checkVerifyNum = (code) =&gt; {
206 210
207 // 密码登录 211 // 密码登录
208 const loginWithPassword = () => { 212 const loginWithPassword = () => {
209 - if (!proxy.$u.test.mobile(iphoneNumber.value)) {  
210 - proxy.$u.toast("请输入正确的手机号");  
211 - return;  
212 - } 213 + // if (!proxy.$u.test.mobile(iphoneNumber.value)) {
  214 + // proxy.$u.toast("请输入正确的手机号");
  215 + // return;
  216 + // }
213 217
214 if (!password.value) { 218 if (!password.value) {
215 proxy.$u.toast("请输入密码"); 219 proxy.$u.toast("请输入密码");
@@ -302,7 +306,8 @@ const handleLoginSuccess = (res) =&gt; { @@ -302,7 +306,8 @@ const handleLoginSuccess = (res) =&gt; {
302 } 306 }
303 } else { 307 } else {
304 verifyFlag.value = true; 308 verifyFlag.value = true;
305 - uni.$u.toast(res.data.msg); 309 + let errorMessage = res.data.error || res.data.msg || res.data.message || "登录失败";
  310 + uni.$u.toast(errorMessage);
306 } 311 }
307 }; 312 };
308 313
garbage-removal/src/pages/login/index.vue
@@ -31,8 +31,8 @@ @@ -31,8 +31,8 @@
31 31
32 <button @tap="submit" :style="[inputStyle]" class="getCaptcha">登录</button> 32 <button @tap="submit" :style="[inputStyle]" class="getCaptcha">登录</button>
33 <view class="alternative"> 33 <view class="alternative">
34 - <text class="link" @click="toRegister">立即注册</text>  
35 - <text class="link" @click="forgetPassword">忘记密码?</text> 34 +<!-- <text class="link" @click="toRegister">立即注册</text>-->
  35 +<!-- <text class="link" @click="forgetPassword">忘记密码?</text>-->
36 </view> 36 </view>
37 </view> 37 </view>
38 <view class="buttom"> 38 <view class="buttom">
garbage-removal/src/pages/order-info/order-disposal/scan-detail/index.vue
@@ -245,26 +245,7 @@ @@ -245,26 +245,7 @@
245 console.log(res); 245 console.log(res);
246 if (res.data.code == 200) { 246 if (res.data.code == 200) {
247 // 修改提示框,添加跳转到订单页面的选项 247 // 修改提示框,添加跳转到订单页面的选项
248 - uni.showModal({  
249 - title: '提示',  
250 - content: '当前趟次记录完毕!',  
251 - showCancel: true,  
252 - cancelText: '稍后处理',  
253 - confirmText: '立即前往',  
254 - success: function (res) {  
255 - if (res.confirm) {  
256 - // 跳转到订单页面  
257 - uni.redirectTo({  
258 - url: '/pages/order-info/order-disposal/transport-detail/index?garOrderId=' + params.garOrderId  
259 - });  
260 - } else if (res.cancel) {  
261 - // 返回上级页面  
262 - uni.navigateBack({  
263 - delta: 1  
264 - });  
265 - }  
266 - }  
267 - }); 248 + uni.$u.toast("当前趟次记录完毕!")
268 } 249 }
269 }).catch((err) => { 250 }).catch((err) => {
270 uni.$u.toast("当前趟次记录失败") 251 uni.$u.toast("当前趟次记录失败")
garbage-removal/src/pages/order-info/order-driver/detail/guest/index.vue 0 → 100644
  1 +
  2 +<template>
  3 + <view class="order-detail-container" v-if="dataGram != null || dataGram != undefined">
  4 + <view class="order-detail-container-box">
  5 + <view class="order-detail-top">
  6 + <view class="order-detail-top-box">
  7 + <view class="order-detail-top-box-step">
  8 + <u-steps :current="currentStep(dataGram.garOrderHandlerStatus)" dot>
  9 + <u-steps-item title="待清运"></u-steps-item>
  10 + <u-steps-item title="清运中"></u-steps-item>
  11 + <u-steps-item title="已完成"></u-steps-item>
  12 + </u-steps>
  13 + </view>
  14 + </view>
  15 + </view>
  16 +
  17 + <!-- 订单信息 -->
  18 + <view class="order-detail-container-box-card">
  19 + <view class="order-detail-container-header-card-title">
  20 + <view class="order-detail-container-header-card-uicon"></view>
  21 + 订单信息
  22 + </view>
  23 + <view class="order-detail-container-header-item">
  24 + <text class="order-detail-container-header-title">清运地点:</text>
  25 + <view class="order-detail-container-header-content" style="text-decoration: underline">
  26 + <text selectable='true'>{{ dataGram.garOrderAddress + dataGram.garOrderAddressDetails }}</text>
  27 + </view>
  28 + </view>
  29 + <view class="order-detail-container-header-item">
  30 + <text class="order-detail-container-header-title">现场图片:</text>
  31 + <view class="order-detail-container-header-content">
  32 + <u-upload width="180" height="130" :fileList="currentImages" name="3" multiple :maxCount="10"
  33 + :previewFullImage="true" :isReadOnly="true"></u-upload>
  34 + </view>
  35 + </view>
  36 + <view class="order-detail-container-header-item">
  37 + <text class="order-detail-container-header-title">负责单位:</text>
  38 + <view class="order-detail-container-header-content">
  39 + {{ dataGram.garOrderCompanyName }}
  40 + </view>
  41 + </view>
  42 + <view class="order-detail-container-header-item">
  43 + <text class="order-detail-container-header-title">垃圾类型:</text>
  44 + <view class="order-detail-container-header-content">
  45 + {{ dataGram.garOrderTrashType }}
  46 + </view>
  47 + </view>
  48 +
  49 + <view class="order-detail-container-header-item" v-for="(disposal,index) in dataGram.orderDisposalCompanyReports">
  50 + <view>
  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>
  53 + </view>
  54 + <view class="order-detail-container-header-content" style="text-decoration: underline">
  55 + <text>{{ disposal.disposalCompanyName }}</text>
  56 + </view>
  57 + </view>
  58 +
  59 + <view class="order-detail-container-header-item">
  60 + <text class="order-detail-container-header-title">订单号:</text>
  61 + <view class="order-detail-container-header-content">
  62 + <text selectable="true">{{ orderId }}</text>
  63 + </view>
  64 + <!-- 生成二维码 -->
  65 + <view class="order-detail-container-header-qrCode" style="display: flex; align-items: center;">
  66 + <view @click="handleQrCodeClick(orderId)" class="iconfont icon-erweima-xian"></view>
  67 + </view>
  68 + </view>
  69 + </view>
  70 +
  71 + <!-- 车辆信息 -->
  72 + <view class="order-detail-container-box-card">
  73 + <view class="order-detail-container-header-card-title">
  74 + <view class="order-detail-container-header-card-uicon"></view>
  75 + 车辆信息
  76 + </view>
  77 + <view class="order-detail-container-header-item" style="justify-content: space-between;"
  78 + v-for="(item) in dataGram.garCarInfoList" :key="item.garId">
  79 + <text class="order-detail-container-header-title" style="color: #303133;">{{ item.garOrderCarType }}
  80 + </text>
  81 + <view class="order-detail-container-header-content">
  82 + <text class="order-detail-container-header-title">
  83 + {{ cleanStatus(dataGram.garOrderHandlerStatus) }}
  84 + </text>
  85 + </view>
  86 + </view>
  87 + </view>
  88 +
  89 + <!-- 订单记录 -->
  90 + <view class="order-detail-container-box-card">
  91 + <view class="order-detail-container-header-card-title">
  92 + <view class="order-detail-container-header-card-uicon"></view>
  93 + 订单人员
  94 + </view>
  95 + <view class="order-detail-container-header-item">
  96 + <text class="order-detail-container-header-title">预约时间:</text>
  97 + <view class="order-detail-container-header-content">
  98 + {{ dataGram.garOrderAgreementTime }}
  99 + </view>
  100 + </view>
  101 + <view class="order-detail-container-header-item">
  102 + <text class="order-detail-container-header-title">联系电话:</text>
  103 + <view class="order-detail-container-header-content">
  104 + <text selectable="true">{{ dataGram.garOrderContactTel }}</text>
  105 + <view class="icon-box" style="display: flex; align-items: center; justify-content: center;">
  106 + <u-icon name="phone" size="28"
  107 + @click="handleContactClick(dataGram.garOrderContactTel)"></u-icon>
  108 + </view>
  109 + </view>
  110 + </view>
  111 + <view class="order-detail-container-header-item">
  112 + <text class="order-detail-container-header-title">订单人:</text>
  113 + <view class="order-detail-container-header-content">
  114 + {{ dataGram.garOrderContactName }}
  115 + </view>
  116 + </view>
  117 +
  118 + <view class="order-detail-container-header-item">
  119 + <text class="order-detail-container-header-title">备注:</text>
  120 + <view class="order-detail-container-header-content">
  121 + {{ dataGram.garRemark }}
  122 + </view>
  123 + </view>
  124 +
  125 + <view v-if="dataGram.needFollowCar" class="follow-car-notice">
  126 + <text style="color: red;">该订单需要搬运上车</text>
  127 + </view>
  128 + </view>
  129 +
  130 + <!-- 处理信息 -->
  131 + <view class="order-detail-container-box-card">
  132 + <view class="order-detail-container-header-card-title">
  133 + <view class="order-detail-container-header-card-uicon"></view>
  134 + 处理信息
  135 + </view>
  136 + <view v-if="putDownImages.length || putOnImages.length" style="width: 100%;">
  137 + <view class="order-detail-container-header-item">
  138 + <text class="order-detail-container-header-title">服务电话:</text>
  139 + <view class="order-detail-container-header-content">
  140 + {{ dataGram.garOrderCompanyTel }}
  141 + </view>
  142 + </view>
  143 + <view class="order-detail-container-header-item">
  144 + <text class=" order-detail-container-header-title">装车照片:</text>
  145 +
  146 + <view class="order-detail-container-header-content" style="flex-direction: column;">
  147 + <view v-for="group in putOnImagesGrouped" :key="group.index" class="image-group">
  148 + <view class="image-group-header">
  149 + <view class="image-group-title">{{ group.carName}}第 {{ group.index }} 趟</view>
  150 + <!-- 根据group.index与真实发车数比较显示状态 -->
  151 + <view class="car-status" :class="{
  152 + 'in-transit': group.index < dataGram.garCarInfoList.length,
  153 + 'completed': group.index >= dataGram.garCarInfoList.length
  154 + }">
  155 + {{ group.index < dataGram.garCarInfoList.length ? '已运完' : '已运完' }}
  156 + </view>
  157 + </view>
  158 + <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20"
  159 + :previewFullImage="true" :isReadOnly="true"></u-upload>
  160 + </view>
  161 + </view>
  162 + </view>
  163 + </view>
  164 + <view v-else class="empty-image" style="width: 100%; display: flex; justify-content: center; align-items: center;">
  165 + <image class="image-style" style="width: 200rpx; height: 200rpx;" :src="emptyBase64Image"></image>
  166 + </view>
  167 + </view>
  168 + <view class="space-box">{{ spaceStr }}</view>
  169 + </view>
  170 + <view v-if="showUQRcode" class="mask-container" @click="showUQRcode = false">
  171 + <uqrcode :h5SaveIsDownload="true" ref="qrCodeRef" canvas-id="qrcode" :value="qrCodeText"
  172 + :options="{ margin: 10, boxSizing: borderBox }"></uqrcode>
  173 + </view>
  174 + </view>
  175 +</template>
  176 +
  177 +<script setup>import { queryGuestOrderDetail, queryByCarCode } from "@/apis/order.js";
  178 +import { createQrCode } from '@/apis/qrcode.js';
  179 +import uqrcode from '@/components/Sansnn-uQRCode_4.0.6/components/uqrcode/uqrcode.vue';
  180 +import zStatic from '@/components/z-paging/js/z-paging-static';
  181 +import {onLoad, onShow} from '@dcloudio/uni-app';
  182 +import {nextTick, ref} from 'vue';
  183 +
  184 +const dataGram = ref();
  185 +const orderId = ref(null)
  186 +const currentImages = ref([])
  187 +const putOnImages = ref([])
  188 +const putOnImagesGrouped = ref([])
  189 +const putDownImages = ref([])
  190 +const emptyBase64Image = ref(zStatic.base64Empty)
  191 +const showUQRcode = ref(false)
  192 +const spaceStr = ref("")
  193 +const qrCodeRef = ref()
  194 +const qrCodeText = ref()
  195 +
  196 +const createQrCodeLocal = (orderId) => {
  197 + // 获取本地地址拼接订单id
  198 + showUQRcode.value = true;
  199 + const hostname = window.location.hostname;
  200 + const port = window.location.port;
  201 + const protocol = window.location.protocol;
  202 + const localAddress = `${protocol}//${hostname}:${port}`;
  203 + qrCodeText.value = localAddress + "/pages/order-info/order-driver/detail/guest/index?orderId=" + orderId;
  204 +
  205 + // 强制刷新二维码显示
  206 + nextTick(() => {
  207 + if (qrCodeRef.value && typeof qrCodeRef.value.makeQRCode === 'function') {
  208 + qrCodeRef.value.makeQRCode();
  209 + }
  210 + });
  211 +}
  212 +
  213 +// 关闭二维码
  214 +const closeQrCode = () => {
  215 + showUQRcode.value = false;
  216 + qrCodeText.value = '';
  217 +}
  218 +
  219 +// 获取二维码
  220 +const handleQrCodeClick = (orderId) => {
  221 + // 每次点击都重新生成二维码,确保是最新的
  222 + showUQRcode.value = true;
  223 +
  224 + // 微信小程序可用
  225 + // #ifdef MP-WEIXIN
  226 + createQrCode(orderId).then((res) => {
  227 + if (res.data.success) {
  228 + uni.previewImage({
  229 + urls: [res.data.data],
  230 + longPressActions: {
  231 + itemList: ['发送给朋友', '保存图片', '收藏'],
  232 + success: function (res) {
  233 + console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
  234 + },
  235 + fail: function (res) {
  236 + console.log(res);
  237 + }
  238 + }
  239 + })
  240 + }
  241 + })
  242 + // #endif
  243 + // H5
  244 + // #ifdef H5
  245 + createQrCodeLocal(orderId)
  246 + // #endif
  247 +}
  248 +
  249 +const handleOrderDetail = (orderId) => {
  250 + queryGuestOrderDetail(orderId).then(res => {
  251 + dataGram.value = res.data.data;
  252 + currentImages.value = res.data.data.currentImages.map(item => {
  253 + return { url: import.meta.env.VITE_BASE_URL + item};
  254 + });
  255 +
  256 + putOnImages.value = res.data.data.putOnImages.map(item => {
  257 + let processedItem = item;
  258 + let carName = '';
  259 +
  260 + // 提取name后面的字符串作为carName并从item中移除
  261 + if (item.includes('name')) {
  262 + const nameIndex = item.indexOf('name');
  263 + carName = item.substring(nameIndex + 4);
  264 + processedItem = item.substring(0, nameIndex);
  265 + }
  266 +
  267 + // 保持原有逻辑不变,但添加carName到返回对象
  268 + const newItem = processedItem.substring(0, processedItem.length - 6);
  269 + const newIndex = processedItem.substring(processedItem.length - 6);
  270 + return { url: import.meta.env.VITE_BASE_URL + newItem, newIndex, carName };
  271 + });
  272 +
  273 + // 按照newIndex升序排序
  274 + putOnImages.value.sort((a, b) => {
  275 + return parseInt(a.newIndex) - parseInt(b.newIndex);
  276 + });
  277 +
  278 + // 重新组织数据,将相同newIndex的图片放在一起
  279 + const groupedImages = {};
  280 + putOnImages.value.forEach(item => {
  281 + if (!groupedImages[item.newIndex]) {
  282 + groupedImages[item.newIndex] = [];
  283 + }
  284 + groupedImages[item.newIndex].push(item);
  285 + });
  286 +
  287 + // 转换newIndex为1,2,3的连续数字
  288 + const sortedKeys = Object.keys(groupedImages).sort((a, b) => parseInt(a) - parseInt(b));
  289 + const newGroupedImages = {};
  290 + sortedKeys.forEach((key, index) => {
  291 + newGroupedImages[index + 1] = groupedImages[key];
  292 + });
  293 +
  294 + // 转换为数组形式,方便在模板中遍历
  295 + putOnImagesGrouped.value = Object.keys(newGroupedImages).map(key => ({
  296 + index: key,
  297 + images: newGroupedImages[key],
  298 + carName: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carName : ''
  299 + }));
  300 +
  301 + putDownImages.value = res.data.data.putDownImages.map(item => {
  302 + return { url: import.meta.env.VITE_BASE_URL + item };
  303 + });
  304 + })
  305 +}
  306 +
  307 +/**
  308 + * 拨打电话回调
  309 + */
  310 +const handleContactClick = (val) => {
  311 + uni.makePhoneCall({ phoneNumber: val }).then(res => {
  312 + }).catch(err => { });
  313 +}
  314 +
  315 +const handlerJumpOtherApp = (latitude, longitude, garCoordinate) => {
  316 + // 给出提示确定要跳转吗
  317 + uni.showModal({
  318 + title: '提示',
  319 + content: '是否跳转到app定位进行导航?',
  320 + success: function (res) {
  321 + if (res.confirm) {
  322 + uni.openLocation({
  323 + latitude: latitude,
  324 + longitude: longitude,
  325 + success: function () {
  326 + console.log('success');
  327 + }
  328 + });
  329 + }
  330 + }
  331 + })
  332 +}
  333 +
  334 +const currentStep = (step) => {
  335 + if (step > 2) {
  336 + return step - 1;
  337 + }
  338 + return step;
  339 +}
  340 +
  341 +/**
  342 + * 清运状态
  343 + * @param {*} status
  344 + */
  345 +const cleanStatus = (status) => {
  346 + if (dataGram.value.garCancelFlag === 1) {
  347 + return '取消清运';
  348 + }
  349 + switch (status) {
  350 + case 0:
  351 + return '准备清运';
  352 + case 1:
  353 + return '正在清运';
  354 + case 3:
  355 + return '清运完成';
  356 + }
  357 +}
  358 +
  359 +/**
  360 + * 初始化信息
  361 + */
  362 +onLoad((options) => {
  363 + if (options.carCode) {
  364 + // 通过车牌号直接查询订单详情
  365 + queryByCarCode(options.carCode).then(res => {
  366 + if (res.data.success) {
  367 + // 直接设置订单数据,不再需要二次查询
  368 + dataGram.value = res.data.data;
  369 + // 从garCarInfoList中提取订单ID
  370 + if (res.data.data.garCarInfoList && res.data.data.garCarInfoList.length > 0) {
  371 + orderId.value = res.data.data.garCarInfoList[0].garOrderId;
  372 + }
  373 +
  374 + // 处理图片数据
  375 + currentImages.value = res.data.data.currentImages.map(item => {
  376 + return { url: import.meta.env.VITE_BASE_URL + item};
  377 + });
  378 +
  379 + putOnImages.value = res.data.data.putOnImages.map(item => {
  380 + let processedItem = item;
  381 + let carName = '';
  382 +
  383 + // 提取name后面的字符串作为carName并从item中移除
  384 + if (item.includes('name')) {
  385 + const nameIndex = item.indexOf('name');
  386 + carName = item.substring(nameIndex + 4);
  387 + processedItem = item.substring(0, nameIndex);
  388 + }
  389 +
  390 + // 保持原有逻辑不变,但添加carName到返回对象
  391 + const newItem = processedItem.substring(0, processedItem.length - 6);
  392 + const newIndex = processedItem.substring(processedItem.length - 6);
  393 + return { url: import.meta.env.VITE_BASE_URL + newItem, newIndex, carName };
  394 + });
  395 +
  396 + // 按照newIndex升序排序
  397 + putOnImages.value.sort((a, b) => {
  398 + return parseInt(a.newIndex) - parseInt(b.newIndex);
  399 + });
  400 +
  401 + // 重新组织数据,将相同newIndex的图片放在一起
  402 + const groupedImages = {};
  403 + putOnImages.value.forEach(item => {
  404 + if (!groupedImages[item.newIndex]) {
  405 + groupedImages[item.newIndex] = [];
  406 + }
  407 + groupedImages[item.newIndex].push(item);
  408 + });
  409 +
  410 + // 转换newIndex为1,2,3的连续数字
  411 + const sortedKeys = Object.keys(groupedImages).sort((a, b) => parseInt(a) - parseInt(b));
  412 + const newGroupedImages = {};
  413 + sortedKeys.forEach((key, index) => {
  414 + newGroupedImages[index + 1] = groupedImages[key];
  415 + });
  416 +
  417 + // 转换为数组形式,方便在模板中遍历
  418 + putOnImagesGrouped.value = Object.keys(newGroupedImages).map(key => ({
  419 + index: key,
  420 + images: newGroupedImages[key],
  421 + carName: newGroupedImages[key] && newGroupedImages[key].length > 0 ? newGroupedImages[key][0].carName : ''
  422 + }));
  423 +
  424 + putDownImages.value = res.data.data.putDownImages.map(item => {
  425 + return { url: import.meta.env.VITE_BASE_URL + item };
  426 + });
  427 + } else {
  428 + uni.$u.toast('未找到该车牌号对应的订单');
  429 + }
  430 + }).catch(err => {
  431 + console.error('查询订单失败:', err);
  432 + uni.$u.toast('查询订单失败');
  433 + });
  434 + } else if (options.orderId) {
  435 + // 保持原有的orderId逻辑
  436 + orderId.value = options.orderId;
  437 + handleOrderDetail(orderId.value);
  438 + }
  439 +});
  440 +onShow(() => {
  441 + if (orderId.value) {
  442 + handleOrderDetail(orderId.value);
  443 + }
  444 +});
  445 +</script>
  446 +
  447 +<style lang="scss" scoped>$custom-marin-bottom: 20rpx;
  448 +$custom-page-padding: 20rpx;
  449 +$custom-border-radio: 20rpx;
  450 +$custom-bottom-height: 200rpx;
  451 +
  452 +@mixin card {
  453 + padding: $custom-page-padding;
  454 + box-sizing: border-box;
  455 + background-color: #ffffff;
  456 + border-radius: $custom-border-radio;
  457 + margin-bottom: $custom-marin-bottom;
  458 +}
  459 +
  460 +.order-detail-container {
  461 + height: 100%;
  462 + width: 100%;
  463 + background-color: $u-info-light;
  464 + box-sizing: border-box;
  465 + overflow-y: scroll;
  466 + background: linear-gradient(to bottom, #19a97c, $u-info-light, $u-info-light, $u-info-light);
  467 +
  468 + .order-detail-container-box {
  469 + height: 100%;
  470 + width: 100%;
  471 + padding: $custom-page-padding;
  472 + box-sizing: border-box;
  473 +
  474 + .order-detail-top {
  475 + @include card();
  476 +
  477 + .order-detail-top-box {
  478 + .order-detail-top-box-step {
  479 + u-steps {
  480 + u-steps-item {}
  481 + }
  482 + }
  483 + }
  484 + }
  485 +
  486 + .order-detail-container-box-card {
  487 + @include card();
  488 +
  489 + .order-detail-container-header-card-title {
  490 + font-weight: bold;
  491 + line-height: 80rpx;
  492 + border-bottom: 3rpx solid $u-info-light;
  493 + margin-bottom: $custom-marin-bottom;
  494 + color: $u-primary;
  495 + display: flex;
  496 + align-items: center;
  497 +
  498 + .order-detail-container-header-card-uicon {
  499 + background-color: $u-primary;
  500 + margin-right: 10rpx;
  501 + height: 35rpx;
  502 + width: 15rpx;
  503 + }
  504 + }
  505 +
  506 + .order-detail-container-header-item {
  507 + display: flex;
  508 + margin-bottom: $custom-marin-bottom;
  509 +
  510 + .order-detail-container-header-title {
  511 + color: $u-main-color;
  512 + white-space: nowrap;
  513 + color: $u-info;
  514 + }
  515 +
  516 + .order-detail-container-header-content {
  517 + display: flex;
  518 + }
  519 + }
  520 + }
  521 + }
  522 +
  523 + .space-box {
  524 + padding-bottom: $custom-bottom-height;
  525 + margin-bottom: 40rpx;
  526 + }
  527 +}
  528 +
  529 +.mask-container {
  530 + position: fixed;
  531 + top: 0;
  532 + left: 0;
  533 + width: 100%;
  534 + height: 100%;
  535 + z-index: 999;
  536 + background-color: rgba(0, 0, 0, 0.5);
  537 + display: flex;
  538 + align-items: center;
  539 + justify-content: center;
  540 +}
  541 +
  542 +.image-group {
  543 + margin-bottom: 20px;
  544 + padding: 10px;
  545 + background-color: #f5f5f5;
  546 + border-radius: 5px;
  547 +}
  548 +
  549 +.image-group-title {
  550 + margin-bottom: 10px;
  551 + font-weight: bold;
  552 + color: #333;
  553 +}
  554 +
  555 +/* 确保u-upload组件内的图片水平排列 */
  556 +.image-group .u-upload {
  557 + display: flex;
  558 + flex-wrap: wrap;
  559 +}
  560 +
  561 +.image-group-header {
  562 + display: flex;
  563 + justify-content: space-between;
  564 + align-items: center;
  565 + margin-bottom: 10rpx;
  566 +}
  567 +
  568 +.car-status {
  569 + padding: 4rpx 12rpx;
  570 + border-radius: 6rpx;
  571 + font-size: 24rpx;
  572 + font-weight: bold;
  573 +
  574 + &.in-transit {
  575 + background-color: #fff7e6;
  576 + color: #ff9900;
  577 + }
  578 +
  579 + &.completed {
  580 + background-color: #e6f7ff;
  581 + color: #19a97c;
  582 + }
  583 +}
  584 +</style>
0 \ No newline at end of file 585 \ No newline at end of file
garbage-removal/src/pages/order-info/order-driver/detail/index.vue
@@ -156,7 +156,7 @@ @@ -156,7 +156,7 @@
156 'in-transit': group.index < dataGram.garCarInfoList.length, 156 'in-transit': group.index < dataGram.garCarInfoList.length,
157 'completed': group.index >= dataGram.garCarInfoList.length 157 'completed': group.index >= dataGram.garCarInfoList.length
158 }"> 158 }">
159 - {{ group.index < dataGram.garCarInfoList.length ? '运输中' : '已运完' }} 159 + {{ group.index < dataGram.garCarInfoList.length ? '已运完' : '已运完' }}
160 </view> 160 </view>
161 </view> 161 </view>
162 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20" 162 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20"
@@ -226,7 +226,13 @@ @@ -226,7 +226,13 @@
226 </template> 226 </template>
227 227
228 <script setup> 228 <script setup>
229 -import {createHandlerQrCode, queryGarOrderMatchAsk, queryOrderDetail, updateOrder} from "@/apis/order.js"; 229 +import {
  230 + createHandlerQrCode, queryErrType,
  231 + queryGarOrderMatchAsk,
  232 + queryGarOrderMatchAsks,
  233 + queryOrderDetail,
  234 + updateOrder
  235 +} from "@/apis/order.js";
230 import { createQrCode } from '@/apis/qrcode.js'; 236 import { createQrCode } from '@/apis/qrcode.js';
231 import uqrcode from '@/components/Sansnn-uQRCode_4.0.6/components/uqrcode/uqrcode.vue'; 237 import uqrcode from '@/components/Sansnn-uQRCode_4.0.6/components/uqrcode/uqrcode.vue';
232 import zStatic from '@/components/z-paging/js/z-paging-static'; 238 import zStatic from '@/components/z-paging/js/z-paging-static';
@@ -401,11 +407,18 @@ const handleOrder = (orderId) =&gt; { @@ -401,11 +407,18 @@ const handleOrder = (orderId) =&gt; {
401 } 407 }
402 408
403 // 接收订单 409 // 接收订单
  410 +
404 const driverHandleOrder = (orderId) => { 411 const driverHandleOrder = (orderId) => {
405 - updateOrder({ garOrderId: orderId, handleType: 0 }).then(res => {  
406 - if (res.data.success) {  
407 - uni.$u.toast(res.data.data)  
408 - handleOrderDetail(orderId) 412 + queryErrType().then(res => {
  413 + if (res.data.data >= 3 ) {
  414 + uni.$u.toast('异常趟次过多,已被限制接单!');
  415 + }else {
  416 + updateOrder({ garOrderId: orderId, handleType: 0 }).then(res => {
  417 + if (res.data.success) {
  418 + uni.$u.toast(res.data.data)
  419 + handleOrderDetail(orderId)
  420 + }
  421 + })
409 } 422 }
410 }) 423 })
411 } 424 }
@@ -459,27 +472,41 @@ const handleUploadImage = (orderId, putType) =&gt; { @@ -459,27 +472,41 @@ const handleUploadImage = (orderId, putType) =&gt; {
459 const data = dataGram.value; 472 const data = dataGram.value;
460 473
461 // 查询运输趟次 474 // 查询运输趟次
462 - queryGarOrderMatchAsk(orderId).then(res => {  
463 - console.log(res.data.success+"sssss") 475 + queryGarOrderMatchAsk(orderId).then(async res => {
  476 +
464 // 正确处理响应数据 477 // 正确处理响应数据
465 if (res && res.data) { 478 if (res && res.data) {
466 if (res.data.success) { 479 if (res.data.success) {
467 let number = res.data.data; 480 let number = res.data.data;
  481 + let stop = false;
468 482
469 // 检查当前要上传的是第几趟 483 // 检查当前要上传的是第几趟
470 const currentGroupIndex = putOnImagesGrouped.value.length + 1; 484 const currentGroupIndex = putOnImagesGrouped.value.length + 1;
  485 + if(number !== 0){
  486 + await queryGarOrderMatchAsks(orderId).then(res => {
  487 + if (res.data.data === 0) {
  488 + stop = true;
  489 + }
  490 + });
  491 + if (stop == true) {
  492 + uni.$u.toast('已完成所有订单');
  493 + return;
  494 + }
  495 + }
  496 +
471 497
472 // 如果当前趟次大于上一趟次+1,说明上一趟次未完成 498 // 如果当前趟次大于上一趟次+1,说明上一趟次未完成
473 - if (currentGroupIndex > number) { 499 + if (currentGroupIndex > number + 1) {
474 uni.$u.toast('上一趟次未扫码'); 500 uni.$u.toast('上一趟次未扫码');
475 return; 501 return;
476 } 502 }
477 503
  504 +
478 uni.showActionSheet({ 505 uni.showActionSheet({
479 itemList: ['上传装车图片'], 506 itemList: ['上传装车图片'],
480 success: function (res) { 507 success: function (res) {
481 console.log('选中了第' + (res.tapIndex + 1) + '个按钮'); 508 console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
482 - if(res.tapIndex === 0){ 509 + if (res.tapIndex === 0) {
483 uni.$u.route(`pages/order-info/order-driver/upload/index?orderId=${orderId}&carPlate=${data.garHandlerCarCode}&driver=${store.userInfo.userName}&putType=putOnImages`) 510 uni.$u.route(`pages/order-info/order-driver/upload/index?orderId=${orderId}&carPlate=${data.garHandlerCarCode}&driver=${store.userInfo.userName}&putType=putOnImages`)
484 } 511 }
485 }, 512 },
garbage-removal/src/pages/order-info/order-driver/upload/index.vue
@@ -82,18 +82,22 @@ @@ -82,18 +82,22 @@
82 window.takeLocationCallBack = takeLocalCallBack 82 window.takeLocationCallBack = takeLocalCallBack
83 }) 83 })
84 84
85 - const takeLocation = () => {  
86 - // 添加定位超时处理  
87 - setInterval(() => {  
88 - if (!location.value.latitude) {  
89 - uni.$u.toast("定位获取超时,请检查权限");  
90 - }else{  
91 -  
92 - }  
93 - }, 5000);  
94 - // 获取定位信息  
95 - window.JsInterface.takeLocation();  
96 - } 85 + const takeLocation = () => {
  86 + // 添加定位超时处理
  87 + const timer = setTimeout(() => {
  88 + if (!location.value.latitude) {
  89 + uni.$u.toast("定位获取超时,请检查权限");
  90 + }
  91 + }, 5000);
  92 +
  93 + // 获取定位信息
  94 + if (window.JsInterface && typeof window.JsInterface.takeLocation === 'function') {
  95 + window.JsInterface.takeLocation();
  96 + } else {
  97 + clearTimeout(timer);
  98 + uni.$u.toast("当前环境不支持定位功能");
  99 + }
  100 + }
97 // 新增图片 101 // 新增图片
98 const afterRead = async (event) => { 102 const afterRead = async (event) => {
99 // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式 103 // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
garbage-removal/src/pages/order-info/order-other/detail/index.vue
@@ -21,12 +21,12 @@ @@ -21,12 +21,12 @@
21 <view class="company-clean-container-car-popup-content-box-item-text"> 21 <view class="company-clean-container-car-popup-content-box-item-text">
22 {{ item.garOrderCarType }} 22 {{ item.garOrderCarType }}
23 </view> 23 </view>
24 - <view class="company-clean-container-car-popup-content-box-item-number" 24 + <view class="company-clean-container-car-popup-content-box-item-number"
25 hover-class="hoverClickStyle"> 25 hover-class="hoverClickStyle">
26 - <u-number-box :min="0" :max="9999" integer buttonSize="46" :inputWidth="100"  
27 - v-model="garCarInfoList[item.garOrderCarType].garOrderCarNumber"  
28 - :disabledInput="true"></u-number-box>  
29 - </view> 26 + <u-number-box :min="1" :max="9999" integer buttonSize="46" :inputWidth="100"
  27 + v-model="garCarInfoList[item.garOrderCarType].garOrderCarNumber"
  28 + :disabledInput="true"></u-number-box>
  29 + </view>
30 </view> 30 </view>
31 </view> 31 </view>
32 </view> 32 </view>
@@ -120,16 +120,39 @@ @@ -120,16 +120,39 @@
120 <view class="order-detail-container-header-card-uicon"></view> 120 <view class="order-detail-container-header-card-uicon"></view>
121 车辆信息 121 车辆信息
122 </view> 122 </view>
  123 + <view class="order-detail-container-box-card" v-if="driverList.length > 0">
  124 + <view class="driver-info-container">
  125 + <view class="driver-info-row" v-for="(driver, index) in driverList" :key="index">
  126 + <text class="driver-name">驾驶员: {{ driver.garOrderHandlerName }}</text>
  127 + <text class="car-code">车牌号: {{ driver.garHandlerCarCode }}</text>
  128 + <text>正在清运</text>
  129 + </view>
  130 + </view>
  131 + </view>
123 <view class="order-detail-container-header-item" style="justify-content: space-between;" 132 <view class="order-detail-container-header-item" style="justify-content: space-between;"
124 v-for="(item) in dataGram.garCarInfoList" :key="item.garId"> 133 v-for="(item) in dataGram.garCarInfoList" :key="item.garId">
125 <text class="order-detail-container-header-title" style="color: #303133;">{{ item.garOrderCarType }} 134 <text class="order-detail-container-header-title" style="color: #303133;">{{ item.garOrderCarType }}
126 </text> 135 </text>
127 <view class="order-detail-container-header-content"> 136 <view class="order-detail-container-header-content">
128 <text class="order-detail-container-header-title"> 137 <text class="order-detail-container-header-title">
129 - {{ cleanStatus(dataGram.garOrderHandlerStatus) }} 138 + {{dataGram.garHandlerCarCode}}{{ cleanStatus(dataGram.garOrderHandlerStatus) }}
130 </text> 139 </text>
131 </view> 140 </view>
132 </view> 141 </view>
  142 + <view v-if="userType == '运输企业负责人'" class="order-detail-container-header-item" style="justify-content: space-between; align-items: center;">
  143 + <text class="order-detail-container-header-title" style="color: #303133;">新增趟次:</text>
  144 + <view class="order-detail-container-header-content" style="display: flex; align-items: center;">
  145 + <u-number-box
  146 + v-model="totalCarNumber"
  147 + :min="0"
  148 + :max="999"
  149 + integer
  150 + buttonSize="46"
  151 + inputWidth="100">
  152 + </u-number-box>
  153 + <u-button type="primary" color="#19a97c" style="margin-left: 20rpx; height: 46rpx; width: 120rpx;" @click="confirmAddVehicle">确定</u-button>
  154 + </view>
  155 + </view>
133 </view> 156 </view>
134 <!-- 订单记录 --> 157 <!-- 订单记录 -->
135 <view class="order-detail-container-box-card"> 158 <view class="order-detail-container-box-card">
@@ -192,7 +215,7 @@ @@ -192,7 +215,7 @@
192 'in-transit': group.index < dataGram.garCarInfoList.length, 215 'in-transit': group.index < dataGram.garCarInfoList.length,
193 'completed': group.index >= dataGram.garCarInfoList.length 216 'completed': group.index >= dataGram.garCarInfoList.length
194 }"> 217 }">
195 - {{ group.index < dataGram.garCarInfoList.length ? '运输中' : '已运完' }} 218 + {{ group.index < dataGram.garCarInfoList.length ? '已运完' : '已运完' }}
196 </view> 219 </view>
197 </view> 220 </view>
198 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20" 221 <u-upload width="180" height="130" :fileList="group.images" name="3" multiple :maxCount="20"
@@ -224,16 +247,15 @@ @@ -224,16 +247,15 @@
224 @click="handleOderCancelClick()" shape="square" color="#19a97c" text="取消订单"></u-button> 247 @click="handleOderCancelClick()" shape="square" color="#19a97c" text="取消订单"></u-button>
225 <u-button 248 <u-button
226 v-if="dataGram.garOrderScanHandlerFlag === 0 && userType == '用户' && dataGram.garOrderHandlerStatus != 3 && dataGram.garAskStatus != '1'" 249 v-if="dataGram.garOrderScanHandlerFlag === 0 && userType == '用户' && dataGram.garOrderHandlerStatus != 3 && dataGram.garAskStatus != '1'"
227 - @click="handlerUpdateOrderClick()" shape="square" color="#19a97c" text="修改车辆信息"></u-button> 250 + @click="handlerUpdateOrderClick()" shape="square" color="#19a97c" text="修改车辆"></u-button>
228 <u-button v-if="dataGram.garOrderHandlerStatus === 1 && userType == '运输企业负责人'" 251 <u-button v-if="dataGram.garOrderHandlerStatus === 1 && userType == '运输企业负责人'"
229 @click="handleOrderDispatchClick(orderId)" shape="square" color="#19a97c" 252 @click="handleOrderDispatchClick(orderId)" shape="square" color="#19a97c"
230 text="分配驾驶员"></u-button> 253 text="分配驾驶员"></u-button>
231 </view> 254 </view>
232 255
233 - <view class="order-detail-bottom-center" v-if="dataGram.garOrderHandlerStatus === 1 && userType == '运输企业负责人'">  
234 - <u-button @click="handleSubmitSuccess(orderId)" shape="square" color="#19a97c" text="完成订单"></u-button> 256 + <view class="order-detail-bottom-center" v-if="dataGram.garOrderHandlerStatus === 1 && userType == '运输企业负责人' && isAllTripsCompleted()">
  257 + <u-button @click="handleSubmitSuccess(orderId)" shape="square" color="#19a97c" text="完成订单"></u-button>
235 </view> 258 </view>
236 -  
237 <view class="order-detail-bottom-right"> 259 <view class="order-detail-bottom-right">
238 <u-button 260 <u-button
239 v-if="dataGram.garOrderHandlerStatus === 0 && userType == '用户' && dataGram.garCancelFlag === 0" 261 v-if="dataGram.garOrderHandlerStatus === 0 && userType == '用户' && dataGram.garCancelFlag === 0"
@@ -269,20 +291,41 @@ @@ -269,20 +291,41 @@
269 <uqrcode :h5SaveIsDownload="true" ref="qrCodeRef" canvas-id="qrcode" :value="qrCodeText" 291 <uqrcode :h5SaveIsDownload="true" ref="qrCodeRef" canvas-id="qrcode" :value="qrCodeText"
270 :options="{ margin: 10, boxSizing: borderBox }"></uqrcode> 292 :options="{ margin: 10, boxSizing: borderBox }"></uqrcode>
271 </view> 293 </view>
  294 +
  295 + <u-popup :zIndex="10075" closeOnClickOverlay :show="driverListPopupShowFlag" :round="10" @close="driverListPopupShowFlag = false">
  296 + <view class="driver-list-popup">
  297 + <view class="driver-list-popup-header">
  298 + <text class="driver-list-popup-title">司机信息列表</text>
  299 + </view>
  300 + <view class="driver-list-popup-content">
  301 + <view class="driver-item" v-for="(driver, index) in driverListForAssignment" :key="index">
  302 + <view class="driver-info">
  303 + <text class="driver-name">{{ driver.garOrderHandlerName }}</text>
  304 + <text class="driver-phone">{{driver.garOrderHandlerTel }}</text>
  305 + </view>
  306 + <u-button type="primary" size="mini" color="#19a97c" @click="assignTripToDriver()" style="width: 120rpx; height: 50rpx; font-size: 24rpx; padding: 0 10rpx; margin-right: 0;">分配趟次</u-button>
  307 + </view>
  308 + </view>
  309 + <view class="driver-list-popup-footer">
  310 + <u-button @click="driverListPopupShowFlag = false">关闭</u-button>
  311 + </view>
  312 + </view>
  313 + </u-popup>
272 </template> 314 </template>
273 315
274 <script setup> 316 <script setup>
275 import { 317 import {
276 queryCarList 318 queryCarList
277 } from '@/apis/carinfo.js'; 319 } from '@/apis/carinfo.js';
278 - import {  
279 - dispatchDisposalOrders,  
280 - dispatchOrders,  
281 - queryDisposalDispatch,  
282 - queryOrderDetail,  
283 - queryOrderDispatch,  
284 - updateOrder  
285 - } from "@/apis/order.js"; 320 + import {
  321 + dispatchDisposalOrders,
  322 + dispatchOrders, getGarOrderMatchHandlers,
  323 + queryDisposalDispatch,
  324 + queryOrderDetail,
  325 + queryOrderDispatch, sendToDriver, updateGarRealCarCount,
  326 + updateOrder,
  327 + queryCarCode
  328 + } from "@/apis/order.js";
286 import { 329 import {
287 createQrCode 330 createQrCode
288 } from '@/apis/qrcode.js'; 331 } from '@/apis/qrcode.js';
@@ -298,15 +341,19 @@ @@ -298,15 +341,19 @@
298 onShow 341 onShow
299 } from '@dcloudio/uni-app'; 342 } from '@dcloudio/uni-app';
300 import { 343 import {
301 - computed,  
302 - ref 344 + computed
303 } from 'vue'; 345 } from 'vue';
  346 + import { ref } from 'vue';
304 const paramFrom = ref({ 347 const paramFrom = ref({
305 carNumber: 0, 348 carNumber: 0,
306 carType: "" 349 carType: ""
307 }) 350 })
  351 + const totalCarNumber = ref(0);
  352 + const driverListPopupShowFlag = ref(false);
  353 + const driverListForAssignment = ref([]);
308 const garCarInfoList = ref({}) 354 const garCarInfoList = ref({})
309 const carPopupShowFlag = ref(false) 355 const carPopupShowFlag = ref(false)
  356 + const driverList = ref([]);
310 const isOnloadIn = ref(false) 357 const isOnloadIn = ref(false)
311 const clashDriverDispatchRef = ref() 358 const clashDriverDispatchRef = ref()
312 const clashDisposalDispatchRef = ref() 359 const clashDisposalDispatchRef = ref()
@@ -330,6 +377,9 @@ @@ -330,6 +377,9 @@
330 const candidates = ref([]) 377 const candidates = ref([])
331 const garCarLabelInfoList = ref({}) 378 const garCarLabelInfoList = ref({})
332 const garCarLabelInfoNow = ref() 379 const garCarLabelInfoNow = ref()
  380 + const driverAssigned = ref(false); // 添加这行,跟踪驾驶员是否已分配
  381 +const disposalAssigned = ref(false); // 添加这行,跟踪处置场所是否已分配
  382 +
333 const list = computed(() => { 383 const list = computed(() => {
334 let reason = [{ 384 let reason = [{
335 name: '订单信息填写有误', 385 name: '订单信息填写有误',
@@ -355,6 +405,67 @@ @@ -355,6 +405,67 @@
355 return reason 405 return reason
356 }) 406 })
357 407
  408 + const isAllTripsCompleted = () => {
  409 + // 检查所有趟次是否已完成
  410 + if (!dataGram.value || !dataGram.value.garCarInfoList || !putOnImagesGrouped.value) {
  411 + return false;
  412 + }
  413 +
  414 + // 获取订单要求的趟次数
  415 + const requiredTrips = dataGram.value.garCarInfoList.length;
  416 +
  417 + // 获取实际完成的趟次数
  418 + const completedTrips = putOnImagesGrouped.value.length;
  419 +
  420 + // 如果完成的趟次数大于等于要求的趟次数,则表示全部运完
  421 + return completedTrips >= requiredTrips;
  422 + }
  423 +
  424 + const assignTripToDriver = ()=>{
  425 + sendToDriver(orderId.value).then(res=>{
  426 + if (res.data.success) {
  427 + uni.$u.toast('分配成功');
  428 + }
  429 + })
  430 + }
  431 + // 获取驾驶员列表的方法
  432 + const fetchDriverList = (orderId) => {
  433 + queryCarCode(orderId).then(res => {
  434 + if (res.data.success) {
  435 + driverList.value = res.data.data;
  436 + }
  437 + });
  438 + };
  439 +
  440 + const confirmAddVehicle = () => {
  441 + console.log('新增车辆数量:', totalCarNumber.value);
  442 +
  443 + // 调用API传递订单ID和新增车辆数量
  444 + updateGarRealCarCount(orderId.value, totalCarNumber.value)
  445 + .then(res => {
  446 + if (res.data.success) {
  447 + uni.$u.toast(`成功新增${totalCarNumber.value}辆车`);
  448 + getGarOrderMatchHandlers(orderId.value).then(res => {
  449 + console.log('司机列表:', res.data);
  450 + if (res.data.success && res.data.data && res.data.data.length > 0) {
  451 + driverListForAssignment.value = res.data.data;
  452 + driverListPopupShowFlag.value = true;
  453 + }
  454 + })
  455 + // 重置输入框
  456 + totalCarNumber.value = 0;
  457 + // 刷新订单详情
  458 + handleOrderDetail(orderId.value);
  459 + } else {
  460 + uni.$u.toast(res.data.msg || '新增车辆失败');
  461 + }
  462 + })
  463 + .catch(err => {
  464 + uni.$u.toast('新增车辆请求失败');
  465 + console.error('新增车辆失败:', err);
  466 + });
  467 + };
  468 +
358 const handlePopupClick = (val) => { 469 const handlePopupClick = (val) => {
359 carPopupShowFlag.value = val 470 carPopupShowFlag.value = val
360 } 471 }
@@ -444,6 +555,7 @@ @@ -444,6 +555,7 @@
444 const handleOrderDetail = (orderId) => { 555 const handleOrderDetail = (orderId) => {
445 queryOrderDetail(orderId).then(res => { 556 queryOrderDetail(orderId).then(res => {
446 dataGram.value = res.data.data; 557 dataGram.value = res.data.data;
  558 + fetchDriverList(orderId);
447 currentImages.value = res.data.data.currentImages.map(item => { 559 currentImages.value = res.data.data.currentImages.map(item => {
448 return { 560 return {
449 url: import.meta.env.VITE_BASE_URL + item 561 url: import.meta.env.VITE_BASE_URL + item
@@ -569,7 +681,7 @@ @@ -569,7 +681,7 @@
569 }) 681 })
570 } 682 }
571 // 提交完成 683 // 提交完成
572 - const handleSubmitSuccess = (orderId) => { 684 +const handleSubmitSuccess = (orderId) => {
573 uni.showModal({ 685 uni.showModal({
574 title: '提示', 686 title: '提示',
575 content: '订单已经清运完成了吗?', 687 content: '订单已经清运完成了吗?',
@@ -587,7 +699,6 @@ @@ -587,7 +699,6 @@
587 } else if (res.cancel) {} 699 } else if (res.cancel) {}
588 } 700 }
589 }); 701 });
590 -  
591 } 702 }
592 const handleEvaluate = (orderId, userType) => { 703 const handleEvaluate = (orderId, userType) => {
593 uni.$u.route(`pages/order-info/order-other/evaluate/index?orderId=${orderId}&userType=${userType}`) 704 uni.$u.route(`pages/order-info/order-other/evaluate/index?orderId=${orderId}&userType=${userType}`)
@@ -639,7 +750,7 @@ @@ -639,7 +750,7 @@
639 } 750 }
640 } 751 }
641 752
642 - const handleDisposalDispatchConfirm = (val) => { 753 + const handleDisposalDispatchConfirm = (val) => {
643 console.log(val); 754 console.log(val);
644 if (!val) { 755 if (!val) {
645 return 756 return
@@ -657,12 +768,25 @@ @@ -657,12 +768,25 @@
657 dispatchDisposalOrders(data).then(res => { 768 dispatchDisposalOrders(data).then(res => {
658 if (res.data.success) { 769 if (res.data.success) {
659 uni.$u.toast(res.data.msg) 770 uni.$u.toast(res.data.msg)
  771 + // 标记处置场所已分配
  772 + disposalAssigned.value = true;
  773 + // 检查是否两个任务都已完成
  774 + checkAndRedirect();
660 } else { 775 } else {
661 uni.$u.toast("指定人员失败,请重试") 776 uni.$u.toast("指定人员失败,请重试")
662 } 777 }
663 clashDriverDispatchRef.value.close() 778 clashDriverDispatchRef.value.close()
664 }) 779 })
665 } 780 }
  781 + const checkAndRedirect = () => {
  782 + // 当两个任务都完成时跳转到订单页
  783 + if (driverAssigned.value && disposalAssigned.value) {
  784 + uni.$u.route({
  785 + type: "reLaunch",
  786 + url: `pages/order/index`,
  787 + });
  788 + }
  789 + }
666 790
667 const handlerUpdateOrderClick = () => { 791 const handlerUpdateOrderClick = () => {
668 carPopupShowFlag.value = true; 792 carPopupShowFlag.value = true;
@@ -684,7 +808,7 @@ @@ -684,7 +808,7 @@
684 // 设置初始车辆数量 808 // 设置初始车辆数量
685 candidates.value[0].forEach((item, index) => { 809 candidates.value[0].forEach((item, index) => {
686 garCarInfoList.value[item] = { 810 garCarInfoList.value[item] = {
687 - garOrderCarNumber: 0, 811 + garOrderCarNumber: 1,
688 garOrderCarType: item, 812 garOrderCarType: item,
689 id: garCarLabelInfoList.value[item].id, 813 id: garCarLabelInfoList.value[item].id,
690 containerVolume: garCarLabelInfoList.value[item].containerVolume 814 containerVolume: garCarLabelInfoList.value[item].containerVolume
@@ -728,6 +852,10 @@ const handleDriverDispatchConfirm = (val) =&gt; { @@ -728,6 +852,10 @@ const handleDriverDispatchConfirm = (val) =&gt; {
728 dispatchOrders(data).then(res => { 852 dispatchOrders(data).then(res => {
729 if (res.data.success) { 853 if (res.data.success) {
730 uni.$u.toast(res.data.msg); 854 uni.$u.toast(res.data.msg);
  855 + // 标记驾驶员已分配
  856 + driverAssigned.value = true;
  857 + // 检查是否两个任务都已完成
  858 + checkAndRedirect();
731 } else { 859 } else {
732 uni.$u.toast("指定人员失败,请重试"); 860 uni.$u.toast("指定人员失败,请重试");
733 } 861 }
@@ -1095,4 +1223,77 @@ const handleDriverDispatchConfirm = (val) =&gt; { @@ -1095,4 +1223,77 @@ const handleDriverDispatchConfirm = (val) =&gt; {
1095 color: #19a97c; 1223 color: #19a97c;
1096 } 1224 }
1097 } 1225 }
  1226 + .driver-list-popup {
  1227 + min-height: 400rpx;
  1228 + max-height: 800rpx;
  1229 + padding: $custom-page-padding;
  1230 + box-sizing: border-box;
  1231 +
  1232 + .driver-list-popup-header {
  1233 + text-align: center;
  1234 + margin-bottom: 30rpx;
  1235 +
  1236 + .driver-list-popup-title {
  1237 + font-size: 32rpx;
  1238 + font-weight: bold;
  1239 + color: $u-main-color;
  1240 + }
  1241 + }
  1242 +
  1243 + .driver-list-popup-content {
  1244 + max-height: 600rpx;
  1245 + overflow-y: auto;
  1246 +
  1247 + .driver-item {
  1248 + display: flex;
  1249 + justify-content: space-between;
  1250 + align-items: center;
  1251 + padding: 20rpx 0;
  1252 + border-bottom: 1rpx solid $u-border-color;
  1253 +
  1254 + .driver-info {
  1255 + display: flex;
  1256 + flex-direction: column;
  1257 +
  1258 + .driver-name {
  1259 + font-size: 28rpx;
  1260 + font-weight: bold;
  1261 + margin-bottom: 10rpx;
  1262 + }
  1263 +
  1264 + .driver-phone {
  1265 + font-size: 24rpx;
  1266 + color: $u-tips-color;
  1267 + }
  1268 + }
  1269 + }
  1270 + }
  1271 +
  1272 + .driver-list-popup-footer {
  1273 + margin-top: 30rpx;
  1274 + text-align: center;
  1275 + }
  1276 + }
  1277 + .driver-info-container {
  1278 + .driver-info-row {
  1279 + display: flex;
  1280 + flex-wrap: wrap;
  1281 + padding: 10rpx 0;
  1282 + border-bottom: 1rpx solid $u-border-color;
  1283 + justify-content: flex-start;
  1284 +
  1285 + .driver-name, .car-code {
  1286 + margin-right: 20rpx;
  1287 + color: $u-main-color;
  1288 + }
  1289 +
  1290 + .driver-name {
  1291 + font-weight: bold;
  1292 + }
  1293 + }
  1294 +
  1295 + .driver-info-row:last-child {
  1296 + border-bottom: none;
  1297 + }
  1298 + }
1098 </style> 1299 </style>
1099 \ No newline at end of file 1300 \ No newline at end of file
garbage-removal/src/pages/order/order-disposal/swiper-list-item/index.vue
@@ -16,7 +16,12 @@ @@ -16,7 +16,12 @@
16 <view class="title u-line-2">{{ item.garOrderAddressDetails }}</view> 16 <view class="title u-line-2">{{ item.garOrderAddressDetails }}</view>
17 <view class="type">垃圾类型: {{ item.garOrderTrashType }}</view> 17 <view class="type">垃圾类型: {{ item.garOrderTrashType }}</view>
18 <view class="delivery-time">创建时间 {{ item.garCreateTime }}</view> 18 <view class="delivery-time">创建时间 {{ item.garCreateTime }}</view>
19 - <view class="transport-num">载运量 {{ item.garNowCarCount }} /{{ item.garRealCarCount }}</view> 19 + <view class="transport-num" :style="{ color: item.garNowCarCount === item.garRealCarCount ? 'red' : '#19a97c' }">
  20 + 载运量 {{ item.garNowCarCount }} /{{ item.garRealCarCount }}
  21 + </view>
  22 + <view v-if="item.garNowCarCount === item.garRealCarCount" class="completion-tip">
  23 + 全部完成
  24 + </view>
20 </view> 25 </view>
21 </view> 26 </view>
22 </view> 27 </view>
@@ -108,6 +113,21 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; { @@ -108,6 +113,21 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; {
108 </script> 113 </script>
109 114
110 <style lang="scss" scoped> 115 <style lang="scss" scoped>
  116 +.completion-tip {
  117 + font-size: 24rpx;
  118 + color: red;
  119 + text-align: end;
  120 + margin-top: 10rpx;
  121 +}
  122 +.transport-num {
  123 + font-size: 24rpx;
  124 + color: #19a97c;
  125 + text-align: end;
  126 +
  127 + &.completed {
  128 + color: red;
  129 + }
  130 +}
111 .content-container { 131 .content-container {
112 height: 100%; 132 height: 100%;
113 133
garbage-removal/src/pages/order/order-driver/index.vue
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 <script setup> 34 <script setup>
35 import { nextTick, onMounted, ref, computed } from 'vue'; 35 import { nextTick, onMounted, ref, computed } from 'vue';
36 import swiperListItem from './swiper-list-item/index.vue'; 36 import swiperListItem from './swiper-list-item/index.vue';
37 -import { queryOrderList } from "@/apis/order.js"; 37 +import {queryOrderList, queryDriverSend, updateDriverSend} from "@/apis/order.js";
38 38
39 // 初始化订单类型列表,添加count属性 39 // 初始化订单类型列表,添加count属性
40 const list = ref([{ name: '待清运', count: 0 }, { name: '清运中', count: 0 }, { name: '全部', count: 0 }, { name: '已完成', count: 0 }]) 40 const list = ref([{ name: '待清运', count: 0 }, { name: '清运中', count: 0 }, { name: '全部', count: 0 }, { name: '已完成', count: 0 }])
@@ -44,7 +44,41 @@ const uTabsElement = ref() @@ -44,7 +44,41 @@ const uTabsElement = ref()
44 const topMargin = ref() 44 const topMargin = ref()
45 const lightHeight = ref() 45 const lightHeight = ref()
46 const title = ref('订单列表') 46 const title = ref('订单列表')
  47 +const driverTasks = ref([]);
47 48
  49 +const loadDriverTasks = async () => {
  50 + try {
  51 + const response = await queryDriverSend();
  52 +
  53 + if (response && response.data && response.data.success) {
  54 + const taskObject = response.data.data;
  55 +
  56 + if (taskObject && taskObject.phone && taskObject.orderId) {
  57 + driverTasks.value = taskObject;
  58 +
  59 + showDriverTasks(taskObject);
  60 + }
  61 + }
  62 + } catch (error) {
  63 + alert('获取司机任务列表失败: ' + error.message);
  64 + }
  65 +};
  66 +
  67 +// 修改方法:显示司机任务(接收对象而不是数组)
  68 +const showDriverTasks = (task) => {
  69 + // 使用 uni.showModal 弹出任务信息
  70 + uni.showModal({
  71 + title: '司机任务提醒',
  72 + content: `您有新的任务需要处理\n订单号: ${task.orderId}`,
  73 + showCancel: true,
  74 + confirmText: '确定',
  75 + success: function (res) {
  76 + if (res.confirm) {
  77 + updateDriverSend()
  78 + }
  79 + }
  80 + });
  81 +};
48 // 创建一个计算属性用于显示带数量的标签 82 // 创建一个计算属性用于显示带数量的标签
49 const displayList = computed(() => { 83 const displayList = computed(() => {
50 return list.value.map(item => ({ 84 return list.value.map(item => ({
@@ -108,6 +142,7 @@ onMounted(() =&gt; { @@ -108,6 +142,7 @@ onMounted(() =&gt; {
108 } 142 }
109 // 页面加载后获取所有订单总数 143 // 页面加载后获取所有订单总数
110 getAllOrderCounts(); 144 getAllOrderCounts();
  145 + loadDriverTasks();
111 }) 146 })
112 }) 147 })
113 </script> 148 </script>
garbage-removal/src/pages/order/order-driver/swiper-list-item/index.vue
@@ -24,6 +24,9 @@ @@ -24,6 +24,9 @@
24 <view class="type">垃圾类型: {{ item.garOrderTrashType }}</view> 24 <view class="type">垃圾类型: {{ item.garOrderTrashType }}</view>
25 <view class="delivery-time">预约时间 {{ item.garOrderAgreementTime }}</view> 25 <view class="delivery-time">预约时间 {{ item.garOrderAgreementTime }}</view>
26 <view style="font-size: 24rpx;color: #19a97c;text-align: end;">载运量{{ item.garRealCarCount }}</view> 26 <view style="font-size: 24rpx;color: #19a97c;text-align: end;">载运量{{ item.garRealCarCount }}</view>
  27 + <view v-if="item.garNowCarCount === item.garRealCarCount" class="completion-tip">
  28 + 全部完成
  29 + </view>
27 </view> 30 </view>
28 </view> 31 </view>
29 </view> 32 </view>
@@ -34,8 +37,8 @@ @@ -34,8 +37,8 @@
34 37
35 <script setup> 38 <script setup>
36 import { queryOrderList } from "@/apis/order.js"; 39 import { queryOrderList } from "@/apis/order.js";
37 -import { onShow } from "@dcloudio/uni-app";  
38 -import { ref, watch } from 'vue'; 40 +import { onShow} from "@dcloudio/uni-app";
  41 +import { ref, watch} from 'vue';
39 const props = defineProps({ 42 const props = defineProps({
40 tabIndex: { 43 tabIndex: {
41 type: Number 44 type: Number
@@ -68,6 +71,7 @@ const handleClick = (orderId) =&gt; { @@ -68,6 +71,7 @@ const handleClick = (orderId) =&gt; {
68 }) 71 })
69 } 72 }
70 73
  74 +
71 // list集合 75 // list集合
72 const queryList = (pageNo, pageSize) => { 76 const queryList = (pageNo, pageSize) => {
73 //这里的pageNo和pageSize会自动计算好,直接传给服务器即可 77 //这里的pageNo和pageSize会自动计算好,直接传给服务器即可
garbage-removal/src/pages/order/order-other/swiper-list-item/index.vue
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
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" class="right">清运中 </view>
  17 + <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0 && item.garNowCarCount === item.garRealCarCount" class="right">已完成 </view>
17 </view> 18 </view>
18 <view v-if="item.garEvaluateFlag === 0 && userType === '用户'" class="right">待评价 19 <view v-if="item.garEvaluateFlag === 0 && userType === '用户'" class="right">待评价
19 </view> 20 </view>
@@ -31,6 +32,19 @@ @@ -31,6 +32,19 @@
31 <view class="title u-line-2">{{ item.garOrderAddress + item.garOrderAddressDetails }}</view> 32 <view class="title u-line-2">{{ item.garOrderAddress + item.garOrderAddressDetails }}</view>
32 <view class="type">垃圾类型: {{ item.garOrderTrashType }}</view> 33 <view class="type">垃圾类型: {{ item.garOrderTrashType }}</view>
33 <view class="delivery-time">预约时间 {{ item.garOrderAgreementTime }}</view> 34 <view class="delivery-time">预约时间 {{ item.garOrderAgreementTime }}</view>
  35 + <view class="transport-num" :style="{ color: item.garNowCarCount === item.garRealCarCount ? 'red' : '#19a97c' }">
  36 + 载运量 {{ item.garNowCarCount }} /{{ item.garRealCarCount }}
  37 + </view>
  38 + <view v-if="item.garNowCarCount === item.garRealCarCount" class="completion-tip">
  39 + 全部完成
  40 + </view>
  41 +
  42 + <!-- 在订单底部操作区域添加完成订单按钮 -->
  43 + <view class="bottom" v-if="item.garNowCarCount === item.garRealCarCount && item.garOrderHandlerStatus !== 3 && userType === '运输企业负责人'">
  44 + <view hover-class="btn-hover" class="finish-order btn" @click="handleFinishOrder(item.garOrderId)">
  45 + 完成订单
  46 + </view>
  47 + </view>
34 </view> 48 </view>
35 </view> 49 </view>
36 <view class="bottom" v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0"> 50 <view class="bottom" v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0">
@@ -144,6 +158,26 @@ const goDetail = (val) =&gt; { @@ -144,6 +158,26 @@ const goDetail = (val) =&gt; {
144 const selectClick = (index) => { 158 const selectClick = (index) => {
145 currentCancelName.value = index.name; 159 currentCancelName.value = index.name;
146 } 160 }
  161 +const handleFinishOrder = (orderId) => {
  162 + uni.showModal({
  163 + title: '提示',
  164 + content: '订单已经清运完成了吗?',
  165 + success: function(res) {
  166 + if (res.confirm) {
  167 + updateOrder({
  168 + garOrderId: orderId,
  169 + handleType: 3
  170 + }).then(res => {
  171 + if (res.data.success) {
  172 + uni.$u.toast("已完成")
  173 + handleOrderDetail(orderId)
  174 + }
  175 + })
  176 + } else if (res.cancel) {}
  177 + }
  178 + });
  179 +
  180 +}
147 /** 181 /**
148 * 提交取消订单 182 * 提交取消订单
149 */ 183 */
@@ -228,6 +262,18 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; { @@ -228,6 +262,18 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; {
228 </script> 262 </script>
229 263
230 <style lang="scss" scoped> 264 <style lang="scss" scoped>
  265 +.transport-num {
  266 + font-size: 24rpx;
  267 + color: #19a97c;
  268 + text-align: end;
  269 +}
  270 +
  271 +.completion-tip {
  272 + font-size: 24rpx;
  273 + color: red;
  274 + text-align: end;
  275 + margin-top: 10rpx;
  276 +}
231 .content-container { 277 .content-container {
232 height: 100%; 278 height: 100%;
233 width: 100%; 279 width: 100%;
garbage-removal/src/pages/sign-up/index.vue
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 class="login-input" 24 class="login-input"
25 type="text" 25 type="text"
26 v-model="nickname" 26 v-model="nickname"
27 - placeholder="请输入用户名" 27 + placeholder="请输入账号"
28 placeholder-class="placeholder-style" 28 placeholder-class="placeholder-style"
29 /> 29 />
30 </view> 30 </view>
garbage-removal/src/utils/request/request.js
@@ -68,8 +68,15 @@ instance.interceptors.response.use((response) =&gt; { @@ -68,8 +68,15 @@ instance.interceptors.response.use((response) =&gt; {
68 return response; 68 return response;
69 } 69 }
70 if (response.data.code != 200) { 70 if (response.data.code != 200) {
71 - if (response.data.code == 401) {  
72 - reSetLoginStatus(); 71 + // 对于匿名访问的页面,不处理401和403错误
  72 + const url = response.config?.url || '';
  73 + const isGuestAccess = url.startsWith("/order-info/order-other/webDetail/") ||
  74 + url.startsWith("/order-info/order-driver/detail/guest/");
  75 +
  76 + if (response.data.code == 401 || response.data.code == 403) {
  77 + if (!isGuestAccess) {
  78 + reSetLoginStatus();
  79 + }
73 } else { 80 } else {
74 uni.showToast({ 81 uni.showToast({
75 title: response.data.msg, 82 title: response.data.msg,
@@ -79,12 +86,18 @@ instance.interceptors.response.use((response) =&gt; { @@ -79,12 +86,18 @@ instance.interceptors.response.use((response) =&gt; {
79 } 86 }
80 return response; 87 return response;
81 }, (error) => { 88 }, (error) => {
  89 + // 对于匿名访问的页面,不处理401和403错误
  90 + const url = error.config?.url || '';
  91 + const isGuestAccess = url.startsWith("/order-info/order-other/webDetail/") ||
  92 + url.startsWith("/order-info/order-driver/detail/guest/");
82 93
83 if (error.response.status) { 94 if (error.response.status) {
84 switch (error.response.status) { 95 switch (error.response.status) {
85 case 401: 96 case 401:
86 case 403: 97 case 403:
87 - reSetLoginStatus(); 98 + if (!isGuestAccess) {
  99 + reSetLoginStatus();
  100 + }
88 break; 101 break;
89 default: 102 default:
90 break; 103 break;
@@ -152,7 +165,9 @@ const handleGet = (config) =&gt; { @@ -152,7 +165,9 @@ const handleGet = (config) =&gt; {
152 } 165 }
153 config.url += strUrl; 166 config.url += strUrl;
154 config.params = ""; 167 config.params = "";
155 - if (config.url.startsWith("/order-info/order-other/webDetail/")) { 168 + // 对于匿名访问的页面,移除Authorization头
  169 + if (config.url.startsWith("/order-info/order-other/webDetail/") ||
  170 + config.url.startsWith("/order-info/order-driver/detail/guest/")) {
156 config.headers["Authorization"] = ""; 171 config.headers["Authorization"] = "";
157 } 172 }
158 } 173 }