This commit is contained in:
TOP糯米 2023-03-24 02:24:14 +08:00
commit 5c5fca874b
25 changed files with 812 additions and 258 deletions

View File

@ -214,5 +214,41 @@ export default {
color: #999999; color: #999999;
} }
} }
.upload-item {
display: flex;
flex-wrap: wrap;
padding: 0 30rpx;
.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%;
}
}
.image-box.upload {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: #999999;
border-radius: 0;
border: 1px solid #999999;
.iconfont {
font-size: 50rpx;
line-height: 50rpx;
}
.text {
font-size: 24rpx;
margin-top: 18rpx;
line-height: 24rpx;
}
}
}
} }
</style> </style>

View File

@ -3,17 +3,13 @@
<widget-modal title="提交报价" @close="closeModal"> <widget-modal title="提交报价" @close="closeModal">
<view class="modal-content"> <view class="modal-content">
<view class="input-row"> <view class="input-row">
<text class="title">需要支付</text> <text class="title">预计需要</text>
<input class="input" type="number" v-model="price" @input="price = parseFloat(price)" /> <input class="input" type="number" v-model="price" @input="price = parseFloat(price)" />
<text class="unit"> <text class="unit">
<text class="iconfont icon-qingchu" @click="price = 0"></text> <text class="iconfont icon-qingchu" @click="price = 0"></text>
<text class="text"></text> <text class="text"></text>
</text> </text>
</view> </view>
<view class="desc">
<text class="text">1)哈哈哈哈</text>
<text class="text">2)哈哈哈哈哈哈哈哈</text>
</view>
<view class="btn" @click="postPrice">确认</view> <view class="btn" @click="postPrice">确认</view>
</view> </view>
</widget-modal> </widget-modal>

View File

@ -18,6 +18,13 @@
<block v-if="order.state == 6"> <block v-if="order.state == 6">
<view class="btn normal">已完成</view> <view class="btn normal">已完成</view>
</block> </block>
<block v-if="order.state == 7">
<view class="btn" @click.stop="refund">同意退款</view>
<view class="btn" @click.stop="appeal">申诉</view>
</block>
<block v-if="order.state == 8">
<view class="btn normal">退款成功</view>
</block>
</block> </block>
<block v-if="order.listType == 't3'"> <block v-if="order.listType == 't3'">
<block v-if="order.state == 2"> <block v-if="order.state == 2">
@ -55,6 +62,34 @@ export default {
confirmPrice() { confirmPrice() {
this.$emit("confirmPrice"); this.$emit("confirmPrice");
}, },
/**
* 退款
*/
refund() {
this.$models.order
.refundOrder({
request: {
api: "order.refund." + this.order.listType,
data: {
id: this.order.id,
},
},
})
.then((response) => {
this.$utils.toast(response.msg).then(() => {
this.$emit("refresh");
});
})
.catch((e) => {
this.$utils.toast(e);
});
},
/**
* 申诉
*/
appeal() {
this.$utils.toPage("/pages/order/appeal?list=" + this.order.listType + "&id=" + this.order.id);
},
}, },
}; };
</script> </script>

View File

