Commit 3e43dae6 by liangjianmin

feat(approve): refactor detail page with modal approval workflow and uView config

- Update uView configuration to use setConfig with unit and component size settings
- Add approval modal component with radio selection and textarea for remarks
- Refactor detail page field bindings to use snake_case API response format
- Simplify order information section and remove agent fee details
- Add bottom action buttons for cancel and review approval
- Implement modal state management for approval workflow
- Add approve-modal styling with proper padding and layout
- Format code with consistent spacing and indentation in main.js
parent 448118af
......@@ -183,4 +183,30 @@
align-items: center;
z-index: 100;
}
.approve-modal {
padding: 40rpx 32rpx;
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
.modal-title {
font-size: 34rpx;
font-weight: 700;
color: #1e293b;
text-align: center;
margin-bottom: 40rpx;
}
.modal-body {
margin-bottom: 40rpx;
.modal-textarea-wrap {
margin-top: 32rpx;
}
}
.modal-footer {
display: flex;
align-items: center;
}
}
}
import App from './App'
import {request} from './util/util.js'
import { request } from './util/util.js'
import uView from '@/uni_modules/uview-ui'
// #ifndef VUE3
import Vue from 'vue'
Vue.use(uView)
uni.$u.config.unit = 'rpx'
uni.$u.setConfig({
config: {
unit: 'rpx'
},
props: {
radio: {
size: 30,
labelSize: 30
},
checkbox: {
labelSize: 30
},
text: {
size: 30
},
input: {
fontSize: 30
},
textarea: {
fontSize: 30
}
}
})
Vue.config.productionTip = false;
Vue.prototype.request = request;
App.mpType = 'app'
const app = new Vue({
...App
...App
})
app.$mount()
// #endif
......
......@@ -3,15 +3,15 @@
<view class="section">
<view class="section-title">申请信息</view>
<u-cell-group>
<u-cell title="申请类型" :value="detail.applyType"></u-cell>
<u-cell title="客户名称" :value="detail.customerName"></u-cell>
<u-cell title="减免明细" :value="detail.deductionType"></u-cell>
<u-cell title="申请时间" :value="detail.applyTime"></u-cell>
<u-cell title="订单号" :value="detail.orderNo" :value-style="{ flex: 1 }" :border="false">
<u-cell title="申请类型" :value="detail.apply_type"></u-cell>
<u-cell title="客户名称" :value="detail.customer_name"></u-cell>
<u-cell title="减免明细" :value="detail.relief_detail"></u-cell>
<u-cell title="申请时间" :value="detail.create_time_cn"></u-cell>
<u-cell title="订单号" :value="detail.order_sn" :value-style="{ flex: 1 }" :border="false">
<template #value>
<view class="row verCenter bothSide" style="flex: 1;">
<text>{{ detail.orderNo }}</text>
<text class="link-text">申请人:{{ detail.applicant }}</text>
<text>{{ detail.order_sn }}</text>
<text class="link-text">申请人:{{ detail.applicant_name }}</text>
</view>
</template>
</u-cell>
......@@ -21,16 +21,8 @@
<view class="section">
<view class="section-title">订单信息</view>
<u-cell-group>
<u-cell title="订单金额(商币)" :value="detail.orderAmount"></u-cell>
<u-cell title="订单币别" :value="detail.currency"></u-cell>
<u-cell title="代理费金额" :value="detail.agentFee" :border="false">
<template #value>
<view class="row verCenter">
<text style="margin-right: 40rpx;">{{ detail.agentFee }}</text>
<text>最低代理费:{{ detail.minAgentFee }}</text>
</view>
</template>
</u-cell>
<u-cell title="订单金额(商币)" :value="detail.apply_fee_amount"></u-cell>
<u-cell title="减免明细" :value="detail.relief_detail" :border="false"></u-cell>
</u-cell-group>
</view>
......@@ -39,96 +31,136 @@
<view class="detail-content">
<view class="amount-box">
<text class="amount-label">申请免收金额(元)</text>
<text class="amount-value">{{ detail.amount }}</text>
<text class="amount-value">{{ detail.apply_fee_amount }}</text>
</view>
<view class="reason-box">
<text class="reason-label">免收原因</text>
<text class="reason-text">{{ detail.reason }}</text>
<text class="reason-text">{{ detail.relief_reason }}</text>
</view>
</view>
</view>
<view class="section">
<view class="section-title">审批日志</view>
<view class="timeline-wrap">
<view class="timeline-item" v-for="(log, index) in detail.logs" :key="index">
<view class="timeline-dot"></view>
<view class="timeline-content">
<view class="log-header row verCenter bothSide">
<text class="log-time">{{ log.time }}</text>
<text class="log-user">审批人:{{ log.approver }}</text>
</view>
<view class="log-body">
<text class="log-label">审批意见:</text>
<text class="log-text">{{ log.comment }}</text>
</view>
<view class="log-footer">
<text class="log-label">审批结果:</text>
<text :class="['log-status', log.status]">{{ log.statusText }}</text>
</view>
<!-- 审批日志 - 暂不渲染,等通知 -->
<view class="bottom-actions" v-if="detail.status === 0">
<u-button text="取消" shape="circle" :customStyle="{ flex: 1, marginRight: '24rpx', background: '#ffffff', color: '#606266', border: '1rpx solid #dcdfe6' }" @click="goBack"></u-button>
<u-button text="审核" type="primary" shape="circle" :customStyle="{ flex: 1, background: '#2979ff' }" @click="openModal"></u-button>
</view>
<!-- 审批弹窗 - 底部弹出 -->
<u-popup :show="showModal" mode="bottom" round="24" @close="closeModal">
<view class="approve-modal">
<view class="modal-title">审核销售订单</view>
<view class="modal-body">
<u-radio-group v-model="modalStatus" placement="row">
<u-radio :name="1" label="同意" :customStyle="{ marginRight: '60rpx' }"></u-radio>
<u-radio :name="2" label="不同意" activeColor="#2979ff"></u-radio>
</u-radio-group>
<view class="modal-textarea-wrap">
<u-textarea v-model="remark" :placeholder="modalStatus === 2 ? '不同意时,必须填写说明...' : '请输入审批意见(选填)'" :maxlength="200" height="200"></u-textarea>
</view>
</view>
<view class="modal-footer">
<u-button text="取消" shape="circle" :customStyle="{ flex: 1, marginRight: '20rpx', background: '#ffffff', color: '#606266', border: '1rpx solid #dcdfe6' }" @click="closeModal"></u-button>
<u-button text="确认" type="primary" shape="circle" :loading="submitting" :customStyle="{ flex: 1, background: '#2979ff' }" @click="submitApprove"></u-button>
</view>
</view>
</view>
<view class="bottom-actions">
<u-button text="拒绝" shape="circle" :customStyle="{ flex: 1, marginRight: '24rpx', background: '#ffffff', color: '#606266', border: '1rpx solid #dcdfe6' }" @click="handleReject"></u-button>
<u-button text="同意" type="primary" shape="circle" :customStyle="{ flex: 1, background: 'linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)' }" @click="handleApprove"></u-button>
</view>
</u-popup>
</view>
</template>
<script>
import { API } from '@/util/api';
export default {
data() {
return {
detail: {
applyType: '费用减免申请',
customerName: '深圳市海克斯科技有限公司',
deductionType: '代理费减免',
applyTime: '2026-04-10 15:00',
orderNo: 'B123456',
applicant: '陈小将',
orderAmount: '100000.00',
currency: '美元',
agentFee: '300.00',
minAgentFee: '300.00',
amount: '3,000.00',
reason: '业务员在发起申请的时必须填写,字数长度不限定,宇航长度不限定',
logs: [
{
time: '1.2026-01-20 16:37',
approver: '周家仪',
comment: 'xxxxxxxxxxxx',
status: 'approved',
statusText: '通过'
},
{
time: '2.2026-01-20 16:37',
approver: '周家仪',
comment: 'xxxxxxxxxxxx',
status: 'approved',
statusText: '通过'
}
]
}
id: '',
detail: {},
showModal: false,
modalStatus: 1,
remark: '',
submitting: false
};
},
onLoad(options) {
this.id = options.id || '';
},
onShow() {
if (this.id) {
this.getData();
}
},
methods: {
/**
* 拒绝审批
* 通过列表接口获取当前审批详情
* @return {void}
*/
handleReject() {
// 后续接入接口逻辑
getData() {
this.request(API.feeApproveList, 'GET', { id: this.id }, true).then(res => {
if (res.code === 0) {
var { list = [] } = res.data || {};
this.detail = list[0] || {};
if (this.detail.order_sn) {
uni.setNavigationBarTitle({
title: `${this.detail.order_sn} - 审核详情`
});
}
}
});
},
/**
* 返回上一页
* @return {void}
*/
goBack() {
uni.navigateBack();
},
/**
* 打开审批弹窗
* @return {void}
*/
openModal() {
this.modalStatus = 1;
this.remark = '';
this.showModal = true;
},
/**
* 同意审批
* 关闭审批弹窗
* @return {void}
*/
handleApprove() {
// 后续接入接口逻辑
closeModal() {
this.showModal = false;
},
/**
* 提交审批
* @return {void}
*/
submitApprove() {
if (this.modalStatus === 2 && !this.remark.trim()) {
uni.showToast({ title: '请输入驳回原因', icon: 'none' });
return;
}
this.submitting = true;
var params = {
id: this.id,
status: this.modalStatus
};
if (this.remark.trim()) {
params.remark = this.remark.trim();
}
this.request(API.updateFeeApproveStatus, 'POST', params).then(res => {
this.submitting = false;
if (res.code === 0) {
uni.showToast({ title: '操作成功', icon: 'success' });
this.closeModal();
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
}).catch(() => {
this.submitting = false;
});
}
}
};
......
......@@ -117,7 +117,7 @@
*/
handleApprove(item) {
uni.navigateTo({
url: '/pages/approve/detail'
url: `/pages/approve/detail?id=${item.id}`
});
}
}
......
......@@ -58,7 +58,11 @@ const API = {
/**
* 获取审批列表
*/
feeApproveList: API_BASE + '/api/approve/feeApproveList'
feeApproveList: API_BASE + '/api/approve/feeApproveList',
/**
* 费用审批状态修改
*/
updateFeeApproveStatus: API_BASE + '/api/approve/updateFeeApproveStatus'
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment