a3ab5d87 by lttnew

去支付

1 parent 10c86415
......@@ -1702,14 +1702,16 @@ export function goPay(params) {
// 再次支付
export function payForOrder(params) {
let url = `/common/order/payForOrder/${params.id}`
const queryParams = []
if (params.id) queryParams.push(`id=${params.id}`)
if (params.payType) queryParams.push(`payType=${params.payType}`)
if (queryParams.length > 0) {
url += '?' + queryParams.join('&')
}
export function payForOrder(params) {
let url = `/common/order/payForOrder/${params.id}`
const queryParams = []
if (params.id) queryParams.push(`id=${encodeURIComponent(params.id)}`)
if (params.payType) queryParams.push(`payType=${encodeURIComponent(params.payType)}`)
if (params.contactPerson) queryParams.push(`contactPerson=${encodeURIComponent(params.contactPerson)}`)
if (params.contactTel) queryParams.push(`contactTel=${encodeURIComponent(params.contactTel)}`)
if (queryParams.length > 0) {
url += '?' + queryParams.join('&')
}
return request({
url,
method: 'post',
......
// dev
const baseUrl_api = 'http://192.168.1.134:8787'
const baseUrl_api = 'http://192.168.1.222:8787'
// const baseUrl_api = 'http://47.98.186.233:8787'
// const baseUrl_api = 'https://tk001.wxjylt.com/stage-api/'
const loginImage_api = 'https://tk001.wxjylt.com/stage-api'
......
<template>
<view class="pay-order-container">
<!-- 页面头部 -->
<view class="page-header">
<text class="title">确认并支付</text>
</view>
<!-- 订单核心信息 -->
<view class="order-info">
<view class="info-item">
<text class="label">人数合计:</text>
<text class="value red">{{ formData.all ?? 0 }}</text>
</view>
<view class="info-item">
<text class="label">新会员合计:</text>
<text class="value red">{{ formData.new ?? 0 }}</text>
</view>
<view class="info-item">
<text class="label">续费会员合计:</text>
<text class="value red">{{ formData.old ?? 0 }}</text>
</view>
<view class="info-item total-price">
<text class="label">支付总费用:</text>
<text class="value red">{{ formData.price ?? 0 }}</text>
</view>
</view>
<!-- 支付方式选择 -->
<view class="pay-type-section">
<view class="section-title">选择支付方式</view>
<view class="payment-methods">
<radio-group @change="handlePayTypeChange">
<label :class="{ selected: payType === '1' }" class="payment-item">
<radio :checked="payType =='0'" value="0"/>
<image :src="config.baseUrl_api + '/fs/static/min.png'" class="icon ml10" mode="widthFix"></image>
<text class="pay-name ml10">民生付</text>
</label>
<label :class="{ selected: payType === '3' }" class="payment-item">
<radio :checked="payType === '3'" value="1"/>
<image :src="config.baseUrl_api + '/fs/static/min.png'" class="icon ml10" mode="widthFix"></image>
<text class="pay-name ml10">对公转账</text>
</label>
</radio-group>
</view>
</view>
<!-- 对公转账表单 -->
<view v-if="payType === '3'" class="transfer-form">
<view class="form-item">
<text class="form-label">联系人</text>
<input v-model="form.contactPerson" class="form-input" placeholder="请输入联系人"/>
</view>
<view class="form-item">
<text class="form-label">联系电话</text>
<input v-model="form.contactTel" class="form-input" placeholder="请输入联系电话" type="number"/>
</view>
</view>
<!-- 底部支付按钮 -->
<view class="fixed-bottom">
<button :loading="payLoading" class="pay-btn red-bg" @click="handlePay">立即支付</button>
</view>
</view>
</template>
<script setup>
import {
ref
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
import config from '@/config.js'
import {minShengPay} from "@/common/pay";
// 核心数据
const formData = ref({}) // 订单统计数据
const rangeId = ref('') // 核心业务ID
const payType = ref('0') // 支付方式(默认0=民生付)
const payLoading = ref(false) // 支付按钮加载状态
const form = ref({
contactPerson: '',
contactTel: ''
})
// 页面加载接收参数
onLoad(async (options) => {
console.log('订单ID:', options.rangeId)
if (options.rangeId) {
rangeId.value = options.rangeId
await getCount()
}
})
async function getCount() {
try {
const res = await api.getNewCountByRangeId(rangeId.value)
formData.value = res.data || {
all: 0,
new: 0,
old: 0
}
} catch (e) {
formData.value = {
all: 0,
new: 0,
old: 0
}
}
}
// 支付方式切换
function handlePayTypeChange(e) {
payType.value = e.detail.value == '0' ? '0' : '3'
console.log('支付方式:', payType.value)
if (payType.value === '3') {
form.value.contactPerson = ''
form.value.contactTel = ''
}
}
// 立即支付核心逻辑
async function handlePay() {
// 基础校验
if (!rangeId.value || rangeId.value === '-1') {
return uni.showToast({
title: '订单ID异常',
icon: 'none'
})
}
// 对公转账校验
if (payType.value === '3') {
if (!form.value.contactPerson) {
return uni.showToast({title: '请输入联系人', icon: 'none'})
}
if (!form.value.contactTel) {
return uni.showToast({title: '请输入联系电话', icon: 'none'})
}
// 手机号格式校验
if (!/^1[3-9]\d{9}$/.test(form.value.contactTel)) {
return uni.showToast({title: '请输入正确的手机号', icon: 'none'})
}
}
try {
payLoading.value = true
uni.showLoading({
title: '提交中...',
mask: true
})
// 构建请求参数
const params = {
id: rangeId.value,
payType: payType.value
}
if (payType.value === '3') {
params.contactPerson = form.value.contactPerson
params.contactTel = form.value.contactTel
}
const res = await api.goPay(params)
const resData = res.data
// 对公转账 - 跳转转账信息页面
if (resData.payFlag == 2) {
uni.hideLoading()
uni.redirectTo({
url: `/myCenter/transferPay?orderId=${resData.orderId}`
})
return
}
// 民生付
if (resData.payResult && resData.payResult.encryptedData) {
const reason = await minShengPay(resData.orderId, resData.payResult.encryptedData)
if (reason == 'OK') {
uni.showToast({title: '支付成功', icon: 'success'})
setTimeout(() => {
uni.hideLoading()
uni.redirectTo({
url: `/personalVip/payment`
})
}, 1500)
}
}
} catch (err) {
console.log(err)
const errMsg = err?.data?.msg || err?.message || '支付失败,请稍后重试'
uni.showToast({
title: errMsg,
icon: 'none'
})
} finally {
uni.hideLoading()
payLoading.value = false
}
}
</script>
<style lang="scss" scoped>
.pay-order-container {
padding: 30rpx;
background-color: #fff;
min-height: 100vh;
box-sizing: border-box;
}
.icon {
width: 30px;
}
// 页面头部
.page-header {
text-align: center;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
margin-bottom: 40rpx;
.title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
}
// 订单信息区域
.order-info {
margin-bottom: 60rpx;
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 0;
border-bottom: 1px solid #f5f5f5;
font-size: 32rpx;
.label {
color: #666;
}
.value {
font-weight: 600;
font-size: 34rpx;
}
.red {
color: #E60012;
}
}
.total-price {
border-bottom: none;
margin-top: 10rpx;
.label {
font-size: 34rpx;
color: #333;
}
.value {
font-size: 38rpx;
}
}
}
// 支付方式区域
.pay-type-section {
margin-bottom: 30rpx;
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
position: relative;
padding-left: 20rpx;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 6rpx;
height: 28rpx;
background: linear-gradient(180deg, #FF755A, #F51722);
border-radius: 3rpx;
}
}
}
.payment-methods {
background: #f8f9fa;
border-radius: 12rpx;
padding: 20rpx;
.payment-item {
display: flex;
align-items: center;
padding: 16rpx;
border-radius: 12rpx;
border: 2rpx solid transparent;
&.selected {
border-color: #e4393c;
background: #fff;
}
// 覆盖原生 radio 样式
::v-deep radio .wx-radio-input,
::v-deep radio .uni-radio-input {
width: 36rpx;
height: 36rpx;
border-color: #ccc !important;
}
::v-deep radio .wx-radio-input.wx-radio-input-checked,
::v-deep radio .uni-radio-input-checked {
border-color: #e4393c !important;
background: #e4393c !important;
}
.icon {
width: 40rpx;
height: 40rpx;
}
.pay-name {
font-size: 30rpx;
color: #333;
font-weight: 500;
}
.ml10 {
margin-left: 10rpx;
}
}
}
// 对公转账表单
.transfer-form {
background: #f8f9fa;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 30rpx;
.form-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
&:last-child {
border-bottom: none;
}
}
.form-label {
font-size: 28rpx;
color: #333;
width: 140rpx;
flex-shrink: 0;
}
.form-input {
flex: 1;
font-size: 28rpx;
color: #333;
text-align: right;
}
}
// 底部支付按钮
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx 30rpx;
background-color: #fff;
border-top: 1px solid #eee;
.pay-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
border-radius: 44rpx;
font-size: 34rpx;
font-weight: 600;
}
.red-bg {
background-color: #E60012;
color: #fff;
}
}
</style>
<template>
<view class="pay-order-container">
<!-- 订单核心信息 -->
<view class="order-info">
<view class="info-item">
<text class="label">缴费单位:</text>
<text class="value normal">{{ displayPayName }}</text>
</view>
<view class="info-item">
<text class="label">所属协会:</text>
<text class="value normal">{{ displayAssoName }}</text>
</view>
<view class="info-item">
<text class="label">人数合计:</text>
<text class="value red">{{ formData.all ?? 0 }}</text>
</view>
<view class="info-item">
<text class="label">新会员合计:</text>
<text class="value red">{{ formData.new ?? 0 }}</text>
</view>
<view class="info-item">
<text class="label">续费会员合计:</text>
<text class="value red">{{ formData.old ?? 0 }}</text>
</view>
<view class="info-item total-price">
<text class="label">支付总费用:</text>
<text class="value red">{{ formData.price ?? 0 }}</text>
</view>
</view>
<!-- 支付方式选择 -->
<view class="pay-type-section">
<view class="section-title">选择支付方式</view>
<view class="payment-methods">
<radio-group @change="handlePayTypeChange">
<label :class="{ selected: payType === '0' }" class="payment-item">
<radio :checked="payType =='0'" value="0"/>
<image :src="config.baseUrl_api + '/fs/static/min.png'" class="icon ml10" mode="widthFix"></image>
<text class="pay-name ml10">民生付</text>
</label>
<label :class="{ selected: payType === '3' }" class="payment-item">
<radio :checked="payType === '3'" value="3"/>
<image :src="config.baseUrl_api + '/fs/static/min.png'" class="icon ml10" mode="widthFix"></image>
<text class="pay-name ml10">对公转账</text>
</label>
</radio-group>
</view>
</view>
<!-- 对公转账表单 -->
<view v-if="payType === '3'" class="transfer-form">
<view class="form-item">
<text class="form-label">联系人</text>
<input v-model="form.contactPerson" class="form-input" placeholder="请输入联系人"/>
</view>
<view class="form-item">
<text class="form-label">联系电话</text>
<input v-model="form.contactTel" class="form-input" placeholder="请输入联系电话" type="number"/>
</view>
</view>
<!-- 底部支付按钮 -->
<view class="fixed-bottom">
<button :loading="payLoading" class="pay-btn red-bg" @click="handlePay">立即支付</button>
</view>
</view>
</template>
<script setup>
import {
computed,
ref
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
import config from '@/config.js'
import {minShengPay} from "@/common/pay";
// 核心数据
const formData = ref({}) // 订单统计数据
const rangeId = ref('') // 核心业务ID
const orderId = ref('') // common/order 订单ID,用于订单列表再次支付
const payName = ref('')
const assoName = ref('')
const payType = ref('0') // 支付方式(默认0=民生付)
const payLoading = ref(false) // 支付按钮加载状态
const form = ref({
contactPerson: '',
contactTel: ''
})
const app = getApp()
const memberInfo = app.globalData?.memberInfo || {}
const deptInfo = app.globalData?.dept || app.globalData?.userInfo?.dept || {}
const pickFirst = (...values) => {
const value = values.find(item => item !== undefined && item !== null && String(item).trim() !== '')
return value ? String(value) : ''
}
const displayPayName = computed(() => {
return pickFirst(
memberInfo.name,
memberInfo.deptName,
deptInfo.deptName,
formData.value.orderName,
formData.value.payDeptName,
formData.value.payMemName,
formData.value.memberName,
payName.value,
formData.value.memName
) || '-'
})
const displayAssoName = computed(() => {
return pickFirst(
deptInfo.aname,
deptInfo.associateName,
memberInfo.aname,
memberInfo.associateName,
memberInfo.assoName,
formData.value.assoName,
formData.value.associateName,
formData.value.associationName,
formData.value.aname,
formData.value.parentName,
assoName.value
) || '-'
})
// 页面加载接收参数
onLoad(async (options) => {
console.log('缴费范围ID:', options.rangeId, '订单ID:', options.orderId)
payName.value = decodeURIComponent(options.payName || '')
assoName.value = decodeURIComponent(options.assoName || '')
if (options.orderId) {
orderId.value = options.orderId
}
if (options.rangeId) {
rangeId.value = options.rangeId
await getCount()
}
if (options.orderId) {
await getOrderDetail()
}
})
async function getCount() {
try {
const res = await api.getNewCountByRangeId(rangeId.value)
formData.value = {
...formData.value,
...(res.data || {
all: 0,
new: 0,
old: 0
})
}
} catch (e) {
formData.value = {
...formData.value,
all: 0,
new: 0,
old: 0
}
}
}
async function getOrderDetail() {
try {
const res = await api.orderDetail(orderId.value)
const data = res.data || {}
let content = {}
if (data.content) {
try {
content = typeof data.content === 'string' ? JSON.parse(data.content) : data.content
} catch (e) {
content = {}
}
}
formData.value = {
...formData.value,
...data,
...content,
all: content.allPersonCount ?? data.allCount ?? data.all ?? 0,
new: content.newPersonCount ?? data.newCount ?? data.new ?? 0,
old: content.renewPersonCount ?? data.oldCount ?? data.old ?? 0,
price: data.price ?? content.price ?? 0
}
payName.value = pickFirst(data.orderName, content.orderName, data.payDeptName, data.payMemName, content.payDeptName, content.payMemName, data.memberName, content.memberName, payName.value)
assoName.value = pickFirst(data.assoName, data.associateName, data.associationName, data.aname, data.parentName, content.assoName, content.associateName, content.associationName, content.aname, content.parentName, assoName.value)
} catch (e) {
formData.value = {
...formData.value,
all: 0,
new: 0,
old: 0
}
}
}
// 支付方式切换
function handlePayTypeChange(e) {
payType.value = e.detail.value
console.log('支付方式:', payType.value)
if (payType.value === '3') {
form.value.contactPerson = ''
form.value.contactTel = ''
}
}
// 立即支付核心逻辑
async function handlePay() {
// 基础校验
if ((!rangeId.value && !orderId.value) || rangeId.value === '-1') {
return uni.showToast({
title: '订单ID异常',
icon: 'none'
})
}
// 对公转账校验
if (payType.value === '3') {
if (!form.value.contactPerson) {
return uni.showToast({title: '请输入联系人', icon: 'none'})
}
if (!form.value.contactTel) {
return uni.showToast({title: '请输入联系电话', icon: 'none'})
}
// 手机号格式校验
if (!/^1[3-9]\d{9}$/.test(form.value.contactTel)) {
return uni.showToast({title: '请输入正确的手机号', icon: 'none'})
}
}
try {
payLoading.value = true
uni.showLoading({
title: '提交中...',
mask: true
})
// 构建请求参数
const params = {
id: orderId.value || rangeId.value,
payType: payType.value
}
if (payType.value === '3') {
params.contactPerson = form.value.contactPerson
params.contactTel = form.value.contactTel
}
const res = orderId.value ? await api.payForOrder(params) : await api.goPay(params)
const resData = res.data
// 对公转账 - 跳转转账信息页面
if (resData.payFlag == 2) {
uni.hideLoading()
uni.redirectTo({
url: `/myCenter/transferPay?orderId=${resData.orderId}`
})
return
}
// 民生付
if (resData.payResult && resData.payResult.encryptedData) {
const reason = await minShengPay(resData.orderId, resData.payResult.encryptedData)
if (reason == 'OK') {
uni.showToast({title: '支付成功', icon: 'success'})
setTimeout(() => {
uni.hideLoading()
uni.redirectTo({
url: `/personalVip/payment`
})
}, 1500)
}
}
} catch (err) {
console.log(err)
const errMsg = err?.data?.msg || err?.message || '支付失败,请稍后重试'
uni.showToast({
title: errMsg,
icon: 'none'
})
} finally {
uni.hideLoading()
payLoading.value = false
}
}
</script>
<style lang="scss" scoped>
.pay-order-container {
padding: 30rpx;
background-color: #fff;
min-height: 100vh;
box-sizing: border-box;
}
.icon {
width: 30px;
}
// 页面头部
.page-header {
text-align: center;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
margin-bottom: 40rpx;
.title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
}
// 订单信息区域
.order-info {
margin-bottom: 60rpx;
border-top: 1px solid #f5f5f5;
border-bottom: 1px solid #f5f5f5;
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 0;
border-bottom: 1px solid #f5f5f5;
font-size: 32rpx;
.label {
color: #666;
flex-shrink: 0;
}
.value {
font-weight: 600;
font-size: 34rpx;
text-align: right;
word-break: break-all;
}
.normal {
color: #111;
font-size: 30rpx;
}
.red {
color: #E60012;
}
}
.total-price {
border-bottom: none;
margin-top: 10rpx;
.label {
font-size: 34rpx;
color: #333;
}
.value {
font-size: 38rpx;
}
}
}
// 支付方式区域
.pay-type-section {
margin-bottom: 30rpx;
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
position: relative;
padding-left: 20rpx;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 6rpx;
height: 28rpx;
background: linear-gradient(180deg, #FF755A, #F51722);
border-radius: 3rpx;
}
}
}
.payment-methods {
background: #f8f9fa;
border-radius: 12rpx;
padding: 20rpx;
.payment-item {
display: flex;
align-items: center;
padding: 16rpx;
border-radius: 12rpx;
border: 2rpx solid transparent;
&.selected {
border-color: #e4393c;
background: #fff;
}
// 覆盖原生 radio 样式
::v-deep radio .wx-radio-input,
::v-deep radio .uni-radio-input {
width: 36rpx;
height: 36rpx;
border-color: #ccc !important;
}
::v-deep radio .wx-radio-input.wx-radio-input-checked,
::v-deep radio .uni-radio-input-checked {
border-color: #e4393c !important;
background: #e4393c !important;
}
.icon {
width: 40rpx;
height: 40rpx;
}
.pay-name {
font-size: 30rpx;
color: #333;
font-weight: 500;
}
.ml10 {
margin-left: 10rpx;
}
}
}
// 对公转账表单
.transfer-form {
background: #f8f9fa;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 30rpx;
.form-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
&:last-child {
border-bottom: none;
}
}
.form-label {
font-size: 28rpx;
color: #333;
width: 140rpx;
flex-shrink: 0;
}
.form-input {
flex: 1;
font-size: 28rpx;
color: #333;
text-align: right;
}
}
// 底部支付按钮
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx 30rpx;
background-color: #fff;
border-top: 1px solid #eee;
.pay-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
border-radius: 44rpx;
font-size: 34rpx;
font-weight: 600;
}
.red-bg {
background-color: #E60012;
color: #fff;
}
}
</style>
......
......@@ -17,7 +17,7 @@
v-model="queryParams.wfCode"
:input-border="false"
class="search-input"
placeholder="输入订单编号/名称/单位/日期"
placeholder="输入缴费编号查询"
placeholderStyle="font-size:28rpx;color:#999"
prefixIcon="search"
@blur="handelSearch"
......@@ -229,31 +229,15 @@
</view>
</view>
</view>
<!-- 缴费方式 -->
<!-- <view class="pay-way-row">
<text class="pay-way-label">缴费方式:</text>
<text class="pay-way-value">{{ item.payType == '3' ? '对公转账' : '民生付' }}</text>
</view> -->
<!-- 按钮组:靠右展示 -->
<view class="btn-group">
<!-- 已缴费:申请开票/已开票(需要审核通过才能开票) -->
<template v-if="item.payStatus == 1 && item.invoiceStatus != 1&& item.auditStatus == 2 &&item.price>0">
<button :disabled="item.invoiceStatus === 1" class="btn btn-view-invoice"
@click.stop="makeInvoiceFN(item)">
申请开票
</button>
</template>
<!-- 已申请票据:查看票据 -->
<template v-if="item.invoiceStatus == 1">
<button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看票据</button>
<button :class="{ disabled: isPayDisabled(item) }" :disabled="isPayDisabled(item)" class="btn btn-pay" @click.stop="handlePay(item)">支付</button>
<button :class="{ disabled: isCancelDisabled(item) }" :disabled="isCancelDisabled(item)" class="btn btn-cancel" @click.stop="handleCancel(item)">取消订单</button>
<template v-if="!hasInvoice(item)">
<button :class="{ disabled: isInvoiceDisabled(item) }" :disabled="isInvoiceDisabled(item)" class="btn btn-view-invoice" @click.stop="makeInvoiceFN(item)">申请开票</button>
</template>
<!-- 未缴费:去缴费 + 取消订单 -->
<template v-if="item.payStatus == 0">
<!-- 支付按钮:仅 auditStatus==='0' && payStatus==='0' 时可点 -->
<button :disabled="!(item.auditStatus == '0' && item.payStatus == 0)" class="btn btn-pay" @click.stop="handlePay(item)">去支付</button>
<button :disabled="item.payStatus != 0" class="btn btn-cancel" @click.stop="handleCancel(item)">取消订单</button>
<template v-else>
<button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看发票</button>
</template>
</view>
</view>
......@@ -542,6 +526,46 @@ const filterType = (row) => {
if (row == 4) return '越位考试办理'
}
const getRowType = (item) => String(item?.type ?? currentTab.value)
const isPersonalOrder = (item) => getRowType(item) === '0'
const isGroupOrder = (item) => getRowType(item) === '1'
const isPayDisabled = (item) => {
if (isPersonalOrder(item)) return String(item?.auditStatus) !== '9'
if (String(item?.payStatus) !== '0') return true
return String(item?.auditStatus) !== '0'
}
const isCancelDisabled = (item) => {
if (isPersonalOrder(item)) return String(item?.auditStatus) !== '9'
if (String(item?.payStatus) !== '0') return true
return false
}
const hasInvoice = (item) => String(item?.invoiceStatus) === '1'
const isInvoiceDisabled = (item) => {
if (hasInvoice(item)) return true
if (isPersonalOrder(item)) return String(item?.auditStatus) !== '2'
return String(item?.payStatus) !== '1' || String(item?.auditStatus) !== '2' || Number(item?.price || 0) <= 0
}
const encodeQueryValue = (value) => encodeURIComponent(value || '')
const getPayName = (item) => {
return item?.orderName || item?.content?.orderName || item?.payDeptName || item?.payMemName || item?.content?.payDeptName || item?.content?.payMemName || item?.memberName || item?.content?.memberName || ''
}
const getAssoName = (item) => {
return item?.assoName || item?.associateName || item?.associationName || item?.aname || item?.parentName || item?.content?.assoName || item?.content?.associateName || item?.content?.associationName || item?.content?.aname || item?.content?.parentName || ''
}
const buildPayInfoQuery = (item) => {
return `payName=${encodeQueryValue(getPayName(item))}&assoName=${encodeQueryValue(getAssoName(item))}`
}
// 数据请求核心方法
const initData = async () => {
......@@ -617,7 +641,7 @@ const confirmDel = async () => {
const goToDetail = (item) => {
const form = encodeURIComponent(JSON.stringify(item))
switch (currentTab.value) {
switch (getRowType(item)) {
case '1':
uni.navigateTo({url: `/group/groupOrderDetail?form=${form}`});
break;
......@@ -641,13 +665,27 @@ const closeDelPopup = () => {
currentOrder.value = null;
};
// 去缴费 - 跳转到单位会员支付页面
// 去支付:个人会员订单走 payOrder,再次支付携带 common/order 的 id;单位会员订单走 goPay。
const handlePay = async (item) => {
if (item.payStatus !== 0) return;
// 跳转到单位会员支付页面
uni.navigateTo({
url: `/myCenter/goPay?orderId=${item.id}&renewYear=${item.content?.yearCount || 1}`
});
if (isPayDisabled(item)) return;
const payInfoQuery = buildPayInfoQuery(item)
if (isPersonalOrder(item)) {
const rangeId = item.sourceId || item.rangId || ''
uni.navigateTo({
url: `/myCenter/payOrder?orderId=${item.id}&rangeId=${rangeId}&${payInfoQuery}`
});
return;
}
if (isGroupOrder(item)) {
uni.navigateTo({
url: `/myCenter/goPay?orderId=${item.id}&renewYear=${item.content?.yearCount || 1}&${payInfoQuery}`
});
return;
}
uni.navigateTo({url: `/pages/rank/applyDetail?examId=${item.sourceId || item.id}&type=${getRowType(item)}`});
};
// 申请开票
......@@ -715,7 +753,7 @@ const closeInvoiceWebview = () => {
// 取消订单
const handleCancel = (item) => {
currentOrder.value = item;
cancelModalContent.value = `是否确认取消订单编号为"${item.tradeNo}"的订单?`;
cancelModalContent.value = `是否确认取消缴费编号为"${item.wfCode}"的订单?`;
showCancelPopup.value = true;
isPopupOpen.value = true;
};
......@@ -1204,9 +1242,13 @@ const onTabSwitch = (index, url) => {
//border: none;
border: 1rpx solid #c30d23;
}
&:disabled {
opacity: 0.6;
&.disabled,
&[disabled] {
background: #f5f5f5 !important;
color: #b8b8b8 !important;
border: 1rpx solid #e1e1e1 !important;
opacity: 1;
pointer-events: none;
}
}
......
......@@ -11,8 +11,8 @@
placeholderStyle="font-size:30rpx;color:#999"
:input-border="false"
prefixIcon="search"
v-model="queryParams.memName"
placeholder="搜索缴费名称"
v-model="queryParams.wfCode"
placeholder="搜索缴费编号"
@blur="getList"
@clear="getList">
</uni-easyinput>
......@@ -37,55 +37,64 @@
<view class="scroll-content">
<!-- 会员缴费列表 -->
<view class="list-container" v-if="list.length > 0">
<view class="list-item" v-for="(item, index) in list" :key="index" @click="goDetail(item)">
<view class="item-header">
<view class="left-info">
<text class="mem-name">{{ item.memName }}</text>
<text class="wf-code" v-if="item.wfCode">{{ item.wfCode }}</text>
<view class="order-card-new" v-for="(item, index) in list" :key="index" @click="goDetail(item)">
<view class="card-header">
<view class="date">
<view class="data-header">
<text class="member-label">{{ item.memName }}·</text>
<text class="value">{{ item.wfCode || '——' }}</text>
</view>
</view>
<view class="status-badge" :class="getStatusClass(item.auditStatus)">
{{ getStatusText(item.auditStatus) }}
<view class="price">
<view :class="getStatusClass(item.auditStatus)">{{ getStatusText(item.auditStatus) }}</view>
</view>
</view>
<view class="member-time">
<view class="label">
<!-- <text class="star"></text>
{{ item.memName || '——' }} -->
<view v-if="item.commitTime" class="pay-name">提交时间:{{ formatDate(item.commitTime) }}</view>
</view>
<view class="stats-row">
<view class="stat-item">
<text class="stat-label">人数合计</text>
<text class="stat-value">{{ item.allCount || '/' }}</text>
</view>
<view class="summary-row">
<view class="summary-item">
<text class="summary-label">人数合计</text>
<text class="summary-value">{{ item.allCount || 0 }}</text>
</view>
<view class="stat-item">
<text class="stat-label">新会员合计</text>
<text class="stat-value">{{ item.newCount || '/' }}</text>
<view class="summary-item">
<text class="summary-label">新会员合计</text>
<text class="summary-value">{{ item.newCount || 0 }}</text>
</view>
<view class="stat-item">
<text class="stat-label">年限合计</text>
<text class="stat-value">{{ item.yearCount || '/' }}</text>
<view class="summary-item">
<text class="summary-label">年限合计</text>
<text class="summary-value">{{ item.yearCount || 0 }}</text>
</view>
</view>
<view class="submit-time" v-if="item.commitTime">
<uni-icons type="calendar-filled" size="16" color="#AD181F"></uni-icons>
<text class="time-text">{{ item.commitTime }} 提交</text>
</view>
<view class="action-buttons">
<view class="btn-group">
<button
class="action-btn delete-btn"
class="btn btn-cancel"
:class="{ disabled: item.auditStatus == 1 || item.auditStatus == 9 }"
@click.stop="handleDel(item)"
:disabled="item.auditStatus == 1 || item.auditStatus == 9">
删除
</button>
<button
class="action-btn edit-btn"
class="btn btn-info"
:class="{ disabled: item.auditStatus != 0 }"
@click.stop="handleUpdate(item)"
:disabled="item.auditStatus != 0">
编辑
</button>
<button
class="action-btn submit-btn"
class="btn btn-pay"
:class="{ disabled: isMainActionDisabled(item) }"
@click.stop="commitFN(item)"
:disabled="item.auditStatus != 0&&item.auditStatus != 9">
提交审核
:disabled="isMainActionDisabled(item)">
{{ getMainActionText(item) }}
</button>
</view>
</view>
......@@ -269,9 +278,45 @@ function handleDel(row) {
})
}
function getMainActionText(row) {
return String(row.auditStatus) === '0' ? '提交审核' : '支付'
}
function isMainActionDisabled(row) {
const auditStatus = String(row.auditStatus)
return auditStatus === '0' ? false : auditStatus !== '9'
}
function buildPayOrderUrl(row) {
const params = [
`rangeId=${encodeURIComponent(row.rangId || '')}`,
`payName=${encodeURIComponent(row.memName || '')}`,
`assoName=${encodeURIComponent(row.associateName || row.assoName || row.associationName || '')}`
]
if (row.orderId) {
params.push(`orderId=${encodeURIComponent(row.orderId)}`)
}
return `/myCenter/payOrder?${params.join('&')}`
}
function formatDate(value) {
if (!value) return '——'
const text = String(value)
const dateText = text.includes('T') ? text.split('T')[0] : text.slice(0, 10)
return dateText || '——'
}
function commitFN(row) {
if (String(row.auditStatus) !== '0') {
openModal('是否确认去支付', () => {
uni.navigateTo({
url: buildPayOrderUrl(row)
})
})
return
}
uni.navigateTo({
url: `/myCenter/payOrder?rangeId=${row.rangId}`
url: buildPayOrderUrl(row)
})
}
......@@ -289,9 +334,10 @@ function getStatusText(status) {
1: '审核中',
2: '审核通过',
3: '审核拒绝',
9: '缴费中'
4: '已取消',
9: '待支付'
}
return statusMap[status] || ''
return statusMap[String(status)] || ''
}
function getStatusClass(status) {
......@@ -422,127 +468,202 @@ onUnmounted(() => {
}
/* 列表 */
.list-container {
padding: 0 30rpx;
.list-container {
padding: 0 24rpx;
}
.list-item {
background: #ffffff;
border-radius: 24rpx;
padding: 36rpx 32rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
.order-card-new {
background: #fff;
margin-bottom: 22rpx;
padding: 22rpx 18rpx 18rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
border-radius: 18rpx;
display: flex;
flex-direction: column;
}
.item-header {
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
.left-info {
display: flex;
align-items: center;
flex:1;
flex-wrap: wrap;
padding-bottom: 10rpx;
.date {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8rpx;
font-size: 26rpx;
}
.mem-name {
font-size:34rpx;
font-weight:600;
color:#1a1a1a;
margin-right:16rpx;
.data-header {
display: flex;
min-width: 0;
}
.wf-code {
font-size:24rpx;
color:#666;
background:#f0f8fb;
padding:6rpx 12rpx;
border-radius: 16rpx;
.member-label {
color: #c30d23;
font-size: 28rpx;
font-weight: bold;
flex-shrink: 0;
}
.status-badge {
font-size:24rpx;
padding:8rpx 16rpx;
border-radius: 20rpx;
.value {
color: #000;
font-size: 27rpx;
font-weight: bold;
max-width: 460rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.status-pending { background:#f5f5f5; color:#888; }
.status-processing { background:#e8e8ff; color:#1890ff; }
.status-success { background:#f0fff4; color:#52c41a; }
.status-rejected { background:#fff2f2; color:#ff4d4f; }
.status-withdrawn { background:#fffbe6; color:#faad14; }
.status-default { background:#f5f5f5; color:#999; }
.status-tag {
font-size: 24rpx;
flex-shrink: 0;
}
.status-pending { color:#888; }
.status-processing { color:#1890ff; }
.status-success { color:#52c41a; }
.status-rejected { color:#ff4d4f; }
.status-withdrawn { color:#faad14; }
.status-default { color:#999; }
.stats-row {
.member-time {
width: 100%;
display: flex;
justify-content: space-between;
padding-bottom: 24rpx;
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
flex:1;
.stat-label {
font-size:24rpx;
color:#999;
margin-bottom:10rpx;
padding-bottom: 4rpx;
.label {
max-width: 480rpx;
color: #555;
font-size: 26rpx;
font-weight: 700;
line-height: 1.4;
.star {
color: #777;
font-size: 26rpx;
}
.stat-value {
font-size:32rpx;
// font-weight:700;
color:#333;
.pay-name {
margin-top: 8rpx;
color: #999;
font-size: 24rpx;
font-weight: 500;
}
}
}
.submit-time {
.price {
min-width: 130rpx;
font-size: 26rpx;
font-weight: 500;
text-align: right;
.person {
font-size: 24rpx;
color: #999;
text-align: right;
}
}
.summary-row {
display: flex;
align-items: center;
padding-bottom: 20rpx;
.time-text {
font-size:24rpx;
color:#666;
margin-left:20rpx;
}
margin-top: 14rpx;
padding: 16rpx 0 0;
border-top: 1rpx dashed #f0f0f0;
margin-bottom: 10rpx;
padding-bottom: 14rpx;
border-bottom: 1rpx dashed #f0f0f0;
}
.summary-item {
flex: 1;
text-align: center;
}
.summary-label {
display: block;
color: #999;
font-size: 23rpx;
}
.summary-value {
display: block;
margin-top: 6rpx;
color: #333;
font-size: 25rpx;
font-weight: 600;
}
.action-buttons {
.btn-group {
display: flex;
.action-btn {
flex:1;
height:60rpx;
line-height:60rpx;
font-size:26rpx;
border-radius:40rpx;
margin:0 8rpx;
border:none;
font-weight: 500;
}
justify-content: flex-end;
align-items: center;
gap: 16rpx;
width: 100%;
margin-top: 16rpx;
flex-wrap: wrap;
.btn {
width: 108rpx;
height: 48rpx;
line-height: 48rpx;
padding: 0;
border-radius: 10rpx;
font-size: 24rpx;
white-space: nowrap;
font-weight: bold;
border: none;
background: transparent;
text-align: center;
margin: 0;
.delete-btn {
background:#fff2f2;
color:#ff4d4f;
}
.edit-btn {
background:#e8f4ff;
color:#1890ff;
}
.submit-btn {
background:#fffbe6;
color:#faad14;
&::after {
border: none;
display: none;
}
&.btn-cancel {
width: 108rpx;
flex: 0 0 108rpx;
max-width: 108rpx;
background: #fff;
color: #666;
border: 1rpx solid #ccc;
}
&.btn-info {
flex: 0 0 108rpx;
max-width: 108rpx;
color: #444;
border: 1rpx solid #d7d7d7;
background: #fff;
}
&.btn-pay {
flex: 0 0 108rpx;
max-width: 108rpx;
color: #c30d23;
border: 1rpx solid #c30d23;
}
&.disabled,
&[disabled] {
background: #f5f5f5 !important;
color: #b8b8b8 !important;
border: 1rpx solid #e1e1e1 !important;
opacity: 1;
pointer-events: none;
}
}
}
.action-btn[disabled] {
background: #f0f0f0 !important;
color: #ccc !important;
opacity: 0.6 !important;
}
/* 空状态 */
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!