8f77dd9a by lttnew

单位缴费校验营业执照

1 parent 4e1f81c6
......@@ -89,7 +89,7 @@ export function fillMemberPhoto(item = {}, fallback = '') {
return photo ? fillImgUrl(photo) : fallback
}
export function previewAttachment(file, options = {}) {
export async function previewAttachment(file, options = {}) {
const item = normalizeAttachment(file)
const rawUrl = item.rawUrl || item.url
const previewUrl = getAttachmentPreviewUrl(rawUrl, 0)
......@@ -101,6 +101,14 @@ export function previewAttachment(file, options = {}) {
return
}
if (isAttachmentImage(item) || isImageUrl(rawUrl) || isImageUrl(previewUrl)) {
const errorMsg = await checkAttachmentError(previewUrl)
if (errorMsg) {
uni.showToast({
title: errorMsg,
icon: 'none'
})
return
}
uni.previewImage({
urls: [previewUrl],
current: previewUrl,
......@@ -120,11 +128,7 @@ export function previewAttachment(file, options = {}) {
})
return
}
if (getAttachmentExt(item) === 'pdf' && options.preferWebView !== false) {
openAttachmentWebView(previewUrl, options.title || '附件预览')
return
}
openDocumentAttachment(item, getAttachmentPreviewUrl(rawUrl, 1), false, options)
openDocumentAttachment(item, getAttachmentPreviewUrl(rawUrl, 0), false, options)
}
export function normalizeAttachment(file) {
......@@ -163,7 +167,7 @@ export function getAttachmentPreviewUrl(url, downFlag = 0) {
const value = String(url).trim()
if (!value || value === 'null' || value === 'undefined') return ''
if (value.startsWith('msr:')) {
return `${trimBaseUrl(config.baseUrl_api)}/fileServer/download?file=${value}&downFlag=${downFlag}`
return `${trimBaseUrl(config.baseUrl_api)}/fileServer/download?file=${encodeURIComponent(value)}&downFlag=${downFlag}`
}
return fillImgUrl(value)
}
......@@ -192,8 +196,6 @@ function openDocumentAttachment(item, url, retried = false, options = {}) {
uni.hideLoading()
if (redirectUrl) {
openDocumentAttachment(item, redirectUrl, true, options)
} else if (getAttachmentExt(item) === 'pdf') {
openAttachmentWebView(getAttachmentPreviewUrl(item.rawUrl || item.url, 0), options.title || '附件预览')
} else {
uni.showToast({
title: '文件下载失败',
......@@ -202,10 +204,7 @@ function openDocumentAttachment(item, url, retried = false, options = {}) {
}
return
}
uni.showToast({
title: '文件下载失败',
icon: 'none'
})
showAttachmentFailToast(url, '文件下载失败')
return
}
uni.openDocument({
......@@ -213,10 +212,6 @@ function openDocumentAttachment(item, url, retried = false, options = {}) {
fileType: getDocumentFileType(item),
showMenu: true,
fail: () => {
if (getAttachmentExt(item) === 'pdf') {
openAttachmentWebView(getAttachmentPreviewUrl(item.rawUrl || item.url, 0), options.title || '附件预览')
return
}
uni.showToast({
title: '文件暂不支持预览',
icon: 'none'
......@@ -225,14 +220,7 @@ function openDocumentAttachment(item, url, retried = false, options = {}) {
})
},
fail: () => {
if (getAttachmentExt(item) === 'pdf') {
openAttachmentWebView(getAttachmentPreviewUrl(item.rawUrl || item.url, 0), options.title || '附件预览')
return
}
uni.showToast({
title: '文件下载失败',
icon: 'none'
})
showAttachmentFailToast(url, '文件下载失败')
},
complete: () => {
uni.hideLoading()
......@@ -260,9 +248,64 @@ function openAttachmentWebView(url, title = '附件预览') {
}
function getAttachmentExt(file) {
const name = `${file?.extname || file?.name || file?.rawUrl || file?.url || ''}`
const ext = name.includes('.') ? name.split('.').pop() : name
return ext.split('?')[0].toLowerCase()
const name = `${file?.extname || file?.name || file?.rawUrl || file?.url || file || ''}`
const fileParam = getQueryParam(name, 'file')
const cleanName = safeDecodeURIComponent(fileParam || name).split('?')[0].split('#')[0]
const fileName = cleanName.split('/').pop() || cleanName
const ext = fileName.includes('.') ? fileName.split('.').pop() : fileName
return ext.toLowerCase()
}
function checkAttachmentError(url) {
if (!isFileDownloadUrl(url)) return Promise.resolve('')
return new Promise(resolve => {
uni.request({
url,
method: 'GET',
header: {
Authorization: uni.getStorageSync('token') || ''
},
success: res => {
const data = parseAttachmentResponse(res.data)
if (res.statusCode >= 400 || (data && data.code && data.code !== 200)) {
resolve(getAttachmentErrorMsg(data))
return
}
resolve('')
},
fail: () => resolve('')
})
})
}
async function showAttachmentFailToast(url, fallback) {
const errorMsg = await checkAttachmentError(url)
uni.showToast({
title: errorMsg || fallback,
icon: 'none'
})
}
function parseAttachmentResponse(data) {
if (!data) return null
if (typeof data === 'object') return data
if (typeof data === 'string') {
try {
return JSON.parse(data)
} catch (e) {
return null
}
}
return null
}
function getAttachmentErrorMsg(data) {
const msg = data?.msg || data?.message || ''
if (!msg) return '附件预览失败'
if (msg.includes('Hostname') || msg.includes('certificate')) {
return '附件服务证书异常,请稍后再试'
}
return msg.length > 40 ? msg.slice(0, 40) : msg
}
function isAttachmentImage(file) {
......@@ -282,6 +325,16 @@ function getRedirectUrl(header = {}) {
return `${trimBaseUrl(config.baseUrl_api)}/${String(location).replace(/^\/+/, '')}`
}
function isFileDownloadUrl(url) {
const value = String(url || '')
return value.includes('/fileServer/download') || value.startsWith('fileServer/download')
}
function getQueryParam(url, key) {
const match = String(url || '').match(new RegExp(`[?&]${key}=([^&#]+)`))
return match ? safeDecodeURIComponent(match[1]) : ''
}
function isValidUrlValue(value) {
if (value === undefined || value === null) return false
const url = String(value).trim()
......
......@@ -251,6 +251,7 @@
const coordinates1 = ref([])
const pictures = ref()
const legalIdcPhoto = ref([])
const currentBusinessLicenseAddress = ref('')
const carriedReadonlyFields = ['companyName', 'creditCode', 'name', 'address', 'adress', 'parentId', 'legal', 'legalIdcCode']
function isFieldDisabled(field) {
......@@ -281,9 +282,21 @@
}
}
function unlockOcrFields() {
ocrLockedFields.value = {}
}
function unlockOcrFields() {
ocrLockedFields.value = {}
}
function clearBusinessLicenseUpload() {
selectFileValue = {}
form.value.businessLicense = ''
currentBusinessLicenseAddress.value = ''
}
function lockParentIdField() {
if (hasValue(form.value.parentId)) {
ocrLockedFields.value.parentId = true
}
}
onLoad(option => {
if (app.globalData.isLogin) {
......@@ -295,11 +308,14 @@
}
});
async function init() {
getRegionsList()
await getForm()
await canUseDiscountApi()
await getZtxDiscountPolicyApi()
async function init() {
await Promise.all([
getRegionsList(),
getTree()
])
await getForm()
await canUseDiscountApi()
await getZtxDiscountPolicyApi()
handelGetMyRecent()
}
......@@ -340,11 +356,10 @@
flag.value = newResult.value
}
form.value = {
...res.data.dept,
...res.data.memberInfo
}
getTree()
form.value = {
...res.data.dept,
...res.data.memberInfo
}
form.value.deptType = res.data.dept.deptType
form.value.parentId = form.value.parentId ?? ''
// creditCode.value = form.value.creditCode
......@@ -383,6 +398,8 @@
creditCode.value = form.value.creditCode
parentId.value = form.value.parentId
restoreAssoFullName()
lockParentIdField()
companyName.value = form.value.companyName
legal.value = form.value.legal
legalIdcCode.value = form.value.legalIdcCode
......@@ -408,7 +425,7 @@
}
function getRegionsList() {
api.regionsList().then(res => {
return api.regionsList().then(res => {
regionsList.value = res.data;
});
}
......@@ -465,16 +482,24 @@
})
return
}
if (form.value.parentId == -1 || form.value.parentId == 0) {
uni.showToast({
title: '请选择所属协会',
icon: 'none'
})
return
}
if (legalIdcPhoto1.value == '' || legalIdcPhoto2.value == '') {
uni.showToast({
title: '请上传法人身份证',
if (form.value.parentId == -1 || form.value.parentId == 0) {
uni.showToast({
title: '请选择所属协会',
icon: 'none'
})
return
}
if (currentBusinessLicenseAddress.value && !validateBusinessLicenseProvince(currentBusinessLicenseAddress.value)) {
uni.showToast({
title: '请上传省内的营业执照',
icon: 'none',
duration: 3000
})
return
}
if (legalIdcPhoto1.value == '' || legalIdcPhoto2.value == '') {
uni.showToast({
title: '请上传法人身份证',
icon: 'none'
})
return
......@@ -895,55 +920,39 @@
return true
}
function findAssoPathByRegionNames(regionPath) {
if (!regionPath?.length || !tree.value?.length) return null
const names = regionPath.map(node => normalizeAddressText(getNodeText(node))).filter(Boolean)
const candidates = []
function walk(listData, path) {
for (const item of listData || []) {
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(tree.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
}
async function applyBusinessAddress(address) {
const businessAddress = String(address || '').trim()
if (!businessAddress) return
if (!businessAddress) return false
form.value.adress = businessAddress
lockOcrField('adress', businessAddress)
if (!regionsList.value?.length) {
await getRegionsList().catch(() => {})
}
if (!tree.value?.length) {
await getTree().catch(() => {})
}
const regionPath = findRegionPathByAddress(businessAddress)
if (applyRegionPath(regionPath)) {
const assoPath = findAssoPathByRegionNames(regionPath)
applyAssoPath(assoPath)
}
return applyRegionPath(regionPath)
}
function validateBusinessLicenseProvince(address) {
const businessAddress = String(address || '').trim()
if (!businessAddress) return true
const regionPath = findRegionPathByAddress(businessAddress)
const currentAssoName = assoFullName.value || getAssoName(form.value.parentId)
return isSameProvince(regionPath, currentAssoName)
}
function isSameProvince(regionPath, assoName) {
const regionProvince = normalizeProvinceName(getNodeText(regionPath?.[0]))
if (!regionProvince) return false
const normalizedAssoName = normalizeProvinceName(assoName)
return normalizedAssoName && (
normalizedAssoName.includes(regionProvince) ||
regionProvince.includes(normalizedAssoName)
)
}
function normalizeProvinceName(name) {
return normalizeAddressText(name).replace(/省|市|自治区|壮族自治区|回族自治区|维吾尔自治区/g, '')
}
// 恢复协会完整路径名称
......@@ -1102,7 +1111,18 @@
lockOcrField('companyName', form.value.companyName)
lockOcrField('creditCode', form.value.creditCode)
lockOcrField('legal', form.value.legal)
currentBusinessLicenseAddress.value = ocrData.businessAddress || ''
await applyBusinessAddress(ocrData.businessAddress)
if (!validateBusinessLicenseProvince(ocrData.businessAddress)) {
clearBusinessLicenseUpload()
uni.hideLoading()
uni.showToast({
title: '请上传省内的营业执照',
icon: 'none',
duration: 3000
})
return
}
await onCreditCodeBlur(false)
}
selectFileValue = {
......@@ -1120,12 +1140,12 @@
})
}
}
function delSupplementFile() {
selectFileValue = {}
form.value.businessLicense = ''
unlockOcrFields()
}
clearBusinessLicenseUpload()
unlockOcrFields()
lockParentIdField()
}
function getBusinessLicenseOcr(filePath) {
if (!filePath) return Promise.resolve(null)
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!