Commit 7641998c3f30cae4b369eaa232e7c5e1741de264

Authored by 芋道源码
Committed by Gitee
2 parents 3a44eacd 3d0cb520

!227 fix: vue2代码生成模板error && 添加vue3代码生成预览版

Merge pull request !227 from xingyu/master
Showing 53 changed files with 548 additions and 122 deletions
README.md
... ... @@ -189,16 +189,16 @@ ps:核心功能已经实现,正在对接微信小程序中...
189 189  
190 190 ### Vue3 前端
191 191  
192   -| 框架 | 说明 | 版本 |
193   -|----------------------------------------------------------------------|---------------------|--------|
194   -| [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.37 |
195   -| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 3.0.2 |
196   -| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.9 |
197   -| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.7.4 |
198   -| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.16 |
199   -| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.1.10 |
200   -| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架| 3.5.6 |
201   -| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1 |
  192 +| 框架 | 说明 | 版本 |
  193 +|----------------------------------------------------------------------|------------------|--------|
  194 +| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.37 |
  195 +| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 3.0.3 |
  196 +| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.9 |
  197 +| [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.7.4 |
  198 +| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.17 |
  199 +| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.1.10 |
  200 +| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |
  201 +| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1 |
202 202  
203 203 ## 🐷 演示图
204 204  
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java
... ... @@ -98,10 +98,10 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
98 98 if (values!= null && values.length >0 && values[0] != null && values[1] != null) {
99 99 return (LambdaQueryWrapperX<T>) super.between(column, values[0], values[1]);
100 100 }
101   - if (values != null && values[0] != null) {
  101 + if (values != null && values.length >0 && values[0] != null) {
102 102 return (LambdaQueryWrapperX<T>) ge(column, values[0]);
103 103 }
104   - if (values != null && values[1] != null) {
  104 + if (values != null && values.length >0 && values[1] != null) {
105 105 return (LambdaQueryWrapperX<T>) le(column, values[2]);
106 106 }
107 107 return this;
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/QueryWrapperX.java
... ... @@ -95,13 +95,13 @@ public class QueryWrapperX&lt;T&gt; extends QueryWrapper&lt;T&gt; {
95 95 }
96 96  
97 97 public QueryWrapperX<T> betweenIfPresent(String column, Object[] values) {
98   - if (values!= null && values[0] != null && values[1] != null) {
  98 + if (values!= null && values.length != 0 && values[0] != null && values[1] != null) {
99 99 return (QueryWrapperX<T>) super.between(column, values[0], values[1]);
100 100 }
101   - if (values!= null && values[0] != null) {
  101 + if (values!= null && values.length != 0 && values[0] != null) {
102 102 return (QueryWrapperX<T>) ge(column, values[0]);
103 103 }
104   - if (values!= null && values[1] != null) {
  104 + if (values!= null && values.length != 0 && values[1] != null) {
105 105 return (QueryWrapperX<T>) le(column, values[1]);
106 106 }
107 107 return this;
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
... ... @@ -79,11 +79,20 @@ public class CodegenEngine {
79 79 javaModuleImplTestFilePath("service/${table.businessName}/${table.className}ServiceImplTest"))
80 80 // Java module-api Main
81 81 .put(javaTemplatePath("enums/errorcode"), javaModuleApiMainFilePath("enums/ErrorCodeConstants_手动操作"))
82   - // Vue
  82 + // Vue2
83 83 .put(vueTemplatePath("views/index.vue"),
84 84 vueFilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
85 85 .put(vueTemplatePath("api/api.js"),
86 86 vueFilePath("api/${table.moduleName}/${classNameVar}.js"))
  87 + // Vue3
  88 + .put(vue3TemplatePath("views/index.vue"),
  89 + vue3FilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
  90 + .put(vue3TemplatePath("views/data.ts"),
  91 + vue3FilePath("views/${table.moduleName}/${classNameVar}/${classNameVar}.data.ts"))
  92 + .put(vue3TemplatePath("api/api.ts"),
  93 + vue3FilePath("api/${table.moduleName}/${classNameVar}/index.ts"))
  94 + .put(vue3TemplatePath("api/types.ts"),
  95 + vue3FilePath("api/${table.moduleName}/${classNameVar}/types.ts"))
87 96 // SQL
88 97 .put("codegen/sql/sql.vm", "sql/sql.sql")
89 98 .put("codegen/sql/h2.vm", "sql/h2.sql")
... ... @@ -228,5 +237,12 @@ public class CodegenEngine {
228 237 return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录
229 238 "src/" + path;
230 239 }
  240 + private static String vue3TemplatePath(String path) {
  241 + return "codegen/vue3/" + path + ".vm";
  242 + }
231 243  
  244 + private static String vue3FilePath(String path) {
  245 + return "yudao-ui-${sceneEnum.basePackage}-vue3/" + // 顶级目录
  246 + "src/" + path;
  247 + }
232 248 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm
... ... @@ -15,9 +15,6 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
15 15 #end
16 16 ## 字段模板
17 17 #macro(columnTpl $prefix $prefixStr)
18   -#if (${column.javaType} == "Date")## 时间类型
19   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
20   -#end
21 18 @ApiModelProperty(value = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
22 19 private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
23 20 #end
... ... @@ -27,12 +24,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
27 24 public class ${sceneEnum.prefixClass}${table.className}ExportReqVO {
28 25  
29 26 #foreach ($column in $columns)
30   -#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
31 27 #if (${column.listOperation})##查询操作
32 28 #if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候
33   - #columnTpl('begin', '开始')
34   -
35   - #columnTpl('end', '结束')
  29 + @ApiModelProperty(value = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + private ${column.javaType}[] ${column.javaField};
36 32 #else##情况二,非 Between 的时间
37 33 #columnTpl('', '')
38 34 #end
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm
... ... @@ -15,9 +15,6 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
15 15 #end
16 16 ## 字段模板
17 17 #macro(columnTpl $prefix $prefixStr)
18   -#if (${column.javaType} == "Date")## 时间类型
19   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
20   -#end
21 18 @ApiModelProperty(value = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
22 19 private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
23 20 #end
... ... @@ -29,12 +26,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
29 26 public class ${sceneEnum.prefixClass}${table.className}PageReqVO extends PageParam {
30 27  
31 28 #foreach ($column in $columns)
32   -#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
33 29 #if (${column.listOperation})##查询操作
34 30 #if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候
35   - #columnTpl('begin', '开始')
36   -
37   - #columnTpl('end', '结束')
  31 + @ApiModelProperty(value = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
  32 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  33 + private ${column.javaType}[] ${column.javaField};
38 34 #else##情况二,非 Between 的时间
39 35 #columnTpl('', '')
40 36 #end
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/views/index.vue.vm
... ... @@ -219,22 +219,16 @@ export default {
219 219 title: "",
220 220 // 是否显示弹出层
221 221 open: false,
222   - #foreach ($column in $columns)## 时间范围
223   - #if ($column.listOperation)
224   - #if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
225   - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
226   - dateRange${AttrName}: [],
227   - #end
228   - #end
229   - #end
230 222 // 查询参数
231 223 queryParams: {
232 224 pageNo: 1,
233 225 pageSize: 10,
234 226 #foreach ($column in $columns)
235   - #if ($column.listOperation && $column.listOperationCondition != 'BETWEEN')
  227 + #if ($column.listOperation)
  228 + #if ($column.listOperationCondition != 'BETWEEN')
236 229 $column.javaField: null,
237   - #else if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
  230 + #end
  231 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
238 232 $column.javaField: [],
239 233 #end
240 234 #end
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm 0 → 100644
  1 +import { useAxios } from '@/hooks/web/useAxios'
  2 +import { ${simpleClassName}VO,${simpleClassName}PageReqVO,${simpleClassName}ExcelReqVO } from './types'
  3 +
  4 +const request = useAxios()
  5 +
  6 +#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
  7 +// 查询${table.classComment}列表
  8 +export const getPostPageApi = async (params: ${simpleClassName}PageReqVO) => {
  9 + return await request.get({ url: '${baseURL}/page', params })
  10 +}
  11 +
  12 +// 查询${table.classComment}详情
  13 +export const getPostApi = async (id: number) => {
  14 + return await request.get({ url: '${baseURL}/get?id=' + id })
  15 +}
  16 +
  17 +// 新增${table.classComment}
  18 +export const createPostApi = async (data: ${simpleClassName}VO) => {
  19 + return await request.post({ url: '${baseURL}/create', data })
  20 +}
  21 +
  22 +// 修改${table.classComment}
  23 +export const updatePostApi = async (data: ${simpleClassName}VO) => {
  24 + return await request.put({ url: '${baseURL}/update', data })
  25 +}
  26 +
  27 +// 删除${table.classComment}
  28 +export const deletePostApi = async (id: number) => {
  29 + return await request.delete({ url: '${baseURL}/delete?id=' + id })
  30 +}
  31 +
  32 +// 导出${table.classComment} Excel
  33 +export const exportPostApi = async (params: ${simpleClassName}ExcelReqVO) => {
  34 + return await request.download({ url: '${baseURL}/export-excel', params })
  35 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/types.ts.vm 0 → 100644
  1 +export type ${simpleClassName}VO = {
  2 +#foreach ($column in $columns)
  3 +#if ($column.createOperation || $column.updateOperation)
  4 +#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
  5 + ${column.javaField}: number
  6 +#else
  7 + ${column.javaField}: ${column.javaType.toLowerCase()}
  8 +#end
  9 +#end
  10 +#end
  11 +}
  12 +
  13 +export type ${simpleClassName}PageReqVO = {
  14 +#foreach ($column in $columns)
  15 +#if (${column.listOperation})##查询操作
  16 +#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
  17 + ${column.javaField}: number
  18 +#else
  19 + ${column.javaField}: ${column.javaType.toLowerCase()}
  20 +#end
  21 +#end
  22 +#end
  23 +}
  24 +
  25 +export type ${simpleClassName}ExcelReqVO = {
  26 +#foreach ($column in $columns)
  27 +#if (${column.listOperation})##查询操作
  28 +#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
  29 + ${column.javaField}: number
  30 +#else
  31 + ${column.javaField}: ${column.javaType.toLowerCase()}
  32 +#end
  33 +#end
  34 +#end
  35 +}
0 36 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/data.ts.vm 0 → 100644
  1 +import { reactive } from 'vue'
  2 +import { useI18n } from '@/hooks/web/useI18n'
  3 +import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
  4 +import { DICT_TYPE } from '@/utils/dict'
  5 +const { t } = useI18n() // 国际化
  6 +// 表单校验
  7 +export const rules = reactive({
  8 +#foreach ($column in $columns)
  9 +#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  10 +#set($comment=$column.columnComment)
  11 + $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
  12 +#end
  13 +#end
  14 +})
  15 +// CrudSchema
  16 +const crudSchemas = reactive<CrudSchema[]>([
  17 +#foreach($column in $columns)
  18 + #if ($column.listOperation || $column.listOperationResult || $column.createOperation || $column.updateOperation)
  19 + #set ($dictType = $column.dictType)
  20 + {
  21 + label: '${column.columnComment}',
  22 + field: '${column.javaField}',
  23 + #if ("" != $dictType)## 有数据字典
  24 + dictType: DICT_TYPE.$dictType.toUpperCase(),
  25 + #end
  26 + #if($column.primaryKey)
  27 + type: 'index',
  28 + form: {
  29 + show: false
  30 + },
  31 + detail: {
  32 + show: false
  33 + }
  34 + #else
  35 + #if (!$column.createOperation && !$column.updateOperation)
  36 + form: {
  37 + false
  38 + },
  39 + #elseif(!("" != $column.dictType))
  40 + form: {
  41 + show: true,
  42 + #if ($column.htmlType == "datetime")## 时间框
  43 + component: 'DatePicker',
  44 + componentProps: {
  45 + type: 'datetime',
  46 + valueFormat: 'YYYY-MM-DD HH:mm:ss'
  47 + }
  48 + #elseif($column.htmlType == "editor")## 文本编辑器
  49 + component: 'Editor',
  50 + colProps: {
  51 + span: 24
  52 + },
  53 + componentProps: {
  54 + valueHtml: ''
  55 + }
  56 + #elseif($column.htmlType == "textarea")## 文本框
  57 + component: 'Input',
  58 + componentProps: {
  59 + type: 'textarea',
  60 + rows: 4
  61 + },
  62 + colProps: {
  63 + span: 24
  64 + }
  65 + #end
  66 + },
  67 + #end
  68 + #if ($column.listOperationResult)
  69 + search: {
  70 + #if($column.htmlType == "input")
  71 + show: true
  72 + #else
  73 + #if($column.htmlType == "datetime")
  74 + show: true,
  75 + component: 'DatePicker',
  76 + componentProps: {
  77 + type: 'datetimerange',
  78 + valueFormat: 'YYYY-MM-DD HH:mm:ss'
  79 + }
  80 + #elseif($column.htmlType == "select" || $column.htmlType == "radio")
  81 + #if ("" == $dictType)## 没有数据字典
  82 + show: true,
  83 + component: 'Select',
  84 + componentProps: {
  85 + option: [{'','请选择字典生成'}]
  86 + }
  87 + #else
  88 + show: true
  89 + #end
  90 + #end
  91 + #end
  92 + }
  93 + #end
  94 + #end
  95 + },
  96 + #end
  97 +#end
  98 + {
  99 + label: t('table.action'),
  100 + field: 'action',
  101 + width: '240px',
  102 + form: {
  103 + show: false
  104 + },
  105 + detail: {
  106 + show: false
  107 + }
  108 + }
  109 +])
  110 +
  111 +export const { allSchemas } = useCrudSchemas(crudSchemas)
0 112 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm 0 → 100644
  1 +<script setup lang="ts">
  2 + import { ref, unref } from 'vue'
  3 + import dayjs from 'dayjs'
  4 + import { ElMessage } from 'element-plus'
  5 + import { DICT_TYPE } from '@/utils/dict'
  6 + import { useTable } from '@/hooks/web/useTable'
  7 + import { useI18n } from '@/hooks/web/useI18n'
  8 + import { FormExpose } from '@/components/Form'
  9 + import type { ${simpleClassName}VO } from '@/api/system/post/types'
  10 + import { rules, allSchemas } from './post.data'
  11 + import * as ${simpleClassName}Api from '@/api/system/post'
  12 + const { t } = useI18n() // 国际化
  13 +
  14 + // ========== 列表相关 ==========
  15 + const { register, tableObject, methods } = useTable<${simpleClassName}VO>({
  16 + getListApi: ${simpleClassName}Api.get${simpleClassName}PageApi,
  17 + delListApi: ${simpleClassName}Api.delete${simpleClassName}Api,
  18 + exportListApi: ${simpleClassName}Api.export${simpleClassName}Api
  19 + })
  20 + const { getList, setSearchParams, delList, exportList } = methods
  21 +
  22 + // 导出操作
  23 + const handleExport = async () => {
  24 + await exportList('数据.xls')
  25 + }
  26 +
  27 + // ========== CRUD 相关 ==========
  28 + const actionLoading = ref(false) // 遮罩层
  29 + const actionType = ref('') // 操作按钮的类型
  30 + const dialogVisible = ref(false) // 是否显示弹出层
  31 + const dialogTitle = ref('edit') // 弹出层标题
  32 + const formRef = ref<FormExpose>() // 表单 Ref
  33 +
  34 + // 设置标题
  35 + const setDialogTile = (type: string) => {
  36 + dialogTitle.value = t('action.' + type)
  37 + actionType.value = type
  38 + dialogVisible.value = true
  39 + }
  40 +
  41 + // 新增操作
  42 + const handleCreate = () => {
  43 + setDialogTile('create')
  44 + // 重置表单
  45 + unref(formRef)?.getElFormRef()?.resetFields()
  46 + }
  47 +
  48 + // 修改操作
  49 + const handleUpdate = async (row: ${simpleClassName}VO) => {
  50 + setDialogTile('update')
  51 + // 设置数据
  52 + const res = await ${simpleClassName}Api.get${simpleClassName}Api(row.id)
  53 + unref(formRef)?.setValues(res)
  54 + }
  55 +
  56 + // 提交按钮
  57 + const submitForm = async () => {
  58 + actionLoading.value = true
  59 + // 提交请求
  60 + try {
  61 + const data = unref(formRef)?.formModel as ${simpleClassName}VO
  62 + if (actionType.value === 'create') {
  63 + await ${simpleClassName}Api.create${simpleClassName}Api(data)
  64 + ElMessage.success(t('common.createSuccess'))
  65 + } else {
  66 + await ${simpleClassName}Api.update${simpleClassName}Api(data)
  67 + ElMessage.success(t('common.updateSuccess'))
  68 + }
  69 + // 操作成功,重新加载列表
  70 + dialogVisible.value = false
  71 + await getList()
  72 + } finally {
  73 + actionLoading.value = false
  74 + }
  75 + }
  76 +
  77 + // 删除操作
  78 + const handleDelete = (row: ${simpleClassName}VO) => {
  79 + delList(row.id, false)
  80 + }
  81 +
  82 + // ========== 详情相关 ==========
  83 + const detailRef = ref() // 详情 Ref
  84 +
  85 + // 详情操作
  86 + const handleDetail = async (row: ${simpleClassName}VO) => {
  87 + // 设置数据
  88 + detailRef.value = row
  89 + setDialogTile('detail')
  90 + }
  91 +
  92 + // ========== 初始化 ==========
  93 + getList()
  94 +</script>
  95 +
  96 +<template>
  97 + <!-- 搜索工作区 -->
  98 + <ContentWrap>
  99 + <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  100 + </ContentWrap>
  101 + <ContentWrap>
  102 + <!-- 操作工具栏 -->
  103 + <div class="mb-10px">
  104 + <el-button type="primary" v-hasPermi="['${permissionPrefix}:create']" @click="handleCreate">
  105 + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
  106 + </el-button>
  107 + <el-button
  108 + type="warning"
  109 + v-hasPermi="['${permissionPrefix}:export']"
  110 + :loading="tableObject.exportLoading"
  111 + @click="handleExport"
  112 + >
  113 + <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
  114 + </el-button>
  115 + </div>
  116 + <!-- 列表 -->
  117 + <Table
  118 + :columns="allSchemas.tableColumns"
  119 + :selection="false"
  120 + :data="tableObject.tableList"
  121 + :loading="tableObject.loading"
  122 + :pagination="{
  123 + total: tableObject.total
  124 + }"
  125 + v-model:pageSize="tableObject.pageSize"
  126 + v-model:currentPage="tableObject.currentPage"
  127 + @register="register"
  128 + >
  129 +#foreach($column in $columns)
  130 +#if ($column.listOperationResult)
  131 + #set ($dictType=$column.dictType)
  132 + #if ($column.javaType == "Date")## 时间类型
  133 + <template #${column.javaField}="{ row }">
  134 + <span>{{ dayjs(row.${column.javaField}).format('YYYY-MM-DD HH:mm:ss') }}</span>
  135 + </template>
  136 + #elseif("" != $column.dictType)## 数据字典
  137 + <template #${column.javaField}="{ row }">
  138 + <DictTag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${column.javaField}" />
  139 + </template>
  140 + #end
  141 +#end
  142 +#end
  143 + <template #action="{ row }">
  144 + <el-button
  145 + link
  146 + type="primary"
  147 + v-hasPermi="['${permissionPrefix}:update']"
  148 + @click="handleUpdate(row)"
  149 + >
  150 + <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
  151 + </el-button>
  152 + <el-button
  153 + link
  154 + type="primary"
  155 + v-hasPermi="['${permissionPrefix}:update']"
  156 + @click="handleDetail(row)"
  157 + >
  158 + <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
  159 + </el-button>
  160 + <el-button
  161 + link
  162 + type="primary"
  163 + v-hasPermi="['${permissionPrefix}:delete']"
  164 + @click="handleDelete(row)"
  165 + >
  166 + <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
  167 + </el-button>
  168 + </template>
  169 + </Table>
  170 + </ContentWrap>
  171 +
  172 + <Dialog v-model="dialogVisible" :title="dialogTitle">
  173 + <!-- 对话框(添加 / 修改) -->
  174 + <Form
  175 + v-if="['create', 'update'].includes(actionType)"
  176 + :schema="allSchemas.formSchema"
  177 + :rules="rules"
  178 + ref="formRef"
  179 + />
  180 + <!-- 对话框(详情) -->
  181 + <Descriptions
  182 + v-if="actionType === 'detail'"
  183 + :schema="allSchemas.detailSchema"
  184 + :data="detailRef"
  185 + >
  186 +#foreach($column in $columns)
  187 + #if ($column.listOperationResult)
  188 + #set ($dictType=$column.dictType)
  189 + #if ($column.javaType == "Date")## 时间类型
  190 + <template #${column.javaField}="{ row }">
  191 + <span>{{ dayjs(row.${column.javaField}).format('YYYY-MM-DD HH:mm:ss') }}</span>
  192 + </template>
  193 + #elseif("" != $column.dictType)## 数据字典
  194 + <template #${column.javaField}="{ row }">
  195 + <DictTag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${column.javaField}" />
  196 + </template>
  197 + #end
  198 + #end
  199 +#end
  200 + </Descriptions>
  201 + <!-- 操作按钮 -->
  202 + <template #footer>
  203 + <el-button
  204 + v-if="['create', 'update'].includes(actionType)"
  205 + type="primary"
  206 + :loading="actionLoading"
  207 + @click="submitForm"
  208 + >
  209 + {{ t('action.save') }}
  210 + </el-button>
  211 + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  212 + </template>
  213 + </Dialog>
  214 +</template>
... ...
yudao-ui-admin-vue3/package.json
... ... @@ -41,7 +41,7 @@
41 41 "lodash-es": "^4.17.21",
42 42 "mitt": "^3.0.0",
43 43 "nprogress": "^0.2.0",
44   - "pinia": "^2.0.16",
  44 + "pinia": "^2.0.17",
45 45 "pinia-plugin-persist": "^1.0.0",
46 46 "qrcode": "^1.5.1",
47 47 "qs": "^6.11.0",
... ... @@ -56,12 +56,12 @@
56 56 "devDependencies": {
57 57 "@commitlint/cli": "^17.0.3",
58 58 "@commitlint/config-conventional": "^17.0.3",
59   - "@iconify/json": "^2.1.81",
  59 + "@iconify/json": "^2.1.82",
60 60 "@intlify/vite-plugin-vue-i18n": "^5.0.1",
61 61 "@purge-icons/generated": "^0.8.1",
62 62 "@types/intro.js": "^5.1.0",
63 63 "@types/lodash-es": "^4.17.6",
64   - "@types/node": "^18.6.0",
  64 + "@types/node": "^18.6.1",
65 65 "@types/nprogress": "^0.2.0",
66 66 "@types/qrcode": "^1.4.2",
67 67 "@types/qs": "^6.9.7",
... ... @@ -74,7 +74,7 @@
74 74 "eslint-config-prettier": "^8.5.0",
75 75 "eslint-define-config": "^1.5.1",
76 76 "eslint-plugin-prettier": "^4.2.1",
77   - "eslint-plugin-vue": "^9.2.0",
  77 + "eslint-plugin-vue": "^9.3.0",
78 78 "less": "^4.1.3",
79 79 "lint-staged": "^13.0.3",
80 80 "plop": "^3.1.1",
... ... @@ -92,7 +92,7 @@
92 92 "stylelint-order": "^5.0.0",
93 93 "typescript": "4.7.4",
94 94 "unplugin-vue-define-options": "^0.6.2",
95   - "vite": "3.0.2",
  95 + "vite": "3.0.3",
96 96 "vite-plugin-compression": "^0.5.1",
97 97 "vite-plugin-eslint": "^1.7.0",
98 98 "vite-plugin-html": "^3.2.0",
... ...
yudao-ui-admin-vue3/src/api/infra/apiAccessLog/index.ts
... ... @@ -9,5 +9,5 @@ export const getApiAccessLogPageApi = (params) =&gt; {
9 9  
10 10 // 导出API 访问日志
11 11 export const exportApiAccessLogApi = (params) => {
12   - return request.get({ url: '/infra/api-access-log/export-excel', params, responseType: 'blob' })
  12 + return request.download({ url: '/infra/api-access-log/export-excel', params })
13 13 }
... ...
yudao-ui-admin-vue3/src/api/infra/apiErrorLog/index.ts
... ... @@ -16,5 +16,8 @@ export const updateApiErrorLogPageApi = (id: number, processStatus: number) =&gt; {
16 16  
17 17 // 导出API 访问日志
18 18 export const exportApiErrorLogApi = (params) => {
19   - return request.get({ url: '/infra/api-error-log/export-excel', params, responseType: 'blob' })
  19 + return request.download({
  20 + url: '/infra/api-error-log/export-excel',
  21 + params
  22 + })
20 23 }
... ...
yudao-ui-admin-vue3/src/api/infra/codegen/index.ts
... ... @@ -40,7 +40,7 @@ export const previewCodegenApi = (id: number) =&gt; {
40 40  
41 41 // 下载生成代码
42 42 export const downloadCodegenApi = (id: number) => {
43   - return request.get({ url: '/infra/codegen/download?tableId=' + id, responseType: 'blob' })
  43 + return request.download({ url: '/infra/codegen/download?tableId=' + id })
44 44 }
45 45  
46 46 // 获得表定义
... ...
yudao-ui-admin-vue3/src/api/infra/config/index.ts
... ... @@ -35,5 +35,5 @@ export const deleteConfigApi = (id: number) =&gt; {
35 35  
36 36 // 导出参数
37 37 export const exportConfigApi = (params) => {
38   - return request.get({ url: '/infra/config/export', params, responseType: 'blob' })
  38 + return request.download({ url: '/infra/config/export', params })
39 39 }
... ...
yudao-ui-admin-vue3/src/api/infra/dbDoc/index.ts
... ... @@ -4,15 +4,15 @@ const request = useAxios()
4 4  
5 5 // 导出Html
6 6 export const exportHtmlApi = () => {
7   - return request.get({ url: '/infra/db-doc/export-html', responseType: 'blob' })
  7 + return request.download({ url: '/infra/db-doc/export-html' })
8 8 }
9 9  
10 10 // 导出Word
11 11 export const exportWordApi = () => {
12   - return request.get({ url: '/infra/db-doc/export-word', responseType: 'blob' })
  12 + return request.download({ url: '/infra/db-doc/export-word' })
13 13 }
14 14  
15 15 // 导出Markdown
16 16 export const exportMarkdownApi = () => {
17   - return request.get({ url: '/infra/db-doc/export-markdown', responseType: 'blob' })
  17 + return request.download({ url: '/infra/db-doc/export-markdown' })
18 18 }
... ...
yudao-ui-admin-vue3/src/api/infra/job/index.ts
... ... @@ -30,7 +30,7 @@ export const deleteJobApi = (id: number) =&gt; {
30 30  
31 31 // 导出定时任务调度
32 32 export const exportJobApi = (params) => {
33   - return request.get({ url: '/infra/job/export-excel', params, responseType: 'blob' })
  33 + return request.download({ url: '/infra/job/export-excel', params })
34 34 }
35 35  
36 36 // 任务状态修改
... ...
yudao-ui-admin-vue3/src/api/infra/jobLog/index.ts
... ... @@ -14,9 +14,8 @@ export const getJobLogApi = (id: number) =&gt; {
14 14  
15 15 // 导出定时任务日志
16 16 export const exportJobLogApi = (params) => {
17   - return request.get({
  17 + return request.download({
18 18 url: '/infra/job-log/export-excel',
19   - params,
20   - responseType: 'blob'
  19 + params
21 20 })
22 21 }
... ...
yudao-ui-admin-vue3/src/api/pay/app/index.ts
... ... @@ -39,7 +39,7 @@ export const deleteAppApi = (id: number) =&gt; {
39 39  
40 40 // 导出支付应用
41 41 export const exportAppApi = (params) => {
42   - return request.get({ url: '/pay/app/export-excel', params, responseType: 'blob' })
  42 + return request.download({ url: '/pay/app/export-excel', params })
43 43 }
44 44  
45 45 // 根据商ID称搜索应用列表
... ...
yudao-ui-admin-vue3/src/api/pay/channel/index.ts
... ... @@ -35,5 +35,5 @@ export const deleteChannelApi = (id: number) =&gt; {
35 35  
36 36 // 导出支付渠道
37 37 export const exportChannelApi = (params) => {
38   - return request.get({ url: '/pay/channel/export-excel', params, responseType: 'blob' })
  38 + return request.download({ url: '/pay/channel/export-excel', params })
39 39 }
... ...
yudao-ui-admin-vue3/src/api/pay/merchant/index.ts
... ... @@ -40,7 +40,7 @@ export const deleteMerchantApi = (id: number) =&gt; {
40 40  
41 41 // 导出支付商户
42 42 export const exportMerchantApi = (params) => {
43   - return request.get({ url: '/pay/merchant/export-excel', params, responseType: 'blob' })
  43 + return request.download({ url: '/pay/merchant/export-excel', params })
44 44 }
45 45 // 支付商户状态修改
46 46 export const changeMerchantStatusApi = (id: number, status: number) => {
... ...
yudao-ui-admin-vue3/src/api/pay/order/index.ts
... ... @@ -30,5 +30,5 @@ export const deleteOrderApi = async (id: number) =&gt; {
30 30  
31 31 // 导出支付订单
32 32 export const exportOrderApi = async (params) => {
33   - return await request.get({ url: '/pay/order/export-excel', params, responseType: 'blob' })
  33 + return await request.download({ url: '/pay/order/export-excel', params })
34 34 }
... ...
yudao-ui-admin-vue3/src/api/pay/refund/index.ts
... ... @@ -30,5 +30,5 @@ export const deleteRefundApi = (id: number) =&gt; {
30 30  
31 31 // 导出退款订单
32 32 export const exportRefundApi = (params) => {
33   - return request.get({ url: '/pay/refund/export-excel', params, responseType: 'blob' })
  33 + return request.download({ url: '/pay/refund/export-excel', params })
34 34 }
... ...
yudao-ui-admin-vue3/src/api/system/errorCode/index.ts
... ... @@ -29,5 +29,5 @@ export const deleteErrorCodeApi = (id: number) =&gt; {
29 29 }
30 30 // 导出错误码
31 31 export const excelErrorCodeApi = (params) => {
32   - return request.get({ url: '/system/error-code/export-excel', params, responseType: 'blob' })
  32 + return request.download({ url: '/system/error-code/export-excel', params })
33 33 }
... ...
yudao-ui-admin-vue3/src/api/system/loginLog/index.ts
... ... @@ -8,5 +8,5 @@ export const getLoginLogPageApi = (params) =&gt; {
8 8 }
9 9 // 导出登录日志
10 10 export const exportLoginLogApi = (params) => {
11   - return request.get({ url: '/system/login-log/export', params, responseType: 'blob' })
  11 + return request.download({ url: '/system/login-log/export', params })
12 12 }
... ...
yudao-ui-admin-vue3/src/api/system/operatelog/index.ts
... ... @@ -8,5 +8,5 @@ export const getOperateLogPageApi = (params) =&gt; {
8 8 }
9 9 // 导出操作日志
10 10 export const exportOperateLogApi = (params) => {
11   - return request.get({ url: '/system/operate-log/export', params, responseType: 'blob' })
  11 + return request.download({ url: '/system/operate-log/export', params })
12 12 }
... ...
yudao-ui-admin-vue3/src/api/system/post/index.ts
... ... @@ -34,5 +34,5 @@ export const deletePostApi = async (id: number) =&gt; {
34 34  
35 35 // 导出岗位
36 36 export const exportPostApi = async (params) => {
37   - return await request.get({ url: '/system/post/export', params, responseType: 'blob' })
  37 + return await request.download({ url: '/system/post/export', params })
38 38 }
... ...
yudao-ui-admin-vue3/src/api/system/sensitiveWord/index.ts
... ... @@ -30,7 +30,7 @@ export const deleteSensitiveWordApi = (id: number) =&gt; {
30 30  
31 31 // 导出敏感词
32 32 export const exportSensitiveWordApi = (params) => {
33   - return request.get({ url: '/system/sensitive-word/export', params, responseType: 'blob' })
  33 + return request.download({ url: '/system/sensitive-word/export-excel', params })
34 34 }
35 35  
36 36 // 获取所有敏感词的标签数组
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsLog/index.ts
... ... @@ -9,5 +9,5 @@ export const getSmsLogPageApi = (params) =&gt; {
9 9  
10 10 // 导出短信日志
11 11 export const exportSmsLogApi = (params) => {
12   - return request.get({ url: '/system/sms-log/export', params, responseType: 'blob' })
  12 + return request.download({ url: '/system/sms-log/export', params })
13 13 }
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsTemplate/index.ts
... ... @@ -35,5 +35,8 @@ export const sendSmsApi = (data) =&gt; {
35 35  
36 36 // 导出短信模板
37 37 export const exportPostApi = (params) => {
38   - return request.get({ url: '/system/sms-template/export-excel', params, responseType: 'blob' })
  38 + return request.download({
  39 + url: '/system/sms-template/export-excel',
  40 + params
  41 + })
39 42 }
... ...
yudao-ui-admin-vue3/src/api/system/tenant/index.ts
... ... @@ -30,5 +30,5 @@ export const deleteTenantApi = (id: number) =&gt; {
30 30  
31 31 // 导出租户
32 32 export const exportTenantApi = (params) => {
33   - return request.get({ url: '/system/tenant/export-excel', params, responseType: 'blob' })
  33 + return request.download({ url: '/system/tenant/export-excel', params })
34 34 }
... ...
yudao-ui-admin-vue3/src/api/system/user/index.ts
... ... @@ -30,12 +30,12 @@ export const deleteUserApi = (id: number) =&gt; {
30 30  
31 31 // 导出用户
32 32 export const exportUserApi = (params) => {
33   - return request.get({ url: '/system/user/export', params, responseType: 'blob' })
  33 + return request.download({ url: '/system/user/export', params })
34 34 }
35 35  
36 36 // 下载用户导入模板
37 37 export const importUserTemplateApi = () => {
38   - return request.get({ url: '/system/user/get-import-template', responseType: 'blob' })
  38 + return request.download({ url: '/system/user/get-import-template' })
39 39 }
40 40  
41 41 // 用户密码重置
... ...
yudao-ui-admin-vue3/src/config/axios/index.ts
... ... @@ -29,7 +29,8 @@ export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH]
29 29 // 创建axios实例
30 30 const service: AxiosInstance = axios.create({
31 31 baseURL: BASE_URL + BASE_API, // api 的 base_url
32   - timeout: config.request_timeout // 请求超时时间
  32 + timeout: config.request_timeout, // 请求超时时间
  33 + withCredentials: false // 禁用 Cookie 等信息
33 34 })
34 35  
35 36 // request拦截器
... ...
yudao-ui-admin-vue3/src/hooks/web/useAxios.ts
... ... @@ -37,12 +37,17 @@ async function putFn&lt;T = any&gt;(option: AxiosConfig): Promise&lt;T&gt; {
37 37 const res = await request({ method: 'PUT', ...option })
38 38 return res.data
39 39 }
  40 +async function downloadFn<T = any>(option: AxiosConfig): Promise<T> {
  41 + const res = await request({ method: 'GET', responseType: 'blob', ...option })
  42 + return res as unknown as Promise<T>
  43 +}
40 44  
41 45 export const useAxios = () => {
42 46 return {
43 47 get: getFn,
44 48 post: postFn,
45 49 delete: deleteFn,
46   - put: putFn
  50 + put: putFn,
  51 + download: downloadFn
47 52 }
48 53 }
... ...
yudao-ui-admin-vue3/src/router/modules/remaining.ts
... ... @@ -72,7 +72,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
72 72 children: [
73 73 {
74 74 path: 'edit',
75   - component: () => import('@/views/infra/codegen/EditTable.vue'),
  75 + component: () => import('@/views/infra/codegen/components/EditTable.vue'),
76 76 name: 'EditTable',
77 77 meta: {
78 78 noCache: true,
... ...
yudao-ui-admin-vue3/src/utils/download.ts
1   -const download0 = (data: any, fileName: string, mineType: string) => {
  1 +const download0 = (data: Blob, fileName: string, mineType: string) => {
2 2 // 创建 blob
3 3 const blob = new Blob([data], { type: mineType })
4 4 // 创建 href 超链接,点击进行下载
... ... @@ -14,23 +14,23 @@ const download0 = (data: any, fileName: string, mineType: string) =&gt; {
14 14  
15 15 const download = {
16 16 // 下载 Excel 方法
17   - excel: (data: any, fileName: string) => {
  17 + excel: (data: Blob, fileName: string) => {
18 18 download0(data, fileName, 'application/vnd.ms-excel')
19 19 },
20 20 // 下载 Word 方法
21   - word: (data: any, fileName: string) => {
  21 + word: (data: Blob, fileName: string) => {
22 22 download0(data, fileName, 'application/msword')
23 23 },
24 24 // 下载 Zip 方法
25   - zip: (data: any, fileName: string) => {
  25 + zip: (data: Blob, fileName: string) => {
26 26 download0(data, fileName, 'application/zip')
27 27 },
28 28 // 下载 Html 方法
29   - html: (data: any, fileName: string) => {
  29 + html: (data: Blob, fileName: string) => {
30 30 download0(data, fileName, 'text/html')
31 31 },
32 32 // 下载 Markdown 方法
33   - markdown: (data: any, fileName: string) => {
  33 + markdown: (data: Blob, fileName: string) => {
34 34 download0(data, fileName, 'text/markdown')
35 35 }
36 36 }
... ...
yudao-ui-admin-vue3/src/views/infra/codegen/EditTable.vue renamed to yudao-ui-admin-vue3/src/views/infra/codegen/components/EditTable.vue
1 1 <script setup lang="ts">
2 2 import { ref, unref, onMounted } from 'vue'
3 3 import { ContentDetailWrap } from '@/components/ContentDetailWrap'
4   -import BasicInfoForm from './components/BasicInfoForm.vue'
5   -import CloumInfoFormVue from './components/CloumInfoForm.vue'
6   -import GenInfoFormVue from './components/GenInfoForm.vue'
  4 +import BasicInfoForm from './BasicInfoForm.vue'
  5 +import CloumInfoFormVue from './CloumInfoForm.vue'
  6 +import GenInfoFormVue from './GenInfoForm.vue'
7 7 import { ElTabs, ElTabPane, ElButton } from 'element-plus'
8 8 import { getCodegenTableApi } from '@/api/infra/codegen'
9 9 import { useRouter, useRoute } from 'vue-router'
... ... @@ -38,7 +38,6 @@ const submitForm = async () =&gt; {
38 38 console.info(basicInfoData)
39 39 console.info(genInfoData)
40 40 }
41   - console.info(1)
42 41 }
43 42 onMounted(() => {
44 43 getList()
... ...
yudao-ui-admin-vue3/src/views/infra/codegen/components/GenInfoForm.vue
... ... @@ -47,6 +47,7 @@ const schema = reactive&lt;FormSchema[]&gt;([
47 47 label: '模块名',
48 48 field: 'moduleName',
49 49 component: 'Input',
  50 + labelMessage: '模块名,即一级目录,例如 system、infra、tool 等等',
50 51 colProps: {
51 52 span: 12
52 53 }
... ... @@ -55,6 +56,7 @@ const schema = reactive&lt;FormSchema[]&gt;([
55 56 label: '业务名',
56 57 field: 'businessName',
57 58 component: 'Input',
  59 + labelMessage: '业务名,即二级目录,例如 user、permission、dict 等等',
58 60 colProps: {
59 61 span: 12
60 62 }
... ... @@ -63,6 +65,7 @@ const schema = reactive&lt;FormSchema[]&gt;([
63 65 label: '类名称',
64 66 field: 'className',
65 67 component: 'Input',
  68 + labelMessage: '类名称(首字母大写),例如SysUser、SysMenu、SysDictData 等等',
66 69 colProps: {
67 70 span: 12
68 71 }
... ... @@ -71,6 +74,7 @@ const schema = reactive&lt;FormSchema[]&gt;([
71 74 label: '类描述',
72 75 field: 'classComment',
73 76 component: 'Input',
  77 + labelMessage: '用作类描述,例如 用户',
74 78 colProps: {
75 79 span: 12
76 80 }
... ... @@ -79,6 +83,7 @@ const schema = reactive&lt;FormSchema[]&gt;([
79 83 label: '上级菜单',
80 84 field: 'parentMenuId',
81 85 component: 'Input',
  86 + labelMessage: '分配到指定菜单下,例如 系统管理',
82 87 colProps: {
83 88 span: 12
84 89 }
... ...
yudao-ui-admin-vue3/src/views/infra/codegen/components/ImportTable.vue
... ... @@ -8,17 +8,18 @@ import {
8 8 ElForm,
9 9 ElFormItem,
10 10 ElInput,
11   - ElEmpty
  11 + ElSelect,
  12 + ElOption
12 13 } from 'element-plus'
13 14 import { useI18n } from '@/hooks/web/useI18n'
14   -import { useEmitt } from '@/hooks/web/useEmitt'
15 15 import { getDataSourceConfigListApi } from '@/api/infra/dataSourceConfig'
16 16 import type { DataSourceConfigVO } from '@/api/infra/dataSourceConfig/types'
17 17 import type { DatabaseTableVO } from '@/api/infra/codegen/types'
18 18 const { t } = useI18n() // 国际化
19   -const { emitter } = useEmitt()
  19 +const emit = defineEmits(['ok'])
20 20 // ======== 显示页面 ========
21 21 const visible = ref(false)
  22 +const dbLoading = ref(true)
22 23 const queryParams = reactive({
23 24 tableName: undefined,
24 25 tableComment: undefined,
... ... @@ -37,8 +38,10 @@ const dbTableList = ref&lt;DatabaseTableVO[]&gt;([])
37 38  
38 39 /** 查询表数据 */
39 40 const getList = async () => {
  41 + dbLoading.value = true
40 42 const res = await getSchemaTableListApi(queryParams)
41 43 dbTableList.value = res
  44 + dbLoading.value = false
42 45 }
43 46 // 查询操作
44 47 const handleQuery = async () => {
... ... @@ -56,19 +59,18 @@ const handleSelectionChange = (val: DatabaseTableVO[]) =&gt; {
56 59 tables.value = val.map((item) => item.name)
57 60 }
58 61 /** 导入按钮操作 */
59   -const handleImportTable = () => {
  62 +const handleImportTable = async () => {
60 63 if (tables.value.length === 0) {
61 64 ElMessage.error('请选择要导入的表')
62 65 return
63 66 }
64   - createCodegenListApi({
  67 + await createCodegenListApi({
65 68 dataSourceConfigId: queryParams.dataSourceConfigId,
66 69 tableNames: tables.value
67   - }).then((res) => {
68   - ElMessage.success(res.msg)
69   - visible.value = false
70   - emitter.emit('ok')
71 70 })
  71 + ElMessage.success('导入成功')
  72 + visible.value = false
  73 + emit('ok')
72 74 }
73 75 defineExpose({
74 76 show
... ... @@ -78,7 +80,7 @@ defineExpose({
78 80 <!-- 导入表 -->
79 81 <Dialog title="导入表" v-model="visible" maxHeight="500px" width="50%">
80 82 <el-form :model="queryParams" ref="queryRef" :inline="true">
81   - <!-- <el-form-item label="数据源" prop="dataSourceConfigId">
  83 + <el-form-item label="数据源" prop="dataSourceConfigId">
82 84 <el-select v-model="queryParams.dataSourceConfigId" placeholder="请选择数据源" clearable>
83 85 <el-option
84 86 v-for="config in dataSourceConfigs"
... ... @@ -87,7 +89,7 @@ defineExpose({
87 89 :value="config.id"
88 90 />
89 91 </el-select>
90   - </el-form-item> -->
  92 + </el-form-item>
91 93 <el-form-item label="表名称" prop="tableName">
92 94 <el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable />
93 95 </el-form-item>
... ... @@ -109,11 +111,9 @@ defineExpose({
109 111 ref="table"
110 112 :data="dbTableList"
111 113 @selection-change="handleSelectionChange"
  114 + v-loading="dbLoading"
112 115 height="400px"
113 116 >
114   - <template #empty>
115   - <el-empty description="加载中" />
116   - </template>
117 117 <el-table-column type="selection" width="55" />
118 118 <el-table-column prop="name" label="表名称" :show-overflow-tooltip="true" />
119 119 <el-table-column prop="comment" label="表描述" :show-overflow-tooltip="true" />
... ...
yudao-ui-admin-vue3/src/views/infra/codegen/components/index.ts 0 → 100644
  1 +import BasicInfoForm from './BasicInfoForm.vue'
  2 +import CloumInfoForm from './CloumInfoForm.vue'
  3 +import EditTable from './EditTable.vue'
  4 +import GenInfoForm from './GenInfoForm.vue'
  5 +import ImportTable from './ImportTable.vue'
  6 +import Preview from './Preview.vue'
  7 +export { BasicInfoForm, CloumInfoForm, EditTable, GenInfoForm, ImportTable, Preview }
... ...
yudao-ui-admin-vue3/src/views/infra/codegen/index.vue
... ... @@ -6,8 +6,7 @@ import { useTable } from &#39;@/hooks/web/useTable&#39;
6 6 import { CodegenTableVO } from '@/api/infra/codegen/types'
7 7 import { allSchemas } from './codegen.data'
8 8 import { useI18n } from '@/hooks/web/useI18n'
9   -import ImportTable from './components/ImportTable.vue'
10   -import Preview from './components/Preview.vue'
  9 +import { ImportTable, Preview } from './components'
11 10 import download from '@/utils/download'
12 11 import { useRouter } from 'vue-router'
13 12 import { useMessage } from '@/hooks/web/useMessage'
... ... @@ -46,8 +45,8 @@ const handleSynchDb = (row: CodegenTableVO) =&gt; {
46 45 })
47 46 }
48 47 // 生成代码操作
49   -const handleGenTable = (row: CodegenTableVO) => {
50   - const res = CodegenApi.downloadCodegenApi(row.id)
  48 +const handleGenTable = async (row: CodegenTableVO) => {
  49 + const res = await CodegenApi.downloadCodegenApi(row.id)
51 50 download.zip(res, 'codegen-' + row.className + '.zip')
52 51 }
53 52 // 删除操作
... ...
yudao-ui-admin-vue3/src/views/system/errorCode/errorCode.data.ts
... ... @@ -61,8 +61,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
61 61 show: true,
62 62 component: 'DatePicker',
63 63 componentProps: {
64   - type: 'datetimerange',
65   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  64 + type: 'daterange',
  65 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  66 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
66 67 }
67 68 }
68 69 },
... ...
yudao-ui-admin-vue3/src/views/system/loginlog/loginLog.data.ts
... ... @@ -59,8 +59,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
59 59 show: true,
60 60 component: 'DatePicker',
61 61 componentProps: {
62   - type: 'datetimerange',
63   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  62 + type: 'daterange',
  63 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  64 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
64 65 }
65 66 }
66 67 },
... ...
yudao-ui-admin-vue3/src/views/system/oauth2/client/index.vue
... ... @@ -113,7 +113,7 @@ getList()
113 113 @register="register"
114 114 >
115 115 <template #logo="{ row }">
116   - <el-image :src="row.logo" />
  116 + <el-image :src="row.logo" :preview-src-list="[row.logo]" />
117 117 </template>
118 118 <template #status="{ row }">
119 119 <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
... ...
yudao-ui-admin-vue3/src/views/system/operatelog/operatelog.data.ts
... ... @@ -88,8 +88,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
88 88 show: true,
89 89 component: 'DatePicker',
90 90 componentProps: {
91   - type: 'datetimerange',
92   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  91 + type: 'daterange',
  92 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  93 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
93 94 }
94 95 }
95 96 },
... ...
yudao-ui-admin-vue3/src/views/system/role/role.data.ts
... ... @@ -72,8 +72,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
72 72 show: true,
73 73 component: 'DatePicker',
74 74 componentProps: {
75   - type: 'datetimerange',
76   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  75 + type: 'daterange',
  76 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  77 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
77 78 }
78 79 }
79 80 },
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsChannel/sms.channel.data.ts
... ... @@ -71,8 +71,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
71 71 show: true,
72 72 component: 'DatePicker',
73 73 componentProps: {
74   - type: 'datetimerange',
75   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  74 + type: 'daterange',
  75 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  76 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
76 77 }
77 78 }
78 79 },
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsLog/sms.log.data.ts
... ... @@ -84,8 +84,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
84 84 show: true,
85 85 component: 'DatePicker',
86 86 componentProps: {
87   - type: 'datetimerange',
88   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  87 + type: 'daterange',
  88 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  89 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
89 90 }
90 91 }
91 92 },
... ...
yudao-ui-admin-vue3/src/views/system/sms/smsTemplate/sms.template.data.ts
... ... @@ -82,8 +82,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
82 82 show: true,
83 83 component: 'DatePicker',
84 84 componentProps: {
85   - type: 'datetimerange',
86   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  85 + type: 'daterange',
  86 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  87 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
87 88 }
88 89 }
89 90 },
... ...
yudao-ui-admin-vue3/src/views/system/user/index.vue
... ... @@ -386,7 +386,7 @@ getList()
386 386 />
387 387 </template>
388 388 <template #postIds>
389   - <el-select v-model="postIds" multiple placeholder="Select">
  389 + <el-select v-model="postIds" multiple :placeholder="t('common.selectText')">
390 390 <el-option
391 391 v-for="item in postOptions"
392 392 :key="item.id"
... ...
yudao-ui-admin-vue3/src/views/system/user/user.data.ts
... ... @@ -115,8 +115,9 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
115 115 show: true,
116 116 component: 'DatePicker',
117 117 componentProps: {
118   - type: 'datetimerange',
119   - valueFormat: 'YYYY-MM-DD HH:mm:ss'
  118 + type: 'daterange',
  119 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  120 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
120 121 }
121 122 }
122 123 },
... ...
yudao-ui-admin/src/views/infra/codegen/index.vue
... ... @@ -85,7 +85,7 @@
85 85  
86 86 <script>
87 87 import { getCodegenTablePage, previewCodegen, downloadCodegen, deleteCodegen,
88   - syncCodegenFromDB, syncCodegenFromSQL, createCodegenListFromSQL } from "@/api/infra/codegen";
  88 + syncCodegenFromDB } from "@/api/infra/codegen";
89 89  
90 90 import importTable from "./importTable";
91 91 // 代码高亮插件
... ... @@ -98,7 +98,7 @@ hljs.registerLanguage(&quot;html&quot;, require(&quot;highlight.js/lib/languages/xml&quot;));
98 98 hljs.registerLanguage("vue", require("highlight.js/lib/languages/xml"));
99 99 hljs.registerLanguage("javascript", require("highlight.js/lib/languages/javascript"));
100 100 hljs.registerLanguage("sql", require("highlight.js/lib/languages/sql"));
101   -
  101 +hljs.registerLanguage("typescript", require("highlight.js/lib/languages/typescript"));
102 102 export default {
103 103 name: "Codegen",
104 104 components: { importTable },
... ...