Commit 98c4741181e8994230bd07543d3b171e7b719b9f

Authored by guzijian
1 parent 89352c3f

feat: 完善订单流程

Showing 31 changed files with 2096 additions and 551 deletions
garbage-removal/.env.production
1 1 # VITE_BASE_URL=http://1.14.107.94:8820
  2 +# VITE_BASE_FILE_UPLOAD_PREFIX=/common/upload
2 3 # VITE_STOMP_URL=http://localhost:8860/ws
... ...
garbage-removal/src/App.vue
... ... @@ -5,7 +5,7 @@ import { setRequestToken } from "./utils/request/request.js";
5 5 const store = useMainStore();
6 6  
7 7 onLaunch(async () => {
8   - console.log("store::==>", store);
  8 + console.log("onLaunch");
9 9 if (store.token) {
10 10 setRequestToken(store.token);
11 11 // store.userInfo = (await getUserInfo()).data.data;
... ...
garbage-removal/src/apis/address.js
1   -
2 1 import { request } from "@/utils/request";
3 2 /**
4 3 * @method 新增用户地址
... ...
garbage-removal/src/apis/carinfo.js 0 → 100644
  1 +import { request } from "@/utils/request";
  2 +/**
  3 + * @method 编辑用户地址
  4 + */
  5 +export async function queryCarList(params) {
  6 + return await request.get(
  7 + `/unit/carInfo/list`,
  8 + {params:params}
  9 + );
  10 +}
... ...
garbage-removal/src/apis/common.js 0 → 100644
  1 +
  2 +
  3 +import { useMainStore } from '@/stores';
  4 +const store = useMainStore();
  5 +export const uploadFilePromise = async (requestPath, url) => {
  6 + return new Promise((resolve, reject) => {
  7 + let a = uni.uploadFile({
  8 + url: requestPath, // 仅为示例,非真实的接口地址
  9 + filePath: url,
  10 + name: 'file',
  11 + header: {
  12 + "Authorization": store.token
  13 + },
  14 + success: (res) => {
  15 + setTimeout(() => {
  16 + resolve(JSON.parse(res.data));
  17 + }, 1000);
  18 + },
  19 + });
  20 + });
  21 +};
... ...
garbage-removal/src/apis/company.js
1 1 import { request } from "@/utils/request";
2 2  
3 3 /**
4   - * @method 编辑用户地址
  4 + * @method 查询运输单位信息
5 5 */
6 6 export async function queryDisposalSiteList() {
7 7 return await request.get(
8   - `/enterprise/list`
  8 + `/disposalSite/list`
  9 + );
  10 +}
  11 +
  12 +
  13 +/**
  14 + * @method 企业详情
  15 + */
  16 +export async function queryEnterpriseList(params) {
  17 + return await request.get(
  18 + `/unit/enterprise/list`,
  19 + {params:params}
9 20 );
10 21 }
... ...
garbage-removal/src/apis/order.js 0 → 100644
  1 +import { request } from "@/utils/request";
  2 +
  3 +/**
  4 + * @method 保存订单
  5 + */
  6 +export async function saveOrder( params,config) {
  7 + return await request.post(
  8 + `/order/add`,
  9 + params,
  10 + config
  11 + );
  12 +}
  13 +
  14 +/**
  15 + * @method 订单详情
  16 + */
  17 +export async function queryOrderDetail(id) {
  18 + return await request.get(
  19 + `/order/detail/${id}`
  20 + );
  21 +}
  22 +
  23 +
  24 +
  25 +/**
  26 + * @method 订单列表
  27 + */
  28 +export async function queryOrderList(data) {
  29 + return await request.get(
  30 + `/order/query/list?type=${data.type}&pageNo=${data.pageNo}&pageSize=${data.pageSize}`,
  31 + );
  32 +}
  33 +
  34 +
  35 +/**
  36 + * @method 修改订单状态
  37 + */
  38 +export async function updateOrder(params,config) {
  39 + return await request.put(
  40 + `/order/update`,
  41 + params,
  42 + config
  43 + );
  44 +}
  45 +
  46 +/**
  47 + * @method 上传图片
  48 + */
  49 +export async function uploadImageUrlByType(params,config) {
  50 + return await request.post(
  51 + `/order/upload/imageUrl`,
  52 + params,
  53 + config
  54 + );
  55 +}
  56 +
  57 +
  58 +/**
  59 + * @method 提交评价
  60 + */
  61 +export async function uploadEvaluate(params,config) {
  62 + return await request.post(
  63 + `/order/evaluate`,
  64 + params,
  65 + config
  66 + );
  67 +}
... ...
garbage-removal/src/apis/user.js
... ... @@ -29,3 +29,13 @@ export async function sendCode(params) {
29 29 `${prefix}/send/verify?tel=${params}`
30 30 );
31 31 }
  32 +
  33 +
  34 +/**
  35 + * @method 发送验证码
  36 + */
  37 +export async function updateUserInfo(params,config) {
  38 + return await request.put(
  39 + `${prefix}/update`,params,config
  40 + );
  41 +}
... ...
garbage-removal/src/components/liu-delivery-time/liu-delivery-time.vue 0 → 100644
  1 +<template>
  2 + <view style="position: absolute; left: 0;" v-if="days && days.length">
  3 + <!-- 弹出层 -->
  4 + <view :class="scrollClass">
  5 + <view class="time-title" :style="{ borderRadius: getRadius }">
  6 + <span @click.stop="close">取消</span>
  7 + {{ title }}
  8 + <text @click.stop="confirm" :style="selectedTimeIndex ? 'color:#007aff;' : ''">确定</text>
  9 + </view>
  10 + <view class="time-picker" :style="{ height: height }">
  11 + <scroll-view class="date-scroll" scroll-y>
  12 + <view class="date-item" v-for="(item, index) in days" :key="index">
  13 + <view class="date" :class="{ active: selectedIndex === index }" @click="handleDateClick(index)">
  14 + {{ item.day }}
  15 + </view>
  16 + </view>
  17 + </scroll-view>
  18 + <scroll-view class="time-scroll" scroll-y>
  19 + <view class="time-item" v-for="(time, index) in selectedDay.timeList" :key="index">
  20 + <view class="time" :class="{ active: selectedTimeIndex === index }" @click="handleTimeClick(index)">
  21 + {{ time.time }}
  22 + </view>
  23 + </view>
  24 + </scroll-view>
  25 + </view>
  26 + </view>
  27 + <view v-show="isShow" class="scroll-mask" @click="isMask ? close() : ''"></view>
  28 + </view>
  29 +</template>
  30 +
  31 +<script>
  32 +export default {
  33 + props: {
  34 + //标题
  35 + title: {
  36 + type: String,
  37 + default: '请选择预约时间',
  38 + },
  39 + //盒子高度
  40 + height: {
  41 + type: String,
  42 + default: '500rpx',
  43 + },
  44 + //展示近几日时间
  45 + day: {
  46 + type: Number,
  47 + default: 7
  48 + },
  49 + //是否点击阴影关闭
  50 + isMask: {
  51 + type: Boolean,
  52 + default: true,
  53 + },
  54 + //是否开启动画
  55 + animation: {
  56 + type: Boolean,
  57 + default: true,
  58 + },
  59 + //是否开启安全条
  60 + safeArea: {
  61 + type: Boolean,
  62 + default: true,
  63 + },
  64 + //圆角
  65 + radius: {
  66 + type: String,
  67 + default: '24rpx',
  68 + },
  69 + },
  70 + data() {
  71 + return {
  72 + isShow: false,
  73 + selectedIndex: 0,
  74 + selectedDay: {},
  75 + selectedTimeIndex: 999,
  76 + days: []
  77 + };
  78 + },
  79 + mounted() {
  80 + this.days = this.getFutureDays()
  81 + this.selectedDay = this.days[0]
  82 + },
  83 + computed: {
  84 + scrollClass() {
  85 + const classes = ['scroll-popup'];
  86 + if (this.isShow) classes.push('scroll-open');
  87 + if (this.animation) classes.push('scroll-animation');
  88 + if (this.safeArea) classes.push('scroll-temp');
  89 + return classes;
  90 + },
  91 + getRadius() {
  92 + return `${this.radius} ${this.radius} 0 0`;
  93 + },
  94 + },
  95 + methods: {
  96 + //时间数据构造
  97 + getFutureDays() {
  98 + const days = [];
  99 + for (let i = 0; i < this.day; i++) {
  100 + const date = new Date();
  101 + date.setDate(date.getDate() + i);
  102 + const year = date.getFullYear();
  103 + const month = (date.getMonth() + 1).toString().padStart(2, '0');
  104 + const day = date.getDate().toString().padStart(2, '0');
  105 + const timeList = [{
  106 + time: '06:00-08:00',
  107 + start: '06:00',
  108 + end: '08:00'
  109 + }, {
  110 + time: '08:00-10:00',
  111 + start: '08:00',
  112 + end: '10:00'
  113 + },
  114 + {
  115 + time: '10:00-12:00',
  116 + start: '10:00',
  117 + end: '12:00'
  118 + },
  119 + {
  120 + time: '12:00-14:00',
  121 + start: '12:00',
  122 + end: '14:00'
  123 + },
  124 + {
  125 + time: '14:00-16:00',
  126 + start: '14:00',
  127 + end: '16:00'
  128 + },
  129 + {
  130 + time: '16:00-18:00',
  131 + start: '16:00',
  132 + end: '18:00'
  133 + },
  134 + {
  135 + time: '18:00-20:00',
  136 + start: '18:00',
  137 + end: '20:00'
  138 + },
  139 + {
  140 + time: '20:00-22:00',
  141 + start: '20:00',
  142 + end: '22:00'
  143 + }
  144 + ];
  145 + days.push({
  146 + day: `${year}-${month}-${day}`,
  147 + timeList: timeList
  148 + });
  149 + }
  150 + return days;
  151 + },
  152 + open() {
  153 + this.isShow = true;
  154 + this.init();
  155 + },
  156 + init() {
  157 + this.selectedIndex = 0;
  158 + this.selectedDay = this.days[0];
  159 + this.selectedTimeIndex = 999;
  160 + },
  161 + close() {
  162 + this.isShow = false;
  163 + },
  164 + handleDateClick(index) {
  165 + this.selectedIndex = index;
  166 + this.selectedDay = this.days[index];
  167 + this.selectedTimeIndex = 999;
  168 + },
  169 + handleTimeClick(index) {
  170 + this.selectedTimeIndex = index;
  171 + },
  172 + confirm() {
  173 + if (this.selectedTimeIndex == 999) {
  174 + uni.showToast({
  175 + title: this.title,
  176 + icon: 'none'
  177 + })
  178 + return
  179 + }
  180 + const time = this.selectedDay.timeList[this.selectedTimeIndex]
  181 + this.close();
  182 + this.$emit('change', {
  183 + day: this.selectedDay.day,
  184 + time: time.time,
  185 + startHour: time.start,
  186 + endHour: time.end,
  187 + value: `${this.selectedDay.day} ${time.time}`,
  188 + });
  189 + }
  190 + },
  191 +};
  192 +</script>
  193 +
  194 +<style>
  195 +::v-deep .-webkit-scrollbar {
  196 + width: 0;
  197 + height: 0;
  198 + color: transparent;
  199 + display: none;
  200 +}
  201 +</style>
  202 +<style scoped>
  203 +/* 弹出层默认样式 */
  204 +.scroll-popup {
  205 + width: 100%;
  206 + position: fixed;
  207 + bottom: -100%;
  208 + z-index: 999;
  209 +}
  210 +
  211 +/* 点击按钮是将盒子 bottom 值归零即可实现弹出效果,
  212 + 同理,如需更改弹出方向只需将bottom改成top、left、right即可
  213 + (默认样式的方向也需一起更改哦) */
  214 +.scroll-open {
  215 + bottom: 0px !important;
  216 +}
  217 +
  218 +.scroll-animation {
  219 + transition: all 0.25s linear;
  220 +}
  221 +
  222 +.scroll-temp {
  223 + padding-bottom: env(safe-area-inset-bottom);
  224 +}
  225 +
  226 +/* 遮罩层样式 */
  227 +.scroll-mask {
  228 + position: fixed;
  229 + top: 0;
  230 + left: 0;
  231 + right: 0;
  232 + bottom: 0;
  233 + background: rgba(0, 0, 0, 0.3);
  234 + z-index: 998;
  235 +}
  236 +
  237 +.time-picker {
  238 + display: flex;
  239 + align-items: center;
  240 + color: #666666;
  241 + background-color: #fff;
  242 +}
  243 +
  244 +.time-title {
  245 + width: 100%;
  246 + height: 88rpx;
  247 + line-height: 88rpx;
  248 + font-size: 32rpx;
  249 + font-weight: bold;
  250 + color: #333333;
  251 + background-color: #ffffff;
  252 + text-align: center;
  253 + position: relative;
  254 + border-bottom: 1rpx solid #f6f6f6;
  255 +}
  256 +
  257 +.time-title span {
  258 + font-size: 28rpx;
  259 + font-weight: 400;
  260 + position: absolute;
  261 + left: 32rpx;
  262 + top: 0;
  263 + bottom: 0;
  264 + margin: auto 0;
  265 + color: #666666;
  266 +}
  267 +
  268 +.time-title text {
  269 + font-size: 28rpx;
  270 + font-weight: 400;
  271 + position: absolute;
  272 + right: 32rpx;
  273 + top: 0;
  274 + bottom: 0;
  275 + margin: auto 0;
  276 + color: #666666;
  277 +}
  278 +
  279 +.date-scroll {
  280 + flex: 1;
  281 + height: 100%;
  282 + border-right: 1rpx solid #f6f6f6;
  283 + box-sizing: border-box;
  284 +}
  285 +
  286 +.date-item {
  287 + height: 88rpx;
  288 + line-height: 88rpx;
  289 + text-align: center;
  290 + box-sizing: border-box;
  291 + border-bottom: 1rpx solid #f6f6f6;
  292 +}
  293 +
  294 +.date {
  295 + font-size: 28rpx;
  296 +}
  297 +
  298 +.date.active {
  299 + font-size: 30rpx;
  300 + font-weight: bold;
  301 + color: #007aff;
  302 +}
  303 +
  304 +.time-scroll {
  305 + flex: 1;
  306 + height: 100%;
  307 +}
  308 +
  309 +.time-item {
  310 + height: 88rpx;
  311 + line-height: 88rpx;
  312 + text-align: center;
  313 + box-sizing: border-box;
  314 + border-bottom: 1rpx solid #f6f6f6;
  315 +}
  316 +
  317 +.time {
  318 + font-size: 28rpx;
  319 +}
  320 +
  321 +.time.active {
  322 + font-size: 30rpx;
  323 + font-weight: bold;
  324 + color: #007aff;
  325 +}
  326 +</style>
... ...
garbage-removal/src/manifest.json
... ... @@ -57,6 +57,15 @@
57 57 },
58 58 "usingComponents" : true
59 59 },
  60 + "h5" : {
  61 + "sdkConfigs" : {
  62 + "maps" : {
  63 + "qqmap" : {
  64 + "key" : "LNFBZ-YRSW3-HMU3T-RZP6V-XCWV5-EKFWP"
  65 + }
  66 + }
  67 + }
  68 + },
