潘志宝
2024-11-14 afa8fc57084c423218c6816b710dfb2f0b87ea89
提交 | 用户 | 时间
e7c126 1 <template>
H 2   <el-form
3     ref="formRef"
4     :model="formData"
5     :rules="formRules"
6     v-loading="formLoading"
7     label-width="0px"
8     :inline-message="true"
9   >
10     <el-table :data="formData" class="-mt-10px">
11       <el-table-column label="序号" type="index" width="100" />
12        <el-table-column label="名字" min-width="150">
13         <template #default="{ row, $index }">
14           <el-form-item :prop="`${$index}.name`" :rules="formRules.name" class="mb-0px!">
15             <el-input v-model="row.name" placeholder="请输入名字" />
16           </el-form-item>
17         </template>
18       </el-table-column>
19       <el-table-column label="简介" min-width="200">
20         <template #default="{ row, $index }">
21           <el-form-item :prop="`${$index}.description`" :rules="formRules.description" class="mb-0px!">
22             <el-input v-model="row.description" type="textarea" placeholder="请输入简介" />
23           </el-form-item>
24         </template>
25       </el-table-column>
26       <el-table-column label="出生日期" min-width="150">
27         <template #default="{ row, $index }">
28           <el-form-item :prop="`${$index}.birthday`" :rules="formRules.birthday" class="mb-0px!">
29             <el-date-picker
30               v-model="row.birthday"
31               type="date"
32               value-format="x"
33               placeholder="选择出生日期"
34             />
35           </el-form-item>
36         </template>
37       </el-table-column>
38       <el-table-column label="性别" min-width="150">
39         <template #default="{ row, $index }">
40           <el-form-item :prop="`${$index}.sex`" :rules="formRules.sex" class="mb-0px!">
41             <el-select v-model="row.sex" placeholder="请选择性别">
42                 <el-option
43                   v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
44                   :key="dict.value"
45                   :label="dict.label"
46                   :value="dict.value"
47                 />
48             </el-select>
49           </el-form-item>
50         </template>
51       </el-table-column>
52       <el-table-column label="是否有效" min-width="150">
53         <template #default="{ row, $index }">
54           <el-form-item :prop="`${$index}.enabled`" :rules="formRules.enabled" class="mb-0px!">
55             <el-radio-group v-model="row.enabled">
56                 <el-radio
57                   v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
58                   :key="dict.value"
59                   :label="dict.value"
60                 >
61                   {{ dict.label }}
62                 </el-radio>
63             </el-radio-group>
64           </el-form-item>
65         </template>
66       </el-table-column>
67       <el-table-column label="头像" min-width="200">
68         <template #default="{ row, $index }">
69           <el-form-item :prop="`${$index}.avatar`" :rules="formRules.avatar" class="mb-0px!">
70             <UploadImg v-model="row.avatar" />
71           </el-form-item>
72         </template>
73       </el-table-column>
74       <el-table-column label="附件" min-width="200">
75         <template #default="{ row, $index }">
76           <el-form-item :prop="`${$index}.video`" :rules="formRules.video" class="mb-0px!">
77             <UploadFile v-model="row.video" />
78           </el-form-item>
79         </template>
80       </el-table-column>
81       <el-table-column label="备注" min-width="400">
82         <template #default="{ row, $index }">
83           <el-form-item :prop="`${$index}.memo`" :rules="formRules.memo" class="mb-0px!">
84             <Editor v-model="row.memo" height="150px" />
85           </el-form-item>
86         </template>
87       </el-table-column>
88       <el-table-column align="center" fixed="right" label="操作" width="60">
89         <template #default="{ $index }">
90           <el-button @click="handleDelete($index)" link>—</el-button>
91         </template>
92       </el-table-column>
93     </el-table>
94   </el-form>
95   <el-row justify="center" class="mt-3">
96     <el-button @click="handleAdd" round>+ 添加学生联系人</el-button>
97   </el-row>
98 </template>
99 <script setup lang="ts">
100 import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
101 import * as StudentApi from '@/api/infra/demo'
102
103 const props = defineProps<{
104   studentId: undefined // 学生编号(主表的关联字段)
105 }>()
106 const formLoading = ref(false) // 表单的加载中
107 const formData = ref([])
108 const formRules = reactive({
109   studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
110   name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
111   description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
112   birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
113   sex: [{ required: true, message: '性别不能为空', trigger: 'change' }],
114   enabled: [{ required: true, message: '是否有效不能为空', trigger: 'blur' }],
115   avatar: [{ required: true, message: '头像不能为空', trigger: 'blur' }],
116   memo: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
117 })
118 const formRef = ref() // 表单 Ref
119
120 /** 监听主表的关联字段的变化,加载对应的子表数据 */
121 watch(
122   () => props.studentId,
123   async (val) => {
124     // 1. 重置表单
125     formData.value = []
126     // 2. val 非空,则加载数据
127     if (!val) {
128       return;
129     }
130     try {
131       formLoading.value = true
132       formData.value = await StudentApi.getStudentContactListByStudentId(val)
133     } finally {
134       formLoading.value = false
135     }
136   },
137   { immediate: true }
138 )
139
140 /** 新增按钮操作 */
141 const handleAdd = () => {
142   const row = {
143     id: undefined,
144     studentId: undefined,
145     name: undefined,
146     description: undefined,
147     birthday: undefined,
148     sex: undefined,
149     enabled: undefined,
150     avatar: undefined,
151     video: undefined,
152     memo: undefined,
153   }
154   row.studentId = props.studentId
155   formData.value.push(row)
156 }
157
158 /** 删除按钮操作 */
159 const handleDelete = (index) => {
160   formData.value.splice(index, 1)
161 }
162
163 /** 表单校验 */
164 const validate = () => {
165   return formRef.value.validate()
166 }
167
168 /** 表单值 */
169 const getData = () => {
170   return formData.value
171 }
172
173 defineExpose({ validate, getData })
174 </script>