@ -48,6 +48,14 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.component-widgets-modal { .component-widgets-modal {
z-index: 25; z-index: 25;
position: fixed; position: fixed;
@ -61,6 +69,7 @@ export default {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
animation: fadeIn 0.2s;
.modal-mask { .modal-mask {
z-index: 0; z-index: 0;
position: absolute; position: absolute;

View File

@ -0,0 +1,56 @@
<template>
<view class="components-service">
<widget-modal v-show="showService" @close="close" title="请选择客服">
<view class="service-list">
<button class="btn-item" @click="call">电话客服</button>
<button class="btn-item" open-type="contact">微信客服</button>
</view>
</widget-modal>
</view>
</template>
<script>
import WidgetModal from "@/components/widgets/modal";
export default {
name: "widget-service",
data() {
return {};
},
props: {
showService: {
type: Boolean,
default: false,
},
},
components: {
WidgetModal,
},
created() {},
mounted() {},
destroyed() {},
methods: {
close() {
this.$emit("close");
},
call() {},
},
};
</script>
<style lang="less" scoped>
.components-service {
width: 100%;
.service-list {
width: 100%;
}
.btn-item {
color: #666666;
font-size: 30rpx;
background-color: unset;
border-bottom: 2rpx solid #e0e0e0;
}
.btn-item::after {
border: 0;
}
}
</style>

View File

@ -9,6 +9,24 @@ const apis = {
showLoading: true, showLoading: true,
auth: true, auth: true,
}, },
carefree: {
url: "/user/workerinfo/carefree",
showLoading: true,
auth: true,
},
notify: {
cate: {
url: "/wxapp/index/newcate",
showLoading: true,
},
list: {
url: "/wxapp/index/newlistbycateid",
showLoading: true,
},
detail: {
url: ""
}
}
}, },
user: { user: {
sendCode: { sendCode: {
@ -28,12 +46,25 @@ const apis = {
}, },
info: { info: {
url: "/user/workerinfo/getuserinfo", url: "/user/workerinfo/getuserinfo",
showLoading: true,
auth: true, auth: true,
}, },
setServiceInfo: { setServiceInfo: {
url: "/user/workerinfo/setinfo", url: "/user/workerinfo/setinfo",
auth: true, auth: true,
}, },
withdraw: {
withdraw: {
url: "/user/workerinfo/drawmoney",
showLoading: true,
auth: true,
},
explain: {
url: "/wxapp/index/getdistributionmoney",
showLoading: true,
auth: true,
}
}
}, },
service: { service: {
cate: { cate: {
@ -144,8 +175,36 @@ const apis = {
}, },
t3: { t3: {
url: "", url: "",
}
},
refund: {
t1: {
url: "/user/workerorderb/agreerefund",
showLoading: true, showLoading: true,
auth: true, auth: true,
},
t2: {
url: "/user/workerorderc/agreerefund",
showLoading: true,
auth: true,
},
t3: {
url: "",
}
},
appeal: {
t1: {
url: "/user/workerorderb/disagreerefund",
showLoading: true,
auth: true,
},
t2: {
url: "/user/workerorderc/disagreerefund",
showLoading: true,
auth: true,
},
t3: {
url: "",
} }
} }
}, },

View File

@ -2,7 +2,7 @@ const config = {
name: "熊熊安装", name: "熊熊安装",
storagePrefix: "worker_", storagePrefix: "worker_",
appId: "wx2401c65b68a6c9b5", appId: "wx2401c65b68a6c9b5",
root: "http://xiongxiong.vipwjf.com/api.php" root: "https://xiongxiong.vipwjf.com/api.php"
} }
export default config export default config

View File

@ -215,18 +215,6 @@ function formatNumber(num, limit) {
return num > 0 ? num.toFixed(limit) : 0; return num > 0 ? num.toFixed(limit) : 0;
} }
function serviceActions() {
uni.showActionSheet({
itemList: ['电话客服', '微信客服'],
success(res) {
console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
},
fail(res) {
console.log(res.errMsg);
}
});
}
function chooseImage(count) { function chooseImage(count) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let tempFiles = []; let tempFiles = [];
@ -281,6 +269,5 @@ export default {
toPage, toPage,
toast, toast,
formatNumber, formatNumber,
serviceActions,
chooseImage, chooseImage,
} }

View File

@ -20,7 +20,7 @@ export default {
case 4: return ['待支付尾款']; case 4: return ['待支付尾款'];
case 5: return ['待客户确认']; case 5: return ['待客户确认'];
case 6: return ['订单已完成']; case 6: return ['订单已完成'];
case 7: return ['退款申请审核中']; case 7: return ['退款中'];
case 8: return ['已退款']; case 8: return ['已退款'];
case 9: return ['退款未通过']; case 9: return ['退款未通过'];
} }
@ -31,7 +31,7 @@ export default {
case 4: return ['待支付尾款']; case 4: return ['待支付尾款'];
case 5: return ['服务已完成,待确认']; case 5: return ['服务已完成,待确认'];
case 6: return ['订单已完成']; case 6: return ['订单已完成'];
case 7: return ['退款申请审核中']; case 7: return ['退款中'];
case 8: return ['已退款']; case 8: return ['已退款'];
case 9: return ['退款未通过']; case 9: return ['退款未通过'];
} }
@ -158,5 +158,31 @@ export default {
return reject(response.msg); return reject(response.msg);
}).catch(e => { }); }).catch(e => { });
}); });
},
/**
* 退款
*/
refundOrder(options) {
return new Promise((resolve, reject) => {
prototype.$request(options.request).then(response => {
if (response.code == 1) {
return resolve(response);
}
return reject(response.msg);
}).catch(e => { });
});
},
/**
* 退款
*/
appealOrder(options) {
return new Promise((resolve, reject) => {
prototype.$request(options.request).then(response => {
if (response.code == 1) {
return resolve(response);
}
return reject(response.msg);
}).catch(e => { });
});
} }
} }

View File

@ -83,4 +83,53 @@ export default {
}); });
}); });
}, },
} /**
* 服务数据
*/
serviceData() {
return new Promise((resolve, reject) => {
prototype.$request({
api: "system.serviceData",
}).then(response => {
if (response.code == 1) {
return resolve(response.data);
}
return reject(response.msg);
}).catch(e => { });
});
},
/**
* 公告分类
*/
notifyCate() {
return new Promise((resolve, reject) => {
prototype.$request({
api: "system.notify.cate"
}).then((response) => {
if (response.code == 1) {
return resolve(response.data);
}
return reject(response.msg);
});
});
},
/**
* 公告列表
*/
notifyList(cateId, page) {
return new Promise((resolve, reject) => {
prototype.$request({
api: "system.notify.list",
data: {
cateid: cateId,
page: page,
}
}).then((response) => {
if (response.code == 1) {
return resolve(response.data);
}
return reject(response.msg);
});
});
}
}

