完成接单部分功能

This commit is contained in:
TOP糯米 2023-03-14 01:12:30 +08:00
parent c67f1e7216
commit b4ad20eac3
11 changed files with 658 additions and 128 deletions

View File

@ -1,11 +1,15 @@
<template> <template>
<view class="component-get-action"> <view class="component-get-action">
<view class="btn active" @click.stop="getOrder" v-if="order.orderType == models.order.type.NORMAL"> <block v-if="order.listType == 't1' || order.listType == 't3' || (order.listType == 't2' && order.orderType == 1)">
<text>立即抢单</text> <view class="btn active" @click.stop="getOrder">
</view> <text>立即抢单</text>
<view class="btn active" @click.stop="postPrice" v-if="order.orderType == models.order.type.WORKER_PRICE"> </view>
<text>立即报价</text> </block>
</view> <block v-if="order.listType == 't2' && order.orderType == 2">
<view class="btn active" @click.stop="postPrice">
<text>立即报价</text>
</view>
</block>
</view> </view>
</template> </template>
@ -35,7 +39,7 @@ export default {
destroyed() {}, destroyed() {},
methods: { methods: {
getOrder() { getOrder() {
console.log("获取" + this.order.id); this.$emit("getOrder");
}, },
postPrice() { postPrice() {
this.$emit("postPrice"); this.$emit("postPrice");

View File

@ -14,7 +14,7 @@
<text class="text">1)哈哈哈哈</text> <text class="text">1)哈哈哈哈</text>
<text class="text">2)哈哈哈哈哈哈哈哈</text> <text class="text">2)哈哈哈哈哈哈哈哈</text>
</view> </view>
<view class="btn" @click="confirmPrice">确认</view> <view class="btn" @click="postPrice">确认</view>
</view> </view>
</widget-modal> </widget-modal>
</view> </view>
@ -42,16 +42,20 @@ export default {
created() {}, created() {},
mounted() {}, mounted() {},
destroyed() {}, destroyed() {},
watch: {}, watch: {
postId() {
this.price = 0;
},
},
methods: { methods: {
closeModal() { closeModal() {
this.$store.commit("order/setConfirmId", 0);
this.price = 0;
this.$emit("close"); this.$emit("close");
}, },
confirmPrice() { postPrice() {
console.log("当前id" + this.postId + ",价格:" + this.price); this.$emit("post", {
this.$emit("confirm"); id: this.postId,
price: this.price,
});
}, },
}, },
}; };

View File

@ -2,8 +2,8 @@
<view class="component-order-item"> <view class="component-order-item">
<view class="order-head"> <view class="order-head">
<view class="order-title"> <view class="order-title">
<text class="type" :style="{ backgroundColor: models.order.getOrderTypeColor(order.orderType) }"> <text class="type" :style="{ backgroundColor: typeTextBg }">
{{ models.order.getOrderTypeText(order.orderType) }} {{ typeText }}
</text> </text>
<text class="text">{{ order.username }}-{{ order.cate }}</text> <text class="text">{{ order.username }}-{{ order.cate }}</text>
</view> </view>
@ -49,6 +49,8 @@ export default {
data() { data() {
return { return {
models: this.$models, models: this.$models,
typeText: "",
typeTextBg: "",
}; };
}, },
props: { props: {
@ -59,7 +61,11 @@ export default {
}, },
components: {}, components: {},
created() {}, created() {},
mounted() {}, mounted() {
let [typeText, typeTextBg] = this.$models.order.getOrderTypeText(this.order.listType, this.order.orderType);
this.typeText = typeText;
this.typeTextBg = typeTextBg ? typeTextBg : "#8b9beb";
},
destroyed() {}, destroyed() {},
methods: {}, methods: {},
}; };

View File

