Commit 5fc1101900cf929d1dde909254ac469610126db7

Authored by 安贞
1 parent 3cd13585

1、关联表删除额外的service。

2、service中删除mybatis plus 的操作,技术和业务解耦。
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java
1 package cn.iocoder.yudao.module.system.dal.mysql.dept; 1 package cn.iocoder.yudao.module.system.dal.mysql.dept;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
4 import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO; 5 import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
5 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
6 7
  8 +import java.util.Collection;
  9 +import java.util.List;
  10 +import java.util.stream.Collectors;
  11 +
7 @Mapper 12 @Mapper
8 public interface UserPostMapper extends BaseMapperX<UserPostDO> { 13 public interface UserPostMapper extends BaseMapperX<UserPostDO> {
9 14
  15 + default List<Long> selectIdList(Long id) {
  16 + return selectList(new LambdaQueryWrapperX<UserPostDO>()
  17 + .eq(UserPostDO::getUserId, id)
  18 + .select(UserPostDO::getPostId)
  19 + )
  20 + .stream()
  21 + .map(UserPostDO::getPostId)
  22 + .collect(Collectors.toList());
  23 +
  24 + }
  25 +
  26 + default void insertList(Long userId, Collection<Long> createPostIds) {
  27 + List<UserPostDO> list = createPostIds
  28 + .stream()
  29 + .map(postId -> {
  30 + UserPostDO entity = new UserPostDO();
  31 + entity.setUserId(userId);
  32 + entity.setPostId(postId);
  33 + return entity;
  34 + })
  35 + .collect(Collectors.toList());
  36 + insertBatch(list);
  37 + }
  38 +
  39 + default void deleteByUserAndPost(Long userId, Collection<Long> deletePostIds) {
  40 + delete(new LambdaQueryWrapperX<UserPostDO>()
  41 + .eq(UserPostDO::getUserId, userId)
  42 + .in(UserPostDO::getPostId, deletePostIds));
  43 + }
  44 +
  45 + default List<Long> getUserIdByPostIds(Collection<Long> postIds) {
  46 + return selectList(new LambdaQueryWrapperX<UserPostDO>()
  47 + .in(UserPostDO::getPostId, postIds))
  48 + .stream()
  49 + .map(UserPostDO::getUserId)
  50 + .distinct()
  51 + .collect(Collectors.toList());
  52 + }
10 } 53 }
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostService.java deleted
1 -package cn.iocoder.yudao.module.system.service.dept;  
2 -  
3 -import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;  
4 -import com.baomidou.mybatisplus.extension.service.IService;  
5 -  
6 -/**  
7 - * <p>  
8 - * 工作流的表单定义 Mapper 接口  
9 - * </p>  
10 - *  
11 - * @author anzhen  
12 - * @since 2022-03-03  
13 - */  
14 -public interface UserPostService extends IService<UserPostDO> {  
15 -  
16 -}  
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.system.service.dept;  
2 -  
3 -import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;  
4 -import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;  
5 -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;  
6 -import org.springframework.stereotype.Service;  
7 -  
8 -/**  
9 - * <p>  
10 - * 工作流的表单定义 Mapper 接口  
11 - * </p>  
12 - *  
13 - * @author anzhen  
14 - * @since 2022-03-03  
15 - */  
16 -@Service  
17 -public class UserPostServiceImpl extends ServiceImpl<UserPostMapper, UserPostDO> implements UserPostService {  
18 -  
19 -}  
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
1 package cn.iocoder.yudao.module.system.service.user; 1 package cn.iocoder.yudao.module.system.service.user;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.collection.CollectionUtil;
4 import cn.hutool.core.io.IoUtil; 5 import cn.hutool.core.io.IoUtil;
5 import cn.hutool.core.util.StrUtil; 6 import cn.hutool.core.util.StrUtil;
6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 7 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
@@ -10,15 +11,20 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; @@ -10,15 +11,20 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
10 import cn.iocoder.yudao.module.infra.api.file.FileApi; 11 import cn.iocoder.yudao.module.infra.api.file.FileApi;
11 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO; 12 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
12 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; 13 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
13 -import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*; 14 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserCreateReqVO;
  15 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserExportReqVO;
  16 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO;
  17 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
  18 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
  19 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserUpdateReqVO;