View File

@ -247,5 +247,38 @@ export default {
prototype.$utils.toast('注销成功').then(() => { prototype.$utils.toast('注销成功').then(() => {
prototype.$utils.toPage('/pages/index/index', {}, 'switch'); prototype.$utils.toPage('/pages/index/index', {}, 'switch');
}); });
},
/**
* 提现
*/
withdraw(money) {
return new Promise((resolve, reject) => {
prototype.$request({
api: "user.withdraw.withdraw",
data: {
money: money
}
}).then(response => {
if (response.code == 1) {
return resolve(response);
}
return reject(response.msg);
}).catch(e => { });
});
},
/**
* 提现说明
*/
withdrawExplain() {
return new Promise((resolve, reject) => {
prototype.$request({
api: "user.withdraw.explain",
}).then(response => {
if (response.code == 1) {
return resolve(response.data);
}
return reject(response.msg);
}).catch(e => { });
});
} }
} }

View File

@ -38,15 +38,15 @@
} }
}, },
{ {
"path": "pages/message/message", "path": "pages/order/appeal",
"style": { "style": {
"navigationBarTitleText": "消息" "navigationBarTitleText": "退款申诉"
} }
}, },
{ {
"path": "pages/message/detail", "path": "pages/message/message",
"style": { "style": {
"navigationBarTitleText": "详情" "navigationBarTitleText": "消息"
} }
}, },
{ {

View File

@ -27,15 +27,17 @@
<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 <view class="price">
v-if=" <text
v.listType == 't1' || v-if="
v.listType == 't3' || v.listType == 't1' ||
(v.listType == 't2' && v.orderType == 1) v.listType == 't3' ||
" (v.listType == 't2' && v.orderType == 1)
class="price" "
>¥ {{ v.price }}</view >
> ¥ {{ v.price }}
</text>
</view>
<get-action <get-action
:order="v" :order="v"
@postPrice="showPostPriceModal(v.id)" @postPrice="showPostPriceModal(v.id)"
@ -221,7 +223,7 @@ export default {
}); });
}, },
setting() { setting() {
console.log("设置"); this.$utils.toPage("/pages/member/service-info");
}, },
/** /**
* 刷新列表 * 刷新列表

View File

@ -25,7 +25,7 @@
interval="3000" interval="3000"
duration="1000" duration="1000"
> >
<swiper-item v-for="(item, index) in notifyList" :key="index"> <swiper-item v-for="(item, index) in notifyList" :key="index" @click="notifyDetail(item)">
<view class="swiper-item notify-item"> <view class="swiper-item notify-item">
<text class="limit-line clamp-1"> <text class="limit-line clamp-1">
{{ item.title }} {{ item.title }}
@ -36,9 +36,21 @@
</view> </view>
</view> </view>
<view class="nav"> <view class="nav">
<view class="nav-item" v-for="(item, index) in navList" :key="index" @click="utils.toPage(item.page)"> <view class="nav-item" @click="utils.toPage('/pages/get/index')">
<image class="icon" :src="item.icon" mode="aspectFill" /> <image class="icon" :src="require('@/static/temp/index/1.png')" mode="aspectFill" />
<text class="title">{{ item.name }}</text> <text class="title">接单大厅</text>
</view>
<view class="nav-item" @click="toMessage(1)">
<image class="icon" :src="require('@/static/temp/index/2.png')" mode="aspectFill" />
<text class="title">平台规则</text>
</view>
<view class="nav-item" @click="utils.serviceActions()">
<image class="icon" :src="require('@/static/temp/index/3.png')" mode="aspectFill" />
<text class="title">平台客服</text>
</view>
<view class="nav-item" @click="toMessage(2)">
<image class="icon" :src="require('@/static/temp/index/4.png')" mode="aspectFill" />
<text class="title">帮助中心</text>
</view> </view>
</view> </view>
<view class="action-group"> <view class="action-group">
@ -62,11 +74,17 @@
</view> </view>
</view> </view>
</view> </view>
<widget-modal v-show="showNotifyModal" @close="showNotifyModal = false" :title="notify.title">
<view class="message-box">
<rich-text :nodes="notify.content"></rich-text>
</view>
</widget-modal>
</app-layout> </app-layout>
</template> </template>
<script> <script>
import AppLayout from "@/components/layout/layout"; import AppLayout from "@/components/layout/layout";
import WidgetModal from "@/components/widgets/modal";
export default { export default {
name: "index", name: "index",
data() { data() {
@ -74,54 +92,12 @@ export default {
utils: this.$utils, utils: this.$utils,
safePt: 0, safePt: 0,
backgroundImage: require("@/static/temp/1.png"), backgroundImage: require("@/static/temp/1.png"),
notifyList: [ notifyList: [],
{ showNotifyModal: false,
id: 1, notify: {
title: "恭喜成都市王先生订购xxxxxx服务一套", title: "",
}, content: "",
{ },
id: 2,
title: "恭喜成都市王先生订购xxxxxx服务一套",
},
{
id: 3,
title: "恭喜成都市王先生订购xxxxxx服务一套",
},
{
id: 4,
title: "恭喜成都市王先生订购xxxxxx服务一套",
},
{
id: 5,
title: "恭喜成都市王先生订购xxxxxx服务一套",
},
],
navList: [
{
id: 1,
icon: require("@/static/temp/index/1.png"),
name: "接单大厅",
page: "/pages/get/index",
},
{
id: 1,
icon: require("@/static/temp/index/2.png"),
name: "平台规则",
page: "",
},
{
id: 1,
icon: require("@/static/temp/index/3.png"),
name: "平台客服",
page: "",
},
{
id: 1,
icon: require("@/static/temp/index/4.png"),
name: "帮助中心",
page: "",
},
],
action: { action: {
item1: 0, item1: 0,
item2: 0, item2: 0,
@ -132,26 +108,35 @@ export default {
}, },
components: { components: {
AppLayout, AppLayout,
WidgetModal,
},
onLoad() {
this.$models.system.notifyList(1, 1).then((list) => {
this.notifyList = list;
});
}, },
onLoad() {},
onShow() { onShow() {
this.$request({ this.$models.system.serviceData().then((data) => {
api: "system.serviceData", this.action.item1 = data.order1;
}) this.action.item2 = data.order2;
.then((response) => { this.action.item3 = data.order3;
if (response.code == 1) { this.action.item4 = data.order4;
this.action.item1 = response.data.order1; });
this.action.item2 = response.data.order2;
this.action.item3 = response.data.order3;
this.action.item4 = response.data.order4;
}
})
.catch((e) => {});
}, },
onReady() {}, onReady() {},
onReachBottom() {}, onReachBottom() {},
onPullDownRefresh() {}, onPullDownRefresh() {},
methods: {}, methods: {
toMessage(id) {
this.$store.commit("system/messageTabIndex", id);
this.$utils.toPage("/pages/message/message", {}, "switch");
},
notifyDetail(detail) {
this.showNotifyModal = true;
this.notify.title = detail.title;
this.notify.content = detail.message;
},
},
}; };
</script> </script>
@ -272,4 +257,8 @@ export default {
background: linear-gradient(135deg, #328eff, #2fb2fe, #44c2ee); background: linear-gradient(135deg, #328eff, #2fb2fe, #44c2ee);
} }
} }
.message-box {
max-height: 400rpx;
overflow-y: scroll;
}
</style> </style>

View File

@ -8,46 +8,77 @@
class="input" class="input"
type="number" type="number"
v-model="money" v-model="money"
placeholder="请输入提现金额不可低于20元" :placeholder="'请输入提现金额,不可低于' + min + '元'"
placeholder-class="placeholder-style-4" placeholder-class="placeholder-style-4"
/> />
</view> </view>
<view class="total-box"> <view class="total-box">
<text class="text">可提现金额</text> <text class="text">可提现金额</text>
<text class="num">¥0.00</text> <text class="num">¥ {{ balance }}</text>
</view> </view>
</view> </view>
<view class="withdraw-section withdraw-desc"> <view class="withdraw-section withdraw-desc">
<view class="title">提现说明</view> <view class="title">提现说明</view>
<view class="content"> <view class="content">
1提现周期为每周三提现一次2小时内到账 2请谨慎绑定微信号信息错误将导致错误打款责任由师傅自行承担 <rich-text :nodes="explain"></rich-text>
3家居售后问题通常在用户试用中出现如漏水渗水堵塞固定松动等因此平台对服务后订单设置7日反馈期反馈期内若服务无售后问题或非安装问题所造成售后反馈期过后该笔订单金额自动转入可提现余额
</view> </view>
</view> </view>
<view class="common-save-form-btn"> <view class="common-save-form-btn">
<view class="btn">确定提现</view> <view class="btn" @click="submit">确定提现</view>
</view> </view>
</app-layout> </app-layout>
</template> </template>
<script> <script>
import AppLayout from "@/components/layout/layout"; import AppLayout from "@/components/layout/layout";
import { mapState } from "vuex";
export default { export default {
name: "member-cash-withdraw", name: "member-cash-withdraw",
data() { data() {
return { return {
min: 0,
money: null, money: null,
balance: 0,
explain: "",
}; };
}, },
components: { components: {
AppLayout, AppLayout,
}, },
computed: {
...mapState({
userInfo: (state) => state.user.info,
}),
},
onLoad() {}, onLoad() {},
onShow() {}, async onShow() {
await this.$store.dispatch("user/info");
this.$models.user.serviceData().then((data) => {
this.balance = data.disposableBalance;
});
this.$models.user.withdrawExplain().then((data) => {
this.explain = data.tixian_content;
this.min = data.min;
});
},
onReady() {}, onReady() {},
onReachBottom() {}, onReachBottom() {},
onPullDownRefresh() {}, onPullDownRefresh() {},
methods: {}, methods: {
submit() {
if (this.money <= 0) {
return this.$utils.toast("请输入提现金额");
}
this.$models.user
.withdraw(this.money)
.then((response) => {
this.$utils.toast(response.msg);
})
.catch((e) => {
this.$utils.toast(e);
});
},
},
}; };
</script> </script>

View File

@ -68,7 +68,7 @@
<text class="title limit-line clamp-1">我要提现</text> <text class="title limit-line clamp-1">我要提现</text>
<text class="iconfont icon-jinru"></text> <text class="iconfont icon-jinru"></text>
</view> </view>
<view class="widget-item"> <view class="widget-item" @click="showCarefree">
<text class="title limit-line clamp-1">服务无忧保</text> <text class="title limit-line clamp-1">服务无忧保</text>
<text class="iconfont icon-jinru"></text> <text class="iconfont icon-jinru"></text>
</view> </view>
@ -90,7 +90,7 @@
<text class="title limit-line clamp-1">我的评价</text> <text class="title limit-line clamp-1">我的评价</text>
<text class="iconfont icon-jinru"></text> <text class="iconfont icon-jinru"></text>
</view> </view>
<view class="widget-item" @click="utils.serviceActions()"> <view class="widget-item" @click="showService = true">
<text class="title limit-line clamp-1">在线客服</text> <text class="title limit-line clamp-1">在线客服</text>
<text class="iconfont icon-jinru"></text> <text class="iconfont icon-jinru"></text>
</view> </view>
@ -101,12 +101,20 @@
</view> </view>
</view> </view>
</view> </view>
<widget-modal v-show="showCarefreeModal" title="服务无忧保" @close="showCarefreeModal = false">
<view class="modal-content-box">
<rich-text :nodes="carefreeContent"></rich-text>
</view>
</widget-modal>
<widget-service :showService="showService" @close="showService = false" />
</app-layout> </app-layout>
</template> </template>
<script> <script>
import AppLayout from "@/components/layout/layout"; import AppLayout from "@/components/layout/layout";
import WidgetSwitch from "@/components/widgets/switch"; import WidgetSwitch from "@/components/widgets/switch";
import WidgetModal from "@/components/widgets/modal";
import WidgetService from "@/components/widgets/service";
import { mapGetters, mapState } from "vuex"; import { mapGetters, mapState } from "vuex";
export default { export default {
name: "member", name: "member",
@ -120,6 +128,9 @@ export default {
acceptOrderState: false, acceptOrderState: false,
typeText: "", typeText: "",
typeTextColor: "", typeTextColor: "",
showService: false,
showCarefreeModal: false,
carefreeContent: "",
serviceData: { serviceData: {
times: 0, times: 0,
favorableRate: "0", favorableRate: "0",
@ -132,6 +143,8 @@ export default {
components: { components: {
AppLayout, AppLayout,
WidgetSwitch, WidgetSwitch,
WidgetModal,
WidgetService,
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
@ -167,6 +180,14 @@ export default {
} }
this.$utils.toPage(url); this.$utils.toPage(url);
}, },
showCarefree() {
// this.showCarefreeModal = true;
// this.$request({
// api: "system.carefree",
// }).then((response) => {
// this.carefreeContent = response.data.content;
// });
},
}, },
}; };
</script> </script>
@ -298,4 +319,8 @@ export default {
margin-right: 14rpx; margin-right: 14rpx;
} }
} }
.modal-content-box {
max-height: 400rpx;
overflow-y: scroll;
}
</style> </style>

View File

@ -1,61 +0,0 @@
<template>
<app-layout title="详情">
<div class="message-container">
<view class="head">
<text class="title limit-line clamp-1">{{ title }}</text>
<text class="date">{{ date }}</text>
</view>
<view class="body">
<rich-text :nodes="content"></rich-text>
</view>
</div>
</app-layout>
</template>
<script>
import AppLayout from "@/components/layout/layout";
export default {
name: "message-detail",
data() {
return {
title: "接单后要求多久与客户预约安装时间?",
date: "2022-11-01 18:14",
content: "哈哈哈",
};
},
components: {
AppLayout,
},
onLoad() {},
onShow() {},
onReady() {},
onReachBottom() {},
onPullDownRefresh() {},
methods: {},
};
</script>
<style lang="less" scoped>
.message-container {
width: 100%;
box-sizing: border-box;
padding: 40rpx;
.head {
width: 100%;
font-size: 30rpx;
font-weight: bold;
line-height: 30rpx;
.title {
color: #333333;
}
.date {
display: inline-block;
color: #999999;
margin-top: 24rpx;
}
}
.body {
margin-top: 40rpx;
}
}
</style>

View File

@ -12,113 +12,87 @@
</view> </view>
</scroll-view> </scroll-view>
<view class="message-container"> <view class="message-container">
<swiper :current="tabIndex" :style="{ minHeight: '75vh', height: tabHeight + 'px' }" @change="changeTab"> <swiper
:current="tabIndex"
:style="{ minHeight: '75vh', 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 <view class="message-item" v-for="(v, k) in item.list" :key="k" @click="toDetail(v)">
class="message-item" <text class="title limit-line clamp-1">{{ v.title }}</text>
v-for="(v, k) in item.list"
:key="k"
@click="utils.toPage('/pages/message/detail?id=' + v.id)"
>
<text class="title limit-line clamp-1" :class="{ active: !v.read }">{{ v.title }}</text>
<text class="date">{{ v.date }}</text> <text class="date">{{ v.date }}</text>
</view> </view>
</view> </view>
</swiper-item> </swiper-item>
</swiper> </swiper>
</view> </view>
<widget-modal v-show="showDetail" :title="detail.title" @close="showDetail = false">
<view class="message-box">
<rich-text :nodes="detail.content"></rich-text>
</view>
</widget-modal>
</app-layout> </app-layout>
</template> </template>
<script> <script>
import AppLayout from "@/components/layout/layout"; import AppLayout from "@/components/layout/layout";
import WidgetModal from "@/components/widgets/modal";
import { mapState } from "vuex";
export default { export default {
name: "message", name: "message",
data() { data() {
return { return {
utils: this.$utils, utils: this.$utils,
bodyPt: 0, bodyPt: 0,
timer: null,
tabIndex: 0, tabIndex: 0,
tabHeight: 0, tabHeight: 0,
tabList: [ tabList: [],
{ showDetail: false,
id: 1, detail: {
name: "公告", title: "",
list: [ content: "",
{ },
id: 1,
title: "接单后要求多久与客户预约安装时间?",
date: "2022-11-01 18:14",
read: false,
},
{
id: 2,
title: "接单后要求多久与客户预约安装时间?",
date: "2022-11-01 18:14",
read: true,
},
{
id: 3,
title: "接单后要求多久与客户预约安装时间?",
date: "2022-11-01 18:14",
read: true,
},
{
id: 4,
title: "接单后要求多久与客户预约安装时间?",
date: "2022-11-01 18:14",
read: true,
},
],
},
{
id: 2,
name: "平台规则",
list: [
{
id: 5,
title: "接单后要求多久与客户预约安装时间?",
date: "2022-11-01 18:14",
read: false,
},
],
},
{
id: 3,
name: "帮助中心",
list: [],
},
{
id: 4,
name: "平台消息",
list: [],
},
],
}; };
}, },
components: { components: {
AppLayout, AppLayout,
WidgetModal,
}, },
computed: {}, computed: {
onLoad() { ...mapState({
this.$nextTick(() => { messageTabIndex: (state) => state.system.messageTabIndex,
this.setTabHeight(); }),
}); },
onLoad() {},
async onShow() {
if (this.messageTabIndex != this.tabIndex) {
this.tabList = [];
await this.loadCate();
this.switchTab(this.messageTabIndex);
}
}, },
onShow() {},
onReady() {}, onReady() {},
onReachBottom() {}, onReachBottom() {
let currentTab = this.tabList[this.tabIndex];
if (currentTab.more) {
this.loadList(this.tabIndex);
}
},
onPullDownRefresh() {}, onPullDownRefresh() {},
methods: { methods: {
switchTab(index) { switchTab(index) {
this.tabIndex = index; this.tabIndex = index;
this.$nextTick(() => { this.$store.commit("system/messageTabIndex", index);
this.setTabHeight(); let currentTab = this.tabList[this.tabIndex];
}); currentTab.page = 1;
}, currentTab.list = [];
changeTab(e) { currentTab.more = true;
this.switchTab(e.detail.current); clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.loadList(index);
}, 100);
}, },
setTabHeight() { setTabHeight() {
let query = uni.createSelectorQuery().in(this); let query = uni.createSelectorQuery().in(this);
@ -129,6 +103,54 @@ export default {
} }
}); });
}, },
/**
* 加载分类
*/
async loadCate() {
await this.$models.system.notifyCate().then((cate) => {
cate.forEach((item) => {
this.tabList.push({
id: item.id,
name: item.title,
more: true,
page: 1,
list: [],
});
});
});
},
/**
* 加载列表
*/
loadList() {
let currentTab = this.tabList[this.tabIndex];
this.$models.system.notifyList(currentTab.id, currentTab.page).then((list) => {
if (list.length > 0) {
list.forEach((item) => {
currentTab.list.push({
id: item.id,
title: item.title,
date: item.times,
content: item.message,
});
});
currentTab.page++;
} else {
currentTab.more = false;
}
this.$nextTick(() => {
this.setTabHeight();
});
});
},
/**
* 详情
*/
toDetail(detail) {
this.showDetail = true;
this.detail.title = detail.title;
this.detail.content = detail.content;
},
}, },
}; };
</script> </script>
@ -190,4 +212,8 @@ export default {
} }
} }
} }
.message-box {
max-height: 400rpx;
overflow-y: scroll;
}
</style> </style>