@ -37,7 +37,60 @@ const apis = {
carType: { carType: {
url: "/wxapp/index/getallcar" url: "/wxapp/index/getallcar"
}, },
} },
get: {
list: {
t1: {
url: "/user/workerorderb/getallorder",
showLoading: true,
auth: true,
},
t2: {
url: "/user/workerorderc/getallorder",
showLoading: true,
auth: true,
},
t3: {
url: "/user/workerorder/getallcarorder",
showLoading: true,
auth: true,
}
},
detail: {
t1: {
url: "/user/workerorderb/orderinfo",
showLoading: true,
auth: true,
},
t2: {
url: "/user/workerorderc/orderinfobyid",
showLoading: true,
auth: true,
},
t3: {
url: "/user/workerorder/getcarorderinfobyid",
showLoading: true,
auth: true,
},
},
getOrder: {
t1: {
url: "/user/workerorderb/workerorderbyid",
showLoading: true,
auth: true,
},
t2: {
url: "/user/workerorderc/joinorder",
showLoading: true,
auth: true,
},
t3: {
url: "/user/workerorder/workerorderbyid",
showLoading: true,
auth: true,
},
}
},
} }
export default apis export default apis

View File

@ -3,11 +3,13 @@ import user from "@/core/models/user";
import worker from "@/core/models/worker"; import worker from "@/core/models/worker";
import system from "@/core/models/system"; import system from "@/core/models/system";
import service from "@/core/models/service"; import service from "@/core/models/service";
import get from "@/core/models/get";
export default { export default {
order, order,
user, user,
worker, worker,
system, system,
service service,
get
} }

60
src/core/models/get.js Normal file
View File

@ -0,0 +1,60 @@
import Vue from "vue"
let prototype = Vue.prototype;
export default {
/**
* 获取列表
*/
getList(options) {
return new Promise((resolve, reject) => {
prototype.$request(options.request).then(response => {
if (response.code == 1) {
let list = [];
response.data.forEach(item => {
list.push({
listType: options.listType,
id: item.id,
orderId: item.order,
username: "用户名称",
cate: "待返数据",
content: item.desc,
createTime: item.time,
serviceTime: item.times,
orderType: item.types,
state: item.status,
price: item.money,
});
});
return resolve(list);
}
return reject(response.msg);
}).catch(e => { });
});
},
/**
* 获取详情
*/
getDetail(options) {
return new Promise((resolve, reject) => {
prototype.$request(options.request).then(response => {
if (response.code == 1) {
return resolve(response.data);
}
return reject(response.msg);
}).catch(e => { });
});
},
/**
* 接单
*/
getOrder(options) {
return new Promise((resolve, reject) => {
prototype.$request(options).then(response => {
if (response.code == 1) {
return resolve(response.msg);
}
return reject(response.msg);
}).catch(e => { });
});
}
}

View File

@ -26,28 +26,15 @@ export default {
// 无法退款 // 无法退款
CAN_NOT_REFUND: 8, CAN_NOT_REFUND: 8,
}, },
getOrderTypeColor(type) { getOrderTypeText(listType, orderType) {
switch (type) { switch (listType) {
case this.type.NORMAL: case "t1": return ["购买服务", "#3ABCF6"];
return '#0ec4ad'; case "t2":
case this.state.WORKER_PRICE: if (orderType == 1) {
return '#0ec4ad'; return ["一口价", "#3ABCF6"];
case this.state.CUSTOM_PRICE: }
return '#0ec4ad'; return ["报价"];
default: case "t3": return ["货运", "#628BE7"];
return '#ff0000';
}
},
getOrderTypeText(type) {
switch (type) {
case this.type.NORMAL:
return '一口价';
case this.state.WORKER_PRICE:
return '报价';
case this.state.CUSTOM_PRICE:
return '议价';
default:
return '未知';
} }
}, },
getOrderStateTextColor(state) { getOrderStateTextColor(state) {

View File

@ -69,7 +69,14 @@
{ {
"path": "pages/get/index", "path": "pages/get/index",
"style": { "style": {
"navigationBarTitleText": "接单大厅" "navigationBarTitleText": "接单大厅",
"enablePullDownRefresh": true
}
},
{
"path": "pages/get/detail",
"style": {
"navigationBarTitleText": "单子详情"
} }
} }
], ],

374
src/pages/get/detail.vue Normal file
View File

