ai取件码+若干优化

This commit is contained in:
2025-03-11 04:17:23 +08:00
parent 1a3311b6aa
commit 259cde75bb
13 changed files with 532 additions and 403 deletions

View File

@ -1,7 +1,7 @@
import request from './request' import request from './request'
let app = getApp(); let app = getApp();
export default { const commonApi = {
getConfig:()=>request.get('/api/config'), getConfig:()=>request.get('/api/config'),
community:{ community:{
list:(data)=>request.get('/api/community',data), list:(data)=>request.get('/api/community',data),
@ -36,7 +36,11 @@ export default {
receive:(activity_id)=>request.post(`/api/coupon-activities/${activity_id}/receive`,{},{noTips:true}) receive:(activity_id)=>request.post(`/api/coupon-activities/${activity_id}/receive`,{},{noTips:true})
}, },
getPickupCodeWidthImgUrl:(url)=>request.post('/api/ai/recognition/pickup_code_with_url',{url}), getPickupCodeWidthImgUrl:(url)=>request.post('/api/ai/recognition/pickup_code_with_url',{url}),
uploadImg(file,progress){ getPickupCodeWidthFile:(file,options)=>{
return commonApi.uploadImg(file,{...options,requestUrl:'/api/ai/recognition/pickup_code'});
},
uploadImg(file,options){
options = options||{};
if(!app)app = getApp(); if(!app)app = getApp();
return new Promise((rs,rj)=>{ return new Promise((rs,rj)=>{
const task = wx.uploadFile({ const task = wx.uploadFile({
@ -45,7 +49,7 @@ export default {
header:{ header:{
Authorization: `Bearer ${app?.globalData?.accessToken}` Authorization: `Bearer ${app?.globalData?.accessToken}`
}, },
url: request.baseUrl+'/api/upload/image', url: `${request.baseUrl}${options.requestUrl||'/api/upload/image'}`,
success:(res)=>{ success:(res)=>{
const response = JSON.parse(res.data); const response = JSON.parse(res.data);
rs(response.data); rs(response.data);
@ -54,10 +58,12 @@ export default {
rj(res); rj(res);
} }
}) })
if(progress){ if(options&&options.progress){
progress.task = task;
task.onProgressUpdate(progress); task.onProgressUpdate(progress);
} }
file.task = task;
}); });
} }
} }
export default commonApi;

View File

@ -394,3 +394,9 @@ list-view{
background-size:100% background-size:100%
} }
.weui-loading.white{
font-size:16px;width:1em;height:1em;display:inline-block;vertical-align:middle;
background:transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='160rpx' height='160rpx' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23ededed' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23ededed' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23ededed' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3CanimateTransform attributeName='transform' begin='0s' dur='1s' type='rotate' values='0 40 40;360 40 40' repeatCount='indefinite'/%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
background-size:100%
}

BIN
assets/icon/help/ai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,6 +1,6 @@
// components/modalView/index.js const app = getApp();
Component({
Component({
/** /**
* 组件的属性列表 * 组件的属性列表
*/ */
@ -17,6 +17,14 @@ Component({
type:Boolean, type:Boolean,
value:false value:false
}, },
editRequired:{
type:Boolean,
value:false
},
row:{
type:Number,
value:4
},
content:{ content:{
type:String, type:String,
value:'' value:''
@ -29,6 +37,10 @@ Component({
type:Boolean, type:Boolean,
value:true value:true
}, },
isShowOk:{
type:Boolean,
value:true
},
cancelButtonText:{ cancelButtonText:{
type:String, type:String,
value:'取消' value:'取消'
@ -50,60 +62,77 @@ Component({
}) })
}).exec(); }).exec();
} }
this.setData({
_show:show
})
} }
} },
overlayClose:{
type:Boolean,
value:true
},
showCloseButton:{
type:Boolean,
value:false
},
autoFocus:{
type:Boolean,
value:false
},
useInput:{
type:Boolean,
value:false
},
}, },
/** /**
* 组件的初始数据 * 组件的初始数据
*/ */
data: { data: {
dynamicsStyle:'' dynamicsStyle:'',
textareaHeight:124,
_show:false
}, },
/** /**
* 组件的方法列表 * 组件的方法列表
*/ */
methods: { methods: {
abc(event){
console.log(event);
},
cancelButtonTap(){ cancelButtonTap(){
wx.showTabBar({ this.setData({
complete:()=>{ _show:false
this.setData({ });
show:false this.triggerEvent('cancel');
});
this.triggerEvent('cancel');
}
})
}, },
okButtonTap(){ okButtonTap(){
wx.showTabBar({ if(this.properties.editRequired){
complete:()=>{ const valid = app.validateForm({
this.setData({ content:{
show:false required:true,
}); message:this.properties.contentPlaceholder,
this.triggerEvent('ok'); shake:true,
} // autoFocus:true //textarea 有 bug
}
},this);
if(valid.length>0)return;
}
this.setData({
show:false
}); });
this.triggerEvent('ok',this.properties.content);
}, },
enterPageContainer(){ afterLeave(event){
wx.hideTabBar(); this.setData({
}, show:false
leavePageContainer(){ })
wx.showTabBar();
} }
}, },
lifetimes:{ lifetimes:{
// attached(){ attached(){
// console.log(this); console.log('init model view');
// const windowInfo = wx.getWindowInfo(); }
// this.createSelectorQuery().select('#modalViewMain').boundingClientRect((res)=>{
// const viewHeight = res.height;
// console.log(res);
// this.setData({
// dynamicsStyle:`top:${(windowInfo.screenHeight-viewHeight)/2}px;height:${viewHeight}px;`
// })
// }).exec();
// }
} }
}) })

