mirror of
https://github.com/1024-lab/smart-admin.git
synced 2025-09-19 18:45:20 +00:00
【v3.3.0】 1、uniapp 首页菜单功能区多平台适配;2、菜单组件路径说明;3、长时间不在线自动返回登录页;4、标签页 tab 为圆角;5、升级 sa token 到 1.37.0;6、代码生成表单弹窗 关闭事件;7、接口操作日志@OperateLogAspect 对文件的处理;
This commit is contained in:
@@ -27,6 +27,7 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -238,6 +239,7 @@ public abstract class OperateLogAspect {
|
||||
if (arg instanceof HttpServletRequest
|
||||
|| arg instanceof HttpServletResponse
|
||||
|| arg instanceof ModelAndView
|
||||
|| arg instanceof MultipartFile
|
||||
|| arg instanceof BindResult) {
|
||||
continue;
|
||||
}
|
||||
|
@@ -6,230 +6,234 @@
|
||||
* @Copyright ${basic.copyright}
|
||||
-->
|
||||
<template>
|
||||
<a-$!{insertAndUpdate.pageType}
|
||||
<a-$!{insertAndUpdate.pageType}
|
||||
:title="form.$!{primaryKeyFieldName} ? '编辑' : '添加'"
|
||||
width="$!{insertAndUpdate.width}"
|
||||
:open="visibleFlag"
|
||||
#if($!{insertAndUpdate.pageType} == 'drawer')
|
||||
@close="onClose"
|
||||
#else
|
||||
@cancel="onClose"
|
||||
#end
|
||||
:maskClosable="false"
|
||||
:destroyOnClose="true"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" >
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" >
|
||||
#if($insertAndUpdate.countPerLine == 1)
|
||||
<a-row>
|
||||
#foreach ($field in $formFields)
|
||||
#if($field.frontComponent == "Input")
|
||||
<a-row>
|
||||
#foreach ($field in $formFields)
|
||||
#if($field.frontComponent == "Input")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-input style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
<a-input style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "InputNumber")
|
||||
#end
|
||||
#if($field.frontComponent == "InputNumber")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-input-number style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
<a-input-number style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Textarea")
|
||||
#end
|
||||
#if($field.frontComponent == "Textarea")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-textarea style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
<a-textarea style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "BooleanSelect")
|
||||
#end
|
||||
#if($field.frontComponent == "BooleanSelect")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<BooleanSelect v-model:value="form.${field.fieldName}" style="width: 100%" />
|
||||
<BooleanSelect v-model:value="form.${field.fieldName}" style="width: 100%" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "SmartEnumSelect")
|
||||
#end
|
||||
#if($field.frontComponent == "SmartEnumSelect")
|
||||
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
|
||||
<SmartEnumSelect width="100%" v-model:value="form.${field.fieldName}" enumName="$!{field.upperUnderscoreEnum}" placeholder="$codeGeneratorTool.removeEnumDesc($!{field.label})"/>
|
||||
<SmartEnumSelect width="100%" v-model:value="form.${field.fieldName}" enumName="$!{field.upperUnderscoreEnum}" placeholder="$codeGeneratorTool.removeEnumDesc($!{field.label})"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "DictSelect")
|
||||
#end
|
||||
#if($field.frontComponent == "DictSelect")
|
||||
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
|
||||
<DictSelect width="100%" v-model:value="form.${field.fieldName}" keyCode="$!{field.dict}" placeholder="$!{field.label}"/>
|
||||
<DictSelect width="100%" v-model:value="form.${field.fieldName}" keyCode="$!{field.dict}" placeholder="$!{field.label}"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Date")
|
||||
#end
|
||||
#if($field.frontComponent == "Date")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-date-picker valueFormat="YYYY-MM-DD" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}"/>
|
||||
<a-date-picker valueFormat="YYYY-MM-DD" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "DateTime")
|
||||
#end
|
||||
#if($field.frontComponent == "DateTime")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-date-picker show-time valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}" />
|
||||
<a-date-picker show-time valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Upload")
|
||||
#end
|
||||
#if($field.frontComponent == "Upload")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<FileUpload
|
||||
:defaultFileList="form.$!{field.fieldName}"
|
||||
:folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
|
||||
buttonText="上传 $!{field.label}"
|
||||
listType="text"
|
||||
@change="e => form.$!{field.fieldName} = e"
|
||||
/>
|
||||
<FileUpload
|
||||
:defaultFileList="form.$!{field.fieldName}"
|
||||
:folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
|
||||
buttonText="上传 $!{field.label}"
|
||||
listType="text"
|
||||
@change="e => form.$!{field.fieldName} = e"
|
||||
/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#end
|
||||
</a-row>
|
||||
#end
|
||||
#end
|
||||
</a-row>
|
||||
#end
|
||||
|
||||
#if($insertAndUpdate.countPerLine > 1)
|
||||
<a-row>
|
||||
#set($span=24 / $!insertAndUpdate.countPerLine )
|
||||
#foreach ($field in $formFields)
|
||||
<a-col :span="$!{span}">
|
||||
#if($field.frontComponent == "Input")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-input style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "InputNumber")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-input-number style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Textarea")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-textarea style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "BooleanSelect")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<BooleanSelect v-model:value="form.${field.fieldName}" style="width: 100%" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "SmartEnumSelect")
|
||||
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
|
||||
<SmartEnumSelect width="100%" v-model:value="form.${field.fieldName}" enumName="$!{field.upperUnderscoreEnum}" placeholder="$codeGeneratorTool.removeEnumDesc($!{field.label})"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "DictSelect")
|
||||
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
|
||||
<DictSelect width="100%" v-model:value="form.${field.fieldName}" keyCode="$!{field.dict}" placeholder="$!{field.label}"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Date")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-date-picker valueFormat="YYYY-MM-DD" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "DateTime")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-date-picker show-time valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Upload")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<FileUpload
|
||||
:defaultFileList="form.$!{field.fieldName}"
|
||||
:folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
|
||||
buttonText="上传 $!{field.label}"
|
||||
listType="text"
|
||||
@change="e => form.$!{field.fieldName} = e"
|
||||
/>
|
||||
</a-form-item>
|
||||
#end
|
||||
</a-col>
|
||||
#end
|
||||
</a-row>
|
||||
<a-row>
|
||||
#set($span=24 / $!insertAndUpdate.countPerLine )
|
||||
#foreach ($field in $formFields)
|
||||
<a-col :span="$!{span}">
|
||||
#if($field.frontComponent == "Input")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-input style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "InputNumber")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-input-number style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Textarea")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-textarea style="width: 100%" v-model:value="form.${field.fieldName}" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "BooleanSelect")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<BooleanSelect v-model:value="form.${field.fieldName}" style="width: 100%" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "SmartEnumSelect")
|
||||
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
|
||||
<SmartEnumSelect width="100%" v-model:value="form.${field.fieldName}" enumName="$!{field.upperUnderscoreEnum}" placeholder="$codeGeneratorTool.removeEnumDesc($!{field.label})"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "DictSelect")
|
||||
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
|
||||
<DictSelect width="100%" v-model:value="form.${field.fieldName}" keyCode="$!{field.dict}" placeholder="$!{field.label}"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Date")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-date-picker valueFormat="YYYY-MM-DD" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}"/>
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "DateTime")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<a-date-picker show-time valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.$!{field.fieldName}" style="width: 100%" placeholder="$!{field.label}" />
|
||||
</a-form-item>
|
||||
#end
|
||||
#if($field.frontComponent == "Upload")
|
||||
<a-form-item label="$!{field.label}" name="${field.fieldName}">
|
||||
<FileUpload
|
||||
:defaultFileList="form.$!{field.fieldName}"
|
||||
:folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
|
||||
buttonText="上传 $!{field.label}"
|
||||
listType="text"
|
||||
@change="e => form.$!{field.fieldName} = e"
|
||||
/>
|
||||
</a-form-item>
|
||||
#end
|
||||
</a-col>
|
||||
#end
|
||||
</a-row>
|
||||
#end
|
||||
</a-form>
|
||||
</a-form>
|
||||
|
||||
<template #footer>
|
||||
<a-space>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit">保存</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-$!{insertAndUpdate.pageType}>
|
||||
<template #footer>
|
||||
<a-space>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit">保存</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-$!{insertAndUpdate.pageType}>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, nextTick } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { $!{name.lowerCamel}Api } from '/@/api/business/$!{name.lowerHyphenCamel}/$!{name.lowerHyphenCamel}-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
#foreach ($import in $frontImportList)
|
||||
$!{import}
|
||||
#end
|
||||
import { reactive, ref, nextTick } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { $!{name.lowerCamel}Api } from '/@/api/business/$!{name.lowerHyphenCamel}/$!{name.lowerHyphenCamel}-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
#foreach ($import in $frontImportList)
|
||||
$!{import}
|
||||
#end
|
||||
|
||||
// ------------------------ 事件 ------------------------
|
||||
// ------------------------ 事件 ------------------------
|
||||
|
||||
const emits = defineEmits(['reloadList']);
|
||||
const emits = defineEmits(['reloadList']);
|
||||
|
||||
// ------------------------ 显示与隐藏 ------------------------
|
||||
// 是否显示
|
||||
const visibleFlag = ref(false);
|
||||
// ------------------------ 显示与隐藏 ------------------------
|
||||
// 是否显示
|
||||
const visibleFlag = ref(false);
|
||||
|
||||
function show(rowData) {
|
||||
Object.assign(form, formDefault);
|
||||
if (rowData && !_.isEmpty(rowData)) {
|
||||
Object.assign(form, rowData);
|
||||
}
|
||||
visibleFlag.value = true;
|
||||
nextTick(() => {
|
||||
formRef.value.clearValidate();
|
||||
});
|
||||
function show(rowData) {
|
||||
Object.assign(form, formDefault);
|
||||
if (rowData && !_.isEmpty(rowData)) {
|
||||
Object.assign(form, rowData);
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
Object.assign(form, formDefault);
|
||||
visibleFlag.value = false;
|
||||
}
|
||||
|
||||
// ------------------------ 表单 ------------------------
|
||||
|
||||
// 组件ref
|
||||
const formRef = ref();
|
||||
|
||||
const formDefault = {
|
||||
$!{primaryKeyFieldName}: undefined,
|
||||
#foreach ($field in $formFields)
|
||||
$!{field.fieldName}: undefined, //$!{field.label}
|
||||
#end
|
||||
};
|
||||
|
||||
let form = reactive({ ...formDefault });
|
||||
|
||||
const rules = {
|
||||
#foreach ($field in $formFields)
|
||||
#if($field.requiredFlag)
|
||||
$!{field.fieldName}: [{ required: true, message: '$!{field.label} 必填' }],
|
||||
#end
|
||||
#end
|
||||
};
|
||||
|
||||
// 点击确定,验证表单
|
||||
async function onSubmit() {
|
||||
try {
|
||||
await formRef.value.validateFields();
|
||||
save();
|
||||
} catch (err) {
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
}
|
||||
}
|
||||
|
||||
// 新建、编辑API
|
||||
async function save() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
if (form.$!{primaryKeyFieldName}) {
|
||||
await $!{name.lowerCamel}Api.update(form);
|
||||
} else {
|
||||
await $!{name.lowerCamel}Api.add(form);
|
||||
}
|
||||
message.success('操作成功');
|
||||
emits('reloadList');
|
||||
onClose();
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
visibleFlag.value = true;
|
||||
nextTick(() => {
|
||||
formRef.value.clearValidate();
|
||||
});
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
Object.assign(form, formDefault);
|
||||
visibleFlag.value = false;
|
||||
}
|
||||
|
||||
// ------------------------ 表单 ------------------------
|
||||
|
||||
// 组件ref
|
||||
const formRef = ref();
|
||||
|
||||
const formDefault = {
|
||||
$!{primaryKeyFieldName}: undefined,
|
||||
#foreach ($field in $formFields)
|
||||
$!{field.fieldName}: undefined, //$!{field.label}
|
||||
#end
|
||||
};
|
||||
|
||||
let form = reactive({ ...formDefault });
|
||||
|
||||
const rules = {
|
||||
#foreach ($field in $formFields)
|
||||
#if($field.requiredFlag)
|
||||
$!{field.fieldName}: [{ required: true, message: '$!{field.label} 必填' }],
|
||||
#end
|
||||
#end
|
||||
};
|
||||
|
||||
// 点击确定,验证表单
|
||||
async function onSubmit() {
|
||||
try {
|
||||
await formRef.value.validateFields();
|
||||
save();
|
||||
} catch (err) {
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
}
|
||||
}
|
||||
|
||||
// 新建、编辑API
|
||||
async function save() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
if (form.$!{primaryKeyFieldName}) {
|
||||
await $!{name.lowerCamel}Api.update(form);
|
||||
} else {
|
||||
await $!{name.lowerCamel}Api.add(form);
|
||||
}
|
||||
message.success('操作成功');
|
||||
emits('reloadList');
|
||||
onClose();
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
</script>
|
||||
|
@@ -3,7 +3,7 @@ spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: Zhuoda#1024lab
|
||||
password: Zhuoda1024lab
|
||||
initial-size: 10
|
||||
min-idle: 10
|
||||
max-active: 100
|
||||
|
@@ -3,7 +3,7 @@ spring:
|
||||
datasource:
|
||||
url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: Java@1024
|
||||
password: Zhuoda1024lab
|
||||
initial-size: 2
|
||||
min-idle: 2
|
||||
max-active: 10
|
||||
|
Reference in New Issue
Block a user