yonge 3 years ago
parent
commit
98b1f2636d
40 changed files with 1885 additions and 172 deletions
  1. 0 22
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/filters/TenantIdThreadLocal.java
  2. 37 29
      cooleshow-user/pom.xml
  3. 5 0
      cooleshow-user/user-admin/pom.xml
  4. 52 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/config/PermissionCheckService.java
  5. 38 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/config/ResourceServerConfig.java
  6. 48 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/config/WebMvcConfig.java
  7. 72 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/AppVersionInfoController.java
  8. 57 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SubjectController.java
  9. 60 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SysSuggestionController.java
  10. 39 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SysUserContractsController.java
  11. 48 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/UploadFileController.java
  12. 33 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/interceptor/OperationLogInterceptor.java
  13. 1 1
      cooleshow-user/user-biz/pom.xml
  14. 9 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysSuggestionDao.java
  15. 31 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysUserContractsDao.java
  16. 135 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysSuggestion.java
  17. 126 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysUserContracts.java
  18. 34 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SuggestionType.java
  19. 55 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/SysSuggestionQueryInfo.java
  20. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysSuggestionService.java
  21. 27 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysUserContractsService.java
  22. 136 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UploadFileService.java
  23. 23 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysSuggestionServiceImpl.java
  24. 35 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysUserContractsServiceImpl.java
  25. 101 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysUserContractsMapper.xml
  26. 64 60
      cooleshow-user/user-student/pom.xml
  27. 36 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/config/ResourceServerConfig.java
  28. 56 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/config/WebMvcConfig.java
  29. 44 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionController.java
  30. 43 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/interceptor/MDCInterceptor.java
  31. 33 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/interceptor/OperationLogInterceptor.java
  32. 55 0
      cooleshow-user/user-student/src/main/resources/logback-spring.xml
  33. 64 60
      cooleshow-user/user-teacher/pom.xml
  34. 42 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/config/ResourceServerConfig.java
  35. 57 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/config/WebMvcConfig.java
  36. 44 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionController.java
  37. 43 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/interceptor/MDCInterceptor.java
  38. 33 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/interceptor/OperationLogInterceptor.java
  39. 55 0
      cooleshow-user/user-teacher/src/main/resources/logback-spring.xml
  40. 6 0
      pom.xml

+ 0 - 22
cooleshow-common/src/main/java/com/yonge/cooleshow/common/filters/TenantIdThreadLocal.java

@@ -1,22 +0,0 @@
-package com.yonge.cooleshow.common.filters;
-
-public class TenantIdThreadLocal {
-    private static final ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
-        @Override
-        protected Integer initialValue() {
-            return null;
-        }
-    };
-
-    public static Integer get(){
-        return threadLocal.get();
-    }
-
-    public static void set(Integer tenantId){
-        threadLocal.set(tenantId);
-    }
-
-    public static void remove(){
-        threadLocal.remove();
-    }
-}

+ 37 - 29
cooleshow-user/pom.xml

@@ -1,31 +1,39 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>com.yonge.cooleshow</groupId>
-        <artifactId>cooleshow</artifactId>
-        <version>1.0</version>
-    </parent>
-
-    <groupId>com.yonge.cooleshow</groupId>
-    <artifactId>cooleshow-user</artifactId>
-    <version>1.0</version>
-    <packaging>pom</packaging>
-
-    <name>cooleshow-user</name>
-    <url>http://maven.apache.org</url>
-
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    </properties>
-
-    <dependencies>
-    </dependencies>
-    <modules>
-        <module>user-student</module>
-        <module>user-teacher</module>
-        <module>user-admin</module>
-      <module>user-biz</module>
-  </modules>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>com.yonge.cooleshow</groupId>
+		<artifactId>cooleshow</artifactId>
+		<version>1.0</version>
+	</parent>
+
+	<groupId>com.yonge.cooleshow</groupId>
+	<artifactId>cooleshow-user</artifactId>
+	<version>1.0</version>
+	<packaging>pom</packaging>
+
+	<name>cooleshow-user</name>
+	<url>http://maven.apache.org</url>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>com.yonge.cooleshow</groupId>
+			<artifactId>auth-api</artifactId>
+		</dependency>
+
+	</dependencies>
+
+	<modules>
+		<module>user-student</module>
+		<module>user-teacher</module>
+		<module>user-admin</module>
+		<module>user-biz</module>
+	</modules>
 </project>

+ 5 - 0
cooleshow-user/user-admin/pom.xml

@@ -55,6 +55,11 @@
 		</dependency>
 
 		<dependency>
+			<groupId>com.yonge.cooleshow</groupId>
+			<artifactId>user-biz</artifactId>
+		</dependency>
+
+		<dependency>
 			<groupId>com.github.whvcse</groupId>
 			<artifactId>easy-captcha</artifactId>
 			<version>1.6.2</version>

