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,14 +759,12 @@ export function delcertified(ids) { ...@@ -746,14 +759,12 @@ 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 767 })
755 }
756 })
757 } 768 }
758 769
759 export function editGroupYear(data) { 770 export function editGroupYear(data) {
...@@ -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;
...@@ -205,55 +210,55 @@ page { ...@@ -205,55 +210,55 @@ page {
205 margin: 0 0 0 30rpx;padding: 0 40rpx;box-sizing: border-box; 210 margin: 0 0 0 30rpx;padding: 0 40rpx;box-sizing: border-box;
206 } 211 }
207 text{font-size: 30rpx;padding:30rpx 0 0;box-sizing: border-box;} 212 text{font-size: 30rpx;padding:30rpx 0 0;box-sizing: border-box;}
208 } 213 }
209 .colorful { 214 .colorful {
210 width: 100rpx; 215 width: 100rpx;
211 margin-right: 14rpx; 216 margin-right: 14rpx;
212 height: 100rpx; 217 height: 100rpx;
213 line-height: 100rpx; 218 line-height: 100rpx;
214 font-size: 44rpx; 219 font-size: 44rpx;
215 color: #fff; 220 color: #fff;
216 text-align: center; 221 text-align: center;
217 border-radius: 50%; 222 border-radius: 50%;
218 } 223 }
219 .w100{width: 100%;} 224 .w100{width: 100%;}
220 .item { 225 .item {
221 display: flex;width: 100%; 226 display: flex;width: 100%;
222 background: #FFFFFF;box-sizing: border-box; 227 background: #FFFFFF;box-sizing: border-box;
223 align-items: center; 228 align-items: center;
224 border-radius: 15rpx; 229 border-radius: 15rpx;
225 margin: 0 0 26rpx; 230 margin: 0 0 26rpx;
226 padding:20rpx;position: relative; 231 padding:20rpx;position: relative;
227 .date{color: #999;font-size: 24rpx;} 232 .date{color: #999;font-size: 24rpx;}
228 .status{font-size: 28rpx;position: absolute;right: 30rpx;} 233 .status{font-size: 28rpx;position: absolute;right: 30rpx;}
229 .name{font-size: 30rpx;margin-bottom: 10rpx;word-wrap: break-all; 234 .name{font-size: 30rpx;margin-bottom: 10rpx;word-wrap: break-all;
230 text{font-size: 28rpx;color: #666;} 235 text{font-size: 28rpx;color: #666;}
231 } 236 }
232 .icon { 237 .icon {
233 width: 50rpx; 238 width: 50rpx;
234 height: 50rpx; 239 height: 50rpx;
235 margin-right: 20rpx; 240 margin-right: 20rpx;
236 } 241 }
237 242
238 &:nth-child(5n) .colorful { 243 &:nth-child(5n) .colorful {
239 background: #014A9F; 244 background: #014A9F;
240 } 245 }
241 246
242 &:nth-child(5n+1) .colorful { 247 &:nth-child(5n+1) .colorful {
243 background: #AD181F; 248 background: #AD181F;
244 } 249 }
245 250
246 &:nth-child(5n+2) .colorful { 251 &:nth-child(5n+2) .colorful {
247 background: #D3B267; 252 background: #D3B267;
248 } 253 }
249 254
250 &:nth-child(5n+3) .colorful { 255 &:nth-child(5n+3) .colorful {
251 background: #3195F5; 256 background: #3195F5;
252 } 257 }
253 258
254 &:nth-child(5n+4) .colorful { 259 &:nth-child(5n+4) .colorful {
255 background: #E79222; 260 background: #E79222;
256 } 261 }
257 } 262 }
258 .photobox{} 263 .photobox{}
259 .photo{width: 100rpx;margin-right: 14rpx; 264 .photo{width: 100rpx;margin-right: 14rpx;
...@@ -278,7 +283,7 @@ page { ...@@ -278,7 +283,7 @@ page {
278 .text-warning{color: #e6a23c;} 283 .text-warning{color: #e6a23c;}
279 } 284 }
280 } 285 }
281 286
282 } 287 }
283 .stepItem{position: relative; 288 .stepItem{position: relative;
284 padding: 0 0 30rpx 30rpx;box-sizing: border-box; 289 padding: 0 0 30rpx 30rpx;box-sizing: border-box;
...@@ -306,65 +311,65 @@ page { ...@@ -306,65 +311,65 @@ page {
306 font-size: 30rpx;} 311 font-size: 30rpx;}
307 } 312 }
308 } 313 }
309 .personitem { 314 .personitem {
310 background: #fff; 315 background: #fff;
311 box-sizing: border-box; 316 box-sizing: border-box;
312 margin-bottom: 30rpx; 317 margin-bottom: 30rpx;
313 318
314 .content-box { 319 .content-box {
315 display: flex; 320 display: flex;
316 align-items: center; 321 align-items: center;
317 padding: 16rpx 30rpx;box-sizing: border-box; 322 padding: 16rpx 30rpx;box-sizing: border-box;
318 border-radius: 15rpx; 323 border-radius: 15rpx;
319 justify-content: space-between; 324 justify-content: space-between;
320 325
321 .photobox { 326 .photobox {
322 position: relative; 327 position: relative;
323 } 328 }
324 329
325 .photo { 330 .photo {
326 width: 100rpx; 331 width: 100rpx;
327 object-fit: cover; 332 object-fit: cover;
328 margin-right: 14rpx; 333 margin-right: 14rpx;
329 height: 100rpx; 334 height: 100rpx;
330 border-radius: 50%; 335 border-radius: 50%;
331 } 336 }
332 337
333 .noborder { 338 .noborder {
334 border: none; 339 border: none;
335 340
336 :deep(.uni-select) { 341 :deep(.uni-select) {
337 border: none; 342 border: none;
338 text-align: right; 343 text-align: right;
339 } 344 }
340 } 345 }
341 } 346 }
342 347
343 .flexbox { 348 .flexbox {
344 align-items: center; 349 align-items: center;
345 } 350 }
346 .date{font-size: 28rpx;color: #666;margin-top: 10rpx;} 351 .date{font-size: 28rpx;color: #666;margin-top: 10rpx;}
347 &:nth-child(3n) .colorful { 352 &:nth-child(3n) .colorful {
348 background: #AD181F; 353 background: #AD181F;
349 } 354 }
350 355
351 &:nth-child(3n+1) .colorful { 356 &:nth-child(3n+1) .colorful {
352 background: #014A9F; 357 background: #014A9F;
353 } 358 }
354 359
355 &:nth-child(3n+2) .colorful { 360 &:nth-child(3n+2) .colorful {
356 background: #D3B267; 361 background: #D3B267;
357 } 362 }
358 } 363 }
359 .colorful { 364 .colorful {
360 width: 100rpx; 365 width: 100rpx;
361 margin-right: 14rpx; 366 margin-right: 14rpx;
362 height: 100rpx; 367 height: 100rpx;
363 line-height: 100rpx; 368 line-height: 100rpx;
364 font-size: 44rpx; 369 font-size: 44rpx;
365 color: #fff; 370 color: #fff;
366 text-align: center; 371 text-align: center;
367 border-radius: 50%; 372 border-radius: 50%;
368 } 373 }
369 .slot-button { 374 .slot-button {
370 display: flex; 375 display: flex;
......
...@@ -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>
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
...@@ -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 }
...@@ -636,4 +671,4 @@ ...@@ -636,4 +671,4 @@
636 :deep(.item-text-overflow) { 671 :deep(.item-text-overflow) {
637 text-align: left; 672 text-align: left;
638 } 673 }
639 </style> 674 </style>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -5,37 +5,33 @@ ...@@ -5,37 +5,33 @@
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>
30 <text v-if="n.auditResult==1" class="text-success">审核通过</text> 28 <text v-if="n.auditResult==1" class="text-success">审核通过</text>
31 <text v-if="n.auditResult==2" class="text-danger"> 审核拒绝</text> 29 <text v-if="n.auditResult==2" class="text-danger"> 审核拒绝</text>
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 }
81 })
82 } 75 }
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,52 +2,52 @@ ...@@ -2,52 +2,52 @@
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.perIdcCode}}
23 证件号:{{n.personIdcCode}} 24 </view>
24 </view> 25 </view>
25 </view> 26 </view>
26 </view> 27 <view class="flexbox" @click="changeYear(n)">
27 <view class="flexbox" @click="changeYear(n)"> 28 <view class="text-danger">({{yearlist[n.payYear-1].text}})</view>
28 <view class="text-danger">({{yearlist[n.payYear-1].text}})</view> 29 <uni-icons type="forward" size="18" color="#999"></uni-icons>
29 <uni-icons type="forward" size="18" color="#999"></uni-icons>
30 </view>
31
32 </view>
33 <template v-slot:right>
34 <view class="slot-button">
35 <view @click="handleDelete(n)">
36 <uni-icons type="trash-filled" color="#fff" size="20"></uni-icons>
37 <text class="slot-button-text">删除</text>
38 </view> 30 </view>
39 </view>
40 </template>
41 </uni-swipe-action-item>
42 </uni-swipe-action>
43 31
32 </view>
33 <template v-slot:right>
34 <view class="slot-button">
35 <view @click="handleDelete(n)">
36 <uni-icons type="trash-filled" color="#fff" size="20"></uni-icons>
37 <text class="slot-button-text">删除</text>
38 </view>
39 </view>
40 </template>
41 </uni-swipe-action-item>
42 </uni-swipe-action>
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,71 +112,89 @@ ...@@ -114,71 +112,89 @@
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: '删除成功' 186 getList()
164 })
165 if (list.value.length == 1) {
166 queryParams.value.rangeId = -1
167 }
168 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() 197 })
181 })
182 } 198 }
183 </script> 199 </script>
184 200
...@@ -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 }
266 }
260 267
261 &:nth-child(3n) .colorful { 268 .vipData {
262 background: #014A9F; 269 padding: 10rpx 20rpx;
263 } 270 font-size: 28rpx;
271 color: #666;
272 view { margin-bottom: 10rpx; }
273 text { color: #AD181F; font-weight: bold; }
274 }
264 275
265 &:nth-child(3n+1) .colorful { 276 .nodata {
266 background: #AD181F; 277 text-align: center;
267 } 278 padding: 100rpx 0;
279 image { width: 200rpx; height: 200rpx; margin-bottom: 20rpx; }
280 text { font-size: 28rpx; color: #999; }
281 }
268 282
269 &:nth-child(3n+2) .colorful { 283 .fixedBottom {
270 background: #D3B267; 284 position: fixed;
271 } 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,18 +7,17 @@ ...@@ -7,18 +7,17 @@
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)">
14 <image class="icon" v-if="n.checked" :src="config.baseUrl_api+'/fs/static/member/dx_dwn.png'" /> 13 <image class="icon" v-if="n.checked" :src="config.baseUrl_api+'/fs/static/member/dx_dwn.png'" />
15 <image class="icon" v-else :src="config.baseUrl_api+'/fs/static/member/dx.png'" /> 14 <image class="icon" v-else :src="config.baseUrl_api+'/fs/static/member/dx.png'" />
16 </view> 15 </view>
17 <view class="photobox"> 16 <view class="photobox">
18 <image class="photo" v-if="n.photo" :src="n.photo" mode='aspectFill'></image> 17 <image class="photo" v-if="n.photo" :src="n.photo" mode='aspectFill'></image>
19 <view class="colorful" v-else>{{n.name.slice(0,1)}}</view> 18 <view class="colorful" v-else>{{n.name.slice(0,1)}}</view>
20 </view> 19 </view>
21 <view @click="handleInfo(n)"> 20 <view @click="handleInfo(n)">
22 <view class="name">{{n.name}}</view> 21 <view class="name">{{n.name}}</view>
23 <view class="date" v-if="n.validityDate">到期时间:{{n.validityDate?.slice(0,10)}}</view> 22 <view class="date" v-if="n.validityDate">到期时间:{{n.validityDate?.slice(0,10)}}</view>
24 <view class="date" v-else>注册时间:{{n.createTime?.slice(0,10)}}</view> 23 <view class="date" v-else>注册时间:{{n.createTime?.slice(0,10)}}</view>
...@@ -40,25 +39,21 @@ ...@@ -40,25 +39,21 @@
40 过期 39 过期
41 </text> 40 </text>
42 </view> 41 </view>
43 </view> 42 </view>
44 <view class="nodata" v-if="list.length==0"> 43 <view class="nodata" v-if="list.length==0">
45 <image mode="aspectFit" src="/static/nodata.png"></image> 44 <image mode="aspectFit" src="/static/nodata.png"></image>
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,34 +62,46 @@ ...@@ -67,34 +62,46 @@
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()
73 const app = getApp(); 70 const app = getApp();
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
91 for(var l of list.value){ 96 // 处理图片路径
92 if(l.photo&&l.photo.indexOf('http')==-1){ 97 for(var l of list.value){
93 l.photo = config.baseUrl_api + l.photo 98 if(l.photo&&l.photo.indexOf('http')==-1){
94 } 99 l.photo = config.baseUrl_api + l.photo
95 } 100 }
96 total.value = res.total 101 // 初始化选中状态
97 }) 102 l.checked = false
103 }
104 total.value = res.total
98 } 105 }
99 106
100 function handleInfo(n) { 107 function handleInfo(n) {
...@@ -106,46 +113,59 @@ ...@@ -106,46 +113,59 @@
106 function goAddRenew() { 113 function goAddRenew() {
107 uni.navigateBack() 114 uni.navigateBack()
108 } 115 }
109 function checkThis(n){ 116
110 if(n.checked){ 117 function checkThis(n){
111 n.checked = false 118 n.checked = !n.checked
112 }else{ 119 }
113 n.checked = true 120
114 } 121 async function handleImport(){
115 } 122 const arr = []
116 function handleImport(){ 123 const idcCodeList = []
117 var arr=[] 124 for(var n of list.value){
118 for(var n of list.value){ 125 if(n.checked){
119 if(n.checked){ 126 arr.push(n.perId)
120 arr.push(n.perId) 127 idcCodeList.push(n.idcCode)
121 } 128 }
122 } 129 }
123 if(arr.length==0){ 130
124 uni.showToast({ 131 if(arr.length==0){
125 title:"请选择会员", 132 uni.showToast({
126 icon:"none" 133 title:"请选择会员",
127 }) 134 icon:"none"
128 return 135 })
129 } 136 return
130 api.addPersonPaymentGroup({ rangeId: queryParams.value.paymentRangeId, personIdArray: arr.join(',') }).then(res=>{ 137 }
131 let path = `/personalVip/renew?rangeId=${res.data.rangeId}` 138
132 uni.redirectTo({ 139 try {
133 url: path 140 const res = await api.memberInsertPersons({
134 }); 141 rangeId: queryParams.value.paymentRangeId,
135 }) 142 year: 1,
143 idcCode: idcCodeList
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
145 .tt { 165 .tt {
146 font-size: 30rpx; 166 font-size: 30rpx;
147 margin: 0 0 30rpx; 167 margin: 0 0 30rpx;
148 color: #4C5359; 168 color: #4C5359;
149 text{font-size: 26rpx;margin-left: 10px;} 169 text{font-size: 26rpx;margin-left: 10px;}
150 } 170 }
151 171
...@@ -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!