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