c554bd67 by lttnew

开票+订单+详情

1 parent 4cf9d409
1 {
2 "permissions": {
3 "allow": [
4 "Bash(ls D:/ltt/ztx_wx_gzt/views/*/index.vue)"
5 ]
6 }
7 }
...@@ -127,6 +127,14 @@ export function deptTreeSelect(params) { ...@@ -127,6 +127,14 @@ export function deptTreeSelect(params) {
127 return res 127 return res
128 }) 128 })
129 } 129 }
130 // 注册选择协会树
131 export function certifiedDeptTreeRegister(params) {
132 return request({
133 url: '/system/user/certifiedDeptTreeWithNoDaoguan2',
134 method: 'get',
135 params
136 })
137 }
130 const setIdToString = (list) => { 138 const setIdToString = (list) => {
131 for (var l of list) { 139 for (var l of list) {
132 l.id += '' 140 l.id += ''
...@@ -1503,3 +1511,176 @@ export function getAssoPers(perId) { ...@@ -1503,3 +1511,176 @@ export function getAssoPers(perId) {
1503 method: 'get' 1511 method: 'get'
1504 }) 1512 })
1505 } 1513 }
1514 export function checkMember(data) {
1515 return request({
1516 url: '/member/info/checkMember',
1517 method: 'post',
1518 data
1519 })
1520 }
1521
1522 export function getBusinessLicense(data) {
1523 return request({
1524 url: `/member/info/getBusinessLicense`,
1525 method: 'post',
1526 data: data
1527 })
1528 }
1529 export function getLogs(examId, type) {
1530 return request({
1531 url: `/exam/info/getLogs/${examId}`,
1532 method: 'get',
1533 params: { type } // 1 级位 2 段位 3 段位成绩 4 越段 5 越段成绩
1534 })
1535 }
1536 export function newGetLogs(id) {
1537 return request({
1538 url: `/person/paymentRangeNew/getLogs/${id}`,
1539 method: 'get',
1540 })
1541 }
1542
1543 export function certifiedNewList(params) {
1544 return request({
1545 url: `/system/certifiedNew/list`,
1546 method: 'get',
1547 params
1548 })
1549 }
1550 export function certifiedNewGetLogs(id) {
1551 return request({
1552 url: `/system/certifiedNew/getLogs/${id}`,
1553 method: 'get',
1554 })
1555 }
1556
1557 // 地址管理
1558 export function getAddressList(params) {
1559 return request({
1560 url: `/member/postAddress/list`,
1561 method: 'get',
1562 params
1563 })
1564 }
1565
1566
1567 export function setDefaultAddress(id) {
1568 return request({
1569 url: `/system/address/setDefault/${id}`,
1570 method: 'put'
1571 })
1572 }
1573
1574 // 级位考试确认
1575 export function confirmExam(examId) {
1576 return request({
1577 url: `/exam/info/confirmExam/${examId}`,
1578 method: 'get'
1579 })
1580 }
1581
1582 // 提交级位考试订单
1583 export function commitJiExam(data) {
1584 return request({
1585 url: `/exam/person/commitJi`,
1586 method: 'post',
1587 data
1588 })
1589 }
1590
1591 // 级位考试支付
1592 export function payJiExam(orderId) {
1593 return request({
1594 url: `/exam/person/pay/${orderId}`,
1595 method: 'post'
1596 })
1597 }
1598
1599 /**
1600 * 新增收货地址
1601 * @param data
1602 * @returns {*}
1603 */
1604 export function addMyAddress(data) {
1605 return request({
1606 url: `/member/postAddress/addMyAddress`,
1607 method: 'post',
1608 params: data
1609 })
1610 }
1611
1612 /**
1613 * 地址列表
1614 * @param params
1615 * @returns {*}
1616 */
1617 export function postAddressListAPI(params) {
1618 return request({
1619 url: `/member/postAddress/list`,
1620 method: 'get',
1621 params
1622 })
1623 }
1624
1625 /**
1626 * 编辑地址
1627 * @data data
1628 * @returns {*}
1629 */
1630 export function editMyAddress(data) {
1631 return request({
1632 url: `/member/postAddress/editMyAddress`,
1633 method: 'post',
1634 params: data
1635 })
1636 }
1637
1638
1639 /**
1640 * 删除地址
1641 * @param id
1642 * @returns {*}
1643 */
1644 export function postAddressDel(id) {
1645 return request({
1646 url: `/member/postAddress/${id}`,
1647 method: 'delete',
1648 })
1649 }
1650
1651 /**
1652 * 默认地址
1653 * @param id
1654 * @returns {*}
1655 */
1656 export function setDefault(id) {
1657 return request({
1658 url: `/member/postAddress/setDefault/${id}`,
1659 method: 'put',
1660 })
1661 }
1662
1663 /**
1664 * 获取默认地址
1665 * @param id
1666 * @returns {*}
1667 */
1668 export function getDefaultAddress() {
1669 return request({
1670 url: `/member/postAddress/getDefaultAddress`,
1671 method: 'get',
1672 })
1673 }
1674
1675
1676 /**
1677 * 订单修改地址
1678 * @param examId,addressId
1679 * @returns {*}
1680 */
1681 export function editAddressOrder(examId, addressId) {
1682 return request({
1683 url: `/exam/info/editAddress/${examId}/${addressId}`,
1684 method: 'put'
1685 })
1686 }
......
1 // dev 1 // dev
2 const baseUrl_api = 'http://192.168.1.137:8787' 2 // const baseUrl_api = 'http://192.168.1.137:8787'
3 const baseUrl_api = 'http://tk001.wxjylt.com/stage-api'
3 const payUrl = 'https://wxpay.cmbc.com.cn/mobilePlatform/appserver/lcbpPay.do' 4 const payUrl = 'https://wxpay.cmbc.com.cn/mobilePlatform/appserver/lcbpPay.do'
4 5
5 // prod 6 // prod
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 28
29 <!-- 成员 --> 29 <!-- 成员 -->
30 <view class="userlist"> 30 <view class="userlist">
31 <view class="item" style="padding: 20rpx 0 0;" v-for="(n,index) in list" :key="n.index" @click="goGroupInfo(n)"> 31 <view class="item" style="padding: 20rpx 0 0;" v-for="(n,index) in list" :key="index" @click="goGroupInfo(n)">
32 <view style="width: 100%"> 32 <view style="width: 100%">
33 <view class="name text-primary underLine">{{n.memberName}}</view> 33 <view class="name text-primary underLine">{{n.memberName}}</view>
34 <view class="date">单位类型: 34 <view class="date">单位类型:
......
1 <template>
2 <view class="order-page">
3 <!-- 顶部Tab -->
4 <view class="tab-bar">
5 <view
6 v-for="(tab, index) in statusTabs"
7 :key="index"
8 class="tab-item"
9 :class="{ active: currentTab === index }"
10 @click="switchTab(index)"
11 >
12 {{ tab.name }}
13 </view>
14 </view>
15
16 <!-- 列表 -->
17 <scroll-view
18 scroll-y
19 class="order-list-scroll"
20 :show-scrollbar="false"
21 @scrolltolower="loadMore"
22 lower-threshold="200"
23 >
24 <view class="order-list">
25 <view v-if="list.length > 0">
26 <view
27 class="order-card"
28 v-for="(item, index) in list"
29 :key="index"
30 >
31 <!-- 卡片头部:日期 + 状态 -->
32 <view class="card-header">
33 <view class="date">
34 <image src="/static/calendar@2x.png" v-if="item.commitTime" mode="widthFix" style="width:30rpx;height:30rpx;"/>
35 <text class="date-text" v-if="item.commitTime">{{ item.commitTime }}</text>
36 </view>
37 <view class="status-tags">
38 <view class="status-tag" :class="getAuditStatusClass(item.auditStatus)">
39 {{ getAuditStatusText(item.auditStatus) }}
40 </view>
41 </view>
42 </view>
43
44 <!-- 基本信息 -->
45 <view class="info-row">
46 <text class="label">缴费编号:</text>
47 <text class="value">{{ item.wfCode || '--' }}</text>
48 </view>
49 <view class="info-row">
50 <text class="label">缴费单位:</text>
51 <text class="value">{{ item.memName || '--' }}</text>
52 </view>
53 <view class="info-row">
54 <text class="label">所属协会:</text>
55 <text class="value">{{ item.shenMemName || '--' }}</text>
56 </view>
57
58 <!-- 费用信息区 -->
59 <view class="info-section">
60 <view class="info-item">
61 <text class="item-label">新会员</text>
62 <text class="item-value">{{ item.isNew == 1 ? '是' : '否' }}</text>
63 </view>
64 <view class="info-line"></view>
65 <view class="info-item">
66 <text class="item-label">认证年限</text>
67 <text class="item-value">{{ item.renewYear ? item.renewYear + '年' : '--' }}</text>
68 </view>
69 <view class="info-line"></view>
70 <view class="info-item">
71 <text class="item-label">费用合计</text>
72 <text class="item-value">¥{{ (Number(item.allPrice) || 0).toFixed(2) }}</text>
73 </view>
74 </view>
75
76 <!-- 费用明细 -->
77 <view class="price-section">
78 <view class="price-row">
79 <text class="price-label">政策优惠</text>
80 <text class="price-value">{{ item.discount || '--' }}</text>
81 </view>
82 <view class="price-row">
83 <text class="price-label">付款费用</text>
84 <text class="price-value">¥{{ (Number(item.finalPrice) || 0).toFixed(2) }}</text>
85 </view>
86 <view class="price-row">
87 <text class="price-label">审核日期</text>
88 <text class="price-value">{{ item.auditTime || '--' }}</text>
89 </view>
90 </view>
91
92 <!-- 协会信息 -->
93 <view class="info-row">
94 <text class="label">协会信息:</text>
95 <text class="value" :class="item.checkPass == 0 ? 'text-danger' : 'text-success'">
96 {{ item.checkPass == 0 ? '异常' : '正常' }}
97 </text>
98 </view>
99 </view>
100 </view>
101
102 <!-- 空状态 -->
103 <view v-else class="empty">
104 <text class="empty-text">暂无审核记录</text>
105 </view>
106
107 <!-- 加载/无更多提示 -->
108 <view class="loading-tip" v-if="loading">加载中...</view>
109 <view class="no-more" v-if="!loading && !hasMore && list.length > 0">没有更多了</view>
110 </view>
111 </scroll-view>
112 </view>
113 </template>
114
115 <script setup>
116 import { ref, onMounted } from 'vue';
117 import { onLoad } from '@dcloudio/uni-app';
118 import * as api from '@/common/api.js';
119
120 // 状态Tab配置
121 const statusTabs = [
122 { name: '全部', type: '' },
123 { name: '审核中', type: '1' },
124 { name: '审核通过', type: '2' },
125 { name: '审核拒绝', type: '3' }
126 ];
127
128 const currentTab = ref(0);
129 const list = ref([]);
130 const loading = ref(false);
131 const hasMore = ref(true);
132 const pageNum = ref(1);
133 const pageSize = ref(10);
134
135 onMounted(() => {
136 initData();
137 });
138
139 // 切换Tab
140 const switchTab = (index) => {
141 currentTab.value = index;
142 pageNum.value = 1;
143 list.value = [];
144 hasMore.value = true;
145 initData();
146 };
147
148 // 上拉加载更多
149 const loadMore = () => {
150 console.log("触发上拉加载");
151 if (loading.value || !hasMore.value) return;
152 pageNum.value++;
153 initData();
154 };
155
156 // 获取列表数据
157 const initData = async () => {
158 loading.value = true;
159 try {
160 const params = {
161 pageNum: pageNum.value,
162 pageSize: pageSize.value,
163 auditStatus: statusTabs[currentTab.value].type
164 };
165 const res = await api.certifiedNewList(params);
166 console.log("接口返回:", res);
167
168 if (!res || !res.rows || res.rows.length === 0) {
169 hasMore.value = false;
170 loading.value = false;
171 return;
172 }
173 // 第一页覆盖,后面页数追加
174 if (pageNum.value === 1) {
175 list.value = res.rows;
176 } else {
177 list.value.push(...res.rows);
178 }
179 // 关键修复:只要返回条数 < pageSize 就说明没有更多了
180 hasMore.value = res.rows.length === pageSize.value;
181 } catch (e) {
182 console.error('审核记录加载异常:', e);
183 uni.showToast({ title: '加载失败', icon: 'none' });
184 hasMore.value = false;
185 } finally {
186 loading.value = false;
187 }
188 };
189
190 // 审核状态文本
191 const getAuditStatusText = (status) => {
192 const map = { 1: '审核中', 2: '审核通过', 3: '审核拒绝' };
193 return map[status] || '未知';
194 };
195
196 const getAuditStatusClass = (status) => {
197 const map = { 1: 'pending', 2: 'success', 3: 'danger' };
198 return map[status] || '';
199 };
200 </script>
201
202 <style lang="scss" scoped>
203 .order-page {
204 height: 100vh;
205 background: #f5f7fa;
206 display: flex;
207 flex-direction: column;
208 }
209
210 // Tab
211 .tab-bar {
212 display: flex;
213 background: #fff;
214 border-bottom: 1rpx solid #eee;
215 flex-shrink: 0;
216
217 .tab-item {
218 flex: 1;
219 text-align: center;
220 padding: 24rpx 0;
221 font-size: 28rpx;
222 color: #666;
223 position: relative;
224
225 &.active {
226 color: #e4393c;
227 font-weight: 500;
228
229 &::after {
230 content: '';
231 position: absolute;
232 bottom: 0;
233 left: 50%;
234 transform: translateX(-50%);
235 width: 60rpx;
236 height: 4rpx;
237 background: linear-gradient(90deg, #FF755A, #F51722);
238 border-radius: 2rpx;
239 }
240 }
241 }
242 }
243
244 // 滚动列表容器
245 .order-list-scroll {
246 flex: 1;
247 height: auto;
248 overflow: auto;
249 }
250
251 .order-list {
252 padding: 20rpx;
253 }
254
255 .order-card {
256 background: #fff;
257 margin-bottom: 20rpx;
258 padding: 24rpx;
259 border-radius: 12rpx;
260 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
261 border-top: 6rpx solid transparent;
262 background-clip: padding-box, border-box;
263 background-origin: padding-box, border-box;
264 background-image: linear-gradient(#fff, #fff), linear-gradient(90deg, #FF755A, #F51722);
265 }
266
267 .card-header {
268 display: flex;
269 justify-content: space-between;
270 align-items: center;
271 padding-bottom: 20rpx;
272 margin-bottom: 20rpx;
273 border-bottom: 1rpx dashed #eee;
274
275 .date {
276 display: flex;
277 align-items: center;
278 gap: 8rpx;
279
280 .date-text {
281 font-size: 26rpx;
282 color: #666;
283 }
284 }
285
286 .status-tags {
287 display: flex;
288 gap: 10rpx;
289 }
290
291 .status-tag {
292 font-size: 22rpx;
293 padding: 6rpx 16rpx;
294 border-radius: 20rpx;
295
296 &.success {
297 background: #e6f7ef;
298 color: #52c41a;
299 }
300
301 &.danger {
302 background: #fff1f0;
303 color: #ff4d4f;
304 }
305
306 &.pending {
307 background: #f5f5f5;
308 color: #999;
309 }
310
311 &.warning {
312 background: #fff7e6;
313 color: #faad14;
314 }
315 }
316 }
317
318 .info-row {
319 display: flex;
320 align-items: center;
321 margin-bottom: 16rpx;
322 font-size: 26rpx;
323
324 .label {
325 color: #999;
326 flex-shrink: 0;
327 min-width: 140rpx;
328 }
329
330 .value {
331 color: #333;
332 word-break: break-all;
333
334 &.text-success {
335 color: #52c41a;
336 }
337
338 &.text-danger {
339 color: #ff4d4f;
340 }
341 }
342 }
343
344 .info-section {
345 display: flex;
346 align-items: center;
347 background: #f3f6fc;
348 padding: 16rpx 20rpx;
349 margin: 16rpx 0;
350 border-radius: 8rpx;
351
352 .info-item {
353 flex: 1;
354 display: flex;
355 flex-direction: column;
356 align-items: center;
357
358 .item-label {
359 font-size: 24rpx;
360 color: #999;
361 }
362
363 .item-value {
364 font-size: 28rpx;
365 color: #333;
366 font-weight: 500;
367 margin-top: 8rpx;
368 }
369 }
370
371 .info-line {
372 width: 1rpx;
373 height: 60rpx;
374 background: #ddd;
375 }
376 }
377
378 .price-section {
379 border-top: 1rpx dashed #eee;
380 padding-top: 16rpx;
381 margin-top: 8rpx;
382
383 .price-row {
384 display: flex;
385 justify-content: space-between;
386 align-items: center;
387 padding: 8rpx 0;
388
389 .price-label {
390 font-size: 26rpx;
391 color: #333;
392 }
393
394 .price-value {
395 font-size: 26rpx;
396 color: #666;
397 }
398 }
399 }
400
401 .empty {
402 display: flex;
403 justify-content: center;
404 align-items: center;
405 padding: 120rpx 0;
406
407 .empty-text {
408 color: #999;
409 font-size: 28rpx;
410 }
411 }
412
413 .loading-tip,
414 .no-more {
415 text-align: center;
416 padding: 20rpx 0;
417 color: #999;
418 font-size: 26rpx;
419 }
420 </style>
...@@ -605,15 +605,23 @@ ...@@ -605,15 +605,23 @@
605 605
606 uni.showModal({ 606 uni.showModal({
607 title: '提示', 607 title: '提示',
608 content: `确定提交审核?`, 608 content: `请确认人员照片是否已更新?`,
609 success: function(res) { 609 success: function(res) {
610 if (res.confirm) { 610 if (res.confirm) {
611 console.log('用户点击确定'); 611 console.log('用户点击确定');
612 saveStep2(flag).then(Response => { 612 saveStep2(flag).then(Response => {
613 if (flag === 1) {
614 uni.showToast({
615 title: `提交成功`
616 })
617 uni.navigateTo({
618 url: `/level/paymentDetail?examId=${form.value.examId}`
619 })
620 } else {
613 uni.showToast({ 621 uni.showToast({
614 title: `操作成功` 622 title: `操作成功`
615 }) 623 })
616 uni.navigateBack() 624 }
617 }) 625 })
618 } else if (res.cancel) { 626 } else if (res.cancel) {
619 console.log('用户点击取消'); 627 console.log('用户点击取消');
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 <view class="invertedbtn-red" v-if="isExam=='0'" @click="goAdd">+ 添加级位考试</view> 7 <view class="invertedbtn-red" v-if="isExam=='0'" @click="goAdd">+ 添加级位考试</view>
8 </view> 8 </view>
9 <view class="appList"> 9 <view class="appList">
10 <view class="appItem" v-for="(item,index) in list" :key="item"> 10 <view class="appItem" v-for="(item,index) in list" :key="item.examId || index">
11 <view class="status" @click="goDetail(item)"> 11 <view class="status" @click="goDetail(item)">
12 <text v-if="item.status=='0'" class="text-primary">{{ item.statusStr }}</text> 12 <text v-if="item.status=='0'" class="text-primary">{{ item.statusStr }}</text>
13 <text v-if="item.status=='1'" class="text-primary">{{ item.statusStr }}</text> 13 <text v-if="item.status=='1'" class="text-primary">{{ item.statusStr }}</text>
...@@ -125,13 +125,13 @@ ...@@ -125,13 +125,13 @@
125 function handleSubmit(item) { 125 function handleSubmit(item) {
126 uni.showModal({ 126 uni.showModal({
127 title: '提示', 127 title: '提示',
128 content: `确定提交${item.name}进行审核吗`, 128 content: `请确认人员照片是否已更新`,
129 success: function(res) { 129 success: function(res) {
130 if (res.confirm) { 130 if (res.confirm) {
131 uni.showLoading({ 131 // 跳转到付款详情页面
132 title: `提交中` 132 uni.navigateTo({
133 }) 133 url: `/level/paymentDetail?examId=${item.examId}`
134 upApply(item.examId) 134 });
135 } 135 }
136 } 136 }
137 }) 137 })
......
...@@ -171,7 +171,7 @@ ...@@ -171,7 +171,7 @@
171 } 171 }
172 172
173 function getRecordList() { 173 function getRecordList() {
174 api.getApprovalRecord(examId).then(res => { 174 api.getLogs(examId).then(res => {
175 recordList.value = res.data.levelSteps 175 recordList.value = res.data.levelSteps
176 uni.hideLoading() 176 uni.hideLoading()
177 }) 177 })
......
1 <template>
2 <view class="order-page">
3 <!-- 顶部Tab -->
4 <view class="tab-bar">
5 <view
6 v-for="(tab, index) in statusTabs"
7 :key="index"
8 class="tab-item"
9 :class="{ active: currentTab === index }"
10 @click="switchTab(index)"
11 >
12 {{ tab.name }}
13 </view>
14 </view>
15
16 <!-- 列表 -->
17 <scroll-view
18 scroll-y
19 class="order-list-scroll"
20 :show-scrollbar="false"
21 @scrolltolower="loadMore"
22 lower-threshold="200"
23 >
24 <view class="order-list">
25 <view v-if="list.length > 0">
26 <view
27 class="order-card"
28 v-for="(item, index) in list"
29 :key="index"
30 >
31 <!-- 卡片头部:日期 + 状态 -->
32 <view class="card-header">
33 <view class="date">
34 <image src="/static/calendar@2x.png" v-if="item.commitTime" mode="widthFix" style="width:30rpx;height:30rpx;"/>
35 <text class="date-text" v-if="item.commitTime">{{ item.commitTime }}</text>
36 </view>
37 <view class="status-tags">
38 <view class="status-tag" :class="getStatusClass(item.status)">
39 {{ item.statusStr || '待提交' }}
40 </view>
41 </view>
42 </view>
43
44 <!-- 基本信息 -->
45 <view class="info-row">
46 <text class="label">缴费编号:</text>
47 <text class="value">{{ item.examCode || '--' }}</text>
48 </view>
49 <view class="info-row">
50 <text class="label">缴费名称:</text>
51 <text class="value">{{ item.name || '--' }}</text>
52 </view>
53 <view class="info-row">
54 <text class="label">上报单位:</text>
55 <text class="value">{{ item.memberName || '--' }}</text>
56 </view>
57
58 <!-- 费用信息区 -->
59 <view class="info-section">
60 <view class="info-item">
61 <text class="item-label">考试人数</text>
62 <text class="item-value">{{ item.totalNum || 0 }}</text>
63 </view>
64 <view class="info-line"></view>
65 <view class="info-item">
66 <text class="item-label">总金额</text>
67 <text class="item-value">¥{{ (Number(item.price) || 0).toFixed(2) }}</text>
68 </view>
69 <view class="info-line"></view>
70 <view class="info-item">
71 <text class="item-label">支付方式</text>
72 <text class="item-value">民生付</text>
73 </view>
74 </view>
75
76 <!-- 审核信息 -->
77 <view class="price-section">
78 <view class="price-row">
79 <text class="price-label">提交日期</text>
80 <text class="price-value">{{ item.commitTime || '--' }}</text>
81 </view>
82 <view class="price-row">
83 <text class="price-label">审核日期</text>
84 <text class="price-value">{{ item.handleDate || '--' }}</text>
85 </view>
86 </view>
87 </view>
88 </view>
89
90 <!-- 空状态 -->
91 <view v-else class="empty">
92 <text class="empty-text">暂无审核记录</text>
93 </view>
94
95 <!-- 加载/无更多提示 -->
96 <view class="loading-tip" v-if="loading">加载中...</view>
97 <view class="no-more" v-if="!loading && !hasMore && list.length > 0">没有更多了</view>
98 </view>
99 </scroll-view>
100 </view>
101 </template>
102
103 <script setup>
104 import { ref, onMounted } from 'vue';
105 import * as api from '@/common/api.js';
106
107 // 状态Tab配置
108 const statusTabs = [
109 { name: '全部', type: '' },
110 { name: '审批中', type: '1' },
111 { name: '审批通过', type: '2' },
112 { name: '审批拒绝', type: '3' }
113 ];
114
115 const currentTab = ref(0);
116 const list = ref([]);
117 const loading = ref(false);
118 const hasMore = ref(true);
119 const pageNum = ref(1);
120 const pageSize = ref(10);
121
122 onMounted(() => {
123 initData();
124 });
125
126 // 切换Tab
127 const switchTab = (index) => {
128 currentTab.value = index;
129 pageNum.value = 1;
130 list.value = [];
131 hasMore.value = true;
132 initData();
133 };
134
135 // 上拉加载更多
136 const loadMore = () => {
137 console.log("触发上拉加载");
138 if (loading.value || !hasMore.value) return;
139 pageNum.value++;
140 initData();
141 };
142
143 // 获取列表数据
144 const initData = async () => {
145 loading.value = true;
146 try {
147 const params = {
148 pageNum: pageNum.value,
149 pageSize: pageSize.value,
150 status: statusTabs[currentTab.value].type,
151 auditSelectType: '1'
152 };
153 const res = await api.getLevelList(params);
154 console.log("接口返回:", res);
155
156 if (!res || !res.rows || res.rows.length === 0) {
157 hasMore.value = false;
158 loading.value = false;
159 return;
160 }
161
162 // 第一页覆盖,后面页数追加
163 if (pageNum.value === 1) {
164 list.value = res.rows;
165 } else {
166 list.value.push(...res.rows);
167 }
168
169 // 关键修复:只要返回条数 < pageSize 就说明没有更多了
170 hasMore.value = res.rows.length === pageSize.value;
171 } catch (e) {
172 console.error('加载失败:', e);
173 uni.showToast({ title: '加载失败', icon: 'none' });
174 hasMore.value = false;
175 } finally {
176 loading.value = false;
177 }
178 };
179
180 // 状态样式
181 const getStatusClass = (status) => {
182 const map = { '1': 'pending', '2': 'success', '3': 'danger', '4': 'warning' };
183 return map[status] || '';
184 };
185 </script>
186
187 <style lang="scss" scoped>
188 .order-page {
189 height: 100vh;
190 background: #f5f7fa;
191 display: flex;
192 flex-direction: column;
193 }
194
195 // Tab
196 .tab-bar {
197 display: flex;
198 background: #fff;
199 border-bottom: 1rpx solid #eee;
200 flex-shrink: 0;
201
202 .tab-item {
203 flex: 1;
204 text-align: center;
205 padding: 24rpx 0;
206 font-size: 28rpx;
207 color: #666;
208 position: relative;
209
210 &.active {
211 color: #e4393c;
212 font-weight: 500;
213
214 &::after {
215 content: '';
216 position: absolute;
217 bottom: 0;
218 left: 50%;
219 transform: translateX(-50%);
220 width: 60rpx;
221 height: 4rpx;
222 background: linear-gradient(90deg, #FF755A, #F51722);
223 border-radius: 2rpx;
224 }
225 }
226 }
227 }
228
229 // 滚动列表容器 —— 这里是关键修复
230 .order-list-scroll {
231 flex: 1;
232 height: auto;
233 overflow: auto;
234 }
235
236 .order-list {
237 padding: 20rpx;
238 }
239
240 .order-card {
241 background: #fff;
242 margin-bottom: 20rpx;
243 padding: 24rpx;
244 border-radius: 12rpx;
245 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
246 border-top: 6rpx solid transparent;
247 background-clip: padding-box, border-box;
248 background-origin: padding-box, border-box;
249 background-image: linear-gradient(#fff, #fff), linear-gradient(90deg, #FF755A, #F51722);
250 }
251
252 .card-header {
253 display: flex;
254 justify-content: space-between;
255 align-items: center;
256 padding-bottom: 20rpx;
257 margin-bottom: 20rpx;
258 border-bottom: 1rpx dashed #eee;
259
260 .date {
261 display: flex;
262 align-items: center;
263 gap: 8rpx;
264
265 .date-text {
266 font-size: 26rpx;
267 color: #666;
268 }
269 }
270
271 .status-tags {
272 display: flex;
273 gap: 10rpx;
274 }
275
276 .status-tag {
277 font-size: 22rpx;
278 padding: 6rpx 16rpx;
279 border-radius: 20rpx;
280
281 &.success {
282 background: #e6f7ef;
283 color: #52c41a;
284 }
285
286 &.danger {
287 background: #fff1f0;
288 color: #ff4d4f;
289 }
290
291 &.pending {
292 background: #f5f5f5;
293 color: #999;
294 }
295
296 &.warning {
297 background: #fff7e6;
298 color: #faad14;
299 }
300 }
301 }
302
303 .info-row {
304 display: flex;
305 align-items: center;
306 margin-bottom: 16rpx;
307 font-size: 26rpx;
308
309 .label {
310 color: #999;
311 flex-shrink: 0;
312 min-width: 140rpx;
313 }
314
315 .value {
316 color: #333;
317 word-break: break-all;
318 }
319 }
320
321 .info-section {
322 display: flex;
323 align-items: center;
324 background: #f3f6fc;
325 padding: 16rpx 20rpx;
326 margin: 16rpx 0;
327 border-radius: 8rpx;
328
329 .info-item {
330 flex: 1;
331 display: flex;
332 flex-direction: column;
333 align-items: center;
334
335 .item-label {
336 font-size: 24rpx;
337 color: #999;
338 }
339
340 .item-value {
341 font-size: 28rpx;
342 color: #333;
343 font-weight: 500;
344 margin-top: 8rpx;
345 }
346 }
347
348 .info-line {
349 width: 1rpx;
350 height: 60rpx;
351 background: #ddd;
352 }
353 }
354
355 .price-section {
356 border-top: 1rpx dashed #eee;
357 padding-top: 16rpx;
358 margin-top: 8rpx;
359
360 .price-row {
361 display: flex;
362 justify-content: space-between;
363 align-items: center;
364 padding: 8rpx 0;
365
366 .price-label {
367 font-size: 26rpx;
368 color: #333;
369 }
370
371 .price-value {
372 font-size: 26rpx;
373 color: #666;
374 }
375 }
376 }
377
378 .empty {
379 display: flex;
380 justify-content: center;
381 align-items: center;
382 padding: 120rpx 0;
383
384 .empty-text {
385 color: #999;
386 font-size: 28rpx;
387 }
388 }
389
390 .loading-tip,
391 .no-more {
392 text-align: center;
393 padding: 20rpx 0;
394 color: #999;
395 font-size: 26rpx;
396 }
397 </style>
...\ No newline at end of file ...\ No newline at end of file
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
62 <button @click="login" class="btn-red">登录</button> 62 <button @click="login" class="btn-red">登录</button>
63 </view> 63 </view>
64 <view class="center-item"> 64 <view class="center-item">
65 <!-- <text class="text-red" @click="goRegister">没有账号,去注册</text> --> 65 <text class="text-red" @click="goRegister">没有账号,去注册</text>
66 </view> 66 </view>
67 </view> 67 </view>
68 <view class="wNumber"> 68 <view class="wNumber">
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
8 <view class="loginbox"> 8 <view class="loginbox">
9 9
10 <view class="formbox"> 10 <view class="formbox">
11 <view class="nav active">团体会员注册</view> 11 <view class="nav active">单位会员注册</view>
12 <form> 12 <form>
13 <view class="round-input-item"> 13 <view class="round-input-item">
14 <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag01@2x.png'"></image> 14 <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag01@2x.png'"></image>
...@@ -139,7 +139,7 @@ function register() { ...@@ -139,7 +139,7 @@ function register() {
139 } 139 }
140 140
141 function goLogin() { 141 function goLogin() {
142 let path = '/login/login'; 142 let path = '/login/loginC';
143 uni.navigateTo({ 143 uni.navigateTo({
144 url: path 144 url: path
145 }); 145 });
......
1 <template>
2 <view class="audit-page">
3
4 <!-- 审核记录表格 -->
5 <view class="table-container">
6 <view class="table-header">
7 <view class="th th-index">序号</view>
8 <view class="th th-dept">审核协会</view>
9 <view class="th th-date">审核日期</view>
10 <view class="th th-status">审核状态</view>
11 <view class="th th-reason">理由</view>
12 </view>
13
14 <view class="table-body" v-if="loading">
15 <view class="loading-row">加载中...</view>
16 </view>
17
18 <view class="table-body" v-if="recordList.length > 0">
19 <view class="table-row" v-for="(item, index) in recordList" :key="index">
20 <view class="td td-index">{{ index + 1 }}</view>
21 <view class="td td-dept">{{ item.auditDeptName || '/' }}</view>
22 <view class="td td-date">{{ formatDate(item.auditTime) }}</view>
23 <view class="td td-status">
24 <text v-if="item.auditResult == 1" class="status-success">审核通过</text>
25 <text v-else-if="item.auditResult == 0" class="status-reject">审核拒绝</text>
26 <text v-else class="status-pending">待审核</text>
27 </view>
28 <view class="td td-reason">{{ item.auditMsg || '/' }}</view>
29 </view>
30 </view>
31
32 <view class="table-body" v-else>
33 <view class="empty-row">暂无审核记录</view>
34 </view>
35 </view>
36 </view>
37 </template>
38
39 <script setup>
40 import * as api from '@/common/api.js'
41 import {
42 ref,
43 onMounted
44 } from 'vue'
45 import {
46 onLoad
47 } from '@dcloudio/uni-app'
48
49 const loading = ref(true)
50 const recordList = ref([])
51
52 onLoad(async (option) => {
53 await getMyRecentFN()
54 })
55
56 onMounted(() => {
57 getMyRecentFN()
58 })
59
60 async function getMyRecentFN() {
61 loading.value = true
62 try {
63 const res = await api.getMyRecent()
64 loading.value = false
65 if (res.code === 200 && res.data && res.data.auditLogs) {
66 recordList.value = JSON.parse(res.data.auditLogs)
67 } else {
68 // 清空记录列表,显示暂无记录
69 recordList.value = []
70 }
71 } catch (e) {
72 loading.value = false
73 // 清空记录列表,显示暂无记录
74 recordList.value = []
75 console.error('获取审核记录失败', e)
76 }
77 }
78
79 function formatDate(dateStr) {
80 if (!dateStr) return '/'
81 const date = new Date(dateStr)
82 const year = date.getFullYear()
83 const month = String(date.getMonth() + 1).padStart(2, '0')
84 const day = String(date.getDate()).padStart(2, '0')
85 return `${year}-${month}-${day}`
86 }
87 </script>
88
89 <style scoped lang="scss">
90 .audit-page {
91 min-height: 100vh;
92 background: #f5f5f5;
93 padding-bottom: 40rpx;
94 }
95
96 .page-header {
97 background: linear-gradient(135deg, #1561cb 0%, #1e7de1 100%);
98 padding: 30rpx;
99 text-align: center;
100
101 .header-title {
102 font-size: 32rpx;
103 font-weight: 600;
104 color: #fff;
105 }
106 }
107
108 .table-container {
109 margin: 30rpx;
110 background: #fff;
111 border-radius: 12rpx;
112 overflow: hidden;
113 box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
114 }
115
116 .table-header {
117 display: flex;
118 background: #f5f7fa;
119 padding: 20rpx 0;
120 border-bottom: 1rpx solid #eee;
121
122 .th {
123 font-size: 24rpx;
124 color: #666;
125 font-weight: 600;
126 text-align: center;
127 }
128
129 .th-index {
130 width: 80rpx;
131 }
132
133 .th-dept {
134 flex: 1;
135 min-width: 150rpx;
136 }
137
138 .th-date {
139 width: 160rpx;
140 }
141
142 .th-status {
143 width: 140rpx;
144 }
145
146 .th-reason {
147 flex: 1;
148 min-width: 120rpx;
149 }
150 }
151
152 .table-body {
153 .table-row {
154 display: flex;
155 padding: 24rpx 0;
156 border-bottom: 1rpx solid #f0f0f0;
157
158 &:last-child {
159 border-bottom: none;
160 }
161 }
162
163 .td {
164 font-size: 24rpx;
165 color: #333;
166 text-align: center;
167 display: flex;
168 align-items: center;
169 justify-content: center;
170 }
171
172 .td-index {
173 width: 80rpx;
174 color: #999;
175 }
176
177 .td-dept {
178 flex: 1;
179 min-width: 150rpx;
180 padding: 0 10rpx;
181 word-break: break-all;
182 }
183
184 .td-date {
185 width: 160rpx;
186 color: #666;
187 font-size: 22rpx;
188 }
189
190 .td-status {
191 width: 140rpx;
192
193 .status-success {
194 color: #07c07e;
195 }
196
197 .status-reject {
198 color: #e64329;
199 }
200
201 .status-pending {
202 color: #ff9800;
203 }
204 }
205
206 .td-reason {
207 flex: 1;
208 min-width: 120rpx;
209 padding: 0 10rpx;
210 font-size: 22rpx;
211 color: #666;
212 word-break: break-all;
213 }
214 }
215
216 .loading-row,
217 .empty-row {
218 padding: 60rpx 0;
219 text-align: center;
220 font-size: 26rpx;
221 color: #999;
222 }
223 </style>
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
22 22
23 <uni-list-item thumb="/static/user_icon03.png" title="账号安全" showArrow clickable @click="goPath('/myCenter/safe')"> 23 <uni-list-item thumb="/static/user_icon03.png" title="账号安全" showArrow clickable @click="goPath('/myCenter/safe')">
24 </uni-list-item> 24 </uni-list-item>
25 <uni-list-item thumb="/static/user_icon03.png" title="我的订单" showArrow clickable @click="goPath('/myCenter/order')"> 25 <uni-list-item thumb="/static/user_icon03.png" v-if="userType==2 || userType==6" title="我的订单" showArrow clickable @click="goPath('/myCenter/order')">
26 </uni-list-item> 26 </uni-list-item>
27 27
28 </uni-list> 28 </uni-list>
...@@ -57,7 +57,7 @@ const { ...@@ -57,7 +57,7 @@ const {
57 const app = getApp(); 57 const app = getApp();
58 const userType = ref('1') 58 const userType = ref('1')
59 const memberInfo = ref({}) 59 const memberInfo = ref({})
60 60 const deptInfo = ref({})
61 let proId; 61 let proId;
62 const svId = ref(null); 62 const svId = ref(null);
63 const numData = ref({}); 63 const numData = ref({});
...@@ -125,6 +125,7 @@ function init() { ...@@ -125,6 +125,7 @@ function init() {
125 loginServer.getMyOwnMemberInfo().then(res => { 125 loginServer.getMyOwnMemberInfo().then(res => {
126 userType.value = app.globalData.userType 126 userType.value = app.globalData.userType
127 memberInfo.value = app.globalData.memberInfo 127 memberInfo.value = app.globalData.memberInfo
128 deptInfo.value = app.globalData.dept || {}
128 uni.hideLoading(); 129 uni.hideLoading();
129 }) 130 })
130 } 131 }
......
...@@ -17,9 +17,10 @@ ...@@ -17,9 +17,10 @@
17 <scroll-view 17 <scroll-view
18 scroll-y 18 scroll-y
19 class="order-list-scroll" 19 class="order-list-scroll"
20 :enhanced="true"
21 :show-scrollbar="false" 20 :show-scrollbar="false"
22 :scroll-enabled="!isPopupOpen" 21 :scroll-enabled="!isPopupOpen"
22 @scrolltolower="loadMore"
23 lower-threshold="200"
23 > 24 >
24 <view class="order-list"> 25 <view class="order-list">
25 <!-- 有数据才循环 --> 26 <!-- 有数据才循环 -->
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
35 <image src="/static/calendar@2x.png" v-if="item.payTime" mode="widthFix" style="width:30rpx;height:30rpx;"/> 36 <image src="/static/calendar@2x.png" v-if="item.payTime" mode="widthFix" style="width:30rpx;height:30rpx;"/>
36 <text class="date-text" v-if="item.payTime">{{ item.payTime }}</text> 37 <text class="date-text" v-if="item.payTime">{{ item.payTime }}</text>
37 </view> 38 </view>
39 <view class="status-tags">
38 <view 40 <view
39 class="status-tag" 41 class="status-tag"
40 :class="{ 42 :class="{
...@@ -45,6 +47,17 @@ ...@@ -45,6 +47,17 @@
45 > 47 >
46 {{ getStatusText(item.payStatus) }} 48 {{ getStatusText(item.payStatus) }}
47 </view> 49 </view>
50 <view
51 class="status-tag ml-10"
52 :class="{
53 'status-pending': item.auditStatus == 0 || item.auditStatus == 1,
54 'status-success': item.auditStatus == 2,
55 'status-danger': item.auditStatus == 3
56 }"
57 >
58 {{ getAuditStatusText(item.auditStatus) }}
59 </view>
60 </view>
48 </view> 61 </view>
49 62
50 <!-- 订单编号、缴费编号 --> 63 <!-- 订单编号、缴费编号 -->
...@@ -64,38 +77,46 @@ ...@@ -64,38 +77,46 @@
64 <view class="label">缴费年限:</view> 77 <view class="label">缴费年限:</view>
65 <view class="value">{{ item.content.yearCount || 0 }}</view> 78 <view class="value">{{ item.content.yearCount || 0 }}</view>
66 </view> 79 </view>
67 <view class="line"></view> 80 <view class="line" v-if="currentTab === 0 || currentTab === 1"></view>
68 <!-- 级位/段位考试(仅人数合计) --> 81 <!-- 级位/段位考试(仅人数合计) -->
69 <view v-if="currentTab === 2 || currentTab === 3" class="single-info"> 82 <view v-if="currentTab === 2 || currentTab === 3" class="single-info">
70 <view class="label">人数合计</view> 83 <view class="label">人数合计</view>
71 <view class="value">{{ item.content.allPersonCount || 0 }}</view> 84 <view class="value">{{ item.content.allPersonCount || 0 }}</view>
72 </view> 85 </view>
86 <view class="line" v-if="currentTab === 2 || currentTab === 3"></view>
73 <view class="single-info"> 87 <view class="single-info">
74 <view class="label">缴费方式</view> 88 <view class="label">订单状态</view>
75 <view class="value">民生付</view> 89 <view class="value" :class="item.effect == 1 ? 'text-success' : 'text-warning'">
90 {{ item.effect == 1 ? '已生效' : '未生效' }}
91 </view>
76 </view> 92 </view>
77 </view> 93 </view>
78 94
79 <!-- 费用合计 --> 95 <!-- 费用合计 + 缴费方式 -->
80 <view class="total-row"> 96 <view class="price-section">
81 <text class="label">费用合计:</text> 97 <view class="price-row">
82 <text class="amount">¥{{ (Number(item.price) || 0).toFixed(2) }}</text> 98 <text class="price-label">费用合计</text>
99 <text class="price-value">¥{{ (Number(item.price) || 0).toFixed(2) }}</text>
100 </view>
101 <view class="price-row">
102 <text class="price-label">缴费方式</text>
103 <text class="price-value">民生付</text>
104 </view>
83 </view> 105 </view>
84 106
85 <!-- 按钮组:靠右紧凑展示 --> 107 <!-- 按钮组:靠右紧凑展示 -->
86 <view class="btn-group"> 108 <view class="btn-group">
87 <button class="btn btn-delete" @click="handleDelete(item)">删除</button> 109 <!-- 已缴费:申请开票/已开票(需要审核通过才能开票) -->
88 <!-- 已缴费:申请开票/已开票 --> 110 <template v-if="item.payStatus == 1 && item.invoiceStatus != 1&& item.auditStatus == 2">
89 <template v-if="item.payStatus == 1">
90 <button class="btn btn-invoice" @click="makeInvoiceFN(item)" :disabled="item.invoiceStatus === 1"> 111 <button class="btn btn-invoice" @click="makeInvoiceFN(item)" :disabled="item.invoiceStatus === 1">
91 {{ item.invoiceStatus === 1 ? '已开票' : '申请开票' }} 112 开票
92 </button> 113 </button>
93 </template> 114 </template>
94 <!-- 未缴费:去缴费 + 取消订单 --> 115 <!-- 未缴费:去缴费 + 取消订单 -->
95 <template v-if="item.payStatus == 0"> 116 <!-- <template v-if="item.payStatus == 0">
96 <button class="btn btn-cancel" @click="handleCancel(item)">取消订单</button> 117 <button class="btn btn-cancel" @click="handleCancel(item)">取消订单</button>
97 <button class="btn btn-pay" @click="handlePay(item)">去缴费</button> 118 <button class="btn btn-pay" @click="handlePay(item)">去缴费</button>
98 </template> 119 </template> -->
99 </view> 120 </view>
100 </view> 121 </view>
101 </view> 122 </view>
...@@ -139,7 +160,10 @@ ...@@ -139,7 +160,10 @@
139 160
140 <script setup> 161 <script setup>
141 import { ref, reactive, onMounted, computed } from 'vue'; 162 import { ref, reactive, onMounted, computed } from 'vue';
142 import { onReachBottom, } from '@dcloudio/uni-app' 163 import {
164 onShow,
165 onLoad
166 } from '@dcloudio/uni-app'
143 import * as api from '@/common/api.js' 167 import * as api from '@/common/api.js'
144 168
145 // 获取deptType值(初始值为0,在onMounted中设置实际值) 169 // 获取deptType值(初始值为0,在onMounted中设置实际值)
...@@ -161,7 +185,7 @@ const tabs = computed(() => { ...@@ -161,7 +185,7 @@ const tabs = computed(() => {
161 } else if (dt === 2) { 185 } else if (dt === 2) {
162 console.log('返回3个tab: 单位会员、段位考试、越段考试'); 186 console.log('返回3个tab: 单位会员、段位考试、越段考试');
163 return [ 187 return [
164 { name: '单位会员', type: '1' }, 188 // { name: '单位会员', type: '1' },
165 { name: '段位考试', type: '3' }, 189 { name: '段位考试', type: '3' },
166 { name: '越段考试', type: '4' } 190 { name: '越段考试', type: '4' }
167 ]; 191 ];
...@@ -217,14 +241,29 @@ onMounted(() => { ...@@ -217,14 +241,29 @@ onMounted(() => {
217 initData(); 241 initData();
218 }); 242 });
219 243
220 // 小程序原生触底加载 244 // 页面显示时刷新数据(从开票页面返回时)
221 onReachBottom(() => { 245 onShow(() => {
222 if (!loading.value && hasMore.value && !isPopupOpen.value) { 246 // 如果有缓存的刷新标记,则刷新列表
223 pageNum.value++; 247 if (needRefresh.value) {
248 needRefresh.value = false;
249 pageNum.value = 1;
250 list.value = [];
251 hasMore.value = true;
224 initData(); 252 initData();
225 } 253 }
226 }); 254 });
227 255
256 // 是否需要刷新
257 const needRefresh = ref(false);
258
259 // 上拉加载更多
260 const loadMore = () => {
261 console.log("触发上拉加载");
262 if (loading.value || !hasMore.value || isPopupOpen.value) return;
263 pageNum.value++;
264 initData();
265 };
266
228 // 切换标签 267 // 切换标签
229 const switchTab = (index) => { 268 const switchTab = (index) => {
230 currentTab.value = index; 269 currentTab.value = index;
...@@ -245,6 +284,17 @@ const getStatusText = (status) => { ...@@ -245,6 +284,17 @@ const getStatusText = (status) => {
245 return map[status] || '未知状态'; 284 return map[status] || '未知状态';
246 }; 285 };
247 286
287 // 审核状态文本映射
288 const getAuditStatusText = (status) => {
289 const map = {
290 0: '待提交',
291 1: '审核中',
292 2: '审核通过',
293 3: '审核拒绝'
294 };
295 return map[status] || '未知状态';
296 };
297
248 // 数据请求核心方法 298 // 数据请求核心方法
249 const initData = async () => { 299 const initData = async () => {
250 loading.value = true; 300 loading.value = true;
...@@ -252,9 +302,11 @@ const initData = async () => { ...@@ -252,9 +302,11 @@ const initData = async () => {
252 302
253 try { 303 try {
254 const res = await api.orderList(queryParams); 304 const res = await api.orderList(queryParams);
255 if (!res || !res.rows) { 305 console.log("接口返回:", res);
256 list.value = []; 306
307 if (!res || !res.rows || res.rows.length === 0) {
257 hasMore.value = false; 308 hasMore.value = false;
309 loading.value = false;
258 return; 310 return;
259 } 311 }
260 // 安全解析content字段 312 // 安全解析content字段
...@@ -267,17 +319,18 @@ const initData = async () => { ...@@ -267,17 +319,18 @@ const initData = async () => {
267 } 319 }
268 } 320 }
269 }); 321 });
270 // 分页拼接数据 322 // 第一页覆盖,后面页数追加
271 if (pageNum.value === 1) { 323 if (pageNum.value === 1) {
272 list.value = res.rows; 324 list.value = res.rows;
273 } else { 325 } else {
274 list.value.push(...res.rows); 326 list.value.push(...res.rows);
275 } 327 }
276 // 判断是否还有更多数据 328 // 关键修复:只要返回条数 < pageSize 就说明没有更多了
277 hasMore.value = list.value.length < (res.total || 0); 329 hasMore.value = res.rows.length === pageSize.value;
278 } catch (e) { 330 } catch (e) {
279 console.error('订单加载异常:', e); 331 console.error('订单加载异常:', e);
280 uni.showToast({ title: '加载失败', icon: 'none' }); 332 uni.showToast({ title: '加载失败', icon: 'none' });
333 hasMore.value = false;
281 } finally { 334 } finally {
282 loading.value = false; 335 loading.value = false;
283 } 336 }
...@@ -326,8 +379,16 @@ const handlePay = async (item) => { ...@@ -326,8 +379,16 @@ const handlePay = async (item) => {
326 379
327 // 申请开票 380 // 申请开票
328 const makeInvoiceFN = (item) => { 381 const makeInvoiceFN = (item) => {
329 // if (item.payStatus !== 1 || item.invoiceStatus === 1) return; 382 // 开票条件:缴费成功 && 未开票 && 审核通过
330 uni.navigateTo({ url: `/pages/invoice/apply?orderId=${item.id}amount=${item.price}` }); 383 // if (item.payStatus !== 1 || item.invoiceStatus === 1 || item.auditStatus !== 2) {
384 // return;
385 // }
386 // 设置刷新标记,从开票页面返回时刷新列表
387 needRefresh.value = true;
388 // 跳转到开票页面
389 uni.navigateTo({
390 url: `/pages/invoice/apply?orderId=${item.id}&amount=${item.price}`
391 });
331 }; 392 };
332 393
333 // 取消订单 394 // 取消订单
...@@ -364,7 +425,7 @@ const closeCancelPopup = () => { ...@@ -364,7 +425,7 @@ const closeCancelPopup = () => {
364 <style lang="scss" scoped> 425 <style lang="scss" scoped>
365 .order-page { 426 .order-page {
366 background: #f5f7fa; 427 background: #f5f7fa;
367 min-height: 100vh; 428 height: 100vh;
368 display: flex; 429 display: flex;
369 flex-direction: column; 430 flex-direction: column;
370 431
...@@ -411,7 +472,8 @@ const closeCancelPopup = () => { ...@@ -411,7 +472,8 @@ const closeCancelPopup = () => {
411 // 滚动列表容器 472 // 滚动列表容器
412 .order-list-scroll { 473 .order-list-scroll {
413 flex: 1; 474 flex: 1;
414 height: 0; 475 height: auto;
476 overflow: auto;
415 } 477 }
416 478
417 // 订单列表 479 // 订单列表
...@@ -450,8 +512,13 @@ const closeCancelPopup = () => { ...@@ -450,8 +512,13 @@ const closeCancelPopup = () => {
450 } 512 }
451 } 513 }
452 514
515 .status-tags {
516 display: flex;
517 gap: 10rpx;
518 }
519
453 .status-tag { 520 .status-tag {
454 font-size: 24rpx; 521 font-size: 22rpx;
455 padding: 6rpx 16rpx; 522 padding: 6rpx 16rpx;
456 border-radius: 20rpx; 523 border-radius: 20rpx;
457 524
...@@ -469,6 +536,25 @@ const closeCancelPopup = () => { ...@@ -469,6 +536,25 @@ const closeCancelPopup = () => {
469 background: #f5f5f5; 536 background: #f5f5f5;
470 color: #999; 537 color: #999;
471 } 538 }
539
540 &.ml-10 {
541 margin-left: 10rpx;
542 }
543
544 &.status-pending {
545 background: #fff7e6;
546 color: #faad14;
547 }
548
549 &.status-success {
550 background: #e6f7ef;
551 color: #52c41a;
552 }
553
554 &.status-danger {
555 background: #fff1f0;
556 color: #ff4d4f;
557 }
472 } 558 }
473 } 559 }
474 560
...@@ -519,27 +605,46 @@ const closeCancelPopup = () => { ...@@ -519,27 +605,46 @@ const closeCancelPopup = () => {
519 font-weight: 500; 605 font-weight: 500;
520 text-align: center; 606 text-align: center;
521 margin-top: 10rpx; 607 margin-top: 10rpx;
608
609 &.text-success {
610 color: #52c41a;
611 }
612
613 &.text-warning {
614 color: #faad14;
615 }
522 } 616 }
523 } 617 }
524 618
525 // 费用合计 619 // 费用合计
526 .total-row { 620 .price-section {
621 border-top: 1rpx dashed #eee;
622 padding-top: 16rpx;
623 margin-top: 8rpx;
624
625 .price-row {
527 display: flex; 626 display: flex;
528 justify-content: space-between; 627 justify-content: space-between;
529 align-items: center; 628 align-items: center;
530 margin: 0 0 30rpx; 629 padding: 8rpx 0;
531 padding: 15rpx 0;
532 font-size: 28rpx;
533 border-bottom: 1rpx dashed #eee;
534 630
535 .label { 631 .price-label {
632 font-size: 26rpx;
536 color: #333; 633 color: #333;
537 } 634 }
538 635
539 .amount { 636 .price-value {
540 color: #EB6100; 637 font-size: 26rpx;
541 font-weight: 600; 638 color: #666;
542 font-size: 32rpx; 639
640 &.text-success {
641 color: #52c41a;
642 }
643
644 &.text-warning {
645 color: #faad14;
646 }
647 }
543 } 648 }
544 } 649 }
545 650
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
49 }, { 49 }, {
50 "path": "pages/rank/applyDetail", 50 "path": "pages/rank/applyDetail",
51 "style": { 51 "style": {
52 "navigationBarTitleText": "段位考试详情", 52 "navigationBarTitleText": "考试详情",
53 "enablePullDownRefresh": false 53 "enablePullDownRefresh": false
54 } 54 }
55 55
...@@ -61,6 +61,14 @@ ...@@ -61,6 +61,14 @@
61 } 61 }
62 62
63 }, { 63 }, {
64 "path": "pages/index/orderList",
65 "style": {
66 "navigationBarTitleText": "订单列表",
67 "enablePullDownRefresh": false,
68 "navigationStyle": "custom"
69 }
70
71 }, {
64 "path": "pages/rank/scoreApproval", 72 "path": "pages/rank/scoreApproval",
65 "style": { 73 "style": {
66 "navigationBarTitleText": "段位考试成绩审核", 74 "navigationBarTitleText": "段位考试成绩审核",
...@@ -296,6 +304,17 @@ ...@@ -296,6 +304,17 @@
296 "navigationBarTitleText": "会员调动", 304 "navigationBarTitleText": "会员调动",
297 "enablePullDownRefresh": false 305 "enablePullDownRefresh": false
298 } 306 }
307 }, {"path": "order",
308 "style": {
309 "navigationBarTitleText": "订单列表",
310 "enablePullDownRefresh": false
311 }
312 }, {
313 "path": "orderDetail",
314 "style": {
315 "navigationBarTitleText": "订单详情",
316 "enablePullDownRefresh": false
317 }
299 }, { 318 }, {
300 "path": "mobilizeDetail", 319 "path": "mobilizeDetail",
301 "style": { 320 "style": {
...@@ -456,6 +475,19 @@ ...@@ -456,6 +475,19 @@
456 }, { 475 }, {
457 "root": "group", 476 "root": "group",
458 "pages": [{ 477 "pages": [{
478 "path": "auditRecord1",
479 "style": {
480 "navigationBarTitleText": "审核记录",
481 "enablePullDownRefresh": false
482 }
483 }, {
484 "path": "groupOrderDetail",
485 "style": {
486 "navigationBarTitleText": "订单详情",
487 "enablePullDownRefresh": false
488 }
489
490 }, {
459 "path": "addGroupMemberPay", 491 "path": "addGroupMemberPay",
460 "style": { 492 "style": {
461 "navigationBarTitleText": "添加缴费", 493 "navigationBarTitleText": "添加缴费",
...@@ -596,6 +628,24 @@ ...@@ -596,6 +628,24 @@
596 }, { 628 }, {
597 "root": "level", 629 "root": "level",
598 "pages": [{ 630 "pages": [{
631 "path": "auditRecord2",
632 "style": {
633 "navigationBarTitleText": "审核记录",
634 "enablePullDownRefresh": false
635 }
636 }, {
637 "path": "paymentDetail",
638 "style": {
639 "navigationBarTitleText": "付款详情",
640 "enablePullDownRefresh": false
641 }
642 }, {
643 "path": "addressManage",
644 "style": {
645 "navigationBarTitleText": "地址管理",
646 "enablePullDownRefresh": false
647 }
648 }, {
599 "path": "ztx/examList", 649 "path": "ztx/examList",
600 "style": { 650 "style": {
601 "navigationBarTitleText": "级位考试详情", 651 "navigationBarTitleText": "级位考试详情",
...@@ -735,6 +785,13 @@ ...@@ -735,6 +785,13 @@
735 { 785 {
736 "path": "reviewList", 786 "path": "reviewList",
737 "style": { 787 "style": {
788 "navigationBarTitleText": "审核信息",
789 "enablePullDownRefresh": false
790 }
791 },
792 {
793 "path": "certAuditDetail",
794 "style": {
738 "navigationBarTitleText": "审核详情", 795 "navigationBarTitleText": "审核详情",
739 "enablePullDownRefresh": false 796 "enablePullDownRefresh": false
740 } 797 }
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
27 考试信息 27 考试信息
28 </view> 28 </view>
29 <view class="userlist"> 29 <view class="userlist">
30 <view class="item" v-for="n in infoList" @click="goDetail(n)" style="background-color: #fffafa;"> 30 <view class="item" v-for="(n,index) in infoList" :key="index" @click="goDetail(n)" style="background-color: #fffafa;">
31 <view class="w100"> 31 <view class="w100">
32 <view class="text-primary">{{n.examCode}}</view> 32 <view class="text-primary">{{n.examCode}}</view>
33 <view class="name">{{n.name}}</view> 33 <view class="name">{{n.name}}</view>
......
...@@ -114,6 +114,10 @@ ...@@ -114,6 +114,10 @@
114 <image :src="config.baseUrl_api+'/fs/static/icon/27.png'" /> 114 <image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
115 信息变更 115 信息变更
116 </view> 116 </view>
117 <view @click="goPath('/group/auditRecord1')">
118 <image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
119 审核记录
120 </view>
117 </view> 121 </view>
118 <view class="ttt">级位管理</view> 122 <view class="ttt">级位管理</view>
119 <view class="girdBox"> 123 <view class="girdBox">
...@@ -128,6 +132,10 @@ ...@@ -128,6 +132,10 @@
128 <image :src="config.baseUrl_api+'/fs/static/icon/26.png'" /> 132 <image :src="config.baseUrl_api+'/fs/static/icon/26.png'" />
129 级位变更 133 级位变更
130 </view> 134 </view>
135 <view @click="goPath('/level/auditRecord2')">
136 <image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
137 审核记录
138 </view>
131 </view> 139 </view>
132 140
133 <!-- <view class="ttt">段位管理</view> 141 <!-- <view class="ttt">段位管理</view>
...@@ -178,6 +186,10 @@ ...@@ -178,6 +186,10 @@
178 <image :src="config.baseUrl_api+'/fs/static/icon/28.png'" /> 186 <image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
179 合并审核 187 合并审核
180 </view> 188 </view>
189 <view @click="goPath('/personalVip/order?type=0')">
190 <image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
191 订单列表
192 </view>
181 </view> 193 </view>
182 194
183 <view class="ttt">团体会员</view> 195 <view class="ttt">团体会员</view>
...@@ -191,7 +203,10 @@ ...@@ -191,7 +203,10 @@
191 <image :src="config.baseUrl_api+'/fs/static/icon/27.png'" /> 203 <image :src="config.baseUrl_api+'/fs/static/icon/27.png'" />
192 变更审核 204 变更审核
193 </view> 205 </view>
194 206 <view @click="goPath('/personalVip/order?type=1')">
207 <image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
208 订单列表
209 </view>
195 </view> 210 </view>
196 211
197 <view class="ttt">级位管理</view> 212 <view class="ttt">级位管理</view>
...@@ -209,6 +224,10 @@ ...@@ -209,6 +224,10 @@
209 <image :src="config.baseUrl_api+'/fs/static/icon/26.png'" /> 224 <image :src="config.baseUrl_api+'/fs/static/icon/26.png'" />
210 变更审核 225 变更审核
211 </view> 226 </view>
227 <view @click="goPath('/personalVip/order?type=2')">
228 <image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
229 订单列表
230 </view>
212 </view> 231 </view>
213 232
214 <view class="ttt">段位管理</view> 233 <view class="ttt">段位管理</view>
...@@ -224,7 +243,10 @@ ...@@ -224,7 +243,10 @@
224 <view @click="goPath('/level/ztx/cert?type=2')"> 243 <view @click="goPath('/level/ztx/cert?type=2')">
225 <image :src="config.baseUrl_api+'/fs/static/icon/20.png'" />证书发布 244 <image :src="config.baseUrl_api+'/fs/static/icon/20.png'" />证书发布
226 </view> 245 </view>
227 246 <view @click="goPath('/personalVip/order?type=3')">
247 <image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
248 订单列表
249 </view>
228 </view> 250 </view>
229 251
230 <view class="ttt">越段考试</view> 252 <view class="ttt">越段考试</view>
...@@ -240,6 +262,10 @@ ...@@ -240,6 +262,10 @@
240 <view @click="goPath('/level/ztx/cert?type=3')"> 262 <view @click="goPath('/level/ztx/cert?type=3')">
241 <image :src="config.baseUrl_api+'/fs/static/icon/23.png'" />证书发布 263 <image :src="config.baseUrl_api+'/fs/static/icon/23.png'" />证书发布
242 </view> 264 </view>
265 <view @click="goPath('/personalVip/order?type=4')">
266 <image :src="config.baseUrl_api+'/fs/static/icon/28.png'" />
267 订单列表
268 </view>
243 </view> 269 </view>
244 270
245 </view> 271 </view>
...@@ -285,7 +311,7 @@ ...@@ -285,7 +311,7 @@
285 const app = getApp(); 311 const app = getApp();
286 const userType = ref('1') 312 const userType = ref('1')
287 const memberInfo = ref({}) 313 const memberInfo = ref({})
288 314 const deptInfo = ref({})
289 let proId; 315 let proId;
290 const svId = ref(null); 316 const svId = ref(null);
291 const numData = ref({}); 317 const numData = ref({});
...@@ -409,9 +435,21 @@ ...@@ -409,9 +435,21 @@
409 435
410 function init() { 436 function init() {
411 isInit.value = true 437 isInit.value = true
438
439
412 loginServer.getMyOwnMemberInfo().then(res => { 440 loginServer.getMyOwnMemberInfo().then(res => {
413 userType.value = app.globalData.userType 441 userType.value = app.globalData.userType
414 memberInfo.value = app.globalData.memberInfo 442 memberInfo.value = app.globalData.memberInfo
443 // deptInfo.value = app.globalData.dept || {}
444 // app.globalData.deptInfo = res.dept || {}
445 console.log(43,res)
446 if (userType.value != '1' && app.globalData.authenticationStatus != '2' && app.globalData
447 .authenticationStatus != '4') {
448 // 注册引导
449 uni.navigateTo({
450 url: '/pages/index/perfect'
451 });
452 }
415 // console.log(userType.value, app.globalData.authenticationStatus) 453 // console.log(userType.value, app.globalData.authenticationStatus)
416 if (app.globalData.authenticationStatus == '5') { 454 if (app.globalData.authenticationStatus == '5') {
417 if (app.globalData.genFlag == 1) { 455 if (app.globalData.genFlag == 1) {
...@@ -442,13 +480,6 @@ ...@@ -442,13 +480,6 @@
442 success: function(res) {} 480 success: function(res) {}
443 }) 481 })
444 } 482 }
445 if (userType.value != '1' && app.globalData.authenticationStatus != '2' && app.globalData
446 .authenticationStatus != '4') {
447 // 注册引导
448 // uni.navigateTo({
449 // url: '/pages/index/perfect'
450 // });
451 }
452 if (memberInfo.value.activeStatus == 0) { 483 if (memberInfo.value.activeStatus == 0) {
453 uni.showModal({ 484 uni.showModal({
454 content: '账号未激活,请前去激活', 485 content: '账号未激活,请前去激活',
......
...@@ -80,8 +80,8 @@ const form = reactive({ ...@@ -80,8 +80,8 @@ const form = reactive({
80 80
81 // 页面加载(接收PC端传来的参数) 81 // 页面加载(接收PC端传来的参数)
82 onLoad((options) => { 82 onLoad((options) => {
83 if (options.id) { 83 if (options.id || options.orderId) {
84 form.id = options.id; 84 form.id = options.id|| options.orderId;
85 form.amount = options.amount; 85 form.amount = options.amount;
86 console.log(33,form.amount); 86 console.log(33,form.amount);
87 } 87 }
......
1 <template>
2 <view>
3 <scroll-view scroll-y class="detail-content">
4 <!-- 成员信息 -->
5 <view class="card">
6 <view class="card-header">
7 <view class="header-left">成员信息</view>
8 <view class="header-right">{{ total || 0 }}</view>
9 </view>
10
11 <!-- 加载状态 -->
12 <view v-if="loading" class="state-tip">加载中...</view>
13 <view v-else-if="memberList.length === 0" class="state-tip">暂无成员信息</view>
14
15 <!-- 成员列表 - 与级位考试详情考生信息样式一致 -->
16 <view class="student-list" v-else>
17 <view class="student-card" v-for="n in memberList" :key="n.payId || n.perId || n.id">
18 <view class="student-top">
19 <view class="student-name">
20 <text class="name">{{ n.perName || n.realName || '——' }}</text>
21 <text class="unit">{{ n.memName || '' }}</text>
22 </view>
23 <view class="new-tag" :class="n.isNew == 1 ? 'is-new' : ''">
24 {{ n.isNew == 1 ? '新会员' : '续费' }}
25 </view>
26 </view>
27 <view class="student-info">
28 <view class="info-col">
29 <text class="info-text">{{ n.perIdcCode || n.idcCode || '——' }}</text>
30 </view>
31 <view class="info-col">
32 <text class="info-text">{{ n.payYear || n.renewYear || '——' }}</text>
33 </view>
34 <view class="info-col">
35 <text class="info-text">{{ getIdcTypeText(n.perIdcType || n.idcType) }}</text>
36 </view>
37 </view>
38 </view>
39 </view>
40
41 <!-- 加载更多 -->
42 <view class="load-more" v-if="memberList.length > 0 && hasMore" @click="loadMore">
43 {{ loadingMore ? '加载中...' : '加载更多' }}
44 </view>
45 </view>
46
47 <!-- 审核记录 -->
48 <view class="card">
49 <view class="card-header">
50 <view class="header-left">审核记录</view>
51 </view>
52
53 <view v-if="loadingAudit" class="state-tip">加载中...</view>
54 <view v-else-if="auditList.length === 0" class="state-tip">暂无审核记录</view>
55
56 <view class="audit-list" v-else>
57 <view class="audit-item" v-for="(n, index) in auditList" :key="index">
58 <view class="audit-dot" :class="n.auditResult == 1 ? 'pass' : 'fail'"></view>
59 <view class="audit-content">
60 <view class="audit-time">{{ parseDateTime(n.auditTime) }}</view>
61 <view class="audit-status" :class="n.auditResult == 1 ? 'text-green' : 'text-red'">
62 {{ getAuditResultText(n.auditResult) }}
63 </view>
64 <view class="audit-dept">{{ n.auditDeptName || '——' }}</view>
65 <view class="audit-remark" v-if="n.auditMsg">备注:{{ n.auditMsg }}</view>
66 </view>
67 </view>
68 </view>
69 </view>
70 </scroll-view>
71 </view>
72 </template>
73
74 <script setup>
75 import * as api from '@/common/api.js'
76 import { ref } from 'vue'
77 import { onLoad } from '@dcloudio/uni-app'
78
79 const orderInfo = ref({})
80 const memberList = ref([])
81 const auditList = ref([])
82 const total = ref(0)
83 const loading = ref(false)
84 const loadingAudit = ref(false)
85 const loadingMore = ref(false)
86 const hasMore = ref(false)
87
88 const queryParams = ref({
89 pageNum: 1,
90 pageSize: 10
91 })
92
93 let rangeId = ''
94
95 onLoad((option) => {
96 if (!option.rangeId) {
97 uni.showToast({ title: '参数错误', icon: 'none' })
98 setTimeout(() => uni.navigateBack(), 1500)
99 return
100 }
101 rangeId = option.rangeId
102 initData()
103 })
104
105 function initData() {
106 uni.showLoading({ title: '加载中' })
107 getMemberList()
108 getAuditList()
109 }
110
111 function getMemberList() {
112 loading.value = true
113 queryParams.value.rangeId = rangeId
114 api.listAPI(queryParams.value).then(res => {
115 uni.hideLoading()
116 if (res && res.rows) {
117 if (queryParams.value.pageNum === 1) {
118 memberList.value = res.rows
119 } else {
120 memberList.value.push(...res.rows)
121 }
122 total.value = res.total || memberList.value.length
123 hasMore.value = memberList.value.length < (res.total || 0)
124 } else {
125 memberList.value = []
126 total.value = 0
127 hasMore.value = false
128 }
129 }).catch(err => {
130 uni.hideLoading()
131 console.error('getMemberList error:', err)
132 memberList.value = []
133 }).finally(() => {
134 loading.value = false
135 })
136 }
137
138 function getAuditList() {
139 loadingAudit.value = true
140 api.newGetLogs(rangeId).then(res => {
141 if (res && res.data) {
142 auditList.value = Array.isArray(res.data) ? res.data : (res.data.levelSteps || [])
143 } else {
144 auditList.value = []
145 }
146 }).catch(err => {
147 console.error('getAuditList error:', err)
148 auditList.value = []
149 }).finally(() => {
150 loadingAudit.value = false
151 })
152 }
153
154 function loadMore() {
155 if (hasMore.value && !loadingMore.value) {
156 loadingMore.value = true
157 queryParams.value.pageNum++
158 getMemberList()
159 loadingMore.value = false
160 }
161 }
162
163 function getAuditResultText(result) {
164 const map = { 0: '审核拒绝', 1: '审核通过' }
165 return map[result] || '审核中'
166 }
167
168 function getIdcTypeText(type) {
169 const map = { 1: '身份证', 2: '护照', 3: '其他' }
170 return map[type] || '其他'
171 }
172
173 function parseDate(dateStr) {
174 if (!dateStr) return '——'
175 if (typeof dateStr === 'string' && dateStr.indexOf('T') > -1) {
176 return dateStr.slice(0, 10)
177 }
178 return dateStr
179 }
180
181 function parseDateTime(dateStr) {
182 if (!dateStr) return '——'
183 if (typeof dateStr === 'string' && dateStr.indexOf('T') > -1) {
184 const [date, time] = dateStr.split('T')
185 return `${date} ${time?.slice(0, 5) || ''}`
186 }
187 return dateStr
188 }
189 </script>
190
191 <style scoped lang="scss">
192 $primary-color: #e8341d;
193 $success-color: #52c41a;
194 $danger-color: #e8341c;
195 $bg-color: #f5f7fa;
196 $card-bg: #ffffff;
197 $text-primary: #333;
198 $text-secondary: #666;
199 $text-placeholder: #999;
200 $border-color: #eee;
201 $content-gap: 24rpx;
202
203 .detail-content {
204 padding: 20rpx;
205 background: $bg-color;
206 min-height: 100vh;
207 box-sizing: border-box;
208 }
209
210 .card {
211 background: $card-bg;
212 border-radius: 16rpx;
213 margin-bottom: 20rpx;
214 overflow: hidden;
215 box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
216 }
217
218 .card-header {
219 display: flex;
220 justify-content: space-between;
221 align-items: center;
222 padding: 24rpx $content-gap 20rpx;
223 border-bottom: 1rpx solid $border-color;
224
225 .header-left {
226 font-size: 30rpx;
227 font-weight: 600;
228 color: $text-primary;
229 }
230
231 .header-right {
232 font-size: 26rpx;
233 color: $primary-color;
234 font-weight: 500;
235 }
236 }
237
238 .state-tip {
239 text-align: center;
240 padding: 60rpx 0;
241 font-size: 26rpx;
242 color: $text-placeholder;
243 }
244
245 .student-list {
246 padding: 0 $content-gap 24rpx;
247 }
248
249 .student-card {
250 border-radius: 12rpx;
251 padding: 24rpx;
252 margin-top: 16rpx;
253 border: 1rpx solid $border-color;
254
255 .student-top {
256 display: flex;
257 justify-content: space-between;
258 align-items: center;
259 margin-bottom: 20rpx;
260
261 .student-name {
262 .name {
263 font-size: 32rpx;
264 font-weight: 600;
265 color: $text-primary;
266 }
267
268 .unit {
269 font-size: 24rpx;
270 color: $text-placeholder;
271 margin-left: 16rpx;
272 }
273 }
274
275 .new-tag {
276 font-size: 22rpx;
277 padding: 6rpx 16rpx;
278 border-radius: 20rpx;
279 background: rgba($text-placeholder, 0.1);
280 color: $text-placeholder;
281 flex-shrink: 0;
282
283 &.is-new {
284 background: rgba($primary-color, 0.1);
285 color: $primary-color;
286 }
287 }
288 }
289
290 .student-info {
291 display: flex;
292 justify-content: space-between;
293 align-items: center;
294 gap: 12rpx;
295
296 .info-col {
297 flex: 1;
298 text-align: center;
299
300 .info-text {
301 font-size: 28rpx;
302 color: $text-primary;
303 font-weight: 500;
304 line-height: 1.4;
305 }
306 }
307 }
308 }
309
310 .load-more {
311 text-align: center;
312 padding: 24rpx 0;
313 font-size: 26rpx;
314 color: $primary-color;
315 }
316
317 .audit-list {
318 padding: 0 $content-gap 24rpx;
319 }
320
321 .audit-item {
322 display: flex;
323 padding: 20rpx 0;
324 border-bottom: 1rpx dashed $border-color;
325
326 &:last-child {
327 border-bottom: none;
328 }
329
330 .audit-dot {
331 width: 14rpx;
332 height: 14rpx;
333 border-radius: 50%;
334 margin-top: 8rpx;
335 margin-right: 20rpx;
336 flex-shrink: 0;
337
338 &.pass {
339 background: $success-color;
340 }
341
342 &.fail {
343 background: $danger-color;
344 }
345 }
346
347 .audit-content {
348 flex: 1;
349 padding-right: 8rpx;
350
351 .audit-time {
352 font-size: 24rpx;
353 color: $text-placeholder;
354 margin-bottom: 6rpx;
355 }
356
357 .audit-status {
358 font-size: 28rpx;
359 font-weight: 600;
360 margin-bottom: 6rpx;
361 }
362
363 .audit-dept {
364 font-size: 26rpx;
365 color: $text-secondary;
366 }
367
368 .audit-remark {
369 font-size: 24rpx;
370 color: $text-placeholder;
371 margin-top: 6rpx;
372 padding: 8rpx 12rpx;
373 background: #f8f8f8;
374 border-radius: 8rpx;
375 }
376 }
377 }
378
379 .text-red {
380 color: $danger-color !important;
381 }
382
383 .text-green {
384 color: $success-color !important;
385 }
386 </style>
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!