正在显示
13 个修改的文件
包含
117 行增加
和
25 行删除
@@ -25,7 +25,7 @@ | @@ -25,7 +25,7 @@ | ||
25 | <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> | 25 | <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> |
26 | <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> | 26 | <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> |
27 | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | 27 | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
28 | - <level>info</level> | 28 | + <level>debug</level> |
29 | </filter> | 29 | </filter> |
30 | <encoder> | 30 | <encoder> |
31 | <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> | 31 | <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> |
@@ -169,7 +169,7 @@ | @@ -169,7 +169,7 @@ | ||
169 | 不能设置为INHERITED或者同义词NULL。默认是DEBUG | 169 | 不能设置为INHERITED或者同义词NULL。默认是DEBUG |
170 | 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 | 170 | 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 |
171 | --> | 171 | --> |
172 | - <logger name="com.tianbo.warehouse.dao" level="info" /> | 172 | + <logger name="com.tianbo.warehouse.dao" level="debug" /> |
173 | <!--开发环境:打印控制台--> | 173 | <!--开发环境:打印控制台--> |
174 | <springProfile name="dev"> | 174 | <springProfile name="dev"> |
175 | <logger name="org.springframework.security" level="debug"/> | 175 | <logger name="org.springframework.security" level="debug"/> |
@@ -205,10 +205,10 @@ | @@ -205,10 +205,10 @@ | ||
205 | <groupId>org.springframework.boot</groupId> | 205 | <groupId>org.springframework.boot</groupId> |
206 | <artifactId>spring-boot-starter-data-redis</artifactId> | 206 | <artifactId>spring-boot-starter-data-redis</artifactId> |
207 | </dependency> | 207 | </dependency> |
208 | - <dependency> | ||
209 | - <groupId>org.springframework.cloud</groupId> | ||
210 | - <artifactId>spring-cloud-starter-zipkin</artifactId> | ||
211 | - </dependency> | 208 | +<!-- <dependency>--> |
209 | +<!-- <groupId>org.springframework.cloud</groupId>--> | ||
210 | +<!-- <artifactId>spring-cloud-starter-zipkin</artifactId>--> | ||
211 | +<!-- </dependency>--> | ||
212 | 212 | ||
213 | <dependency> | 213 | <dependency> |
214 | <groupId>de.codecentric</groupId> | 214 | <groupId>de.codecentric</groupId> |
@@ -5,6 +5,7 @@ import com.tianbo.warehouse.annotation.LogAnnotation; | @@ -5,6 +5,7 @@ import com.tianbo.warehouse.annotation.LogAnnotation; | ||
5 | import com.tianbo.warehouse.controller.response.ResultJson; | 5 | import com.tianbo.warehouse.controller.response.ResultJson; |
6 | import com.tianbo.warehouse.model.PERMISSION; | 6 | import com.tianbo.warehouse.model.PERMISSION; |
7 | import com.tianbo.warehouse.service.PermissionService; | 7 | import com.tianbo.warehouse.service.PermissionService; |
8 | +import io.swagger.annotations.ApiOperation; | ||
8 | import org.springframework.beans.factory.annotation.Autowired; | 9 | import org.springframework.beans.factory.annotation.Autowired; |
9 | import org.springframework.web.bind.annotation.*; | 10 | import org.springframework.web.bind.annotation.*; |
10 | 11 | ||
@@ -89,7 +90,7 @@ public class PermssionController { | @@ -89,7 +90,7 @@ public class PermssionController { | ||
89 | } | 90 | } |
90 | return resultJson; | 91 | return resultJson; |
91 | } | 92 | } |
92 | - @LogAnnotation(moduleName = "权限管理",operate = "查找权限") | 93 | +// @LogAnnotation(moduleName = "权限管理",operate = "查找权限") |
93 | @GetMapping("/findByRoleId") | 94 | @GetMapping("/findByRoleId") |
94 | public ResultJson findByRoleId(@RequestParam Integer roleId){ | 95 | public ResultJson findByRoleId(@RequestParam Integer roleId){ |
95 | 96 | ||
@@ -110,8 +111,15 @@ public class PermssionController { | @@ -110,8 +111,15 @@ public class PermssionController { | ||
110 | 111 | ||
111 | @GetMapping("/userMenu") | 112 | @GetMapping("/userMenu") |
112 | public ResultJson<List<PERMISSION>> userMenu( | 113 | public ResultJson<List<PERMISSION>> userMenu( |
113 | - @RequestParam(value = "userId", required = true) Integer userId){ | 114 | + @RequestParam(value = "userId") Integer userId){ |
114 | return new ResultJson<List<PERMISSION>>("200","success",permissionService.getUserMenuTreeByUserId(userId)); | 115 | return new ResultJson<List<PERMISSION>>("200","success",permissionService.getUserMenuTreeByUserId(userId)); |
115 | 116 | ||
116 | } | 117 | } |
118 | + | ||
119 | + @ApiOperation(value = "所有目录列表", notes = "查询所有目录菜单的树形结构信息") | ||
120 | + @GetMapping("/menu") | ||
121 | + public ResultJson<List<PERMISSION>> menu(){ | ||
122 | + return new ResultJson<List<PERMISSION>>("200","success",permissionService.getUserMenuTreeByUserId(0)); | ||
123 | + | ||
124 | + } | ||
117 | } | 125 | } |
@@ -70,11 +70,12 @@ public class UserController { | @@ -70,11 +70,12 @@ public class UserController { | ||
70 | UserDetails userDetails =(UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); | 70 | UserDetails userDetails =(UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); |
71 | return userDetails.getUsername(); | 71 | return userDetails.getUsername(); |
72 | } | 72 | } |
73 | - | 73 | + @ApiOperation(value = "更新用户信息", notes = "跟新用户信息除了用户密码") |
74 | @LogAnnotation(moduleName = "用户管理",operate = "用户编辑") | 74 | @LogAnnotation(moduleName = "用户管理",operate = "用户编辑") |
75 | @PutMapping("/edit") | 75 | @PutMapping("/edit") |
76 | public ResultJson updateUserById(@Validated(UpdateUser.class) @RequestBody USERS user){ | 76 | public ResultJson updateUserById(@Validated(UpdateUser.class) @RequestBody USERS user){ |
77 | int i = userService.updateByPrimaryKeySelective(user); | 77 | int i = userService.updateByPrimaryKeySelective(user); |
78 | + user.setPassword(null); | ||
78 | ResultJson resultJson = new ResultJson(); | 79 | ResultJson resultJson = new ResultJson(); |
79 | return i==1 ? new ResultJson("200","success") :new ResultJson("500","update faild"); | 80 | return i==1 ? new ResultJson("200","success") :new ResultJson("500","update faild"); |
80 | 81 |
@@ -39,7 +39,7 @@ public interface PERMISSIONMapper { | @@ -39,7 +39,7 @@ public interface PERMISSIONMapper { | ||
39 | 39 | ||
40 | List<PERMISSION> getRolePermisson(Integer roleId); | 40 | List<PERMISSION> getRolePermisson(Integer roleId); |
41 | 41 | ||
42 | - List<PERMISSION> getUserMenuTreeByUserId(Integer userId); | 42 | + List<PERMISSION> getUserMenuTreeByUserId(@Param("userId") Integer userId); |
43 | 43 | ||
44 | List<PERMISSION> getChildMenu(Integer parentId); | 44 | List<PERMISSION> getChildMenu(Integer parentId); |
45 | } | 45 | } |
@@ -18,6 +18,13 @@ public interface ROLEMapper { | @@ -18,6 +18,13 @@ public interface ROLEMapper { | ||
18 | 18 | ||
19 | List<ROLE> selectByParentId(Integer roleId); | 19 | List<ROLE> selectByParentId(Integer roleId); |
20 | 20 | ||
21 | + /** | ||
22 | + * 查询最顶层企业信息 | ||
23 | + * @param roleId 组织机构ID | ||
24 | + * @return | ||
25 | + */ | ||
26 | + List<ROLE> selectTopByChildID(Integer roleId); | ||
27 | + | ||
21 | List<ROLE> findAll(@Param("roleName") String roleName, | 28 | List<ROLE> findAll(@Param("roleName") String roleName, |
22 | @Param("type") String type); | 29 | @Param("type") String type); |
23 | 30 |
@@ -20,8 +20,6 @@ public class ROLE implements GrantedAuthority { | @@ -20,8 +20,6 @@ public class ROLE implements GrantedAuthority { | ||
20 | 20 | ||
21 | private String description; | 21 | private String description; |
22 | 22 | ||
23 | - private String departmentId; | ||
24 | - | ||
25 | private String type; | 23 | private String type; |
26 | 24 | ||
27 | private List<PERMISSION> permissions; | 25 | private List<PERMISSION> permissions; |
@@ -38,7 +36,6 @@ public class ROLE implements GrantedAuthority { | @@ -38,7 +36,6 @@ public class ROLE implements GrantedAuthority { | ||
38 | 36 | ||
39 | private List<ROLE> children; | 37 | private List<ROLE> children; |
40 | 38 | ||
41 | - | ||
42 | public Integer getRoleId() { | 39 | public Integer getRoleId() { |
43 | return roleId; | 40 | return roleId; |
44 | } | 41 | } |
@@ -79,6 +76,13 @@ public class ROLE implements GrantedAuthority { | @@ -79,6 +76,13 @@ public class ROLE implements GrantedAuthority { | ||
79 | this.type = type == null ? null : type.trim(); | 76 | this.type = type == null ? null : type.trim(); |
80 | } | 77 | } |
81 | 78 | ||
79 | + public String getDepartmentid() { | ||
80 | + return departmentid; | ||
81 | + } | ||
82 | + | ||
83 | + public void setDepartmentid(String departmentid) { | ||
84 | + this.departmentid = departmentid; | ||
85 | + } | ||
82 | 86 | ||
83 | @Override | 87 | @Override |
84 | public String getAuthority(){ | 88 | public String getAuthority(){ |
@@ -24,7 +24,7 @@ public class USERS implements UserDetails { | @@ -24,7 +24,7 @@ public class USERS implements UserDetails { | ||
24 | private Integer userId; | 24 | private Integer userId; |
25 | 25 | ||
26 | @NotBlank(message="用户名不能为空",groups={InsertUser.class, UpdateUser.class}) | 26 | @NotBlank(message="用户名不能为空",groups={InsertUser.class, UpdateUser.class}) |
27 | - @Length(min = 5, max = 11, message = "username 长度必须在 {min} - {max} 之间",groups={InsertUser.class, UpdateUser.class}) | 27 | + @Length(min = 1, max = 11, message = "username 长度必须在 {min} - {max} 之间",groups={InsertUser.class, UpdateUser.class}) |
28 | @CheckUserExist(message = "用户已存在",groups=InsertUser.class) | 28 | @CheckUserExist(message = "用户已存在",groups=InsertUser.class) |
29 | private String username; | 29 | private String username; |
30 | 30 | ||
@@ -58,7 +58,9 @@ public class USERS implements UserDetails { | @@ -58,7 +58,9 @@ public class USERS implements UserDetails { | ||
58 | 58 | ||
59 | private String token; | 59 | private String token; |
60 | 60 | ||
61 | + //用户所属企业ID,企业ID为用户绑定的组织机构顶层parentid为0的组织机构ID | ||
61 | private Integer companyId; | 62 | private Integer companyId; |
63 | + private String companyName; | ||
62 | 64 | ||
63 | private ROLE companyInfo; | 65 | private ROLE companyInfo; |
64 | 66 | ||
@@ -222,6 +224,14 @@ public class USERS implements UserDetails { | @@ -222,6 +224,14 @@ public class USERS implements UserDetails { | ||
222 | this.companyInfo = companyInfo; | 224 | this.companyInfo = companyInfo; |
223 | } | 225 | } |
224 | 226 | ||
227 | + public String getCompanyName() { | ||
228 | + return companyName; | ||
229 | + } | ||
230 | + | ||
231 | + public void setCompanyName(String companyName) { | ||
232 | + this.companyName = companyName; | ||
233 | + } | ||
234 | + | ||
225 | /** | 235 | /** |
226 | * | 236 | * |
227 | * @return 账户未过期 | 237 | * @return 账户未过期 |
@@ -67,6 +67,9 @@ public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticat | @@ -67,6 +67,9 @@ public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticat | ||
67 | loginedUser.setUserface(user.getUserface()); | 67 | loginedUser.setUserface(user.getUserface()); |
68 | loginedUser.setUserId(user.getUserId()); | 68 | loginedUser.setUserId(user.getUserId()); |
69 | loginedUser.setRealname(user.getRealname()); | 69 | loginedUser.setRealname(user.getRealname()); |
70 | + loginedUser.setCompanyId(user.getCompanyId()); | ||
71 | + loginedUser.setCompanyName(user.getCompanyName()); | ||
72 | + loginedUser.setCompanyInfo(user.getCompanyInfo()); | ||
70 | 73 | ||
71 | 74 | ||
72 | //设置用户的TOKEN的有效时间,时间配置在配置文件中设置 | 75 | //设置用户的TOKEN的有效时间,时间配置在配置文件中设置 |
@@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; | ||
13 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
14 | 14 | ||
15 | import javax.annotation.Resource; | 15 | import javax.annotation.Resource; |
16 | +import javax.validation.constraints.NotNull; | ||
16 | import java.util.ArrayList; | 17 | import java.util.ArrayList; |
17 | import java.util.HashMap; | 18 | import java.util.HashMap; |
18 | import java.util.List; | 19 | import java.util.List; |
@@ -26,7 +27,7 @@ public class PermissionServiceImp implements PermissionService { | @@ -26,7 +27,7 @@ public class PermissionServiceImp implements PermissionService { | ||
26 | PERMISSIONMapper permissionMapper; | 27 | PERMISSIONMapper permissionMapper; |
27 | 28 | ||
28 | @Override | 29 | @Override |
29 | - @RedisCacheable(cacheKey = "findAllMenus") | 30 | +// @RedisCacheable(cacheKey = "findAllMenus") |
30 | public PageInfo<PERMISSION> findAll(int pageNum, int pageSize, String name) { | 31 | public PageInfo<PERMISSION> findAll(int pageNum, int pageSize, String name) { |
31 | Page<PERMISSION> page = PageHelper.startPage(pageNum, 0,true,true,true); | 32 | Page<PERMISSION> page = PageHelper.startPage(pageNum, 0,true,true,true); |
32 | List<PERMISSION> list = permissionMapper.findAll(name); | 33 | List<PERMISSION> list = permissionMapper.findAll(name); |
@@ -35,7 +36,7 @@ public class PermissionServiceImp implements PermissionService { | @@ -35,7 +36,7 @@ public class PermissionServiceImp implements PermissionService { | ||
35 | } | 36 | } |
36 | 37 | ||
37 | @Override | 38 | @Override |
38 | - @RedisCacheable(cacheKey = "findByRoleId") | 39 | +// @RedisCacheable(cacheKey = "findByRoleId") |
39 | public List<PERMISSION> findByRoleId(Integer roleId) { | 40 | public List<PERMISSION> findByRoleId(Integer roleId) { |
40 | List<PERMISSION> list = getPermissionList(permissionMapper.findByRoleId(roleId), 0); | 41 | List<PERMISSION> list = getPermissionList(permissionMapper.findByRoleId(roleId), 0); |
41 | return list; | 42 | return list; |
@@ -66,7 +67,7 @@ public class PermissionServiceImp implements PermissionService { | @@ -66,7 +67,7 @@ public class PermissionServiceImp implements PermissionService { | ||
66 | * @return | 67 | * @return |
67 | */ | 68 | */ |
68 | @Override | 69 | @Override |
69 | - @RedisCacheable(cacheKey = "findByUserIdWithLogin") | 70 | +// @RedisCacheable(cacheKey = "findByUserIdWithLogin") |
70 | public List<PERMISSION> findByUserIdWithLogin(Integer userId){ | 71 | public List<PERMISSION> findByUserIdWithLogin(Integer userId){ |
71 | return permissionMapper.findByUserIdWithLogin(userId); | 72 | return permissionMapper.findByUserIdWithLogin(userId); |
72 | } | 73 | } |
@@ -77,7 +78,7 @@ public class PermissionServiceImp implements PermissionService { | @@ -77,7 +78,7 @@ public class PermissionServiceImp implements PermissionService { | ||
77 | * @return | 78 | * @return |
78 | */ | 79 | */ |
79 | @Override | 80 | @Override |
80 | - @RedisCacheable(cacheKey = "getUserMenusTree")//添加缓存 | 81 | +// @RedisCacheable(cacheKey = "getUserMenusTree")//添加缓存 |
81 | public Map<String, Object> getUserMenus(Integer userId) { | 82 | public Map<String, Object> getUserMenus(Integer userId) { |
82 | Map<String, Object> data = new HashMap<String, Object>(); | 83 | Map<String, Object> data = new HashMap<String, Object>(); |
83 | try { | 84 | try { |
@@ -181,8 +182,8 @@ public class PermissionServiceImp implements PermissionService { | @@ -181,8 +182,8 @@ public class PermissionServiceImp implements PermissionService { | ||
181 | } | 182 | } |
182 | 183 | ||
183 | @Override | 184 | @Override |
184 | - @RedisCacheable(cacheKey = "getUserMenuTreeByUserId") | ||
185 | - public List<PERMISSION> getUserMenuTreeByUserId(Integer userId) { | 185 | +// @RedisCacheable(cacheKey = "getUserMenuTreeByUserId") |
186 | + public List<PERMISSION> getUserMenuTreeByUserId(@NotNull Integer userId) { | ||
186 | return permissionMapper.getUserMenuTreeByUserId(userId); | 187 | return permissionMapper.getUserMenuTreeByUserId(userId); |
187 | } | 188 | } |
188 | 189 |
@@ -18,6 +18,8 @@ import org.springframework.stereotype.Service; | @@ -18,6 +18,8 @@ import org.springframework.stereotype.Service; | ||
18 | import org.springframework.transaction.annotation.Transactional; | 18 | import org.springframework.transaction.annotation.Transactional; |
19 | 19 | ||
20 | import javax.annotation.Resource; | 20 | import javax.annotation.Resource; |
21 | +import javax.management.relation.Role; | ||
22 | +import java.util.Collections; | ||
21 | import java.util.List; | 23 | import java.util.List; |
22 | import java.util.Random; | 24 | import java.util.Random; |
23 | 25 | ||
@@ -46,15 +48,34 @@ public class UserServiceImpl implements UserService{ | @@ -46,15 +48,34 @@ public class UserServiceImpl implements UserService{ | ||
46 | if (userList != null && userList.size() > 0) { | 48 | if (userList != null && userList.size() > 0) { |
47 | USERS user = userList.get(0); | 49 | USERS user = userList.get(0); |
48 | 50 | ||
51 | + //获取用户角色列表,用户没有配置相关组织机构时,获取不到权限 | ||
52 | + List<ROLE> roleList = roleMapper.findRolesByUserId(user.getUserId()); | ||
53 | + //用户未绑定组织机构时会查询出null数组信息,现象为All elements are null | ||
54 | + | ||
55 | + if (!roleList.isEmpty()){ | ||
56 | + ROLE ur = roleList.get(0); | ||
57 | + /** | ||
58 | + * 一个用户只能对应一个总组织机构(公司),可以在多个部门/岗位任职,设置用户所属顶级组织机构信息 | ||
59 | + */ | ||
60 | + List<ROLE> topRoles = roleMapper.selectTopByChildID(ur.getRoleId()); | ||
61 | + topRoles.removeAll(Collections.singleton(null)); | ||
62 | + if (!topRoles.isEmpty()){ | ||
63 | + user.setCompanyId(topRoles.get(0).getRoleId()); | ||
64 | + user.setCompanyName(topRoles.get(0).getRoleName()); | ||
65 | + topRoles.get(0).setChildren(null); | ||
66 | + topRoles.get(0).setPermissions(null); | ||
67 | + user.setCompanyInfo(topRoles.get(0)); | ||
68 | + } | ||
69 | + user.setRoles(roleList); | ||
70 | + } | ||
71 | + | ||
72 | + //用户权限列表 | ||
49 | List<PERMISSION> permissionList = permissionService.findByUserIdWithLogin(user.getUserId()); | 73 | List<PERMISSION> permissionList = permissionService.findByUserIdWithLogin(user.getUserId()); |
50 | - if (permissionList!=null && permissionList.size()>0){ | 74 | + if (!permissionList.isEmpty()){ |
51 | user.setPermissions(permissionList); | 75 | user.setPermissions(permissionList); |
52 | } | 76 | } |
53 | 77 | ||
54 | - List<ROLE> roleList = roleMapper.findRolesByUserId(user.getUserId()); | ||
55 | - if (roleList!=null && roleList.size()>0){ | ||
56 | - user.setRoles(roleList); | ||
57 | - } | 78 | + |
58 | return user; | 79 | return user; |
59 | } | 80 | } |
60 | return null; | 81 | return null; |
@@ -352,8 +352,10 @@ where P.url = #{permissionUrl,jdbcType=VARCHAR} ORDER BY permission_order | @@ -352,8 +352,10 @@ where P.url = #{permissionUrl,jdbcType=VARCHAR} ORDER BY permission_order | ||
352 | UR.role_id | 352 | UR.role_id |
353 | FROM | 353 | FROM |
354 | user_role UR | 354 | user_role UR |
355 | + <if test="userId != 0" > | ||
355 | WHERE | 356 | WHERE |
356 | UR.user_id = #{userId,jdbcType=INTEGER} | 357 | UR.user_id = #{userId,jdbcType=INTEGER} |
358 | + </if> | ||
357 | ) | 359 | ) |
358 | ) | 360 | ) |
359 | ) | 361 | ) |
@@ -32,6 +32,41 @@ | @@ -32,6 +32,41 @@ | ||
32 | from role | 32 | from role |
33 | where parentId = #{roleId,jdbcType=INTEGER} | 33 | where parentId = #{roleId,jdbcType=INTEGER} |
34 | </select> | 34 | </select> |
35 | + <select id="selectTopByChildID" parameterType="java.lang.Integer" resultMap="BaseResultMap"> | ||
36 | + SELECT | ||
37 | + * | ||
38 | +FROM | ||
39 | + ( | ||
40 | + SELECT | ||
41 | + t3.* | ||
42 | + FROM | ||
43 | + ( | ||
44 | + SELECT | ||
45 | + t1.*, | ||
46 | + IF | ||
47 | + ( | ||
48 | + FIND_IN_SET( role_id, @ids ) > 0, | ||
49 | + @ids := CONCAT( parentId, ',', @ids ), | ||
50 | + '0' | ||
51 | + ) AS isparent | ||
52 | + FROM | ||
53 | + ( | ||
54 | + SELECT | ||
55 | + t.* | ||
56 | + FROM | ||
57 | + role AS t | ||
58 | + ORDER BY | ||
59 | + t.role_id DESC | ||
60 | + ) t1, | ||
61 | + ( SELECT @ids := #{roleId,jdbcType=INTEGER} ) t2 | ||
62 | + ) t3 | ||
63 | + WHERE | ||
64 | + t3.isparent != '0' | ||
65 | + ) t4 | ||
66 | +WHERE | ||
67 | + t4.parentId = 0 | ||
68 | + order by role_id | ||
69 | + </select> | ||
35 | <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> | 70 | <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> |
36 | delete from role | 71 | delete from role |
37 | where role_id = #{roleId,jdbcType=INTEGER} | 72 | where role_id = #{roleId,jdbcType=INTEGER} |
-
请 注册 或 登录 后发表评论