Bladeren bron

定级审核动态表单

Signed-off-by: 李妹妹 <1639016684@qq.com>
李妹妹 16 uur geleden
bovenliggende
commit
170ccc8560
6 gewijzigde bestanden met toevoegingen van 976 en 178 verwijderingen
  1. 1 36
      package-lock.json
  2. 886 62
      pages_speaker/gradeApplication.vue
  3. 3 1
      pages_speaker/index.vue
  4. 86 23
      pages_task/approvalTaskDetail.vue
  5. 0 35
      project.config.json
  6. 0 21
      project.private.config.json

+ 1 - 36
package-lock.json

@@ -1,43 +1,8 @@
 {
     "name": "shop",
     "version": "1.0.0",
-    "lockfileVersion": 2,
+    "lockfileVersion": 1,
     "requires": true,
-    "packages": {
-        "": {
-            "name": "shop",
-            "version": "1.0.0",
-            "dependencies": {
-                "animate.css": "^3.7.2",
-                "dayjs": "^1.11.13",
-                "uqrcodejs": "^4.0.7",
-                "uview-ui": "^2.0.36"
-            }
-        },
-        "node_modules/animate.css": {
-            "version": "3.7.2",
-            "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-3.7.2.tgz",
-            "integrity": "sha512-0bE8zYo7C0KvgOYrSVfrzkbYk6IOTVPNqkiHg2cbyF4Pq/PXzilz4BRWA3hwEUBoMp5VBgrC29lQIZyhRWdBTw=="
-        },
-        "node_modules/dayjs": {
-            "version": "1.11.13",
-            "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
-            "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
-        },
-        "node_modules/uqrcodejs": {
-            "version": "4.0.7",
-            "resolved": "https://registry.npmjs.org/uqrcodejs/-/uqrcodejs-4.0.7.tgz",
-            "integrity": "sha512-84+aZmD2godCVI+93lxE3YUAPNY8zAJvNA7xRS7R7U+q57KzMDepBSfNCwoRUhWOfR6eHFoAOcHRPwsP6ka1cA=="
-        },
-        "node_modules/uview-ui": {
-            "version": "2.0.36",
-            "resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.36.tgz",
-            "integrity": "sha512-ASSZT6M8w3GTO1eFPbsgEFV0U5UujK+8pTNr+MSUbRNcRMC1u63DDTLJVeArV91kWM0bfAexK3SK9pnTqF9TtA==",
-            "engines": {
-                "HBuilderX": "^3.1.0"
-            }
-        }
-    },
     "dependencies": {
         "animate.css": {
             "version": "3.7.2",

+ 886 - 62
pages_speaker/gradeApplication.vue

@@ -7,9 +7,218 @@
 				<view class="rejection-text">驳回意见: {{ rejectionInfo }}</view>
 			</view>
 
+			
+
 			<!-- 基本信息 -->
 			<view class="form-section">
-				<view class="form-item">
+				<!-- 动态表单(来自 formJson) -->
+				<view v-if="formFields.length > 0">
+					<view 
+						class="form-item form-item-dynamic" 
+						:class="{ column: isDynamicFieldColumn(field) }"
+						v-for="(field, index) in formFields" 
+						:key="getFieldKey(field, index)">
+						<view class="form-label">
+							<text class="required" v-if="field.__config__ && field.__config__.required">*</text>
+							<text>{{ field.__config__ ? field.__config__.label : '' }}</text>
+						</view>
+						
+						<template v-if="field.__config__.tag === 'el-input' && field.type !== 'textarea'">
+							<input 
+								class="form-input" 
+								:value="formData[field.__vModel__] || ''" 
+								@input="(e) => onInputChange(field, e)"
+								:placeholder="field.placeholder || '请输入' + (field.__config__.label || '')"
+								type="text"
+								:disabled="field.disabled"
+								placeholder-class="text-placeholder"
+							/>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-input' && field.type === 'textarea'">
+							<textarea 
+								class="form-textarea" 
+								:value="formData[field.__vModel__] || ''" 
+								@input="(e) => onInputChange(field, e)"
+								:placeholder="field.placeholder || '请输入' + (field.__config__.label || '')"
+								:maxlength="field.maxlength"
+								:disabled="field.disabled"
+								placeholder-class="text-placeholder"
+							/>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-input-number'">
+							<view class="input-number-wrapper">
+								<view class="input-number-btn" @click="(e) => decreaseNumber(field, index)" :class="{ disabled: isNumberMin(field) }">-</view>
+								<input 
+									class="form-input input-number-input" 
+									:value="formData[field.__vModel__] != null ? formData[field.__vModel__] : ''" 
+									@input="(e) => onNumberInputChange(field, e)"
+									type="number"
+									:placeholder="field.placeholder || '请输入'"
+									:disabled="field.disabled"
+									placeholder-class="text-placeholder"
+								/>
+								<view class="input-number-btn" @click="(e) => increaseNumber(field, index)" :class="{ disabled: isNumberMax(field) }">+</view>
+							</view>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-select'">
+							<picker 
+								mode="selector" 
+								:range="getSelectOptions(field)" 
+								range-key="label"
+								:value="getSelectIndex(field)"
+								@change="(e) => onSelectChange(field, e)">
+								<view class="form-input picker-input" :class="{ placeholder: !formData[field.__vModel__] }">
+									{{ getSelectLabel(field) || field.placeholder || '请选择' }}
+									<image class="w48 h48" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png" mode=""></image>
+								</view>
+							</picker>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-slider'">
+							<view class="slider-wrapper">
+								<slider 
+									:value="formData[field.__vModel__] != null ? formData[field.__vModel__] : (field.__config__.defaultValue != null ? field.__config__.defaultValue : 0)"
+									:min="field.min != null ? field.min : 0"
+									:max="field.max != null ? field.max : 100"
+									:step="field.step || 1"
+									:show-value="true"
+									activeColor="#388BFF"
+									@change="(e) => onSliderChange(field, e)"
+								/>
+							</view>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-checkbox-group'">
+							<checkbox-group @change="(e) => onCheckboxChange(field, e)" class="checkbox-group">
+								<label 
+									class="checkbox-item"
+									v-for="(option, optIndex) in getSelectOptions(field)" 
+									:key="optIndex">
+									<checkbox 
+										:value="option.value" 
+										:checked="isCheckboxChecked(field, option.value)" 
+										color="#388BFF" 
+									/>
+									<text>{{ option.label }}</text>
+								</label>
+							</checkbox-group>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-radio-group'">
+							<radio-group @change="(e) => onRadioChange(field, e)" class="radio-group">
+								<label 
+									class="radio-item"
+									v-for="(option, optIndex) in getSelectOptions(field)" 
+									:key="optIndex">
+									<radio 
+										:value="option.value" 
+										:checked="formData[field.__vModel__] == option.value" 
+										color="#388BFF" 
+									/>
+									<text>{{ option.label }}</text>
+								</label>
+							</radio-group>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-upload'">
+							<view class="upload-section">
+								<view class="upload-item" v-for="(file, fileIndex) in getUploadFiles(field)" :key="fileIndex">
+									<image class="uploaded-image" :src="file" mode="aspectFill" v-if="isImageFile(file)"></image>
+									<view class="uploaded-file" v-else>
+										<text class="file-name">{{ getFileName(file) }}</text>
+									</view>
+									<view class="delete-btn" @click="(e) => removeUploadFile(field, fileIndex, index)">×</view>
+								</view>
+								<view class="upload-item upload-placeholder" @click="(e) => chooseUploadFile(field, index)">
+									<image class="w48 h48" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_camera.png" mode=""></image>
+									<text class="upload-text">{{ field.__config__.buttonText || '点击上传' }}</text>
+								</view>
+							</view>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-switch'">
+							<switch 
+								:checked="formData[field.__vModel__] || false"
+								:disabled="field.disabled"
+								:color="field['active-color'] || '#388BFF'"
+								@change="(e) => onSwitchChange(field, e)"
+							/>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-time-picker' && !field['is-range']">
+							<picker 
+								mode="time" 
+								:value="formData[field.__vModel__] || ''"
+								@change="(e) => onTimePickerChange(field, e)">
+								<view class="form-input picker-input" :class="{ placeholder: !formData[field.__vModel__] }">
+									{{ formData[field.__vModel__] || field.placeholder || '请选择' }}
+								</view>
+							</picker>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-time-picker' && field['is-range']">
+							<view class="time-range-wrapper">
+								<picker 
+									mode="time" 
+									:value="getTimeRangeStart(field)"
+									@change="(e) => onTimeRangeStartChange(field, e)">
+									<view class="form-input picker-input time-range-input" :class="{ placeholder: !getTimeRangeStart(field) }">
+										{{ getTimeRangeStart(field) || field['start-placeholder'] || '开始时间' }}
+									</view>
+								</picker>
+								<text class="time-range-separator">{{ field['range-separator'] || '至' }}</text>
+								<picker 
+									mode="time" 
+									:value="getTimeRangeEnd(field)"
+									@change="(e) => onTimeRangeEndChange(field, e)">
+									<view class="form-input picker-input time-range-input" :class="{ placeholder: !getTimeRangeEnd(field) }">
+										{{ getTimeRangeEnd(field) || field['end-placeholder'] || '结束时间' }}
+									</view>
+								</picker>
+							</view>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-date-picker' && field.type !== 'daterange'">
+							<picker 
+								mode="date" 
+								:value="formData[field.__vModel__] || ''"
+								:start="field['start-date'] || ''"
+								:end="field['end-date'] || ''"
+								@change="(e) => onDatePickerChange(field, e)">
+								<view class="form-input picker-input" :class="{ placeholder: !formData[field.__vModel__] }">
+									{{ formData[field.__vModel__] || field.placeholder || '请选择' }}
+								</view>
+							</picker>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-date-picker' && field.type === 'daterange'">
+							<view class="date-range-wrapper">
+								<picker 
+									mode="date" 
+									:value="getDateRangeStart(field)"
+									@change="(e) => onDateRangeStartChange(field, e)">
+									<view class="form-input picker-input date-range-input" :class="{ placeholder: !getDateRangeStart(field) }">
+										{{ getDateRangeStart(field) || field['start-placeholder'] || '开始日期' }}
+									</view>
+								</picker>
+								<text class="date-range-separator">{{ field['range-separator'] || '至' }}</text>
+								<picker 
+									mode="date" 
+									:value="getDateRangeEnd(field)"
+									@change="(e) => onDateRangeEndChange(field, e)">
+									<view class="form-input picker-input date-range-input" :class="{ placeholder: !getDateRangeEnd(field) }">
+										{{ getDateRangeEnd(field) || field['end-placeholder'] || '结束日期' }}
+									</view>
+								</picker>
+							</view>
+						</template>
+						<template v-else-if="field.__config__.tag === 'el-rate'">
+							<view class="rate-wrapper">
+								<view 
+									class="rate-star" 
+									v-for="(star, starIndex) in (field.max || 5)" 
+									:key="starIndex"
+									@click="(e) => setRate(field, starIndex + 1, index)"
+									:class="{ active: (formData[field.__vModel__] || 0) >= (starIndex + 1) }">
+									★
+								</view>
+								<text class="rate-text" v-if="field['show-score']">{{ formData[field.__vModel__] || 0 }}分</text>
+							</view>
+						</template>
+					</view>
+				</view>
+				<!-- <view class="form-item">
 					<view class="form-label">
 						<text class="required">*</text>
 						<text>学术头衔</text>
@@ -19,9 +228,9 @@
 						{{ formData.academicTitle || '请选择' }}
 						<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
 					</view>
-				</view>
+				</view> -->
 
-				<view class="form-item">
+				<!-- <view class="form-item">
 					<view class="form-label">
 						<text class="required">*</text>
 						<text>学术任职(多选)</text>
@@ -31,7 +240,7 @@
 						{{ formData.academicPositions || '请选择' }}
 						<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
 					</view>
-				</view>
+				</view> -->
 				<view class="form-item">
 					<view class="form-label">
 						<text class="required">*</text>
@@ -46,7 +255,7 @@
 					</view>
 					<input type="number" class="input" v-model="formData.nationalPapers"></input>
 				</view>
-				<view class="form-item">
+				<!-- <view class="form-item">
 					<view class="form-label">
 						<text class="required">*</text>
 						<text>学术研究(多选)</text>
@@ -56,7 +265,7 @@
 						{{ formData.researchAreas || '请选择' }}
 						<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
 					</view>
-				</view>
+				</view> -->
 				<view class="form-item">
 					<view class="form-label">
 						<text class="required">*</text>
@@ -64,7 +273,7 @@
 					</view>
 					<input type="number" class="input" v-model="formData.clinicalExperience"></input>
 				</view>
-				<view class="form-item">
+				<!-- <view class="form-item">
 					<view class="form-label">
 						<text class="required">*</text>
 						<text>学位</text>
@@ -74,15 +283,15 @@
 						{{ formData.degree || '请选择' }}
 						<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
 					</view>
-				</view>
+				</view> -->
 				<view class="form-item">
 					<view class="form-label">
 						<text class="required">*</text>
 						<text>申请级别</text>
 					</view>
-					<view class="form-input picker-input" :class="{ placeholder: !formData.applicationLevel }"
+					<view class="form-input picker-input" :class="{ placeholder: !formData.applicationLevelLabel }"
 						@click="showPicker('申请级别', 'doctor_apply_level')">
-						{{ formData.applicationLevel || '请选择' }}
+						{{ formData.applicationLevelLabel || '请选择' }}
 						<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
 					</view>
 				</view>
@@ -172,20 +381,22 @@
 					['一级', '二级', '三级', '四级']
 				],
 				rejectionInfo: '',
+				formTitle: '',
+				formFields: [],
 				formData: {
 					// 学术信息
 					academicTitle: '', // 学术头衔
 					academicPositions: '', // 学术任职
-					internationalPapers: 0, // 国际性期刊论文/著作数
-					nationalPapers: 0, // 全国性期刊论文/著作数
+					internationalPapers: null, // 国际性期刊论文/著作数
+					nationalPapers: null, // 全国性期刊论文/著作数
 					researchAreas: '', // 学术研究
-					clinicalExperience: 0, // 临床工作经验年数
+					clinicalExperience: null, // 临床工作经验年数
 					degree: '', // 学位
-					applicationLevel: '', // 申请级别
+					applicationLevel: '', // 申请级别(提交用 dictValue)
+					applicationLevelLabel: '', // 申请级别展示用 dictLabel
 					proofImages: [] // 证明材料图片
 				},
 				pickerTitle: '默认标题',
-				pickerData: [],
 				userInfo: {},
 				doctorId: null
 			}
@@ -194,10 +405,10 @@
 			try {
 				console.log("options", options)
 				this.doctorId = options.doctorId;
-				this.academicTitle = await utils.getDicts("doctor_academic_title"); //学术头衔
-				this.academicPosition = await utils.getDicts("doctor_academic_position"); //学术任职
-				this.academicResearch = await utils.getDicts("doctor_academic_research"); //学术研究
-				this.degree = await utils.getDicts("doctor_degree"); //学位
+				// this.academicTitle = await utils.getDicts("doctor_academic_title"); //学术头衔
+				// this.academicPosition = await utils.getDicts("doctor_academic_position"); //学术任职
+				// this.academicResearch = await utils.getDicts("doctor_academic_research"); //学术研究
+				// this.degree = await utils.getDicts("doctor_degree"); //学位
 				this.applyLevel = await utils.getDicts("doctor_apply_level"); //申请级别
 			} catch (e) {
 				console.log('获取字典数据失败:', e)
@@ -209,6 +420,13 @@
 			}
 			// 获取用户信息
 			this.userInfo = uni.getStorageSync('userInfo') || '{}'
+			if (typeof this.userInfo === 'string') {
+				try {
+					this.userInfo = JSON.parse(this.userInfo) || {}
+				} catch (e) {
+					this.userInfo = {}
+				}
+			}
 			await this.getCompanyDoctorLevelApplyQuestionnaire()
 
 		},
