c554bd67 by lttnew

开票+订单+详情

1 parent 4cf9d409
{
"permissions": {
"allow": [
"Bash(ls D:/ltt/ztx_wx_gzt/views/*/index.vue)"
]
}
}
......@@ -127,6 +127,14 @@ export function deptTreeSelect(params) {
return res
})
}
// 注册选择协会树
export function certifiedDeptTreeRegister(params) {
return request({
url: '/system/user/certifiedDeptTreeWithNoDaoguan2',
method: 'get',
params
})
}
const setIdToString = (list) => {
for (var l of list) {
l.id += ''
......@@ -1502,4 +1510,177 @@ export function getAssoPers(perId) {
url: '/person/info/getRoleListByPerId/' + perId,
method: 'get'
})
}
\ No newline at end of file
}
export function checkMember(data) {
return request({
url: '/member/info/checkMember',
method: 'post',
data
})
}
export function getBusinessLicense(data) {
return request({
url: `/member/info/getBusinessLicense`,
method: 'post',
data: data
})
}
export function getLogs(examId, type) {
return request({
url: `/exam/info/getLogs/${examId}`,
method: 'get',
params: { type } // 1 级位 2 段位 3 段位成绩 4 越段 5 越段成绩
})
}
export function newGetLogs(id) {
return request({
url: `/person/paymentRangeNew/getLogs/${id}`,
method: 'get',
})
}
export function certifiedNewList(params) {
return request({
url: `/system/certifiedNew/list`,
method: 'get',
params
})
}
export function certifiedNewGetLogs(id) {
return request({
url: `/system/certifiedNew/getLogs/${id}`,
method: 'get',
})
}
// 地址管理
export function getAddressList(params) {
return request({
url: `/member/postAddress/list`,
method: 'get',
params
})
}
export function setDefaultAddress(id) {
return request({
url: `/system/address/setDefault/${id}`,
method: 'put'
})
}
// 级位考试确认
export function confirmExam(examId) {
return request({
url: `/exam/info/confirmExam/${examId}`,
method: 'get'
})
}
// 提交级位考试订单
export function commitJiExam(data) {
return request({
url: `/exam/person/commitJi`,
method: 'post',
data
})
}
// 级位考试支付
export function payJiExam(orderId) {
return request({
url: `/exam/person/pay/${orderId}`,
method: 'post'
})
}
/**
* 新增收货地址
* @param data
* @returns {*}
*/
export function addMyAddress(data) {
return request({
url: `/member/postAddress/addMyAddress`,
method: 'post',
params: data
})
}
/**
* 地址列表
* @param params
* @returns {*}
*/
export function postAddressListAPI(params) {
return request({
url: `/member/postAddress/list`,
method: 'get',
params
})
}
/**
* 编辑地址
* @data data
* @returns {*}
*/
export function editMyAddress(data) {
return request({
url: `/member/postAddress/editMyAddress`,
method: 'post',
params: data
})
}
/**
* 删除地址
* @param id
* @returns {*}
*/
export function postAddressDel(id) {
return request({
url: `/member/postAddress/${id}`,
method: 'delete',
})
}
/**
* 默认地址
* @param id
* @returns {*}
*/
export function setDefault(id) {
return request({
url: `/member/postAddress/setDefault/${id}`,
method: 'put',
})
}
/**
* 获取默认地址
* @param id
* @returns {*}
*/
export function getDefaultAddress() {
return request({
url: `/member/postAddress/getDefaultAddress`,
method: 'get',
})
}
/**
* 订单修改地址
* @param examId,addressId
* @returns {*}
*/
export function editAddressOrder(examId, addressId) {
return request({
url: `/exam/info/editAddress/${examId}/${addressId}`,
method: 'put'
})
}
......
// dev
const baseUrl_api = 'http://192.168.1.137:8787'
// const baseUrl_api = 'http://192.168.1.137:8787'
const baseUrl_api = 'http://tk001.wxjylt.com/stage-api'
const payUrl = 'https://wxpay.cmbc.com.cn/mobilePlatform/appserver/lcbpPay.do'
// prod
......
......@@ -28,7 +28,7 @@
<!-- 成员 -->
<view class="userlist">
<view class="item" style="padding: 20rpx 0 0;" v-for="(n,index) in list" :key="n.index" @click="goGroupInfo(n)">
<view class="item" style="padding: 20rpx 0 0;" v-for="(n,index) in list" :key="index" @click="goGroupInfo(n)">
<view style="width: 100%">
<view class="name text-primary underLine">{{n.memberName}}</view>
<view class="date">单位类型:
......@@ -139,7 +139,7 @@
}
list.value = form.content?.certifiedSimpleList || []
listArr.value = form.content?.certifiedSimpleList || []
queryParams.value.recordId = form.value.recordId
queryParams.value.recordId = form.value.recordId
console.log(form.value)
if (app.globalData.isLogin) {
init()
......@@ -217,11 +217,11 @@
reason: reason || '',
rangeIds: rangeIds
}
console.log(obj)
uni.showLoading({
title: '加载中'
console.log(obj)
uni.showLoading({
title: '加载中'
})
api.mobilizeAudit(obj).then((res) => {
api.mobilizeAudit(obj).then((res) => {
uni.hideLoading()
uni.showToast({
title: '操作成功',
......@@ -229,11 +229,11 @@
})
uni.navigateBack()
})
}
function goGroupInfo(row){
uni.navigateTo({
url: `/group/groupInfo?memId=${row.memId}`
})
}
function goGroupInfo(row){
uni.navigateTo({
url: `/group/groupInfo?memId=${row.memId}`
})
}
</script>
......
<template>
<view class="order-page">
<!-- 顶部Tab -->
<view class="tab-bar">
<view
v-for="(tab, index) in statusTabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@click="switchTab(index)"
>
{{ tab.name }}
</view>
</view>
<!-- 列表 -->
<scroll-view
scroll-y
class="order-list-scroll"
:show-scrollbar="false"
@scrolltolower="loadMore"
lower-threshold="200"
>
<view class="order-list">
<view v-if="list.length > 0">
<view
class="order-card"
v-for="(item, index) in list"
:key="index"
>
<!-- 卡片头部:日期 + 状态 -->
<view class="card-header">
<view class="date">
<image src="/static/calendar@2x.png" v-if="item.commitTime" mode="widthFix" style="width:30rpx;height:30rpx;"/>
<text class="date-text" v-if="item.commitTime">{{ item.commitTime }}</text>
</view>
<view class="status-tags">
<view class="status-tag" :class="getAuditStatusClass(item.auditStatus)">
{{ getAuditStatusText(item.auditStatus) }}
</view>
</view>
</view>
<!-- 基本信息 -->
<view class="info-row">
<text class="label">缴费编号:</text>
<text class="value">{{ item.wfCode || '--' }}</text>
</view>
<view class="info-row">
<text class="label">缴费单位:</text>
<text class="value">{{ item.memName || '--' }}</text>
</view>
<view class="info-row">
<text class="label">所属协会:</text>
<text class="value">{{ item.shenMemName || '--' }}</text>
</view>
<!-- 费用信息区 -->
<view class="info-section">
<view class="info-item">
<text class="item-label">新会员</text>
<text class="item-value">{{ item.isNew == 1 ? '是' : '否' }}</text>
</view>
<view class="info-line"></view>
<view class="info-item">
<text class="item-label">认证年限</text>
<text class="item-value">{{ item.renewYear ? item.renewYear + '年' : '--' }}</text>
</view>
<view class="info-line"></view>
<view class="info-item">
<text class="item-label">费用合计</text>
<text class="item-value">¥{{ (Number(item.allPrice) || 0).toFixed(2) }}</text>
</view>
</view>
<!-- 费用明细 -->
<view class="price-section">
<view class="price-row">
<text class="price-label">政策优惠</text>
<text class="price-value">{{ item.discount || '--' }}</text>
</view>
<view class="price-row">
<text class="price-label">付款费用</text>
<text class="price-value">¥{{ (Number(item.finalPrice) || 0).toFixed(2) }}</text>
</view>
<view class="price-row">
<text class="price-label">审核日期</text>
<text class="price-value">{{ item.auditTime || '--' }}</text>
</view>
</view>
<!-- 协会信息 -->
<view class="info-row">
<text class="label">协会信息:</text>
<text class="value" :class="item.checkPass == 0 ? 'text-danger' : 'text-success'">
{{ item.checkPass == 0 ? '异常' : '正常' }}
</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-else class="empty">
<text class="empty-text">暂无审核记录</text>
</view>
<!-- 加载/无更多提示 -->
<view class="loading-tip" v-if="loading">加载中...</view>
<view class="no-more" v-if="!loading && !hasMore && list.length > 0">没有更多了</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import * as api from '@/common/api.js';
// 状态Tab配置
const statusTabs = [
{ name: '全部', type: '' },
{ name: '审核中', type: '1' },
{ name: '审核通过', type: '2' },
{ name: '审核拒绝', type: '3' }
];
const currentTab = ref(0);
const list = ref([]);
const loading = ref(false);
const hasMore = ref(true);
const pageNum = ref(1);
const pageSize = ref(10);
onMounted(() => {
initData();
});
// 切换Tab
const switchTab = (index) => {
currentTab.value = index;
pageNum.value = 1;
list.value = [];
hasMore.value = true;
initData();
};
// 上拉加载更多
const loadMore = () => {
console.log("触发上拉加载");
if (loading.value || !hasMore.value) return;
pageNum.value++;
initData();
};
// 获取列表数据
const initData = async () => {
loading.value = true;
try {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value,
auditStatus: statusTabs[currentTab.value].type
};
const res = await api.certifiedNewList(params);
console.log("接口返回:", res);
if (!res || !res.rows || res.rows.length === 0) {
hasMore.value = false;
loading.value = false;
return;
}
// 第一页覆盖,后面页数追加
if (pageNum.value === 1) {
list.value = res.rows;
} else {
list.value.push(...res.rows);
}
// 关键修复:只要返回条数 < pageSize 就说明没有更多了
hasMore.value = res.rows.length === pageSize.value;
} catch (e) {
console.error('审核记录加载异常:', e);
uni.showToast({ title: '加载失败', icon: 'none' });
hasMore.value = false;
} finally {
loading.value = false;
}
};
// 审核状态文本
const getAuditStatusText = (status) => {
const map = { 1: '审核中', 2: '审核通过', 3: '审核拒绝' };
return map[status] || '未知';
};
const getAuditStatusClass = (status) => {
const map = { 1: 'pending', 2: 'success', 3: 'danger' };
return map[status] || '';
};
</script>
<style lang="scss" scoped>
.order-page {
height: 100vh;
background: #f5f7fa;
display: flex;
flex-direction: column;
}
// Tab
.tab-bar {
display: flex;
background: #fff;
border-bottom: 1rpx solid #eee;
flex-shrink: 0;
.tab-item {
flex: 1;
text-align: center;
padding: 24rpx 0;
font-size: 28rpx;
color: #666;
position: relative;
&.active {
color: #e4393c;
font-weight: 500;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 4rpx;
background: linear-gradient(90deg, #FF755A, #F51722);
border-radius: 2rpx;
}
}
}
}
// 滚动列表容器
.order-list-scroll {
flex: 1;
height: auto;
overflow: auto;
}
.order-list {
padding: 20rpx;
}
.order-card {
background: #fff;
margin-bottom: 20rpx;
padding: 24rpx;
border-radius: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
border-top: 6rpx solid transparent;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
background-image: linear-gradient(#fff, #fff), linear-gradient(90deg, #FF755A, #F51722);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
margin-bottom: 20rpx;
border-bottom: 1rpx dashed #eee;
.date {
display: flex;
align-items: center;
gap: 8rpx;
.date-text {
font-size: 26rpx;
color: #666;
}
}
.status-tags {
display: flex;
gap: 10rpx;
}
.status-tag {
font-size: 22rpx;
padding: 6rpx 16rpx;
border-radius: 20rpx;
&.success {
background: #e6f7ef;
color: #52c41a;
}
&.danger {
background: #fff1f0;
color: #ff4d4f;
}
&.pending {
background: #f5f5f5;
color: #999;
}
&.warning {
background: #fff7e6;
color: #faad14;
}
}
}
.info-row {
display: flex;
align-items: center;
margin-bottom: 16rpx;
font-size: 26rpx;
.label {
color: #999;
flex-shrink: 0;
min-width: 140rpx;
}
.value {
color: #333;
word-break: break-all;
&.text-success {
color: #52c41a;
}
&.text-danger {
color: #ff4d4f;
}
}
}
.info-section {
display: flex;
align-items: center;
background: #f3f6fc;
padding: 16rpx 20rpx;
margin: 16rpx 0;
border-radius: 8rpx;
.info-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.item-label {
font-size: 24rpx;
color: #999;
}
.item-value {
font-size: 28rpx;
color: #333;
font-weight: 500;
margin-top: 8rpx;
}
}
.info-line {
width: 1rpx;
height: 60rpx;
background: #ddd;
}
}
.price-section {
border-top: 1rpx dashed #eee;
padding-top: 16rpx;
margin-top: 8rpx;
.price-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8rpx 0;
.price-label {
font-size: 26rpx;
color: #333;
}
.price-value {
font-size: 26rpx;
color: #666;
}
}
}
.empty {
display: flex;
justify-content: center;
align-items: center;
padding: 120rpx 0;
.empty-text {
color: #999;
font-size: 28rpx;
}
}
.loading-tip,
.no-more {
text-align: center;
padding: 20rpx 0;
color: #999;
font-size: 26rpx;
}
</style>
......@@ -605,15 +605,23 @@
uni.showModal({
title: '提示',
content: `确定提交审核?`,
content: `请确认人员照片是否已更新?`,
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
saveStep2(flag).then(Response => {
uni.showToast({
title: `操作成功`
})
uni.navigateBack()
if (flag === 1) {
uni.showToast({
title: `提交成功`
})
uni.navigateTo({
url: `/level/paymentDetail?examId=${form.value.examId}`
})
} else {
uni.showToast({
title: `操作成功`
})
}
})
} else if (res.cancel) {
console.log('用户点击取消');
......
......@@ -7,7 +7,7 @@
<view class="invertedbtn-red" v-if="isExam=='0'" @click="goAdd">+ 添加级位考试</view>
</view>
<view class="appList">
<view class="appItem" v-for="(item,index) in list" :key="item">
<view class="appItem" v-for="(item,index) in list" :key="item.examId || index">
<view class="status" @click="goDetail(item)">
<text v-if="item.status=='0'" class="text-primary">{{ item.statusStr }}</text>
<text v-if="item.status=='1'" class="text-primary">{{ item.statusStr }}</text>
......@@ -125,13 +125,13 @@
function handleSubmit(item) {
uni.showModal({
title: '提示',
content: `确定提交${item.name}进行审核吗`,
content: `请确认人员照片是否已更新`,
success: function(res) {
if (res.confirm) {
uni.showLoading({
title: `提交中`
})
upApply(item.examId)
// 跳转到付款详情页面
uni.navigateTo({
url: `/level/paymentDetail?examId=${item.examId}`
});
}
}
})
......
......@@ -171,7 +171,7 @@
}
function getRecordList() {
api.getApprovalRecord(examId).then(res => {
api.getLogs(examId).then(res => {
recordList.value = res.data.levelSteps
uni.hideLoading()
})
......
<template>
<view class="order-page">
<!-- 顶部Tab -->
<view class="tab-bar">
<view
v-for="(tab, index) in statusTabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@click="switchTab(index)"
>
{{ tab.name }}
</view>
</view>
<!-- 列表 -->
<scroll-view
scroll-y
class="order-list-scroll"
:show-scrollbar="false"
@scrolltolower="loadMore"
lower-threshold="200"
>
<view class="order-list">
<view v-if="list.length > 0">
<view
class="order-card"
v-for="(item, index) in list"
:key="index"
>
<!-- 卡片头部:日期 + 状态 -->
<view class="card-header">
<view class="date">
<image src="/static/calendar@2x.png" v-if="item.commitTime" mode="widthFix" style="width:30rpx;height:30rpx;"/>
<text class="date-text" v-if="item.commitTime">{{ item.commitTime }}</text>
</view>
<view class="status-tags">
<view class="status-tag" :class="getStatusClass(item.status)">
{{ item.statusStr || '待提交' }}
</view>
</view>
</view>
<!-- 基本信息 -->
<view class="info-row">
<text class="label">缴费编号:</text>
<text class="value">{{ item.examCode || '--' }}</text>
</view>
<view class="info-row">
<text class="label">缴费名称:</text>
<text class="value">{{ item.name || '--' }}</text>
</view>
<view class="info-row">
<text class="label">上报单位:</text>
<text class="value">{{ item.memberName || '--' }}</text>
</view>
<!-- 费用信息区 -->
<view class="info-section">
<view class="info-item">
<text class="item-label">考试人数</text>
<text class="item-value">{{ item.totalNum || 0 }}</text>
</view>
<view class="info-line"></view>
<view class="info-item">
<text class="item-label">总金额</text>
<text class="item-value">¥{{ (Number(item.price) || 0).toFixed(2) }}</text>
</view>
<view class="info-line"></view>
<view class="info-item">
<text class="item-label">支付方式</text>
<text class="item-value">民生付</text>
</view>
</view>
<!-- 审核信息 -->
<view class="price-section">
<view class="price-row">
<text class="price-label">提交日期</text>
<text class="price-value">{{ item.commitTime || '--' }}</text>
</view>
<view class="price-row">
<text class="price-label">审核日期</text>
<text class="price-value">{{ item.handleDate || '--' }}</text>
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-else class="empty">
<text class="empty-text">暂无审核记录</text>
</view>
<!-- 加载/无更多提示 -->
<view class="loading-tip" v-if="loading">加载中...</view>
<view class="no-more" v-if="!loading && !hasMore && list.length > 0">没有更多了</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import * as api from '@/common/api.js';
// 状态Tab配置
const statusTabs = [
{ name: '全部', type: '' },
{ name: '审批中', type: '1' },
{ name: '审批通过', type: '2' },
{ name: '审批拒绝', type: '3' }
];
const currentTab = ref(0);
const list = ref([]);
const loading = ref(false);
const hasMore = ref(true);
const pageNum = ref(1);
const pageSize = ref(10);
onMounted(() => {
initData();
});
// 切换Tab
const switchTab = (index) => {
currentTab.value = index;
pageNum.value = 1;
list.value = [];
hasMore.value = true;
initData();
};
// 上拉加载更多
const loadMore = () => {
console.log("触发上拉加载");
if (loading.value || !hasMore.value) return;
pageNum.value++;
initData();
};
// 获取列表数据
const initData = async () => {
loading.value = true;
try {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value,
status: statusTabs[currentTab.value].type,
auditSelectType: '1'
};
const res = await api.getLevelList(params);
console.log("接口返回:", res);
if (!res || !res.rows || res.rows.length === 0) {
hasMore.value = false;
loading.value = false;
return;
}
// 第一页覆盖,后面页数追加
if (pageNum.value === 1) {
list.value = res.rows;
} else {
list.value.push(...res.rows);
}
// 关键修复:只要返回条数 < pageSize 就说明没有更多了
hasMore.value = res.rows.length === pageSize.value;
} catch (e) {
console.error('加载失败:', e);
uni.showToast({ title: '加载失败', icon: 'none' });
hasMore.value = false;
} finally {
loading.value = false;
}
};
// 状态样式
const getStatusClass = (status) => {
const map = { '1': 'pending', '2': 'success', '3': 'danger', '4': 'warning' };
return map[status] || '';
};
</script>
<style lang="scss" scoped>
.order-page {
height: 100vh;
background: #f5f7fa;
display: flex;
flex-direction: column;
}
// Tab
.tab-bar {
display: flex;
background: #fff;
border-bottom: 1rpx solid #eee;
flex-shrink: 0;
.tab-item {
flex: 1;
text-align: center;
padding: 24rpx 0;
font-size: 28rpx;
color: #666;
position: relative;
&.active {
color: #e4393c;
font-weight: 500;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 4rpx;
background: linear-gradient(90deg, #FF755A, #F51722);
border-radius: 2rpx;
}
}
}
}
// 滚动列表容器 —— 这里是关键修复
.order-list-scroll {
flex: 1;
height: auto;
overflow: auto;
}
.order-list {
padding: 20rpx;
}
.order-card {
background: #fff;
margin-bottom: 20rpx;
padding: 24rpx;
border-radius: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
border-top: 6rpx solid transparent;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
background-image: linear-gradient(#fff, #fff), linear-gradient(90deg, #FF755A, #F51722);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
margin-bottom: 20rpx;
border-bottom: 1rpx dashed #eee;
.date {
display: flex;
align-items: center;
gap: 8rpx;
.date-text {
font-size: 26rpx;
color: #666;
}
}
.status-tags {
display: flex;
gap: 10rpx;
}
.status-tag {
font-size: 22rpx;
padding: 6rpx 16rpx;
border-radius: 20rpx;
&.success {
background: #e6f7ef;
color: #52c41a;
}
&.danger {
background: #fff1f0;
color: #ff4d4f;
}
&.pending {
background: #f5f5f5;
color: #999;
}
&.warning {
background: #fff7e6;
color: #faad14;
}
}
}
.info-row {
display: flex;
align-items: center;
margin-bottom: 16rpx;
font-size: 26rpx;
.label {
color: #999;
flex-shrink: 0;
min-width: 140rpx;
}
.value {
color: #333;
word-break: break-all;
}
}
.info-section {
display: flex;
align-items: center;
background: #f3f6fc;
padding: 16rpx 20rpx;
margin: 16rpx 0;
border-radius: 8rpx;
.info-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.item-label {
font-size: 24rpx;
color: #999;
}
.item-value {
font-size: 28rpx;
color: #333;
font-weight: 500;
margin-top: 8rpx;
}
}
.info-line {
width: 1rpx;
height: 60rpx;
background: #ddd;
}
}
.price-section {
border-top: 1rpx dashed #eee;
padding-top: 16rpx;
margin-top: 8rpx;
.price-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8rpx 0;
.price-label {
font-size: 26rpx;
color: #333;
}
.price-value {
font-size: 26rpx;
color: #666;
}
}
}
.empty {
display: flex;
justify-content: center;
align-items: center;
padding: 120rpx 0;
.empty-text {
color: #999;
font-size: 28rpx;
}
}
.loading-tip,
.no-more {
text-align: center;
padding: 20rpx 0;
color: #999;
font-size: 26rpx;
}
</style>
\ No newline at end of file
......@@ -62,8 +62,8 @@
<button @click="login" class="btn-red">登录</button>
</view>
<view class="center-item">
<!-- <text class="text-red" @click="goRegister">没有账号,去注册</text> -->
</view>
<text class="text-red" @click="goRegister">没有账号,去注册</text>
</view>
</view>
<view class="wNumber">
技术服务热线:<text @click="call('15606190026')">15606190026</text> / <text
......
This diff could not be displayed because it is too large.
<template>
<view class="audit-page">
<!-- 审核记录表格 -->
<view class="table-container">
<view class="table-header">
<view class="th th-index">序号</view>
<view class="th th-dept">审核协会</view>
<view class="th th-date">审核日期</view>
<view class="th th-status">审核状态</view>
<view class="th th-reason">理由</view>
</view>
<view class="table-body" v-if="loading">
<view class="loading-row">加载中...</view>
</view>
<view class="table-body" v-if="recordList.length > 0">
<view class="table-row" v-for="(item, index) in recordList" :key="index">
<view class="td td-index">{{ index + 1 }}</view>
<view class="td td-dept">{{ item.auditDeptName || '/' }}</view>
<view class="td td-date">{{ formatDate(item.auditTime) }}</view>
<view class="td td-status">
<text v-if="item.auditResult == 1" class="status-success">审核通过</text>
<text v-else-if="item.auditResult == 0" class="status-reject">审核拒绝</text>
<text v-else class="status-pending">待审核</text>
</view>
<view class="td td-reason">{{ item.auditMsg || '/' }}</view>
</view>
</view>
<view class="table-body" v-else>
<view class="empty-row">暂无审核记录</view>
</view>
</view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import {
ref,
onMounted
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app'
const loading = ref(true)
const recordList = ref([])
onLoad(async (option) => {
await getMyRecentFN()
})
onMounted(() => {
getMyRecentFN()
})
async function getMyRecentFN() {
loading.value = true
try {
const res = await api.getMyRecent()
loading.value = false
if (res.code === 200 && res.data && res.data.auditLogs) {
recordList.value = JSON.parse(res.data.auditLogs)
} else {
// 清空记录列表,显示暂无记录
recordList.value = []
}
} catch (e) {
loading.value = false
// 清空记录列表,显示暂无记录
recordList.value = []
console.error('获取审核记录失败', e)
}
}
function formatDate(dateStr) {
if (!dateStr) return '/'
const date = new Date(dateStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
</script>
<style scoped lang="scss">
.audit-page {
min-height: 100vh;
background: #f5f5f5;
padding-bottom: 40rpx;
}
.page-header {
background: linear-gradient(135deg, #1561cb 0%, #1e7de1 100%);
padding: 30rpx;
text-align: center;
.header-title {
font-size: 32rpx;
font-weight: 600;
color: #fff;
}
}
.table-container {
margin: 30rpx;
background: #fff;
border-radius: 12rpx;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
.table-header {
display: flex;
background: #f5f7fa;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
.th {
font-size: 24rpx;
color: #666;
font-weight: 600;
text-align: center;
}
.th-index {
width: 80rpx;
}
.th-dept {
flex: 1;
min-width: 150rpx;
}
.th-date {
width: 160rpx;
}
.th-status {
width: 140rpx;
}
.th-reason {
flex: 1;
min-width: 120rpx;
}
}
.table-body {
.table-row {
display: flex;
padding: 24rpx 0;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
}
.td {
font-size: 24rpx;
color: #333;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.td-index {
width: 80rpx;
color: #999;
}
.td-dept {
flex: 1;
min-width: 150rpx;
padding: 0 10rpx;
word-break: break-all;
}
.td-date {
width: 160rpx;
color: #666;
font-size: 22rpx;
}
.td-status {
width: 140rpx;
.status-success {
color: #07c07e;
}
.status-reject {
color: #e64329;
}
.status-pending {
color: #ff9800;
}
}
.td-reason {
flex: 1;
min-width: 120rpx;
padding: 0 10rpx;
font-size: 22rpx;
color: #666;
word-break: break-all;
}
}
.loading-row,
.empty-row {
padding: 60rpx 0;
text-align: center;
font-size: 26rpx;
color: #999;
}
</style>
......@@ -22,7 +22,7 @@
<uni-list-item thumb="/static/user_icon03.png" title="账号安全" showArrow clickable @click="goPath('/myCenter/safe')">
</uni-list-item>
<uni-list-item thumb="/static/user_icon03.png" title="我的订单" showArrow clickable @click="goPath('/myCenter/order')">
<uni-list-item thumb="/static/user_icon03.png" v-if="userType==2 || userType==6" title="我的订单" showArrow clickable @click="goPath('/myCenter/order')">
</uni-list-item>
</uni-list>
......@@ -57,7 +57,7 @@ const {
const app = getApp();
const userType = ref('1')
const memberInfo = ref({})
const deptInfo = ref({})
let proId;
const svId = ref(null);
const numData = ref({});
......@@ -125,6 +125,7 @@ function init() {
loginServer.getMyOwnMemberInfo().then(res => {
userType.value = app.globalData.userType
memberInfo.value = app.globalData.memberInfo
deptInfo.value = app.globalData.dept || {}
uni.hideLoading();
})
}
......
......@@ -49,7 +49,7 @@
}, {
"path": "pages/rank/applyDetail",
"style": {
"navigationBarTitleText": "段位考试详情",
"navigationBarTitleText": "考试详情",
"enablePullDownRefresh": false
}
......@@ -61,6 +61,14 @@
}
}, {
"path": "pages/index/orderList",
"style": {
"navigationBarTitleText": "订单列表",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}, {
"path": "pages/rank/scoreApproval",
"style": {
"navigationBarTitleText": "段位考试成绩审核",
......@@ -296,6 +304,17 @@
"navigationBarTitleText": "会员调动",
"enablePullDownRefresh": false
}
}, {"path": "order",
"style": {
"navigationBarTitleText": "订单列表",
"enablePullDownRefresh": false
}
}, {
"path": "orderDetail",
"style": {
"navigationBarTitleText": "订单详情",
"enablePullDownRefresh": false
}
}, {
"path": "mobilizeDetail",
"style": {
......@@ -456,6 +475,19 @@
}, {
"root": "group",
"pages": [{
"path": "auditRecord1",
"style": {
"navigationBarTitleText": "审核记录",
"enablePullDownRefresh": false
}
}, {
"path": "groupOrderDetail",
"style": {
"navigationBarTitleText": "订单详情",
"enablePullDownRefresh": false
}
}, {
"path": "addGroupMemberPay",
"style": {
"navigationBarTitleText": "添加缴费",
......@@ -596,6 +628,24 @@
}, {
"root": "level",
"pages": [{
"path": "auditRecord2",
"style": {
"navigationBarTitleText": "审核记录",
"enablePullDownRefresh": false
}
}, {
"path": "paymentDetail",
"style": {
"navigationBarTitleText": "付款详情",
"enablePullDownRefresh": false
}
}, {
"path": "addressManage",
"style": {
"navigationBarTitleText": "地址管理",
"enablePullDownRefresh": false
}
}, {
"path": "ztx/examList",
"style": {
"navigationBarTitleText": "级位考试详情",
......@@ -735,6 +785,13 @@
{
"path": "reviewList",
"style": {
"navigationBarTitleText": "审核信息",
"enablePullDownRefresh": false
}
},
{
"path": "certAuditDetail",
"style": {
"navigationBarTitleText": "审核详情",
"enablePullDownRefresh": false
}
......
......@@ -27,7 +27,7 @@
考试信息
</view>
<view class="userlist">
<view class="item" v-for="n in infoList" @click="goDetail(n)" style="background-color: #fffafa;">
<view class="item" v-for="(n,index) in infoList" :key="index" @click="goDetail(n)" style="background-color: #fffafa;">
<view class="w100">
<view class="text-primary">{{n.examCode}}</view>
<view class="name">{{n.name}}</view>
......
......@@ -114,6 +114,10 @@
<image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
信息变更
</view>
<view @click="goPath('/group/auditRecord1')">
<image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
审核记录
</view>
</view>
<view class="ttt">级位管理</view>
<view class="girdBox">
......@@ -128,6 +132,10 @@
<image :src="config.baseUrl_api+'/fs/static/icon/26.png'" />
级位变更
</view>
<view @click="goPath('/level/auditRecord2')">
<image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
审核记录
</view>
</view>
<!-- <view class="ttt">段位管理</view>
......@@ -178,6 +186,10 @@
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
合并审核
</view>
<view @click="goPath('/personalVip/order?type=0')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
订单列表
</view>
</view>
<view class="ttt">团体会员</view>
......@@ -191,7 +203,10 @@
<image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
变更审核
</view>
<view @click="goPath('/personalVip/order?type=1')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
订单列表
</view>
</view>
<view class="ttt">级位管理</view>
......@@ -209,6 +224,10 @@
<image :src="config.baseUrl_api+'/fs/static/icon/26.png'" />
变更审核
</view>
<view @click="goPath('/personalVip/order?type=2')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
订单列表
</view>
</view>
<view class="ttt">段位管理</view>
......@@ -224,7 +243,10 @@
<view @click="goPath('/level/ztx/cert?type=2')">
<image :src="config.baseUrl_api+'/fs/static/icon/20.png'" />证书发布
</view>
<view @click="goPath('/personalVip/order?type=3')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
订单列表
</view>
</view>
<view class="ttt">越段考试</view>
......@@ -240,6 +262,10 @@
<view @click="goPath('/level/ztx/cert?type=3')">
<image :src="config.baseUrl_api+'/fs/static/icon/23.png'" />证书发布
</view>
<view @click="goPath('/personalVip/order?type=4')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
订单列表
</view>
</view>
</view>
......@@ -285,7 +311,7 @@
const app = getApp();
const userType = ref('1')
const memberInfo = ref({})
const deptInfo = ref({})
let proId;
const svId = ref(null);
const numData = ref({});
......@@ -409,9 +435,21 @@
function init() {
isInit.value = true
loginServer.getMyOwnMemberInfo().then(res => {
userType.value = app.globalData.userType
memberInfo.value = app.globalData.memberInfo
// deptInfo.value = app.globalData.dept || {}
// app.globalData.deptInfo = res.dept || {}
console.log(43,res)
if (userType.value != '1' && app.globalData.authenticationStatus != '2' && app.globalData
.authenticationStatus != '4') {
// 注册引导
uni.navigateTo({
url: '/pages/index/perfect'
});
}
// console.log(userType.value, app.globalData.authenticationStatus)
if (app.globalData.authenticationStatus == '5') {
if (app.globalData.genFlag == 1) {
......@@ -442,13 +480,6 @@
success: function(res) {}
})
}
if (userType.value != '1' && app.globalData.authenticationStatus != '2' && app.globalData
.authenticationStatus != '4') {
// 注册引导
// uni.navigateTo({
// url: '/pages/index/perfect'
// });
}
if (memberInfo.value.activeStatus == 0) {
uni.showModal({
content: '账号未激活,请前去激活',
......
......@@ -80,8 +80,8 @@ const form = reactive({
// 页面加载(接收PC端传来的参数)
onLoad((options) => {
if (options.id) {
form.id = options.id;
if (options.id || options.orderId) {
form.id = options.id|| options.orderId;
form.amount = options.amount;
console.log(33,form.amount);
}
......
<template>
<view>
<scroll-view scroll-y class="detail-content">
<!-- 成员信息 -->
<view class="card">
<view class="card-header">
<view class="header-left">成员信息</view>
<view class="header-right">{{ total || 0 }}</view>
</view>
<!-- 加载状态 -->
<view v-if="loading" class="state-tip">加载中...</view>
<view v-else-if="memberList.length === 0" class="state-tip">暂无成员信息</view>
<!-- 成员列表 - 与级位考试详情考生信息样式一致 -->
<view class="student-list" v-else>
<view class="student-card" v-for="n in memberList" :key="n.payId || n.perId || n.id">
<view class="student-top">
<view class="student-name">
<text class="name">{{ n.perName || n.realName || '——' }}</text>
<text class="unit">{{ n.memName || '' }}</text>
</view>
<view class="new-tag" :class="n.isNew == 1 ? 'is-new' : ''">
{{ n.isNew == 1 ? '新会员' : '续费' }}
</view>
</view>
<view class="student-info">
<view class="info-col">
<text class="info-text">{{ n.perIdcCode || n.idcCode || '——' }}</text>
</view>
<view class="info-col">
<text class="info-text">{{ n.payYear || n.renewYear || '——' }}</text>
</view>
<view class="info-col">
<text class="info-text">{{ getIdcTypeText(n.perIdcType || n.idcType) }}</text>
</view>
</view>
</view>
</view>
<!-- 加载更多 -->
<view class="load-more" v-if="memberList.length > 0 && hasMore" @click="loadMore">
{{ loadingMore ? '加载中...' : '加载更多' }}
</view>
</view>
<!-- 审核记录 -->
<view class="card">
<view class="card-header">
<view class="header-left">审核记录</view>
</view>
<view v-if="loadingAudit" class="state-tip">加载中...</view>
<view v-else-if="auditList.length === 0" class="state-tip">暂无审核记录</view>
<view class="audit-list" v-else>
<view class="audit-item" v-for="(n, index) in auditList" :key="index">
<view class="audit-dot" :class="n.auditResult == 1 ? 'pass' : 'fail'"></view>
<view class="audit-content">
<view class="audit-time">{{ parseDateTime(n.auditTime) }}</view>
<view class="audit-status" :class="n.auditResult == 1 ? 'text-green' : 'text-red'">
{{ getAuditResultText(n.auditResult) }}
</view>
<view class="audit-dept">{{ n.auditDeptName || '——' }}</view>
<view class="audit-remark" v-if="n.auditMsg">备注:{{ n.auditMsg }}</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
const orderInfo = ref({})
const memberList = ref([])
const auditList = ref([])
const total = ref(0)
const loading = ref(false)
const loadingAudit = ref(false)
const loadingMore = ref(false)
const hasMore = ref(false)
const queryParams = ref({
pageNum: 1,
pageSize: 10
})
let rangeId = ''
onLoad((option) => {
if (!option.rangeId) {
uni.showToast({ title: '参数错误', icon: 'none' })
setTimeout(() => uni.navigateBack(), 1500)
return
}
rangeId = option.rangeId
initData()
})
function initData() {
uni.showLoading({ title: '加载中' })
getMemberList()
getAuditList()
}
function getMemberList() {
loading.value = true
queryParams.value.rangeId = rangeId
api.listAPI(queryParams.value).then(res => {
uni.hideLoading()
if (res && res.rows) {
if (queryParams.value.pageNum === 1) {
memberList.value = res.rows
} else {
memberList.value.push(...res.rows)
}
total.value = res.total || memberList.value.length
hasMore.value = memberList.value.length < (res.total || 0)
} else {
memberList.value = []
total.value = 0
hasMore.value = false
}
}).catch(err => {
uni.hideLoading()
console.error('getMemberList error:', err)
memberList.value = []
}).finally(() => {
loading.value = false
})
}
function getAuditList() {
loadingAudit.value = true
api.newGetLogs(rangeId).then(res => {
if (res && res.data) {
auditList.value = Array.isArray(res.data) ? res.data : (res.data.levelSteps || [])
} else {
auditList.value = []
}
}).catch(err => {
console.error('getAuditList error:', err)
auditList.value = []
}).finally(() => {
loadingAudit.value = false
})
}
function loadMore() {
if (hasMore.value && !loadingMore.value) {
loadingMore.value = true
queryParams.value.pageNum++
getMemberList()
loadingMore.value = false
}
}
function getAuditResultText(result) {
const map = { 0: '审核拒绝', 1: '审核通过' }
return map[result] || '审核中'
}
function getIdcTypeText(type) {
const map = { 1: '身份证', 2: '护照', 3: '其他' }
return map[type] || '其他'
}
function parseDate(dateStr) {
if (!dateStr) return '——'
if (typeof dateStr === 'string' && dateStr.indexOf('T') > -1) {
return dateStr.slice(0, 10)
}
return dateStr
}
function parseDateTime(dateStr) {
if (!dateStr) return '——'
if (typeof dateStr === 'string' && dateStr.indexOf('T') > -1) {
const [date, time] = dateStr.split('T')
return `${date} ${time?.slice(0, 5) || ''}`
}
return dateStr
}
</script>
<style scoped lang="scss">
$primary-color: #e8341d;
$success-color: #52c41a;
$danger-color: #e8341c;
$bg-color: #f5f7fa;
$card-bg: #ffffff;
$text-primary: #333;
$text-secondary: #666;
$text-placeholder: #999;
$border-color: #eee;
$content-gap: 24rpx;
.detail-content {
padding: 20rpx;
background: $bg-color;
min-height: 100vh;
box-sizing: border-box;
}
.card {
background: $card-bg;
border-radius: 16rpx;
margin-bottom: 20rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx $content-gap 20rpx;
border-bottom: 1rpx solid $border-color;
.header-left {
font-size: 30rpx;
font-weight: 600;
color: $text-primary;
}
.header-right {
font-size: 26rpx;
color: $primary-color;
font-weight: 500;
}
}
.state-tip {
text-align: center;
padding: 60rpx 0;
font-size: 26rpx;
color: $text-placeholder;
}
.student-list {
padding: 0 $content-gap 24rpx;
}
.student-card {
border-radius: 12rpx;
padding: 24rpx;
margin-top: 16rpx;
border: 1rpx solid $border-color;
.student-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.student-name {
.name {
font-size: 32rpx;
font-weight: 600;
color: $text-primary;
}
.unit {
font-size: 24rpx;
color: $text-placeholder;
margin-left: 16rpx;
}
}
.new-tag {
font-size: 22rpx;
padding: 6rpx 16rpx;
border-radius: 20rpx;
background: rgba($text-placeholder, 0.1);
color: $text-placeholder;
flex-shrink: 0;
&.is-new {
background: rgba($primary-color, 0.1);
color: $primary-color;
}
}
}
.student-info {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12rpx;
.info-col {
flex: 1;
text-align: center;
.info-text {
font-size: 28rpx;
color: $text-primary;
font-weight: 500;
line-height: 1.4;
}
}
}
}
.load-more {
text-align: center;
padding: 24rpx 0;
font-size: 26rpx;
color: $primary-color;
}
.audit-list {
padding: 0 $content-gap 24rpx;
}
.audit-item {
display: flex;
padding: 20rpx 0;
border-bottom: 1rpx dashed $border-color;
&:last-child {
border-bottom: none;
}
.audit-dot {
width: 14rpx;
height: 14rpx;
border-radius: 50%;
margin-top: 8rpx;
margin-right: 20rpx;
flex-shrink: 0;
&.pass {
background: $success-color;
}
&.fail {
background: $danger-color;
}
}
.audit-content {
flex: 1;
padding-right: 8rpx;
.audit-time {
font-size: 24rpx;
color: $text-placeholder;
margin-bottom: 6rpx;
}
.audit-status {
font-size: 28rpx;
font-weight: 600;
margin-bottom: 6rpx;
}
.audit-dept {
font-size: 26rpx;
color: $text-secondary;
}
.audit-remark {
font-size: 24rpx;
color: $text-placeholder;
margin-top: 6rpx;
padding: 8rpx 12rpx;
background: #f8f8f8;
border-radius: 8rpx;
}
}
}
.text-red {
color: $danger-color !important;
}
.text-green {
color: $success-color !important;
}
</style>
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!