mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 02:08:43 +08:00 
			
		
		
		
	fix: todo
This commit is contained in:
		| @@ -16,7 +16,7 @@ export interface ConfigType { | ||||
| export interface FileConfigVO { | ||||
|   id: number | ||||
|   name: string | ||||
|   storage: string | ||||
|   storage: number | ||||
|   master: boolean | ||||
|   visible: boolean | ||||
|   config: ConfigType | ||||
|   | ||||
| @@ -40,14 +40,14 @@ const crudSchemas = reactive<VxeCrudSchema>({ | ||||
|     { | ||||
|       title: '存储器', | ||||
|       field: 'storage', | ||||
|       dictType: DICT_TYPE.INFRA_FILE_STORAGE, // TODO @星语:不同存储器,不同表单 | ||||
|       dictType: DICT_TYPE.INFRA_FILE_STORAGE, | ||||
|       dictClass: 'number', | ||||
|       isSearch: true | ||||
|     }, | ||||
|     { | ||||
|       title: '主配置', | ||||
|       field: 'master', | ||||
|       dictType: DICT_TYPE.INFRA_BOOLEAN_STRING, // TODO @星语:新增时,不选择主配置 | ||||
|       dictType: DICT_TYPE.INFRA_BOOLEAN_STRING, | ||||
|       dictClass: 'boolean' | ||||
|     }, | ||||
|     { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|           preIcon="ep:zoom-in" | ||||
|           :title="t('action.add')" | ||||
|           v-hasPermi="['infra:file-config:create']" | ||||
|           @click="handleCreate()" | ||||
|           @click="handleCreate(formRef)" | ||||
|         /> | ||||
|       </template> | ||||
|       <template #actionbtns_default="{ row }"> | ||||
| @@ -53,12 +53,94 @@ | ||||
|   </ContentWrap> | ||||
|   <XModal v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <!-- 对话框(添加 / 修改) --> | ||||
|     <Form | ||||
|       v-if="['create', 'update'].includes(actionType)" | ||||
|       :schema="allSchemas.formSchema" | ||||
|       :rules="rules" | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|     /> | ||||
|       v-if="['create', 'update'].includes(actionType)" | ||||
|       :model="form" | ||||
|       :rules="rules" | ||||
|       label-width="120px" | ||||
|     > | ||||
|       <el-form-item label="配置名" prop="name"> | ||||
|         <el-input v-model="form.name" placeholder="请输入配置名" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="备注" prop="remark"> | ||||
|         <el-input v-model="form.remark" placeholder="请输入备注" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="存储器" prop="storage"> | ||||
|         <el-select v-model="form.storage" placeholder="请选择存储器" :disabled="form.id !== 0"> | ||||
|           <el-option | ||||
|             v-for="dict in getIntDictOptions(DICT_TYPE.INFRA_FILE_STORAGE)" | ||||
|             :key="dict.value" | ||||
|             :label="dict.label" | ||||
|             :value="dict.value" | ||||
|           /> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <!-- DB --> | ||||
|       <!-- Local / FTP / SFTP --> | ||||
|       <el-form-item | ||||
|         v-if="form.storage >= 10 && form.storage <= 12" | ||||
|         label="基础路径" | ||||
|         prop="config.basePath" | ||||
|       > | ||||
|         <el-input v-model="form.config.basePath" placeholder="请输入基础路径" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item | ||||
|         v-if="form.storage >= 11 && form.storage <= 12" | ||||
|         label="主机地址" | ||||
|         prop="config.host" | ||||
|       > | ||||
|         <el-input v-model="form.config.host" placeholder="请输入主机地址" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item | ||||
|         v-if="form.storage >= 11 && form.storage <= 12" | ||||
|         label="主机端口" | ||||
|         prop="config.port" | ||||
|       > | ||||
|         <el-input-number :min="0" v-model="form.config.port" placeholder="请输入主机端口" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item | ||||
|         v-if="form.storage >= 11 && form.storage <= 12" | ||||
|         label="用户名" | ||||
|         prop="config.username" | ||||
|       > | ||||
|         <el-input v-model="form.config.username" placeholder="请输入密码" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item | ||||
|         v-if="form.storage >= 11 && form.storage <= 12" | ||||
|         label="密码" | ||||
|         prop="config.password" | ||||
|       > | ||||
|         <el-input v-model="form.config.password" placeholder="请输入密码" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item v-if="form.storage === 11" label="连接模式" prop="config.mode"> | ||||
|         <el-radio-group v-model="form.config.mode"> | ||||
|           <el-radio key="Active" label="Active">主动模式</el-radio> | ||||
|           <el-radio key="Passive" label="Passive">主动模式</el-radio> | ||||
|         </el-radio-group> | ||||
|       </el-form-item> | ||||
|       <!-- S3 --> | ||||
|       <el-form-item v-if="form.storage === 20" label="节点地址" prop="config.endpoint"> | ||||
|         <el-input v-model="form.config.endpoint" placeholder="请输入节点地址" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item v-if="form.storage === 20" label="存储 bucket" prop="config.bucket"> | ||||
|         <el-input v-model="form.config.bucket" placeholder="请输入 bucket" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item v-if="form.storage === 20" label="accessKey" prop="config.accessKey"> | ||||
|         <el-input v-model="form.config.accessKey" placeholder="请输入 accessKey" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item v-if="form.storage === 20" label="accessSecret" prop="config.accessSecret"> | ||||
|         <el-input v-model="form.config.accessSecret" placeholder="请输入 accessSecret" /> | ||||
|       </el-form-item> | ||||
|       <!-- 通用 --> | ||||
|       <el-form-item v-if="form.storage === 20" label="自定义域名"> | ||||
|         <!-- 无需参数校验,所以去掉 prop --> | ||||
|         <el-input v-model="form.config.domain" placeholder="请输入自定义域名" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item v-else-if="form.storage" label="自定义域名" prop="config.domain"> | ||||
|         <el-input v-model="form.config.domain" placeholder="请输入自定义域名" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <!-- 对话框(详情) --> | ||||
|     <Descriptions | ||||
|       v-if="actionType === 'detail'" | ||||
| @@ -73,7 +155,7 @@ | ||||
|         type="primary" | ||||
|         :title="t('action.save')" | ||||
|         :loading="actionLoading" | ||||
|         @click="submitForm()" | ||||
|         @click="submitForm(formRef)" | ||||
|       /> | ||||
|       <!-- 按钮:关闭 --> | ||||
|       <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" /> | ||||
| @@ -82,15 +164,26 @@ | ||||
| </template> | ||||
| <script setup lang="ts" name="FileConfig"> | ||||
| // 全局相关的 import | ||||
| import { ref, unref } from 'vue' | ||||
| import { reactive, ref } from 'vue' | ||||
| import { | ||||
|   ElForm, | ||||
|   ElFormItem, | ||||
|   FormInstance, | ||||
|   ElSelect, | ||||
|   ElOption, | ||||
|   ElInput, | ||||
|   ElInputNumber, | ||||
|   ElRadio, | ||||
|   ElRadioGroup | ||||
| } from 'element-plus' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { useMessage } from '@/hooks/web/useMessage' | ||||
| import { useVxeGrid } from '@/hooks/web/useVxeGrid' | ||||
| import { VxeGridInstance } from 'vxe-table' | ||||
| import { FormExpose } from '@/components/Form' | ||||
| // 业务相关的 import | ||||
| import * as FileConfigApi from '@/api/infra/fileConfig' | ||||
| import { rules, allSchemas } from './fileConfig.data' | ||||
| import { getIntDictOptions, DICT_TYPE } from '@/utils/dict' | ||||
|  | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| @@ -107,8 +200,30 @@ const actionLoading = ref(false) // 遮罩层 | ||||
| const actionType = ref('') // 操作按钮的类型 | ||||
| const dialogVisible = ref(false) // 是否显示弹出层 | ||||
| const dialogTitle = ref('edit') // 弹出层标题 | ||||
| const formRef = ref<FormExpose>() // 表单 Ref | ||||
| const formRef = ref<FormInstance>() // 表单 Ref | ||||
| const detailData = ref() // 详情 Ref | ||||
| let form = reactive<FileConfigApi.FileConfigVO>({ | ||||
|   id: 0, | ||||
|   name: '', | ||||
|   storage: 0, | ||||
|   master: false, | ||||
|   visible: false, | ||||
|   config: { | ||||
|     basePath: '', | ||||
|     host: '', | ||||
|     port: '', | ||||
|     username: '', | ||||
|     password: '', | ||||
|     mode: '', | ||||
|     endpoint: '', | ||||
|     bucket: '', | ||||
|     accessKey: '', | ||||
|     accessSecret: '', | ||||
|     domain: '' | ||||
|   }, | ||||
|   remark: '', | ||||
|   createTime: '' | ||||
| }) | ||||
| // 设置标题 | ||||
| const setDialogTile = (type: string) => { | ||||
|   dialogTitle.value = t('action.' + type) | ||||
| @@ -117,16 +232,17 @@ const setDialogTile = (type: string) => { | ||||
| } | ||||
|  | ||||
| // 新增操作 | ||||
| const handleCreate = () => { | ||||
| const handleCreate = (formEl: FormInstance | undefined) => { | ||||
|   setDialogTile('create') | ||||
|   formEl?.resetFields() | ||||
| } | ||||
|  | ||||
| // 修改操作 | ||||
| const handleUpdate = async (rowId: number) => { | ||||
|   setDialogTile('update') | ||||
|   // 设置数据 | ||||
|   const res = await FileConfigApi.getFileConfigApi(rowId) | ||||
|   unref(formRef)?.setValues(res) | ||||
|   form = res | ||||
|   setDialogTile('update') | ||||
| } | ||||
|  | ||||
| // 详情操作 | ||||
| @@ -153,20 +269,18 @@ const handleDelete = async (rowId: number) => { | ||||
| } | ||||
|  | ||||
| // 提交按钮 | ||||
| const submitForm = async () => { | ||||
|   const elForm = unref(formRef)?.getElFormRef() | ||||
|   if (!elForm) return | ||||
|   elForm.validate(async (valid) => { | ||||
| const submitForm = async (formEl: FormInstance | undefined) => { | ||||
|   if (!formEl) return | ||||
|   formEl.validate(async (valid) => { | ||||
|     if (valid) { | ||||
|       actionLoading.value = true | ||||
|       // 提交请求 | ||||
|       try { | ||||
|         const data = unref(formRef)?.formModel as FileConfigApi.FileConfigVO | ||||
|         if (actionType.value === 'create') { | ||||
|           await FileConfigApi.createFileConfigApi(data) | ||||
|           await FileConfigApi.createFileConfigApi(form) | ||||
|           message.success(t('common.createSuccess')) | ||||
|         } else { | ||||
|           await FileConfigApi.updateFileConfigApi(data) | ||||
|           await FileConfigApi.updateFileConfigApi(form) | ||||
|           message.success(t('common.updateSuccess')) | ||||
|         } | ||||
|         dialogVisible.value = false | ||||
|   | ||||
| @@ -100,7 +100,9 @@ | ||||
|       <template #monitorTimeout="{ row }"> | ||||
|         <span>{{ row.monitorTimeout > 0 ? row.monitorTimeout + ' 毫秒' : '未开启' }}</span> | ||||
|       </template> | ||||
|       <!-- TODO @星语:有个【后续执行时间】字段:2022-11-26 23:03:16; 2022-11-26 23:03:17; 2022-11-26 23:03:18; 2022-11-26 23:03:19; 2022-11-26 23:03:20 --> | ||||
|       <template #nextTimes> | ||||
|         <span>{{ Array.from(nextTimes, (x) => parseTime(x)).join('; ') }}</span> | ||||
|       </template> | ||||
|     </Descriptions> | ||||
|     <!-- 操作按钮 --> | ||||
|     <template #footer> | ||||
| @@ -151,6 +153,7 @@ const dialogTitle = ref('edit') // 弹出层标题 | ||||
| const formRef = ref<FormExpose>() // 表单 Ref | ||||
| const detailRef = ref() // 详情 Ref | ||||
| const cronExpression = ref('') | ||||
| const nextTimes = ref([]) | ||||
| const shortcuts = ref([ | ||||
|   { | ||||
|     text: '每天8点和12点 (自定义追加)', | ||||
| @@ -169,10 +172,12 @@ const handleCreate = () => { | ||||
|   cronExpression.value = '' | ||||
|   setDialogTile('create') | ||||
| } | ||||
|  | ||||
| // 导出操作 | ||||
| const handleExport = async () => { | ||||
|   await exportList(xGrid, '定时任务.xls') | ||||
| } | ||||
|  | ||||
| // 修改操作 | ||||
| const handleUpdate = async (rowId: number) => { | ||||
|   setDialogTile('update') | ||||
| @@ -187,8 +192,57 @@ const handleDetail = async (rowId: number) => { | ||||
|   // 设置数据 | ||||
|   const res = await JobApi.getJobApi(rowId) | ||||
|   detailRef.value = res | ||||
|   // 后续执行时长 | ||||
|   const jobNextTime = await JobApi.getJobNextTimesApi(rowId) | ||||
|   nextTimes.value = jobNextTime | ||||
|   setDialogTile('detail') | ||||
| } | ||||
|  | ||||
| const parseTime = (time) => { | ||||
|   if (!time) { | ||||
|     return null | ||||
|   } | ||||
|   const format = '{y}-{m}-{d} {h}:{i}:{s}' | ||||
|   let date | ||||
|   if (typeof time === 'object') { | ||||
|     date = time | ||||
|   } else { | ||||
|     if (typeof time === 'string' && /^[0-9]+$/.test(time)) { | ||||
|       time = parseInt(time) | ||||
|     } else if (typeof time === 'string') { | ||||
|       time = time | ||||
|         .replace(new RegExp(/-/gm), '/') | ||||
|         .replace('T', ' ') | ||||
|         .replace(new RegExp(/\.[\d]{3}/gm), '') | ||||
|     } | ||||
|     if (typeof time === 'number' && time.toString().length === 10) { | ||||
|       time = time * 1000 | ||||
|     } | ||||
|     date = new Date(time) | ||||
|   } | ||||
|   const formatObj = { | ||||
|     y: date.getFullYear(), | ||||
|     m: date.getMonth() + 1, | ||||
|     d: date.getDate(), | ||||
|     h: date.getHours(), | ||||
|     i: date.getMinutes(), | ||||
|     s: date.getSeconds(), | ||||
|     a: date.getDay() | ||||
|   } | ||||
|   const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { | ||||
|     let value = formatObj[key] | ||||
|     // Note: getDay() returns 0 on Sunday | ||||
|     if (key === 'a') { | ||||
|       return ['日', '一', '二', '三', '四', '五', '六'][value] | ||||
|     } | ||||
|     if (result.length > 0 && value < 10) { | ||||
|       value = '0' + value | ||||
|     } | ||||
|     return value || 0 | ||||
|   }) | ||||
|   return time_str | ||||
| } | ||||
|  | ||||
| // 删除操作 | ||||
| const handleDelete = async (rowId: number) => { | ||||
|   await deleteData(xGrid, rowId) | ||||
|   | ||||
| @@ -48,6 +48,12 @@ const crudSchemas = reactive<VxeCrudSchema>({ | ||||
|       title: 'CRON 表达式', | ||||
|       field: 'cronExpression' | ||||
|     }, | ||||
|     { | ||||
|       title: '后续执行时间', | ||||
|       field: 'nextTimes', | ||||
|       isTable: false, | ||||
|       isForm: false | ||||
|     }, | ||||
|     { | ||||
|       title: '重试次数', | ||||
|       field: 'retryCount', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 xingyu
					xingyu