潘志宝
2025-02-28 4a859a6d69984c77fa8166255c65f5a94eb0bd71
提交 | 用户 | 时间
c62768 1 <template>
J 2   <Dialog v-model="dialogVisible" :title="dialogTitle" width="55%">
3     <el-form
4       ref="formRef"
5       v-loading="formLoading"
6       :model="formData"
7       :rules="formRules" label-width="100px">
8       <el-row>
9         <el-col :span="12">
683738 10           <el-form-item label="指标编码" prop="itemNo">
11             <el-input v-model="formData.itemNo" disabled/>
12           </el-form-item>
13         </el-col>
14         <el-col :span="12">
15           <el-form-item label="指标名称" prop="itemName">
16             <el-input v-model="formData.itemName"/>
17           </el-form-item>
18         </el-col>
19       </el-row>
20       <el-row>
21         <el-col :span="12">
6f74c2 22           <el-form-item label="原子指标" prop="atomItem.itemId">
6a72da 23             <el-select v-model="formData.atomItem.itemId" filterable
J 24                        allow-create clearable placeholder="请选择原子指标"
c62768 25                        @change="handleChange($event)">
J 26               <el-option
27                 v-for="item in atomItemList"
28                 :key="item.id"
29                 :label="item.itemNo"
6f74c2 30                 :value="item.id + ''"
c62768 31               />
J 32             </el-select>
33           </el-form-item>
34         </el-col>
35         <el-col :span="12">
36           <el-form-item label="原子指标名称" prop="atomItem.itemName">
37             <el-input v-model="formData.atomItem.itemName" disabled/>
38           </el-form-item>
39         </el-col>
40       </el-row>
41       <el-row>
42         <el-col :span="12">
43           <el-form-item label="指标分类" prop="itemCategory">
6a72da 44             <el-tree-select
J 45               v-model="formData.itemCategory"
46               :data="dataCategoryList"
47               :default-expanded-keys="[0]"
48               :props="defaultProps"
49               check-strictly
50               node-key="id"
51             />
c62768 52           </el-form-item>
J 53         </el-col>
54         <el-col :span="12">
55           <el-form-item label="时间粒度" prop="timeGranularity">
56             <el-select v-model="formData.timeGranularity" placeholder="请选择">
57               <el-option
58                 v-for="dict in getStrDictOptions(DICT_TYPE.TIME_GRANULARITY)"
59                 :key="dict.value"
60                 :label="dict.label"
61                 :value="dict.value"
62               />
63             </el-select>
64           </el-form-item>
65         </el-col>
66       </el-row>
67       <el-row>
d3ee81 68         <el-col :span="6">
c62768 69           <el-form-item label="指标精度" prop="precision">
J 70             <el-input v-model="formData.precision"/>
71           </el-form-item>
72         </el-col>
d3ee81 73         <el-col :span="6">
c62768 74           <el-form-item label="转换系数" prop="coefficient">
J 75             <el-input v-model="formData.coefficient"/>
76           </el-form-item>
77         </el-col>
78         <el-col :span="6">
79           <el-form-item label="数量单位" prop="unit">
80             <el-input v-model="formData.unit"/>
81           </el-form-item>
82         </el-col>
331bbb 83         <el-col :span="6">
J 84           <el-form-item label="固化标识" prop="solidifyFlag">
85             <el-select v-model="formData.solidifyFlag"
86                        clearable
87                        filterable
88                        allow-create
89                        placeholder="请选择">
90               <el-option
91                 v-for="dict in getStrDictOptions(DICT_TYPE.SOLIDIFY_FLAG)"
92                 :key="dict.value"
93                 :label="dict.label"
94                 :value="dict.value"
95               />
96             </el-select>
97           </el-form-item>
98         </el-col>
c62768 99       </el-row>
J 100       <el-row>
d3ee81 101         <el-col :span="6">
c62768 102           <el-form-item label="时间标识" prop="timeLabel">
71db7a 103             <el-select v-model="formData.derItem.timeLabel" allow-create filterable clearable placeholder="请选择时间标识">
c62768 104               <el-option
J 105                 v-for="item in dataSetFieldList"
106                 :key="item.id"
107                 :label="item.fieldCode"
fb7d46 108                 :value="item.fieldCode"
c62768 109               />
J 110             </el-select>
111           </el-form-item>
112         </el-col>
d3ee81 113         <el-col :span="6">
c62768 114           <el-form-item label="时间限定" prop="timeLimit">
6497f9 115             <el-select v-model="formData.derItem.timeLimit" placeholder="请选择"
c62768 116                        @change="handleTimeLimitChange($event)">
J 117               <el-option
d3ee81 118                 v-for="dict in getStrDictOptions(DICT_TYPE.IND_TIME_LIMIT)"
c62768 119                 :key="dict.value"
J 120                 :label="dict.label"
121                 :value="dict.value"
122               />
123             </el-select>
124           </el-form-item>
125         </el-col>
126       </el-row>
127       <el-row v-if="showTimeChange">
d3ee81 128         <el-col :span="6">
c62768 129           <el-form-item label="开始时间" prop="timeStart">
J 130             <el-date-picker
131               v-model="formData.derItem.timeStart"
132               type="datetime"
133               placeholder="请选择开始时间"
134             />
135           </el-form-item>
136         </el-col>
d3ee81 137         <el-col :span="6">
c62768 138           <el-form-item label="结束时间" prop="timeEnd">
J 139             <el-date-picker
140               v-model="formData.derItem.timeEnd"
141               type="datetime"
142               placeholder="请选择结束时间"
143             />
144           </el-form-item>
145         </el-col>
146       </el-row>
147       <el-row>
d3ee81 148         <el-col :span="24">
c62768 149           <el-form-item label="分析维度" prop="dimension">
6a72da 150             <el-select v-model="formData.derItem.dimension" filterable
J 151                        allow-create clearable placeholder="请选择分析维度" multiple>
c62768 152               <el-option
J 153                 v-for="item in dataSetFieldList"
154                 :key="item.id"
155                 :label="item.fieldCode"
fb7d46 156                 :value="item.fieldCode"
c62768 157               />
J 158             </el-select>
d3ee81 159           </el-form-item>
160         </el-col>
161       </el-row>
162       <el-row>
163         <el-col :span="24">
164           <el-form-item label="备注" prop="remark">
165             <el-input v-model="formData.remark" type="textarea" maxlength="100"/>
c62768 166           </el-form-item>
J 167         </el-col>
168       </el-row>
169     </el-form>
170     <template #footer>
171       <el-button :="formLoading" type="primary" @click="submitForm">确 定</el-button>
172       <el-button @click="dialogVisible = false">取 消</el-button>
173     </template>
174   </Dialog>
175 </template>
176 <script lang="ts" setup>
177   import {DICT_TYPE, getStrDictOptions} from '@/utils/dict'
178   import * as DataSetApi from '@/api/data/ind/data/data.set'
179   import * as ItemApi from '@/api/data/ind/item/item'
180   import {CommonStatusEnum} from '@/utils/constants'
181   import * as DataSourceConfigApi from "@/api/infra/dataSourceConfig";
182   import {PageParam} from "@/api/data/ind/item/item";
183   import * as CategoryApi from "@/api/data/ind/category";
184   import * as DataSetFieldApi from "@/api/data/ind/data/data.field";
6a72da 185   import {handleTree} from "@/utils/tree";
c62768 186
J 187   defineOptions({name: 'IndDataSetForm'})
188
189   const {t} = useI18n() // 国际化
190   const message = useMessage() // 消息弹窗
191
192   const dialogVisible = ref(false) // 弹窗的是否展示
193   const dialogTitle = ref('') // 弹窗的标题
194   const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
195   const formType = ref('') // 表单的类型:create - 新增;update - 修改
196   let formData = ref({
197     id: undefined,
198     itemNo: '',
199     itemName: '',
200     itemType: '',
201     itemCategory: '',
d3ee81 202     coefficient: 1,
203     precision: 0,
c62768 204     businessType: '',
J 205     timeRange: '',
206     timeGranularity: '',
4058b7 207     solidifyFlag:'',
c62768 208     atomItem: {
J 209       id: '',
6f74c2 210       itemId: '',
c62768 211       itemNo: '',
J 212       itemName: '',
213     },
214     derItem: {
215       atomItemId: '',
216       timeLabel: '',
217       timeLimit: '',
218       timeStart: '',
219       timeEnd: '',
220       dimension: ''
221     }
222   })
223
224   const validateAsNumber = (rule, value, callback) => {
225     const regex = /^(\-|\+)?\d+(\.\d+)?$/;
226     if (!regex.test(value)) {
227       callback(new Error('请输入数字!'));
228     }
229   }
230
231   const formRules = reactive({
232     itemName: [{required: true, message: '指标名称不能为空', trigger: 'blur'}],
233     itemCategory: [{required: true, message: '指标类型不能为空', trigger: 'blur'}],
d3ee81 234     /*precision: [{validator: validateAsNumber, trigger: 'blur' }],
235     coefficient: [{validator: validateAsNumber, trigger: 'blur' }],*/
236     /*"atomItem.id": [{required: true, message: '原子指标不能为空', trigger: 'blur'}]*/
c62768 237   })
J 238   const formRef = ref() // 表单 Ref
239   const atomItemList = ref([] as ItemApi.ItemVO[])
240   const showTimeChange = ref(false)
241   const dataSetFieldList = ref([] as DataSetFieldApi.DataSetFieldVO[])
6a72da 242   const dataCategoryList = ref<Tree[]>([])
c62768 243
6a72da 244   const getCategoryTree = async () => {
J 245     dataCategoryList.value = []
246     const res = await CategoryApi.getCategoryListAllSimple()
247     let category: Tree = {id: 0, label: '主类目', children: []}
248     category.children = handleTree(res, 'id', 'pid')
249     dataCategoryList.value.push(category)
250   }
c62768 251   /** 打开弹窗 */
J 252   const open = async (type: string, id?: string) => {
253     dialogVisible.value = true
254     dialogTitle.value = '派生指标'
255     formType.value = type
256     resetForm()
257     // 加载数据源列表
6a72da 258     await getCategoryTree()
6f74c2 259     const queryParams = reactive({
J 260       itemType: 'ATOM'
261     })
c62768 262     atomItemList.value = await ItemApi.getItemList(queryParams)
J 263     // 修改时,设置数据
264     if (id) {
265       formLoading.value = true
266       try {
267         formData.value = await ItemApi.getItem(id)
6497f9 268         if(formData.value.derItem.dimension.length > 0){
J 269           formData.value.derItem.dimension = formData.value.derItem.dimension.split(',')
270         }else {
271           formData.value.derItem.dimension = ""
272         }
fb7d46 273         showTimeChange.value = formData.value.derItem.timeLimit === 'CUSTOM'
8c605f 274         await handleChange(formData.value.derItem.atomItemId)
c62768 275       } finally {
J 276         formLoading.value = false
277       }
278     }
279   }
280   defineExpose({open}) // 提供 open 方法,用于打开弹窗
281
282   /** 提交表单 */
283   const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
284   const submitForm = async () => {
285     // 校验表单
286     if (!formRef) return
287     const valid = await formRef.value.validate()
288     if (!valid) return
289     // 提交请求
290     formLoading.value = true
291     try {
292       formData.value.itemType = 'DER'
ea0250 293       formData.value.derItem.atomItemId = formData.value.atomItem.itemId
c62768 294       if(formData.value.derItem.dimension.length > 0){
J 295         let dimension = ''
296         for (let index in formData.value.derItem.dimension){
297           dimension = dimension + formData.value.derItem.dimension[index] + ','
298         }
299         formData.value.derItem.dimension = dimension.substring(0, dimension.length - 1)
6497f9 300       }else{
J 301         formData.value.derItem.dimension = ''
c62768 302       }
J 303       const data = formData.value as ItemApi.ItemVO
304       if (formType.value === 'create') {
305         await ItemApi.createItem(data)
306         message.success(t('common.createSuccess'))
307       } else {
308         await ItemApi.updateItem(data)
309         message.success(t('common.updateSuccess'))
310       }
311       dialogVisible.value = false
312       // 发送操作成功的事件
313       emit('success')
314     } finally {
315       formLoading.value = false
316     }
317   }
318   /** 重置表单 */
319   const resetForm = () => {
320     formData.value = {
321       id: undefined,
322       itemNo: '',
323       itemName: '',
324       itemType: '',
325       itemCategory: '',
d3ee81 326       coefficient: 1,
327       precision: 0,
c62768 328       businessType: '',
J 329       timeRange: '',
330       timeGranularity: '',
331       remark: '',
332       atomItem: {
333         id: '',
334         itemNo: '',
335         itemName: '',
336       },
337       derItem: {
338         atomItemId: '',
339         timeLabel: '',
340         timeLimit: '',
341         timeStart: '',
342         timeEnd: '',
343         dimension: ''
344       }
345     }
346   }
347
348   async function handleChange(event) {
349     if (event !== null && event !== undefined) {
350       const itemData = await ItemApi.getItem(event)
8c605f 351       let a = itemData.atomItem.id
J 352       formData.value.atomItem.id = a
c62768 353       formData.value.atomItem.itemName = itemData.itemName
ea0250 354       formData.value.atomItem.itemId = itemData.atomItem.itemId
c62768 355       const queryParams = reactive({
J 356         dataSetId: itemData.atomItem.dataSet,
357       })
358       dataSetFieldList.value = (await DataSetFieldApi.getDataSetFieldPage(queryParams)).list
359     }
360   }
361
362   function handleTimeLimitChange(event) {
363     showTimeChange.value = event === 'CUSTOM';
364   }
365 </script>