232
src/pages/order/appeal.vue Normal file
View File

@ -0,0 +1,232 @@
<template>
<app-layout title="退款申诉">
<view class="common-form-container explain">
<view class="textarea-item">
<view class="title-box">
<text>申诉说明</text>
<text class="desc">您还可输入{{ maxlength - content.length }}个字</text>
</view>
<view class="textarea-box">
<textarea
v-model="content"
:maxlength="maxlength"
class="textarea"
placeholder="请您详细填写申诉说明"
placeholder-class="placeholder-style-3"
/>
</view>
</view>
<view class="upload-item">
<block v-for="(item, index) in images" :key="index">
<view class="image-box" @click="removeImage(index)">
<image class="image" :src="item" mode="aspectFill" />
</view>
</block>
<view class="image-box upload" @click="chooseImage">
<text class="iconfont icon-shangchuantupian"></text>
<text class="text">上传图片</text>
</view>
</view>
</view>
<view class="common-save-form-btn">
<view class="btn" @click="submit">提交</view>
</view>
</app-layout>
</template>
<script>
import AppLayout from "@/components/layout/layout";
export default {
name: "order-appeal",
data() {
return {
listType: "",
maxlength: 300,
id: 0,
content: "",
images: [],
};
},
components: {
AppLayout,
},
onLoad(e) {
if (e.list && e.id && e.id > 0) {
this.id = e.id;
this.listType = e.list;
} else {
return this.$utils.toast("参数错误").then(() => {
this.$utils.toPage("", {}, "back");
});
}
},
onShow() {},
onReady() {},
onReachBottom() {},
onPullDownRefresh() {},
methods: {
/**
* 删除图片
*/
removeImage(index) {
this.images.splice(index, 1);
},
/**
* 上传图片
*/
chooseImage() {
this.$utils.chooseImage(8).then((tempFiles) => {
tempFiles.forEach((item) => {
this.$models.system.upload(item.path).then((response) => {
this.images.push(response.img);
});
});
});
},
/**
* 提交
*/
submit() {
this.$models.order
.appealOrder({
request: {
api: "order.appeal." + this.listType,
data: {
id: this.id,
title: this.content,
img: this.images,
},
},
})
.then((response) => {
this.$utils.toast(response.msg).then(() => {
this.$utils.toPage("", {}, "back");
});
})
.catch((e) => {
this.$utils.toast(e);
});
},
},
};
</script>
<style lang="less" scoped>
.order-id {
width: 100%;
box-sizing: border-box;
background-color: #ffffff;
.title {
font-size: 28rpx;
color: #999999;
}
}
.order-id {
padding: 22rpx 40rpx;
margin-bottom: 18rpx;
.value {
font-size: 28rpx;
color: #000000;
}
}
.price {
width: 100%;
box-sizing: border-box;
padding: 40rpx;
margin-bottom: 18rpx;
background-color: #ffffff;
.title-box {
font-size: 28rpx;
color: #000000;
}
.price-box {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 20rpx;
.number {
font-size: 48rpx;
font-weight: bold;
color: #000000;
}
}
.modify-icon {
display: flex;
align-items: center;
flex-direction: column;
.iconfont {
font-size: 46rpx;
color: #999999;
}
.text {
display: inline-block;
font-size: 24rpx;
color: #999999;
margin-top: 6rpx;
}
}
}
.common-form-container.explain {
width: 100%;
margin-top: 0;
.textarea-item {
padding: 30rpx 40rpx;
.title-box {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.desc {
font-size: 24rpx;
color: #999999;
}
.textarea-box {
border: 0;
}
.textarea {
width: 100%;
padding: 20rpx 0;
font-style: 28rpx;
}
}
.upload-item {
padding: 0 40rpx 30rpx 40rpx;
}
}
.price-box {
.submit-price {
width: 100%;
height: 68rpx;
background: #7286f1;
text-align: center;
line-height: 68rpx;
font-size: 32rpx;
color: #ffffff;
}
.price-input {
display: flex;
justify-content: space-between;
margin: 35rpx 0 50rpx 0;
line-height: 72rpx;
.input-box {
display: flex;
}
.input {
width: 450rpx;
height: 72rpx;
border: 2rpx solid #d8d8d8;
box-sizing: border-box;
padding: 4rpx;
font-size: 30rpx;
font-weight: bold;
color: #000000;
text-align: center;
}
.iconfont {
margin-left: 18rpx;
}
}
}
</style>

View File

@ -107,22 +107,21 @@
</view> </view>
</view> </view>
</block> </block>
<block v-if="listType == 't1' || listType == 't3' || (listType == 't2' && order.orderType == 1)"> <view class="detail-section">
<view class="detail-section"> <text class="price-box">¥ {{ utils.formatNumber(order.price, 2) }}</text>
<text class="price-box">¥ {{ utils.formatNumber(order.price, 2) }}</text> </view>
</view>
</block>
</view> </view>
<view class="common-bottom-components" :style="{ bottom: pageConfig.safeAreaInsets.bottom + 'px' }"> <view class="common-bottom-components" :style="{ bottom: pageConfig.safeAreaInsets.bottom + 'px' }">
<view class="service" @click="utils.serviceActions()"> <view class="service" @click="showService = true">
<text class="iconfont icon-kefu"></text> <text class="iconfont icon-kefu"></text>
<text class="text">客服</text> <text class="text">客服</text>
</view> </view>
<view class="action"> <view class="action">
<order-action :order="order" @confirmPrice="showPriceModal(order.id)" /> <order-action :order="order" @confirmPrice="showPriceModal(order.id)" @refresh="refresh" />
</view> </view>
</view> </view>
<order-confirm-price v-show="showConfirmModal" @close="showConfirmModal = false" @confirm="finishOrder" /> <order-confirm-price v-show="showConfirmModal" @close="showConfirmModal = false" @confirm="finishOrder" />
<widget-service :showService="showService" @close="showService = false" />
</app-layout> </app-layout>
</template> </template>
@ -131,6 +130,7 @@ import AppLayout from "@/components/layout/layout";
import OrderAction from "@/components/order/action"; 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 WidgetService from "@/components/widgets/service";
export default { export default {
name: "order-detail", name: "order-detail",
data() { data() {
@ -144,6 +144,7 @@ export default {
typeTextBg: "", typeTextBg: "",
stateText: "", stateText: "",
stateTextColor: "", stateTextColor: "",
showService: false,
order: { order: {
address: {}, address: {},
}, },
@ -154,6 +155,7 @@ export default {
OrderAction, OrderAction,
GetAction, GetAction,
OrderConfirmPrice, OrderConfirmPrice,
WidgetService,
}, },
onLoad(e) { onLoad(e) {
this.pageConfig = getApp().globalData.pageConfig; this.pageConfig = getApp().globalData.pageConfig;
@ -164,9 +166,10 @@ export default {
return; return;
} }
this.listType = e.list; this.listType = e.list;
},
onShow() {
this.loadDetail(); this.loadDetail();
}, },
onShow() {},
onReady() {}, onReady() {},
onReachBottom() {}, onReachBottom() {},
onPullDownRefresh() {}, onPullDownRefresh() {},
@ -235,6 +238,9 @@ export default {
this.order = order; this.order = order;
}); });
}, },
refresh() {
this.loadDetail();
},
}, },
}; };
</script> </script>

