You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

580 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view>
<!-- staff内容 -->
<view class="order-page">
<!-- 顶部栏 -->
<u-navbar :is-back="false" title="订单管理系统" :background="{'background':'#1479ff'}" title-color="#fff"
:border-bottom="false">
</u-navbar>
<view class="b-border"></view>
<!-- Tabs -->
<view class="tabs">
<view v-for="(tab, idx) in statusListStaff" :key="idx" :class="['tab', {active: currentTab === idx}]"
@click="changeTab(idx)">
{{ tab.name }}
</view>
</view>
<!-- 订单列表 -->
<view class="order">
<scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom">
<block v-if="list.length>0">
<view class="order-list">
<view class="order-card" v-for="item in list" :key="item.id">
<view class="order-icon" :class="typeText[item.type]['class']">
{{ typeText[item.type]['name'] }}
</view>
<view class="order-header">
<view class="order-time">
服务时间:<text>{{ item.time }}</text>
</view>
<view class="order-status">{{ statusListStaff[currentTab].name }}</view>
</view>
<view class="order-body">
<view class="order-left">
<block v-if="item.type === 2">
<view>服务地址:{{ item.city?item.city:'' }}</view>
</block>
<block v-else>
<view>就诊医院:{{ item.hospital?item.hospital.name:'' }}</view>
</block>
<view>被服务人:{{ item.user_archive?item.user_archive.name:'' }}</view>
<view>服务项目:{{ item.accompany_product?item.accompany_product.name:'' }}</view>
<view>订单号:{{ item.no }} <text class="copy" @click="copy(item.no)">复制</text></view>
</view>
<view class="order-price">¥<text>{{ item.price }}</text></view>
</view>
<view class="order-footer">
<u-button size="mini" @click="toUrl(item.id)" shape="circle" type="default"
:custom-style="normalStyle">详情</u-button>
<!-- 其他按钮如需开放可自行添加 -->
</view>
</view>
</view>
<u-loadmore v-if="!(list.length===0 && select.page===1)" :margin-top="20" :margin-bottom="40"
:status="loadStatus"></u-loadmore>
</block>
<view v-else style="height: 100%;" class="d-flex ai-center jc-center">
<u-empty mode="list" text="暂无订单"></u-empty>
</view>
</scroll-view>
</view>
<!-- 二维码 -->
<u-popup v-model="showPayCode" z-index="99999" :mask-close-able="false" mode="center" border-radius="12"
width="690rpx">
<view class="payment-popup">
<view class="title">付款二维码</view>
<view class="amount">
<text class="symbol">¥</text>
<text class="number">{{diff_price}}</text>
</view>
<view class="qr-code">
<!-- <image :src="qrCodeUrl" mode="aspectFit"></image> -->
<uqrcode v-if="myQrcode" ref="uqrcode" canvas-id="qrcode" :value="myQrcode" :sizeUnit="'rpx'"
:size="200" :options="{
margin: 10,
}"></uqrcode>
</view>
<view class="tips">
<text>请扫码支付差额</text>
<text class="sub-tips">支付完成后订单将自动完成</text>
</view>
<view class="close-btn">
<u-button size="mini" shape="circle" type="default" :custom-style="normalStyle"
@click="closePayCode">关闭</u-button>
<u-button size="mini" shape="circle" type="default" :custom-style="parStyle"
@click="isPayCode">我已支付</u-button>
</view>
</view>
</u-popup>
</view>
<view class="add-order-btn-wrapper">
<u-button
type="primary"
shape="circle"
class="add-order-btn"
@click="addOrder"
>新增订单</u-button>
</view>
<TabBar :tabbarList="tabbarList" :current="currentTabIndex" />
</view>
</template>
<script>
import uqrcode from '@/uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue'
import { nurseTabbar, staffTabbar } from '@/common/tabbarConfig.js'
import TabBar from '@/components/tab-bar/tab-bar.vue'
export default {
components: {
uqrcode,
TabBar
},
data() {
return {
loginRole: uni.getStorageSync('login_role') || 'staff',
showPayCode: false,
diff_price: '0.00',
myQrcode: '',
statusListStaff: [
{ id: 0, name: "待支付" },
{ id: 1, name: "已支付" },
{ id: 3, name: "待审核" }, //2 是已退款.
{ id: 4, name: "已拒绝" }
],
typeText: {
1: { name: '诊', class: 'doctor' },
2: { name: '护', class: 'nurse' }
},
currentTab: 0,
normalStyle: {
'background': '#969da7',
'color': '#fff',
'font-size': '28rpx',
'padding': '0 30rpx',
'margin-left': '15rpx'
},
parStyle: {
'background': 'linear-gradient(to right, #476de4, #7bb9f7)',
'color': '#fff',
'font-size': '28rpx',
'padding': '0 30rpx',
'margin-left': '15rpx'
},
last_page: 1,
select: {
page: 1,
page_size: 5,
status: 0,
},
list: [],
loadStatus: 'loadmore',
}
},
computed: {
tabbarList() {
return this.loginRole === 'nurse' ? nurseTabbar : staffTabbar
},
currentTabIndex() {
const path = '/' + (this.$mp?.page?.route || this.$route?.path || '')
return this.tabbarList.findIndex(item => path === item.pagePath)
}
},
onShow() {
this.select.page = 1
this.list = []
this.getStaffOrderList()
// 监听切换到待审核标签页的事件
uni.$on('switchToPendingReview', () => {
// 直接切换到待审核标签页changeTab内部会清空数据
this.changeTab(2);
});
},
onShareAppMessage() {
return {
title: '医康养服务', // 分享标题
path: '/pages/index/index', // 分享路径,通常指向首页
}
},
onUnload() {
// 移除事件监听,避免内存泄漏
uni.$off('switchToPendingReview');
},
methods: {
copy(text) {
uni.setClipboardData({
data: text,
success: () => {
uni.showToast({
title: '已复制',
icon: 'none'
});
}
});
},
// 详情
toUrl(id) {
uni.navigateTo({
url: '/package_sub/order/orderStaffDetail?&id=' + id
})
},
// 修改
editOrder(id) {
uni.navigateTo({
url: '/package_sub/order/editPrice?&id=' + id
})
},
// 付款二维码
async showCode(item) {
const res = await this.$u.api.payCode({
no:item.no
})
if(res.result.return_code==='SUCCESS'){
this.myQrcode = res.result.code_url
this.diff_price = parseFloat(item.diff_price).toFixed(2)
this.showPayCode = true
}else{
uni.showToast({
icon:'none',
title:'获取失败'
})
}
},
closePayCode(){
this.myQrcode = ''
this.diff_price = '0.00'
this.showPayCode = false
},
isPayCode(){
this.myQrcode = ''
this.diff_price = '0.00'
this.showPayCode = false
this.list = []
this.select.page = 1
this.getStaffOrderList()
},
// 结束服务
closeOrder(item){
let that = this
uni.showModal({
title: '是否确认订单已完成?',
success(res) {
if (res.confirm) {
that.$u.api.saveOrder({
id: item.id,
status:4
}).then(res => {
that.base.toast("服务完成", 1500, function() {
setTimeout(function() {
that.select.status = 4
that.select.page = 1
that.currentTab = 3
that.list = []
that.getStaffOrderList()
}, 1500)
})
})
}
}
})
},
changeTab(idx) {
this.currentTab = idx
this.select.status = this.statusListStaff[idx].id
this.list = []
this.select.page = 1
this.getStaffOrderList()
},
async getStaffOrderList() {
try {
const res = await this.$u.api.staffOrder({
page: this.select.page,
page_size: this.select.page_size,
pay_status: this.select.status
})
if (res && res.data) {
this.last_page = res.last_page || 1
this.loadStatus = this.select.page >= this.last_page ? 'nomore' : 'loadmore'
// 第一页替换数据,其他页追加数据
if (this.select.page === 1) {
this.list = res.data;
} else {
this.list.push(...res.data);
}
} else {
this.last_page = 1
this.loadStatus = 'nomore'
// 如果没有数据,清空列表
if (this.select.page === 1) {
this.list = [];
}
uni.showToast({
title: '获取订单列表失败',
icon: 'none'
})
}
} catch (error) {
console.error('获取订单列表错误:', error)
this.last_page = 1
this.loadStatus = 'nomore'
// 出错时,如果是第一页则清空列表
if (this.select.page === 1) {
this.list = [];
}
uni.showToast({
title: '获取订单列表失败',
icon: 'none'
})
}
},
reachBottom() {
if (this.select.page >= this.last_page) {
this.loadStatus = 'nomore'
return
}
this.loadStatus = 'loading'
this.select.page++
this.getStaffOrderList()
},
addOrder() {
uni.navigateTo({
url: '/package_sub/order/service'
})
},
}
}
</script>
<style scoped lang="scss">
.order-page {
background: #f6f8fb;
height: 100vh;
overflow: hidden;
}
.b-border {
width: 100%;
height: 30rpx;
border-radius: 0 0 120rpx 120rpx;
background-color: #1479ff;
}
.tabs {
display: flex;
padding: 0 30rpx;
}
.tab {
flex: 1;
text-align: center;
font-size: 28rpx;
padding: 30rpx 0 20rpx 0;
color: #333333;
position: relative;
}
.tab.active {
color: #000;
font-weight: bold;
font-size: 32rpx;
}
.tab.active::after {
content: '';
display: block;
width: 70%;
height: 9rpx;
background: linear-gradient(to right, #476de4, #7bb9f7);
border-radius: 6rpx;
margin: 0 auto;
margin-top: 10rpx;
}
.order {
height: calc(100vh - 270rpx);
padding-bottom: 170rpx;
}
.order-list {
padding: 30rpx 0;
padding-bottom: 0;
}
.order-card {
background: #fff;
border-radius: 20rpx;
margin: 0 30rpx 30rpx 30rpx;
box-shadow: 0 4rpx 16rpx #e6eaf1;
padding: 30rpx;
position: relative;
overflow: hidden;
padding-top: 25rpx;
}
.order-icon {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
border: 2rpx solid #e6eaf1;
display: flex;
align-items: center;
justify-content: center;
font-size: 40rpx;
font-weight: bold;
position: absolute;
top: -15rpx;
left: -15rpx;
}
.order-icon.nurse {
color: #cce0ff;
border-color: #cce0ff;
}
.order-icon.doctor {
color: #ffe0b2;
border-color: #ffe0b2;
}
.order-header {
display: flex;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1rpx dotted #bbb;
width: calc(100% - 80rpx);
margin-left: 80rpx;
}
.order-time {
flex: 1;
color: #969da7;
font-size: 28rpx;
text {
color: #000;
}
}
.order-status {
color: #969da7;
font-size: 28rpx;
}
.order-body {
color: #333;
margin-top: 30rpx;
// margin-bottom: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
.order-left {
&>view {
margin-bottom: 20rpx;
}
}
}
.copy {
color: #969da7;
margin-left: 10rpx;
font-size: 28rpx;
}
.order-price {
color: #333;
font-size: 36rpx;
font-weight: bold;
}
.order-price text {
font-size: 46rpx;
color: #d80808;
}
.order-footer {
display: flex;
align-items: center;
justify-content: flex-end;
}
.order-actions {
display: flex;
align-items: center;
}
.payment-popup {
background: #fff;
padding: 40rpx;
.title {
font-size: 32rpx;
color: #333;
text-align: center;
font-weight: 500;
margin-bottom: 30rpx;
}
.amount {
text-align: center;
margin-bottom: 40rpx;
.symbol {
font-size: 36rpx;
color: #000;
}
.number {
font-size: 48rpx;
color: #d80808;
font-weight: bold;
}
}
.qr-code {
width: 200rpx;
height: 200rpx;
margin: 0 auto 40rpx;
image {
width: 100%;
height: 100%;
}
}
.tips {
text-align: center;
margin-bottom: 40rpx;
text {
display: block;
color: #333;
font-size: 28rpx;
line-height: 1.8;
}
.sub-tips {
color: #999;
font-size: 24rpx;
}
}
.close-btn {
width: 80%;
margin: 0 auto;
display: flex;
justify-content: center;
}
}
.add-order-btn-wrapper {
position: fixed;
left: 0;
right: 0;
bottom: 180rpx;
display: flex;
justify-content: center;
z-index: 1001;
pointer-events: none;
}
.add-order-btn {
width: 40vw;
background: linear-gradient(to right, #476de4, #7bb9f7);
color: #fff;
font-size: 32rpx;
border-radius: 50rpx;
pointer-events: auto;
}
</style>