升级指南
v1.2.2-beta
优化UploadFiles多文件上传组件, 简化使用方式并修复一些已知问题。
上传中:
上传完毕:
vue
<UploadFiles
v-model:file-list="fileList" // file-list
multiple
:limit="5"
:file-size="3"
width="300px"
height="200px"
@change="fileChange"
:accept="'.xlsx,.xls,.doc,.docx'"
tip="支持上传 .xlsx, .xls, .docx, .doc, .pdf 格式的文件,单个文件大小不能超过 3M"
>
<template #tip> 支持上传 .xlsx, .xls, .docx, .doc, .pdf 格式的文件,单个文件大小不能超过 3M </template>
</UploadFiles>
<script setup lang="ts">
...
const fileList = ref<UploadUserFile[]>();
...
// 接收父组件传过来的参数
const acceptParams = (params: View.DefaultParams) => {
paramsProps.value = params;
visible.value = true;
fileList.value = params.row.url // 入参赋值,回显
? [
{
name: getFileNameFromUrl(params.row.url),
url: params.row.url
}
]
: [];
fileUrls.value = params.row.url;
};
...
</script>
vue
<UploadFiles
v-model:modelValue="fileUrls" // 使用modelValue
multiple
:limit="5"
:file-size="3"
@change="fileChange"
accept=".xlsx,.xls,.docx,.doc,.pdf"
tip="支持上传 .xlsx, .xls, .docx, .doc, .pdf 格式的文件,单个文件大小不能超过 3M" // [可选] 使用tip自定义显示信息,如不输入也会生成默认值,效果与所示话术一致
>
</UploadFiles>
<script setup lang="ts">
...
const fileUrls = ref<string[]>([]);
...
// 接收父组件传过来的参数
const acceptParams = (params: View.DefaultParams) => {
paramsProps.value = params;
visible.value = true;
fileUrls.value = params.row.url; // 入参赋值,回显
};
// 提交数据(新增/编辑)
const ruleFormRef = ref<InstanceType<typeof ElForm>>();
const handleSubmit = () => {
ruleFormRef.value!.validate(async valid => {
if (!valid) return;
try {
const urlArr = fileUrls.value; // 提交时获取值。如果接受参数是数组,无需处理
paramsProps.value.row.url = urlArr[0];
await paramsProps.value.api!(paramsProps.value.row);
ElMessage.success({ message: `${paramsProps.value.title}成功!` });
paramsProps.value.getTableList!();
visible.value = false;
} catch (error) {
console.log(error);
}
});
};
</script>
v1.2.1-beta
- 新增Liquibase管理数据库脚本
yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/sz_admin_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: Yanfa2023@
hikari:
#连接池名
pool-name: HikariCP
#最小空闲连接数
minimum-idle: 5
# 空闲连接存活最大时间,默认10分钟
idle-timeout: 600000
# 连接池最大连接数,默认是10
maximum-pool-size: 10
# 此属性控制从池返回的连接的默认自动提交行为,默认值:true
auto-commit: true
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
max-lifetime: 1800000
# 数据库连接超时时间,默认30秒
connection-timeout: 30000
# 连接测试query
connection-test-query: SELECT 1
# -- 切换数据库脚本管理工具为 liquibase --
liquibase: #
change-log: classpath:db/changelog/changelog-master.xml #
enabled: true #
IMPORTANT
结构变动:
shell
└─resources
├─db
│ ├─business
│ │ V0.1__README_DDL.sql
│ ├─changelog # Liquibase脚本目录
│ │ │ changelog-master.xml # changelog主配置
│ │ ├─business # 业务脚本
│ │ │ └─1.0.0 # 版本号
│ │ │ 000_demo.sql #//
│ │ └─framework # 框架脚本
│ │ ├─1.1.0-beta # 版本号
│ │ │ 001_system.sql # sql脚本
│ │ └─1.2.0-beta # 版本号
│ │ 001_sys_message.sql # sql脚本
│ │
│ └─framework
│ V1.1__20230509_Init_DDL.sql
│ V1.2__20240511_Update_DDL.sql
│ V1.3__20240530_Update_DDL.sql
│ V1.4__20240603_Update_DDL.sql
...
│ V2.6__20250422_Update_DDL.sql
- 关闭Flyway脚本管理工具(Flyway将于v1.3.0-beta版本弃用)
yml
flyway:
framework: # 框架迁移脚本管理
enabled: true #
enabled: false #
locations: classpath:/db/framework
baseline-on-migrate: true
baseline-version: 1
table: t_db_version
validate-on-migrate: true
business: # 业务迁移脚本管理
enabled: true #
enabled: false #
locations: classpath:db/business
baseline-on-migrate: true
baseline-version: 1
table: t_db_version_business
validate-on-migrate: true
v1.2.0-beta
代码生成忽略表前缀功能
ymlsz: # 生成工具 generator: path: # 前端项目地址 web: # 后端项目地址,默认自动检测springboot项目路径,无需配置。 api: E://code//Gitlab//sz-framework//sz-admin # 模块名,指定代码生成的模块 module-name: sz-service service-name: sz-service-admin global: author: sz-admin packages: com.sz.admin # 忽略的表前缀。若启用此配置,以表名 `t_db_version` 为例,生成的代码和实体类将自动去除前缀 `t_`,仅使用 `db_version` 或 `DbVersion`。 ignore-table-prefix: # enabled: true # prefixes: # - t_ #
v1.1.0-beta
升级Eslint9
删除 .eslintignore、.eslintrc.cjs,切换Eslint配置为eslint.config.js
遵循Eslint和TypeScript最佳实践,避免使用namespace,切换至type。
切换目录
/api/interface
至/api/types
下面以
/api/interface/captcha.ts
为例:ts// 登录模块 export namespace ICaptcha { export interface Info { bigImageBase64: string; bigWidth: number; bigHeight: number; smallImageBase64: string; smallWidth: number; smallHeight: number; requestId: string; posY: number; secretKey: string; } export interface VerifyImageParams { requestId: string; moveEncrypted: string; } }
ts// 登录模块 export type CaptchaInfo = { bigImageBase64: string; bigWidth: number; bigHeight: number; smallImageBase64: string; smallWidth: number; smallHeight: number; requestId: string; posY: number; secretKey: string; }; export type CaptchaVerifyImageParams = { requestId: string; moveEncrypted: string; }
新增
useDictOptions
hook,用于简化optionsStore.getDictOptions('dynamic_user_options')
写法tsimport { useOptionsStore } from '@/stores/modules/options'; import { useDictOptions } from "@/hooks/useDictOptions"; // 先声明store const optionsStore = useOptionsStore(); // 使用时 // 表格配置项 const columns: ColumnProps<SysTempFileRow>[] = [ { type: 'selection', width: 80 }, { prop: 'id', label: '模板标识', width: 120 }, { prop: 'tempName', label: '模版名' }, { prop: 'url', label: '文件', width: 120 }, { prop: 'remark', label: '备注' }, { prop: 'history', label: '历史' }, { prop: 'createId', label: '创建人', tag: true, enum: optionsStore.getDictOptions('dynamic_user_options'), enum: useDictOptions('dynamic_user_options'), fieldNames: { label: 'codeName', value: 'id', tagType: 'callbackShowStyle' } }, { prop: 'createTime', label: '创建时间' }, { prop: 'updateId', label: '更新人', tag: true, enum: optionsStore.getDictOptions('dynamic_user_options'), enum: useDictOptions('dynamic_user_options'), fieldNames: { label: 'codeName', value: 'id', tagType: 'callbackShowStyle' } }, { prop: 'updateTime', label: '更新时间' }, { prop: 'operation', label: '操作', width: 250, fixed: 'right' } ]
ts<template> <el-dialog v-model="visible" :title="`${paramsProps.title}`" :destroy-on-close="true" width="580px" draggable> <el-form ref="ruleFormRef" label-width="140px" label-suffix=" :" :rules="rules" :model="paramsProps.row" @submit.enter.prevent="handleSubmit" > ... <el-form-item label="讲师区分类型" prop="teacherCommonType"> <el-select v-model="paramsProps.row.teacherCommonType" clearable placeholder="请选择讲师区分类型"> <el-option v-for="item in optionsStore.getDictOptions('account_status')" v-for="item in accountStatusOption" :key="item.id" :label="item.codeName" :value="Number(item.id)" /> </el-select> </el-form-item> ... </el-form> <template #footer> <el-button @click="visible = false"> 取消 </el-button> <el-button type="primary" @click="handleSubmit"> 确定 </el-button> </template> </el-dialog> </template> <script setup lang="ts"> import { ref, reactive } from 'vue'; import { type ElForm, ElMessage } from 'element-plus'; import { useDictOptions } from '@/hooks/useDictOptions'; defineOptions({ name: 'TeacherStatisticsForm' }); const optionsStore = useOptionsStore(); const accountStatusOption = useDictOptions('account_status'); ... defineExpose({ acceptParams }); </script> <style scoped lang="scss"></style>
(sass)官方已经不推荐使用
@import
规则来导入 SCSS 文件,而是提倡使用新的@use
规则vue<style scoped lang="scss"> @import './index.scss'; // [!code --] @use './index'; // [!code ++] </style>
升级sa-token 1.40.0 至 1.41.0,官方更换了sa-session的序列化对象结构,因此对redis序列化可能失效,导致账户登录失败。
解决方案:清空redis中的
Authorization
key下的缓存对象,重新登陆即可!