From 4f94090b42a23a2c393d0b24b96e76b62e49078e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=AF=E8=BE=89?= <13935151924@163.com> Date: Wed, 22 Oct 2025 13:15:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E4=BF=A1=E6=81=AF=E8=A1=A5?= =?UTF-8?q?=E5=85=A8=E6=8E=A5=E5=8F=A3=E8=81=94=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/UniStorageHelper.js | 17 ++ pages/complete-info/company-info.vue | 318 ++++++++++++++++++++++++--- pages/index/components/index-one.vue | 2 +- stores/useDictStore.js | 3 +- test-contact-fields.js | 1 + test-delete-contact.js | 1 + test-dict-format.js | 1 + test-dictstore-fix.js | 1 + test-enterprise-type-picker.js | 1 + utils/request.js | 18 +- 10 files changed, 331 insertions(+), 32 deletions(-) create mode 100644 test-contact-fields.js create mode 100644 test-delete-contact.js create mode 100644 test-dict-format.js create mode 100644 test-dictstore-fix.js create mode 100644 test-enterprise-type-picker.js diff --git a/common/UniStorageHelper.js b/common/UniStorageHelper.js index b8241b3..4cfa722 100644 --- a/common/UniStorageHelper.js +++ b/common/UniStorageHelper.js @@ -111,6 +111,23 @@ class UniStorageHelper { return storeData.filter(item => item[fieldName] === value); } + async getRecordCount(storeName) { + const storeData = this._storageGet(this._getStoreKey(storeName)) || []; + return storeData.length; + } + + async deleteOldestRecord(storeName) { + const storeKey = this._getStoreKey(storeName); + const storeData = this._storageGet(storeKey) || []; + if (storeData.length > 0) { + // 删除第一条记录(最早的记录) + const newData = storeData.slice(1); + this._storageSet(storeKey, newData); + this._log(`删除最早的记录,剩余${newData.length}条记录`); + } + return Promise.resolve(); + } + /*================== 更新/删除方法 ==================*/ diff --git a/pages/complete-info/company-info.vue b/pages/complete-info/company-info.vue index c474095..46c814e 100644 --- a/pages/complete-info/company-info.vue +++ b/pages/complete-info/company-info.vue @@ -65,6 +65,50 @@ /> + + + 企业类型 + + + + + + + + + 是否是就业见习基地 + + + {{ formData.enterpriseType === null ? '请选择' : (formData.enterpriseType ? '是' : '否') }} + + + + + + + + 法人身份证号 + + + + + + 法人联系方式 + + + 本地重点发展产业 @@ -78,7 +122,7 @@ - 是否是本地企业 + 是否是本地重点发展产业 {{ formData.isLocalCompany === null ? '请选择' : (formData.isLocalCompany ? '是' : '否') }} @@ -94,15 +138,25 @@ - 联系人{{ index + 1 }} + + 联系人{{ index + 1 }} + + + 删除 + + 联系人姓名 @@ -111,7 +165,7 @@ 联系人电话 @@ -120,7 +174,7 @@ - + 添加联系人 @@ -159,6 +213,9 @@ + + + @@ -166,8 +223,11 @@ import { ref, reactive, computed, inject } from 'vue' import { onLoad } from '@dcloudio/uni-app' import AreaCascadePicker from '@/components/area-cascade-picker/area-cascade-picker.vue' +import SelectPopup from '@/components/selectPopup/selectPopup.vue' +import useDictStore from '@/stores/useDictStore' const { $api } = inject('globalFunction') +const dictStore = useDictStore() // 表单数据 const formData = reactive({ @@ -179,10 +239,15 @@ const formData = reactive({ latitude: null, companyIntro: '', legalPersonName: '', + nature: '', // 企业类型 + natureText: '', // 企业类型显示文本 + enterpriseType: null, // 是否是就业见习基地 (true/false/null) + legalIdCard: '', // 法人身份证号 + legalPhone: '', // 法人联系方式 industryType: '', // 是否是本地重点发展产业 isLocalCompany: null, // 是否是本地企业 (true/false/null) - contacts: [ - { name: '', phone: '' } + companyContactList: [ + { contactPerson: '', contactPersonPhone: '' } ] }) @@ -197,6 +262,16 @@ const currentEditField = ref('') // 地址选择器引用 const areaPicker = ref(null) +// 滚动选择器引用 +const selectPopupRef = ref(null) + +// 创建本地的 openSelectPopup 函数 +const openSelectPopup = (config) => { + if (selectPopupRef.value) { + selectPopupRef.value.open(config); + } +} + // 产业类型选项数据 const industryOptions = [ '人工智能', @@ -206,6 +281,23 @@ const industryOptions = [ '其他' ] +// 备用企业类型选项(当字典数据加载失败时使用) +const fallbackEnterpriseTypes = [ + { label: '有限责任公司', value: '1' }, + { label: '股份有限公司', value: '2' }, + { label: '个人独资企业', value: '3' }, + { label: '合伙企业', value: '4' }, + { label: '外商投资企业', value: '5' }, + { label: '其他', value: '6' } +] + +// 企业类型选项数据从字典中获取 +const enterpriseTypeOptions = computed(() => { + const natureData = dictStore.state?.nature || [] + console.log('企业类型选项数据:', natureData) + return natureData +}) + // 完成度计算 const completionPercentage = computed(() => { const fields = [ @@ -214,12 +306,16 @@ const completionPercentage = computed(() => { formData.registeredAddress, formData.companyIntro, formData.legalPersonName, + formData.nature, + formData.enterpriseType !== null ? 'filled' : '', + formData.legalIdCard, + formData.legalPhone, formData.industryType, formData.isLocalCompany !== null ? 'filled' : '' ] // 检查联系人信息 - const hasContact = formData.contacts.some(contact => contact.name && contact.phone) + const hasContact = formData.companyContactList.some(contact => contact.contactPerson && contact.contactPersonPhone) const filledFields = fields.filter(field => field && field.trim()).length + (hasContact ? 1 : 0) const totalFields = fields.length + 1 @@ -294,6 +390,68 @@ const selectIndustry = () => { }) } +// 选择企业类型 +const selectEnterpriseType = () => { + console.log('点击企业类型,当前数据:', enterpriseTypeOptions.value) + console.log('字典store状态:', dictStore.state.nature) + + // 获取企业类型选项,优先使用字典数据,失败时使用备用数据 + let options = enterpriseTypeOptions.value + + if (!options || !options.length) { + console.log('企业类型数据为空,尝试重新加载') + // 尝试重新加载字典数据 + dictStore.getDictData().then(() => { + if (dictStore.state.nature && dictStore.state.nature.length > 0) { + selectEnterpriseType() // 递归调用 + } else { + // 使用备用数据 + console.log('使用备用企业类型数据') + options = fallbackEnterpriseTypes + showEnterpriseTypeSelector(options) + } + }).catch(() => { + // 使用备用数据 + console.log('字典加载失败,使用备用企业类型数据') + options = fallbackEnterpriseTypes + showEnterpriseTypeSelector(options) + }) + return + } + + showEnterpriseTypeSelector(options) +} + +// 显示企业类型选择器 +const showEnterpriseTypeSelector = (options) => { + console.log('企业类型选项列表:', options) + + openSelectPopup({ + title: '企业类型', + maskClick: true, + data: [options], + success: (_, [value]) => { + console.log('选择的企业类型:', value) + formData.nature = value.value + formData.natureText = value.label + updateCompletion() + $api.msg('企业类型选择成功') + } + }) +} + +// 选择是否是就业见习基地 +const selectEmploymentBase = () => { + uni.showActionSheet({ + itemList: ['是', '否'], + success: (res) => { + formData.enterpriseType = res.tapIndex === 0 + updateCompletion() + $api.msg('选择成功') + } + }) +} + // 选择是否是本地企业 const selectLocalCompany = () => { uni.showActionSheet({ @@ -309,11 +467,31 @@ const selectLocalCompany = () => { // 添加联系人 const addContact = () => { - if (formData.contacts.length < 3) { - formData.contacts.push({ name: '', phone: '' }) + if (formData.companyContactList.length < 3) { + formData.companyContactList.push({ contactPerson: '', contactPersonPhone: '' }) } } +// 删除联系人 +const deleteContact = (index) => { + if (formData.companyContactList.length <= 1) { + $api.msg('至少需要保留一个联系人') + return + } + + uni.showModal({ + title: '确认删除', + content: '确定要删除这个联系人吗?', + success: (res) => { + if (res.confirm) { + formData.companyContactList.splice(index, 1) + updateCompletion() + $api.msg('联系人已删除') + } + } + }) +} + // 关闭弹窗 const closePopup = () => { popup.value?.close() @@ -365,6 +543,26 @@ const confirm = () => { return } + if (!formData.nature.trim()) { + $api.msg('请选择企业类型') + return + } + + if (formData.enterpriseType === null) { + $api.msg('请选择是否是就业见习基地') + return + } + + if (!formData.legalIdCard.trim()) { + $api.msg('请输入法人身份证号') + return + } + + if (!formData.legalPhone.trim()) { + $api.msg('请输入法人联系方式') + return + } + if (!formData.industryType.trim()) { $api.msg('请选择产业类型') return @@ -375,9 +573,23 @@ const confirm = () => { return } + // 验证身份证号格式 + const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/ + if (!idCardRegex.test(formData.legalIdCard)) { + $api.msg('请输入正确的身份证号') + return + } + + // 验证法人电话格式 + const phoneRegex = /^1[3-9]\d{9}$/ + if (!phoneRegex.test(formData.legalPhone)) { + $api.msg('请输入正确的法人联系方式') + return + } + // 验证至少有一个联系人 - const hasValidContact = formData.contacts.some(contact => - contact.name.trim() && contact.phone.trim() + const hasValidContact = formData.companyContactList.some(contact => + contact.contactPerson.trim() && contact.contactPersonPhone.trim() ) if (!hasValidContact) { @@ -386,10 +598,9 @@ const confirm = () => { } // 验证联系人电话格式 - const phoneRegex = /^1[3-9]\d{9}$/ - for (let contact of formData.contacts) { - if (contact.name.trim() && contact.phone.trim()) { - if (!phoneRegex.test(contact.phone)) { + for (let contact of formData.companyContactList) { + if (contact.contactPerson.trim() && contact.contactPersonPhone.trim()) { + if (!phoneRegex.test(contact.contactPersonPhone)) { $api.msg('请输入正确的手机号码') return } @@ -399,13 +610,28 @@ const confirm = () => { // 提交数据 uni.showLoading({ title: '保存中...' }) - // 这里调用后端接口保存企业信息 - const submitData = { - ...formData, - contacts: formData.contacts.filter(contact => contact.name.trim() && contact.phone.trim()) + // 构建提交数据,按照要求的字段映射 + const companyData = { + name: formData.companyName, + code: formData.socialCreditCode, + registeredAddress: formData.registeredAddress, + description: formData.companyIntro, + legalPerson: formData.legalPersonName, + nature: formData.nature, + enterpriseType: formData.enterpriseType, + legalIdCard: formData.legalIdCard, + legalPhone: formData.legalPhone, + industryType: formData.industryType, + isLocalCompany: formData.isLocalCompany, + companyContactList: formData.companyContactList.filter(contact => contact.contactPerson.trim() && contact.contactPersonPhone.trim()) } - $api.createRequest('/app/company/complete-info', submitData, 'post') + // 调用新的接口地址,数据格式为company数组 + const submitData = { + company: companyData + } + + $api.createRequest('/app/user/registerUser', submitData, 'post') .then((resData) => { uni.hideLoading() $api.msg('企业信息保存成功') @@ -421,9 +647,20 @@ const confirm = () => { }) } -onLoad((options) => { - // 可以在这里加载已有的企业信息 - console.log('企业信息补全页面加载') +onLoad(async (options) => { + console.log('企业信息补全页面开始加载') + try { + // 初始化字典数据 + await dictStore.getDictData() + console.log('字典数据加载完成:', { + nature: dictStore.state.nature, + complete: dictStore.complete + }) + } catch (error) { + console.error('字典数据加载失败:', error) + $api.msg('数据加载失败,请重试') + } + console.log('企业信息补全页面加载完成') }) // 暴露方法给其他页面调用 @@ -487,6 +724,19 @@ defineExpose({ &::placeholder color: #999 font-size: 26rpx + + .input-con + flex: 1 + font-size: 28rpx + color: #333 + text-align: right + background: transparent + border: none + outline: none + + &::placeholder + color: #999 + font-size: 26rpx .input-content flex: 1 @@ -534,6 +784,23 @@ defineExpose({ background: #f8f9fa font-weight: 500 border-bottom: 1rpx solid #e8e8e8 + display: flex + justify-content: space-between + align-items: center + + .delete-btn + display: flex + align-items: center + padding: 8rpx 16rpx + background: #fff5f5 + border: 1rpx solid #ff4757 + border-radius: 8rpx + cursor: pointer + + .delete-text + margin-left: 8rpx + font-size: 24rpx + color: #ff4757 .form-item border-bottom: 1rpx solid #f0f0f0 @@ -630,3 +897,4 @@ defineExpose({ button::after border: none + diff --git a/pages/index/components/index-one.vue b/pages/index/components/index-one.vue index 8f70960..2d6a516 100644 --- a/pages/index/components/index-one.vue +++ b/pages/index/components/index-one.vue @@ -538,7 +538,7 @@ function nextDetail(job) { const recordData = recommedIndexDb.JobParameter(job); recommedIndexDb.addRecord(recordData); } - navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}`); + navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(job.jobId)}`); } } diff --git a/stores/useDictStore.js b/stores/useDictStore.js index 5cc02e3..5cf02ce 100644 --- a/stores/useDictStore.js +++ b/stores/useDictStore.js @@ -98,7 +98,7 @@ const useDictStore = defineStore("dict", () => { } function dictLabel(dictType, value) { - if (state[dictType]) { + if (state[dictType] && Array.isArray(state[dictType])) { for (let i = 0; i < state[dictType].length; i++) { let element = state[dictType][i]; if (element.value === value) { @@ -176,6 +176,7 @@ const useDictStore = defineStore("dict", () => { // 导入 return { + state, getDictData, dictLabel, oneDictData, diff --git a/test-contact-fields.js b/test-contact-fields.js new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/test-contact-fields.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-delete-contact.js b/test-delete-contact.js new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/test-delete-contact.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-dict-format.js b/test-dict-format.js new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/test-dict-format.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-dictstore-fix.js b/test-dictstore-fix.js new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/test-dictstore-fix.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-enterprise-type-picker.js b/test-enterprise-type-picker.js new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/test-enterprise-type-picker.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/utils/request.js b/utils/request.js index 3fa541d..020fa11 100644 --- a/utils/request.js +++ b/utils/request.js @@ -104,15 +104,23 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h resolve(resData.data) return } + // 处理业务错误 + if (resData.data?.code === 401 || resData.data?.code === 402) { + useUserStore().logOut() + } + // 显示具体的错误信息 + const errorMsg = msg || '请求出现异常,请联系工作人员' uni.showToast({ - title: msg, + title: errorMsg, icon: 'none' }) + const err = new Error(errorMsg) + err.error = resData + reject(err) + return } - if (resData.data?.code === 401 || resData.data?.code === 402) { - useUserStore().logOut() - } - const err = new Error('请求出现异常,请联系工作人员') + // HTTP状态码不是200的情况 + const err = new Error('网络请求失败,请检查网络连接') err.error = resData reject(err) },