14 import cn.iocoder.yudao.module.system.convert.user.UserConvert; 20 import cn.iocoder.yudao.module.system.convert.user.UserConvert;
15 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; 21 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
16 import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO; 22 import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
17 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 23 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  24 +import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
18 import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; 25 import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
19 import cn.iocoder.yudao.module.system.service.dept.DeptService; 26 import cn.iocoder.yudao.module.system.service.dept.DeptService;
20 import cn.iocoder.yudao.module.system.service.dept.PostService; 27 import cn.iocoder.yudao.module.system.service.dept.PostService;
21 -import cn.iocoder.yudao.module.system.service.dept.UserPostService;  
22 import cn.iocoder.yudao.module.system.service.permission.PermissionService; 28 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
23 import cn.iocoder.yudao.module.system.service.tenant.TenantService; 29 import cn.iocoder.yudao.module.system.service.tenant.TenantService;
24 import com.baomidou.mybatisplus.core.toolkit.Wrappers; 30 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -31,15 +37,28 @@ import org.springframework.transaction.annotation.Transactional; @@ -31,15 +37,28 @@ import org.springframework.transaction.annotation.Transactional;
31 37
32 import javax.annotation.Resource; 38 import javax.annotation.Resource;
33 import java.io.InputStream; 39 import java.io.InputStream;
34 -import java.util.*; 40 +import java.util.ArrayList;
  41 +import java.util.Collection;
  42 +import java.util.Collections;
  43 +import java.util.Date;
  44 +import java.util.LinkedHashMap;
  45 +import java.util.List;
  46 +import java.util.Map;
  47 +import java.util.Set;
35 import java.util.stream.Collectors; 48 import java.util.stream.Collectors;
36 49
37 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 50 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
38 -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; 51 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_COUNT_MAX;
  52 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_EMAIL_EXISTS;
  53 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IMPORT_LIST_IS_EMPTY;
  54 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IS_DISABLE;
  55 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_MOBILE_EXISTS;
  56 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
  57 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_PASSWORD_FAILED;
  58 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_USERNAME_EXISTS;
39 59
40 /** 60 /**
41 * 后台用户 Service 实现类 61 * 后台用户 Service 实现类
42 - *  
43 * @author 芋道源码 62 * @author 芋道源码
44 */ 63 */
45 @Service("adminUserService") 64 @Service("adminUserService")
@@ -64,7 +83,7 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -64,7 +83,7 @@ public class AdminUserServiceImpl implements AdminUserService {
64 private TenantService tenantService; 83 private TenantService tenantService;
65 84
66 @Resource 85 @Resource
67 - private UserPostService userPostService; 86 + private UserPostMapper userPostMapper;
68 87
69 @Resource 88 @Resource
70 private FileApi fileApi; 89 private FileApi fileApi;
@@ -81,7 +100,7 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -81,7 +100,7 @@ public class AdminUserServiceImpl implements AdminUserService {
81 }); 100 });
82 // 校验正确性 101 // 校验正确性
83 this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), 102 this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
84 - reqVO.getDeptId(), reqVO.getPostIds()); 103 + reqVO.getDeptId(), reqVO.getPostIds());
85 // 插入用户 104 // 插入用户
86 AdminUserDO user = UserConvert.INSTANCE.convert(reqVO); 105 AdminUserDO user = UserConvert.INSTANCE.convert(reqVO);
87 user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 106 user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
@@ -89,14 +108,14 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -89,14 +108,14 @@ public class AdminUserServiceImpl implements AdminUserService {
89 userMapper.insert(user); 108 userMapper.insert(user);
90 Set<Long> postIds = user.getPostIds(); 109 Set<Long> postIds = user.getPostIds();
91 if (!org.springframework.util.CollectionUtils.isEmpty(postIds)) { 110 if (!org.springframework.util.CollectionUtils.isEmpty(postIds)) {
92 - ArrayList<UserPostDO> userPostList = new ArrayList<>(); 111 + List<UserPostDO> userPostList = new ArrayList<>();
93 for (Long postId : postIds) { 112 for (Long postId : postIds) {
94 UserPostDO entity = new UserPostDO(); 113 UserPostDO entity = new UserPostDO();
95 entity.setUserId(entity.getUserId()); 114 entity.setUserId(entity.getUserId());
96 entity.setPostId(postId); 115 entity.setPostId(postId);
97 userPostList.add(entity); 116 userPostList.add(entity);
98 } 117 }
99 - userPostService.saveBatch(userPostList); 118 + userPostMapper.insertBatch(userPostList);
100 } 119 }
101 return user.getId(); 120 return user.getId();
102 } 121 }
@@ -106,23 +125,25 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -106,23 +125,25 @@ public class AdminUserServiceImpl implements AdminUserService {
106 public void updateUser(UserUpdateReqVO reqVO) { 125 public void updateUser(UserUpdateReqVO reqVO) {
107 // 校验正确性 126 // 校验正确性
108 this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), 127 this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
109 - reqVO.getDeptId(), reqVO.getPostIds()); 128 + reqVO.getDeptId(), reqVO.getPostIds());
110 // 更新用户 129 // 更新用户
111 AdminUserDO updateObj = UserConvert.INSTANCE.convert(reqVO); 130 AdminUserDO updateObj = UserConvert.INSTANCE.convert(reqVO);
112 userMapper.updateById(updateObj); 131 userMapper.updateById(updateObj);
  132 + // 更新岗位
