houzhongjian
2024-08-08 820397e43a0b64d35c6d31d2a55475061438593b
提交 | 用户 | 时间
820397 1 <template>
H 2   <Dialog v-model="dialogVisible" :title="dialogTitle" max-height="500px" scroll>
3     <el-form
4       ref="formRef"
5       v-loading="formLoading"
6       :model="formData"
7       :rules="formRules"
8       label-width="160px"
9     >
10       <el-form-item label="客户端编号" prop="secret">
11         <el-input v-model="formData.clientId" placeholder="请输入客户端编号" />
12       </el-form-item>
13       <el-form-item label="客户端密钥" prop="secret">
14         <el-input v-model="formData.secret" placeholder="请输入客户端密钥" />
15       </el-form-item>
16       <el-form-item label="应用名" prop="name">
17         <el-input v-model="formData.name" placeholder="请输入应用名" />
18       </el-form-item>
19       <el-form-item label="应用图标">
20         <UploadImg v-model="formData.logo" :limit="1" />
21       </el-form-item>
22       <el-form-item label="应用描述">
23         <el-input v-model="formData.description" placeholder="请输入应用名" type="textarea" />
24       </el-form-item>
25       <el-form-item label="状态" prop="status">
26         <el-radio-group v-model="formData.status">
27           <el-radio
28             v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
29             :key="dict.value"
30             :label="dict.value"
31           >
32             {{ dict.label }}
33           </el-radio>
34         </el-radio-group>
35       </el-form-item>
36       <el-form-item label="访问令牌的有效期" prop="accessTokenValiditySeconds">
37         <el-input-number v-model="formData.accessTokenValiditySeconds" placeholder="单位:秒" />
38       </el-form-item>
39       <el-form-item label="刷新令牌的有效期" prop="refreshTokenValiditySeconds">
40         <el-input-number v-model="formData.refreshTokenValiditySeconds" placeholder="单位:秒" />
41       </el-form-item>
42       <el-form-item label="授权类型" prop="authorizedGrantTypes">
43         <el-select
44           v-model="formData.authorizedGrantTypes"
45           filterable
46           multiple
47           placeholder="请输入授权类型"
48           style="width: 500px"
49         >
50           <el-option
51             v-for="dict in getDictOptions(DICT_TYPE.SYSTEM_OAUTH2_GRANT_TYPE)"
52             :key="dict.value"
53             :label="dict.label"
54             :value="dict.value"
55           />
56         </el-select>
57       </el-form-item>
58       <el-form-item label="授权范围" prop="scopes">
59         <el-select
60           v-model="formData.scopes"
61           filterable
62           multiple
63           allow-create
64           placeholder="请输入授权范围"
65           style="width: 500px"
66         >
67           <el-option v-for="scope in formData.scopes" :key="scope" :label="scope" :value="scope" />
68         </el-select>
69       </el-form-item>
70       <el-form-item label="自动授权范围" prop="autoApproveScopes">
71         <el-select
72           v-model="formData.autoApproveScopes"
73           filterable
74           multiple
75           placeholder="请输入授权范围"
76           style="width: 500px"
77         >
78           <el-option v-for="scope in formData.scopes" :key="scope" :label="scope" :value="scope" />
79         </el-select>
80       </el-form-item>
81       <el-form-item label="可重定向的 URI 地址" prop="redirectUris">
82         <el-select
83           v-model="formData.redirectUris"
84           allow-create
85           filterable
86           multiple
87           placeholder="请输入可重定向的 URI 地址"
88           style="width: 500px"
89         >
90           <el-option
91             v-for="redirectUri in formData.redirectUris"
92             :key="redirectUri"
93             :label="redirectUri"
94             :value="redirectUri"
95           />
96         </el-select>
97       </el-form-item>
98       <el-form-item label="权限" prop="authorities">
99         <el-select
100           v-model="formData.authorities"
101           allow-create
102           filterable
103           multiple
104           placeholder="请输入权限"
105           style="width: 500px"
106         >
107           <el-option
108             v-for="authority in formData.authorities"
109             :key="authority"
110             :label="authority"
111             :value="authority"
112           />
113         </el-select>
114       </el-form-item>
115       <el-form-item label="资源" prop="resourceIds">
116         <el-select
117           v-model="formData.resourceIds"
118           allow-create
119           filterable
120           multiple
121           placeholder="请输入资源"
122           style="width: 500px"
123         >
124           <el-option
125             v-for="resourceId in formData.resourceIds"
126             :key="resourceId"
127             :label="resourceId"
128             :value="resourceId"
129           />
130         </el-select>
131       </el-form-item>
132       <el-form-item label="附加信息" prop="additionalInformation">
133         <el-input
134           v-model="formData.additionalInformation"
135           placeholder="请输入附加信息,JSON 格式数据"
136           type="textarea"
137         />
138       </el-form-item>
139     </el-form>
140     <template #footer>
141       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
142       <el-button @click="dialogVisible = false">取 消</el-button>
143     </template>
144   </Dialog>
145 </template>
146 <script lang="ts" setup>
147 import { DICT_TYPE, getDictOptions, getIntDictOptions } from '@/utils/dict'
148 import { CommonStatusEnum } from '@/utils/constants'
149 import * as ClientApi from '@/api/system/oauth2/client'
150
151 defineOptions({ name: 'SystemOAuth2ClientForm' })
152
153 const { t } = useI18n() // 国际化
154 const message = useMessage() // 消息弹窗
155
156 const dialogVisible = ref(false) // 弹窗的是否展示
157 const dialogTitle = ref('') // 弹窗的标题
158 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
159 const formType = ref('') // 表单的类型:create - 新增;update - 修改
160 const formData = ref({
161   id: undefined,
162   clientId: undefined,
163   secret: undefined,
164   name: undefined,
165   logo: undefined,
166   description: undefined,
167   status: CommonStatusEnum.ENABLE,
168   accessTokenValiditySeconds: 30 * 60,
169   refreshTokenValiditySeconds: 30 * 24 * 60,
170   redirectUris: [],
171   authorizedGrantTypes: [],
172   scopes: [],
173   autoApproveScopes: [],
174   authorities: [],
175   resourceIds: [],
176   additionalInformation: undefined
177 })
178 const formRules = reactive({
179   clientId: [{ required: true, message: '客户端编号不能为空', trigger: 'blur' }],
180   secret: [{ required: true, message: '客户端密钥不能为空', trigger: 'blur' }],
181   name: [{ required: true, message: '应用名不能为空', trigger: 'blur' }],
182   logo: [{ required: true, message: '应用图标不能为空', trigger: 'blur' }],
183   status: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
184   accessTokenValiditySeconds: [
185     { required: true, message: '访问令牌的有效期不能为空', trigger: 'blur' }
186   ],
187   refreshTokenValiditySeconds: [
188     { required: true, message: '刷新令牌的有效期不能为空', trigger: 'blur' }
189   ],
190   redirectUris: [{ required: true, message: '可重定向的 URI 地址不能为空', trigger: 'blur' }],
191   authorizedGrantTypes: [{ required: true, message: '授权类型不能为空', trigger: 'blur' }]
192 })
193 const formRef = ref() // 表单 Ref
194
195 /** 打开弹窗 */
196 const open = async (type: string, id?: number) => {
197   dialogVisible.value = true
198   dialogTitle.value = t('action.' + type)
199   formType.value = type
200   resetForm()
201   // 修改时,设置数据
202   if (id) {
203     formLoading.value = true
204     try {
205       formData.value = await ClientApi.getOAuth2Client(id)
206     } finally {
207       formLoading.value = false
208     }
209   }
210 }
211 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
212
213 /** 提交表单 */
214 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
215 const submitForm = async () => {
216   // 校验表单
217   if (!formRef) return
218   const valid = await formRef.value.validate()
219   if (!valid) return
220   // 提交请求
221   formLoading.value = true
222   try {
223     const data = formData.value as unknown as ClientApi.OAuth2ClientVO
224     if (formType.value === 'create') {
225       await ClientApi.createOAuth2Client(data)
226       message.success(t('common.createSuccess'))
227     } else {
228       await ClientApi.updateOAuth2Client(data)
229       message.success(t('common.updateSuccess'))
230     }
231     dialogVisible.value = false
232     // 发送操作成功的事件
233     emit('success')
234   } finally {
235     formLoading.value = false
236   }
237 }
238
239 /** 重置表单 */
240 const resetForm = () => {
241   formData.value = {
242     id: undefined,
243     clientId: undefined,
244     secret: undefined,
245     name: undefined,
246     logo: undefined,
247     description: undefined,
248     status: CommonStatusEnum.ENABLE,
249     accessTokenValiditySeconds: 30 * 60,
250     refreshTokenValiditySeconds: 30 * 24 * 60,
251     redirectUris: [],
252     authorizedGrantTypes: [],
253     scopes: [],
254     autoApproveScopes: [],
255     authorities: [],
256     resourceIds: [],
257     additionalInformation: undefined
258   }
259   formRef.value?.resetFields()
260 }
261 </script>