@ -0,0 +1,374 @@
<template>
<app-layout title="订单详情">
<view class="order-detail-container">
<view class="detail-section">
<view class="order-head">
<view class="order-title">
<text class="type" :style="{ backgroundColor: typeTextBg }">
{{ typeText }}
</text>
<text class="text">{{ order.username }}-{{ order.cate }}</text>
</view>
</view>
<view class="order-body">
<view class="order-desc-row datetime">
<text class="text">订单号{{ order.orderId }}</text>
<text class="copy" @click.stop="copyOrderId(order.orderId)">复制</text>
</view>
<view class="order-desc-row datetime">
<text class="text">{{ order.createTime }}</text>
</view>
</view>
</view>
<block v-if="listType == 't1'">
<view class="detail-section">
<view class="section-title">需求信息</view>
<view class="section-content">
<view class="demand-item">
<view class="title">需求内容</view>
<view class="content">
{{ order.content }}
</view>
</view>
<view class="demand-item">
<view class="title">上门时间</view>
<view class="content service-time">
<text class="datetime">
{{ order.serviceTime }}
</text>
<text class="iconfont icon-bianji"></text>
</view>
</view>
<view class="demand-item">
<view class="demand-images">
<view class="image-box" v-for="(item, index) in order.images" :key="index">
<image class="image" :src="item" mode="aspectFill" />
</view>
</view>
</view>
</view>
</view>
<view class="detail-section">
<view class="section-title">上门地址</view>
<view class="address-box">
<text class="iconfont icon-dingwei"></text>
<view>
<view class="contact limit-line clamp-1">
<text class="name">
{{ order.address.name }}({{ order.address.sex == "男" ? "先生" : "女士" }})
</text>
<text class="mobile">{{ order.address.mobile }}</text>
</view>
<view class="detail">
<text>{{ order.address.address }}{{ order.address.detail }}</text>
</view>
</view>
</view>
</view>
</block>
<block v-if="listType == 't3'">
<view class="detail-section">
<view class="section-title">取货时间</view>
<view class="section-content">
<view class="demand-item">
<view class="title">上门时间</view>
<view class="content service-time">
<text class="datetime">
{{ order.serviceTime }}
</text>
<text class="iconfont icon-bianji"></text>
</view>
</view>
</view>
</view>
</block>
<view class="detail-section">
<text class="price-box">¥ {{ utils.formatNumber(order.price, 2) }}</text>
</view>
</view>
<view class="common-bottom-components" :style="{ bottom: pageConfig.safeAreaInsets.bottom + 'px' }">
<view class="service" @click="utils.serviceActions()">
<text class="iconfont icon-kefu"></text>
<text class="text">客服</text>
</view>
<view class="action">
<get-action :order="order" @postPrice="postPrice(order.id)" />
</view>
</view>
<get-post-price v-show="showPriceModal" @close="showPriceModal = false" @confirm="showPriceModal = false" />
</app-layout>
</template>
<script>
import AppLayout from "@/components/layout/layout";
import OrderAction from "@/components/order/action";
import GetAction from "@/components/get/action";
import GetPostPrice from "@/components/get/post-price";
export default {
name: "order-detail",
data() {
return {
utils: this.$utils,
models: this.$models,
pageConfig: {},
showPriceModal: false,
showConfirmModal: false,
typeText: "",
typeTextBg: "",
listType: "",
order: {
address: {},
},
};
},
components: {
AppLayout,
OrderAction,
GetAction,
GetPostPrice,
},
onLoad(e) {
this.pageConfig = getApp().globalData.pageConfig;
if (!e.id || e.id <= 0 || !e.list) {
this.$utils.toast("参数错误");
return;
}
this.id = e.id;
this.listType = e.list;
this.loadDetail();
},
onShow() {},
onReady() {},
onReachBottom() {},
onPullDownRefresh() {},
methods: {
copyOrderId(orderId) {
const that = this;
uni.setClipboardData({
data: orderId,
success(result) {
that.$utils.toast("内容已复制");
},
fail(error) {
that.$utils.toast("复制失败");
},
});
},
postPrice(id) {
this.$store.commit("order/setPostId", id);
this.showPriceModal = true;
},
/**
* 获取详情
*/
loadDetail() {
this.$models.get
.getDetail({
request: {
api: "get.detail." + this.listType,
data: {
id: this.id,
},
},
})
.then((response) => {
if (this.listType == "t1") {
this.order = {
listType: this.listType,
id: response.id,
orderId: response.order,
username: "用户名称",
cate: "待返数据",
content: response.desc,
createTime: response.time,
serviceTime: response.times,
orderType: response.types,
state: response.status,
price: response.money,
orderId: response.order,
images: response.goods.map((item) => item.thumbnail),
address: {
address: response.address.address,
detail: response.address.doorplate,
name: response.address.name,
mobile: response.address.mobil,
},
};
} else if (this.listType == "t3") {
this.order = {
listType: this.listType,
id: response.id,
orderId: response.order,
username: "用户名称",
cate: "待返数据",
createTime: response.time,
serviceTime: response.starttime,
state: response.status,
price: response.money,
};
}
let [typeText, typeTextBg] = this.$models.order.getOrderTypeText(this.listType, this.order.orderType);
this.typeText = typeText;
this.typeTextBg = typeTextBg ? typeTextBg : "#8b9beb";
});
},
},
};
</script>
<style lang="less" scoped>
.order-detail-container {
padding-bottom: 120rpx;
}
.detail-section {
width: 100%;
box-sizing: border-box;
padding: 40rpx;
background-color: #ffffff;
margin-bottom: 24rpx;
.section-title {
font-size: 30rpx;
font-weight: bold;
color: #000000;
}
}
.order-head {
display: flex;
align-items: center;
justify-content: space-between;
.order-title {
display: flex;
align-items: center;
.type {
display: inline-block;
box-sizing: border-box;
padding: 9rpx 24rpx;
border-radius: 10rpx;
font-size: 24rpx;
color: #ffffff;
line-height: 24rpx;
margin-right: 22rpx;
}
.text {
font-size: 30rpx;
font-weight: bold;
color: #000000;
line-height: 30rpx;
}
}
.state {
font-size: 26rpx;
line-height: 32rpx;
}
}
.order-body {
width: 100%;
.order-desc-row {
position: relative;
width: 100%;
font-size: 28rpx;
line-height: 30rpx;
margin-top: 30rpx;
.title {
color: #999999;
}
.text {
color: #000000;
}
.copy {
color: #8194f2;
margin-left: 24rpx;
}
}
}
.demand-item {
width: 100%;
display: flex;
font-size: 28rpx;
line-height: 36rpx;
margin-top: 40rpx;
.title {
width: 150rpx;
flex-shrink: 0;
color: #999999;
}
.content {
width: 100%;
color: #000000;
}
.service-time {
display: flex;
justify-content: space-between;
.datetime {
color: #000000;
}
.iconfont {
font-size: 32rpx;
color: #999999;
}
}
}
.demand-images {
display: flex;
flex-wrap: wrap;
.image-box {
width: 133.2rpx;
height: 133.2rpx;
background: rgba(184, 180, 179, 0);
box-sizing: border-box;
border-radius: 25rpx;
overflow: hidden;
border: 1px solid #f7f7f7;
.image {
width: 100%;
height: 100%;
}
}
}
.address-box {
display: flex;
align-items: center;
margin-top: 40rpx;
.iconfont {
font-size: 40rpx;
color: #8194f2;
padding: 0 50rpx;
}
.contact,
.detail {
font-size: 26rpx;
font-weight: 500;
}
.contact {
color: #000000;
line-height: 26rpx;
}
.detail {
color: #2d2d2d;
line-height: 36rpx;
margin-top: 16rpx;
}
}
.price-box {
font-size: 48rpx;
line-height: 48rpx;
font-weight: bold;
color: #ec7655;
}
.common-bottom-components {
.service {
display: flex;
align-items: center;
.iconfont {
font-size: 60rpx;
color: #999999;
}
.text {
display: inline-block;
font-size: 28rpx;
color: #999999;
margin-left: 10rpx;
}
}
}
</style>