View File

@ -9,6 +9,7 @@
v-model="keywords" v-model="keywords"
placeholder="输入订单编号/客户姓名/电话" placeholder="输入订单编号/客户姓名/电话"
placeholder-class="placeholder-style-3" placeholder-class="placeholder-style-3"
@input="inputKeywords"
/> />
</view> </view>
<view class="scroll-box"> <view class="scroll-box">
@ -39,7 +40,7 @@
<order-item :order="v"> <order-item :order="v">
<view class="order-action"> <view class="order-action">
<view class="price">¥ {{ v.price }}</view> <view class="price">¥ {{ v.price }}</view>
<order-action :order="v" @confirmPrice="showPriceModal(v.id)" /> <order-action :order="v" @confirmPrice="showPriceModal(v.id)" @refresh="refresh" />
</view> </view>
</order-item> </order-item>
</view> </view>
@ -94,6 +95,7 @@ export default {
}, },
], ],
currentId: 0, currentId: 0,
keywordsTimer: null,
keywords: "", keywords: "",
}; };
}, },
@ -179,6 +181,7 @@ export default {
data: { data: {
page: currentTab.page, page: currentTab.page,
status: currentTab.status, status: currentTab.status,
key: this.keywords,
}, },
}, },
listType: currentTab.listType, listType: currentTab.listType,
@ -200,6 +203,15 @@ export default {
let currentTab = this.tabList[this.tabIndex]; let currentTab = this.tabList[this.tabIndex];
this.$utils.toPage("/pages/order/detail?list=" + currentTab.listType + "&id=" + id); this.$utils.toPage("/pages/order/detail?list=" + currentTab.listType + "&id=" + id);
}, },
refresh() {
this.switchTab(this.tabIndex);
},
inputKeywords(e) {
clearTimeout(this.keywordsTimer);
this.keywordsTimer = setTimeout(() => {
this.loadData();
}, 1000);
},
}, },
}; };
</script> </script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,7 +1,13 @@
export default { export default {
namespaced: true, namespaced: true,
state: {}, state: {
messageTabIndex: 0,
},
getters: {}, getters: {},
mutations: {}, mutations: {
messageTabIndex(state, data) {
state.messageTabIndex = data;
}
},
actions: {} actions: {}
} }