Commit 7641998c3f30cae4b369eaa232e7c5e1741de264
Committed by
Gitee
!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<T> extends QueryWrapper<T> { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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) => { |
| 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<T = any>(option: AxiosConfig): Promise<T> { |
| 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) => { |
| 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 () => { |
| 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<FormSchema[]>([ |
| 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<FormSchema[]>([ |
| 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<FormSchema[]>([ |
| 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<FormSchema[]>([ |
| 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<FormSchema[]>([ |
| 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<DatabaseTableVO[]>([]) |
| 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[]) => { |
| 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 '@/hooks/web/useTable' |
| 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) => { |
| 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<CrudSchema[]>([ |
| 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<CrudSchema[]>([ |
| 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<CrudSchema[]>([ |
| 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<CrudSchema[]>([ |
| 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<CrudSchema[]>([ |
| 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<CrudSchema[]>([ |
| 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<CrudSchema[]>([ |
| 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<CrudSchema[]>([ |
| 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("html", require("highlight.js/lib/languages/xml")); |
| 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 }, | ... | ... |