View File

@ -17,14 +17,18 @@
</scroll-view> </scroll-view>
</view> </view>
<view class="order-group"> <view class="order-group">
<swiper :current="tabIndex" :style="{ height: tabHeight + 'px' }" @change="changeTab"> <swiper :current="tabIndex" :style="{ height: tabHeight + 'px' }" @change="switchTab($event.detail.current)">
<swiper-item v-for="(item, index) in tabList" :key="index"> <swiper-item v-for="(item, index) in tabList" :key="index">
<view :class="['tab' + index]"> <view :class="['tab' + index]">
<view class="order-item-box" v-for="(v, k) in item.list" :key="k" @click.stop="toDetail(v.id)"> <view class="order-item-box" v-for="(v, k) in item.list" :key="k" @click.stop="toDetail(v.id)">
<order-item :order="v"> <order-item :order="v">
<view class="order-action"> <view class="order-action">
<view class="price">¥ 306.00</view> <view class="price">¥ 306.00</view>
<get-action :order="v" @postPrice="postPrice(v.id)" /> <get-action
:order="v"
@postPrice="postPrice(v.id)"
@getOrder="getOrder({ id: v.id, listType: v.listType })"
/>
</view> </view>
</order-item> </order-item>
</view> </view>
@ -43,7 +47,7 @@
<text class="text">刷新列表</text> <text class="text">刷新列表</text>
</view> </view>
</view> </view>
<get-post-price v-show="showPriceModal" @close="showPriceModal = false" @confirm="showPriceModal = false" /> <get-post-price v-show="showPriceModal" @close="showPriceModal = false" @post="rcvPostPrice" />
</app-layout> </app-layout>
</template> </template>
@ -63,73 +67,24 @@ export default {
tabHeight: 0, tabHeight: 0,
tabList: [ tabList: [
{ {
id: 1, listType: "t1",
name: "一口价订单", name: "购买订单",
list: [ page: 1,
{ more: true,
id: 1,
orderId: "xxgfdkgn1223",
cate: "家具安装",
content: "我想要安装一个书柜,需要上墙啊啊啊啊",
createTime: "2022-10-18 10:56:34",
serviceTime: "2022-10-18 10:56:34",
orderType: 1,
state: 1,
price: 306,
username: "李先生",
},
{
id: 2,
orderId: "xxgfdkgn1223",
cate: "家具安装",
content: "我想要安装一个书柜,需要上墙啊啊啊啊",
createTime: "2022-10-18 10:56:34",
serviceTime: "2022-10-18 10:56:34",
orderType: 1,
state: 1,
price: 306,
username: "李先生",
},
{
id: 3,
orderId: "xxgfdkgn1223",
cate: "家具安装",
content: "我想要安装一个书柜,需要上墙啊啊啊啊",
createTime: "2022-10-18 10:56:34",
serviceTime: "2022-10-18 10:56:34",
orderType: 1,
state: 1,
price: 306,
username: "李先生",
},
],
},
{
id: 2,
name: "报价订单",
list: [
{
id: 2,
orderId: "xxgfdkgn1223",
cate: "家具安装",
content: "我想要安装一个书柜,需要上墙啊啊啊啊",
createTime: "2022-10-18 10:56:34",
serviceTime: "2022-10-18 10:56:34",
orderType: 2,
state: 1,
price: 306,
username: "李先生",
},
],
},
{
id: 3,
name: "指派订单",
list: [], list: [],
}, },
{ {
id: 4, listType: "t2",
name: "报/议价订单",
page: 1,
more: true,
list: [],
},
{
listType: "t3",
name: "配送订单", name: "配送订单",
page: 1,
more: true,
list: [], list: [],
}, },
], ],
@ -142,23 +97,28 @@ export default {
GetPostPrice, GetPostPrice,
}, },
onLoad() { onLoad() {
this.$nextTick(() => { this.switchTab(0);
this.setTabHeight();
});
}, },
onShow() {}, onShow() {},
onReady() {}, onReady() {},
onReachBottom() {}, onReachBottom() {
onPullDownRefresh() {}, this.loadData();
},
onPullDownRefresh() {
this.switchTab(this.tabIndex);
uni.stopPullDownRefresh();
},
methods: { methods: {
/**
* 切换列表
*/
switchTab(index) { switchTab(index) {
this.tabIndex = index; this.tabIndex = index;
this.$nextTick(() => { let currentTab = this.tabList[index];
this.setTabHeight(); currentTab.page = 1;
}); currentTab.more = true;
}, currentTab.list = [];
changeTab(e) { this.loadData();
this.switchTab(e.detail.current);
}, },
setTabHeight() { setTabHeight() {
let query = uni.createSelectorQuery().in(this); let query = uni.createSelectorQuery().in(this);
@ -169,18 +129,95 @@ export default {
} }
}); });
}, },
/**
* 加载数据
*/
loadData() {
let currentTab = this.tabList[this.tabIndex];
return new Promise((resolve, reject) => {
if (!currentTab.more) {
return;
}
this.$models.get
.getList({
request: {
api: "get.list." + currentTab.listType,
data: {
page: currentTab.page,
},
},
listType: currentTab.listType,
})
.then((list) => {
if (list.length == 0) {
currentTab.more = false;
} else {
currentTab.page++;
currentTab.list = currentTab.list.concat(list);
}
this.$nextTick(() => {
this.setTabHeight();
});
});
});
},
/**
* 报价
*/
postPrice(id) { postPrice(id) {
this.$store.commit("order/setPostId", id); this.$store.commit("order/setPostId", id);
this.showPriceModal = true; this.showPriceModal = true;
}, },
/**
* 确认价格
*/
rcvPostPrice(e) {
this.showPriceModal = false;
this.getOrder({
id: e.id,
listType: "t2",
price: e.price,
});
},
/**
* 接单
*/
getOrder(order) {
let requestData = {
id: order.id,
};
if (order.price) {
requestData.money = order.price;
}
this.$models.get
.getOrder({
api: "get.getOrder." + order.listType,
data: requestData,
})
.then((message) => {
this.$utils.toast(message).then(() => {
this.switchTab(this.tabIndex);
});
})
.catch((e) => {
this.$utils.toast(e);
});
},
setting() { setting() {
console.log("设置"); console.log("设置");
}, },
/**
* 刷新列表
*/
refresh() { refresh() {
console.log("刷新"); this.switchTab(this.tabIndex);
}, },
/**
* 查看详情
*/
toDetail(id) { toDetail(id) {
this.$utils.toPage("/pages/order/detail?type=preview&id=" + id); let currentTab = this.tabList[this.tabIndex];
this.$utils.toPage("/pages/get/detail?list=" + currentTab.listType + "&id=" + id);
}, },
}, },
}; };

