Commit 7b66c349a9fa1be581853b3a56cd9b4850afff2f

Authored by 2c2c2c
1 parent 70490f92

改变文件上传,用安卓原生拍照

garbage-removal/.env.local
1 -VITE_BASE_URL=http://192.169.1.125:8080/workflow 1 +VITE_BASE_URL=http://192.169.1.98:8080/workflow
2 VITE_BASE_FILE_UPLOAD_PREFIX=/order/upload 2 VITE_BASE_FILE_UPLOAD_PREFIX=/order/upload
3 -VITE_STOMP_URL=http://192.169.1.125:8080/ws 3 +VITE_STOMP_URL=http://192.169.1.98:8080/ws
garbage-removal/package-lock.json
@@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
33 "sass": "1.58.3", 33 "sass": "1.58.3",
34 "sass-loader": "13.2.0", 34 "sass-loader": "13.2.0",
35 "uqrcodejs": "^4.0.7", 35 "uqrcodejs": "^4.0.7",
  36 + "vconsole": "^3.15.1",
36 "vue": "^3.2.45", 37 "vue": "^3.2.45",
37 "vue-i18n": "^9.1.9", 38 "vue-i18n": "^9.1.9",
38 "vue3-qr-reader": "^1.0.0" 39 "vue3-qr-reader": "^1.0.0"
@@ -5400,6 +5401,17 @@ @@ -5400,6 +5401,17 @@
5400 "dev": true, 5401 "dev": true,
5401 "license": "MIT" 5402 "license": "MIT"
5402 }, 5403 },
  5404 + "node_modules/copy-text-to-clipboard": {
  5405 + "version": "3.2.0",
  5406 + "resolved": "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz",
  5407 + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==",
  5408 + "engines": {
  5409 + "node": ">=12"
  5410 + },
  5411 + "funding": {
  5412 + "url": "https://github.com/sponsors/sindresorhus"
  5413 + }
  5414 + },
5403 "node_modules/core-js": { 5415 "node_modules/core-js": {
5404 "version": "3.33.2", 5416 "version": "3.33.2",
5405 "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.33.2.tgz", 5417 "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.33.2.tgz",
@@ -9293,6 +9305,11 @@ @@ -9293,6 +9305,11 @@
9293 "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 9305 "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
9294 "license": "MIT" 9306 "license": "MIT"
9295 }, 9307 },
  9308 + "node_modules/mutation-observer": {
  9309 + "version": "1.0.3",
  9310 + "resolved": "https://registry.npmmirror.com/mutation-observer/-/mutation-observer-1.0.3.tgz",
  9311 + "integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
  9312 + },
9296 "node_modules/nanoid": { 9313 "node_modules/nanoid": {
9297 "version": "3.3.7", 9314 "version": "3.3.7",
9298 "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", 9315 "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
@@ -11328,6 +11345,17 @@ @@ -11328,6 +11345,17 @@
11328 "node": ">= 0.8" 11345 "node": ">= 0.8"
11329 } 11346 }
11330 }, 11347 },
  11348 + "node_modules/vconsole": {
  11349 + "version": "3.15.1",
  11350 + "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz",
  11351 + "integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==",
  11352 + "dependencies": {
  11353 + "@babel/runtime": "^7.17.2",
  11354 + "copy-text-to-clipboard": "^3.0.1",
  11355 + "core-js": "^3.11.0",
  11356 + "mutation-observer": "^1.0.3"
  11357 + }
  11358 + },