60 69 "mp-alipay" : {
61 70 "usingComponents" : true
62 71 },
... ...
garbage-removal/src/pages.json
... ... @@ -10,12 +10,44 @@
10 10 {
11 11 "path": "pages/login/index",
12 12 "style": {
13   - "navigationBarTitleText": "装饰装修垃圾智慧功能模块登录"
  13 + "navigationBarTitleText": "装饰装修垃圾智慧功能模块登录",
  14 + "enablePullDownRefresh": false
14 15 }
15 16 },{
16 17 "path": "pages/login/code",
17 18 "style": {
18   - "navigationBarTitleText": "输入验证码"
  19 + "navigationBarTitleText": "输入验证码",
  20 + "enablePullDownRefresh": false
  21 + }
  22 + },{
  23 + "path": "pages/wode/choose/index",
  24 + "style": {
  25 + "navigationBarTitleText": "选择身份",
  26 + "enablePullDownRefresh": false
  27 + }
  28 + },{
  29 + "path": "pages/order/detail/index",
  30 + "style": {
  31 + "navigationBarTitleText": "派单详情",
  32 + "navigationBarTextStyle": "white",
  33 + "navigationBarBackgroundColor": "#53c21d",
  34 + "enablePullDownRefresh": false
  35 + }
  36 + },{
  37 + "path": "pages/order/upload/index",
  38 + "style": {
  39 + "navigationBarTitleText": "上传照片",
  40 + "navigationBarTextStyle": "white",
  41 + "navigationBarBackgroundColor": "#53c21d",
  42 + "enablePullDownRefresh": false
  43 + }
  44 + },{
  45 + "path": "pages/order/evaluate/index",
  46 + "style": {
  47 + "navigationBarTitleText": "写评价",
  48 + "navigationBarTextStyle": "white",
  49 + "navigationBarBackgroundColor": "#53c21d",
  50 + "enablePullDownRefresh": false
19 51 }
20 52 },
21 53 {
... ... @@ -39,13 +71,15 @@
39 71 {
40 72 "path": "pages/home/clean/company-detail/index",
41 73 "style": {
42   - "navigationBarTitleText": "公司信息"
  74 + "navigationBarTitleText": "公司信息",
  75 + "enablePullDownRefresh": false
43 76 }
44 77 },
45 78 {
46 79 "path": "pages/home/clean/index",
47 80 "style": {
48   - "navigationBarTitleText": "装修垃圾"
  81 + "navigationBarTitleText": "装修垃圾",
  82 + "enablePullDownRefresh": false
49 83 }
50 84 },
51 85 {
... ... @@ -53,7 +87,8 @@
53 87 "style": {
54 88 "navigationBarTitleText": "清运地址",
55 89 "navigationBarTextStyle":"white",
56   - "navigationBarBackgroundColor":"#53c21d"
  90 + "navigationBarBackgroundColor":"#53c21d",
  91 + "enablePullDownRefresh": false
57 92 }
58 93 },
59 94 {
... ... @@ -61,19 +96,23 @@
61 96 "style": {
62 97 "navigationBarTitleText": "清运地址",
63 98 "navigationBarTextStyle":"white",
64   - "navigationBarBackgroundColor":"#53c21d"
  99 + "navigationBarBackgroundColor":"#53c21d",
  100 + "enablePullDownRefresh": false
65 101 }
66 102 },{
67 103 "path": "pages/order/index",
68 104 "style": {
69   - "navigationBarTitleText": "单详情",
  105 + "navigationBarTitleText": "单详情",
70 106 "navigationBarTextStyle":"white",
71   - "navigationBarBackgroundColor":"#53c21d"
  107 + "navigationBarBackgroundColor":"#53c21d",
  108 + "enablePullDownRefresh": false
72 109 }
73 110 },{
74 111 "path": "pages/wode/index",
75 112 "style": {
76   - "navigationBarTitleText": ""
  113 + "navigationBarTitleText": "",
  114 + "navigationBarBackgroundColor": "#ffffff",
  115 + "enablePullDownRefresh": false
77 116 }
78 117 }
79 118 ],
... ... @@ -91,7 +130,7 @@
91 130 "pagePath": "pages/order/index",
92 131 "iconPath": "static/tabbar/icon/order.png",
93 132 "selectedIconPath": "static/tabbar/icon/order-green.png",
94   - "text": "单"
  133 + "text": "单"