+ 52 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/config/PermissionCheckService.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.web.config;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.common.security.SecurityUtils;
+
+@Component("pcs")
+public class PermissionCheckService {
+	
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	public boolean hasPermissions(String... permissions) {
+		Authentication authentication = SecurityUtils.getAuthentication();
+		if (authentication == null) {
+			return false;
+		}
+
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if(user.getIsSuperAdmin()){
+			return true;
+		}
+
+		Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
+
+		for (String perm : permissions) {
+			for (GrantedAuthority authority : authorities) {
+				if (StringUtils.equalsIgnoreCase(perm, authority.getAuthority())) {
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+
+	public boolean hasRoles(String... roles) {
+
+		return hasPermissions(roles);
+	}
+
+}

+ 38 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/config/ResourceServerConfig.java

@@ -0,0 +1,38 @@
+package com.yonge.cooleshow.web.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+
+import com.yonge.cooleshow.common.security.BaseAccessDeniedHandler;
+import com.yonge.cooleshow.common.security.BaseAuthenticationEntryPoint;
+
+@Configuration
+@EnableResourceServer
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+	@Autowired
+	private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+	@Autowired
+	private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+	@Override
+	public void configure(HttpSecurity http) throws Exception {
+		http.csrf().disable().exceptionHandling().accessDeniedHandler(baseAccessDeniedHandler).authenticationEntryPoint(baseAuthenticationEntryPoint).and()
+				.authorizeRequests().antMatchers("/task/**").hasIpAddress("0.0.0.0/0")
+				.antMatchers("/v2/api-docs", "/code/*", "/api/*", "/appVersionInfo/queryByPlatform", "/uploadFile").permitAll().anyRequest().authenticated()
+				.and().httpBasic();
+	}
+
+	@Override
+	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+		resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+	}
+
+}

+ 48 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/config/WebMvcConfig.java

@@ -0,0 +1,48 @@
+package com.yonge.cooleshow.web.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.cooleshow.common.config.LocalFastJsonHttpMessageConverter;
+import com.yonge.cooleshow.web.interceptor.OperationLogInterceptor;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+	@Autowired
+	private OperationLogInterceptor operationLogInterceptor;
+
+	/**
+	 * 枚举类的转换器 addConverterFactory
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		registry.addConverterFactory(new EnumConverterFactory());
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+
+		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
+	}
+
+	@Bean
+	public HttpMessageConverters fastJsonHttpMessageConverters() {
+		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
+		List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
+		fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+		converter.setSupportedMediaTypes(fastMediaTypes);
+		return new HttpMessageConverters(converter);
+	}
+
+}

+ 72 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/AppVersionInfoController.java

@@ -0,0 +1,72 @@
+package com.yonge.cooleshow.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.yonge.cooleshow.biz.dal.entity.AppVersionInfo;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.page.QueryInfo;
+
+@RequestMapping("appVersionInfo")
+@Api(tags = "APP版本信息服务")
+@RestController
+public class AppVersionInfoController extends BaseController {
+
+	@Autowired
+	private AppVersionInfoService appVersionInfoService;
+
+	@ApiOperation("分页查询")
+	@GetMapping(value = "/list")
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/list')")
+	public Object getList(QueryInfo queryInfo) {
+		return succeed(appVersionInfoService.queryPage(queryInfo));
+	}
+
+	@ApiOperation("根据app客户端查询对象")
+	@ApiImplicitParam(name = "platform", value = "平台名称", required = true, dataType = "String", paramType = "path")
+	@GetMapping(value = "/queryByPlatform")
+	public Object queryByPlatform(String platform) {
+		List<AppVersionInfo> list = appVersionInfoService.queryNewestByPlatform(platform);
+		if (list.size() > 0) {
+			return succeed(list.get(0));
+		}
+		return failed();
+	}
+
+	@ApiOperation("单查询")
+	@ApiImplicitParam(name = "id", value = "ID编号", required = true, dataType = "Integer", paramType = "path")
+	@GetMapping(value = "/query")
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/query')")
+	public Object query(Integer id) {
+		return succeed(appVersionInfoService.get(id));
+	}
+
+	@ApiOperation("新增")
+	@PostMapping(value = "/add", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/add')")
+	public Object add(AppVersionInfo appVersionInfo) {
+		appVersionInfoService.add(appVersionInfo);
+		return succeed();
+	}
+
+	@ApiOperation("更新")
+	@PostMapping(value = "/update", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/update')")
+	public Object update(AppVersionInfo appVersionInfo) {
+		appVersionInfoService.updateVersion(appVersionInfo);
+		return succeed();
+	}
+
+}

+ 57 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SubjectController.java

@@ -0,0 +1,57 @@
+package com.yonge.cooleshow.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.queryInfo.SubjectQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.common.controller.BaseController;
+
+@RequestMapping("subject")
+@Api(tags = "科目服务")
+@RestController
+public class SubjectController extends BaseController {
+
+	@Autowired
+	private SubjectService subjectService;
+
+	@ApiOperation(value = "修改、新增科目")
+	@PostMapping("/upset")
+	@PreAuthorize("@pcs.hasPermissions('subject/upset')")
+	public Object update(@RequestBody Subject subject) {
+		subjectService.upSetSubject(subject);
+		return succeed();
+	}
+
+	@ApiOperation(value = "根据科目编号查询科目")
+	@GetMapping("/get/{id}")
+	@PreAuthorize("@pcs.hasPermissions('subject/get')")
+	public Object get(@ApiParam(value = "科目编号", required = true) @PathVariable("id") Integer id) {
+		return succeed(subjectService.get(id));
+	}
+
+	@ApiOperation(value = "分页查询科目列表")
+	@GetMapping("/queryPage")
+	@PreAuthorize("@pcs.hasPermissions('subject/queryPage')")
+	public Object queryPage(SubjectQueryInfo queryInfo) {
+		return succeed(subjectService.queryPage(queryInfo));
+	}
+
+	@ApiOperation(value = "分页查询科目树状列表")
+	@GetMapping("/queryPageTree")
+	@PreAuthorize("@pcs.hasPermissions('subject/queryPageTree')")
+	public Object queryPageTree(SubjectQueryInfo queryInfo) {
+		return succeed(subjectService.queryPageTree(queryInfo));
+	}
+}

+ 60 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SysSuggestionController.java

@@ -0,0 +1,60 @@
+package com.yonge.cooleshow.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysSuggestionQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.common.controller.BaseController;
+
+@Api(tags = "意见反馈")
+@RestController
+public class SysSuggestionController extends BaseController {
+
+    @Autowired
+    private SysSuggestionService sysSuggestionService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增")
+    @RequestMapping("sysSuggestion/add")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/add')")
+    public Object add(SysSuggestion sysSuggestion) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        sysSuggestion.setUserId(sysUser.getId().longValue());
+        sysSuggestion.setClientType("TEACHER");
+        if(StringUtils.isEmpty(sysSuggestion.getMobileNo())){
+            sysSuggestion.setMobileNo(sysUser.getPhone());
+        }
+        sysSuggestionService.insert(sysSuggestion);
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除")
+    @RequestMapping("sysSuggestion/del")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/del')")
+    public Object del(Long id) {
+        sysSuggestionService.delete(id);
+        return succeed();
+    }
+
+    @ApiOperation(value = "分页查询")
+    @RequestMapping("sysSuggestion/queryPage")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/queryPage')")
+    public Object queryPage(SysSuggestionQueryInfo queryInfo) {
+        return succeed(sysSuggestionService.queryPage(queryInfo));
+    }
+
+}

+ 39 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SysUserContractsController.java

@@ -0,0 +1,39 @@
+package com.yonge.cooleshow.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.yonge.cooleshow.biz.dal.entity.SysUserContracts;
+import com.yonge.cooleshow.biz.dal.service.SysUserContractsService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+
+@RequestMapping("sysUserContracts")
+@Api(tags = "用户协议服务")
+@RestController
+public class SysUserContractsController extends BaseController {
+
+	@Autowired
+	private SysUserContractsService sysUserContractsService;
+	
+    @ApiOperation(value = "查询学生最新协议")
+    @GetMapping("/getLatest")
+    @PreAuthorize("@pcs.hasPermissions('sysUserContracts/getLatest')")
+	public HttpResponseResult<SysUserContracts> getLatest(Integer userId) {
+		
+		SysUserContracts sysUserContracts = sysUserContractsService.getLatestUserContract(userId);
+
+		if(sysUserContracts == null){
+			return failed("该学员尚未签署协议");
+		}
+
+		return succeed(sysUserContracts);
+	}
+
+}

+ 48 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/UploadFileController.java

@@ -0,0 +1,48 @@
+package com.yonge.cooleshow.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.UploadReturnBean;
+import com.yonge.toolset.utils.upload.UploadUtil;
+
+/** 
+ * 上传控制层
+ */
+@RestController
+@Api(tags = "文件上传服务")
+public class UploadFileController extends BaseController {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(UploadFileController.class);
+
+	@Autowired
+	private UploadFileService uploadFileService;
+
+	@PostMapping(value = "uploadFile")
+	public Object uploadFile(@ApiParam(value = "上传的文件", required = true) @RequestParam("file") MultipartFile file) {
+		try {
+			if (file != null && StringUtils.isNotBlank(file.getOriginalFilename())) {
+				UploadReturnBean bean = uploadFileService.uploadFile(file.getInputStream(), UploadUtil.getExtension(file.getOriginalFilename()));
+				bean.setName(file.getOriginalFilename());
+				if (bean.isStatus()) {
+					return succeed(bean);
+				}
+				return failed(bean.getMessage());
+			}
+		} catch (Exception e) {
+			LOGGER.error("上传失败", e);
+		}
+		return failed("上传失败");
+	}
+}

+ 33 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/interceptor/OperationLogInterceptor.java

@@ -0,0 +1,33 @@
+package com.yonge.cooleshow.web.interceptor;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.toolset.log.interceptor.AuditLogInterceptor;
+
+@Component
+public class OperationLogInterceptor extends AuditLogInterceptor {
+
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser != null) {
+			setUsername(sysUser.getRealName(),sysUser.getId());
+		}
+		return true;
+	}
+
+}

