|
|
@@ -194,9 +194,19 @@
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
<el-form-item label="适用症状" prop="symptomsList">
|
|
|
- <el-checkbox-group v-model="formData.symptomsList">
|
|
|
+ <el-checkbox-group v-model="formData.symptomsList" class="symptom-checkboxes">
|
|
|
<el-checkbox v-for="s in symptomsOptions" :key="s" :label="s" />
|
|
|
</el-checkbox-group>
|
|
|
+ <div v-if="dialogMode !== 'view'" class="symptom-add-row">
|
|
|
+ <el-input
|
|
|
+ v-model="customSymptom"
|
|
|
+ placeholder="输入症状名称"
|
|
|
+ maxlength="20"
|
|
|
+ clearable
|
|
|
+ @keyup.enter="addCustomSymptom"
|
|
|
+ />
|
|
|
+ <el-button type="primary" :icon="Plus" @click="addCustomSymptom">添加</el-button>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="方案描述">
|
|
|
<el-input v-model="formData.description" type="textarea" :rows="2" maxlength="200" show-word-limit />
|
|
|
@@ -365,7 +375,8 @@ import { useUserStore } from '@/store/user'
|
|
|
import { formatDateTime } from '@/utils/date'
|
|
|
// ============ 枚举常量 ============
|
|
|
const effectOptions = ['驱寒', '祛湿', '祛风', '化瘀', '活血', '化痰', '养颜', '扶阳']
|
|
|
-const symptomsOptions = ['怕冷', '感冒', '咳嗽', '痰多', '疼痛', '腰酸', '失眠', '疲劳', '皮肤暗沉', '手脚冰凉', '其他']
|
|
|
+const defaultSymptomsOptions = ['怕冷', '感冒', '咳嗽', '痰多', '疼痛', '腰酸', '失眠', '疲劳', '皮肤暗沉', '手脚冰凉']
|
|
|
+const symptomsOptions = ref([...defaultSymptomsOptions])
|
|
|
const userStore = useUserStore()
|
|
|
|
|
|
// ============ 选项列表(用于选择框) ============
|
|
|
@@ -488,6 +499,7 @@ const dialogTitle = ref('')
|
|
|
const dialogMode = ref('add')
|
|
|
const submitLoading = ref(false)
|
|
|
const formRef = ref(null)
|
|
|
+const customSymptom = ref('')
|
|
|
|
|
|
const defaultStep = () => ({
|
|
|
acupointId: null,
|
|
|
@@ -548,6 +560,39 @@ function onTechniqueChange(id, index) {
|
|
|
formData.steps[index].techniqueName = found ? found.name : ''
|
|
|
}
|
|
|
|
|
|
+function parseSymptoms(symptoms) {
|
|
|
+ return (symptoms || '')
|
|
|
+ .split(',')
|
|
|
+ .map(item => item.trim())
|
|
|
+ .filter(Boolean)
|
|
|
+ .filter((item, index, list) => list.indexOf(item) === index)
|
|
|
+}
|
|
|
+
|
|
|
+function syncSymptomOptions(symptoms) {
|
|
|
+ symptoms.forEach(item => {
|
|
|
+ if (!symptomsOptions.value.includes(item)) {
|
|
|
+ symptomsOptions.value.push(item)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function addCustomSymptom() {
|
|
|
+ const symptom = customSymptom.value.trim()
|
|
|
+ if (!symptom) {
|
|
|
+ ElMessage.warning('请输入症状名称')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (/[,,]/.test(symptom)) {
|
|
|
+ ElMessage.warning('症状名称不能包含逗号')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ syncSymptomOptions([symptom])
|
|
|
+ if (!formData.symptomsList.includes(symptom)) {
|
|
|
+ formData.symptomsList.push(symptom)
|
|
|
+ }
|
|
|
+ customSymptom.value = ''
|
|
|
+}
|
|
|
+
|
|
|
function getCurrentAuthorId() {
|
|
|
return userStore.userInfo?.userId || null
|
|
|
}
|
|
|
@@ -588,6 +633,7 @@ function removeStep(index) {
|
|
|
function handleAdd() {
|
|
|
Object.assign(formData, defaultForm())
|
|
|
formData.steps = [defaultStep()]
|
|
|
+ customSymptom.value = ''
|
|
|
applyCurrentAuthor()
|
|
|
dialogTitle.value = '新增方案'
|
|
|
dialogMode.value = 'add'
|
|
|
@@ -600,11 +646,14 @@ function handleAdd() {
|
|
|
async function handleEdit(row) {
|
|
|
const res = await getPlanDetail(row.id)
|
|
|
const detail = res.data
|
|
|
+ const symptomsList = parseSymptoms(detail.symptoms)
|
|
|
+ syncSymptomOptions(symptomsList)
|
|
|
Object.assign(formData, defaultForm(), {
|
|
|
...detail,
|
|
|
- symptomsList: detail.symptoms ? detail.symptoms.split(',') : [],
|
|
|
+ symptomsList,
|
|
|
steps: detail.steps?.length > 0 ? detail.steps : [defaultStep()]
|
|
|
})
|
|
|
+ customSymptom.value = ''
|
|
|
applyCurrentAuthor()
|
|
|
dialogTitle.value = '编辑方案'
|
|
|
dialogMode.value = 'edit'
|
|
|
@@ -759,6 +808,20 @@ onMounted(() => {
|
|
|
justify-content: flex-end;
|
|
|
}
|
|
|
|
|
|
+.symptom-checkboxes {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 0 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.symptom-add-row {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ width: 360px;
|
|
|
+ max-width: 100%;
|
|
|
+ margin-top: 8px;
|
|
|
+}
|
|
|
+
|
|
|
.step-row {
|
|
|
border: 1px solid #ebeef5;
|
|
|
border-radius: 6px;
|