commit:修改微服务工程目录名称

This commit is contained in:
Jerry
2020-09-26 20:14:58 +08:00
parent d05ad53a17
commit 322b3bc19d
463 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<groupId>com.orange.demo</groupId>
<artifactId>stats</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>stats-service</artifactId>
<version>1.0.0</version>
<name>stats-service</name>
<packaging>jar</packaging>
<dependencies>
<!-- 业务组件依赖 -->
<dependency>
<groupId>com.orange.demo</groupId>
<artifactId>stats-interface</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.orange.demo</groupId>
<artifactId>course-class-interface</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.orange.demo</groupId>
<artifactId>common-redis</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.orange.demo</groupId>
<artifactId>common-sequence</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,22 @@
package com.orange.demo.statsservice;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
/**
* stats服务启动类。
*
* @author Orange Team
* @date 2020-08-08
*/
@SpringCloudApplication
@EnableFeignClients(basePackages = "com.orange.demo")
@ComponentScan("com.orange.demo")
public class StatsApplication {
public static void main(String[] args) {
SpringApplication.run(StatsApplication.class, args);
}
}

View File

@@ -0,0 +1,37 @@
package com.orange.demo.statsservice.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
* 应用程序自定义的程序属性配置文件。
* 在yml格式的配置文件中配置application开头应用配置信息
*
* application:
* uploadFileBaseDir: /user/xxx/fileRoot/
* defaultSomething: defaultValue
*
* @author Orange Team
* @date 2020-08-08
*/
@Data
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "application")
public class ApplicationConfig {
/**
* 上传文件的基础目录
*/
private String uploadFileBaseDir;
/**
* 每个微服务的url目录上下文如(/admin/upms),通常和网关的路由目录一致。
*/
private String serviceContextPath;
/**
* 是否忽略远程调用中出现的任何错误,包括逻辑异常和系统异常。
* 通常在调试和测试阶段设置为false以便及时发现问题。
*/
private Boolean ignoreRpcError;
}

View File

@@ -0,0 +1,30 @@
package com.orange.demo.statsservice.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import tk.mybatis.spring.annotation.MapperScan;
import javax.sql.DataSource;
/**
* 数据源配置Bean对象。
*
* @author Orange Team
* @date 2020-08-08
*/
@Configuration
@EnableTransactionManagement
@MapperScan(value = {"com.orange.demo.*.dao"})
public class DataSourceConfig {
@Bean(initMethod = "init", destroyMethod = "close")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DataSource druidDataSource() {
return DruidDataSourceBuilder.create().build();
}
}

View File

@@ -0,0 +1,225 @@
package com.orange.demo.statsservice.controller;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.orange.demo.statsservice.model.*;
import com.orange.demo.statsservice.service.*;
import com.orange.demo.statsinterface.dto.*;
import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.util.*;
import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.base.controller.BaseController;
import com.orange.demo.common.core.base.service.BaseService;
import com.orange.demo.common.core.annotation.MyRequestBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 课程统计操作控制器类。
*
* @author Orange Team
* @date 2020-08-08
*/
@Slf4j
@RestController
@RequestMapping("/courseTransStats")
public class CourseTransStatsController extends BaseController<CourseTransStats, CourseTransStatsDto, Long> {
@Autowired
private CourseTransStatsService courseTransStatsService;
@Override
protected BaseService<CourseTransStats, CourseTransStatsDto, Long> service() {
return courseTransStatsService;
}
/**
* 列出符合过滤条件的课程统计列表。
*
* @param courseTransStatsDtoFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody("courseTransStatsFilter") CourseTransStatsDto courseTransStatsDtoFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
CourseTransStats courseTransStatsFilter = CourseTransStats.INSTANCE.toModel(courseTransStatsDtoFilter);
String orderBy = MyOrderParam.buildOrderBy(orderParam, CourseTransStats.class);
List<CourseTransStats> courseTransStatsList =
courseTransStatsService.getCourseTransStatsListWithRelation(courseTransStatsFilter, orderBy);
long totalCount = 0L;
if (courseTransStatsList instanceof Page) {
totalCount = ((Page<CourseTransStats>) courseTransStatsList).getTotal();
}
// 分页连同对象数据转换copy工作下面的方法一并完成。
Tuple2<List<CourseTransStatsDto>, Long> responseData =
new Tuple2<>(CourseTransStats.INSTANCE.fromModelList(courseTransStatsList), totalCount);
return ResponseResult.success(MyPageUtil.makeResponseData(responseData));
}
/**
* 分组列出符合过滤条件的课程统计列表。
*
* @param courseTransStatsDtoFilter 过滤对象。
* @param groupParam 分组参数。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/listWithGroup")
public ResponseResult<JSONObject> listWithGroup(
@MyRequestBody("courseTransStatsFilter") CourseTransStatsDto courseTransStatsDtoFilter,
@MyRequestBody MyGroupParam groupParam,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
String orderBy = MyOrderParam.buildOrderBy(orderParam, CourseTransStats.class);
groupParam = MyGroupParam.buildGroupBy(groupParam, CourseTransStats.class);
if (groupParam == null) {
return ResponseResult.error(
ErrorCodeEnum.INVALID_ARGUMENT_FORMAT, "数据参数错误,分组参数不能为空!");
}
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
CourseTransStats filter = CourseTransStats.INSTANCE.toModel(courseTransStatsDtoFilter);
MyGroupCriteria criteria = groupParam.getGroupCriteria();
List<CourseTransStats> resultList = courseTransStatsService.getGroupedCourseTransStatsListWithRelation(
filter, criteria.getGroupSelect(), criteria.getGroupBy(), orderBy);
// 分页连同对象数据转换copy工作下面的方法一并完成。
JSONObject responseData = MyPageUtil.makeResponseData(resultList, CourseTransStats.INSTANCE);
return ResponseResult.success(responseData);
}
/**
* 查看指定课程统计对象详情。
*
* @param statsId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<CourseTransStatsDto> view(@RequestParam Long statsId) {
if (MyCommonUtil.existBlankArgument(statsId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
CourseTransStats courseTransStats =
courseTransStatsService.getByIdWithRelation(statsId, MyRelationParam.full());
if (courseTransStats == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
CourseTransStatsDto courseTransStatsDto = CourseTransStats.INSTANCE.fromModel(courseTransStats);
return ResponseResult.success(courseTransStatsDto);
}
/**
* 根据主键Id集合获取数据对象集合。仅限于微服务间远程接口调用。
*
* @param statsIds 主键Id集合。
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象集合。
*/
@PostMapping("/listByIds")
public ResponseResult<List<CourseTransStatsDto>> listByIds(
@RequestParam Set<Long> statsIds, @RequestParam Boolean withDict) {
return super.baseListByIds(statsIds, withDict, CourseTransStats.INSTANCE);
}
/**
* 根据主键Id获取数据对象。仅限于微服务间远程接口调用。
*
* @param statsId 主键Id。
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象数据。
*/
@PostMapping("/getById")
public ResponseResult<CourseTransStatsDto> getById(
@RequestParam Long statsId, @RequestParam Boolean withDict) {
return super.baseGetById(statsId, withDict, CourseTransStats.INSTANCE);
}
/**
* 判断参数列表中指定的主键Id集合是否全部存在。仅限于微服务间远程接口调用。
*
* @param statsIds 主键Id集合。
* @return 应答结果对象包含true全部存在否则false。
*/
@PostMapping("/existIds")
public ResponseResult<Boolean> existIds(@RequestParam Set<Long> statsIds) {
return super.baseExistIds(statsIds);
}
/**
* 判断参数列表中指定的主键Id是否存在。仅限于微服务间远程接口调用。
*
* @param statsId 主键Id。
* @return 应答结果对象包含true表示存在否则false。
*/
@PostMapping("/existId")
public ResponseResult<Boolean> existId(@RequestParam Long statsId) {
return super.baseExistId(statsId);
}
/**
* 复杂的查询调用,包括(in list)过滤,对象条件过滤,分组和排序等。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/listBy")
public ResponseResult<List<CourseTransStatsDto>> listBy(@RequestBody MyQueryParam queryParam) {
return super.baseListBy(queryParam, CourseTransStats.INSTANCE);
}
/**
* 复杂的查询调用,包括(in list)过滤,对象条件过滤,分组和排序等。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/listMapBy")
public ResponseResult<List<Map<String, Object>>> listMapBy(@RequestBody MyQueryParam queryParam) {
return super.baseListMapBy(queryParam, CourseTransStats.INSTANCE);
}
/**
* 复杂的查询调用,仅返回单体记录。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/getBy")
public ResponseResult<CourseTransStatsDto> getBy(@RequestBody MyQueryParam queryParam) {
return super.baseGetBy(queryParam, CourseTransStats.INSTANCE);
}
/**
* 获取远程主对象中符合查询条件的数据数量。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含结果数量。
*/
@PostMapping("/countBy")
public ResponseResult<Integer> countBy(@RequestBody MyQueryParam queryParam) {
return super.baseCountBy(queryParam);
}
/**
* 获取远程对象中符合查询条件的分组聚合计算Map列表。
*
* @param aggregationParam 聚合参数。
* @return 应该结果对象包含聚合计算后的分组Map列表。
*/
@PostMapping("/aggregateBy")
public ResponseResult<List<Map<String, Object>>> aggregateBy(@RequestBody MyAggregationParam aggregationParam) {
return super.baseAggregateBy(aggregationParam);
}
}

View File