View File

@ -72,7 +72,7 @@
<text class="price-box">¥ {{ utils.formatNumber(order.price, 2) }}</text> <text class="price-box">¥ {{ utils.formatNumber(order.price, 2) }}</text>
</view> </view>
</view> </view>
<view class="common-bottom-components" :style="{ bottom: config.safeAreaInsets.bottom + 'px' }"> <view class="common-bottom-components" :style="{ bottom: pageConfig.safeAreaInsets.bottom + 'px' }">
<view class="service" @click="utils.serviceActions()"> <view class="service" @click="utils.serviceActions()">
<text class="iconfont icon-kefu"></text> <text class="iconfont icon-kefu"></text>
<text class="text">客服</text> <text class="text">客服</text>
@ -97,13 +97,13 @@ import OrderAction from "@/components/order/action";
import GetAction from "@/components/get/action"; import GetAction from "@/components/get/action";
import OrderConfirmPrice from "@/components/order/confirm-price"; import OrderConfirmPrice from "@/components/order/confirm-price";
import GetPostPrice from "@/components/get/post-price"; import GetPostPrice from "@/components/get/post-price";
import { mapState } from "vuex";
export default { export default {
name: "order-detail", name: "order-detail",
data() { data() {
return { return {
utils: this.$utils, utils: this.$utils,
models: this.$models, models: this.$models,
pageConfig: {},
showPriceModal: false, showPriceModal: false,
showConfirmModal: false, showConfirmModal: false,
type: "detail", type: "detail",
@ -145,12 +145,8 @@ export default {
OrderConfirmPrice, OrderConfirmPrice,
GetPostPrice, GetPostPrice,
}, },
computed: {
...mapState({
config: (state) => state.system.config,
}),
},
onLoad(e) { onLoad(e) {
this.pageConfig = getApp().globalData.pageConfig;
if (e.id && e.id > 0) { if (e.id && e.id > 0) {
this.id = e.id; this.id = e.id;
} else { } else {