提交 | 用户 | 时间
b1d33f 1 <template>
2   <Dialog v-model="dialogVisible" :title="dialogTitle">
3     <el-form
4       ref="formRef"
5       v-loading="formLoading"
6       :model="formData"
7       :rules="formRules"
8       label-width="80px"
9     >
10       <el-form-item label="名称" prop="name">
11         <el-input v-model="formData.name" placeholder="请输入名称" />
12       </el-form-item>
13       <el-form-item label="数据源" prop="dataSource">
14         <el-select v-model="formData.dataSource" clearable placeholder="请选择数据源">
15           <el-option
16             v-for="item in dataSourceList"
17             :key="item.id"
18             :label="item.name"
19             :value="item.id + ''"
20           />
21         </el-select>
22       </el-form-item>
23       <el-form-item label="查询语句" prop="querySql">
24         <el-input v-model="formData.querySql" placeholder="请输入内容" type="textarea" maxlength="300"
cb0791 25                   show-word-limit :rows="6" @input="checkSensitiveWords" spellcheck="false"/>
H 26       </el-form-item>
27       <el-form-item v-if="showError">
28         <p>输入中包含以下敏感词:<span style="color: red">{{sensitiveMessage}}</span></p>
b1d33f 29       </el-form-item>
30       <el-form-item label="备注" prop="remark">
31         <el-input v-model="formData.remark" placeholder="请输入内容" type="textarea" maxlength="100"
32                   show-word-limit/>
33       </el-form-item>
34     </el-form>
35     <template #footer>
cb0791 36       <el-button :disabled="disableSubmit" type="primary" @click="submitForm">确 定</el-button>
b1d33f 37       <el-button @click="dialogVisible = false">取 消</el-button>
38     </template>
39   </Dialog>
40 </template>
41 <script lang="ts" setup>
42 import * as DataSetApi from '@/api/data/plan/data'
43 import * as DataSourceConfigApi from "@/api/infra/dataSourceConfig";
44
45 defineOptions({ name: 'PlanDataSetForm' })
46
47 const { t } = useI18n() // 国际化
48 const message = useMessage() // 消息弹窗
49
cb0791 50 const showError = ref(false)
H 51 const foundSensitiveWords = ref()
52 const sensitiveMessage = ref('')
53 const sensitiveWords = [';', 'master', 'truncate', 'insert', 'select', 'delete', 'update', 'declare', 'alter', 'drop']
54
b1d33f 55 const dialogVisible = ref(false) // 弹窗的是否展示
56 const dialogTitle = ref('') // 弹窗的标题
cb0791 57 const formLoading = ref(false) // 表单的加载中:修改时的数据加载;
H 58 const disableSubmit = ref(false) // 禁止提交
b1d33f 59 const formType = ref('') // 表单的类型:create - 新增;update - 修改
60 const formData = ref({
61   id: undefined,
62   name: '',
63   dataSource: '',
64   querySql: '',
65   remark: ''
66 })
67 const formRules = reactive({
68   name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
69   dataSource: [{ required: true, message: '数据源不能为空', trigger: 'blur' }],
70   querySql: [{ required: true, message: '查询语句不能为空', trigger: 'change' }]
71 })
72 const formRef = ref() // 表单 Ref
73 const dataSourceList = ref([] as DataSourceConfigApi.DataSourceConfigVO[])
74
75 /** 打开弹窗 */
76 const open = async (type: string, id?: number) => {
77   dialogVisible.value = true
78   dialogTitle.value = t('action.' + type)
79   formType.value = type
80   resetForm()
81
82   // 加载数据源列表
83   dataSourceList.value = await DataSourceConfigApi.getDataSourceConfigList()
84
85   // 修改时,设置数据
86   if (id) {
87     formLoading.value = true
88     try {
89       formData.value = await DataSetApi.getDataSet(id)
90     } finally {
91       formLoading.value = false
92     }
93   }
94 }
95 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
cb0791 96
H 97 /**
98  * 验证敏感词
99  */
100 const checkSensitiveWords = () => {
101   showError.value = false;
102   const regex = new RegExp(sensitiveWords.map(word => `${word}`).join('|'), 'gi');
103   let matches = formData.value.querySql.match(regex);
104   if (matches) {
105     showError.value = true;
106     foundSensitiveWords.value = Array.from(new Set(matches));
107     disableSubmit.value = true
108     sensitiveMessage.value = foundSensitiveWords.value.join('、')
109   } else {
110     foundSensitiveWords.value = undefined
111     disableSubmit.value = false
112   }
113 }
b1d33f 114
115 /** 提交表单 */
116 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
117 const submitForm = async () => {
118   // 校验表单
119   if (!formRef) return
120   const valid = await formRef.value.validate()
121   if (!valid) return
122   // 提交请求
123   formLoading.value = true
cb0791 124   disableSubmit.value = true
b1d33f 125   try {
126     const data = formData.value as DataSetApi.DataSetVO
127     if (formType.value === 'create') {
128       await DataSetApi.createDataSet(data)
129       message.success(t('common.createSuccess'))
130     } else {
131       await DataSetApi.updateDataSet(data)
132       message.success(t('common.updateSuccess'))
133     }
134     dialogVisible.value = false
135     // 发送操作成功的事件
136     emit('success')
137   } finally {
138     formLoading.value = false
cb0791 139     disableSubmit.value = false
b1d33f 140   }
141 }
142
143 /** 重置表单 */
144 const resetForm = () => {
145   formData.value = {
146     id: undefined,
147     name: '',
148     dataSource: '',
149     querySql: '',
150     remark: ''
151   }
152   formRef.value?.resetFields()
153 }
154 </script>