+ 1 - 1
cooleshow-user/user-biz/pom.xml

@@ -21,7 +21,7 @@
 			<groupId>com.yonge.cooleshow</groupId>
 			<artifactId>cooleshow-common</artifactId>
 		</dependency>
-		
+
 		<dependency>
 			<groupId>com.spring4all</groupId>
 			<artifactId>swagger-spring-boot-starter</artifactId>

+ 9 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysSuggestionDao.java

@@ -0,0 +1,9 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+
+public interface SysSuggestionDao extends BaseDAO<Long, SysSuggestion> {
+
+	
+}

+ 31 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysUserContractsDao.java

@@ -0,0 +1,31 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.yonge.cooleshow.biz.dal.entity.SysUserContracts;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+
+public interface SysUserContractsDao extends BaseDAO<Long, SysUserContracts> {
+
+    /**
+     * @describe 获取用户指定类型的协议记录
+     * @author Joburgess
+     * @date 2020.09.18
+     * @param userId:
+     * @param contractType:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.SysUserContracts>
+     */
+    List<SysUserContracts> getUserContractWithType(@Param("userId") Integer userId,
+                                                   @Param("contractType") SysUserContracts.ContractType contractType,
+                                                   @Param("version") Integer version);
+
+    /**
+     * 获取最近一次的协议
+     * @param userId
+     * @return
+     */
+    SysUserContracts getLatestUserContract(Integer userId);
+
+}

+ 135 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysSuggestion.java

