58412f8a by lttnew

会员缴费

1 parent 1d933336
...@@ -313,9 +313,16 @@ export function delInfo(perId) { ...@@ -313,9 +313,16 @@ export function delInfo(perId) {
313 }) 313 })
314 } 314 }
315 // 查询个人个人会员缴费列表 315 // 查询个人个人会员缴费列表
316 // export function getPaymentList(query) {
317 // return request({
318 // url: '/person/paymentRange/selectPageList',
319 // method: 'get',
320 // params: query
321 // })
322 // }
316 export function getPaymentList(query) { 323 export function getPaymentList(query) {
317 return request({ 324 return request({
318 url: '/person/paymentRange/selectPageList', 325 url: '/person/paymentRangeNew/list',
319 method: 'get', 326 method: 'get',
320 params: query 327 params: query
321 }) 328 })
...@@ -725,6 +732,12 @@ export function personalCommit(id) { ...@@ -725,6 +732,12 @@ export function personalCommit(id) {
725 params: id 732 params: id
726 }) 733 })
727 } 734 }
735 export function getNewCountByRangeId(rangeId) {
736 return request({
737 url: `/person/paymentNew/getNewCountByRangeId/${rangeId}`,
738 method: 'get',
739 })
740 }
728 741
729 export function delPayment(payIds) { 742 export function delPayment(payIds) {
730 return request({ 743 return request({
...@@ -746,13 +759,11 @@ export function delcertified(ids) { ...@@ -746,13 +759,11 @@ export function delcertified(ids) {
746 }) 759 })
747 } 760 }
748 761
749 export function editYear(id, year) { 762 export function editYear(data) {
750 return request({ 763 return request({
751 url: `/person/payment/editYear/${id}`, 764 url: `/person/paymentNew/editYear/${data.payId}?payId=${data.payId}&year=${data.year}`,
752 method: 'get', 765 method: 'post',
753 params: { 766 params: data
754 year: year
755 }
756 }) 767 })
757 } 768 }
758 769
...@@ -1256,3 +1267,130 @@ export function checkPersonByPersonId(perId) { ...@@ -1256,3 +1267,130 @@ export function checkPersonByPersonId(perId) {
1256 method: 'get' 1267 method: 'get'
1257 }) 1268 })
1258 } 1269 }
1270 // 获取团体会员优惠政策
1271 export function canUseDiscount(params) {
1272 return request({
1273 url: `/system/certifiedNew/canUseDiscount`,
1274 method: 'get',
1275 params
1276 })
1277 }
1278 // 获取团体会员一年缴费价格
1279 export function getMyMemberCertUnitFee(params) {
1280 return request({
1281 url: `/system/certifiedNew/getMyMemberCertUnitFee`,
1282 method: 'get',
1283 params
1284 })
1285 }
1286 export function checkBusinessLicense(data) {
1287 return request({
1288 url: `/member/info/checkBusinessLicense`,
1289 method: 'post',
1290 params: data
1291 })
1292 }
1293
1294 // 生成团体订单renewYear
1295 export function certifiedNew(params) {
1296 return request({
1297 url: `/system/certifiedNew/commit`,
1298 method: 'post',
1299 params
1300 })
1301 }
1302
1303 // 模拟回调
1304 export function callBack2(orderId) {
1305 return request({
1306 url: `/system/certifiedNew/callBack2/${orderId}`
1307 })
1308 }
1309 // 优惠政策回显
1310 export function getZtxDiscountPolicy(params) {
1311 return request({
1312 url: '/system/config/getZtxDiscountPolicy',
1313 method: 'get',
1314 params
1315 })
1316 }
1317 // 考官列表
1318 export function listApi(params) {
1319 return request({
1320 url: `/member/examiner/list`,
1321 method: 'get',
1322 params
1323 })
1324 }
1325
1326 // 考官列表
1327 export function examinerDel(id) {
1328 return request({
1329 url: `/member/examiner/${id}`,
1330 method: 'delete'
1331 })
1332 }
1333
1334 // 添加考官
1335 export function otherAdd(memId, ids) {
1336 return request({
1337 url: `/member/examiner/otherAdd/${memId}/${ids}`,
1338 method: 'post'
1339 })
1340 }
1341
1342 export function commitExamPointApply(params) {
1343 return request({
1344 url: `/member/examPointApply/commit?selfSelect=${params.selfSelect}`,
1345 method: 'post',
1346 params
1347 })
1348 }
1349
1350 export function getMyStatus() {
1351 return request({
1352 url: `/member/examPointApply/getMyStatus`
1353 })
1354 }
1355
1356 // 个人会员缴费支付
1357 export function goPay(id) {
1358 return request({
1359 url: `/person/paymentRangeNew/pay/${id}`,
1360 method: 'post'
1361 })
1362 }
1363 // 缴费单列表学员
1364 export function listAPI(params) {
1365 return request({
1366 url: `/person/paymentNew/list`,
1367 method: 'get',
1368 params
1369 })
1370 }
1371
1372
1373 // 删除学员
1374 export function paymentNewDel(id) {
1375 return request({
1376 url: `/person/paymentNew/${id}`,
1377 method: 'delete'
1378 })
1379 }
1380
1381
1382 // 缴费单列表
1383 export function memberInsertPersons(data) {
1384 return request({
1385 url: `/person/paymentNew/memberInsertPersons/${data.rangeId}/${data.year}/${data.idcCode}`,
1386 method: 'post',
1387 data
1388 })
1389 }
1390 export function createMemberPayRange(data) {
1391 return request({
1392 url: `/person/paymentRangeNew/createMemberPayRange`,
1393 method: 'post',
1394 data
1395 })
1396 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -42,7 +42,12 @@ page { ...@@ -42,7 +42,12 @@ page {
42 .text-primary{text-decoration: underline;}} 42 .text-primary{text-decoration: underline;}}
43 } 43 }
44 } 44 }
45 45 .flex{
46 display: flex;
47 }
48 .f-j-s{
49 justify-content: space-between;
50 }
46 .vipData{ 51 .vipData{
47 font-size: 24rpx;padding: 10px 20px;box-sizing: border-box; 52 font-size: 24rpx;padding: 10px 20px;box-sizing: border-box;
48 display: flex;background: #F7E7E8; 53 display: flex;background: #F7E7E8;
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
4 4
5 // staging 会员系统 5 // staging 会员系统
6 // const baseUrl_api = "http://22yidpjzjifv.ngrok.xiaomiqiu123.top/stage-api/"; 6 // const baseUrl_api = "http://22yidpjzjifv.ngrok.xiaomiqiu123.top/stage-api/";
7 const baseUrl_api = "https://ztx.itechtop.cn:8443/stage-api"; 7 // const baseUrl_api = "https://ztx.itechtop.cn:8443/stage-api";
8 // const baseUrl_api = 'http://192.168.1.132:8787' 8 const baseUrl_api = 'http://192.168.1.154:8788'
9 // const baseUrl_api = 'https://tkcn.19wk.cn:8443/stage-api' 9 // const baseUrl_api = 'https://tkcn.19wk.cn:8443/stage-api'
10 // const baseUrl_api = 'http://tk004.wxjylt.com/stage-api'
10 11
11 // const baseUrl_api = 'https://system.taekwondo.org.cn/stage-api' 12 // const baseUrl_api = 'https://system.taekwondo.org.cn/stage-api'
12 export default { 13 export default {
......
1 <template> 1 <template>
2 <view> 2 <view :class="{ 'lock-scroll': popupShow }">
3 <view v-if="showDirectly&&directUnderFlag==0"> 3 <view v-if="showDirectly&&directUnderFlag==0">
4 <view class="flexbox"> 4 <view class="flexbox">
5 <view> 5 <view>
...@@ -15,25 +15,25 @@ ...@@ -15,25 +15,25 @@
15 <text v-if="authenticationStatusa == 4" class="text-danger">即将过期</text> 15 <text v-if="authenticationStatusa == 4" class="text-danger">即将过期</text>
16 <text v-if="authenticationStatusa == 5" class="text-danger">已过期</text> 16 <text v-if="authenticationStatusa == 5" class="text-danger">已过期</text>
17 </text> 17 </text>
18
19 </view> 18 </view>
20 </view> 19 </view>
21 <view class="flexbox" style="justify-content: end;padding: 0 30rpx 40rpx;"> 20 <view class="flexbox" style="justify-content: flex-end;padding: 0 30rpx 40rpx;">
22 <button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini" 21 <button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini"
23 v-if="activeStatus==0&&authenticationStatusa" @click="payTheFees">激活</button> 22 v-if="activeStatus==0&&authenticationStatusa" @click="payTheFees">激活</button>
24 <view v-else> 23 <view v-else >
24 <button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini" :disabled="auditStatus==1||auditStatus==2||form.isPoints==0"
25 @click="showApplyDialog">考点申请</button>
25 <button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini" :disabled="btn" 26 <button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini" :disabled="btn"
26 @click="payTheFees">去缴费</button> 27 @click="payTheFees">去缴费</button>
27 <button class="btn-red-kx" style="margin: 0 20rpx 0 0;" size="mini" v-if="form.deptType!=1" 28 <button class="btn-red-kx" style="margin: 0 20rpx 0 0;" size="mini" v-if="form.deptType!=1"
28 @click="auditEditFN">审核详情</button> 29 @click="auditEditFN">审核详情</button>
29 </view> 30 </view>
30 </view> 31 </view>
31 </view> 32 </view>
32 <view class="mainbox"> 33 <view class="mainbox">
33 <uni-list> 34 <uni-list>
34 <uni-list-item v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3" 35 <uni-list-item v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3"
35 title="所属协会" :rightText="form.aname"> 36 title="所属协会" :rightText="form.aname">
36
37 </uni-list-item> 37 </uni-list-item>
38 <uni-list-item title="会员编号" v-if="form.menCode" :rightText="form.menCode" /> 38 <uni-list-item title="会员编号" v-if="form.menCode" :rightText="form.menCode" />
39 <uni-list-item title="机构名称" :rightText="form.name" /> 39 <uni-list-item title="机构名称" :rightText="form.name" />
...@@ -43,9 +43,7 @@ ...@@ -43,9 +43,7 @@
43 <uni-data-picker readonly :clear-icon="false" 43 <uni-data-picker readonly :clear-icon="false"
44 v-model="form.belongProvinceId" :localdata="options"> 44 v-model="form.belongProvinceId" :localdata="options">
45 </uni-data-picker> 45 </uni-data-picker>
46
47 </view> 46 </view>
48
49 </template> 47 </template>
50 </uni-list-item> 48 </uni-list-item>
51 <uni-list-item title="社会信用代码" 49 <uni-list-item title="社会信用代码"
...@@ -101,13 +99,27 @@ ...@@ -101,13 +99,27 @@
101 </image> 99 </image>
102 <text>{{form.picturesArr?.length}}</text> 100 <text>{{form.picturesArr?.length}}</text>
103 </view> 101 </view>
104
105 </view> 102 </view>
106 </template> 103 </template>
107 </uni-list-item> 104 </uni-list-item>
108 </uni-list> 105 </uni-list>
109 </view> 106 </view>
110 107 <!-- 弹窗添加触摸事件拦截 -->
108 <uni-popup ref="applyPopup" type="center"
109 @touchmove.stop.prevent="() => {}"
110 @open="onPopupOpen"
111 @close="onPopupClose">
112 <view class="apply-dialog" @touchmove.stop.prevent="() => {}">
113 <view class="dialog-title">考点申请</view>
114 <view class="dialog-content">
115 <text class="remind">友情提示:非考点无法申请级位考试</text>
116 </view>
117 <view class="dialog-buttons">
118 <button class="btn-cancel" @click="closeApplyDialog">暂不申请</button>
119 <button class="btn-confirm" @click="goToApplyPage">立即申请</button>
120 </view>
121 </view>
122 </uni-popup>
111 <view class="height1"></view> 123 <view class="height1"></view>
112 </view> 124 </view>
113 </template> 125 </template>
...@@ -119,7 +131,7 @@ ...@@ -119,7 +131,7 @@
119 131
120 import _ from 'underscore' 132 import _ from 'underscore'
121 import { 133 import {
122 ref 134 ref, onUnmounted
123 } from 'vue' 135 } from 'vue'
124 import { 136 import {
125 onLoad,onShow 137 onLoad,onShow
...@@ -141,8 +153,23 @@ ...@@ -141,8 +153,23 @@
141 const pr = ref({}) 153 const pr = ref({})
142 const applicationForMembership1 = ref({}) 154 const applicationForMembership1 = ref({})
143 const options = ref([]) 155 const options = ref([])
156 const applyPopup = ref(null)
157 // 新增:控制弹窗显示状态(用于锁定滚动)
158 const popupShow = ref(false)
159 // 考点审核状态 0 未提交 1 审核中 2 审核成功 3 审核失败
160 const auditStatus = ref(0)
161
144 onShow(() => { 162 onShow(() => {
145 init() 163 init()
164 if (form.value.deptType != 1) { // 修复:原代码deptType未定义,改为form.value.deptType
165 getMyStatusAPI()
166 }
167 })
168
169 // 页面卸载时恢复滚动(防止异常锁死)
170 onUnmounted(() => {
171 uni.setPageScrollEnabled({ enabled: true })
172 popupShow.value = false
146 }) 173 })
147 174
148 function init() { 175 function init() {
...@@ -190,12 +217,10 @@ ...@@ -190,12 +217,10 @@
190 // 入会材料 217 // 入会材料
191 if (form.value.materials) { 218 if (form.value.materials) {
192 form.value.materials1 = JSON.parse(form.value.materials) 219 form.value.materials1 = JSON.parse(form.value.materials)
193 // form.value.materials = JSON.parse(form.value.materials)
194 } 220 }
195 // 入会申请书 221 // 入会申请书
196 if (form.value.applicationForMembership) { 222 if (form.value.applicationForMembership) {
197 form.value.applicationForMembership1 = JSON.parse(form.value.applicationForMembership) 223 form.value.applicationForMembership1 = JSON.parse(form.value.applicationForMembership)
198 // form.value.applicationForMembership = JSON.parse(form.value.applicationForMembership)
199 } 224 }
200 applicationForMembership1.value = form.value.applicationForMembership || [] 225 applicationForMembership1.value = form.value.applicationForMembership || []
201 form.value.deptType = res.data.dept.deptType 226 form.value.deptType = res.data.dept.deptType
...@@ -238,7 +263,53 @@ ...@@ -238,7 +263,53 @@
238 } 263 }
239 console.log(form.value.picturesArr) 264 console.log(form.value.picturesArr)
240 } 265 }
266 })
267 }
268
269 async function getMyStatusAPI() {
270 const { data } = await api.getMyStatus()
271 if (data && data.auditStatus) {
272 auditStatus.value = data.auditStatus
273 } else {
274 auditStatus.value = 0
275 }
276 }
277
278 // 新增:弹窗打开时锁定滚动
279 function onPopupOpen() {
280 popupShow.value = true
281 // 1. 小程序API锁定页面滚动
282 uni.setPageScrollEnabled({ enabled: false })
283 // 延时兜底(防止API生效延迟)
284 setTimeout(() => {
285 uni.setPageScrollEnabled({ enabled: false })
286 }, 100)
287 }
288
289 // 新增:弹窗关闭时恢复滚动
290 function onPopupClose() {
291 popupShow.value = false
292 // 恢复页面滚动
293 uni.setPageScrollEnabled({ enabled: true })
294 setTimeout(() => {
295 uni.setPageScrollEnabled({ enabled: true })
296 }, 100)
297 }
298
299 function showApplyDialog() {
300 applyPopup.value.open()
301 }
241 302
303 // 关闭申请弹窗
304 function closeApplyDialog() {
305 applyPopup.value.close()
306 }
307
308 // 跳转到考点申请页面
309 function goToApplyPage() {
310 closeApplyDialog()
311 uni.navigateTo({
312 url: `/myCenter/examPointApply?memId=${form.value.memId}`
242 }) 313 })
243 } 314 }
244 315
...@@ -247,13 +318,12 @@ ...@@ -247,13 +318,12 @@
247 url: `/myCenter/reviewList` 318 url: `/myCenter/reviewList`
248 }) 319 })
249 } 320 }
321
250 function showImage(arr, index) { 322 function showImage(arr, index) {
251 uni.previewImage({ 323 uni.previewImage({
252 urls: arr, 324 urls: arr,
253 current: index, 325 current: index,
254 success: function(res) { 326 success: function(res) {}
255
256 }
257 }) 327 })
258 } 328 }
259 329
...@@ -263,15 +333,12 @@ ...@@ -263,15 +333,12 @@
263 if(url.indexOf('http')>-1){ 333 if(url.indexOf('http')>-1){
264 uni.previewImage({ 334 uni.previewImage({
265 urls: [url], 335 urls: [url],
266 success: function(res) { 336 success: function(res) {}
267
268 }
269 }) 337 })
270 } else { 338 } else {
271 uni.previewImage({ 339 uni.previewImage({
272 urls: [config.baseUrl_api + url], 340 urls: [config.baseUrl_api + url],
273 success: function(res) { 341 success: function(res) {}
274 }
275 }) 342 })
276 } 343 }
277 } else { 344 } else {
...@@ -322,12 +389,14 @@ ...@@ -322,12 +389,14 @@
322 } 389 }
323 }); 390 });
324 } 391 }
392
325 function payTheFees(){ 393 function payTheFees(){
326 if (!form.value.name) { 394 if (!form.value.name) {
327 uni.showToast({ 395 uni.showToast({
328 title: `请先完善团体信息`, 396 title: `请先完善团体信息`,
329 icon: 'none' 397 icon: 'none'
330 }); 398 });
399 return; // 新增:防止无名称时跳转
331 } 400 }
332 uni.navigateTo({ 401 uni.navigateTo({
333 url:`/myCenter/perfect` 402 url:`/myCenter/perfect`
...@@ -336,6 +405,17 @@ ...@@ -336,6 +405,17 @@
336 </script> 405 </script>
337 406
338 <style scoped lang="scss"> 407 <style scoped lang="scss">
408 // 新增:锁定滚动的核心样式
409 .lock-scroll {
410 position: fixed !important;
411 top: 0;
412 left: 0;
413 right: 0;
414 bottom: 0;
415 overflow: hidden !important;
416 height: 100vh !important;
417 }
418
339 .height1{height: 100rpx;} 419 .height1{height: 100rpx;}
340 .photobox { 420 .photobox {
341 position: relative; 421 position: relative;
...@@ -399,4 +479,57 @@ ...@@ -399,4 +479,57 @@
399 .mainbox { 479 .mainbox {
400 margin: 30rpx; 480 margin: 30rpx;
401 } 481 }
482 .apply-dialog {
483 width: 530rpx;
484 background: #fff;
485 border-radius: 16rpx;
486 padding: 40rpx;
487 // 新增:禁止弹窗内部滚动
488 touch-action: none;
489 }
490 .dialog-title {
491 font-size: 32rpx;
492 font-weight: bold;
493 text-align: center;
494 margin-bottom: 30rpx;
495 }
496 .dialog-content {
497 margin: 40rpx;
498 }
499 .remind {
500 color: #FF8124;
501 font-size: 26rpx;
502 margin-top: 40rpx;
503 }
504 .dialog-buttons {
505 display: flex;
506 justify-content: space-between;
507 margin-top: 40rpx;
508 }
509 .btn-cancel {
510 width: 225rpx;
511 height: 80rpx;
512 line-height: 80rpx;
513 border: 1rpx solid #ddd;
514 border-radius: 40rpx;
515 background: #fff;
516 color: #333;
517 text-align: center;
518 font-size: 14px;
519 }
520 .btn-confirm {
521 width: 225rpx;
522 height: 80rpx;
523 line-height: 80rpx;
524 border-radius: 40rpx;
525 background: #C4121B;
526 font-size: 14px;
527 color: #fff;
528 text-align: center;
529 }
530
531 // 新增:给uni-popup蒙版添加禁止滚动样式
532 :deep(.uni-popup__mask) {
533 touch-action: none !important;
534 }
402 </style> 535 </style>
...\ No newline at end of file ...\ No newline at end of file
......
1 <template>
2 <view class="container">
3 <!-- 搜索区域:固定在顶部 -->
4 <view class="search-area">
5 <view class="search-item">
6 <text>考官姓名:</text>
7 <input v-model="queryParams.name" placeholder="请输入考官姓名" class="search-input" />
8 </view>
9 <view class="search-item">
10 <text>考官编号:</text>
11 <input v-model="queryParams.certCode" placeholder="请输入考官编号" class="search-input" />
12 </view>
13 <view class="search-buttons">
14 <button class="search-btn" @click="handleQuery">查询</button>
15 <button class="reset-btn" @click="resetQuery">重置</button>
16 </view>
17 </view>
18
19 <view class="list-item" v-for="(item, index) in infoList" :key="item.perId">
20 <view class="info">
21 <view class="name">{{ item.name }} {{ item.perCode }}</view>
22 <view class="idc">证件号码:{{ item.idcCode }}</view>
23 <view class="reg">注册地:{{ item.memName }}</view>
24 </view>
25 <button
26 class="choose-btn"
27 :class="{ disabled: checkChosen(item) }"
28 @click="handleChoose(item)"
29 :disabled="checkChosen(item)"
30 >
31 {{ checkChosen(item) ? '已选择' : '选择' }}
32 </button>
33 </view>
34
35 <uni-popup ref="expirePopup" type="center" background-color="rgba(0,0,0,0.5)">
36 <view class="custom-modal">
37 <view class="modal-title">提示</view>
38 <view class="modal-content">该考官资质已过期,是否继续添加?</view>
39 <view class="modal-btns">
40 <button class="btn-cancel" @click="closeExpirePopup()">取消</button>
41 <button class="btn-confirm" @click="confirmAddExpireExaminer()">确定</button>
42 </view>
43 </view>
44 </uni-popup>
45 </view>
46 </template>
47
48 <script setup>
49 import { ref, reactive, toRefs } from 'vue'
50 import { onLoad } from '@dcloudio/uni-app';
51 import * as api from '@/common/api.js'
52 import _ from 'lodash'
53
54 const props = defineProps({
55 isValidity: {
56 type: String,
57 default: '0'
58 }
59 })
60
61 const isValidity = ref('0')
62 const memId = ref('')
63 const chosen = ref([])
64 const expirePopup = ref(null)
65 const currentExpireItem = ref(null)
66
67 onLoad((option) => {
68 isValidity.value = option.isValidity
69 memId.value = option.memId
70 chosen.value = JSON.parse(option.chosen)
71 })
72
73 const data = reactive({
74 queryParams: {
75 pageNum: 1,
76 pageSize: 10,
77 name: null,
78 certCode: null,
79 type: 1,
80 shenMemId: ''
81 }
82 })
83 const { queryParams } = toRefs(data)
84
85 const infoList = ref([])
86 const loading = ref(false)
87 const total = ref(0)
88
89 // 获取考官列表
90 async function getList() {
91 if (!queryParams.value.name)
92 return uni.showToast({ title: '请输入考官姓名', icon: 'none' })
93 if (queryParams.value.type == 1 && !queryParams.value.certCode)
94 return uni.showToast({ title: '请输入考官编号', icon: 'none' })
95
96 loading.value = true
97 const res = await api.getCoachList(queryParams.value)
98 infoList.value = res.rows
99 total.value = res.total
100 loading.value = false
101
102 if (infoList.value.length === 0) {
103 uni.showToast({ title: '请核实考官编号、有效期及归属地!', icon: 'none' })
104 }
105 }
106
107 // 检查是否已选择
108 function checkChosen(row) {
109 return _.some(chosen.value, (c) => {
110 return c.perId == row.perId
111 })
112 }
113
114 // 查询
115 function handleQuery() {
116 queryParams.value.pageNum = 1
117 getList()
118 }
119
120 // 重置
121 function resetQuery() {
122 queryParams.value.name = null
123 queryParams.value.certCode = null
124 infoList.value = []
125 total.value = 0
126 }
127
128 async function handleChoose(row) {
129 if (checkChosen(row)) {
130 return uni.showToast({ title: '已选择该考官', icon: 'none' })
131 }
132
133 // 资质过期逻辑
134 if (row.canChoose != 1) {
135 // 暂存当前考官数据
136 currentExpireItem.value = row
137 // 打开自定义过期确认弹窗
138 expirePopup.value.open()
139 return
140 }
141 }
142
143 // 关闭过期确认弹窗
144 function closeExpirePopup() {
145 expirePopup.value.close()
146 }
147
148 // 确认添加过期考官
149 async function confirmAddExpireExaminer() {
150 if (!currentExpireItem.value) return
151
152 try {
153 await api.otherAdd(memId.value, currentExpireItem.value.perId)
154 uni.showToast({ title: '添加成功', icon: 'success' })
155 uni.navigateBack({ delta: 1 })
156 } catch (err) {
157 uni.showToast({ title: '添加失败', icon: 'none' })
158 } finally {
159 expirePopup.value.close()
160 currentExpireItem.value = null
161 }
162 }
163 </script>
164
165 <style scoped>
166 .container {
167 display: flex;
168 flex-direction: column;
169 background: #f7f7f7;
170 min-height: 100vh;
171 padding: 0;
172 }
173
174 .search-area {
175 background: #ffffff;
176 border-radius: 16rpx;
177 padding: 30rpx;
178 margin: 30rpx;
179 flex-shrink: 0;
180 }
181
182 .search-item {
183 display: flex;
184 align-items: center;
185 margin-bottom: 20rpx;
186 }
187 .search-input {
188 flex: 1;
189 border: 1rpx solid #ddd;
190 border-radius: 8rpx;
191 padding: 20rpx;
192 font-size: 28rpx;
193 }
194
195 .search-buttons {
196 display: flex;
197 justify-content: space-between;
198 margin-top: 10rpx;
199 }
200 .search-btn, .reset-btn {
201 width: 200rpx;
202 height: 70rpx;
203 line-height: 70rpx;
204 border-radius: 8rpx;
205 text-align: center;
206 font-size: 28rpx;
207 }
208 .search-btn {
209 background: #C4121B;
210 color: #fff;
211 }
212 .reset-btn {
213 background: #f7f7f7;
214 color: #333;
215 }
216
217 /* 列表区域:滚动 */
218 .list-area {
219 flex: 1;
220 background: #ffffff;
221 border-radius: 16rpx;
222 margin: 0 30rpx 30rpx;
223 padding: 0 30rpx;
224 }
225
226 .list-item {
227 padding: 30rpx;
228 margin: 0 30rpx;
229 border-bottom: 1rpx solid #eee;
230 background-color: #fff;
231 }
232 .info {
233 flex: 1;
234 }
235 .name {
236 font-size: 30rpx;
237 font-weight: bold;
238 color: #333;
239 }
240 .idc, .reg {
241 font-size: 26rpx;
242 color: #666;
243 margin: 20rpx 0;
244 }
245 .choose-btn {
246 color: #C4121B;
247 font-size: 26rpx;
248 border: 1rpx solid #C4121B;
249 border-radius: 8rpx;
250 padding: 10rpx 20rpx;
251 background-color: #fff;
252 margin: 10rpx auto;
253 }
254 .choose-btn.disabled {
255 color: #ccc;
256 border-color: #ccc;
257 }
258
259 /* 自定义弹窗样式(和之前保持统一) */
260 .custom-modal {
261 width: 600rpx;
262 background: #fff;
263 border-radius: 20rpx;
264 padding: 40rpx 30rpx;
265 box-sizing: border-box;
266 text-align: center;
267 }
268 .modal-title {
269 font-size: 36rpx;
270 font-weight: 600;
271 color: #333;
272 margin-bottom: 30rpx;
273 }
274 .modal-content {
275 font-size: 30rpx;
276 color: #666;
277 line-height: 1.6;
278 margin-bottom: 30rpx;
279 }
280 .modal-btns {
281 display: flex;
282 justify-content: space-between;
283 gap: 20rpx;
284 }
285 .btn-cancel {
286 flex: 1;
287 height: 80rpx;
288 line-height: 80rpx;
289 background: #f5f5f5;
290 color: #999;
291 border-radius: 40rpx;
292 font-size: 32rpx;
293 border: none;
294 }
295 .btn-confirm {
296 flex: 1;
297 height: 80rpx;
298 line-height: 80rpx;
299 background: #C4121B;
300 color: #fff;
301 border-radius: 40rpx;
302 font-size: 32rpx;
303 border: none;
304 }
305 /* 去除button默认边框 */
306 .btn-cancel::after, .btn-confirm::after {
307 border: none;
308 }
309 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <template>
2 <view class="container">
3 <!-- 考官选择类型 -->
4 <view class="radio-section">
5 <radio-group @change="onSelfSelectChange" class="radio-group">
6 <label class="radio-item">
7 <radio value="1" :checked="form.selfSelect == '1'" class="custom-radio" />
8 <text class="radio-text">自行录入考官(级位考官)</text>
9 </label>
10 <label class="radio-item">
11 <radio value="0" :checked="form.selfSelect == '0'" class="custom-radio" />
12 <text class="radio-text">省跆协指派考官</text>
13 </label>
14 </radio-group>
15 </view>
16 <view class="section">
17 <!-- 自行录入考官区域 -->
18 <view class="section examiner-section" v-if="showExamine">
19 <button class="add-btn" @click="handelAddExamine">+ 添加考官</button>
20 </view>
21
22 <view class="examiner-list" v-if="showExamine">
23 <view class="examiner-item" v-for="(item, index) in list" :key="item.id">
24 <view class="info">
25 <text class="name">{{ item.perName }} {{ item.perCode }}</text>
26 <text class="idc">证件号码:{{ item.perIdcCode }}</text>
27 <text class="reg">注册地:{{ item.memName }}</text>
28 </view>
29 <button class="del-btn" @click="handleDel(item)">删除</button>
30 </view>
31 </view>
32 </view>
33 <!-- 提交按钮 -->
34 <view class="submit-area">
35 <button class="submit-btn" @click="handelSubmit">确定提交</button>
36 </view>
37
38 <!-- 自定义考点申请弹窗(替换原uni.showModal) -->
39 <uni-popup ref="applyPopup" type="center" background-color="rgba(0,0,0,0.5)">
40 <view class="custom-modal">
41 <view class="modal-title">考点申请</view>
42 <view class="modal-btns">
43 <button class="btn-cancel" @click="closeApplyPopup()">暂不申请</button>
44 <button class="btn-confirm" @click="confirmApply()">立即申请</button>
45 </view>
46 <view class="modal-tip">友情提示:非考点无法申请级位考试</view>
47 </view>
48 </uni-popup>
49
50 <!-- 自定义删除确认弹窗 -->
51 <uni-popup ref="delPopup" type="center" background-color="rgba(0,0,0,0.5)">
52 <view class="custom-modal">
53 <view class="modal-title">提示</view>
54 <view class="modal-content">确定删除该考官吗?</view>
55 <view class="modal-btns">
56 <button class="btn-cancel" @click="closeDelPopup()">取消</button>
57 <button class="btn-confirm" @click="confirmDel()">确定</button>
58 </view>
59 </view>
60 </uni-popup>
61
62 <!-- 自定义省跆协指派提示弹窗 -->
63 <uni-popup ref="assignPopup" type="center" background-color="rgba(0,0,0,0.5)">
64 <view class="custom-modal">
65 <view class="modal-title">温馨提示</view>
66 <view class="modal-content">关于考官指派,请联系河北省跆协,联系电话:XXXX</view>
67 <view class="modal-btns">
68 <button class="btn-confirm single-btn" @click="closeAssignPopup()">我知道了</button>
69 </view>
70 </view>
71 </uni-popup>
72
73 <!-- 自定义提交成功弹窗 -->
74 <uni-popup ref="successPopup" type="center" background-color="rgba(0,0,0,0.5)">
75 <view class="custom-modal">
76 <view class="modal-title">成功</view>
77 <view class="modal-content">提交成功,请等待审核</view>
78 <view class="modal-btns">
79 <button class="btn-confirm single-btn" @click="confirmSuccess()">确定</button>
80 </view>
81 </view>
82 </uni-popup>
83 </view>
84 </template>
85
86 <script setup>
87 import { ref, } from 'vue'
88 import { onLoad,onShow } from '@dcloudio/uni-app'
89 import * as api from '@/common/api.js'
90
91 const form = ref({
92 selfSelect: '1' // 1:自行录入 0:省跆协指派
93 })
94 const showExamine = ref(true)
95 const loading = ref(false)
96 const list = ref([])
97 const memId = ref(null)
98
99 // 弹窗引用
100 const applyPopup = ref(null)
101 const delPopup = ref(null)
102 const assignPopup = ref(null)
103 const successPopup = ref(null)
104 let currentDelItem = ref(null)
105
106 onLoad((option) => {
107 memId.value = option.memId
108 getExaminer()
109 })
110
111 onShow(() => {
112 if (memId.value) {
113 getExaminer()
114 }
115 })
116
117 async function getExaminer() {
118 loading.value = true
119 const res = await api.listApi({ memId: memId.value })
120 list.value = res.rows
121 loading.value = false
122 }
123
124 // 删除考官:打开自定义弹窗
125 function handleDel(row) {
126 currentDelItem.value = row
127 delPopup.value.open()
128 }
129 // 确认删除
130 async function confirmDel() {
131 await api.examinerDel(currentDelItem.value.id)
132 uni.showToast({ title: '删除成功', icon: 'success' })
133 getExaminer()
134 closeDelPopup()
135 }
136 function closeDelPopup() {
137 delPopup.value.close()
138 }
139
140 // 切换考官类型:打开自定义提示弹窗
141 function onSelfSelectChange(e) {
142 form.value.selfSelect = e.detail.value
143 showExamine.value = e.detail.value == '1'
144 if (e.detail.value == '2') {
145 assignPopup.value.open()
146 }
147 }
148 function closeAssignPopup() {
149 assignPopup.value.close()
150 }
151
152 function handelAddExamine() {
153 const chosenStr = JSON.stringify(list.value)
154 uni.navigateTo({
155 url: `/myCenter/chooseExaminer?memId=${memId.value}&isValidity=0&chosen=${chosenStr}`
156 })
157 }
158
159 // 提交申请:打开自定义成功弹窗
160 async function handelSubmit() {
161 if (!form.value.selfSelect) {
162 return uni.showToast({ title: '请选择考官类型', icon: 'none' })
163 }
164 if (form.value.selfSelect == '1' && list.value.length == 0) {
165 return uni.showToast({ title: '请添加考官', icon: 'none' })
166 }
167
168 try {
169 await api.commitExamPointApply(form.value)
170 successPopup.value.open()
171 } catch (err) {
172 uni.showToast({ title: err.data.msg, icon: 'none' })
173 }
174 }
175 function confirmSuccess() {
176 successPopup.value.close()
177 uni.navigateBack()
178 }
179
180 // 考点申请弹窗(如需调用可在合适位置打开)
181 function openApplyPopup() {
182 applyPopup.value.open()
183 }
184 function closeApplyPopup() {
185 applyPopup.value.close()
186 }
187 function confirmApply() {
188 applyPopup.value.close()
189 // 此处添加考点申请逻辑
190 }
191 </script>
192
193 <style scoped>
194 /* 全局容器 */
195 .container {
196 min-height: 100vh;
197 }
198 .section{
199 padding:15rpx 20rpx;
200 }
201 /* 单选框区域 */
202 .radio-section {
203 background: #fff;
204 padding: 20rpx 15rpx;
205 margin-bottom: 10rpx;
206 border: none;
207 border-radius: 0;
208 }
209
210 .radio-group {
211 display: flex;
212 align-items: center;
213 gap: 30rpx;
214 }
215
216 .radio-item {
217 display: flex;
218 align-items: center;
219 margin: 0;
220 }
221
222 ::v-deep .custom-radio .wx-radio-input {
223 width: 30rpx;
224 height: 30rpx;
225 border-radius: 50%;
226 }
227
228 ::v-deep .custom-radio .wx-radio-input.wx-radio-input-checked {
229 border-color: #C4121B !important;
230 background: #C4121B !important;
231 }
232
233 .radio-text {
234 font-size: 14px;
235 color: #333;
236 margin-left: 8rpx;
237 }
238
239 /* 考官区域 */
240 .examiner-section {
241 background: #fff;
242 padding: 15rpx;
243 margin-bottom: 20rpx;
244 border: none;
245 border-radius: 0;
246 }
247
248 .add-btn {
249 background: #fff;
250 color: #C4121B;
251 border: 1rpx solid #C4121B;
252 border-radius: 10rpx;
253 padding: 10rpx 0;
254 width: 100%;
255 font-size: 14px;
256 }
257
258 .examiner-list {
259 padding: 0 10rpx;
260 background-color: #fff;
261 margin-bottom: 20rpx;
262 overflow-y: auto;
263 margin-bottom: 70px;
264 }
265
266 .examiner-item {
267 display: flex;
268 justify-content: space-between;
269 align-items: flex-start;
270 padding: 20rpx;
271 border-bottom: 1rpx solid #eee;
272 align-items: center;
273 }
274
275 .info {
276 flex: 1;
277 }
278
279 .name {
280 font-size: 14px;
281 font-weight: 500;
282 color: #333;
283 display: block;
284 margin-bottom: 5rpx;
285 }
286
287 .idc, .reg {
288 font-size: 12px;
289 color: #666;
290 display: block;
291 margin: 10rpx 0;
292 }
293
294 .del-btn {
295 color: #C4121B;
296 font-size: 12px;
297 border: 1rpx solid #C4121B;
298 border-radius: 50rpx;
299 padding: 10rpx 25rpx;
300 line-height: 1.2;
301 background: #fff;
302 }
303
304 /* 提交按钮 */
305 .submit-area {
306 padding: 20rpx 0;
307 background-color: #fff;
308 width: 100%;
309 position: fixed;
310 bottom: 0;
311 }
312
313 .submit-btn {
314 width: 80%;
315 height: 88rpx;
316 border-radius: 44rpx;
317 margin: 0 auto;
318 line-height: 88rpx;
319 background: #C4121B;
320 color: #fff;
321 text-align: center;
322 font-size: 16px;
323 border: none;
324 }
325
326 /* 自定义弹窗样式(核心) */
327 .custom-modal {
328 width: 600rpx;
329 background: #fff;
330 border-radius: 20rpx;
331 padding: 40rpx 30rpx;
332 box-sizing: border-box;
333 text-align: center;
334 }
335 .modal-title {
336 font-size: 36rpx;
337 font-weight: 600;
338 color: #333;
339 margin-bottom: 30rpx;
340 }
341 .modal-content {
342 font-size: 30rpx;
343 color: #666;
344 line-height: 1.6;
345 margin-bottom: 30rpx;
346 }
347 .modal-tip {
348 font-size: 28rpx;
349 color: #FF7A00;
350 margin-top: 20rpx;
351 }
352 .modal-btns {
353 display: flex;
354 justify-content: space-between;
355 gap: 20rpx;
356 }
357 .btn-cancel {
358 flex: 1;
359 height: 80rpx;
360 line-height: 80rpx;
361 background: #f5f5f5;
362 color: #999;
363 border-radius: 40rpx;
364 font-size: 32rpx;
365 border: none;
366 }
367 .btn-confirm {
368 flex: 1;
369 height: 80rpx;
370 line-height: 80rpx;
371 background: #C4121B;
372 color: #fff;
373 border-radius: 40rpx;
374 font-size: 32rpx;
375 border: none;
376 }
377 .single-btn {
378 flex: 1;
379 }
380 .btn-cancel::after, .btn-confirm::after {
381 border: none;
382 }
383 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <template>
2 <view class="container">
3 <!-- 主内容区域 -->
4 <view class="content">
5 <!-- 缴费年限 + 费用卡片 -->
6 <view class="card">
7 <!-- 缴费年限 -->
8 <view class="yearRow">
9 <view class="label">缴费年限</view>
10 <view class="control">
11 <image class="icon" @click="minusYear" src="/static/dd_02.png" mode="widthFix" v-if="form.renewYear > 1" ></image>
12 <image class="icon" src="/static/dd_02_g.png" mode="widthFix" v-else ></image>
13 <text class="num">{{ form.renewYear }}</text>
14 <image class="icon" src="/static/btn_03.png" mode="widthFix" @click="plusYear" v-if="form.renewYear < 5" ></image>
15 <image class="icon" src="/static/btn_03_g.png" mode="widthFix" v-else ></image>
16 </view>
17 </view>
18 </view>
19
20 <view class="card ">
21 <!-- 费用合计 -->
22 <view class="row ">
23 <text class="label">费用合计</text>
24 <text class="value red">{{ form.renewYear * memberFee }}</text>
25 </view>
26
27 <view class="hintRow" v-if="preferentialPolicy">
28 <text class="hintText">温馨提示:根据中国跆协{{ preferentialData.name || '优惠' }}政策减免一年费用,每个单位在政策有效期内只享受一次</text>
29 </view>
30 </view>
31
32 <view class="payRow ">
33 <radio-group @change="onPayTypeChange">
34 <label class="radioItem">
35 <radio value="1" :checked="payType === '1'" class="custom-radio" />
36 <view class="payInfo">
37 <image class="icon" src="/static/min.png" mode="widthFix"></image>
38 <text>民生付</text>
39 </view>
40 </label>
41 </radio-group>
42 </view>
43
44 <view class="totalRow ">
45 <text class="label">支付费用合计</text>
46 <text class="value redBig">{{ memberTotalFee }}</text>
47 </view>
48
49 </view>
50
51 <view class="bottomBtn">
52 <view class="deductRow">
53 <text class="label">减免费用</text>
54 <text class="value red">-{{ memberFee }}</text>
55 </view>
56 <button class="payBtn" @click="handelPay" :loading="isPaying">立即支付 ¥{{ memberTotalFee }}</button>
57 </view>
58
59 </view>
60 </template>
61
62 <script setup>
63 import { ref, computed } from 'vue'
64 import { onLoad } from '@dcloudio/uni-app';
65 import * as api from '@/common/api.js'
66
67 const form = ref({
68 renewYear: 1
69 })
70 const memberFee = ref(0)
71 const preferentialPolicy = ref(false)
72 const preferentialData = ref({ name: '优惠' })
73 const payType = ref('1')
74 const isPaying = ref(false)
75
76 const memberTotalFee = computed(() => {
77 if (preferentialPolicy.value) {
78 return memberFee.value * form.value.renewYear - memberFee.value * 1
79 } else {
80 return memberFee.value * form.value.renewYear
81 }
82 })
83
84 // 年限减
85 const minusYear = () => {
86 if (form.value.renewYear > 1) {
87 form.value.renewYear--
88 }
89 }
90 // 年限加
91 const plusYear = () => {
92 if (form.value.renewYear < 6) {
93 form.value.renewYear++
94 }
95 }
96
97 // 支付方式切换
98 const onPayTypeChange = (e) => {
99 payType.value = e.detail.value
100 }
101
102 // 支付操作
103 const handelPay = async () => {
104 // if (memberTotalFee.value <= 0) return
105
106 isPaying.value = true
107 const { data } = await api.certifiedNew({ renewYear: form.value.renewYear })
108 isPaying.value = false
109 if (data.payFlag == 0) {
110 uni.navigateTo({
111 url: `/myCenter/sucPay`
112 })
113 } else {
114 if (data.orderId) {
115 await callBack2(data.orderId)
116 uni.navigateTo({
117 url: `/myCenter/goPay`
118 })
119
120 }
121 }
122 }
123
124 onLoad((option) => {
125 // 接收年限
126 form.value.renewYear = Number(option.renewYear || 1)
127 // 初始化获取费用和优惠
128 init()
129 })
130
131 // 初始化接口
132 async function init() {
133 try {
134 await getMyMemberCertUnitFeeApi()
135 await canUseDiscountApi()
136 await getZtxDiscountPolicyApi()
137 } catch (err) {
138 console.error('初始化失败:', err)
139 }
140 }
141
142 // 获取会员单价
143 async function getMyMemberCertUnitFeeApi() {
144 const res = await api.getMyMemberCertUnitFee()
145 memberFee.value = Number(res.data || 1500)
146 }
147
148 // 是否可用优惠
149 async function canUseDiscountApi() {
150 const res = await api.canUseDiscount()
151 preferentialPolicy.value = res.data || true
152 }
153
154 // 获取优惠政策详情
155 async function getZtxDiscountPolicyApi() {
156 const res = await api.getZtxDiscountPolicy()
157 preferentialData.value = res.data || { name: '优惠' }
158 }
159 </script>
160
161 <style scoped>
162 /* 整体容器 */
163 .container {
164 min-height: 100vh;
165 background-color: #f7f7f7;
166 }
167
168 /* 内容区域 */
169 .content {
170 padding: 20rpx 20rpx 120rpx;
171 }
172
173 /* 卡片 */
174 .card {
175 background: #fff;
176 border-radius: 8rpx;
177 padding: 25rpx 20rpx;
178 margin-bottom: 20rpx;
179 }
180
181 /* 缴费年限行 */
182 .yearRow {
183 display: flex;
184 align-items: center;
185 justify-content: space-between;
186 margin-bottom: 20rpx;
187 }
188
189 .yearRow .label {
190 font-size: 28rpx;
191 color: #333;
192 }
193
194 .yearRow .control {
195 display: flex;
196 align-items: center;
197 }
198 .control image {
199 width: 50rpx;
200 height: 50rpx;
201 }
202
203 /* 加减按钮样式 */
204 .num-btn {
205 width: 40rpx;
206 height: 40rpx;
207 border-radius: 50%;
208 display: flex;
209 align-items: center;
210 justify-content: center;
211 background-color: #fff;
212 border: 1rpx solid #C4121B;
213 }
214
215 .num-btn.disabled {
216 border-color: #ccc;
217 }
218
219 .num-btn.disabled .btn-icon {
220 color: #ccc;
221 }
222
223 .btn-icon {
224 font-size: 24rpx;
225 color: #C4121B;
226 font-weight: bold;
227 }
228
229 .yearRow .num {
230 font-size: 28rpx;
231 color: #333;
232 min-width: 80rpx;
233 text-align: center;
234 margin: 0 10rpx;
235 }
236
237
238 /* 通用行 */
239 .row {
240 display: flex;
241 justify-content: space-between;
242 align-items: center;
243
244 }
245
246 .row .label {
247 font-size: 28rpx;
248 color: #333;
249 }
250
251 .row .value {
252 font-size: 30rpx;
253 color: #C4121B;
254 font-weight: 500;
255 }
256
257 /* 优惠提示 */
258 .hintRow {
259 display: flex;
260 align-items: flex-start;
261 font-size: 24rpx;
262 line-height: 1.4;
263 }
264
265 .hint-icon {
266 width: 24rpx;
267 height: 24rpx;
268 border-radius: 50%;
269 background-color: #C4121B;
270 display: flex;
271 align-items: center;
272 justify-content: center;
273 margin-right: 10rpx;
274 flex-shrink: 0;
275 margin-top: 2rpx;
276 }
277 .icon{
278 width:30px;
279 }
280
281 .icon-check {
282 color: #fff;
283 font-size: 16rpx;
284 }
285
286 .hintRow .hintText {
287 color: #FF8124;
288 flex: 1;
289 margin-top: 10rpx;
290 }
291
292 /* 减免费用 */
293 .deductRow {
294 background: #fff;
295 padding: 20rpx 20rpx;
296 display: flex;
297 justify-content: space-between;
298 align-items: center;
299 margin-bottom: 10rpx;
300 border-radius: 8rpx;
301 }
302
303 .deductRow .label {
304 font-size: 28rpx;
305 color: #333;
306 }
307
308 .deductRow .value {
309 font-size: 30rpx;
310 color: #C4121B;
311 }
312
313 /* 支付方式行 */
314 .payRow {
315 background: #fff;
316 border-radius: 8rpx;
317 padding: 20rpx 20rpx;
318 margin-bottom: 20rpx;
319 }
320
321 .radioItem {
322 display: flex;
323 align-items: center;
324 }
325
326 /* 自定义红色单选框 */
327 ::v-deep .custom-radio .wx-radio-input {
328 width: 30rpx;
329 height: 30rpx;
330 border-radius: 50%;
331 border: 2rpx solid #ccc;
332 }
333
334 ::v-deep .custom-radio .wx-radio-input.wx-radio-input-checked {
335 border-color: #C4121B !important;
336 background: #C4121B !important;
337 }
338
339
340 .payInfo {
341 display: flex;
342 align-items: center;
343 margin-left: 15rpx;
344 }
345
346 .payInfo .icon {
347 width: 40rpx;
348 height: 40rpx;
349 margin-right: 10rpx;
350 }
351
352 .payInfo text {
353 font-size: 28rpx;
354 color: #333;
355 }
356
357 /* 总费用行(突出显示) */
358 .totalRow {
359 background: #fff;
360 border-radius: 8rpx;
361 padding: 20rpx 20rpx;
362 display: flex;
363 justify-content: space-between;
364 align-items: center;
365 margin-top: 10rpx;
366 }
367
368 .totalRow .label {
369 font-size: 28rpx;
370 color: #333;
371 }
372
373 .redBig {
374 font-size: 32rpx;
375 color: #C4121B;
376 font-weight: bold;
377 }
378
379 /* 底部按钮 */
380 .bottomBtn {
381 position: fixed;
382 bottom: 0;
383 left: 0;
384 right: 0;
385 padding: 20rpx 20rpx;
386 background: #fff;
387 border-top: 1rpx solid #eee;
388 }
389
390 .payBtn {
391 width: 100%;
392 height: 88rpx;
393 line-height: 88rpx;
394 background-color: #C4121B;
395 color: #fff;
396 border-radius: 8rpx;
397 font-size: 32rpx;
398 text-align: center;
399 border: none;
400 }
401
402 .payBtn[disabled] {
403 background-color: #ccc;
404 color: #999;
405 }
406
407 /* 通用红色文字 */
408 .red {
409 color: #C4121B;
410 }
411 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <template>
2 <view class="pay-order-container">
3 <!-- 页面头部 -->
4 <view class="page-header">
5 <text class="title">确认并支付</text>
6 </view>
7
8 <!-- 订单核心信息 -->
9 <view class="order-info">
10 <view class="info-item">
11 <text class="label">人数合计:</text>
12 <text class="value red">{{ formData.all ?? 0 }}</text>
13 </view>
14 <view class="info-item">
15 <text class="label">新会员合计:</text>
16 <text class="value red">{{ formData.new ?? 0 }}</text>
17 </view>
18 <view class="info-item">
19 <text class="label">续费会员合计:</text>
20 <text class="value red">{{ formData.old ?? 0 }}</text>
21 </view>
22 <view class="info-item total-price">
23 <text class="label">支付总费用:</text>
24 <text class="value red">{{ formData.price ?? 0 }}</text>
25 </view>
26 </view>
27
28 <!-- 支付方式选择(修复v-model报错 + 默认勾选) -->
29 <view class="pay-type-section">
30 <text class="section-title">选择支付方式</text>
31 <!-- uni-app小程序原生radio-group写法 -->
32 <radio-group :value="payType" @change="handlePayTypeChange">
33 <label class="radio-item">
34 <!-- checked属性实现默认勾选 -->
35 <radio value="0" color="#E60012" :checked="payType === '0'" />
36 <view class="pay-method">
37 <image class="icon" src="/static/min.png" mode="widthFix"></image>
38 <text class="pay-name">民生付</text>
39 </view>
40 </label>
41 </radio-group>
42 </view>
43
44 <!-- 底部支付按钮 -->
45 <view class="fixed-bottom">
46 <button class="pay-btn red-bg" :loading="payLoading" @click="handlePay">立即支付</button>
47 </view>
48 </view>
49 </template>
50
51 <script setup>
52 import { ref } from 'vue'
53 import { onLoad } from '@dcloudio/uni-app';
54 import * as api from '@/common/api.js'
55
56 // 核心数据
57 const formData = ref({}) // 订单统计数据
58 const rangeId = ref('') // 核心业务ID
59 const payType = ref('0') // 支付方式(默认0=民生付)
60 const payLoading = ref(false) // 支付按钮加载状态
61
62 // 页面加载接收参数
63 onLoad(async (options) => {
64 console.log('订单ID:', options.rangeId)
65 if (options.rangeId) {
66 rangeId.value = options.rangeId
67 await getCount()
68 }
69 })
70
71 async function getCount() {
72 try {
73 const res = await api.getNewCountByRangeId(rangeId.value)
74 formData.value = res.data || { all: 0, new: 0, old: 0 }
75 } catch (e) {
76 formData.value = { all: 0, new: 0, old: 0 }
77 }
78 }
79
80 // 支付方式切换
81 function handlePayTypeChange(e) {
82 payType.value = e.detail.value
83 }
84
85 // 立即支付核心逻辑
86 async function handlePay() {
87 // 基础校验
88 if (!rangeId.value || rangeId.value === '-1') {
89 return uni.showToast({ title: '订单ID异常', icon: 'none' })
90 }
91
92 try {
93 payLoading.value = true
94 const res = await api.goPay(rangeId.value)
95
96 // 订单ID存在则调用回调接口
97 if (res.data?.orderId) {
98 await api.callBack2(res.data.orderId)
99 }
100
101 // 跳转到支付成功页
102 uni.navigateTo({
103 url: `/pages/payOk/payOk?rangeId=${rangeId.value}`
104 })
105 } catch (err) {
106 console.error('支付失败:', err)
107 uni.showToast({ title: err.data.msg, icon: 'none' })
108 } finally {
109 payLoading.value = false
110 }
111 }
112 </script>
113
114 <style scoped lang="scss">
115 .pay-order-container {
116 padding: 30rpx;
117 background-color: #fff;
118 min-height: 100vh;
119 box-sizing: border-box;
120 }
121 .icon{
122 width:30px;
123 }
124 // 页面头部
125 .page-header {
126 text-align: center;
127 padding: 20rpx 0;
128 border-bottom: 1px solid #eee;
129 margin-bottom: 40rpx;
130
131 .title {
132 font-size: 36rpx;
133 font-weight: 600;
134 color: #333;
135 }
136 }
137
138 // 订单信息区域
139 .order-info {
140 margin-bottom: 60rpx;
141
142 .info-item {
143 display: flex;
144 justify-content: space-between;
145 align-items: center;
146 padding: 25rpx 0;
147 border-bottom: 1px solid #f5f5f5;
148 font-size: 32rpx;
149
150 .label {
151 color: #666;
152 }
153
154 .value {
155 font-weight: 600;
156 font-size: 34rpx;
157 }
158
159 .red {
160 color: #E60012;
161 }
162 }
163
164 .total-price {
165 border-bottom: none;
166 margin-top: 10rpx;
167
168 .label {
169 font-size: 34rpx;
170 color: #333;
171 }
172
173 .value {
174 font-size: 38rpx;
175 }
176 }
177 }
178
179 // 支付方式区域
180 .pay-type-section {
181 margin-bottom: 80rpx;
182
183 .section-title {
184 font-size: 32rpx;
185 color: #333;
186 margin-bottom: 20rpx;
187 display: block;
188 }
189
190 .radio-item {
191 display: flex;
192 align-items: center;
193 font-size: 32rpx;
194 padding: 10rpx 0;
195
196 .pay-method {
197 display: flex;
198 align-items: center;
199 margin-left: 10rpx;
200
201 .pay-name {
202 font-size: 32rpx;
203 margin-left: 20rpx;
204 color: #333;
205 }
206 }
207 }
208 }
209
210 // 底部支付按钮
211 .fixed-bottom {
212 position: fixed;
213 bottom: 0;
214 left: 0;
215 right: 0;
216 padding: 20rpx 30rpx 30rpx;
217 background-color: #fff;
218 border-top: 1px solid #eee;
219
220 .pay-btn {
221 width: 100%;
222 height: 88rpx;
223 line-height: 88rpx;
224 border-radius: 44rpx;
225 font-size: 34rpx;
226 font-weight: 600;
227 }
228
229 .red-bg {
230 background-color: #E60012;
231 color: #fff;
232 }
233 }
234 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <template>
2 <view class="success-container">
3 <!-- 成功图标(渐变圆形+动效) -->
4 <view class="success-icon">
5 <view class="icon-circle">
6 <text class="check-icon"></text>
7 </view>
8 </view>
9
10 <!-- 支付成功标题(动画) -->
11 <view class="success-title">支付成功</view>
12 <view class="success-subtitle">支付成功,请等待审核</view>
13
14 <!-- 订单信息卡片(带阴影) -->
15 <view class="info-card">
16 <view class="info-item">
17 <text class="label">付款账户</text>
18 <text class="value">(5437)</text>
19 </view>
20 <view class="info-item">
21 <text class="label">交易流水号</text>
22 <text class="value">2205051351076117833</text>
23 </view>
24 <view class="info-item">
25 <text class="label">商户名称</text>
26 <text class="value">中国跆拳道协会</text>
27 </view>
28 <view class="info-item">
29 <text class="label">订单金额</text>
30 <text class="value amount">1500.00元</text>
31 </view>
32 <view class="info-item">
33 <text class="label">会员编号</text>
34 <text class="value">CTA00004</text>
35 </view>
36 <view class="info-item">
37 <text class="label">会员有效期</text>
38 <text class="value">2028年1月25日</text>
39 </view>
40 </view>
41
42 <!-- 确定按钮(渐变+动效) -->
43 <view class="confirm-btn-area">
44 <button class="confirm-btn" @click="handleConfirm">确定</button>
45 </view>
46 </view>
47 </template>
48
49 <script setup>
50 import { onLoad } from '@dcloudio/uni-app'
51
52 // 确定按钮点击事件
53 const handleConfirm = () => {
54 uni.navigateBack({ delta: 1 })
55 // 也可跳转首页:uni.redirectTo({ url: '/pages/index/index' })
56 }
57
58 onLoad((option) => {
59 // 可接收订单参数动态渲染,示例:
60 // if (option.amount) { /* 赋值给金额变量 */ }
61 })
62 </script>
63
64 <style scoped>
65 /* 全局容器 */
66 .success-container {
67 display: flex;
68 flex-direction: column;
69 align-items: center;
70 padding: 100rpx 40rpx 60rpx;
71 min-height: 100vh;
72 background-color: #f8f9fa;
73 box-sizing: border-box;
74 }
75
76 /* 成功图标容器 */
77 .success-icon {
78 margin-bottom: 40rpx;
79 animation: fadeIn 0.6s ease-out;
80 }
81
82 /* 渐变圆形背景 */
83 .icon-circle {
84 width: 180rpx;
85 height: 180rpx;
86 border-radius: 50%;
87 /* 青绿色渐变 */
88 background: linear-gradient(135deg, #06c1ae, #04a896);
89 display: flex;
90 align-items: center;
91 justify-content: center;
92 box-shadow: 0 8rpx 30rpx rgba(6, 193, 174, 0.3);
93 /* 轻微上浮动效 */
94 animation: scaleIn 0.8s ease-out;
95 }
96
97 /* 对勾图标 */
98 .check-icon {
99 font-size: 90rpx;
100 color: #ffffff;
101 font-weight: bold;
102 }
103
104 /* 支付成功标题 */
105 .success-title {
106 font-size: 48rpx;
107 font-weight: 700;
108 color: #333333;
109 margin-bottom: 12rpx;
110 animation: slideUp 0.6s ease-out;
111 }
112
113 /* 副标题 */
114 .success-subtitle {
115 font-size: 28rpx;
116 color: #666666;
117 margin-bottom: 60rpx;
118 animation: slideUp 0.8s ease-out;
119 }
120
121 /* 订单信息卡片 */
122 .info-card {
123 width: 100%;
124 background: #ffffff;
125 border-radius: 20rpx;
126 padding: 40rpx 30rpx;
127 box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.05);
128 margin-bottom: 80rpx;
129 animation: fadeIn 1s ease-out;
130 }
131
132 /* 单个信息项 */
133 .info-item {
134 display: flex;
135 justify-content: space-between;
136 align-items: center;
137 padding: 24rpx 0;
138 border-bottom: 1rpx solid #f5f5f5;
139 }
140 /* 最后一项去掉下划线 */
141 .info-item:last-child {
142 border-bottom: none;
143 }
144
145 /* 标签样式 */
146 .label {
147 font-size: 32rpx;
148 color: #666666;
149 }
150
151 /* 值样式 */
152 .value {
153 font-size: 32rpx;
154 color: #333333;
155 text-align: right;
156 }
157 /* 金额特殊样式 */
158 .amount {
159 color: #cd1e27;
160 font-weight: 600;
161 }
162
163 /* 确定按钮区域 */
164 .confirm-btn-area {
165 width: 100%;
166 padding: 0 20rpx;
167 box-sizing: border-box;
168 }
169
170 /* 确定按钮(渐变+动效) */
171 .confirm-btn {
172 width: 100%;
173 height: 90rpx;
174 line-height: 90rpx;
175 /* 按钮渐变背景 */
176 background: #fff;
177 color: #C4121B;
178 font-size: 36rpx;
179 font-weight: 600;
180 border-radius: 45rpx;
181 border: 1px solid #C4121B;
182 animation: slideUp 1s ease-out;
183 /* 禁止默认样式 */
184 position: relative;
185 overflow: hidden;
186 }
187 /* 按钮点击反馈 */
188 .confirm-btn::after {
189 border: none;
190 }
191 .confirm-btn:active {
192 transform: scale(0.98);
193 box-shadow: 0 4rpx 10rpx rgba(6, 193, 174, 0.2);
194 }
195
196 /* 动画定义 */
197 @keyframes fadeIn {
198 0% { opacity: 0; }
199 100% { opacity: 1; }
200 }
201 @keyframes scaleIn {
202 0% { transform: scale(0); }
203 70% { transform: scale(1.1); }
204 100% { transform: scale(1); }
205 }
206 @keyframes slideUp {
207 0% { opacity: 0; transform: translateY(30rpx); }
208 100% { opacity: 1; transform: translateY(0); }
209 }
210 </style>
...\ No newline at end of file ...\ No newline at end of file
...@@ -675,6 +675,46 @@ ...@@ -675,6 +675,46 @@
675 "navigationBarTitleText" : "团体会员缴费", 675 "navigationBarTitleText" : "团体会员缴费",
676 "enablePullDownRefresh" : false 676 "enablePullDownRefresh" : false
677 } 677 }
678 },
679 {
680 "path" : "goPay",
681 "style" :
682 {
683 "navigationBarTitleText" : "付款详情",
684 "enablePullDownRefresh" : false
685 }
686 },
687 {
688 "path" : "examPointApply",
689 "style" :
690 {
691 "navigationBarTitleText" : "申请考点",
692 "enablePullDownRefresh" : false
693 }
694 },
695 {
696 "path" : "chooseExaminer",
697 "style" :
698 {
699 "navigationBarTitleText" : "选择考官",
700 "enablePullDownRefresh" : false
701 }
702 },
703 {
704 "path" : "sucPay",
705 "style" :
706 {
707 "navigationBarTitleText" : "支付成功",
708 "enablePullDownRefresh" : false
709 }
710 },
711 {
712 "path" : "payOrder",
713 "style" :
714 {
715 "navigationBarTitleText" : "支付详情",
716 "enablePullDownRefresh" : false
717 }
678 } 718 }
679 ] 719 ]
680 }], 720 }],
......
...@@ -557,13 +557,48 @@ ...@@ -557,13 +557,48 @@
557 } 557 }
558 </script> 558 </script>
559 559
560 <style lang="scss" scoped> 560 <style lang="scss">
561
562 /* 字段名左对齐 */
563 .uni-forms-item .uni-forms-item__label {
564 text-align: left !important;
565 justify-content: flex-start !important;
566 padding-left: 0 !important;
567 width: auto !important;
568 }
569
570 /* 内容右对齐 */
571 .uni-forms-item .uni-forms-item__content {
572 display: flex !important;
573 align-items: center !important;
574 justify-content: flex-end !important;
575 text-align: right !important;
576 }
577
578 /* 输入框内容右对齐 */
579 .uni-forms-item .uni-easyinput .uni-easyinput__content-input,
580 .uni-forms-item .uni-easyinput input,
581 .uni-forms-item input,
582 .uni-forms-item .uni-data-select .uni-select__input-box,
583 .uni-forms-item .uni-data-picker .uni-data-picker__input-box {
584 text-align: right !important;
585 }
586
587 /* 文本内容右对齐 */
588 .uni-forms-item .uni-forms-item__content text,
589 .uni-forms-item .uni-forms-item__content > text {
590 text-align: right !important;
591 width: 100%;
592 display: block;
593 }
594
595 /* 覆盖原有样式 */
561 :deep(.uni-forms-item__content) { 596 :deep(.uni-forms-item__content) {
562 display: flex; 597 justify-content: flex-end !important;
563 align-items: center;
564 justify-content: flex-end;
565 } 598 }
599 </style>
566 600
601 <style lang="scss" scoped>
567 :deep(.segmented-control) { 602 :deep(.segmented-control) {
568 height: 100rpx; 603 height: 100rpx;
569 } 604 }
......
...@@ -5,25 +5,23 @@ ...@@ -5,25 +5,23 @@
5 <view class="info"> 5 <view class="info">
6 <view><text>{{list.length}}</text></view> 6 <view><text>{{list.length}}</text></view>
7 </view> 7 </view>
8 <!-- 成员 -->
9 <view class="userlist"> 8 <view class="userlist">
10 <view class="item" v-for="(n,index) in list" :key="index"> 9 <view class="item" v-for="(n,index) in list" :key="index">
11 <view> 10 <view>
12 <view class="name">{{n.personName}}<text>({{n.memberInfoName}})</text></view> 11 <view class="name">{{n.perName}}<text v-if="n.memberInfoName">({{n.memberInfoName || ''}})</text></view>
13 <view class="date">原有效期至 {{n.originValidityDate?.slice(0,10)||'--'}}</view> 12 <view class="date">原有效期至 {{n.originValidityDate ? n.originValidityDate.slice(0,10) : '--'}}</view>
14 </view> 13 </view>
15 <view class="nian"> 14 <view class="nian">
16 {{n.payYear}} 15 {{n.payYear}}
17 </view> 16 </view>
18 </view> 17 </view>
19 </view> 18 </view>
20
21 </view> 19 </view>
22 20
23 <view class="h3-padding" v-if="feelList.length>0">审核流程</view> 21 <view class="h3-padding" v-if="feelList.length>0">审核流程</view>
24 <view class="wBox" v-if="feelList.length>0"> 22 <view class="wBox" v-if="feelList.length>0">
25 <view class="stepItem" v-for="(n,index) in feelList" :key="index"> 23 <view class="stepItem" v-for="(n,index) in feelList" :key="index">
26 <view class="time">{{n.auditTime||'待审批'}}</view> 24 <view class="time">{{n.auditTime || '待审批'}}</view>
27 <view class="content"> 25 <view class="content">
28 <view class="status"> 26 <view class="status">
29 <text v-if="n.auditResult==0" class="text-primary"> 审核中</text> 27 <text v-if="n.auditResult==0" class="text-primary"> 审核中</text>
...@@ -32,10 +30,8 @@ ...@@ -32,10 +30,8 @@
32 <text v-if="n.auditResult==3" class="text-warning"> 已撤回</text> 30 <text v-if="n.auditResult==3" class="text-warning"> 已撤回</text>
33 </view> 31 </view>
34 <view class="name">{{index+1}}</view> 32 <view class="name">{{index+1}}</view>
35 <view class="deptName">{{n.auditDeptName||n.auditBy}}</view> 33 <view class="deptName">{{n.auditDeptName || n.auditBy}}</view>
36 <view> 34 <view>备注:{{n.auditMsg || '/' }}</view>
37 备注:{{n.auditMsg||'/' }}
38 </view>
39 </view> 35 </view>
40 </view> 36 </view>
41 </view> 37 </view>
...@@ -44,47 +40,48 @@ ...@@ -44,47 +40,48 @@
44 40
45 <script setup> 41 <script setup>
46 import * as api from '@/common/api.js' 42 import * as api from '@/common/api.js'
47 import config from '@/config.js' 43 import { ref } from 'vue'
48 import { 44 import { onLoad } from '@dcloudio/uni-app'
49 onMounted, 45
50 ref 46 // 查询参数(和PC保持一致)
51 } from 'vue'
52 import {
53 onLoad
54 } from '@dcloudio/uni-app'
55 const queryParams = ref({ 47 const queryParams = ref({
56 // pageNum: 1, 48 rangeId: '',
57 // pageSize: 10 49 pageNum: 1,
50 pageSize: 999
58 }) 51 })
59 const wfCode = ref('') 52
60 const form = ref([]) 53 const form = ref({})
61 const list = ref([]) 54 const list = ref([])
62 const feelList = ref([]) 55 const feelList = ref([])
63 const total = ref(0) 56
64 onLoad((option) => { 57 onLoad((option) => {
65 if ('form' in option) { 58 if (option.form) {
66 form.value = JSON.parse(decodeURIComponent(option.form)) 59 form.value = JSON.parse(decodeURIComponent(option.form))
60 queryParams.value.rangeId = form.value.rangId || form.value.rangeId
61
62 getList()
63 getAuditLogs()
67 } 64 }
68 getFillList(form.value.rangId)
69 getPersons()
70 }) 65 })
71 66
72 function getPersons() { 67 async function getList() {
73 queryParams.value.rangeId = form.value.rangId 68 try {
74 api.addSelectPageList(queryParams.value).then(res => { 69 const res = await api.listAPI(queryParams.value)
75 list.value = res.pageData.rows 70 list.value = res.rows || []
76 for (var l of list.value) { 71 } catch (e) {
77 if (l.photo && l.photo.indexOf('http') == -1) { 72 list.value = []
78 l.photo = config.baseUrl_api + l.photo 73 console.error('获取成员失败', e)
79 } 74 }
80 } 75 }
81 })
82 }
83 76
84 function getFillList(id) { 77 function getAuditLogs() {
85 api.fillAuditLog(id).then(res => { 78 if (form.value.auditLogs) {
86 feelList.value = res.data 79 try {
87 }) 80 feelList.value = JSON.parse(form.value.auditLogs)
81 } catch (e) {
82 feelList.value = []
83 }
84 }
88 } 85 }
89 </script> 86 </script>
90 87
...@@ -107,12 +104,16 @@ ...@@ -107,12 +104,16 @@
107 .item { 104 .item {
108 border-bottom: 1px dashed #e5e5e5; 105 border-bottom: 1px dashed #e5e5e5;
109 position: relative; 106 position: relative;
107 padding: 20rpx 0;
110 108
111 .date { 109 .date {
112 margin-top: 10rpx; 110 margin-top: 10rpx;
111 font-size: 24rpx;
112 color: #999;
113 } 113 }
114 114
115 .name { 115 .name {
116 font-size: 30rpx;
116 text { 117 text {
117 margin-left: 1em; 118 margin-left: 1em;
118 color: #4C5359; 119 color: #4C5359;
...@@ -123,6 +124,7 @@ ...@@ -123,6 +124,7 @@
123 .nian { 124 .nian {
124 position: absolute; 125 position: absolute;
125 right: 0; 126 right: 0;
127 top: 30rpx;
126 font-size: 30rpx; 128 font-size: 30rpx;
127 color: #AD181F; 129 color: #AD181F;
128 } 130 }
...@@ -137,10 +139,56 @@ ...@@ -137,10 +139,56 @@
137 view { 139 view {
138 color: #7D8592; 140 color: #7D8592;
139 margin-right: 20rpx; 141 margin-right: 20rpx;
140
141 text { 142 text {
142 color: #AD181F; 143 color: #AD181F;
143 } 144 }
144 } 145 }
145 } 146 }
147
148 .h3-padding {
149 padding: 20rpx 30rpx 0;
150 font-size: 30rpx;
151 font-weight: 500;
152 }
153
154 .stepItem {
155 border-left: 2rpx solid #E60012;
156 padding-left: 20rpx;
157 position: relative;
158 margin-bottom: 30rpx;
159
160 &:before {
161 content: '';
162 width: 12rpx;
163 height: 12rpx;
164 background: #E60012;
165 border-radius: 50%;
166 position: absolute;
167 left: -7rpx;
168 top: 0;
169 }
170
171 .time {
172 font-size: 24rpx;
173 color: #999;
174 }
175
176 .content {
177 margin-top: 10rpx;
178 font-size: 28rpx;
179
180 .status {
181 margin-bottom: 8rpx;
182 }
183
184 .name {
185 font-weight: 500;
186 }
187
188 .deptName {
189 margin: 6rpx 0;
190 color: #666;
191 }
192 }
193 }
146 </style> 194 </style>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,25 +2,25 @@ ...@@ -2,25 +2,25 @@
2 <view class="hasfixedbottom"> 2 <view class="hasfixedbottom">
3 <view class="searchbar"> 3 <view class="searchbar">
4 <uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search" 4 <uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search"
5 v-model="queryParams.personName" placeholder="搜索姓名或证件号码" @blur="getList" @clear="getList"> 5 v-model="queryParams.perName" placeholder="搜索姓名或证件号码" @blur="getList" @clear="getList">
6 </uni-easyinput> 6 </uni-easyinput>
7 <view class="invertedbtn-red" @click="goVipList">+ 添加会员</view> 7 <view class="invertedbtn-red" @click="goVipList">+ 添加会员</view>
8 </view> 8 </view>
9 <view style="padding:0 20rpx">
9 10
10 <view class="vipData mtb30"> 11 <view class="vipData mtb30">
11 <view> 人数合计:<text>{{ formData.personCount? formData.personCount:0 }}</text></view> 12 <view> 人数合计:<text>{{ countData.all? countData.all:0 }}</text></view>
12 <view> 新会员合计:<text>{{ formData.newPersonCount? formData.newPersonCount:0 }}</text></view> 13 <view> 新会员合计:<text>{{ countData.new? countData.new:0 }}</text></view>
13 <view> 续费会员合计:<text>{{ formData.oldPersonCount? formData.oldPersonCount:0 }}</text></view> 14 <view> 续费会员合计:<text>{{ countData.old? countData.old:0 }}</text></view>
14 </view> 15 </view>
15 16
16 <uni-swipe-action> 17 <uni-swipe-action>
17 <uni-swipe-action-item class="personitem" v-for="(n,index) in list" :key="index"> 18 <uni-swipe-action-item class="personitem" v-for="(n,index) in list" :key="index">
18 <view class="content-box"> 19 <view class="content-box">
19 <view class="flexbox"> 20 <view class="flexbox">
20 <!-- <view class="colorful">{{n.personName?.slice(0,1)}}</view> --> 21 <view>{{n.perName}}
21 <view>{{n.personName}}
22 <view class="date"> 22 <view class="date">
23 证件号:{{n.personIdcCode}} 23 证件号:{{n.perIdcCode}}
24 </view> 24 </view>
25 </view> 25 </view>
26 </view> 26 </view>
...@@ -40,14 +40,14 @@ ...@@ -40,14 +40,14 @@
40 </template> 40 </template>
41 </uni-swipe-action-item> 41 </uni-swipe-action-item>
42 </uni-swipe-action> 42 </uni-swipe-action>
43 43 </view>
44 <view class="nodata" v-if="list.length==0"> 44 <view class="nodata" v-if="list.length==0">
45 <image mode="aspectFit" src="/static/nodata.png"></image> 45 <image mode="aspectFit" src="/static/nodata.png"></image>
46 <text>请添加会员</text> 46 <text>请添加会员</text>
47 </view> 47 </view>
48 48
49 <view class="fixedBottom"> 49 <view class="fixedBottom">
50 <button class="btn-red" :disabled="list?.length <= 0" @click="commitFN">保存并提交</button> 50 <button class="btn-red" :disabled="list?.length <= 0" @click="commitFN">保存并缴费</button>
51 </view> 51 </view>
52 52
53 <uni-popup ref="pickView" type="bottom"> 53 <uni-popup ref="pickView" type="bottom">
...@@ -62,21 +62,17 @@ ...@@ -62,21 +62,17 @@
62 </template> 62 </template>
63 63
64 <script setup> 64 <script setup>
65 import { 65 import { ref } from 'vue'
66 ref 66 import { onShow, onLoad } from '@dcloudio/uni-app'
67 } from 'vue'
68 import {
69 onShow,
70 onLoad
71 } from '@dcloudio/uni-app'
72 import * as api from '@/common/api.js' 67 import * as api from '@/common/api.js'
73 import config from '@/config.js'
74 const app = getApp() 68 const app = getApp()
75 const queryParams = ref({ 69 const queryParams = ref({
76 rangeId: -1 70 rangeId: '',
71 pageNum: 1,
72 pageSize: 10,
77 }) 73 })
78 const formData = ref({}) 74 const countData = ref({})
79 const list = ref({}) 75 const list = ref([])
80 const total = ref(0) 76 const total = ref(0)
81 const nowYear = ref(1) 77 const nowYear = ref(1)
82 const nowItem = ref({}) 78 const nowItem = ref({})
...@@ -98,11 +94,13 @@ ...@@ -98,11 +94,13 @@
98 text: '五年', 94 text: '五年',
99 value: 5 95 value: 5
100 }]) 96 }])
97
101 onLoad((option) => { 98 onLoad((option) => {
102 if (option.rangeId) { 99 if (option.rangeId) {
103 queryParams.value.rangeId = option.rangeId 100 queryParams.value.rangeId = option.rangeId
104 } 101 }
105 }) 102 })
103
106 onShow(() => { 104 onShow(() => {
107 if (app.globalData.isLogin) { 105 if (app.globalData.isLogin) {
108 init() 106 init()
...@@ -114,70 +112,88 @@ ...@@ -114,70 +112,88 @@
114 }) 112 })
115 113
116 function init() { 114 function init() {
115 console.log('init',queryParams.value.rangeId )
117 getList() 116 getList()
117 getCount()
118 } 118 }
119 119
120 function getList() { 120 // 获取列表 + 统计(修复版)
121 api.addSelectPageList(queryParams.value).then(res => { 121 async function getList() {
122 list.value = res.pageData.rows 122 try {
123 total.value = res.pageData.total 123 const res = await api.listAPI(queryParams.value)
124 formData.value = res 124 list.value = res.rows || []
125 }) 125 total.value = res.total || 0
126 } catch (e) {
127 list.value = []
128 total.value = 0
129 }
130
131 // 只有 rangeId 合法时才获取统计(修复关键)
132 // if (queryParams.value.rangeId && queryParams.value.rangeId > 0) {
133 // await getCount()
134 // } else {
135 // // 清空统计
136 // countData.value = { all: 0, new: 0, old: 0 }
137 // }
138 }
139
140 // 获取统计
141 async function getCount() {
142 try {
143 const res = await api.getNewCountByRangeId(queryParams.value.rangeId)
144 countData.value = res.data || { all: 0, new: 0, old: 0 }
145 } catch (e) {
146 countData.value = { all: 0, new: 0, old: 0 }
147 }
126 } 148 }
127 149
128 function goVipList() { 150 function goVipList() {
129 let path = `/personalVip/vipList?rangeId=${queryParams.value.rangeId}` 151 let path = `/personalVip/vipList?rangeId=${queryParams.value.rangeId}`
130 uni.redirectTo({ 152 uni.navigateTo({ url: path });
131 url: path
132 });
133 } 153 }
134 154
135 function changeYear(e) { 155 function changeYear(e) {
136 nowItem.value = e 156 nowItem.value = e
137 nowYear.value = e.payYear 157 nowYear.value = e.payYear
138 pickView.value.open() 158 pickView.value.open()
139
140 } 159 }
141 160
142 function bindyear(n) { 161 // 修改年限
162 async function bindyear(n) {
143 nowYear.value = n.value 163 nowYear.value = n.value
144 pickView.value.close() 164 pickView.value.close()
145 nowItem.value.payYear = n.value 165 nowItem.value.payYear = n.value
146 api.editYear(nowItem.value.payId, nowItem.value.payYear).then(res => { 166
147 for (var nn of list.value) { 167 await api.editYear({
148 if (nn.perId == nowItem.value.perId) { 168 payId: nowItem.value.payId,
149 nn.payYear = nowItem.value.payYear 169 year: nowItem.value.payYear
150 }
151 }
152 }) 170 })
171
172 // 刷新列表和统计
173 await getList()
174 uni.showToast({ title: '操作成功' })
153 } 175 }
154 176
155 function handleDelete(row) { 177 // 删除(修复关键逻辑)
178 async function handleDelete(row) {
156 uni.showModal({ 179 uni.showModal({
157 title: '提示', 180 title: '提示',
158 content: `确定删除${row.personName}吗`, 181 content: `确定删除${row.perName}吗`,
159 success: function(res) { 182 success: async function(res) {
160 if (res.confirm) { 183 if (res.confirm) {
161 api.delPayment([row.payId]).then(res => { 184 await api.paymentNewDel(row.payId)
162 uni.showToast({ 185 uni.showToast({ title: '删除成功' })
163 title: '删除成功'
164 })
165 if (list.value.length == 1) {
166 queryParams.value.rangeId = -1
167 }
168 getList() 186 getList()
169 })
170 } 187 }
171 } 188 }
172 }) 189 })
173 } 190 }
174 function commitFN(){ 191
175 if (queryParams.value.rangeId == -1) return 192 // 保存缴费
176 api.commitRenew(queryParams.value.rangeId).then(res=>{ 193 async function commitFN(){
177 uni.showToast({ 194 if (!queryParams.value.rangeId) return
178 title: '提交成功' 195 uni.navigateTo({
179 }) 196 url: `/myCenter/payOrder?rangeId=${queryParams.value.rangeId}`
180 uni.navigateBack()
181 }) 197 })
182 } 198 }
183 </script> 199 </script>
...@@ -186,10 +202,7 @@ ...@@ -186,10 +202,7 @@
186 .pickViewBox { 202 .pickViewBox {
187 background-color: #fff; 203 background-color: #fff;
188 text-align: center; 204 text-align: center;
189 205 view { line-height: 3; }
190 view {
191 line-height: 3;
192 }
193 } 206 }
194 207
195 .searchbar { 208 .searchbar {
...@@ -201,7 +214,7 @@ ...@@ -201,7 +214,7 @@
201 .invertedbtn-red { 214 .invertedbtn-red {
202 margin-left: 15rpx; 215 margin-left: 15rpx;
203 font-size: 30rpx; 216 font-size: 30rpx;
204 padding: 16rpx 20rpx; 217 padding: 10rpx 20rpx;
205 box-sizing: border-box; 218 box-sizing: border-box;
206 border-radius: 50rpx; 219 border-radius: 50rpx;
207 background-color: #fff; 220 background-color: #fff;
...@@ -238,47 +251,53 @@ ...@@ -238,47 +251,53 @@
238 margin-bottom: 30rpx; 251 margin-bottom: 30rpx;
239 252
240 .content-box { 253 .content-box {
241 display: flex;background-color: #fff; 254 display: flex;
255 background-color: #fff;
242 align-items: center; 256 align-items: center;
243 padding: 16rpx; 257 padding: 16rpx;
244 border-radius: 15rpx; 258 border-radius: 15rpx;
245 justify-content: space-between; 259 justify-content: space-between;
246 260 margin-bottom: 20rpx;
247 .noborder {
248 border: none;
249
250 :deep(.uni-select) {
251 border: none;
252 text-align: right;
253 }
254 }
255 } 261 }
256 262
257 .flexbox { 263 .flexbox {
258 align-items: center; 264 align-items: center;
259 } 265 }
260
261 &:nth-child(3n) .colorful {
262 background: #014A9F;
263 } 266 }
264 267
265 &:nth-child(3n+1) .colorful { 268 .vipData {
266 background: #AD181F; 269 padding: 10rpx 20rpx;
270 font-size: 28rpx;
271 color: #666;
272 view { margin-bottom: 10rpx; }
273 text { color: #AD181F; font-weight: bold; }
267 } 274 }
268 275
269 &:nth-child(3n+2) .colorful { 276 .nodata {
270 background: #D3B267; 277 text-align: center;
278 padding: 100rpx 0;
279 image { width: 200rpx; height: 200rpx; margin-bottom: 20rpx; }
280 text { font-size: 28rpx; color: #999; }
271 } 281 }
282
283 .fixedBottom {
284 position: fixed;
285 bottom: 0;
286 left: 0;
287 right: 0;
288 padding: 20rpx;
289 background: #fff;
290 border-top: 1rpx solid #eee;
272 } 291 }
273 292
274 .colorful { 293 .btn-red {
275 width: 100rpx; 294 width: 100%;
276 margin-right: 14rpx; 295 height: 80rpx;
277 height: 100rpx; 296 line-height: 80rpx;
278 line-height: 100rpx; 297 background: #E60012;
279 font-size: 44rpx;
280 color: #fff; 298 color: #fff;
281 text-align: center; 299 border-radius: 40rpx;
282 border-radius: 50%; 300 font-size: 32rpx;
301 border: none;
283 } 302 }
284 </style> 303 </style>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
7 </view> 7 </view>
8 <view class="indexboxre"> 8 <view class="indexboxre">
9 <view class="tt">会员列表<text class="text-danger">(列表只显示不在缴费中的个人会员)</text></view> 9 <view class="tt">会员列表<text class="text-danger">(列表只显示不在缴费中的个人会员)</text></view>
10 <!-- <uni-indexed-list :options="list" :showSelect="true" @click="bindClick"></uni-indexed-list> -->
11 <view class="userlist"> 10 <view class="userlist">
12 <view class="item" v-for="(n,index) in list" :key="index"> 11 <view class="item" v-for="(n,index) in list" :key="index">
13 <view @click="checkThis(n)"> 12 <view @click="checkThis(n)">
...@@ -46,19 +45,15 @@ ...@@ -46,19 +45,15 @@
46 <text>暂无数据</text> 45 <text>暂无数据</text>
47 </view> 46 </view>
48 </view> 47 </view>
49
50 </view> 48 </view>
51 49
52 <view class="fixedBottom" v-if="list.length>0"> 50 <view class="fixedBottom" v-if="list.length>0">
53
54 <button class="btn-red" @click="handleImport">导入</button> 51 <button class="btn-red" @click="handleImport">导入</button>
55 </view> 52 </view>
56
57 </view> 53 </view>
58 </template> 54 </template>
59 55
60 <script setup> 56 <script setup>
61 import * as api from '@/common/api.js'
62 import config from '@/config.js' 57 import config from '@/config.js'
63 import { 58 import {
64 ref, 59 ref,
...@@ -67,6 +62,8 @@ ...@@ -67,6 +62,8 @@
67 import { 62 import {
68 onLoad 63 onLoad
69 } from '@dcloudio/uni-app' 64 } from '@dcloudio/uni-app'
65 import * as api from '@/common/api.js'
66
70 const { 67 const {
71 proxy 68 proxy
72 } = getCurrentInstance() 69 } = getCurrentInstance()
...@@ -74,27 +71,37 @@ ...@@ -74,27 +71,37 @@
74 const queryParams = ref({ 71 const queryParams = ref({
75 showMyPersonFlag: 1, 72 showMyPersonFlag: 1,
76 checkPaymentCommit: 1, 73 checkPaymentCommit: 1,
77 fromChoose: 1 74 fromChoose: 1,
75 pageNum: 1,
76 pageSize: 10,
77 paymentRangeId: -1,
78 name: '',
79 isBlack: 0,
80 // certStage: '',
81 validityDateRange: null
78 }) 82 })
79 const list = ref([]) 83 const list = ref([])
80 const total = ref(0) 84 const total = ref(0)
81 const userType = ref('') 85 const userType = ref('')
86
82 onLoad((option) => { 87 onLoad((option) => {
83 userType.value = app.globalData.userType 88 userType.value = app.globalData.userType
84 queryParams.value.paymentRangeId = option.rangeId 89 queryParams.value.paymentRangeId = option.rangeId
85 getList() 90 getList()
86 }) 91 })
87 92
88 function getList() { 93 async function getList() {
89 api.selectPageList(queryParams.value).then(res => { 94 const res = await api.selectPageList(queryParams.value)
90 list.value = res.rows 95 list.value = res.rows
96 // 处理图片路径
91 for(var l of list.value){ 97 for(var l of list.value){
92 if(l.photo&&l.photo.indexOf('http')==-1){ 98 if(l.photo&&l.photo.indexOf('http')==-1){
93 l.photo = config.baseUrl_api + l.photo 99 l.photo = config.baseUrl_api + l.photo
94 } 100 }
101 // 初始化选中状态
102 l.checked = false
95 } 103 }
96 total.value = res.total 104 total.value = res.total
97 })
98 } 105 }
99 106
100 function handleInfo(n) { 107 function handleInfo(n) {
...@@ -106,20 +113,21 @@ ...@@ -106,20 +113,21 @@
106 function goAddRenew() { 113 function goAddRenew() {
107 uni.navigateBack() 114 uni.navigateBack()
108 } 115 }
116
109 function checkThis(n){ 117 function checkThis(n){
110 if(n.checked){ 118 n.checked = !n.checked
111 n.checked = false
112 }else{
113 n.checked = true
114 }
115 } 119 }
116 function handleImport(){ 120
117 var arr=[] 121 async function handleImport(){
122 const arr = []
123 const idcCodeList = []
118 for(var n of list.value){ 124 for(var n of list.value){
119 if(n.checked){ 125 if(n.checked){
120 arr.push(n.perId) 126 arr.push(n.perId)
127 idcCodeList.push(n.idcCode)
121 } 128 }
122 } 129 }
130
123 if(arr.length==0){ 131 if(arr.length==0){
124 uni.showToast({ 132 uni.showToast({
125 title:"请选择会员", 133 title:"请选择会员",
...@@ -127,18 +135,30 @@ ...@@ -127,18 +135,30 @@
127 }) 135 })
128 return 136 return
129 } 137 }
130 api.addPersonPaymentGroup({ rangeId: queryParams.value.paymentRangeId, personIdArray: arr.join(',') }).then(res=>{ 138
131 let path = `/personalVip/renew?rangeId=${res.data.rangeId}` 139 try {
132 uni.redirectTo({ 140 const res = await api.memberInsertPersons({
133 url: path 141 rangeId: queryParams.value.paymentRangeId,
134 }); 142 year: 1,
143 idcCode: idcCodeList
135 }) 144 })
145 uni.navigateBack()
146
147 uni.showToast({
148 title: '导入成功',
149 icon: 'success'
150 })
151 } catch (e) {
152 uni.showToast({
153 title: '导入失败',
154 icon: 'none'
155 })
156 console.error('批量添加失败:', e)
157 }
136 } 158 }
137 </script> 159 </script>
138 160
139 <style scoped lang="scss"> 161 <style scoped lang="scss">
140
141
142 .indexboxre { 162 .indexboxre {
143 padding: 0 30rpx; 163 padding: 0 30rpx;
144 164
...@@ -169,4 +189,92 @@ ...@@ -169,4 +189,92 @@
169 font-size: 26rpx; 189 font-size: 26rpx;
170 } 190 }
171 } 191 }
192
193 .userlist {
194 .item {
195 display: flex;
196 align-items: center;
197 padding: 20rpx 0;
198 border-bottom: 1px solid #f5f5f5;
199
200 .icon {
201 width: 40rpx;
202 height: 40rpx;
203 margin-right: 20rpx;
204 }
205
206 .photobox {
207 margin-right: 20rpx;
208
209 .photo {
210 width: 80rpx;
211 height: 80rpx;
212 border-radius: 50%;
213 }
214
215 .colorful {
216 width: 80rpx;
217 height: 80rpx;
218 line-height: 80rpx;
219 text-align: center;
220 color: #fff;
221 border-radius: 50%;
222 font-size: 36rpx;
223 }
224 }
225
226 .name {
227 font-size: 32rpx;
228 font-weight: 500;
229 }
230
231 .date {
232 font-size: 24rpx;
233 color: #999;
234 margin-top: 8rpx;
235 }
236
237 .status {
238 margin-left: auto;
239 font-size: 28rpx;
240 }
241 }
242 }
243
244 .nodata {
245 text-align: center;
246 padding: 100rpx 0;
247
248 image {
249 width: 200rpx;
250 height: 200rpx;
251 margin-bottom: 20rpx;
252 }
253
254 text {
255 font-size: 28rpx;
256 color: #999;
257 }
258 }
259
260 .fixedBottom {
261 position: fixed;
262 bottom: 0;
263 left: 0;
264 right: 0;
265 padding: 20rpx;
266 background: #fff;
267 border-top: 1px solid #eee;
268
269 .btn-red {
270 width: 100%;
271 height: 80rpx;
272 line-height: 80rpx;
273 background: #E60012;
274 color: #fff;
275 border-radius: 40rpx;
276 font-size: 32rpx;
277 border: none;
278 }
279 }
172 </style> 280 </style>
...\ No newline at end of file ...\ No newline at end of file
......
1 { 1 {
2 "appid": "wx5d51e8ed31bbdbb7", 2 "appid": "wx523ee37fff4fea9d",
3 "compileType": "miniprogram", 3 "compileType": "miniprogram",
4 "libVersion": "3.0.0", 4 "libVersion": "3.0.0",
5 "packOptions": { 5 "packOptions": {
...@@ -19,11 +19,23 @@ ...@@ -19,11 +19,23 @@
19 "disablePlugins": [], 19 "disablePlugins": [],
20 "outputPath": "" 20 "outputPath": ""
21 }, 21 },
22 "condition": false 22 "condition": false,
23 "compileWorklet": false,
24 "uglifyFileName": false,
25 "uploadWithSourceMap": true,
26 "packNpmManually": false,
27 "minifyWXSS": true,
28 "minifyWXML": true,
29 "localPlugins": false,
30 "disableUseStrict": false,
31 "useCompilerPlugins": false,
32 "swc": false,
33 "disableSWC": true
23 }, 34 },
24 "condition": {}, 35 "condition": {},
25 "editorSetting": { 36 "editorSetting": {
26 "tabIndent": "insertSpaces", 37 "tabIndent": "insertSpaces",
27 "tabSize": 2 38 "tabSize": 2
28 } 39 },
40 "simulatorPluginLibVersion": {}
29 } 41 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,6 +2,23 @@ ...@@ -2,6 +2,23 @@
2 "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", 2 "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
3 "projectname": "Venue", 3 "projectname": "Venue",
4 "setting": { 4 "setting": {
5 "compileHotReLoad": true 5 "compileHotReLoad": true,
6 } 6 "urlCheck": true,
7 "coverView": true,
8 "lazyloadPlaceholderEnable": false,
9 "skylineRenderEnable": false,
10 "preloadBackgroundData": false,
11 "autoAudits": false,
12 "useApiHook": true,
13 "useApiHostProcess": true,
14 "showShadowRootInWxmlPanel": true,
15 "useStaticServer": false,
16 "useLanDebug": false,
17 "showES6CompileOption": false,
18 "checkInvalidKey": true,
19 "ignoreDevUnusedFiles": true,
20 "bigPackageSizeSupport": false
21 },
22 "libVersion": "3.15.0",
23 "condition": {}
7 } 24 }
...\ No newline at end of file ...\ No newline at end of file
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!