Skip to content

升级指南

v1.2.2-beta

  • 优化UploadFiles多文件上传组件, 简化使用方式并修复一些已知问题。

    上传中:

    image-20250528172638236

    上传完毕:

    image-20250528173006129

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

  • 代码生成忽略表前缀功能

    yml
    sz:
      # 生成工具
      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

    1. 删除 .eslintignore、.eslintrc.cjs,切换Eslint配置为eslint.config.js

    2. 遵循Eslint和TypeScript最佳实践,避免使用namespace,切换至type。

    3. 切换目录/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;
    }
  • 新增useDictOptionshook,用于简化optionsStore.getDictOptions('dynamic_user_options')写法

    ts
    import { 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中的Authorizationkey下的缓存对象,重新登陆即可!