113 Set<Long> postIds = updateObj.getPostIds(); 133 Set<Long> postIds = updateObj.getPostIds();
114 - if (!org.springframework.util.CollectionUtils.isEmpty(postIds)) {  
115 - for (Long postId : postIds) {  
116 - UserPostDO entity = new UserPostDO();  
117 - entity.setUserId(reqVO.getId());  
118 - entity.setPostId(postId);  
119 - userPostService.saveOrUpdate(entity,  
120 - Wrappers.lambdaUpdate(UserPostDO.class)  
121 - .eq(UserPostDO::getUserId, entity.getUserId())  
122 - .eq(UserPostDO::getPostId, entity.getPostId())  
123 - );  
124 - } 134 + Long userId = reqVO.getId();
  135 + List<Long> dbPostIds = userPostMapper.selectIdList(userId);
  136 + // 计算新增和删除的岗位编号
  137 + Collection<Long> createPostIds = CollUtil.subtract(postIds, dbPostIds);
  138 + Collection<Long> deletePostIds = CollUtil.subtract(dbPostIds, postIds);
  139 + // 执行新增和删除。对于已经授权的菜单,不用做任何处理
  140 + if (!CollectionUtil.isEmpty(createPostIds)) {
  141 + userPostMapper.insertList(userId, createPostIds);
125 } 142 }
  143 + if (!CollectionUtil.isEmpty(deletePostIds)) {
  144 + userPostMapper.deleteByUserAndPost(userId, deletePostIds);
  145 + }
  146 +
