Commit 74b5d9c1b15bcb4cb5577d99c7834f84d370b55f
1 parent
6283a76f
提交12-19
Showing
11 changed files
with
527 additions
and
289 deletions
garbage-removal/src/components/clash-disposal-dispatch/index.vue
| ... | ... | @@ -142,7 +142,7 @@ function changeVerify(current, chooseList) { |
| 142 | 142 | function open(dataList) { |
| 143 | 143 | treeData.value = handlerTreeData(dataList) |
| 144 | 144 | treeData.value = treeData.value.filter(item => { |
| 145 | - return item.children[0].id | |
| 145 | + return item.children && item.children.length > 0 && item.children[0] && item.children[0].id | |
| 146 | 146 | }) |
| 147 | 147 | setTimeout(() => { |
| 148 | 148 | nextTick(() => { |
| ... | ... | @@ -158,7 +158,7 @@ function handlerTreeData(dataList) { |
| 158 | 158 | "id": (index + 1), |
| 159 | 159 | "name": item.garOrderDisposalCompanyName, |
| 160 | 160 | "label": item.garOrderDisposalCompanyName, |
| 161 | - "children": item.personnelInfo.map((childrenItem, childrenIndex) => { | |
| 161 | + "children": (item.personnelInfo || []).map((childrenItem, childrenIndex) => { | |
| 162 | 162 | return { |
| 163 | 163 | "id": (index + 1) + '-' + (childrenIndex + 1), |
| 164 | 164 | "tel": childrenItem.tel, | ... | ... |
garbage-removal/src/components/clash-driver-dispatch/index.vue
| ... | ... | @@ -123,7 +123,7 @@ function changeVerify(current, chooseList) { |
| 123 | 123 | function open(dataList) { |
| 124 | 124 | treeData.value = handlerTreeData(dataList) |
| 125 | 125 | treeData.value = treeData.value.filter(item => { |
| 126 | - return item.children[0].id | |
| 126 | + return item.children && item.children.length > 0 && item.children[0] && item.children[0].id | |
| 127 | 127 | }) |
| 128 | 128 | setTimeout(() => { |
| 129 | 129 | nextTick(() => { |
| ... | ... | @@ -140,7 +140,7 @@ function handlerTreeData(dataList) { |
| 140 | 140 | "licensePlateNumber": item.licensePlateNumber, |
| 141 | 141 | "containerVolume": item.containerVolume + "方车", |
| 142 | 142 | "label": item.containerVolume + "方车" + '-' + item.licensePlateNumber, |
| 143 | - "children": item.personnelInfo.map((childrenItem, childrenIndex) => { | |
| 143 | + "children": (item.personnelInfo || []).map((childrenItem, childrenIndex) => { | |
| 144 | 144 | return { |
| 145 | 145 | "id": (index + 1) + '-' + (childrenIndex + 1), |
| 146 | 146 | "garOrderContainerVolume": item.containerVolume, | ... | ... |
garbage-removal/src/components/next-tree/next-tree.vue
| ... | ... | @@ -347,6 +347,10 @@ export default { |
| 347 | 347 | }, |
| 348 | 348 | //扁平化树结构 |
| 349 | 349 | _renderTreeList(list = [], rank = 0, parentId = [], parents = []) { |
| 350 | + if (!Array.isArray(list)) { | |
| 351 | + console.warn('next-tree: _renderTreeList received non-array data:', list); | |
| 352 | + return; | |
| 353 | + } | |
| 350 | 354 | list.forEach(item => { |
| 351 | 355 | const halfChecked = this.getHalfCheckedFormTreeData(item); |
| 352 | 356 | let ouputText = ''; |
| ... | ... | @@ -375,24 +379,25 @@ export default { |
| 375 | 379 | halfChecked, |
| 376 | 380 | disabled: this.disabledKey && item[this.disabledKey] === true |
| 377 | 381 | }) |
| 378 | - if ( | |
| 379 | - (Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length > 0) || | |
| 380 | - (this.loadData && Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length === 0) | |
| 381 | - ) { | |
| 382 | - let parentid = [...parentId], | |
| 383 | - parentArr = [...parents], | |
| 384 | - childrenid = []; | |
| 385 | - delete parentArr.children | |
| 386 | - parentid.push(item[this.valueKey]); | |
| 387 | - parentArr.push({ | |
| 388 | - [this.valueKey]: item[this.valueKey], | |
| 389 | - [this.labelKey]: item[this.labelKey], | |
| 390 | - "data": item | |
| 391 | - }) | |
| 392 | - this._renderTreeList(item[this.childrenKey], rank + 1, parentid, parentArr); | |
| 393 | - } else { | |
| 394 | - this.treeList[this.treeList.length - 1].lastRank = true; | |
| 395 | - } | |
| 382 | + const children = item[this.childrenKey]; | |
| 383 | + if ( | |
| 384 | + (Array.isArray(children) && children.length > 0) || | |
| 385 | + (this.loadData && Array.isArray(children) && children.length === 0) | |
| 386 | + ) { | |
| 387 | + let parentid = [...parentId], | |
| 388 | + parentArr = [...parents], | |
| 389 | + childrenid = []; | |
| 390 | + delete parentArr.children | |
| 391 | + parentid.push(item[this.valueKey]); | |
| 392 | + parentArr.push({ | |
| 393 | + [this.valueKey]: item[this.valueKey], | |
| 394 | + [this.labelKey]: item[this.labelKey], | |
| 395 | + "data": item | |
| 396 | + }) | |
| 397 | + this._renderTreeList(children, rank + 1, parentid, parentArr); | |
| 398 | + } else { | |
| 399 | + this.treeList[this.treeList.length - 1].lastRank = true; | |
| 400 | + } | |
| 396 | 401 | }) |
| 397 | 402 | }, |
| 398 | 403 | // 处理默认选择 |
| ... | ... | @@ -522,38 +527,39 @@ export default { |
| 522 | 527 | } else if (!this.showHalfCheckedTips) { |
| 523 | 528 | return false |
| 524 | 529 | } else { |
| 525 | - if (item[this.childrenKey] && item[this.childrenKey].length) { | |
| 526 | - return item[this.childrenKey].some(it => { | |
| 527 | - if (it.checked === true) { | |
| 528 | - return true; | |
| 529 | - } else if (it[this.childrenKey] && it[this.childrenKey].length) { | |
| 530 | - return this.getHalfCheckedFormTreeData(it); | |
| 531 | - } else { | |
| 532 | - return false; | |
| 533 | - }; | |
| 534 | - }); | |
| 535 | - } else { | |
| 536 | - return false; | |
| 537 | - } | |
| 530 | + const children = item[this.childrenKey]; | |
| 531 | + if (Array.isArray(children) && children.length) { | |
| 532 | + return children.some(it => { | |
| 533 | + if (it.checked === true) { | |
| 534 | + return true; | |
| 535 | + } else if (it[this.childrenKey] && Array.isArray(it[this.childrenKey]) && it[this.childrenKey].length) { | |
| 536 | + return this.getHalfCheckedFormTreeData(it); | |
| 537 | + } else { | |
| 538 | + return false; | |
| 539 | + }; | |
| 540 | + }); | |
| 541 | + } else { | |
| 542 | + return false; | |
| 543 | + } | |
| 538 | 544 | } |
| 539 | 545 | }, |
| 540 | 546 | getItemFromTreeData(treeData, id) { |
| 541 | - if (id) { | |
| 542 | - let item = null; | |
| 543 | - (treeData || []).some(it => { | |
| 544 | - if (it[this.valueKey] === id) { | |
| 545 | - item = it | |
| 546 | - return true | |
| 547 | - } else if (it[this.childrenKey] && it[this.childrenKey].length) { | |
| 548 | - item = this.getItemFromTreeData(it[this.childrenKey], id) | |
| 549 | - return !!item | |
| 550 | - } else { | |
| 551 | - return false | |
| 552 | - } | |
| 553 | - }); | |
| 554 | - return item | |
| 555 | - }; | |
| 556 | - return null | |
| 547 | + if (id) { | |
| 548 | + let item = null; | |
| 549 | + (treeData || []).some(it => { | |
| 550 | + if (it[this.valueKey] === id) { | |
| 551 | + item = it | |
| 552 | + return true | |
| 553 | + } else if (it[this.childrenKey] && Array.isArray(it[this.childrenKey]) && it[this.childrenKey].length) { | |
| 554 | + item = this.getItemFromTreeData(it[this.childrenKey], id) | |
| 555 | + return !!item | |
| 556 | + } else { | |
| 557 | + return false | |
| 558 | + } | |
| 559 | + }); | |
| 560 | + return item | |
| 561 | + }; | |
| 562 | + return null | |
| 557 | 563 | }, |
| 558 | 564 | _treeItemSelect(item, _index) { |
| 559 | 565 | const index = this.treeList.findIndex(it => it.id === item.id); |
| ... | ... | @@ -598,79 +604,87 @@ export default { |
| 598 | 604 | this._fixMultiple(index); |
| 599 | 605 | } |
| 600 | 606 | }, |
| 601 | - updateParentChecked(index) { | |
| 602 | - const parentId = (this.treeList[index].parentId || []).concat([]).reverse(); | |
| 603 | - if (parentId && parentId.length) { | |
| 604 | - parentId.map(id => { | |
| 605 | - const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); | |
| 606 | - const childrenIds = (parentTreeDataItem[this.childrenKey] || []).map(item => item[this.valueKey]); | |
| 607 | - const bool = this.treeList | |
| 608 | - .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 609 | - .every(it => it.checked === true); | |
| 607 | + updateParentChecked(index) { | |
| 608 | + const parentId = (this.treeList[index].parentId || []).concat([]).reverse(); | |
| 609 | + if (parentId && parentId.length) { | |
| 610 | + parentId.map(id => { | |
| 611 | + const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); | |
| 612 | + // 添加安全检查:确保parentTreeDataItem和childrenKey存在 | |
| 613 | + const children = parentTreeDataItem && parentTreeDataItem[this.childrenKey]; | |
| 614 | + if (!Array.isArray(children)) return; | |
| 610 | 615 | |
| 611 | - const _bool = this.treeList | |
| 612 | - .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 613 | - .every(it => it.checked === false); | |
| 616 | + const childrenIds = children.map(item => item[this.valueKey]); | |
| 617 | + const bool = this.treeList | |
| 618 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 619 | + .every(it => it.checked === true); | |
| 614 | 620 | |
| 615 | - const parentItem = this.treeList.find(it => it.id === id); | |
| 616 | - if (parentItem) { | |
| 617 | - if (this.checkStrictlyModel === 'weak') { | |
| 618 | - if (bool && !parentItem.disabled) { | |
| 619 | - parentItem.checked = true; | |
| 620 | - } else if (_bool && !parentItem.disabled) { | |
| 621 | - parentItem.checked = false; | |
| 622 | - } | |
| 623 | - } else if (this.checkStrictlyModel === 'strong') { | |
| 624 | - if (bool) { | |
| 625 | - parentItem.checked = true; | |
| 626 | - } else { | |
| 627 | - parentItem.checked = false; | |
| 628 | - } | |
| 629 | - } | |
| 630 | - } | |
| 631 | - }) | |
| 632 | - } | |
| 633 | - }, | |
| 634 | - updateHalfChecked(index) { | |
| 635 | - const _parentId = this.treeList[index].parentId || []; | |
| 636 | - const parentId = _parentId.concat([]).reverse(); | |
| 637 | - if (parentId && parentId.length) { | |
| 638 | - parentId.map(id => { | |
| 639 | - const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); | |
| 640 | - const childrenIds = (parentTreeDataItem[this.childrenKey] || []).map(item => item[this.valueKey]); | |
| 621 | + const _bool = this.treeList | |
| 622 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 623 | + .every(it => it.checked === false); | |
| 641 | 624 | |
| 642 | - const bool = this.treeList | |
| 643 | - .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 644 | - .every(it => it.checked === false && it.halfChecked === false); | |
| 625 | + const parentItem = this.treeList.find(it => it.id === id); | |
| 626 | + if (parentItem) { | |
| 627 | + if (this.checkStrictlyModel === 'weak') { | |
| 628 | + if (bool && !parentItem.disabled) { | |
| 629 | + parentItem.checked = true; | |
| 630 | + } else if (_bool && !parentItem.disabled) { | |
| 631 | + parentItem.checked = false; | |
| 632 | + } | |
| 633 | + } else if (this.checkStrictlyModel === 'strong') { | |
| 634 | + if (bool) { | |
| 635 | + parentItem.checked = true; | |
| 636 | + } else { | |
| 637 | + parentItem.checked = false; | |
| 638 | + } | |
| 639 | + } | |
| 640 | + } | |
| 641 | + }) | |
| 642 | + } | |
| 643 | + }, | |
| 644 | + updateHalfChecked(index) { | |
| 645 | + const _parentId = this.treeList[index].parentId || []; | |
| 646 | + const parentId = _parentId.concat([]).reverse(); | |
| 647 | + if (parentId && parentId.length) { | |
| 648 | + parentId.map(id => { | |
| 649 | + const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); | |
| 650 | + // 添加安全检查:确保parentTreeDataItem和childrenKey存在 | |
| 651 | + const children = parentTreeDataItem && parentTreeDataItem[this.childrenKey]; | |
| 652 | + if (!Array.isArray(children)) return; | |
| 645 | 653 | |
| 646 | - const _bool = this.treeList | |
| 647 | - .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 648 | - .some(it => it.checked === true || it.halfChecked === true); | |
| 654 | + const childrenIds = children.map(item => item[this.valueKey]); | |
| 649 | 655 | |
| 650 | - const parentItem = this.treeList.find(it => it.id === id); | |
| 651 | - if (parentItem) { | |
| 652 | - if (!parentItem.checked) { | |
| 653 | - if (bool) { | |
| 654 | - parentItem.halfChecked = false | |
| 655 | - } else if (_bool) { | |
| 656 | - parentItem.halfChecked = true | |
| 657 | - } else { | |
| 658 | - parentItem.halfChecked = false | |
| 659 | - } | |
| 660 | - } | |
| 661 | - } | |
| 662 | - }) | |
| 663 | - } | |
| 664 | - if (this.treeList[index].checked == false) { | |
| 665 | - const source = this.treeList[index].source || {}; | |
| 666 | - const children = source[this.childrenKey] || []; | |
| 667 | - const checkedKeyList = this.getChildrenKeys(children); | |
| 668 | - const bool = this.treeList.filter(item => checkedKeyList.indexOf(item.id) !== -1).some(item => item.checked); | |
| 669 | - if (bool) { | |
| 670 | - this.treeList[index].halfChecked = true; | |
| 671 | - } | |
| 672 | - } | |
| 673 | - }, | |
| 656 | + const bool = this.treeList | |
| 657 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 658 | + .every(it => it.checked === false && it.halfChecked === false); | |
| 659 | + | |
| 660 | + const _bool = this.treeList | |
| 661 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | |
| 662 | + .some(it => it.checked === true || it.halfChecked === true); | |
| 663 | + | |
| 664 | + const parentItem = this.treeList.find(it => it.id === id); | |
| 665 | + if (parentItem) { | |
| 666 | + if (!parentItem.checked) { | |
| 667 | + if (bool) { | |
| 668 | + parentItem.halfChecked = false | |
| 669 | + } else if (_bool) { | |
| 670 | + parentItem.halfChecked = true | |
| 671 | + } else { | |
| 672 | + parentItem.halfChecked = false | |
| 673 | + } | |
| 674 | + } | |
| 675 | + } | |
| 676 | + }) | |
| 677 | + } | |
| 678 | + if (this.treeList[index].checked == false) { | |
| 679 | + const source = this.treeList[index].source || {}; | |
| 680 | + const children = source[this.childrenKey] || []; | |
| 681 | + const checkedKeyList = this.getChildrenKeys(children); | |
| 682 | + const bool = this.treeList.filter(item => checkedKeyList.indexOf(item.id) !== -1).some(item => item.checked); | |
| 683 | + if (bool) { | |
| 684 | + this.treeList[index].halfChecked = true; | |
| 685 | + } | |
| 686 | + } | |
| 687 | + }, | |
| 674 | 688 | showHalfChecked(item) { |
| 675 | 689 | if (this.multiple && !this.checkStrictly && item.halfChecked === true) { |
| 676 | 690 | return true |
| ... | ... | @@ -678,16 +692,19 @@ export default { |
| 678 | 692 | return false |
| 679 | 693 | } |
| 680 | 694 | }, |
| 681 | - getChildrenKeys(children) { | |
| 682 | - let keys = []; | |
| 683 | - (children || []).map(item => { | |
| 684 | - keys.push(item[this.valueKey]) | |
| 685 | - if (item[this.childrenKey] && item[this.childrenKey].length) { | |
| 686 | - keys = keys.concat(this.getChildrenKeys(item[this.childrenKey])) | |
| 687 | - } | |
| 688 | - }) | |
| 689 | - return keys | |
| 690 | - }, | |
| 695 | + getChildrenKeys(children) { | |
| 696 | + let keys = []; | |
| 697 | + (children || []).map(item => { | |
| 698 | + // 添加安全检查:确保item和valueKey存在 | |
| 699 | + if (item && item[this.valueKey]) { | |
| 700 | + keys.push(item[this.valueKey]) | |
| 701 | + if (item[this.childrenKey] && Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length) { | |
| 702 | + keys = keys.concat(this.getChildrenKeys(item[this.childrenKey])) | |
| 703 | + } | |
| 704 | + } | |
| 705 | + }) | |
| 706 | + return keys | |
| 707 | + }, | |
| 691 | 708 | // 处理单选多选 |
| 692 | 709 | _fixMultiple(index) { |
| 693 | 710 | if (!this.multiple) { | ... | ... |
garbage-removal/src/pages/home-info/clean/index.vue
garbage-removal/src/pages/order-info/order-disposal/scan-detail/index.vue
| ... | ... | @@ -97,7 +97,8 @@ |
| 97 | 97 | import { |
| 98 | 98 | askTransport, |
| 99 | 99 | scanDetail, |
| 100 | - queryMileage | |
| 100 | + queryMileage, | |
| 101 | + queryLatitudeLongitude | |
| 101 | 102 | } from '@/apis/order.js'; |
| 102 | 103 | import { |
| 103 | 104 | onLoad |
| ... | ... | @@ -158,59 +159,47 @@ |
| 158 | 159 | const mileageData = JSON.parse(res.data.data); |
| 159 | 160 | details.value.transportDistance = mileageData.mileage+ ' 公里'; // 米转公里 |
| 160 | 161 | |
| 161 | - // 使用接口返回的定位信息 | |
| 162 | - if (mileageData.endLatitude && mileageData.endLongitude) { | |
| 163 | - location.value = { | |
| 164 | - latitude: mileageData.endLatitude, | |
| 165 | - longitude: mileageData.endLongitude | |
| 166 | - }; | |
| 167 | - } else { | |
| 168 | - // 当接口返回的定位信息为空时,调用手机定位 | |
| 169 | - console.log("接口返回的定位信息为空,尝试获取手机定位"); | |
| 170 | - details.value.transportDistance = "1 公里"; | |
| 171 | - getPhoneLocation(); | |
| 172 | - } | |
| 162 | + // 统一使用车辆实时定位接口(避免不同接口返回坐标差异) | |
| 163 | + await getLocationFromApi(); | |
| 173 | 164 | } else { |
| 174 | 165 | console.log("获取运距失败:" + res.data.msg); |
| 175 | - // 运距获取失败时,尝试获取手机定位 | |
| 166 | + // 运距获取失败时,同样使用车辆实时定位接口 | |
| 176 | 167 | details.value.transportDistance = "1 公里"; |
| 177 | - getPhoneLocation(); | |
| 168 | + await getLocationFromApi(); | |
| 178 | 169 | } |
| 179 | 170 | } catch (error) { |
| 180 | 171 | console.error("调用运距接口出错:", error); |
| 181 | 172 | details.value.transportDistance = "1 公里"; |
| 182 | - // 接口调用异常时,尝试获取手机定位 | |
| 183 | - getPhoneLocation(); | |
| 173 | + // 接口调用异常时,改为获取车辆实时定位 | |
| 174 | + await getLocationFromApi(); | |
| 184 | 175 | } |
| 185 | 176 | }; |
| 186 | 177 | |
| 187 | - const getPhoneLocation = () => { | |
| 188 | - // 设置5秒超时 | |
| 189 | - const timeout = setTimeout(() => { | |
| 190 | - uni.$u.toast('获取手机定位超时,请检查定位权限'); | |
| 191 | - }, 5000); | |
| 192 | - | |
| 193 | - // 调用uni.getLocation获取手机GPS定位 | |
| 194 | - uni.getLocation({ | |
| 195 | - type: 'gcj02', | |
| 196 | - success: (res) => { | |
| 197 | - clearTimeout(timeout); | |
| 198 | - console.log('手机定位获取成功', res); | |
| 199 | - location.value = { | |
| 200 | - latitude: res.latitude, | |
| 201 | - longitude: res.longitude | |
| 202 | - }; | |
| 203 | - uni.$u.toast('手机定位获取成功'); | |
| 204 | - }, | |
| 205 | - fail: (err) => { | |
| 206 | - clearTimeout(timeout); | |
| 207 | - console.error('手机定位获取失败', err); | |
| 208 | - uni.$u.toast('获取手机定位失败,请检查定位权限'); | |
| 209 | - }, | |
| 210 | - complete: () => { | |
| 211 | - clearTimeout(timeout); | |
| 178 | + // 通过接口获取车辆实时定位(coordinates 由后端/车辆服务统一口径) | |
| 179 | + const getLocationFromApi = async () => { | |
| 180 | + const carNo = details.value?.garHandlerCarCode; | |
| 181 | + if (!carNo) return; | |
| 182 | + | |
| 183 | + try { | |
| 184 | + const res = await queryLatitudeLongitude(carNo); | |
| 185 | + if (res?.data?.success) { | |
| 186 | + const data = res.data.data || {}; | |
| 187 | + if (typeof data.latitude !== "undefined" && typeof data.longitude !== "undefined") { | |
| 188 | + location.value = { | |
| 189 | + latitude: data.latitude, | |
| 190 | + longitude: data.longitude | |
| 191 | + }; | |
| 192 | + uni.$u.toast("车辆位置获取成功"); | |
| 193 | + } else { | |
| 194 | + uni.$u.toast("车辆位置返回为空"); | |
| 195 | + } | |
| 196 | + } else { | |
| 197 | + uni.$u.toast("车辆位置获取失败"); | |
| 212 | 198 | } |
| 213 | - }); | |
| 199 | + } catch (err) { | |
| 200 | + console.error("获取车辆位置失败:", err); | |
| 201 | + uni.$u.toast("车辆位置获取异常"); | |
| 202 | + } | |
| 214 | 203 | }; |
| 215 | 204 | |
| 216 | 205 | ... | ... |
garbage-removal/src/pages/order-info/order-driver/detail/guest/index.vue
| ... | ... | @@ -144,7 +144,7 @@ |
| 144 | 144 | <text class=" order-detail-container-header-title">装车照片:</text> |
| 145 | 145 | |
| 146 | 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"> | |
| 147 | + <view v-for="group in putOnImages" :key="group.index" class="image-group"> | |
| 148 | 148 | <view class="image-group-header"> |
| 149 | 149 | <view class="image-group-title">{{ group.carName}}第 {{ group.index }} 趟</view> |
| 150 | 150 | <!-- 根据group.index与真实发车数比较显示状态 --> | ... | ... |
garbage-removal/src/pages/order-info/order-driver/detail/index.vue
| ... | ... | @@ -19,12 +19,12 @@ |
| 19 | 19 | 订单信息 |
| 20 | 20 | </view> |
| 21 | 21 | <view class="order-detail-container-header-item" |
| 22 | - @click.stop="handlerJumpOtherApp(dataGram.garOrderAddress + dataGram.garOrderAddressDetails)"> | |
| 23 | - <text class="order-detail-container-header-title">清运地点:</text> | |
| 24 | - <view class="order-detail-container-header-content" style="text-decoration: underline"> | |
| 25 | - <text selectable='true'>{{ dataGram.garOrderAddress + dataGram.garOrderAddressDetails }}</text> | |
| 26 | - </view> | |
| 22 | + @click.stop="showNavDialog(dataGram.garLongitude,dataGram.garLatitude, dataGram.garOrderAddressDetails)"> | |
| 23 | + <text class="order-detail-container-header-title">清运地点:</text> | |
| 24 | + <view class="order-detail-container-header-content" style="text-decoration: underline"> | |
| 25 | + <text selectable='true'>{{ dataGram.garOrderAddress + dataGram.garOrderAddressDetails }}</text> | |
| 27 | 26 | </view> |
| 27 | + </view> | |
| 28 | 28 | <view class="order-detail-container-header-item"> |
| 29 | 29 | <text class="order-detail-container-header-title">现场图片:</text> |
| 30 | 30 | <view class="order-detail-container-header-content"> |
| ... | ... | @@ -57,7 +57,7 @@ |
| 57 | 57 | </view> |
| 58 | 58 | </view> |
| 59 | 59 | |
| 60 | - | |
| 60 | + | |
| 61 | 61 | <view class="order-detail-container-header-item"> |
| 62 | 62 | <text class="order-detail-container-header-title">订单号:</text> |
| 63 | 63 | <view class="order-detail-container-header-content"> |
| ... | ... | @@ -448,10 +448,37 @@ const handleContactClick = (val) => { |
| 448 | 448 | }).catch(err => { }); |
| 449 | 449 | } |
| 450 | 450 | |
| 451 | -const handlerJumpOtherApp = (locationName) => { | |
| 452 | - // 方案一:使用腾讯地图URI API(推荐) | |
| 453 | - // 构建腾讯地图搜索链接,使用更完整的参数 | |
| 454 | - window.location.href =`https://apis.map.qq.com/uri/v1/search?keyword=${encodeURIComponent(locationName)}®ion=${encodeURIComponent(locationName)}&referer=XICBZ-ALWKT-2KPXZ-VCBL7-XMRYO-2QFS4&policy=1`; | |
| 451 | +const showNavDialog = (longitude, latitude, locationName) => { | |
| 452 | + // 校验经纬度有效性 | |
| 453 | + if (!longitude || !latitude) { | |
| 454 | + uni.$u.toast('暂无有效导航坐标'); | |
| 455 | + return; | |
| 456 | + } | |
| 457 | + | |
| 458 | + uni.showActionSheet({ | |
| 459 | + itemList: ['高德导航', '百度导航'], | |
| 460 | + success: function (res) { | |
| 461 | + if (res.tapIndex === 0) { | |
| 462 | + // 调用你原来的高德导航方法 | |
| 463 | + handlerJumpGaoDeApp(longitude, latitude, locationName); | |
| 464 | + } else if (res.tapIndex === 1) { | |
| 465 | + // 调用你原来的百度导航方法 | |
| 466 | + handlerJumpBaiDuApp(longitude, latitude, locationName); | |
| 467 | + } | |
| 468 | + }, | |
| 469 | + fail: function (res) { | |
| 470 | + console.log('取消导航选择:', res.errMsg); | |
| 471 | + } | |
| 472 | + }); | |
| 473 | +}; | |
| 474 | +// ===== 新增结束 ===== | |
| 475 | + | |
| 476 | +const handlerJumpGaoDeApp = (longitude,latitude,locationName) => { | |
| 477 | + window.location.href =`https://uri.amap.com/marker?position=${longitude},${latitude}&name=${locationName}`; | |
| 478 | +} | |
| 479 | + | |
| 480 | +const handlerJumpBaiDuApp = (longitude,latitude,locationName) => { | |
| 481 | + window.location.href =`http://api.map.baidu.com/marker?location=${longitude},${latitude}&title=${locationName}&output=html`; | |
| 455 | 482 | } |
| 456 | 483 | |
| 457 | 484 | ... | ... |
garbage-removal/src/pages/order-info/order-other/detail/index.vue
| ... | ... | @@ -73,7 +73,7 @@ |
| 73 | 73 | <u-icon name="map" size="16" color="#19a97c" style="margin-right: 8rpx;"></u-icon> |
| 74 | 74 | <text>清运地点:</text> |
| 75 | 75 | </view> |
| 76 | - <view class="info-content" @click.stop="handlerJumpOtherApp(dataGram.garLatitude, dataGram.garLongitude, dataGram.garCoordinate)"> | |
| 76 | + <view class="info-content" @click.stop="showNavDialog(dataGram.garLongitude,dataGram.garLatitude, dataGram.garOrderAddressDetails)"> | |
| 77 | 77 | <text class="content-text" selectable='true'>{{ dataGram.garOrderAddress + dataGram.garOrderAddressDetails }}</text> |
| 78 | 78 | </view> |
| 79 | 79 | </view> |
| ... | ... | @@ -941,20 +941,84 @@ const handleOrderDispatchClick = (orderId) => { |
| 941 | 941 | // 获取订单车辆数量 |
| 942 | 942 | const orderCarCount = dataGram.value?.garCarInfoList?.length || 0; |
| 943 | 943 | |
| 944 | - // 获取驾驶员人员 | |
| 945 | - queryOrderDispatch(orderId).then(res => { | |
| 946 | - console.log(res.data.data); | |
| 947 | - if (res.data.success) { | |
| 948 | - // 过滤车辆 非用户选择的车辆无法选中 | |
| 949 | - driverPersonnelList.value = res.data.data; | |
| 950 | - // 恢复原始的open调用方式,只传递dataList | |
| 951 | - clashDriverDispatchRef.value.open(res.data.data); | |
| 952 | - refreshOrderData() | |
| 953 | - } else { | |
| 954 | - uni.$u.toast("驾驶员分配成功!"); | |
| 955 | - refreshOrderData() | |
| 944 | + // 在调用API前验证token有效性 | |
| 945 | + const validateTokenAndCallAPI = async () => { | |
| 946 | + try { | |
| 947 | + // 检查当前token是否存在 | |
| 948 | + if (!store.token) { | |
| 949 | + uni.$u.toast("登录已过期,请重新登录"); | |
| 950 | + // 跳转到登录页面 | |
| 951 | + uni.reLaunch({ | |
| 952 | + url: "/pages/login/code", | |
| 953 | + }); | |
| 954 | + return; | |
| 955 | + } | |
| 956 | + | |
| 957 | + // 获取驾驶员人员 - 添加时间戳避免缓存 | |
| 958 | + const timestamp = new Date().getTime(); | |
| 959 | + | |
| 960 | + // 添加重试机制 | |
| 961 | + let retryCount = 0; | |
| 962 | + const maxRetries = 2; | |
| 963 | + | |
| 964 | + const attemptRequest = async () => { | |
| 965 | + try { | |
| 966 | + const res = await queryOrderDispatch(`${orderId}?t=${timestamp}`); | |
| 967 | + | |
| 968 | + if (res.data.success) { | |
| 969 | + // 过滤车辆 非用户选择的车辆无法选中 | |
| 970 | + driverPersonnelList.value = res.data.data; | |
| 971 | + // 恢复原始的open调用方式,只传递dataList | |
| 972 | + clashDriverDispatchRef.value.open(res.data.data); | |
| 973 | + refreshOrderData(); | |
| 974 | + } else { | |
| 975 | + uni.$u.toast("驾驶员分配成功!"); | |
| 976 | + refreshOrderData(); | |
| 977 | + } | |
| 978 | + } catch (error) { | |
| 979 | + console.error('获取驾驶员信息失败:', error); | |
| 980 | + | |
| 981 | + // 检查是否是token相关错误 | |
| 982 | + if (error.response && (error.response.status === 401 || error.response.status === 403)) { | |
| 983 | + retryCount++; | |
| 984 | + | |
| 985 | + if (retryCount <= maxRetries) { | |
| 986 | + console.log(`token可能已过期,正在进行第${retryCount}次重试`); | |
| 987 | + | |
| 988 | + // 清除当前token | |
| 989 | + store.token = null; | |
| 990 | + setRequestToken(null); | |
| 991 | + uni.removeStorageSync("Authorization"); | |
| 992 | + | |
| 993 | + // 跳转重新登录 | |
| 994 | + uni.$u.toast("登录已过期,请重新登录"); | |
| 995 | + setTimeout(() => { | |
| 996 | + uni.reLaunch({ | |
| 997 | + url: "/pages/login/code", | |
| 998 | + }); | |
| 999 | + }, 1500); | |
| 1000 | + return; | |
| 1001 | + } | |
| 1002 | + } | |
| 1003 | + | |
| 1004 | + // 其他错误或重试次数用完 | |
| 1005 | + uni.$u.toast("获取驾驶员信息失败,请稍后重试"); | |
| 1006 | + } | |
| 1007 | + }; | |
| 1008 | + | |
| 1009 | + await attemptRequest(); | |
| 1010 | + | |
| 1011 | + } catch (error) { | |
| 1012 | + console.error('验证token时发生错误:', error); | |
| 1013 | + uni.$u.toast("系统错误,请重新登录"); | |
| 1014 | + uni.reLaunch({ | |
| 1015 | + url: "/pages/login/code", | |
| 1016 | + }); | |
| 956 | 1017 | } |
| 957 | - }) | |
| 1018 | + }; | |
| 1019 | + | |
| 1020 | + // 执行验证和API调用 | |
| 1021 | + validateTokenAndCallAPI(); | |
| 958 | 1022 | } |
| 959 | 1023 | const handleDisposalDispatchClick = (orderId) => { |
| 960 | 1024 | // 获取处置场所人员 |
| ... | ... | @@ -1575,6 +1639,39 @@ const submitUpdateCarInfo = () => { |
| 1575 | 1639 | }) |
| 1576 | 1640 | } |
| 1577 | 1641 | |
| 1642 | +const showNavDialog = (longitude, latitude, locationName) => { | |
| 1643 | + // 校验经纬度有效性 | |
| 1644 | + if (!longitude || !latitude) { | |
| 1645 | + uni.$u.toast('暂无有效导航坐标'); | |
| 1646 | + return; | |
| 1647 | + } | |
| 1648 | + | |
| 1649 | + uni.showActionSheet({ | |
| 1650 | + itemList: ['高德导航', '百度导航'], | |
| 1651 | + success: function (res) { | |
| 1652 | + if (res.tapIndex === 0) { | |
| 1653 | + // 调用你原来的高德导航方法 | |
| 1654 | + handlerJumpGaoDeApp(longitude, latitude, locationName); | |
| 1655 | + } else if (res.tapIndex === 1) { | |
| 1656 | + // 调用你原来的百度导航方法 | |
| 1657 | + handlerJumpBaiDuApp(longitude, latitude, locationName); | |
| 1658 | + } | |
| 1659 | + }, | |
| 1660 | + fail: function (res) { | |
| 1661 | + console.log('取消导航选择:', res.errMsg); | |
| 1662 | + } | |
| 1663 | + }); | |
| 1664 | +}; | |
| 1665 | +// ===== 新增结束 ===== | |
| 1666 | + | |
| 1667 | +const handlerJumpGaoDeApp = (longitude,latitude,locationName) => { | |
| 1668 | + window.location.href =`https://uri.amap.com/marker?position=${longitude},${latitude}&name=${locationName}`; | |
| 1669 | +} | |
| 1670 | + | |
| 1671 | +const handlerJumpBaiDuApp = (longitude,latitude,locationName) => { | |
| 1672 | + window.location.href =`http://api.map.baidu.com/marker?location=${longitude},${latitude}&title=${locationName}&output=html`; | |
| 1673 | +} | |
| 1674 | + | |
| 1578 | 1675 | |
| 1579 | 1676 | const deleteHandler = (handler) => { |
| 1580 | 1677 | uni.showModal({ | ... | ... |
garbage-removal/src/pages/order/order-disposal/index.vue
| 1 | 1 | <template> |
| 2 | - <view class="order-container"> | |
| 3 | - <!-- #ifdef H5 --> | |
| 4 | - <z-paging-swiper :fixed="false"> | |
| 5 | - <!-- #endif --> | |
| 6 | - <!-- #ifdef MP-WEIXIN --> | |
| 7 | - <z-paging-swiper> | |
| 8 | - <!-- #endif --> | |
| 9 | - <template v-slot:top> | |
| 10 | - <view class="header-box" :style="{ | |
| 2 | + <view class="order-container"> | |
| 3 | + <!-- #ifdef H5 --> | |
| 4 | + <z-paging-swiper :fixed="false"> | |
| 5 | + <!-- #endif --> | |
| 6 | + <!-- #ifdef MP-WEIXIN --> | |
| 7 | + <z-paging-swiper> | |
| 8 | + <!-- #endif --> | |
| 9 | + <template v-slot:top> | |
| 10 | + <view class="header-box" :style="{ | |
| 11 | 11 | 'height': lightHeight, 'line-height': lightHeight, |
| 12 | 12 | 'padding-top': topMargin |
| 13 | 13 | } |
| 14 | 14 | "> |
| 15 | - <view class="header-box-left-message"> | |
| 16 | - | |
| 17 | - </view> | |
| 18 | - <view class="header-box-title"> | |
| 19 | - {{ title }} | |
| 20 | - </view> | |
| 21 | - </view> | |
| 22 | - <u-tabs lineWidth=" 40" lineColor="#ffffff" lineHeight="6" | |
| 23 | - :activeStyle="{ 'color': '#ffffff', 'font-weight': 'bolder' }" | |
| 24 | - :inactiveStyle="{ color: '#ffffff' }" ref="uTabsElement" :list="displayList" :current="current" | |
| 25 | - @change="tabsChange" :scrollable="false"></u-tabs> | |
| 26 | - </template> | |
| 27 | - | |
| 28 | - <swiper class="swiper" :current="swiperCurrent" @translation="translation" | |
| 29 | - @animationfinish="animationfinish"> | |
| 30 | - <swiper-item class="swiper-item" v-for="( item, index ) in list " :key="index"> | |
| 31 | - <swiper-list-item :tabIndex="index" :currentIndex="swiperCurrent"></swiper-list-item> | |
| 32 | - </swiper-item> | |
| 33 | - </swiper> | |
| 34 | - | |
| 35 | - </z-paging-swiper> | |
| 36 | - | |
| 37 | - </view> | |
| 38 | - <view class="scan-box"> | |
| 15 | + <view class="header-box-left-message"> | |
| 16 | + | |
| 17 | + </view> | |
| 18 | + <view class="header-box-title"> | |
| 19 | + {{ title }} | |
| 20 | + </view> | |
| 21 | + </view> | |
| 22 | + <u-tabs lineWidth=" 40" lineColor="#ffffff" lineHeight="6" | |
| 23 | + :activeStyle="{ 'color': '#ffffff', 'font-weight': 'bolder' }" | |
| 24 | + :inactiveStyle="{ color: '#ffffff' }" ref="uTabsElement" :list="displayList" :current="current" | |
| 25 | + @change="tabsChange" :scrollable="false"></u-tabs> | |
| 26 | + </template> | |
| 27 | + | |
| 28 | + <swiper class="swiper" :current="swiperCurrent" @translation="translation" | |
| 29 | + @animationfinish="animationfinish"> | |
| 30 | + <swiper-item class="swiper-item" v-for="( item, index ) in list " :key="index"> | |
| 31 | + <swiper-list-item :tabIndex="index" :currentIndex="swiperCurrent"></swiper-list-item> | |
| 32 | + </swiper-item> | |
| 33 | + </swiper> | |
| 34 | + | |
| 35 | + </z-paging-swiper> | |
| 36 | + | |
| 37 | + </view> | |
| 38 | + <view class="scan-box"> | |
| 39 | 39 | <view class="scan-tip">在此处扫码</view> |
| 40 | - <view class="scan-btn"> | |
| 41 | - <view class="scan-icon"> | |
| 42 | - <!-- #ifdef H5 --> | |
| 43 | - <u-icon @click="handleScanH5" name="scan" :size="180" color="#fff"></u-icon> | |
| 44 | - <!-- #endif --> | |
| 45 | - </view> | |
| 46 | - </view> | |
| 47 | - </view> | |
| 48 | - <QrScannerVue v-if="showScan" @decode="onDecodeHandler" @close="qrReaderClose" /> | |
| 40 | + <view class="scan-btn"> | |
| 41 | + <view class="scan-icon"> | |
| 42 | + <!-- #ifdef H5 --> | |
| 43 | + <u-icon @click="handleScanH5" name="scan" :size="180" color="#fff"></u-icon> | |
| 44 | + <!-- #endif --> | |
| 45 | + </view> | |
| 46 | + </view> | |
| 47 | + </view> | |
| 48 | + <QrScannerVue v-if="showScan" @decode="onDecodeHandler" @close="qrReaderClose" /> | |
| 49 | 49 | </template> |
| 50 | 50 | |
| 51 | 51 | <script setup> |
| ... | ... | @@ -115,7 +115,7 @@ const handleScan = () => { |
| 115 | 115 | url: `pages/order-info/order-disposal/scan-detail/index`, |
| 116 | 116 | params: { |
| 117 | 117 | data: encodeURIComponent(JSON.stringify(res.data |
| 118 | - .data)) | |
| 118 | + .data)) | |
| 119 | 119 | } |
| 120 | 120 | }) |
| 121 | 121 | return |
| ... | ... | @@ -134,29 +134,36 @@ const handleScan = () => { |
| 134 | 134 | } |
| 135 | 135 | }); |
| 136 | 136 | } |
| 137 | -const takeLocation = () => { | |
| 138 | - window.JsInterface.takeLocation(); | |
| 139 | -} | |
| 140 | - | |
| 141 | -// 接收定位结果的回调函数 | |
| 142 | -const takeLocalCallBack = (lngLat) => { | |
| 143 | - const ll = lngLat.split(","); | |
| 144 | - location.value = { | |
| 145 | - longitude: ll[0], | |
| 146 | - latitude: ll[1] | |
| 147 | - }; | |
| 148 | -} | |
| 149 | - | |
| 150 | -// 设置全局回调 | |
| 151 | -onMounted(() => { | |
| 152 | - window.takeLocationCallBack = takeLocalCallBack | |
| 153 | -}) | |
| 154 | - | |
| 155 | -onLoad((options) => { | |
| 156 | - // 获取定位信息 | |
| 157 | - takeLocation(); | |
| 158 | -}); | |
| 159 | 137 | |
| 138 | +// 获取手机定位(GCJ-02 坐标系) | |
| 139 | +const getPhoneLocation = () => { | |
| 140 | + // 设置 5 秒超时 | |
| 141 | + const timeout = setTimeout(() => { | |
| 142 | + uni.$u.toast('获取手机定位超时,请检查定位权限'); | |
| 143 | + }, 5000); | |
| 144 | + | |
| 145 | + // 调用 uni.getLocation 获取手机 GPS 定位 | |
| 146 | + uni.getLocation({ | |
| 147 | + type: 'gcj02', | |
| 148 | + success: (res) => { | |
| 149 | + clearTimeout(timeout); | |
| 150 | + console.log('手机定位获取成功', res); | |
| 151 | + location.value = { | |
| 152 | + latitude: res.latitude, | |
| 153 | + longitude: res.longitude | |
| 154 | + }; | |
| 155 | + console.log('定位信息:', location.value); | |
| 156 | + }, | |
| 157 | + fail: (err) => { | |
| 158 | + clearTimeout(timeout); | |
| 159 | + console.error('手机定位获取失败', err); | |
| 160 | + uni.$u.toast('获取手机定位失败,请检查定位权限'); | |
| 161 | + }, | |
| 162 | + complete: () => { | |
| 163 | + clearTimeout(timeout); | |
| 164 | + } | |
| 165 | + }); | |
| 166 | +}; | |
| 160 | 167 | |
| 161 | 168 | const handleScanH5 = async () => { |
| 162 | 169 | showScan.value = true; |
| ... | ... | @@ -174,9 +181,9 @@ const handleScanH5 = async () => { |
| 174 | 181 | // if (error.message.includes("用户拒绝")) { |
| 175 | 182 | // uni.$u.toast("请允许访问位置信息以验证卸货地址"); |
| 176 | 183 | // } else if (error.message.includes("安全来源")) { |
| 177 | - // uni.$u.toast("当前环境不支持位置验证,请使用HTTPS访问"); | |
| 184 | + // uni.$u.toast("当前环境不支持位置验证,请使用 HTTPS 访问"); | |
| 178 | 185 | // } else { |
| 179 | - // uni.$u.toast("位置验证失败: " + error.message); | |
| 186 | + // uni.$u.toast("位置验证失败:" + error.message); | |
| 180 | 187 | // } |
| 181 | 188 | // } |
| 182 | 189 | } |
| ... | ... | @@ -199,7 +206,7 @@ const validateUnloadingSite = async (location) => { |
| 199 | 206 | site.garLongitude // 使用 garLongitude |
| 200 | 207 | ); |
| 201 | 208 | console.log(distance) |
| 202 | - return distance <= 200; // 200米范围内 | |
| 209 | + return distance <= 200; // 200 米范围内 | |
| 203 | 210 | }); |
| 204 | 211 | } catch (error) { |
| 205 | 212 | console.error('验证卸货地址失败:', error); |
| ... | ... | @@ -221,26 +228,26 @@ const calculateDistance = (lat1, lng1, lat2, lng2) => { |
| 221 | 228 | ) |
| 222 | 229 | ); |
| 223 | 230 | |
| 224 | - return distance * 6371000; // 地球半径(米) | |
| 231 | + return distance * 6371000; // 地球半径 (米) | |
| 225 | 232 | } |
| 226 | 233 | |
| 227 | 234 | const onDecodeHandler = (data) => { |
| 228 | 235 | showScan.value = false |
| 229 | 236 | try { |
| 230 | - checkCode(data).then(res => { | |
| 231 | - console.log(res); | |
| 232 | - if (res.data.code == 200) { | |
| 233 | - uni.$u.route({ | |
| 234 | - url: `pages/order-info/order-disposal/scan-detail/index`, | |
| 235 | - params: { | |
| 236 | - data: encodeURIComponent(JSON.stringify(res.data | |
| 237 | - .data)) | |
| 238 | - } | |
| 239 | - }) | |
| 240 | - return | |
| 241 | - } | |
| 242 | - alert(res.data.msg); | |
| 243 | - }) | |
| 237 | + checkCode(data).then(res => { | |
| 238 | + console.log(res); | |
| 239 | + if (res.data.code == 200) { | |
| 240 | + uni.$u.route({ | |
| 241 | + url: `pages/order-info/order-disposal/scan-detail/index`, | |
| 242 | + params: { | |
| 243 | + data: encodeURIComponent(JSON.stringify(res.data | |
| 244 | + .data)) | |
| 245 | + } | |
| 246 | + }) | |
| 247 | + return | |
| 248 | + } | |
| 249 | + alert(res.data.msg); | |
| 250 | + }) | |
| 244 | 251 | } catch (error) { |
| 245 | 252 | alert("无法确认当前二维码趟次,请扫描正在进行的运输趟次"); |
| 246 | 253 | } |
| ... | ... | @@ -253,7 +260,7 @@ const getOrderCountByType = (tabIndex) => { |
| 253 | 260 | const type = tabIndex === 0 ? 1 : 3; |
| 254 | 261 | queryOrderList({ type, pageNo: 1, pageSize: 1 }).then((res) => { |
| 255 | 262 | if (res.data && res.data.data) { |
| 256 | - // 这里假设接口返回的total是订单总数 | |
| 263 | + // 这里假设接口返回的 total 是订单总数 | |
| 257 | 264 | list.value[tabIndex].count = res.data.data.total || 0; |
| 258 | 265 | } |
| 259 | 266 | }).catch(() => { |
| ... | ... | @@ -284,6 +291,11 @@ onMounted(() => { |
| 284 | 291 | getAllOrderCounts(); |
| 285 | 292 | }) |
| 286 | 293 | }) |
| 294 | + | |
| 295 | +onLoad((options) => { | |
| 296 | + // 获取定位信息 | |
| 297 | + getPhoneLocation(); | |
| 298 | +}); | |
| 287 | 299 | </script> |
| 288 | 300 | <style lang="scss" scoped> |
| 289 | 301 | .scanCode { | ... | ... |
garbage-removal/src/pages/wode/index.vue
| ... | ... | @@ -130,6 +130,8 @@ const handleLoginOut = () => { |
| 130 | 130 | if (res.confirm) { |
| 131 | 131 | loginOut().then(res => { |
| 132 | 132 | if (res.data.success) { |
| 133 | + // 清除所有缓存 | |
| 134 | + clearAllCache(); | |
| 133 | 135 | store.token = null; |
| 134 | 136 | setRequestToken(); |
| 135 | 137 | uni.$u.toast("已退出") |
| ... | ... | @@ -146,6 +148,77 @@ const handleLoginOut = () => { |
| 146 | 148 | }); |
| 147 | 149 | } |
| 148 | 150 | |
| 151 | +// 清除所有缓存的函数 | |
| 152 | +const clearAllCache = () => { | |
| 153 | + try { | |
| 154 | + // 1. 清除Pinia持久化存储 | |
| 155 | + store.$reset(); | |
| 156 | + | |
| 157 | + // 2. 清除所有本地存储 | |
| 158 | + const storageKeys = [ | |
| 159 | + 'cancelFlag', | |
| 160 | + 'refreshFlag', | |
| 161 | + 'Z-PAGING-CONFIG-STORAGE-KEY' | |
| 162 | + ]; | |
| 163 | + | |
| 164 | + // 获取所有存储的key并清除 | |
| 165 | + const allKeys = getAllStorageKeys(); | |
| 166 | + allKeys.forEach(key => { | |
| 167 | + // 保留一些必要的系统key,清除业务相关的key | |
| 168 | + if (!isSystemKey(key)) { | |
| 169 | + uni.removeStorageSync(key); | |
| 170 | + } | |
| 171 | + }); | |
| 172 | + | |
| 173 | + // 3. 清除z-paging相关缓存 | |
| 174 | + clearZPagingCache(); | |
| 175 | + | |
| 176 | + // 4. 清除请求token | |
| 177 | + setRequestToken(); | |
| 178 | + | |
| 179 | + console.log('所有缓存已清除'); | |
| 180 | + } catch (error) { | |
| 181 | + console.error('清除缓存时发生错误:', error); | |
| 182 | + } | |
| 183 | +}; | |
| 184 | + | |
| 185 | +// 获取所有存储的key | |
| 186 | +const getAllStorageKeys = () => { | |
| 187 | + const res = uni.getStorageInfoSync(); | |
| 188 | + return res.keys || []; | |
| 189 | +}; | |
| 190 | + | |
| 191 | +// 判断是否为系统保留的key | |
| 192 | +const isSystemKey = (key) => { | |
| 193 | + // 系统保留的key,不要清除 | |
| 194 | + const systemKeys = [ | |
| 195 | + '__webviewId__', | |
| 196 | + '__uniapp__', | |
| 197 | + '__UNI__', | |
| 198 | + // 可以根据实际情况添加其他系统key | |
| 199 | + ]; | |
| 200 | + | |
| 201 | + return systemKeys.some(systemKey => key.includes(systemKey)); | |
| 202 | +}; | |
| 203 | + | |
| 204 | +// 清除z-paging缓存 | |
| 205 | +const clearZPagingCache = () => { | |
| 206 | + try { | |
| 207 | + // 清除z-paging配置缓存 | |
| 208 | + uni.removeStorageSync('Z-PAGING-CONFIG-STORAGE-KEY'); | |
| 209 | + | |
| 210 | + // 清除所有z-paging缓存前缀的数据 | |
| 211 | + const allKeys = getAllStorageKeys(); | |
| 212 | + allKeys.forEach(key => { | |
| 213 | + if (key.startsWith('z-paging-cache')) { | |
| 214 | + uni.removeStorageSync(key); | |
| 215 | + } | |
| 216 | + }); | |
| 217 | + } catch (error) { | |
| 218 | + console.error('清除z-paging缓存时发生错误:', error); | |
| 219 | + } | |
| 220 | +}; | |
| 221 | + | |
| 149 | 222 | |
| 150 | 223 | </script> |
| 151 | 224 | ... | ... |
garbage-removal/src/utils/request/request.js
| ... | ... | @@ -61,28 +61,38 @@ instance.interceptors.request.use((config) => { |
| 61 | 61 | }); |
| 62 | 62 | // 响应拦截器 |
| 63 | 63 | instance.interceptors.response.use((response) => { |
| 64 | - | |
| 65 | 64 | // 没有网络时 message的内容为"Network Error" |
| 66 | 65 | if (response.errMsg === "request:fail") { |
| 67 | 66 | uni.$u.toast("网络错误~") |
| 68 | 67 | return response; |
| 69 | 68 | } |
| 69 | + | |
| 70 | + // 特别处理queryOrderDispatch相关的401/403错误 | |
| 71 | + const url = response.config?.url || ''; | |
| 72 | + const isOrderDispatchRequest = url.includes('/order/queryDispatch/'); | |
| 73 | + | |
| 70 | 74 | if (response.data.code != 200) { |
| 71 | 75 | // 对于匿名访问的页面,不处理401和403错误 |
| 72 | - const url = response.config?.url || ''; | |
| 73 | 76 | const isGuestAccess = url.startsWith("/order-info/order-other/webDetail/") || |
| 74 | 77 | url.startsWith("/order-info/order-driver/detail/guest/")|| |
| 75 | 78 | url.startsWith("/gar/car/requestStrByEnergyType"); |
| 76 | 79 | |
| 77 | 80 | if (response.data.code == 401 || response.data.code == 403) { |
| 78 | 81 | if (!isGuestAccess) { |
| 82 | + // 如果是订单分配相关的请求,给出明确提示 | |
| 83 | + if (isOrderDispatchRequest) { | |
| 84 | + uni.$u.toast("登录已过期,请重新登录"); | |
| 85 | + } | |
| 79 | 86 | reSetLoginStatus(); |
| 80 | 87 | } |
| 81 | 88 | } else { |
| 82 | - uni.showToast({ | |
| 83 | - title: response.data.msg, | |
| 84 | - icon: "none", | |
| 85 | - }); | |
| 89 | + // 非权限错误才显示具体错误信息 | |
| 90 | + if (!isOrderDispatchRequest || response.data.code !== 401) { | |
| 91 | + uni.showToast({ | |
| 92 | + title: response.data.msg, | |
| 93 | + icon: "none", | |
| 94 | + }); | |
| 95 | + } | |
| 86 | 96 | } |
| 87 | 97 | } |
| 88 | 98 | return response; |
| ... | ... | @@ -92,18 +102,32 @@ instance.interceptors.response.use((response) => { |
| 92 | 102 | const isGuestAccess = url.startsWith("/order-info/order-other/webDetail/") || |
| 93 | 103 | url.startsWith("/order-info/order-driver/detail/guest/")|| |
| 94 | 104 | url.startsWith("/gar/car/requestStrByEnergyType"); |
| 105 | + const isOrderDispatchRequest = url.includes('/order/queryDispatch/'); | |
| 95 | 106 | |
| 96 | - if (error.response.status) { | |
| 107 | + if (error.response && error.response.status) { | |
| 97 | 108 | switch (error.response.status) { |
| 98 | 109 | case 401: |
| 99 | 110 | case 403: |
| 100 | 111 | if (!isGuestAccess) { |
| 112 | + // 订单分配请求的特殊处理 | |
| 113 | + if (isOrderDispatchRequest) { | |
| 114 | + uni.$u.toast("登录已过期,请重新登录"); | |
| 115 | + } | |
| 101 | 116 | reSetLoginStatus(); |
| 102 | 117 | } |
| 103 | 118 | break; |
| 104 | 119 | default: |
| 120 | + // 其他HTTP错误 | |
| 121 | + if (!isOrderDispatchRequest) { | |
| 122 | + uni.$u.toast("请求失败,请稍后重试"); | |
| 123 | + } | |
| 105 | 124 | break; |
| 106 | 125 | } |
| 126 | + } else { | |
| 127 | + // 网络错误 | |
| 128 | + if (!isOrderDispatchRequest) { | |
| 129 | + uni.$u.toast("网络连接异常"); | |
| 130 | + } | |
| 107 | 131 | } |
| 108 | 132 | return Promise.reject(error) |
| 109 | 133 | }); | ... | ... |