版本研发

This commit is contained in:
yangdanqi 2022-04-27 10:00:39 +08:00
parent a5aab460c6
commit b0a396f9bd
13 changed files with 1157 additions and 192 deletions

View File

@ -1179,14 +1179,32 @@ const myAddressList = [{
id: 1,
person2Contact: '卢翰',
phone: '18928799765',
area: ['广西壮族自治区', '梧桐洲', '藤县'],
area: [{
id: 1,
name: '广西壮族自治区'
}, {
id: 2,
name: '梧桐洲'
}, {
id: 3,
name: '藤县'
}],
address: '同心镇同心村同心路88号',
isDefault: true
}, {
id: 2,
person2Contact: '卢翰',
phone: '12434455432',
area: ['广西壮族自治区', '梧桐洲', '藤县'],
area: [{
id: 1,
name: '广西壮族自治区'
}, {
id: 2,
name: '梧桐洲'
}, {
id: 3,
name: '藤县'
}],
address: '同心镇同心村同心路88号',
isDefault: false
}]
@ -1255,7 +1273,7 @@ const myOperator = {
}]
}
const myOperaMembers = {
const myOperaMembers = {
totalMembers: 1,
members: [{
id: 1,
@ -1300,41 +1318,41 @@ const certificationInfo = {
idCardImgList: [],
licenseImgList: []
}
const servDetail = {
taskTraceLine: [{
time: '2022-01-09 16:45:28',
action: '上门'
}, {
time: '2022-01-07 16:45:28',
action: '预约时间'
}],
mainServOrder: {
servTitle: '清洗-空调',
orderTag: ['挂机', '到付试单', '到付款单'],
address: '北京市东城区东华街道0.1到付+0.1代收',
person2Contact: {
name: '杨先生',
phone: '12222233222'
},
bookTime: '2022-01-07 16:45:28',
boodTime: '2022-01-07 16:45:28',
doorTime: '2022-01-07 16:45:28',
taskPrice: '-5.91',
gratuityRecord: [{
type: '服务费',
price: '-3.00'
}, {
type: '加急费',
price: '-3.00'
}]
},
const servDetail = {
taskTraceLine: [{
time: '2022-01-09 16:45:28',
action: '上门'
}, {
time: '2022-01-07 16:45:28',
action: '预约时间'
}],
mainServOrder: {
servTitle: '清洗-空调',
orderTag: ['挂机', '到付试单', '到付款单'],
address: '北京市东城区东华街道0.1到付+0.1代收',
person2Contact: {
name: '杨先生',
phone: '12222233222'
},
bookTime: '2022-01-07 16:45:28',
boodTime: '2022-01-07 16:45:28',
doorTime: '2022-01-07 16:45:28',
taskPrice: '-5.91',
gratuityRecord: [{
type: '服务费',
price: '-3.00'
}, {
type: '加急费',
price: '-3.00'
}]
},
product: {
id: 1,
// indexPath: '0-0',
picUrl: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big20000.jpg',
name: '空调挂机柜机清洗服务',
comments: '高温清洗拆洗空调部分挂机柜机',
comments: '高温清洗拆洗空调部分挂机柜机',
pickedNum: 1,
salePrice: 199,
price: 250,
@ -1353,30 +1371,156 @@ const servDetail = {
pickedNum: 1,
toServNum: 1
}]
},
finishRecord: [{
finishTime: '2022-08-18 16:45:28',
finishList: [{
id: 101,
// indexPath: '0-0-0',
name: '直径5.5mm黑色5米价',
pickedNum: 1,
servedNum: 1
}]
}, {
finishTime: '2022-08-20 16:45:28',
finishList: [{
id: 102,
// indexPath: '0-0-1',
name: '直径6.5mm黑色5米价',
pickedNum: 1,
servedNum: 1
}]
}],
talkMsgNum: 1,
serialCode: '20211007859098945',
createTime: '2021-10-07 16:15:46'
}
},
finishRecord: [{
finishTime: '2022-08-18 16:45:28',
finishList: [{
id: 101,
// indexPath: '0-0-0',
name: '直径5.5mm黑色5米价',
pickedNum: 1,
servedNum: 1
}]
}, {
finishTime: '2022-08-20 16:45:28',
finishList: [{
id: 102,
// indexPath: '0-0-1',
name: '直径6.5mm黑色5米价',
pickedNum: 1,
servedNum: 1
}]
}],
talkMsgNum: 1,
serialCode: '20211007859098945',
createTime: '2021-10-07 16:15:46'
}
const servCategory = [{
id: 0,
name: '家具服务',
children: [{
id: 10,
name: '某家具服务1'
}, {
id: 11,
name: '某家具服务2'
}, {
id: 12,
name: '某家具服务3'
}]
}, {
id: 1,
name: '一级类目',
children: [{
id: 20,
name: '二级类目1'
}, {
id: 21,
name: '二级类目2'
}, {
id: 22,
name: '二级类目3'
}]
}]
const categoryList = [{
id: 1,
name: '家电清洗',
children: [{
pId: 1,
id: 2,
name: '空调',
children: [{
id: 3,
name: '单台清洗'
}, {
id: 4,
name: '套餐清洗'
}, {
id: 5,
name: '空调加氧'
}]
}, {
pId: 1,
id: 6,
name: '烟灶',
children: [{
id: 7,
name: '单台清洗'
}, {
id: 8,
name: '套餐清洗'
}]
}]
}, {
id: 9,
name: '衣物洗护',
children: [{
pId: 9,
id: 10,
name: '丝绸服装',
children: [{
id: 11,
name: '单件清洗'
}, {
id: 12,
name: '套餐清洗'
}]
}, {
pId: 9,
id: 14,
name: '呢绒服装',
children: [{
id: 15,
name: '单件清洗'
}]
}]
}, {
id: 16,
name: 'Tab3',
children: [{
id: 17,
name: 'Tab3-0',
children: [{
id: 18,
name: 'Tab3-0-0'
}, {
id: 19,
name: 'Tab3-0-1'
}]
}]
}, {
id: 20,
name: 'Tab4',
children: [{
id: 21,
name: 'Tab4-0',
children: [{
id: 22,
name: 'Tab4-0-0'
}, {
id: 23,
name: 'Tab4-0-1'
}]
}]
}]
const areaList = [[{
id: 100,
name: '广东'
}, {
id: 101,
name: '海南'
}], [{
id: 200,
name: '广州'
}], [{
id: 300,
name: '天河'
}]]
const defaultAddress = null;
export default {
swiperList,
@ -1397,7 +1541,11 @@ export default {
ordersFinish,
myAddressList,
myOperator,
certificationInfo,
myOperaMembers,
servDetail
certificationInfo,
myOperaMembers,
servDetail,
servCategory,
categoryList,
areaList,
defaultAddress
}

View File

@ -1,3 +1,6 @@
export default {
CONFIRM: 'confirmCallback'
CONFIRM: 'confirmCallback',
VERTICAL_NAV_GET_ITEM: 'verticalNavGetItem',
VERTICAL_NAV_SEARCH: 'verticalNavSearch',
CHOOSE_ADDRESS: 'chooseAddress'
}

View File

@ -0,0 +1,185 @@
<template>
<view>
<!-- 搜索栏 -->
<view class="cu-bar search bg-white">
<view class="search-form round">
<text class="cuIcon-search"></text>
<input @confirm="searchGoods" :adjust-position="true" type="text" placeholder="输入搜索内容"
confirm-type="search"></input>
</view>
</view>
<view class="VerticalBox" :style="'height:calc(' + containerHeight + ' - 100rpx)'">
<scroll-view class="VerticalNav nav" scroll-y scroll-with-animation :scroll-top="verticalNavTop">
<view class="cu-item" :class="item.id==tabCur?'text-main-color cur':''" v-for="(item,index) in list"
:key="index" @tap="tabSelect" :data-index="index" :data-id="item.id"
:data-main-cur="item.children && item.children.length > 0 ? item.children[0].id : -1">
{{item.name}}
</view>
</scroll-view>
<scroll-view class="VerticalMain" scroll-y scroll-with-animation :scroll-into-view="'main-'+mainCur"
@scroll="verticalMain">
<view class="padding-top padding-lr" v-for="(type, index1) in childrenList" :key="index1"
:id="'main-'+type.id">
<view class="cu-bar solid-bottom bg-white">
<view class="action">
<text class="cuIcon-title text-main-color"></text>{{type.name}}
</view>
</view>
<view class="cu-list menu">
<view class="cu-item" :class="curNavItem.id === subType.id ? 'bg-main-color light' : ''" v-for="(subType,index2) in type.children" :key="index2" @click="chooseNavItem(subType)">
<view class="content">
<text>{{subType.name}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
name: 'vertical-nav',
props: {
list: {
type: Array,
default: []
},
containerHeight: {
type: String,
default: '100vh'
}
},
data() {
return {
// list: [],
childrenList: [],
tabCur: 0,
mainCur: 0,
load: true,
verticalNavTop: 0,
curNavItem: {}
}
},
onReady() {
this.loadData();
},
// onLoad() {
// this.loadData();
// },
methods: {
async loadData() {
// this.list = await this.$api.data('categoryList');
this.tabCur = this.list[0].id;
for (let i = 0; i < this.list.length; i++) {
let children = this.list[i].children;
if (children && children.length > 0) {
for (let j = 0; j < children.length; j++) {
children[j].pIndex = i;
children[j].pId = this.list[i].id;
}
this.childrenList = this.childrenList.concat(children);
}
}
},
tabSelect(e) {
this.tabCur = e.currentTarget.dataset.id;
this.mainCur = e.currentTarget.dataset.mainCur;
this.verticalNavTop = (e.currentTarget.dataset.index - 1) * 50;
},
verticalMain(e) {
// #ifdef MP-ALIPAY
return false //
// #endif
let that = this;
let tabHeight = 0;
if (this.load) {
for (let i = 0; i < this.childrenList.length; i++) {
let view = uni.createSelectorQuery().select("#main-" + this.childrenList[i].id);
view.fields({
size: true
}, data => {
this.childrenList[i].top = tabHeight;
tabHeight = tabHeight + data.height;
this.childrenList[i].bottom = tabHeight;
}).exec();
}
this.load = false
}
let scrollTop = e.detail.scrollTop + 10;
for (let i = 0; i < this.childrenList.length; i++) {
if (scrollTop > this.childrenList[i].top && scrollTop < this.childrenList[i].bottom) {
this.verticalNavTop = (this.childrenList[i].pIndex - 1) * 50
this.tabCur = this.childrenList[i].pId;
console.log(scrollTop + ";tabCur=" + this.tabCur)
return false
}
}
},
chooseNavItem(curNavItem) {
this.curNavItem = curNavItem;
uni.$emit(this.$globalFun.VERTICAL_NAV_GET_ITEM, curNavItem);
},
searchGoods(e) {
uni.$emit(this.$globalFun.VERTICAL_NAV_SEARCH, e.detail.value);
}
}
}
</script>
<style scoped>
/* .fixed {
position: fixed;
z-index: 99;
} */
.VerticalNav.nav {
width: 200upx;
white-space: initial;
}
.VerticalNav.nav .cu-item {
width: 100%;
text-align: center;
background-color: #fff;
margin: 0;
border: none;
height: 50px;
position: relative;
}
.VerticalNav.nav .cu-item.cur {
background-color: #f1f1f1;
}
.VerticalNav.nav .cu-item.cur::after {
content: "";
width: 8upx;
height: 30upx;
border-radius: 10upx 0 0 10upx;
position: absolute;
background-color: currentColor;
top: 0;
right: 0upx;
bottom: 0;
margin: auto;
}
.VerticalBox {
display: flex;
}
.VerticalMain {
background-color: #f1f1f1;
flex: 1;
}
.cu-list>.cu-item {
transition: all 0.2s ease-in-out 0s;
-webkit-transform: translateX(0.5px);
transform: translateX(0rpx);
}
</style>

View File

@ -1,6 +1,7 @@
{
"pages": [{
"path": "pages/index/index"
"path": "pages/index/index"
// "path": "components/multi-level-nav/vertical-nav"
}],
"subPackages": [{
"root": "pages/order/",
@ -39,6 +40,11 @@
}, {
"path": "serv-detail"
}]
}, {
"root":"pages/publish/",
"pages": [{
"path": "publish-task"
}]
}],
// "pages": [{
// "path": "pages/my/serv-detail"

View File

@ -12,7 +12,7 @@
<view class="cu-avatar round middle-avatar first-avatar">
<view class="cuIcon-formfill"></view>
</view>
<view class="flex flex-column-around text-left margin-left-sm text-white">
<view class="flex flex-column-around text-left margin-left-sm text-white" @click="showPage('/pages/publish/publish-task')">
<view class="text-xl">发布任务</view>
<view>公司家居家政雇佣上门服务</view>
</view>
@ -62,7 +62,7 @@
import index from '@/pages/index/home.vue';
import workerCircle from '@/pages/index/worker-home.vue';
import personalCenter from '@/pages/index/my-home.vue';
import publishHome from '@/pages/index/publish-home.vue';
// import publishHome from '@/pages/index/publish-home.vue';
export default {
components: {
@ -70,7 +70,7 @@
index,
workerCircle,
personalCenter,
publishHome
// publishHome
},
data() {
return {
@ -105,6 +105,12 @@
},
hidePublish() {
this.isShowPublish = false;
},
showPage(url) {
console.log(url)
uni.navigateTo({
url: url
})
}
}
}

View File

@ -18,11 +18,11 @@
</view>
<!-- #ifndef H5 || APP-PLUS || MP-ALIPAY -->
<view class="cu-form-group">
<view class="title">地址选择</view>
<picker mode="region" @change="regionChange" name="area" :value="formData.area">
<view class="picker">
{{formData.area[0]}}{{formData.area[1]}}{{formData.area[2]}}
</view>
<view class="title">地址选择</view>
<picker :mode="'multiSelector'" @change="regionChange" :value="multiIndex" :range-key="'name'" :range="areaList">
<view class="picker">
{{areaList[0][multiIndex[0]].name}}{{areaList[1][multiIndex[1]].name}}{{areaList[2][multiIndex[2]].name}}
</view>
</picker>
</view>
<!-- #endif -->
@ -30,7 +30,7 @@
<view class="title">详细地址</view>
<input name="address" :value="formData.address"></input>
</view>
<view class="cu-form-group margin-top">
<view class="cu-form-group margin-top margin-bottom-with-bar">
<view class="title">默认地址</view>
<switch class="main-color radius" @change="isDefaultChange" :class="formData.isDefault?'checked':''"
:checked="formData.isDefault?true:false" name="isDefault" :value="formData.isDefault"></switch>
@ -47,38 +47,59 @@
<script>
export default {
data() {
return {
return {
areaList: [],
multiIndex: [0, 0, 0],
formData: {
id: 1,
person2Contact: '卢翰',
phone: '18928799765',
area: ['广西壮族自治区', '梧桐洲', '藤县'],
address: '同心镇同心村同心路88号',
isDefault: true
}
}
},
onLoad(options) {
onLoad(options) {
this.loadData();
const addressInfo = JSON.parse(decodeURIComponent(options.addressInfo));
this.fillForm(addressInfo);
},
methods: {
fillForm(addressInfo) {
this.formData = addressInfo ? addressInfo : this.formData;
methods: {
async loadData() {
this.areaList = await this.$api.data('areaList');
},
regionChange(e) {
this.formData.area = e.detail.value;
fillForm(addressInfo) {
this.formData = addressInfo && Object.keys(addressInfo).length > 0 ? addressInfo : this.formData;
},
regionChange(e) {
this.multiIndex = e.detail.value;
let chosenArea = [];
for(let i = 0; i < this.areaList.length; i++) {
chosenArea.push(this.areaList[i][this.multiIndex[i]]);
}
this.formData.area = chosenArea;
},
isDefaultChange(e) {
this.formData.isDefault = e.detail.value;
},
validateForm(confirmFormData) {
return Boolean(confirmFormData.person2Contact) &&
Boolean(confirmFormData.phone) &&
Boolean(confirmFormData.address);
validateForm(addressInfo) {
let valid = Boolean(addressInfo.person2Contact) &&
Boolean(addressInfo.phone) &&
Boolean(addressInfo.address);
if (!valid) {
uni.showToast({
title: '请填写完整信息',
icon: 'none',
mask: true
})
} else if (!this.$validate.validContactNum(addressInfo.phone)) {
valid = false;
uni.showToast({
title: '联系号码格式错误',
icon: 'none',
mask: true
})
}
return valid;
},
submit(e) {
const confirmFormData = e.detail.value;
const confirmFormData = Object.assign({}, this.formData, e.detail.value)
let formValid = this.validateForm(confirmFormData);
if (formValid) {
uni.showToast({
@ -86,12 +107,6 @@
icon: 'success',
mask: true
})
} else {
uni.showToast({
title: '请填写完整信息',
icon: 'none',
mask: true
})
}
}
}

View File

@ -8,10 +8,11 @@
<!-- 地址列表 -->
<view class="margin-bottom-lg">
<view class="padding margin-lr-sm margin-top-sm bg-white flex justify-between align-center" v-for="(item, index) in myAddressList">
<view>
<view @click="chooseAddress(item)">
<view class="flex justify-start align-center">
<view class='cu-tag bg-yellow margin-right-sm' v-if="item.isDefault">默认</view>
<view class="text-gray">{{item.area}}</view>
<view class="text-gray margin-right-xs" v-for="(areaObj, index) in item.area">
{{areaObj.name}}</view>
</view>
<view class="text-lg margin-tb-sm">{{item.address}}</view>
<view class="text-gray">
@ -49,10 +50,14 @@
myAddressList: [],
modalName: '',
delAddressInfo: {},
delAddressIndex: 0
delAddressIndex: 0,
chooseMode: false
}
},
onLoad() {
onLoad(options) {
if (Boolean(options)) {
this.chooseMode = options.chooseMode === 'true' ? true : false;
}
this.loadData();
this.bindEvent();
},
@ -67,7 +72,7 @@
uni.$on(this.$globalFun.CONFIRM, this.delAddress);
},
offBindEvent() {
uni.$off(this.globalFun.CONFIRM);
uni.$off(this.$globalFun.CONFIRM);
},
showAddressDetail(addressInfo) {
uni.navigateTo({
@ -88,6 +93,14 @@
hideModal(e) {
this.modalName = null
},
chooseAddress(addressInfo) {
if (this.chooseMode) {
uni.$emit(this.$globalFun.CHOOSE_ADDRESS, addressInfo);
uni.navigateBack({
delta: -1
})
}
}
}
}
</script>

View File

@ -41,7 +41,7 @@
</view>
</view>
<!-- 团队订单统计 -->
<view class="margin-lr-sm margin-top-sm padding bg-white">
<view class="margin-lr-sm margin-top-sm padding bg-white margin-bottom-with-bar">
<view class="cu-list grid no-border col-4">
<view class="cu-item" v-for="(item, index) in myOperator.orderAnalyse">
<view class="margin-bottom-xs">{{item.title}}</view>

View File

@ -6,38 +6,68 @@
<block slot="content">订单确认</block>
</cu-custom>
<!-- 服务地址 -->
<view class="padding-lg bg-white">
<view class="flex justify-between align-center">
<view v-if="defaultAddress" class="bg-white">
<view class="padding flex justify-between align-center" @click="showAddress2Choose">
<view>
<view class="flex justify-start align-center">
<view class="text-gray margin-right-xs" v-for="(areaObj, index) in defaultAddress.area">
{{areaObj.name}}
</view>
</view>
<view class="text-lg margin-tb-sm">{{defaultAddress.address}}</view>
<view class="text-gray">
<text class="margin-right">{{defaultAddress.person2Contact}}</text>
<text>{{defaultAddress.phone}}</text>
</view>
</view>
<view class="text-lg"><text class="text-bold text-gray cuIcon-right"></text></view>
</view>
<view class="cu-progress sm striped">
<view class="bg-orange" style="width: 100%;"></view>
</view>
</view>
<view v-else class="bg-white" @click="showAddress2Choose">
<view class="flex justify-between align-center padding-lg">
<view class="text-lg text-black">
<text class="cuIcon-locationfill text-blue light"></text>
选择服务地址
</view>
<view>选择<text class="text-sm text-bold text-gray cuIcon-right"></text></view>
</view>
<view class="cu-progress sm striped">
<view class="bg-orange" style="width: 100%;"></view>
</view>
</view>
<!-- 预约时间 -->
<view class="margin-lr-sm margin-top-sm bg-white padding">
<view class="flex justify-between align-center">
<text class="text-black">预约时间</text>
<view class="text-red text-sm">请选择上门时间<text class="text-bold cuIcon-right"></text></view>
<uni-datetime-picker v-model="doorTime" @change="changeDoorTime">
<view v-if="doorTime" class="text-sm">{{doorTime}}<text class="text-bold cuIcon-right"></text>
</view>
<view v-else class="text-red text-sm">请选择上门时间<text class="text-bold cuIcon-right"></text></view>
</uni-datetime-picker>
</view>
<view class="text-sm text-gray margin-top-sm"><text
class="cuIcon-question">选择的为期望上门时间稍后工程师将与你确认具体上门时间</text></view>
</view>
<!-- 选购的商品列表 -->
<view class="margin-lr-sm margin-top-sm bg-white">
<view class="solid-top" v-for="(item, index0) in pickedProductList">
<view class="cu-bar">
<view class="action bar-first-action">
<text class="cuIcon-shopfill text-main-color"></text>
{{item.shopName}}
<view><view class="cuIcon-right"></view></view>
</view>
</view>
<view class="margin-top-sm padding-lr">
<product-picked :columnTitleArr="columnTitleArr" v-for="(product, index1) in item.product" :product="product" :pickedList="product.pickedList">
</product-picked>
</view>
<view class="margin-lr-sm margin-top-sm bg-white">
<view class="solid-top" v-for="(item, index0) in pickedProductList">
<view class="cu-bar">
<view class="action bar-first-action">
<text class="cuIcon-shopfill text-main-color"></text>
{{item.shopName}}
<view>
<view class="cuIcon-right"></view>
</view>
</view>
</view>
<view class="margin-top-sm padding-lr">
<product-picked :columnTitleArr="columnTitleArr" v-for="(product, index1) in item.product"
:product="product" :pickedList="product.pickedList">
</product-picked>
</view>
</view>
<!-- <view class="solid-bottom" v-for="(item, index) in pickedProductList">
<product-picked :columnTitleArr="columnTitleArr" :product="item.product" :pickedList="item.pickedList">
@ -50,42 +80,42 @@
<text class="text-black">支付方式</text>
<radio-group @change="changePayWay">
<label class="radio">
<radio class="main-color" value="online" :checked="payWay=='online'" />
<radio class="main-color" value="online" :checked="payWay=='online'" />
<text class="margin-left-xs">在线支付</text>
</label>
<label class="radio margin-left">
<radio class="main-color" value="offline" :checked="payWay=='offline'" />
<radio class="main-color" value="offline" :checked="payWay=='offline'" />
<text class="margin-left-xs">上门到付</text>
</label>
</radio-group>
</view>
</view>
<!-- 发票信息 -->
<view class="margin-lr-sm margin-top-sm bg-white padding">
<view class="flex justify-between align-center">
<text class="text-black">发票信息</text>
<text class="text-sm text-bold cuIcon-right"></text>
</view>
</view>
<!-- 备注留言 -->
<view class="margin-lr-sm margin-top-sm bg-white padding">
<text class="text-black">备注留言</text>
<view class="margin-top uni-textarea">
<textarea class="solid" maxlength="-1" @input="inputComments" placeholder="请填写备注" />
</view>
</view>
<!-- 平台提醒 -->
<view class="margin-lr-sm margin-top-sm bg-white padding margin-bottom-with-bar">
<view class="text-sm text-orange"><text
class="cuIcon-roundcheck">为保障您的权益请在平台内交易师傅服务离开后发生损坏或退款以及售后质保平台可为您追责</text></view>
</view>
<!-- 底部操作栏 -->
<view class="cu-bar bg-white tabbar border shop fixed-bottom-bar">
<view class="action text-df left-grid">
<text class="margin-left-lg">共计</text>
<text class="margin-left-xs text-red text-price text-xl">{{formInfo.totalPrice}}</text>
</view>
<view class="bg-main-color submit">确定</view>
</view>
<!-- 发票信息 -->
<view class="margin-lr-sm margin-top-sm bg-white padding">
<view class="flex justify-between align-center">
<text class="text-black">发票信息</text>
<text class="text-sm text-bold cuIcon-right"></text>
</view>
</view>
<!-- 备注留言 -->
<view class="margin-lr-sm margin-top-sm bg-white padding">
<text class="text-black">备注留言</text>
<view class="margin-top uni-textarea">
<textarea class="solid" maxlength="-1" @input="inputComments" placeholder="请填写备注" />
</view>
</view>
<!-- 平台提醒 -->
<view class="margin-lr-sm margin-top-sm bg-white padding margin-bottom-with-bar">
<view class="text-sm text-orange"><text
class="cuIcon-roundcheck">为保障您的权益请在平台内交易师傅服务离开后发生损坏或退款以及售后质保平台可为您追责</text></view>
</view>
<!-- 底部操作栏 -->
<view class="cu-bar bg-white tabbar border shop fixed-bottom-bar">
<view class="action text-df left-grid">
<text class="margin-left-lg">共计</text>
<text class="margin-left-xs text-red text-price text-xl">{{formInfo.totalPrice}}</text>
</view>
<view class="bg-main-color submit">确定</view>
</view>
</view>
</template>
@ -102,42 +132,74 @@
columnTitleArr: ['购买型号', '购买数量'],
pickedProductList: [],
formInfo: {
payWay: 'online',
comments: '',
payWay: 'online',
comments: '',
totalPrice: 0
}
},
defaultAddress: null,
doorTime: null
}
},
onLoad() {
this.loadData();
this.bindEvent();
},
onUnload() {
this.offBindEvent();
},
methods: {
async loadData() {
this.pickedProductList = await this.$api.data('pickedProductList');
this.defaultAddress = await this.$api.data('defaultAddress');
},
bindEvent() {
uni.$on(this.$globalFun.CHOOSE_ADDRESS, this.chooseAddress);
},
offBindEvent() {
uni.$off(this.$globalFun.CHOOSE_ADDRESS);
},
changePayWay(e) {
this.formInfo.payWay = e.detail.value;
},
inputComments(e) {
this.comments = e.detail.value
},
inputComments(e) {
this.comments = e.detail.value
},
showAddress2Choose() {
uni.navigateTo({
url: '/pages/my/my-address?chooseMode=true'
})
},
chooseAddress(addressInfo) {
this.defaultAddress = addressInfo;
},
changeDoorTime(value) {
this.doorTime = value;
}
},
}
</script>
<style scoped>
.fixed-bottom-bar .text-df {
font-size: 28rpx !important;
}
.fixed-bottom-bar .left-grid {
width: 55% !important;
text-align: left;
}
.bar-first-action {
margin-left: unset !important;
padding-left: 40rpx;
font-size: 30rpx !important;
<style scoped>
.fixed-bottom-bar .text-df {
font-size: 28rpx !important;
}
.fixed-bottom-bar .left-grid {
width: 55% !important;
text-align: left;
}
.bar-first-action {
margin-left: unset !important;
padding-left: 40rpx;
font-size: 30rpx !important;
}
.cu-progress {
display: inherit;
}
.cu-progress.sm {
height: 12rpx;
}
</style>

View File

@ -119,6 +119,7 @@
.certern-height-with-scroll {
height: 600rpx;
margin-bottom: calc(100rpx - constant(safe-area-inset-bottom)/2);
margin-bottom: calc(100rpx - env(safe-area-inset-bottom)/2);
}

View File

@ -0,0 +1,509 @@
<template>
<view>
<!-- 顶部操作条 -->
<cu-custom :bgColor="'bg-main-color'" :isBack="true">
<block slot="backText">返回</block>
<block slot="content">发布任务</block>
</cu-custom>
<!-- 步骤条 -->
<view class="bg-white padding">
<view class="cu-steps">
<view class="cu-item" :class="index>curStep?'':'text-main-color'" v-for="(stepName, index) in stepList">
<text class='cuIcon-radioboxfill'></text> {{stepName}}
</view>
</view>
</view>
<!-- 商品信息-->
<view v-if="curStep === 0">
<view class="bg-white margin-top-sm">
<form @submit="submitServInfo">
<view class="cu-form-group">
<view class="title"><text class="text-red">*</text>发布类目</view>
<input :value="formData.category.name" disabled></input>
<button class='cu-btn bg-main-color light shadow' @tap="showModal"
data-target="categoryModal">选择</button>
</view>
<view class="cu-form-group">
<view class="title"><text class="text-red">*</text>发布规格</view>
<input name="spec" type="text" placeholder="请输入规格,如200*300cm" :value="formData.spec"></input>
</view>
<view class="cu-form-group">
<view class="title"><text class="text-red">*</text>发布数量</view>
<uni-number-box :min="0" :value="formData.publishNum" @change="changePublishNum">
</uni-number-box>
</view>
<view class="cu-form-group">
<view class="title"><text class="text-red">*</text>期望价格</view>
<input name="expectPrice" type="digit" placeholder="请输入期望价格"
:value="formData.expectPrice"></input>
<text>参考价<text class="padding-left-xs text-price">100</text></text>
</view>
<view class="cu-form-group">
<view class="title"><text class="text-red">*</text>上门时间</view>
<uni-datetime-picker type="datetime" v-model="formData.doorTime" @change="changeDoorTime"
:clear-icon="false" />
</view>
<view class="cu-bar bg-white">
<view class="action">
上传图片
</view>
</view>
<view class="cu-form-group">
<view class="grid col-4 grid-square flex-sub img-grid">
<view class="bg-img" v-for="(item,index) in formData.imgList" :key="index"
@tap="viewImage($event, formData.imgList)" :data-url="item">
<image :src="item" mode="aspectFill"></image>
<view class="cu-tag bg-red" @tap.stop="delImg($event, formData.imgList)"
:data-index="index">
<text class='cuIcon-close'></text>
</view>
</view>
<view class="solids" @tap="chooseImage" v-if="formData.imgList.length<4">
<text class='cuIcon-cameraadd'></text>
</view>
</view>
</view>
<view class="cu-bar bg-white">
<view class="action">
备注说明
</view>
</view>
<view class="cu-form-group margin-bottom-with-bar">
<textarea class="solid radius" maxlength="-1" name="comments" :value="formData.comments"
placeholder="请输入商品的特殊要求或对师傅服务过程中的要求"></textarea>
</view>
<!-- 下一步 -->
<view class="cu-bar tabbar border shop fixed-bottom-bar">
<button class="bg-main-color long-btn margin-lr" form-type="submit">下一步</button>
</view>
</form>
</view>
</view>
<!-- 类目抽屉 -->
<view class="DrawerClose" :class="modalName=='categoryModal'?'show':''" @tap="hideModal">
<view class="cuIcon-roundcheckfill text-main-color" @click="chooseCategory"></view>
<view class="cuIcon-roundclosefill"></view>
</view>
<scroll-view scroll-y class="DrawerWindow bg-gray" :class="modalName=='categoryModal'?'show':''">
<vertical-nav :list="categoryList" :containerHeight="'calc(100vh - 200rpx)'"></vertical-nav>
</scroll-view>
<view v-if="curStep === 1">
<view class="margin-top-sm bg-white">
<view v-if="defaultAddress">
<view class="padding margin-lr-sm flex justify-between align-center" @click="showAddress2Choose">
<view>
<view class="flex justify-start align-center">
<view class="text-gray margin-right-xs" v-for="(areaObj, index) in defaultAddress.area">
{{areaObj.name}}
</view>
</view>
<view class="text-lg margin-tb-sm">{{defaultAddress.address}}</view>
<view class="text-gray">
<text class="margin-right">{{defaultAddress.person2Contact}}</text>
<text>{{defaultAddress.phone}}</text>
</view>
</view>
<view class="text-lg"><text class="text-bold text-gray cuIcon-right"></text></view>
</view>
<view class="cu-progress sm striped">
<view class="bg-orange" style="width: 100%;"></view>
</view>
</view>
<view v-else @click="showAddress2Choose">
<view class="flex justify-between align-center padding-lg">
<view class="text-lg text-black">
<text class="cuIcon-locationfill text-blue light"></text>
选择服务地址
</view>
<view class="text-lg">选择<text class="text-bold text-gray cuIcon-right"></text></view>
</view>
<view class="cu-progress sm striped">
<view class="bg-orange" style="width: 100%;"></view>
</view>
</view>
</view>
<view class="bg-white margin-top-sm margin-lr-sm margin-bottom-with-bar">
<form @submit="saveAndUseAddress">
<view class="cu-form-group">
<view class="title">联系人</view>
<input name="person2Contact" placeholder="请输入姓名"></input>
</view>
<view class="cu-form-group">
<view class="title">联系号码</view>
<input name="phone" placeholder="请输入联系号码"></input>
</view>
<view class="cu-form-group">
<view class="title">地址选择</view>
<picker :mode="'multiSelector'" @change="regionChange" @columnchange="regionColumnChange"
:value="multiIndex" :range-key="'name'" :range="areaList">
<view class="picker">
{{areaList[0][multiIndex[0]].name}}{{areaList[1][multiIndex[1]].name}}{{areaList[2][multiIndex[2]].name}}
</view>
</picker>
</view>
<view class="cu-form-group">
<view class="title">详细地址</view>
<input name="address" placeholder="请输入小区/写字楼"></input>
</view>
<view class="padding-tb">
<button class="bg-main-color margin-lr-sm" form-type="submit">保存地址</button>
</view>
<!-- <view class="cu-form-group margin-top">
<view class="title">默认地址</view>
<switch class="main-color radius" @change="isDefaultChange" :class="formData.isDefault?'checked':''"
:checked="formData.isDefault?true:false" name="isDefault" :value="formData.isDefault"></switch>
</view> -->
</form>
</view>
<!-- 底部操作栏 -->
<view class="cu-bar tabbar border shop fixed-bottom-bar">
<button class="bg-white long-btn margin-lr" @click="preStep">上一步</button>
<button class="bg-main-color long-btn margin-lr" @click="submitPublishOrder">提交订单</button>
</view>
</view>
<view v-if="curStep === 2">
<view class="bg-white margin-top-sm margin-bottom-with-bar">
<view class="padding-lg text-center">
<view class="text-price text-sl text-bold">{{formData.expectPrice}}</view>
<view class="text-gray">
{{formData.category.name}}/规格{{formData.spec}}({{formData.publishNum}})
</view>
</view>
<view class="margin-top-lg">
<radio-group @change="changePayWay" style="width: 100vw;">
<view class="cu-list menu">
<view class="cu-item text-lg flex justify-between">
<view class="cuIcon-moneybag padding-left text-main-color"><text
class="padding-left-sm text-black">在线支付</text></view>
<radio class="main-color" value="online" />
</view>
<view class="cu-item text-lg">
<view class="cuIcon-repair padding-left text-main-color"><text
class="padding-left-sm text-black">上门到付</text></view>
<radio class="main-color" value="offline" />
</view>
</view>
</radio-group>
</view>
</view>
<!-- 底部操作栏 -->
<view class="cu-bar tabbar border shop fixed-bottom-bar">
<button class="bg-white long-btn margin-lr" @click="preStep">上一步</button>
<button class="bg-main-color long-btn margin-lr" @click="nextStep">确认支付</button>
</view>
</view>
</view>
</template>
<script>
import verticalNav from '@/components/multi-level-nav/vertical-nav.vue';
export default {
components: {
verticalNav
},
data() {
return {
curStep: 0,
stepList: ['商品信息', '客户信息', '支付订单'],
modalName: null,
categoryList: [],
tmpCategory: {},
formData: {
imgList: [],
category: {}
},
defaultAddress: null,
areaList: [],
multiIndex: [0, 0, 0]
}
},
onLoad() {
this.loadData();
this.bindEvent();
},
onUnload() {
this.offBindEvent();
},
methods: {
async loadData() {
this.categoryList = await this.$api.data('categoryList');
this.areaList = await this.$api.data('areaList');
this.defaultAddress = await this.$api.data('defaultAddress');
},
nextStep() {
this.curStep = this.curStep === this.stepList.length - 1 ? this.curStep : ++this.curStep
},
preStep() {
this.curStep = this.curStep === 0 ? 0 : --this.curStep
},
showModal(e) {
this.modalName = e.currentTarget.dataset.target;
},
hideModal(e) {
this.modalName = null
},
bindEvent() {
uni.$on(this.$globalFun.VERTICAL_NAV_GET_ITEM, this.tmpChooseCategory);
uni.$on(this.$globalFun.VERTICAL_NAV_SEARCH, this.searchCategory);
uni.$on(this.$globalFun.CHOOSE_ADDRESS, this.chooseAddress);
},
offBindEvent() {
uni.$off(this.$globalFun.VERTICAL_NAV_GET_ITEM);
uni.$off(this.$globalFun.VERTICAL_NAV_SEARCH);
uni.$off(this.$globalFun.CHOOSE_ADDRESS);
},
tmpChooseCategory(category) {
this.tmpCategory = category;
console.log("tmpCategory=" + JSON.stringify(category))
},
searchCategory(content) {
console.log("搜索[" + content + "]中......")
},
chooseCategory() {
this.formData.category = this.tmpCategory;
},
changePublishNum(value) {
this.formData.publishNum = value;
},
changeDoorTime(value) {
this.formData.doorTime = value;
},
viewImage(e, imgList) {
uni.previewImage({
urls: imgList,
current: e.currentTarget.dataset.url
});
},
delImg(e, imgList) {
uni.showModal({
title: '',
content: '确定要删除这张图片吗?',
cancelText: '取消',
confirmText: '确定',
success: res => {
if (res.confirm) {
imgList.splice(e.currentTarget.dataset.index, 1)
}
}
})
},
chooseImage(e) {
uni.chooseImage({
count: 4, //9
sizeType: ['original', 'compressed'], //
sourceType: ['album'], //
success: (res) => {
if (this.formData.imgList.length != 0) {
this.formData.imgList = this.formData.imgList.concat(res.tempFilePaths)
} else {
this.formData.imgList = res.tempFilePaths
}
}
});
},
regionChange(e) {
this.multiIndex = e.detail.value;
},
showAddress2Choose() {
uni.navigateTo({
url: '/pages/my/my-address?chooseMode=true'
})
},
chooseAddress(addressInfo) {
this.defaultAddress = addressInfo;
},
saveAndUseAddress(e) {
let addressInfo = e.detail.value;
let valid = this.validateAddress(addressInfo);
if (!valid) {
return;
}
let chosenArea = [];
for (let i = 0; i < this.areaList.length; i++) {
chosenArea.push(this.areaList[i][this.multiIndex[i]]);
}
console.log("chosenArea=" + JSON.stringify(chosenArea))
addressInfo.area = chosenArea;
//
this.defaultAddress = addressInfo;
},
submitServInfo(e) {
let formData = e.detail.value;
this.formData = Object.assign({}, this.formData, formData);
console.log(this.formData)
let valid = this.validateServInfo();
if (valid) {
this.nextStep();
} else {
uni.showToast({
title: '请填写必填项信息',
icon: 'none',
mask: true
})
}
},
submitPublishOrder() {
if (this.defaultAddress && Object.keys(this.defaultAddress).length > 0) {
this.nextStep();
} else {
uni.showToast({
title: '请选择服务地址',
icon: 'none',
mask: true
})
}
},
validateServInfo() {
if ((this.formData.category && Object.keys(this.formData.category).length > 0) &&
Boolean(this.formData.spec) &&
Boolean(this.formData.publishNum) &&
Boolean(this.formData.expectPrice) &&
Boolean(this.formData.doorTime)) {
return true
}
return false;
},
validateAddress(addressInfo) {
let valid = Boolean(addressInfo.person2Contact) &&
Boolean(addressInfo.phone) &&
Boolean(addressInfo.address);
if (!valid) {
uni.showToast({
title: '请填写完整信息',
icon: 'none',
mask: true
})
} else if (!this.$validate.validContactNum(addressInfo.phone)) {
valid = false;
uni.showToast({
title: '联系号码格式错误',
icon: 'none',
mask: true
})
}
return valid;
}
}
}
</script>
<style scoped>
.DrawerPage {
position: fixed;
width: 100vw;
height: 100vh;
left: 0vw;
background-color: #f1f1f1;
transition: all 0.4s;
}
.DrawerPage.show {
transform: scale(0.9, 0.9);
left: 85vw;
box-shadow: 0 0 60upx rgba(0, 0, 0, 0.2);
transform-origin: 0;
}
.DrawerWindow {
z-index: 9999;
position: absolute;
width: 85vw;
height: 100vh;
left: 0;
top: 0;
transform: scale(0.9, 0.9) translateX(-100%);
opacity: 0;
pointer-events: none;
transition: all 0.4s;
padding: 100upx 0;
}
.DrawerWindow.show {
transform: scale(1, 1) translateX(0%);
opacity: 1;
pointer-events: all;
}
.DrawerClose {
position: absolute;
width: 40vw;
height: 100vh;
right: 0;
top: 0;
color: transparent;
padding-bottom: 30upx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
background-image: linear-gradient(90deg, rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 0.6));
letter-spacing: 5px;
font-size: 60upx;
opacity: 0;
pointer-events: none;
transition: all 0.4s;
z-index: 9999;
}
.DrawerClose.show {
opacity: 1;
pointer-events: all;
width: 15vw;
color: #fff;
}
/* .DrawerPage .cu-bar.tabbar .action button.cuIcon {
width: 64upx;
height: 64upx;
line-height: 64upx;
margin: 0;
display: inline-block;
}
.DrawerPage .cu-bar.tabbar .action .cu-avatar {
margin: 0;
}
.DrawerPage .nav {
flex: 1;
}
.DrawerPage .nav .cu-item.cur {
border-bottom: 0;
position: relative;
}
.DrawerPage .nav .cu-item.cur::after {
content: "";
width: 10upx;
height: 10upx;
background-color: currentColor;
position: absolute;
bottom: 10upx;
border-radius: 10upx;
left: 0;
right: 0;
margin: auto;
}
.DrawerPage .cu-bar.tabbar .action {
flex: initial;
} */
.cu-form-group.img-grid {
border: none;
}
.cu-progress {
display: inherit;
}
.cu-progress.sm {
height: 12rpx;
}
</style>

View File

@ -1,8 +1,8 @@
.line-default {
color: #aaaaaa;
}
.line-main-color,
.line-default {
color: #aaaaaa;
}
.line-main-color,
.text-main-color {
color: #0081ff;
}
@ -20,20 +20,25 @@
.bg-gradual-color {
background-image: linear-gradient(45deg, #0081ff, #1cbbb4);
color: #ffffff;
}
switch.main-color[checked] .wx-switch-input,
checkbox.main-color[checked] .wx-checkbox-input,
radio.main-color[checked] .wx-radio-input,
switch.main-color.checked .uni-switch-input,
checkbox.main-color.checked .uni-checkbox-input,
radio.main-color.checked .uni-radio-input {
background-color: #0081ff !important;
border-color: #0081ff !important;
color: #ffffff !important;
}
.oper-bar button:last-child {
background-color: #0081ff;
color: #ffffff;
}
.cu-list.menu>.cu-item.bg-main-color.light {
color: #0081ff;
background-color: #cce6ff;
}
switch.main-color[checked] .wx-switch-input,
checkbox.main-color[checked] .wx-checkbox-input,
radio.main-color[checked] .wx-radio-input,
switch.main-color.checked .uni-switch-input,
checkbox.main-color.checked .uni-checkbox-input,
radio.main-color.checked .uni-radio-input {
background-color: #0081ff !important;
border-color: #0081ff !important;
color: #ffffff !important;
}
.oper-bar button:last-child {
background-color: #0081ff;
color: #ffffff;
}

View File

@ -1,5 +1,6 @@
.margin-bottom-with-bar {
margin-bottom: calc(120rpx + env(safe-area-inset-bottom) / 2)
.margin-bottom-with-bar {
margin-bottom: calc(120rpx + constant(safe-area-inset-bottom) / 2);
margin-bottom: calc(120rpx + env(safe-area-inset-bottom) / 2);
}
.fixed-bottom-bar {
@ -7,7 +8,9 @@
width: 100% !important;
bottom: 0 !important;
margin-bottom: 0 !important;
z-index: 98;
z-index: 98;
padding-bottom: constant(safe-area-inset-bottom / 2) !important; /*兼容 IOS<11.2*/
padding-bottom: env(safe-area-inset-bottom / 2) !important; /*兼容 IOS>11.2*/
}
.cu-bar.tabbar.border .action checkbox {
@ -47,7 +50,7 @@
}
.cu-form-group .title {
flex-basis: 23%;
flex-basis: 24%;
text-align: justify;
padding-right: 30rpx;
font-size: 30rpx;
@ -72,7 +75,7 @@
font-size: 28rpx;
color: #555;
padding-right: 20rpx;
}
}
.uni-forms-item__inner {
display: flex !important;
@ -82,4 +85,13 @@
.is-input-border {
border: none !important;
}
.dialog-close {
display: none !important;
}
.cu-form-group textarea {
margin: 0 0 20rpx 0 !important;
padding: 20rpx !important;
}