126 } 147 }
127 148
128 @Override 149 @Override
@@ -194,8 +215,8 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -194,8 +215,8 @@ public class AdminUserServiceImpl implements AdminUserService {
194 userMapper.deleteById(id); 215 userMapper.deleteById(id);
195 // 删除用户关联数据 216 // 删除用户关联数据
196 permissionService.processUserDeleted(id); 217 permissionService.processUserDeleted(id);
197 -  
198 - userPostService.remove(Wrappers.lambdaUpdate(UserPostDO.class).eq(UserPostDO::getUserId, id)); 218 + // 删除用户岗位
  219 + userPostMapper.delete(Wrappers.lambdaUpdate(UserPostDO.class).eq(UserPostDO::getUserId, id));
199 } 220 }
200 221
201 @Override 222 @Override
@@ -226,14 +247,7 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -226,14 +247,7 @@ public class AdminUserServiceImpl implements AdminUserService {
226 if (CollUtil.isEmpty(postIds)) { 247 if (CollUtil.isEmpty(postIds)) {
227 return Collections.emptyList(); 248 return Collections.emptyList();
228 } 249 }
229 - List<Long> userIdList = userPostService  
230 - .lambdaQuery()  
231 - .in(UserPostDO::getPostId, postIds)  
232 - .list()  
233 - .stream()  
234 - .map(UserPostDO::getUserId)  
235 - .distinct()  
236 - .collect(Collectors.toList()); 250 + List<Long> userIdList = userPostMapper.getUserIdByPostIds(postIds);
237 if (userIdList.isEmpty()) { 251 if (userIdList.isEmpty()) {
238 return Collections.emptyList(); 252 return Collections.emptyList();
239 } 253 }
@@ -289,7 +303,6 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -289,7 +303,6 @@ public class AdminUserServiceImpl implements AdminUserService {
289 303
290 /** 304 /**
291 * 获得部门条件:查询指定部门的子部门编号们,包括自身 305 * 获得部门条件:查询指定部门的子部门编号们,包括自身
292 - *  
293 * @param deptId 部门编号 306 * @param deptId 部门编号
294 * @return 部门编号集合 307 * @return 部门编号集合
295 */ 308 */
@@ -298,7 +311,7 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -298,7 +311,7 @@ public class AdminUserServiceImpl implements AdminUserService {
298 return Collections.emptySet(); 311 return Collections.emptySet();
299 } 312 }
300 Set<Long> deptIds = CollectionUtils.convertSet(deptService.getDeptsByParentIdFromCache( 313 Set<Long> deptIds = CollectionUtils.convertSet(deptService.getDeptsByParentIdFromCache(
301 - deptId, true), DeptDO::getId); 314 + deptId, true), DeptDO::getId);
302 deptIds.add(deptId); // 包括自身 315 deptIds.add(deptId); // 包括自身
303 return deptIds; 316 return deptIds;
304 } 317 }
@@ -386,7 +399,6 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -386,7 +399,6 @@ public class AdminUserServiceImpl implements AdminUserService {
386 399
387 /** 400 /**
388 * 校验旧密码 401 * 校验旧密码
389 - *  
390 * @param id 用户 id 402 * @param id 用户 id
391 * @param oldPassword 旧密码 403 * @param oldPassword 旧密码
392 */ 404 */
@@ -408,12 +420,12 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -408,12 +420,12 @@ public class AdminUserServiceImpl implements AdminUserService {
408 throw exception(USER_IMPORT_LIST_IS_EMPTY); 420 throw exception(USER_IMPORT_LIST_IS_EMPTY);
409 } 421 }
410 UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>()) 422 UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
411 - .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build(); 423 + .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
412 importUsers.forEach(importUser -> { 424 importUsers.forEach(importUser -> {
413 // 校验,判断是否有不符合的原因 425 // 校验,判断是否有不符合的原因
414 try { 426 try {
415 checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), 427 checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
416 - importUser.getDeptId(), null); 428 + importUser.getDeptId(), null);
417 } catch (ServiceException ex) { 429 } catch (ServiceException ex) {
418 respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage()); 430 respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
419 return; 431 return;
@@ -422,7 +434,7 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -422,7 +434,7 @@ public class AdminUserServiceImpl implements AdminUserService {
422 AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername()); 434 AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
423 if (existUser == null) { 435 if (existUser == null) {
424 userMapper.insert(UserConvert.INSTANCE.convert(importUser) 436 userMapper.insert(UserConvert.INSTANCE.convert(importUser)
425 - .setPassword(passwordEncoder.encode(userInitPassword))); // 设置默认密码 437 + .setPassword(passwordEncoder.encode(userInitPassword))); // 设置默认密码
426 respVO.getCreateUsernames().add(importUser.getUsername()); 438 respVO.getCreateUsernames().add(importUser.getUsername());
427 return; 439 return;
428 } 440 }
yudao-module-system/yudao-module-system-impl/src/test/resources/sql/clean.sql
@@ -4,6 +4,7 @@ DELETE FROM &quot;system_role&quot;; @@ -4,6 +4,7 @@ DELETE FROM &quot;system_role&quot;;
4 DELETE FROM "system_role_menu"; 4 DELETE FROM "system_role_menu";
5 DELETE FROM "system_menu"; 5 DELETE FROM "system_menu";
6 DELETE FROM "system_user_role"; 6 DELETE FROM "system_user_role";
  7 +DELETE FROM "system_user_post";
7 DELETE FROM "system_dict_type"; 8 DELETE FROM "system_dict_type";
8 DELETE FROM "system_user_session"; 9 DELETE FROM "system_user_session";
9 DELETE FROM "system_post"; 10 DELETE FROM "system_post";
yudao-module-system/yudao-module-system-impl/src/test/resources/sql/create_tables.sql
@@ -145,6 +145,20 @@ CREATE TABLE IF NOT EXISTS &quot;system_post&quot; ( @@ -145,6 +145,20 @@ CREATE TABLE IF NOT EXISTS &quot;system_post&quot; (
145 PRIMARY KEY ("id") 145 PRIMARY KEY ("id")
146 ) COMMENT '岗位信息表'; 146 ) COMMENT '岗位信息表';
147 147
  148 +CREATE TABLE IF NOT EXISTS `system_user_post`(
  149 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  150 + "user_id" bigint DEFAULT NULL,
  151 + "post_id" bigint DEFAULT NULL,
  152 + "creator" varchar(64) DEFAULT '',
  153 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  154 + "updater" varchar(64) DEFAULT '',
  155 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  156 + "deleted" bit NOT NULL DEFAULT FALSE,
  157 + "tenant_id" bigint not null default '0',
  158 + PRIMARY KEY (`id`)
  159 +) COMMENT ='部门表';
  160 +
  161 +
148 CREATE TABLE IF NOT EXISTS "system_notice" ( 162 CREATE TABLE IF NOT EXISTS "system_notice" (
149 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, 163 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
150 "title" varchar(50) NOT NULL COMMENT '公告标题', 164 "title" varchar(50) NOT NULL COMMENT '公告标题',