View File

@ -1,4 +1,5 @@
{ {
"component": true, "component": true,
"usingComponents": {} "usingComponents": {},
"styleIsolation": "apply-shared"
} }

View File

@ -1,16 +1,27 @@
<page-container model:show="{{show}}" position="center" class="custom-modal-view"
custom-style="background-color:transparent;left:27px;width:calc(100vw - 54px);height:200px;{{dynamicsStyle}}" <page-container model:show="{{_show}}" wx:if="{{show}}" position="center"
bind:enter="enterPageContainer" bind:leave="leavePageContainer"> class="custom-modal-view" bind:afterleave="afterLeave"
custom-style="background-color:transparent;left:27px;width:calc(100vw - 54px);height:200px;{{dynamicsStyle}}">
<view class="custom-modal-view-overlay" wx:if="{{!overlayClose}}"></view>
<view class="modal-view-main" id="modalViewMain"> <view class="modal-view-main" id="modalViewMain">
<view class="title {{titleTextCenter?'center':''}}">{{titleText}}</view> <view class="title {{titleTextCenter?'center':''}}">
<view class="content"> <view class="text">{{titleText}}</view>
<textarea class="textarea" row="3" wx:if="{{editable}}">{{content}}</textarea> <view class="close-btn-area">
<view class="text" wx:else>{{content}}</view> <view class="close-btn" bind:tap="cancelButtonTap" wx:if="{{showCloseButton}}"></view>
</view>
</view> </view>
<view class="btns"> <input wx:if="{{editable&&useInput}}" model:value="{{content}}" cursor-spacing="140px"
<button class="button cancel" plain wx:if="{{isShowCancel}}" bind:tap="cancelButtonTap">{{cancelButtonText}}</button> focus="{{show&&autoFocus}}" class="content-input"
<button class="button confirm" type="primary" bind:tap="okButtonTap">{{okButtonText}}</button> placeholder="{{contentPlaceholder}}"/>
<textarea class="textarea {{contentMessage?'error':''}}" model:value="{{content}}" row="3" wx:elif="{{editable}}" focus="{{show&&autoFocus}}"
placeholder="{{contentPlaceholder}}" focus="{{contentFocus}}" animation="{{contentAnimation}}" cursor-spacing="200rpx"></textarea>
<view class="content-text" wx:elif="{{content}}">{{content}}</view>
<slot/>
<view class="btns" wx:if="{{isShowCancel||isShowOk}}">
<button class="button cancel" plain wx:if="{{isShowCancel}}" bind:tap="cancelButtonTap">{{cancelButtonText}}</button>
<button class="button confirm" wx:if="{{isShowOk}}" type="primary" bind:tap="okButtonTap">{{okButtonText}}</button>
</view> </view>
</view> </view>
</page-container> </page-container>

View File

@ -1,47 +1,104 @@
.custom-modal-view{ .custom-modal-view{
border-radius: 20px; border-radius: 20px;
} }
.custom-modal-view-overlay{
position: fixed;
top:0;left:0;right:0;
height:100vh;
opacity: 0;
}
.custom-modal-view .title{ .custom-modal-view .title{
font-size: 34rpx; font-size: 36rpx;
font-weight: 500; font-weight: 500;
line-height: 50rpx; line-height: 50rpx;
position: relative;
} }
.custom-modal-view .title.center{ .custom-modal-view .title.center{
text-align: center; text-align: center;
} }
.close-btn-area{
position: absolute;
right:-32rpx;top:-32rpx;
width:100rpx;height:82rpx;
display: flex;
align-items: flex-end;
justify-content: center;
}
.custom-modal-view .title .close-btn{
position: relative;
width:50rpx;height:50rpx;
}
.custom-modal-view .title .close-btn::before,.custom-modal-view .title .close-btn::after{
content: '';
position: absolute;
width:80%;
height:4rpx;
left:10%;top:50%;
margin-top:-2rpx;
background-color: #999999;
transform: rotate(45deg);
}
.custom-modal-view .title .close-btn::after{
width:4rpx;
height:80%;
left:50%;top:10%;
margin-top:0;
margin-left: -2rpx;
}
.modal-view-main{ .modal-view-main{
border-radius: 24rpx; border-radius: 24rpx;
background-color: #fff; background-color: #fff;
padding:32rpx; padding:32rpx;
position: relative;
z-index: 111;
} }
.modal-view-main .content .text{ .custom-modal-view .textarea{
border: 1.2px solid rgba(85, 85, 85, 0.3);
border-radius: 18px;
margin:30rpx 0;
padding:24rpx 20rpx;
font-size: 34rpx;
width:100%;
box-sizing: border-box;
line-height:50rpx;
height: 214rpx;
}
.custom-modal-view .content-input{
background-color: rgba(124, 134, 149, 0.08);
border-radius: 12rpx;
padding:20rpx;
margin-top:20rpx;
}
.custom-modal-view .content-text{
color: #666666; color: #666666;
font-size: 28rpx; font-size: 28rpx;
text-align: center; text-align: center;
margin:16rpx 0 40rpx 0; margin:16rpx 0 40rpx 0;
} }
.custom-modal-view .textarea{ .custom-modal-view .textarea.error{
border-color:red;
} }
.modal-view-main .btns{ .modal-view-main .btns{
margin-top:32rpx; margin-top:32rpx;
display: flex; display: flex;
gap: 20rpx; gap: 18rpx;
} }
.modal-view-main .btns .button{ .modal-view-main .btns .button{
flex:1; flex:1;
font-size: 32rpx; font-size: 16px;
padding:32rpx; padding:16px;
line-height: 1; line-height: 1;
font-weight: 500; font-weight: 500;
border-width: 2rpx; border-width: 2rpx;/* 边框显示不完整 bug */
} }
.modal-view-main .btns .button.cancel{ .modal-view-main .btns .button.cancel{
border-color:rgba(153, 153, 153, 0.5); border-color:rgba(153, 153, 153, 0.5);
background-color: rgba(153, 153, 153, 0.1); background-color: rgba(153, 153, 153, 0.1);
color:var(--main-font-color); color:var(--main-font-color);
} }
.modal-view-main .btns .button.confirm{ .modal-view-main .btns .button.confirm{
font-weight: bold; font-weight: bold;
} }

