-
+
+
+
+ 请上传
+ 大小不超过 {{ fileSize }}MB
+ 格式为 {{ fileType.join("/") }}
+ 的文件
+
+
+
+
@@ -40,36 +45,128 @@
import { getToken } from "@/utils/auth";
export default {
+ props: {
+ value: [String, Object, Array],
+ // 图片数量限制
+ limit: {
+ type: Number,
+ default: 5,
+ },
+ // 大小限制(MB)
+ fileSize: {
+ type: Number,
+ default: 5,
+ },
+ // 文件类型, 例如['png', 'jpg', 'jpeg']
+ fileType: {
+ type: Array,
+ default: () => ["png", "jpg", "jpeg"],
+ },
+ // 是否显示提示
+ isShowTip: {
+ type: Boolean,
+ default: true
+ }
+ },
data() {
return {
+ dialogImageUrl: "",
dialogVisible: false,
+ hideUpload: false,
+ baseUrl: process.env.VUE_APP_BASE_API,
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
headers: {
Authorization: "Bearer " + getToken(),
},
+ fileList: []
};
},
- props: {
+ watch: {
value: {
- type: String,
- default: "",
+ handler(val) {
+ if (val) {
+ // 首先将值转为数组
+ const list = Array.isArray(val) ? val : this.value.split(',');
+ // 然后将数组转为对象数组
+ this.fileList = list.map(item => {
+ if (typeof item === "string") {
+ if (item.indexOf(this.baseUrl) === -1) {
+ item = { name: this.baseUrl + item, url: this.baseUrl + item };
+ } else {
+ item = { name: item, url: item };
+ }
+ }
+ return item;
+ });
+ } else {
+ this.fileList = [];
+ return [];
+ }
+ },
+ deep: true,
+ immediate: true
+ }
+ },
+ computed: {
+ // 是否显示提示
+ showTip() {
+ return this.isShowTip && (this.fileType || this.fileSize);
},
},
methods: {
- removeImage() {
- this.$emit("input", "");
+ // 删除图片
+ handleRemove(file, fileList) {
+ const findex = this.fileList.indexOf(file.name);
+ this.fileList.splice(findex, 1);
+ this.$emit("input", this.listToString(this.fileList));
},
+ // 上传成功回调
handleUploadSuccess(res) {
- this.$emit("input", res.data.url);
+ this.fileList.push({ name: res.data.fileName, url: res.data.fileName });
+ this.$emit("input", this.listToString(this.fileList));
this.loading.close();
},
- handleBeforeUpload() {
+ // 上传前loading加载
+ handleBeforeUpload(file) {
+ let isImg = false;
+ if (this.fileType.length) {
+ let fileExtension = "";
+ if (file.name.lastIndexOf(".") > -1) {
+ fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
+ }
+ isImg = this.fileType.some(type => {
+ if (file.type.indexOf(type) > -1) return true;
+ if (fileExtension && fileExtension.indexOf(type) > -1) return true;
+ return false;
+ });
+ } else {
+ isImg = file.type.indexOf("image") > -1;
+ }
+
+ if (!isImg) {
+ this.$message.error(
+ `文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`
+ );
+ return false;
+ }
+ if (this.fileSize) {
+ const isLt = file.size / 1024 / 1024 < this.fileSize;
+ if (!isLt) {
+ this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
+ return false;
+ }
+ }
this.loading = this.$loading({
lock: true,
text: "上传中",
background: "rgba(0, 0, 0, 0.7)",
});
},
+ // 文件个数超出
+ handleExceed() {
+ this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
+ },
+ // 上传失败
handleUploadError() {
this.$message({
type: "error",
@@ -77,24 +174,37 @@ export default {
});
this.loading.close();
},
- },
- watch: {},
+ // 预览
+ handlePictureCardPreview(file) {
+ this.dialogImageUrl = file.url;
+ this.dialogVisible = true;
+ },
+ // 对象转成指定字符串分隔
+ listToString(list, separator) {
+ let strs = "";
+ separator = separator || ",";
+ for (let i in list) {
+ strs += list[i].url + separator;
+ }
+ return strs != '' ? strs.substr(0, strs.length - 1) : '';
+ }
+ }
};
-
+
diff --git a/ruoyi-ui/src/components/TopNav/index.vue b/ruoyi-ui/src/components/TopNav/index.vue
index d89930a8..c8837f2a 100644
--- a/ruoyi-ui/src/components/TopNav/index.vue
+++ b/ruoyi-ui/src/components/TopNav/index.vue
@@ -73,9 +73,9 @@ export default {
if(router.path === "/") {
router.children[item].path = "/redirect/" + router.children[item].path;
} else {
- if(!this.ishttp(router.children[item].path)) {
+ if(!this.ishttp(router.children[item].path)) {
router.children[item].path = router.path + "/" + router.children[item].path;
- }
+ }
}
router.children[item].parentPath = router.path;
}
diff --git a/ruoyi-ui/src/directive/dialog/drag.js b/ruoyi-ui/src/directive/dialog/drag.js
new file mode 100644
index 00000000..728f49dc
--- /dev/null
+++ b/ruoyi-ui/src/directive/dialog/drag.js
@@ -0,0 +1,64 @@
+/**
+* v-dialogDrag 弹窗拖拽
+* Copyright (c) 2019 ruoyi
+*/
+
+export default {
+ bind(el, binding, vnode, oldVnode) {
+ const value = binding.value
+ if (value == false) return
+ // 获取拖拽内容头部
+ const dialogHeaderEl = el.querySelector('.el-dialog__header');
+ const dragDom = el.querySelector('.el-dialog');
+ dialogHeaderEl.style.cursor = 'move';
+ // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
+ const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
+ dragDom.style.position = 'absolute';
+ dragDom.style.marginTop = 0;
+ let width = dragDom.style.width;
+ if (width.includes('%')) {
+ width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100);
+ } else {
+ width = +width.replace(/\px/g, '');
+ }
+ dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`;
+ // 鼠标按下事件
+ dialogHeaderEl.onmousedown = (e) => {
+ // 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
+ const disX = e.clientX - dialogHeaderEl.offsetLeft;
+ const disY = e.clientY - dialogHeaderEl.offsetTop;
+
+ // 获取到的值带px 正则匹配替换
+ let styL, styT;
+
+ // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
+ if (sty.left.includes('%')) {
+ styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
+ styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
+ } else {
+ styL = +sty.left.replace(/\px/g, '');
+ styT = +sty.top.replace(/\px/g, '');
+ };
+
+ // 鼠标拖拽事件
+ document.onmousemove = function (e) {
+ // 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
+ const l = e.clientX - disX;
+ const t = e.clientY - disY;
+
+ let finallyL = l + styL
+ let finallyT = t + styT
+
+ // 移动当前元素
+ dragDom.style.left = `${finallyL}px`;
+ dragDom.style.top = `${finallyT}px`;
+
+ };
+
+ document.onmouseup = function (e) {
+ document.onmousemove = null;
+ document.onmouseup = null;
+ };
+ }
+ }
+};
\ No newline at end of file
diff --git a/ruoyi-ui/src/directive/permission/index.js b/ruoyi-ui/src/directive/index.js
similarity index 55%
rename from ruoyi-ui/src/directive/permission/index.js
rename to ruoyi-ui/src/directive/index.js
index e3d76d38..550109b4 100644
--- a/ruoyi-ui/src/directive/permission/index.js
+++ b/ruoyi-ui/src/directive/index.js
@@ -1,14 +1,17 @@
-import hasRole from './hasRole'
-import hasPermi from './hasPermi'
+import hasRole from './permission/hasRole'
+import hasPermi from './permission/hasPermi'
+import dialogDrag from './dialog/drag'
const install = function(Vue) {
Vue.directive('hasRole', hasRole)
Vue.directive('hasPermi', hasPermi)
+ Vue.directive('dialogDrag', dialogDrag)
}
if (window.Vue) {
window['hasRole'] = hasRole
window['hasPermi'] = hasPermi
+ window['dialogDrag'] = dialogDrag
Vue.use(install); // eslint-disable-line
}
diff --git a/ruoyi-ui/src/directive/permission/hasPermi.js b/ruoyi-ui/src/directive/permission/hasPermi.js
index d7107cec..7101e3e8 100644
--- a/ruoyi-ui/src/directive/permission/hasPermi.js
+++ b/ruoyi-ui/src/directive/permission/hasPermi.js
@@ -1,8 +1,8 @@
/**
- * 操作权限处理
+ * v-hasPermi 操作权限处理
* Copyright (c) 2019 ruoyi
*/
-
+
import store from '@/store'
export default {
diff --git a/ruoyi-ui/src/directive/permission/hasRole.js b/ruoyi-ui/src/directive/permission/hasRole.js
index 13038099..ad9d4d79 100644
--- a/ruoyi-ui/src/directive/permission/hasRole.js
+++ b/ruoyi-ui/src/directive/permission/hasRole.js
@@ -1,8 +1,8 @@
/**
- * 角色权限处理
+ * v-hasRole 角色权限处理
* Copyright (c) 2019 ruoyi
*/
-
+
import store from '@/store'
export default {
diff --git a/ruoyi-ui/src/layout/components/AppMain.vue b/ruoyi-ui/src/layout/components/AppMain.vue
index a8976380..0c6f4b78 100644
--- a/ruoyi-ui/src/layout/components/AppMain.vue
+++ b/ruoyi-ui/src/layout/components/AppMain.vue
@@ -51,7 +51,7 @@ export default {
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
.fixed-header {
- padding-right: 15px;
+ padding-right: 17px;
}
}
diff --git a/ruoyi-ui/src/layout/components/InnerLink/index.vue b/ruoyi-ui/src/layout/components/InnerLink/index.vue
new file mode 100644
index 00000000..227ff2a7
--- /dev/null
+++ b/ruoyi-ui/src/layout/components/InnerLink/index.vue
@@ -0,0 +1,27 @@
+
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index d1f8973b..d07dead4 100644
--- a/ruoyi-ui/src/main.js
+++ b/ruoyi-ui/src/main.js
@@ -10,7 +10,7 @@ import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'
import store from './store'
import router from './router'
-import permission from './directive/permission'
+import directive from './directive' //directive
import './assets/icons' // icon
import './permission' // permission control
@@ -20,6 +20,12 @@ import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels,
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
import RightToolbar from "@/components/RightToolbar"
+// 富文本组件
+import Editor from "@/components/Editor"
+// 文件上传组件
+import FileUpload from "@/components/FileUpload"
+// 图片上传组件
+import ImageUpload from "@/components/ImageUpload"
// 字典标签组件
import DictTag from '@/components/DictTag'
// 头部标签组件
@@ -52,8 +58,11 @@ Vue.prototype.msgInfo = function (msg) {
Vue.component('DictTag', DictTag)
Vue.component('Pagination', Pagination)
Vue.component('RightToolbar', RightToolbar)
+Vue.component('Editor', Editor)
+Vue.component('FileUpload', FileUpload)
+Vue.component('ImageUpload', ImageUpload)
-Vue.use(permission)
+Vue.use(directive)
Vue.use(VueMeta)
/**
diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js
index ffb12e7d..c7b9371b 100644
--- a/ruoyi-ui/src/router/index.js
+++ b/ruoyi-ui/src/router/index.js
@@ -6,6 +6,7 @@ Vue.use(Router)
/* Layout */
import Layout from '@/layout'
import ParentView from '@/components/ParentView';
+import InnerLink from '@/layout/components/InnerLink'
/**
* Note: 路由配置项
@@ -80,6 +81,32 @@ export const constantRoutes = [
}
]
},
+ {
+ path: '/auth',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'role/:userId(\\d+)',
+ component: (resolve) => require(['@/views/system/user/authRole'], resolve),
+ name: 'AuthRole',
+ meta: { title: '分配角色'}
+ }
+ ]
+ },
+ {
+ path: '/auth',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'user/:roleId(\\d+)',
+ component: (resolve) => require(['@/views/system/role/authUser'], resolve),
+ name: 'AuthUser',
+ meta: { title: '分配用户'}
+ }
+ ]
+ },
{
path: '/dict',
component: Layout,
diff --git a/ruoyi-ui/src/store/modules/permission.js b/ruoyi-ui/src/store/modules/permission.js
index aacfc8c9..81026f36 100644
--- a/ruoyi-ui/src/store/modules/permission.js
+++ b/ruoyi-ui/src/store/modules/permission.js
@@ -2,6 +2,7 @@ import { constantRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView';
+import InnerLink from '@/layout/components/InnerLink'
const permission = {
state: {
@@ -65,6 +66,8 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
route.component = Layout
} else if (route.component === 'ParentView') {
route.component = ParentView
+ } else if (route.component === 'InnerLink') {
+ route.component = InnerLink
} else {
route.component = loadView(route.component)
}
diff --git a/ruoyi-ui/src/views/demo/demo/index.vue b/ruoyi-ui/src/views/demo/demo/index.vue
index 279c4693..a6679f39 100644
--- a/ruoyi-ui/src/views/demo/demo/index.vue
+++ b/ruoyi-ui/src/views/demo/demo/index.vue
@@ -304,17 +304,19 @@ export default {
this.buttonLoading = true;
if (this.form.id != null) {
updateDemo(this.form).then(response => {
- this.buttonLoading = false;
this.msgSuccess("修改成功");
this.open = false;
this.getList();
+ }).finally(() => {
+ this.buttonLoading = false;
});
} else {
addDemo(this.form).then(response => {
- this.buttonLoading = false;
this.msgSuccess("新增成功");
this.open = false;
this.getList();
+ }).finally(() => {
+ this.buttonLoading = false;
});
}
}
diff --git a/ruoyi-ui/src/views/demo/tree/index.vue b/ruoyi-ui/src/views/demo/tree/index.vue
index afe96c4a..57b152fc 100644
--- a/ruoyi-ui/src/views/demo/tree/index.vue
+++ b/ruoyi-ui/src/views/demo/tree/index.vue
@@ -255,17 +255,19 @@ export default {
this.buttonLoading = true;
if (this.form.id != null) {
updateTree(this.form).then(response => {
- this.buttonLoading = false;
this.msgSuccess("修改成功");
this.open = false;
this.getList();
+ }).finally(() => {
+ this.buttonLoading = false;
});
} else {
addTree(this.form).then(response => {
- this.buttonLoading = false;
this.msgSuccess("新增成功");
this.open = false;
this.getList();
+ }).finally(() => {
+ this.buttonLoading = false;
});
}
}
diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue
index dba6dfe8..671dcde2 100644
--- a/ruoyi-ui/src/views/index.vue
+++ b/ruoyi-ui/src/views/index.vue
@@ -91,6 +91,32 @@
更新日志
+
+
+ - update springboot 2.4.7 => 2.4.8
+ - update knife4j 3.0.2 => 3.0.3
+ - update hutool 5.7.2 => 5.7.4
+ - update spring-boot-admin 2.4.1 => 2.4.3
+ - update redisson 3.15.2 => 3.16.0
+ - add 增加 docker 编排 与 shell 脚本
+ - add 增加 feign 熔断 自定义结构体解析方法 与 demo 注释
+ - add 用户管理新增分配角色功能
+ - add 角色管理新增分配用户功能
+ - add 增加spring-cache演示案例
+ - update 独立 springboot-admin 监控到扩展模块项目
+ - update springboot-admin 监控 增加用户登录权限管理
+ - update 优化代码生成器 批量导入
+ - update 优化 增加MP注入异常拦截
+ - update 关闭默认二级缓存 推荐使用 spring-cache 注解手动缓存
+ - update FileUpload ImageUpload组件 支持多图片上传
+ - update 优化中英文语言配置
+ - update 规范maven写法
+ - fix redis获取map属性bug修复。
+ - fix 修复 按钮loading 后端500卡死问题
+ - fix 相对路径下载问题
+ - fix 修复 hutool 工具返回结果不一致问题
+
+
- update springboot 2.3.11 => 2.4.7
diff --git a/ruoyi-ui/src/views/monitor/admin/index.vue b/ruoyi-ui/src/views/monitor/admin/index.vue
index f1d48b0a..ad35dc46 100644
--- a/ruoyi-ui/src/views/monitor/admin/index.vue
+++ b/ruoyi-ui/src/views/monitor/admin/index.vue
@@ -1,26 +1,16 @@
-
-
-
+
diff --git a/ruoyi-ui/src/views/system/notice/index.vue b/ruoyi-ui/src/views/system/notice/index.vue
index 31155437..0ffd9d6c 100644
--- a/ruoyi-ui/src/views/system/notice/index.vue
+++ b/ruoyi-ui/src/views/system/notice/index.vue
@@ -177,13 +177,9 @@
\ No newline at end of file
diff --git a/ruoyi-ui/src/views/system/role/index.vue b/ruoyi-ui/src/views/system/role/index.vue
index 081ea81d..5bedd490 100644
--- a/ruoyi-ui/src/views/system/role/index.vue
+++ b/ruoyi-ui/src/views/system/role/index.vue
@@ -124,7 +124,7 @@
-
+
修改
- 数据权限
删除
+ handleCommand(command, scope.row)">
+
+ 更多
+
+
+ 数据权限
+ 分配用户
+
+
@@ -469,6 +473,19 @@ export default {
this.single = selection.length!=1
this.multiple = !selection.length
},
+ // 更多操作触发
+ handleCommand(command, row) {
+ switch (command) {
+ case "handleDataScope":
+ this.handleDataScope(row);
+ break;
+ case "handleAuthUser":
+ this.handleAuthUser(row);
+ break;
+ default:
+ break;
+ }
+ },
// 树权限(展开/折叠)
handleCheckedTreeExpand(value, type) {
if (type == 'menu') {
@@ -548,6 +565,11 @@ export default {
this.title = "分配数据权限";
});
},
+ /** 分配用户操作 */
+ handleAuthUser: function(row) {
+ const roleId = row.roleId;
+ this.$router.push("/auth/user/" + roleId);
+ },
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
diff --git a/ruoyi-ui/src/views/system/role/selectUser.vue b/ruoyi-ui/src/views/system/role/selectUser.vue
new file mode 100644
index 00000000..14ae0bb8
--- /dev/null
+++ b/ruoyi-ui/src/views/system/role/selectUser.vue
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/system/user/authRole.vue b/ruoyi-ui/src/views/system/user/authRole.vue
new file mode 100644
index 00000000..8e7f82a9
--- /dev/null
+++ b/ruoyi-ui/src/views/system/user/authRole.vue
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{(pageNum - 1) * pageSize + scope.$index + 1}}
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+ 提交
+ 返回
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue
index 471e66f2..605cf6ee 100644
--- a/ruoyi-ui/src/views/system/user/index.vue
+++ b/ruoyi-ui/src/views/system/user/index.vue
@@ -167,7 +167,7 @@
width="160"
class-name="small-padding fixed-width"
>
-
+
修改
删除
- 重置
+ handleCommand(command, scope.row)">
+
+ 更多
+
+
+ 重置密码
+ 分配角色
+
+
@@ -561,6 +564,19 @@ export default {
this.single = selection.length != 1;
this.multiple = !selection.length;
},
+ // 更多操作触发
+ handleCommand(command, row) {
+ switch (command) {
+ case "handleResetPwd":
+ this.handleResetPwd(row);
+ break;
+ case "handleAuthRole":
+ this.handleAuthRole(row);
+ break;
+ default:
+ break;
+ }
+ },
/** 新增按钮操作 */
handleAdd() {
this.reset();
@@ -603,6 +619,11 @@ export default {
});
}).catch(() => {});
},
+ /** 分配角色操作 */
+ handleAuthRole: function(row) {
+ const userId = row.userId;
+ this.$router.push("/auth/role/" + userId);
+ },
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js
index c749c8c1..ee6353c2 100644
--- a/ruoyi-ui/vue.config.js
+++ b/ruoyi-ui/vue.config.js
@@ -109,7 +109,7 @@ module.exports = {
config.optimization.runtimeChunk('single'),
{
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
- to: './', //到根目录下
+ to: './' //到根目录下
}
}
)
diff --git a/sql/ry_20210210.sql b/sql/ry_20210210.sql
index 1d8ec367..59a55f12 100644
--- a/sql/ry_20210210.sql
+++ b/sql/ry_20210210.sql
@@ -159,7 +159,7 @@ create table sys_menu (
insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录');
-insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null , 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址');
+insert into sys_menu values('4', 'PLUS官网', '0', '4', 'https://gitee.com/JavaLionLi/RuoYi-Vue-Plus', null , 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, 'RuoYi-Vue-Plus官网地址');
-- 二级菜单
insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单');
insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单');
@@ -685,4 +685,4 @@ create table gen_table_column (
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
primary key (column_id)
-) engine=innodb auto_increment=1 comment = '代码生成业务表字段';
\ No newline at end of file
+) engine=innodb auto_increment=1 comment = '代码生成业务表字段';