@@ -223,12 +441,391 @@
 						companyId: this.userInfo.companyId
 					})
 					if (res.code === 200) {
-						this.formData.questionnaireId = res.data.questionnaireId
+						// 从 res.data.formJson 获取动态表单配置
+						let formConfigData = res.data.formJson || null
+						if (typeof formConfigData === 'string') {
+							try {
+								formConfigData = JSON.parse(formConfigData)
+							} catch (e) {
+								console.error('解析表单配置 JSON 失败', e)
+								formConfigData = null
+							}
+						}
+						if (formConfigData && formConfigData.fields && Array.isArray(formConfigData.fields)) {
+							this.formFields = formConfigData.fields
+							this.formTitle = formConfigData.formTitle || formConfigData.title || '补充信息'
+							this.initFormData()
+						}
+						if (res.data.formData) {
+							Object.assign(this.formData, res.data.formData)
+						}
+						this.formData.questionnaireId=res.data.versionId
 					}
 				} catch (e) {
 					console.log('获取公司医生等级申请问卷失败:', e)
 				}
 			},
+			// ---------- 动态表单(formJson)相关方法 ----------
+			getFieldKey(field, index) {
+				return field && field.__config__ && field.__config__.formId ? field.__config__.formId : `field_${index}`
+			},
+			isDynamicFieldColumn(field) {
+				if (!field || !field.__config__) return false
+				const tag = field.__config__.tag
+				if (tag === 'el-input' && field.type === 'textarea') return true
+				if (tag === 'el-checkbox-group' || tag === 'el-radio-group') return true
+				if (tag === 'el-upload' || tag === 'el-slider' || tag === 'el-rate') return true
+				if (tag === 'el-time-picker' && field['is-range']) return true
+				if (tag === 'el-date-picker' && field.type === 'daterange') return true
+				return false
+			},
+			initFormData() {
+				this.formFields.forEach(field => {
+					const vModel = field.__vModel__
+					if (!vModel) return
+					if (this.formData[vModel] !== undefined && this.formData[vModel] !== null) return
+					const tag = field.__config__.tag
+					const defaultValue = field.__config__.defaultValue
+					switch (tag) {
+						case 'el-input':
+							this.$set(this.formData, vModel, defaultValue !== undefined ? defaultValue : '')
+							break
+						case 'el-input-number':
+							if (defaultValue !== undefined) {
+								this.$set(this.formData, vModel, Number(defaultValue))
+							} else {
+								const minValue = field.min !== undefined ? Number(field.min) : null
+								this.$set(this.formData, vModel, minValue)
+							}
+							break
+						case 'el-select':
+							this.$set(this.formData, vModel, defaultValue !== undefined ? defaultValue : '')
+							break
+						case 'el-slider':
+							this.$set(this.formData, vModel, defaultValue !== undefined ? Number(defaultValue) : (field.min !== undefined ? Number(field.min) : 0))
+							break
+						case 'el-checkbox-group':
+							this.$set(this.formData, vModel, defaultValue !== undefined && Array.isArray(defaultValue) ? [...defaultValue] : [])
+							break
+						case 'el-radio-group':
+							this.$set(this.formData, vModel, defaultValue !== undefined ? defaultValue : '')
+							break
+						case 'el-upload':
+							if (defaultValue !== undefined && Array.isArray(defaultValue)) {
+								this.$set(this.formData, vModel, [...defaultValue])
+							} else if (defaultValue !== undefined && typeof defaultValue === 'string') {
+								this.$set(this.formData, vModel, defaultValue.split(',').filter(item => item.trim()))
+							} else {
+								this.$set(this.formData, vModel, [])
+							}
+							break
+						case 'el-switch':
+							this.$set(this.formData, vModel, defaultValue !== undefined ? Boolean(defaultValue) : false)
+							break
+						case 'el-time-picker':
+							if (field['is-range']) {
+								this.$set(this.formData, vModel, defaultValue !== undefined && Array.isArray(defaultValue) ? [...defaultValue] : ['', ''])
+							} else {
+								this.$set(this.formData, vModel, defaultValue !== undefined ? defaultValue : '')
+							}
+							break
+						case 'el-date-picker':
+							if (field.type === 'daterange') {
+								this.$set(this.formData, vModel, defaultValue !== undefined && Array.isArray(defaultValue) ? [...defaultValue] : ['', ''])
+							} else {
+								this.$set(this.formData, vModel, defaultValue !== undefined ? defaultValue : '')
+							}
+							break
+						case 'el-rate':
+							this.$set(this.formData, vModel, defaultValue !== undefined ? Number(defaultValue) : 0)
+							break
+						default:
+							this.$set(this.formData, vModel, defaultValue !== undefined ? defaultValue : '')
+							break
+					}
+				})
+			},
+			getSelectOptions(field) {
+				return field.__slot__ && field.__slot__.options ? field.__slot__.options : []
+			},
+			getSelectIndex(field) {
+				const value = this.formData[field.__vModel__]
+				const options = this.getSelectOptions(field)
+				const index = options.findIndex(opt => opt.value == value)
+				return index >= 0 ? index : 0
+			},
+			getSelectLabel(field) {
+				const value = this.formData[field.__vModel__]
+				const options = this.getSelectOptions(field)
+				const option = options.find(opt => opt.value == value)
+				return option ? option.label : ''
+			},
+			onInputChange(field, e) {
+				const value = e.detail && e.detail.value !== undefined ? e.detail.value : (e.target && e.target.value !== undefined ? e.target.value : '')
+				this.$set(this.formData, field.__vModel__, value)
+			},
+			onNumberInputChange(field, e) {
+				const value = e.detail && e.detail.value !== undefined ? e.detail.value : (e.target && e.target.value !== undefined ? e.target.value : '')
+				const numValue = value === '' ? null : Number(value)
+				if (value !== '' && isNaN(numValue)) return
+				this.$set(this.formData, field.__vModel__, numValue)
+			},
+			onSelectChange(field, e) {
+				const options = this.getSelectOptions(field)
+				const index = e.detail.value
+				if (options[index]) {
+					this.$set(this.formData, field.__vModel__, options[index].value)
+				}
+			},
+			onSliderChange(field, e) {
+				this.$set(this.formData, field.__vModel__, e.detail.value)
+			},
+			onCheckboxChange(field, e) {
+				this.$set(this.formData, field.__vModel__, e.detail.value)
+			},
+			onRadioChange(field, e) {
+				this.$set(this.formData, field.__vModel__, e.detail.value)
+			},
+			isCheckboxChecked(field, value) {
+				const checkedValues = this.formData[field.__vModel__] || []
+				return checkedValues.includes(value)
+			},
+			getUploadFiles(field) {
+				if (!field || !field.__vModel__) return []
+				const files = this.formData[field.__vModel__] || []
+				return Array.isArray(files) ? files : []
+			},
+			isImageFile(file) {
+				if (typeof file === 'string') {
+					return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file) || file.startsWith('data:image')
+				}
+				return false
+			},
+			getFileName(file) {
+				if (typeof file === 'string') {
+					const parts = file.split('/')
+					return parts[parts.length - 1]
+				}
+				return '文件'
+			},
+			chooseUploadFile(field, formIndex) {
+				if (!field && formIndex !== undefined) field = this.formFields[formIndex]
+				if (!field || !field.__vModel__) return
+				const maxCount = field.multiple ? 9 : 3
+				const currentFiles = this.getUploadFiles(field)
+				const remaining = maxCount - currentFiles.length
+				if (remaining <= 0) {
+					uni.showToast({ icon: 'none', title: '已达到最大上传数量' })
+					return
+				}
+				const vm = this
+				uni.chooseImage({
+					sizeType: ['compressed'],
+					sourceType: ['album', 'camera'],
+					success: (res) => {
+						if (!res.tempFilePaths || res.tempFilePaths.length === 0) return
+						uni.showLoading({ title: '上传中...' })
+						const files = vm.formData[field.__vModel__] || []
+						const requestPath = uni.getStorageSync('requestPath')
+						const totalCount = res.tempFilePaths.length
+						let completedCount = 0
+						const uploadedUrls = []
+						res.tempFilePaths.forEach((filePath) => {
+							uni.uploadFile({
+								url: `${requestPath}/app/common/uploadOSS`,
+								filePath: filePath,
+								name: 'file',
+								formData: {},
+								success: (uploadRes) => {
+									completedCount++
+									try {
+										const result = typeof uploadRes.data === 'string' ? JSON.parse(uploadRes.data) : uploadRes.data
+										if (result.code == 200 && result.data && result.data.url) {
+											uploadedUrls.push(result.data.url)
+										} else if (result.code == 200 && result.url) {
+											uploadedUrls.push(result.url)
+										}
+									} catch (e) {}
+									if (completedCount === totalCount) {
+										uni.hideLoading()
+										if (uploadedUrls.length > 0) {
+											vm.$set(vm.formData, field.__vModel__, [...files, ...uploadedUrls])
+											uni.showToast({ icon: 'success', title: uploadedUrls.length === totalCount ? '上传成功' : `成功上传${uploadedUrls.length}/${totalCount}个文件` })
+										} else {
+											uni.showToast({ icon: 'none', title: '上传失败' })
+										}
+									}
+								},
+								fail: () => {
+									completedCount++
+									if (completedCount === totalCount) {
+										uni.hideLoading()
+										if (uploadedUrls.length > 0) {
+											vm.$set(vm.formData, field.__vModel__, [...files, ...uploadedUrls])
+											uni.showToast({ icon: 'none', title: `成功上传${uploadedUrls.length}/${totalCount}个文件` })
+										} else {
+											uni.showToast({ icon: 'none', title: '上传失败' })
+										}
+									}
+								}
+							})
+						})
+					},
+					fail: () => {
+						uni.showToast({ icon: 'none', title: '选择文件失败' })
+					}
+				})
+			},
+			removeUploadFile(field, fileIndex, formIndex) {
+				if (!field && formIndex !== undefined) field = this.formFields[formIndex]
+				if (!field || !field.__vModel__) return
+				const files = this.formData[field.__vModel__] || []
+				if (fileIndex >= 0 && fileIndex < files.length) {
+					files.splice(fileIndex, 1)
+					this.$set(this.formData, field.__vModel__, files)
+				}
+			},
+			decreaseNumber(field, index) {
+				if (!field && index !== undefined) field = this.formFields[index]
+				if (!field || !field.__vModel__) return
+				if (this.isNumberMin(field)) return
+				const current = Number(this.formData[field.__vModel__] || 0)
+				const step = field.step || 1
+				const min = field.min !== undefined ? field.min : 0
+				this.$set(this.formData, field.__vModel__, Math.max(min, current - step))
+			},
+			increaseNumber(field, index) {
+				if (!field && index !== undefined) field = this.formFields[index]
+				if (!field || !field.__vModel__) return
+				if (this.isNumberMax(field)) return
+				const current = Number(this.formData[field.__vModel__] || 0)
+				const step = field.step || 1
+				const max = field.max !== undefined ? field.max : Infinity
+				this.$set(this.formData, field.__vModel__, Math.min(max, current + step))
+			},
+			isNumberMin(field) {
+				if (!field || !field.__vModel__) return false
+				const current = Number(this.formData[field.__vModel__] || 0)
+				const min = field.min !== undefined ? field.min : 0
+				return current <= min
+			},
+			isNumberMax(field) {
+				if (!field || !field.__vModel__) return false
+				const current = Number(this.formData[field.__vModel__] || 0)
+				const max = field.max !== undefined ? field.max : Infinity
+				return current >= max
+			},
+			onSwitchChange(field, e) {
+				this.$set(this.formData, field.__vModel__, e.detail.value)
+			},
+			onTimePickerChange(field, e) {
+				this.$set(this.formData, field.__vModel__, e.detail.value)
+			},
+			getTimeRangeStart(field) {
+				const value = this.formData[field.__vModel__]
+				return Array.isArray(value) && value.length > 0 ? value[0] : ''
+			},
+			getTimeRangeEnd(field) {
+				const value = this.formData[field.__vModel__]
+				return Array.isArray(value) && value.length > 1 ? value[1] : ''
+			},
+			onTimeRangeStartChange(field, e) {
+				const value = this.formData[field.__vModel__] || []
+				value[0] = e.detail.value
+				this.$set(this.formData, field.__vModel__, [...value])
+			},
+			onTimeRangeEndChange(field, e) {
+				const value = this.formData[field.__vModel__] || []
+				value[1] = e.detail.value
+				this.$set(this.formData, field.__vModel__, [...value])
+			},
+			onDatePickerChange(field, e) {
+				this.$set(this.formData, field.__vModel__, e.detail.value)
+			},
+			getDateRangeStart(field) {
+				const value = this.formData[field.__vModel__]
+				return Array.isArray(value) && value.length > 0 ? value[0] : ''
+			},
+			getDateRangeEnd(field) {
+				const value = this.formData[field.__vModel__]
+				return Array.isArray(value) && value.length > 1 ? value[1] : ''
+			},
+			onDateRangeStartChange(field, e) {
+				const value = this.formData[field.__vModel__] || []
+				value[0] = e.detail.value
+				this.$set(this.formData, field.__vModel__, [...value])
+			},
+			onDateRangeEndChange(field, e) {
+				const value = this.formData[field.__vModel__] || []
+				value[1] = e.detail.value
+				this.$set(this.formData, field.__vModel__, [...value])
+			},
+			setRate(field, value, formIndex) {
+				if (!field && formIndex !== undefined) field = this.formFields[formIndex]
+				if (!field || !field.__vModel__) return
+				if (field.disabled) return
+				this.$set(this.formData, field.__vModel__, value)
+			},
+			validateDynamicForm() {
+				for (let field of this.formFields) {
+					const value = this.formData[field.__vModel__]
+					const fieldLabel = field.__config__.label || '该字段'
+					const tag = field.__config__.tag
+					const isRequired = field.__config__.required
+					if (isRequired) {
+						if (tag === 'el-checkbox-group' || tag === 'el-upload') {
+							const arr = tag === 'el-upload' ? this.getUploadFiles(field) : value
+							if (!arr || !Array.isArray(arr) || arr.length === 0) {
+								return { valid: false, message: tag === 'el-upload' ? `请上传${fieldLabel}` : `请选择${fieldLabel}` }
+							}
+						} else if ((tag === 'el-time-picker' && field['is-range']) || (tag === 'el-date-picker' && field.type === 'daterange')) {
+							const range = value || []
+							if (!Array.isArray(range) || range.length < 2 || !range[0] || !range[1]) {
+								return { valid: false, message: `请选择${fieldLabel}` }
+							}
+						} else if (tag === 'el-select' || tag === 'el-radio-group' || (tag === 'el-time-picker' && !field['is-range']) || (tag === 'el-date-picker' && field.type !== 'daterange')) {
+							if (!value && value !== 0 && value !== '0' && value !== false) {
+								return { valid: false, message: `请选择${fieldLabel}` }
+							}
+						} else if (tag === 'el-input') {
+							if (!value || (typeof value === 'string' && value.trim() === '')) {
+								return { valid: false, message: `请输入${fieldLabel}` }
+							}
+						} else if (tag === 'el-input-number' || tag === 'el-slider') {
+							if (value === null || value === undefined || value === '') {
+								return { valid: false, message: tag === 'el-slider' ? `请设置${fieldLabel}` : `请输入${fieldLabel}` }
+							}
+						} else if (tag === 'el-rate') {
+							if (!value || value === 0) {
+								return { valid: false, message: `请为${fieldLabel}评分` }
+							}
+						} else if (!value && value !== 0 && value !== false) {
+							return { valid: false, message: `请填写${fieldLabel}` }
+						}
+					}
+					if (value !== null && value !== undefined && value !== '') {
+						if (tag === 'el-input' && typeof value === 'string') {
+							if (field.maxlength && value.length > field.maxlength) {
+								return { valid: false, message: `${fieldLabel}不能超过${field.maxlength}个字符` }
+							}
+							if (field.minlength && value.length < field.minlength) {
+								return { valid: false, message: `${fieldLabel}不能少于${field.minlength}个字符` }
+							}
+						} else if (tag === 'el-input-number' || tag === 'el-slider') {
+							const numValue = Number(value)
+							if (!isNaN(numValue)) {
+								if (field.min !== undefined && numValue < field.min) {
+									return { valid: false, message: `${fieldLabel}不能小于${field.min}` }
+								}
+								if (field.max !== undefined && numValue > field.max) {
+									return { valid: false, message: `${fieldLabel}不能大于${field.max}` }
+								}
+							}
+						}
+					}
+				}
+				return { valid: true }
+			},
 			// 选择证明材料图片
 			chooseProofImages() {
 				uni.chooseImage({
@@ -337,14 +934,16 @@
 
 					// 根据字典类型获取对应的数据
 					let dictData = []
-					if (type === 'doctor_academic_title') {
-						dictData = this.academicTitle.map(item => item.dictLabel)
-					} else if (type === 'doctor_degree') {
-						dictData = this.degree.map(item => item.dictLabel)
-					} else if (type === 'doctor_apply_level') {
+					// if (type === 'doctor_academic_title') {
+					// 	dictData = this.academicTitle.map(item => item.dictLabel)
+					// } else if (type === 'doctor_degree') {
+					// 	dictData = this.degree.map(item => item.dictLabel)
+					// } else if (type === 'doctor_apply_level') {
+					// 	dictData = this.applyLevel.map(item => item.dictLabel)
+					// }
+                    if (type === 'doctor_apply_level') {
 						dictData = this.applyLevel.map(item => item.dictLabel)
 					}
-
 					// 设置数据
 					this.pickerData = [dictData]
 					this.pickerTitle = title
@@ -358,17 +957,15 @@
 
 			// 选择器确认
 			confirm(e) {
+				console.log(e)
 				if (e.value && e.value.length > 0) {
-					if (this.pickerTitle === '学术头衔') {
-						this.formData.academicTitle = e.value[0]
-					} else if (this.pickerTitle === '学术任职') {
-						this.formData.academicPositions = e.value[0]
-					} else if (this.pickerTitle === '学术研究') {
-						this.formData.researchAreas = e.value[0]
-					} else if (this.pickerTitle === '学位') {
-						this.formData.degree = e.value[0]
-					} else if (this.pickerTitle === '申请级别') {
-						this.formData.applicationLevel = e.value[0]
+					if (this.pickerTitle === '申请级别') {
+						// e.value[0] 为选中的 dictLabel,用其找到对应项并保存 dictValue 提交、dictLabel 展示
+						const item = this.applyLevel.find(a => a.dictLabel === e.value[0])
+						if (item) {
+							this.formData.applicationLevel = item.dictValue
+							this.formData.applicationLevelLabel=item.dictLabel
+						}
 					}
 				}
 				// 关闭选择器
@@ -414,18 +1011,50 @@
 
 			// 提交表单
 			submitForm() {
-				// 验证表单数据
-				if (!this.formData.academicTitle) {
+				// 动态表单校验
+				if (this.formFields.length > 0) {
+					const validation = this.validateDynamicForm()
+					if (!validation.valid) {
+						uni.showToast({
+							icon: 'none',
+							title: validation.message
+						})
+						return
+					}
+				}
+				// 验证静态表单数据
+				// if (!this.formData.academicTitle) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: '请选择学术头衔'
+				// 	})
+				// 	return
+				// }
+				// if (!this.formData.degree) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: '请选择学位'
+				// 	})
+				// 	return
+				// }
+				if (this.formData.internationalPapers==null||this.formData.internationalPapers==0) {
+					uni.showToast({
+						icon: 'none',
+						title: '请输入国际性期刊论文/著作数'
+					})
+					return
+				}
+				if (this.formData.nationalPapers==null||this.formData.nationalPapers==0) {
 					uni.showToast({
 						icon: 'none',
-						title: '请选择学术头衔'
+						title: '请输入全国性期刊论文/著作数'
 					})
 					return
 				}
-				if (!this.formData.degree) {
+				if (this.formData.clinicalExperience==null||this.formData.clinicalExperience==0) {
 					uni.showToast({
 						icon: 'none',
-						title: '请选择学位'
+						title: '请输入临床工作经验年数'
 					})
 					return
 				}
@@ -436,39 +1065,36 @@
 					})
 					return
 				}
-				if (this.formData.proofImages.length === 0) {
+				if (this.formData.proofImages && this.formData.proofImages.length === 0) {
 					uni.showToast({
 						icon: 'none',
 						title: '请上传证明材料'
 					})
 					return
 				}
-
-				// 构建表单数据
+               ///console.log(this.formData.questionnaireId,'this.formData.questionnaireId')
+				// 构建表单数据(静态字段)
 				const formData = {
 					// 基础字段
-					id: 0,
+					id: null,
 					doctorId: this.doctorId || '',
-					companyId: this.userInfo.companyId || 0,
-					companyName: this.userInfo.companyName || '',
+					companyId: (this.userInfo && this.userInfo.companyId) || 0,
+					//companyName: (this.userInfo && this.userInfo.companyName) || '',
+					questionnaireVersionId:this.formData.questionnaireId,
 					// 学术信息
-					academicTitle: this.formData.academicTitle,
-					academicPosition: this.formData.academicPositions,
+					// academicTitle: this.formData.academicTitle,
+					// academicPosition: this.formData.academicPositions,
 					internationalPapers: parseInt(this.formData.internationalPapers) || 0,
 					nationalPapers: parseInt(this.formData.nationalPapers) || 0,
-					academicResearch: this.formData.researchAreas,
+					// academicResearch: this.formData.researchAreas,
 					clinicalExperienceYears: parseInt(this.formData.clinicalExperience) || 0,
-					degree: this.formData.degree,
+					// degree: this.formData.degree,
 					applyLevel: this.formData.applicationLevel,
-					// 状态字段
-					status: 0,
-					deleted: 0,
-					auditInstanceId: 0,
 					// 证明材料
-					materials: this.formData.proofImages.map((url, index) => {
+					materials: (this.formData.proofImages || []).map((url, index) => {
 						return {
 							id: 0,
-							companyId: this.userInfo.companyId || 0,
+							companyId: (this.userInfo && this.userInfo.companyId) || 0,
 							applyId: 0,
 							fileUrl: url,
 							fileName: `proof_${index + 1}.jpg`,
@@ -479,6 +1105,24 @@
 						}
 					})
 				}
+				// 动态表单字段放入 dynamicFormData 传到接口
+				const dynamicFormData = {}
+				if (this.formFields && this.formFields.length > 0) {
+					this.formFields.forEach(field => {
+						const vModel = field.__vModel__
+						if (!vModel) return
+						if (!field.__config__) return
+						let value = this.formData[vModel]
+						if (field.__config__.tag === 'el-upload') {
+							dynamicFormData[vModel] = Array.isArray(value) && value.length > 0 ? value.join(',') : (value || '')
+						} else if (field.__config__.tag === 'el-checkbox-group') {
+							dynamicFormData[vModel] = Array.isArray(value) && value.length > 0 ? value.join(',') : (value || '')
+						} else {
+							dynamicFormData[vModel] = value
+						}
+					})
+					formData.dynamicFormData = dynamicFormData
+				}
 
 				// 调用apply接口提交表单
 				uni.showLoading({
@@ -517,6 +1161,16 @@
 </script>
 
 <style lang="scss" scoped>
+	.text-placeholder {
+		color: #C8C9CC !important;
+	}
+	checkbox .wx-checkbox-input {
+		border-radius: 0 !important;
+	}
+	checkbox .wx-checkbox-input.wx-checkbox-input-checked {
+		border-radius: 0 !important;
+	}
+
 	.container {
 		min-height: 100vh;
 		background: #ffffff;
@@ -556,13 +1210,23 @@
 				}
 			}
 
-			.form-section {
+			.form-header {
+				margin: 20rpx 20rpx 0;
+				padding-bottom: 16rpx;
+				.form-title {
+					font-weight: 600;
+					font-size: 32rpx;
+					color: #333333;
+				}
+			}
+
+			.form-section, .dynamic-form-section {
 				background: #fff;
-				margin: 20rpx;
+				// margin: 20rpx;
 				border-radius: 16rpx;
 				padding: 32rpx;
 
-				.form-item {
+				.form-item, .form-item-dynamic {
 					display: flex;
 					justify-content: space-between;
 					align-items: center;
@@ -583,7 +1247,7 @@
 					.input {
 						text-align: end;
 						font-size: 28rpx;
-						color: #C8C9CC;
+						color: #333;
 					}
 
 					.form-label {
@@ -681,7 +1345,7 @@
 					.form-input {
 						flex: 1;
 						font-size: 28rpx;
-						color: #C8C9CC;
+						color: #333;
 
 						&.placeholder {
 							color: #C8C9CC;
@@ -698,6 +1362,166 @@
 							height: 36rpx;
 						}
 					}
+
+					/* 动态表单项控件(与现有样式一致) */
+					.form-textarea {
+						flex: 1;
+						width: 100%;
+						min-height: 160rpx;
+						padding: 16rpx;
+						border-radius: 12rpx;
+						border: 2rpx solid #EBEDF0;
+						font-size: 28rpx;
+						color: #333;
+						box-sizing: border-box;
+					}
+					.input-number-wrapper {
+						display: flex;
+						align-items: center;
+						gap: 16rpx;
+						flex: 1;
+						justify-content: flex-end;
+						.input-number-btn {
+							width: 60rpx;
+							height: 60rpx;
+							display: flex;
+							align-items: center;
+							justify-content: center;
+							border: 2rpx solid #EBEDF0;
+							border-radius: 8rpx;
+							font-size: 32rpx;
+							color: #333;
+							background: #fff;
+							&.disabled {
+								opacity: 0.5;
+								color: #C8C9CC;
+							}
+						}
+						.input-number-input {
+							width: 120rpx;
+							text-align: center;
+							font-size: 28rpx;
+							color: #333;
+						}
+					}
+					.slider-wrapper {
+						flex: 1;
+						padding: 0 0 0 24rpx;
+					}
+					.checkbox-group, .radio-group {
+						flex: 1;
+						display: flex;
+						flex-direction: column;
+						gap: 24rpx;
+						.checkbox-item, .radio-item {
+							display: flex;
+							align-items: center;
+							gap: 16rpx;
+							font-size: 28rpx;
+							color: #333;
+						}
+					}
+					.upload-section {
+						flex: 1;
+						display: flex;
+						flex-wrap: wrap;
+						gap: 20rpx;
+						.upload-item {
+							width: 160rpx;
+							height: 160rpx;
+							border-radius: 16rpx;
+							overflow: hidden;
+							position: relative;
+							box-sizing: border-box;
+							.uploaded-image {
+								width: 100%;
+								height: 100%;
+							}
+							.uploaded-file {
+								width: 100%;
+								height: 100%;
+								background: #F7F8FA;
+								display: flex;
+								align-items: center;
+								justify-content: center;
+								padding: 16rpx;
+								.file-name {
+									font-size: 24rpx;
+									color: #666;
+									word-break: break-all;
+								}
+							}
+							.delete-btn {
+								position: absolute;
+								top: -12rpx;
+								right: -12rpx;
+								width: 40rpx;
+								height: 40rpx;
+								background: rgba(0, 0, 0, 0.6);
+								color: #FFFFFF;
+								border-radius: 50%;
+								display: flex;
+								align-items: center;
+								justify-content: center;
+								font-size: 32rpx;
+								font-weight: bold;
+								z-index: 1;
+							}
+							&.upload-placeholder {
+								width: 160rpx;
+								height: 160rpx;
+								background: #F7F8FA;
+								border-radius: 16rpx;
+								display: flex;
+								flex-direction: column;
+								align-items: center;
+								justify-content: center;
+								gap: 8rpx;
+								image {
+									width: 48rpx;
+									height: 48rpx;
+								}
+								.upload-text {
+									font-size: 24rpx;
+									color: #999999;
+								}
+							}
+						}
+					}
+					.time-range-wrapper, .date-range-wrapper {
+						flex: 1;
+						display: flex;
+						align-items: center;
+						gap: 16rpx;
+						.time-range-input, .date-range-input {
+							flex: 1;
+						}
+						.time-range-separator, .date-range-separator {
+							font-size: 28rpx;
+							color: #666;
+						}
+					}
+					.rate-wrapper {
+						flex: 1;
+						display: flex;
+						align-items: center;
+						gap: 16rpx;
+						.rate-star {
+							font-size: 40rpx;
+							color: #E0E0E0;
+							&.active {
+								color: #FFD700;
+							}
+						}
+						.rate-text {
+							font-size: 28rpx;
+							color: #666;
+						}
+					}
+					.w48.h48 {
+						width: 36rpx;
+						height: 36rpx;
+					}
 				}
 			}
 		}

+ 3 - 1
pages_speaker/index.vue

@@ -258,7 +258,6 @@
 		},
 		async onLoad() {
 			this.userInfo = uni.getStorageSync('userInfo') || '{}';
-			this.loadData();
 			try {
 				this.identity = await utils.getDicts("doctor_account_identity_type");//学术头衔
 				console.log("identity内容", this.identity)
@@ -267,6 +266,9 @@
 				this.identity = []
 			}
 		},
+		onShow() {
+			this.loadData();
+		},
 		onReachBottom() {
 			this.loadMore()
 

+ 86 - 23
pages_task/approvalTaskDetail.vue

@@ -62,6 +62,38 @@
 					</view>
 				</view>
 			</view>
+			<view class="info-section" v-if="auditData.audit.auditType=='ADUIT_JZSH'">
+				<view class="section-header">
+					<view class="section-indicator"></view>
+					<text class="section-title">基础信息</text>
+				</view>
+				<view class="info-list">
+					<view class="info-item">
+						<text class="info-label">账户身份(医生/药剂师)</text>
+						<text class="info-value">{{ auditData.businessData.doctorName||'-' }}</text>
+					</view>
+					<view class="info-item">
+						<text class="info-label">账户身份</text>
+						<text class="info-value">{{ auditData.businessData.accountType=='0'?'医生':'药剂师' }}</text>
+					</view>
+					<view class="info-item">
+						<text class="info-label">手机号码</text>
+						<text class="info-value">{{ auditData.businessData.mobile||'-' }}</text>
+					</view>
+					<view class="info-item">
+						<text class="info-label">身份证号</text>
+						<text class="info-value">{{ auditData.businessData.idCard||'-'}}</text>
+					</view>
+					<view class="info-item">
+						<text class="info-label">机构名称</text>
+						<text class="info-value">{{ auditData.businessData.institution||'-'}}</text>
+					</view>
+					<view class="info-item">
+						<text class="info-label">注册时间</text>
+						<text class="info-value">{{ auditData.businessData. registerTime||'-'}}</text>
+					</view>
+				</view>
+			</view>
 			<view class="info-section" v-if="auditData.audit.auditType=='ADUIT_JZSH'">
 				<view class="section-header">
 					<view class="section-indicator"></view>
@@ -379,43 +411,43 @@
 
 
 			<!-- 定级审核-->
-			<view class="info-section" v-if="auditData.audit.auditType=='ADUIT_WCRWS'||auditData.audit.auditType=='ADUIT_CJRW'">
+			<view class="info-section" v-if="auditData.audit.auditType=='ADUIT_DJSH'">
 				<view class="section-header">
 					<view class="section-indicator"></view>
-					<text class="section-title">基础信息</text>
+					<text class="section-title">定级信息</text>
 				</view>
 				<view class="info-list">
-					<view class="info-item">
-						<text class="info-label">讲者姓名</text>
-						<text class="info-value">{{ auditData.businessData.doctorVO.doctorName ||'-'}}</text>
+					<view class="info-item" v-if="getFieldDisplay('学术头衔', true)">
+						<text class="info-label">学术头衔</text>
+						<text class="info-value">{{ getFieldDisplay('学术头衔', true)}}</text>
 					</view>
-					<view class="info-item">
-						<text class="info-label">账户身份</text>
-						<text class="info-value">{{auditData.businessData.doctorVO.taskName=='1'?'医生':'药剂师'||'-'}}</text>
+					<view class="info-item" v-if="getFieldDisplay('学位', true)">
+						<text class="info-label">学位</text>
+						<text class="info-value">{{ getFieldDisplay('学位', true)}}</text>
 					</view>
-					<view class="info-item">
-						<text class="info-label">身份证号</text>
-						<text class="info-value">{{auditData.businessData.doctorVO.idCard||'-'}}</text>
+					<view class="info-item" v-if="getFieldDisplay('学术研究', true)">
+						<text class="info-label">学术研究</text>
+						<text class="info-value">{{ getFieldDisplay('学术研究', true)}}</text>
 					</view>
-					<view class="info-item">
-						<text class="info-label">机构</text>
-						<text class="info-value">{{auditData.businessData.doctorVO.institution||'-'}}</text>
+					<view class="info-item" v-if="getFieldDisplay('学术任职', true)">
+						<text class="info-label">学术任职</text>
+						<text class="info-value">{{ getFieldDisplay('学术任职', true)}}</text>
 					</view>
 					<view class="info-item">
-						<text class="info-label">地址</text>
-						<text class="info-value">{{auditData.businessData.doctorVO.provinceName||'-'}}{{auditData.businessData.doctorVO.cityName||'-'}}{{auditData.businessData.doctorVO.districtName||'-'}}</text>
+						<text class="info-label">申请级别</text>
+						<text class="info-value">{{ auditData.businessData.doctorLevelApplyVO.applyLevelName ||'-'}}</text>
 					</view>
 					<view class="info-item">
-						<text class="info-label">科室</text>
-						<text class="info-value">{{auditData.businessData.doctorVO.department||'-'}}</text>
+						<text class="info-label">国际性期刊论文/著作数</text>
+						<text class="info-value">{{auditData.businessData.doctorLevelApplyVO.internationalPapers ||'-'}}</text>
 					</view>
 					<view class="info-item">
-						<text class="info-label">职称</text>
-						<text class="info-value">{{auditData.businessData.doctorVO.jobTitle||'-'}}</text>
+						<text class="info-label">全国性期刊论文/著作数</text>
+						<text class="info-value">{{auditData.businessData.doctorLevelApplyVO.nationalPapers ||'-'}}</text>
 					</view>
 					<view class="info-item">
-						<text class="info-label">公司</text>
-						<text class="info-value">{{auditData.businessData.doctorVO.companyName||'-'}}</text>
+						<text class="info-label">临床工作经验年数</text>
+						<text class="info-value">{{auditData.businessData.doctorLevelApplyVO.clinicalExperienceYears ||'-'}}</text>
 					</view>
 				</view>
 			</view>
@@ -689,7 +721,38 @@
 				// 直接打开驳回弹窗
 				this.showRejectPopup = true
 			},
-
+			//动态表单
+			getFieldDisplay(label, isMultiple = false) {
+			      const apply = this.auditData.businessData.doctorLevelApplyVO;
+				  console.log(this.auditData,'apply')
+			      if (!apply || !apply.formJson || !apply.dynamicFormData) return '-';
+			
+			      let formJson = apply.formJson;
+			      if (typeof formJson === 'string') {
+			        try {
+			          formJson = JSON.parse(formJson);
+			        } catch (e) {
+			          return '-';
+			        }
+			      }
+			      const fields = formJson.fields || [];
+			      const field = fields.find(f => f.__config__.label === label);
+			      if (!field) return '-';
+			
+			      const vModel = field.__vModel__;
+			      let value = apply.dynamicFormData[vModel];
+			      if (value === null || value === undefined || value === '') return '-';
+			
+			      const options = field.__slot__?.options || [];
+			      const optionMap = new Map(options.map(opt => [String(opt.value), opt.label]));
+			
+			      if (isMultiple) {
+			        const values = String(value).split(',').filter(Boolean);
+			        return values.map(v => optionMap.get(v) || v).join('、');
+			      } else {
+			        return optionMap.get(String(value)) || value;
+			      }
+			    },
 			// 确认驳回
 			async handleConfirmReject() {
 				if (!this.rejectReason.trim()) {

+ 0 - 35
project.config.json

@@ -1,35 +0,0 @@
-{
-  "setting": {
-    "es6": true,
-    "postcss": true,
-    "minified": true,
-    "uglifyFileName": false,
-    "enhance": true,
-    "packNpmRelationList": [],
-    "babelSetting": {
-      "ignore": [],
-      "disablePlugins": [],
-      "outputPath": ""
-    },
-    "useCompilerPlugins": false,
-    "minifyWXML": true,
-    "compileWorklet": false,
-    "uploadWithSourceMap": true,
-    "packNpmManually": false,
-    "minifyWXSS": true,
-    "localPlugins": false,
-    "disableUseStrict": false,
-    "condition": false,
-    "swc": false,
-    "disableSWC": true
-  },
-  "compileType": "miniprogram",
-  "simulatorPluginLibVersion": {},
-  "packOptions": {
-    "ignore": [],
-    "include": []
-  },
-  "appid": "wx322a4922f7b81924",
-  "editorSetting": {},
-  "libVersion": "3.14.2"
-}

+ 0 - 21
project.private.config.json

@@ -1,21 +0,0 @@
-{
-  "libVersion": "3.14.2",
-  "projectname": "rtliveCompany",
-  "setting": {
-    "urlCheck": true,
-    "coverView": true,
-    "lazyloadPlaceholderEnable": false,
-    "skylineRenderEnable": false,
-    "preloadBackgroundData": false,
-    "autoAudits": false,
-    "showShadowRootInWxmlPanel": true,
-    "compileHotReLoad": true,
-    "useApiHook": true,
-    "useStaticServer": false,
-    "useLanDebug": false,
-    "showES6CompileOption": false,
-    "checkInvalidKey": true,
-    "ignoreDevUnusedFiles": true,
-    "bigPackageSizeSupport": false
-  }
-}