@@ -0,0 +1,225 @@
package com.orange.demo.statsservice.controller;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.orange.demo.statsservice.model.*;
import com.orange.demo.statsservice.service.*;
import com.orange.demo.statsinterface.dto.*;
import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.util.*;
import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.base.controller.BaseController;
import com.orange.demo.common.core.base.service.BaseService;
import com.orange.demo.common.core.annotation.MyRequestBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 学生行为统计操作控制器类。
*
* @author Orange Team
* @date 2020-08-08
*/
@Slf4j
@RestController
@RequestMapping("/studentActionStats")
public class StudentActionStatsController extends BaseController<StudentActionStats, StudentActionStatsDto, Long> {
@Autowired
private StudentActionStatsService studentActionStatsService;
@Override
protected BaseService<StudentActionStats, StudentActionStatsDto, Long> service() {
return studentActionStatsService;
}
/**
* 列出符合过滤条件的学生行为统计列表。
*
* @param studentActionStatsDtoFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody("studentActionStatsFilter") StudentActionStatsDto studentActionStatsDtoFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
StudentActionStats studentActionStatsFilter = StudentActionStats.INSTANCE.toModel(studentActionStatsDtoFilter);
String orderBy = MyOrderParam.buildOrderBy(orderParam, StudentActionStats.class);
List<StudentActionStats> studentActionStatsList =
studentActionStatsService.getStudentActionStatsListWithRelation(studentActionStatsFilter, orderBy);
long totalCount = 0L;
if (studentActionStatsList instanceof Page) {
totalCount = ((Page<StudentActionStats>) studentActionStatsList).getTotal();
}
// 分页连同对象数据转换copy工作下面的方法一并完成。
Tuple2<List<StudentActionStatsDto>, Long> responseData =
new Tuple2<>(StudentActionStats.INSTANCE.fromModelList(studentActionStatsList), totalCount);
return ResponseResult.success(MyPageUtil.makeResponseData(responseData));
}
/**
* 分组列出符合过滤条件的学生行为统计列表。
*
* @param studentActionStatsDtoFilter 过滤对象。
* @param groupParam 分组参数。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/listWithGroup")
public ResponseResult<JSONObject> listWithGroup(
@MyRequestBody("studentActionStatsFilter") StudentActionStatsDto studentActionStatsDtoFilter,
@MyRequestBody MyGroupParam groupParam,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
String orderBy = MyOrderParam.buildOrderBy(orderParam, StudentActionStats.class);
groupParam = MyGroupParam.buildGroupBy(groupParam, StudentActionStats.class);
if (groupParam == null) {
return ResponseResult.error(
ErrorCodeEnum.INVALID_ARGUMENT_FORMAT, "数据参数错误,分组参数不能为空!");
}
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
StudentActionStats filter = StudentActionStats.INSTANCE.toModel(studentActionStatsDtoFilter);
MyGroupCriteria criteria = groupParam.getGroupCriteria();
List<StudentActionStats> resultList = studentActionStatsService.getGroupedStudentActionStatsListWithRelation(
filter, criteria.getGroupSelect(), criteria.getGroupBy(), orderBy);
// 分页连同对象数据转换copy工作下面的方法一并完成。
JSONObject responseData = MyPageUtil.makeResponseData(resultList, StudentActionStats.INSTANCE);
return ResponseResult.success(responseData);
}
/**
* 查看指定学生行为统计对象详情。
*
* @param statsId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<StudentActionStatsDto> view(@RequestParam Long statsId) {
if (MyCommonUtil.existBlankArgument(statsId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
StudentActionStats studentActionStats =
studentActionStatsService.getByIdWithRelation(statsId, MyRelationParam.full());
if (studentActionStats == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
StudentActionStatsDto studentActionStatsDto = StudentActionStats.INSTANCE.fromModel(studentActionStats);
return ResponseResult.success(studentActionStatsDto);
}
/**
* 根据主键Id集合获取数据对象集合。仅限于微服务间远程接口调用。
*
* @param statsIds 主键Id集合。
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象集合。
*/
@PostMapping("/listByIds")
public ResponseResult<List<StudentActionStatsDto>> listByIds(
@RequestParam Set<Long> statsIds, @RequestParam Boolean withDict) {
return super.baseListByIds(statsIds, withDict, StudentActionStats.INSTANCE);
}
/**
* 根据主键Id获取数据对象。仅限于微服务间远程接口调用。
*
* @param statsId 主键Id。
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象数据。
*/
@PostMapping("/getById")
public ResponseResult<StudentActionStatsDto> getById(
@RequestParam Long statsId, @RequestParam Boolean withDict) {
return super.baseGetById(statsId, withDict, StudentActionStats.INSTANCE);
}
/**
* 判断参数列表中指定的主键Id集合是否全部存在。仅限于微服务间远程接口调用。
*
* @param statsIds 主键Id集合。
* @return 应答结果对象包含true全部存在否则false。
*/
@PostMapping("/existIds")
public ResponseResult<Boolean> existIds(@RequestParam Set<Long> statsIds) {
return super.baseExistIds(statsIds);
}
/**
* 判断参数列表中指定的主键Id是否存在。仅限于微服务间远程接口调用。
*
* @param statsId 主键Id。
* @return 应答结果对象包含true表示存在否则false。
*/
@PostMapping("/existId")
public ResponseResult<Boolean> existId(@RequestParam Long statsId) {
return super.baseExistId(statsId);
}
/**
* 复杂的查询调用,包括(in list)过滤,对象条件过滤,分组和排序等。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/listBy")
public ResponseResult<List<StudentActionStatsDto>> listBy(@RequestBody MyQueryParam queryParam) {
return super.baseListBy(queryParam, StudentActionStats.INSTANCE);
}
/**
* 复杂的查询调用,包括(in list)过滤,对象条件过滤,分组和排序等。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/listMapBy")
public ResponseResult<List<Map<String, Object>>> listMapBy(@RequestBody MyQueryParam queryParam) {
return super.baseListMapBy(queryParam, StudentActionStats.INSTANCE);
}
/**
* 复杂的查询调用,仅返回单体记录。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/getBy")
public ResponseResult<StudentActionStatsDto> getBy(@RequestBody MyQueryParam queryParam) {
return super.baseGetBy(queryParam, StudentActionStats.INSTANCE);
}
/**
* 获取远程主对象中符合查询条件的数据数量。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含结果数量。
*/
@PostMapping("/countBy")
public ResponseResult<Integer> countBy(@RequestBody MyQueryParam queryParam) {
return super.baseCountBy(queryParam);
}
/**
* 获取远程对象中符合查询条件的分组聚合计算Map列表。
*
* @param aggregationParam 聚合参数。
* @return 应该结果对象包含聚合计算后的分组Map列表。
*/
@PostMapping("/aggregateBy")
public ResponseResult<List<Map<String, Object>>> aggregateBy(@RequestBody MyAggregationParam aggregationParam) {
return super.baseAggregateBy(aggregationParam);
}
}

View File