95 134 }, {
96 135 "pagePath": "pages/wode/index",
97 136 "iconPath": "static/tabbar/icon/wode.png",
... ...
garbage-removal/src/pages/home/address/addSite.vue
... ... @@ -160,7 +160,6 @@ const submit = () =&gt; {
160 160 * 打开地图选择地址
161 161 */
162 162 const chooseAddressDetail = () => {
163   - console.log("sss");
164 163 uni.chooseLocation({
165 164 success: function (res) {
166 165 addressInfo.addressDetail = res.address + res.name;
... ...
garbage-removal/src/pages/home/clean/company-detail/index.vue
... ... @@ -3,14 +3,15 @@
3 3 <view class="company-content-box">
4 4 <view class="company-content-header">
5 5 <view class="company-content-left">
6   - <image class="company-content-left-image" src="https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png" />
  6 + <image class="company-content-left-image"
  7 + :src="headerData.carParkPanorama ? headerData.carParkPanorama : 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png'" />
7 8 </view>
8 9 <view class="company-content-right">
9 10 <view class="company-content-right-name">
10   - 宁波垃圾回收公司
  11 + {{ headerData.name }}
11 12 </view>
12 13 <view class="company-content-right-area">
13   - 注册区划:海曙区
  14 + 注册区划:{{ headerData.registrationArea }}
14 15 </view>
15 16 </view>
16 17 </view>
... ... @@ -23,9 +24,13 @@
23 24 <view class="company-content-base-data-info-item-label">
24 25 {{ item.label }}:
25 26 </view>
26   - <view class="company-content-base-data-info-item-txt">
  27 + <view v-if="item.label != '道路运输许可证'" class="company-content-base-data-info-item-txt">
27 28 {{ item.value }}
28 29 </view>
  30 + <view v-else class="company-content-base-data-info-item-txt">
  31 + <u-upload :fileList="[item.value]" name="3" multiple :maxCount="10" :previewFullImage="true"
  32 + :isReadOnly="true"></u-upload>
  33 + </view>
29 34 </view>
30 35 </view>
31 36 </view>
... ... @@ -33,8 +38,8 @@
33 38 <view class="company-content-car-info-title">核准车辆信息</view>
34 39 <view class="company-content-car-info-sub-title">车牌号(车型)</view>
35 40 <view class="company-content-car-info-car-list">
36   - <view v-for="(item, index) in baseDataList" :key="index" class="company-content-car-info-car-list-item">
37   - 浙B5S785<text class="car-type">(自卸车)</text>
  41 + <view v-for="(item, index) in carList" :key="index" class="company-content-car-info-car-list-item">
  42 + {{ item.carCode }}<text class="car-type">({{ item.carType }})</text>
38 43 </view>
39 44 </view>
40 45 <view class="company-content-remark">
... ... @@ -74,38 +79,31 @@
74 79 </view>
75 80 </view>
76 81 <view class="company-bottom-button-right">
77   - <u-button icon="car-fill" :custom-style="customStyle" @click="handleCleanGarbage(companyId, tel)" type="success"
78   - :hairline="true" size="normal" shape="circle" text="垃圾清运"></u-button>
  82 + <u-button icon="car-fill" :custom-style="customStyle" @click="handleCleanGarbage(companyInfo, tel, userAddress)"
  83 + type="success" :hairline="true" size="normal" shape="circle" text="垃圾清运"></u-button>
79 84 </view>
80 85 </view>
81 86 </view>
82 87 </template>
83 88  
84 89 <script setup>
  90 +import { queryCarList } from '@/apis/carinfo.js';
85 91 import { onLoad } from '@dcloudio/uni-app';
86   -import { onMounted, ref } from 'vue';
  92 +import { ref } from 'vue';
87 93 const baseDataList = ref([{ label: '法人' }, { label: '负责人' }, { label: '业务联系电话' }, { label: '道路运输许可证' }, { label: '核准有效期' }, { label: '注册地址' }]);
88   -const baseData = ref({
89   - legalEntity: '王波',
90   - leader: '王波',
91   - contact: '18985336652',
92   - allowCertificate: "无",
93   - validTime: '2020-10-20至2024-10-19',
94   - signAddress: '浙江省宁波市清洲区复明街道会展路128号017幢7-32-3'
95   -})
96 94 const customStyle = ref({
97 95 fontSize: '30rpx',
98 96 lineHeight: '30rpx'
99 97 })
100   -const companyId = ref()
  98 +const carList = ref()
  99 +const companyInfo = ref()
101 100 const tel = ref()
102   -const handleCleanGarbage = (companyId, tel) => {
103   - console.log("垃圾清运");
104   - uni.$u.route({
105   - url: `pages/home/clean/index?companyId=${companyId}&tel=${tel}`,
106   - })
107   -}
108   -
  101 +const userAddress = ref()
  102 +const headerData = ref({
  103 + name: "",
  104 + registrationArea: "",
  105 + carParkPanorama: ""
  106 +})
109 107 const serverData = ref([
110 108 {
111 109 label: '清运区域',
... ... @@ -128,20 +126,32 @@ const handleContactClick = (val) =&gt; {
128 126 }).catch(err => { });
129 127 }
130 128 onLoad((options) => {
131   - console.log(options.companyId);
132   - companyId.value = options.companyId
133   - tel.value = options.tel
134   -})
135   -onMounted(() => {
136   - initData();
  129 + companyInfo.value = JSON.parse(options.companyObj);
  130 + userAddress.value = JSON.parse(options.userAddress);
  131 + tel.value = options.tel;
  132 + initData(companyInfo.value);
  133 + queryCarList({ companyId: companyInfo.value.id }).then(res => {
  134 + carList.value = res.data.rows
  135 + })
137 136 })
138   -const initData = () => {
139   - baseDataList.value[0].value = baseData.value.legalEntity
140   - baseDataList.value[1].value = baseData.value.leader
141   - baseDataList.value[2].value = baseData.value.contact
142   - baseDataList.value[3].value = baseData.value.allowCertificate
143   - baseDataList.value[4].value = baseData.value.validTime
144   - baseDataList.value[5].value = baseData.value.signAddress
  137 +
  138 +const handleCleanGarbage = (companyObj, tel, userAddress) => {
  139 + uni.$u.route({
  140 + url: `pages/home/clean/index?companyObj=${JSON.stringify(companyObj)}&tel=${tel}&userAddress=${JSON.stringify(userAddress)}`,
  141 + })
  142 +}
  143 +
  144 +const initData = (baseData) => {
  145 + console.log(baseData);
  146 + baseDataList.value[0].value = baseData.legalRepresentative
  147 + baseDataList.value[1].value = baseData.safetyManagerName
  148 + baseDataList.value[2].value = baseData.safetyManagerPhone
  149 + baseDataList.value[3].value = baseData.transportPermission
  150 + baseDataList.value[4].value = baseData.businessLicenseDate
  151 + baseDataList.value[5].value = baseData.officeAddress
  152 + headerData.value.name = baseData.name;
  153 + headerData.value.registrationArea = baseData.registrationArea;
  154 + headerData.value.carParkPanorama = baseData.carParkPanorama;
145 155 }
146 156 </script>
147 157  
... ...
garbage-removal/src/pages/home/clean/index.vue
... ... @@ -3,21 +3,22 @@
3 3 <view class="company-clean-container-box">
4 4 <view class="company-clean-container-header">
5 5 <view class="company-clean-container-header-address">
6   - 宁波市海曙区昱湖街道上海
  6 + {{ userAddress.garUserAddress + userAddress.garRemark }}
7 7 </view>
8 8 <view class="company-clean-container-header-base-info">
9   - 李云龙 189802245165
  9 + {{ userAddress.garUserContactName }} {{ userAddress.garUserContactTel }}
10 10 </view>
11 11 <view class="company-clean-container-header-reservation">
12 12 <view class="company-clean-container-header-reservation-left">
13 13 <u-icon name="calendar" size="40"></u-icon>
14 14 预约时间
15 15 </view>
16   - <view class="company-clean-container-header-reservation-right" @click="handleTimeChoose">
17   - <text style="margin-right: 10rpx;">请选择时间</text> <u-icon name="arrow-right" size="25"></u-icon>
  16 + <view class="company-clean-container-header-reservation-right">
  17 + <text style="margin-right: 10rpx;" @click="handleTimeChoose">{{ dayTime ? dayTime : "请选择时间" }}</text> <u-icon
  18 + name="arrow-right" size="25"></u-icon>
  19 + <liu-delivery-time @change="changeTime" ref="chooseTime" title="请选择预约时间"></liu-delivery-time>
18 20 </view>
19 21 </view>
20   -
21 22 </view>
22 23 <view class="company-clean-container-car-main">
23 24 <view class="company-clean-container-car-main-title">
... ... @@ -36,7 +37,7 @@
36 37 <u-icon name="arrow-down" size="30" color="#ffffff"></u-icon>
37 38 </view>
38 39 <view class="company-clean-container-car-main-content-type-price-area">
39   - $5000元/
  40 +
40 41 </view>
41 42 </view>
42 43 <view class="company-clean-container-car-main-content-number">
... ... @@ -72,7 +73,7 @@
72 73 <view class="company-clean-container-site-image-info-sure-button-radio">
73 74 <u-radio-group v-model="paramFrom.sureReadFlag">
74 75 <u-radio activeColor="#a9e08f" size="27" labelSize="25" :labelDisabled="true" labelColor="#909399"
75   - label="本人已确认信息真实有效,并将上述信息告知市容环境卫生主管部门。"></u-radio>
  76 + label=""></u-radio>本人已确认信息真实有效,并将上述信息告知市容环境卫生主管部门。
76 77 </u-radio-group>
77 78 </view>
78 79 </view>
... ... @@ -90,7 +91,7 @@
90 91 <u-icon @click="handleCarInfo" :stop="true" size="50" name="car-fill"></u-icon>
91 92 </view>
92 93 <view class="company-clean-bottom-right">
93   - <u-button @click="handleOderSure" shape="circle" color="#a9e08f" text="立即单"></u-button>
  94 + <u-button @click="handleOderSure" shape="circle" color="#a9e08f" text="立即单"></u-button>
94 95 </view>
95 96 </view>
96 97 </view>
... ... @@ -98,44 +99,55 @@
98 99 </template>
99 100  
100 101 <script setup>
  102 +import { queryCarList } from '@/apis/carinfo.js';
  103 +import { uploadFilePromise } from '@/apis/common.js';
  104 +import { saveOrder } from '@/apis/order.js';
  105 +import liuDeliveryTime from "@/components/liu-delivery-time/liu-delivery-time.vue";
101 106 import { onLoad } from '@dcloudio/uni-app';
102 107 import { getCurrentInstance, onMounted, ref } from 'vue';
103 108 const { proxy } = getCurrentInstance();
104 109 const x = ref(5)
105 110 const y = ref()
106 111 const movableAreaElement = ref()
107   -const companyId = ref()
  112 +const companyObj = ref()
108 113 const tel = ref()
  114 +const userAddress = ref()
  115 +const carList = ref();
109 116 const paramFrom = ref({
110 117 carNumber: 0,
111 118 remark: "",
112 119 sureReadFlag: false
113 120 })
  121 +const dayTime = ref()
114 122  
115   -const fileList = ref([{
116   -
117   -}])
  123 +const chooseTime = ref()
  124 +const fileList = ref([])
118 125  
119 126 const handleTimeChoose = () => {
120   - console.log("选择时间");
  127 + chooseTime.value.open();
  128 +}
  129 +
  130 +const changeTime = (e) => {
  131 + dayTime.value = e.value
121 132 }
122 133 /**
123 134 * 初始化信息
124 135 */
125 136 onLoad((options) => {
126   - companyId.value = options.companyId;
  137 + companyObj.value = JSON.parse(options.companyObj);
  138 + console.log(companyObj.value);
127 139 tel.value = options.tel;
128   - console.log("tel:", tel);
129   -
  140 + userAddress.value = JSON.parse(options.userAddress);
  141 + queryCarList({ companyId: companyObj.value.id }.then(res => {
  142 + carList.value = res.data.rows
  143 + }))
130 144 })
131 145  
132 146 /**
133 147 * 拨打电话回调
134 148 */
135 149 const handleContactClick = (val) => {
136   - console.log("拨打电话");
137 150 uni.makePhoneCall({ phoneNumber: val }).then(res => {
138   - console.log(res);
139 151 }).catch(err => { });
140 152 }
141 153  
... ... @@ -157,35 +169,20 @@ const afterRead = async (event) =&gt; {
157 169 });
158 170 });
159 171 for (let i = 0; i < lists.length; i++) {
160   - const result = await uploadFilePromise(lists[i].url);
  172 + let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_BASE_FILE_UPLOAD_PREFIX;
  173 + const result = await uploadFilePromise(requestPath, lists[i].url);
161 174 let item = fileList.value[fileListLen];
162 175 fileList.value.splice(fileListLen, 1, {
163 176 ...item,
164 177 status: 'success',
165 178 message: '',
166   - url: result,
  179 + url: result.data.fileName,
167 180 });
168 181 fileListLen++;
169 182 }
170 183 };
171 184  
172   -const uploadFilePromise = (url) => {
173   - return new Promise((resolve, reject) => {
174   - let a = uni.uploadFile({
175   - url: 'http://192.168.2.21:7001/upload', // 仅为示例,非真实的接口地址
176   - filePath: url,
177   - name: 'file',
178   - formData: {
179   - user: 'test',
180   - },
181   - success: (res) => {
182   - setTimeout(() => {
183   - resolve(res.data.data);
184   - }, 1000);
185   - },
186   - });
187   - });
188   -};
  185 +
189 186  
190 187 /**
191 188 * 处理车子数量
... ... @@ -198,7 +195,79 @@ const handleCarInfo = () =&gt; {
198 195 * 处理下单
199 196 */
200 197 const handleOderSure = () => {
201   - console.log("下单了");
  198 + console.log("下单了", companyObj.value);
  199 + let params = {
  200 + /**
  201 + * 订单地址
  202 + */
  203 + garOrderAddress: userAddress.value.garUserAddress,
  204 +
  205 + /**
  206 + * 订单详细地址
  207 + */
  208 + garOrderAddressDetails: userAddress.value.garRemark,
  209 +
  210 + /**
  211 + * 订单姓名
  212 + */
  213 + garOrderContactName: userAddress.value.garUserContactName,
  214 +
  215 + /**
  216 + * 垃圾类型
  217 + */
  218 + garOrderTrashType: "建筑垃圾",
  219 +
  220 + /**
  221 + * 订单人电话
  222 + */
  223 + garOrderContactTel: userAddress.value.garUserContactTel,
  224 +
  225 + /**
  226 + * 承接经营单位
  227 + */
  228 + garOrderCompanyId: companyObj.value.id,
  229 +
  230 + /**
  231 + * 公司名称
  232 + */
  233 + garOrderCompanyName: companyObj.value.name,
  234 +
  235 + /**
  236 + * 公司负责人电话
  237 + */
  238 + garOrderCompanyTel: companyObj.value.safetyManagerPhone,
  239 +
  240 + /**
  241 + * 约定时间
  242 + */
  243 + garOrderAgreementTime: dayTime.value,
  244 + /**
  245 + * 备注
  246 + */
  247 + garRemark: paramFrom.value.remark,
  248 + /**
  249 + * 图片列表
  250 + */
  251 + imageUrls: fileList.value.map(item => item.url),
  252 + }
  253 + if (!validateParams(params)) {
  254 + return;
  255 + }
  256 + saveOrder(params).then(res => {
  257 + console.log(res);
  258 + // TODO 订单详情
  259 + if (res.data.success) {
  260 + uni.$u.route({
  261 + type: "redirect",
  262 + url: `pages/order/detail/index`,
  263 + params: {
  264 + orderId: res.data.data
  265 + }
  266 + })
  267 + }
  268 + uni.$u.toast(res.data.msg)
  269 + })
  270 +
202 271 }
203 272  
204 273 onMounted(() => {
... ... @@ -207,7 +276,6 @@ onMounted(() =&gt; {
207 276 let movableArea = uni.createSelectorQuery().in(proxy).select(".movableArea");
208 277 movableArea.boundingClientRect(function (data) {
209 278 // data - 包含元素的高度等信息
210   - console.log("area:", data.height) // 获取元素宽度
211 279 areaHeight = data.height;
212 280 y.value = areaHeight;
213 281 }).exec(function (res) {
... ... @@ -215,6 +283,10 @@ onMounted(() =&gt; {
215 283 })
216 284 })
217 285  
  286 +const validateParams = (params) => {
  287 + return true;
  288 +}
  289 +
218 290 </script>
219 291  
220 292 <style lang="scss" scoped>
... ... @@ -410,6 +482,7 @@ $custom-bottom-height: 200rpx;
410 482 box-sizing: border-box;
411 483 display: flex;
412 484 flex-flow: row wrap;
  485 + color: $u-info;
413 486 }
414 487 }
415 488  
... ...
garbage-removal/src/pages/home/index.vue
... ... @@ -9,7 +9,7 @@
9 9 }" class="top-address">
10 10 <view class="address-icon-image"><u-icon name="map" color="#fff" size="28"></u-icon></view>
11 11 <view class="address-text" @click="handleAddressInfo">
12   - {{ userAddress ? userAddress : "请设置清运地址" }}
  12 + {{ addressInfo ? addressInfo : "请设置清运地址" }}
13 13 </view>
14 14 <view class="address-icon-label">
15 15 <u-icon name="arrow-right" color="#fff" size="28"></u-icon>
... ... @@ -40,45 +40,52 @@
40 40 </view>
41 41 <view class="company-list-content">
42 42 <view class="company-list-content-box">
43   - <view class="company-list-item" v-for="item in companyList" :key="item.companyId">
44   - <view class="company-list-item-main">
45   - <view class="company-list-item-main-left">
46   - <image class="company-list-item-main-left-img" :src="item.image" />
47   - </view>
48   - <view class="company-list-item-main-right" @click="handleDetailClick(item.companyId, item.tel)">
49   - <view class="company-list-item-main-right-name">
50   - {{ item.companyName }}
  43 + <z-paging ref="paging" :fixed="false" v-model="companyList" @query="queryList">
  44 + <empty-view slot:empty></empty-view>
  45 + <view class="company-list-item" v-for="item in companyList" :key="item.id">
  46 + <view class="company-list-item-main">
  47 + <view class="company-list-item-main-left">
  48 + <image class="company-list-item-main-left-img"
  49 + :src="item.carParkPanorama ? item.carParkPanorama : 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png'" />
51 50 </view>
52   - <view class="company-list-item-main-right-score">
53   - <text class="company-list-item-main-right-text">评分:</text>
54   - <view class="company-list-item-main-right-score-start">
55   - <u-icon v-for="todo in maxStar" :name="item.score > todo ? 'star-fill' : 'star'" :key="todo"
56   - color="#f9ae3d" size="28"></u-icon>
  51 + <view class="company-list-item-main-right"
  52 + @click="handleDetailClick(item, item.legalRepresentativePhone, userAddress)">
  53 + <view class="company-list-item-main-right-name">
  54 + {{ item.abbreviation }}
57 55 </view>
58   - <text class="company-list-item-main-right-text" style="color: #fd5d00;">5分</text>
59   - </view>
60   - <view class="company-list-item-main-right-price-number">
61   - <view class="company-list-item-main-right-price">¥{{ item.startPrice }}起</view>
62   - <view class="company-list-item-main-right-number">
63   - 清运数:<text class="company-list-item-main-right-number-text">{{ item.cleanNumber }}</text>
  56 + <view class="company-list-item-main-right-score">
  57 + <text class="company-list-item-main-right-text">评分:</text>
  58 + <view class="company-list-item-main-right-score-start">
  59 + <u-icon v-for="todo in maxStar" :name="item.score > todo ? 'star-fill' : 'star'" :key="todo"
  60 + color="#f9ae3d" size="28"></u-icon>
  61 + </view>
  62 + <text class="company-list-item-main-right-text" style="color: #fd5d00;">5分</text>
  63 + </view>
  64 + <view class="company-list-item-main-right-price-number">
  65 + <view class="company-list-item-main-right-price">公司类型:{{ item.companyType == 0 ? "经营单位" : "运输公司"
  66 + }}&nbsp;&nbsp;</view>
  67 + <view class="company-list-item-main-right-number">
  68 + 车辆数:<text class="company-list-item-main-right-number-text">{{ item.carNumber }}</text>
  69 + </view>
  70 + </view>
  71 + <view class="company-list-item-main-right-remark">
  72 + {{ item.remark }}
64 73 </view>
65 74 </view>
66   - <view class="company-list-item-main-right-remark">
67   - {{ item.remark }}
68   - </view>
69   - </view>
70   - </view>
71   - <view class="company-list-item-bottom">
72   - <view class="company-list-item-bottom-contact-company">
73   - <u-button @click="handleContactClick(item.tel)" color="#a9e08f" size="normal" type="success"
74   - :hairline="true" shape="circle" text="联系公司"></u-button>
75 75 </view>
76   - <view class="company-list-item-bottom-button-clean">
77   - <u-button @click="handleCleanGarbage(item.companyId, item.tel)" type="success" :hairline="true"
78   - size="normal" shape="circle" text="垃圾清运"></u-button>
  76 + <view class="company-list-item-bottom">
  77 + <view class="company-list-item-bottom-contact-company">
  78 + <u-button @click="handleContactClick(item.legalRepresentativePhone)" color="#a9e08f" size="normal"
  79 + type="success" :hairline="true" shape="circle" text="联系公司"></u-button>
  80 + </view>
  81 + <view class="company-list-item-bottom-button-clean">
  82 + <u-button @click="handleCleanGarbage(item, item.legalRepresentativePhone, userAddress)"
  83 + type="success" :hairline="true" size="normal" shape="circle" text="垃圾清运"></u-button>
  84 + </view>
79 85 </view>
80 86 </view>
81   - </view>
  87 + </z-paging>
  88 +
82 89 </view>
83 90 </view>
84 91 </view>
... ... @@ -89,7 +96,7 @@
89 96  
90 97 <script setup >
91 98 import { queryAddress } from '@/apis/address.js';
92   -import { queryDisposalSiteList } from '@/apis/company.js';
  99 +import { queryEnterpriseList } from '@/apis/company.js';
93 100 import { onLoad, onShow } from '@dcloudio/uni-app';
94 101 import { ref } from 'vue';
95 102 // 定义最大积分
... ... @@ -98,6 +105,7 @@ const maxStar = ref([])
98 105 const lightHeight = ref();//胶囊按钮信息
99 106 const topMargin = ref(null);//状态栏高度
100 107 const musicheadHeight = ref();
  108 +const paging = ref(null)
101 109 const swiperImageList = ref([{
102 110 image: 'https://cdn.uviewui.com/uview/swiper/swiper2.png',
103 111 }, {
... ... @@ -106,8 +114,8 @@ const swiperImageList = ref([{
106 114 image: 'https://cdn.uviewui.com/uview/swiper/swiper3.png',
107 115 }])
108 116  
109   -const userAddress = ref()
110   -
  117 +const userAddress = ref({})
  118 +const addressInfo = ref()
111 119  
112 120 // 信息指南
113 121 const infoBoxList = ref([{
... ... @@ -125,55 +133,14 @@ const infoBoxList = ref([{
125 133 },])
126 134  
127 135 //公司列表
128   -const companyList = ref([
129   - {
130   - companyId: '1',
131   - score: 4,
132   - image: 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png',
133   - companyName: '宁波垃圾回收公司',
134   - startPrice: '500',
135   - cleanNumber: '1996',
136   - remark: '我司专业拆除清运,装修大件垃圾的环保科技企业。',
137   - tel: '18980249130',
138   - }
139   - , {
140   - companyId: '2',
141   - score: 4,
142   - image: 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png',
143   - companyName: '宁波垃圾回收公司',
144   - startPrice: '500',
145   - cleanNumber: '1996',
146   - remark: '我司专业拆除清运,装修大件垃圾的环保科技企业。',
147   - tel: '18980249130',
148   - },
149   - {
150   - companyId: '3',
151   - score: 4,
152   - image: 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png',
153   - companyName: '宁波垃圾回收公司',
154   - startPrice: '500',
155   - cleanNumber: '1996',
156   - remark: '我司专业拆除清运,装修大件垃圾的环保科技企业。',
157   - tel: '18980249130',
158   - },
159   - // {
160   - // companyId: '1',
161   - // score: 4,
162   - // image: 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png',
163   - // companyName: '宁波垃圾回收公司',
164   - // startPrice: '500',
165   - // cleanNumber: '1996',
166   - // remark: '我司专业拆除清运,装修大件垃圾的环保科技企业。',
167   - // tel: '18980249130',
168   - // }
169   -])
  136 +const companyList = ref([])
170 137  
171 138  
172 139 /**
173 140 * 拨打电话回调
174 141 */
175 142 const handleContactClick = (val) => {
176   - console.log("拨打电话");
  143 + console.log("拨打电话", val);
177 144 uni.makePhoneCall({ phoneNumber: val }).then(res => {
178 145 console.log(res);
179 146 }).catch(err => { });
... ... @@ -191,19 +158,20 @@ function handleAddressInfo() {
191 158 /**
192 159 * 公司详情
193 160 */
194   -function handleDetailClick(companyId, tel) {
  161 +function handleDetailClick(company, tel, userAddress) {
  162 + console.log(company);
195 163 uni.$u.route({
196   - url: `pages/home/clean/company-detail/index?companyId=${companyId}&tel=${tel}`,
  164 + url: `pages/home/clean/company-detail/index?companyObj=${JSON.stringify(company)}&tel=${tel}&userAddress=${userAddress}`,
197 165 })
198 166 }
199 167  
200 168 /**
201 169 * 清运跳转
202 170 */
203   -const handleCleanGarbage = (companyId, tel) => {
  171 +const handleCleanGarbage = (companyObj, tel, userAddress) => {
204 172 console.log("垃圾清运");
205 173 uni.$u.route({
206   - url: `pages/home/clean/index?companyId=${companyId}&tel=${tel}`,
  174 + url: `pages/home/clean/index?companyObj=${JSON.stringify(companyObj)}&tel=${tel}&userAddress=${userAddress}`,
207 175 })
208 176 }
209 177  
... ... @@ -223,7 +191,6 @@ onLoad(() =&gt; {
223 191 maxStar.value.push(index);
224 192 }
225 193  
226   - // 获取胶囊按钮信息(width、height、top等)
227 194 try {
228 195 const { height, top } = uni.getMenuButtonBoundingClientRect();
229 196 topMargin.value = top + "px";
... ... @@ -242,22 +209,23 @@ const initData = () =&gt; {
242 209 userAddress.value = null;
243 210 // 查询用户当前地址
244 211 queryAddress('CURRENT').then(res => {
245   - userAddress.value = res.data.data[0].garUserAddress + res.data.data[0].garRemark
  212 + if (res.data.data instanceof Array) {
  213 + addressInfo.value = res.data.data[0].garUserAddress + res.data.data[0].garRemark
  214 + userAddress.value = JSON.stringify(res.data.data[0] ? res.data.data[0] : {});
  215 + }
246 216 })
  217 +
  218 +}
  219 +const queryList = (pageNo, pageSize) => {
247 220 // 查询公司信息
248   - queryDisposalSiteList().then(res => {
249   - console.log("company====>", res);
  221 + queryEnterpriseList({ companyType: 0, pageNum: pageNo, pageSize }).then(res => {
  222 + paging.value.complete(res.data.rows);
250 223 })
251 224 }
252 225 </script>
253 226  
254 227 <style lang="scss" scoped>
255 228 .home-container {
256   - // position: fixed;
257   - // top: 0;
258   - // bottom: 0;
259   - // left: 0;
260   - // right: 0;
261 229 background: linear-gradient(to bottom, $u-info-light, $u-info-light);
262 230 box-sizing: border-box;
263 231 display: flex;
... ... @@ -475,9 +443,7 @@ const initData = () =&gt; {
475 443 justify-content: space-around;
476 444 align-items: center;
477 445  
478   - .company-list-item-main-right-price {
479   - color: red;
480   - }
  446 + .company-list-item-main-right-price {}
481 447  
482 448 .company-list-item-main-right-number {
483 449 font-size: small;
... ...
garbage-removal/src/pages/login/code.vue
... ... @@ -17,7 +17,6 @@
17 17 <script setup>
18 18 import { sendCode, userLogin } from "@/apis/user.js";
19 19 import { useMainStore } from '@/stores/index.js';
20   -import { setRequestToken } from '@/utils/request/request.js';
21 20 import { onLoad } from "@dcloudio/uni-app";
22 21 import { ref } from "vue";
23 22 const store = useMainStore();
... ... @@ -80,11 +79,9 @@ const checkVerifyNum = (code) =&gt; {
80 79 // 登录成功
81 80 if (res.data.success) {
82 81 verifyFlag.value = false;
83   - setRequestToken(res.data.data)
84   - store.token = res.data.data
  82 + store.tempToken = res.data.data
85 83 uni.$u.route({
86   - type: "switchTab",
87   - url: `pages/home/index`,
  84 + url: `pages/wode/choose/index`,
88 85 })
89 86 } else {
90 87 verifyFlag.value = true;
... ...
garbage-removal/src/pages/order/detail/index.vue 0 → 100644
  1 +<template>
  2 + <view class="order-detail-container" v-if="dataGram != null || dataGram != undefined">
  3 + <view class="order-detail-container-box">
  4 + <view class="order-detail-top">
  5 + <view class="order-detail-top-box">
  6 + <view class="order-detail-top-box-step">
  7 + <u-steps :current="currentStep(dataGram.garOrderHandlerStatus)" dot>
  8 + <u-steps-item title="待清运"></u-steps-item>
  9 + <u-steps-item title="清运中"></u-steps-item>
  10 + <u-steps-item title="已完成"></u-steps-item>
  11 + </u-steps>
  12 + </view>
  13 + </view>
  14 + </view>
  15 + <!-- 信息提示 -->
  16 + <view class="order-detail-container-box-card">
  17 + <text style="color: red;">请于交易完成后线下支付!!</text>
  18 + </view>
  19 + <!-- 派单信息 -->
  20 + <view class="order-detail-container-box-card">
  21 + <view class="order-detail-container-header-card-title">
  22 + 派单信息
  23 + </view>
  24 + <view class="order-detail-container-header-item">
  25 + <text class="order-detail-container-header-title">派单地点:</text>
  26 + <view class="order-detail-container-header-content">
  27 + {{ dataGram.garOrderAddress + dataGram.garOrderAddressDetails }}
  28 + </view>
  29 + </view>
  30 +
  31 + <view class="order-detail-container-header-item">
  32 + <text class="order-detail-container-header-title">现场图片:</text>
  33 + <view class="order-detail-container-header-content">
  34 + <u-upload :fileList="currentImages" name="3" multiple :maxCount="10" :previewFullImage="true"
  35 + :isReadOnly="true"></u-upload>
  36 + </view>
  37 + </view>
  38 + <view class="order-detail-container-header-item">
  39 + <text class="order-detail-container-header-title">负责单位:</text>
  40 + <view class="order-detail-container-header-content">
  41 + {{ dataGram.garOrderCompanyName }}
  42 + </view>
  43 + </view>
  44 + <view class="order-detail-container-header-item">
  45 + <text class="order-detail-container-header-title">垃圾类型:</text>
  46 + <view class="order-detail-container-header-content">
  47 + {{ dataGram.garOrderTrashType }}
  48 + </view>
  49 + </view>
  50 + <view class="order-detail-container-header-item">
  51 + <text class="order-detail-container-header-title">订单号:</text>
  52 + <view class="order-detail-container-header-content">
  53 + {{ orderId }}
  54 + </view>
  55 + </view>
  56 + </view>
  57 + <!-- 派单记录 -->
  58 + <view class="order-detail-container-box-card">
  59 + <view class="order-detail-container-header-card-title">
  60 + 派单人员
  61 + </view>
  62 + <!-- <view class="order-detail-container-header-item">
  63 + <text class="order-detail-container-header-title">派单时间:</text>
  64 + <view class="order-detail-container-header-content">
  65 + {{ dataGram.garCreateTime }}
  66 + </view>
  67 + </view> -->
  68 + <view class="order-detail-container-header-item">
  69 + <text class="order-detail-container-header-title">约定时间:</text>
  70 + <view class="order-detail-container-header-content">
  71 + {{ dataGram.garOrderAgreementTime }}
  72 + </view>
  73 + </view>
  74 + <view class="order-detail-container-header-item">
  75 + <text class="order-detail-container-header-title">联系电话:</text>
  76 + <view class="order-detail-container-header-content">
  77 + {{ dataGram.garOrderContactTel }}
  78 + <u-icon name="phone" size="28" @click="handleContactClick(dataGram.garOrderCompanyTel)"></u-icon>
  79 + </view>
  80 + </view>
  81 + <view class="order-detail-container-header-item">
  82 + <text class="order-detail-container-header-title">派单人:</text>
  83 + <view class="order-detail-container-header-content">
  84 + {{ dataGram.garOrderContactName }}
  85 + </view>
  86 + </view>
  87 + <view class="order-detail-container-header-item">
  88 + <text class="order-detail-container-header-title">备注:</text>
  89 + <view class="order-detail-container-header-content">
  90 + {{ dataGram.garRemark }}
  91 + </view>
  92 + </view>
  93 + </view>
  94 + <!-- 处理信息 -->
  95 + <view class="order-detail-container-box-card">
  96 + <view class="order-detail-container-header-card-title">
  97 + 处理信息
  98 + </view>
  99 + <view class="order-detail-container-header-item">
  100 + <text class="order-detail-container-header-title">负责人:</text>
  101 + <view class="order-detail-container-header-content">
  102 + {{ dataGram.garOrderHandlerId }}
  103 + </view>
  104 + </view>
  105 + <view class="order-detail-container-header-item">
  106 + <text class="order-detail-container-header-title">装车照片:</text>
  107 + <view class="order-detail-container-header-content">
  108 + <u-upload :fileList="putOnImages" name="3" multiple :maxCount="20" :previewFullImage="true"
  109 + :isReadOnly="true"></u-upload>
  110 + </view>
  111 + </view>
  112 + <view class="order-detail-container-header-item">
  113 + <text class="order-detail-container-header-title">卸车照片:</text>
  114 + <view class="order-detail-container-header-content">
  115 + <u-upload :fileList="putDownImages" name="3" multiple :maxCount="20" :previewFullImage="true"
  116 + :isReadOnly="true"></u-upload>
  117 + </view>
  118 + </view>
  119 + <!-- <view class="order-detail-container-header-item">
  120 + <text class="order-detail-container-header-title">备注:</text>
  121 + <view class="order-detail-container-header-content">
  122 + {{ dataGram.garRemark }}
  123 + </view>
  124 + </view> -->
  125 + </view>
  126 + </view>
  127 + <view class="space-box"></view>
  128 + <view class="order-detail-bottom">
  129 + <view class="order-detail-bottom-box">
  130 + <view class="order-detail-bottom-left">
  131 + <!-- <u-button @click="handleOderSure" shape="circle" color="#a9e08f" text="取消订单"></u-button> -->
  132 + <u-button v-if="dataGram.garOrderHandlerStatus == 1" @click="handleSubmitSuccess(orderId)" shape="circle"
  133 + color="#a9e08f" text="完成派单"></u-button>
  134 + </view>
  135 + <view class="order-detail-bottom-right">
  136 + <u-button @click="handleOrder(orderId)" v-if="dataGram.garOrderHandlerStatus == 0 && dataGram.handleFlag"
  137 + shape="circle" color="#a9e08f" text="处理派单"></u-button>
  138 + <u-button @click="handleUploadImage(orderId)" v-if="dataGram.garOrderHandlerStatus == 1" shape="circle"
  139 + color="#a9e08f" text="上传照片"></u-button>
  140 + <u-button @click="handleEvaluate(orderId)" v-if="dataGram.garEvaluateFlag == 0" shape="circle" color="#a9e08f"
  141 + text="去评价"></u-button>
  142 + </view>
  143 + </view>
  144 + </view>
  145 + </view>
  146 +</template>
  147 +
  148 +<script setup>
  149 +import { queryOrderDetail, updateOrder } from "@/apis/order.js";
  150 +import { onLoad, onShow } from '@dcloudio/uni-app';
  151 +import { ref } from 'vue';
  152 +const dataGram = ref();
  153 +const orderId = ref(null)
  154 +const currentImages = ref([])
  155 +const putOnImages = ref([])
  156 +const putDownImages = ref([])
  157 +/**
  158 + * 初始化信息
  159 + */
  160 +onLoad((options) => {
  161 + orderId.value = options.orderId
  162 +})
  163 +const handleOrderDetail = (orderId) => {
  164 + queryOrderDetail(orderId).then(res => {
  165 + dataGram.value = res.data.data;
  166 + currentImages.value = res.data.data.currentImages.map(item => {
  167 + return { url: import.meta.env.VITE_BASE_URL + item };
  168 + });
  169 + putOnImages.value = res.data.data.putOnImages.map(item => {
  170 + return { url: import.meta.env.VITE_BASE_URL + item };
  171 + });
  172 + putDownImages.value = res.data.data.putDownImages.map(item => {
  173 + return { url: import.meta.env.VITE_BASE_URL + item };
  174 + });
  175 + })
  176 +}
  177 +/**
  178 + * 拨打电话回调
  179 + */
  180 +const handleContactClick = (val) => {
  181 + uni.makePhoneCall({ phoneNumber: val }).then(res => {
  182 + }).catch(err => { });
  183 +}
  184 +
  185 +// 提交完成
  186 +const handleSubmitSuccess = (orderId) => {
  187 + uni.showModal({
  188 + title: '提示',
  189 + content: '派单已经清运完成了吗?',
  190 + success: function (res) {
  191 + if (res.confirm) {
  192 + updateOrder({ garOrderId: orderId, handleType: 3 }).then(res => {
  193 + if (res.data.success) {
  194 + uni.$u.toast("已完成")
  195 + handleOrderDetail(orderId)
  196 + }
  197 + })
  198 + } else if (res.cancel) {
  199 + console.log('用户点击取消');
  200 + }
  201 + }
  202 + });
  203 +}
  204 +const handleEvaluate = (orderId) => [
  205 + uni.$u.route(`pages/order/evaluate/index?orderId=${orderId}`)
  206 +]
  207 +
  208 +// 接收订单
  209 +const handleOrder = (orderId) => {
  210 + updateOrder({ garOrderId: orderId, handleType: 0 }).then(res => {
  211 + if (res.data.success) {
  212 + uni.$u.toast("派单状态已被改变")
  213 + handleOrderDetail(orderId)
  214 + }
  215 + })
  216 +}
  217 +
  218 +
  219 +const currentStep = (step) => {
  220 + console.log(step);
  221 + if (step > 2) {
  222 + return step - 1;
  223 + }
  224 + return step;
  225 +}
  226 +
  227 +const handleUploadImage = (orderId) => {
  228 + uni.$u.route(`pages/order/upload/index?orderId=${orderId}`)
  229 +}
  230 +
  231 +onShow(() => {
  232 + if (orderId.value != null) {
  233 + handleOrderDetail(orderId.value)
  234 + }
  235 +})
  236 +
  237 +</script>
  238 +
  239 +<style lang="scss" scoped>
  240 +$custom-marin-bottom: 20rpx;
  241 +$custom-page-padding: 20rpx;
  242 +$custom-border-radio: 20rpx;
  243 +$custom-bottom-height: 200rpx;
  244 +
  245 +@mixin card {
  246 +
  247 + padding: $custom-page-padding;
  248 + box-sizing: border-box;
  249 + background-color: #ffffff;
  250 + border-radius: $custom-border-radio;
  251 + margin-bottom: $custom-marin-bottom;
  252 +}
  253 +
  254 +.order-detail-container {
  255 + height: 100%;
  256 + width: 100%;
  257 + background-color: $u-info-light;
  258 + box-sizing: border-box;
  259 + overflow-y: scroll;
  260 +
  261 +
  262 + .order-detail-container-box {
  263 + height: 100%;
  264 + width: 100%;
  265 + padding: $custom-page-padding;
  266 + box-sizing: border-box;
  267 + background: linear-gradient(to bottom, $u-success-dark, $u-info-light, $u-info-light, $u-info-light);
  268 +
  269 + .order-detail-top {
  270 + @include card();
  271 +
  272 + .order-detail-top-box {
  273 + .order-detail-top-box-step {
  274 + u-steps {
  275 + u-steps-item {}
  276 + }
  277 + }
  278 + }
  279 + }
  280 +
  281 + .order-detail-container-box-card {
  282 + @include card();
  283 +
  284 + .order-detail-container-header-card-title {
  285 + font-weight: bold;
  286 + line-height: 80rpx;
  287 + border-bottom: 3rpx solid $u-info-light;
  288 + margin-bottom: $custom-marin-bottom;
  289 + color: $u-primary;
  290 + }
  291 +
  292 + .order-detail-container-header-item {
  293 + display: flex;
  294 + margin-bottom: $custom-marin-bottom;
  295 +
  296 + // font-size: 30rpx;
  297 + // font-weight: bold;
  298 + // color: $u-main-color;
  299 + .order-detail-container-header-title {
  300 + color: $u-main-color;
  301 + white-space: nowrap; //溢出不换行
  302 + color: $u-info;
  303 + }
  304 +
  305 + .order-detail-container-header-content {
  306 + display: flex;
  307 + }
  308 + }
  309 + }
  310 + }
  311 +
  312 +
  313 + .space-box {
  314 + padding-bottom: $custom-bottom-height;
  315 + }
  316 +
  317 +
  318 + .order-detail-bottom {
  319 + position: absolute;
  320 + width: 100%;
  321 + // height: 100%;
  322 + bottom: 0;
  323 + left: 0;
  324 +
  325 + .movableAreaDetail {
  326 + pointer-events: none;
  327 + position: fixed;
  328 + left: 0;
  329 + top: 0;
  330 + width: 100%;
  331 + height: calc(100% - $custom-bottom-height);
  332 + z-index: 999;
  333 +
  334 + .movableView {
  335 + pointer-events: auto;
  336 + min-height: 60rpx;
  337 + min-width: 60rpx;
  338 +
  339 + .order-detail-call-box-container {
  340 + min-height: 60rpx;
  341 + min-width: 60rpx;
  342 + display: flex;
  343 + align-items: center;
  344 + justify-content: center;
  345 + background-color: #a9e08f;
  346 + border-radius: 100%;
  347 + }
  348 + }
  349 + }
  350 +
  351 + .order-detail-bottom-box {
  352 + height: $custom-bottom-height;
  353 + padding: 50rpx;
  354 + box-sizing: border-box;
  355 + display: flex;
  356 + justify-content: space-between;
  357 + align-items: center;
  358 +
  359 + .order-detail-bottom-left {
  360 + min-width: 200rpx;
  361 + }
  362 +
  363 + .order-detail-bottom-right {
  364 + min-width: 200rpx;
  365 + }
  366 + }
  367 +
  368 + }
  369 +
  370 +
  371 +}
  372 +</style>
... ...
garbage-removal/src/pages/order/evaluate/index.vue 0 → 100644
  1 +<template>
  2 + <view class='issue'>
  3 + <view class="issue-head">
  4 + <text class="issue-head-title">派单评价</text>
  5 + <view class="issue-head-star-box">
  6 + <u-icon v-for="(todo, index) in maxStar" :name="score > todo ? 'star-fill' : 'star'" :key="todo" color="#f9ae3d"
  7 + size="28" @click="setScore(index + 1)"></u-icon>
  8 + </view>
  9 + </view>
  10 + <textarea v-if="textareaShow" @blur="blur" :value="textareaValue" :placeholder="textareaPlaceholder" />
  11 + <view class="issue-btn-box">
  12 + <button class="submit-btn" type="primary" @click="doSubmit(orderId, score, content)">提交评价</button>
  13 + </view>
  14 + </view>
  15 +</template>
  16 +<script setup>
  17 +import { uploadEvaluate } from "@/apis/order.js";
  18 +import { onLoad } from '@dcloudio/uni-app';
  19 +// import
  20 +import { ref } from 'vue';
  21 +let maxScore = ref(5);
  22 +const orderId = ref()
  23 +const maxStar = ref([])
  24 +const score = ref(5)
  25 +const textareaShow = ref(true)
  26 +const textareaPlaceholder = ref("请输入对此次服务得评价")
  27 +const content = ref("")
  28 +const doSubmit = (orderId, score, content) => {
  29 + uploadEvaluate({ orderId, score, content }).then(res => {
  30 + if (res.data.success) {
  31 + uni.$u.toast("评价成功")
  32 + setTimeout(() => {
  33 + uni.$u.route({
  34 + type: "switchTab",
  35 + url: "pages/order/index"
  36 + })
  37 + }, 200);
  38 + }
  39 + })
  40 +}
  41 +const setScore = (index) => {
  42 + score.value = index
  43 +}
  44 +const blur = (e) => {
  45 + content.value = e.detail.value
  46 +}
  47 +onLoad((options) => {
  48 + orderId.value = options.orderId
  49 + // 积分初始化
  50 + for (let index = 0; index < maxScore.value; index++) {
  51 + maxStar.value.push(index);
  52 + }
  53 +})
  54 +
  55 +</script>
  56 +<style lang='scss' scoped>
  57 +$backgroundC: #f9f9f9;
  58 +$borderColor: #f5f5f5;
  59 +$white: #ffffff;
  60 +$fontSize: 28rpx;
  61 +
  62 +.issue {
  63 + background-color: $backgroundC;
  64 + height: 100%;
  65 + width: 100%;
  66 + box-sizing: border-box;
  67 + padding: 20rpx;
  68 +
  69 + &-head {
  70 + background-color: $white;
  71 + height: 100rpx;
  72 + border-top: 1rpx solid $borderColor;
  73 + border-bottom: 1rpx solid $borderColor;
  74 + padding: 0 25rpx;
  75 + display: flex;
  76 +
  77 + &-pic {
  78 + width: 70rpx;
  79 + height: 70rpx;
  80 + border-radius: 50%;
  81 + vertical-align: middle;
  82 + margin-right: 17rpx;
  83 + }
  84 +
  85 + &-title {
  86 + line-height: 100rpx;
  87 + font-size: 30rpx;
  88 + vertical-align: middle;
  89 + margin-right: 35rpx;
  90 + color: $u-primary;
  91 + }
  92 +
  93 + &-star-box {
  94 + display: flex;
  95 +
  96 + image {
  97 + width: 32rpx;
  98 + height: 32rpx;
  99 + vertical-align: middle;
  100 + margin-right: 14rpx;
  101 + }
  102 +
  103 + image.active {
  104 + animation: star_move ease-in 1 1s, star_rotate ease 1.5s infinite 1s;
  105 + }
  106 + }
  107 + }
  108 +
  109 + textarea {
  110 + width: 100%;
  111 + height: 420rpx;
  112 + background-color: $white;
  113 + font-size: $fontSize;
  114 + color: #898989;
  115 + padding: 24rpx;
  116 + box-sizing: border-box;
  117 + line-height: 40rpx;
  118 + border: 2rpx solid $u-info-light;
  119 + }
  120 +
  121 + &-btn-box {
  122 + padding: 54rpx 30rpx;
  123 +
  124 + button {
  125 + width: 100%;
  126 + height: 80rpx;
  127 + border-radius: 80rpx;
  128 + font-size: $fontSize;
  129 + background-color: #3682FF;
  130 + line-height: 80rpx
  131 + }
  132 + }
  133 +}
  134 +
  135 +@keyframes star_move {
  136 + from {
  137 + width: 50rpx;
  138 + height: 50rpx;
  139 + transform: rotate(180deg)
  140 + }
  141 +
  142 + to {
  143 + width: 32rpx;
  144 + height: 32rpx;
  145 + transform: rotate(0)
  146 + }
  147 +}
  148 +
  149 +@keyframes star_rotate {
  150 + 0% {
  151 + transform: rotateY(360deg)
  152 + }
  153 +
  154 + 100% {
  155 + transform: rotateY(180deg)
  156 + }
  157 +}
  158 +</style>
... ...
garbage-removal/src/pages/order/index.vue
... ... @@ -15,7 +15,7 @@
15 15 <script setup>
16 16 import { ref } from 'vue';
17 17 import swiperListItem from './swiper-list-item/index.vue';
18   -const list = ref([{ name: '待清运' }, { name: '清运中' }, { name: '全部' }, { name: '待支付' }, { name: '已完成' }])
  18 +const list = ref([{ name: '待清运' }, { name: '清运中' }, { name: '全部' }, { name: '已完成' }])
19 19 const current = ref(0);
20 20 const swiperCurrent = ref(0)
21 21 const uTabsElement = ref()
... ... @@ -37,6 +37,6 @@ const translation = (e) =&gt; {
37 37  
38 38 .swiper {
39 39 height: 100%;
40   - background: linear-gradient(to bottom, $u-success-dark, #ffffff, #ffffff, #ffffff, #ffffff, #ffffff, #ffffff);
  40 + background: linear-gradient(to bottom, $u-success-dark, $u-bg-color, $u-bg-color, $u-bg-color, $u-bg-color, $u-bg-color, $u-bg-color);
41 41 }
42 42 </style>
... ...
garbage-removal/src/pages/order/swiper-list-item/index.vue
1 1 <template>
2 2 <view class="content-container">
3   - <z-paging ref="paging" :fixed="false" v-model="dataList" @query="queryList">
  3 + <z-paging ref="paging" :fixed="false" v-model="dataList" :auto="false" @query="queryList">
4 4 <empty-view slot:empty></empty-view>
5   - <view class="content-container-item-box" v-for="(item, index) in dataList">
6   - <view class="content-container-item-box-title">{{ item }}</view>
  5 + <view class="page-box">
  6 + <view class="order" v-for="(item, index) in dataList" :key="index">
  7 + <view class="top">
  8 + <view class="left">
  9 + <u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
  10 + <view class="store">{{ item.garOrderCompanyName }}</view>
  11 + <u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon>
  12 + </view>
  13 + <view v-if="item.garOrderHandlerStatus === 0" class="right">待清运 </view>
  14 + <view v-if="item.garOrderHandlerStatus === 1" class="right">清运中 </view>
  15 + <view v-if="item.garEvaluateFlag === 0" class="right">待评价 </view>
  16 + <view v-if="item.garEvaluateFlag === 1" class="right">已评价 </view>
  17 + </view>
  18 + <view class="item" @click="handleClick(item.garOrderId)">
  19 + <view class="left">
  20 + <image :src="item.goodsUrl" mode="aspectFill"></image>
  21 + </view>
  22 + <view class="content">
  23 + <view class="title u-line-2">{{ item.garOrderAddress + item.garOrderAddressDetails }}</view>
  24 + <view class="type">垃圾类型: {{ item.garOrderTrashType }}</view>
  25 + <view class="delivery-time">预约时间 {{ item.garOrderAgreementTime }}</view>
  26 + </view>
  27 + </view>
  28 + <!-- <view class="bottom">
  29 + <view class="more">
  30 + <u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon>
  31 + </view>
  32 + <view class="logistics btn" v-if="item.garOrderHandlerStatus === 0" @click="">取消订单</view>
  33 + <view class="evaluate btn" v-if="item.garOrderHandlerStatus === 4">评价</view>
  34 + </view> -->
  35 + </view>
7 36 </view>
8 37 </z-paging>
9 38 </view>
10 39 </template>
11 40  
12 41 <script setup>
13   -import { onMounted, ref } from 'vue';
14   -
  42 +import { queryOrderList } from "@/apis/order.js";
  43 +import { ref, watch } from 'vue';
15 44 const props = defineProps({
16 45 tabIndex: {
17 46 type: Number
... ... @@ -20,43 +49,177 @@ const props = defineProps({
20 49 type: Number
21 50 }
22 51 })
23   -const paging = ref(null)
24   -const dataList = ref([])
25   -const count = ref(0)
26   -const timer = ref()
  52 +const dataList = ref([]);
  53 +const paging = ref(null);
  54 +const firstLoaded = ref(false)
  55 +
  56 +const handleClick = (orderId) => {
  57 + uni.$u.route({
  58 + url: `pages/order/detail/index`,
  59 + params: {
  60 + orderId: orderId
  61 + }
  62 + })
  63 +}
  64 +// list集合
27 65 const queryList = (pageNo, pageSize) => {
28 66 //这里的pageNo和pageSize会自动计算好,直接传给服务器即可
29 67 //这里的请求只是演示,请替换成自己的项目的网络请求,并在网络请求回调中通过paging.value.complete(请求回来的数组)将请求结果传给z-paging
30 68 // request.queryList({ pageNo, pageSize }).then(res => {
31 69 // //请勿在网络请求回调中给dataList赋值!!只需要调用complete就可以了
  70 + queryOrderList({ type: props.tabIndex, pageNo, pageSize }).then((res) => {
  71 + paging.value.complete(res.data.data.list);
  72 + firstLoaded.value = true
  73 + console.log(res.data.data.list);
  74 + }).catch(res => {
  75 + //如果请求失败写paging.value.complete(false),会自动展示错误页面
  76 + //注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
  77 + //在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
  78 + paging.value.complete(false);
  79 + })
32 80 if (props.tabIndex == 3) {
33 81 paging.value.complete([])
34 82 return
35 83 }
36   - if (++count.value < 3) {
37   - clearTimeout(timer.value)
38   - timer.value = setTimeout(() => {
39   - console.log("hhhh");
40   - paging.value.complete([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
41   - }, 500);
42   - }
43   -
44   - // }).catch(res => {
45   - // //如果请求失败写paging.value.complete(false),会自动展示错误页面
46   - // //注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
47   - // //在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
48   - // paging.value.complete(false);
49   - // })
50 84 }
  85 +watch(() => props.currentIndex, (val1, val2) => {
  86 + if (props.currentIndex == props.tabIndex) {
  87 + if (!firstLoaded.value) {
  88 + setTimeout(() => {
  89 + paging.value.reload();
  90 + }, 50);
  91 + }
51 92  
52   -onMounted(() => {
53   - console.log("tabIndex:", props.tabIndex);
54   - console.log("currentIndex:", props.currentIndex);
55   -})
  93 + }
  94 +}, { immediate: true })
56 95 </script>
57 96  
58 97 <style lang="scss" scoped>
59 98 .content-container {
60 99 height: 100%;
  100 +
  101 + .order {
  102 + width: 710rpx;
  103 + background-color: #ffffff;
  104 + margin: 20rpx auto;
  105 + border-radius: 20rpx;
  106 + box-sizing: border-box;
  107 + padding: 20rpx;
  108 + font-size: 28rpx;
  109 +
  110 + .top {
  111 + display: flex;
  112 + justify-content: space-between;
  113 +
  114 + .left {
  115 + display: flex;
  116 + align-items: center;
  117 +
  118 + .store {
  119 + margin: 0 10rpx;
  120 + font-size: 32rpx;
  121 + font-weight: bold;
  122 + }
  123 + }
  124 + }
  125 +
  126 + .item {
  127 + display: flex;
  128 + margin: 20rpx 0 0;
  129 +
  130 + .left {
  131 + margin-right: 20rpx;
  132 +
  133 + image {
  134 + width: 200rpx;
  135 + height: 200rpx;
  136 + border-radius: 10rpx;
  137 + }
  138 + }
  139 +
  140 + .content {
  141 +
  142 + .title {
  143 + font-size: 28rpx;
  144 + line-height: 50rpx;
  145 + }
  146 +
  147 + .type {
  148 + margin: 10rpx 0;
  149 + font-size: 24rpx;
  150 + color: $u-tips-color;
  151 + }
  152 +
  153 + .delivery-time {
  154 + color: #e5d001;
  155 + font-size: 24rpx;
  156 + }
  157 + }
  158 +
  159 +
  160 + }
  161 +
  162 + .total {
  163 + margin-top: 20rpx;
  164 + text-align: right;
  165 + font-size: 24rpx;
  166 +
  167 + .total-price {
  168 + font-size: 32rpx;
  169 + }
  170 + }
  171 +
  172 + .bottom {
  173 + display: flex;
  174 + margin-top: 40rpx;
  175 + padding: 0 10rpx;
  176 + justify-content: space-between;
  177 + align-items: center;
  178 +
  179 + .btn {
  180 + line-height: 52rpx;
  181 + width: 160rpx;
  182 + border-radius: 26rpx;
  183 + border: 2rpx solid $u-border-color;
  184 + font-size: 26rpx;
  185 + text-align: center;
  186 + color: $u-info-dark;
  187 + }
  188 +
  189 + .evaluate {
  190 + color: $u-warning-dark;
  191 + border-color: $u-warning-dark;
  192 + }
  193 + }
  194 + }
  195 +
  196 + .centre {
  197 + text-align: center;
  198 + margin: 200rpx auto;
  199 + font-size: 32rpx;
  200 +
  201 + image {
  202 + width: 164rpx;
  203 + height: 164rpx;
  204 + border-radius: 50%;
  205 + margin-bottom: 20rpx;
  206 + }
  207 +
  208 + .tips {
  209 + font-size: 24rpx;
  210 + color: #999999;
  211 + margin-top: 20rpx;
  212 + }
  213 +
  214 + .btn {
  215 + margin: 80rpx auto;
  216 + width: 200rpx;
  217 + border-radius: 32rpx;
  218 + line-height: 64rpx;
  219 + color: #ffffff;
  220 + font-size: 26rpx;
  221 + background: linear-gradient(270deg, rgba(249, 116, 90, 1) 0%, rgba(255, 158, 1, 1) 100%);
  222 + }
  223 + }
61 224 }
62 225 </style>
... ...
garbage-removal/src/pages/order/upload/index.vue 0 → 100644
  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="singleItem" @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">{{ singleItem }}(最多上传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, singleItem)">
  22 + <view class="upload-image-box-submit-box-button-container">
  23 + <up-button color="#19be6b" type="primary" shape="circle" text="确定"></up-button>
  24 + </view>
  25 + </view>
  26 + </view>
  27 + </view>
  28 +</template>
  29 +
  30 +<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 +
  36 +const orderId = ref();
  37 +const fileList = ref([])
  38 +const singleItem = ref("装车图片")
  39 +const chooseList = reactive([{ name: "装车图片" }, { name: "卸车图片" }])
  40 +// 删除图片
  41 +const deletePic = (event) => {
  42 + fileList.value.splice(event.index, 1);
  43 +};
  44 +
  45 +const groupChange = (e) => {
  46 + console.log(e);
  47 +}
  48 +const radioChange = (e) => {
  49 + console.log(e);
  50 +}
  51 +
  52 +// 新增图片
  53 +const afterRead = async (event) => {
  54 + // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
  55 + let lists = [].concat(event.file);
  56 + let fileListLen = fileList.value.length;
  57 + lists.map((item) => {
  58 + fileList.value.push({
  59 + ...item,
  60 + status: 'uploading',
  61 + message: '上传中',
  62 + });
  63 + });
  64 + for (let i = 0; i < lists.length; i++) {
  65 + let requestPath = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_BASE_FILE_UPLOAD_PREFIX;
  66 + const result = await uploadFilePromise(requestPath, lists[i].url);
  67 + let item = fileList.value[fileListLen];
  68 + fileList.value.splice(fileListLen, 1, {
  69 + ...item,
  70 + status: 'success',
  71 + message: '',
  72 + url: result.data.fileName,
  73 + });
  74 + fileListLen++;
  75 + }
  76 +};
  77 +// 提交图片
  78 +const handleSubmit = (id, type) => {
  79 + if (!validateImage()) {
  80 + uni.$u.toast("请等待图片上传~")
  81 + return
  82 + }
  83 + let params = {
  84 + garOrderId: id,
  85 + type: type == "装车图片" ? 1 : 2,
  86 + imageUrls: fileList.value.map(item => item.url)
  87 + }
  88 + uploadImageUrlByType(params).then(res => {
  89 + console.log(res);
  90 + if (res.data.success) {
  91 + uni.$u.toast("图片上传完毕!");
  92 + uni.$u.route({
  93 + type: "navigateBack",
  94 + url: "pages/order/detail/index"
  95 + })
  96 + }
  97 + })
  98 +}
  99 +
  100 +const validateImage = () => {
  101 + for (let index = 0; index < fileList.value.length; index++) {
  102 + const str = fileList.value[index].url;
  103 + if (str.startsWith("blob")) {
  104 + return false;
  105 + }
  106 + }
  107 + return true;
  108 +}
  109 +
  110 +onLoad((options) => {
  111 + orderId.value = options.orderId;
  112 +})
  113 +</script>
  114 +
  115 +<style lang="scss" scoped>
  116 +.upload-image-box {
  117 + height: 100%;
  118 + width: 100%;
  119 + background-color: #ffffff;
  120 + padding: 20rpx;
  121 + box-sizing: border-box;
  122 + line-height: 80rpx;
  123 +
  124 + .upload-image-box-choose {
  125 + display: flex;
  126 +
  127 + .upload-image-box-choose-txt {
  128 + white-space: nowrap;
  129 + }
  130 +
  131 + .upload-image-box-choose-type {
  132 + display: flex;
  133 + justify-content: center;
  134 + align-items: center;
  135 + }
  136 + }
  137 +
  138 + .upload-image-box-bottom {
  139 + .upload-image-box-bottom-txt {
  140 + color: $u-info;
  141 + }
  142 +
  143 + .upload-image-box-button-container {
  144 + min-height: 350rpx;
  145 + min-width: 100%;
  146 + padding: 20rpx;
  147 + // background-color: $u-info-light;
  148 + border: 2rpx solid $u-border-color;
  149 + box-sizing: border-box;
  150 + border-radius: 10rpx;
  151 + }
  152 + }
  153 +
  154 + .upload-image-box-submit-box {
  155 + box-sizing: border-box;
  156 + margin-top: 80rpx;
  157 + width: 100%;
  158 +
  159 + .upload-image-box-submit-box-button {
  160 + box-sizing: border-box;
  161 + display: flex;
  162 + justify-content: flex-end;
  163 + align-items: center;
  164 +
  165 + .upload-image-box-submit-box-button-container {
  166 + white-space: nowrap;
  167 + box-sizing: border-box;
  168 + width: 200rpx;
  169 + }
  170 + }
  171 + }
  172 +}
  173 +</style>
... ...
garbage-removal/src/pages/wode/choose/index.vue 0 → 100644
  1 +<template>
  2 + <view class="wrap">
  3 + <u-radio-group v-model="userType" placement="row" @change="groupChange">
  4 + <view class="choose-type" v-for="(item, index) in typeList">
  5 + <u-radio :customStyle="{ marginBottom: '8px' }" size="28" labelSize="28" :key="index" :label="item.name"
  6 + :name="item.name" @change="radioChange">
  7 + </u-radio>
  8 + </view>
  9 + </u-radio-group>
  10 + <view class="choose-button">
  11 + <u-button shape="circle" color="#a9e08f" @click="submit(userType)">确定</u-button>
  12 + </view>
  13 + </view>
  14 +</template>
  15 +
  16 +<script setup>
  17 +import { updateUserInfo } from "@/apis/user.js";
  18 +import { useMainStore } from '@/stores/index.js';
  19 +import { setRequestToken } from '@/utils/request/request.js';
  20 +import { ref } from 'vue';
  21 +const store = useMainStore();
  22 +const userType = ref("居民用户")
  23 +const typeList = ref([{ name: "居民用户" }, { name: "管理负责人" }])
  24 +const radioChange = (e) => {
  25 + console.log(e);
  26 +}
  27 +const groupChange = (e) => {
  28 + console.log(e);
  29 +}
  30 +const submit = (userType) => {
  31 + setRequestToken(store.tempToken)
  32 + updateUserInfo({ garUserType: userType }).then(res => {
  33 + store.token = store.tempToken
  34 + store.tempToken = "";
  35 + if (res.data.success) {
  36 + uni.$u.route({
  37 + type: "switchTab",
  38 + url: `pages/home/index`,
  39 + })
  40 + }
  41 + })
  42 +
  43 +}
  44 +</script>
  45 +
  46 +<style lang="scss" scoped>
  47 +.wrap {
  48 + height: 100%;
  49 + width: 100%;
  50 + box-sizing: border-box;
  51 + padding: 20rpx;
  52 + background-color: $u-info-light;
  53 +
  54 + .choose-type {
  55 + width: 100%;
  56 + box-sizing: border-box;
  57 + padding: 30rpx;
  58 + background-color: #ffffff;
  59 + border-radius: 20rpx;
  60 +
  61 + &:first-child {
  62 + margin-right: 20rpx;
  63 + }
  64 + }
  65 +
  66 + .choose-button {
  67 + position: relative;
  68 + width: 100%;
  69 + height: 100%;
  70 + display: flex;
  71 + justify-content: center;
  72 + align-items: center;
  73 + }
  74 +}
  75 +</style>
... ...
garbage-removal/src/pages/wode/index.vue
1 1 <template>
2 2 <view>
3   - myself
  3 + <view class="u-flex u-flex-y-center u-flex-around user-box u-p-l-30 u-p-r-20 u-p-b-30">
  4 + <view class="u-m-r-10">
  5 + <u-avatar :src="pic" size="140"></u-avatar>
  6 + </view>
  7 + <view class="u-flex-1">
  8 + <view class="u-font-18 u-p-b-20">普通用户</view>
  9 + <!-- <view class="u-font-14 u-tips-color"></view> -->
  10 + </view>
  11 + <!-- <view class="u-m-l-10 u-p-10">
  12 + <u-icon name="scan" color="#969799" size="28"></u-icon>
  13 + </view>
  14 + <view class="u-m-l-10 u-p-10">
  15 + <u-icon name="arrow-right" color="#969799" size="28"></u-icon>
  16 + </view> -->
  17 + </view>
  18 +
  19 + <view class="u-m-t-20">
  20 + <u-cell-group>
  21 + <u-cell icon="map" title="地址管理"></u-cell>
  22 + </u-cell-group>
  23 + </view>
  24 +
  25 + <view class="u-m-t-20">
  26 + <u-cell-group>
  27 + <u-cell icon="star" title="收藏"></u-cell>
  28 + <u-cell icon="photo" title="相册"></u-cell>
  29 + <u-cell icon="coupon" title="卡券"></u-cell>
  30 + <u-cell icon="heart" title="关注"></u-cell>
  31 + </u-cell-group>
  32 + </view>
  33 +
  34 + <view class="u-m-t-20">
  35 + <u-cell-group>
  36 + <u-cell icon="setting" title="设置"></u-cell>
  37 + </u-cell-group>
  38 + </view>
4 39 </view>
5 40 </template>
6 41  
7   -<script setup>
  42 +<script>
  43 +import headImg from "@/static/image/st_pic.png";
  44 +export default {
  45 + data() {
  46 + return {
  47 + pic: headImg,
  48 + show: true
  49 + }
  50 + },
  51 + onLoad() {
  52 +
  53 + },
  54 + methods: {
8 55  
  56 + }
  57 +}
9 58 </script>
10 59  
11   -<style lang="scss" scoped>
  60 +<style lang="scss">
  61 +page {
  62 + background-color: #ededed;
  63 +}
  64 +
  65 +.camera {
  66 + width: 54px;
  67 + height: 44px;
  68 +
  69 + &:active {
  70 + background-color: #ededed;
  71 + }
  72 +}
  73 +
  74 +.user-box {
  75 + background-color: #fff;
  76 +}
  77 +
  78 +.u-cell-group {
  79 + background-color: #fff;
  80 +}
12 81 </style>
... ...
garbage-removal/src/static/image/st_pic.png 0 → 100644

2.76 KB

garbage-removal/src/stores/main.js
... ... @@ -4,9 +4,9 @@ export const useMainStore = defineStore(
4 4 "main",
5 5 () => {
6 6 const token = ref(null);
7   - const userInfo = ref(null);
  7 + const tempToken = ref(null);
8 8  
9   - return { token, userInfo };
  9 + return { token,tempToken };
10 10 },
11 11 {
12 12 persist: {
... ...
garbage-removal/src/utils/request/request.js
... ... @@ -2,9 +2,6 @@ import axios from &quot;axios&quot;;
2 2 import settle from "axios/lib/core/settle";
3 3 import buildURL from "axios/lib/helpers/buildURL";
4 4 /* 格式化路径 */
5   -const URLFormat = function (baseURL, url) {
6   - return url.startsWith("http") ? url : baseURL
7   -}
8 5 axios.defaults.adapter = function (config) {
9 6 return new Promise((resolve, reject) => {
10 7 const timer = setTimeout(() => {
... ... @@ -54,17 +51,21 @@ const instance = axios.create({
54 51 });
55 52 // 请求拦截器
56 53 instance.interceptors.request.use((config) => {
  54 + if (config.method.toLocaleLowerCase() == "get") {
  55 + handleGet(config);
  56 + }
57 57 return config;
58 58 });
59 59 // 响应拦截器
60 60 instance.interceptors.response.use((response) => {
61 61 if (response.data.code != 200) {
62   - uni.showToast({
63   - title: response.data.message,
64   - icon: "none",
65   - });
66 62 if (response.data.code == 401) {
67 63 reSetLoginStatus();
  64 + } else {
  65 + uni.showToast({
  66 + title: response.data.message,
  67 + icon: "none",
  68 + });
68 69 }
69 70 }
70 71 return response;
... ... @@ -89,8 +90,30 @@ export function setRequestToken(token) {
89 90 }
90 91  
91 92 const reSetLoginStatus = () => {
  93 + setRequestToken(null);
  94 + uni.showToast({
  95 + title: "登录已过期,请重新登录!",
  96 + icon: "none",
  97 + });
92 98 uni.navigateTo({
93   - type: "reLaunch",
94   - url: "/pages/login/index",
95   - });
  99 + url: "/pages/login/index",
  100 + })
  101 + return
  102 +}
  103 +
  104 +const handleGet = (config) => {
  105 + let strUrl = "";
  106 + let params = config.params;
  107 + let firstElement = true;
  108 + for (const key in params) {
  109 + if (firstElement) {
  110 + firstElement = false;
  111 + strUrl = "?" + key + "=" + params[key];
  112 + } else {
  113 + strUrl += "&" + key + "=" + params[key];
  114 + }
  115 + }
  116 + config.url += strUrl;
  117 + config.params = "";
  118 + console.log("请求拦截",config);
96 119 }
... ...
garbage-removal/src/uview-plus/components/u-radio-group/u-radio-group.vue
... ... @@ -109,8 +109,9 @@ export default {
109 109 &--row {
110 110 /* #ifndef APP-NVUE */
111 111 display: flex;
112   - /* #endif */
113   - // flex-flow: row wrap;
  112 + flex-direction: row
  113 + /* #endif */
  114 + // flex-flow: row wrap;
114 115 }
115 116  
116 117 &--column {
... ...
garbage-removal/src/uview-plus/components/u-steps-item/u-steps-item.vue
... ... @@ -6,35 +6,34 @@
6 6 :class="[`u-steps-item__wrapper--${parentData.direction}`, parentData.dot && `u-steps-item__wrapper--${parentData.direction}--dot`]">
7 7 <slot name="icon">
8 8 <view class="u-steps-item__wrapper__dot" v-if="parentData.dot" :style="{
9   - backgroundColor: statusColor
10   - }">
  9 + backgroundColor: statusColor
  10 + }">
11 11  
12 12 </view>
13 13 <view class="u-steps-item__wrapper__icon" v-else-if="parentData.activeIcon || parentData.inactiveIcon">
14   - <u-icon :name="index <= parentData.current ? parentData.activeIcon : parentData.inactiveIcon"
15   - :size="iconSize"
  14 + <u-icon :name="index <= parentData.current ? parentData.activeIcon : parentData.inactiveIcon" :size="iconSize"
16 15 :color="index <= parentData.current ? parentData.activeColor : parentData.inactiveColor">
17 16 </u-icon>
18 17 </view>
19 18 <view v-else :style="{
20   - backgroundColor: statusClass === 'process' ? parentData.activeColor : 'transparent',
21   - borderColor: statusColor
22   - }" class="u-steps-item__wrapper__circle">
23   - <text v-if="statusClass === 'process' || statusClass === 'wait'"
24   - class="u-steps-item__wrapper__circle__text" :style="{
  19 + backgroundColor: statusClass === 'process' ? parentData.activeColor : 'transparent',
  20 + borderColor: statusColor
  21 + }" class="u-steps-item__wrapper__circle">
  22 + <text v-if="statusClass === 'process' || statusClass === 'wait'" class="u-steps-item__wrapper__circle__text"
  23 + :style="{
25 24 color: index == parentData.current ? '#ffffff' : parentData.inactiveColor
26   - }">{{ index + 1}}</text>
27   - <u-icon v-else :color="statusClass === 'error' ? 'error' : parentData.activeColor" size="12"
  25 + }">{{ index + 1 }}</text>
  26 + <u-icon v-else :color="statusClass === 'error' ? 'error' : parentData.activeColor" size="24"
28 27 :name="statusClass === 'error' ? 'close' : 'checkmark'"></u-icon>
29 28 </view>
30 29 </slot>
31 30 </view>
32 31 <view class="u-steps-item__content" :class="[`u-steps-item__content--${parentData.direction}`]"
33 32 :style="[contentStyle]">
34   - <u--text :text="title" :type="parentData.current == index ? 'main' : 'content'" lineHeight="20px"
35   - :size="parentData.current == index ? 14 : 13"></u--text>
  33 + <u--text align="center" :text="title" :type="parentData.current == index ? 'main' : 'content'" lineHeight="20px"
  34 + :size="parentData.current == index ? 28 : 26"></u--text>
36 35 <slot name="desc">
37   - <u--text :text="desc" type="tips" size="12"></u--text>
  36 + <u--text align="center" :text="desc" type="tips" size="24"></u--text>
38 37 </slot>
39 38 </view>
40 39 <!-- <view
... ... @@ -47,272 +46,272 @@
47 46 </template>
48 47  
49 48 <script>
50   - import props from './props.js';
51   - import mpMixin from '../../libs/mixin/mpMixin.js';
52   - import mixin from '../../libs/mixin/mixin.js';
53   - // #ifdef APP-NVUE
54   - const dom = uni.requireNativePlugin('dom')
55   - // #endif
56   - /**
57   - * StepsItem 步骤条的子组件
58   - * @description 本组件需要和u-steps配合使用
59   - * @tutorial https://uviewui.com/components/steps.html
60   - * @property {String} title 标题文字
61   - * @property {String} current 描述文本
62   - * @property {String | Number} iconSize 图标大小 (默认 17 )
63   - * @property {Boolean} error 当前步骤是否处于失败状态 (默认 false )
64   - * @example <u-steps current="0"><u-steps-item title="已出库" desc="10:35" ></u-steps-item></u-steps>
65   - */
66   - export default {
67   - name: 'u-steps-item',
68   - mixins: [mpMixin, mixin, props],
69   - data() {
70   - return {
71   - index: 0,
72   - childLength: 0,
73   - showLine: false,
74   - size: {
75   - height: 0,
76   - width: 0
77   - },
78   - parentData: {
79   - direction: 'row',
80   - current: 0,
81   - activeColor: '',
82   - inactiveColor: '',
83   - activeIcon: '',
84   - inactiveIcon: '',
85   - dot: false
86   - }
  49 +import mixin from '../../libs/mixin/mixin.js';
  50 +import mpMixin from '../../libs/mixin/mpMixin.js';
  51 +import props from './props.js';
  52 +// #ifdef APP-NVUE
  53 +const dom = uni.requireNativePlugin('dom')
  54 +// #endif
  55 +/**
  56 + * StepsItem 步骤条的子组件
  57 + * @description 本组件需要和u-steps配合使用
  58 + * @tutorial https://uviewui.com/components/steps.html
  59 + * @property {String} title 标题文字
  60 + * @property {String} current 描述文本
  61 + * @property {String | Number} iconSize 图标大小 (默认 17 )
  62 + * @property {Boolean} error 当前步骤是否处于失败状态 (默认 false )
  63 + * @example <u-steps current="0"><u-steps-item title="已出库" desc="10:35" ></u-steps-item></u-steps>
  64 + */
  65 +export default {
  66 + name: 'u-steps-item',
  67 + mixins: [mpMixin, mixin, props],
  68 + data() {
  69 + return {
  70 + index: 0,
  71 + childLength: 0,
  72 + showLine: false,
  73 + size: {
  74 + height: 0,
  75 + width: 0
  76 + },
  77 + parentData: {
  78 + direction: 'row',
  79 + current: 0,
  80 + activeColor: '',
  81 + inactiveColor: '',
  82 + activeIcon: '',
  83 + inactiveIcon: '',
  84 + dot: false
87 85 }
  86 + }
  87 + },
  88 + watch: {
  89 + 'parentData'(newValue, oldValue) {
  90 + }
  91 + },
  92 + created() {
  93 + this.init()
  94 + },
  95 + computed: {
  96 + lineStyle() {
  97 + const style = {}
  98 + if (this.parentData.direction === 'row') {
  99 + style.width = this.size.width + 'px'
  100 + style.left = this.size.width / 2 + 'px'
  101 + } else {
  102 + style.height = this.size.height + 'px'
  103 + // style.top = this.size.height / 2 + 'px'
  104 + }
  105 + style.backgroundColor = this.parent.children?.[this.index + 1]?.error ? uni.$u.color.error : this.index <
  106 + this
  107 + .parentData
  108 + .current ? this.parentData.activeColor : this.parentData.inactiveColor
  109 + return style
88 110 },
89   - watch: {
90   - 'parentData'(newValue, oldValue) {
  111 + statusClass() {
  112 + const {
  113 + index,
  114 + error
  115 + } = this
  116 + const {
  117 + current
  118 + } = this.parentData
  119 + if (current == index) {
  120 + return error === true ? 'error' : 'process'
  121 + } else if (error) {
  122 + return 'error'
  123 + } else if (current > index) {
  124 + return 'finish'
  125 + } else {
  126 + return 'wait'
91 127 }
92 128 },
93   - created() {
94   - this.init()
  129 + statusColor() {
  130 + let color = ''
  131 + switch (this.statusClass) {
  132 + case 'finish':
  133 + color = this.parentData.activeColor
  134 + break
  135 + case 'error':
  136 + color = uni.$u.color.error
  137 + break
  138 + case 'process':
  139 + color = this.parentData.dot ? this.parentData.activeColor : 'transparent'
  140 + break
  141 + default:
  142 + color = this.parentData.inactiveColor
  143 + break
  144 + }
  145 + return color
95 146 },
96   - computed: {
97   - lineStyle() {
98   - const style = {}
99   - if (this.parentData.direction === 'row') {
100   - style.width = this.size.width + 'px'
101   - style.left = this.size.width / 2 + 'px'
102   - } else {
103   - style.height = this.size.height + 'px'
104   - // style.top = this.size.height / 2 + 'px'
105   - }
106   - style.backgroundColor = this.parent.children?.[this.index + 1]?.error ? uni.$u.color.error : this.index <
107   - this
108   - .parentData
109   - .current ? this.parentData.activeColor : this.parentData.inactiveColor
110   - return style
111   - },
112   - statusClass() {
113   - const {
114   - index,
115   - error
116   - } = this
117   - const {
118   - current
119   - } = this.parentData
120   - if (current == index) {
121   - return error === true ? 'error' : 'process'
122   - } else if (error) {
123   - return 'error'
124   - } else if (current > index) {
125   - return 'finish'
126   - } else {
127   - return 'wait'
128   - }
129   - },
130   - statusColor() {
131   - let color = ''
132   - switch (this.statusClass) {
133   - case 'finish':
134   - color = this.parentData.activeColor
135   - break
136   - case 'error':
137   - color = uni.$u.color.error
138   - break
139   - case 'process':
140   - color = this.parentData.dot ? this.parentData.activeColor : 'transparent'
141   - break
142   - default:
143   - color = this.parentData.inactiveColor
144   - break
145   - }
146   - return color
147   - },
148   - contentStyle() {
149   - const style = {}
150   - if (this.parentData.direction === 'column') {
151   - style.marginLeft = this.parentData.dot ? '2px' : '6px'
152   - style.marginTop = this.parentData.dot ? '0px' : '6px'
153   - } else {
154   - style.marginTop = this.parentData.dot ? '2px' : '6px'
155   - style.marginLeft = this.parentData.dot ? '2px' : '6px'
156   - }
  147 + contentStyle() {
  148 + const style = {}
  149 + if (this.parentData.direction === 'column') {
  150 + style.marginLeft = this.parentData.dot ? '2px' : '6px'
  151 + style.marginTop = this.parentData.dot ? '0px' : '6px'
  152 + } else {
  153 + style.marginTop = this.parentData.dot ? '2px' : '6px'
  154 + style.marginLeft = this.parentData.dot ? '2px' : '6px'
  155 + }
157 156  
158   - return style
  157 + return style
  158 + }
  159 + },
  160 + mounted() {
  161 + this.parent && this.parent.updateFromChild()
  162 + uni.$u.sleep().then(() => {
  163 + this.getStepsItemRect()
  164 + })
  165 + },
  166 + methods: {
  167 + init() {
  168 + // 初始化数据
  169 + this.updateParentData()
  170 + if (!this.parent) {
  171 + return uni.$u.error('u-steps-item必须要搭配u-steps组件使用')
159 172 }
  173 + this.index = this.parent.children.indexOf(this)
  174 + this.childLength = this.parent.children.length
160 175 },
161   - mounted() {
162   - this.parent && this.parent.updateFromChild()
163   - uni.$u.sleep().then(() => {
164   - this.getStepsItemRect()
165   - })
  176 + updateParentData() {
  177 + // 此方法在mixin中
  178 + this.getParentData('u-steps')
166 179 },
167   - methods: {
168   - init() {
169   - // 初始化数据
170   - this.updateParentData()
171   - if (!this.parent) {
172   - return uni.$u.error('u-steps-item必须要搭配u-steps组件使用')
173   - }
174   - this.index = this.parent.children.indexOf(this)
175   - this.childLength = this.parent.children.length
176   - },
177   - updateParentData() {
178   - // 此方法在mixin中
179   - this.getParentData('u-steps')
180   - },
181   - // 父组件数据发生变化
182   - updateFromParent() {
183   - this.init()
184   - },
185   - // 获取组件的尺寸,用于设置横线的位置
186   - getStepsItemRect() {
187   - // #ifndef APP-NVUE
188   - this.$uGetRect('.u-steps-item').then(size => {
189   - this.size = size
190   - })
191   - // #endif
  180 + // 父组件数据发生变化
  181 + updateFromParent() {
  182 + this.init()
  183 + },
  184 + // 获取组件的尺寸,用于设置横线的位置
  185 + getStepsItemRect() {
  186 + // #ifndef APP-NVUE
  187 + this.$uGetRect('.u-steps-item').then(size => {
  188 + this.size = size
  189 + })
  190 + // #endif
192 191  
193   - // #ifdef APP-NVUE
194   - dom.getComponentRect(this.$refs['u-steps-item'], res => {
195   - const {
196   - size
197   - } = res
198   - this.size = size
199   - })
200   - // #endif
201   - }
  192 + // #ifdef APP-NVUE
  193 + dom.getComponentRect(this.$refs['u-steps-item'], res => {
  194 + const {
  195 + size
  196 + } = res
  197 + this.size = size
  198 + })
  199 + // #endif
202 200 }
203 201 }
  202 +}
204 203 </script>
205 204  
206 205 <style lang="scss" scoped>
207   - @import "../../libs/css/components.scss";
  206 +@import "../../libs/css/components.scss";
208 207  
209   - .u-steps-item {
210   - flex: 1;
211   - @include flex;
  208 +.u-steps-item {
  209 + flex: 1;
  210 + @include flex;
212 211  
213   - &--row {
214   - flex-direction: column;
215   - align-items: center;
216   - position: relative;
217   - }
218   -
219   - &--column {
220   - position: relative;
221   - flex-direction: row;
222   - justify-content: flex-start;
223   - padding-bottom: 5px;
224   - }
  212 + &--row {
  213 + flex-direction: column;
  214 + align-items: center;
  215 + position: relative;
  216 + }
225 217  
226   - &__wrapper {
227   - @include flex;
228   - justify-content: center;
229   - align-items: center;
230   - position: relative;
231   - background-color: #fff;
  218 + &--column {
  219 + position: relative;
  220 + flex-direction: row;
  221 + justify-content: flex-start;
  222 + padding-bottom: 5px;
  223 + }
232 224  
233   - &--column {
234   - width: 20px;
235   - height: 32px;
  225 + &__wrapper {
  226 + @include flex;
  227 + justify-content: center;
  228 + align-items: center;
  229 + position: relative;
  230 + background-color: #fff;
236 231  
237   - &--dot {
238   - height: 20px;
239   - width: 20px;
240   - }
241   - }
  232 + &--column {
  233 + width: 20px;
  234 + height: 32px;
242 235  
243   - &--row {
244   - width: 32px;
  236 + &--dot {
245 237 height: 20px;
246   -
247   - &--dot {
248   - width: 20px;
249   - height: 20px;
250   - }
  238 + width: 20px;
251 239 }
  240 + }
252 241  
253   - &__circle {
  242 + &--row {
  243 + width: 32px;
  244 + height: 20px;
  245 +
  246 + &--dot {
254 247 width: 20px;
255 248 height: 20px;
256   - /* #ifndef APP-NVUE */
257   - box-sizing: border-box;
258   - flex-shrink: 0;
259   - /* #endif */
260   - border-radius: 100px;
261   - border-width: 1px;
262   - border-color: $u-tips-color;
263   - border-style: solid;
  249 + }
  250 + }
  251 +
  252 + &__circle {
  253 + width: 20px;
  254 + height: 20px;
  255 + /* #ifndef APP-NVUE */
  256 + box-sizing: border-box;
  257 + flex-shrink: 0;
  258 + /* #endif */
  259 + border-radius: 100px;
  260 + border-width: 1px;
  261 + border-color: $u-tips-color;
  262 + border-style: solid;
  263 + @include flex(row);
  264 + align-items: center;
  265 + justify-content: center;
  266 + transition: background-color 0.3s;
  267 +
  268 + &__text {
  269 + color: $u-tips-color;
  270 + font-size: 11px;
264 271 @include flex(row);
265 272 align-items: center;
266 273 justify-content: center;
267   - transition: background-color 0.3s;
268   -
269   - &__text {
270   - color: $u-tips-color;
271   - font-size: 11px;
272   - @include flex(row);
273   - align-items: center;
274   - justify-content: center;
275   - text-align: center;
276   - line-height: 11px;
277   - }
  274 + text-align: center;
  275 + line-height: 11px;
278 276 }
  277 + }
279 278  
280   - &__dot {
281   - width: 10px;
282   - height: 10px;
283   - border-radius: 100px;
284   - background-color: $u-content-color;
285   - }
  279 + &__dot {
  280 + width: 10px;
  281 + height: 10px;
  282 + border-radius: 100px;
  283 + background-color: $u-content-color;
286 284 }
  285 + }
287 286  
288   - &__content {
289   - @include flex;
290   - flex: 1;
  287 + &__content {
  288 + @include flex;
  289 + flex: 1;
291 290  
292   - &--row {
293   - flex-direction: column;
294   - align-items: center;
295   - }
  291 + &--row {
  292 + flex-direction: column;
  293 + align-items: center;
  294 + }
296 295  
297   - &--column {
298   - flex-direction: column;
299   - margin-left: 6px;
300   - }
  296 + &--column {
  297 + flex-direction: column;
  298 + margin-left: 6px;
301 299 }
  300 + }
302 301  
303   - &__line {
304   - position: absolute;
305   - background: $u-tips-color;
  302 + &__line {
  303 + position: absolute;
  304 + background: $u-tips-color;
306 305  
307   - &--row {
308   - top: 10px;
309   - height: 1px;
310   - }
  306 + &--row {
  307 + top: 10px;
  308 + height: 1px;
  309 + }
311 310  
312   - &--column {
313   - width: 1px;
314   - left: 10px;
315   - }
  311 + &--column {
  312 + width: 1px;
  313 + left: 10px;
316 314 }
317 315 }
  316 +}
318 317 </style>
... ...
garbage-removal/src/uview-plus/components/u-text/u-text.vue
1 1 <template>
2   - <view
3   - class="u-text"
4   - :class="[]"
5   - v-if="show"
6   - :style="{
7   - margin: margin,
8   - justifyContent: align === 'left' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end'
9   - }"
10   - @tap="clickHandler"
11   - >
12   - <text
13   - :class="['u-text__price', type && `u-text__value--${type}`]"
14   - v-if="mode === 'price'"
15   - :style="[valueStyle]"
16   - >¥</text
17   - >
  2 + <view class="u-text" :class="[]" v-if="show" :style="{
  3 + margin: margin,
  4 + justifyContent: align === 'left' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end',
  5 + textAlign: align === 'left' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end'
  6 + }" @tap="clickHandler">
  7 + <text :class="['u-text__price', type && `u-text__value--${type}`]" v-if="mode === 'price'"
  8 + :style="[valueStyle]">¥</text>
18 9 <view class="u-text__prefix-icon" v-if="prefixIcon">
19   - <u-icon
20   - :name="prefixIcon"
21   - :customStyle="$u.addStyle(iconStyle)"
22   - ></u-icon>
  10 + <u-icon :name="prefixIcon" :customStyle="$u.addStyle(iconStyle)"></u-icon>
23 11 </view>
24   - <u-link
25   - v-if="mode === 'link'"
26   - :text="value"
27   - :href="href"
28   - underLine
29   - ></u-link>
  12 + <u-link v-if="mode === 'link'" :text="value" :href="href" underLine></u-link>
30 13 <template v-else-if="openType && isMp">
31   - <button
32   - class="u-reset-button u-text__value"
33   - :style="[valueStyle]"
34   - :data-index="index"
35   - :openType="openType"
36   - @getuserinfo="onGetUserInfo"
37   - @contact="onContact"
38   - @getphonenumber="onGetPhoneNumber"
39   - @error="onError"
40   - @launchapp="onLaunchApp"
41   - @opensetting="onOpenSetting"
42   - :lang="lang"
43   - :session-from="sessionFrom"
44   - :send-message-title="sendMessageTitle"
45   - :send-message-path="sendMessagePath"
46   - :send-message-img="sendMessageImg"
47   - :show-message-card="showMessageCard"
48   - :app-parameter="appParameter"
49   - >
  14 + <button class="u-reset-button u-text__value" :style="[valueStyle]" :data-index="index" :openType="openType"
  15 + @getuserinfo="onGetUserInfo" @contact="onContact" @getphonenumber="onGetPhoneNumber" @error="onError"
  16 + @launchapp="onLaunchApp" @opensetting="onOpenSetting" :lang="lang" :session-from="sessionFrom"
  17 + :send-message-title="sendMessageTitle" :send-message-path="sendMessagePath"
  18 + :send-message-img="sendMessageImg" :show-message-card="showMessageCard" :app-parameter="appParameter">
50 19 {{ value }}
51 20 </button>
52 21 </template>
53   - <text
54   - v-else
55   - class="u-text__value"
56   - :style="[valueStyle]"
57   - :class="[
58   - type && `u-text__value--${type}`,
59   - lines && `u-line-${lines}`
60   - ]"
61   - >{{ value }}</text
62   - >
  22 + <text v-else class="u-text__value" :style="[valueStyle]" :class="[
  23 + type && `u-text__value--${type}`,
  24 + lines && `u-line-${lines}`
  25 + ]">{{ value }}</text>
63 26 <view class="u-text__suffix-icon" v-if="suffixIcon">
64   - <u-icon
65   - :name="suffixIcon"
66   - :customStyle="$u.addStyle(iconStyle)"
67   - ></u-icon>
  27 + <u-icon :name="suffixIcon" :customStyle="$u.addStyle(iconStyle)"></u-icon>
68 28 </view>
69 29 </view>
70 30 </template>
71 31  
72 32 <script>
73   -import value from './value.js'
74   -import mpMixin from '../../libs/mixin/mpMixin.js';
  33 +import button from '../../libs/mixin/button.js';
75 34 import mixin from '../../libs/mixin/mixin.js';
76   -import button from '../../libs/mixin/button.js'
77   -import openType from '../../libs/mixin/openType.js'
78   -import props from './props.js'
  35 +import mpMixin from '../../libs/mixin/mpMixin.js';
  36 +import openType from '../../libs/mixin/openType.js';
  37 +import props from './props.js';
  38 +import value from './value.js';
79 39 /**
80 40 * Text 文本
81 41 * @description 此组件集成了文本类在项目中的常用功能,包括状态,拨打电话,格式化日期,*替换,超链接...等功能。 您大可不必在使用特殊文本时自己定义,text组件几乎涵盖您能使用的大部分场景。
... ... @@ -112,7 +72,7 @@ export default {
112 72 // #ifndef MP
113 73 mixins: [mpMixin, mixin, value, props],
114 74 // #endif
115   - emits: ['click'],
  75 + emits: ['click'],
116 76 computed: {
117 77 valueStyle() {
118 78 const style = {
... ... @@ -168,9 +128,9 @@ export default {
168 128 align-items: center;
169 129 flex-wrap: nowrap;
170 130 flex: 1;
171   - /* #ifndef APP-NVUE */
172   - width: 100%;
173   - /* #endif */
  131 + /* #ifndef APP-NVUE */
  132 + width: 100%;
  133 + /* #endif */
174 134  
175 135 &__price {
176 136 font-size: 14px;
... ...
garbage-removal/src/uview-plus/components/u-upload/props.js
... ... @@ -120,6 +120,11 @@ export default {
120 120 previewImage: {
121 121 type: Boolean,
122 122 default: defprops.upload.previewImage
  123 + },
  124 + // 是否只读
  125 + isReadOnly: {
  126 + type: Boolean,
  127 + default: false
123 128 }
124 129 }
125 130 }
... ...
garbage-removal/src/uview-plus/components/u-upload/u-upload.vue
... ... @@ -21,13 +21,14 @@
21 21 </view>
22 22 <text v-if="item.message" class="u-upload__status__message">{{ item.message }}</text>
23 23 </view>
24   - <view class="u-upload__deletable" v-if="item.status !== 'uploading' && (deletable || item.deletable)"
  24 + <view class="u-upload__deletable"
  25 + v-if="item.status !== 'uploading' && (deletable || item.deletable) && !isReadOnly"
25 26 @tap.stop="deleteItem(index)">
26 27 <view class="u-upload__deletable__icon">
27 28 <u-icon name="close" color="#ffffff" size="25"></u-icon>
28 29 </view>
29 30 </view>
30   - <view class="u-upload__success" v-if="item.status === 'success'">
  31 + <view class="u-upload__success" v-if="false">
31 32 <!-- #ifdef APP-NVUE -->
32 33 <image :src="successIcon" class="u-upload__success__icon"></image>
33 34 <!-- #endif -->
... ... @@ -41,7 +42,7 @@
41 42  
42 43 </template>
43 44  
44   - <template v-if="isInCount">
  45 + <template v-if="isInCount && !isReadOnly">
45 46 <view v-if="$slots.default || $slots.$default" @tap="chooseFile">
46 47 <slot />
47 48 </view>
... ... @@ -250,9 +251,16 @@ export default {
250 251 // 预览图片
251 252 onPreviewImage(item) {
252 253 if (!item.isImage || !this.previewFullImage) return
  254 + let baseUrl = import.meta.env.VITE_BASE_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 + }
253 261 uni.previewImage({
254 262 // 先filter找出为图片的item,再返回filter结果中的图片url
255   - urls: this.lists.filter((item) => this.accept === 'image' || uni.$u.test.image(item.url || item.thumb)).map((item) => item.url || item.thumb),
  263 + urls: imageArray,
256 264 current: item.url || item.thumb,
257 265 fail() {
258 266 uni.$u.toast('预览图片失败')
... ... @@ -414,6 +422,7 @@ $u-upload-disabled-opacity: .5 !default;
414 422 }
415 423  
416 424 &__success {
  425 + display: none;
417 426 position: absolute;
418 427 bottom: $u-upload-success-bottom;
419 428 right: $u-upload-success-right;
... ...