c9bf47f3 by lttnew

6.5 认证重新排版

1 parent e28234aa
......@@ -1570,14 +1570,15 @@ export function creditCodeExist(code) {
}
// 生成单位订单renewYear
export function certifiedNew(data) {
let url = '/system/certifiedNew/commit'
const params = []
if (data.renewYear) params.push(`renewYear=${data.renewYear}`)
params.push(`type=${data.type}`)
if (data.contactPerson) params.push(`contactPerson=${data.contactPerson}`)
if (data.contactTel) params.push(`contactTel=${data.contactTel}`)
if (params.length > 0) {
export function certifiedNew(data) {
let url = '/system/certifiedNew/commit'
const params = []
if (data.renewYear) params.push(`renewYear=${data.renewYear}`)
params.push(`type=${data.type}`)
if (data.payType) params.push(`payType=${data.payType}`)
if (data.contactPerson) params.push(`contactPerson=${data.contactPerson}`)
if (data.contactTel) params.push(`contactTel=${data.contactTel}`)
if (params.length > 0) {
url += '?' + params.join('&')
}
return request({
......
......@@ -51,12 +51,12 @@
<form v-if="isActive==0">
<view class="round-input-item">
<image :src="config.baseUrl_api+'/fs/static/lg/tag01.png'" class="icon"></image>
<uni-easyinput v-model="form.username" :styles="inputstyle" placeholder="账号"/>
<uni-easyinput v-model="form.username" :styles="inputstyle" placeholder="新用户请注册后进行登陆"/>
</view>
<view class="round-input-item">
<image :src="config.baseUrl_api+'/fs/static/lg/tag02.png'" class="icon"></image>
<uni-easyinput v-model="form.password" :styles="inputstyle"
placeholder="初次登录请联系省级协会获取初始密码"
placeholder="新用户请注册后进行登陆"
type="password"/>
</view>
<view class="round-input-item">
......@@ -104,6 +104,10 @@
</view>
<view class="fixedagree">
<!-- <text>仅供中国跆拳道协会会员单位登录使用</text> -->
<view class="">
中国跆拳道协会
<text @click="call('010-87188971')">010-87188971</text>
</view>
<view class="wNumber">
技术服务热线:
<text @click="call('15606190026')">15606190026</text>
......
......@@ -21,8 +21,11 @@
<!-- 温馨提示 -->
<view class="tip-box">
<text class="tip-text">温馨提示:
您可以自行录入考官信息,如果暂时没有考官,可以选择由省跆协指派进行考点申报,请尽快完成考点考官的认证。
<text class="tip-text">温馨提示:
根据中国跆拳道协会考点管理办法请添加考点考官
如若已有考官:点击【录入考官信息】,根据相关信息填写考官资料进行录入。
如若没有考官:点击【申请省跆协指派考官】,选择省内相关考官并及时参加考官培训
完成考官设置后,才能继续提交考点申报。请您尽快操作,以免影响后续考试安排。
</text>
</view>
......
......@@ -34,13 +34,15 @@
<!-- 费用合计 -->
<view class="row ">
<text class="label">费用合计</text>
<text class="value red">{{ (form.renewYear * memberFee).toFixed(2) }}</text>
<text class="value red">{{ originalTotalFee }}</text>
</view>
<view v-if="preferentialPolicy" class="hintRow">
<text
class="hintText">温馨提示:根据中国跆协{{ preferentialData.name || '优惠' }}政策减免一年费用,每个单位在政策有效期内只享受一次
</text>
<view v-if="preferentialPolicy" class="discountPolicy">
<!-- <view class="discountPolicyTitle">减免政策</view> -->
<view class="discountPolicyRow">
<text class="discountLabel">{{ preferentialData.name || '减免费用' }}</text>
<text class="discountValue">-{{ discountAmount }}</text>
</view>
</view>
</view>
......@@ -83,14 +85,18 @@
</view>
<view class="bottomBtn">
<view v-if="preferentialPolicy" class="deductRow">
<text class="label">减免费用</text>
<text class="value red">-{{ memberFee.toFixed(2) }}</text>
</view>
<button :loading="isPaying" class="payBtn" @click="handelPay">立即支付 ¥{{ memberTotalFee }}</button>
</view>
</view>
<custom-modal
ref="preferentialModalRef"
title="优惠政策"
:content="preferentialModalContent"
:showCancel="false"
confirmText="我知道了"
/>
</template>
<script setup>
......@@ -105,6 +111,7 @@ import to from 'await-to-js'
import * as api from '@/common/api.js'
import {minShengPay} from '@/common/pay.js'
import config from '@/config.js'
import customModal from '@/components/custom-modal.vue'
// 订单信息(再次支付时传入)
const payForm = ref({})
......@@ -120,11 +127,13 @@ const preferentialData = ref({
})
const payType = ref('2')
const isPaying = ref(false)
const payName = ref('')
const assoName = ref('')
const app = getApp()
const sourcePage = ref('')
const PERFECT_PAY_REFRESH_KEY = 'perfectNeedRefreshAfterPay'
const payName = ref('')
const assoName = ref('')
const app = getApp()
const sourcePage = ref('')
const PERFECT_PAY_REFRESH_KEY = 'perfectNeedRefreshAfterPay'
const preferentialModalRef = ref(null)
const hasShownPreferentialModal = ref(false)
const pickFirst = (...values) => {
const value = values.find(item => item !== undefined && item !== null && String(item).trim() !== '')
......@@ -144,25 +153,20 @@ const getOrderContent = (content) => {
const fillPayDisplayInfo = (data = {}, content = {}, option = {}) => {
const memberInfo = app.globalData?.memberInfo || {}
const deptInfo = app.globalData?.dept || app.globalData?.userInfo?.dept || {}
payName.value = pickFirst(
memberInfo.name,
const optionPayName = option.payName ? decodeURIComponent(option.payName) : ''
const optionAssoName = option.assoName ? decodeURIComponent(option.assoName) : ''
const hasOrderId = !!option.orderId
const orderPayNames = [
data.orderName,
content.orderName,
content.memberName,
data.memberName,
data.payDeptName,
content.payDeptName,
data.payMemName,
content.payMemName,
option.payName ? decodeURIComponent(option.payName) : '',
data.orderName,
content.orderName,
deptInfo.deptName
)
assoName.value = pickFirst(
memberInfo.aname,
memberInfo.associateName,
memberInfo.assoName,
deptInfo.aname,
deptInfo.associateName,
content.payMemName
]
const orderAssoNames = [
data.assoName,
data.associateName,
data.associationName,
......@@ -172,19 +176,55 @@ const fillPayDisplayInfo = (data = {}, content = {}, option = {}) => {
content.associateName,
content.associationName,
content.aname,
content.parentName,
option.assoName ? decodeURIComponent(option.assoName) : ''
)
content.parentName
]
const cachePayNames = [
memberInfo.name,
deptInfo.deptName
]
const cacheAssoNames = [
memberInfo.aname,
memberInfo.associateName,
memberInfo.assoName,
deptInfo.aname,
deptInfo.associateName
]
// 再次支付以订单详情为准;新认证缴费没有订单详情,以入口页面最新传参为准。
payName.value = hasOrderId
? pickFirst(...orderPayNames, optionPayName, ...cachePayNames)
: pickFirst(optionPayName, ...orderPayNames, ...cachePayNames)
assoName.value = hasOrderId
? pickFirst(...orderAssoNames, optionAssoName, ...cacheAssoNames)
: pickFirst(optionAssoName, ...orderAssoNames, ...cacheAssoNames)
}
const originalTotal = computed(() => {
return Number(memberFee.value || 0) * Number(form.value.renewYear || 0)
})
const originalTotalFee = computed(() => {
return originalTotal.value.toFixed(2)
})
const discountValue = computed(() => {
if (!preferentialPolicy.value) return 0
return Math.min(Number(memberFee.value || 0), originalTotal.value)
})
const discountAmount = computed(() => {
return discountValue.value.toFixed(2)
})
const memberTotalFee = computed(() => {
const total = memberFee.value * form.value.renewYear
if (preferentialPolicy.value) {
return (total - memberFee.value).toFixed(2)
}
return total.toFixed(2)
return Math.max(originalTotal.value - discountValue.value, 0).toFixed(2)
})
const preferentialModalContent = computed(() => {
return `根据中国跆协${preferentialData.value.name || '优惠'}政策减免一年费用,每个单位在政策有效期内只享受一次。`
})
// 年限减
const minusYear = () => {
if (form.value.renewYear > 1) {
......@@ -205,16 +245,16 @@ const onPayTypeChange = (e) => {
// 支付操作
const handelPay = async () => {
if (memberTotalFee.value < 0) {
uni.showToast({
title: '支付金额异常',
icon: 'none'
})
return
}
// 对公转账校验
if (payType.value === '3') {
if (Number(memberTotalFee.value || 0) < 0) {
uni.showToast({
title: '支付金额异常',
icon: 'none'
})
return
}
// 对公转账校验
if (payType.value === '3') {
if (!form.value.contactPerson) {
uni.showToast({
title: '请输入联系人',
......@@ -267,12 +307,13 @@ const handelPay = async () => {
}
data = res.data
} else {
// 第一次下单
const [err, res] = await to(api.certifiedNew({
renewYear: form.value.renewYear,
type: payType.value,
contactPerson: form.value.contactPerson,
contactTel: form.value.contactTel
// 第一次下单
const [err, res] = await to(api.certifiedNew({
renewYear: form.value.renewYear,
payType: payType.value,
type: payType.value,
contactPerson: form.value.contactPerson,
contactTel: form.value.contactTel
}))
if (err || res.code !== 200) {
uni.hideLoading()
......@@ -283,12 +324,12 @@ const handelPay = async () => {
})
return
}
data = res.data
}
markPerfectNeedRefresh()
data = res.data
}
markPerfectNeedRefresh()
// 无需支付,直接成功
if (data.payFlag == 0) {
if (data.payFlag == 0) {
uni.hideLoading()
isPaying.value = false
uni.redirectTo({
......@@ -306,8 +347,7 @@ const handelPay = async () => {
})
return
}
// 民生支付
// 民生支付
if (data.payResult && data.payResult.encryptedData) {
uni.hideLoading()
try {
......@@ -328,10 +368,10 @@ const handelPay = async () => {
isPaying.value = false
}
onLoad((option) => {
console.log(66, option)
sourcePage.value = option.source || ''
fillPayDisplayInfo({}, {}, option)
onLoad((option) => {
console.log(66, option)
sourcePage.value = option.source || ''
fillPayDisplayInfo({}, {}, option)
// 接收订单ID(再次支付时)
if (option.orderId) {
payForm.value.id = option.orderId
......@@ -351,13 +391,13 @@ onLoad((option) => {
}
// 初始化获取费用和优惠
init()
})
function markPerfectNeedRefresh() {
if (sourcePage.value === 'perfect') {
uni.setStorageSync(PERFECT_PAY_REFRESH_KEY, '1')
}
}
})
function markPerfectNeedRefresh() {
if (sourcePage.value === 'perfect') {
uni.setStorageSync(PERFECT_PAY_REFRESH_KEY, '1')
}
}
// 初始化接口
async function init() {
......@@ -372,7 +412,18 @@ async function init() {
uni.hideLoading()
if (err) {
console.error('初始化失败:', err)
return
}
showPreferentialPolicyModal()
}
function showPreferentialPolicyModal() {
// 已享受过优惠时 canUseDiscount 返回 false,不再提示。
if (!preferentialPolicy.value || hasShownPreferentialModal.value) return
hasShownPreferentialModal.value = true
setTimeout(() => {
preferentialModalRef.value?.open()
}, 100)
}
// 获取会员单价
......@@ -524,12 +575,33 @@ async function getZtxDiscountPolicyApi() {
font-weight: 500;
}
/* 优惠提示 */
.hintRow {
display: flex;
align-items: flex-start;
.discountPolicy {
margin-top: 18rpx;
padding-top: 18rpx;
border-top: 1rpx solid #f1f1f1;
}
.discountPolicyTitle {
font-size: 24rpx;
line-height: 1.4;
color: #999;
margin-bottom: 12rpx;
}
.discountPolicyRow {
display: flex;
justify-content: space-between;
align-items: center;
}
.discountLabel {
font-size: 26rpx;
color: #666;
}
.discountValue {
font-size: 30rpx;
color: #C4121B;
font-weight: 600;
}
/* 对公转账表单 */
......@@ -584,33 +656,6 @@ async function getZtxDiscountPolicyApi() {
font-size: 16rpx;
}
.hintRow .hintText {
color: #FF8124;
flex: 1;
margin-top: 10rpx;
}
/* 减免费用 */
.deductRow {
background: #fff;
padding: 20rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
border-radius: 8rpx;
}
.deductRow .label {
font-size: 28rpx;
color: #333;
}
.deductRow .value {
font-size: 30rpx;
color: #C4121B;
}
/* 支付方式行 */
.payRow {
background: #fff;
......
<template>
<view>
<view class="pd30" style="padding: 30rpx 30rpx 180rpx;">
<view class="wBox">
<uni-forms ref="baseForm" label-width="100">
<uni-forms-item label="所属协会" required>
<view style="width: 60vw;overflow:auto;">
<uni-data-picker v-model="form.parentId" :localdata="tree"
:readonly="type&&parentId!=-1&&parentId!=0" :clear-icon="false" placeholder="请选择协会"
:map="{text:'label',value:'id'}" popup-title="" @change="changCase">
</uni-data-picker>
</view>
</uni-forms-item>
<uni-forms-item v-if="form.memCode" label="会员编号" required>
<uni-easyinput v-model="form.memCode" disabled />
<view class="wBox">
<uni-forms ref="baseForm" label-width="100">
<uni-forms-item label="营业执照" required>
<uni-file-picker limit="1" v-model="businessLicenseArr" file-mediatype="image" mode="grid"
:image-styles="businessLicenseImageStyles" @select="selectFile"
@delete="delSupplementFile"></uni-file-picker>
</uni-forms-item>
<uni-forms-item label="营业执照名称" required>
<uni-easyinput v-model="form.companyName" :disabled="isFieldDisabled('companyName')" />
</uni-forms-item>
<uni-forms-item label="机构名称" required>
<uni-easyinput v-model="form.name" :disabled="type" placeholder="机构名称" /></uni-forms-item>
<!-- <uni-forms-item label="所属省份" required>
<uni-data-select :clear="false" :disabled="type&&(belongProvinceId||belongProvinceId==0)"
v-model="form.belongProvinceId" :localdata="regionsList"></uni-data-select>
</uni-forms-item> -->
<uni-forms-item label="社会信用代码" required>
<uni-easyinput v-model="form.creditCode" :disabled="type&&!!creditCode&&newResult" />
</uni-forms-item>
<uni-forms-item label="联系人" required>
<uni-easyinput v-model="form.siteContact" />
<uni-easyinput v-model="form.creditCode" :disabled="isFieldDisabled('creditCode')" />
</uni-forms-item>
<uni-forms-item label="联系方式" required>
<uni-easyinput v-model="form.siteTel" />
<uni-forms-item label="机构名称" required>
<uni-easyinput v-model="form.name" :disabled="type" placeholder="机构名称" />
</uni-forms-item>
<uni-forms-item label="认证地址" required>
<uni-data-picker v-model="form.coordinates1" @change="changeCoordinates1" placeholder="请选择认证地址"
:localdata="regionsList"></uni-data-picker>
</uni-forms-item>
<uni-forms-item label="详细地址" required>
<uni-easyinput v-model="form.adress" placeholder="请输入详细地址" type='textarea' /></uni-forms-item>
<uni-forms-item label="法人姓名" required>
<uni-easyinput v-model="form.legal" />
<uni-forms-item label="认证详细地址" required>
<uni-easyinput v-model="form.adress" :disabled="isFieldDisabled('adress')" placeholder="请输入详细地址" type='textarea' />
</uni-forms-item>
<uni-forms-item label="法人证件号" required>
<uni-easyinput v-model="form.legalIdcCode" />
<uni-forms-item label="所属协会" required>
<view style="width: 60vw;overflow:auto;">
<uni-data-picker v-model="form.parentId" :localdata="tree"
:readonly="type&&parentId!=-1&&parentId!=0" :clear-icon="false" placeholder="请选择协会"
:map="{text:'label',value:'id'}" popup-title="" @change="changCase">
</uni-data-picker>
</view>
</uni-forms-item>
<!-- <uni-forms-item v-if="form.deptType==6&&activeStatus!= 0" label="是否申请考点" required>
<uni-data-checkbox v-model="form.applyPoints" :localdata="yesno" />
</uni-forms-item> -->
<uni-forms-item label="法人身份证" required>
<view class="imgArea">
<uni-file-picker v-model="imgfront" @delete="delimgFont" return-type="object" limit="1"
......@@ -61,22 +44,26 @@
</uni-file-picker>
</view>
</uni-forms-item>
<uni-forms-item label="营业执照名称" required>
<uni-easyinput v-model="form.companyName" />
<uni-forms-item label="法人姓名" required>
<uni-easyinput v-model="form.legal" :disabled="isFieldDisabled('legal')" />
</uni-forms-item>
<uni-forms-item label="营业执照" required>
<uni-file-picker limit="1" v-model="businessLicenseArr" file-extname="png,jpg,jpeg,pdf"
file-mediatype="all" @select="selectFile" @delete="delSupplementFile"></uni-file-picker>
<uni-forms-item label="法人证件号" required>
<uni-easyinput v-model="form.legalIdcCode" />
</uni-forms-item>
<!-- <uni-forms-item label="社会信用代码" required>
<uni-file-picker limit="1" v-model="businessLicenseArr" file-extname="png,jpg,jpeg,pdf"
file-mediatype="all" @select="selectFile" @delete="delSupplementFile"></uni-file-picker>
</uni-forms-item> -->
<uni-forms-item label="机构照片" required>
<uni-forms-item label="联系人" required>
<uni-easyinput v-model="form.siteContact" />
</uni-forms-item>
<uni-forms-item label="联系方式" required>
<uni-easyinput v-model="form.siteTel" />
</uni-forms-item>
<uni-forms-item label="上传机构照片" required>
<uni-file-picker v-model="picArrR" limit="3" mode="grid" file-mediatype="image"
@select="upPicArr" @delete="delpicArr">
</uni-file-picker>
</uni-forms-item>
<!-- <uni-forms-item v-if="form.memCode" label="会员编号" required>
<uni-easyinput v-model="form.memCode" disabled />
</uni-forms-item> -->
<view class="notice-box">
<checkbox-group @change="onNoticeChange">
<label class="notice-label">
......@@ -141,13 +128,13 @@
} from 'vue';
import * as api from '@/common/api.js';
import _ from 'underscore'
import {
onLoad,
onShow
} from '@dcloudio/uni-app';
import config from '@/config.js'
import { reLaunchHomeByRole } from '@/common/utils.js'
const app = getApp();
import {
onLoad,
onShow
} from '@dcloudio/uni-app';
import config from '@/config.js'
import { reLaunchHomeByRole } from '@/common/utils.js'
const app = getApp();
const verifyPopup = ref(null)
const applyPopup = ref(null)
......@@ -173,6 +160,7 @@
const memberFee = ref('')
const preferentialPolicy = ref(false)
const preferentialData = ref({})
const ocrLockedFields = ref({})
const typeList = ref([{
value: '1',
text: '企业'
......@@ -222,10 +210,14 @@
}, {
title: '会员认证'
}])
const imageStylesZJ = ref({
width: '400rpx',
height: '253rpx'
});
const imageStylesZJ = ref({
width: '400rpx',
height: '253rpx'
});
const businessLicenseImageStyles = ref({
width: '240rpx',
height: '160rpx'
});
const indicatorStyle = ref(`height: 50px;`)
const imgfront = ref({})
const imgBack = ref({})
......@@ -236,6 +228,20 @@
const legalIdcPhoto2 = ref('')
const companyName = ref('')
function isFieldDisabled(field) {
return type.value || !!ocrLockedFields.value[field]
}
function lockOcrField(field, value) {
if (value !== undefined && value !== null && String(value).trim() !== '') {
ocrLockedFields.value[field] = true
}
}
function unlockOcrFields() {
ocrLockedFields.value = {}
}
onLoad(option => {
if (app.globalData.isLogin) {
init()
......@@ -310,16 +316,16 @@
form.value.coordinates1 = ''
}
if (form.value.businessLicense) {
try {
businessLicenseArr.value = JSON.parse(form.value.businessLicense) || []
} catch (e) {
businessLicenseArr.value = [{
url: form.value.businessLicense,
name: '营业执照'
}]
}
}
if (form.value.businessLicense) {
try {
businessLicenseArr.value = formatBusinessLicensePickerFiles(JSON.parse(form.value.businessLicense) || [])
} catch (e) {
businessLicenseArr.value = formatBusinessLicensePickerFiles([{
url: form.value.businessLicense,
name: '营业执照'
}])
}
}
if (form.value.legalIdcPhoto) {
legalIdcPhoto1.value = form.value.legalIdcPhoto.split(',')?.[0] || ''
......@@ -401,58 +407,58 @@
// 核心:修改submit方法,改用自定义弹窗
async function submit() {
// 基础表单验证
if (form.value.name == '') {
if (!form.value.businessLicense) {
uni.showToast({
title: '请填写机构名称',
title: '请上传营业执照',
icon: 'none'
})
return
}
if (form.value.creditCode == '') {
if (form.value.companyName == '') {
uni.showToast({
title: '请填写社会信用代码',
title: '请填写营业执照名称',
icon: 'none'
})
return
}
if (form.value.companyName == '') {
if (form.value.creditCode == '') {
uni.showToast({
title: '请填写营业执照名称',
title: '请填写社会信用代码',
icon: 'none'
})
return
}
if (form.value.legalIdcCode == '') {
if (form.value.name == '') {
uni.showToast({
title: '请填写法人证件号',
title: '请填写机构名称',
icon: 'none'
})
return
}
if (form.value.siteContact == '') {
if (form.value.coordinates1 == '') {
uni.showToast({
title: '请填写联系人',
title: '请选择认证地址',
icon: 'none'
})
return
}
if (form.value.siteTel == '') {
if (form.value.adress == '') {
uni.showToast({
title: '请填写联系方式',
title: '请填写认证详细地址',
icon: 'none'
})
return
}
if (form.value.coordinates1 == '') {
if (form.value.parentId == -1 || form.value.parentId == 0) {
uni.showToast({
title: '请选择认证地址',
title: '请选择所属协会',
icon: 'none'
})
return
}
if (form.value.adress == '') {
if (legalIdcPhoto1.value == '' || legalIdcPhoto2.value == '') {
uni.showToast({
title: '请填写详细地址',
title: '请上传法人身份证',
icon: 'none'
})
return
......@@ -464,37 +470,37 @@
})
return
}
if (legalIdcPhoto1.value == '' || legalIdcPhoto2.value == '') {
if (form.value.legalIdcCode == '') {
uni.showToast({
title: '请上传法人身份证',
title: '请填写法人证件号',
icon: 'none'
})
return
}
if (!form.value.businessLicense) {
if (form.value.siteContact == '') {
uni.showToast({
title: '请上传营业执照',
title: '请填写联系人',
icon: 'none'
})
return
}
if (picArr.value.length == 0) {
if (form.value.siteTel == '') {
uni.showToast({
title: '请上传机构照片',
title: '请填写联系方式',
icon: 'none'
})
return
}
if (!form.value.notice) {
if (picArr.value.length == 0) {
uni.showToast({
title: '请阅读并同意注册须知、入会须知、免责声明',
title: '请上传机构照片',
icon: 'none'
})
return
}
if (form.value.parentId == -1 || form.value.parentId == 0) {
if (!form.value.notice) {
uni.showToast({
title: '请选择所属协会',
title: '请阅读并同意注册须知、入会须知、免责声明',
icon: 'none'
})
return
......@@ -654,11 +660,11 @@
uni.showModal({
content: '激活成功,返回首页',
success: function(resp) {
if (resp.confirm) {
reLaunchHomeByRole()
} else {
uni.navigateBack()
}
if (resp.confirm) {
reLaunchHomeByRole()
} else {
uni.navigateBack()
}
}
})
}).catch(err => {
......@@ -817,35 +823,87 @@
let selectFileValue = {}
function selectFile(e) {
async function selectFile(e) {
let file = e.tempFiles[0]
if (!file) return
uni.showLoading({
title: '上传中'
})
api.uploadFile(e).then(data => {
selectFileValue = {
url: data.msg,
name: file.name,
extname: file.extname
try {
const data = await api.uploadFile(e)
const ocrData = await getBusinessLicenseOcr(file.url || file.path || e.tempFilePaths?.[0])
if (ocrData) {
form.value.companyName = ocrData.companyName || form.value.companyName
form.value.creditCode = ocrData.creditCode || form.value.creditCode
form.value.legal = ocrData.legalPerson || form.value.legal
form.value.adress = ocrData.businessAddress || form.value.adress
lockOcrField('companyName', form.value.companyName)
lockOcrField('creditCode', form.value.creditCode)
lockOcrField('legal', form.value.legal)
lockOcrField('adress', form.value.adress)
}
form.value.businessLicense = JSON.stringify([selectFileValue])
uni.hideLoading()
}).catch(err => {
selectFileValue = {
url: data.msg,
name: ocrData?.name || file.name || '营业执照',
extname: file.extname
}
businessLicenseArr.value = formatBusinessLicensePickerFiles([selectFileValue])
form.value.businessLicense = JSON.stringify([selectFileValue])
uni.hideLoading()
} catch (err) {
uni.hideLoading()
uni.showToast({
title: '上传失败',
icon: 'none'
})
})
}
}
function delSupplementFile() {
selectFileValue = {}
form.value.businessLicense = ''
unlockOcrFields()
}
function upPicArr(e) {
function getBusinessLicenseOcr(filePath) {
if (!filePath) return Promise.resolve(null)
return new Promise((resolve) => {
uni.uploadFile({
url: config.baseUrl_api + '/member/info/getBusinessLicense',
filePath,
name: 'pic',
header: {
'Authorization': uni.getStorageSync('token')
},
success: (res) => {
try {
const data = JSON.parse(res.data || '{}')
resolve(data.code === 200 ? data.data : null)
} catch (e) {
resolve(null)
}
},
fail: () => resolve(null)
})
})
}
function normalizeFileUrl(url) {
if (!url) return ''
if (url.indexOf('http') === 0) return url
if (url.indexOf('/') === 0) return config.baseUrl_api + url
return `${config.baseUrl_api}/fileServer/download?file=${encodeURIComponent(url)}&downFlag=0`
}
function formatBusinessLicensePickerFiles(files = []) {
return files.map(item => ({
...item,
rawUrl: item.url,
url: normalizeFileUrl(item.url)
}))
}
function upPicArr(e) {
const tempFilePaths = e.tempFilePaths;
const imgUrl = tempFilePaths[0]
if (!imgUrl) return
......@@ -954,13 +1012,13 @@
color: #666;
}
.notice-link {
color: #007AFF;
}
.imgArea {
padding: 1px;
display: flex;
.notice-link {
color: #007AFF;
}
.imgArea {
padding: 1px;
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
......@@ -1069,4 +1127,4 @@
.apply-btns {
margin-bottom: 20rpx;
}
</style>
</style>
......
......@@ -19,12 +19,11 @@
<view class="member-left">
<view class="hello">您好!</view>
<view class="member-name">{{ memberName }}</view>
<view class="member-desc">您已经是中国跆拳道协会的金牌会员了</view>
<view class="name-line"></view>
<!-- <view class="member-desc">您已经是中国跆拳道协会的金牌会员了</view> -->
</view>
<view class="level-box" @click="goPath('/myCenter/reviewList')">
<image class="star" :src="config.baseUrl_api + '/fs/static/img/star.png'" mode="aspectFit"></image>
<view class="level-title">晋级考点</view>
<image class="star" :src="examPointIcon" mode="aspectFit"></image>
<view class="level-title" :class="{ disabled: !isExamPoint }">晋级考点</view>
<view class="detail-btn">查看详情</view>
</view>
</view>
......@@ -154,6 +153,13 @@ const validityDate = computed(() => {
return value ? String(value).slice(0, 10) : '--'
})
const isExamPoint = computed(() => String(memberInfo.value?.isPoints) === '0')
const examPointIcon = computed(() => {
const fileName = isExamPoint.value ? 'star.png' : 'star_g.png'
return `${config.baseUrl_api}/fs/static/img/${fileName}`
})
onLoad((option) => {
const userName = uni.getStorageSync('userName')
if (!userName) {
......@@ -412,7 +418,7 @@ function closeExamPointDialog() {
function goExamPointApply() {
closeExamPointDialog()
uni.navigateTo({ url: '/myCenter/examPointApplyList' })
uni.navigateTo({ url: '/pages/index/notice-examPointApply' })
}
async function handleNoDisplay() {
......@@ -509,10 +515,23 @@ function handelCancelOrder() {
function handelGetMyRecent() {
return new Promise(async (resolve) => {
const res = await to(api.getMyRecent())
if (res[0] || !res[1]?.data) return resolve(false)
payForm.value = res[1].data?.comOrder || {}
if (payForm.value.content) payForm.value.content = JSON.parse(payForm.value.content)
const [err, res] = await to(api.getMyRecent())
if (err) {
uni.showToast({ title: '获取缴费状态失败,请稍后重试', icon: 'none' })
return resolve(false)
}
const recentData = res?.data
if (!recentData) {
payForm.value = {}
return resolve(true)
}
payForm.value = recentData?.comOrder || {}
if (!payForm.value.id) return resolve(true)
if (payForm.value.content && typeof payForm.value.content === 'string') {
try {
payForm.value.content = JSON.parse(payForm.value.content)
} catch (e) {}
}
if (payForm.value.payStatus === '0') {
unpaidPopup.value?.open()
return resolve(false)
......@@ -609,6 +628,7 @@ function handelGetMyRecent() {
color: #181818;
font-size: 34rpx;
font-weight: 700;
// border-bottom:6rpx solid #111;
}
.member-desc {
......@@ -617,13 +637,7 @@ function handelGetMyRecent() {
font-size: 22rpx;
}
.name-line {
width: 112rpx;
height: 6rpx;
margin-top: 14rpx;
background: #111;
border-radius: 8rpx;
}
.level-box {
display: flex;
......@@ -644,6 +658,10 @@ function handelGetMyRecent() {
font-weight: 700;
}
.level-title.disabled {
color: #9a9a9a;
}
.detail-btn {
margin-top: 8rpx;
padding: 4rpx 14rpx;
......
......@@ -77,10 +77,14 @@
<text v-if="authenticationStatus == 0 || !authenticationStatus" class="text-danger">未认证</text>
<text v-if="authenticationStatus == 1" class="text-warning">认证中</text>
<text v-if="authenticationStatus == 2" class="text-success">已认证</text>
<text v-if="authenticationStatus == 3" class="text-danger">认证未通过</text>
<text v-if="authenticationStatus == 3" class="text-danger">审核未通过</text>
<text v-if="authenticationStatus == 4" class="text-warning">即将过期</text>
<text v-if="authenticationStatus == 5" class="text-danger">已过期</text>
</view>
<view v-if="authenticationStatus == 3 && rejectReason" class="reject-reason">
<text class="reject-label">未通过理由:</text>
<text class="reject-text">{{ rejectReason }}</text>
</view>
<!-- <view class="logout-btn" @click="handleLogout">
<text class="logout-icon"></text>
<text class="logout-text">退出</text>
......@@ -88,47 +92,6 @@
</view>
<uni-forms ref="certForm" :modelValue="form" label-width="90">
<uni-forms-item label="选择所属协会" required>
<view class="picker-wrapper">
<uni-data-picker
v-model="form.parentId"
:disabled="!editIng"
:level="3"
:localdata="assoList"
class="custom-picker"
popup-title="请选择所属协会"
@change="changCase"
></uni-data-picker>
</view>
</uni-forms-item>
<uni-forms-item label="机构名称" required>
<uni-easyinput v-model="form.name" :disabled="!editIng" class="input-with-border"
placeholder="请输入机构名称"/>
</uni-forms-item>
<uni-forms-item label="认证地址" required>
<view class="picker-wrapper">
<uni-data-picker
v-model="coordinates1"
:disabled="!editIng"
:localdata="regionOptions"
class="custom-picker"
popup-title="请选择所在地区"
@change="changeAddress"
></uni-data-picker>
</view>
</uni-forms-item>
<uni-forms-item label="认证详细地址" required>
<uni-easyinput v-model="form.adress" :disabled="!editIng" class="input-with-border"
placeholder="请输入详细地址"/>
</uni-forms-item>
<uni-forms-item label="联系人" required>
<uni-easyinput v-model="form.siteContact" :disabled="!editIng" class="input-with-border"
placeholder="请输入联系人"/>
</uni-forms-item>
<uni-forms-item label="联系方式" required>
<uni-easyinput v-model="form.siteTel" :disabled="!editIng" class="input-with-border"
placeholder="请输入联系方式"/>
</uni-forms-item>
<uni-forms-item label="营业执照" required>
<view class="upload-box">
<view v-if="!form.businessLicense" class="upload-placeholder" @click="onBusinessLicenseSelect">
......@@ -142,19 +105,52 @@
</view>
</uni-forms-item>
<uni-forms-item label="营业执照名称" required>
<uni-easyinput v-model="form.companyName" :disabled="!editIng" class="input-with-border"
<uni-easyinput v-model="form.companyName" :disabled="isFieldDisabled('companyName')" class="input-with-border"
placeholder="请输入营业执照名称"/>
</uni-forms-item>
<uni-forms-item label="社会信用代码" required>
<uni-easyinput
v-model="form.creditCode"
:disabled="!editIng"
:disabled="isFieldDisabled('creditCode')"
class="input-with-border"
placeholder="请输入社会信用代码"
@blur="onCreditCodeBlur"
@change="onCreditCodeBlur"
/>
</uni-forms-item>
<uni-forms-item label="机构名称" required>
<uni-easyinput v-model="form.name" :disabled="isFieldDisabled('name')" class="input-with-border"
placeholder="请输入机构名称"/>
</uni-forms-item>
<uni-forms-item label="认证地址" required>
<view class="picker-wrapper">
<uni-data-picker
v-model="coordinates1"
:disabled="isFieldDisabled('address')"
:localdata="regionOptions"
class="custom-picker"
popup-title="请选择所在地区"
@change="changeAddress"
></uni-data-picker>
</view>
</uni-forms-item>
<uni-forms-item label="认证详细地址" required>
<uni-easyinput v-model="form.adress" :disabled="isFieldDisabled('adress')" class="input-with-border"
placeholder="请输入详细地址"/>
</uni-forms-item>
<uni-forms-item label="所属协会" required>
<view class="picker-wrapper">
<uni-data-picker
v-model="form.parentId"
:disabled="isFieldDisabled('parentId')"
:level="3"
:localdata="assoList"
class="custom-picker"
popup-title="请选择所属协会"
@change="changCase"
></uni-data-picker>
</view>
</uni-forms-item>
<uni-forms-item label="法人身份证" required>
<view class="idcard-box">
<view class="idcard-item">
......@@ -182,13 +178,21 @@
</view>
</uni-forms-item>
<uni-forms-item label="法人姓名" required>
<uni-easyinput v-model="form.legal" :disabled="!editIng" class="input-with-border"
<uni-easyinput v-model="form.legal" :disabled="isFieldDisabled('legal')" class="input-with-border"
placeholder="请输入法人姓名"/>
</uni-forms-item>
<uni-forms-item label="法人证件号" required>
<uni-easyinput v-model="form.legalIdcCode" :disabled="!editIng" class="input-with-border"
<uni-easyinput v-model="form.legalIdcCode" :disabled="isFieldDisabled('legalIdcCode')" class="input-with-border"
placeholder="请输入法人证件号"/>
</uni-forms-item>
<uni-forms-item label="联系人" required>
<uni-easyinput v-model="form.siteContact" :disabled="!editIng" class="input-with-border"
placeholder="请输入联系人"/>
</uni-forms-item>
<uni-forms-item label="联系方式" required>
<uni-easyinput v-model="form.siteTel" :disabled="!editIng" class="input-with-border"
placeholder="请输入联系方式"/>
</uni-forms-item>
<uni-forms-item label="上传机构照片" required>
<view class="pictures-box">
<view v-if="!form.pictures" class="picture-placeholder" @click="onPicturesSelect">
......@@ -412,10 +416,28 @@ const auditStatus = ref('0')
// 审核详情
const auditList = ref([])
const auditLoading = ref(false)
const rejectReason = ref('')
// 社会信用代码校验状态(true=校验通过,false=校验失败/已存在)
const creditCodeValid = ref(true)
// OCR 自动带出的字段默认不可编辑,避免手动改动导致和营业执照信息不一致。
const ocrLockedFields = ref({})
function isFieldDisabled(field) {
return !editIng.value || !!ocrLockedFields.value[field]
}
function lockOcrField(field, value) {
if (value !== undefined && value !== null && String(value).trim() !== '') {
ocrLockedFields.value[field] = true
}
}
function unlockOcrFields() {
ocrLockedFields.value = {}
}
// 须知勾选
function onNoticeChange(e) {
if (!editIng.value) return
......@@ -500,7 +522,7 @@ function handelGetMyRecent() {
confirmText: '去支付',
onConfirm: () => {
// 去支付,跳转到缴费页面
const assoName = assoFullName.value
const assoName = getCurrentAssoName()
uni.navigateTo({
url: `/myCenter/goPay?payName=${encodeURIComponent(payForm.value.orderName || form.value.name || '')}&assoName=${encodeURIComponent(assoName)}&orderId=${payForm.value.id}&source=perfect`
})
......@@ -552,27 +574,51 @@ function getMyCertStageFN() {
auditLoading.value = true
api.getMyRecent({showLoading: false}).then(res => {
auditLoading.value = false
const directReason = getRejectReasonFromData(res.data)
if (res.data && res.data.auditLogs) {
try {
auditList.value = JSON.parse(res.data.auditLogs)
updateRejectReason(directReason)
} catch (e) {
auditList.value = []
rejectReason.value = directReason
}
} else {
auditList.value = []
rejectReason.value = directReason
}
}).catch(() => {
auditLoading.value = false
auditList.value = []
rejectReason.value = ''
})
}
function getRejectReasonFromData(data = {}) {
return data?.auditReason || data?.auditMsg || data?.reason || data?.rejectReason || data?.refuseReason || ''
}
function getRejectReasonFromLog(item = {}) {
return item.auditMsg || item.auditReason || item.reason || item.rejectReason || item.refuseReason || item.remark || ''
}
function isRejectAuditLog(item = {}) {
return item.auditResult == 2 || item.auditResult == 3 || item.auditStatus == 3 || item.status == 3
}
function updateRejectReason(fallbackReason = '') {
const logs = Array.isArray(auditList.value) ? auditList.value : []
const rejectItem = [...logs].reverse().find(item => isRejectAuditLog(item) && getRejectReasonFromLog(item))
const latestReasonItem = [...logs].reverse().find(item => getRejectReasonFromLog(item))
rejectReason.value = getRejectReasonFromLog(rejectItem) || fallbackReason || getRejectReasonFromLog(latestReasonItem) || ''
}
// 审核状态文字
function getAuditStatusText(status) {
const map = {
0: '待审核',
1: '审核通过',
2: '审核拒绝'
2: '审核未通过'
}
return map[status] || '待审核'
}
......@@ -664,7 +710,7 @@ function getDetail() {
form.value.type = String(form.value.type)
}
authenticationStatus.value = res.data.authenticationStatus
switch (res.data.authenticationStatus) {
switch (String(res.data.authenticationStatus ?? '')) {
case '0' :
activeStep.value = 2
break
......@@ -676,6 +722,7 @@ function getDetail() {
break
case '3':
activeStep.value = 2
getMyCertStageFN()
break
default:
activeStep.value = 1
......@@ -745,6 +792,10 @@ function getDetail() {
} else {
editIng.value = true
}
if (authenticationStatus.value != 3) {
rejectReason.value = ''
}
// creditCode.value = form.value.creditCode
// legal.value = form.value.legal
......@@ -769,7 +820,7 @@ function formatRegionTree(node) {
// 获取地区列表
function getRegionsList() {
api.regionsList(null, {showLoading: false}).then(res => {
return api.regionsList(null, {showLoading: false}).then(res => {
options.value = res.data
// 转换为级联选择器格式
regionOptions.value = res.data
......@@ -779,7 +830,7 @@ function getRegionsList() {
// 获取协会树
function getTree() {
api.certifiedDeptTreeRegister({
return api.certifiedDeptTreeRegister({
selfDeptId: -1, // 修复:传数字类型,避免后端类型转换错误
webSiteShow: 1,
showDisabled: 1,
......@@ -837,7 +888,7 @@ function findAssoNodeWithPath(list, targetId, currentPath) {
// 协会选择(修复:100%对齐PC端el-cascader emitPath: false逻辑,只取最后一级ID)
function changCase(e) {
if (!editIng.value) return
if (isFieldDisabled('parentId')) return
const valueArr = e.detail?.value || e;
// 取最后一级的value(纯ID)
const lastNode = valueArr[valueArr.length - 1];
......@@ -848,7 +899,7 @@ function changCase(e) {
// 地址选择(核心修复:从对象中提取纯value,对齐PC端格式)
// 地址选择(还原成你之前能用的版本:纯ID数组赋值)
function changeAddress(e) {
if (!editIng.value) return
if (isFieldDisabled('address')) return
const selectedValue = e.detail?.value ?? e;
// 直接赋值纯ID,不要再取 .value
......@@ -936,30 +987,6 @@ function submitStep1() {
// 步骤2提交
async function submitStep2() {
// 验证必填项
if (!form.value.parentId || form.value.parentId == 0 || form.value.parentId == -1) {
uni.showToast({title: '请选择所属协会', duration: 2000, icon: 'none'})
return
}
if (!form.value.name) {
uni.showToast({title: '请输入机构名称', duration: 2000, icon: 'none'})
return
}
if (coordinates1.value.length === 0) {
uni.showToast({title: '请选择认证地址', duration: 2000, icon: 'none'})
return
}
if (!form.value.adress) {
uni.showToast({title: '请输入认证详细地址', duration: 2000, icon: 'none'})
return
}
if (!form.value.siteContact) {
uni.showToast({title: '请输入联系人', duration: 2000, icon: 'none'})
return
}
if (!form.value.siteTel) {
uni.showToast({title: '请输入联系方式', duration: 2000, icon: 'none'})
return
}
if (!form.value.businessLicense) {
uni.showToast({title: '请上传营业执照', duration: 2000, icon: 'none'})
return
......@@ -976,6 +1003,22 @@ async function submitStep2() {
uni.showToast({title: '社会信用代码已存在,请联系中跆协修改', icon: 'none', duration: 3000})
return
}
if (!form.value.name) {
uni.showToast({title: '请输入机构名称', duration: 2000, icon: 'none'})
return
}
if (coordinates1.value.length === 0) {
uni.showToast({title: '请选择认证地址', duration: 2000, icon: 'none'})
return
}
if (!form.value.adress) {
uni.showToast({title: '请输入认证详细地址', duration: 2000, icon: 'none'})
return
}
if (!form.value.parentId || form.value.parentId == 0 || form.value.parentId == -1) {
uni.showToast({title: '请选择所属协会', duration: 2000, icon: 'none'})
return
}
if (!form.value.legalIdcPhoto1 || !form.value.legalIdcPhoto2) {
uni.showToast({title: '请上传身份证正反面', duration: 2000, icon: 'none'})
return
......@@ -988,6 +1031,14 @@ async function submitStep2() {
uni.showToast({title: '请输入法人证件号', duration: 2000, icon: 'none'})
return
}
if (!form.value.siteContact) {
uni.showToast({title: '请输入联系人', duration: 2000, icon: 'none'})
return
}
if (!form.value.siteTel) {
uni.showToast({title: '请输入联系方式', duration: 2000, icon: 'none'})
return
}
if (!form.value.pictures) {
uni.showToast({title: '请上传机构照片', duration: 2000, icon: 'none'})
return
......@@ -1079,7 +1130,7 @@ function submitCertification() {
uni.showToast({title: '提交成功', duration: 1500, icon: 'success'})
// 跳转缴费页面
setTimeout(() => {
const assoName = assoFullName.value
const assoName = getCurrentAssoName()
// 跳转到缴费页面
uni.navigateTo({
url: `/myCenter/goPay?payName=${encodeURIComponent(form.value.name || '')}&assoName=${encodeURIComponent(assoName)}&source=perfect`
......@@ -1120,13 +1171,25 @@ function onBusinessLicenseSelect() {
}).then(ocrRes => {
return {url, ocrRes}
})
}).then(({url, ocrRes}) => {
}).then(async ({url, ocrRes}) => {
uni.hideLoading()
const data = JSON.parse(ocrRes.data)
let name = '营业执照'
if (data.code === 200 && data.data) {
form.value.creditCode = data.data.creditCode
form.value.companyName = data.data.companyName
const ocrData = data.data
form.value.creditCode = ocrData.creditCode || form.value.creditCode
form.value.companyName = ocrData.companyName || form.value.companyName
form.value.legal = ocrData.legalPerson || form.value.legal
lockOcrField('creditCode', form.value.creditCode)
lockOcrField('companyName', form.value.companyName)
lockOcrField('legal', form.value.legal)
if (!regionOptions.value?.length) {
await getRegionsList().catch(() => {})
}
if (!assoList.value?.length) {
await getTree().catch(() => {})
}
applyBusinessAddress(ocrData.businessAddress)
name = data.data.name || '营业执照'
onCreditCodeBlur()
}
......@@ -1150,6 +1213,121 @@ function removeBusinessLicense() {
if (!editIng.value) return
form.value.businessLicense = ''
form.value.businessLicenseName = ''
unlockOcrFields()
}
function getNodeValue(node) {
return node?.value ?? node?.id ?? ''
}
function getNodeText(node) {
return node?.text ?? node?.label ?? node?.name ?? ''
}
function normalizeAddressText(text) {
return String(text || '').replace(/\s/g, '')
}
function getAddressKeywords(name) {
const fullName = normalizeAddressText(name)
const shortName = fullName.replace(/省|市|区|县|自治区|壮族自治区|回族自治区|维吾尔自治区|地区|自治州|盟|旗/g, '')
return [...new Set([fullName, shortName].filter(keyword => keyword && keyword.length > 1))]
}
function addressIncludes(target, name) {
return getAddressKeywords(name).some(keyword => target.includes(keyword))
}
function findRegionPathByAddress(address) {
const target = normalizeAddressText(address)
if (!target || !regionOptions.value?.length) return null
const candidates = []
for (const province of regionOptions.value) {
const provinceMatched = addressIncludes(target, getNodeText(province))
const provincePath = [province]
const cities = province.children || []
for (const city of cities) {
const cityMatched = addressIncludes(target, getNodeText(city))
const cityPath = [province, city]
const regions = city.children || []
for (const region of regions) {
const regionMatched = addressIncludes(target, getNodeText(region))
if (provinceMatched || cityMatched || regionMatched) {
const score = (provinceMatched ? 1 : 0) + (cityMatched ? 2 : 0) + (regionMatched ? 4 : 0)
candidates.push({path: [province, city, region], score})
}
}
if (provinceMatched || cityMatched) {
const score = (provinceMatched ? 1 : 0) + (cityMatched ? 2 : 0)
candidates.push({path: cityPath, score})
}
}
if (provinceMatched) {
candidates.push({path: provincePath, score: 1})
}
}
candidates.sort((a, b) => b.score - a.score || b.path.length - a.path.length)
return candidates[0]?.path || null
}
function applyRegionPath(path) {
if (!path?.length) return false
const valuePath = path.map(node => ({
value: getNodeValue(node),
text: getNodeText(node)
}))
coordinates1.value = valuePath
form.value.provinceId = getNodeValue(path[0]) || ''
form.value.cityId = getNodeValue(path[1]) || ''
form.value.regionId = getNodeValue(path[2]) || ''
lockOcrField('address', form.value.provinceId || form.value.cityId || form.value.regionId)
return true
}
function findAssoPathByRegionNames(regionPath) {
if (!regionPath?.length || !assoList.value?.length) return null
const names = regionPath.map(node => normalizeAddressText(getNodeText(node))).filter(Boolean)
const candidates = []
function walk(list, path) {
for (const item of list || []) {
const itemName = normalizeAddressText(getNodeText(item))
const nextPath = [...path, item]
const score = names.reduce((total, name, index) => {
const shortName = name.replace(/省|市|区|县|自治区|壮族自治区|回族自治区|维吾尔自治区|地区|自治州|盟|旗/g, '')
return total + (itemName.includes(name) || (shortName.length > 1 && itemName.includes(shortName)) ? index + 1 : 0)
}, 0)
if (score > 0) candidates.push({path: nextPath, score})
if (item.children?.length) walk(item.children, nextPath)
}
}
walk(assoList.value, [])
candidates.sort((a, b) => b.score - a.score || b.path.length - a.path.length)
return candidates[0]?.path || null
}
function applyAssoPath(path) {
if (!path?.length) return false
const lastNode = path[path.length - 1]
form.value.parentId = getNodeValue(lastNode) || ''
assoFullName.value = getAssoFullName(path.map(node => ({value: getNodeValue(node)})))
lockOcrField('parentId', form.value.parentId)
return !!form.value.parentId
}
function applyBusinessAddress(address) {
const businessAddress = String(address || '').trim()
if (!businessAddress) return
form.value.adress = businessAddress
lockOcrField('adress', businessAddress)
const regionPath = findRegionPathByAddress(businessAddress)
if (applyRegionPath(regionPath)) {
const assoPath = findAssoPathByRegionNames(regionPath)
applyAssoPath(assoPath)
}
}
// 删除身份证正面
......@@ -1292,7 +1470,7 @@ function goPay() {
return
}
// 使用完整的协会路径名称
const assoName = assoFullName.value || getAssoName(form.value.parentId)
const assoName = getCurrentAssoName()
// 跳转到缴费页面
uni.navigateTo({
url: `/myCenter/goPay?payName=${encodeURIComponent(form.value.name || '')}&assoName=${encodeURIComponent(assoName)}&source=perfect`
......@@ -1322,6 +1500,10 @@ function getAssoName(parentId) {
return findInTree(assoList.value) || ''
}
function getCurrentAssoName() {
return assoFullName.value || getAssoName(form.value.parentId)
}
// 根据选择的值数组获取完整的协会路径名称
function getAssoFullName(valueArr) {
if (!valueArr || valueArr.length === 0 || !assoList.value || assoList.value.length === 0) {
......@@ -1574,8 +1756,8 @@ watch(activeStep, (newVal) => {
.status-box {
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: column;
align-items: flex-start;
padding: 20rpx 0;
margin-bottom: 20rpx;
}
......@@ -1593,6 +1775,26 @@ watch(activeStep, (newVal) => {
width: 100px;
}
.reject-reason {
width: 100%;
margin-top: 14rpx;
padding: 16rpx 18rpx;
box-sizing: border-box;
background: #fff1f1;
border-radius: 12rpx;
color: #AD181F;
line-height: 1.5;
font-size: 24rpx;
}
.reject-label {
font-weight: 600;
}
.reject-text {
word-break: break-all;
}
.logout-btn {
display: flex;
align-items: center;
......
......@@ -9,38 +9,25 @@
</view>
<view class="pdbox">
<view class="personitem" v-for="(n,index) in list" :key="index">
<uni-swipe-action>
<uni-swipe-action-item>
<view class="content-box" @click="handleInfo(n)">
<view class="flexbox" style="flex: 1 1 auto;">
<view class="photobox">
<image class="photo" v-if="n.photo" :src="n.photo" mode='aspectFill'></image>
<view class="colorful" v-else>{{n.name.slice(0,1)}}</view>
</view>
<view>
{{n.name}} <text class="date">({{n.perCode}})</text>
</view>
</view>
<view class="flexbox" style="flex:0 0 auto">
<text v-if="n.certStage==0" class="text-primary">
新会员
</text>
<text v-if="n.certStage==1" class="text-warning">
待提交
</text>
<text v-if="n.certStage==2" class="text-red">
缴费中
</text>
<text v-if="n.certStage==3" class="text-success">
正常
</text>
<text v-if="n.certStage==4" class="text-gray">
过期
</text>
</view>
</view>
<view class="personitem" v-for="(n,index) in list" :key="index">
<uni-swipe-action>
<uni-swipe-action-item>
<view class="content-box" :class="{ normal: isNormalMember(n) }" @click="handleInfo(n)">
<view v-if="isNormalMember(n)" class="normal-corner">正常会员</view>
<view class="flexbox" style="flex: 1 1 auto;">
<view class="photobox">
<image class="photo" v-if="n.photo" :src="n.photo" mode='aspectFill'></image>
<view class="colorful" v-else>{{n.name.slice(0,1)}}</view>
</view>
<view class="member-info">
<view class="member-name">
{{n.name}} <text class="date">({{n.perCode || '--'}})</text>
</view>
<view class="validity-line">有效期:{{ formatValidityDate(n.validityDate) }}</view>
</view>
</view>
</view>
<template v-slot:right>
<view class="slot-button">
<!-- <view class="edit-button" @click="handleUpdate(n)">
......@@ -160,11 +147,19 @@
})
}
function handleInfo(n) {
uni.navigateTo({
url: `/personalVip/detail?perId=${n.perId}`
})
}
function handleInfo(n) {
uni.navigateTo({
url: `/personalVip/detail?perId=${n.perId}`
})
}
function isNormalMember(item) {
return String(item.certStage) === '3'
}
function formatValidityDate(value) {
return value ? String(value).slice(0, 10) : '--'
}
function goVipList() {
let path = '/personalVip/addVip';
......@@ -202,10 +197,44 @@
}
}
.content-box {
background: #fff;
.photobox{margin-right: 20rpx;
}
}
.pdbox{padding: 0 20rpx;}
</style>
\ No newline at end of file
.content-box {
position: relative;
background: #fff;
overflow: hidden;
.photobox{margin-right: 20rpx;
}
}
.content-box.normal {
background: linear-gradient(135deg, #fff3f4 0%, #ffffff 58%, #fff0f1 100%);
border: 1rpx solid rgba(196, 18, 27, 0.22);
box-shadow: 0 10rpx 26rpx rgba(196, 18, 27, 0.12);
}
.normal-corner {
position: absolute;
top: 0;
right: 0;
padding: 8rpx 18rpx;
border-radius: 0 0 0 20rpx;
background: linear-gradient(135deg, #C4121B 0%, #e24a52 100%);
color: #fff;
font-size: 22rpx;
font-weight: 600;
}
.member-info {
min-width: 0;
padding-right: 120rpx;
}
.member-name {
color: #222;
font-size: 30rpx;
font-weight: 600;
line-height: 1.4;
}
.validity-line {
margin-top: 8rpx;
color: #777;
font-size: 24rpx;
line-height: 1.4;
}
.pdbox{padding: 0 20rpx;}
</style>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!