@@ -0,0 +1,276 @@
package com.orange.demo.statsservice.controller;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.orange.demo.statsservice.model.*;
import com.orange.demo.statsservice.service.*;
import com.orange.demo.statsinterface.dto.*;
import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.util.*;
import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.base.controller.BaseController;
import com.orange.demo.common.core.base.service.BaseService;
import com.orange.demo.common.core.annotation.MyRequestBody;
import com.orange.demo.common.core.validator.UpdateGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.groups.Default;
import java.util.*;
/**
* 学生行为流水操作控制器类。
*
* @author Orange Team
* @date 2020-08-08
*/
@Slf4j
@RestController
@RequestMapping("/studentActionTrans")
public class StudentActionTransController extends BaseController<StudentActionTrans, StudentActionTransDto, Long> {
@Autowired
private StudentActionTransService studentActionTransService;
@Override
protected BaseService<StudentActionTrans, StudentActionTransDto, Long> service() {
return studentActionTransService;
}
/**
* 新增学生行为流水数据。
*
* @param studentActionTransDto 新增对象。
* @return 应答结果对象包含新增对象主键Id。
*/
@PostMapping("/add")
public ResponseResult<JSONObject> add(@MyRequestBody("studentActionTrans") StudentActionTransDto studentActionTransDto) {
String errorMessage = MyCommonUtil.getModelValidationError(studentActionTransDto);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
StudentActionTrans studentActionTrans = StudentActionTrans.INSTANCE.toModel(studentActionTransDto);
// 验证远程服务关联Id的数据合法性
CallResult remoteCallResult = studentActionTransService.verifyRemoteRelatedData(studentActionTrans, null);
if (!remoteCallResult.isSuccess()) {
errorMessage = remoteCallResult.getErrorMessage();
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
studentActionTrans = studentActionTransService.saveNew(studentActionTrans);
JSONObject responseData = new JSONObject();
responseData.put("transId", studentActionTrans.getTransId());
return ResponseResult.success(responseData);
}
/**
* 更新学生行为流水数据。
*
* @param studentActionTransDto 更新对象。
* @return 应答结果对象。
*/
@PostMapping("/update")
public ResponseResult<Void> update(@MyRequestBody("studentActionTrans") StudentActionTransDto studentActionTransDto) {
String errorMessage = MyCommonUtil.getModelValidationError(studentActionTransDto, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
StudentActionTrans studentActionTrans = StudentActionTrans.INSTANCE.toModel(studentActionTransDto);
StudentActionTrans originalStudentActionTrans = studentActionTransService.getById(studentActionTrans.getTransId());
if (originalStudentActionTrans == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
// 验证远程服务关联Id的数据合法性
CallResult remoteCallResult = studentActionTransService.verifyRemoteRelatedData(studentActionTrans, originalStudentActionTrans);
if (!remoteCallResult.isSuccess()) {
errorMessage = remoteCallResult.getErrorMessage();
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATAED_FAILED, errorMessage);
}
if (!studentActionTransService.update(studentActionTrans, originalStudentActionTrans)) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
/**
* 删除学生行为流水数据。
*
* @param transId 删除对象主键Id。
* @return 应答结果对象。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long transId) {
String errorMessage;
if (MyCommonUtil.existBlankArgument(transId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
// 验证关联Id的数据合法性
StudentActionTrans originalStudentActionTrans = studentActionTransService.getById(transId);
if (originalStudentActionTrans == null) {
//NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!studentActionTransService.remove(transId)) {
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 列出符合过滤条件的学生行为流水列表。
*
* @param studentActionTransDtoFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<JSONObject> list(
@MyRequestBody("studentActionTransFilter") StudentActionTransDto studentActionTransDtoFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
StudentActionTrans studentActionTransFilter = StudentActionTrans.INSTANCE.toModel(studentActionTransDtoFilter);
String orderBy = MyOrderParam.buildOrderBy(orderParam, StudentActionTrans.class);
List<StudentActionTrans> studentActionTransList =
studentActionTransService.getStudentActionTransListWithRelation(studentActionTransFilter, orderBy);
long totalCount = 0L;
if (studentActionTransList instanceof Page) {
totalCount = ((Page<StudentActionTrans>) studentActionTransList).getTotal();
}
// 分页连同对象数据转换copy工作下面的方法一并完成。
Tuple2<List<StudentActionTransDto>, Long> responseData =
new Tuple2<>(StudentActionTrans.INSTANCE.fromModelList(studentActionTransList), totalCount);
return ResponseResult.success(MyPageUtil.makeResponseData(responseData));
}
/**
* 查看指定学生行为流水对象详情。
*
* @param transId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<StudentActionTransDto> view(@RequestParam Long transId) {
if (MyCommonUtil.existBlankArgument(transId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
StudentActionTrans studentActionTrans =
studentActionTransService.getByIdWithRelation(transId, MyRelationParam.full());
if (studentActionTrans == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
StudentActionTransDto studentActionTransDto = StudentActionTrans.INSTANCE.fromModel(studentActionTrans);
return ResponseResult.success(studentActionTransDto);
}
/**
* 根据主键Id集合获取数据对象集合。仅限于微服务间远程接口调用。
*
* @param transIds 主键Id集合。
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象集合。
*/
@PostMapping("/listByIds")
public ResponseResult<List<StudentActionTransDto>> listByIds(
@RequestParam Set<Long> transIds, @RequestParam Boolean withDict) {
return super.baseListByIds(transIds, withDict, StudentActionTrans.INSTANCE);
}
/**
* 根据主键Id获取数据对象。仅限于微服务间远程接口调用。
*
* @param transId 主键Id。
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象数据。
*/
@PostMapping("/getById")
public ResponseResult<StudentActionTransDto> getById(
@RequestParam Long transId, @RequestParam Boolean withDict) {
return super.baseGetById(transId, withDict, StudentActionTrans.INSTANCE);
}
/**
* 判断参数列表中指定的主键Id集合是否全部存在。仅限于微服务间远程接口调用。
*
* @param transIds 主键Id集合。
* @return 应答结果对象包含true全部存在否则false。
*/
@PostMapping("/existIds")
public ResponseResult<Boolean> existIds(@RequestParam Set<Long> transIds) {
return super.baseExistIds(transIds);
}
/**
* 判断参数列表中指定的主键Id是否存在。仅限于微服务间远程接口调用。
*
* @param transId 主键Id。
* @return 应答结果对象包含true表示存在否则false。
*/
@PostMapping("/existId")
public ResponseResult<Boolean> existId(@RequestParam Long transId) {
return super.baseExistId(transId);
}
/**
* 复杂的查询调用,包括(in list)过滤,对象条件过滤,分组和排序等。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/listBy")
public ResponseResult<List<StudentActionTransDto>> listBy(@RequestBody MyQueryParam queryParam) {
return super.baseListBy(queryParam, StudentActionTrans.INSTANCE);
}
/**
* 复杂的查询调用,包括(in list)过滤,对象条件过滤,分组和排序等。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/listMapBy")
public ResponseResult<List<Map<String, Object>>> listMapBy(@RequestBody MyQueryParam queryParam) {
return super.baseListMapBy(queryParam, StudentActionTrans.INSTANCE);
}
/**
* 复杂的查询调用,仅返回单体记录。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果集。
*/
@PostMapping("/getBy")
public ResponseResult<StudentActionTransDto> getBy(@RequestBody MyQueryParam queryParam) {
return super.baseGetBy(queryParam, StudentActionTrans.INSTANCE);
}
/**
* 获取远程主对象中符合查询条件的数据数量。主要用于微服务间远程过程调用。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含结果数量。
*/
@PostMapping("/countBy")
public ResponseResult<Integer> countBy(@RequestBody MyQueryParam queryParam) {
return super.baseCountBy(queryParam);
}
/**
* 获取远程对象中符合查询条件的分组聚合计算Map列表。
*
* @param aggregationParam 聚合参数。
* @return 应该结果对象包含聚合计算后的分组Map列表。
*/
@PostMapping("/aggregateBy")
public ResponseResult<List<Map<String, Object>>> aggregateBy(@RequestBody MyAggregationParam aggregationParam) {
return super.baseAggregateBy(aggregationParam);
}
}

View File

@@ -0,0 +1,59 @@
package com.orange.demo.statsservice.dao;
import com.orange.demo.common.core.base.dao.BaseDaoMapper;
import com.orange.demo.statsservice.model.CourseTransStats;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 课程统计数据操作访问接口。
*
* @author Orange Team
* @date 2020-08-08
*/
public interface CourseTransStatsMapper extends BaseDaoMapper<CourseTransStats> {
/**
* 获取分组计算后的数据对象列表。
*
* @param courseTransStatsFilter 主表过滤对象。
* @param groupSelect 分组显示字段列表字符串SELECT从句的参数。
* @param groupBy 分组字段列表字符串GROUP BY从句的参数。
* @param orderBy 排序字符串ORDER BY从句的参数。
* @return 对象列表。
*/
List<CourseTransStats> getGroupedCourseTransStatsList(
@Param("courseTransStatsFilter") CourseTransStats courseTransStatsFilter,
@Param("groupSelect") String groupSelect,
@Param("groupBy") String groupBy,
@Param("orderBy") String orderBy);
/**
* 获取过滤后的对象列表。
*
* @param inFilterColumn 参与(In-list)过滤的数据表列。
* @param inFilterValues 参与(In-list)过滤的数据表列值集合。
* @param courseTransStatsFilter 过滤对象。
* @param orderBy 排序字符串order by从句的参数。
* @return 对象列表。
*/
<M> List<CourseTransStats> getCourseTransStatsList(
@Param("inFilterColumn") String inFilterColumn,
@Param("inFilterValues") Set<M> inFilterValues,
@Param("courseTransStatsFilter") CourseTransStats courseTransStatsFilter,
@Param("orderBy") String orderBy);
/**
* 获取对象列表过滤条件中包含like和between条件以及指定属性的(in list)过滤条件。
*
* @param inFilterColumn 参与(In-list)过滤的数据表列。
* @param inFilterValues 参与(In-list)过滤的数据表列值集合。
* @param courseTransStatsFilter 过滤对象。
* @return 对象列表。
*/
<M> Integer getCourseTransStatsCount(
@Param("inFilterColumn") String inFilterColumn,
@Param("inFilterValues") Set<M> inFilterValues,
@Param("courseTransStatsFilter") CourseTransStats courseTransStatsFilter);
}

View File

@@ -0,0 +1,59 @@
package com.orange.demo.statsservice.dao;
import com.orange.demo.common.core.base.dao.BaseDaoMapper;
import com.orange.demo.statsservice.model.StudentActionStats;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 学生行为统计数据操作访问接口。
*
* @author Orange Team
* @date 2020-08-08
*/
public interface StudentActionStatsMapper extends BaseDaoMapper<StudentActionStats> {
/**
* 获取分组计算后的数据对象列表。
*
* @param studentActionStatsFilter 主表过滤对象。
* @param groupSelect 分组显示字段列表字符串SELECT从句的参数。
* @param groupBy 分组字段列表字符串GROUP BY从句的参数。
* @param orderBy 排序字符串ORDER BY从句的参数。
* @return 对象列表。
*/
List<StudentActionStats> getGroupedStudentActionStatsList(
@Param("studentActionStatsFilter") StudentActionStats studentActionStatsFilter,
@Param("groupSelect") String groupSelect,
@Param("groupBy") String groupBy,
@Param("orderBy") String orderBy);
/**
* 获取过滤后的对象列表。
*
* @param inFilterColumn 参与(In-list)过滤的数据表列。
* @param inFilterValues 参与(In-list)过滤的数据表列值集合。
* @param studentActionStatsFilter 过滤对象。
* @param orderBy 排序字符串order by从句的参数。
* @return 对象列表。
*/
<M> List<StudentActionStats> getStudentActionStatsList(
@Param("inFilterColumn") String inFilterColumn,
@Param("inFilterValues") Set<M> inFilterValues,
@Param("studentActionStatsFilter") StudentActionStats studentActionStatsFilter,
@Param("orderBy") String orderBy);
/**
* 获取对象列表过滤条件中包含like和between条件以及指定属性的(in list)过滤条件。
*
* @param inFilterColumn 参与(In-list)过滤的数据表列。
* @param inFilterValues 参与(In-list)过滤的数据表列值集合。
* @param studentActionStatsFilter 过滤对象。
* @return 对象列表。
*/
<M> Integer getStudentActionStatsCount(
@Param("inFilterColumn") String inFilterColumn,
@Param("inFilterValues") Set<M> inFilterValues,
@Param("studentActionStatsFilter") StudentActionStats studentActionStatsFilter);
}

View File

@@ -0,0 +1,44 @@
package com.orange.demo.statsservice.dao;
import com.orange.demo.common.core.base.dao.BaseDaoMapper;
import com.orange.demo.statsservice.model.StudentActionTrans;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 学生行为流水数据操作访问接口。
*
* @author Orange Team
* @date 2020-08-08
*/
public interface StudentActionTransMapper extends BaseDaoMapper<StudentActionTrans> {
/**
* 获取过滤后的对象列表。
*
* @param inFilterColumn 参与(In-list)过滤的数据表列。
* @param inFilterValues 参与(In-list)过滤的数据表列值集合。
* @param studentActionTransFilter 过滤对象。
* @param orderBy 排序字符串order by从句的参数。
* @return 对象列表。
*/
<M> List<StudentActionTrans> getStudentActionTransList(
@Param("inFilterColumn") String inFilterColumn,
@Param("inFilterValues") Set<M> inFilterValues,
@Param("studentActionTransFilter") StudentActionTrans studentActionTransFilter,
@Param("orderBy") String orderBy);
/**
* 获取对象列表过滤条件中包含like和between条件以及指定属性的(in list)过滤条件。
*
* @param inFilterColumn 参与(In-list)过滤的数据表列。
* @param inFilterValues 参与(In-list)过滤的数据表列值集合。
* @param studentActionTransFilter 过滤对象。
* @return 对象列表。
*/
<M> Integer getStudentActionTransCount(
@Param("inFilterColumn") String inFilterColumn,
@Param("inFilterValues") Set<M> inFilterValues,
@Param("studentActionTransFilter") StudentActionTrans studentActionTransFilter);
}

View File

@@ -0,0 +1,79 @@
<?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.orange.demo.statsservice.dao.CourseTransStatsMapper">
<resultMap id="BaseResultMap" type="com.orange.demo.statsservice.model.CourseTransStats">
<id column="stats_id" jdbcType="BIGINT" property="statsId"/>
<result column="stats_date" jdbcType="DATE" property="statsDate"/>
<result column="subject_id" jdbcType="TINYINT" property="subjectId"/>
<result column="grade_id" jdbcType="TINYINT" property="gradeId"/>
<result column="grade_name" jdbcType="VARCHAR" property="gradeName"/>
<result column="course_id" jdbcType="BIGINT" property="courseId"/>
<result column="course_name" jdbcType="VARCHAR" property="courseName"/>
<result column="student_attend_count" jdbcType="INTEGER" property="studentAttendCount"/>
<result column="student_flower_amount" jdbcType="INTEGER" property="studentFlowerAmount"/>
<result column="student_flower_count" jdbcType="INTEGER" property="studentFlowerCount"/>
</resultMap>
<sql id="filterRef">
<if test="courseTransStatsFilter != null">
<if test="courseTransStatsFilter.statsDateStart != null and courseTransStatsFilter.statsDateStart != ''">
AND zz_course_trans_stats.stats_date &gt;= #{courseTransStatsFilter.statsDateStart}
</if>
<if test="courseTransStatsFilter.statsDateEnd != null and courseTransStatsFilter.statsDateEnd != ''">
AND zz_course_trans_stats.stats_date &lt;= #{courseTransStatsFilter.statsDateEnd}
</if>
<if test="courseTransStatsFilter.subjectId != null">
AND zz_course_trans_stats.subject_id = #{courseTransStatsFilter.subjectId}
</if>
<if test="courseTransStatsFilter.gradeId != null">
AND zz_course_trans_stats.grade_id = #{courseTransStatsFilter.gradeId}
</if>
</if>
</sql>
<select id="getGroupedCourseTransStatsList" resultMap="BaseResultMap" parameterType="com.orange.demo.statsservice.model.CourseTransStats">
SELECT * FROM
(SELECT
SUM(student_attend_count) student_attend_count,
SUM(student_flower_amount) student_flower_amount,
SUM(student_flower_count) student_flower_count,
${groupSelect}
FROM zz_course_trans_stats
<where>
<include refid="filterRef"/>
</where>
GROUP BY ${groupBy}) zz_course_trans_stats
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
<select id="getCourseTransStatsList" resultMap="BaseResultMap" parameterType="com.orange.demo.statsservice.model.CourseTransStats">
SELECT * FROM zz_course_trans_stats
<where>
<if test="inFilterColumn != null and inFilterColumn != '' and inFilterValues != null and inFilterValues.size &gt; 0">
AND ${inFilterColumn} IN
<foreach collection="inFilterValues" item="item" open="(" separator="," close=")">
'${item}'
</foreach>
</if>
<include refid="filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
<select id="getCourseTransStatsCount" resultType="java.lang.Integer" parameterType="com.orange.demo.statsservice.model.CourseTransStats">
SELECT COUNT(1) FROM zz_course_trans_stats
<where>
<if test="inFilterColumn != null and inFilterColumn != '' and inFilterValues != null and inFilterValues.size &gt; 0">
AND ${inFilterColumn} IN
<foreach collection="inFilterValues" item="item" open="(" separator="," close=")">
'${item}'
</foreach>
</if>
<include refid="filterRef"/>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,105 @@
<?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.orange.demo.statsservice.dao.StudentActionStatsMapper">
<resultMap id="BaseResultMap" type="com.orange.demo.statsservice.model.StudentActionStats">
<id column="stats_id" jdbcType="BIGINT" property="statsId"/>
<result column="stats_date" jdbcType="DATE" property="statsDate"/>
<result column="stats_month" jdbcType="DATE" property="statsMonth"/>
<result column="grade_id" jdbcType="INTEGER" property="gradeId"/>
<result column="province_id" jdbcType="BIGINT" property="provinceId"/>
<result column="city_id" jdbcType="BIGINT" property="cityId"/>
<result column="buy_course_amount" jdbcType="INTEGER" property="buyCourseAmount"/>
<result column="buy_course_count" jdbcType="INTEGER" property="buyCourseCount"/>
<result column="buy_video_amount" jdbcType="INTEGER" property="buyVideoAmount"/>
<result column="buy_video_count" jdbcType="INTEGER" property="buyVideoCount"/>
<result column="buy_paper_amount" jdbcType="INTEGER" property="buyPaperAmount"/>
<result column="buy_paper_count" jdbcType="INTEGER" property="buyPaperCount"/>
<result column="buy_flower_amount" jdbcType="INTEGER" property="buyFlowerAmount"/>
<result column="buy_flower_count" jdbcType="INTEGER" property="buyFlowerCount"/>
<result column="recharge_coin_amount" jdbcType="INTEGER" property="rechargeCoinAmount"/>
<result column="recharge_coin_count" jdbcType="INTEGER" property="rechargeCoinCount"/>
<result column="do_course_count" jdbcType="INTEGER" property="doCourseCount"/>
<result column="watch_video_count" jdbcType="INTEGER" property="watchVideoCount"/>
<result column="watch_video_total_second" jdbcType="INTEGER" property="watchVideoTotalSecond"/>
<result column="do_exercise_count" jdbcType="INTEGER" property="doExerciseCount"/>
<result column="do_exercise_correct_count" jdbcType="INTEGER" property="doExerciseCorrectCount"/>
</resultMap>
<sql id="filterRef">
<if test="studentActionStatsFilter != null">
<if test="studentActionStatsFilter.statsDateStart != null and studentActionStatsFilter.statsDateStart != ''">
AND zz_student_action_stats.stats_date &gt;= #{studentActionStatsFilter.statsDateStart}
</if>
<if test="studentActionStatsFilter.statsDateEnd != null and studentActionStatsFilter.statsDateEnd != ''">
AND zz_student_action_stats.stats_date &lt;= #{studentActionStatsFilter.statsDateEnd}
</if>
<if test="studentActionStatsFilter.gradeId != null">
AND zz_student_action_stats.grade_id = #{studentActionStatsFilter.gradeId}
</if>
<if test="studentActionStatsFilter.provinceId != null">
AND zz_student_action_stats.province_id = #{studentActionStatsFilter.provinceId}
</if>
<if test="studentActionStatsFilter.cityId != null">
AND zz_student_action_stats.city_id = #{studentActionStatsFilter.cityId}
</if>
</if>
</sql>
<select id="getGroupedStudentActionStatsList" resultMap="BaseResultMap" parameterType="com.orange.demo.statsservice.model.StudentActionStats">
SELECT * FROM
(SELECT
SUM(buy_course_amount) buy_course_amount,
COUNT(buy_course_count) buy_course_count,
SUM(buy_video_amount) buy_video_amount,
COUNT(buy_video_count) buy_video_count,
SUM(buy_paper_amount) buy_paper_amount,
COUNT(buy_paper_count) buy_paper_count,
SUM(buy_flower_amount) buy_flower_amount,
COUNT(buy_flower_count) buy_flower_count,
SUM(recharge_coin_amount) recharge_coin_amount,
COUNT(recharge_coin_count) recharge_coin_count,
SUM(do_course_count) do_course_count,
SUM(watch_video_count) watch_video_count,
SUM(watch_video_total_second) watch_video_total_second,
SUM(do_exercise_count) do_exercise_count,
SUM(do_exercise_correct_count) do_exercise_correct_count,
${groupSelect}
FROM zz_student_action_stats
<where>
<include refid="filterRef"/>
</where>
GROUP BY ${groupBy}) zz_student_action_stats
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
<select id="getStudentActionStatsList" resultMap="BaseResultMap" parameterType="com.orange.demo.statsservice.model.StudentActionStats">
SELECT * FROM zz_student_action_stats
<where>
<if test="inFilterColumn != null and inFilterColumn != '' and inFilterValues != null and inFilterValues.size &gt; 0">
AND ${inFilterColumn} IN
<foreach collection="inFilterValues" item="item" open="(" separator="," close=")">
'${item}'
</foreach>
</if>
<include refid="filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
<select id="getStudentActionStatsCount" resultType="java.lang.Integer" parameterType="com.orange.demo.statsservice.model.StudentActionStats">
SELECT COUNT(1) FROM zz_student_action_stats
<where>
<if test="inFilterColumn != null and inFilterColumn != '' and inFilterValues != null and inFilterValues.size &gt; 0">
AND ${inFilterColumn} IN
<foreach collection="inFilterValues" item="item" open="(" separator="," close=")">
'${item}'
</foreach>
</if>
<include refid="filterRef"/>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,76 @@
<?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.orange.demo.statsservice.dao.StudentActionTransMapper">
<resultMap id="BaseResultMap" type="com.orange.demo.statsservice.model.StudentActionTrans">
<id column="trans_id" jdbcType="BIGINT" property="transId"/>
<result column="student_id" jdbcType="BIGINT" property="studentId"/>
<result column="student_name" jdbcType="VARCHAR" property="studentName"/>
<result column="school_id" jdbcType="BIGINT" property="schoolId"/>
<result column="grade_id" jdbcType="INTEGER" property="gradeId"/>
<result column="action_type" jdbcType="TINYINT" property="actionType"/>
<result column="device_type" jdbcType="TINYINT" property="deviceType"/>
<result column="watch_video_seconds" jdbcType="INTEGER" property="watchVideoSeconds"/>
<result column="flower_count" jdbcType="INTEGER" property="flowerCount"/>
<result column="paper_count" jdbcType="INTEGER" property="paperCount"/>
<result column="video_count" jdbcType="INTEGER" property="videoCount"/>
<result column="course_count" jdbcType="INTEGER" property="courseCount"/>
<result column="coin_count" jdbcType="INTEGER" property="coinCount"/>
<result column="exercise_correct_flag" jdbcType="TINYINT" property="exerciseCorrectFlag"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
</resultMap>
<sql id="filterRef">
<if test="studentActionTransFilter != null">
<if test="studentActionTransFilter.studentId != null">
AND zz_student_action_trans.student_id = #{studentActionTransFilter.studentId}
</if>
<if test="studentActionTransFilter.schoolId != null">
AND zz_student_action_trans.school_id = #{studentActionTransFilter.schoolId}
</if>
<if test="studentActionTransFilter.gradeId != null">
AND zz_student_action_trans.grade_id = #{studentActionTransFilter.gradeId}
</if>
<if test="studentActionTransFilter.actionType != null">
AND zz_student_action_trans.action_type = #{studentActionTransFilter.actionType}
</if>
<if test="studentActionTransFilter.deviceType != null">
AND zz_student_action_trans.device_type = #{studentActionTransFilter.deviceType}
</if>
<if test="studentActionTransFilter.createTimeStart != null and studentActionTransFilter.createTimeStart != ''">
AND zz_student_action_trans.create_time &gt;= #{studentActionTransFilter.createTimeStart}
</if>
<if test="studentActionTransFilter.createTimeEnd != null and studentActionTransFilter.createTimeEnd != ''">
AND zz_student_action_trans.create_time &lt;= #{studentActionTransFilter.createTimeEnd}
</if>
</if>
</sql>
<select id="getStudentActionTransList" resultMap="BaseResultMap" parameterType="com.orange.demo.statsservice.model.StudentActionTrans">
SELECT * FROM zz_student_action_trans
<where>
<if test="inFilterColumn != null and inFilterColumn != '' and inFilterValues != null and inFilterValues.size &gt; 0">
AND ${inFilterColumn} IN
<foreach collection="inFilterValues" item="item" open="(" separator="," close=")">
'${item}'
</foreach>
</if>
<include refid="filterRef"/>
</where>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
<select id="getStudentActionTransCount" resultType="java.lang.Integer" parameterType="com.orange.demo.statsservice.model.StudentActionTrans">
SELECT COUNT(1) FROM zz_student_action_trans
<where>
<if test="inFilterColumn != null and inFilterColumn != '' and inFilterValues != null and inFilterValues.size &gt; 0">
AND ${inFilterColumn} IN
<foreach collection="inFilterValues" item="item" open="(" separator="," close=")">
'${item}'
</foreach>
</if>
<include refid="filterRef"/>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,159 @@
package com.orange.demo.statsservice.model;
import com.orange.demo.courseclassinterface.client.GradeClient;
import com.orange.demo.courseclassinterface.dto.GradeDto;
import com.orange.demo.courseclassinterface.client.CourseClient;
import com.orange.demo.courseclassinterface.dto.CourseDto;
import com.orange.demo.application.common.constant.Subject;
import com.orange.demo.common.core.annotation.RelationDict;
import com.orange.demo.common.core.annotation.RelationConstDict;
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
import com.orange.demo.common.core.validator.ConstDictRef;
import com.orange.demo.statsinterface.dto.CourseTransStatsDto;
import lombok.Data;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Map;
/**
* CourseTransStats实体对象。
*
* @author Orange Team
* @date 2020-08-08
*/
@Data
@Table(name = "zz_course_trans_stats")
public class CourseTransStats {
/**
* 主键Id。
*/
@NotNull(message = "数据验证失败主键Id不能为空")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "stats_id")
private Long statsId;
/**
* 统计日期。
*/
@NotNull(message = "数据验证失败,统计日期不能为空!")
@Column(name = "stats_date")
private Date statsDate;
/**
* 科目Id。
*/
@NotNull(message = "数据验证失败,所属科目不能为空!")
@ConstDictRef(constDictClass = Subject.class, message = "数据验证失败,所属科目为无效值!")
@Column(name = "subject_id")
private Integer subjectId;
/**
* 年级Id。
*/
@NotNull(message = "数据验证失败,所属年级不能为空!")
@Column(name = "grade_id")
private Integer gradeId;
/**
* 年级名称。
*/
@Column(name = "grade_name")
private String gradeName;
/**
* 课程Id。
*/
@NotNull(message = "数据验证失败课程ID不能为空")
@Column(name = "course_id")
private Long courseId;
/**
* 课程名称。
*/
@Column(name = "course_name")
private String courseName;
/**
* 学生上课次数。
*/
@NotNull(message = "数据验证失败,上课次数不能为空!")
@Column(name = "student_attend_count")
private Integer studentAttendCount;
/**
* 学生献花数量。
*/
@NotNull(message = "数据验证失败,献花数量不能为空!")
@Column(name = "student_flower_amount")
private Integer studentFlowerAmount;
/**
* 学生献花次数。
*/
@NotNull(message = "数据验证失败,献花次数不能为空!")
@Column(name = "student_flower_count")
private Integer studentFlowerCount;
/**
* statsDate 范围过滤起始值(>=)。
*/
@Transient
private String statsDateStart;
/**
* statsDate 范围过滤结束值(<=)。
*/
@Transient
private String statsDateEnd;
@RelationDict(
masterIdField = "gradeId",
slaveClientClass = GradeClient.class,
slaveModelClass = GradeDto.class,
slaveIdField = "gradeId",
slaveNameField = "gradeName")
@Transient
private Map<String, Object> gradeIdDictMap;
@RelationDict(
masterIdField = "courseId",
slaveClientClass = CourseClient.class,
slaveModelClass = CourseDto.class,
slaveIdField = "courseId",
slaveNameField = "courseName")
@Transient
private Map<String, Object> courseIdDictMap;
@RelationConstDict(
masterIdField = "subjectId",
constantDictClass = Subject.class)
@Transient
private Map<String, Object> subjectIdDictMap;
@Mapper
public interface CourseTransStatsModelMapper extends BaseModelMapper<CourseTransStatsDto, CourseTransStats> {
/**
* 转换Dto对象到实体对象。
*
* @param courseTransStatsDto 域对象。
* @return 实体对象。
*/
@Override
CourseTransStats toModel(CourseTransStatsDto courseTransStatsDto);
/**
* 转换实体对象到Dto对象。
*
* @param courseTransStats 实体对象。
* @return 域对象。
*/
@Override
CourseTransStatsDto fromModel(CourseTransStats courseTransStats);
}
public static final CourseTransStatsModelMapper INSTANCE = Mappers.getMapper(CourseTransStatsModelMapper.class);
}

View File

@@ -0,0 +1,235 @@
package com.orange.demo.statsservice.model;
import com.orange.demo.courseclassinterface.client.GradeClient;
import com.orange.demo.courseclassinterface.dto.GradeDto;
import com.orange.demo.courseclassinterface.client.AreaCodeClient;
import com.orange.demo.courseclassinterface.dto.AreaCodeDto;
import com.orange.demo.common.core.annotation.RelationDict;
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
import com.orange.demo.statsinterface.dto.StudentActionStatsDto;
import lombok.Data;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Map;
/**
* StudentActionStats实体对象。
*
* @author Orange Team
* @date 2020-08-08
*/
@Data
@Table(name = "zz_student_action_stats")
public class StudentActionStats {
/**
* 主键Id。
*/
@NotNull(message = "数据验证失败主键Id不能为空")
@Id
@Column(name = "stats_id")
private Long statsId;
/**
* 统计日期。
*/
@NotNull(message = "数据验证失败,统计日期不能为空!")
@Column(name = "stats_date")
private Date statsDate;
/**
* 统计小时。
*/
@Column(name = "stats_month")
private Date statsMonth;
/**
* 年级Id。
*/
@NotNull(message = "数据验证失败,所属年级不能为空!")
@Column(name = "grade_id")
private Integer gradeId;
/**
* 学生所在省Id。
*/
@NotNull(message = "数据验证失败,所在省份不能为空!")
@Column(name = "province_id")
private Long provinceId;
/**
* 学生所在城市Id。
*/
@NotNull(message = "数据验证失败,所在城市不能为空!")
@Column(name = "city_id")
private Long cityId;
/**
* 购课学币数量。
*/
@NotNull(message = "数据验证失败,购课学币数量不能为空!")
@Column(name = "buy_course_amount")
private Integer buyCourseAmount;
/**
* 购买课程次数。
*/
@NotNull(message = "数据验证失败,购买课程次数不能为空!")
@Column(name = "buy_course_count")
private Integer buyCourseCount;
/**
* 购买视频学币数量。
*/
@NotNull(message = "数据验证失败,购买视频学币数量不能为空!")
@Column(name = "buy_video_amount")
private Integer buyVideoAmount;
/**
* 购买视频次数。
*/
@NotNull(message = "数据验证失败,购买视频次数不能为空!")
@Column(name = "buy_video_count")
private Integer buyVideoCount;
/**
* 购买作业学币数量。
*/
@NotNull(message = "数据验证失败,购买作业学币数量不能为空!")
@Column(name = "buy_paper_amount")
private Integer buyPaperAmount;
/**
* 购买作业次数。
*/
@NotNull(message = "数据验证失败,购买作业次数不能为空!")
@Column(name = "buy_paper_count")
private Integer buyPaperCount;
/**
* 购买献花数量。
*/
@NotNull(message = "数据验证失败,购买献花数量不能为空!")
@Column(name = "buy_flower_amount")
private Integer buyFlowerAmount;
/**
* 购买献花次数。
*/
@NotNull(message = "数据验证失败,购买献花次数不能为空!")
@Column(name = "buy_flower_count")
private Integer buyFlowerCount;
/**
* 充值学币数量。
*/
@NotNull(message = "数据验证失败,充值学币数量不能为空!")
@Column(name = "recharge_coin_amount")
private Integer rechargeCoinAmount;
/**
* 充值学币次数。
*/
@NotNull(message = "数据验证失败,充值学币次数不能为空!")
@Column(name = "recharge_coin_count")
private Integer rechargeCoinCount;
/**
* 线下课程上课次数。
*/
@NotNull(message = "数据验证失败,线下课程上课次数不能为空!")
@Column(name = "do_course_count")
private Integer doCourseCount;
/**
* 观看视频次数。
*/
@NotNull(message = "数据验证失败,观看视频次数不能为空!")
@Column(name = "watch_video_count")
private Integer watchVideoCount;
/**
* 购买献花消费学币数量。
*/
@NotNull(message = "数据验证失败,购买献花消费学币数量不能为空!")
@Column(name = "watch_video_total_second")
private Integer watchVideoTotalSecond;
/**
* 做题数量。
*/
@NotNull(message = "数据验证失败,做题数量不能为空!")
@Column(name = "do_exercise_count")
private Integer doExerciseCount;
/**
* 做题正确的数量。
*/
@NotNull(message = "数据验证失败,做题正确的数量不能为空!")
@Column(name = "do_exercise_correct_count")
private Integer doExerciseCorrectCount;
/**
* statsDate 范围过滤起始值(>=)。
*/
@Transient
private String statsDateStart;
/**
* statsDate 范围过滤结束值(<=)。
*/
@Transient
private String statsDateEnd;
@RelationDict(
masterIdField = "gradeId",
slaveClientClass = GradeClient.class,
slaveModelClass = GradeDto.class,
slaveIdField = "gradeId",
slaveNameField = "gradeName")
@Transient
private Map<String, Object> gradeIdDictMap;
@RelationDict(
masterIdField = "provinceId",
slaveClientClass = AreaCodeClient.class,
slaveModelClass = AreaCodeDto.class,
slaveIdField = "areaId",
slaveNameField = "areaName")
@Transient
private Map<String, Object> provinceIdDictMap;
@RelationDict(
masterIdField = "cityId",
slaveClientClass = AreaCodeClient.class,
slaveModelClass = AreaCodeDto.class,
slaveIdField = "areaId",
slaveNameField = "areaName")
@Transient
private Map<String, Object> cityIdDictMap;
@Mapper
public interface StudentActionStatsModelMapper extends BaseModelMapper<StudentActionStatsDto, StudentActionStats> {
/**
* 转换Dto对象到实体对象。
*
* @param studentActionStatsDto 域对象。
* @return 实体对象。
*/
@Override
StudentActionStats toModel(StudentActionStatsDto studentActionStatsDto);
/**
* 转换实体对象到Dto对象。
*
* @param studentActionStats 实体对象。
* @return 域对象。
*/
@Override
StudentActionStatsDto fromModel(StudentActionStats studentActionStats);
}
public static final StudentActionStatsModelMapper INSTANCE = Mappers.getMapper(StudentActionStatsModelMapper.class);
}

View File

@@ -0,0 +1,196 @@
package com.orange.demo.statsservice.model;
import com.orange.demo.courseclassinterface.dto.SchoolInfoDto;
import com.orange.demo.courseclassinterface.client.GradeClient;
import com.orange.demo.courseclassinterface.dto.GradeDto;
import com.orange.demo.courseclassinterface.client.SchoolInfoClient;
import com.orange.demo.application.common.constant.StudentActionType;
import com.orange.demo.application.common.constant.DeviceType;
import com.orange.demo.common.core.annotation.RelationDict;
import com.orange.demo.common.core.annotation.RelationConstDict;
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
import com.orange.demo.common.core.validator.ConstDictRef;
import com.orange.demo.statsinterface.dto.StudentActionTransDto;
import lombok.Data;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Map;
/**
* StudentActionTrans实体对象。
*
* @author Jerry
* @date 2020-08-13
*/
@Data
@Table(name = "zz_student_action_trans")
public class StudentActionTrans {
/**
* 主键Id。
*/
@NotNull(message = "数据验证失败主键Id不能为空")
@Id
@Column(name = "trans_id")
private Long transId;
/**
* 学生Id。
*/
@NotNull(message = "数据验证失败学生Id不能为空")
@Column(name = "student_id")
private Long studentId;
/**
* 学生名称。
*/
@NotBlank(message = "数据验证失败,学生名称不能为空!")
@Column(name = "student_name")
private String studentName;
/**
* 学生校区。
*/
@NotNull(message = "数据验证失败,学生校区不能为空!")
@Column(name = "school_id")
private Long schoolId;
/**
* 年级Id。
*/
@NotNull(message = "数据验证失败,所属年级不能为空!")
@Column(name = "grade_id")
private Integer gradeId;
/**
* 行为类型(0: 充值 1: 购课 2: 上课签到 3: 上课签退 4: 看视频课 5: 做作业 6: 刷题 7: 献花)。
*/
@NotNull(message = "数据验证失败,行为类型不能为空!")
@ConstDictRef(constDictClass = StudentActionType.class, message = "数据验证失败,行为类型为无效值!")
@Column(name = "action_type")
private Integer actionType;
/**
* 设备类型(0: iOS 1: Android 2: PC)。
*/
@NotNull(message = "数据验证失败,设备类型不能为空!")
@ConstDictRef(constDictClass = DeviceType.class, message = "数据验证失败,设备类型为无效值!")
@Column(name = "device_type")
private Integer deviceType;
/**
* 看视频秒数。
*/
@Column(name = "watch_video_seconds")
private Integer watchVideoSeconds;
/**
* 购买献花数量。
*/
@Column(name = "flower_count")
private Integer flowerCount;
/**
* 购买作业数量。
*/
@Column(name = "paper_count")
private Integer paperCount;
/**
* 购买视频数量。
*/
@Column(name = "video_count")
private Integer videoCount;
/**
* 购买课程数量。
*/
@Column(name = "course_count")
private Integer courseCount;
/**
* 充值学币数量。
*/
@Column(name = "coin_count")
private Integer coinCount;
/**
* 做题是否正确标记。
*/
@Column(name = "exercise_correct_flag")
private Integer exerciseCorrectFlag;
/**
* 发生时间。
*/
@NotNull(message = "数据验证失败,发生时间不能为空!")
@Column(name = "create_time")
private Date createTime;
/**
* createTime 范围过滤起始值(>=)。
*/
@Transient
private String createTimeStart;
/**
* createTime 范围过滤结束值(<=)。
*/
@Transient
private String createTimeEnd;
@RelationDict(
masterIdField = "schoolId",
slaveClientClass = SchoolInfoClient.class,
slaveModelClass = SchoolInfoDto.class,
slaveIdField = "schoolId",
slaveNameField = "schoolName")
@Transient
private Map<String, Object> schoolIdDictMap;
@RelationDict(
masterIdField = "gradeId",
slaveClientClass = GradeClient.class,
slaveModelClass = GradeDto.class,
slaveIdField = "gradeId",
slaveNameField = "gradeName")
@Transient
private Map<String, Object> gradeIdDictMap;
@RelationConstDict(
masterIdField = "actionType",
constantDictClass = StudentActionType.class)
@Transient
private Map<String, Object> actionTypeDictMap;
@RelationConstDict(
masterIdField = "deviceType",
constantDictClass = DeviceType.class)
@Transient
private Map<String, Object> deviceTypeDictMap;
@Mapper
public interface StudentActionTransModelMapper extends BaseModelMapper<StudentActionTransDto, StudentActionTrans> {
/**
* 转换Dto对象到实体对象。
*
* @param studentActionTransDto 域对象。
* @return 实体对象。
*/
@Override
StudentActionTrans toModel(StudentActionTransDto studentActionTransDto);
/**
* 转换实体对象到Dto对象。
*
* @param studentActionTrans 实体对象。
* @return 域对象。
*/
@Override
StudentActionTransDto fromModel(StudentActionTrans studentActionTrans);
}
public static final StudentActionTransModelMapper INSTANCE = Mappers.getMapper(StudentActionTransModelMapper.class);
}

View File

@@ -0,0 +1,119 @@
package com.orange.demo.statsservice.service;
import com.orange.demo.statsservice.dao.*;
import com.orange.demo.statsservice.model.*;
import com.orange.demo.statsinterface.dto.*;
import com.orange.demo.common.core.util.*;
import com.orange.demo.common.core.object.MyRelationParam;
import com.orange.demo.common.core.object.MyWhereCriteria;
import com.orange.demo.common.core.base.dao.BaseDaoMapper;
import com.orange.demo.common.core.base.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 课程统计数据操作服务类。
*
* @author Orange Team
* @date 2020-08-08
*/
@Service
public class CourseTransStatsService extends BaseService<CourseTransStats, CourseTransStatsDto, Long> {
@Autowired
private CourseTransStatsMapper courseTransStatsMapper;
/**
* 返回当前Service的主表Mapper对象。
*
* @return 主表Mapper对象。
*/
@Override
protected BaseDaoMapper<CourseTransStats> mapper() {
return courseTransStatsMapper;
}
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getCourseTransStatsListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<CourseTransStats> getCourseTransStatsList(CourseTransStats filter, String orderBy) {
return courseTransStatsMapper.getCourseTransStatsList(null, null, filter, orderBy);
}
/**
* 获取主表的查询结果,查询条件中包括主表过滤对象和指定字段的(in list)过滤。
* 由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getCourseTransStatsListWithRelation)方法。
*
* @param inFilterField (In-list)指定的字段(Java成员字段而非数据列名)。
* @param inFilterValues inFilterField指定字段的(In-list)数据列表。
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public <M> List<CourseTransStats> getCourseTransStatsList(
String inFilterField, Set<M> inFilterValues, CourseTransStats filter, String orderBy) {
String inFilterColumn = MyModelUtil.mapToColumnName(inFilterField, CourseTransStats.class);
return courseTransStatsMapper.getCourseTransStatsList(inFilterColumn, inFilterValues, filter, orderBy);
}
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getCourseTransStatsList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param orderBy 排序对象。
* @return 查询结果集。
*/
public List<CourseTransStats> getCourseTransStatsListWithRelation(CourseTransStats filter, String orderBy) {
List<CourseTransStats> resultList = courseTransStatsMapper.getCourseTransStatsList(null, null, filter, orderBy);
Map<String, List<MyWhereCriteria>> criteriaMap = buildAggregationAdditionalWhereCriteria();
this.buildRelationForDataList(resultList, MyRelationParam.normal(), criteriaMap);
return resultList;
}
/**
* 获取主表的查询结果,查询条件中包括主表过滤对象和指定字段的(in list)过滤。
* 同时还包含主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getCourseTransStatsList),以便获取更好的查询性能。
*
* @param inFilterField (In-list)指定的字段(Java成员字段而非数据列名)。
* @param inFilterValues inFilterField指定字段的(In-list)数据列表。
* @param filter 主表过滤对象。
* @param orderBy 排序对象。
* @return 查询结果集。
*/
public <M> List<CourseTransStats> getCourseTransStatsListWithRelation(
String inFilterField, Set<M> inFilterValues, CourseTransStats filter, String orderBy) {
List<CourseTransStats> resultList =
courseTransStatsMapper.getCourseTransStatsList(inFilterField, inFilterValues, filter, orderBy);
this.buildRelationForDataList(resultList, MyRelationParam.dictOnly(), null);
return resultList;
}
/**
* 获取分组过滤后的数据查询结果,以及关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
*
* @param filter 过滤对象。
* @param groupSelect 分组显示列表参数。位于SQL语句SELECT的后面。
* @param groupBy 分组参数。位于SQL语句的GROUP BY后面。
* @param orderBy 排序字符串ORDER BY从句的参数。
* @return 分组过滤结果集。
*/
public List<CourseTransStats> getGroupedCourseTransStatsListWithRelation(
CourseTransStats filter, String groupSelect, String groupBy, String orderBy) {
List<CourseTransStats> resultList =
courseTransStatsMapper.getGroupedCourseTransStatsList(filter, groupSelect, groupBy, orderBy);
// NOTE: 这里只是包含了本地关联数据和远程关联数据,本地聚合计算数据和远程聚合计算数据没有包含。
// 主要原因是由于聚合字段通常被视为普通字段使用不会在group by的从句中出现语义上也不会在此关联。
this.buildRelationForDataList(resultList, MyRelationParam.normal(), null);
return resultList;
}
}

View File

@@ -0,0 +1,119 @@
package com.orange.demo.statsservice.service;
import com.orange.demo.statsservice.dao.*;
import com.orange.demo.statsservice.model.*;
import com.orange.demo.statsinterface.dto.*;
import com.orange.demo.common.core.util.*;
import com.orange.demo.common.core.object.MyRelationParam;
import com.orange.demo.common.core.object.MyWhereCriteria;
import com.orange.demo.common.core.base.dao.BaseDaoMapper;
import com.orange.demo.common.core.base.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 学生行为统计数据操作服务类。
*
* @author Orange Team
* @date 2020-08-08
*/
@Service
public class StudentActionStatsService extends BaseService<StudentActionStats, StudentActionStatsDto, Long> {
@Autowired
private StudentActionStatsMapper studentActionStatsMapper;
/**
* 返回当前Service的主表Mapper对象。
*
* @return 主表Mapper对象。
*/
@Override
protected BaseDaoMapper<StudentActionStats> mapper() {
return studentActionStatsMapper;
}
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getStudentActionStatsListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<StudentActionStats> getStudentActionStatsList(StudentActionStats filter, String orderBy) {
return studentActionStatsMapper.getStudentActionStatsList(null, null, filter, orderBy);
}
/**
* 获取主表的查询结果,查询条件中包括主表过滤对象和指定字段的(in list)过滤。
* 由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getStudentActionStatsListWithRelation)方法。
*
* @param inFilterField (In-list)指定的字段(Java成员字段而非数据列名)。
* @param inFilterValues inFilterField指定字段的(In-list)数据列表。
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public <M> List<StudentActionStats> getStudentActionStatsList(
String inFilterField, Set<M> inFilterValues, StudentActionStats filter, String orderBy) {
String inFilterColumn = MyModelUtil.mapToColumnName(inFilterField, StudentActionStats.class);
return studentActionStatsMapper.getStudentActionStatsList(inFilterColumn, inFilterValues, filter, orderBy);
}
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getStudentActionStatsList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param orderBy 排序对象。
* @return 查询结果集。
*/
public List<StudentActionStats> getStudentActionStatsListWithRelation(StudentActionStats filter, String orderBy) {
List<StudentActionStats> resultList = studentActionStatsMapper.getStudentActionStatsList(null, null, filter, orderBy);
Map<String, List<MyWhereCriteria>> criteriaMap = buildAggregationAdditionalWhereCriteria();
this.buildRelationForDataList(resultList, MyRelationParam.normal(), criteriaMap);
return resultList;
}
/**
* 获取主表的查询结果,查询条件中包括主表过滤对象和指定字段的(in list)过滤。
* 同时还包含主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getStudentActionStatsList),以便获取更好的查询性能。
*
* @param inFilterField (In-list)指定的字段(Java成员字段而非数据列名)。
* @param inFilterValues inFilterField指定字段的(In-list)数据列表。
* @param filter 主表过滤对象。
* @param orderBy 排序对象。
* @return 查询结果集。
*/
public <M> List<StudentActionStats> getStudentActionStatsListWithRelation(
String inFilterField, Set<M> inFilterValues, StudentActionStats filter, String orderBy) {
List<StudentActionStats> resultList =
studentActionStatsMapper.getStudentActionStatsList(inFilterField, inFilterValues, filter, orderBy);
this.buildRelationForDataList(resultList, MyRelationParam.dictOnly(), null);
return resultList;
}
/**
* 获取分组过滤后的数据查询结果,以及关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
*
* @param filter 过滤对象。
* @param groupSelect 分组显示列表参数。位于SQL语句SELECT的后面。
* @param groupBy 分组参数。位于SQL语句的GROUP BY后面。
* @param orderBy 排序字符串ORDER BY从句的参数。
* @return 分组过滤结果集。
*/
public List<StudentActionStats> getGroupedStudentActionStatsListWithRelation(
StudentActionStats filter, String groupSelect, String groupBy, String orderBy) {
List<StudentActionStats> resultList =
studentActionStatsMapper.getGroupedStudentActionStatsList(filter, groupSelect, groupBy, orderBy);
// NOTE: 这里只是包含了本地关联数据和远程关联数据,本地聚合计算数据和远程聚合计算数据没有包含。
// 主要原因是由于聚合字段通常被视为普通字段使用不会在group by的从句中出现语义上也不会在此关联。
this.buildRelationForDataList(resultList, MyRelationParam.normal(), null);
return resultList;
}
}

View File

@@ -0,0 +1,174 @@
package com.orange.demo.statsservice.service;
import com.orange.demo.statsservice.dao.*;
import com.orange.demo.statsservice.model.*;
import com.orange.demo.statsinterface.dto.*;
import com.orange.demo.courseclassinterface.client.*;
import com.orange.demo.common.core.util.*;
import com.orange.demo.common.core.object.MyRelationParam;
import com.orange.demo.common.core.object.ResponseResult;
import com.orange.demo.common.core.object.CallResult;
import com.orange.demo.common.core.object.MyWhereCriteria;
import com.orange.demo.common.core.base.dao.BaseDaoMapper;
import com.orange.demo.common.core.base.service.BaseService;
import com.orange.demo.common.sequence.wrapper.IdGeneratorWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* 学生行为流水数据操作服务类。
*
* @author Orange Team
* @date 2020-08-08
*/
@Service
public class StudentActionTransService extends BaseService<StudentActionTrans, StudentActionTransDto, Long> {
@Autowired
private StudentActionTransMapper studentActionTransMapper;
@Autowired
private SchoolInfoClient schoolInfoClient;
@Autowired
private GradeClient gradeClient;
@Autowired
private IdGeneratorWrapper idGenerator;
/**
* 返回当前Service的主表Mapper对象。
*
* @return 主表Mapper对象。
*/
@Override
protected BaseDaoMapper<StudentActionTrans> mapper() {
return studentActionTransMapper;
}
/**
* 保存新增对象。
*
* @param studentActionTrans 新增对象。
* @return 返回新增对象。
*/
@Transactional(rollbackFor = Exception.class)
public StudentActionTrans saveNew(StudentActionTrans studentActionTrans) {
studentActionTrans.setTransId(idGenerator.nextLongId());
studentActionTransMapper.insert(studentActionTrans);
return studentActionTrans;
}
/**
* 更新数据对象。
*
* @param studentActionTrans 更新的对象。
* @param originalStudentActionTrans 原有数据对象。
* @return 成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean update(StudentActionTrans studentActionTrans, StudentActionTrans originalStudentActionTrans) {
return studentActionTransMapper.updateByPrimaryKey(studentActionTrans) == 1;
}
/**
* 删除指定数据。
*
* @param transId 主键Id。
* @return 成功返回true否则false。
*/
@Transactional(rollbackFor = Exception.class)
public boolean remove(Long transId) {
return studentActionTransMapper.deleteByPrimaryKey(transId) != 0;
// 这里可继续删除关联数据。
}
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getStudentActionTransListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public List<StudentActionTrans> getStudentActionTransList(StudentActionTrans filter, String orderBy) {
return studentActionTransMapper.getStudentActionTransList(null, null, filter, orderBy);
}
/**
* 获取主表的查询结果,查询条件中包括主表过滤对象和指定字段的(in list)过滤。
* 由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getStudentActionTransListWithRelation)方法。
*
* @param inFilterField (In-list)指定的字段(Java成员字段而非数据列名)。
* @param inFilterValues inFilterField指定字段的(In-list)数据列表。
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
public <M> List<StudentActionTrans> getStudentActionTransList(
String inFilterField, Set<M> inFilterValues, StudentActionTrans filter, String orderBy) {
String inFilterColumn = MyModelUtil.mapToColumnName(inFilterField, StudentActionTrans.class);
return studentActionTransMapper.getStudentActionTransList(inFilterColumn, inFilterValues, filter, orderBy);
}
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getStudentActionTransList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param orderBy 排序对象。
* @return 查询结果集。
*/
public List<StudentActionTrans> getStudentActionTransListWithRelation(StudentActionTrans filter, String orderBy) {
List<StudentActionTrans> resultList = studentActionTransMapper.getStudentActionTransList(null, null, filter, orderBy);
Map<String, List<MyWhereCriteria>> criteriaMap = buildAggregationAdditionalWhereCriteria();
this.buildRelationForDataList(resultList, MyRelationParam.normal(), criteriaMap);
return resultList;
}
/**
* 获取主表的查询结果,查询条件中包括主表过滤对象和指定字段的(in list)过滤。
* 同时还包含主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 如果仅仅需要获取主表数据,请移步(getStudentActionTransList),以便获取更好的查询性能。
*
* @param inFilterField (In-list)指定的字段(Java成员字段而非数据列名)。
* @param inFilterValues inFilterField指定字段的(In-list)数据列表。
* @param filter 主表过滤对象。
* @param orderBy 排序对象。
* @return 查询结果集。
*/
public <M> List<StudentActionTrans> getStudentActionTransListWithRelation(
String inFilterField, Set<M> inFilterValues, StudentActionTrans filter, String orderBy) {
List<StudentActionTrans> resultList =
studentActionTransMapper.getStudentActionTransList(inFilterField, inFilterValues, filter, orderBy);
this.buildRelationForDataList(resultList, MyRelationParam.dictOnly(), null);
return resultList;
}
/**
* 根据最新对象和原有对象的数据对比,判断关联的远程字典数据和多对一主表数据是否都是合法数据。
*
* @param studentActionTrans 最新数据对象。
* @param originalStudentActionTrans 原有数据对象。
* @return 数据全部正确返回true否则false同时返回具体的错误信息。
*/
public CallResult verifyRemoteRelatedData(StudentActionTrans studentActionTrans, StudentActionTrans originalStudentActionTrans) {
String errorMessageFormat = "数据验证失败,关联的%s并不存在请刷新后重试";
if (this.needToVerify(studentActionTrans, originalStudentActionTrans, StudentActionTrans::getSchoolId)) {
ResponseResult<Boolean> responseResult =
schoolInfoClient.existId(studentActionTrans.getSchoolId());
if (this.hasErrorOfVerifyRemoteRelatedData(responseResult)) {
return CallResult.error(String.format(errorMessageFormat, "学生校区"));
}
}
if (this.needToVerify(studentActionTrans, originalStudentActionTrans, StudentActionTrans::getGradeId)) {
ResponseResult<Boolean> responseResult =
gradeClient.existId(studentActionTrans.getGradeId());
if (this.hasErrorOfVerifyRemoteRelatedData(responseResult)) {
return CallResult.error(String.format(errorMessageFormat, "所属年级"));
}
}
return CallResult.ok();
}
}

View File

@@ -0,0 +1,30 @@
spring:
application:
name: stats
profiles:
active: dev
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
file-extension: yaml
# 共享配置文件,排序越高后,优先级越高。
shared-configs:
- data-id: application-dev.yaml
group: DEFAULT_GROUP
refresh: true
sentinel:
eager: true
datasource:
ds1:
nacos:
server-addr: localhost:8848
data-id: ${spring.application.name}-dev-sentinel
group-id: DEFAULT_GROUP
data-type: json
# 如果是降级服务需要改为degrade
rule-type: flow
main:
allow-bean-definition-overriding: true

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 本项目全部使用log4j2性能上有很大提升 -->
<!--monitorInterval="60" 自动检测配置文件更改时间 单位为秒 最小值为5 -->
<!--Configuration后面的status这个用于设置log4j2自身内部的信息输出可以不设置当设置成trace时你会看到log4j2内部各种详细输出。 -->
<configuration monitorInterval="20" status="OFF">
<!--日志变量 -->
<properties>
<!-- 日志主目录 ,需要保存到文件时请自己配置-->
<property name="LOG_HOME">./zzlogs/stats</property>
<!-- 日志备份目录 -->
<property name="BACKUP_HOME">./zzlogs/stats/backup</property>
<!-- 日志输出级别 -->
<property name="OUTPUT_LOG_LEVEL">info</property>
<!-- 日志输出格式 -->
<property name="LOG_PATTERN">
<!-- 输出格式%d{HH:mm:ss}时间24小时制 -->
<!-- %-5p日志级别 5位左对齐 [%t]线程名 [%c]类名 -->
<!--%l输出日志事件的发生位置相当于%c.%M(%F:%L)的组合包括类全名、方法、文件名以及在代码中的行数。例如test.TestLog4j.main(TestLog4j.java:10)。 -->
<!-- 另一种输出风格<PatternLayout pattern="级别%-5p [%d{YYYY-MM-dd HH:mm:ss}] [%t] 位置[%l] - 信息:%msg%n" /> -->
<!-- [%-5p][%d{yy-MM-dd HH:mm:ss}][%t]==>%m==>%c==>%L%n -->
[%-5p] [%d{YYYY-MM-dd HH:mm:ss}] [%t] ==> %msg%n
</property>
<property name="LOG_PATTERN_EX">
<!-- 下面注释中 %X{PtxId}, SpanId: %X{PspanId} 为PinPoint 中的traceid -->
[%-5p] [%d{YYYY-MM-dd HH:mm:ss}] 请求Id[%X{traceId}] [%t] ==> [TxId: %X{PtxId}, SpanId: %X{PspanId}] %msg%n
</property>
<!-- 日志保留天数 -->
<property name="EVERY_FILE_COUNT">31</property>
<!-- 日志切割的最小单位 -->
<property name="EVERY_FILE_SIZE">20M</property>
</properties>
<appenders>
<!--Kafka输出 -->
<Kafka name="kafka_log" topic="zz-log-topic" syncSend="false" ignoreExceptions="false">
<PatternLayout pattern="${LOG_PATTERN_EX}"/>
<Property name="bootstrap.servers">localhost:9092</Property>
<Property name="max.block.ms">10000</Property>
</Kafka>
<!--控制台输出 -->
<console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</console>
<!--每次大小超过size则这size大小的日志会自动进行压缩作为存档 -->
<rollingFile name="file_log" fileName="${LOG_HOME}/stats.log"
filePattern="${LOG_HOME}/stats-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout charset="UTF-8" pattern="${LOG_PATTERN_EX}"/>
<!-- 日志切割的最小单位 -->
<SizeBasedTriggeringPolicy size="${EVERY_FILE_SIZE}"/>
<!-- 默认的日志文件数量 -->
<DefaultRolloverStrategy max="${EVERY_FILE_COUNT}"/>
</rollingFile>
</appenders>
<!-- 然后定义logger只有定义了logger并引入的appenderappender才会生效 -->
<!-- 这里我们把输出到控制台appender的日志级别设置为DEBUG便于调试。但是输出文件我们缺省为INFO两者均可随时修改。-->
<Loggers>
<Root level="${OUTPUT_LOG_LEVEL}">
<AppenderRef ref="console"/>
</Root>
<!-- AsyncLogger 是基于Disruptor的全量异步队列性能极高队列默认大小4096。-->
<!-- 队列默认值可通过JVM参数设置参考博客https://www.jianshu.com/p/82469047acbf -->
<AsyncLogger name="com.orange.demo" additivity="false" level="info">
<AppenderRef ref="console"/>
<AppenderRef ref="kafka_log"/>
<AppenderRef ref="file_log"/>
</AsyncLogger>
<!-- 这里将dao的日志级别设置为DEBUG是为了SQL语句的输出 -->
<AsyncLogger name="com.orange.demo.statsservice.dao" additivity="false" level="debug">
<AppenderRef ref="console"/>
<AppenderRef ref="kafka_log"/>
<AppenderRef ref="file_log"/>
</AsyncLogger>
</Loggers>
</configuration>

View File

@@ -0,0 +1,329 @@
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
.b1{white-space-collapsing:preserve;}
.t1{border-collapse:collapse;border-spacing:0;}
.r1{height:23.25pt;}
.r2{height:18.75pt;}
.r3{height:17.25pt;}
.r4{height:15.0pt;}
.r5{height:14.25pt;}
.r6{height:21.0pt;}
.r7{height:18.0pt;}
.r8{height:15.75pt;}
.r9{height:19.5pt;}
.r10{height:17.0pt;}
.r11{height:20.25pt;}
.r12{height:28.5pt;}
.c1{white-space:pre-wrap;text-align:center;border-bottom:thin solid black;font-weight:bold;color: #dd0806; font-size:18pt;}
.c2{white-space:pre-wrap;text-align:center;background-color:#ffff00;border-top:thin solid black;border-left:thin solid black;color: #dd0806; font-size:12pt;}
.c3{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-left:thin solid black;color: #dd0806; font-size:12pt;}
.c4{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;color: #dd0806; font-size:12pt;}
.c5{white-space:pre-wrap;text-align:center;color: #dd0806; font-size:10pt;}
.c6{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;color: #dd0806; font-size:10pt;}
.c7{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;color: #dd0806; font-size:10pt;}
.c8{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:9pt;}
.c9{white-space:pre-wrap;text-align:center;background-color:#ffff00;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;color: #dd0806; font-size:11pt;}
.c10{white-space:pre-wrap;text-align:center;border-right:thin solid black;border-left:thin solid black;font-size:10pt;}
.c11{white-space:pre-wrap;text-align:center;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:10pt;}
.c12{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-left:thin solid black;font-size:10pt;}
.c13{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:8pt;}
.c14{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-left:thin solid black;font-size:8pt;}
.c15{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:10pt;}
.c16{white-space:pre-wrap;text-align:center;background-color:#ffff00;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:11pt;}
.c17{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:11pt;}
.c18{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:6pt;}
.c19{white-space:pre-wrap;text-align:center;border-right:thin solid black;border-bottom:thin solid black;border-left:thin solid black;font-size:6pt;}
.c20{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-left:thin solid black;font-weight:bold;font-size:6pt;}
.c21{white-space:pre-wrap;text-align:center;border-top:thin solid black;border-right:thin solid black;border-left:thin solid black;font-weight:bold;font-size:8pt;}
.c22{white-space:pre-wrap;text-align:left;border-top:thin solid black;font-weight:bold;font-size:9pt;}
</style>
</head>
<body class="b1">
<table class="t1">
<colgroup>
<col width="40">
<col width="40">
<col width="57">
<col width="57">
<col width="57">
<col width="57">
<col width="57">
<col width="56">
<col width="59">
<col width="57">
<col width="57">
<col width="57">
<col width="57">
<col width="57">
<col width="57">
<col width="57">
</colgroup>
<tbody>
<tr class="r1">
<td class="c1" colspan="16">天津公安警官职业学院2017—2018学年度第一学期课程表</td>
</tr>
<tr class="r1">
<td class="c2" colspan="2" rowspan="2">班 级</td>
<td class="c3" colspan="3">星期一</td>
<td class="c4" colspan="3">星期二</td>
<td class="c4" colspan="3">星期三</td>
<td class="c4" colspan="3">星期四</td>
<td class="c4" colspan="2">星期五</td>
</tr>
<tr class="r2">
<td class="c5">第1节</td>
<td class="c5">第2节</td>
<td class="c5">第3节</td>
<td class="c6">第1节</td>
<td class="c7">第2节</td>
<td class="c7">第3节</td>
<td class="c7">第1节</td>
<td class="c7">第2节</td>
<td class="c7">第3节</td>
<td class="c7">第1节</td>
<td class="c7">第2节</td>
<td class="c7">第3节</td>
<td class="c7">第1节</td>
<td class="c7">第2节</td>
</tr>
<tr class="r2">
<td class="c8" rowspan="6">16 级 刑 事 技 术 班 </td>
<td class="c9" rowspan="2">课程</td>
<td class="c10" rowspan="2">刑法</td>
<td class="c10" rowspan="6">自习</td>
<td class="c11">刑事图像</td>
<td class="c12" rowspan="2">民 法(选修)</td>
<td class="c13">派出所工作</td>
<td class="c12" rowspan="2">刑事图像</td>
<td class="c12" rowspan="2">法医学</td>
<td class="c14" rowspan="2">派出所工作</td>
<td class="c15">法医学</td>
<td class="c12" rowspan="2">国内安全保卫</td>
<td class="c12" rowspan="2">体能</td>
<td class="c12" rowspan="6">自习</td>
<td class="c12" rowspan="2">刑事技术总论</td>
<td class="c12" rowspan="2">刑法</td>
</tr>
<tr class="r3">
<td class="c11">自习</td>
<td class="c11">自习</td>
<td class="c11">自习</td>
</tr>
<tr class="r3">
<td class="c16" rowspan="2">教师</td>
<td class="c12" rowspan="2">曾岚</td>
<td class="c15">陈磊</td>
<td class="c12" rowspan="2">邵刚</td>
<td class="c15">杨丽伟</td>
<td class="c12" rowspan="2">陈磊</td>
<td class="c12" rowspan="2">于辉</td>
<td class="c12" rowspan="2">杨丽伟</td>
<td class="c15">于辉</td>
<td class="c12" rowspan="2">朱学强</td>
<td class="c12" rowspan="2">张付海</td>
<td class="c12" rowspan="2">王 伟(刑技)</td>
<td class="c12" rowspan="2">曾岚</td>
</tr>
<tr class="r3">
<td class="c11"> </td>
<td class="c11"> </td>
<td class="c11"> </td>
</tr>
<tr class="r3">
<td class="c16" rowspan="2">教室</td>
<td class="c15" rowspan="2">206</td>
<td class="c15">206</td>
<td class="c15" rowspan="2">206</td>
<td class="c15">206</td>
<td class="c15" rowspan="2">206</td>
<td class="c15" rowspan="2">206</td>
<td class="c15" rowspan="2">206</td>
<td class="c15">206</td>
<td class="c15" rowspan="2">206</td>
<td class="c15" rowspan="2">操场</td>
<td class="c15" rowspan="2">206</td>
<td class="c15" rowspan="2">206</td>
</tr>
<tr class="r4">
<td class="c15"> </td>
<td class="c11"> </td>
<td class="c11"> </td>
</tr>
<tr class="r2">
<td class="c8" rowspan="6">16 级 刑 事 侦 查 </td>
<td class="c17" rowspan="2">课程</td>
<td class="c12" rowspan="6">自习</td>
<td class="c12" rowspan="2">侦查措施</td>
<td class="c12" rowspan="2">经济案件侦查</td>
<td class="c14" rowspan="2">公安信息化</td>
<td class="c14" rowspan="2">公安信息化</td>
<td class="c12" rowspan="2">刑法</td>
<td class="c12" rowspan="2">体能</td>
<td class="c12" rowspan="6">自习</td>
<td class="c12" rowspan="2">痕迹检验</td>
<td class="c12" rowspan="2">刑法</td>
<td class="c12" rowspan="2">国内安全保卫</td>
<td class="c18">经济案件侦查</td>
<td class="c12" rowspan="2">痕迹检验</td>
<td class="c12" rowspan="2">民 法(选修)</td>
</tr>
<tr class="r3">
<td class="c11">侦查措施</td>
</tr>
<tr class="r3">
<td class="c17" rowspan="2">教师</td>
<td class="c12" rowspan="2">徐宏涛</td>
<td class="c12" rowspan="2">张静</td>
<td class="c12" rowspan="2">赵晓松</td>
<td class="c12" rowspan="2">赵晓松</td>
<td class="c12" rowspan="2">王骏强</td>
<td class="c12" rowspan="2">张付海</td>
<td class="c12" rowspan="2">郭海川</td>
<td class="c12" rowspan="2">王骏强</td>
<td class="c12" rowspan="2">朱学强</td>
<td class="c15">张静</td>
<td class="c12" rowspan="2">郭海川</td>
<td class="c12" rowspan="2">邵刚</td>
</tr>
<tr class="r3">
<td class="c11">徐宏涛</td>
</tr>
<tr class="r3">
<td class="c17" rowspan="2">教室</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">3号机房</td>
<td class="c15" rowspan="2">3号机房</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">操场</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">202</td>
<td class="c15" rowspan="2">202</td>
</tr>
<tr class="r5">
</tr>
<tr class="r2">
<td class="c8" rowspan="6">16 级 治 安 管 理 班 </td>
<td class="c17" rowspan="2">课程</td>
<td class="c12" rowspan="2">刑事技术</td>
<td class="c12" rowspan="2">体能</td>
<td class="c12" rowspan="2">刑事技术</td>
<td class="c12" rowspan="2">治安秩序管理</td>
<td class="c12" rowspan="2">刑事侦查概论</td>
<td class="c12" rowspan="2">刑法</td>
<td class="c18">群众工作与纠纷调解</td>
<td class="c12" rowspan="2">群众工作与纠纷调解</td>
<td class="c12" rowspan="2">公共关系(选修)</td>
<td class="c12" rowspan="2">刑事侦查概论</td>
<td class="c12" rowspan="2">刑法</td>
<td class="c12" rowspan="6">自习</td>
<td class="c12" rowspan="6">自习</td>
<td class="c12" rowspan="6">自习</td>
</tr>
<tr class="r6">
<td class="c19">q</td>
</tr>
<tr class="r7">
<td class="c17" rowspan="2">教师</td>
<td class="c12" rowspan="2">郭海川 韩易浦</td>
<td class="c12" rowspan="2">张付海</td>
<td class="c12" rowspan="2">郭海川 韩易浦</td>
<td class="c12" rowspan="2">翟政亮</td>
<td class="c12" rowspan="2">邵妍</td>
<td class="c12" rowspan="2">薛强</td>
<td class="c15">刘晓鹏</td>
<td class="c12" rowspan="2">刘晓鹏</td>
<td class="c12" rowspan="2">尚欣</td>
<td class="c12" rowspan="2">邵妍</td>
<td class="c12" rowspan="2">薛强</td>
</tr>
<tr class="r7">
<td class="c11">翟政亮</td>
</tr>
<tr class="r3">
<td class="c17" rowspan="2">教室</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">操场</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
<td class="c15" rowspan="2">218</td>
</tr>
<tr class="r8">
</tr>
<tr class="r2">
<td class="c13" rowspan="6">16 网 络 安 全 监 察 1 班</td>
<td class="c17" rowspan="2">课程</td>
<td class="c12" rowspan="2">应用写作</td>
<td class="c14" rowspan="2">数据库系统应用</td>
<td class="c20" rowspan="2">周二中午:计算机安全管理及实用技术</td>
<td class="c13">刑事诉讼法</td>
<td class="c21" rowspan="2">周一中午:数据库系统应用</td>
<td class="c12" rowspan="2">民法</td>
<td class="c12" rowspan="2">体育</td>
<td class="c12" rowspan="2">VB语言程序设计</td>
<td class="c12" rowspan="6">选修</td>
<td class="c12" rowspan="2">VB语言程序设计</td>
<td class="c12" rowspan="2">刑事诉讼法</td>
<td class="c12" rowspan="6">选修</td>
<td class="c15">应用写作</td>
<td class="c12" rowspan="2">犯罪心理</td>
</tr>
<tr class="r2">
<td class="c11">民法</td>
<td class="c11">犯罪心理</td>
</tr>
<tr class="r9">
<td class="c17" rowspan="2">教师</td>
<td class="c12" rowspan="2">关利</td>
<td class="c12" rowspan="2">杨斌</td>
<td class="c12" rowspan="2">赵晓松</td>
<td class="c15">王伟</td>
<td class="c12" rowspan="2">杨斌</td>
<td class="c12" rowspan="2">李静</td>
<td class="c12" rowspan="2">程军</td>
<td class="c12" rowspan="2">赵伟</td>
<td class="c12" rowspan="2">赵伟</td>
<td class="c12" rowspan="2">王伟</td>
<td class="c15">关利</td>
<td class="c12" rowspan="2">张学林</td>
</tr>
<tr class="r10">
<td class="c11">李静</td>
<td class="c11">张学林</td>
</tr>
<tr class="r3">
<td class="c17" rowspan="2">教室</td>
<td class="c15" rowspan="2">东阶梯</td>
<td class="c15" rowspan="2">2号机房</td>
<td class="c15" rowspan="2">主楼201</td>
<td class="c15" rowspan="2">101</td>
<td class="c15" rowspan="2">2号机房</td>
<td class="c15" rowspan="2">101</td>
<td class="c15" rowspan="2">操场</td>
<td class="c15" rowspan="2">3号机房</td>
<td class="c15" rowspan="2">3号机房</td>
<td class="c15" rowspan="2">101</td>
<td class="c15">东阶梯</td>
<td class="c15" rowspan="2">主楼201</td>
</tr>
<tr class="r11">
<td class="c11">主楼201</td>
</tr>
<tr class="r12">
<td class="c22" colspan="16">注:1、课程一栏中有两科次的上面的课程单周上课下面的课程双周上课。2、每天上课时间上午第1节8:30至9:55第2节10:15至11:40中午上课时间12:30至13:55下午第3节14:00至15:25。</td>
</tr>
</tbody>
</table>
</body>
</html>