11331 "node_modules/vite": { 11359 "node_modules/vite": {
11332 "version": "4.0.3", 11360 "version": "4.0.3",
11333 "resolved": "https://registry.npmmirror.com/vite/-/vite-4.0.3.tgz", 11361 "resolved": "https://registry.npmmirror.com/vite/-/vite-4.0.3.tgz",
garbage-removal/package.json
@@ -65,6 +65,7 @@ @@ -65,6 +65,7 @@
65 "sass": "1.58.3", 65 "sass": "1.58.3",
66 "sass-loader": "13.2.0", 66 "sass-loader": "13.2.0",
67 "uqrcodejs": "^4.0.7", 67 "uqrcodejs": "^4.0.7",
  68 + "vconsole": "^3.15.1",
68 "vue": "^3.2.45", 69 "vue": "^3.2.45",
69 "vue-i18n": "^9.1.9", 70 "vue-i18n": "^9.1.9",
70 "vue3-qr-reader": "^1.0.0" 71 "vue3-qr-reader": "^1.0.0"
garbage-removal/src/apis/common.js
@@ -6,7 +6,7 @@ export const uploadFilePromise = async (requestPath, url) => { @@ -6,7 +6,7 @@ export const uploadFilePromise = async (requestPath, url) => {
6 return new Promise((resolve, reject) => { 6 return new Promise((resolve, reject) => {
7 let a = uni.uploadFile({ 7 let a = uni.uploadFile({
8 url: requestPath, // 仅为示例,非真实的接口地址 8 url: requestPath, // 仅为示例,非真实的接口地址
9 - filePath: url, 9 + file: url,
10 name: 'file', 10 name: 'file',
11 header: { 11 header: {
12 "Authorization": store.token 12 "Authorization": store.token
garbage-removal/src/main.js
@@ -4,6 +4,7 @@ import * as Pinia from 'pinia'; @@ -4,6 +4,7 @@ import * as Pinia from 'pinia';
4 import piniaPersistUni from "pinia-plugin-persist-uni"; 4 import piniaPersistUni from "pinia-plugin-persist-uni";
5 import { createSSRApp } from "vue"; 5 import { createSSRApp } from "vue";
6 import mixin from './common/mixin'; 6 import mixin from './common/mixin';
  7 +import Vconsole from 'vconsole'
7 8
8 // 引入uView对小程序分享的mixin封装 9 // 引入uView对小程序分享的mixin封装
9 import mpShare from '@/uview-plus/libs/mixin/mpShare.js'; 10 import mpShare from '@/uview-plus/libs/mixin/mpShare.js';
@@ -52,6 +53,7 @@ export function createApp() { @@ -52,6 +53,7 @@ export function createApp() {
52 // 配置uView 53 // 配置uView
53 // 调用setConfig方法,方法内部会进行对象属性深度合并,可以放心嵌套配置 54 // 调用setConfig方法,方法内部会进行对象属性深度合并,可以放心嵌套配置
54 // 需要在app.use(uview-plus)之后执行 55 // 需要在app.use(uview-plus)之后执行
  56 + new Vconsole();
55 uni.$u.setConfig({ 57 uni.$u.setConfig({
56 // 修改$u.config对象的属性 58 // 修改$u.config对象的属性
57 config: { 59 config: {
garbage-removal/src/pages.json
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 { 18 {
19 "path": "pages/login/index", 19 "path": "pages/login/index",
20 "style": { 20 "style": {
21 - "navigationBarTitleText": "长沙清运通智慧功能模块登录", 21 + "navigationBarTitleText": "",
22 "enablePullDownRefresh": false 22 "enablePullDownRefresh": false
23 } 23 }
24 },{ 24 },{
garbage-removal/src/pages/home-info/clean/index.vue
1 <template> 1 <template>
2 - <view id="ccccccccccccc">  
3 - <scroll-view :scroll-top="scrollTop" scroll-y="true">  
4 - <view class="mask-box">  
5 - <address-popup ref="addressPopupRef" @currentChange="currentChange"></address-popup>  
6 - <liu-delivery-time :isMask="true" :change="changeTime" ref="chooseTime" title="请选择预约时间">  
7 - </liu-delivery-time>  
8 - </view>  
9 - <view class="company-clean-container">  
10 -  
11 - <view class="company-clean-container-box">  
12 - <view class="company-clean-container-header">  
13 - <view class="company-clean-container-header-address">  
14 - {{ userAddress.garUserAddress }}{{ userAddress.garRemark }}  
15 - </view>  
16 - <view class="company-clean-container-header-base-info">  
17 - <view class="company-clean-container-header-base-info-left">  
18 - {{ userAddress.garUserContactName }} {{ userAddress.garUserContactTel }}  
19 - </view>  
20 - <view class="company-clean-container-header-base-info-right">  
21 - <view class="company-clean-container-header-base-info-right-icon">  
22 - <image width="35" height="35" :src="changeAddressUrl" @click="handlerChooseAddress"></image>  
23 - </view>  
24 - </view>  
25 - </view>  
26 - <view @click.stop="handleTimeChoose" class="company-clean-container-header-reservation">  
27 - <view class="company-clean-container-header-reservation-left">  
28 - <text style="color: red;">*</text> <u-icon name="calendar" size="40"></u-icon>预约时间  
29 - </view>  
30 - <view class="company-clean-container-header-reservation-right">  
31 - <text style="margin-right: 10rpx;">{{ dayTime ? dayTime : "请选择时间" }}</text> <u-icon name="arrow-right"  
32 - size="25"></u-icon>  
33 - </view>  
34 - </view>  
35 - </view>  
36 -  
37 - <view class="company-clean-container-car-main">  
38 - <view class="company-clean-container-car-main-content">  
39 - <view class="company-clean-container-car-main-content-type">  
40 - <view class="company-clean-container-car-main-content-type-price-area">  
41 - <text style="color: red;">*</text>选择车型: {{carName}}  
42 - </view>  
43 - </view>  
44 -  
45 - <view>  
46 - <swiper :class="swiperClass" @change="onChangeSwiper" indicator-dots circular="true" easing-function="linear" duration="2000">  
47 - <swiper-item v-for="(car,index) in garCarInfoList" :key="index" >  
48 - <view><image :src="combinationImagePath(car)" mode ="widthFix"></image></view>  
49 - <view><text style="color:#909399;font-size: 14px;">{{car.remark}}</text></view>  
50 - </swiper-item>  
51 - </swiper>  
52 - </view>  
53 -  
54 - <view class="company-clean-container-car-main-content-type">  
55 - <view class="company-clean-container-car-main-content-type-price-area">  
56 - <text style="color: red;">*</text>车辆容积:  
57 - </view>  
58 - <view style=" width:100%;display:flex; color:#909399; align-items: center;">  
59 - <text>{{containerVolume}} 方</text>  
60 - </view>  
61 - </view>  
62 -  
63 - <view class="company-clean-container-car-main-content-type">  
64 - <view class="company-clean-container-car-main-content-type-price-area">  
65 - <text style="color: red;">*</text>添加车辆数量:  
66 - </view>  
67 - <view style=" width:100%;display:flex; color:#909399; align-items: center;">  
68 - <u-number-box :min="0" :max="9999" integer buttonSize="46" :inputWidth="100" :disabledInput="true" v-model="carNumber[swiperIndex]" @change="numberBoxChange"></u-number-box>  
69 - </view>  
70 - </view>  
71 -  
72 -  
73 - <view class="company-clean-container-car-main-content-type">  
74 - <view class="company-clean-container-car-main-content-type-price-area">  
75 - <text style="color: red;">*</text>垃圾类型:  
76 - </view>  
77 - <view style=" width:100%;display:flex; color:#909399; align-items: center;">  
78 - <myPiker :parentValue="paramFrom.garbageType" :title="'垃圾类型'" @change="handlePickerGarbageTypeConfirm"  
79 - :array="garbageTypeList">  
80 - </myPiker>  
81 - </view>  
82 - </view>  
83 -  
84 -  
85 - <view class="company-clean-container-car-main-content-type">  
86 - <view class="company-clean-container-car-main-content-type-price-area">  
87 - <text style="color: red;">*</text>进入地下车库:  
88 - </view>  
89 - <view style="width:100%;display: flex;justify-content: flex-start;align-items: center; ">  
90 - <view style="display: flex; align-items: center;">  
91 - <up-radio-group shape="square" size="34" v-model="paramFrom.garInCarStore" placement="row"  
92 - @change="handleInCarClick">  
93 - <up-radio activeColor="#19a97c" labelSize="32" iconSize="30" :customStyle="{ marginRight: '30rpx' }" label="需要"  
94 - :name="true">  
95 - </up-radio>  
96 - <up-radio activeColor="#19a97c" labelSize="32" iconSize="30" :customStyle="{ marginRight: '30rp' }" label="不需要"  
97 - :name="false">  
98 - </up-radio>  
99 - </up-radio-group>  
100 - </view>  
101 - </view>  
102 - </view>  
103 - <view v-if="paramFrom.garInCarStore" class="company-in-car-store-box-info">  
104 - <view class="company-clean-container-site-image-info-input-remark-box">  
105 - <u--textarea v-model="paramFrom.remark" placeholder="请填写限制高度(米)"></u--textarea>  
106 - </view>  
107 - <!-- <view class="company-clean-container-car-main-content-remark" style="margin-top: 20rpx; font-size: 23rpx;"> 2 + <view id="ccccccccccccc">
  3 + <scroll-view :scroll-top="scrollTop" scroll-y="true">
  4 + <view class="mask-box">
  5 + <address-popup ref="addressPopupRef" @currentChange="currentChange"></address-popup>
  6 + <liu-delivery-time :isMask="true" :change="changeTime" ref="chooseTime" title="请选择预约时间">
  7 + </liu-delivery-time>
  8 + </view>
  9 + <view class="company-clean-container">
  10 +
  11 + <view class="company-clean-container-box">
  12 + <view class="company-clean-container-header">
  13 + <view class="company-clean-container-header-address">
  14 + {{ userAddress.garUserAddress }}{{ userAddress.garRemark }}
  15 + </view>
  16 + <view class="company-clean-container-header-base-info">
  17 + <view class="company-clean-container-header-base-info-left">
  18 + {{ userAddress.garUserContactName }} {{ userAddress.garUserContactTel }}
  19 + </view>
  20 + <view class="company-clean-container-header-base-info-right">
  21 + <view class="company-clean-container-header-base-info-right-icon">
  22 + <image width="35" height="35" :src="changeAddressUrl" @click="handlerChooseAddress">
  23 + </image>
  24 + </view>
  25 + </view>
  26 + </view>
  27 + <view @click.stop="handleTimeChoose" class="company-clean-container-header-reservation">
  28 + <view class="company-clean-container-header-reservation-left">
  29 + <text style="color: red;">*</text> <u-icon name="calendar" size="40"></u-icon>预约时间
  30 + </view>
  31 + <view class="company-clean-container-header-reservation-right">
  32 + <text style="margin-right: 10rpx;">{{ dayTime ? dayTime : "请选择时间" }}</text> <u-icon
  33 + name="arrow-right" size="25"></u-icon>
  34 + </view>
  35 + </view>
  36 + </view>
  37 +
  38 + <view class="company-clean-container-car-main">
  39 + <view class="company-clean-container-car-main-content">
  40 + <view class="company-clean-container-car-main-content-type">
  41 + <view class="company-clean-container-car-main-content-type-price-area">
  42 + <text style="color: red;">*</text>选择车型: {{carName}}
  43 + </view>
  44 + </view>
  45 +
  46 + <view>
  47 + <swiper :class="swiperClass" @change="onChangeSwiper" indicator-dots circular="true"
  48 + easing-function="linear" duration="2000">
  49 + <swiper-item v-for="(car,index) in garCarInfoList" :key="index">
  50 + <view>
  51 + <image :src="combinationImagePath(car)" mode="widthFix"></image>
  52 + </view>
  53 + <view><text style="color:#909399;font-size: 14px;">{{car.remark}}</text></view>
  54 + </swiper-item>
  55 + </swiper>
  56 + </view>
  57 +
  58 + <view class="company-clean-container-car-main-content-type">
  59 + <view class="company-clean-container-car-main-content-type-price-area">
  60 + <text style="color: red;">*</text>车辆容积:
  61 + </view>
  62 + <view style=" width:100%;display:flex; color:#909399; align-items: center;">
  63 + <text>{{containerVolume}} 方</text>
  64 + </view>
  65 + </view>
  66 +
  67 + <view class="company-clean-container-car-main-content-type">
  68 + <view class="company-clean-container-car-main-content-type-price-area">
  69 + <text style="color: red;">*</text>添加车辆数量:
  70 + </view>
  71 + <view style=" width:100%;display:flex; color:#909399; align-items: center;">
  72 + <u-number-box :min="0" :max="9999" integer buttonSize="46" :inputWidth="100"
  73 + :disabledInput="true" v-model="carNumber[swiperIndex]"
  74 + @change="numberBoxChange"></u-number-box>
  75 + </view>
  76 + </view>
  77 +
  78 +
  79 + <view class="company-clean-container-car-main-content-type">
  80 + <view class="company-clean-container-car-main-content-type-price-area">
  81 + <text style="color: red;">*</text>垃圾类型:
  82 + </view>
  83 + <view style=" width:100%;display:flex; color:#909399; align-items: center;">
  84 + <myPiker :parentValue="paramFrom.garbageType" :title="'垃圾类型'"
  85 + @change="handlePickerGarbageTypeConfirm" :array="garbageTypeList">
  86 + </myPiker>
  87 + </view>
  88 + </view>
  89 +
  90 +
  91 + <view class="company-clean-container-car-main-content-type">
  92 + <view class="company-clean-container-car-main-content-type-price-area">
  93 + <text style="color: red;">*</text>进入地下车库:
  94 + </view>
  95 + <view
  96 + style="width:100%;display: flex;justify-content: flex-start;align-items: center; ">
  97 + <view style="display: flex; align-items: center;">
  98 + <up-radio-group shape="square" size="34" v-model="paramFrom.garInCarStore"
  99 + placement="row" @change="handleInCarClick">
  100 + <up-radio activeColor="#19a97c" labelSize="32" iconSize="30"
  101 + :customStyle="{ marginRight: '30rpx' }" label="需要" :name="true">
  102 + </up-radio>
  103 + <up-radio activeColor="#19a97c" labelSize="32" iconSize="30"
  104 + :customStyle="{ marginRight: '30rp' }" label="不需要" :name="false">
  105 + </up-radio>
  106 + </up-radio-group>
  107 + </view>
  108 + </view>
  109 + </view>
  110 + <view v-if="paramFrom.garInCarStore" class="company-in-car-store-box-info">
  111 + <view class="company-clean-container-site-image-info-input-remark-box">
  112 + <u--textarea v-model="paramFrom.remark" placeholder="请填写限制高度(米)"></u--textarea>
  113 + </view>
  114 + <!-- <view class="company-clean-container-car-main-content-remark" style="margin-top: 20rpx; font-size: 23rpx;">
108 提示:需要进入车库需要写车辆限高,部门车库限高2.3m,如果装修垃圾在车库,要考虑车辆是否能进入。 115 提示:需要进入车库需要写车辆限高,部门车库限高2.3m,如果装修垃圾在车库,要考虑车辆是否能进入。
109 </view> --> 116 </view> -->
110 - </view>  
111 - <view class="company-clean-container-car-main-content-prompt">  
112 - 温馨提示:垃圾类型不符合,企业有权拒绝清运。  
113 - </view>  
114 - </view>  
115 - </view>  
116 - <view class="company-clean-container-site-image-info">  
117 - <view class="company-clean-container-site-image-info-remark">  
118 - <text style="color: red;" @click="openPhone">*测试</text>请上传垃圾量照片(至少1张,最多5张),照片须看清全貌。  
119 - </view>  
120 - <view class="company-clean-container-site-image-info-img">  
121 - <u-upload width="200" height="150" :fileList="fileList" @afterRead="afterRead" :deletable="deletable"  
122 - @delete="deletePic" name="5" multiple :maxCount="5" :previewFullImage="true"></u-upload>  
123 - </view>  
124 - </view>  
125 - <view class="company-clean-container-site-image-info-sure-button">  
126 - <view class="company-clean-container-site-image-info-sure-button-radio">  
127 - <view @click="changeAgree">  
128 - <u-checkbox-group v-model="paramFrom.sureReadFlag" placement="row">  
129 - <u-checkbox activeColor="#19a97c" :customStyle="{ marginBottom: '0px', marginTop: '1px' }" size="30"  
130 - labelSize="28" shape="square" :key="0" :name="true" :labelDisabled="true" iconSize="28"  
131 - labelColor="#909399"></u-checkbox>  
132 - </u-checkbox-group>  
133 - </view>  
134 - <view>  
135 - 本人完全同意<text class="link">《装修垃圾收运意向协议》</text>且已确认信息真实有效,并承担相应法律责任。  
136 - </view>  
137 - </view>  
138 - </view>  
139 - </view>  
140 -  
141 - <view class="company-clean-bottom" style="z-index: 10074;">  
142 - <view class="company-clean-bottom-box">  
143 - <view class="company-clean-bottom-left">  
144 - <view class="company-clean-bottom-left-icon">  
145 - <u-icon :stop="true" size="50" name="car-fill"></u-icon>  
146 - </view>  
147 - <view class="company-clean-bottom-left-number">  
148 - <up-badge :type="type" max="99" :value="garCarNumberCount"></up-badge>  
149 - </view>  
150 - </view>  
151 - <view class="company-clean-bottom-right">  
152 - <u-button @click="handleOderSure" shape="square" color="#19a97c" text="立即下单"></u-button>  
153 - </view>  
154 - </view>  
155 - </view>  
156 -  
157 -  
158 -  
159 - <view v-if="!carPopupShowFlag" ref="movableAreaElement" >  
160 - <uni-fab horizontal="right" vertical="bottom" popMenu="false" @fabClick="handleContactClick(tel)"></uni-fab>  
161 - </view>  
162 - </view>  
163 -</scroll-view>  
164 -</view> 117 + </view>
  118 + <view class="company-clean-container-car-main-content-prompt">
  119 + 温馨提示:垃圾类型不符合,企业有权拒绝清运。
  120 + </view>
  121 + </view>
  122 + </view>
  123 + <view class="company-clean-container-site-image-info">
  124 + <view class="company-clean-container-site-image-info-remark">
  125 + <text style="color: red;">*</text>请上传垃圾量照片(至少1张,最多5张),照片须看清全貌。
  126 + </view>
  127 + <view class="company-clean-container-site-image-info-img">
  128 + <u-upload width="200" height="150" :fileList="fileList" @afterRead="afterRead"
  129 + :deletable="deletable" @delete="deletePic" name="5" multiple :maxCount="5"
  130 + :previewFullImage="true"></u-upload>
  131 + </view>
  132 + </view>
  133 + <view class="company-clean-container-site-image-info-sure-button">
  134 + <view class="company-clean-container-site-image-info-sure-button-radio">
  135 + <view @click="changeAgree">
  136 + <u-checkbox-group v-model="paramFrom.sureReadFlag" placement="row">
  137 + <u-checkbox activeColor="#19a97c"
  138 + :customStyle="{ marginBottom: '0px', marginTop: '1px' }" size="30"
  139 + labelSize="28" shape="square" :key="0" :name="true" :labelDisabled="true"
  140 + iconSize="28" labelColor="#909399"></u-checkbox>
  141 + </u-checkbox-group>
  142 + </view>
  143 + <view>
  144 + 本人完全同意<text class="link">《装修垃圾收运意向协议》</text>且已确认信息真实有效,并承担相应法律责任。
  145 + </view>
  146 + </view>
  147 + </view>
  148 + </view>
  149 +
  150 + <view class="company-clean-bottom" style="z-index: 10074;">
  151 + <view class="company-clean-bottom-box">
  152 + <view class="company-clean-bottom-left">
  153 + <view class="company-clean-bottom-left-icon">
  154 + <u-icon :stop="true" size="50" name="car-fill"></u-icon>
  155 + </view>
  156 + <view class="company-clean-bottom-left-number">
  157 + <up-badge :type="type" max="99" :value="garCarNumberCount"></up-badge>
  158 + </view>
  159 + </view>
  160 + <view class="company-clean-bottom-right">
  161 + <u-button @click="handleOderSure" shape="square" color="#19a97c" text="立即下单"></u-button>
  162 + </view>
  163 + </view>
  164 + </view>
  165 +
  166 +
  167 +
  168 + <view v-if="!carPopupShowFlag" ref="movableAreaElement">
  169 + <uni-fab horizontal="right" vertical="bottom" popMenu="false"
  170 + @fabClick="handleContactClick(tel)"></uni-fab>
  171 + </view>
  172 + </view>
  173 + </scroll-view>
  174 + </view>
165 </template> 175 </template>
166 <script setup> 176 <script setup>
167 -import { queryAddress } from '@/apis/address.js';  
168 -import { queryCarList } from '@/apis/carinfo.js';  
169 -import { uploadFilePromise } from '@/apis/common.js';  
170 -import { saveOrder } from '@/apis/order.js';  
171 -import addressPopup from '@/components/address-popup/address-popup.vue';  
172 -import liuDeliveryTime from "@/components/liu-delivery-time/liu-delivery-time.vue";  
173 -import myPiker from '@/components/my-piker/index.vue';  
174 -import changeAddressUrl from '@/static/image/change-address.png';  
175 -import garbageUrl from '@/static/image/garbage.png';  
176 -import { useMainStore } from '@/stores/index.js';  
177 -import { onLoad } from '@dcloudio/uni-app';  
178 -import { computed, getCurrentInstance, ref, watch } from 'vue';  
179 -const { proxy } = getCurrentInstance();  
180 -const store = useMainStore();  
181 -const userType = computed(() => store.userType)  
182 -const x = ref(360)  
183 -const y = ref(650)  
184 -const movableAreaElement = ref()  
185 -const deletable = ref(false)  
186 -const companyObj = ref()  
187 -const tel = ref()  
188 -const carName=ref("")  
189 -const carTypeShowFlag = ref(false)  
190 -const garbageTypeShowFlag = ref(false)  
191 -const carPopupShowFlag = ref(false)  
192 -const addressPopupRef = ref(null);  
193 -const swiperClass=ref("swiperHeight1")  
194 -const pageStyle=ref("")  
195 -const userAddress = ref({  
196 - garUserContactName: "",  
197 - garUserContactTel: "",  
198 - garRemark: "",  
199 - garUserAddress: "",  
200 - garCoordinate: "",  
201 - garLongitude: "",  
202 - garLatitude: "",  
203 -})  
204 -const isCallBtn = ref(false);  
205 -// 车辆信息  
206 -const garCarInfoList = ref({})  
207 -const garCarLabelInfoList = ref({})  
208 -const garCarLabelInfoNow = ref()  
209 -const swiperIndex =ref(0)  
210 -const containerVolume=ref("")  
211 -const carNumber=ref([]);  
212 -const scrollTop=ref(0)  
213 -// 车辆数量  
214 -const garCarNumberCount = ref()  
215 -const garbageTypeList = ref(["装修垃圾", "建筑垃圾"])  
216 -const paramFrom = ref({  
217 - carNumber: 0,  
218 - remark: "",  
219 - sureReadFlag: [],  
220 - carType: "",  
221 - garbageType: "装修垃圾",  
222 - garInCarStore: false,  
223 - garEstimatedCost:""  
224 -})  
225 -const dayTime = ref()  
226 -const dayTimeType =ref()  
227 -  
228 -const chooseTime = ref()  
229 -const fileList = ref([  
230 - {  
231 - url: garbageUrl,  
232 - label: '预览'  
233 - }  
234 -])  
235 -const candidates = ref([])  
236 -const handleTimeChoose = () => {  
237 - chooseTime.value.open();  
238 -}  
239 -  
240 -const openPhone = () => {  
241 - alert("网页调试---->>> 拍照点击事件 调用安卓层功能 ");  
242 - window.JsInterface.takePhone();  
243 -}  
244 -  
245 -const takePhoneCallBack = (path) => {  
246 - //如果用户不授予权限 或者没有权限 获取拍照之后没确定 不会过这里  
247 - //最好也是判断 path 非空的时候 去处理逻辑  
248 - alert("网页调试---->>> 拍照后回调 路径=" + path); 177 + import {
  178 + queryAddress
  179 + } from '@/apis/address.js';
  180 + import {
  181 + queryCarList
  182 + } from '@/apis/carinfo.js';
  183 + import {
  184 + uploadFilePromise
  185 + } from '@/apis/common.js';
  186 + import {
  187 + saveOrder
  188 + } from '@/apis/order.js';
  189 + import addressPopup from '@/components/address-popup/address-popup.vue';
  190 + import liuDeliveryTime from "@/components/liu-delivery-time/liu-delivery-time.vue";
  191 + import myPiker from '@/components/my-piker/index.vue';
  192 + import changeAddressUrl from '@/static/image/change-address.png';
  193 + import garbageUrl from '@/static/image/garbage.png';
  194 + import {
  195 + useMainStore
  196 + } from '@/stores/index.js';
  197 + import {
  198 + onLoad
  199 + } from '@dcloudio/uni-app';
  200 + import {
  201 + computed,
  202 + getCurrentInstance,
  203 + ref,
  204 + watch,
  205 + onMounted,
  206 + onBeforeUnmount
  207 + } from 'vue';
  208 + const {
  209 + proxy
  210 + } = getCurrentInstance();
  211 + const store = useMainStore();
  212 + const userType = computed(() => store.userType)
  213 + const x = ref(360)
  214 + const y = ref(650)
  215 + const movableAreaElement = ref()
  216 + const deletable = ref(false)
  217 + const companyObj = ref()
  218 + const tel = ref()
  219 + const carName = ref("")
  220 + const carTypeShowFlag = ref(false)
  221 + const garbageTypeShowFlag = ref(false)
  222 + const carPopupShowFlag = ref(false)
  223 + const addressPopupRef = ref(null);
  224 + const swiperClass = ref("swiperHeight1")
  225 + const pageStyle = ref("")
  226 + const userAddress = ref({
  227 + garUserContactName: "",
  228 + garUserContactTel: "",
  229 + garRemark: "",
  230 + garUserAddress: "",
  231 + garCoordinate: "",
  232 + garLongitude: "",
  233 + garLatitude: "",
  234 + })
  235 + const isCallBtn = ref(false);
  236 + // 车辆信息
  237 + const garCarInfoList = ref({})
  238 + const garCarLabelInfoList = ref({})
  239 + const garCarLabelInfoNow = ref()
  240 + const swiperIndex = ref(0)
  241 + const containerVolume = ref("")
  242 + const carNumber = ref([]);
  243 + const scrollTop = ref(0)
  244 + // 车辆数量
  245 + const garCarNumberCount = ref()
  246 + const garbageTypeList = ref(["装修垃圾", "建筑垃圾"])
  247 + const paramFrom = ref({
  248 + carNumber: 0,
  249 + remark: "",
  250 + sureReadFlag: [],
  251 + carType: "",
  252 + garbageType: "装修垃圾",
  253 + garInCarStore: false,
  254 + garEstimatedCost: ""
  255 + })
  256 + const dayTime = ref()
  257 + const dayTimeType = ref()
  258 +
  259 + const chooseTime = ref()
  260 + const fileList = ref([{
  261 + url: garbageUrl,
  262 + label: '预览'
  263 + }])
  264 + const candidates = ref([])
  265 +
  266 + const photoPath = ref(null)
  267 +
  268 + const handleTimeChoose = () => {
  269 + chooseTime.value.open();
  270 + }
  271 +
  272 + const changeTime = (e) => {
  273 + dayTime.value = e.value
  274 +
  275 + if (e.startHour == "00:00" || e.startHour == "01:00" || e.startHour == "02:00" || e.startHour == "03:00" || e
  276 + .startHour == "04:00" || e.startHour == "05:00" ||
  277 + e.startHour == "06:00" || e.startHour == "22:00" || e.startHour == "23:00") {
  278 + dayTimeType.value = "2207";
  279 +
  280 + } else {
  281 + dayTimeType.value = "";
  282 + if (swiperClass.value == "swiperHeight3") {
  283 + jumpPrompt("中大型车辆只能选择22:00-07:00时间段")
  284 + }
  285 + }
  286 +
  287 +
  288 + }
  289 + const changeAgree = (e) => {
  290 + // paramFrom.value.sureReadFlag = e
  291 + paramFrom.value.sureReadFlag[0] = !paramFrom.value.sureReadFlag[0]
  292 + }
  293 + const onChange = (e) => {}
  294 +
  295 + const onChangeSwiper = (e) => {
  296 + if (garCarInfoList.value) {
  297 + carName.value = garCarInfoList.value[e.detail.current].carType;
  298 + swiperIndex.value = e.detail.current;
  299 + containerVolume.value = garCarInfoList.value[e.detail.current].containerVolume;
  300 + if (garCarInfoList.value[e.detail.current].containerVolume == "4") {
  301 + swiperClass.value = "swiperHeight1";
  302 + } else if (garCarInfoList.value[e.detail.current].containerVolume == "6") {
  303 + swiperClass.value = "swiperHeight2";
  304 + } else {
  305 + swiperClass.value = "swiperHeight3";
  306 +
  307 + if (dayTimeType.value == '2207') {
  308 +
  309 + } else if ((dayTime.value != null && dayTime.value != "" && dayTime.value != undefined) &&
  310 + garCarInfoList.value[e.detail.current].containerVolume && parseFloat(garCarInfoList.value[e.detail
  311 + .current].containerVolume) >= 8) {
  312 + jumpPrompt("中大型车辆只能选择22:00-07:00时间段")
  313 + }
  314 + }
  315 +
  316 +
  317 + }
  318 +
  319 + }
  320 +
  321 + const numberBoxChange = (value) => {
  322 + garCarInfoList.value[swiperIndex.value].garOrderCarNumber = value.value;
  323 + carNumber.value[swiperIndex.value] = value.value;
  324 + if (!garCarNumberCount.value) {
  325 + garCarNumberCount.value = 0;
  326 + }
  327 + let va = 0;
  328 + console.log(garCarInfoList.value[swiperIndex.value].garOrderCarNumber);
  329 + carNumber.value.forEach(function(item, index, arr) {
  330 + if (item) {
  331 + va = va + item;
  332 + }
  333 + })
  334 +
  335 + garCarNumberCount.value = va;
  336 + }
  337 + /**
  338 + * 初始化信息
  339 + */
  340 + onLoad((options) => {
  341 + initOptions(options);
  342 + })
  343 +
  344 +
  345 + const combinationImagePath = (car) => {
  346 + return import.meta.env.VITE_BASE_URL + "/" + car.carLeft;
  347 + }
  348 +
  349 + const initOptions = async (options) => {
  350 + companyObj.value = JSON.parse(options.companyObj);
  351 + tel.value = options.tel;
  352 + await queryAddress('CURRENT').then(res => {
  353 + try {
  354 + if (res.data.data && res.data.data[0]) {
  355 + userAddress.value = res.data.data[0] ? res.data.data[0] : {}
  356 + } else {
  357 + userAddress.value = {};
  358 + }
  359 + } catch (error) {
  360 + userAddress.value = {};
  361 + }
  362 + })
  363 + if (!userAddress.value.garLongitude) {
  364 + uni.$u.toast("请设置清运地址!")
  365 + // 返回上级
  366 + uni.navigateBack({
  367 + delta: 1
  368 + })
  369 + return
  370 + }
  371 + queryCarList({
  372 + companyId: companyObj.value.id
  373 + }).then(res => {
  374 +
  375 + garCarInfoList.value = res.data.rows;
  376 + if (garCarInfoList.value[0]) {
  377 + carName.value = garCarInfoList.value[0].carType;
  378 + containerVolume.value = garCarInfoList.value[0].containerVolume;
  379 + }
  380 + })
  381 + }
  382 +
  383 + const handleInCarClick = (val) => {
  384 + // paramFrom.value.garInCarStore = !paramFrom.value.garInCarStore
  385 + }
  386 + /**
  387 + * 拨打电话回调
  388 + */
  389 + const handleContactClick = (val) => {
  390 + console.log("点击了电话");
  391 + if (isCallBtn.value) {
  392 + uni.makePhoneCall({
  393 + phoneNumber: val
  394 + }).then(res => {}).catch(err => {});
  395 + }
  396 + }
  397 +
  398 + // 删除图片
  399 + const deletePic = (event) => {
  400 + fileList.value.splice(event.index, 1);
  401 + };
  402 +
  403 + // 新增图片
  404 + const afterRead = async (event) => {
  405 + // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
  406 + let lists = [].concat(event.file);
  407 +
  408 + lists.map((item) => {
  409 + fileList.value.push({
  410 + ...item,
  411 + status: 'uploading',
  412 + message: '上传中',
  413 + });
  414 + });
  415 + let fileListLen = fileList.value.length--;
  416 + // 将blob转为file对象的方法
  417 + function blobToFile(blob, fileName) {
  418 + return new File([blob], fileName, {
  419 + type: 'image/png'
  420 + })
  421 + }
  422 + for (let i = 0; i < lists.length; i++) {
  423 + // 获取blob对象
  424 + fetch(lists[i].url)
  425 + .then(response => response.blob())
  426 + .then(blob => {
  427 + // 将blob转换为file
  428 + let fileN = blobToFile(blob, lists[i].name)
  429 + // 上传file对象
  430 + let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env
  431 + .VITE_BASE_FILE_UPLOAD_PREFIX;
  432 + uploadFilePromise(requestPath, fileN).then(result => {
  433 + let item = fileList.value[fileListLen];
  434 + fileList.value.splice(fileListLen, 1, {
  435 + ...item,
  436 + status: 'success',
  437 + message: '',
  438 + url: result.data.url,
  439 + });
  440 + fileListLen++;
  441 + });
  442 +
  443 + })
  444 +
  445 +
  446 + }
  447 + fileList.value = fileList.value.filter(item => {
  448 + deletable.value = true
  449 + return !item.label
  450 + })
  451 + };
  452 +
  453 +
  454 + const handlePickerGarbageTypeConfirm = (e) => {
  455 + paramFrom.value.garbageType = e
  456 + garbageTypeShowFlag.value = false
  457 + }
  458 + const handlePickerCarInfoConfirm = (e) => {
  459 + paramFrom.value.carType = e
  460 + garCarLabelInfoNow.value = garCarLabelInfoList.value[paramFrom.value.carType]
  461 + carTypeShowFlag.value = false
  462 + }
  463 +
  464 + const orderClick = ref(true)
  465 + /**
  466 + * 处理下单
  467 + */
  468 + const handleOderSure = async () => {
  469 + let garCarInfos = [];
  470 + for (const key in garCarInfoList.value) {
  471 + if (garCarInfoList.value[key] && garCarInfoList.value[key].garOrderCarNumber && garCarInfoList.value[
  472 + key].garOrderCarNumber > 0) {
  473 + garCarInfos.push(garCarInfoList.value[key]);
  474 + }
  475 +
  476 + }
  477 + if (dayTime.value != null && dayTime.value != "" && dayTime.value != undefined) {
  478 + if (dayTimeType.value != '2207') {
  479 + let length = garCarInfos.length;
  480 + for (let index = 0; index < length; index++) {
  481 +
  482 + if (garCarInfos[index].containerVolume && parseFloat(garCarInfos[index].containerVolume) >=
  483 + 8) {
  484 + jumpPrompt("中大型车辆只能选择22:00-07:00时间段");
  485 +
  486 + return;
  487 + }
  488 +
  489 + }
249 } 490 }
  491 + }
  492 +
  493 +
  494 +
  495 + let params = {
  496 + /**
  497 + * 订单地址
  498 + */
  499 + garOrderAddress: userAddress.value.garUserAddress,
  500 +
  501 + /**
  502 + * 订单详细地址
  503 + */
  504 + garOrderAddressDetails: userAddress.value.garRemark,
  505 +
  506 + /**
  507 + * 订单姓名
  508 + */
  509 + garOrderContactName: userAddress.value.garUserContactName,
  510 + garCarInfoList: garCarInfos,
  511 +
  512 + /**
  513 + * 垃圾类型
  514 + */
  515 + garOrderTrashType: paramFrom.value.garbageType,
  516 +
  517 + /**
  518 + * 订单人电话
  519 + */
  520 + garOrderContactTel: userAddress.value.garUserContactTel,
  521 +
  522 + /**
  523 + * 承接经营单位
  524 + */
  525 + garOrderCompanyId: companyObj.value.id,
  526 +
  527 + /**
  528 + * 公司名称
  529 + */
  530 + garOrderCompanyName: companyObj.value.name,
  531 +
  532 + /**
  533 + * 公司负责人电话
  534 + */
  535 + garOrderCompanyTel: companyObj.value.servicePhone,
  536 +
  537 + /**
  538 + * 约定时间
  539 + */
  540 + garOrderAgreementTime: dayTime.value,
  541 + /**
  542 + * 备注
  543 + */
  544 + garRemark: paramFrom.value.remark,
  545 + /**
  546 + * 图片列表
  547 + */
  548 + imageUrls: fileList.value.filter(item => !item.label).map(item => item.url),
  549 + garLongitude: userAddress.value.garLongitude,
  550 + garLatitude: userAddress.value.garLatitude,
  551 + garCoordinate: userAddress.value.garCoordinate,
  552 + garInCarStore: paramFrom.value.garInCarStore
  553 + }
  554 + console.log("----------------------->5");
  555 + if (!validateParams(params)) {
  556 + console.log("未通过", params);
  557 +
  558 + return;
  559 + }
  560 +
  561 + // 请求防抖
  562 + if (orderClick.value) {
  563 + orderClick.value = false
  564 + setTimeout(async () => {
  565 + orderClick.value = true
  566 + await handlerSaveOrder(params);
  567 + }, 800);
  568 + } else {
  569 + uni.$u.toast("请勿频繁操作")
  570 + }
  571 + }
  572 + const handlerSaveOrder = async (params) => {
  573 + await saveOrder(params).then(res => {
  574 + if (res.data.success) {
  575 + if (userType.value != "用户") {
  576 + uni.$u.toast("下单成功,请切换成且角色查看订单详情")
  577 + uni.$u.route({
  578 + type: 'navigateBack',
  579 + url: `pages/home/index`,
  580 + })
  581 + } else {
  582 + uni.$u.toast('下单成功')
  583 + uni.$u.route({
  584 + type: "redirect",
  585 + url: `pages/order-info/order-other/detail/index`,
  586 + params: {
  587 + orderId: res.data.data
  588 + }
  589 + })
  590 + }
  591 + }
  592 + })
  593 + }
250 594
251 -const changeTime = (e) => {  
252 - dayTime.value = e.value  
253 -  
254 - if(e.startHour=="00:00" || e.startHour=="01:00" || e.startHour=="02:00" || e.startHour=="03:00" ||e.startHour=="04:00" || e.startHour=="05:00"  
255 - || e.startHour=="06:00" || e.startHour=="22:00" ||e.startHour=="23:00"){  
256 - dayTimeType.value = "2207";  
257 -  
258 - }else{  
259 - dayTimeType.value = "";  
260 - if( swiperClass.value == "swiperHeight3"){  
261 - jumpPrompt("中大型车辆只能选择22:00-07:00时间段")  
262 - }  
263 - }  
264 -  
265 -  
266 -}  
267 -const changeAgree = (e) => {  
268 - // paramFrom.value.sureReadFlag = e  
269 - paramFrom.value.sureReadFlag[0] = !paramFrom.value.sureReadFlag[0]  
270 -}  
271 -const onChange = (e) => {  
272 -}  
273 -  
274 -const onChangeSwiper=(e)=>{  
275 - if(garCarInfoList.value){  
276 - carName.value=garCarInfoList.value[e.detail.current].carType;  
277 - swiperIndex.value = e.detail.current;  
278 - containerVolume.value = garCarInfoList.value[e.detail.current].containerVolume;  
279 - if(garCarInfoList.value[e.detail.current].containerVolume=="4"){  
280 - swiperClass.value = "swiperHeight1";  
281 - }else if(garCarInfoList.value[e.detail.current].containerVolume=="6"){  
282 - swiperClass.value = "swiperHeight2";  
283 - }else{  
284 - swiperClass.value = "swiperHeight3";  
285 -  
286 - if(dayTimeType.value == '2207'){  
287 -  
288 - }else if((dayTime.value != null && dayTime.value != "" && dayTime.value != undefined) && garCarInfoList.value[e.detail.current].containerVolume && parseFloat(garCarInfoList.value[e.detail.current].containerVolume) >= 8){  
289 - jumpPrompt("中大型车辆只能选择22:00-07:00时间段")  
290 - }  
291 - }  
292 -  
293 -  
294 - }  
295 -  
296 -}  
297 -  
298 -const numberBoxChange=(value)=>{  
299 - garCarInfoList.value[swiperIndex.value].garOrderCarNumber=value.value;  
300 - carNumber.value[swiperIndex.value]=value.value;  
301 - if(!garCarNumberCount.value){  
302 - garCarNumberCount.value=0;  
303 - }  
304 - let va = 0;  
305 - console.log(garCarInfoList.value[swiperIndex.value].garOrderCarNumber);  
306 - carNumber.value.forEach(function(item,index,arr){  
307 - if(item){  
308 - va = va+item;  
309 - }  
310 - })  
311 -  
312 - garCarNumberCount.value = va;  
313 -}  
314 -/**  
315 - * 初始化信息  
316 - */  
317 -onLoad((options) => {  
318 - initOptions(options);  
319 -})  
320 -  
321 -  
322 -const combinationImagePath=(car)=>{  
323 - return import.meta.env.VITE_BASE_URL+"/"+car.carLeft;  
324 -}  
325 -  
326 -const initOptions = async (options) => {  
327 - companyObj.value = JSON.parse(options.companyObj);  
328 - tel.value = options.tel;  
329 - await queryAddress('CURRENT').then(res => {  
330 - try {  
331 - if (res.data.data && res.data.data[0]) {  
332 - userAddress.value = res.data.data[0] ? res.data.data[0] : {}  
333 - } else {  
334 - userAddress.value = {};  
335 - }  
336 - } catch (error) {  
337 - userAddress.value = {};  
338 - }  
339 - })  
340 - if (!userAddress.value.garLongitude) {  
341 - uni.$u.toast("请设置清运地址!")  
342 - // 返回上级  
343 - uni.navigateBack({  
344 - delta: 1  
345 - })  
346 - return  
347 - }  
348 - queryCarList({ companyId: companyObj.value.id }).then(res => {  
349 -  
350 - garCarInfoList.value=res.data.rows;  
351 - if(garCarInfoList.value[0]){  
352 - carName.value=garCarInfoList.value[0].carType;  
353 - containerVolume.value=garCarInfoList.value[0].containerVolume;  
354 - }  
355 - })  
356 -}  
357 -  
358 -const handleInCarClick = (val) => {  
359 - // paramFrom.value.garInCarStore = !paramFrom.value.garInCarStore  
360 -}  
361 -/**  
362 - * 拨打电话回调  
363 - */  
364 -const handleContactClick = (val) => {  
365 - console.log("点击了电话");  
366 - if (isCallBtn.value) {  
367 - uni.makePhoneCall({ phoneNumber: val }).then(res => {  
368 - }).catch(err => { });  
369 - }  
370 -}  
371 -  
372 -// 删除图片  
373 -const deletePic = (event) => {  
374 - fileList.value.splice(event.index, 1);  
375 -};  
376 -  
377 -// 新增图片  
378 -const afterRead = async (event) => {  
379 - // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式  
380 - let lists = [].concat(event.file);  
381 - let fileListLen = fileList.value.length;  
382 - lists.map((item) => {  
383 - fileList.value.push({  
384 - ...item,  
385 - status: 'uploading',  
386 - message: '上传中',  
387 - });  
388 - });  
389 - for (let i = 0; i < lists.length; i++) {  
390 - let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_BASE_FILE_UPLOAD_PREFIX;  
391 - const result = await uploadFilePromise(requestPath, lists[i].url);  
392 - let item = fileList.value[fileListLen];  
393 - fileList.value.splice(fileListLen, 1, {  
394 - ...item,  
395 - status: 'success',  
396 - message: '',  
397 - url: result.data.fileName,  
398 - });  
399 - fileListLen++;  
400 - }  
401 - fileList.value = fileList.value.filter(item => {  
402 - deletable.value = true  
403 - return !item.label  
404 - })  
405 -};  
406 -  
407 -  
408 -const handlePickerGarbageTypeConfirm = (e) => {  
409 - paramFrom.value.garbageType = e  
410 - garbageTypeShowFlag.value = false  
411 -}  
412 -const handlePickerCarInfoConfirm = (e) => {  
413 - paramFrom.value.carType = e  
414 - garCarLabelInfoNow.value = garCarLabelInfoList.value[paramFrom.value.carType]  
415 - carTypeShowFlag.value = false  
416 -}  
417 -  
418 -const orderClick = ref(true)  
419 -/**  
420 - * 处理下单  
421 - */  
422 -const handleOderSure = async () => {  
423 - let garCarInfos = [];  
424 - for (const key in garCarInfoList.value) {  
425 - if(garCarInfoList.value[key]&& garCarInfoList.value[key].garOrderCarNumber && garCarInfoList.value[key].garOrderCarNumber>0){  
426 - garCarInfos.push(garCarInfoList.value[key]);  
427 - }  
428 -  
429 - }  
430 - if(dayTime.value != null && dayTime.value != "" && dayTime.value != undefined){  
431 - if(dayTimeType.value != '2207' ){  
432 - let length = garCarInfos.length;  
433 - for (let index = 0; index <length; index++) {  
434 -  
435 - if(garCarInfos[index].containerVolume && parseFloat(garCarInfos[index].containerVolume) >=8){  
436 - jumpPrompt("中大型车辆只能选择22:00-07:00时间段");  
437 -  
438 - return;  
439 - }  
440 -  
441 - }  
442 - }  
443 - }  
444 -  
445 -  
446 -  
447 - let params = {  
448 - /**  
449 - * 订单地址  
450 - */  
451 - garOrderAddress: userAddress.value.garUserAddress,  
452 -  
453 - /**  
454 - * 订单详细地址  
455 - */  
456 - garOrderAddressDetails: userAddress.value.garRemark,  
457 -  
458 - /**  
459 - * 订单姓名  
460 - */  
461 - garOrderContactName: userAddress.value.garUserContactName,  
462 - garCarInfoList: garCarInfos,  
463 -  
464 - /**  
465 - * 垃圾类型  
466 - */  
467 - garOrderTrashType: paramFrom.value.garbageType,  
468 -  
469 - /**  
470 - * 订单人电话  
471 - */  
472 - garOrderContactTel: userAddress.value.garUserContactTel,  
473 -  
474 - /**  
475 - * 承接经营单位  
476 - */  
477 - garOrderCompanyId: companyObj.value.id,  
478 -  
479 - /**  
480 - * 公司名称  
481 - */  
482 - garOrderCompanyName: companyObj.value.name,  
483 -  
484 - /**  
485 - * 公司负责人电话  
486 - */  
487 - garOrderCompanyTel: companyObj.value.servicePhone,  
488 -  
489 - /**  
490 - * 约定时间  
491 - */  
492 - garOrderAgreementTime: dayTime.value,  
493 - /**  
494 - * 备注  
495 - */  
496 - garRemark: paramFrom.value.remark,  
497 - /**  
498 - * 图片列表  
499 - */  
500 - imageUrls: fileList.value.filter(item => !item.label).map(item => item.url),  
501 - garLongitude: userAddress.value.garLongitude,  
502 - garLatitude: userAddress.value.garLatitude,  
503 - garCoordinate: userAddress.value.garCoordinate,  
504 - garInCarStore: paramFrom.value.garInCarStore  
505 - }  
506 - console.log("----------------------->5");  
507 - if (!validateParams(params)) {  
508 - console.log("未通过", params);  
509 -  
510 - return;  
511 - }  
512 -  
513 - // 请求防抖  
514 - if (orderClick.value) {  
515 - orderClick.value = false  
516 - setTimeout(async () => {  
517 - orderClick.value = true  
518 - await handlerSaveOrder(params);  
519 - }, 800);  
520 - } else {  
521 - uni.$u.toast("请勿频繁操作")  
522 - }  
523 -}  
524 -const handlerSaveOrder = async (params) => {  
525 - await saveOrder(params).then(res => {  
526 - if (res.data.success) {  
527 - if (userType.value != "用户") {  
528 - uni.$u.toast("下单成功,请切换成且角色查看订单详情")  
529 - uni.$u.route({  
530 - type: 'navigateBack',  
531 - url: `pages/home/index`,  
532 - })  
533 - } else {  
534 - uni.$u.toast('下单成功')  
535 - uni.$u.route({  
536 - type: "redirect",  
537 - url: `pages/order-info/order-other/detail/index`,  
538 - params: {  
539 - orderId: res.data.data  
540 - }  
541 - })  
542 - }  
543 - }  
544 - })  
545 -}  
546 -  
547 -const handlerChooseAddress = () => {  
548 - addressPopupRef.value.open(userAddress.value)  
549 -}  
550 -const currentChange = (val) => {  
551 - userAddress.value = val  
552 - console.log("currentChange====================>");  
553 -  
554 - console.log(userAddress.value);  
555 -  
556 -}  
557 -/**  
558 - * 校验参数  
559 - * @param {Object} params  
560 - */  
561 -const validateParams = (params) => {  
562 -  
563 - if (params.garInCarStore && !params.garRemark) {  
564 - jumpPrompt('请输入限高')  
565 - return false;  
566 - }  
567 -  
568 - if (!paramFrom.value.sureReadFlag[0]) {  
569 - jumpPrompt('请勾选"本人已确认信息真实有效,并承担相应法律责任"')  
570 - return false;  
571 - }  
572 - for (const key in params) {  
573 - // 跳过garInCarStore  
574 - if (key == "garInCarStore") {  
575 - continue;  
576 - }  
577 - if (!params[key] && key != "garRemark") {  
578 - switch (key) {  
579 - case "garOrderAgreementTime":  
580 - jumpPrompt('请选择预约时间')  
581 - break;  
582 - case "garOrderCompanyTel":  
583 - jumpPrompt('企业负责人手机号不能为空')  
584 - break;  
585 - }  
586 - console.log("201================="+key);  
587 -  
588 - return false;  
589 - }  
590 - if (key === "garCarInfoList") {  
591 - let count = 0;  
592 - params[key].forEach(item => {  
593 - count += item.garOrderCarNumber;  
594 - })  
595 - if (count === 0) {  
596 - jumpPrompt('请添加车辆数量')  
597 - return false;  
598 - }  
599 - }  
600 -  
601 - if (key == "imageUrls") {  
602 - if (params[key].length == 0) {  
603 - jumpPrompt('请上传现场图片')  
604 - return false;  
605 - }  
606 - if (!validateImage(params[key])) {  
607 - uni.$u.toast('请等待图片上传完毕')  
608 - return false;  
609 - }  
610 - }  
611 - }  
612 - return true;  
613 -}  
614 -  
615 -const jumpPrompt = (msg) => {  
616 - uni.showModal({  
617 - title: '提示',  
618 - content: msg,  
619 - showCancel: false,  
620 - success: function (res) {  
621 - if (res.confirm) {  
622 - } else if (res.cancel) {  
623 - }  
624 - }  
625 - });  
626 -}  
627 -const validateImage = (fileList) => {  
628 - for (let index = 0; index < fileList.length; index++) {  
629 - const str = fileList[index];  
630 - if (!str.startsWith("/profile/upload")) {  
631 - return false;  
632 - }  
633 - }  
634 - return true;  
635 -}  
636 -  
637 -const garEstimatedCostFocusFun=()=>{  
638 - //pageStyle.value="height:2000px";  
639 - scrollTop.value=11900  
640 - console.log(scrollTop.value);  
641 -  
642 -}  
643 -  
644 -const garEstimatedCostBlurFun=()=>{  
645 - pageStyle.value="";  
646 -}  
647 -  
648 -// 开始执行一次  
649 -watch(carPopupShowFlag, (val) => {  
650 - // carPopupShowFlag.value = val  
651 - if (!val) {  
652 - setTimeout(() => {  
653 - isCallBtn.value = true;  
654 - }, 1500)  
655 - }  
656 -}, {  
657 - immediate: true  
658 -}) 595 + const handlerChooseAddress = () => {
  596 + addressPopupRef.value.open(userAddress.value)
  597 + }
  598 + const currentChange = (val) => {
  599 + userAddress.value = val
  600 + console.log("currentChange====================>");
659 601
  602 + console.log(userAddress.value);
  603 +
  604 + }
  605 + /**
  606 + * 校验参数
  607 + * @param {Object} params
  608 + */
  609 + const validateParams = (params) => {
  610 +
  611 + if (params.garInCarStore && !params.garRemark) {
  612 + jumpPrompt('请输入限高')
  613 + return false;
  614 + }
  615 +
  616 + if (!paramFrom.value.sureReadFlag[0]) {
  617 + jumpPrompt('请勾选"本人已确认信息真实有效,并承担相应法律责任"')
  618 + return false;
  619 + }
  620 + for (const key in params) {
  621 + // 跳过garInCarStore
  622 + if (key == "garInCarStore") {
  623 + continue;
  624 + }
  625 + if (!params[key] && key != "garRemark") {
  626 + switch (key) {
  627 + case "garOrderAgreementTime":
  628 + jumpPrompt('请选择预约时间')
  629 + break;
  630 + case "garOrderCompanyTel":
  631 + jumpPrompt('企业负责人手机号不能为空')
  632 + break;
  633 + }
  634 + console.log("201=================" + key);
  635 +
  636 + return false;
  637 + }
  638 + if (key === "garCarInfoList") {
  639 + let count = 0;
  640 + params[key].forEach(item => {
  641 + count += item.garOrderCarNumber;
  642 + })
  643 + if (count === 0) {
  644 + jumpPrompt('请添加车辆数量')
  645 + return false;
  646 + }
  647 + }
  648 +
  649 + if (key == "imageUrls") {
  650 + if (params[key].length == 0) {
  651 + jumpPrompt('请上传现场图片')
  652 + return false;
  653 + }
  654 + if (!validateImage(params[key])) {
  655 + uni.$u.toast('请等待图片上传完毕')
  656 + return false;
  657 + }
  658 + }
  659 + }
  660 + return true;
  661 + }
  662 +
  663 + const jumpPrompt = (msg) => {
  664 + uni.showModal({
  665 + title: '提示',
  666 + content: msg,
  667 + showCancel: false,
  668 + success: function(res) {
  669 + if (res.confirm) {} else if (res.cancel) {}
  670 + }
  671 + });
  672 + }
  673 + const validateImage = (fileList) => {
  674 + for (let index = 0; index < fileList.length; index++) {
  675 + const str = fileList[index];
  676 + if (!str.includes("/profile/upload")) {
  677 + return false;
  678 + }
  679 + }
  680 + return true;
  681 + }
660 682
  683 + const garEstimatedCostFocusFun = () => {
  684 + //pageStyle.value="height:2000px";
  685 + scrollTop.value = 11900
  686 + console.log(scrollTop.value);
  687 +
  688 + }
  689 +
  690 + const garEstimatedCostBlurFun = () => {
  691 + pageStyle.value = "";
  692 + }
  693 +
  694 + // 开始执行一次
  695 + watch(carPopupShowFlag, (val) => {
  696 + // carPopupShowFlag.value = val
  697 + if (!val) {
  698 + setTimeout(() => {
  699 + isCallBtn.value = true;
  700 + }, 1500)
  701 + }
  702 + }, {
  703 + immediate: true
  704 + })
661 </script> 705 </script>
662 706
663 <style lang="scss" scoped> 707 <style lang="scss" scoped>
664 -$custom-marin-bottom: 20rpx;  
665 -$custom-page-padding: 20rpx;  
666 -$custom-border-radio: 20rpx;  
667 -$custom-bottom-height: 200rpx; 708 + $custom-marin-bottom: 20rpx;
  709 + $custom-page-padding: 20rpx;
  710 + $custom-border-radio: 20rpx;
  711 + $custom-bottom-height: 200rpx;
  712 +
  713 + .link {
  714 + color: blue;
  715 + }
668 716
669 -.link {  
670 - color: blue; 717 + .swiperHeight1 {
  718 + height: 280px;
  719 + text-align: center;
  720 + justify-content: center;
671 } 721 }
672 722
673 -.swiperHeight1{  
674 - height: 280px;  
675 - text-align: center;  
676 - justify-content: center;  
677 -}  
678 -.swiperHeight2{  
679 - height: 300px;  
680 - text-align: center;  
681 - justify-content: center;  
682 -}  
683 -.swiperHeight3{  
684 - height: 310px;  
685 - text-align: center;  
686 - justify-content: center;  
687 -}  
688 -.company-clean-container {  
689 - height: 100%;  
690 - width: 100%;  
691 - background-color: $u-info-light;  
692 - box-sizing: border-box;  
693 - overflow-y: scroll;  
694 -  
695 -  
696 - .company-clean-container-box {  
697 - height: 100%;  
698 - width: 100%;  
699 - padding: $custom-page-padding;  
700 - box-sizing: border-box;  
701 -  
702 - .company-clean-container-header {  
703 - padding: $custom-page-padding;  
704 - box-sizing: border-box;  
705 - background-color: #ffffff;  
706 - border-radius: $custom-border-radio;  
707 - margin-bottom: $custom-marin-bottom;  
708 -  
709 - .company-clean-container-header-address {  
710 - font-size: 30rpx;  
711 - font-weight: bold;  
712 - color: $u-main-color;  
713 - }  
714 -  
715 - .company-clean-container-header-base-info {  
716 - font-size: 25rpx;  
717 - color: $u-info;  
718 - line-height: 80rpx;  
719 - display: flex;  
720 -  
721 - .company-clean-container-header-base-info-left {  
722 - flex: 2;  
723 - }  
724 -  
725 - .company-clean-container-header-base-info-right {  
726 - flex: 1;  
727 - display: flex;  
728 - align-items: center;  
729 - justify-content: flex-end;  
730 -  
731 - .company-clean-container-header-base-info-right-icon {  
732 - width: 37rpx;  
733 - height: 37rpx;  
734 - @include handleClick;  
735 - display: flex;  
736 - align-items: center;  
737 -  
738 - image {  
739 - height: 100%;  
740 - width: 100%;  
741 - background-size: 100% 100;  
742 - }  
743 - }  
744 - }  
745 - }  
746 -  
747 - .company-clean-container-header-reservation {  
748 - line-height: 80rpx;  
749 - display: flex;  
750 - justify-content: space-between;  
751 - font-size: 28rpx;  
752 - @include handleClick;  
753 -  
754 - .company-clean-container-header-reservation-left {  
755 - display: flex;  
756 - align-items: center;  
757 - color: $u-content-color;  
758 - }  
759 -  
760 - .company-clean-container-header-reservation-right {  
761 - display: flex;  
762 - align-items: center;  
763 - color: $u-content-color;  
764 - }  
765 - }  
766 -  
767 -  
768 - }  
769 -  
770 - .company-clean-container-car-main {  
771 - padding: $custom-page-padding;  
772 - border-radius: $custom-border-radio;  
773 - box-sizing: border-box;  
774 - background-color: #ffffff;  
775 - margin-bottom: $custom-marin-bottom;  
776 -  
777 - .company-clean-container-car-main-title {  
778 - font-size: 30rpx;  
779 - font-weight: bold;  
780 - color: #a9e08f;  
781 - display: flex;  
782 - justify-content: center;  
783 - }  
784 -  
785 - .company-clean-container-car-main-content {  
786 - width: 100%;  
787 - display: flex;  
788 - flex-direction: column;  
789 - justify-content: center;  
790 -  
791 - .company-clean-container-car-main-content-img {  
792 - width: 600rpx;  
793 - height: 400rpx;  
794 -  
795 - .company-clean-container-car-main-content-img {  
796 - width: 600rpx;  
797 - height: 400rpx;  
798 - }  
799 - }  
800 -  
801 - .company-clean-container-car-main-content-remark {  
802 - color: $u-tips-color;  
803 - font-size: 23rpx;  
804 - line-height: 30rpx;  
805 - padding: $custom-page-padding;  
806 - background-color: $u-info-light;  
807 - word-break: break-all;  
808 - }  
809 -  
810 - .company-clean-container-car-main-content-type {  
811 - margin-top: $custom-marin-bottom;  
812 - margin-bottom: $custom-marin-bottom;  
813 - display: flex;  
814 - justify-content: space-between;  
815 - border-radius: $custom-border-radio;  
816 - // background-color: $u-info-light;  
817 - box-sizing: border-box;  
818 -  
819 - .company-clean-container-car-main-content-type-price-area {  
820 - display: flex;  
821 - justify-content: flex-start;  
822 - align-items: center;  
823 - color: $u-info;  
824 - white-space: nowrap;  
825 - width: 100%;  
826 - }  
827 - }  
828 -  
829 - .company-clean-container-car-main-content-number {  
830 - display: flex;  
831 - justify-content: space-between;  
832 - font-size: 28rpx;  
833 - color: $u-tips-color;  
834 - font-weight: small;  
835 - align-items: center;  
836 -  
837 - .company-clean-container-car-main-content-number-txt {  
838 - line-height: 80rpx;  
839 - }  
840 -  
841 - .company-clean-container-car-main-content-number-button {}  
842 - }  
843 - }  
844 -  
845 -  
846 - }  
847 -  
848 - .company-clean-container-car-main-content-prompt {  
849 - color: $u-tips-color;  
850 - font-size: 23rpx;  
851 - line-height: 30rpx;  
852 - padding: $custom-page-padding;  
853 - word-break: break-all;  
854 - text-align: center;  
855 - }  
856 -  
857 - .company-clean-container-site-image-info {  
858 - padding: $custom-page-padding;  
859 - background-color: #ffffff;  
860 - border-radius: $custom-border-radio;  
861 - color: $u-info;  
862 - font-size: 28rpx;  
863 - margin-bottom: $custom-marin-bottom;  
864 -  
865 - .company-clean-container-site-image-info-remark {  
866 - line-height: 50rpx;  
867 -  
868 - }  
869 -  
870 - .company-clean-container-site-image-info-img {}  
871 -  
872 - .company-clean-container-site-image-info-input-remark {  
873 - line-height: 80rpx;  
874 - }  
875 -  
876 - .company-clean-container-site-image-info-input-remark-box {}  
877 - }  
878 -  
879 - .company-clean-container-site-image-info-sure-button {  
880 - padding-bottom: $custom-bottom-height;  
881 - font-size: 28rpx;  
882 -  
883 - .company-clean-container-site-image-info-sure-button-radio {  
884 - padding: $custom-page-padding;  
885 - box-sizing: border-box;  
886 - display: flex;  
887 - // flex-flow: row wrap;  
888 - font-size: 28rpx;  
889 - color: $u-info;  
890 - }  
891 - }  
892 - }  
893 -  
894 - .company-clean-bottom {  
895 - position: absolute;  
896 - width: 100%;  
897 - bottom: 0;  
898 - left: 0;  
899 - box-shadow: 0 0 10rpx 0 rgba(0, 0, 0, 0.1);  
900 -  
901 - .company-clean-bottom-box {  
902 - height: $custom-bottom-height;  
903 - background-color: #ffffff;  
904 - padding: 50rpx;  
905 - box-sizing: border-box;  
906 - display: flex;  
907 - justify-content: space-between;  
908 - align-items: center;  
909 -  
910 - .company-clean-bottom-left {  
911 - display: flex;  
912 -  
913 - .company-clean-bottom-left-icon {  
914 - transform: rotateY(180deg);  
915 - }  
916 -  
917 - }  
918 -  
919 - .company-clean-bottom-right {  
920 - min-width: 200rpx;  
921 - }  
922 - }  
923 -  
924 - }  
925 -  
926 - .movableArea {  
927 - pointer-events: none;  
928 - position: absolute;  
929 - left: 0;  
930 - bottom: 240rpx;  
931 - width: 100%;  
932 - z-index: 99;  
933 -  
934 - .movableView {  
935 - box-sizing: border-box;  
936 -  
937 - display: flex;  
938 - justify-content: flex-end;  
939 - margin-right: 50rpx;  
940 -  
941 - .company-clean-call-box-container {  
942 - max-height: 60rpx;  
943 - max-width: 60rpx;  
944 - display: flex;  
945 - align-items: center;  
946 - justify-content: center;  
947 - background-color: #19a97c;  
948 - border-radius: 100%;  
949 - padding: 5rpx;  
950 - }  
951 - }  
952 - }  
953 -  
954 -  
955 -  
956 -}  
957 -  
958 -.hoverClickStyle {  
959 - @include handleClick;  
960 -}  
961 -  
962 -// 弹出框  
963 -.company-clean-container-car-popup {  
964 - box-sizing: border-box;  
965 - color: $u-info;  
966 -  
967 - .company-clean-container-car-popup-content {  
968 - font-size: 28rpx;  
969 -  
970 - .company-clean-container-car-popup-content-box {  
971 - box-sizing: border-box;  
972 - padding: 0 $custom-page-padding;  
973 - border-radius: 10rpx;  
974 - border: 1rpx solid $u-info;  
975 -  
976 - .company-clean-container-car-popup-content-box-item {  
977 - display: flex;  
978 - align-items: center;  
979 - justify-content: space-between;  
980 - margin: 20rpx 0;  
981 - box-sizing: border-box;  
982 -  
983 - .company-clean-container-car-popup-content-box-item-text {}  
984 -  
985 - .company-clean-container-car-popup-content-box-item-number {}  
986 - }  
987 - }  
988 -  
989 - .company-clean-container-car-popup-content-title {  
990 - color: $u-info;  
991 - box-sizing: border-box;  
992 - font-size: 30rpx !important;  
993 - line-height: 30rpx;  
994 - margin-bottom: 20rpx;  
995 - }  
996 - }  
997 -  
998 - .company-clean-container-car-popup-button-safe {  
999 - width: 100%;  
1000 - height: $custom-bottom-height;  
1001 - }  
1002 -}  
1003 -  
1004 -.company-in-car-store-box-text-yes {  
1005 - background: #19a97c;  
1006 -}  
1007 -  
1008 -.company-in-car-store-box-text-no {  
1009 - background: #909399;  
1010 -}  
1011 -</style> 723 + .swiperHeight2 {
  724 + height: 300px;
  725 + text-align: center;
  726 + justify-content: center;
  727 + }
  728 +
  729 + .swiperHeight3 {
  730 + height: 310px;
  731 + text-align: center;
  732 + justify-content: center;
  733 + }
  734 +
  735 + .company-clean-container {
  736 + height: 100%;
  737 + width: 100%;
  738 + background-color: $u-info-light;
  739 + box-sizing: border-box;
  740 + overflow-y: scroll;
  741 +
  742 +
  743 + .company-clean-container-box {
  744 + height: 100%;
  745 + width: 100%;
  746 + padding: $custom-page-padding;
  747 + box-sizing: border-box;
  748 +
  749 + .company-clean-container-header {
  750 + padding: $custom-page-padding;
  751 + box-sizing: border-box;
  752 + background-color: #ffffff;
  753 + border-radius: $custom-border-radio;
  754 + margin-bottom: $custom-marin-bottom;
  755 +
  756 + .company-clean-container-header-address {
  757 + font-size: 30rpx;
  758 + font-weight: bold;
  759 + color: $u-main-color;
  760 + }
  761 +
  762 + .company-clean-container-header-base-info {
  763 + font-size: 25rpx;
  764 + color: $u-info;
  765 + line-height: 80rpx;
  766 + display: flex;
  767 +
  768 + .company-clean-container-header-base-info-left {
  769 + flex: 2;
  770 + }
  771 +
  772 + .company-clean-container-header-base-info-right {
  773 + flex: 1;
  774 + display: flex;
  775 + align-items: center;
  776 + justify-content: flex-end;
  777 +
  778 + .company-clean-container-header-base-info-right-icon {
  779 + width: 37rpx;
  780 + height: 37rpx;
  781 + @include handleClick;
  782 + display: flex;
  783 + align-items: center;
  784 +
  785 + image {
  786 + height: 100%;
  787 + width: 100%;
  788 + background-size: 100% 100;
  789 + }
  790 + }
  791 + }
  792 + }
  793 +
  794 + .company-clean-container-header-reservation {
  795 + line-height: 80rpx;
  796 + display: flex;
  797 + justify-content: space-between;
  798 + font-size: 28rpx;
  799 + @include handleClick;
  800 +
  801 + .company-clean-container-header-reservation-left {
  802 + display: flex;
  803 + align-items: center;
  804 + color: $u-content-color;
  805 + }
  806 +
  807 + .company-clean-container-header-reservation-right {
  808 + display: flex;
  809 + align-items: center;
  810 + color: $u-content-color;
  811 + }
  812 + }
  813 +
  814 +
  815 + }
  816 +
  817 + .company-clean-container-car-main {
  818 + padding: $custom-page-padding;
  819 + border-radius: $custom-border-radio;
  820 + box-sizing: border-box;
  821 + background-color: #ffffff;
  822 + margin-bottom: $custom-marin-bottom;
  823 +
  824 + .company-clean-container-car-main-title {
  825 + font-size: 30rpx;
  826 + font-weight: bold;
  827 + color: #a9e08f;
  828 + display: flex;
  829 + justify-content: center;
  830 + }
  831 +
  832 + .company-clean-container-car-main-content {
  833 + width: 100%;
  834 + display: flex;
  835 + flex-direction: column;
  836 + justify-content: center;
  837 +
  838 + .company-clean-container-car-main-content-img {
  839 + width: 600rpx;
  840 + height: 400rpx;
  841 +
  842 + .company-clean-container-car-main-content-img {
  843 + width: 600rpx;
  844 + height: 400rpx;
  845 + }
  846 + }
  847 +
  848 + .company-clean-container-car-main-content-remark {
  849 + color: $u-tips-color;
  850 + font-size: 23rpx;
  851 + line-height: 30rpx;
  852 + padding: $custom-page-padding;
  853 + background-color: $u-info-light;
  854 + word-break: break-all;
  855 + }
  856 +
  857 + .company-clean-container-car-main-content-type {
  858 + margin-top: $custom-marin-bottom;
  859 + margin-bottom: $custom-marin-bottom;
  860 + display: flex;
  861 + justify-content: space-between;
  862 + border-radius: $custom-border-radio;
  863 + // background-color: $u-info-light;
  864 + box-sizing: border-box;
  865 +
  866 + .company-clean-container-car-main-content-type-price-area {
  867 + display: flex;
  868 + justify-content: flex-start;
  869 + align-items: center;
  870 + color: $u-info;
  871 + white-space: nowrap;
  872 + width: 100%;
  873 + }
  874 + }
  875 +
  876 + .company-clean-container-car-main-content-number {
  877 + display: flex;
  878 + justify-content: space-between;
  879 + font-size: 28rpx;
  880 + color: $u-tips-color;
  881 + font-weight: small;
  882 + align-items: center;
  883 +
  884 + .company-clean-container-car-main-content-number-txt {
  885 + line-height: 80rpx;
  886 + }
  887 +
  888 + .company-clean-container-car-main-content-number-button {}
  889 + }
  890 + }
  891 +
  892 +
  893 + }
  894 +
  895 + .company-clean-container-car-main-content-prompt {
  896 + color: $u-tips-color;
  897 + font-size: 23rpx;
  898 + line-height: 30rpx;
  899 + padding: $custom-page-padding;
  900 + word-break: break-all;
  901 + text-align: center;
  902 + }
  903 +
  904 + .company-clean-container-site-image-info {
  905 + padding: $custom-page-padding;
  906 + background-color: #ffffff;
  907 + border-radius: $custom-border-radio;
  908 + color: $u-info;
  909 + font-size: 28rpx;
  910 + margin-bottom: $custom-marin-bottom;
  911 +
  912 + .company-clean-container-site-image-info-remark {
  913 + line-height: 50rpx;
  914 +
  915 + }
  916 +
  917 + .company-clean-container-site-image-info-img {}
  918 +
  919 + .company-clean-container-site-image-info-input-remark {
  920 + line-height: 80rpx;
  921 + }
  922 +
  923 + .company-clean-container-site-image-info-input-remark-box {}
  924 + }
  925 +
  926 + .company-clean-container-site-image-info-sure-button {
  927 + padding-bottom: $custom-bottom-height;
  928 + font-size: 28rpx;
  929 +
  930 + .company-clean-container-site-image-info-sure-button-radio {
  931 + padding: $custom-page-padding;
  932 + box-sizing: border-box;
  933 + display: flex;
  934 + // flex-flow: row wrap;
  935 + font-size: 28rpx;
  936 + color: $u-info;
  937 + }
  938 + }
  939 + }
  940 +
  941 + .company-clean-bottom {
  942 + position: absolute;
  943 + width: 100%;
  944 + bottom: 0;
  945 + left: 0;
  946 + box-shadow: 0 0 10rpx 0 rgba(0, 0, 0, 0.1);
  947 +
  948 + .company-clean-bottom-box {
  949 + height: $custom-bottom-height;
  950 + background-color: #ffffff;
  951 + padding: 50rpx;
  952 + box-sizing: border-box;
  953 + display: flex;
  954 + justify-content: space-between;
  955 + align-items: center;
  956 +
  957 + .company-clean-bottom-left {
  958 + display: flex;
  959 +
  960 + .company-clean-bottom-left-icon {
  961 + transform: rotateY(180deg);
  962 + }
  963 +
  964 + }
  965 +
  966 + .company-clean-bottom-right {
  967 + min-width: 200rpx;
  968 + }
  969 + }
  970 +
  971 + }
  972 +
  973 + .movableArea {
  974 + pointer-events: none;
  975 + position: absolute;
  976 + left: 0;
  977 + bottom: 240rpx;
  978 + width: 100%;
  979 + z-index: 99;
  980 +
  981 + .movableView {
  982 + box-sizing: border-box;
  983 +
  984 + display: flex;
  985 + justify-content: flex-end;
  986 + margin-right: 50rpx;
  987 +
  988 + .company-clean-call-box-container {
  989 + max-height: 60rpx;
  990 + max-width: 60rpx;
  991 + display: flex;
  992 + align-items: center;
  993 + justify-content: center;
  994 + background-color: #19a97c;
  995 + border-radius: 100%;
  996 + padding: 5rpx;
  997 + }
  998 + }
  999 + }
  1000 +
  1001 +
  1002 +
  1003 + }
  1004 +
  1005 + .hoverClickStyle {
  1006 + @include handleClick;
  1007 + }
  1008 +
  1009 + // 弹出框
  1010 + .company-clean-container-car-popup {
  1011 + box-sizing: border-box;
  1012 + color: $u-info;
  1013 +
  1014 + .company-clean-container-car-popup-content {
  1015 + font-size: 28rpx;
  1016 +
  1017 + .company-clean-container-car-popup-content-box {
  1018 + box-sizing: border-box;
  1019 + padding: 0 $custom-page-padding;
  1020 + border-radius: 10rpx;
  1021 + border: 1rpx solid $u-info;
  1022 +
  1023 + .company-clean-container-car-popup-content-box-item {
  1024 + display: flex;
  1025 + align-items: center;
  1026 + justify-content: space-between;
  1027 + margin: 20rpx 0;
  1028 + box-sizing: border-box;
  1029 +
  1030 + .company-clean-container-car-popup-content-box-item-text {}
  1031 +
  1032 + .company-clean-container-car-popup-content-box-item-number {}
  1033 + }
  1034 + }
  1035 +
  1036 + .company-clean-container-car-popup-content-title {
  1037 + color: $u-info;
  1038 + box-sizing: border-box;
  1039 + font-size: 30rpx !important;
  1040 + line-height: 30rpx;
  1041 + margin-bottom: 20rpx;
  1042 + }
  1043 + }
  1044 +
  1045 + .company-clean-container-car-popup-button-safe {
  1046 + width: 100%;
  1047 + height: $custom-bottom-height;
  1048 + }
  1049 + }
  1050 +
  1051 + .company-in-car-store-box-text-yes {
  1052 + background: #19a97c;
  1053 + }
  1054 +
  1055 + .company-in-car-store-box-text-no {
  1056 + background: #909399;
  1057 + }
  1058 +</style>
1012 \ No newline at end of file 1059 \ No newline at end of file
garbage-removal/src/pages/login/code.vue
@@ -87,7 +87,7 @@ const checkVerifyNum = (code) =&gt; { @@ -87,7 +87,7 @@ const checkVerifyNum = (code) =&gt; {
87 87
88 } else { 88 } else {
89 verifyFlag.value = true; 89 verifyFlag.value = true;
90 - uni.$u.toast(res.data.message); 90 + uni.$u.toast(res.data.msg);
91 } 91 }
92 }) 92 })
93 } 93 }
garbage-removal/src/pages/login/index.vue
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <view class="content"> 5 <view class="content">
6 <view class="title">欢迎登录</view> 6 <view class="title">欢迎登录</view>
7 <input class="u-border-bottom" type="number" v-model="tel" placeholder="请输入手机号" /> 7 <input class="u-border-bottom" type="number" v-model="tel" placeholder="请输入手机号" />
8 - <view class="tips">未注册的手机号验证后自动创建账号</view> 8 + <!-- <view class="tips">未注册的手机号验证后自动创建账号</view> -->
9 <button @tap="submit" :style="[inputStyle]" class="getCaptcha">获取短信验证码</button> 9 <button @tap="submit" :style="[inputStyle]" class="getCaptcha">获取短信验证码</button>
10 <view class="alternative"> 10 <view class="alternative">
11 </view> 11 </view>
garbage-removal/src/pages/order-info/order-disposal/scan-detail/index.vue
@@ -102,7 +102,8 @@ @@ -102,7 +102,8 @@
102 } from '@dcloudio/uni-app'; 102 } from '@dcloudio/uni-app';
103 import { 103 import {
104 computed, 104 computed,
105 - ref 105 + ref,
  106 + onMounted
106 } from 'vue'; 107 } from 'vue';
107 const details = ref({}); 108 const details = ref({});
108 const fileList = ref([]); 109 const fileList = ref([]);
@@ -113,9 +114,36 @@ @@ -113,9 +114,36 @@
113 fileList.value.splice(event.index, 1); 114 fileList.value.splice(event.index, 1);
114 }; 115 };
115 116
  117 +
  118 + const location = ref({});
  119 +
  120 + const takeLocalCallBack = (lngLat) => {
  121 + const ll = lngLat.split(",");
  122 + console.log(ll);
  123 + location.value = {
  124 + longitude: ll[0],
  125 + latitude: ll[1]
  126 + };
  127 + }
  128 +
  129 + // 生命周期处理
  130 + onMounted(() => {
  131 + // 挂载全局回调
  132 + window.takeLocationCallBack = takeLocalCallBack
  133 + })
  134 +
  135 + const takeLocation = () => {
  136 + console.log("获取定位信息");
  137 + // 获取定位信息
  138 + window.JsInterface.takeLocation();
  139 + }
  140 +
  141 +
116 const isNew = ref(false) 142 const isNew = ref(false)
117 // 新增图片 143 // 新增图片
118 const afterRead = async (event) => { 144 const afterRead = async (event) => {
  145 + // 获取定位信息
  146 + takeLocation();
119 // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式 147 // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
120 let lists = [].concat(event.file); 148 let lists = [].concat(event.file);
121 let fileListLen = fileList.value.length; 149 let fileListLen = fileList.value.length;
@@ -126,66 +154,70 @@ @@ -126,66 +154,70 @@
126 message: '上传中', 154 message: '上传中',
127 }); 155 });
128 }); 156 });
  157 + // 将blob转为file对象的方法
  158 + function blobToFile(blob, fileName) {
  159 + return new File([blob], fileName, {
  160 + type: 'image/png'
  161 + })
  162 + }
129 for (let i = 0; i < lists.length; i++) { 163 for (let i = 0; i < lists.length; i++) {
130 - let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_BASE_FILE_UPLOAD_PREFIX;  
131 - const result = await uploadFilePromise(requestPath, lists[i].url);  
132 - let item = fileList.value[fileListLen];  
133 - fileList.value.splice(fileListLen, 1, {  
134 - ...item,  
135 - status: 'success',  
136 - message: '',  
137 - url: result.data.fileName,  
138 - });  
139 - fileListLen++; 164 + // 获取blob对象
  165 + fetch(lists[i].url)
  166 + .then(response => response.blob())
  167 + .then(blob => {
  168 + // 将blob转换为file
  169 + let fileN = blobToFile(blob, lists[i].name)
  170 + // 上传file对象
  171 + let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env
  172 + .VITE_BASE_FILE_UPLOAD_PREFIX;
  173 + uploadFilePromise(requestPath, fileN).then(result => {
  174 + let item = fileList.value[fileListLen];
  175 + fileList.value.splice(fileListLen, 1, {
  176 + ...item,
  177 + status: 'success',
  178 + message: '',
  179 + url: result.data.url,
  180 + });
  181 + fileListLen++;
  182 + });
  183 +
  184 + })
140 } 185 }
141 }; 186 };
142 const handlerInputChange = (val) => { 187 const handlerInputChange = (val) => {
143 console.log(val); 188 console.log(val);
144 } 189 }
145 const handlerSubmit = async () => { 190 const handlerSubmit = async () => {
146 - try {  
147 - // 获取定位信息  
148 - const location = await new Promise((resolve, reject) => {  
149 - uni.getLocation({  
150 - type: 'wgs84',  
151 - success: resolve,  
152 - fail: reject  
153 - });  
154 - });  
155 - // 校验参数  
156 - let params = {  
157 - ...details.value,  
158 - fillImageList: fileList.value.map((item) => item.url),  
159 - garOrderHandlerCompanyName: details.value.garOrderCompanyName,  
160 - garOrderHandlerCompanyId: details.value.garOrderCompanyId,  
161 - // 添加定位信息  
162 - latitude: location.latitude,  
163 - longitude: location.longitude  
164 - }  
165 - if (validateParams(params)) {  
166 - await askTransport(params).then((res) => {  
167 - console.log(res);  
168 - if (res.data.code == 200) {  
169 - uni.$u.toast("当前趟次记录完毕!")  
170 - }  
171 - }).catch((err) => {  
172 - uni.$u.toast("当前趟次记录失败")  
173 - })  
174 - // 返回上级  
175 - uni.navigateBack({  
176 - delta: 1  
177 - });  
178 - }  
179 - } catch (error) {  
180 - console.error('定位获取失败:', error); 191 + if (typeof(location.value.latitude) === 'undefined') {
  192 + console.log('定位获取失败', );
181 uni.$u.toast("需要位置权限才能提交"); 193 uni.$u.toast("需要位置权限才能提交");
182 - // 可选:引导用户打开设置  
183 - uni.openSetting({  
184 - success(res) {  
185 - console.log('授权设置:', res.authSetting); 194 + return;
  195 + }
  196 + // 校验参数
  197 + let params = {
  198 + ...details.value,
  199 + fillImageList: fileList.value.map((item) => item.url),
  200 + garOrderHandlerCompanyName: details.value.garOrderCompanyName,
  201 + garOrderHandlerCompanyId: details.value.garOrderCompanyId,
  202 + // 添加定位信息
  203 + latitude: location.value.latitude,
  204 + longitude: location.value.longitude
  205 + }
  206 + if (validateParams(params)) {
  207 + await askTransport(params).then((res) => {
  208 + console.log(res);
  209 + if (res.data.code == 200) {
  210 + uni.$u.toast("当前趟次记录完毕!")
186 } 211 }
  212 + }).catch((err) => {
  213 + uni.$u.toast("当前趟次记录失败")
  214 + })
  215 + // 返回上级
  216 + uni.navigateBack({
  217 + delta: 1
187 }); 218 });
188 } 219 }
  220 +
189 } 221 }
190 222
191 const validateParams = (params) => { 223 const validateParams = (params) => {
@@ -215,7 +247,7 @@ @@ -215,7 +247,7 @@
215 if (fillImageList instanceof Array && fillImageList.length > 0) { 247 if (fillImageList instanceof Array && fillImageList.length > 0) {
216 for (let index = 0; index < fillImageList.length; index++) { 248 for (let index = 0; index < fillImageList.length; index++) {
217 const str = fillImageList[index]; 249 const str = fillImageList[index];
218 - if (!str.startsWith("/profile/upload")) { 250 + if (!str.includes("/profile/upload")) {
219 uni.$u.toast("请等待图片上传~"); 251 uni.$u.toast("请等待图片上传~");
220 return false; 252 return false;
221 } 253 }
garbage-removal/src/pages/order-info/order-disposal/transport-detail/index.vue
@@ -159,7 +159,7 @@ const handleOrderDetail = (orderId) =&gt; { @@ -159,7 +159,7 @@ const handleOrderDetail = (orderId) =&gt; {
159 element.fillImage = import.meta.env.VITE_BASE_URL + element.fillImage 159 element.fillImage = import.meta.env.VITE_BASE_URL + element.fillImage
160 }) 160 })
161 currentImages.value = dataGram.value.currentImages.map(element => { 161 currentImages.value = dataGram.value.currentImages.map(element => {
162 - return { url: import.meta.env.VITE_BASE_URL + element } 162 + return { url: element }
163 }); 163 });
164 transportWeightCount.value = dataGram.value.transportDetails.reduce((pre, cur) => { 164 transportWeightCount.value = dataGram.value.transportDetails.reduce((pre, cur) => {
165 console.log(pre, cur); 165 console.log(pre, cur);
garbage-removal/src/pages/order-info/order-driver/detail/index.vue
@@ -284,13 +284,13 @@ const handleOrderDetail = (orderId) =&gt; { @@ -284,13 +284,13 @@ const handleOrderDetail = (orderId) =&gt; {
284 dataGram.value = res.data.data; 284 dataGram.value = res.data.data;
285 console.log(res.data.data); 285 console.log(res.data.data);
286 currentImages.value = res.data.data.currentImages.map(item => { 286 currentImages.value = res.data.data.currentImages.map(item => {
287 - return { url: import.meta.env.VITE_BASE_URL + item }; 287 + return { url: item };
288 }); 288 });
289 putOnImages.value = res.data.data.putOnImages.map(item => { 289 putOnImages.value = res.data.data.putOnImages.map(item => {
290 - return { url: import.meta.env.VITE_BASE_URL + item }; 290 + return { url: item };
291 }); 291 });
292 putDownImages.value = res.data.data.putDownImages.map(item => { 292 putDownImages.value = res.data.data.putDownImages.map(item => {
293 - return { url: import.meta.env.VITE_BASE_URL + item }; 293 + return { url: item };
294 }); 294 });
295 }) 295 })
296 } 296 }
garbage-removal/src/pages/order-info/order-driver/upload/index.vue
1 <template> 1 <template>
2 - <view class="upload-image-box">  
3 - <view class="upload-image-box-choose">  
4 - <text class="upload-image-box-choose-txt">请选着上传图片类型:</text>  
5 - <view class="upload-image-box-choose-type">  
6 - <u-radio-group v-model="putType" @change="groupChange" placement="row">  
7 - <u-radio activeColor="#19be6b" :customStyle="{ marginBottom: '8px' }" size="28" labelSize="28"  
8 - v-for="(item, index) in chooseList" :key="index" :label="item.name" :name="item.name" @change="radioChange">  
9 - </u-radio>  
10 - </u-radio-group>  
11 - </view>  
12 - </view>  
13 - <view class="upload-image-box-bottom">  
14 - <text class="upload-image-box-bottom-txt">{{ putType }}(最多上传10张)</text>  
15 - <view class="upload-image-box-button-container">  
16 - <u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="3" multiple :maxCount="10"  
17 - :previewFullImage="true" width="200" height="150"></u-upload>  
18 - </view>  
19 - </view>  
20 - <view class="upload-image-box-submit-box">  
21 - <view class="upload-image-box-submit-box-button" @click="handleSubmit(orderId, putType,driver,carPlate)">  
22 - <view class="upload-image-box-submit-box-button-container">  
23 - <up-button color="#19be6b" type="primary" shape="square" text="确定"></up-button>  
24 - </view>  
25 - </view>  
26 - </view>  
27 - </view> 2 + <view class="upload-image-box">
  3 + <view class="upload-image-box-choose">
  4 + <text class="upload-image-box-choose-txt">请选着上传图片类型:</text>
  5 + <view class="upload-image-box-choose-type">
  6 + <u-radio-group v-model="putType" @change="groupChange" placement="row">
  7 + <u-radio activeColor="#19be6b" :customStyle="{ marginBottom: '8px' }" size="28" labelSize="28"
  8 + v-for="(item, index) in chooseList" :key="index" :label="item.name" :name="item.name"
  9 + @change="radioChange">
  10 + </u-radio>
  11 + </u-radio-group>
  12 + </view>
  13 + </view>
  14 + <view class="upload-image-box-bottom">
  15 + <text class="upload-image-box-bottom-txt">{{ putType }}(最多上传10张)</text>
  16 + <view class="upload-image-box-button-container">
  17 + <u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="3" multiple
  18 + :maxCount="10" :previewFullImage="true" width="200" height="150"></u-upload>
  19 + </view>
  20 + </view>
  21 + <view class="upload-image-box-submit-box">
  22 + <view class="upload-image-box-submit-box-button" @click="handleSubmit(orderId, putType,driver,carPlate)">
  23 + <view class="upload-image-box-submit-box-button-container">
  24 + <up-button color="#19be6b" type="primary" shape="square" text="确定"></up-button>
  25 + </view>
  26 + </view>
  27 + </view>
  28 + </view>
28 </template> 29 </template>
29 30
30 <script setup> 31 <script setup>
31 -import { uploadFilePromise } from '@/apis/common.js';  
32 -import { uploadImageUrlByType } from '@/apis/order.js';  
33 -import { onLoad } from '@dcloudio/uni-app';  
34 -import { reactive, ref } from 'vue';  
35 -import { useMainStore } from '@/stores/index.js';  
36 -const store = useMainStore();  
37 -const putType = ref("装车图片")  
38 -const orderId = ref();  
39 -const carPlate = ref();  
40 -const driver = ref();  
41 -const fileList = ref([])  
42 -const chooseList = reactive([{ name: "装车图片" }, { name: "卸车图片" }])  
43 -// 删除图片  
44 -const deletePic = (event) => {  
45 - fileList.value.splice(event.index, 1);  
46 -};  
47 -  
48 -// 新增图片  
49 -const afterRead = async (event) => {  
50 - // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式  
51 - let lists = [].concat(event.file);  
52 - let fileListLen = fileList.value.length;  
53 - lists.map((item) => {  
54 - fileList.value.push({  
55 - ...item,  
56 - status: 'uploading',  
57 - message: '上传中',  
58 - });  
59 - });  
60 - for (let i = 0; i < lists.length; i++) {  
61 - let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_BASE_FILE_UPLOAD_PREFIX;  
62 - const result = await uploadFilePromise(requestPath, lists[i].url);  
63 - let item = fileList.value[fileListLen];  
64 - fileList.value.splice(fileListLen, 1, {  
65 - ...item,  
66 - status: 'success',  
67 - message: '',  
68 - url: result.data.fileName,  
69 - });  
70 - fileListLen++;  
71 - }  
72 -};  
73 -// 提交图片  
74 -const handleSubmit = async (id, type, driver, carPlate) => {  
75 - try {  
76 - // 获取定位信息  
77 - const location = await new Promise((resolve, reject) => {  
78 - uni.getLocation({  
79 - type: 'wgs84',  
80 - success: resolve,  
81 - fail: reject  
82 - });  
83 - });  
84 -  
85 - if (!validateImage()) {  
86 - uni.$u.toast("请等待图片上传~")  
87 - return  
88 - }  
89 -  
90 - const userPhone = store.userPhone;  
91 - let params = {  
92 - garOrderId: id,  
93 - driver: driver,  
94 - carPlate: carPlate,  
95 - userPhone: userPhone,  
96 - type: type == "装车图片" ? 1 : 2,  
97 - imageUrls: fileList.value.map(item => item.url),  
98 - // 添加定位信息  
99 - latitude: location.latitude,  
100 - longitude: location.longitude  
101 - }  
102 -  
103 - if(params.imageUrls && params.imageUrls.length == 0){  
104 - uni.$u.toast("请上传现场图片");  
105 - return;  
106 - }  
107 -  
108 - uploadImageUrlByType(params).then(res => {  
109 - if (res.data.success) {  
110 - uni.$u.toast("图片上传完毕!");  
111 - setTimeout(() => {  
112 - uni.$u.route({  
113 - type: 'navigateBack',  
114 - url: `pages/order-info/order-other/detail/index`,  
115 - })  
116 - }, 300)  
117 - }  
118 - })  
119 -  
120 - } catch (error) {  
121 - console.error('定位获取失败:', error);  
122 - uni.$u.toast("需要位置权限才能提交");  
123 - // 可选:引导用户打开设置  
124 - uni.openSetting({  
125 - success(res) {  
126 - console.log('授权设置:', res.authSetting);  
127 - }  
128 - });  
129 - }  
130 -}  
131 -// 提交图片  
132 -// const handleSubmit = async (id, type,driver,carPlate) => {  
133 -// if (!validateImage()) {  
134 -// uni.$u.toast("请等待图片上传~")  
135 -// return  
136 -// }  
137 -// const userPhone = store.userPhone;  
138 -// let params = {  
139 -// garOrderId: id,  
140 -// driver:driver,  
141 -// carPlate:carPlate,  
142 -// userPhone:userPhone,  
143 -// type: type == "装车图片" ? 1 : 2,  
144 -// imageUrls: fileList.value.map(item => item.url)  
145 -// }  
146 -// if(params.imageUrls && params.imageUrls.length == 0){  
147 -// uni.$u.toast("请上传现场图片");  
148 -// return;  
149 -// }  
150 -  
151 -// uploadImageUrlByType(params).then(res => {  
152 -// if (res.data.success) {  
153 -// uni.$u.toast("图片上传完毕!");  
154 -// setTimeout(() => {  
155 -// uni.$u.route({  
156 -// type: 'navigateBack',  
157 -// url: `pages/order-info/order-other/detail/index`,  
158 -// })  
159 -// }, 300)  
160 -// }  
161 -// })  
162 -// }  
163 -  
164 -const validateImage = () => {  
165 - for (let index = 0; index < fileList.value.length; index++) {  
166 - const str = fileList.value[index].url;  
167 - if (!str.startsWith("/profile/upload")) {  
168 - return false;  
169 - }  
170 - }  
171 - return true;  
172 -}  
173 -  
174 -onLoad((options) => {  
175 - orderId.value = options.orderId;  
176 - carPlate.value = options.carPlate;  
177 - driver.value = options.driver;  
178 - // putType.value = options.putType === "putOnImages" ? "装车图片" : "卸车图片";  
179 -  
180 -}) 32 + import {
  33 + uploadFilePromise
  34 + } from '@/apis/common.js';
  35 + import {
  36 + uploadImageUrlByType
  37 + } from '@/apis/order.js';
  38 + import {
  39 + onLoad
  40 + } from '@dcloudio/uni-app';
  41 + import {
  42 + reactive,
  43 + ref,
  44 + onMounted
  45 + } from 'vue';
  46 + import {
  47 + useMainStore
  48 + } from '@/stores/index.js';
  49 + const store = useMainStore();
  50 + const putType = ref("装车图片")
  51 + const orderId = ref();
  52 + const carPlate = ref();
  53 + const driver = ref();
  54 + const fileList = ref([])
  55 + const chooseList = reactive([{
  56 + name: "装车图片"
  57 + }, {
  58 + name: "卸车图片"
  59 + }])
  60 + const location = ref({});
  61 + // 删除图片
  62 + const deletePic = (event) => {
  63 + fileList.value.splice(event.index, 1);
  64 + };
  65 +
  66 + const takeLocalCallBack = (lngLat) => {
  67 + const ll = lngLat.split(",");
  68 + console.log(ll);
  69 + location.value = {
  70 + longitude: ll[0],
  71 + latitude: ll[1]
  72 + };
  73 + }
  74 +
  75 + // 生命周期处理
  76 + onMounted(() => {
  77 + // 挂载全局回调
  78 + window.takeLocationCallBack = takeLocalCallBack
  79 + })
  80 +
  81 + const takeLocation = () => {
  82 + console.log("获取定位信息");
  83 + // 获取定位信息
  84 + window.JsInterface.takeLocation();
  85 + }
  86 + // 新增图片
  87 + const afterRead = async (event) => {
  88 + // 获取定位信息
  89 + takeLocation();
  90 + // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
  91 + let lists = [].concat(event.file);
  92 + let fileListLen = fileList.value.length;
  93 + lists.map((item) => {
  94 + fileList.value.push({
  95 + ...item,
  96 + status: 'uploading',
  97 + message: '上传中',
  98 + });
  99 + });
  100 + // 将blob转为file对象的方法
  101 + function blobToFile(blob, fileName) {
  102 + return new File([blob], fileName, {
  103 + type: 'image/png'
  104 + })
  105 + }
  106 + for (let i = 0; i < lists.length; i++) {
  107 + // 获取blob对象
  108 + fetch(lists[i].url)
  109 + .then(response => response.blob())
  110 + .then(blob => {
  111 + // 将blob转换为file
  112 + let fileN = blobToFile(blob, lists[i].name)
  113 + // 上传file对象
  114 + let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env
  115 + .VITE_BASE_FILE_UPLOAD_PREFIX;
  116 + uploadFilePromise(requestPath, fileN).then(result => {
  117 + let item = fileList.value[fileListLen];
  118 + fileList.value.splice(fileListLen, 1, {
  119 + ...item,
  120 + status: 'success',
  121 + message: '',
  122 + url: result.data.url,
  123 + });
  124 + fileListLen++;
  125 + });
  126 +
  127 + })
  128 + }
  129 + };
  130 + // 提交图片
  131 + const handleSubmit = async (id, type, driver, carPlate) => {
  132 + if (!validateImage()) {
  133 + uni.$u.toast("请等待图片上传~")
  134 + return
  135 + }
  136 + if(typeof(location.value.latitude) === 'undefined'){
  137 + console.log('定位获取失败');
  138 + uni.$u.toast("需要位置权限才能提交");
  139 + return;
  140 + }
  141 + const userPhone = store.userPhone;
  142 + let params = {
  143 + garOrderId: id,
  144 + driver: driver,
  145 + carPlate: carPlate,
  146 + userPhone: userPhone,
  147 + type: type == "装车图片" ? 1 : 2,
  148 + imageUrls: fileList.value.map(item => item.url),
  149 + // 添加定位信息
  150 + latitude: location.latitude,
  151 + longitude: location.longitude
  152 + }
  153 +
  154 + if (params.imageUrls && params.imageUrls.length == 0) {
  155 + uni.$u.toast("请上传现场图片");
  156 + return;
  157 + }
  158 +
  159 + uploadImageUrlByType(params).then(res => {
  160 + if (res.data.success) {
  161 + uni.$u.toast("图片上传完毕!");
  162 + setTimeout(() => {
  163 + uni.$u.route({
  164 + type: 'navigateBack',
  165 + url: `pages/order-info/order-other/detail/index`,
  166 + })
  167 + }, 300)
  168 + }
  169 + })
  170 + }
  171 + // 提交图片
  172 + // const handleSubmit = async (id, type,driver,carPlate) => {
  173 + // if (!validateImage()) {
  174 + // uni.$u.toast("请等待图片上传~")
  175 + // return
  176 + // }
  177 + // const userPhone = store.userPhone;
  178 + // let params = {
  179 + // garOrderId: id,
  180 + // driver:driver,
  181 + // carPlate:carPlate,
  182 + // userPhone:userPhone,
  183 + // type: type == "装车图片" ? 1 : 2,
  184 + // imageUrls: fileList.value.map(item => item.url)
  185 + // }
  186 + // if(params.imageUrls && params.imageUrls.length == 0){
  187 + // uni.$u.toast("请上传现场图片");
  188 + // return;
  189 + // }
  190 +
  191 + // uploadImageUrlByType(params).then(res => {
  192 + // if (res.data.success) {
  193 + // uni.$u.toast("图片上传完毕!");
  194 + // setTimeout(() => {
  195 + // uni.$u.route({
  196 + // type: 'navigateBack',
  197 + // url: `pages/order-info/order-other/detail/index`,
  198 + // })
  199 + // }, 300)
  200 + // }
  201 + // })
  202 + // }
  203 +
  204 + const validateImage = () => {
  205 + for (let index = 0; index < fileList.value.length; index++) {
  206 + const str = fileList.value[index].url;
  207 + if (!str.includes("/profile/upload")) {
  208 + return false;
  209 + }
  210 + }
  211 + return true;
  212 + }
  213 +
  214 + onLoad((options) => {
  215 + orderId.value = options.orderId;
  216 + carPlate.value = options.carPlate;
  217 + driver.value = options.driver;
  218 + // putType.value = options.putType === "putOnImages" ? "装车图片" : "卸车图片";
  219 +
  220 + })
181 </script> 221 </script>
182 222
183 <style lang="scss" scoped> 223 <style lang="scss" scoped>
184 -.upload-image-box {  
185 - height: 100%;  
186 - width: 100%;  
187 - background-color: #ffffff;  
188 - padding: 20rpx;  
189 - box-sizing: border-box;  
190 - line-height: 80rpx;  
191 -  
192 - .upload-image-box-choose {  
193 - display: flex;  
194 -  
195 - .upload-image-box-choose-txt {  
196 - white-space: nowrap;  
197 - }  
198 -  
199 - .upload-image-box-choose-type {  
200 - display: flex;  
201 - justify-content: center;  
202 - align-items: center;  
203 - }  
204 - }  
205 -  
206 - .upload-image-box-bottom {  
207 - .upload-image-box-bottom-txt {  
208 - color: $u-info;  
209 - }  
210 -  
211 - .upload-image-box-button-container {  
212 - min-height: 350rpx;  
213 - min-width: 100%;  
214 - padding: 20rpx;  
215 - // background-color: $u-info-light;  
216 - border: 2rpx solid $u-border-color;  
217 - box-sizing: border-box;  
218 - border-radius: 10rpx;  
219 - }  
220 - }  
221 -  
222 - .upload-image-box-submit-box {  
223 - box-sizing: border-box;  
224 - margin-top: 80rpx;  
225 - width: 100%;  
226 -  
227 - .upload-image-box-submit-box-button {  
228 - box-sizing: border-box;  
229 - display: flex;  
230 - justify-content: flex-end;  
231 - align-items: center;  
232 -  
233 - .upload-image-box-submit-box-button-container {  
234 - white-space: nowrap;  
235 - box-sizing: border-box;  
236 - width: 200rpx;  
237 - }  
238 - }  
239 - }  
240 -}  
241 -</style> 224 + .upload-image-box {
  225 + height: 100%;
  226 + width: 100%;
  227 + background-color: #ffffff;
  228 + padding: 20rpx;
  229 + box-sizing: border-box;
  230 + line-height: 80rpx;
  231 +
  232 + .upload-image-box-choose {
  233 + display: flex;
  234 +
  235 + .upload-image-box-choose-txt {
  236 + white-space: nowrap;
  237 + }
  238 +
  239 + .upload-image-box-choose-type {
  240 + display: flex;
  241 + justify-content: center;
  242 + align-items: center;
  243 + }
  244 + }
  245 +
  246 + .upload-image-box-bottom {
  247 + .upload-image-box-bottom-txt {
  248 + color: $u-info;
  249 + }
  250 +
  251 + .upload-image-box-button-container {
  252 + min-height: 350rpx;
  253 + min-width: 100%;
  254 + padding: 20rpx;
  255 + // background-color: $u-info-light;
  256 + border: 2rpx solid $u-border-color;
  257 + box-sizing: border-box;
  258 + border-radius: 10rpx;
  259 + }
  260 + }
  261 +
  262 + .upload-image-box-submit-box {
  263 + box-sizing: border-box;
  264 + margin-top: 80rpx;
  265 + width: 100%;
  266 +
  267 + .upload-image-box-submit-box-button {
  268 + box-sizing: border-box;
  269 + display: flex;
  270 + justify-content: flex-end;
  271 + align-items: center;
  272 +
  273 + .upload-image-box-submit-box-button-container {
  274 + white-space: nowrap;
  275 + box-sizing: border-box;
  276 + width: 200rpx;
  277 + }
  278 + }
  279 + }
  280 + }
  281 +</style>
242 \ No newline at end of file 282 \ No newline at end of file
garbage-removal/src/pages/wode/index.vue
@@ -142,7 +142,7 @@ const handleLoginOut = () =&gt; { @@ -142,7 +142,7 @@ const handleLoginOut = () =&gt; {
142 padding: 20rpx 30rpx; 142 padding: 20rpx 30rpx;
143 box-sizing: border-box; 143 box-sizing: border-box;
144 border-radius: 0 0 30rpx 30rpx; 144 border-radius: 0 0 30rpx 30rpx;
145 - height: 200rpx; 145 + // height: 200rpx;
146 146
147 .head-image-box { 147 .head-image-box {
148 display: flex; 148 display: flex;
garbage-removal/src/uview-plus/components/u-upload/u-upload.vue
@@ -124,6 +124,9 @@ export default { @@ -124,6 +124,9 @@ export default {
124 deep: true, 124 deep: true,
125 }, 125 },
126 }, 126 },
  127 + mounted() {
  128 + window.takePhoneCallBack = this.onTakePhoneCallBack;
  129 + },
127 // #ifdef VUE3 130 // #ifdef VUE3
128 emits: ['error', 'beforeRead', 'oversize', 'afterRead', 'delete', 'clickPreview'], 131 emits: ['error', 'beforeRead', 'oversize', 'afterRead', 'delete', 'clickPreview'],
129 // #endif 132 // #endif
@@ -144,40 +147,30 @@ export default { @@ -144,40 +147,30 @@ export default {
144 this.isInCount = lists.length < maxCount 147 this.isInCount = lists.length < maxCount
145 }, 148 },
146 chooseFile() { 149 chooseFile() {
147 - const {  
148 - maxCount,  
149 - multiple,  
150 - lists,  
151 - disabled  
152 - } = this;  
153 - if (disabled) return;  
154 - // 如果用户传入的是字符串,需要格式化成数组  
155 - let capture;  
156 - try {  
157 - capture = uni.$u.test.array(this.capture) ? this.capture : this.capture.split(',');  
158 - } catch (e) {  
159 - capture = [];  
160 - }  
161 - chooseFile(  
162 - Object.assign({  
163 - accept: this.accept,  
164 - multiple: this.multiple,  
165 - capture: capture,  
166 - compressed: this.compressed,  
167 - maxDuration: this.maxDuration,  
168 - sizeType: this.sizeType,  
169 - camera: this.camera,  
170 - }, {  
171 - maxCount: maxCount - lists.length,  
172 - })  
173 - )  
174 - .then((res) => {  
175 - this.onBeforeRead(multiple ? res : res[0]);  
176 - })  
177 - .catch((error) => {  
178 - this.$emit('error', error);  
179 - }); 150 + this.takePhoto();
180 }, 151 },
  152 + takePhoto() {
  153 + if (window.JsInterface && typeof window.JsInterface.takePhone === 'function') {
  154 + window.JsInterface.takePhone();
  155 + } else {
  156 + uni.$u.toast('当前环境不支持原生拍照');
  157 + }
  158 + },
  159 +
  160 + onTakePhoneCallBack(path) {
  161 + if (!path) return;
  162 + console.log(">>>进入回调path:",path);
  163 + const file = {
  164 + url: path,
  165 + thumb: path,
  166 + size: 0,
  167 + name: path.split('/').pop(),
  168 + type: 'image'
  169 + };
  170 + console.log(file);
  171 + this.onBeforeRead(file);
  172 + // this.onAfterRead(file);
  173 + },
181 // 文件读取之前 174 // 文件读取之前
182 onBeforeRead(file) { 175 onBeforeRead(file) {
183 const { 176 const {
garbage-removal/src/uview-plus/components/u-upload/u-uploadbf.vue 0 → 100644
  1 +<template>
  2 + <view class="u-upload" :style="[$u.addStyle(customStyle)]">
  3 + <view class="u-upload__wrap">
  4 + <template v-if="previewImage">
  5 + <view class="u-upload__wrap__preview" v-for="(item, index) in lists" :key="index">
  6 + <image v-if="item.isImage || (item.type && item.type === 'image')" :src="item.thumb || item.url"
  7 + :mode="imageMode" class="u-upload__wrap__preview__image" @tap="onPreviewImage(item)" :style="[{
  8 + // width: $u.addUnit(width),
  9 + // height: $u.addUnit(height)
  10 + }]" />
  11 + <view v-else class="u-upload__wrap__preview__other">
  12 + <u-icon color="#80CBF9" size="26"
  13 + :name="item.isVideo || (item.type && item.type === 'video') ? 'movie' : 'folder'"></u-icon>
  14 + <text class="u-upload__wrap__preview__other__text">{{ item.isVideo || (item.type && item.type === 'video') ?
  15 + '视频' : '文件' }}</text>
  16 + </view>
  17 + <view class="u-upload__status" v-if="item.status === 'uploading' || item.status === 'failed'">
  18 + <view class="u-upload__status__icon">
  19 + <u-icon v-if="item.status === 'failed'" name="close-circle" color="#ffffff" size="25" />
  20 + <u-loading-icon size="22" mode="circle" color="#ffffff" v-else />
  21 + </view>
  22 + <text v-if="item.message" class="u-upload__status__message">{{ item.message }}</text>
  23 + </view>
  24 + <view class="u-upload__deletable"
  25 + v-if="item.status !== 'uploading' && (deletable || item.deletable) && !isReadOnly"
  26 + @tap.stop="deleteItem(index)">
  27 + <view class="u-upload__deletable__icon">
  28 + <u-icon name="close" color="#ffffff" size="25"></u-icon>
  29 + </view>
  30 + </view>
  31 + <view class="u-upload__success" v-if="false">
  32 + <!-- #ifdef APP-NVUE -->
  33 + <image :src="successIcon" class="u-upload__success__icon"></image>
  34 + <!-- #endif -->
  35 + <!-- #ifndef APP-NVUE -->
  36 + <view class="u-upload__success__icon">
  37 + <u-icon name="checkmark" color="#ffffff" size="12"></u-icon>
  38 + </view>
  39 + <!-- #endif -->
  40 + </view>
  41 + </view>
  42 +
  43 + </template>
  44 +
  45 + <template v-if="isInCount && !isReadOnly">
  46 + <view v-if="$slots.default || $slots.$default" @tap="chooseFile">
  47 + <slot />
  48 + </view>
  49 + <view v-else class="u-upload__button" :hover-class="!disabled ? 'u-upload__button--hover' : ''"
  50 + hover-stay-time="150" @tap="chooseFile" :class="[disabled && 'u-upload__button--disabled']" :style="[{
  51 + // width: $u.addUnit(width),
  52 + // height: $u.addUnit(height)
  53 + }]">
  54 + <u-icon :name="uploadIcon" size="26" :color="uploadIconColor"></u-icon>
  55 + <text v-if="uploadText" class="u-upload__button__text">{{ uploadText }}</text>
  56 + </view>
  57 + </template>
  58 + </view>
  59 +
  60 + </view>
  61 +</template>
  62 +
  63 +<script>
  64 +import mixin from '../../libs/mixin/mixin.js';
  65 +import mpMixin from '../../libs/mixin/mpMixin.js';
  66 +import mixinUp from './mixin.js';
  67 +import props from './props.js';
  68 +import {
  69 + chooseFile
  70 +} from './utils';
  71 +
  72 +/**
  73 + * upload 上传
  74 + * @description 该组件用于上传图片场景
  75 + * @tutorial https://uviewui.com/components/upload.html
  76 + * @property {String} accept 接受的文件类型, 可选值为all media image file video (默认 'image' )
  77 + * @property {String | Array} capture 图片或视频拾取模式,当accept为image类型时设置capture可选额外camera可以直接调起摄像头(默认 ['album', 'camera'] )
  78 + * @property {Boolean} compressed 当accept为video时生效,是否压缩视频,默认为true(默认 true )
  79 + * @property {String} camera 当accept为video时生效,可选值为back或front(默认 'back' )
  80 + * @property {Number} maxDuration 当accept为video时生效,拍摄视频最长拍摄时间,单位秒(默认 60 )
  81 + * @property {String} uploadIcon 上传区域的图标,只能内置图标(默认 'camera-fill' )
  82 + * @property {String} uploadIconColor 上传区域的图标的字体颜色,只能内置图标(默认 #D3D4D6 )
  83 + * @property {Boolean} useBeforeRead 是否开启文件读取前事件(默认 false )
  84 + * @property {Boolean} previewFullImage 是否显示组件自带的图片预览功能(默认 true )
  85 + * @property {String | Number} maxCount 最大上传数量(默认 52 )
  86 + * @property {Boolean} disabled 是否启用(默认 false )
  87 + * @property {String} imageMode 预览上传的图片时的裁剪模式,和image组件mode属性一致(默认 'aspectFill' )
  88 + * @property {String} name 标识符,可以在回调函数的第二项参数中获取
  89 + * @property {Array} sizeType 所选的图片的尺寸, 可选值为original compressed(默认 ['original', 'compressed'] )
  90 + * @property {Boolean} multiple 是否开启图片多选,部分安卓机型不支持 (默认 false )
  91 + * @property {Boolean} deletable 是否展示删除按钮(默认 true )
  92 + * @property {String | Number} maxSize 文件大小限制,单位为byte (默认 Number.MAX_VALUE )
  93 + * @property {Array} fileList 显示已上传的文件列表
  94 + * @property {String} uploadText 上传区域的提示文字
  95 + * @property {String | Number} width 内部预览图片区域和选择图片按钮的区域宽度(默认 80 )
  96 + * @property {String | Number} height 内部预览图片区域和选择图片按钮的区域高度(默认 80 )
  97 + * @property {Object} customStyle 组件的样式,对象形式
  98 + * @event {Function} afterRead 读取后的处理函数
  99 + * @event {Function} beforeRead 读取前的处理函数
  100 + * @event {Function} oversize 文件超出大小限制
  101 + * @event {Function} clickPreview 点击预览图片
  102 + * @event {Function} delete 删除图片
  103 + * @example <u-upload :action="action" :fileList="fileList" ></u-upload>
  104 + */
  105 +export default {
  106 + name: "u-upload",
  107 + mixins: [mpMixin, mixin, mixinUp, props],
  108 + data() {
  109 + return {
  110 + // #ifdef APP-NVUE
  111 + successIcon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAKKADAAQAAAABAAAAKAAAAAB65masAAACP0lEQVRYCc3YXygsURwH8K/dpcWyG3LF5u/6/+dKVylSypuUl6uUPMifKMWL8oKEB1EUT1KeUPdR3uTNUsSLxb2udG/cbvInNuvf2rVnazZ/ZndmZ87snjM1Z+Z3zpzfp9+Z5mEAhlvjRtZgCKs+gnPAOcAkkMOR4jEHfItjDvgRxxSQD8cM0BuOCaAvXNCBQrigAsXgggYUiwsK0B9cwIH+4gIKlIILGFAqLiBAOTjFgXJxigJp4BQD0sIpAqSJow6kjSNAFTnRaHJwLenD6Mud52VQAcrBfTd2oyq+HtGaGGWAcnAVcXWoM3bCZrdi+ncPfaAcXE5UKVpdW/vitGPqqAtn98d0gXJwX7Qp6MmegUYVhvmTIezdmHlxJCjpHRTCFerLkRRu4k0aqdajN3sWOo0BK//msHa+xDuPC/oNFMKRhTtM4xjIX0SCNpXL4+7VIaHuyiWEp2L7ahWLf8fejfPdqPmC3mJicORZUp1CQzm+GiphvljGk+PBvWRbxii+xVTj5M6CiZ/tsDufvaXyxEUDxeLIyvu3m0iOyEFWVAkydcVYdyFrE9tQk9iMq6f/GNlvwt3LjQfh60LUrw9/cFyyMJUW/XkLSNMV4Mi6C5ML+ui4x5ClAX9sB9w0wV6wglJwJCv5fOxcr6EstgbGiEw4XcfUry4cWrcEUW8n+ARKxXEJHhw2WG43UKSvwI/TSZgvl7kh0b3XLZaLEy0QmMgLZAVH7J+ALOE+AVnDvQOyiPMAWcW5gSzjCPAV+78S5WE0GrQAAAAASUVORK5CYII=',
  112 + // #endif
  113 + lists: [],
  114 + isInCount: true,
  115 + }
  116 + },
  117 + watch: {
  118 + // 监听文件列表的变化,重新整理内部数据
  119 + fileList: {
  120 + handler() {
  121 + this.formatFileList()
  122 + },
  123 + immediate: true,
  124 + deep: true,
  125 + },
  126 + },
  127 + // #ifdef VUE3
  128 + emits: ['error', 'beforeRead', 'oversize', 'afterRead', 'delete', 'clickPreview'],
  129 + // #endif
  130 + methods: {
  131 + formatFileList() {
  132 + const {
  133 + fileList = [], maxCount
  134 + } = this;
  135 + const lists = fileList.map((item) =>
  136 + Object.assign(Object.assign({}, item), {
  137 + // 如果item.url为本地选择的blob文件的话,无法判断其为video还是image,此处优先通过accept做判断处理
  138 + isImage: this.accept === 'image' || uni.$u.test.image(item.url || item.thumb),
  139 + isVideo: this.accept === 'video' || uni.$u.test.video(item.url || item.thumb),
  140 + deletable: typeof (item.deletable) === 'boolean' ? item.deletable : this.deletable,
  141 + })
  142 + );
  143 + this.lists = lists
  144 + this.isInCount = lists.length < maxCount
  145 + },
  146 + chooseFile() {
  147 + const {
  148 + maxCount,
  149 + multiple,
  150 + lists,
  151 + disabled
  152 + } = this;
  153 + if (disabled) return;
  154 + // 如果用户传入的是字符串,需要格式化成数组
  155 + let capture;
  156 + try {
  157 + capture = uni.$u.test.array(this.capture) ? this.capture : this.capture.split(',');
  158 + } catch (e) {
  159 + capture = [];
  160 + }
  161 + chooseFile(
  162 + Object.assign({
  163 + accept: this.accept,
  164 + multiple: this.multiple,
  165 + capture: capture,
  166 + compressed: this.compressed,
  167 + maxDuration: this.maxDuration,
  168 + sizeType: this.sizeType,
  169 + camera: this.camera,
  170 + }, {
  171 + maxCount: maxCount - lists.length,
  172 + })
  173 + )
  174 + .then((res) => {
  175 + this.onBeforeRead(multiple ? res : res[0]);
  176 + })
  177 + .catch((error) => {
  178 + this.$emit('error', error);
  179 + });
  180 + },
  181 + // 文件读取之前
  182 + onBeforeRead(file) {
  183 + const {
  184 + beforeRead,
  185 + useBeforeRead,
  186 + } = this;
  187 + let res = true
  188 + // beforeRead是否为一个方法
  189 + if (uni.$u.test.func(beforeRead)) {
  190 + // 如果用户定义了此方法,则去执行此方法,并传入读取的文件回调
  191 + res = beforeRead(file, this.getDetail());
  192 + }
  193 + if (useBeforeRead) {
  194 + res = new Promise((resolve, reject) => {
  195 + this.$emit(
  196 + 'beforeRead',
  197 + Object.assign(Object.assign({
  198 + file
  199 + }, this.getDetail()), {
  200 + callback: (ok) => {
  201 + ok ? resolve() : reject();
  202 + },
  203 + })
  204 + );
  205 + });
  206 + }
  207 + if (!res) {
  208 + return;
  209 + }
  210 + if (uni.$u.test.promise(res)) {
  211 + res.then((data) => this.onAfterRead(data || file));
  212 + } else {
  213 + this.onAfterRead(file);
  214 + }
  215 + },
  216 + getDetail(index) {
  217 + return {
  218 + name: this.name,
  219 + index: index == null ? this.fileList.length : index,
  220 + };
  221 + },
  222 + onAfterRead(file) {
  223 + const {
  224 + maxSize,
  225 + afterRead
  226 + } = this;
  227 + const oversize = Array.isArray(file) ?
  228 + file.some((item) => item.size > maxSize) :
  229 + file.size > maxSize;
  230 + if (oversize) {
  231 + this.$emit('oversize', Object.assign({
  232 + file
  233 + }, this.getDetail()));
  234 + return;
  235 + }
  236 + if (typeof afterRead === 'function') {
  237 + afterRead(file, this.getDetail());
  238 + }
  239 + this.$emit('afterRead', Object.assign({
  240 + file
  241 + }, this.getDetail()));
  242 + },
  243 + deleteItem(index) {
  244 + this.$emit(
  245 + 'delete',
  246 + Object.assign(Object.assign({}, this.getDetail(index)), {
  247 + file: this.fileList[index],
  248 + })
  249 + );
  250 + },
  251 + // 预览图片
  252 + onPreviewImage(item) {
  253 + if (!item.isImage || !this.previewFullImage) return
  254 + let baseUrl = item.url.startsWith('/profile/upload/') ? import.meta.env.VITE_BASE_URL : item.url;
  255 + let imageArray = this.lists.filter((item) => this.accept === 'image' || uni.$u.test.image(item.url || item.thumb)).map((item) => item.url || item.thumb);
  256 + for (let index = 0; index < imageArray.length; index++) {
  257 + if (!imageArray[index].startsWith(baseUrl)) {
  258 + imageArray[index] = baseUrl + imageArray[index];
  259 + }
  260 + }
  261 + uni.previewImage({
  262 + // 先filter找出为图片的item,再返回filter结果中的图片url
  263 + urls: imageArray,
  264 + current: item.url || item.thumb,
  265 + fail() {
  266 + uni.$u.toast('预览图片失败')
  267 + },
  268 + });
  269 + },
  270 + onPreviewVideo(event) {
  271 + if (!this.data.previewFullImage) return;
  272 + const {
  273 + index
  274 + } = event.currentTarget.dataset;
  275 + const {
  276 + lists
  277 + } = this.data;
  278 + wx.previewMedia({
  279 + sources: lists
  280 + .filter((item) => isVideoFile(item))
  281 + .map((item) =>
  282 + Object.assign(Object.assign({}, item), {
  283 + type: 'video'
  284 + })
  285 + ),
  286 + current: index,
  287 + fail() {
  288 + uni.$u.toast('预览视频失败')
  289 + },
  290 + });
  291 + },
  292 + onClickPreview(event) {
  293 + const {
  294 + index
  295 + } = event.currentTarget.dataset;
  296 + const item = this.data.lists[index];
  297 + this.$emit(
  298 + 'clickPreview',
  299 + Object.assign(Object.assign({}, item), this.getDetail(index))
  300 + );
  301 + }
  302 + }
  303 +}
  304 +</script>
  305 +
  306 +<style lang="scss" scoped>
  307 +@import '../../libs/css/components.scss';
  308 +$u-upload-preview-border-radius: 2px !default;
  309 +$u-upload-preview-margin: 0 8px 8px 0 !default;
  310 +$u-upload-image-width: 80px !default;
  311 +$u-upload-image-height: $u-upload-image-width;
  312 +$u-upload-other-bgColor: rgb(242, 242, 242) !default;
  313 +$u-upload-other-flex: 1 !default;
  314 +$u-upload-text-font-size: 11px !default;
  315 +$u-upload-text-color: $u-tips-color !default;
  316 +$u-upload-text-margin-top: 2px !default;
  317 +$u-upload-deletable-right: 0 !default;
  318 +$u-upload-deletable-top: 0 !default;
  319 +$u-upload-deletable-bgColor: rgb(55, 55, 55) !default;
  320 +$u-upload-deletable-height: 14px !default;
  321 +$u-upload-deletable-width: $u-upload-deletable-height;
  322 +$u-upload-deletable-boder-bottom-left-radius: 100px !default;
  323 +$u-upload-deletable-zIndex: 3 !default;
  324 +$u-upload-success-bottom: 0 !default;
  325 +$u-upload-success-right: 0 !default;
  326 +$u-upload-success-border-style: solid !default;
  327 +$u-upload-success-border-top-color: transparent !default;
  328 +$u-upload-success-border-left-color: transparent !default;
  329 +$u-upload-success-border-bottom-color: $u-success !default;
  330 +$u-upload-success-border-right-color: $u-upload-success-border-bottom-color;
  331 +$u-upload-success-border-width: 9px !default;
  332 +$u-upload-icon-top: 0px !default;
  333 +$u-upload-icon-right: 0px !default;
  334 +$u-upload-icon-h5-top: 1px !default;
  335 +$u-upload-icon-h5-right: 0 !default;
  336 +$u-upload-icon-width: 16px !default;
  337 +$u-upload-icon-height: $u-upload-icon-width;
  338 +$u-upload-success-icon-bottom: -10px !default;
  339 +$u-upload-success-icon-right: -10px !default;
  340 +$u-upload-status-right: 0 !default;
  341 +$u-upload-status-left: 0 !default;
  342 +$u-upload-status-bottom: 0 !default;
  343 +$u-upload-status-top: 0 !default;
  344 +$u-upload-status-bgColor: rgba(0, 0, 0, 0.5) !default;
  345 +$u-upload-status-icon-Zindex: 1 !default;
  346 +$u-upload-message-font-size: 12px !default;
  347 +$u-upload-message-color: #FFFFFF !default;
  348 +$u-upload-message-margin-top: 5px !default;
  349 +$u-upload-button-width: 80px !default;
  350 +$u-upload-button-height: $u-upload-button-width;
  351 +$u-upload-button-bgColor: rgb(244, 245, 247) !default;
  352 +$u-upload-button-border-radius: 2px !default;
  353 +$u-upload-botton-margin: 0 8px 8px 0 !default;
  354 +$u-upload-text-font-size: 11px !default;
  355 +$u-upload-text-color: $u-tips-color !default;
  356 +$u-upload-text-margin-top: 2px !default;
  357 +$u-upload-hover-bgColor: rgb(230, 231, 233) !default;
  358 +$u-upload-disabled-opacity: .5 !default;
  359 +
  360 +.u-upload {
  361 + @include flex(column);
  362 + flex: 1;
  363 +
  364 + &__wrap {
  365 + @include flex;
  366 + flex-wrap: wrap;
  367 + flex: 1;
  368 +
  369 + &__preview {
  370 + border-radius: $u-upload-preview-border-radius;
  371 + margin: $u-upload-preview-margin;
  372 + position: relative;
  373 + overflow: hidden;
  374 + @include flex;
  375 +
  376 + &__image {
  377 + width: $u-upload-image-width;
  378 + height: $u-upload-image-height;
  379 + }
  380 +
  381 + &__other {
  382 + width: $u-upload-image-width;
  383 + height: $u-upload-image-height;
  384 + background-color: $u-upload-other-bgColor;
  385 + flex: $u-upload-other-flex;
  386 + @include flex(column);
  387 + justify-content: center;
  388 + align-items: center;
  389 +
  390 + &__text {
  391 + font-size: $u-upload-text-font-size;
  392 + color: $u-upload-text-color;
  393 + margin-top: $u-upload-text-margin-top;
  394 + }
  395 + }
  396 + }
  397 + }
  398 +
  399 + &__deletable {
  400 + position: absolute;
  401 + top: $u-upload-deletable-top;
  402 + right: $u-upload-deletable-right;
  403 + background-color: $u-upload-deletable-bgColor;
  404 + height: $u-upload-deletable-height;
  405 + width: $u-upload-deletable-width;
  406 + @include flex;
  407 + border-bottom-left-radius: $u-upload-deletable-boder-bottom-left-radius;
  408 + align-items: center;
  409 + justify-content: center;
  410 + z-index: $u-upload-deletable-zIndex;
  411 +
  412 + &__icon {
  413 + position: absolute;
  414 + transform: scale(0.7);
  415 + top: $u-upload-icon-top;
  416 + right: $u-upload-icon-right;
  417 + /* #ifdef H5 */
  418 + top: $u-upload-icon-h5-top;
  419 + right: $u-upload-icon-h5-right;
  420 + /* #endif */
  421 + }
  422 + }
  423 +
  424 + &__success {
  425 + display: none;
  426 + position: absolute;
  427 + bottom: $u-upload-success-bottom;
  428 + right: $u-upload-success-right;
  429 + @include flex;
  430 + // 由于weex(nvue)为阿里巴巴的KPI(部门业绩考核)的laji产物,不支持css绘制三角形
  431 + // 所以在nvue下使用图片,非nvue下使用css实现
  432 + /* #ifndef APP-NVUE */
  433 + border-style: $u-upload-success-border-style;
  434 + border-top-color: $u-upload-success-border-top-color;
  435 + border-left-color: $u-upload-success-border-left-color;
  436 + border-bottom-color: $u-upload-success-border-bottom-color;
  437 + border-right-color: $u-upload-success-border-right-color;
  438 + border-width: $u-upload-success-border-width;
  439 + align-items: center;
  440 + justify-content: center;
  441 + /* #endif */
  442 +
  443 + &__icon {
  444 + /* #ifndef APP-NVUE */
  445 + position: absolute;
  446 + transform: scale(0.7);
  447 + bottom: $u-upload-success-icon-bottom;
  448 + right: $u-upload-success-icon-right;
  449 + /* #endif */
  450 + /* #ifdef APP-NVUE */
  451 + width: $u-upload-icon-width;
  452 + height: $u-upload-icon-height;
  453 + /* #endif */
  454 + }
  455 + }
  456 +
  457 + &__status {
  458 + position: absolute;
  459 + top: $u-upload-status-top;
  460 + bottom: $u-upload-status-bottom;
  461 + left: $u-upload-status-left;
  462 + right: $u-upload-status-right;
  463 + background-color: $u-upload-status-bgColor;
  464 + @include flex(column);
  465 + align-items: center;
  466 + justify-content: center;
  467 +
  468 + &__icon {
  469 + position: relative;
  470 + z-index: $u-upload-status-icon-Zindex;
  471 + }
  472 +
  473 + &__message {
  474 + font-size: $u-upload-message-font-size;
  475 + color: $u-upload-message-color;
  476 + margin-top: $u-upload-message-margin-top;
  477 + }
  478 + }
  479 +
  480 + &__button {
  481 + @include flex(column);
  482 + align-items: center;
  483 + justify-content: center;
  484 + width: $u-upload-button-width;
  485 + height: $u-upload-button-height;
  486 + background-color: $u-upload-button-bgColor;
  487 + border-radius: $u-upload-button-border-radius;
  488 + margin: $u-upload-botton-margin;
  489 + /* #ifndef APP-NVUE */
  490 + box-sizing: border-box;
  491 + /* #endif */
  492 +
  493 + &__text {
  494 + font-size: $u-upload-text-font-size;
  495 + color: $u-upload-text-color;
  496 + margin-top: $u-upload-text-margin-top;
  497 + }
  498 +
  499 + &--hover {
  500 + background-color: $u-upload-hover-bgColor;
  501 + }
  502 +
  503 + &--disabled {
  504 + opacity: $u-upload-disabled-opacity;
  505 + }
  506 + }
  507 +}
  508 +</style>
garbage-removal/yarn.lock
@@ -924,7 +924,7 @@ @@ -924,7 +924,7 @@
924 "resolved" "https://registry.npmmirror.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz" 924 "resolved" "https://registry.npmmirror.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz"
925 "version" "0.8.0" 925 "version" "0.8.0"
926 926
927 -"@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": 927 +"@babel/runtime@^7.17.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
928 "integrity" "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==" 928 "integrity" "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg=="
929 "resolved" "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.2.tgz" 929 "resolved" "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.2.tgz"
930 "version" "7.23.2" 930 "version" "7.23.2"
@@ -3075,6 +3075,11 @@ @@ -3075,6 +3075,11 @@
3075 "resolved" "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz" 3075 "resolved" "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz"
3076 "version" "0.5.0" 3076 "version" "0.5.0"
3077 3077
  3078 +"copy-text-to-clipboard@^3.0.1":
  3079 + "integrity" "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q=="
  3080 + "resolved" "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz"
  3081 + "version" "3.2.0"
  3082 +
3078 "core-js-compat@^3.31.0", "core-js-compat@^3.33.1": 3083 "core-js-compat@^3.31.0", "core-js-compat@^3.33.1":
3079 "integrity" "sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw==" 3084 "integrity" "sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw=="
3080 "resolved" "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.33.2.tgz" 3085 "resolved" "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.33.2.tgz"
@@ -3082,7 +3087,7 @@ @@ -3082,7 +3087,7 @@
3082 dependencies: 3087 dependencies:
3083 "browserslist" "^4.22.1" 3088 "browserslist" "^4.22.1"
3084 3089
3085 -"core-js@^3", "core-js@^3.31.1", "core-js@^3.4.1": 3090 +"core-js@^3", "core-js@^3.11.0", "core-js@^3.31.1", "core-js@^3.4.1":
3086 "integrity" "sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==" 3091 "integrity" "sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ=="
3087 "resolved" "https://registry.npmmirror.com/core-js/-/core-js-3.33.2.tgz" 3092 "resolved" "https://registry.npmmirror.com/core-js/-/core-js-3.33.2.tgz"
3088 "version" "3.33.2" 3093 "version" "3.33.2"
@@ -4817,6 +4822,11 @@ @@ -4817,6 +4822,11 @@
4817 "resolved" "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz" 4822 "resolved" "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz"
4818 "version" "2.1.3" 4823 "version" "2.1.3"
4819 4824
  4825 +"mutation-observer@^1.0.3":
  4826 + "integrity" "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
  4827 + "resolved" "https://registry.npmmirror.com/mutation-observer/-/mutation-observer-1.0.3.tgz"
  4828 + "version" "1.0.3"
  4829 +
4820 "nanoid@^3.3.6": 4830 "nanoid@^3.3.6":
4821 "integrity" "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" 4831 "integrity" "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
4822 "resolved" "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz" 4832 "resolved" "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz"
@@ -5941,6 +5951,16 @@ @@ -5941,6 +5951,16 @@
5941 "resolved" "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz" 5951 "resolved" "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz"
5942 "version" "1.1.2" 5952 "version" "1.1.2"
5943 5953
  5954 +"vconsole@^3.15.1":
  5955 + "integrity" "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g=="
  5956 + "resolved" "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz"
  5957 + "version" "3.15.1"
  5958 + dependencies:
  5959 + "@babel/runtime" "^7.17.2"
  5960 + "copy-text-to-clipboard" "^3.0.1"
  5961 + "core-js" "^3.11.0"
  5962 + "mutation-observer" "^1.0.3"
  5963 +
5944 "vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4.0.0", "vite@4.0.3": 5964 "vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4.0.0", "vite@4.0.3":
5945 "integrity" "sha512-HvuNv1RdE7deIfQb8mPk51UKjqptO/4RXZ5yXSAvurd5xOckwS/gg8h9Tky3uSbnjYTgUm0hVCet1cyhKd73ZA==" 5965 "integrity" "sha512-HvuNv1RdE7deIfQb8mPk51UKjqptO/4RXZ5yXSAvurd5xOckwS/gg8h9Tky3uSbnjYTgUm0hVCet1cyhKd73ZA=="
5946 "resolved" "https://registry.npmmirror.com/vite/-/vite-4.0.3.tgz" 5966 "resolved" "https://registry.npmmirror.com/vite/-/vite-4.0.3.tgz"