个人会员中心+注册+bug
Showing
24 changed files
with
1635 additions
and
126 deletions
| ... | @@ -1714,6 +1714,14 @@ export function unbindUser() { | ... | @@ -1714,6 +1714,14 @@ export function unbindUser() { |
| 1714 | }) | 1714 | }) |
| 1715 | } | 1715 | } |
| 1716 | 1716 | ||
| 1717 | // 电子会员证下载 | ||
| 1718 | export function downStuCertSingle(pId) { | ||
| 1719 | return request({ | ||
| 1720 | url: `/person/info/downStuCertSingle/${pId}`, | ||
| 1721 | method: 'post' | ||
| 1722 | }) | ||
| 1723 | } | ||
| 1724 | |||
| 1717 | /** | 1725 | /** |
| 1718 | * 订单列表 | 1726 | * 订单列表 |
| 1719 | * @param params | 1727 | * @param params |
| ... | @@ -2028,3 +2036,45 @@ export function memBerAuditList(params) { | ... | @@ -2028,3 +2036,45 @@ export function memBerAuditList(params) { |
| 2028 | params: params | 2036 | params: params |
| 2029 | }) | 2037 | }) |
| 2030 | } | 2038 | } |
| 2039 | |||
| 2040 | /** | ||
| 2041 | * 结算审核列表 | ||
| 2042 | * @param params | ||
| 2043 | * @returns {*} | ||
| 2044 | */ | ||
| 2045 | export function settlementList(params) { | ||
| 2046 | return request({ | ||
| 2047 | url: '/exam/paymentSubmit/list', | ||
| 2048 | method: 'get', | ||
| 2049 | params: params | ||
| 2050 | }) | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | /** | ||
| 2054 | * 结算审核(通过/拒绝) | ||
| 2055 | * @param data { ids, type, reason } | ||
| 2056 | * @returns {*} | ||
| 2057 | */ | ||
| 2058 | export function settlementAudit(data) { | ||
| 2059 | return request({ | ||
| 2060 | url: `/exam/paymentSubmit/audit/${data.ids}`, | ||
| 2061 | method: 'post', | ||
| 2062 | params: { | ||
| 2063 | type: data.type, | ||
| 2064 | reason: data.reason | ||
| 2065 | } | ||
| 2066 | }) | ||
| 2067 | } | ||
| 2068 | |||
| 2069 | /** | ||
| 2070 | * 结算详情列表(根据结算单ID获取关联的缴费单) | ||
| 2071 | * @param params { payIds, pageNum, pageSize } | ||
| 2072 | * @returns {*} | ||
| 2073 | */ | ||
| 2074 | export function settlementDetailList(params) { | ||
| 2075 | return request({ | ||
| 2076 | url: '/exam/payment/list', | ||
| 2077 | method: 'get', | ||
| 2078 | params: params | ||
| 2079 | }) | ||
| 2080 | } | ... | ... |
| ... | @@ -120,7 +120,8 @@ function requestPaymentCredential(encodedData) { | ... | @@ -120,7 +120,8 @@ function requestPaymentCredential(encodedData) { |
| 120 | header: { | 120 | header: { |
| 121 | 'Content-Type': 'application/x-www-form-urlencoded' | 121 | 'Content-Type': 'application/x-www-form-urlencoded' |
| 122 | }, | 122 | }, |
| 123 | data: encodedData | 123 | data: encodedData, |
| 124 | timeout: 60000 // 60秒超时,与业务请求保持一致 | ||
| 124 | }) | 125 | }) |
| 125 | } | 126 | } |
| 126 | 127 | ... | ... |
| ... | @@ -60,10 +60,13 @@ function handleTokenExpire() { | ... | @@ -60,10 +60,13 @@ function handleTokenExpire() { |
| 60 | 60 | ||
| 61 | // 显示错误提示 | 61 | // 显示错误提示 |
| 62 | function showError(msg) { | 62 | function showError(msg) { |
| 63 | console.log('showError called:', msg) | ||
| 64 | // 先隐藏可能存在的 loading,确保 Toast 能显示 | ||
| 65 | uni.hideLoading() | ||
| 63 | uni.showToast({ | 66 | uni.showToast({ |
| 64 | title: msg || '请求失败', | 67 | title: msg || '请求失败', |
| 65 | icon: 'none', | 68 | icon: 'none', |
| 66 | duration: 2000 | 69 | duration: 3000 |
| 67 | }) | 70 | }) |
| 68 | } | 71 | } |
| 69 | 72 | ||
| ... | @@ -119,9 +122,16 @@ const request = function (req) { | ... | @@ -119,9 +122,16 @@ const request = function (req) { |
| 119 | return | 122 | return |
| 120 | } | 123 | } |
| 121 | 124 | ||
| 122 | // 其他业务错误 | 125 | // 业务错误(code != 200 且非 Token 过期)- 统一显示错误提示 |
| 123 | showError(data.msg || '请求失败') | 126 | const errorMsg = data.msg || '操作失败' |
| 124 | reject(new Error(data.msg || '请求失败')) | 127 | showError(errorMsg) |
| 128 | |||
| 129 | // code == 500 时仅显示提示,不抛出异常,避免页面 catch 覆盖错误信息 | ||
| 130 | if (data.code == 500) { | ||
| 131 | return | ||
| 132 | } | ||
| 133 | |||
| 134 | reject(new Error(errorMsg)) | ||
| 125 | 135 | ||
| 126 | }).catch(error => { | 136 | }).catch(error => { |
| 127 | console.error('请求失败:', error) | 137 | console.error('请求失败:', error) |
| ... | @@ -139,9 +149,12 @@ const request = function (req) { | ... | @@ -139,9 +149,12 @@ const request = function (req) { |
| 139 | 149 | ||
| 140 | reject(error) | 150 | reject(error) |
| 141 | }).finally(() => { | 151 | }).finally(() => { |
| 152 | // 延迟隐藏 loading,确保错误提示能显示 | ||
| 153 | setTimeout(() => { | ||
| 142 | if (req.showLoading != false) { | 154 | if (req.showLoading != false) { |
| 143 | hideLoading() | 155 | hideLoading() |
| 144 | } | 156 | } |
| 157 | }, 100) | ||
| 145 | }) | 158 | }) |
| 146 | }) | 159 | }) |
| 147 | } | 160 | } | ... | ... |
| ... | @@ -13,15 +13,15 @@ | ... | @@ -13,15 +13,15 @@ |
| 13 | <view class="vipData mt30" style="flex-wrap: wrap;padding: 20rpx;"> | 13 | <view class="vipData mt30" style="flex-wrap: wrap;padding: 20rpx;"> |
| 14 | <view class="w50"> | 14 | <view class="w50"> |
| 15 | 年限合计: | 15 | 年限合计: |
| 16 | <text>{{ form?.renewYear }}个</text> | 16 | <text>{{ form?.renewYear }}年</text> |
| 17 | </view> | 17 | </view> |
| 18 | <view class="w50"> | 18 | <view class="w50"> |
| 19 | 费用合计: | 19 | 费用合计: |
| 20 | <text>{{ form?.allPrice }}个</text> | 20 | <text>{{ form?.allPrice }}元</text> |
| 21 | </view> | 21 | </view> |
| 22 | <view class="w50"> | 22 | <view class="w50"> |
| 23 | 政策优惠: | 23 | 政策优惠: |
| 24 | <text>{{ form?.discount }}年</text> | 24 | <text>{{ form?.discount }}元</text> |
| 25 | </view> | 25 | </view> |
| 26 | <view class="w50"> | 26 | <view class="w50"> |
| 27 | 付款费用: | 27 | 付款费用: | ... | ... |
| ... | @@ -117,7 +117,7 @@ | ... | @@ -117,7 +117,7 @@ |
| 117 | </view> | 117 | </view> |
| 118 | <view class="level-item"> | 118 | <view class="level-item"> |
| 119 | <text class="level-label">考试级别</text> | 119 | <text class="level-label">考试级别</text> |
| 120 | <view class="select-wrapper" @click="changeLevelfather(n)"> | 120 | <view class="select-wrapper exam-level-select" @click="changeLevelfather(n)"> |
| 121 | <uni-data-select v-model="n.levelNew" :clear="false" :localdata="levelArr" @change="changeLevel"/> | 121 | <uni-data-select v-model="n.levelNew" :clear="false" :localdata="levelArr" @change="changeLevel"/> |
| 122 | </view> | 122 | </view> |
| 123 | </view> | 123 | </view> |
| ... | @@ -427,7 +427,10 @@ function getChosedStudentList() { | ... | @@ -427,7 +427,10 @@ function getChosedStudentList() { |
| 427 | d.levelRecommend = '9' | 427 | d.levelRecommend = '9' |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | if (!d.levelNew) { | 430 | // 原级别是一级时,levelNew 默认为空,不使用推荐值 |
| 431 | if (d.levelOld === '1') { | ||
| 432 | d.levelNew = '' | ||
| 433 | } else if (!d.levelNew) { | ||
| 431 | d.levelNew = d.levelRecommend | 434 | d.levelNew = d.levelRecommend |
| 432 | } | 435 | } |
| 433 | 436 | ||
| ... | @@ -475,10 +478,21 @@ function szToHz(num) { | ... | @@ -475,10 +478,21 @@ function szToHz(num) { |
| 475 | 478 | ||
| 476 | let nowRow | 479 | let nowRow |
| 477 | 480 | ||
| 478 | function changeLevelfather(row) { | 481 | function changeLevelfather(row, flag = 0) { |
| 479 | nowRow = row | 482 | const data = _.map(infoList.value, (d) => { |
| 480 | api.jiDropDownBox({ | 483 | return { |
| 481 | perId: row.perId | 484 | id: d.id, |
| 485 | levelNew: d.levelNew, | ||
| 486 | // score: d.score, | ||
| 487 | isPass: d.isPass | ||
| 488 | } | ||
| 489 | }) | ||
| 490 | api.editLevel({ | ||
| 491 | examId: form.value.examId, | ||
| 492 | personInfo: JSON.stringify(data), | ||
| 493 | transcript: form.value.transcript, | ||
| 494 | // perId: row.perId, | ||
| 495 | status: flag | ||
| 482 | }).then(res => { | 496 | }).then(res => { |
| 483 | levelArr.value = res.data | 497 | levelArr.value = res.data |
| 484 | for (let l of levelArr.value) { | 498 | for (let l of levelArr.value) { |
| ... | @@ -489,36 +503,43 @@ function changeLevelfather(row) { | ... | @@ -489,36 +503,43 @@ function changeLevelfather(row) { |
| 489 | } | 503 | } |
| 490 | 504 | ||
| 491 | function changeLevel(e) { | 505 | function changeLevel(e) { |
| 492 | if (e == nowRow.levelOld) { | 506 | // 切换考试级别时弹出确认框 |
| 493 | uni.showToast({title: '考试级别重复,请重新选择!', icon: 'none'}) | ||
| 494 | nowRow.levelNew = nowRow.levelRecommend | ||
| 495 | return | ||
| 496 | } | ||
| 497 | if (e !== nowRow.levelRecommend) { | ||
| 498 | uni.showModal({ | 507 | uni.showModal({ |
| 499 | title: '提示', | 508 | title: '提示', |
| 500 | content: `建议考试级别为 "${szToHz(nowRow.levelRecommend)}级" ,确定要修改为${szToHz(e)}级吗?`, | 509 | content: '请仔细核实本次等级申报是否正确!', |
| 501 | success: function (res) { | 510 | success: function (res) { |
| 502 | if (res.confirm) { | 511 | if (res.confirm) { |
| 512 | // 保存当前行数据 | ||
| 513 | const data = _.map(infoList.value, (d) => { | ||
| 514 | return { | ||
| 515 | id: d.id, | ||
| 516 | levelNew: d.levelNew, | ||
| 517 | isPass: d.isPass | ||
| 518 | } | ||
| 519 | }) | ||
| 520 | api.editLevel({ | ||
| 521 | examId: form.value.examId, | ||
| 522 | personInfo: JSON.stringify(data), | ||
| 523 | transcript: form.value.transcript, | ||
| 524 | status: 0 | ||
| 525 | }).then(() => { | ||
| 526 | // 保存成功后更新统计 | ||
| 503 | getTablePersonInfo() | 527 | getTablePersonInfo() |
| 528 | }) | ||
| 504 | } else { | 529 | } else { |
| 505 | nowRow.levelNew = nowRow.levelRecommend | 530 | // 取消时恢复为推荐级别 |
| 531 | nowRow.levelNew = nowRow.levelRecommend != 0 ? nowRow.levelRecommend : '' | ||
| 506 | } | 532 | } |
| 507 | }, | 533 | }, |
| 508 | fail: function (res) { | 534 | fail: function (res) { |
| 509 | nowRow.levelNew = nowRow.levelRecommend | 535 | nowRow.levelNew = nowRow.levelRecommend != 0 ? nowRow.levelRecommend : '' |
| 510 | } | 536 | } |
| 511 | }) | 537 | }) |
| 512 | } | ||
| 513 | } | 538 | } |
| 514 | 539 | ||
| 515 | function submitForm2(flag) { | 540 | function submitForm2(flag) { |
| 516 | // 循环校验考试级别 | 541 | // 循环校验考试级别是否选择(考试级别重复可以提交) |
| 517 | for (let item of infoList.value) { | 542 | for (let item of infoList.value) { |
| 518 | if (item.levelNew == item.levelOld) { | ||
| 519 | uni.showToast({title: `${item.realName}考试级别重复,请重新选择!`, icon: 'none'}) | ||
| 520 | return | ||
| 521 | } | ||
| 522 | if (!item.levelNew) { | 543 | if (!item.levelNew) { |
| 523 | uni.showToast({title: `${item.realName}请选择考试级别!`, icon: 'none'}) | 544 | uni.showToast({title: `${item.realName}请选择考试级别!`, icon: 'none'}) |
| 524 | return | 545 | return |
| ... | @@ -536,16 +557,11 @@ function submitForm2(flag) { | ... | @@ -536,16 +557,11 @@ function submitForm2(flag) { |
| 536 | content: `请确认人员照片是否已更新?`, | 557 | content: `请确认人员照片是否已更新?`, |
| 537 | success: function (res) { | 558 | success: function (res) { |
| 538 | if (res.confirm) { | 559 | if (res.confirm) { |
| 539 | // saveStep2(flag).then(() => { | 560 | saveStep2(flag).then(() => { |
| 540 | // uni.showToast({title: '提交成功', icon: 'none'}) | ||
| 541 | // uni.navigateTo({ | ||
| 542 | // url: `/level/paymentDetail?examId=${form.value.examId}` | ||
| 543 | // }) | ||
| 544 | // }) | ||
| 545 | |||
| 546 | uni.navigateTo({ | 561 | uni.navigateTo({ |
| 547 | url: `/level/paymentDetail?examId=${form.value.examId}` | 562 | url: `/level/paymentDetail?examId=${form.value.examId}` |
| 548 | }) | 563 | }) |
| 564 | }) | ||
| 549 | } | 565 | } |
| 550 | } | 566 | } |
| 551 | }) | 567 | }) |
| ... | @@ -866,7 +882,15 @@ function handleDelete(row) { | ... | @@ -866,7 +882,15 @@ function handleDelete(row) { |
| 866 | } | 882 | } |
| 867 | 883 | ||
| 868 | .select-wrapper { | 884 | .select-wrapper { |
| 869 | width: 120rpx; | 885 | width: 160rpx; |
| 886 | position: relative; | ||
| 887 | z-index: 99; | ||
| 888 | } | ||
| 889 | |||
| 890 | .exam-level-select { | ||
| 891 | position: relative; | ||
| 892 | z-index: 999; | ||
| 893 | margin-bottom: 300rpx; | ||
| 870 | } | 894 | } |
| 871 | } | 895 | } |
| 872 | } | 896 | } | ... | ... |
| ... | @@ -23,9 +23,10 @@ | ... | @@ -23,9 +23,10 @@ |
| 23 | <view class="date">注册地:{{n.memName||'-'}}</view> | 23 | <view class="date">注册地:{{n.memName||'-'}}</view> |
| 24 | </view> | 24 | </view> |
| 25 | <view class="status"> | 25 | <view class="status"> |
| 26 | <text v-if="isChosen(n)" class="text-gray">已选</text> | 26 | <text v-if="isChosen(n)" class="text-chosen">已选</text> |
| 27 | <!-- <text v-else-if="n.canChoose != 1" class="text-gray">不可选</text> --> | 27 | <!-- <text v-else-if="n.canChoose != 1" class="text-gray">不可选</text> --> |
| 28 | <text v-if="n.canChoose == 1" class="text-primary" @click="handleChoose(n)">选择</text> | 28 | <text v-else-if="n.canChoose == 1" class="text-primary" @click="handleChoose(n)">选择</text> |
| 29 | <text v-else class="text-gray">不可选</text> | ||
| 29 | </view> | 30 | </view> |
| 30 | </view> | 31 | </view> |
| 31 | </view> | 32 | </view> |
| ... | @@ -146,6 +147,15 @@ | ... | @@ -146,6 +147,15 @@ |
| 146 | } | 147 | } |
| 147 | 148 | ||
| 148 | function handleChoose(row) { | 149 | function handleChoose(row) { |
| 150 | // 校验是否已被其他位置选中 | ||
| 151 | if (isChosen(row)) { | ||
| 152 | uni.showToast({ | ||
| 153 | title: '该考官已被选中,不能重复选择', | ||
| 154 | icon: 'none' | ||
| 155 | }) | ||
| 156 | return | ||
| 157 | } | ||
| 158 | |||
| 149 | if (row.canChoose != 1) { | 159 | if (row.canChoose != 1) { |
| 150 | uni.showToast({ | 160 | uni.showToast({ |
| 151 | title: '该考官资质已过期!', | 161 | title: '该考官资质已过期!', |
| ... | @@ -215,7 +225,7 @@ | ... | @@ -215,7 +225,7 @@ |
| 215 | success: (res) => { | 225 | success: (res) => { |
| 216 | if (res.confirm) { | 226 | if (res.confirm) { |
| 217 | uni.showLoading({ title: '添加中' }) | 227 | uni.showLoading({ title: '添加中' }) |
| 218 | api.selfAdd(app.globalData.memberInfo.memId, row.perId).then(() => { | 228 | api.selfAdd(row.perId).then(() => { |
| 219 | uni.hideLoading() | 229 | uni.hideLoading() |
| 220 | uni.showToast({ title: '添加成功', icon: 'success' }) | 230 | uni.showToast({ title: '添加成功', icon: 'success' }) |
| 221 | addPopup.value.close() | 231 | addPopup.value.close() |
| ... | @@ -317,6 +327,11 @@ | ... | @@ -317,6 +327,11 @@ |
| 317 | color: #999; | 327 | color: #999; |
| 318 | } | 328 | } |
| 319 | 329 | ||
| 330 | .text-chosen { | ||
| 331 | color: #AD181F; | ||
| 332 | font-weight: bold; | ||
| 333 | } | ||
| 334 | |||
| 320 | .text-danger { | 335 | .text-danger { |
| 321 | color: #dd524d; | 336 | color: #dd524d; |
| 322 | } | 337 | } | ... | ... |
level/settlementAudit.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="settlement-audit-page"> | ||
| 3 | <!-- Tab 切换 --> | ||
| 4 | <view class="tab-bar"> | ||
| 5 | <view | ||
| 6 | v-for="tab in tabs" | ||
| 7 | :key="tab.value" | ||
| 8 | :class="['tab-item', { active: status === tab.value }]" | ||
| 9 | @click="onTabChange(tab.value)" | ||
| 10 | > | ||
| 11 | {{ tab.text }} | ||
| 12 | </view> | ||
| 13 | </view> | ||
| 14 | |||
| 15 | <!-- 列表区域 --> | ||
| 16 | <scroll-view scroll-y class="list-container" @scrolltolower="loadMore"> | ||
| 17 | <view v-for="item in infoList" :key="item.id" class="list-item"> | ||
| 18 | <!-- 选择框 --> | ||
| 19 | <view class="checkbox-wrap"> | ||
| 20 | <checkbox-group @change="onCheckboxChange(item.id)"> | ||
| 21 | <label> | ||
| 22 | <checkbox :value="item.id" :checked="isChecked(item.id)" :disabled="item.status != '1'" color="#C4121B" /> | ||
| 23 | </label> | ||
| 24 | </checkbox-group> | ||
| 25 | </view> | ||
| 26 | |||
| 27 | <!-- 头部信息 --> | ||
| 28 | <view class="item-header"> | ||
| 29 | <text class="code" @click="goDetail(item)">{{ item.code }}</text> | ||
| 30 | <text :class="['status-tag', 'status-' + item.status]">{{ statusArr[item.status] }}</text> | ||
| 31 | </view> | ||
| 32 | |||
| 33 | <!-- 主体信息 --> | ||
| 34 | <view class="item-body"> | ||
| 35 | <view class="info-row"> | ||
| 36 | <text class="label">结算名称</text> | ||
| 37 | <text class="value">{{ item.name }}</text> | ||
| 38 | </view> | ||
| 39 | <view class="info-row"> | ||
| 40 | <text class="label">结算单位</text> | ||
| 41 | <text class="value">{{ item.memName }}</text> | ||
| 42 | </view> | ||
| 43 | <view class="info-row"> | ||
| 44 | <text class="label">考试人数</text> | ||
| 45 | <text class="value">{{ item.personCount }}人</text> | ||
| 46 | </view> | ||
| 47 | <view class="info-row"> | ||
| 48 | <text class="label">费用合计</text> | ||
| 49 | <text class="value primary">¥{{ item.originPrice }}</text> | ||
| 50 | </view> | ||
| 51 | <view class="info-row"> | ||
| 52 | <text class="label">结算金额</text> | ||
| 53 | <text class="value red">¥{{ item.price }}</text> | ||
| 54 | </view> | ||
| 55 | <view class="info-row"> | ||
| 56 | <text class="label">结算状态</text> | ||
| 57 | <text :class="['value', item.status == '2' ? 'green' : item.status == '3' ? 'red' : '']">{{ item.verityStatusStr }}</text> | ||
| 58 | </view> | ||
| 59 | </view> | ||
| 60 | |||
| 61 | <!-- 底部信息 --> | ||
| 62 | <view class="item-footer"> | ||
| 63 | <view class="footer-left"> | ||
| 64 | <text class="date">提交: {{ formatDate(item.commitTime) }}</text> | ||
| 65 | <text v-if="item.auditTime" class="date">审核: {{ formatDate(item.auditTime) }}</text> | ||
| 66 | </view> | ||
| 67 | <view class="footer-right"> | ||
| 68 | <text v-if="item.fileUrl" class="invoice-btn" @click="downloadInvoice(item)">发票</text> | ||
| 69 | <view v-else class="invoice-btn disabled">发票</view> | ||
| 70 | <button | ||
| 71 | v-if="item.status == '1'" | ||
| 72 | class="btn-settle" | ||
| 73 | @click="openSettlement(item)" | ||
| 74 | >结算</button> | ||
| 75 | </view> | ||
| 76 | </view> | ||
| 77 | </view> | ||
| 78 | |||
| 79 | <!-- 空状态 --> | ||
| 80 | <view v-if="infoList.length === 0 && !loading" class="empty"> | ||
| 81 | <text>暂无数据</text> | ||
| 82 | </view> | ||
| 83 | |||
| 84 | <!-- 加载更多 --> | ||
| 85 | <view v-if="loading" class="loading-more"> | ||
| 86 | <text>加载中...</text> | ||
| 87 | </view> | ||
| 88 | <view v-if="noMore && infoList.length > 0" class="loading-more"> | ||
| 89 | <text>没有更多了</text> | ||
| 90 | </view> | ||
| 91 | </scroll-view> | ||
| 92 | |||
| 93 | <!-- 底部统计和批量按钮 --> | ||
| 94 | <view v-if="selectedIds.length > 0" class="bottom-bar"> | ||
| 95 | <view class="stat-left"> | ||
| 96 | <text class="stat-item">人数: <text class="value">{{ selectedStatistical.personCount }}</text></text> | ||
| 97 | <text class="stat-item">费用: <text class="value">¥{{ selectedStatistical.originPrice?.toFixed(2) }}</text></text> | ||
| 98 | <text class="stat-item">结算: <text class="value red">¥{{ selectedStatistical.price?.toFixed(2) }}</text></text> | ||
| 99 | </view> | ||
| 100 | <view class="btn-right"> | ||
| 101 | <button class="batch-btn" @click="openBatchSettlement"> | ||
| 102 | 批量结算审核 ({{ selectedIds.length }}) | ||
| 103 | </button> | ||
| 104 | </view> | ||
| 105 | </view> | ||
| 106 | </view> | ||
| 107 | </template> | ||
| 108 | |||
| 109 | <script setup> | ||
| 110 | import { ref, computed, onMounted } from 'vue' | ||
| 111 | import {onShow} from '@dcloudio/uni-app' | ||
| 112 | import * as api from '@/common/api.js' | ||
| 113 | import config from '@/config.js' | ||
| 114 | import _ from 'underscore' | ||
| 115 | |||
| 116 | const tabs = ref([ | ||
| 117 | { value: '', text: '全部' }, | ||
| 118 | { value: '1', text: '待结算' }, | ||
| 119 | { value: '2', text: '结算通过' }, | ||
| 120 | { value: '3', text: '结算拒绝' } | ||
| 121 | ]) | ||
| 122 | const statusArr = ref(['未提交', '待结算', '结算通过', '结算拒绝']) | ||
| 123 | const status = ref('') | ||
| 124 | const infoList = ref([]) | ||
| 125 | const loading = ref(false) | ||
| 126 | const noMore = ref(false) | ||
| 127 | const pageNum = ref(1) | ||
| 128 | const pageSize = ref(10) | ||
| 129 | const total = ref(0) | ||
| 130 | |||
| 131 | const selectedIds = ref([]) | ||
| 132 | |||
| 133 | const statistical = ref({ | ||
| 134 | personCount: 0, | ||
| 135 | originPrice: 0, | ||
| 136 | price: 0 | ||
| 137 | }) | ||
| 138 | |||
| 139 | // 选中项的统计 | ||
| 140 | const selectedStatistical = computed(() => { | ||
| 141 | let personCount = 0 | ||
| 142 | let originPrice = 0 | ||
| 143 | let price = 0 | ||
| 144 | _.each(infoList.value, (info) => { | ||
| 145 | if (selectedIds.value.includes(info.id)) { | ||
| 146 | personCount += (info.personCount * 1) | ||
| 147 | originPrice += (info.originPrice * 1) | ||
| 148 | price += (info.price * 1) | ||
| 149 | } | ||
| 150 | }) | ||
| 151 | return { personCount, originPrice, price } | ||
| 152 | }) | ||
| 153 | |||
| 154 | onMounted(() => { | ||
| 155 | getList() | ||
| 156 | }) | ||
| 157 | |||
| 158 | function onTabChange(value) { | ||
| 159 | status.value = value | ||
| 160 | pageNum.value = 1 | ||
| 161 | infoList.value = [] | ||
| 162 | selectedIds.value = [] | ||
| 163 | noMore.value = false | ||
| 164 | getList() | ||
| 165 | } | ||
| 166 | |||
| 167 | async function getList() { | ||
| 168 | if (loading.value) return | ||
| 169 | loading.value = true | ||
| 170 | |||
| 171 | try { | ||
| 172 | const params = { | ||
| 173 | status: status.value, | ||
| 174 | pageNum: pageNum.value, | ||
| 175 | pageSize: pageSize.value | ||
| 176 | } | ||
| 177 | |||
| 178 | const res = await api.settlementList(params) | ||
| 179 | |||
| 180 | if (pageNum.value === 1) { | ||
| 181 | infoList.value = res.rows || [] | ||
| 182 | } else { | ||
| 183 | infoList.value = [...infoList.value, ...(res.rows || [])] | ||
| 184 | } | ||
| 185 | |||
| 186 | total.value = res.total || 0 | ||
| 187 | noMore.value = infoList.value.length >= total.value | ||
| 188 | |||
| 189 | // 计算统计 | ||
| 190 | calculateStatistical() | ||
| 191 | } catch (err) { | ||
| 192 | console.error('获取结算列表失败', err) | ||
| 193 | } finally { | ||
| 194 | loading.value = false | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | function calculateStatistical() { | ||
| 199 | statistical.value = { | ||
| 200 | personCount: 0, | ||
| 201 | originPrice: 0, | ||
| 202 | price: 0 | ||
| 203 | } | ||
| 204 | _.each(infoList.value, (info) => { | ||
| 205 | statistical.value.personCount += (info.personCount * 1) | ||
| 206 | statistical.value.originPrice += (info.originPrice * 1) | ||
| 207 | statistical.value.price += (info.price * 1) | ||
| 208 | }) | ||
| 209 | } | ||
| 210 | |||
| 211 | function loadMore() { | ||
| 212 | if (!noMore.value && !loading.value) { | ||
| 213 | pageNum.value++ | ||
| 214 | getList() | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | function formatDate(dateStr) { | ||
| 219 | if (!dateStr) return '-' | ||
| 220 | return dateStr.substring(0, 10) | ||
| 221 | } | ||
| 222 | |||
| 223 | // 复选框选择 | ||
| 224 | function onCheckboxChange(id) { | ||
| 225 | const index = selectedIds.value.indexOf(id) | ||
| 226 | if (index > -1) { | ||
| 227 | selectedIds.value.splice(index, 1) | ||
| 228 | } else { | ||
| 229 | selectedIds.value.push(id) | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | function isChecked(id) { | ||
| 234 | return selectedIds.value.includes(id) | ||
| 235 | } | ||
| 236 | |||
| 237 | // 进入详情页 | ||
| 238 | function goDetail(item) { | ||
| 239 | const data = encodeURIComponent(JSON.stringify(item)) | ||
| 240 | uni.navigateTo({ | ||
| 241 | url: `/level/settlementView?data=${data}` | ||
| 242 | }) | ||
| 243 | } | ||
| 244 | |||
| 245 | // 下载发票 | ||
| 246 | function downloadInvoice(item) { | ||
| 247 | if (!item.fileUrl) { | ||
| 248 | uni.showToast({ title: '暂无发票', icon: 'none' }) | ||
| 249 | return | ||
| 250 | } | ||
| 251 | try { | ||
| 252 | const invoice = JSON.parse(item.fileUrl) | ||
| 253 | if (invoice && invoice[0]?.url) { | ||
| 254 | let fileUrl = invoice[0].url | ||
| 255 | // 确保 URL 格式正确 | ||
| 256 | if (!fileUrl.startsWith('http')) { | ||
| 257 | fileUrl = config.baseUrl_api + fileUrl | ||
| 258 | } | ||
| 259 | |||
| 260 | // 小程序中使用 previewImage 预览,让用户长按保存 | ||
| 261 | uni.previewImage({ | ||
| 262 | urls: [fileUrl], | ||
| 263 | success: () => { | ||
| 264 | console.log('previewImage success') | ||
| 265 | }, | ||
| 266 | fail: (err) => { | ||
| 267 | console.error('previewImage fail:', err) | ||
| 268 | uni.showToast({ title: '打开图片失败', icon: 'none' }) | ||
| 269 | } | ||
| 270 | }) | ||
| 271 | } else { | ||
| 272 | uni.showToast({ title: '发票文件不存在', icon: 'none' }) | ||
| 273 | } | ||
| 274 | } catch (e) { | ||
| 275 | console.error('解析发票数据失败', e) | ||
| 276 | uni.showToast({ title: '解析发票数据失败', icon: 'none' }) | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | // 打开结算审核 - 跳转到审核页面 | ||
| 281 | function openSettlement(item) { | ||
| 282 | const ids = item.id | ||
| 283 | uni.navigateTo({ | ||
| 284 | url: `/pages/rank/scoreAudit?ids=${ids}&pageType=3` | ||
| 285 | }) | ||
| 286 | } | ||
| 287 | |||
| 288 | // 批量结算审核 - 跳转到审核页面 | ||
| 289 | function openBatchSettlement() { | ||
| 290 | if (selectedIds.value.length === 0) { | ||
| 291 | uni.showToast({ title: '请先选择要结算的项目', icon: 'none' }) | ||
| 292 | return | ||
| 293 | } | ||
| 294 | const ids = selectedIds.value.join(',') | ||
| 295 | uni.navigateTo({ | ||
| 296 | url: `/pages/rank/scoreAudit?ids=${ids}&pageType=3` | ||
| 297 | }) | ||
| 298 | } | ||
| 299 | |||
| 300 | function handleQuery() { | ||
| 301 | pageNum.value = 1 | ||
| 302 | infoList.value = [] | ||
| 303 | noMore.value = false | ||
| 304 | getList() | ||
| 305 | } | ||
| 306 | |||
| 307 | // 页面显示时刷新列表 | ||
| 308 | onShow(() => { | ||
| 309 | handleQuery() | ||
| 310 | }) | ||
| 311 | </script> | ||
| 312 | |||
| 313 | <style lang="scss" scoped> | ||
| 314 | .settlement-audit-page { | ||
| 315 | min-height: 100vh; | ||
| 316 | background: #f5f5f5; | ||
| 317 | } | ||
| 318 | |||
| 319 | /* Tab 切换 */ | ||
| 320 | .tab-bar { | ||
| 321 | display: flex; | ||
| 322 | background: #fff; | ||
| 323 | padding: 20rpx 0; | ||
| 324 | |||
| 325 | .tab-item { | ||
| 326 | flex: 1; | ||
| 327 | text-align: center; | ||
| 328 | font-size: 28rpx; | ||
| 329 | color: #666; | ||
| 330 | position: relative; | ||
| 331 | |||
| 332 | &.active { | ||
| 333 | color: #C4121B; | ||
| 334 | font-weight: 600; | ||
| 335 | |||
| 336 | &::after { | ||
| 337 | content: ''; | ||
| 338 | position: absolute; | ||
| 339 | bottom: -10rpx; | ||
| 340 | left: 50%; | ||
| 341 | transform: translateX(-50%); | ||
| 342 | width: 60rpx; | ||
| 343 | height: 4rpx; | ||
| 344 | background: #C4121B; | ||
| 345 | border-radius: 2rpx; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | /* 列表区域 */ | ||
| 352 | .list-container { | ||
| 353 | height: calc(100vh - 180rpx); | ||
| 354 | } | ||
| 355 | |||
| 356 | .list-item { | ||
| 357 | position: relative; | ||
| 358 | background: #fff; | ||
| 359 | margin: 20rpx 30rpx; | ||
| 360 | border-radius: 12rpx; | ||
| 361 | padding: 24rpx; | ||
| 362 | } | ||
| 363 | |||
| 364 | /* 复选框 */ | ||
| 365 | .checkbox-wrap { | ||
| 366 | position: absolute; | ||
| 367 | top: 44rpx; | ||
| 368 | left: 20rpx; | ||
| 369 | transform: translateY(-50%); | ||
| 370 | z-index: 10; | ||
| 371 | } | ||
| 372 | |||
| 373 | .item-header { | ||
| 374 | display: flex; | ||
| 375 | justify-content: space-between; | ||
| 376 | align-items: center; | ||
| 377 | margin-bottom: 16rpx; | ||
| 378 | padding-left: 60rpx; | ||
| 379 | |||
| 380 | .code { | ||
| 381 | font-size: 30rpx; | ||
| 382 | color: #1561cb; | ||
| 383 | font-weight: 600; | ||
| 384 | } | ||
| 385 | |||
| 386 | .status-tag { | ||
| 387 | font-size: 24rpx; | ||
| 388 | padding: 4rpx 16rpx; | ||
| 389 | border-radius: 20rpx; | ||
| 390 | |||
| 391 | &.status-1 { background: #fff3e0; color: #ff9800; } | ||
| 392 | &.status-2 { background: #e8f5e9; color: #4caf50; } | ||
| 393 | &.status-3 { background: #ffebee; color: #f44336; } | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | .item-body { | ||
| 398 | .info-row { | ||
| 399 | display: flex; | ||
| 400 | justify-content: space-between; | ||
| 401 | padding: 6rpx 0; | ||
| 402 | |||
| 403 | .label { | ||
| 404 | font-size: 26rpx; | ||
| 405 | color: #666; | ||
| 406 | } | ||
| 407 | |||
| 408 | .value { | ||
| 409 | font-size: 26rpx; | ||
| 410 | color: #333; | ||
| 411 | |||
| 412 | &.primary { color: #333; } | ||
| 413 | &.red { color: #C4121B; font-weight: 600; } | ||
| 414 | &.green { color: #4caf50; font-weight: 600; } | ||
| 415 | } | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | .item-footer { | ||
| 420 | display: flex; | ||
| 421 | justify-content: space-between; | ||
| 422 | align-items: center; | ||
| 423 | margin-top: 16rpx; | ||
| 424 | padding-top: 16rpx; | ||
| 425 | border-top: 1rpx solid #f0f0f0; | ||
| 426 | |||
| 427 | .footer-left { | ||
| 428 | display: flex; | ||
| 429 | flex-direction: column; | ||
| 430 | |||
| 431 | .date { | ||
| 432 | font-size: 24rpx; | ||
| 433 | color: #999; | ||
| 434 | margin-bottom: 4rpx; | ||
| 435 | } | ||
| 436 | } | ||
| 437 | |||
| 438 | .footer-right { | ||
| 439 | display: flex; | ||
| 440 | align-items: center; | ||
| 441 | gap: 16rpx; | ||
| 442 | |||
| 443 | .invoice-btn { | ||
| 444 | font-size: 26rpx; | ||
| 445 | color: #1561cb; | ||
| 446 | |||
| 447 | &.disabled { | ||
| 448 | color: #ccc; | ||
| 449 | } | ||
| 450 | } | ||
| 451 | |||
| 452 | .btn-settle { | ||
| 453 | padding: 0rpx 20rpx; | ||
| 454 | background: #fff; | ||
| 455 | color: #C4121B; | ||
| 456 | font-size: 24rpx; | ||
| 457 | border: 2rpx solid #C4121B; | ||
| 458 | border-radius: 35rpx; | ||
| 459 | width: 150rpx; | ||
| 460 | |||
| 461 | &::after { | ||
| 462 | border: none; | ||
| 463 | } | ||
| 464 | } | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | /* 空状态 */ | ||
| 469 | .empty { | ||
| 470 | text-align: center; | ||
| 471 | padding: 100rpx 0; | ||
| 472 | color: #999; | ||
| 473 | font-size: 28rpx; | ||
| 474 | } | ||
| 475 | |||
| 476 | .loading-more { | ||
| 477 | text-align: center; | ||
| 478 | padding: 20rpx; | ||
| 479 | color: #999; | ||
| 480 | font-size: 24rpx; | ||
| 481 | } | ||
| 482 | |||
| 483 | /* 底部栏 */ | ||
| 484 | .bottom-bar { | ||
| 485 | position: fixed; | ||
| 486 | bottom: 0; | ||
| 487 | left: 0; | ||
| 488 | right: 0; | ||
| 489 | display: flex; | ||
| 490 | align-items: center; | ||
| 491 | padding: 30rpx; | ||
| 492 | background: #fff; | ||
| 493 | border-top: 1rpx solid #eee; | ||
| 494 | box-sizing: border-box; | ||
| 495 | |||
| 496 | .stat-left { | ||
| 497 | flex: 1; | ||
| 498 | display: flex; | ||
| 499 | gap: 20rpx; | ||
| 500 | |||
| 501 | .stat-item { | ||
| 502 | font-size: 24rpx; | ||
| 503 | color: #666; | ||
| 504 | |||
| 505 | .value { | ||
| 506 | font-weight: 600; | ||
| 507 | color: #333; | ||
| 508 | |||
| 509 | &.red { | ||
| 510 | color: #C4121B; | ||
| 511 | } | ||
| 512 | } | ||
| 513 | } | ||
| 514 | } | ||
| 515 | |||
| 516 | .btn-right { | ||
| 517 | .batch-btn { | ||
| 518 | padding: 0rpx 30rpx; | ||
| 519 | background: #C4121B; | ||
| 520 | color: #fff; | ||
| 521 | font-size: 28rpx; | ||
| 522 | border-radius: 40rpx; | ||
| 523 | |||
| 524 | &::after { | ||
| 525 | border: none; | ||
| 526 | } | ||
| 527 | } | ||
| 528 | } | ||
| 529 | } | ||
| 530 | </style> |
level/settlementView.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view> | ||
| 3 | <scroll-view scroll-y class="detail-content"> | ||
| 4 | <!-- 结算基本信息 --> | ||
| 5 | <view class="card"> | ||
| 6 | <view class="card-header"> | ||
| 7 | <view class="header-left">结算信息</view> | ||
| 8 | </view> | ||
| 9 | <view class="card-body"> | ||
| 10 | <view class="info-row"> | ||
| 11 | <text class="label">结算编号</text> | ||
| 12 | <text class="value">{{ form.code || '--' }}</text> | ||
| 13 | </view> | ||
| 14 | <view class="info-row"> | ||
| 15 | <text class="label">缴费名称</text> | ||
| 16 | <text class="value">{{ form.name || '--' }}</text> | ||
| 17 | </view> | ||
| 18 | <view class="info-row"> | ||
| 19 | <text class="label">缴费单位</text> | ||
| 20 | <text class="value">{{ form.memName || '--' }}</text> | ||
| 21 | </view> | ||
| 22 | <view class="info-row"> | ||
| 23 | <text class="label">考试人数</text> | ||
| 24 | <text class="value">{{ form.personCount || 0 }}人</text> | ||
| 25 | </view> | ||
| 26 | <view class="info-row"> | ||
| 27 | <text class="label">费用合计</text> | ||
| 28 | <text class="value">¥{{ form.originPrice || 0 }}</text> | ||
| 29 | </view> | ||
| 30 | <view class="info-row"> | ||
| 31 | <text class="label">结算金额</text> | ||
| 32 | <text class="value text-red">¥{{ form.price || 0 }}</text> | ||
| 33 | </view> | ||
| 34 | <view class="info-row"> | ||
| 35 | <text class="label">支付方式</text> | ||
| 36 | <text class="value">民生付</text> | ||
| 37 | </view> | ||
| 38 | <view class="info-row"> | ||
| 39 | <text class="label">提交日期</text> | ||
| 40 | <text class="value">{{ formatDate(form.commitTime) }}</text> | ||
| 41 | </view> | ||
| 42 | <view class="info-row"> | ||
| 43 | <text class="label">结算日期</text> | ||
| 44 | <text class="value">{{ formatDate(form.auditTime) }}</text> | ||
| 45 | </view> | ||
| 46 | <view class="info-row" v-if="form.fileUrl"> | ||
| 47 | <text class="label">发票</text> | ||
| 48 | <text class="value text-primary" @click="downloadInvoice">下载发票</text> | ||
| 49 | </view> | ||
| 50 | </view> | ||
| 51 | </view> | ||
| 52 | |||
| 53 | <!-- 关联缴费单 --> | ||
| 54 | <view class="card"> | ||
| 55 | <view class="card-header"> | ||
| 56 | <view class="header-left">关联缴费单</view> | ||
| 57 | </view> | ||
| 58 | <!-- 统计信息 --> | ||
| 59 | <view class="payment-stat" v-if="paymentList.length > 0"> | ||
| 60 | <text>费用合计: <text class="stat-value">¥{{ paymentStat.totalAmount?.toFixed(2) }}</text></text> | ||
| 61 | <text>人数合计: <text class="stat-value">{{ paymentStat.totalNum }}</text>人</text> | ||
| 62 | </view> | ||
| 63 | <view v-if="loadingPayment" class="state-tip">加载中...</view> | ||
| 64 | <view v-else-if="paymentList.length === 0" class="state-tip">暂无关联缴费单</view> | ||
| 65 | <view class="payment-list" v-else> | ||
| 66 | <view class="payment-item" v-for="(pay, index) in paymentList" :key="pay.payId"> | ||
| 67 | <!-- 头部:序号 + 名称 + 状态 --> | ||
| 68 | <view class="item-header"> | ||
| 69 | <!-- <view class="item-index">{{ index + 1 }}</view> --> | ||
| 70 | <view class="item-name">{{ pay.name }}</view> | ||
| 71 | <view :class="['status-tag', pay.submitId ? 'passed' : 'pending']"> | ||
| 72 | {{ pay.submitId ? '已结算' : '未结算' }} | ||
| 73 | </view> | ||
| 74 | </view> | ||
| 75 | <!-- 主体:单列列表 --> | ||
| 76 | <view class="item-body"> | ||
| 77 | <view class="info-line"> | ||
| 78 | <text class="info-label">缴费编号</text> | ||
| 79 | <text class="info-value">{{ pay.payCode || '--' }}</text> | ||
| 80 | </view> | ||
| 81 | <view class="info-line"> | ||
| 82 | <text class="info-label">缴费单位</text> | ||
| 83 | <text class="info-value">{{ pay.memberName || '--' }}</text> | ||
| 84 | </view> | ||
| 85 | <view class="info-line"> | ||
| 86 | <text class="info-label">考试人数</text> | ||
| 87 | <text class="info-value">{{ pay.totalNum || 0 }}人</text> | ||
| 88 | </view> | ||
| 89 | <view class="info-line"> | ||
| 90 | <text class="info-label">总金额</text> | ||
| 91 | <text class="info-value text-red">¥{{ pay.totalAmount || 0 }}</text> | ||
| 92 | </view> | ||
| 93 | <view class="info-line"> | ||
| 94 | <text class="info-label">支付方式</text> | ||
| 95 | <text class="info-value">民生付</text> | ||
| 96 | </view> | ||
| 97 | <view class="info-line"> | ||
| 98 | <text class="info-label">审核状态</text> | ||
| 99 | <text :class="['info-value', getVerifyStatusClass(pay.verityStatus)]">{{ pay.verityStatusStr || '--' }}</text> | ||
| 100 | </view> | ||
| 101 | <view class="info-line"> | ||
| 102 | <text class="info-label">提交日期</text> | ||
| 103 | <text class="info-value">{{ formatDate(pay.submitTime) }}</text> | ||
| 104 | </view> | ||
| 105 | <view class="info-line"> | ||
| 106 | <text class="info-label">审核日期</text> | ||
| 107 | <text class="info-value">{{ formatDate(pay.verityDate) }}</text> | ||
| 108 | </view> | ||
| 109 | </view> | ||
| 110 | </view> | ||
| 111 | </view> | ||
| 112 | </view> | ||
| 113 | </scroll-view> | ||
| 114 | </view> | ||
| 115 | </template> | ||
| 116 | |||
| 117 | <script setup> | ||
| 118 | import { ref, onMounted } from 'vue' | ||
| 119 | import { onLoad } from '@dcloudio/uni-app' | ||
| 120 | import * as api from '@/common/api.js' | ||
| 121 | import config from '@/config.js' | ||
| 122 | |||
| 123 | const loading = ref(false) | ||
| 124 | const loadingPayment = ref(false) | ||
| 125 | const form = ref({}) | ||
| 126 | const paymentList = ref([]) | ||
| 127 | const paymentStat = ref({ | ||
| 128 | totalAmount: 0, | ||
| 129 | totalNum: 0 | ||
| 130 | }) | ||
| 131 | |||
| 132 | onLoad((options) => { | ||
| 133 | if (options.data) { | ||
| 134 | try { | ||
| 135 | form.value = JSON.parse(decodeURIComponent(options.data)) | ||
| 136 | } catch (e) { | ||
| 137 | console.error('解析结算数据失败', e) | ||
| 138 | } | ||
| 139 | } | ||
| 140 | }) | ||
| 141 | |||
| 142 | onMounted(() => { | ||
| 143 | if (form.value.payids) { | ||
| 144 | getPaymentList() | ||
| 145 | } | ||
| 146 | }) | ||
| 147 | |||
| 148 | async function getPaymentList() { | ||
| 149 | loadingPayment.value = true | ||
| 150 | paymentStat.value = { totalAmount: 0, totalNum: 0 } | ||
| 151 | try { | ||
| 152 | const res = await api.settlementDetailList({ payIds: form.value.payids ,type:1 }) | ||
| 153 | paymentList.value = res.rows || [] | ||
| 154 | // 计算统计 | ||
| 155 | let totalAmount = 0 | ||
| 156 | let totalNum = 0 | ||
| 157 | for (const pay of paymentList.value) { | ||
| 158 | totalAmount += (pay.totalAmount * 1) || 0 | ||
| 159 | totalNum += (pay.totalNum * 1) || 0 | ||
| 160 | } | ||
| 161 | paymentStat.value = { totalAmount, totalNum } | ||
| 162 | } catch (err) { | ||
| 163 | console.error('获取缴费单列表失败', err) | ||
| 164 | paymentList.value = [] | ||
| 165 | } finally { | ||
| 166 | loadingPayment.value = false | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | function formatDate(dateStr) { | ||
| 171 | if (!dateStr) return '--' | ||
| 172 | if (typeof dateStr === 'string' && dateStr.indexOf('T') > -1) { | ||
| 173 | return dateStr.slice(0, 10) | ||
| 174 | } | ||
| 175 | return dateStr | ||
| 176 | } | ||
| 177 | |||
| 178 | function getVerifyStatusClass(status) { | ||
| 179 | if (status == '1') return 'text-success' | ||
| 180 | if (status == '2') return 'text-danger' | ||
| 181 | if (status == '3') return 'text-warning' | ||
| 182 | return '' | ||
| 183 | } | ||
| 184 | |||
| 185 | function downloadInvoice() { | ||
| 186 | if (!form.value.fileUrl) { | ||
| 187 | uni.showToast({ title: '暂无发票', icon: 'none' }) | ||
| 188 | return | ||
| 189 | } | ||
| 190 | try { | ||
| 191 | const invoice = JSON.parse(form.value.fileUrl) | ||
| 192 | if (invoice && invoice[0]?.url) { | ||
| 193 | let fileUrl = invoice[0].url | ||
| 194 | if (!fileUrl.startsWith('http')) { | ||
| 195 | fileUrl = config.baseUrl_api + fileUrl | ||
| 196 | } | ||
| 197 | uni.previewImage({ | ||
| 198 | urls: [fileUrl], | ||
| 199 | success: () => { | ||
| 200 | console.log('previewImage success') | ||
| 201 | }, | ||
| 202 | fail: (err) => { | ||
| 203 | console.error('previewImage fail:', err) | ||
| 204 | uni.showToast({ title: '打开图片失败', icon: 'none' }) | ||
| 205 | } | ||
| 206 | }) | ||
| 207 | } | ||
| 208 | } catch (e) { | ||
| 209 | console.error('解析发票数据失败', e) | ||
| 210 | uni.showToast({ title: '解析发票数据失败', icon: 'none' }) | ||
| 211 | } | ||
| 212 | } | ||
| 213 | </script> | ||
| 214 | |||
| 215 | <style scoped lang="scss"> | ||
| 216 | // 颜色变量 | ||
| 217 | $primary-color: #C4121B; | ||
| 218 | $success-color: #52c41a; | ||
| 219 | $bg-color: #f5f5f5; | ||
| 220 | $card-bg: #ffffff; | ||
| 221 | $text-primary: #333; | ||
| 222 | $text-secondary: #666; | ||
| 223 | $text-placeholder: #999; | ||
| 224 | $border-color: #eee; | ||
| 225 | |||
| 226 | .detail-content { | ||
| 227 | padding: 20rpx; | ||
| 228 | background: $bg-color; | ||
| 229 | min-height: 100vh; | ||
| 230 | box-sizing: border-box; | ||
| 231 | } | ||
| 232 | |||
| 233 | .card { | ||
| 234 | background: $card-bg; | ||
| 235 | border-radius: 16rpx; | ||
| 236 | margin-bottom: 20rpx; | ||
| 237 | overflow: hidden; | ||
| 238 | box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); | ||
| 239 | } | ||
| 240 | |||
| 241 | .card-header { | ||
| 242 | display: flex; | ||
| 243 | justify-content: space-between; | ||
| 244 | align-items: center; | ||
| 245 | padding: 24rpx 24rpx 20rpx; | ||
| 246 | border-bottom: 1rpx solid $border-color; | ||
| 247 | |||
| 248 | .header-left { | ||
| 249 | font-size: 30rpx; | ||
| 250 | font-weight: 600; | ||
| 251 | color: $text-primary; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | .card-body { | ||
| 256 | padding: 8rpx 24rpx 24rpx; | ||
| 257 | } | ||
| 258 | |||
| 259 | .info-row { | ||
| 260 | display: flex; | ||
| 261 | justify-content: space-between; | ||
| 262 | align-items: center; | ||
| 263 | padding: 18rpx 0; | ||
| 264 | border-bottom: 1rpx solid #f5f5f5; | ||
| 265 | |||
| 266 | &:last-child { | ||
| 267 | border-bottom: none; | ||
| 268 | } | ||
| 269 | |||
| 270 | .label { | ||
| 271 | font-size: 28rpx; | ||
| 272 | color: $text-placeholder; | ||
| 273 | flex-shrink: 0; | ||
| 274 | width: 170rpx; | ||
| 275 | } | ||
| 276 | |||
| 277 | .value { | ||
| 278 | font-size: 28rpx; | ||
| 279 | color: $text-primary; | ||
| 280 | text-align: right; | ||
| 281 | flex: 1; | ||
| 282 | word-break: break-all; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | .text-red { | ||
| 287 | color: $primary-color !important; | ||
| 288 | font-weight: 600; | ||
| 289 | } | ||
| 290 | |||
| 291 | .text-primary { | ||
| 292 | color: #1561cb !important; | ||
| 293 | } | ||
| 294 | |||
| 295 | .state-tip { | ||
| 296 | text-align: center; | ||
| 297 | padding: 60rpx 0; | ||
| 298 | font-size: 26rpx; | ||
| 299 | color: $text-placeholder; | ||
| 300 | } | ||
| 301 | |||
| 302 | .payment-stat { | ||
| 303 | display: flex; | ||
| 304 | justify-content: space-between; | ||
| 305 | padding: 20rpx 24rpx; | ||
| 306 | background: #FFF0F0; | ||
| 307 | border-bottom: 1rpx solid $border-color; | ||
| 308 | font-size: 26rpx; | ||
| 309 | color: $text-secondary; | ||
| 310 | |||
| 311 | .stat-value { | ||
| 312 | color: $primary-color; | ||
| 313 | font-weight: 600; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | .payment-list { | ||
| 318 | padding: 0 24rpx 24rpx; | ||
| 319 | } | ||
| 320 | |||
| 321 | .payment-item { | ||
| 322 | border-radius: 12rpx; | ||
| 323 | padding: 24rpx; | ||
| 324 | margin-top: 16rpx; | ||
| 325 | border: 1rpx solid $border-color; | ||
| 326 | background: #fff; | ||
| 327 | |||
| 328 | .item-header { | ||
| 329 | display: flex; | ||
| 330 | align-items: center; | ||
| 331 | margin-bottom: 20rpx; | ||
| 332 | padding-bottom: 16rpx; | ||
| 333 | border-bottom: 1rpx solid #f5f5f5; | ||
| 334 | |||
| 335 | .item-index { | ||
| 336 | width: 40rpx; | ||
| 337 | height: 40rpx; | ||
| 338 | line-height: 40rpx; | ||
| 339 | text-align: center; | ||
| 340 | font-size: 22rpx; | ||
| 341 | color: #fff; | ||
| 342 | background: $primary-color; | ||
| 343 | border-radius: 50%; | ||
| 344 | margin-right: 16rpx; | ||
| 345 | } | ||
| 346 | |||
| 347 | .item-name { | ||
| 348 | flex: 1; | ||
| 349 | font-size: 28rpx; | ||
| 350 | font-weight: 600; | ||
| 351 | color: $text-primary; | ||
| 352 | } | ||
| 353 | |||
| 354 | .status-tag { | ||
| 355 | font-size: 22rpx; | ||
| 356 | padding: 4rpx 16rpx; | ||
| 357 | border-radius: 20rpx; | ||
| 358 | |||
| 359 | &.passed { | ||
| 360 | background: rgba($success-color, 0.1); | ||
| 361 | color: $success-color; | ||
| 362 | } | ||
| 363 | |||
| 364 | &.pending { | ||
| 365 | background: rgba($primary-color, 0.1); | ||
| 366 | color: $primary-color; | ||
| 367 | } | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | .item-body { | ||
| 372 | .info-line { | ||
| 373 | display: flex; | ||
| 374 | justify-content: space-between; | ||
| 375 | align-items: center; | ||
| 376 | padding: 12rpx 0; | ||
| 377 | border-bottom: 1rpx solid #f5f5f5; | ||
| 378 | |||
| 379 | &:last-child { | ||
| 380 | border-bottom: none; | ||
| 381 | } | ||
| 382 | |||
| 383 | .info-label { | ||
| 384 | font-size: 26rpx; | ||
| 385 | color: $text-placeholder; | ||
| 386 | flex-shrink: 0; | ||
| 387 | } | ||
| 388 | |||
| 389 | .info-value { | ||
| 390 | font-size: 26rpx; | ||
| 391 | color: $text-primary; | ||
| 392 | text-align: right; | ||
| 393 | flex: 1; | ||
| 394 | margin-left: 24rpx; | ||
| 395 | word-break: break-all; | ||
| 396 | } | ||
| 397 | } | ||
| 398 | } | ||
| 399 | } | ||
| 400 | </style> |
| ... | @@ -63,7 +63,7 @@ | ... | @@ -63,7 +63,7 @@ |
| 63 | <button class="btn-red" @click="login">登录</button> | 63 | <button class="btn-red" @click="login">登录</button> |
| 64 | </view> | 64 | </view> |
| 65 | <view class="center-item"> | 65 | <view class="center-item"> |
| 66 | <text class="text-red" @click="goRegister">没有账号,去注册</text> | 66 | <button class="btn-red btn-register" @click="goRegister">没有账号,去注册</button> |
| 67 | </view> | 67 | </view> |
| 68 | </view> | 68 | </view> |
| 69 | <view class="wNumber"> | 69 | <view class="wNumber"> |
| ... | @@ -84,6 +84,25 @@ | ... | @@ -84,6 +84,25 @@ |
| 84 | <image v-else src="@/static/login/xz2@2x.png"></image> | 84 | <image v-else src="@/static/login/xz2@2x.png"></image> |
| 85 | <view>登录即代表您同意<text>《用户协议》</text><text>《隐私策略》</text></view> --> | 85 | <view>登录即代表您同意<text>《用户协议》</text><text>《隐私策略》</text></view> --> |
| 86 | </view> | 86 | </view> |
| 87 | |||
| 88 | <!-- 注册提示弹框 --> | ||
| 89 | <uni-popup ref="registerPopup" type="center" :mask-click="false"> | ||
| 90 | <view class="register-popup"> | ||
| 91 | <view class="popup-title">注册提示</view> | ||
| 92 | <view class="popup-content"> | ||
| 93 | <view class="popup-text">请准备以下材料,以便顺利完成注册</view> | ||
| 94 | <view class="popup-list"> | ||
| 95 | <text>1. 单位营业执照(清晰照片)</text> | ||
| 96 | <text>2. 法人身份证正反面照片(清晰照片)</text> | ||
| 97 | <text>3. 单位营业执照(清晰照片)</text> | ||
| 98 | </view> | ||
| 99 | </view> | ||
| 100 | <view class="popup-btns"> | ||
| 101 | <view class="popup-btn cancel" @click="closeRegisterPopup">取消</view> | ||
| 102 | <view class="popup-btn confirm" @click="confirmRegister">确定</view> | ||
| 103 | </view> | ||
| 104 | </view> | ||
| 105 | </uni-popup> | ||
| 87 | </view> | 106 | </view> |
| 88 | </template> | 107 | </template> |
| 89 | 108 | ||
| ... | @@ -107,6 +126,7 @@ const agree = ref(false) | ... | @@ -107,6 +126,7 @@ const agree = ref(false) |
| 107 | const isRember = ref(true) | 126 | const isRember = ref(true) |
| 108 | const loading = ref(false) | 127 | const loading = ref(false) |
| 109 | const codeUrl = ref(null) | 128 | const codeUrl = ref(null) |
| 129 | const registerPopup = ref(null) | ||
| 110 | const inputstyle = ref({ | 130 | const inputstyle = ref({ |
| 111 | borderColor: 'transparent', | 131 | borderColor: 'transparent', |
| 112 | fontSize: '30rpx' | 132 | fontSize: '30rpx' |
| ... | @@ -226,9 +246,17 @@ function login() { | ... | @@ -226,9 +246,17 @@ function login() { |
| 226 | } | 246 | } |
| 227 | 247 | ||
| 228 | function goRegister() { | 248 | function goRegister() { |
| 229 | const path = '/login/register' | 249 | registerPopup.value.open() |
| 250 | } | ||
| 251 | |||
| 252 | function closeRegisterPopup() { | ||
| 253 | registerPopup.value.close() | ||
| 254 | } | ||
| 255 | |||
| 256 | function confirmRegister() { | ||
| 257 | registerPopup.value.close() | ||
| 230 | uni.navigateTo({ | 258 | uni.navigateTo({ |
| 231 | url: path | 259 | url: '/login/register' |
| 232 | }) | 260 | }) |
| 233 | } | 261 | } |
| 234 | 262 | ||
| ... | @@ -517,4 +545,78 @@ function call(num) { | ... | @@ -517,4 +545,78 @@ function call(num) { |
| 517 | margin-right: 20rpx; | 545 | margin-right: 20rpx; |
| 518 | } | 546 | } |
| 519 | } | 547 | } |
| 548 | |||
| 549 | /* 注册按钮 */ | ||
| 550 | .btn-register { | ||
| 551 | border-radius: 40rpx; | ||
| 552 | width: 600rpx; | ||
| 553 | line-height: 80rpx; | ||
| 554 | font-size: 36rpx; | ||
| 555 | background: #fff; | ||
| 556 | color: #AD181F; | ||
| 557 | border: 1rpx solid #AD181F; | ||
| 558 | margin: 0; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* 注册提示弹框 */ | ||
| 562 | .register-popup { | ||
| 563 | width: 600rpx; | ||
| 564 | background: #ffffff; | ||
| 565 | border-radius: 24rpx; | ||
| 566 | overflow: hidden; | ||
| 567 | } | ||
| 568 | |||
| 569 | .popup-title { | ||
| 570 | font-size: 32rpx; | ||
| 571 | font-weight: 500; | ||
| 572 | color: #333; | ||
| 573 | text-align: center; | ||
| 574 | padding: 40rpx 30rpx 20rpx; | ||
| 575 | } | ||
| 576 | |||
| 577 | .popup-content { | ||
| 578 | padding: 20rpx 30rpx 40rpx; | ||
| 579 | } | ||
| 580 | |||
| 581 | .popup-text { | ||
| 582 | font-size: 28rpx; | ||
| 583 | color: #333; | ||
| 584 | margin-bottom: 20rpx; | ||
| 585 | } | ||
| 586 | |||
| 587 | .popup-list { | ||
| 588 | display: flex; | ||
| 589 | flex-direction: column; | ||
| 590 | gap: 16rpx; | ||
| 591 | padding-left: 10rpx; | ||
| 592 | } | ||
| 593 | |||
| 594 | .popup-list text { | ||
| 595 | font-size: 26rpx; | ||
| 596 | color: #666; | ||
| 597 | line-height: 1.5; | ||
| 598 | } | ||
| 599 | |||
| 600 | .popup-btns { | ||
| 601 | display: flex; | ||
| 602 | border-top: 1rpx solid #eee; | ||
| 603 | } | ||
| 604 | |||
| 605 | .popup-btn { | ||
| 606 | flex: 1; | ||
| 607 | height: 100rpx; | ||
| 608 | line-height: 100rpx; | ||
| 609 | text-align: center; | ||
| 610 | font-size: 30rpx; | ||
| 611 | } | ||
| 612 | |||
| 613 | .popup-btn.cancel { | ||
| 614 | color: #666; | ||
| 615 | border-right: 1rpx solid #eee; | ||
| 616 | } | ||
| 617 | |||
| 618 | .popup-btn.confirm { | ||
| 619 | color: #AD181F; | ||
| 620 | font-weight: 500; | ||
| 621 | } | ||
| 520 | </style> | 622 | </style> | ... | ... |
| ... | @@ -12,19 +12,19 @@ | ... | @@ -12,19 +12,19 @@ |
| 12 | <form> | 12 | <form> |
| 13 | <view class="round-input-item"> | 13 | <view class="round-input-item"> |
| 14 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag01@2x.png'"></image> | 14 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag01@2x.png'"></image> |
| 15 | <uni-easyinput :styles="inputstyle" v-model="registerForm.telNo" placeholder="请输入手机号" /> | 15 | <uni-easyinput :styles="inputstyle" v-model="registerForm.telNo" placeholder="请输入手机号" @blur="validateTelNo" /> |
| 16 | </view> | 16 | </view> |
| 17 | <view class="round-input-item"> | 17 | <view class="round-input-item"> |
| 18 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag02@2x.png'"></image> | 18 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag02@2x.png'"></image> |
| 19 | <uni-easyinput :styles="inputstyle" v-model="registerForm.password" placeholder="密码" type="password"/> | 19 | <uni-easyinput :styles="inputstyle" v-model="registerForm.password" placeholder="密码" type="password" @blur="validatePassword" /> |
| 20 | </view> | 20 | </view> |
| 21 | <view class="round-input-item"> | 21 | <view class="round-input-item"> |
| 22 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag03@2x.png'"></image> | 22 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag03@2x.png'"></image> |
| 23 | <uni-easyinput :styles="inputstyle" v-model="registerForm.password2" placeholder="确认密码" type="password"/> | 23 | <uni-easyinput :styles="inputstyle" v-model="registerForm.password2" placeholder="确认密码" type="password" @blur="validatePassword2" /> |
| 24 | </view> | 24 | </view> |
| 25 | <view class="round-input-item"> | 25 | <view class="round-input-item"> |
| 26 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag03@2x.png'"></image> | 26 | <image class="icon" :src="config.baseUrl_api+'/fs/static/login/tag03@2x.png'"></image> |
| 27 | <uni-easyinput :styles="inputstyle" placeholder="图形验证码" v-model="registerForm.captcha" /> | 27 | <uni-easyinput :styles="inputstyle" placeholder="图形验证码" v-model="registerForm.captcha" @blur="validateCaptcha" /> |
| 28 | <image :src="codeUrl" @click="getCode" /> | 28 | <image :src="codeUrl" @click="getCode" /> |
| 29 | </view> | 29 | </view> |
| 30 | <view class="round-input-item"> | 30 | <view class="round-input-item"> |
| ... | @@ -138,12 +138,20 @@ function register() { | ... | @@ -138,12 +138,20 @@ function register() { |
| 138 | 138 | ||
| 139 | groupMemberRegister(registerForm.value) | 139 | groupMemberRegister(registerForm.value) |
| 140 | .then((res) => { | 140 | .then((res) => { |
| 141 | uni.showToast({ | 141 | uni.showModal({ |
| 142 | title: `恭喜你,您的账号 ${registerForm.value.telNo} 注册成功!`, | 142 | title: '提示', |
| 143 | icon: 'none' | 143 | content: `恭喜你,您的账号 ${registerForm.value.telNo} 注册成功!`, |
| 144 | }) | 144 | confirmText: '去登录', |
| 145 | cancelText: '取消', | ||
| 146 | success: (res) => { | ||
| 147 | if (res.confirm) { | ||
| 145 | registerForm.value = {} | 148 | registerForm.value = {} |
| 146 | setTimeout(goLogin, 2000) | 149 | goLogin() |
| 150 | } else { | ||
| 151 | // 取消,保持当前页面 | ||
| 152 | } | ||
| 153 | } | ||
| 154 | }) | ||
| 147 | }) | 155 | }) |
| 148 | } | 156 | } |
| 149 | 157 | ||
| ... | @@ -160,6 +168,58 @@ function validPassword(pwd) { | ... | @@ -160,6 +168,58 @@ function validPassword(pwd) { |
| 160 | return (lowerRegex.test(pwd) && upperRegex.test(pwd) && digitRegex.test(pwd) && symbolRegex.test(pwd) && specific.test(pwd)) | 168 | return (lowerRegex.test(pwd) && upperRegex.test(pwd) && digitRegex.test(pwd) && symbolRegex.test(pwd) && specific.test(pwd)) |
| 161 | } | 169 | } |
| 162 | 170 | ||
| 171 | // 手机号校验 | ||
| 172 | function validateTelNo() { | ||
| 173 | const telNo = registerForm.value.telNo | ||
| 174 | if (!telNo) { | ||
| 175 | uni.showToast({ title: '手机号不能为空', icon: 'none' }) | ||
| 176 | return false | ||
| 177 | } | ||
| 178 | if (!/^1[3-9]\d{9}$/.test(telNo)) { | ||
| 179 | uni.showToast({ title: '手机号格式不正确', icon: 'none' }) | ||
| 180 | return false | ||
| 181 | } | ||
| 182 | return true | ||
| 183 | } | ||
| 184 | |||
| 185 | // 密码校验 | ||
| 186 | function validatePassword() { | ||
| 187 | const password = registerForm.value.password | ||
| 188 | if (!password) { | ||
| 189 | uni.showToast({ title: '密码不能为空', icon: 'none' }) | ||
| 190 | return false | ||
| 191 | } | ||
| 192 | if (!validPassword(password)) { | ||
| 193 | uni.showToast({ title: '密码必须为8~18位大小写字母、数字和特殊符号组合', icon: 'none', duration: 3000 }) | ||
| 194 | return false | ||
| 195 | } | ||
| 196 | return true | ||
| 197 | } | ||
| 198 | |||
| 199 | // 确认密码校验 | ||
| 200 | function validatePassword2() { | ||
| 201 | const password2 = registerForm.value.password2 | ||
| 202 | if (!password2) { | ||
| 203 | uni.showToast({ title: '确认密码不能为空', icon: 'none' }) | ||
| 204 | return false | ||
| 205 | } | ||
| 206 | if (registerForm.value.password && password2 !== registerForm.value.password) { | ||
| 207 | uni.showToast({ title: '两次密码不一致', icon: 'none' }) | ||
| 208 | return false | ||
| 209 | } | ||
| 210 | return true | ||
| 211 | } | ||
| 212 | |||
| 213 | // 图形验证码校验 | ||
| 214 | function validateCaptcha() { | ||
| 215 | const captcha = registerForm.value.captcha | ||
| 216 | if (!captcha) { | ||
| 217 | uni.showToast({ title: '图形验证码不能为空', icon: 'none' }) | ||
| 218 | return false | ||
| 219 | } | ||
| 220 | return true | ||
| 221 | } | ||
| 222 | |||
| 163 | function goLogin() { | 223 | function goLogin() { |
| 164 | let path = '/login/loginC'; | 224 | let path = '/login/loginC'; |
| 165 | uni.navigateTo({ | 225 | uni.navigateTo({ | ... | ... |
| ... | @@ -51,7 +51,7 @@ | ... | @@ -51,7 +51,7 @@ |
| 51 | </uni-list-item> | 51 | </uni-list-item> |
| 52 | <uni-list-item v-if="form.menCode" :rightText="form.menCode" title="会员编号"/> | 52 | <uni-list-item v-if="form.menCode" :rightText="form.menCode" title="会员编号"/> |
| 53 | <uni-list-item :rightText="form.name" title="机构名称"/> | 53 | <uni-list-item :rightText="form.name" title="机构名称"/> |
| 54 | <uni-list-item title="所属省份"> | 54 | <!-- <uni-list-item title="所属省份"> |
| 55 | <template v-slot:footer> | 55 | <template v-slot:footer> |
| 56 | <view class="frrr"> | 56 | <view class="frrr"> |
| 57 | <uni-data-picker v-model="form.belongProvinceId" :clear-icon="false" :localdata="options" | 57 | <uni-data-picker v-model="form.belongProvinceId" :clear-icon="false" :localdata="options" |
| ... | @@ -59,7 +59,7 @@ | ... | @@ -59,7 +59,7 @@ |
| 59 | </uni-data-picker> | 59 | </uni-data-picker> |
| 60 | </view> | 60 | </view> |
| 61 | </template> | 61 | </template> |
| 62 | </uni-list-item> | 62 | </uni-list-item> --> |
| 63 | <uni-list-item | 63 | <uni-list-item |
| 64 | v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3&&newResult||form.associateId&&form.associateId>0||activeStatus==1" | 64 | v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3&&newResult||form.associateId&&form.associateId>0||activeStatus==1" |
| 65 | :rightText="form.creditCode" | 65 | :rightText="form.creditCode" |
| ... | @@ -96,7 +96,8 @@ | ... | @@ -96,7 +96,8 @@ |
| 96 | </view> | 96 | </view> |
| 97 | </template> | 97 | </template> |
| 98 | </uni-list-item> | 98 | </uni-list-item> |
| 99 | 99 | <uni-list-item :rightText="form.companyName||'--'" title="营业执照名称"/> | |
| 100 | <uni-list-item :rightText="form.creditCode||'--'" title="社会信用代码"/> | ||
| 100 | <uni-list-item clickable title="营业执照"> | 101 | <uni-list-item clickable title="营业执照"> |
| 101 | <template v-slot:footer> | 102 | <template v-slot:footer> |
| 102 | <view v-if="form.businessLicenseArr&&form.businessLicenseArr?.length>0" class="frrr" | 103 | <view v-if="form.businessLicenseArr&&form.businessLicenseArr?.length>0" class="frrr" | ... | ... |
| ... | @@ -96,13 +96,21 @@ async function getList() { | ... | @@ -96,13 +96,21 @@ async function getList() { |
| 96 | return uni.showToast({title: '请输入考官编号', icon: 'none'}) | 96 | return uni.showToast({title: '请输入考官编号', icon: 'none'}) |
| 97 | 97 | ||
| 98 | loading.value = true | 98 | loading.value = true |
| 99 | try { | ||
| 99 | const res = await api.getCoachList(queryParams.value) | 100 | const res = await api.getCoachList(queryParams.value) |
| 100 | infoList.value = res.rows | 101 | infoList.value = res.rows || [] |
| 101 | total.value = res.total | 102 | total.value = res.total || 0 |
| 103 | } catch (err) { | ||
| 104 | console.error('获取考官列表失败:', err) | ||
| 105 | infoList.value = [] | ||
| 106 | total.value = 0 | ||
| 107 | } finally { | ||
| 102 | loading.value = false | 108 | loading.value = false |
| 109 | } | ||
| 103 | 110 | ||
| 111 | // 空数组提示 | ||
| 104 | if (infoList.value.length === 0) { | 112 | if (infoList.value.length === 0) { |
| 105 | uni.showToast({title: '请核实考官编号、有效期及归属地!', icon: 'none'}) | 113 | uni.showToast({title: '请核实考官编号、有效期及归属地', icon: 'none', duration: 2000}) |
| 106 | } | 114 | } |
| 107 | } | 115 | } |
| 108 | 116 | ||
| ... | @@ -163,7 +171,8 @@ async function confirmAddExpireExaminer() { | ... | @@ -163,7 +171,8 @@ async function confirmAddExpireExaminer() { |
| 163 | uni.navigateBack({delta: 1}) | 171 | uni.navigateBack({delta: 1}) |
| 164 | } catch (err) { | 172 | } catch (err) { |
| 165 | console.log(err) | 173 | console.log(err) |
| 166 | uni.showToast({title: '添加失败', icon: 'none'}) | 174 | const errMsg = err?.data?.msg || err?.msg || '添加失败' |
| 175 | uni.showToast({title: errMsg, icon: 'none', duration: 3000}) | ||
| 167 | } finally { | 176 | } finally { |
| 168 | expirePopup.value.close() | 177 | expirePopup.value.close() |
| 169 | currentExpireItem.value = null | 178 | currentExpireItem.value = null | ... | ... |
| ... | @@ -18,10 +18,10 @@ | ... | @@ -18,10 +18,10 @@ |
| 18 | <uni-forms-item label="机构名称" required> | 18 | <uni-forms-item label="机构名称" required> |
| 19 | <uni-easyinput v-model="form.name" :disabled="type" placeholder="机构名称" /></uni-forms-item> | 19 | <uni-easyinput v-model="form.name" :disabled="type" placeholder="机构名称" /></uni-forms-item> |
| 20 | 20 | ||
| 21 | <uni-forms-item label="所属省份" required> | 21 | <!-- <uni-forms-item label="所属省份" required> |
| 22 | <uni-data-select :clear="false" :disabled="type&&(belongProvinceId||belongProvinceId==0)" | 22 | <uni-data-select :clear="false" :disabled="type&&(belongProvinceId||belongProvinceId==0)" |
| 23 | v-model="form.belongProvinceId" :localdata="regionsList"></uni-data-select> | 23 | v-model="form.belongProvinceId" :localdata="regionsList"></uni-data-select> |
| 24 | </uni-forms-item> | 24 | </uni-forms-item> --> |
| 25 | <uni-forms-item label="社会信用代码" required> | 25 | <uni-forms-item label="社会信用代码" required> |
| 26 | <uni-easyinput v-model="form.creditCode" :disabled="type&&!!creditCode&&newResult" /> | 26 | <uni-easyinput v-model="form.creditCode" :disabled="type&&!!creditCode&&newResult" /> |
| 27 | </uni-forms-item> | 27 | </uni-forms-item> |
| ... | @@ -43,13 +43,11 @@ | ... | @@ -43,13 +43,11 @@ |
| 43 | <uni-forms-item label="法人证件号" required> | 43 | <uni-forms-item label="法人证件号" required> |
| 44 | <uni-easyinput v-model="form.legalIdcCode" /> | 44 | <uni-easyinput v-model="form.legalIdcCode" /> |
| 45 | </uni-forms-item> | 45 | </uni-forms-item> |
| 46 | <uni-forms-item label="营业执照名称" required> | ||
| 47 | <uni-easyinput v-model="form.companyName" /> | ||
| 48 | </uni-forms-item> | ||
| 49 | 46 | ||
| 50 | <uni-forms-item v-if="form.deptType==6&&activeStatus!= 0" label="是否申请考点" required> | 47 | |
| 48 | <!-- <uni-forms-item v-if="form.deptType==6&&activeStatus!= 0" label="是否申请考点" required> | ||
| 51 | <uni-data-checkbox v-model="form.applyPoints" :localdata="yesno" /> | 49 | <uni-data-checkbox v-model="form.applyPoints" :localdata="yesno" /> |
| 52 | </uni-forms-item> | 50 | </uni-forms-item> --> |
| 53 | 51 | ||
| 54 | <uni-forms-item label="法人身份证" required> | 52 | <uni-forms-item label="法人身份证" required> |
| 55 | <view class="imgArea"> | 53 | <view class="imgArea"> |
| ... | @@ -63,11 +61,17 @@ | ... | @@ -63,11 +61,17 @@ |
| 63 | </uni-file-picker> | 61 | </uni-file-picker> |
| 64 | </view> | 62 | </view> |
| 65 | </uni-forms-item> | 63 | </uni-forms-item> |
| 64 | <uni-forms-item label="营业执照名称" required> | ||
| 65 | <uni-easyinput v-model="form.companyName" /> | ||
| 66 | </uni-forms-item> | ||
| 66 | <uni-forms-item label="营业执照" required> | 67 | <uni-forms-item label="营业执照" required> |
| 67 | <uni-file-picker limit="1" v-model="businessLicenseArr" file-extname="png,jpg,jpeg,pdf" | 68 | <uni-file-picker limit="1" v-model="businessLicenseArr" file-extname="png,jpg,jpeg,pdf" |
| 68 | file-mediatype="all" @select="selectFile" @delete="delSupplementFile"></uni-file-picker> | 69 | file-mediatype="all" @select="selectFile" @delete="delSupplementFile"></uni-file-picker> |
| 69 | |||
| 70 | </uni-forms-item> | 70 | </uni-forms-item> |
| 71 | <!-- <uni-forms-item label="社会信用代码" required> | ||
| 72 | <uni-file-picker limit="1" v-model="businessLicenseArr" file-extname="png,jpg,jpeg,pdf" | ||
| 73 | file-mediatype="all" @select="selectFile" @delete="delSupplementFile"></uni-file-picker> | ||
| 74 | </uni-forms-item> --> | ||
| 71 | <uni-forms-item label="机构照片" required> | 75 | <uni-forms-item label="机构照片" required> |
| 72 | <uni-file-picker v-model="picArrR" limit="3" mode="grid" file-mediatype="image" | 76 | <uni-file-picker v-model="picArrR" limit="3" mode="grid" file-mediatype="image" |
| 73 | @select="upPicArr" @delete="delpicArr"> | 77 | @select="upPicArr" @delete="delpicArr"> | ... | ... |
| ... | @@ -240,6 +240,13 @@ | ... | @@ -240,6 +240,13 @@ |
| 240 | "navigationBarTitleText": "我的订单", | 240 | "navigationBarTitleText": "我的订单", |
| 241 | "enablePullDownRefresh": false | 241 | "enablePullDownRefresh": false |
| 242 | } | 242 | } |
| 243 | }, | ||
| 244 | { | ||
| 245 | "path": "certPreview", | ||
| 246 | "style": { | ||
| 247 | "navigationBarTitleText": "电子会员证", | ||
| 248 | "enablePullDownRefresh": false | ||
| 249 | } | ||
| 243 | } | 250 | } |
| 244 | ] | 251 | ] |
| 245 | }, | 252 | }, |
| ... | @@ -876,6 +883,20 @@ | ... | @@ -876,6 +883,20 @@ |
| 876 | "navigationBarTitleText": "考生信息", | 883 | "navigationBarTitleText": "考生信息", |
| 877 | "enablePullDownRefresh": false | 884 | "enablePullDownRefresh": false |
| 878 | } | 885 | } |
| 886 | }, | ||
| 887 | { | ||
| 888 | "path": "settlementAudit", | ||
| 889 | "style": { | ||
| 890 | "navigationBarTitleText": "结算审核", | ||
| 891 | "enablePullDownRefresh": false | ||
| 892 | } | ||
| 893 | }, | ||
| 894 | { | ||
| 895 | "path": "settlementView", | ||
| 896 | "style": { | ||
| 897 | "navigationBarTitleText": "结算详情", | ||
| 898 | "enablePullDownRefresh": false | ||
| 899 | } | ||
| 879 | } | 900 | } |
| 880 | ] | 901 | ] |
| 881 | }, { | 902 | }, { | ... | ... |
| ... | @@ -239,18 +239,23 @@ | ... | @@ -239,18 +239,23 @@ |
| 239 | <image :src="config.baseUrl_api+'/fs/static/icon/2.png'"/> | 239 | <image :src="config.baseUrl_api+'/fs/static/icon/2.png'"/> |
| 240 | 考试审核 | 240 | 考试审核 |
| 241 | </view> | 241 | </view> |
| 242 | <view @click="goPath('/level/ztx/cert?type=1')"> | ||
| 243 | <image :src="config.baseUrl_api+'/fs/static/icon/18.png'"/> | ||
| 244 | 证书发布 | ||
| 245 | </view> | ||
| 246 | <view @click="goPath('/level/ztx/mail')"> | 242 | <view @click="goPath('/level/ztx/mail')"> |
| 247 | <image :src="config.baseUrl_api+'/fs/static/icon/3.png'"/> | 243 | <image :src="config.baseUrl_api+'/fs/static/icon/3.png'"/> |
| 248 | 证书邮寄 | 244 | 证书邮寄 |
| 249 | </view> | 245 | </view> |
| 246 | <view @click="goPath('/level/ztx/cert?type=1')"> | ||
| 247 | <image :src="config.baseUrl_api+'/fs/static/icon/18.png'"/> | ||
| 248 | 证书发布 | ||
| 249 | </view> | ||
| 250 | <view @click="goPath('/personalVip/changeLevelAudit')"> | 250 | <view @click="goPath('/personalVip/changeLevelAudit')"> |
| 251 | <image :src="config.baseUrl_api+'/fs/static/icon/26.png'"/> | 251 | <image :src="config.baseUrl_api+'/fs/static/icon/26.png'"/> |
| 252 | 变更审核 | 252 | 变更审核 |
| 253 | </view> | 253 | </view> |
| 254 | <view @click="goPath('/level/settlementAudit')"> | ||
| 255 | <image :src="config.baseUrl_api+'/fs/static/icon/10.png'"/> | ||
| 256 | 结算审核 | ||
| 257 | </view> | ||
| 258 | |||
| 254 | <view @click="goPath('/personalVip/order?type=2')"> | 259 | <view @click="goPath('/personalVip/order?type=2')"> |
| 255 | <image :src="config.baseUrl_api+'/fs/static/icon/6.png'"/> | 260 | <image :src="config.baseUrl_api+'/fs/static/icon/6.png'"/> |
| 256 | 订单列表 | 261 | 订单列表 | ... | ... |
| ... | @@ -284,7 +284,7 @@ | ... | @@ -284,7 +284,7 @@ |
| 284 | getDetail() | 284 | getDetail() |
| 285 | getRegionsList() | 285 | getRegionsList() |
| 286 | 286 | ||
| 287 | getMyMemberCertUnitFeeApi() | 287 | // getMyMemberCertUnitFeeApi() |
| 288 | canUseDiscountApi() | 288 | canUseDiscountApi() |
| 289 | getZtxDiscountPolicyApi() | 289 | getZtxDiscountPolicyApi() |
| 290 | getMyStatusAPI() | 290 | getMyStatusAPI() | ... | ... |
| ... | @@ -176,7 +176,7 @@ | ... | @@ -176,7 +176,7 @@ |
| 176 | // 审核 | 176 | // 审核 |
| 177 | function goApproval(item) { | 177 | function goApproval(item) { |
| 178 | uni.navigateTo({ | 178 | uni.navigateTo({ |
| 179 | url: `/pages/rank/scoreAudit?ids=${item.examId}&pageType=2` | 179 | url: `/pages/rank/scoreAudit?ids=${item.examId}&pageType=1` |
| 180 | }) | 180 | }) |
| 181 | } | 181 | } |
| 182 | </script> | 182 | </script> | ... | ... |
| ... | @@ -87,12 +87,16 @@ | ... | @@ -87,12 +87,16 @@ |
| 87 | delete params.reason | 87 | delete params.reason |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | |||
| 90 | try { | 91 | try { |
| 91 | // 根据 pageType 自动切换接口 | 92 | // 根据 pageType 1 审核考试 2 审核成绩 3 结算审核 |
| 92 | if (pageType.value == '1') { | 93 | if (pageType.value == '1') { |
| 93 | await api.auditDuanExam(params); | 94 | await api.auditDuanExam(params); |
| 94 | } else if (pageType.value == '2') { | 95 | } else if (pageType.value == '2') { |
| 95 | await api.auditDuanScore(params); | 96 | await api.auditDuanScore(params); |
| 97 | } else if (pageType.value == '3') { | ||
| 98 | params.type = '1' // 结算审核固定 type = 1 | ||
| 99 | await api.settlementAudit(params); | ||
| 96 | } else { | 100 | } else { |
| 97 | uni.showToast({ title: '页面类型错误', icon: 'none' }); | 101 | uni.showToast({ title: '页面类型错误', icon: 'none' }); |
| 98 | submitting.value = false; | 102 | submitting.value = false; | ... | ... |
| ... | @@ -51,6 +51,14 @@ | ... | @@ -51,6 +51,14 @@ |
| 51 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" | 51 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" |
| 52 | v-model="baseFormData.phone" placeholder="请输入联系方式" /> | 52 | v-model="baseFormData.phone" placeholder="请输入联系方式" /> |
| 53 | </uni-forms-item> | 53 | </uni-forms-item> |
| 54 | <uni-forms-item label="会员编号" name="perCode" v-if="baseFormData.perCode"> | ||
| 55 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" | ||
| 56 | v-model="baseFormData.perCode" placeholder="请输入会员编号" /> | ||
| 57 | </uni-forms-item> | ||
| 58 | <uni-forms-item label="会员有效期" name="validityDate" v-if="baseFormData.validityDate"> | ||
| 59 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" | ||
| 60 | v-model="baseFormData.validityDate" placeholder="请输入会员有效期" /> | ||
| 61 | </uni-forms-item> | ||
| 54 | 62 | ||
| 55 | 63 | ||
| 56 | <!-- <uni-forms-item label="所在地区"> | 64 | <!-- <uni-forms-item label="所在地区"> |
| ... | @@ -148,6 +156,8 @@ | ... | @@ -148,6 +156,8 @@ |
| 148 | sex: '', | 156 | sex: '', |
| 149 | idcType: '0', | 157 | idcType: '0', |
| 150 | perType: '1', // (1:个人会员;2:教练;3:考官;4:裁判;5:临时会员;) | 158 | perType: '1', // (1:个人会员;2:教练;3:考官;4:裁判;5:临时会员;) |
| 159 | perCode:'', | ||
| 160 | validityDate:'' | ||
| 151 | }) | 161 | }) |
| 152 | const items = ref(['身份证添加', '证件照录入']) | 162 | const items = ref(['身份证添加', '证件照录入']) |
| 153 | const idcTypeList = ref([{ | 163 | const idcTypeList = ref([{ |
| ... | @@ -199,7 +209,7 @@ | ... | @@ -199,7 +209,7 @@ |
| 199 | height: '316rpx' | 209 | height: '316rpx' |
| 200 | }); | 210 | }); |
| 201 | 211 | ||
| 202 | onLoad((option) => { | 212 | onLoad(async (option) => { |
| 203 | if (option.tab == '1') { | 213 | if (option.tab == '1') { |
| 204 | current.value = 1 | 214 | current.value = 1 |
| 205 | baseFormData.value.sourceFlag = 1 | 215 | baseFormData.value.sourceFlag = 1 |
| ... | @@ -210,8 +220,11 @@ | ... | @@ -210,8 +220,11 @@ |
| 210 | disabledName.value = true | 220 | disabledName.value = true |
| 211 | } | 221 | } |
| 212 | } | 222 | } |
| 213 | // console.log(current.value,option.tab) | 223 | // 如果传入了 perId,预填会员信息 |
| 214 | // getRegionsList() | 224 | if (option.perId) { |
| 225 | perId.value = option.perId | ||
| 226 | await fetchMemberInfo(option.perId) | ||
| 227 | } | ||
| 215 | }) | 228 | }) |
| 216 | 229 | ||
| 217 | onMounted(() => { | 230 | onMounted(() => { |
| ... | @@ -227,6 +240,40 @@ | ... | @@ -227,6 +240,40 @@ |
| 227 | }) | 240 | }) |
| 228 | } | 241 | } |
| 229 | 242 | ||
| 243 | // 根据 perId 获取会员信息预填表单 | ||
| 244 | async function fetchMemberInfo(id) { | ||
| 245 | if (!id) return | ||
| 246 | uni.showLoading({ title: '加载中...' }) | ||
| 247 | try { | ||
| 248 | const res = await api.getInfo(id) | ||
| 249 | const data = res.data || {} | ||
| 250 | baseFormData.value.name = data.name || '' | ||
| 251 | baseFormData.value.idcCode = data.idcCode || '' | ||
| 252 | baseFormData.value.idcType = data.idcType || '0' | ||
| 253 | baseFormData.value.sex = data.sex || '' | ||
| 254 | baseFormData.value.birth = data.birth || '' | ||
| 255 | baseFormData.value.phone = data.phone || '' | ||
| 256 | baseFormData.value.perCode = data.perCode || '' | ||
| 257 | baseFormData.value.validityDate = data.validityDate ? data.validityDate.slice(0, 10) : '' | ||
| 258 | // 照片处理 | ||
| 259 | if (data.photo2) { | ||
| 260 | const photoUrl = data.photo2.indexOf('http') === -1 ? config.baseUrl_api + data.photo2 : data.photo2 | ||
| 261 | photoArr.value = { | ||
| 262 | url: photoUrl, | ||
| 263 | name: '头像', | ||
| 264 | extname: 'jpg' | ||
| 265 | } | ||
| 266 | baseFormData.value.photo = data.photo | ||
| 267 | baseFormData.value.photo2 = data.photo2 | ||
| 268 | } | ||
| 269 | disabledName.value = true | ||
| 270 | } catch (e) { | ||
| 271 | console.error('获取会员信息失败', e) | ||
| 272 | } finally { | ||
| 273 | uni.hideLoading() | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 230 | function onClickItem(e) { | 277 | function onClickItem(e) { |
| 231 | if (current.value != e.currentIndex) { | 278 | if (current.value != e.currentIndex) { |
| 232 | current.value = e.currentIndex | 279 | current.value = e.currentIndex |
| ... | @@ -277,6 +324,8 @@ | ... | @@ -277,6 +324,8 @@ |
| 277 | baseFormData.value.idcCode = res.data.code | 324 | baseFormData.value.idcCode = res.data.code |
| 278 | baseFormData.value.name = res.data.name | 325 | baseFormData.value.name = res.data.name |
| 279 | baseFormData.value.uuid = res.data.uuid | 326 | baseFormData.value.uuid = res.data.uuid |
| 327 | baseFormData.value.perCode = res.data.perCode ||'' | ||
| 328 | baseFormData.value.validityDate = res.data.validityDate?.slice(0,10) //去掉时分秒 | ||
| 280 | // baseFormData.value.cityId = res.data.cityId | 329 | // baseFormData.value.cityId = res.data.cityId |
| 281 | // baseFormData.value.address = res.data.address | 330 | // baseFormData.value.address = res.data.address |
| 282 | } else { | 331 | } else { |
| ... | @@ -363,6 +412,8 @@ | ... | @@ -363,6 +412,8 @@ |
| 363 | baseFormData.value.birth = res.data.birth | 412 | baseFormData.value.birth = res.data.birth |
| 364 | baseFormData.value.name = res.data.name | 413 | baseFormData.value.name = res.data.name |
| 365 | baseFormData.value.phone = res.data.phone | 414 | baseFormData.value.phone = res.data.phone |
| 415 | baseFormData.value.perCode = res.data.perCode ||'' | ||
| 416 | baseFormData.value.validityDate = res.data.validityDate?.slice(0,10) //去掉时分秒 | ||
| 366 | // baseFormData.value.cityId = res.data.cityId | 417 | // baseFormData.value.cityId = res.data.cityId |
| 367 | // baseFormData.value.address = res.data.address | 418 | // baseFormData.value.address = res.data.address |
| 368 | if (res.data.photo) { | 419 | if (res.data.photo) { | ... | ... |
personal/certPreview.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="preview-container"> | ||
| 3 | <view class="loading-tip" v-if="loading">加载中...</view> | ||
| 4 | <view class="error-tip" v-else-if="showError">{{ errorMsg }}</view> | ||
| 5 | |||
| 6 | <view class="download-btn" @click="openDocument"> | ||
| 7 | <text>查看会员证</text> | ||
| 8 | </view> | ||
| 9 | </view> | ||
| 10 | </template> | ||
| 11 | |||
| 12 | <script setup> | ||
| 13 | import { ref } from "vue"; | ||
| 14 | import { onLoad } from "@dcloudio/uni-app"; | ||
| 15 | import config from "@/config.js"; | ||
| 16 | |||
| 17 | const pdfUrl = ref(""); | ||
| 18 | const loading = ref(true); | ||
| 19 | const showError = ref(false); | ||
| 20 | const errorMsg = ref(""); | ||
| 21 | const tempFilePath = ref(""); | ||
| 22 | |||
| 23 | onLoad(async (option) => { | ||
| 24 | if (option.url) { | ||
| 25 | pdfUrl.value = config.baseUrl_api + decodeURIComponent(option.url); | ||
| 26 | await downloadPdf(); | ||
| 27 | } | ||
| 28 | }); | ||
| 29 | |||
| 30 | const downloadPdf = () => { | ||
| 31 | return new Promise((resolve) => { | ||
| 32 | uni.showLoading({ title: "加载中..." }); | ||
| 33 | uni.downloadFile({ | ||
| 34 | url: pdfUrl.value, | ||
| 35 | success: (res) => { | ||
| 36 | uni.hideLoading(); | ||
| 37 | if (res.statusCode === 200) { | ||
| 38 | tempFilePath.value = res.tempFilePath; | ||
| 39 | loading.value = false; | ||
| 40 | // 自动打开文档 | ||
| 41 | openDocument(); | ||
| 42 | } else { | ||
| 43 | showError.value = true; | ||
| 44 | errorMsg.value = "下载失败"; | ||
| 45 | } | ||
| 46 | resolve(); | ||
| 47 | }, | ||
| 48 | fail: () => { | ||
| 49 | uni.hideLoading(); | ||
| 50 | showError.value = true; | ||
| 51 | errorMsg.value = "下载失败"; | ||
| 52 | resolve(); | ||
| 53 | } | ||
| 54 | }); | ||
| 55 | }); | ||
| 56 | }; | ||
| 57 | |||
| 58 | const openDocument = () => { | ||
| 59 | if (!tempFilePath.value) { | ||
| 60 | uni.showToast({ title: "文件未准备好", icon: "none" }); | ||
| 61 | return; | ||
| 62 | } | ||
| 63 | uni.openDocument({ | ||
| 64 | filePath: tempFilePath.value, | ||
| 65 | fileType: "pdf", | ||
| 66 | showMenu: true, | ||
| 67 | success: () => { | ||
| 68 | console.log("打开文档成功"); | ||
| 69 | }, | ||
| 70 | fail: () => { | ||
| 71 | uni.showToast({ title: "打开失败,请在右上角菜单中下载", icon: "none" }); | ||
| 72 | } | ||
| 73 | }); | ||
| 74 | }; | ||
| 75 | </script> | ||
| 76 | |||
| 77 | <style lang="scss" scoped> | ||
| 78 | .preview-container { | ||
| 79 | min-height: 100vh; | ||
| 80 | background: #f5f5f5; | ||
| 81 | position: relative; | ||
| 82 | } | ||
| 83 | |||
| 84 | .loading-tip { | ||
| 85 | position: absolute; | ||
| 86 | top: 50%; | ||
| 87 | left: 50%; | ||
| 88 | transform: translate(-50%, -50%); | ||
| 89 | font-size: 28rpx; | ||
| 90 | color: #666; | ||
| 91 | } | ||
| 92 | |||
| 93 | .error-tip { | ||
| 94 | position: absolute; | ||
| 95 | top: 50%; | ||
| 96 | left: 50%; | ||
| 97 | transform: translate(-50%, -50%); | ||
| 98 | font-size: 28rpx; | ||
| 99 | color: #C40F18; | ||
| 100 | } | ||
| 101 | |||
| 102 | .download-btn { | ||
| 103 | position: fixed; | ||
| 104 | bottom: 50rpx; | ||
| 105 | left: 50%; | ||
| 106 | transform: translateX(-50%); | ||
| 107 | background: #C40F18; | ||
| 108 | color: #fff; | ||
| 109 | padding: 24rpx 60rpx; | ||
| 110 | border-radius: 40rpx; | ||
| 111 | font-size: 28rpx; | ||
| 112 | z-index: 100; | ||
| 113 | } | ||
| 114 | </style> |
| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | ||
| 8 | <!-- 绑定/解绑学员 --> | 8 | <!-- 绑定/解绑学员 --> |
| 9 | <view class="bind-student" @click="handleBindAction"> | 9 | <view class="bind-student" @click="handleBindAction"> |
| 10 | <text>{{ isBound ? '解绑学员' : '绑定学员' }}</text> | 10 | <text>{{ isBound ? '切换学员' : '绑定学员' }}</text> |
| 11 | <image :src="config.baseUrl_api + '/fs/static/bd@2x.png'" class="bind-icon" mode="aspectFit"></image> | 11 | <image :src="config.baseUrl_api + '/fs/static/bd@2x.png'" class="bind-icon" mode="aspectFit"></image> |
| 12 | </view> | 12 | </view> |
| 13 | 13 | ||
| ... | @@ -22,7 +22,7 @@ | ... | @@ -22,7 +22,7 @@ |
| 22 | mode="aspectFill"> | 22 | mode="aspectFill"> |
| 23 | </image> | 23 | </image> |
| 24 | </view> | 24 | </view> |
| 25 | <view class="member-id">注册会员{{ userInfo.userName }}</view> | 25 | <view class="member-id">{{ userInfo.userName }}</view> |
| 26 | </view> | 26 | </view> |
| 27 | <view class="user-bottom"> | 27 | <view class="user-bottom"> |
| 28 | <view class="user-name">{{ perInfo?.perName }}</view> | 28 | <view class="user-name">{{ perInfo?.perName }}</view> |
| ... | @@ -37,6 +37,16 @@ | ... | @@ -37,6 +37,16 @@ |
| 37 | <image v-if="perInfo?.perValidDateFlag == 0" class="expired-stamp" | 37 | <image v-if="perInfo?.perValidDateFlag == 0" class="expired-stamp" |
| 38 | :src="config.baseUrl_api + '/fs/static/end@2x.png'" mode="aspectFit"> | 38 | :src="config.baseUrl_api + '/fs/static/end@2x.png'" mode="aspectFit"> |
| 39 | </image> | 39 | </image> |
| 40 | |||
| 41 | <!-- 卡片右下角按钮 --> | ||
| 42 | <view class="card-btns"> | ||
| 43 | <view class="card-btn" @click="goToPay"> | ||
| 44 | <text>缴费</text> | ||
| 45 | </view> | ||
| 46 | <view class="card-btn" @click="downCert"> | ||
| 47 | <text>电子会员证</text> | ||
| 48 | </view> | ||
| 49 | </view> | ||
| 40 | </view> | 50 | </view> |
| 41 | 51 | ||
| 42 | <!-- 功能按钮卡片 --> | 52 | <!-- 功能按钮卡片 --> |
| ... | @@ -56,7 +66,7 @@ | ... | @@ -56,7 +66,7 @@ |
| 56 | </view> | 66 | </view> |
| 57 | <text class="func-text">个人会员</text> | 67 | <text class="func-text">个人会员</text> |
| 58 | </view> | 68 | </view> |
| 59 | <view class="func-item" @click="goToRecord"> | 69 | <view class="func-item" @click="goToRecord(0)"> |
| 60 | <view class="func-icon"> | 70 | <view class="func-icon"> |
| 61 | <image :src="config.baseUrl_api + '/fs/static/btn03@2x.png'"></image> | 71 | <image :src="config.baseUrl_api + '/fs/static/btn03@2x.png'"></image> |
| 62 | <!-- <uni-icons type="list" size="40" color="#1E88E5"></uni-icons> --> | 72 | <!-- <uni-icons type="list" size="40" color="#1E88E5"></uni-icons> --> |
| ... | @@ -75,7 +85,7 @@ | ... | @@ -75,7 +85,7 @@ |
| 75 | </view> | 85 | </view> |
| 76 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 86 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 77 | </view> | 87 | </view> |
| 78 | <view class="query-item" @click="goToWebView(1)"> | 88 | <!-- <view class="query-item" @click="goToWebView(1)"> |
| 79 | <view class="query-item-left"> | 89 | <view class="query-item-left"> |
| 80 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> | 90 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> |
| 81 | <text class="query-item-text">单位会员查询</text> | 91 | <text class="query-item-text">单位会员查询</text> |
| ... | @@ -95,7 +105,7 @@ | ... | @@ -95,7 +105,7 @@ |
| 95 | <text class="query-item-text">旧版级位证书查询</text> | 105 | <text class="query-item-text">旧版级位证书查询</text> |
| 96 | </view> | 106 | </view> |
| 97 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 107 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 98 | </view> | 108 | </view> --> |
| 99 | <view class="query-item" @click="goToWebView(4)"> | 109 | <view class="query-item" @click="goToWebView(4)"> |
| 100 | <view class="query-item-left"> | 110 | <view class="query-item-left"> |
| 101 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> | 111 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> |
| ... | @@ -103,59 +113,59 @@ | ... | @@ -103,59 +113,59 @@ |
| 103 | </view> | 113 | </view> |
| 104 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 114 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 105 | </view> | 115 | </view> |
| 106 | <view class="query-item" @click="goToWebView(5)"> | 116 | <!-- <view class="query-item" @click="goToWebView(5)"> |
| 107 | <view class="query-item-left"> | 117 | <view class="query-item-left"> |
| 108 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> | 118 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> |
| 109 | <text class="query-item-text">级位记录查询</text> | 119 | <text class="query-item-text">级位记录查询</text> |
| 110 | </view> | 120 | </view> |
| 111 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 121 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 112 | </view> | 122 | </view> --> |
| 113 | <view class="query-item" @click="goToWebView(6)"> | 123 | <!-- <view class="query-item" @click="goToWebView(6)"> |
| 114 | <view class="query-item-left"> | 124 | <view class="query-item-left"> |
| 115 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> | 125 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> |
| 116 | <text class="query-item-text">国际段位证书查询</text> | 126 | <text class="query-item-text">国际段位证书查询</text> |
| 117 | </view> | 127 | </view> |
| 118 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 128 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 119 | </view> | 129 | </view> --> |
| 120 | <view class="query-item" @click="goToWebView(7)"> | 130 | <view class="query-item" @click="goToRecord(1)"> |
| 121 | <view class="query-item-left"> | 131 | <view class="query-item-left"> |
| 122 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> | 132 | <image :src="config.baseUrl_api + '/fs/static/user_icon02@2x.png'" class="query-item-icon"></image> |
| 123 | <text class="query-item-text">中国段位证书查询</text> | 133 | <text class="query-item-text">我的段位</text> |
| 124 | </view> | 134 | </view> |
| 125 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 135 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 126 | </view> | 136 | </view> |
| 127 | <view class="query-item" @click="goToWebView(8)"> | 137 | <view class="query-item" @click="goToWebView(8)"> |
| 128 | <view class="query-item-left"> | 138 | <view class="query-item-left"> |
| 129 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> | 139 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> |
| 130 | <text class="query-item-text">级位考官查询</text> | 140 | <text class="query-item-text">级位考官</text> |
| 131 | </view> | 141 | </view> |
| 132 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 142 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 133 | </view> | 143 | </view> |
| 134 | <view class="query-item" @click="goToWebView(9)"> | 144 | <view class="query-item" @click="goToWebView(9)"> |
| 135 | <view class="query-item-left"> | 145 | <view class="query-item-left"> |
| 136 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> | 146 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> |
| 137 | <text class="query-item-text">段位考官查询</text> | 147 | <text class="query-item-text">段位考官</text> |
| 138 | </view> | 148 | </view> |
| 139 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 149 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 140 | </view> | 150 | </view> |
| 141 | <view class="query-item" @click="goToWebView(10)"> | 151 | <view class="query-item" @click="goToWebView(10)"> |
| 142 | <view class="query-item-left"> | 152 | <view class="query-item-left"> |
| 143 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> | 153 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> |
| 144 | <text class="query-item-text">大众教练员查询</text> | 154 | <text class="query-item-text">大众教练员</text> |
| 145 | </view> | 155 | </view> |
| 146 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 156 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 147 | </view> | 157 | </view> |
| 148 | <view class="query-item" @click="goToWebView(11)"> | 158 | <view class="query-item" @click="goToWebView(11)"> |
| 149 | <view class="query-item-left"> | 159 | <view class="query-item-left"> |
| 150 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> | 160 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> |
| 151 | <text class="query-item-text">大众裁判员查询</text> | 161 | <text class="query-item-text">大众裁判员</text> |
| 152 | </view> | 162 | </view> |
| 153 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 163 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 154 | </view> | 164 | </view> |
| 155 | <view class="query-item" @click="goToWebView(12)"> | 165 | <view class="query-item" @click="goToWebView(12)"> |
| 156 | <view class="query-item-left"> | 166 | <view class="query-item-left"> |
| 157 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> | 167 | <image :src="config.baseUrl_api + '/fs/static/user_icon03@2x.png'" class="query-item-icon"></image> |
| 158 | <text class="query-item-text">培训讲师查询</text> | 168 | <text class="query-item-text">培训讲师</text> |
| 159 | </view> | 169 | </view> |
| 160 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> | 170 | <uni-icons type="arrowright" size="20" color="#999"></uni-icons> |
| 161 | </view> | 171 | </view> |
| ... | @@ -223,7 +233,8 @@ | ... | @@ -223,7 +233,8 @@ |
| 223 | import to from 'await-to-js' | 233 | import to from 'await-to-js' |
| 224 | import { | 234 | import { |
| 225 | bindUser, | 235 | bindUser, |
| 226 | unbindUser | 236 | unbindUser, |
| 237 | downStuCertSingle | ||
| 227 | } from '@/common/api.js' | 238 | } from '@/common/api.js' |
| 228 | 239 | ||
| 229 | const userStore = useUserStore() | 240 | const userStore = useUserStore() |
| ... | @@ -232,10 +243,10 @@ | ... | @@ -232,10 +243,10 @@ |
| 232 | console.log(222,userInfo.value) | 243 | console.log(222,userInfo.value) |
| 233 | console.log(333,perInfo.value) | 244 | console.log(333,perInfo.value) |
| 234 | 245 | ||
| 235 | // 是否已绑定学员 | 246 | // 是否已绑定学员(根据会员卡号判断) |
| 236 | const isBound = computed(() => { | 247 | const isBound = computed(() => { |
| 237 | const perId = userInfo.value?.perId | 248 | const perCode = perInfo.value?.perCode |
| 238 | return perId !== undefined && perId !== null && perId !== 0 | 249 | return perCode !== undefined && perCode !== null && perCode !== '' |
| 239 | }) | 250 | }) |
| 240 | 251 | ||
| 241 | const bindPopup = ref(null) | 252 | const bindPopup = ref(null) |
| ... | @@ -252,8 +263,8 @@ const showConfirm = ref(false) | ... | @@ -252,8 +263,8 @@ const showConfirm = ref(false) |
| 252 | } | 263 | } |
| 253 | }) | 264 | }) |
| 254 | 265 | ||
| 255 | watch(() => userInfo.value.perId, (val) => { | 266 | watch(() => perInfo.value?.perCode, (val) => { |
| 256 | if (val !== undefined && val == 0) { | 267 | if (val === undefined || val === null || val === '') { |
| 257 | nextTick(() => { | 268 | nextTick(() => { |
| 258 | openBindPopup() | 269 | openBindPopup() |
| 259 | }) | 270 | }) |
| ... | @@ -282,14 +293,10 @@ const showConfirm = ref(false) | ... | @@ -282,14 +293,10 @@ const showConfirm = ref(false) |
| 282 | bindPopup.value?.close() | 293 | bindPopup.value?.close() |
| 283 | } | 294 | } |
| 284 | 295 | ||
| 285 | // 处理绑定/解绑操作 | 296 | // 处理绑定/切换操作 |
| 286 | const handleBindAction = () => { | 297 | const handleBindAction = async () => { |
| 287 | if (isBound.value) { | 298 | if (isBound.value) { |
| 288 | // 已绑定,执行解绑 | 299 | // 已绑定,先解绑再打开绑定弹框 |
| 289 | uni.showModal({ | ||
| 290 | content: '确认解绑吗?', | ||
| 291 | success: async (res) => { | ||
| 292 | if (res.confirm) { | ||
| 293 | uni.showLoading({ | 300 | uni.showLoading({ |
| 294 | title: '解绑中...', | 301 | title: '解绑中...', |
| 295 | mask: true | 302 | mask: true |
| ... | @@ -297,15 +304,8 @@ const showConfirm = ref(false) | ... | @@ -297,15 +304,8 @@ const showConfirm = ref(false) |
| 297 | const [err] = await to(unbindUser()) | 304 | const [err] = await to(unbindUser()) |
| 298 | uni.hideLoading() | 305 | uni.hideLoading() |
| 299 | if (err) return | 306 | if (err) return |
| 300 | uni.showToast({ | ||
| 301 | title: '解绑成功', | ||
| 302 | icon: 'success' | ||
| 303 | }) | ||
| 304 | // 刷新用户信息 | ||
| 305 | getWebInfo() | 307 | getWebInfo() |
| 306 | } | 308 | openBindPopup() |
| 307 | } | ||
| 308 | }) | ||
| 309 | } else { | 309 | } else { |
| 310 | // 未绑定,打开绑定弹框 | 310 | // 未绑定,打开绑定弹框 |
| 311 | openBindPopup() | 311 | openBindPopup() |
| ... | @@ -341,9 +341,13 @@ const showConfirm = ref(false) | ... | @@ -341,9 +341,13 @@ const showConfirm = ref(false) |
| 341 | uni.hideLoading() | 341 | uni.hideLoading() |
| 342 | 342 | ||
| 343 | if (err) { | 343 | if (err) { |
| 344 | uni.showToast({ | ||
| 345 | title: err?.data?.msg || err?.message || '绑定失败,请稍后重试', | ||
| 346 | icon: 'none', | ||
| 347 | duration: 3000 | ||
| 348 | }) | ||
| 344 | return | 349 | return |
| 345 | } | 350 | }else{ |
| 346 | |||
| 347 | uni.showToast({ | 351 | uni.showToast({ |
| 348 | title: '绑定成功', | 352 | title: '绑定成功', |
| 349 | icon: 'success' | 353 | icon: 'success' |
| ... | @@ -352,18 +356,33 @@ const showConfirm = ref(false) | ... | @@ -352,18 +356,33 @@ const showConfirm = ref(false) |
| 352 | getWebInfo() | 356 | getWebInfo() |
| 353 | } | 357 | } |
| 354 | 358 | ||
| 359 | // uni.showToast({ | ||
| 360 | // title: '绑定成功', | ||
| 361 | // icon: 'success' | ||
| 362 | // }) | ||
| 363 | |||
| 364 | } | ||
| 365 | |||
| 355 | // 返回上一页 | 366 | // 返回上一页 |
| 356 | const goBack = () => { | 367 | const goBack = () => { |
| 357 | uni.navigateBack() | 368 | uni.navigateBack() |
| 358 | } | 369 | } |
| 359 | 370 | ||
| 360 | const goToAuth = () => { | 371 | const goToAuth = () => { |
| 372 | if (!isBound.value) { | ||
| 373 | uni.showToast({ title: '请先绑定学员', icon: 'none' }) | ||
| 374 | return | ||
| 375 | } | ||
| 361 | uni.navigateTo({ | 376 | uni.navigateTo({ |
| 362 | url: '/personal/personInfo' | 377 | url: '/personal/personInfo' |
| 363 | }); | 378 | }); |
| 364 | }; | 379 | }; |
| 365 | 380 | ||
| 366 | const goToScore = () => { | 381 | const goToScore = () => { |
| 382 | if (!isBound.value) { | ||
| 383 | uni.showToast({ title: '请先绑定学员', icon: 'none' }) | ||
| 384 | return | ||
| 385 | } | ||
| 367 | uni.navigateTo({ | 386 | uni.navigateTo({ |
| 368 | url: '/personal/memberInfo' | 387 | url: '/personal/memberInfo' |
| 369 | }); | 388 | }); |
| ... | @@ -371,26 +390,67 @@ const showConfirm = ref(false) | ... | @@ -371,26 +390,67 @@ const showConfirm = ref(false) |
| 371 | 390 | ||
| 372 | const goToWebView = (type) => { | 391 | const goToWebView = (type) => { |
| 373 | // const url = "https://member.taekwondo.org.cn/#/authAccurate?type=" + type | 392 | // const url = "https://member.taekwondo.org.cn/#/authAccurate?type=" + type |
| 374 | const url = "http://tk001.wxjylt.com/pc.html#/authAccurate?type=" + type | 393 | const url = "https://tk001.wxjylt.com/pc.html#/authAccurate?type=" + type |
| 375 | uni.navigateTo({ | 394 | uni.navigateTo({ |
| 376 | url: "/pages/webview/webview?url=" + encodeURIComponent(url) | 395 | url: "/pages/webview/webview?url=" + encodeURIComponent(url) |
| 377 | }); | 396 | }); |
| 378 | }; | 397 | }; |
| 379 | 398 | ||
| 380 | // 导航到级位记录 | 399 | // 导航到级位记录 |
| 381 | const goToRecord = () => { | 400 | const goToRecord = (type) => { |
| 401 | if (!isBound.value) { | ||
| 402 | uni.showToast({ title: '请先绑定学员', icon: 'none' }) | ||
| 403 | return | ||
| 404 | } | ||
| 382 | uni.navigateTo({ | 405 | uni.navigateTo({ |
| 383 | url: '/personal/levelRecord' | 406 | url: '/personal/levelRecord?type=' + type |
| 384 | }); | 407 | }); |
| 385 | }; | 408 | }; |
| 386 | 409 | ||
| 387 | // 导航到我的订单 | 410 | // 导航到我的订单 |
| 388 | const goToOrder = () => { | 411 | const goToOrder = () => { |
| 412 | if (!isBound.value) { | ||
| 413 | uni.showToast({ title: '请先绑定学员', icon: 'none' }) | ||
| 414 | return | ||
| 415 | } | ||
| 389 | uni.navigateTo({ | 416 | uni.navigateTo({ |
| 390 | url: '/personal/order' | 417 | url: '/personal/order' |
| 391 | }); | 418 | }); |
| 392 | }; | 419 | }; |
| 393 | 420 | ||
| 421 | // 导航到缴费 | ||
| 422 | const goToPay = () => { | ||
| 423 | const perId = userInfo.value?.perId | ||
| 424 | uni.navigateTo({ | ||
| 425 | url: `/personal/addVip_per?perId=${perId}` | ||
| 426 | }); | ||
| 427 | }; | ||
| 428 | |||
| 429 | // 下载电子会员证 | ||
| 430 | const downCert = async () => { | ||
| 431 | if (!isBound.value) { | ||
| 432 | uni.showToast({ title: '请先绑定学员', icon: 'none' }) | ||
| 433 | return | ||
| 434 | } | ||
| 435 | const perId = userInfo.value?.perId | ||
| 436 | if (!perId) return | ||
| 437 | |||
| 438 | uni.showLoading({ title: '加载中...', mask: true }) | ||
| 439 | const [err, res] = await to(downStuCertSingle(perId)) | ||
| 440 | uni.hideLoading() | ||
| 441 | |||
| 442 | if (err) { | ||
| 443 | uni.showToast({ title: err?.data?.msg || '获取会员证失败', icon: 'none' }) | ||
| 444 | return | ||
| 445 | } | ||
| 446 | const pdfUrl = res?.data | ||
| 447 | if (pdfUrl) { | ||
| 448 | uni.navigateTo({ | ||
| 449 | url: `/personal/certPreview?url=${encodeURIComponent(pdfUrl)}` | ||
| 450 | }) | ||
| 451 | } | ||
| 452 | }; | ||
| 453 | |||
| 394 | 454 | ||
| 395 | 455 | ||
| 396 | // 显示退出登录确认框 | 456 | // 显示退出登录确认框 |
| ... | @@ -549,12 +609,33 @@ const showConfirm = ref(false) | ... | @@ -549,12 +609,33 @@ const showConfirm = ref(false) |
| 549 | .expired-stamp { | 609 | .expired-stamp { |
| 550 | position: absolute; | 610 | position: absolute; |
| 551 | right: 30rpx; | 611 | right: 30rpx; |
| 552 | bottom: 100rpx; | 612 | bottom: 150rpx; |
| 553 | width: 150rpx; | 613 | width: 150rpx; |
| 554 | height: 150rpx; | 614 | height: 150rpx; |
| 555 | z-index: 1; | 615 | z-index: 1; |
| 556 | } | 616 | } |
| 557 | 617 | ||
| 618 | /* 卡片右下角按钮 */ | ||
| 619 | .card-btns { | ||
| 620 | position: absolute; | ||
| 621 | right: 30rpx; | ||
| 622 | bottom: 73rpx; | ||
| 623 | z-index: 10; | ||
| 624 | display: flex; | ||
| 625 | gap: 16rpx; | ||
| 626 | } | ||
| 627 | |||
| 628 | .card-btn { | ||
| 629 | // background: rgba(255, 255, 255, 0.9); | ||
| 630 | border-radius: 30rpx; | ||
| 631 | padding: 12rpx 20rpx; | ||
| 632 | } | ||
| 633 | |||
| 634 | .card-btn text { | ||
| 635 | font-size: 24rpx; | ||
| 636 | color: #C40F18; | ||
| 637 | } | ||
| 638 | |||
| 558 | /* 功能按钮卡片 */ | 639 | /* 功能按钮卡片 */ |
| 559 | .func-card { | 640 | .func-card { |
| 560 | margin: -70rpx 30rpx 30rpx; | 641 | margin: -70rpx 30rpx 30rpx; | ... | ... |
| ... | @@ -76,6 +76,8 @@ | ... | @@ -76,6 +76,8 @@ |
| 76 | 76 | ||
| 77 | <script setup> | 77 | <script setup> |
| 78 | import { ref, onMounted } from 'vue'; | 78 | import { ref, onMounted } from 'vue'; |
| 79 | import { onLoad } from '@dcloudio/uni-app'; | ||
| 80 | |||
| 79 | import { useUserStore } from '../store/modules/user'; | 81 | import { useUserStore } from '../store/modules/user'; |
| 80 | import { getAssoPers } from '@/common/api.js'; | 82 | import { getAssoPers } from '@/common/api.js'; |
| 81 | import { getPersonTecDetails } from '@/common/api.js'; | 83 | import { getPersonTecDetails } from '@/common/api.js'; |
| ... | @@ -90,12 +92,22 @@ | ... | @@ -90,12 +92,22 @@ |
| 90 | // 变更记录相关 | 92 | // 变更记录相关 |
| 91 | const changeRecordPopup = ref(null); | 93 | const changeRecordPopup = ref(null); |
| 92 | const currentChangeRecord = ref(null); | 94 | const currentChangeRecord = ref(null); |
| 95 | const pageType = ref(''); | ||
| 93 | 96 | ||
| 94 | // 返回上一页 | 97 | // 返回上一页 |
| 95 | const goBack = () => { | 98 | const goBack = () => { |
| 96 | uni.navigateBack(); | 99 | uni.navigateBack(); |
| 97 | }; | 100 | }; |
| 98 | 101 | onLoad((option) => { | |
| 102 | if (option.type) { | ||
| 103 | pageType.value = option.type; | ||
| 104 | if (pageType.value == '0') { | ||
| 105 | uni.setNavigationBarTitle({ title: '级位记录' }) | ||
| 106 | } else if (pageType.value == '1') { | ||
| 107 | uni.setNavigationBarTitle({ title: '段位记录' }) | ||
| 108 | } | ||
| 109 | } | ||
| 110 | }); | ||
| 99 | // 显示变更记录 | 111 | // 显示变更记录 |
| 100 | const showChangeRecord = (item) => { | 112 | const showChangeRecord = (item) => { |
| 101 | // remark已经在getLevelRecords中解析过了,直接使用 | 113 | // remark已经在getLevelRecords中解析过了,直接使用 |
| ... | @@ -116,7 +128,7 @@ | ... | @@ -116,7 +128,7 @@ |
| 116 | const getLevelRecords = async () => { | 128 | const getLevelRecords = async () => { |
| 117 | loading.value = true; | 129 | loading.value = true; |
| 118 | try { | 130 | try { |
| 119 | const res = await getPersonTecDetails(0, perId.value); // 0表示级位 | 131 | const res = await getPersonTecDetails(pageType.value, perId.value); // 0表示级位 |
| 120 | levelRecords.value = res.data || []; | 132 | levelRecords.value = res.data || []; |
| 121 | // 处理数据 | 133 | // 处理数据 |
| 122 | levelRecords.value.forEach(item => { | 134 | levelRecords.value.forEach(item => { | ... | ... |
| ... | @@ -51,6 +51,14 @@ | ... | @@ -51,6 +51,14 @@ |
| 51 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" | 51 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" |
| 52 | v-model="baseFormData.phone" placeholder="请输入联系方式" /> | 52 | v-model="baseFormData.phone" placeholder="请输入联系方式" /> |
| 53 | </uni-forms-item> | 53 | </uni-forms-item> |
| 54 | <uni-forms-item label="会员编号" name="perCode" v-if="baseFormData.perCode"> | ||
| 55 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" | ||
| 56 | v-model="baseFormData.perCode" placeholder="请输入会员编号" /> | ||
| 57 | </uni-forms-item> | ||
| 58 | <uni-forms-item label="会员有效期" name="validityDate" v-if="baseFormData.validityDate"> | ||
| 59 | <uni-easyinput :styles="inputstyle" :placeholderStyle="placeholderStyle" | ||
| 60 | v-model="baseFormData.validityDate" placeholder="请输入会员有效期" /> | ||
| 61 | </uni-forms-item> | ||
| 54 | 62 | ||
| 55 | 63 | ||
| 56 | <uni-forms-item label="所在地区"> | 64 | <uni-forms-item label="所在地区"> |
| ... | @@ -142,6 +150,8 @@ | ... | @@ -142,6 +150,8 @@ |
| 142 | sex: '', | 150 | sex: '', |
| 143 | idcType: '0', | 151 | idcType: '0', |
| 144 | perType: '1', // (1:个人会员;2:教练;3:考官;4:裁判;5:临时会员;) | 152 | perType: '1', // (1:个人会员;2:教练;3:考官;4:裁判;5:临时会员;) |
| 153 | perCode:'', | ||
| 154 | validityDate:'' | ||
| 145 | }) | 155 | }) |
| 146 | const items = ref(['身份证添加', '证件照录入']) | 156 | const items = ref(['身份证添加', '证件照录入']) |
| 147 | const idcTypeList = ref([{ | 157 | const idcTypeList = ref([{ |
| ... | @@ -356,6 +366,8 @@ | ... | @@ -356,6 +366,8 @@ |
| 356 | baseFormData.value.phone = res.data.phone | 366 | baseFormData.value.phone = res.data.phone |
| 357 | baseFormData.value.cityId = res.data.cityId | 367 | baseFormData.value.cityId = res.data.cityId |
| 358 | baseFormData.value.address = res.data.address | 368 | baseFormData.value.address = res.data.address |
| 369 | baseFormData.value.perCode = res.data.perCode ||'' | ||
| 370 | baseFormData.value.validityDate = res.data.validityDate?.slice(0,10) //去掉时分秒 | ||
| 359 | if (res.data.photo) { | 371 | if (res.data.photo) { |
| 360 | console.log(res.data.photo) | 372 | console.log(res.data.photo) |
| 361 | if (res.data.photo.indexOf('http') == -1) { | 373 | if (res.data.photo.indexOf('http') == -1) { | ... | ... |
| ... | @@ -51,15 +51,15 @@ | ... | @@ -51,15 +51,15 @@ |
| 51 | <view class="stats-row"> | 51 | <view class="stats-row"> |
| 52 | <view class="stat-item"> | 52 | <view class="stat-item"> |
| 53 | <text class="stat-label">人数合计</text> | 53 | <text class="stat-label">人数合计</text> |
| 54 | <text class="stat-value">{{ item.allCount || 0 }}</text> | 54 | <text class="stat-value">{{ item.allCount || '/' }}</text> |
| 55 | </view> | 55 | </view> |
| 56 | <view class="stat-item"> | 56 | <view class="stat-item"> |
| 57 | <text class="stat-label">新会员合计</text> | 57 | <text class="stat-label">新会员合计</text> |
| 58 | <text class="stat-value">{{ item.newCount || 0 }}</text> | 58 | <text class="stat-value">{{ item.newCount || '/' }}</text> |
| 59 | </view> | 59 | </view> |
| 60 | <view class="stat-item"> | 60 | <view class="stat-item"> |
| 61 | <text class="stat-label">年限合计</text> | 61 | <text class="stat-label">年限合计</text> |
| 62 | <text class="stat-value">{{ item.yearCount || 0 }}</text> | 62 | <text class="stat-value">{{ item.yearCount || '/' }}</text> |
| 63 | </view> | 63 | </view> |
| 64 | </view> | 64 | </view> |
| 65 | 65 | ||
| ... | @@ -493,7 +493,7 @@ onUnmounted(() => { | ... | @@ -493,7 +493,7 @@ onUnmounted(() => { |
| 493 | } | 493 | } |
| 494 | .stat-value { | 494 | .stat-value { |
| 495 | font-size:32rpx; | 495 | font-size:32rpx; |
| 496 | font-weight:700; | 496 | // font-weight:700; |
| 497 | color:#333; | 497 | color:#333; |
| 498 | } | 498 | } |
| 499 | } | 499 | } | ... | ... |
-
Please register or sign in to post a comment