@@ -0,0 +1,135 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import com.yonge.cooleshow.biz.dal.enums.SuggestionType;
+import com.yonge.cooleshow.common.entity.BaseEntity;
+
+/**
+ * 对应数据库表(sys_suggestion):
+ */
+public class SysSuggestion extends BaseEntity {
+
+	/** 编号 */
+	private Long id;
+	
+	/** 联系方式 */
+	@ApiModelProperty(value = "联系方式",required = false)
+	private String mobileNo;
+	
+	/** 标题 */
+	@ApiModelProperty(value = "标题",required = false)
+	private String title;
+	
+	/** 内容 */
+	@ApiModelProperty(value = "内容",required = false)
+	private String content;
+
+	/** 媒体 */
+	@ApiModelProperty(value = "媒体",required = false)
+	private String url;
+	
+	/** 用户编号 */
+	@ApiModelProperty(value = "用户编号",required = false)
+	private Long userId;
+	
+	@ApiModelProperty(value = "客户端类型",required = false)
+	private String clientType;
+
+	@ApiModelProperty(value = "建议类型")
+	private SuggestionType type = SuggestionType.APP;
+
+	@ApiModelProperty(value = "用户名",required = false)
+	private String username;
+	
+	/** 提交时间 */
+	private java.util.Date createTime;
+
+	public String getUrl() {
+		return url;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setMobileNo(String mobileNo){
+		this.mobileNo = mobileNo;
+	}
+	
+	public String getMobileNo(){
+		return this.mobileNo;
+	}
+			
+	public void setTitle(String title){
+		this.title = title;
+	}
+	
+	public String getTitle(){
+		return this.title;
+	}
+			
+	public void setContent(String content){
+		this.content = content;
+	}
+	
+	public String getContent(){
+		return this.content;
+	}
+			
+	public void setUserId(Long userId){
+		this.userId = userId;
+	}
+	
+	public Long getUserId(){
+		return this.userId;
+	}
+			
+	public String getClientType() {
+		return clientType;
+	}
+
+	public void setClientType(String clientType) {
+		this.clientType = clientType;
+	}
+
+	public SuggestionType getType() {
+		return type;
+	}
+
+	public void setType(SuggestionType type) {
+		this.type = type;
+	}
+
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 126 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysUserContracts.java

@@ -0,0 +1,126 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import com.yonge.cooleshow.common.enums.BaseEnum;
+
+/**
+ * 对应数据库表(sys_user_contracts):
+ */
+public class SysUserContracts {
+
+	public enum ContractType implements BaseEnum<String, ContractType> {
+
+		REGISTER("注册"),
+		COURSES("课程购买"),
+		PRODUCT("产品");
+
+		private String desc;
+
+		private ContractType(String desc) {
+			this.desc = desc;
+		}
+
+		@Override
+		public String getCode() {
+			return name();
+		}
+
+		public String getDesc() {
+			return desc;
+		}
+	}
+
+	/**  */
+	private Long id;
+
+	/**  */
+	private Integer userId;
+
+	/** 合同号 */
+	private String contractNo;
+
+	/** 协议类型 */
+	private ContractType type;
+
+	/** 协议地址 */
+	private String url;
+
+	/** 备注 */
+	private String memo;
+
+	private Integer version;
+
+	/** 创建时间 */
+	private java.util.Date createTime;
+
+	public Integer getVersion() {
+		return version;
+	}
+
+	public void setVersion(Integer version) {
+		this.version = version;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public Long getId() {
+		return this.id;
+	}
+
+	public void setUserId(Integer userId) {
+		this.userId = userId;
+	}
+
+	public Integer getUserId() {
+		return this.userId;
+	}
+
+	public void setContractNo(String contractNo) {
+		this.contractNo = contractNo;
+	}
+
+	public String getContractNo() {
+		return this.contractNo;
+	}
+
+	public void setType(ContractType type) {
+		this.type = type;
+	}
+
+	public ContractType getType() {
+		return this.type;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getUrl() {
+		return this.url;
+	}
+
+	public void setMemo(String memo) {
+		this.memo = memo;
+	}
+
+	public String getMemo() {
+		return this.memo;
+	}
+
+	public void setCreateTime(java.util.Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public java.util.Date getCreateTime() {
+		return this.createTime;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 34 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SuggestionType.java

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.yonge.cooleshow.common.enums.BaseEnum;
+
+public enum SuggestionType implements BaseEnum<String, SuggestionType> {
+	APP("APP", "软件反馈"),
+	SMART_PRACTICE("SMART_PRACTICE", "智能陪练");
+
+	private String code;
+
+	private String msg;
+
+	SuggestionType(String code, String msg) {
+		this.code = code;
+		this.msg = msg;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	@Override
+	public String getCode() {
+		return this.code;
+	}
+}

+ 55 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/SysSuggestionQueryInfo.java

@@ -0,0 +1,55 @@
+package com.yonge.cooleshow.biz.dal.queryInfo;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import com.yonge.cooleshow.biz.dal.enums.SuggestionType;
+import com.yonge.cooleshow.common.page.QueryInfo;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/8/10 0010
+ */
+public class SysSuggestionQueryInfo extends QueryInfo {
+
+    @ApiModelProperty(value = "建议类型")
+    private SuggestionType type;
+
+    private String startTime;
+
+    private String endTime;
+
+    @ApiModelProperty(value = "客户端类型",required = false)
+    private String clientType;
+
+    public SuggestionType getType() {
+        return type;
+    }
+
+    public void setType(SuggestionType type) {
+        this.type = type;
+    }
+
+    public String getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(String startTime) {
+        this.startTime = startTime;
+    }
+
+    public String getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(String endTime) {
+        this.endTime = endTime;
+    }
+
+    public String getClientType() {
+        return clientType;
+    }
+
+    public void setClientType(String clientType) {
+        this.clientType = clientType;
+    }
+}

+ 8 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysSuggestionService.java

@@ -0,0 +1,8 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.common.service.BaseService;
+
+public interface SysSuggestionService extends BaseService<Long, SysSuggestion> {
+
+}

+ 27 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysUserContractsService.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import java.util.List;
+
+import com.yonge.cooleshow.biz.dal.entity.SysUserContracts;
+import com.yonge.cooleshow.common.service.BaseService;
+
+public interface SysUserContractsService extends BaseService<Long, SysUserContracts> {
+
+    /**
+     * @describe 获取用户指定类型的协议记录
+     * @author Joburgess
+     * @date 2020.09.18
+     * @param userId:
+     * @param contractType:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.SysUserContracts>
+     */
+    List<SysUserContracts> getUserContractWithType(Integer userId, SysUserContracts.ContractType contractType, Integer contractVersion);
+
+    /**
+     * 获取最近一次的协议
+     * @param userId
+     * @return
+     */
+    SysUserContracts getLatestUserContract(Integer userId);
+
+}

+ 136 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UploadFileService.java

@@ -0,0 +1,136 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.common.entity.UploadReturnBean;
+import com.yonge.cooleshow.common.exception.BizException;
+import com.yonge.toolset.thirdparty.storage.StoragePluginContext;
+import com.yonge.toolset.thirdparty.storage.provider.KS3StoragePlugin;
+import com.yonge.toolset.utils.upload.UploadUtil;
+
+/** 
+ * 上传工具服务层实现类
+ */
+@Service
+public class UploadFileService {
+
+	@Autowired
+	private StoragePluginContext storagePluginContext;
+
+	/** 最大上传大小,单位kb */
+	@Value("${common.upload.maxSize:153600}")
+	private int maxSize;
+
+	/** 支持的扩展名 */
+	@Value("${common.upload.supportExtensions:jpg,jpeg,gif,png,mp3,mid,midi,aac,m4a,mp4,xml,xlsx,xls,doc,docx,txt,pdf,psd,eps,rar,zip}")
+	private String supportExtensions;
+
+	/** 文件根目录 */
+	@Value("/var/tmp/")
+	private String fileRoot;
+
+	public UploadReturnBean uploadFile(InputStream in, String ext) {
+		UploadReturnBean uploadReturn = new UploadReturnBean("", false, "");
+		String fileName = UploadUtil.getFileName(ext);
+
+		String supportType = supportExtensions;
+		if (!UploadUtil.validateImgFile(ext, supportType)) {
+			uploadReturn.setMessage("上传图片格式错误,目前只支持" + supportType);
+			return uploadReturn;
+		}
+
+		String root = fileRoot;
+		if (StringUtils.isBlank(root)) {
+			uploadReturn.setMessage("上传临时目录没有配置");
+			return uploadReturn;
+		}
+
+		String staticFloder = "";
+
+		String folder = UploadUtil.getFileFloder();
+		String filePath = UploadUtil.getFilePath(root, staticFloder, folder);
+		File file = uploadFile(in, filePath, fileName);
+		if (maxSize > 0 && maxSize < file.length() / 1024) {
+			FileUtils.deleteQuietly(file);
+			uploadReturn.setMessage("超出允许的大小(" + (maxSize / 1024) + "M)限制");
+			return uploadReturn;
+		}
+
+		//String url = storagePlugin.uploadFile(staticFloder + folder, file);
+		String url = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME,staticFloder + folder, file);
+
+		FileUtils.deleteQuietly(file);
+		uploadReturn.setStatus(true);
+		uploadReturn.setUrl(url);
+		return uploadReturn;
+	}
+
+
+	@Async
+	public UploadReturnBean uploadImHistoryMsgFile(File msgFile) throws FileNotFoundException {
+		InputStream in = new FileInputStream(msgFile);
+		UploadReturnBean uploadReturn = new UploadReturnBean("", false, "");
+		String fileName = UploadUtil.getFileName(msgFile.getName());
+
+		String root = fileRoot + "im_history_msg/";
+		if (StringUtils.isBlank(root)) {
+			uploadReturn.setMessage("上传临时目录没有配置");
+			return uploadReturn;
+		}
+
+		String staticFloder = "";
+		String folder = UploadUtil.getFileFloder();
+		String filePath = UploadUtil.getFilePath(root, staticFloder, folder);
+		File file = uploadFile(in, filePath, fileName);
+		String url = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME,staticFloder + folder, file);
+
+		FileUtils.deleteQuietly(file);
+
+		uploadReturn.setStatus(true);
+		uploadReturn.setUrl(url);
+		return uploadReturn;
+	}
+
+	public void setMaxSize(int maxSize) {
+		this.maxSize = maxSize;
+	}
+
+	/**
+	 * 上传文件的工具方法
+	 * @param in
+	 * @param path
+	 * @return
+	 */
+	private File uploadFile(InputStream inputStream, String filePath, String fileName) {
+		File file = new File(filePath + "/" + fileName);
+		try {
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			FileOutputStream fos = new FileOutputStream(file);
+			IOUtils.copy(inputStream, fos);
+			if (!file.exists() || file.length() == 0) {
+				throw new BizException("图片上传出现错误,请重新上传");
+			}
+		} catch (IOException e) {
+			throw new BizException("图片上传失败", e);
+		} finally {
+			IOUtils.closeQuietly(inputStream);
+		}
+		return file;
+	}
+
+}

+ 23 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysSuggestionServiceImpl.java

@@ -0,0 +1,23 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.biz.dal.dao.SysSuggestionDao;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+import com.yonge.cooleshow.common.service.impl.BaseServiceImpl;
+
+@Service
+public class SysSuggestionServiceImpl extends BaseServiceImpl<Long, SysSuggestion>  implements SysSuggestionService {
+	
+	@Autowired
+	private SysSuggestionDao sysSuggestionDao;
+
+	@Override
+	public BaseDAO<Long, SysSuggestion> getDAO() {
+		return sysSuggestionDao;
+	}
+	
+}

+ 35 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysUserContractsServiceImpl.java

@@ -0,0 +1,35 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.biz.dal.dao.SysUserContractsDao;
+import com.yonge.cooleshow.biz.dal.entity.SysUserContracts;
+import com.yonge.cooleshow.biz.dal.service.SysUserContractsService;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+import com.yonge.cooleshow.common.service.impl.BaseServiceImpl;
+
+@Service
+public class SysUserContractsServiceImpl extends BaseServiceImpl<Long, SysUserContracts>  implements SysUserContractsService {
+	
+	@Autowired
+	private SysUserContractsDao sysUserContractsDao;
+
+	@Override
+	public BaseDAO<Long, SysUserContracts> getDAO() {
+		return sysUserContractsDao;
+	}
+
+	@Override
+	public List<SysUserContracts> getUserContractWithType(Integer userId, SysUserContracts.ContractType contractType, Integer contractVersion) {
+		return sysUserContractsDao.getUserContractWithType(userId, contractType, contractVersion);
+	}
+
+	@Override
+	public SysUserContracts getLatestUserContract(Integer userId) {
+		return sysUserContractsDao.getLatestUserContract(userId);
+	}
+
+}

+ 101 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysUserContractsMapper.xml

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!-- 这个文件是自动生成的。 不要修改此文件。所有改动将在下次重新自动生成时丢失。 -->
+<mapper namespace="com.yonge.cooleshow.biz.dal.dao.SysUserContractsDao">
+
+	<resultMap type="com.yonge.cooleshow.biz.dal.entity.SysUserContracts"
+			   id="SysUserContracts">
+		<result column="id_" property="id" />
+		<result column="user_id_" property="userId" />
+		<result column="contract_no_" property="contractNo" />
+		<result column="type_" property="type" />
+		<result column="url_" property="url" />
+		<result column="memo_" property="memo" />
+		<result column="create_time_" property="createTime" />
+		<result column="version_" property="version" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="SysUserContracts">
+		SELECT * FROM
+		sys_user_contracts WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="SysUserContracts">
+		SELECT * FROM sys_user_contracts
+		ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.yonge.cooleshow.biz.dal.entity.SysUserContracts"
+			useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
+			AS ID FROM DUAL </selectKey> -->
+		INSERT INTO sys_user_contracts
+		(id_,user_id_,contract_no_,type_,url_,memo_,create_time_,version_)
+		VALUES(#{id},#{userId},#{contractNo},#{type},#{url},#{memo},#{createTime},#{version})
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.yonge.cooleshow.biz.dal.entity.SysUserContracts">
+		UPDATE sys_user_contracts
+		<set>
+			<if test="userId != null">
+				user_id_ = #{userId},
+			</if>
+			<if test="id != null">
+				id_ = #{id},
+			</if>
+			<if test="url != null">
+				url_ = #{url},
+			</if>
+			<if test="memo != null">
+				memo_ = #{memo},
+			</if>
+			<if test="contractNo != null">
+				contract_no_ = #{contractNo},
+			</if>
+			<if test="type != null">
+				type_ = #{type},
+			</if>
+			<if test="createTime != null">
+				create_time_ = #{createTime},
+			</if>
+		</set>
+		WHERE id_ = #{id}
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete">
+		DELETE FROM sys_user_contracts WHERE id_ =
+		#{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="SysUserContracts"
+			parameterType="map">
+		SELECT * FROM sys_user_contracts ORDER BY id_
+		<include refid="global.limit" />
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM
+		sys_user_contracts
+	</select>
+
+	<select id="getUserContractWithType" resultMap="SysUserContracts">
+		SELECT * FROM sys_user_contracts
+		WHERE user_id_=#{userId}
+		  AND type_=#{contractType}
+		  <if test="version!=null">
+			  AND version_=#{version}
+		  </if>
+	</select>
+
+	<select id="getLatestUserContract" resultMap="SysUserContracts">
+		SELECT * FROM sys_user_contracts WHERE user_id_=#{userId} order by id_ desc limit 0,1
+	</select>
+
+</mapper>

+ 64 - 60
cooleshow-user/user-student/pom.xml

@@ -1,72 +1,76 @@
 <?xml version="1.0"?>
 <project
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>com.yonge.cooleshow</groupId>
-    <artifactId>cooleshow-user</artifactId>
-    <version>1.0</version>
-  </parent>
-  <groupId>com.yonge.cooleshow</groupId>
-  <artifactId>user-student</artifactId>
-  <version>1.0</version>
-  <name>user-student</name>
-  <url>http://maven.apache.org</url>
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-  <dependencies>
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.yonge.cooleshow</groupId>
+		<artifactId>cooleshow-user</artifactId>
+		<version>1.0</version>
+	</parent>
+	<groupId>com.yonge.cooleshow</groupId>
+	<artifactId>user-student</artifactId>
+	<version>1.0</version>
+	<name>user-student</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+	<dependencies>
 
-    <dependency>
-      <groupId>com.alibaba.cloud</groupId>
-      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-    </dependency>
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+		</dependency>
 
-    <dependency>
-      <groupId>com.alibaba.cloud</groupId>
-      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
-    </dependency>
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+		</dependency>
 
-    <dependency>
-      <groupId>org.springframework.cloud</groupId>
-      <artifactId>spring-cloud-starter-security</artifactId>
-    </dependency>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-security</artifactId>
+		</dependency>
 
-    <!-- swagger-spring-boot -->
-    <dependency>
-      <groupId>com.spring4all</groupId>
-      <artifactId>swagger-spring-boot-starter</artifactId>
-    </dependency>
+		<!-- swagger-spring-boot -->
+		<dependency>
+			<groupId>com.spring4all</groupId>
+			<artifactId>swagger-spring-boot-starter</artifactId>
+		</dependency>
 
-    <!-- <dependency>
-        <groupId>com.alibaba</groupId>
-        <artifactId>druid-spring-boot-starter</artifactId>
-    </dependency>
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid-spring-boot-starter</artifactId>
+		</dependency>
 
-    <dependency>
-        <groupId>mysql</groupId>
-        <artifactId>mysql-connector-java</artifactId>
-    </dependency>
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
 
-    <dependency>
-        <groupId>com.yonge.toolset</groupId>
-        <artifactId>audit-log</artifactId>
-    </dependency> -->
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>audit-log</artifactId>
+		</dependency>
 
-    <dependency>
-      <groupId>com.yonge.toolset</groupId>
-      <artifactId>thirdparty-component</artifactId>
-      <version>1.0</version>
-    </dependency>
-  </dependencies>
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>thirdparty-component</artifactId>
+		</dependency>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-maven-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
+		<dependency>
+			<groupId>com.yonge.cooleshow</groupId>
+			<artifactId>user-biz</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
 </project>

+ 36 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/config/ResourceServerConfig.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.student.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+
+import com.yonge.cooleshow.common.security.BaseAccessDeniedHandler;
+import com.yonge.cooleshow.common.security.BaseAuthenticationEntryPoint;
+
+@Configuration
+@EnableResourceServer
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+    @Autowired
+    private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+    @Autowired
+    private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable().exceptionHandling().accessDeniedHandler(baseAccessDeniedHandler).authenticationEntryPoint(baseAuthenticationEntryPoint).and()
+                .authorizeRequests().antMatchers("/wechat/*","/v2/api-docs", "/code/*").permitAll().anyRequest().authenticated().and().httpBasic();
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+        resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+    }
+
+}

+ 56 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/config/WebMvcConfig.java

@@ -0,0 +1,56 @@
+package com.yonge.cooleshow.student.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.cooleshow.common.config.LocalFastJsonHttpMessageConverter;
+import com.yonge.cooleshow.student.interceptor.MDCInterceptor;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+	@Autowired
+	private MDCInterceptor mdcInterceptor;
+
+	/**
+	 * 枚举类的转换器 addConverterFactory
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		registry.addConverterFactory(new EnumConverterFactory());
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		// addPathPatterns 用于添加拦截规则, 这里假设拦截 /url 后面的全部链接
+		List<String> includePathPatterns = new ArrayList<String>();
+		includePathPatterns.add("/**");
+
+		// excludePathPatterns 用户排除拦截
+		List<String> excludePathPatterns = new ArrayList<String>();
+		excludePathPatterns.add("/login");
+
+		registry.addInterceptor(mdcInterceptor).addPathPatterns(includePathPatterns).excludePathPatterns(excludePathPatterns);
+
+//		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
+	}
+
+	@Bean
+	public HttpMessageConverters fastJsonHttpMessageConverters() {
+		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
+		List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
+		fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+		converter.setSupportedMediaTypes(fastMediaTypes);
+		return new HttpMessageConverters(converter);
+	}
+}

+ 44 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionController.java

@@ -0,0 +1,44 @@
+package com.yonge.cooleshow.student.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.common.controller.BaseController;
+
+@Api(tags = "意见反馈")
+@RestController
+public class SysSuggestionController extends BaseController {
+
+    @Autowired
+    private SysSuggestionService sysSuggestionService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增")
+    @RequestMapping("sysSuggestion/add")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/add')")
+    public Object add(SysSuggestion sysSuggestion) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        sysSuggestion.setUserId(sysUser.getId().longValue());
+        sysSuggestion.setClientType("STUDENT");
+        if(StringUtils.isEmpty(sysSuggestion.getMobileNo())){
+            sysSuggestion.setMobileNo(sysUser.getPhone());
+        }
+        sysSuggestionService.insert(sysSuggestion);
+        return succeed();
+    }
+
+}

+ 43 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/interceptor/MDCInterceptor.java

@@ -0,0 +1,43 @@
+package com.yonge.cooleshow.student.interceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.toolset.utils.web.WebUtil;
+
+@Component
+public class MDCInterceptor extends HandlerInterceptorAdapter {
+
+	private static final String IP = "ip";
+
+	private static final String USERNAME = "username";
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser != null && sysUser.getId() != null) {
+			// 存储userId以及IP
+			MDC.put(USERNAME, sysUser.getUsername() + "@" + sysUser.getId());
+		}
+		MDC.put(IP, WebUtil.getRemoteIp(request));
+
+		return true;
+	}
+
+	@Override
+	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+		MDC.remove(USERNAME);
+		MDC.remove(IP);
+	}
+}

+ 33 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/interceptor/OperationLogInterceptor.java

@@ -0,0 +1,33 @@
+package com.yonge.cooleshow.student.interceptor;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.toolset.log.interceptor.AuditLogInterceptor;
+
+@Component
+public class OperationLogInterceptor extends AuditLogInterceptor {
+
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser != null && sysUser.getId() != null) {
+			setUsername(sysUser.getRealName(),sysUser.getId());
+		}
+		return true;
+	}
+
+}

+ 55 - 0
cooleshow-user/user-student/src/main/resources/logback-spring.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<property name="LOG_HOME" value="/mdata/logs/cms-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="CONSOLE_LOG_PATTERN"
+		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
+
+	<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder charset="UTF-8">
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="file"
+		class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<FileNamePattern>${LOG_HOME}</FileNamePattern>
+			<MaxHistory>90</MaxHistory>
+			<TimeBasedFileNamingAndTriggeringPolicy
+				class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>20MB</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+		</rollingPolicy>
+
+		<encoder>
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<logger name="com.ym.mec" level="INFO" />
+
+	<!--开发环境:打印控制台 -->
+	<springProfile name="dev">
+		<root level="INFO">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+	
+	<springProfile name="test">
+		<root level="INFO">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+	<!--生产环境:输出到文件 -->
+	<springProfile name="prod">
+		<root level="WARN">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+</configuration>

+ 64 - 60
cooleshow-user/user-teacher/pom.xml

@@ -1,72 +1,76 @@
 <?xml version="1.0"?>
 <project
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>com.yonge.cooleshow</groupId>
-        <artifactId>cooleshow-user</artifactId>
-        <version>1.0</version>
-    </parent>
-    <groupId>com.yonge.cooleshow</groupId>
-    <artifactId>user-teacher</artifactId>
-    <version>1.0</version>
-    <name>user-teacher</name>
-    <url>http://maven.apache.org</url>
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    </properties>
-    <dependencies>
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.yonge.cooleshow</groupId>
+		<artifactId>cooleshow-user</artifactId>
+		<version>1.0</version>
+	</parent>
+	<groupId>com.yonge.cooleshow</groupId>
+	<artifactId>user-teacher</artifactId>
+	<version>1.0</version>
+	<name>user-teacher</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+	<dependencies>
 
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-security</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-security</artifactId>
+		</dependency>
 
-        <!-- swagger-spring-boot -->
-        <dependency>
-            <groupId>com.spring4all</groupId>
-            <artifactId>swagger-spring-boot-starter</artifactId>
-        </dependency>
+		<!-- swagger-spring-boot -->
+		<dependency>
+			<groupId>com.spring4all</groupId>
+			<artifactId>swagger-spring-boot-starter</artifactId>
+		</dependency>
 
-        <!-- <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>druid-spring-boot-starter</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid-spring-boot-starter</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>com.yonge.toolset</groupId>
-            <artifactId>audit-log</artifactId>
-        </dependency> -->
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>audit-log</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>com.yonge.toolset</groupId>
-            <artifactId>thirdparty-component</artifactId>
-            <version>1.0</version>
-        </dependency>
-    </dependencies>
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>thirdparty-component</artifactId>
+		</dependency>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-maven-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
+		<dependency>
+			<groupId>com.yonge.cooleshow</groupId>
+			<artifactId>user-biz</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
 </project>

+ 42 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/config/ResourceServerConfig.java

@@ -0,0 +1,42 @@
+package com.yonge.cooleshow.teacher.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+
+import com.yonge.cooleshow.common.security.BaseAccessDeniedHandler;
+import com.yonge.cooleshow.common.security.BaseAuthenticationEntryPoint;
+
+@Configuration
+@EnableResourceServer
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+	@Autowired
+	private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+	@Autowired
+	private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+	@Override
+	public void configure(HttpSecurity http) throws Exception {
+		http.csrf()
+				.disable()
+				.exceptionHandling()
+				.accessDeniedHandler(baseAccessDeniedHandler)
+				.authenticationEntryPoint(baseAuthenticationEntryPoint)
+				.and()
+				.authorizeRequests()
+				.antMatchers("/v2/api-docs", "/code/*").permitAll().anyRequest().authenticated().and().httpBasic();
+	}
+
+	@Override
+	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+		resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+	}
+
+}

+ 57 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/config/WebMvcConfig.java

@@ -0,0 +1,57 @@
+package com.yonge.cooleshow.teacher.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.cooleshow.common.config.LocalFastJsonHttpMessageConverter;
+import com.yonge.cooleshow.teacher.interceptor.MDCInterceptor;
+import com.yonge.cooleshow.teacher.interceptor.OperationLogInterceptor;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+	@Autowired
+	private MDCInterceptor mdcInterceptor;
+
+	@Autowired
+	private OperationLogInterceptor operationLogInterceptor;
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		List<String> includePathPatterns = new ArrayList<String>();
+		includePathPatterns.add("/**");
+		List<String> excludePathPatterns = new ArrayList<String>();
+		excludePathPatterns.add("/login");
+		registry.addInterceptor(mdcInterceptor).addPathPatterns(includePathPatterns).excludePathPatterns(excludePathPatterns);
+
+//		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
+	}
+
+	/**
+	 * 枚举类的转换器 addConverterFactory
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		registry.addConverterFactory(new EnumConverterFactory());
+	}
+	
+	@Bean
+    public HttpMessageConverters fastJsonHttpMessageConverters(){
+		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
+        List<MediaType> fastMediaTypes =  new ArrayList<MediaType>();
+        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+        converter.setSupportedMediaTypes(fastMediaTypes);
+        return new HttpMessageConverters(converter);
+    }
+
+}

+ 44 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionController.java

@@ -0,0 +1,44 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.common.controller.BaseController;
+
+@Api(tags = "意见反馈")
+@RestController
+public class SysSuggestionController extends BaseController {
+
+    @Autowired
+    private SysSuggestionService sysSuggestionService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增")
+    @RequestMapping("sysSuggestion/add")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/add')")
+    public Object add(SysSuggestion sysSuggestion) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        sysSuggestion.setUserId(sysUser.getId().longValue());
+        sysSuggestion.setClientType("TEACHER");
+        if(StringUtils.isEmpty(sysSuggestion.getMobileNo())){
+            sysSuggestion.setMobileNo(sysUser.getPhone());
+        }
+        sysSuggestionService.insert(sysSuggestion);
+        return succeed();
+    }
+
+}

+ 43 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/interceptor/MDCInterceptor.java

@@ -0,0 +1,43 @@
+package com.yonge.cooleshow.teacher.interceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.toolset.utils.web.WebUtil;
+
+@Component
+public class MDCInterceptor extends HandlerInterceptorAdapter {
+
+	private static final String IP = "ip";
+
+	private static final String USERNAME = "username";
+	
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser != null && sysUser.getId() != null) {
+			// 存储userId以及IP
+			MDC.put(USERNAME, sysUser.getUsername() + "@" + sysUser.getId());
+		}
+		MDC.put(IP, WebUtil.getRemoteIp(request));
+
+		return true;
+	}
+
+	@Override
+	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+	}
+}

+ 33 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/interceptor/OperationLogInterceptor.java

@@ -0,0 +1,33 @@
+package com.yonge.cooleshow.teacher.interceptor;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.toolset.log.interceptor.AuditLogInterceptor;
+
+@Component
+public class OperationLogInterceptor extends AuditLogInterceptor {
+
+	@Autowired
+	@Lazy
+	private SysUserFeignService sysUserFeignService;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser != null && sysUser.getId() != null) {
+			setUsername(sysUser.getRealName(),sysUser.getId());
+		}
+		return true;
+	}
+
+}

+ 55 - 0
cooleshow-user/user-teacher/src/main/resources/logback-spring.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<property name="LOG_HOME" value="/mdata/logs/cms-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="CONSOLE_LOG_PATTERN"
+		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
+
+	<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder charset="UTF-8">
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="file"
+		class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<FileNamePattern>${LOG_HOME}</FileNamePattern>
+			<MaxHistory>90</MaxHistory>
+			<TimeBasedFileNamingAndTriggeringPolicy
+				class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>20MB</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+		</rollingPolicy>
+
+		<encoder>
+			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
+		</encoder>
+	</appender>
+
+	<logger name="com.ym.mec" level="INFO" />
+
+	<!--开发环境:打印控制台 -->
+	<springProfile name="dev">
+		<root level="INFO">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+	
+	<springProfile name="test">
+		<root level="INFO">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+	<!--生产环境:输出到文件 -->
+	<springProfile name="prod">
+		<root level="WARN">
+			<appender-ref ref="stdout" />
+			<appender-ref ref="file" />
+		</root>
+	</springProfile>
+
+</configuration>

+ 6 - 0
pom.xml

@@ -96,6 +96,12 @@
 			</dependency>
 
 			<dependency>
+				<groupId>com.yonge.cooleshow</groupId>
+				<artifactId>user-biz</artifactId>
+				<version>1.0</version>
+			</dependency>
+
+			<dependency>
 				<groupId>com.alibaba.cloud</groupId>
 				<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 				<version>2.1.4.RELEASE</version>