View File

@ -11,7 +11,7 @@
.radio-group .item{ .radio-group .item{
padding:20rpx 0; padding:20rpx 0;
} }
.button{ .editor .button{
margin:30rpx!important; margin:30rpx!important;
} }
.picker.cell-bd{ .picker.cell-bd{

View File

@ -74,13 +74,9 @@ Page({
success:(res)=>{ success:(res)=>{
const name = []; const name = [];
let count = 0; let count = 0;
if(res.data.price_request.pickup_images){
name.push('图片取件');
count+=res.data.price_request.pickup_images_count;
}
res.data.price_request.packages.map((item)=>{ res.data.price_request.packages.map((item)=>{
name.push(item.station_name); name.push(item.name);
count+=item.pickup_codes.split(',').length; count+=item.pickup_codes.length;
}); });
this.setData({ this.setData({
package:{ package:{
@ -176,7 +172,18 @@ Page({
community_id:this.data.currentCommunity.id community_id:this.data.currentCommunity.id
}; };
if(res.data.price_request.packages&&res.data.price_request.packages.length>0){ if(res.data.price_request.packages&&res.data.price_request.packages.length>0){
params.packages = res.data.price_request.packages; let realItem = [];
res.data.price_request.packages.map((item)=>{
let p = {
pickup_codes:item.pickup_codes.join(','),
station_name:item.name
}
if(item.id){
p.station_id = item.id
}
realItem.push(p)
})
params.packages = realItem;
} }
if(res.data.price_request.pickup_images){ if(res.data.price_request.pickup_images){
params.pickup_images_count = res.data.price_request.pickup_images_count; params.pickup_images_count = res.data.price_request.pickup_images_count;
@ -225,6 +232,21 @@ Page({
success:(res)=>{ success:(res)=>{
res.data.addressid = this.data.currentAddress.id; res.data.addressid = this.data.currentAddress.id;
res.data.price_request.community_id = this.data.currentCommunity.id; res.data.price_request.community_id = this.data.currentCommunity.id;
if(res.data.price_request.packages&&res.data.price_request.packages.length>0){
let realItem = [];
res.data.price_request.packages.map((item)=>{
let p = {
pickup_codes:item.pickup_codes.join(','),
station_name:item.name
}
if(item.id){
p.station_id = item.id
}
realItem.push(p)
})
res.data.price_request.packages = realItem;
}
userApi.order.real(res.data).then((data)=>{ userApi.order.real(res.data).then((data)=>{
this.setData({ this.setData({
isShowOrderConfirm:false, isShowOrderConfirm:false,
@ -240,6 +262,10 @@ Page({
}) })
} }
}); });
}).catch((e)=>{
this.setData({
ordering:false
});
}); });
} }
}); });

View File

@ -10,66 +10,71 @@ Page({
*/ */
data: { data: {
stationList:[], stationList:[],
choosedStationList:[],
sendType:'DELIVERY_AT_DOORSTEP',//默认方式 sendType:'DELIVERY_AT_DOORSTEP',//默认方式
tempImgs:[],
imgUploading:false, imgUploading:false,
imgOrderCount:0,
maxChooseImgCount:10,
sendTypeKV:userApi.order.orderDeliverStatusKV, sendTypeKV:userApi.order.orderDeliverStatusKV,
timePeriods:[], timePeriods:[],
timePeriodsIndex:-1, timePeriodsIndex:-1,
isShowDeliverType:false isShowDeliverType:false,
},
validator:{ recogniting:false,
imgOrderCount:{min:1,shake:true}
isShowStationEditor:false,
currentEditStation:{}
}, },
async bottomBarButtonTap(){ async bottomBarButtonTap(){
if(this.data.tempImgs&&this.data.tempImgs.length>0){
const valid = app.validateForm(this.validator,this);
console.log(this.validator,valid);
if(valid.length>0){
wx.showToast({
icon:'none',
title: '请选择包裹数量',
})
return;
}
this.setData({
imgUploading:true
})
const rs = await this.uploadImages();
this.setData({
imgUploading:false
})
if(rs instanceof Error){
return;
}
}
const data = []; const data = [];
this.data.stationList.map((item)=>{ let hasSame = false;
if(item.package.length>0&&item.package[0]!=''){ this.data.choosedStationList.find((item,index)=>{
if(item.pickup_codes.length>0&&item.pickup_codes[0]!=''){
//倒着找相同的索引 因为需要从后往前找
const codes = item.pickup_codes.join(',').split(',').reverse();
let sameValue = '';
let findIndex = codes.findIndex((_item)=>{
let sames = codes.filter((__item)=>_item==__item);
//找到了相同的
if(sames.length>1){
sameValue = _item;
hasSame = true;
return true;
}
})
if(findIndex>-1){
//再反转取得最后一个相同的 index
findIndex = item.pickup_codes.length - findIndex - 1;
this.data.choosedStationList[index].focus = true;
this.data.choosedStationList[index].focusIndex = findIndex;
console.log(findIndex,sameValue);
wx.showToast({
icon:'none',
title: '取件码重复',
})
console.log(this.data.choosedStationList[index],'----');
this.setData({
[`choosedStationList[${index}]`]:this.data.choosedStationList[index]
})
return true;
}
data.push({ data.push({
station_id:item.id, id:item.id||'',
station_name:item.name, name:item.name,
pickup_codes:item.package.filter((item)=>item!='').join(',') imgUrl:item.imgUrl||'',
service_text:item.service_text,
pickup_codes:item.pickup_codes.filter((item)=>item!='')
}); });
} }
}) })
//录入了有效取件码 或者 上传了取件图片 console.log(hasSame,'----');
if(data.length>0||this.data.tempImgs.length>0){ if(hasSame)return;
//录入了有效取件码 或者 上传了取件图片||this.data.tempImgs.length>0
if(data.length>0){
let priceRequest = { let priceRequest = {
packages:data packages:data
}; };
if(this.data.tempImgs.length>0){
let imgs = [];
this.data.tempImgs.map((item)=>{
imgs.push(item.serverUrl);
});
priceRequest.pickup_images_count = this.data.imgOrderCount;
priceRequest.pickup_images = imgs.join(',')
}
if(this.data.timePeriodsIndex==-1){ if(this.data.timePeriodsIndex==-1){
wx.showToast({ wx.showToast({
icon:'none', icon:'none',
@ -80,14 +85,15 @@ Page({
}) })
return; return;
} }
console.log('this.data.sendType',this.data.sendType) const periodId = this.data.timePeriods[this.data.timePeriodsIndex].communtiy_time_period_id;
const deliveryDate = this.data.timePeriods[this.data.timePeriodsIndex].time_period_date;
wx.setStorage({ wx.setStorage({
key:'pre-order', key:'pre-order',
data:{ data:{
price_request:priceRequest, price_request:priceRequest,
delivery_method:this.data.sendType, delivery_method:this.data.sendType,
community_time_period_id:this.data.timePeriods[this.data.timePeriodsIndex].communtiy_time_period_id, community_time_period_id:periodId,
delivery_date:this.data.timePeriods[this.data.timePeriodsIndex].time_period_date delivery_date:deliveryDate
}, },
success(){ success(){
wx.navigateBack(); wx.navigateBack();
@ -105,58 +111,64 @@ Page({
addPackage(event){ addPackage(event){
const index = event.currentTarget.dataset.index; const index = event.currentTarget.dataset.index;
let packages = this.data.stationList[index].package; let packages = this.data.choosedStationList[index].pickup_codes;
if(!packages){
packages = [];
}
if(packages.length>1){
if(packages.filter((item)=>item==packages[packages.length-1]).length>1){
wx.showToast({
icon:'none',
title: '取件码重复'
})
this.data.stationList[index].focus = true;
this.setData({
[`stationList[${index}].focus`]:true
});
return;
}
}
let hasEmptyInput = packages.find((item)=>item=='')!=undefined; let hasEmptyInput = packages.find((item)=>item=='')!=undefined;
if(!hasEmptyInput){ if(!hasEmptyInput){
packages.push(''); packages.push('');
} }
this.data.stationList[index].focus = true; this.data.choosedStationList[index].focus = true;
this.setData({ this.setData({
[`stationList[${index}]`]:this.data.stationList[index] [`choosedStationList[${index}]`]:this.data.choosedStationList[index]
}); });
}, },
deletePackage(event){ deletePackage(event){
const itemIndex = event.currentTarget.dataset.index; const itemIndex = event.currentTarget.dataset.index;
const packageIndex = event.currentTarget.dataset.p_index; const packageIndex = event.currentTarget.dataset.p_index;
this.data.stationList[itemIndex].package.splice(packageIndex,1); this.data.choosedStationList[itemIndex].pickup_codes.splice(packageIndex,1);
this.setData({ if(this.data.choosedStationList[itemIndex].pickup_codes.length==0){
[`stationList[${itemIndex}].package`]:this.data.stationList[itemIndex].package //code 删完了就删除station
}) this.data.choosedStationList.splice(itemIndex,1);
this.setData({
choosedStationList:this.data.choosedStationList
})
}else{
//仅仅删除 code
this.setData({
[`choosedStationList[${itemIndex}].pickup_codes`]:this.data.choosedStationList[itemIndex].pickup_codes
})
}
}, },
setPackageCode(event){ setPackageCode(event){
const itemIndex = event.currentTarget.dataset.index; const itemIndex = event.currentTarget.dataset.index;
const packageIndex = event.currentTarget.dataset.p_index; const packageIndex = event.currentTarget.dataset.p_index;
this.data.stationList[itemIndex].package[packageIndex] = event.detail.value; this.data.choosedStationList[itemIndex].pickup_codes[packageIndex] = event.detail.value;
}, },
checkInput(event){ checkInput(event){
const itemIndex = event.currentTarget.dataset.index; const itemIndex = event.currentTarget.dataset.index;
const packageIndex = event.currentTarget.dataset.p_index; const packageIndex = event.currentTarget.dataset.p_index;
let packages = this.data.stationList[itemIndex].package; let packages = this.data.choosedStationList[itemIndex].pickup_codes;
if(packages.length>1){ if(packages.length>1){
if(packages.filter((item)=>item==packages[packages.length-1]).length>1){ if(packages.filter((item)=>item==packages[packages.length-1]).length>1){
wx.showToast({ wx.showToast({
icon:'none', icon:'none',
title: '取件码重复' title: '取件码重复'
}) })
//清空
// this.setData({
// [`choosedStationList[${itemIndex}].pickup_codes[${packageIndex}]`]:''
// });
//体验不好
// this.data.choosedStationList[itemIndex].focus = true;
// this.data.choosedStationList[itemIndex].focusIndex = packageIndex;
// this.setData({
// [`choosedStationList[${itemIndex}]`]:this.data.choosedStationList[itemIndex]
// })
//清除焦点 有时候 setdata 会触发获取焦点
this.setData({ this.setData({
[`stationList[${itemIndex}].package[${packageIndex}]`]:'' [`choosedStationList[${itemIndex}].focus`]:false
}); })
} }
} }
}, },
@ -166,37 +178,17 @@ Page({
onLoad(options) { onLoad(options) {
let preOrder = wx.getStorageSync('pre-order'); let preOrder = wx.getStorageSync('pre-order');
this.savedTimePeriodId = preOrder.community_time_period_id; this.savedTimePeriodId = preOrder.community_time_period_id;
if(preOrder&&preOrder.price_request){
this.setData({
choosedStationList:preOrder.price_request.packages
})
}
commonApi.station.list(options.communityId).then((data)=>{ commonApi.station.list(options.communityId).then((data)=>{
data.items.map((item,index)=>{
if(preOrder){
const __item = preOrder.price_request.packages.find((_item)=>_item.station_id==item.id);
if(__item){
item.package = __item.pickup_codes.split(',')||[];
return;
}
}
item.package = [];
});
let tempImgs = [],imgOrderCount = 0;
if(preOrder?.price_request?.pickup_images){
const imgs = preOrder.price_request.pickup_images.split(',');
imgs.map((item)=>{
tempImgs.push({
serverUrl:item,
uploaded:true
})
});
imgOrderCount = preOrder.price_request.pickup_images_count||0;
}
this.setData({ this.setData({
sendType:preOrder.delivery_method||this.data.sendType, sendType:preOrder.delivery_method||this.data.sendType,
stationList:data.items, stationList:data.items,
tempImgs,
imgOrderCount
}); });
//获取配送时段 //获取配送时段
return commonApi.community.timePeriods(options.communityId); return commonApi.community.timePeriods(options.communityId);
}).then((data)=>{ }).then((data)=>{
@ -224,80 +216,106 @@ Page({
}) })
}, },
manuallyAdd(){
let stationNames = this.data.stationList.map((item)=>item.name);
wx.showActionSheet({
itemList: stationNames,
success:(res)=>{
const station = this.data.stationList[res.tapIndex];
const alreadyIndex = this.data.choosedStationList.findIndex((item)=>item.id==station.id);
if(alreadyIndex>-1){
const _package = this.data.choosedStationList[alreadyIndex].pickup_codes;
if((_package[_package.length-1]||'').trim()!=''){
_package.push('');
}
this.data.choosedStationList[alreadyIndex].focus = true;
this.setData({
[`choosedStationList[${alreadyIndex}]`]:this.data.choosedStationList[alreadyIndex]
})
}else{
this.data.choosedStationList.unshift({
id:station.id,
name:station.name,
service_text:station.service_text,
pickup_codes:[''],
focus:true
})
this.setData({
choosedStationList:this.data.choosedStationList
})
}
}
})
},
chooseImage(){ chooseImage(){
if(this.data.imgUploading||this.data.recogniting)return;
wx.chooseMedia({ wx.chooseMedia({
count:this.data.maxChooseImgCount - this.data.tempImgs.length, count:1,
mediaType:['image'], mediaType:['image'],
success:(res)=>{ success:(res)=>{
this.setData({ this.setData({
tempImgs:this.data.tempImgs.concat(res.tempFiles) imgUploading:true
}); })
wx.nextTick(()=>{ commonApi.uploadImg(res.tempFiles[0]).then((data)=>{
this.uploadImages(); this.setData({
imgUploading:false
})
this.recognition(data.url);
}) })
} }
}) })
}, },
async uploadImages(){ async recognition(url){
let imgIndex = -1; this.setData({
const file = this.data.tempImgs.find((item,index)=>{ recogniting:true
imgIndex = index; })
return !item.uploaded; commonApi.getPickupCodeWidthImgUrl(url).then((data)=>{
}); if(data[0]&&data[0].stations){
if(!file){ const stations = data[0].stations;
return; let s = [];
} stations.map((item)=>{
var onProgress = (res)=>{ s.push({
//进度 imgUrl:url,
this.setData({ name:item.name,
[`tempImgs[${imgIndex}].progress`]:res.progress pickup_codes:item.pickup_codes
}) });
} })
//无奈之举不大范围改动代码的同时我需要获取到上传任务task来中断上传操作不然要出问题task在上传时被附加到了onProgress this.setData({
this.data.tempImgs[imgIndex].onProgress = onProgress; choosedStationList:s.concat(this.data.choosedStationList)
let uploadResult = {}; })
try{ }
uploadResult = await commonApi.uploadImg(file,onProgress);
}catch(e){
// await this.uploadImages();
// return;
}
if(uploadResult.url){
this.setData({
[`tempImgs[${imgIndex}].uploaded`]:true,
[`tempImgs[${imgIndex}].serverUrl`]:uploadResult.url
})
await this.uploadImages();
}else{
//上传失败
wx.showToast({ wx.showToast({
icon:'error', icon:'none',
title: '图片上传失败', title: '识别成功',
}) })
return new Error('失败') }).catch(()=>{
} }).finally(()=>{
this.setData({
recogniting:false
})
})
}, },
removeImage(event){ showStationName(event){
const index = event.currentTarget.dataset.index; const index = event.currentTarget.dataset.index;
if(this.data.tempImgs[index].onProgress&&this.data.tempImgs[index].onProgress.task){ let item = this.data.choosedStationList[index];
this.data.tempImgs[index].onProgress.task.abort();
}
console.log('remove',new Date().getTime());
this.data.tempImgs.splice(index,1);
this.setData({ this.setData({
tempImgs:this.data.tempImgs isShowStationEditor:true,
}); currentEditStation:item
},
reduceImgOrderCount(){
if(this.data.imgOrderCount<=1)return;
this.setData({
imgOrderCount:this.data.imgOrderCount-1
}) })
}, },
plusImgOrderCount(){ editStationName(event){
if(event.detail.trim()==''){
wx.showToast({
icon:'none',
title: '驿站名称不能为空',
})
return;
}
const index = this.data.choosedStationList.findIndex((item)=>item.imgUrl==this.data.currentEditStation.imgUrl);
this.setData({ this.setData({
imgOrderCount:this.data.imgOrderCount+1 [`choosedStationList[${index}].name`]:event.detail
}) })
}, },
showSendType(){ showSendType(){
@ -324,6 +342,12 @@ Page({
}) })
} }
}, },
viewImage(event){
const url = event.currentTarget.dataset.url;
wx.previewImage({
urls: [url],
})
},
/** /**
* 生命周期函数--监听页面初次渲染完成 * 生命周期函数--监听页面初次渲染完成
*/ */

View File

@ -1,5 +1,6 @@
{ {
"usingComponents": { "usingComponents": {
"modal-view":"/components/modalView"
}, },
"navigationStyle": "default", "navigationStyle": "default",
"navigationBarTitleText": "添加快递信息" "navigationBarTitleText": "添加快递信息"

View File

@ -1,56 +1,48 @@
<view class="custom-scroll-view"> <view class="custom-scroll-view">
<scroll-view class="main" scroll-y scroll-with-animation scroll-into-view="{{scrollToViewId}}" enhanced show-scrollbar="{{false}}"> <scroll-view class="main" scroll-y scroll-with-animation scroll-into-view="{{scrollToViewId}}" enhanced show-scrollbar="{{false}}">
<view class="page-container img-area">
<view class="head"> <view class="page-container ai-img-area" hover-class="hover" bind:tap="chooseImage">
<view class="title"> <view class="title">
<image class="icon" src="/assets/icon/help/images.png"/> <image src="/assets/icon/help/ai.png" class="icon"/>
<view>快捷下单</view> <view>上传图片</view>
</view> </view>
<view class="sub-title">上传含有驿站,取件码信息的截图</view>
<view class="loading" wx:if="{{imgUploading||recogniting}}">
<view class="weui-loading"></view>
<view class="sub-title"> <view class="sub-title">
上传取件信息图片时,图片需清晰显示取件位置信息 {{
imgUploading?'上传图片...':recogniting?'AI图像识别中...':''
}}
</view> </view>
</view> </view>
<button class="button" bind:tap="chooseImage" type="default" wx:if="{{tempImgs.length==0}}">点击上传取件图片</button>
<block wx:else>
<view class="photos">
<view class="item {{item.loading?'current':''}}" wx:for="{{tempImgs}}" wx:key="index">
<image class="image" src="{{item.tempFilePath||item.serverUrl}}"/>
<progress wx:if="{{!item.uploaded}}" class="progress" percent="{{item.progress}}" stroke-width="4"/>
<view class="close-area" bind:tap="removeImage" data-index="{{index}}">
<image src="/assets/icon/help/close-btn.png" class="icon"/>
</view>
</view>
<view class="take-photo item" bind:tap="chooseImage"
wx:if="{{tempImgs.length<maxChooseImgCount}}">
<image class="icon" src="/assets/icon/help/plus2.png"/>
</view>
</view>
<view class="spliter"></view>
<view class="img-count" animation="{{imgOrderCountAnimation}}">
<view class="tips">请正确选择包裹数量</view>
<view class="number-selector">
<view class="button reduce {{imgOrderCount<=1?'disabled':''}}" bind:tap="reduceImgOrderCount"></view>
<view class="value">{{imgOrderCount}}</view>
<view class="button plus" bind:tap="plusImgOrderCount"></view>
</view>
</view>
</block>
</view> </view>
<view class="page-container" wx:for="{{stationList}}" wx:key="index">
<view class="page-container manually-code" bind:tap="manuallyAdd">
<image src="/assets/icon/help/plus2.png" class="icon"/>手动录入取件码
</view>
<view class="page-container station" wx:for="{{choosedStationList}}" wx:key="index">
<view class="head"> <view class="head">
<view class="title"> <view class="title">
<image class="icon" src="/assets/icon/help/house.png"/> <view class="icon ai" wx:if="{{item.imgUrl}}">AI识别</view>
<view>{{item.name}}</view> <image class="icon" src="/assets/icon/help/house.png" wx:else/>
<view class="name">{{item.name}}</view>
<image data-index="{{index}}" bind:tap="showStationName" class="edit"
src="/assets/icon/help/edit@2x.png" wx:if="{{item.imgUrl}}"/>
<view class="right">
<image class="view-image" src="/assets/icon/help/images.png"
data-url="{{item.imgUrl}}" bind:tap="viewImage"/>
</view>
</view> </view>
<view class="sub-title"> <view class="sub-title" wx:if="{{!item.imgUrl}}">
{{item.service_text}} {{item.service_text}}
</view> </view>
</view> </view>
<view class="package-list"> <view class="package-list">
<view class="item" wx:for="{{item.package}}" wx:for-item="pItem" wx:for-index="pIndex" wx:key="pIndex"> <view class="item" wx:for="{{item.pickup_codes}}" wx:for-item="pItem" wx:for-index="pIndex" wx:key="pIndex">
<label class="label">取件码{{pIndex+1}}</label> <label class="label">取件码{{pIndex+1}}</label>
<input value="{{pItem}}" class="input" bindinput="setPackageCode" cursor-spacing="136rpx" bindblur="checkInput" <input value="{{pItem}}" class="input" bindinput="setPackageCode" cursor-spacing="136rpx" bindblur="checkInput" placeholder="输入取件码"
data-index="{{index}}" data-p_index="{{pIndex}}" focus="{{item.focus&&pItem==''}}"/> data-index="{{index}}" data-p_index="{{pIndex}}" focus="{{item.focus&&pItem==''||item.focusIndex==pIndex&&item.focus}}"/>
<button class="button" bind:tap="deletePackage" data-index="{{index}}" data-p_index="{{pIndex}}"> <button class="button" bind:tap="deletePackage" data-index="{{index}}" data-p_index="{{pIndex}}">
<image class="icon" src="/assets/icon/help/delete.png"/> <image class="icon" src="/assets/icon/help/delete.png"/>
</button> </button>
@ -77,26 +69,16 @@
</view> </view>
</view> </view>
<view class="scroll-view-dispatch" id="scrollViewDispatch"></view> <view class="scroll-view-dispatch" id="scrollViewDispatch"></view>
<!-- <view class="page-container send-way">
<view class="title">投递方式</view>
<radio-group bindchange="sendTypeChange" class="radio">
<label class="item">
<radio value="DELIVERY_TO_ROOM" checked="{{sendType=='DELIVERY_TO_ROOM'}}"/>
<label>敲门递件</label>
</label>
<label class="item">
<radio value="DELIVERY_AT_DOORSTEP" checked="{{sendType=='DELIVERY_AT_DOORSTEP'}}"/>
<label>放在门口</label>
</label>
</radio-group>
</view> -->
</scroll-view> </scroll-view>
<view class="bottom-bar-v2"> <view class="bottom-bar-v2">
<button class="button" type="primary" loading="{{imgUploading}}" disabled="{{imgUploading}}" bind:tap="bottomBarButtonTap">保存并使用</button> <button class="button" type="primary" bind:tap="bottomBarButtonTap"
loading="{{imgUploading||recogniting}}" disabled="{{imgUploading||recogniting}}">
保存并使用
</button>
</view> </view>
</view> </view>
<page-container model:show="{{isShowDeliverType}}" position="bottom" round> <page-container model:show="{{isShowDeliverType}}" wx:if="{{isShowDeliverType}}" position="bottom" round>
<view class="content deliver-type-content"> <view class="content deliver-type-content">
<view class="title">投递方式</view> <view class="title">投递方式</view>
<view class="deliver-list"> <view class="deliver-list">
@ -113,4 +95,8 @@
</view> </view>
<button type="primary" class="button" bind:tap="confirmDeliverType">确定</button> <button type="primary" class="button" bind:tap="confirmDeliverType">确定</button>
</view> </view>
</page-container> </page-container>
<modal-view editable titleText="修改驿站" content="{{currentEditStation.name||''}}"
model:show="{{isShowStationEditor}}" use-input auto-focus bind:ok="editStationName"
contentPlaceholder="驿站名不能为空"/>

View File

@ -1,20 +1,50 @@
.page-container{ .station{
padding-top:16rpx;
} }
.page-container .head{ .station .head{
padding-bottom:14rpx; white-space: nowrap;
} }
.page-container .head .icon{ .station .head .icon{
width:40rpx;height:40rpx; width:40rpx;height:40rpx;
margin-right: 20rpx; margin-right: 20rpx;
} }
.page-container .head .title{ .station .head .icon.ai{
background-color: var(--main-color);
font-size: 24rpx;
border-radius: 8rpx;
padding:8rpx 12rpx;
color:#fff;
font-weight: 500;
width: auto;
height: auto;
}
.station .head .edit{
width:36rpx;height:36rpx;
padding:16rpx 20rpx;
/* 要被压缩 */
min-width: 36rpx;
}
.station .head .right{
flex:1;
display: flex;
justify-content: flex-end;
align-items: center;
}
.station .head .view-image{
width:40rpx;height:40rpx;
padding:14rpx;
}
.station .head .title{
font-size: 36rpx; font-size: 36rpx;
font-weight: 500; font-weight: 500;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.page-container .head .sub-title{ .station .head .title .name{
overflow: hidden;
text-overflow: ellipsis;
}
.station .head .sub-title{
font-size:26rpx; font-size:26rpx;
color: #888888; color: #888888;
margin-top:24rpx; margin-top:24rpx;
@ -52,6 +82,8 @@
} }
.package-list .item .input{ .package-list .item .input{
border-radius: 0 12rpx 12rpx 0; border-radius: 0 12rpx 12rpx 0;
font-size: 34rpx;
font-weight: 600;
flex:1; flex:1;
} }
.package-list .item .button{ .package-list .item .button{
@ -64,125 +96,10 @@
width:36rpx;height:36rpx; width:36rpx;height:36rpx;
} }
.img-area.page-container .head .sub-title{
padding-left:0;
}
.img-area .photos{
margin-top:26rpx;
display: flex;
flex-wrap: wrap;
gap: 26rpx;
}
.img-area .photos .item{
text-align: center;
width:144rpx;
height:144rpx;
border-radius: 18rpx;
position: relative;
}
.img-area .photos .item .close-area{
position: absolute;
right:-16rpx;top:-16rpx;
z-index: 2;
padding:5rpx;
display: flex;
align-items: center;
}
.img-area .photos .item .close-area .icon{
width:28rpx;height:28rpx;
}
.img-area .photos .item .progress{
position: absolute;
top:0;left:0;
width:100%;
z-index: 1;
}
.img-area .photos .item.loading::after{
content: '';
position: absolute;
width:100%;height:100%;
left:0;top:0;
background-color: rgba(0, 0, 0, 0.3);
z-index: 0;
}
.img-area .photos .item .image{
width:100%;height:100%;
border-radius: 18rpx;
}
.img-area .photos .take-photo{
border: 1.2rpx dashed rgba(124, 134, 149, 0.3);
border-radius: 18rpx;
display: flex;
align-items: center;
justify-content: center;
}
.img-area .photos .take-photo .icon{
width:36rpx;height:36rpx;
}
.img-area .photos .take-photo .title{
font-size: 24rpx;
color: #7C8695;
margin-top:16rpx;
}
.img-area .img-count{
display: flex;
align-items: center;
}
.img-area .spliter{
margin:30rpx 0;
}
.img-area .img-count .tips{
flex:1;
font-size: 30rpx;
color: #555555;
}
.img-area .img-count .number-selector{
display: flex;
align-items: center;
}
.number-selector .value{
font-size: 36rpx;
padding:0 28rpx;
}
.number-selector .button{
width:48rpx;height:48rpx;
line-height: 1;
padding:0;
text-align: center;
color: #fff;
position: relative;
background-color: var(--main-color);
border-radius: 50%;
border: 1rpx solid #FFC300;
}
.number-selector .button.disabled{
background-color: #fff;
}
.number-selector .reduce::before,
.number-selector .plus::before,
.number-selector .plus::after{
content: '';
width:50%;
height:4rpx;
background-color: #fff;
position:absolute;
left:25%;top:22rpx;
}
.number-selector .reduce.disabled::before,
.number-selector .plus.disabled::before,
.number-selector .plus.disabled::after{
background-color: var(--main-color);
}
.number-selector .plus::after{
width:4rpx;
height:50%;
left:22rpx;top:25%;
z-index: 100;
}
.cells .cell{ .cells .cell{
position: relative; position: relative;
padding:0 20rpx 0 30rpx;
} }
.cells .cell .cell-hd{ .cells .cell .cell-hd{
font-size: 34rpx; font-size: 34rpx;
@ -193,12 +110,14 @@
flex-direction: column; flex-direction: column;
align-items: flex-end; align-items: flex-end;
justify-content: center; justify-content: center;
gap: 26rpx; gap: 30rpx;
min-height: auto; min-height: auto;
padding:36rpx 40rpx 36rpx 0; padding:30rpx 40rpx 36rpx 0;
color: #555555;
} }
.cells .cell .cell-ft{ .cells .cell .cell-ft{
padding: 0; padding: 0;
color: #222222;
} }
.cells .cell .line1{ .cells .cell .line1{
font-size: 32rpx; font-size: 32rpx;
@ -267,4 +186,67 @@
} }
.deliver-type-content .button{ .deliver-type-content .button{
margin-top:40rpx; margin-top:40rpx;
}
.ai-img-area{
min-height: 280rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: relative;
box-sizing: border-box;
}
.ai-img-area::before{
content: '';
position: absolute;
left:10rpx;top:10rpx;right:10rpx;bottom:10rpx;
border: 2rpx dashed rgba(153, 153, 153, 0.3);
border-radius: 16rpx;
}
.ai-img-area.hover::before{
border-color: var(--main-color);
}
.ai-img-area .title{
font-size: 40rpx;
font-weight: 500;
color: #000;
display: flex;
align-items: center;
gap: 12rpx;
}
.ai-img-area .title .icon{
width:66rpx;height:66rpx;
}
.ai-img-area .sub-title{
margin-top:28rpx;
font-size: 25rpx;
color: #555555;
}
.ai-img-area .loading{
position: absolute;
width:100%;height:100%;
top:0;left:0;
background-color: #fff;
/* opacity: .7; */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 18rpx;
}
.ai-img-area .loading .weui-loading{
width:30px;height:30px;
}
.manually-code{
color: #888888;
display: flex;
align-items: center;
justify-content: center;
padding:36rpx;
}
.manually-code .icon{
width:28rpx;height:28rpx;
margin-right:12rpx;
} }