到家服务
This commit is contained in:
parent
fa8d4cc38d
commit
3ed8bd5327
26
api/homeService.js
Normal file
26
api/homeService.js
Normal file
@ -0,0 +1,26 @@
|
||||
export const apiArr = {
|
||||
// 到家服务
|
||||
categoryList: "/api/v2/wechat/service/category/list", // 服务分类列表
|
||||
serviceList: "/api/v2/wechat/service/list", // 服务商品列表
|
||||
serviceInfo: "/api/v2/wechat/service/info", // 服务详情(含SKU+师傅)
|
||||
orderCreate: "/api/v2/wechat/service/order/create", // 下单(定金单)
|
||||
orderList: "/api/v2/wechat/service/order/list", // 我的服务订单列表
|
||||
orderInfo: "/api/v2/wechat/service/order/info", // 服务订单详情
|
||||
orderCancel: "/api/v2/wechat/service/order/cancel", // 取消服务订单
|
||||
preorder: "/api/v2/wechat/service/order/preorder", // 预下单(拉卡拉)
|
||||
tradeQuery: "/api/v2/wechat/service/order/trade-query", // 查单
|
||||
// 师傅端
|
||||
workerOrderList: "/api/v2/wechat/service/worker/order-list", // 师傅服务单列表
|
||||
workerOrderStatus: "/api/v2/wechat/service/worker/order-status", // 师傅更新状态
|
||||
workerExtraOrder: "/api/v2/wechat/service/worker/extra-order", // 师傅代客补差单
|
||||
workerMyInfo: "/api/v2/wechat/service/worker/my-info", // 解析当前用户的师傅信息
|
||||
// 家政合同(客户端)
|
||||
contractList: "/api/v2/wechat/service/contract/list", // 我的家政合同列表
|
||||
contractInfo: "/api/v2/wechat/service/contract/info", // 家政合同详情
|
||||
// 月账单
|
||||
workerMonthlyBillList: "/api/v2/wechat/service/worker/monthly-bill-list", // 师傅月账单列表
|
||||
workerPushBill: "/api/v2/wechat/service/worker/push-bill", // 师傅推送/拒绝月账单
|
||||
userMonthlyBillList: "/api/v2/wechat/service/user/monthly-bill-list", // 用户月账单列表
|
||||
userMonthlyBillPreOrder: "/api/v2/wechat/service/user/monthly-bill/preorder", // 用户月账单预下单
|
||||
userMonthlyBillTradeQuery: "/api/v2/wechat/service/user/monthly-bill/trade-query", // 用户月账单查单
|
||||
}
|
||||
@ -91,6 +91,9 @@ export default {
|
||||
this.currentCommunity = e
|
||||
uni.setStorageSync('changeCommData', { id: e.community_id, name: e.name });
|
||||
uni.setStorageSync('currentCommunityAddr', e.addr);
|
||||
// 缓存该小区已绑定房产的门牌号(room_name,如「1栋1单元1层103」),供到家服务等下单页缺省填写
|
||||
const owner = (e.room_owner_list && e.room_owner_list.length) ? e.room_owner_list[0] : null
|
||||
uni.setStorageSync('currentRoomNo', owner && owner.room_name ? owner.room_name : '');
|
||||
NavgateTo("1")
|
||||
},
|
||||
},
|
||||
|
||||
79
packages/homeService/contractDetail/index.vue
Normal file
79
packages/homeService/contractDetail/index.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="hcd-page" v-if="info.id">
|
||||
<view class="hcd-card">
|
||||
<view class="hcd-status" :class="'st' + info.status">{{ statusText(info.status) }}</view>
|
||||
<view class="hcd-name">{{ info.contract_name }}</view>
|
||||
<view class="hcd-no">合同编号:{{ info.contract_no }}</view>
|
||||
</view>
|
||||
<view class="hcd-block">
|
||||
<view class="hcd-item"><text class="hcd-label">月薪</text><text class="hcd-val amount">¥{{ info.month_amount }}</text></view>
|
||||
<view class="hcd-item"><text class="hcd-label">账单日</text><text class="hcd-val">每月 {{ info.pay_day }} 号</text></view>
|
||||
<view class="hcd-item"><text class="hcd-label">结算方式</text><text class="hcd-val">{{ info.settle_mode === 1 ? '平台月账单' : '线下自付' }}</text></view>
|
||||
<view class="hcd-item"><text class="hcd-label">合同开始</text><text class="hcd-val">{{ fmtDate(info.start_date) }}</text></view>
|
||||
<view class="hcd-item"><text class="hcd-label">合同结束</text><text class="hcd-val">{{ fmtDate(info.end_date) }}</text></view>
|
||||
<view class="hcd-item"><text class="hcd-label">联系人</text><text class="hcd-val">{{ info.contact_name || '-' }}</text></view>
|
||||
<view class="hcd-item"><text class="hcd-label">联系电话</text><text class="hcd-val">{{ info.contact_phone || '-' }}</text></view>
|
||||
<view class="hcd-item"><text class="hcd-label">服务地址</text><text class="hcd-val">{{ info.service_address || '-' }}</text></view>
|
||||
<view class="hcd-item" v-if="info.remark"><text class="hcd-label">备注</text><text class="hcd-val">{{ info.remark }}</text></view>
|
||||
</view>
|
||||
<view class="hcd-block" v-if="info.file_url">
|
||||
<view class="hcd-file" @tap="openFile">查看已签合同</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, picUrl } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return { picUrl, id: 0, info: {} }
|
||||
},
|
||||
onLoad(options) {
|
||||
this.id = Number(options.id)
|
||||
this.loadInfo()
|
||||
},
|
||||
methods: {
|
||||
loadInfo() {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.contractInfo, 'POST', { id: this.id, user_id: userId }, {}, false).then(res => {
|
||||
this.info = res || {}
|
||||
})
|
||||
},
|
||||
statusText(s) {
|
||||
const map = { 1: '待签署', 2: '生效中', 3: '已到期', 4: '已解除', 5: '线下结算' }
|
||||
return map[s] || ''
|
||||
},
|
||||
fmtDate(v) {
|
||||
return v ? String(v).slice(0, 10) : '-'
|
||||
},
|
||||
openFile() {
|
||||
const url = this.info.file_url.startsWith('http') ? this.info.file_url : this.picUrl + this.info.file_url
|
||||
uni.downloadFile({
|
||||
url,
|
||||
success: (d) => {
|
||||
uni.openDocument({ filePath: d.tempFilePath, showMenu: true })
|
||||
},
|
||||
fail: () => uni.showToast({ title: '打开失败', icon: 'none' })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hcd-page { background: #f5f5f5; min-height: 100vh; padding: 20rpx; }
|
||||
.hcd-card { background: #fff; border-radius: 16rpx; padding: 28rpx; margin-bottom: 20rpx; }
|
||||
.hcd-status { font-size: 26rpx; color: #FF370B; margin-bottom: 12rpx; }
|
||||
.hcd-status.st2 { color: #07c160; }
|
||||
.hcd-status.st3, .hcd-status.st4 { color: #999; }
|
||||
.hcd-name { font-size: 34rpx; color: #222; font-weight: 600; }
|
||||
.hcd-no { font-size: 26rpx; color: #888; margin-top: 10rpx; }
|
||||
.hcd-block { background: #fff; border-radius: 16rpx; padding: 8rpx 28rpx; margin-bottom: 20rpx; }
|
||||
.hcd-item { display: flex; justify-content: space-between; padding: 22rpx 0; border-bottom: 1rpx solid #f2f2f2; }
|
||||
.hcd-label { font-size: 28rpx; color: #888; }
|
||||
.hcd-val { font-size: 28rpx; color: #222; max-width: 460rpx; text-align: right; }
|
||||
.hcd-val.amount { color: #FF370B; font-weight: 600; }
|
||||
.hcd-file { text-align: center; color: #2b6cff; font-size: 28rpx; padding: 24rpx 0; }
|
||||
</style>
|
||||
152
packages/homeService/detail/index.vue
Normal file
152
packages/homeService/detail/index.vue
Normal file
@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<view class="hsd-page">
|
||||
<swiper class="hsd-swiper" autoplay circular v-if="carousel.length">
|
||||
<swiper-item v-for="(p, i) in carousel" :key="i">
|
||||
<image :src="p" mode="aspectFill" class="hsd-swiper-img" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<image v-else :src="picUrl + (info.cover_pic || '')" class="hsd-swiper-img" mode="aspectFill" />
|
||||
|
||||
<view class="hsd-main">
|
||||
<view class="hsd-name">{{ info.service_name }}</view>
|
||||
<view class="hsd-pricedesc">{{ info.price_desc }}</view>
|
||||
</view>
|
||||
|
||||
<!-- SKU 选择 -->
|
||||
<view class="hsd-block" v-if="skuList.length">
|
||||
<view class="hsd-block-tit">选择规格</view>
|
||||
<view class="hsd-sku-list">
|
||||
<view class="hsd-sku" :class="{ active: currentSku && currentSku.id === sku.id }"
|
||||
v-for="sku in skuList" :key="sku.id" @tap="selectSku(sku)">
|
||||
<view class="hsd-sku-name">{{ sku.sku_name }}</view>
|
||||
<view class="hsd-sku-price" v-if="isHousekeeping">月薪 ¥{{ sku.month_salary }}</view>
|
||||
<view class="hsd-sku-price" v-else>定金 ¥{{ sku.deposit }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 师傅选择 -->
|
||||
<view class="hsd-block" v-if="workerList.length">
|
||||
<view class="hsd-block-tit">选择师傅</view>
|
||||
<view class="hsd-worker-list">
|
||||
<view class="hsd-worker" :class="{ active: currentWorker && currentWorker.employee_id === w.employee_id }"
|
||||
v-for="w in workerList" :key="w.employee_id" @tap="selectWorker(w)">
|
||||
<image class="hsd-worker-img" :src="w.employee_image || defaultAvatar" mode="aspectFill" />
|
||||
<view class="hsd-worker-name">{{ w.employee_name }}</view>
|
||||
<view class="hsd-worker-exp">{{ w.expertise }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 详情图 -->
|
||||
<view class="hsd-block" v-if="detailPics.length">
|
||||
<view class="hsd-block-tit">服务详情</view>
|
||||
<image v-for="(p, i) in detailPics" :key="i" :src="p" mode="widthFix" class="hsd-detail-img" />
|
||||
</view>
|
||||
|
||||
<view class="hsd-bottom">
|
||||
<template v-if="isHousekeeping">
|
||||
<view class="hsd-bottom-price">月薪 <text>¥{{ currentSku ? currentSku.month_salary : '--' }}</text></view>
|
||||
<view class="hsd-bottom-btn" @tap="goConsult">咨询预约</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="hsd-bottom-price">定金 <text>¥{{ currentSku ? currentSku.deposit : '--' }}</text></view>
|
||||
<view class="hsd-bottom-btn" @tap="goOrder">立即预约</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, picUrl, NavgateTo } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
picUrl,
|
||||
defaultAvatar: 'https://static.hshuishang.com/defaultTx.png',
|
||||
id: 0,
|
||||
info: {},
|
||||
carousel: [],
|
||||
detailPics: [],
|
||||
skuList: [],
|
||||
workerList: [],
|
||||
currentSku: null,
|
||||
currentWorker: null
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.id = Number(options.id)
|
||||
this.loadInfo()
|
||||
},
|
||||
computed: {
|
||||
// 家政服务(原长期服务 service_type=2):走咨询签约,不付定金
|
||||
isHousekeeping() {
|
||||
return Number(this.info.service_type) === 2
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadInfo() {
|
||||
request(apiArr.serviceInfo, 'POST', { id: this.id }, {}, false).then(res => {
|
||||
this.info = res || {}
|
||||
this.carousel = (res.carousel ? res.carousel.split(',') : []).filter(Boolean).map(p => p.startsWith('http') ? p : this.picUrl + p)
|
||||
this.detailPics = (res.detail_pic ? res.detail_pic.split(',') : []).filter(Boolean).map(p => p.startsWith('http') ? p : this.picUrl + p)
|
||||
this.skuList = res.sku_list || []
|
||||
this.workerList = res.worker_list || []
|
||||
if (this.skuList.length) this.currentSku = this.skuList[0]
|
||||
if (this.workerList.length) this.currentWorker = this.workerList[0]
|
||||
})
|
||||
},
|
||||
selectSku(sku) { this.currentSku = sku },
|
||||
selectWorker(w) { this.currentWorker = w },
|
||||
goOrder() {
|
||||
if (!this.currentSku) { uni.showToast({ title: '请选择规格', icon: 'none' }); return }
|
||||
if (!this.currentWorker) { uni.showToast({ title: '请选择师傅', icon: 'none' }); return }
|
||||
const params = {
|
||||
service_info_id: this.id,
|
||||
sku_id: this.currentSku.id,
|
||||
employee_id: this.currentWorker.employee_id,
|
||||
service_name: this.info.service_name,
|
||||
deposit: this.currentSku.deposit
|
||||
}
|
||||
NavgateTo('/packages/homeService/order/index?params=' + encodeURIComponent(JSON.stringify(params)))
|
||||
},
|
||||
// 家政服务:先与商家客服沟通签约,不走定金下单
|
||||
goConsult() {
|
||||
const supplierId = this.info.supplier_id
|
||||
if (!supplierId) { uni.showToast({ title: '商家信息缺失', icon: 'none' }); return }
|
||||
// 客服列表依赖 merchantInfo.id,写入当前服务所属商家
|
||||
const mi = uni.getStorageSync('merchantInfo') || {}
|
||||
mi.id = supplierId
|
||||
uni.setStorageSync('merchantInfo', mi)
|
||||
NavgateTo('/packages/customerService/changeService/index')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hsd-page { background: #f5f5f5; min-height: 100vh; padding-bottom: 130rpx; }
|
||||
.hsd-swiper, .hsd-swiper-img { width: 100%; height: 520rpx; }
|
||||
.hsd-main { background: #fff; padding: 24rpx; }
|
||||
.hsd-name { font-size: 36rpx; font-weight: 600; color: #222; }
|
||||
.hsd-pricedesc { font-size: 26rpx; color: #FF370B; margin-top: 14rpx; }
|
||||
.hsd-block { background: #fff; margin-top: 16rpx; padding: 24rpx; }
|
||||
.hsd-block-tit { font-size: 30rpx; font-weight: 600; color: #222; margin-bottom: 18rpx; }
|
||||
.hsd-sku-list, .hsd-worker-list { display: flex; flex-wrap: wrap; gap: 18rpx; }
|
||||
.hsd-sku { border: 1rpx solid #eee; border-radius: 10rpx; padding: 16rpx 24rpx; }
|
||||
.hsd-sku.active { border-color: #FF370B; background: #FFF1ED; }
|
||||
.hsd-sku-name { font-size: 28rpx; color: #222; }
|
||||
.hsd-sku-price { font-size: 24rpx; color: #FF370B; margin-top: 8rpx; }
|
||||
.hsd-worker { width: 160rpx; display: flex; flex-direction: column; align-items: center; border: 1rpx solid #eee; border-radius: 10rpx; padding: 16rpx 8rpx; }
|
||||
.hsd-worker.active { border-color: #FF370B; background: #FFF1ED; }
|
||||
.hsd-worker-img { width: 100rpx; height: 100rpx; border-radius: 50%; background: #f0f0f0; }
|
||||
.hsd-worker-name { font-size: 26rpx; color: #222; margin-top: 10rpx; }
|
||||
.hsd-worker-exp { font-size: 20rpx; color: #999; margin-top: 4rpx; }
|
||||
.hsd-detail-img { width: 100%; display: block; }
|
||||
.hsd-bottom { position: fixed; left: 0; right: 0; bottom: 0; background: #fff; display: flex; align-items: center; padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.04); }
|
||||
.hsd-bottom-price { flex: 1; font-size: 26rpx; color: #333; }
|
||||
.hsd-bottom-price text { color: #FF370B; font-size: 36rpx; font-weight: 600; }
|
||||
.hsd-bottom-btn { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 30rpx; padding: 20rpx 60rpx; border-radius: 44rpx; }
|
||||
</style>
|
||||
124
packages/homeService/index/index.vue
Normal file
124
packages/homeService/index/index.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<view class="hs-page">
|
||||
<!-- 到家/家政 Tab -->
|
||||
<view class="hs-tabs">
|
||||
<view class="hs-tab" :class="{ active: serviceType === 1 }" @tap="switchType(1)">到家服务</view>
|
||||
<view class="hs-tab" :class="{ active: serviceType === 2 }" @tap="switchType(2)">家政服务</view>
|
||||
</view>
|
||||
|
||||
<view class="hs-body">
|
||||
<!-- 左侧分类 -->
|
||||
<scroll-view class="hs-cate" scroll-y>
|
||||
<view class="hs-cate-item" :class="{ active: currentCate === 0 }" @tap="selectCate(0)">全部</view>
|
||||
<view class="hs-cate-item" :class="{ active: currentCate === item.id }"
|
||||
v-for="item in categoryList" :key="item.id" @tap="selectCate(item.id)">
|
||||
{{ item.category_name }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右侧服务列表 -->
|
||||
<scroll-view class="hs-list" scroll-y @scrolltolower="loadMore">
|
||||
<view class="hs-card" v-for="item in serviceList" :key="item.id" @tap="toDetail(item)">
|
||||
<image class="hs-card-pic" :src="picUrl + item.cover_pic" mode="aspectFill" />
|
||||
<view class="hs-card-info">
|
||||
<view class="hs-card-name">{{ item.service_name }}</view>
|
||||
<view class="hs-card-desc">{{ item.price_desc }}</view>
|
||||
<view class="hs-card-foot">
|
||||
<text class="hs-card-tag">{{ serviceType === 1 ? '到家' : '家政' }}</text>
|
||||
<text class="hs-card-btn">查看</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="serviceList.length === 0" class="hs-empty">暂无服务</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, picUrl, NavgateTo } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
picUrl,
|
||||
serviceType: 1,
|
||||
categoryList: [],
|
||||
currentCate: 0,
|
||||
serviceList: [],
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
hasMore: true
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.loadCategory()
|
||||
this.loadList(true)
|
||||
},
|
||||
methods: {
|
||||
switchType(t) {
|
||||
if (this.serviceType === t) return
|
||||
this.serviceType = t
|
||||
this.currentCate = 0
|
||||
this.loadCategory()
|
||||
this.loadList(true)
|
||||
},
|
||||
selectCate(id) {
|
||||
this.currentCate = id
|
||||
this.loadList(true)
|
||||
},
|
||||
loadCategory() {
|
||||
request(apiArr.categoryList, 'POST', { service_type: this.serviceType }, {}, false).then(res => {
|
||||
this.categoryList = res.rows || []
|
||||
})
|
||||
},
|
||||
loadList(reset) {
|
||||
if (reset) {
|
||||
this.pageNum = 1
|
||||
this.hasMore = true
|
||||
this.serviceList = []
|
||||
}
|
||||
if (!this.hasMore) return
|
||||
request(apiArr.serviceList, 'POST', {
|
||||
service_type: this.serviceType,
|
||||
category_id: this.currentCate,
|
||||
page_num: this.pageNum,
|
||||
page_size: this.pageSize
|
||||
}, {}, false).then(res => {
|
||||
const rows = res.rows || []
|
||||
this.serviceList = this.serviceList.concat(rows)
|
||||
this.hasMore = rows.length === this.pageSize
|
||||
this.pageNum++
|
||||
})
|
||||
},
|
||||
loadMore() {
|
||||
this.loadList(false)
|
||||
},
|
||||
toDetail(item) {
|
||||
NavgateTo('/packages/homeService/detail/index?id=' + item.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hs-page { display: flex; flex-direction: column; height: 100vh; background: #f5f5f5; }
|
||||
.hs-tabs { display: flex; background: #fff; }
|
||||
.hs-tab { flex: 1; text-align: center; padding: 26rpx 0; font-size: 28rpx; color: #666; }
|
||||
.hs-tab.active { color: #FF370B; font-weight: 600; border-bottom: 4rpx solid #FF370B; }
|
||||
.hs-body { flex: 1; display: flex; overflow: hidden; }
|
||||
.hs-cate { width: 180rpx; background: #fafafa; height: 100%; }
|
||||
.hs-cate-item { padding: 28rpx 16rpx; font-size: 26rpx; color: #555; text-align: center; }
|
||||
.hs-cate-item.active { background: #fff; color: #FF370B; font-weight: 600; }
|
||||
.hs-list { flex: 1; padding: 20rpx; box-sizing: border-box; }
|
||||
.hs-card { display: flex; background: #fff; border-radius: 12rpx; padding: 16rpx; margin-bottom: 16rpx; }
|
||||
.hs-card-pic { width: 200rpx; height: 200rpx; border-radius: 8rpx; flex-shrink: 0; background: #f0f0f0; }
|
||||
.hs-card-info { flex: 1; margin-left: 18rpx; display: flex; flex-direction: column; min-width: 0; }
|
||||
.hs-card-name { font-size: 30rpx; color: #222; font-weight: 600; }
|
||||
.hs-card-desc { font-size: 24rpx; color: #999; margin-top: 12rpx; flex: 1; }
|
||||
.hs-card-foot { display: flex; align-items: center; justify-content: space-between; }
|
||||
.hs-card-tag { font-size: 20rpx; color: #FF370B; border: 1rpx solid #FFD9CD; border-radius: 6rpx; padding: 2rpx 10rpx; }
|
||||
.hs-card-btn { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 24rpx; padding: 8rpx 28rpx; border-radius: 30rpx; }
|
||||
.hs-empty { text-align: center; color: #999; font-size: 26rpx; padding: 80rpx 0; }
|
||||
</style>
|
||||
66
packages/homeService/myContracts/index.vue
Normal file
66
packages/homeService/myContracts/index.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<view class="hsc-page">
|
||||
<view class="hsc-list">
|
||||
<view class="hsc-card" v-for="c in contracts" :key="c.id" @tap="toDetail(c)">
|
||||
<view class="hsc-head">
|
||||
<text class="hsc-no">{{ c.contract_no }}</text>
|
||||
<text class="hsc-status" :class="'st' + c.status">{{ statusText(c.status) }}</text>
|
||||
</view>
|
||||
<view class="hsc-body">
|
||||
<view class="hsc-name">{{ c.contract_name }}</view>
|
||||
<view class="hsc-row">月薪:<text class="hsc-amount">¥{{ c.month_amount }}</text></view>
|
||||
<view class="hsc-row">结算:{{ c.settle_mode === 1 ? '平台月账单' : '线下自付' }}</view>
|
||||
<view class="hsc-row">合同期:{{ fmtDate(c.start_date) }} ~ {{ fmtDate(c.end_date) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="contracts.length === 0" class="hsc-empty">暂无家政合同</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, NavgateTo } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return { contracts: [] }
|
||||
},
|
||||
onShow() {
|
||||
this.loadContracts()
|
||||
},
|
||||
methods: {
|
||||
loadContracts() {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.contractList, 'POST', { user_id: userId, page_num: 1, page_size: 50 }, {}, false).then(res => {
|
||||
this.contracts = res.rows || []
|
||||
})
|
||||
},
|
||||
statusText(s) {
|
||||
const map = { 1: '待签署', 2: '生效中', 3: '已到期', 4: '已解除', 5: '线下结算' }
|
||||
return map[s] || ''
|
||||
},
|
||||
fmtDate(v) {
|
||||
return v ? String(v).slice(0, 10) : ''
|
||||
},
|
||||
toDetail(c) {
|
||||
NavgateTo('/packages/homeService/contractDetail/index?id=' + c.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hsc-page { background: #f5f5f5; min-height: 100vh; padding: 20rpx; }
|
||||
.hsc-card { background: #fff; border-radius: 16rpx; padding: 24rpx; margin-bottom: 20rpx; }
|
||||
.hsc-head { display: flex; justify-content: space-between; align-items: center; border-bottom: 1rpx solid #f2f2f2; padding-bottom: 16rpx; }
|
||||
.hsc-no { font-size: 26rpx; color: #888; }
|
||||
.hsc-status { font-size: 26rpx; color: #FF370B; }
|
||||
.hsc-status.st2 { color: #07c160; }
|
||||
.hsc-status.st3, .hsc-status.st4 { color: #999; }
|
||||
.hsc-body { padding-top: 16rpx; }
|
||||
.hsc-name { font-size: 30rpx; color: #222; font-weight: 600; margin-bottom: 12rpx; }
|
||||
.hsc-row { font-size: 26rpx; color: #555; margin-top: 8rpx; }
|
||||
.hsc-amount { color: #FF370B; font-weight: 600; }
|
||||
.hsc-empty { text-align: center; color: #999; font-size: 28rpx; padding-top: 120rpx; }
|
||||
</style>
|
||||
95
packages/homeService/myMonthlyBills/index.vue
Normal file
95
packages/homeService/myMonthlyBills/index.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<view class="hmb-page">
|
||||
<view class="hmb-list">
|
||||
<view class="hmb-card" v-for="b in bills" :key="b.id">
|
||||
<view class="hmb-head">
|
||||
<text class="hmb-no">{{ b.bill_no }}</text>
|
||||
<text class="hmb-status" :class="b.pay_status === 1 ? 'status-warn' : b.pay_status === 2 ? 'status-ok' : ''">{{ statusText(b.pay_status) }}</text>
|
||||
</view>
|
||||
<view class="hmb-body" @tap="toContract(b)">
|
||||
<image class="hmb-pic" :src="picUrl + (b.service_pic || '')" mode="aspectFill" />
|
||||
<view class="hmb-info">
|
||||
<view class="hmb-name">{{ b.service_name }}</view>
|
||||
<view class="hmb-month">{{ b.bill_month }} 月度账单</view>
|
||||
<view class="hmb-amount">¥{{ b.amount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hmb-foot">
|
||||
<view class="hmb-link" @tap.stop="toContract(b)">查看合同 ›</view>
|
||||
<view class="hmb-pay" v-if="b.pay_status === 1" @tap.stop="payBill(b)">去支付</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="bills.length === 0" class="hmb-empty">暂无待支付月账单</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, picUrl, NavgateTo } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return { picUrl, bills: [] }
|
||||
},
|
||||
onShow() {
|
||||
this.loadBills()
|
||||
},
|
||||
methods: {
|
||||
loadBills() {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.userMonthlyBillList, 'POST', { user_id: userId, page_num: 1, page_size: 50 }, {}, false).then(res => {
|
||||
this.bills = res.rows || []
|
||||
})
|
||||
},
|
||||
statusText(payStatus) {
|
||||
return payStatus === 1 ? '待支付' : payStatus === 2 ? '已支付' : payStatus === 3 ? '已退款' : ''
|
||||
},
|
||||
toContract(b) {
|
||||
NavgateTo('/packages/homeService/contractDetail/index?id=' + b.contract_id)
|
||||
},
|
||||
payBill(b) {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.userMonthlyBillPreOrder, 'POST', { bill_id: b.id, user_id: userId, trans_type: '71' }).then(pay => {
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
timeStamp: pay.timeStamp,
|
||||
nonceStr: pay.nonceStr,
|
||||
package: pay.package,
|
||||
signType: pay.signType || 'RSA',
|
||||
paySign: pay.paySign,
|
||||
success: () => {
|
||||
request(apiArr.userMonthlyBillTradeQuery, 'POST', { bill_id: b.id }, {}, false).finally(() => {
|
||||
uni.showToast({ title: '支付成功', icon: 'none' })
|
||||
this.loadBills()
|
||||
})
|
||||
},
|
||||
fail: () => { uni.showToast({ title: '支付已取消', icon: 'none' }) }
|
||||
})
|
||||
}).catch(err => {
|
||||
uni.showToast({ title: err.errMsg || '发起支付失败', icon: 'none' })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hmb-page { background: #f5f5f5; min-height: 100vh; padding: 20rpx; box-sizing: border-box; }
|
||||
.hmb-list {}
|
||||
.hmb-card { background: #fff; border-radius: 12rpx; padding: 20rpx; margin-bottom: 18rpx; border-left: 6rpx solid #FF370B; }
|
||||
.hmb-head { display: flex; justify-content: space-between; align-items: center; font-size: 24rpx; color: #999; margin-bottom: 16rpx; }
|
||||
.hmb-status { font-size: 26rpx; }
|
||||
.status-warn { color: #FF9800; }
|
||||
.status-ok { color: #4CAF50; }
|
||||
.hmb-body { display: flex; }
|
||||
.hmb-pic { width: 150rpx; height: 150rpx; border-radius: 8rpx; background: #f0f0f0; flex-shrink: 0; }
|
||||
.hmb-info { flex: 1; margin-left: 18rpx; display: flex; flex-direction: column; }
|
||||
.hmb-name { font-size: 30rpx; color: #222; font-weight: 600; }
|
||||
.hmb-month { font-size: 24rpx; color: #666; margin-top: 8rpx; }
|
||||
.hmb-amount { font-size: 32rpx; color: #FF370B; font-weight: 600; margin-top: auto; }
|
||||
.hmb-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 16rpx; }
|
||||
.hmb-link { font-size: 24rpx; color: #666; }
|
||||
.hmb-pay { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 26rpx; padding: 12rpx 40rpx; border-radius: 40rpx; margin-left: auto; }
|
||||
.hmb-empty { text-align: center; color: #999; font-size: 26rpx; padding: 80rpx 0; }
|
||||
</style>
|
||||
108
packages/homeService/myOrders/index.vue
Normal file
108
packages/homeService/myOrders/index.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<view class="hsm-page">
|
||||
<view class="hsm-list">
|
||||
<view class="hsm-card" v-for="o in orders" :key="o.id">
|
||||
<view class="hsm-head">
|
||||
<text class="hsm-no">{{ o.order_no }}</text>
|
||||
<text class="hsm-status">{{ statusText(o) }}</text>
|
||||
</view>
|
||||
<view class="hsm-body" @tap="toDetail(o)">
|
||||
<image class="hsm-pic" :src="picUrl + (o.service_pic || '')" mode="aspectFill" />
|
||||
<view class="hsm-info">
|
||||
<view class="hsm-name">{{ o.service_name }}</view>
|
||||
<view class="hsm-kind">{{ kindText(o.order_kind) }}</view>
|
||||
<view class="hsm-amount">¥{{ o.amount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hsm-foot" v-if="o.pay_status === 1 && o.status !== 5 && o.status !== 4">
|
||||
<view class="hsm-cancel" @tap="cancelOrder(o)">取消订单</view>
|
||||
<view class="hsm-pay" @tap="payOrder(o)">去支付</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="orders.length === 0" class="hsm-empty">暂无服务订单</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, picUrl, NavgateTo } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return { picUrl, orders: [] }
|
||||
},
|
||||
onShow() {
|
||||
this.loadOrders()
|
||||
},
|
||||
methods: {
|
||||
loadOrders() {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.orderList, 'POST', { user_id: userId, page_num: 1, page_size: 50 }, {}, false).then(res => {
|
||||
this.orders = res.rows || []
|
||||
})
|
||||
},
|
||||
kindText(k) {
|
||||
return k === 1 ? '定金/上门费' : k === 2 ? '补差/尾款' : k === 3 ? '月账单' : ''
|
||||
},
|
||||
statusText(o) {
|
||||
if (o.status === 5) return '已取消'
|
||||
if (o.status === 4) return '已完成'
|
||||
if (o.pay_status === 1) return '待支付'
|
||||
const map = { 1: '待上门', 2: '服务中', 3: '待补款' }
|
||||
return map[o.status] || ''
|
||||
},
|
||||
toDetail(o) {
|
||||
NavgateTo('/packages/homeService/orderDetail/index?id=' + o.id)
|
||||
},
|
||||
cancelOrder(o) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定取消该订单吗?',
|
||||
success: (r) => {
|
||||
if (!r.confirm) return
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.orderCancel, 'POST', { id: o.id, user_id: Number(userId) || 0 }).then(() => {
|
||||
uni.showToast({ title: '已取消', icon: 'none' })
|
||||
this.loadOrders()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
payOrder(o) {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.preorder, 'POST', { order_id: o.id, user_id: userId, trans_type: '71' }).then(pay => {
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
timeStamp: pay.timeStamp,
|
||||
nonceStr: pay.nonceStr,
|
||||
package: pay.package,
|
||||
signType: pay.signType || 'RSA',
|
||||
paySign: pay.paySign,
|
||||
success: () => {
|
||||
request(apiArr.tradeQuery, 'POST', { order_id: o.id }, {}, false).finally(() => this.loadOrders())
|
||||
},
|
||||
fail: () => { uni.showToast({ title: '支付已取消', icon: 'none' }) }
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hsm-page { background: #f5f5f5; min-height: 100vh; padding: 20rpx; box-sizing: border-box; }
|
||||
.hsm-card { background: #fff; border-radius: 12rpx; padding: 20rpx; margin-bottom: 18rpx; }
|
||||
.hsm-head { display: flex; justify-content: space-between; align-items: center; font-size: 24rpx; color: #999; margin-bottom: 16rpx; }
|
||||
.hsm-status { color: #FF370B; }
|
||||
.hsm-body { display: flex; }
|
||||
.hsm-pic { width: 150rpx; height: 150rpx; border-radius: 8rpx; background: #f0f0f0; flex-shrink: 0; }
|
||||
.hsm-info { flex: 1; margin-left: 18rpx; display: flex; flex-direction: column; }
|
||||
.hsm-name { font-size: 30rpx; color: #222; font-weight: 600; }
|
||||
.hsm-kind { font-size: 24rpx; color: #999; margin-top: 10rpx; flex: 1; }
|
||||
.hsm-amount { font-size: 32rpx; color: #FF370B; font-weight: 600; }
|
||||
.hsm-foot { display: flex; justify-content: flex-end; align-items: center; margin-top: 16rpx; }
|
||||
.hsm-cancel { border: 1rpx solid #ccc; color: #666; font-size: 26rpx; padding: 11rpx 36rpx; border-radius: 40rpx; margin-right: 20rpx; }
|
||||
.hsm-pay { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 26rpx; padding: 12rpx 40rpx; border-radius: 40rpx; }
|
||||
.hsm-empty { text-align: center; color: #999; font-size: 26rpx; padding: 80rpx 0; }
|
||||
</style>
|
||||
221
packages/homeService/order/index.vue
Normal file
221
packages/homeService/order/index.vue
Normal file
@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<view class="hso-page">
|
||||
<view class="hso-card">
|
||||
<view class="hso-svc">{{ params.service_name }}</view>
|
||||
<view class="hso-deposit">定金 ¥{{ params.deposit }}</view>
|
||||
</view>
|
||||
<view class="hso-form">
|
||||
<view class="hso-row">
|
||||
<text class="hso-label">联系人</text>
|
||||
<input class="hso-input" v-model="contactName" placeholder="请输入联系人" />
|
||||
</view>
|
||||
<view class="hso-row">
|
||||
<text class="hso-label">联系电话</text>
|
||||
<input class="hso-input" type="number" v-model="contactPhone" placeholder="请输入联系电话" maxlength="11" />
|
||||
</view>
|
||||
<view class="hso-row">
|
||||
<text class="hso-label">小区地址</text>
|
||||
<input class="hso-input" v-model="serviceAddress" placeholder="请选择或输入小区地址" />
|
||||
<text class="hso-map-btn" @tap="chooseLocation">地图选点</text>
|
||||
</view>
|
||||
<view class="hso-row">
|
||||
<text class="hso-label">门牌号</text>
|
||||
<input class="hso-input" v-model="houseNumber" placeholder="如:1栋1单元103室" />
|
||||
</view>
|
||||
<view class="hso-row" @tap="showDate = true">
|
||||
<text class="hso-label">上门时间</text>
|
||||
<text class="hso-input" :class="{ ph: !serviceTime }">{{ serviceTime || '请选择上门时间' }}</text>
|
||||
</view>
|
||||
<view class="hso-row hso-row--col">
|
||||
<text class="hso-label">备注</text>
|
||||
<textarea class="hso-textarea" v-model="remark" placeholder="选填" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="hso-bottom">
|
||||
<view class="hso-bottom-price">定金 <text>¥{{ params.deposit }}</text></view>
|
||||
<view class="hso-bottom-btn" @tap="submit">提交并支付</view>
|
||||
</view>
|
||||
|
||||
<u-datetime-picker :show="showDate" :value="dateValue" mode="datetime" @confirm="onDate" @cancel="showDate = false" @close="showDate = false" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, NavgateTo, isPhone } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
import { apiArr as commApi } from '@/api/community'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
params: {},
|
||||
contactName: '',
|
||||
contactPhone: '',
|
||||
serviceAddress: '',
|
||||
houseNumber: '',
|
||||
serviceTime: '',
|
||||
dateValue: Date.now(),
|
||||
remark: '',
|
||||
showDate: false,
|
||||
submitting: false
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options.params) {
|
||||
try { this.params = JSON.parse(decodeURIComponent(options.params)) } catch (e) { this.params = {} }
|
||||
}
|
||||
// 先用本地缓存兜底(秒显),再异步拉后台房产数据覆盖为准确值
|
||||
this.fillFromStorage()
|
||||
this.loadBoundHouse()
|
||||
// 默认上门时间:当前时间 3 小时之后的整点
|
||||
this.initDefaultTime()
|
||||
},
|
||||
methods: {
|
||||
// 本地缓存兜底:小区地址(详细地址在前 + 小区名)、门牌号
|
||||
fillFromStorage() {
|
||||
const addr = uni.getStorageSync('currentCommunityAddr')
|
||||
const comm = uni.getStorageSync('changeCommData')
|
||||
const commName = (comm && comm.name) ? comm.name : ''
|
||||
if (addr) {
|
||||
this.serviceAddress = (addr + ' ' + commName).trim()
|
||||
} else if (commName) {
|
||||
this.serviceAddress = commName
|
||||
}
|
||||
const roomNo = uni.getStorageSync('currentRoomNo')
|
||||
if (roomNo) this.houseNumber = roomNo
|
||||
},
|
||||
// 拉取后台已绑定房产:用真实小区地址 + room_name 填充地址与门牌
|
||||
loadBoundHouse() {
|
||||
const loc = uni.getStorageSync('location') || {}
|
||||
const comm = uni.getStorageSync('changeCommData')
|
||||
request(commApi.commInfo, 'POST', {
|
||||
user_id: uni.getStorageSync('userId'),
|
||||
longitude: loc.lng,
|
||||
latitude: loc.lat,
|
||||
page_num: 1,
|
||||
page_size: 20
|
||||
}, { silent: false }).then(res => {
|
||||
const rows = (res && res.rows) ? res.rows : []
|
||||
if (!rows.length) return
|
||||
// 优先匹配当前选中的小区,否则取第一个
|
||||
let target = null
|
||||
if (comm && comm.id) target = rows.find(r => r.community_id === comm.id)
|
||||
if (!target) target = rows[0]
|
||||
const commName = target.name || ''
|
||||
if (target.addr) {
|
||||
this.serviceAddress = (target.addr + ' ' + commName).trim()
|
||||
} else if (commName) {
|
||||
this.serviceAddress = commName
|
||||
}
|
||||
const owner = (target.room_owner_list && target.room_owner_list.length) ? target.room_owner_list[0] : null
|
||||
if (owner && owner.room_name) this.houseNumber = owner.room_name
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 默认上门时间 = 当前时间 + 3 小时,并向上取整到整点
|
||||
initDefaultTime() {
|
||||
const d = new Date()
|
||||
d.setHours(d.getHours() + 3)
|
||||
// 有分/秒/毫秒则进位到下一个整点
|
||||
if (d.getMinutes() > 0 || d.getSeconds() > 0 || d.getMilliseconds() > 0) {
|
||||
d.setHours(d.getHours() + 1)
|
||||
}
|
||||
d.setMinutes(0, 0, 0)
|
||||
this.dateValue = d.getTime()
|
||||
this.serviceTime = this.formatTime(d)
|
||||
},
|
||||
formatTime(d) {
|
||||
const p = n => String(n).padStart(2, '0')
|
||||
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`
|
||||
},
|
||||
// 地图选点:选择后回填地址(详细地址在前,小区/点位名称在后)
|
||||
chooseLocation() {
|
||||
const loc = uni.getStorageSync('location') || {}
|
||||
uni.chooseLocation({
|
||||
latitude: loc.lat,
|
||||
longitude: loc.lng,
|
||||
success: (res) => {
|
||||
const detail = res.name ? (res.address + ' ' + res.name) : res.address
|
||||
this.serviceAddress = (detail || '').trim()
|
||||
},
|
||||
fail: (err) => {
|
||||
if (err && err.errMsg && err.errMsg.indexOf('cancel') === -1) {
|
||||
uni.showToast({ title: '地图选点失败,请检查定位权限', icon: 'none' })
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
onDate(e) {
|
||||
const d = new Date(e.value)
|
||||
this.dateValue = d.getTime()
|
||||
this.serviceTime = this.formatTime(d)
|
||||
this.showDate = false
|
||||
},
|
||||
submit() {
|
||||
if (!this.contactName) { uni.showToast({ title: '请输入联系人', icon: 'none' }); return }
|
||||
if (!isPhone(this.contactPhone)) { uni.showToast({ title: '联系电话格式不正确', icon: 'none' }); return }
|
||||
if (!this.serviceAddress) { uni.showToast({ title: '请选择或输入小区地址', icon: 'none' }); return }
|
||||
if (!this.houseNumber) { uni.showToast({ title: '请输入门牌号', icon: 'none' }); return }
|
||||
if (this.submitting) return
|
||||
this.submitting = true
|
||||
const userId = uni.getStorageSync('userId')
|
||||
const fullAddress = (this.serviceAddress + ' ' + this.houseNumber).trim()
|
||||
request(apiArr.orderCreate, 'POST', {
|
||||
user_id: userId,
|
||||
service_info_id: this.params.service_info_id,
|
||||
sku_id: this.params.sku_id,
|
||||
employee_id: this.params.employee_id,
|
||||
service_address: fullAddress,
|
||||
contact_name: this.contactName,
|
||||
contact_phone: this.contactPhone,
|
||||
service_time: this.serviceTime,
|
||||
remark: this.remark
|
||||
}).then(res => {
|
||||
this.payOrder(res.id, userId)
|
||||
}).catch(() => { this.submitting = false })
|
||||
},
|
||||
payOrder(orderId, userId) {
|
||||
request(apiArr.preorder, 'POST', { order_id: orderId, user_id: userId, trans_type: '71' }).then(pay => {
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
timeStamp: pay.timeStamp,
|
||||
nonceStr: pay.nonceStr,
|
||||
package: pay.package,
|
||||
signType: pay.signType || 'RSA',
|
||||
paySign: pay.paySign,
|
||||
success: () => {
|
||||
// 支付成功后查单回写
|
||||
request(apiArr.tradeQuery, 'POST', { order_id: orderId }, {}, false).finally(() => {
|
||||
uni.redirectTo({ url: '/packages/homeService/myOrders/index' })
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
this.submitting = false
|
||||
uni.showToast({ title: '支付已取消', icon: 'none' })
|
||||
uni.redirectTo({ url: '/packages/homeService/myOrders/index' })
|
||||
}
|
||||
})
|
||||
}).catch(() => { this.submitting = false })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hso-page { background: #f5f5f5; min-height: 100vh; padding-bottom: 130rpx; }
|
||||
.hso-card { background: #fff; padding: 28rpx 24rpx; display: flex; align-items: center; justify-content: space-between; }
|
||||
.hso-svc { font-size: 30rpx; color: #222; font-weight: 600; }
|
||||
.hso-deposit { font-size: 30rpx; color: #FF370B; font-weight: 600; }
|
||||
.hso-form { background: #fff; margin-top: 16rpx; padding: 0 24rpx; }
|
||||
.hso-row { display: flex; align-items: center; padding: 26rpx 0; border-bottom: 1rpx solid #f2f2f2; }
|
||||
.hso-row--col { flex-direction: column; align-items: flex-start; }
|
||||
.hso-label { width: 160rpx; font-size: 28rpx; color: #333; flex-shrink: 0; }
|
||||
.hso-input { flex: 1; font-size: 28rpx; color: #222; }
|
||||
.hso-input.ph { color: #b7b7b7; }
|
||||
.hso-map-btn { flex-shrink: 0; margin-left: 16rpx; font-size: 26rpx; color: #FF370B; padding: 6rpx 16rpx; border: 1rpx solid #FF370B; border-radius: 28rpx; }
|
||||
.hso-textarea { width: 100%; height: 120rpx; font-size: 28rpx; margin-top: 12rpx; }
|
||||
.hso-bottom { position: fixed; left: 0; right: 0; bottom: 0; background: #fff; display: flex; align-items: center; padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.04); }
|
||||
.hso-bottom-price { flex: 1; font-size: 26rpx; color: #333; }
|
||||
.hso-bottom-price text { color: #FF370B; font-size: 36rpx; font-weight: 600; }
|
||||
.hso-bottom-btn { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 30rpx; padding: 20rpx 60rpx; border-radius: 44rpx; }
|
||||
</style>
|
||||
66
packages/homeService/orderDetail/index.vue
Normal file
66
packages/homeService/orderDetail/index.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<view class="hsod-page" v-if="order.id">
|
||||
<view class="hsod-status">{{ statusText }}</view>
|
||||
<view class="hsod-card">
|
||||
<image class="hsod-pic" :src="picUrl + (order.service_pic || '')" mode="aspectFill" />
|
||||
<view class="hsod-info">
|
||||
<view class="hsod-name">{{ order.service_name }}</view>
|
||||
<view class="hsod-kind">{{ kindText(order.order_kind) }}</view>
|
||||
<view class="hsod-amount">¥{{ order.amount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hsod-block">
|
||||
<view class="hsod-row"><text>订单号</text><text>{{ order.order_no }}</text></view>
|
||||
<view class="hsod-row"><text>联系人</text><text>{{ order.contact_name }}</text></view>
|
||||
<view class="hsod-row"><text>联系电话</text><text>{{ order.contact_phone }}</text></view>
|
||||
<view class="hsod-row"><text>服务地址</text><text>{{ order.service_address }}</text></view>
|
||||
<view class="hsod-row" v-if="order.service_time"><text>上门时间</text><text>{{ order.service_time }}</text></view>
|
||||
<view class="hsod-row" v-if="order.remark"><text>备注</text><text>{{ order.remark }}</text></view>
|
||||
<view class="hsod-row"><text>支付状态</text><text>{{ order.pay_status === 2 ? '已支付' : '待支付' }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, picUrl } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return { picUrl, order: {} }
|
||||
},
|
||||
onLoad(options) {
|
||||
request(apiArr.orderInfo, 'POST', { id: Number(options.id) }, {}, false).then(res => {
|
||||
this.order = res || {}
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
statusText() {
|
||||
const o = this.order
|
||||
if (o.pay_status === 1) return '待支付'
|
||||
const map = { 1: '待上门', 2: '服务中', 3: '待补款', 4: '已完成', 5: '已取消' }
|
||||
return map[o.status] || ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
kindText(k) {
|
||||
return k === 1 ? '定金/上门费' : k === 2 ? '补差/尾款' : k === 3 ? '月账单' : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hsod-page { background: #f5f5f5; min-height: 100vh; }
|
||||
.hsod-status { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 34rpx; font-weight: 600; padding: 40rpx 24rpx; }
|
||||
.hsod-card { background: #fff; display: flex; padding: 24rpx; margin-top: 16rpx; }
|
||||
.hsod-pic { width: 150rpx; height: 150rpx; border-radius: 8rpx; background: #f0f0f0; flex-shrink: 0; }
|
||||
.hsod-info { flex: 1; margin-left: 18rpx; display: flex; flex-direction: column; }
|
||||
.hsod-name { font-size: 30rpx; color: #222; font-weight: 600; }
|
||||
.hsod-kind { font-size: 24rpx; color: #999; margin-top: 10rpx; flex: 1; }
|
||||
.hsod-amount { font-size: 32rpx; color: #FF370B; font-weight: 600; }
|
||||
.hsod-block { background: #fff; margin-top: 16rpx; padding: 8rpx 24rpx; }
|
||||
.hsod-row { display: flex; justify-content: space-between; font-size: 26rpx; color: #333; padding: 22rpx 0; border-bottom: 1rpx solid #f5f5f5; }
|
||||
.hsod-row text:first-child { color: #999; }
|
||||
.hsod-row:last-child { border-bottom: none; }
|
||||
</style>
|
||||
307
packages/homeService/worker/index.vue
Normal file
307
packages/homeService/worker/index.vue
Normal file
@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<view class="hsw-page">
|
||||
<!-- 顶部Tab:全部/待上门/服务中/已完成/月账单 -->
|
||||
<view class="hsw-tabs">
|
||||
<view
|
||||
class="hsw-tab"
|
||||
:class="{ active: statusTab === item.v }"
|
||||
v-for="item in orderTabs"
|
||||
:key="item.v"
|
||||
@tap="switchStatus(item.v)"
|
||||
>{{ item.t }}</view>
|
||||
</view>
|
||||
<!-- 月账单子Tab -->
|
||||
<view class="hsw-tabs hsw-tabs-bill" v-if="showMonthlyBill">
|
||||
<view
|
||||
class="hsw-tab"
|
||||
:class="{ active: billTab === item.v }"
|
||||
v-for="item in billTabs"
|
||||
:key="item.v"
|
||||
@tap="switchBillTab(item.v)"
|
||||
>{{ item.t }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 列表区域 -->
|
||||
<scroll-view class="hsw-list" scroll-y>
|
||||
<!-- 普通服务单(非月账单模式) -->
|
||||
<block v-if="!showMonthlyBill">
|
||||
<view class="hsw-card" v-for="o in orders" :key="o.id">
|
||||
<view class="hsw-head">
|
||||
<text class="hsw-no">{{ o.order_no }}</text>
|
||||
<text class="hsw-kind">{{ kindText(o.order_kind) }}</text>
|
||||
</view>
|
||||
<view class="hsw-row"><text>服务</text><text>{{ o.service_name }}</text></view>
|
||||
<view class="hsw-row"><text>客户</text><text>{{ o.contact_name }} {{ o.contact_phone }}</text></view>
|
||||
<view class="hsw-row"><text>地址</text><text>{{ o.service_address }}</text></view>
|
||||
<view class="hsw-row"><text>金额</text><text class="hsw-amount">¥{{ o.amount }}</text></view>
|
||||
<view class="hsw-foot">
|
||||
<view class="hsw-btn ghost" v-if="o.status === 1" @tap="updateStatus(o, 2)">开始服务</view>
|
||||
<view class="hsw-btn" v-if="o.status === 2 && o.order_kind === 1" @tap="openExtra(o)">代客补差</view>
|
||||
<view class="hsw-btn ghost" v-if="o.status === 2" @tap="updateStatus(o, 4)">完成服务</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="orders.length === 0" class="hsw-empty">暂无服务单</view>
|
||||
</block>
|
||||
<!-- 月账单列表(师傅可见所有状态) -->
|
||||
<block v-else>
|
||||
<view class="hsw-card hsw-bill-card" v-for="b in bills" :key="b.id">
|
||||
<view class="hsw-head">
|
||||
<text class="hsw-no">{{ b.bill_no }}</text>
|
||||
<text class="hsw-kind" :class="b.push_status === 0 ? 'status-warn' : b.push_status === 1 ? 'status-info' : b.push_status === 2 ? 'status-ok' : 'status-cancel'">{{ pushStatusText(b.push_status) }}</text>
|
||||
</view>
|
||||
<view class="hsw-row"><text>服务</text><text>{{ b.service_name }}</text></view>
|
||||
<view class="hsw-row"><text>客户</text><text>{{ b.contact_name }} {{ b.contact_phone }}</text></view>
|
||||
<view class="hsw-row"><text>地址</text><text>{{ b.service_address }}</text></view>
|
||||
<view class="hsw-row"><text>账单月份</text><text>{{ b.bill_month }}</text></view>
|
||||
<view class="hsw-row"><text>金额</text><text class="hsw-amount">¥{{ b.amount }}</text></view>
|
||||
<view class="hsw-foot">
|
||||
<view class="hsw-btn" v-if="b.push_status === 0" @tap="openPush(b)">推送至用户支付</view>
|
||||
<view class="hsw-btn ghost" v-if="b.push_status === 0" @tap="openReject(b)">拒绝</view>
|
||||
<view class="hsw-btn ghost" v-if="b.push_status === 1">已推送,待用户支付</view>
|
||||
<view class="hsw-btn ghost" v-if="b.push_status === 2">用户已支付</view>
|
||||
<view class="hsw-btn ghost" v-if="b.push_status === 3">已拒绝{{ b.remark ? ':' + b.remark : '' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="bills.length === 0" class="hsw-empty">暂无月账单</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 代客补差弹层 -->
|
||||
<view class="hsw-mask" v-if="showExtra" @tap.self="showExtra = false">
|
||||
<view class="hsw-dialog">
|
||||
<view class="hsw-dialog-tit">代客生成补差单</view>
|
||||
<input class="hsw-dialog-input" type="digit" v-model="extraAmount" placeholder="请输入补差金额" />
|
||||
<input class="hsw-dialog-input" v-model="extraRemark" placeholder="备注(选填)" />
|
||||
<view class="hsw-dialog-btns">
|
||||
<view class="hsw-dialog-btn cancel" @tap="showExtra = false">取消</view>
|
||||
<view class="hsw-dialog-btn ok" @tap="submitExtra">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 推送月账单弹层 -->
|
||||
<view class="hsw-mask" v-if="showPush" @tap.self="showPush = false">
|
||||
<view class="hsw-dialog">
|
||||
<view class="hsw-dialog-tit">推送月账单</view>
|
||||
<view class="hsw-dialog-info">确认推送至用户端?用户支付后该账单生效。</view>
|
||||
<view class="hsw-dialog-btns">
|
||||
<view class="hsw-dialog-btn cancel" @tap="showPush = false">取消</view>
|
||||
<view class="hsw-dialog-btn ok" @tap="submitPush">确认推送</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 拒绝月账单弹层 -->
|
||||
<view class="hsw-mask" v-if="showReject" @tap.self="showReject = false">
|
||||
<view class="hsw-dialog">
|
||||
<view class="hsw-dialog-tit">拒绝月账单</view>
|
||||
<input class="hsw-dialog-input" v-model="rejectRemark" placeholder="请输入拒绝原因(选填)" />
|
||||
<view class="hsw-dialog-btns">
|
||||
<view class="hsw-dialog-btn cancel" @tap="showReject = false">取消</view>
|
||||
<view class="hsw-dialog-btn ok" @tap="submitReject">确认拒绝</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request } from '@/utils'
|
||||
import { apiArr } from '@/api/homeService'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
employeeId: 0,
|
||||
statusTab: 0,
|
||||
orderTabs: [
|
||||
{ v: 0, t: '全部' },
|
||||
{ v: 1, t: '待上门' },
|
||||
{ v: 2, t: '服务中' },
|
||||
{ v: 4, t: '已完成' },
|
||||
{ v: -1, t: '月账单' }
|
||||
],
|
||||
showMonthlyBill: false,
|
||||
billTab: 0,
|
||||
billTabs: [
|
||||
{ v: 0, t: '全部' },
|
||||
{ v: 1, t: '待推送' },
|
||||
{ v: 2, t: '已推送' }
|
||||
],
|
||||
orders: [],
|
||||
bills: [],
|
||||
showExtra: false,
|
||||
extraOrder: null,
|
||||
extraAmount: '',
|
||||
extraRemark: '',
|
||||
showPush: false,
|
||||
showReject: false,
|
||||
pushBill: null,
|
||||
rejectBill: null,
|
||||
rejectRemark: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.employeeId = Number(options.employeeId || uni.getStorageSync('serviceEmployeeId') || 0)
|
||||
if (!this.employeeId) {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
request(apiArr.workerMyInfo, 'POST', { user_id: userId }, {}, false).then(res => {
|
||||
if (res && res.is_worker && res.employee_id) {
|
||||
this.employeeId = res.employee_id
|
||||
uni.setStorageSync('serviceEmployeeId', res.employee_id)
|
||||
this.loadOrders()
|
||||
} else {
|
||||
uni.showModal({ title: '提示', content: '您还不是服务师傅,请联系商家添加', showCancel: false })
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if (this.employeeId) {
|
||||
if (this.showMonthlyBill) {
|
||||
this.loadBills()
|
||||
} else {
|
||||
this.loadOrders()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
switchStatus(v) {
|
||||
if (v === -1) {
|
||||
this.showMonthlyBill = true
|
||||
this.billTab = 0
|
||||
this.loadBills()
|
||||
} else {
|
||||
this.showMonthlyBill = false
|
||||
this.statusTab = v
|
||||
this.loadOrders()
|
||||
}
|
||||
},
|
||||
switchBillTab(v) {
|
||||
this.billTab = v
|
||||
this.loadBills()
|
||||
},
|
||||
loadOrders() {
|
||||
request(apiArr.workerOrderList, 'POST', {
|
||||
employee_id: this.employeeId,
|
||||
status: this.statusTab,
|
||||
page_num: 1,
|
||||
page_size: 50
|
||||
}, {}, false).then(res => {
|
||||
this.orders = res.rows || []
|
||||
})
|
||||
},
|
||||
loadBills() {
|
||||
request(apiArr.workerMonthlyBillList, 'POST', {
|
||||
employee_id: this.employeeId,
|
||||
user_id: Number(uni.getStorageSync('userId')) || 0,
|
||||
page_num: 1,
|
||||
page_size: 50
|
||||
}, {}, false).then(res => {
|
||||
let rows = res.rows || []
|
||||
if (this.billTab === 1) rows = rows.filter(b => b.push_status === 0)
|
||||
if (this.billTab === 2) rows = rows.filter(b => b.push_status === 1 || b.push_status === 2)
|
||||
this.bills = rows
|
||||
})
|
||||
},
|
||||
kindText(k) {
|
||||
return k === 1 ? '定金/上门费' : k === 2 ? '补差/尾款' : k === 3 ? '月账单' : ''
|
||||
},
|
||||
pushStatusText(s) {
|
||||
return s === 0 ? '待推送' : s === 1 ? '已推送待支付' : s === 2 ? '已支付' : s === 3 ? '已拒绝' : ''
|
||||
},
|
||||
updateStatus(o, status) {
|
||||
request(apiArr.workerOrderStatus, 'POST', { order_id: o.id, status }).then(() => {
|
||||
uni.showToast({ title: '操作成功', icon: 'none' })
|
||||
this.loadOrders()
|
||||
})
|
||||
},
|
||||
openExtra(o) {
|
||||
this.extraOrder = o
|
||||
this.extraAmount = ''
|
||||
this.extraRemark = ''
|
||||
this.showExtra = true
|
||||
},
|
||||
submitExtra() {
|
||||
const amt = Number(this.extraAmount)
|
||||
if (!amt || amt <= 0) { uni.showToast({ title: '请输入补差金额', icon: 'none' }); return }
|
||||
request(apiArr.workerExtraOrder, 'POST', {
|
||||
order_id: this.extraOrder.id,
|
||||
amount: amt,
|
||||
remark: this.extraRemark
|
||||
}).then(() => {
|
||||
this.showExtra = false
|
||||
uni.showToast({ title: '已生成补差单,待客户支付', icon: 'none' })
|
||||
this.loadOrders()
|
||||
})
|
||||
},
|
||||
openPush(b) {
|
||||
this.pushBill = b
|
||||
this.showPush = true
|
||||
},
|
||||
submitPush() {
|
||||
request(apiArr.workerPushBill, 'POST', {
|
||||
bill_id: this.pushBill.id,
|
||||
action: 1
|
||||
}).then(() => {
|
||||
this.showPush = false
|
||||
uni.showToast({ title: '已推送,用户可支付', icon: 'none' })
|
||||
this.loadBills()
|
||||
}).catch(err => {
|
||||
uni.showToast({ title: err.errMsg || '操作失败', icon: 'none' })
|
||||
})
|
||||
},
|
||||
openReject(b) {
|
||||
this.rejectBill = b
|
||||
this.rejectRemark = ''
|
||||
this.showReject = true
|
||||
},
|
||||
submitReject() {
|
||||
request(apiArr.workerPushBill, 'POST', {
|
||||
bill_id: this.rejectBill.id,
|
||||
action: 3,
|
||||
remark: this.rejectRemark
|
||||
}).then(() => {
|
||||
this.showReject = false
|
||||
uni.showToast({ title: '已拒绝', icon: 'none' })
|
||||
this.loadBills()
|
||||
}).catch(err => {
|
||||
uni.showToast({ title: err.errMsg || '操作失败', icon: 'none' })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hsw-page { display: flex; flex-direction: column; height: 100vh; background: #f5f5f5; }
|
||||
.hsw-tabs { display: flex; background: #fff; }
|
||||
.hsw-tab { flex: 1; text-align: center; padding: 24rpx 0; font-size: 26rpx; color: #666; }
|
||||
.hsw-tab.active { color: #FF370B; font-weight: 600; border-bottom: 4rpx solid #FF370B; }
|
||||
.hsw-tabs-bill { border-top: 1rpx solid #f0f0f0; }
|
||||
.hsw-list { flex: 1; padding: 20rpx; box-sizing: border-box; }
|
||||
.hsw-card { background: #fff; border-radius: 12rpx; padding: 20rpx; margin-bottom: 18rpx; }
|
||||
.hsw-bill-card { border-left: 6rpx solid #FF370B; }
|
||||
.hsw-head { display: flex; justify-content: space-between; font-size: 24rpx; color: #999; margin-bottom: 14rpx; }
|
||||
.hsw-kind { color: #FF370B; }
|
||||
.status-warn { color: #FF9800; }
|
||||
.status-info { color: #2196F3; }
|
||||
.status-ok { color: #4CAF50; }
|
||||
.status-cancel { color: #999; }
|
||||
.hsw-row { display: flex; justify-content: space-between; font-size: 26rpx; color: #333; padding: 8rpx 0; }
|
||||
.hsw-row text:first-child { color: #999; }
|
||||
.hsw-amount { color: #FF370B; font-weight: 600; }
|
||||
.hsw-foot { display: flex; justify-content: flex-end; gap: 16rpx; margin-top: 16rpx; }
|
||||
.hsw-btn { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 26rpx; padding: 12rpx 36rpx; border-radius: 40rpx; }
|
||||
.hsw-btn.ghost { background: #fff; color: #FF370B; border: 1rpx solid #FF370B; }
|
||||
.hsw-empty { text-align: center; color: #999; font-size: 26rpx; padding: 80rpx 0; }
|
||||
.hsw-mask { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 999; }
|
||||
.hsw-dialog { width: 600rpx; background: #fff; border-radius: 16rpx; padding: 32rpx; }
|
||||
.hsw-dialog-tit { font-size: 30rpx; font-weight: 600; text-align: center; margin-bottom: 24rpx; }
|
||||
.hsw-dialog-info { font-size: 26rpx; color: #666; text-align: center; margin-bottom: 24rpx; }
|
||||
.hsw-dialog-input { border: 1rpx solid #eee; border-radius: 8rpx; height: 80rpx; padding: 0 20rpx; font-size: 28rpx; margin-bottom: 18rpx; }
|
||||
.hsw-dialog-btns { display: flex; gap: 20rpx; margin-top: 10rpx; }
|
||||
.hsw-dialog-btn { flex: 1; text-align: center; padding: 18rpx 0; border-radius: 44rpx; font-size: 28rpx; }
|
||||
.hsw-dialog-btn.cancel { background: #f2f2f2; color: #666; }
|
||||
.hsw-dialog-btn.ok { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; }
|
||||
</style>
|
||||
41
pages.json
41
pages.json
@ -134,6 +134,47 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "packages/homeService",
|
||||
"pages": [
|
||||
{
|
||||
"path": "index/index",
|
||||
"style": { "navigationBarTitleText": "到家服务", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "detail/index",
|
||||
"style": { "navigationBarTitleText": "服务详情", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "order/index",
|
||||
"style": { "navigationBarTitleText": "确认预约", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "myOrders/index",
|
||||
"style": { "navigationBarTitleText": "我的服务订单", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "orderDetail/index",
|
||||
"style": { "navigationBarTitleText": "订单详情", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "worker/index",
|
||||
"style": { "navigationBarTitleText": "我的接单", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "myContracts/index",
|
||||
"style": { "navigationBarTitleText": "我的家政合同", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "contractDetail/index",
|
||||
"style": { "navigationBarTitleText": "合同详情", "navigationBarBackgroundColor": "#fff" }
|
||||
},
|
||||
{
|
||||
"path": "myMonthlyBills/index",
|
||||
"style": { "navigationBarTitleText": "我的月账单", "navigationBarBackgroundColor": "#fff" }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "packages/customerService",
|
||||
"pages": [
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!--view class="main margin20">
|
||||
<view class="main margin20">
|
||||
<view class="main_title">到家服务</view>
|
||||
<view class="item1 padding_bottom0">
|
||||
<u-grid col="4" :border="false">
|
||||
@ -102,7 +102,7 @@
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
</view-->
|
||||
</view>
|
||||
<view class="main margin20">
|
||||
<view class="main_title">门店服务</view>
|
||||
<view class="item1 padding_bottom0">
|
||||
@ -192,18 +192,18 @@ export default {
|
||||
],
|
||||
visitList: [{
|
||||
image: "https://static.hshuishang.com/property-img-file/page_user_Group_1572.png",
|
||||
name: "服务工单",
|
||||
url: "",
|
||||
name: "到家服务订单",
|
||||
url: "/packages/homeService/myOrders/index",
|
||||
},
|
||||
{
|
||||
image: "https://static.hshuishang.com/property-img-file/page_user_Group_1573.png",
|
||||
name: "服务地址",
|
||||
url: "",
|
||||
name: "我的月账单",
|
||||
url: "/packages/homeService/myMonthlyBills/index",
|
||||
},
|
||||
{
|
||||
image: "https://static.hshuishang.com/property-img-file/page_user_Group_1574.png",
|
||||
name: "服务卡",
|
||||
url: "",
|
||||
name: "我的家政合同",
|
||||
url: "/packages/homeService/myContracts/index",
|
||||
}
|
||||
],
|
||||
shopList: [{
|
||||
@ -240,6 +240,12 @@ export default {
|
||||
name: "物业端",
|
||||
url: "/packages/workOrderDashboard/guide/index",
|
||||
isShow: uni.getStorageSync("is_worker"),
|
||||
},
|
||||
{
|
||||
image: "https://static.hshuishang.com/property-img-file/userPageWuye.png",
|
||||
name: "师傅端",
|
||||
url: "/packages/homeService/worker/index",
|
||||
isShow: uni.getStorageSync("is_merchant"),
|
||||
}
|
||||
],
|
||||
parkList: [
|
||||
@ -347,6 +353,12 @@ export default {
|
||||
name: "物业端",
|
||||
url: "/packages/workOrderDashboard/guide/index",
|
||||
isShow: loginRes.is_worker,
|
||||
},
|
||||
{
|
||||
image: "https://static.hshuishang.com/property-img-file/userPageWuye.png",
|
||||
name: "师傅端",
|
||||
url: "/packages/homeService/worker/index",
|
||||
isShow: loginRes.is_merchant,
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"appid": "wx1addb25675dd8e70",
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "3.9.1",
|
||||
"libVersion": "3.16.0",
|
||||
"packOptions": {
|
||||
"ignore": [],
|
||||
"include": []
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user