Kaynağa Gözat

Merge branch 'feature/1221-suggest' into online

# Conflicts:
#	cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java
yuanliang 1 yıl önce
ebeveyn
işleme
5430f24ec5
32 değiştirilmiş dosya ile 2113 ekleme ve 26 silme
  1. 149 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysSuggestionTypeController.java
  2. 191 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysSuggestionV2Controller.java
  3. 55 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/SysSuggestionTypeVo.java
  4. 94 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/SysSuggestionVo.java
  5. 4 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysMessageController.java
  6. 77 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionTypeController.java
  7. 167 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionV2Controller.java
  8. 4 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysMessageController.java
  9. 77 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionTypeController.java
  10. 152 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionV2Controller.java
  11. 28 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ESuggestionHandleAttitude.java
  12. 4 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMessageDao.java
  13. 52 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysSuggestionType.java
  14. 89 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysSuggestionV2.java
  15. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java
  16. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SuggestionType.java
  17. 27 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/SysSuggestionTypeMapper.java
  18. 25 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/SysSuggestionV2Mapper.java
  19. 7 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMessageService.java
  20. 44 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysSuggestionTypeService.java
  21. 47 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysSuggestionV2Service.java
  22. 25 12
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMessageServiceImpl.java
  23. 69 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysSuggestionTypeServiceImpl.java
  24. 140 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysSuggestionV2ServiceImpl.java
  25. 105 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysMessageWrapper.java
  26. 89 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysSuggestionTypeWrapper.java
  27. 206 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysSuggestionWrapper.java
  28. 37 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMessageMapper.xml
  29. 24 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysSuggestionTypeMapper.xml
  30. 112 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysSuggestionV2Mapper.xml
  31. 4 2
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SysMessageController.java
  32. 4 2
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/SysMessageController.java

+ 149 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysSuggestionTypeController.java

@@ -0,0 +1,149 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.admin.io.request.SysSuggestionTypeVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionType;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionTypeService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionTypeWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/sysSuggestionType")
+@Api(tags = "平台建议类型表")
+public class SysSuggestionTypeController {
+
+    @Autowired
+    private SysSuggestionTypeService sysSuggestionTypeService;
+
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation(value = "详情", notes = "平台建议类型表-根据详情ID查询单条, 传入id")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionType/detail')")
+    @GetMapping("/detail/{id}")
+    public R<SysSuggestionType> detail(@PathVariable("id") Long id) {
+
+        SysSuggestionType wrapper = sysSuggestionTypeService.detail(id);
+
+        return R.from(wrapper);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "平台建议类型表- 传入 SysSuggestionTypeWrapper.SysSuggestionTypeQuery")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionType/page')")
+    @PostMapping("/page")
+    public R<PageInfo<SysSuggestionTypeWrapper.SysSuggestionType>> page(@RequestBody SysSuggestionTypeWrapper.SysSuggestionTypeQuery query) {
+
+        IPage<SysSuggestionType> pages = sysSuggestionTypeService.selectPage(QueryInfo.getPage(query), query);
+
+        Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> idEmpMap = new HashMap<>();
+        List<Long> updateIds = pages.getRecords().stream().map(SysSuggestionType::getUpdateBy)
+            .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (!updateIds.isEmpty()) {
+            Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> idEmpMapTmp = sysUserService.getMapByIds(updateIds);
+            idEmpMap.putAll(idEmpMapTmp);
+        }
+        List<SysSuggestionTypeWrapper.SysSuggestionType> rows = pages.getRecords().stream().map(next -> {
+            SysSuggestionTypeWrapper.SysSuggestionType type =
+                JSON.parseObject(JSON.toJSONString(next), SysSuggestionTypeWrapper.SysSuggestionType.class);
+            if (type.getUpdateBy() != null) {
+                type.setOperator(idEmpMap.getOrDefault(type.getUpdateBy(), new com.yonge.cooleshow.biz.dal.entity.SysUser()).getUsername());
+            }
+            return type;
+        }).collect(Collectors.toList());
+        return R.from(QueryInfo.pageInfo(pages, rows));
+    }
+
+    @ApiOperation(value = "新增", notes = "平台建议类型表- 传入 SysSuggestionTypeWrapper.SysSuggestionType")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionType/save')")
+    @PostMapping("/save")
+    public R<JSONObject> add(@Validated @RequestBody SysSuggestionTypeVo.SysSuggestionType sysSuggestionType) {
+
+        Integer count = sysSuggestionTypeService.lambdaQuery()
+            .eq(SysSuggestionType::getName, sysSuggestionType.getName())
+            .eq(SysSuggestionType::getDelFlag, false)
+            .count();
+        if (count > 0) {
+            throw new BizException("建议类型已存在");
+        }
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        SysSuggestionType suggestionType = new SysSuggestionType();
+        suggestionType.setName(sysSuggestionType.getName());
+        suggestionType.setCreateBy(sysUser.getId());
+        suggestionType.setUpdateBy(sysUser.getId());
+        suggestionType.setDelFlag(false);
+        // 新增数据
+        sysSuggestionTypeService.save(suggestionType);
+
+        return R.defaultR();
+    }
+
+    @ApiOperation(value = "修改", notes = "平台建议类型表- 传入 SysSuggestionTypeWrapper.SysSuggestionType")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionType/update')")
+    @PostMapping("/update")
+    public R<JSONObject> update(@Validated @RequestBody SysSuggestionTypeVo.SysSuggestionType sysSuggestionType) {
+
+        Integer count = sysSuggestionTypeService.lambdaQuery()
+            .eq(SysSuggestionType::getName, sysSuggestionType.getName())
+            .eq(SysSuggestionType::getDelFlag, false)
+            .ne(SysSuggestionType::getId, sysSuggestionType.getId())
+            .count();
+        if (count > 0) {
+            throw new BizException("建议类型已存在");
+        }
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        SysSuggestionType suggestionType = new SysSuggestionType();
+        suggestionType.setId(sysSuggestionType.getId());
+        suggestionType.setName(sysSuggestionType.getName());
+        suggestionType.setUpdateBy(sysUser.getId());
+        suggestionType.setDelFlag(false);
+        // 更新数据
+        sysSuggestionTypeService.updateById(suggestionType);
+
+        return R.defaultR();
+    }
+
+    @ApiOperation(value = "删除", notes = "平台建议类型表- 传入id")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionType/remove')")
+    @PostMapping("/remove")
+    public R<JSONObject> remove(@RequestParam Long id) {
+        sysSuggestionTypeService.lambdaUpdate()
+            .set(SysSuggestionType::getDelFlag, true)
+            .eq(SysSuggestionType::getId, id)
+            .update();
+        return R.defaultR();
+    }
+}

+ 191 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysSuggestionV2Controller.java

@@ -0,0 +1,191 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.admin.io.request.SysSuggestionVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
+import com.yonge.cooleshow.biz.dal.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionV2Service;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+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.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/sysSuggestionV2")
+@Api(tags = "平台建议表")
+public class SysSuggestionV2Controller extends BaseController {
+
+    @Autowired
+    private SysSuggestionV2Service sysSuggestionService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+
+    /**
+     * 查询单条
+     *
+     * @param id 详情ID
+     * @return R<SysSuggestionVo.SysSuggestion>
+     */
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionV2/detail')")
+    @GetMapping("/detail/{id}")
+    public R<SysSuggestionWrapper.SysSuggestion> detail(@PathVariable("id") Long id) {
+
+        // 建议详情
+        SysSuggestionV2 wrapper = sysSuggestionService.detail(id);
+        SysSuggestionWrapper.SysSuggestion suggestion =
+                SysSuggestionWrapper.SysSuggestion.from(JSON.toJSONString(wrapper));
+        if (wrapper != null && wrapper.getSuggestionTypeId() != null) {
+            List<Long> userIdList = new ArrayList<>();
+            userIdList.add(wrapper.getUserId());
+            if (wrapper.getHandleBy() != null) {
+                userIdList.add(wrapper.getHandleBy());
+            }
+            Map<Long, SysUser> userIdMap = sysUserService.getMapByIds(userIdList);
+            suggestion.setNickname(userIdMap.getOrDefault(suggestion.getUserId(), new SysUser()).getUsername());
+            suggestion.setHandleName(userIdMap.getOrDefault(suggestion.getHandleBy(), new SysUser()).getUsername());
+        }
+
+        return R.from(suggestion);
+    }
+
+    /**
+     * 查询分页
+     *
+     * @param query SysSuggestionWrapper.SysSuggestionQuery
+     * @return R<PageInfo < SysSuggestionWrapper.SysSuggestion>>
+     */
+    @ApiOperation(value = "查询分页", notes = "传入sysSuggestionSearch")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionV2/page')")
+    @PostMapping("/page")
+    public R<PageInfo<SysSuggestionWrapper.SysSuggestion>> page(@RequestBody SysSuggestionWrapper.SysSuggestionQuery query) {
+
+        IPage<SysSuggestionWrapper.SysSuggestion> pages = sysSuggestionService.selectPage(QueryInfo.getPage(query), query);
+
+        List<SysSuggestionWrapper.SysSuggestion> records = pages.getRecords();
+        if (CollectionUtils.isNotEmpty(records)) {
+            List<Long> userIdList = records.stream()
+                    .map(SysSuggestionWrapper.SysSuggestion::getUserId)
+                    .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+
+            List<Long> handUserIdList = records.stream()
+                    .map(SysSuggestionWrapper.SysSuggestion::getHandleBy)
+                    .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+            if (!handUserIdList.isEmpty()) {
+                userIdList.addAll(handUserIdList);
+            }
+            Map<Long, SysUser> userIdMap = sysUserService.getMapByIds(userIdList);
+
+            records.forEach(next -> {
+                next.setNickname(userIdMap.getOrDefault(next.getUserId(), new SysUser()).getUsername());
+                next.setHandleName(userIdMap.getOrDefault(next.getHandleBy(), new SysUser()).getUsername());
+            });
+        }
+        return R.from(QueryInfo.pageInfo(pages, records));
+    }
+
+    /**
+     * 新增
+     *
+     * @param suggestion SysSuggestionVo.SysSuggestion
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "传入sysSuggestion")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionV2/save')")
+    @PostMapping("/save")
+    public R<Boolean> add(@Validated @RequestBody SysSuggestionVo.SysSuggestion suggestion,
+                          @RequestHeader(name = "user-agent") String userAgent) {
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserFeignService.queryUserInfo();
+        suggestion.setUserId(sysUser.getId());
+        suggestion.setClientType(ClientEnum.SYSTEM);
+        suggestion.setUserAgent(userAgent);
+
+        return R.from(sysSuggestionService.add(JSON.parseObject(suggestion.jsonString(), SysSuggestionV2.class)));
+    }
+
+    /**
+     * 修改
+     *
+     * @param suggestion SysSuggestionVo.SysSuggestion
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "修改", notes = "传入sysSuggestion")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionV2/update')")
+//	@PostMapping("/update")
+    public R<Boolean> update(@Validated @RequestBody SysSuggestionVo.SysSuggestion suggestion) {
+
+        return R.from(sysSuggestionService.update(JSON.parseObject(suggestion.jsonString(), SysSuggestionV2.class)));
+    }
+
+    /**
+     * 删除
+     *
+     * @param id 详情ID
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "删除", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionV2/remove')")
+    @PostMapping("/remove")
+    public R<Boolean> remove(@RequestParam Long id) {
+
+        return R.from(sysSuggestionService.removeById(id));
+    }
+
+    @ApiOperation(value = "修改", notes = "传入sysSuggestion")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionV2/handleSuggestion')")
+    @PostMapping("/handleSuggestion")
+    public R<Boolean> handleSuggestion(@Validated @RequestBody SysSuggestionWrapper.HandleSuggestion handleSuggestion) {
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserFeignService.queryUserInfo();
+        handleSuggestion.setHandleBy(sysUser.getId());
+        return R.from(sysSuggestionService.handleSuggestion(handleSuggestion));
+    }
+
+    @ApiOperation(value = "查询未处理的建议数量")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestionV2/queryUnHandleNum')")
+    @GetMapping("/queryUnHandleNum")
+    public R<Integer> queryUnHandleNum() {
+        Integer count = sysSuggestionService.lambdaQuery()
+                .eq(SysSuggestionV2::getHandleStatus, false)
+                .count();
+        return R.from(count);
+    }
+}

+ 55 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/SysSuggestionTypeVo.java

@@ -0,0 +1,55 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 平台建议类型表
+ * 2023-08-30 11:26:33
+ */
+@ApiModel(value = "SysSuggestionTypeVo对象", description = "平台建议类型表查询视图对象")
+public class SysSuggestionTypeVo {
+
+    @Data
+    @ApiModel(" SysSuggestionTypeQuery-平台建议类型表")
+    public static class SysSuggestionTypeQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static SysSuggestionTypeQuery from(String json) {
+            return JSON.parseObject(json, SysSuggestionTypeQuery.class);
+        }
+    }
+
+    @Data
+    @ApiModel(" SysSuggestionType-平台建议类型表")
+    public static class SysSuggestionType {
+
+
+        @ApiModelProperty("编号")
+        private Long id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static SysSuggestionType from(String json) {
+            return JSON.parseObject(json, SysSuggestionType.class);
+        }
+    }
+
+}

+ 94 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/SysSuggestionVo.java

@@ -0,0 +1,94 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SuggestionType;
+import com.yonge.cooleshow.common.enums.ESuggestionHandleAttitude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 平台建议表
+ * 2022-11-15 17:59:45
+ */
+@ApiModel(value = "SysSuggestionVo对象", description = "平台建议表查询视图对象")
+public class SysSuggestionVo {
+
+    @Data
+    @ApiModel(" SysSuggestionList-平台建议表")
+    public static class SysSuggestionQuery implements QueryInfo {
+
+        @ApiModelProperty(value = "当前页")
+        private Integer page;
+
+        @ApiModelProperty(value = "分页行数")
+        private Integer rows;
+
+        @ApiModelProperty(value = "客户端类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("建议类型")
+        private SuggestionType suggestionType;
+
+        @ApiModelProperty("开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("结束时间")
+        private Date endTime;
+    }
+
+    @Data
+    @ApiModel(" SysSuggestion-平台建议表")
+    public static class SysSuggestion {
+
+
+        @ApiModelProperty("编号")
+        private Long id;
+
+        @ApiModelProperty(value = "建议类型ID", required = true)
+        @NotNull
+        private Long suggestionTypeId;
+
+        @ApiModelProperty(value = "联系方式", required = true)
+        @NotNull
+        private String mobileNo;
+
+        @ApiModelProperty(value = "建议类型", required = true)
+        @NotNull
+        private SuggestionType type;
+
+        @ApiModelProperty(value = "内容", required = true)
+        @NotNull
+        private String content;
+
+        @ApiModelProperty("附件信息, 多个,隔开")
+        private String attachmentUrls;
+
+        @ApiModelProperty("用户编号")
+        private Long userId;
+
+        @ApiModelProperty("客户端类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("客户端信息")
+        private String userAgent;
+
+        @ApiModelProperty("处理态度")
+        private ESuggestionHandleAttitude handleAttitude;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static SysSuggestion from(String json) {
+            return JSON.parseObject(json, SysSuggestion.class);
+        }
+
+    }
+
+}

+ 4 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysMessageController.java

@@ -5,7 +5,9 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.search.SysMessageQueryInfo;
 import com.yonge.cooleshow.biz.dal.entity.SysMessage;
 import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.Mapper;
@@ -70,13 +72,13 @@ public class SysMessageController extends BaseController {
 
 	@ApiOperation("一键已读")
 	@PostMapping("batchSetRead")
-	public Object batchSetRead() {
+	public Object batchSetRead(@RequestParam(value = "messageType", required = false) MessageTypeEnum messageType) {
 		int status = 1;
 		SysUser sysUser = sysUserFeignService.queryUserInfo();
 		if (sysUser == null) {
 			return failed(HttpStatus.FORBIDDEN, "请登录");
 		}
-		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"STUDENT") > 0 );
+		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"STUDENT",messageType) > 0 );
 	}
 
 	@ApiOperation("设置已读")

+ 77 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionTypeController.java

@@ -0,0 +1,77 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionType;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionTypeService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionTypeWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+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 java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/sysSuggestionType")
+@Api(tags = "平台建议类型表")
+public class SysSuggestionTypeController {
+
+    @Autowired
+    private SysSuggestionTypeService sysSuggestionTypeService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation(value = "详情", notes = "平台建议类型表-根据详情ID查询单条, 传入id")
+    @GetMapping("/detail/{id}")
+    public R<SysSuggestionType> detail(@PathVariable("id") Long id) {
+
+        SysSuggestionType wrapper = sysSuggestionTypeService.detail(id);
+
+        return R.from(wrapper);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "平台建议类型表- 传入 SysSuggestionTypeWrapper.SysSuggestionTypeQuery")
+    @PostMapping("/page")
+    public R<PageInfo<SysSuggestionTypeWrapper.SysSuggestionType>> page(@RequestBody SysSuggestionTypeWrapper.SysSuggestionTypeQuery query) {
+
+        IPage<SysSuggestionType> pages = sysSuggestionTypeService.selectPage(QueryInfo.getPage(query), query);
+
+        Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> idEmpMap = new HashMap<>();
+        List<Long> updateIds = pages.getRecords().stream().map(SysSuggestionType::getUpdateBy)
+            .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (!updateIds.isEmpty()) {
+            Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> idEmpMapTmp = sysUserService.getMapByIds(updateIds);
+            idEmpMap.putAll(idEmpMapTmp);
+        }
+        List<SysSuggestionTypeWrapper.SysSuggestionType> rows = pages.getRecords().stream().map(next -> {
+            SysSuggestionTypeWrapper.SysSuggestionType type =
+                JSON.parseObject(JSON.toJSONString(next), SysSuggestionTypeWrapper.SysSuggestionType.class);
+            if (type.getUpdateBy() != null) {
+                type.setOperator(idEmpMap.getOrDefault(type.getUpdateBy(), new com.yonge.cooleshow.biz.dal.entity.SysUser()).getUsername());
+            }
+            return type;
+        }).collect(Collectors.toList());
+        return R.from(QueryInfo.pageInfo(pages, rows));
+    }
+
+}

+ 167 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionV2Controller.java

@@ -0,0 +1,167 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.admin.io.request.SysSuggestionVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.SysMessageConfig;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
+import com.yonge.cooleshow.biz.dal.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SysMessageConfigService;
+import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionV2Service;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/sysSuggestionV2")
+@Api(tags = "平台建议表")
+public class SysSuggestionV2Controller extends BaseController {
+
+    @Autowired
+    private SysSuggestionV2Service sysSuggestionService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SysMessageService sysMessageService;
+
+    @Autowired
+    private SysMessageConfigService sysMessageConfigService;
+
+    /**
+     * 查询分页
+     *
+     * @param query SysSuggestionWrapper.SysSuggestionQuery
+     * @return R<PageInfo < SysSuggestionWrapper.SysSuggestion>>
+     */
+    @ApiOperation(value = "查询分页", notes = "传入sysSuggestionSearch")
+    @PostMapping("/page")
+    public R<PageInfo<SysSuggestionWrapper.SysSuggestion>> page(@RequestBody SysSuggestionWrapper.SysSuggestionQuery query) {
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserFeignService.queryUserInfo();
+        query.setUserId(sysUser.getId());
+        Student student = studentService.getById(sysUser.getId());
+        if (student.getTenantId() != null && student.getTenantId() != -1) {
+            query.setClientType(ClientEnum.TENANT_STUDENT);
+        } else {
+            query.setClientType(ClientEnum.STUDENT);
+        }
+
+        IPage<SysSuggestionWrapper.SysSuggestion> pages = sysSuggestionService.selectPage(QueryInfo.getPage(query), query);
+
+        List<SysSuggestionWrapper.SysSuggestion> records = pages.getRecords();
+        if (CollectionUtils.isNotEmpty(records)) {
+            List<Long> userIdList = records.stream()
+                    .map(SysSuggestionWrapper.SysSuggestion::getUserId)
+                    .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+
+            List<Long> handUserIdList = records.stream()
+                    .map(SysSuggestionWrapper.SysSuggestion::getHandleBy)
+                    .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+            if (!handUserIdList.isEmpty()) {
+                userIdList.addAll(handUserIdList);
+            }
+            Map<Long, SysUser> userIdMap = sysUserService.getMapByIds(userIdList);
+
+            records.forEach(next -> {
+                next.setNickname(userIdMap.getOrDefault(next.getUserId(), new SysUser()).getUsername());
+                next.setHandleName(userIdMap.getOrDefault(next.getHandleBy(), new SysUser()).getUsername());
+            });
+        }
+        return R.from(QueryInfo.pageInfo(pages, records));
+    }
+
+
+    /**
+     * 新增
+     *
+     * @param suggestion SysSuggestionVo.SysSuggestion
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "传入sysSuggestion")
+    @PostMapping("/save")
+    public R<Boolean> add(@Validated @RequestBody SysSuggestionVo.SysSuggestion suggestion,
+                          @RequestHeader(name = "user-agent") String userAgent) {
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserFeignService.queryUserInfo();
+        suggestion.setUserId(sysUser.getId());
+        String userAgent1 = suggestion.getUserAgent();
+        if(StringUtils.isEmpty(userAgent1)){
+            userAgent1 = userAgent;
+        }
+        suggestion.setUserAgent(userAgent1);
+
+        Student student = studentService.getById(sysUser.getId());
+        if (student.getTenantId() != null && student.getTenantId() != -1) {
+            suggestion.setClientType(ClientEnum.TENANT_STUDENT);
+        } else {
+            suggestion.setClientType(ClientEnum.STUDENT);
+        }
+
+        SysSuggestionV2 sysSuggestion = JSON.parseObject(suggestion.jsonString(), SysSuggestionV2.class);
+        sysSuggestion.setCreateTime(new Date());
+        return R.from(sysSuggestionService.add(sysSuggestion));
+    }
+
+    @ApiOperation(value = "未读消息统计", notes = "统计当前用户推送未读消息数")
+    @GetMapping("/suggestMessageUnread")
+    public R<List<SysMessageWrapper.MessageUnreadStat>> suggestMessageUnread() {
+        com.yonge.cooleshow.auth.api.entity.SysUser userInfo = sysUserFeignService.queryUserInfo();
+
+        SysMessageConfig one = sysMessageConfigService.queryByType(MessageTypeEnum.SYS_SUGGEST_FEEDBACK_STUDENT.getCode());
+
+        // 未读消息统计条件
+        SysMessageWrapper.SysMessageQuery query = SysMessageWrapper.SysMessageQuery.builder()
+                .userId(userInfo.getId())
+                .clientType(ClientEnum.STUDENT)
+                .readStatus(false)
+                .type(MessageSendMode.PUSH)
+                .sendTime(DateTime.now().toDate())
+                .messageConfigId(one.getId())
+                .build();
+
+        // 统计未读消息数
+        List<SysMessageWrapper.MessageUnreadStat> unreadStats = sysMessageService.userMessageUnreadStat(query);
+
+        return R.from(unreadStats);
+    }
+}

+ 4 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysMessageController.java

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.biz.dal.dao.AppVersionInfoDao;
 import com.yonge.cooleshow.biz.dal.dto.search.SysMessageQueryInfo;
 import com.yonge.cooleshow.biz.dal.entity.SysMessage;
 import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.SysMessageService;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -24,6 +25,7 @@ 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.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
@@ -80,13 +82,13 @@ public class SysMessageController extends BaseController {
 
 	@ApiOperation("一键已读")
 	@PostMapping("batchSetRead")
-	public Object batchSetRead() {
+	public Object batchSetRead(@RequestParam(value = "messageType", required = false) MessageTypeEnum messageType) {
 		int status = 1;
 		SysUser sysUser = sysUserFeignService.queryUserInfo();
 		if (sysUser == null) {
 			return failed(HttpStatus.FORBIDDEN, "请登录");
 		}
-		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"TEACHER") > 0 );
+		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"TEACHER",messageType) > 0 );
 	}
 
 	@ApiOperation("设置已读")

+ 77 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionTypeController.java

@@ -0,0 +1,77 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionType;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionTypeService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionTypeWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+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 java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/sysSuggestionType")
+@Api(tags = "平台建议类型表")
+public class SysSuggestionTypeController {
+
+    @Autowired
+    private SysSuggestionTypeService sysSuggestionTypeService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation(value = "详情", notes = "平台建议类型表-根据详情ID查询单条, 传入id")
+    @GetMapping("/detail/{id}")
+    public R<SysSuggestionType> detail(@PathVariable("id") Long id) {
+
+        SysSuggestionType wrapper = sysSuggestionTypeService.detail(id);
+
+        return R.from(wrapper);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "平台建议类型表- 传入 SysSuggestionTypeWrapper.SysSuggestionTypeQuery")
+    @PostMapping("/page")
+    public R<PageInfo<SysSuggestionTypeWrapper.SysSuggestionType>> page(@RequestBody SysSuggestionTypeWrapper.SysSuggestionTypeQuery query) {
+
+        IPage<SysSuggestionType> pages = sysSuggestionTypeService.selectPage(QueryInfo.getPage(query), query);
+
+        Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> idEmpMap = new HashMap<>();
+        List<Long> updateIds = pages.getRecords().stream().map(SysSuggestionType::getUpdateBy)
+            .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (!updateIds.isEmpty()) {
+            Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> idEmpMapTmp = sysUserService.getMapByIds(updateIds);
+            idEmpMap.putAll(idEmpMapTmp);
+        }
+        List<SysSuggestionTypeWrapper.SysSuggestionType> rows = pages.getRecords().stream().map(next -> {
+            SysSuggestionTypeWrapper.SysSuggestionType type =
+                JSON.parseObject(JSON.toJSONString(next), SysSuggestionTypeWrapper.SysSuggestionType.class);
+            if (type.getUpdateBy() != null) {
+                type.setOperator(idEmpMap.getOrDefault(type.getUpdateBy(), new com.yonge.cooleshow.biz.dal.entity.SysUser()).getUsername());
+            }
+            return type;
+        }).collect(Collectors.toList());
+        return R.from(QueryInfo.pageInfo(pages, rows));
+    }
+
+}

+ 152 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionV2Controller.java

@@ -0,0 +1,152 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.admin.io.request.SysSuggestionVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysMessageConfig;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SysMessageConfigService;
+import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionV2Service;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/sysSuggestionV2")
+@Api(tags = "平台建议表")
+public class SysSuggestionV2Controller extends BaseController {
+
+    @Autowired
+    private SysSuggestionV2Service sysSuggestionService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SysMessageService sysMessageService;
+
+    @Autowired
+    private SysMessageConfigService sysMessageConfigService;
+
+    /**
+     * 查询分页
+     *
+     * @param query SysSuggestionWrapper.SysSuggestionQuery
+     * @return R<PageInfo < SysSuggestionWrapper.SysSuggestion>>
+     */
+    @ApiOperation(value = "查询分页", notes = "传入sysSuggestionSearch")
+    @PostMapping("/page")
+    public R<PageInfo<SysSuggestionWrapper.SysSuggestion>> page(@RequestBody SysSuggestionWrapper.SysSuggestionQuery query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        query.setUserId(sysUser.getId());
+        query.setClientType(ClientEnum.TEACHER);
+
+        IPage<SysSuggestionWrapper.SysSuggestion> pages = sysSuggestionService.selectPage(QueryInfo.getPage(query), query);
+
+        List<SysSuggestionWrapper.SysSuggestion> records = pages.getRecords();
+        if (CollectionUtils.isNotEmpty(records)) {
+            List<Long> userIdList = records.stream()
+                    .map(SysSuggestionWrapper.SysSuggestion::getUserId)
+                    .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+
+            List<Long> handUserIdList = records.stream()
+                    .map(SysSuggestionWrapper.SysSuggestion::getHandleBy)
+                    .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+            if (!handUserIdList.isEmpty()) {
+                userIdList.addAll(handUserIdList);
+            }
+            Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> userIdMap = sysUserService.getMapByIds(userIdList);
+
+            records.forEach(next -> {
+                next.setNickname(userIdMap.getOrDefault(next.getUserId(), new com.yonge.cooleshow.biz.dal.entity.SysUser()).getUsername());
+                next.setHandleName(userIdMap.getOrDefault(next.getHandleBy(), new com.yonge.cooleshow.biz.dal.entity.SysUser()).getUsername());
+            });
+        }
+        return R.from(QueryInfo.pageInfo(pages, records));
+    }
+
+
+    /**
+     * 新增
+     *
+     * @param suggestion SysSuggestionVo.SysSuggestion
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "传入sysSuggestion")
+    @PostMapping("/save")
+    public R<Boolean> add(@Validated @RequestBody SysSuggestionVo.SysSuggestion suggestion,
+                          @RequestHeader(name = "user-agent") String userAgent) {
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserFeignService.queryUserInfo();
+        suggestion.setUserId(sysUser.getId());
+        String userAgent1 = suggestion.getUserAgent();
+        if(StringUtils.isEmpty(userAgent1)){
+            userAgent1 = userAgent;
+        }
+        suggestion.setUserAgent(userAgent1);
+        suggestion.setClientType(ClientEnum.TEACHER);
+
+        SysSuggestionV2 sysSuggestion = JSON.parseObject(suggestion.jsonString(), SysSuggestionV2.class);
+        sysSuggestion.setCreateTime(new Date());
+        return R.from(sysSuggestionService.add(sysSuggestion));
+    }
+
+    @ApiOperation(value = "未读消息统计", notes = "统计当前用户推送未读消息数")
+    @GetMapping("/suggestMessageUnread")
+    public R<List<SysMessageWrapper.MessageUnreadStat>> suggestMessageUnread() {
+        SysUser userInfo = sysUserFeignService.queryUserInfo();
+
+        SysMessageConfig one = sysMessageConfigService.queryByType(MessageTypeEnum.SYS_SUGGEST_FEEDBACK_TEACHER.getCode());
+
+        // 未读消息统计条件
+        SysMessageWrapper.SysMessageQuery query = SysMessageWrapper.SysMessageQuery.builder()
+                .userId(userInfo.getId())
+                .clientType(ClientEnum.TEACHER)
+                .readStatus(false)
+                .type(MessageSendMode.PUSH)
+                .sendTime(DateTime.now().toDate())
+                .messageConfigId(one.getId())
+                .build();
+
+        // 统计未读消息数
+        List<SysMessageWrapper.MessageUnreadStat> unreadStats = sysMessageService.userMessageUnreadStat(query);
+
+        return R.from(unreadStats);
+    }
+}

+ 28 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ESuggestionHandleAttitude.java

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Getter;
+
+/**
+ * 系统建议类型
+ */
+@Getter
+public enum ESuggestionHandleAttitude implements BaseEnum<String,ESuggestionHandleAttitude> {
+
+    NEED("需要处理"),
+    NO("不予处理"),
+    ;
+
+    private final String msg;
+
+    @EnumValue
+    private final String code;
+
+    ESuggestionHandleAttitude(String msg) {
+        this.msg = msg;
+
+        this.code = this.name();
+    }
+
+}

+ 4 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMessageDao.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.biz.dal.dao;
 import java.util.List;
 import java.util.Map;
 
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
 import org.apache.ibatis.annotations.Param;
 
 import com.yonge.cooleshow.biz.dal.dto.SysMessageDto;
@@ -46,7 +47,7 @@ public interface SysMessageDao extends BaseDAO<Long, SysMessage> {
 	/**
 	 * 修改用户所有消息阅读状态
 	 */
-	public int updateStatus(@Param("userId") Long userId, @Param("status") int status, @Param("jpushType") String jpushType);
+	public int updateStatus(@Param("userId") Long userId, @Param("status") int status, @Param("jpushType") String jpushType, @Param("messageConfigId") Long messageConfigId);
 
 	/**
 	 * 修改单个消息状态
@@ -54,4 +55,6 @@ public interface SysMessageDao extends BaseDAO<Long, SysMessage> {
 	public int updateOneStatus(@Param("id") Long id, @Param("status") int status);
 
     String selectConfigUrl(String messageType);
+
+	List<SysMessageWrapper.MessageUnreadStat> selectMessageUnreadStat(SysMessageWrapper.SysMessageQuery query);
 }

+ 52 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysSuggestionType.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 平台建议类型表
+ * 2023-08-30 11:26:33
+ */
+@Data
+@ApiModel(" SysSuggestionType-平台建议类型表")
+@TableName("sys_suggestion_type")
+public class SysSuggestionType implements Serializable {
+
+    @ApiModelProperty("编号")
+    @TableId(value = "id_", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("名称")
+    @TableField(value = "name_")
+    private String name;
+
+    @ApiModelProperty("删除标识(0-正常,1-删除)")
+    @TableField(value = "del_flag_")
+    private Boolean delFlag;
+
+    @ApiModelProperty("创建人")
+    @TableField(value = "create_by_")
+    private Long createBy;
+
+    @ApiModelProperty("修改人")
+    @TableField(value = "update_by_")
+    private Long updateBy;
+
+    @ApiModelProperty("更新时间")
+    @TableField(value = "update_time_")
+    private Date updateTime;
+
+    @ApiModelProperty("创建时间")
+    @TableField(value = "create_time_")
+    private Date createTime;
+
+}

+ 89 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysSuggestionV2.java

@@ -0,0 +1,89 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SuggestionType;
+import com.yonge.cooleshow.common.enums.ESuggestionHandleAttitude;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 平台建议表
+ * 2022-11-15 17:59:45
+ */
+@Data
+@TableName("sys_suggestion")
+public class SysSuggestionV2 implements Serializable {
+
+    // 编号
+    @TableId(value = "id_",type = IdType.AUTO)
+    private Long id;
+
+    @TableField(value = "suggestion_type_id_")
+    private Long suggestionTypeId;
+
+    // 联系方式
+	@TableField(value = "mobile_no_")
+    private String mobileNo;
+
+    // 建议类型
+	@TableField(value = "type_")
+    private SuggestionType type;
+
+    // 标题
+	@TableField(value = "title_")
+    private String title;
+
+    // 内容
+	@TableField(value = "content_")
+    private String content;
+
+    // 附件信息, 多个,隔开
+	@TableField(value = "attachment_urls_")
+    private String attachmentUrls;
+
+    // 用户编号
+	@TableField(value = "user_id_")
+    private Long userId;
+
+    // 客户端类型
+	@TableField(value = "client_type_")
+    private ClientEnum clientType;
+
+    // 客户端信息
+	@TableField(value = "user_agent_")
+    private String userAgent;
+
+    // 提交时间
+	@TableField(value = "create_time_")
+    private Date createTime;
+
+    // 处理状态
+    @TableField(value = "handle_status_")
+    private Boolean handleStatus;
+
+    // 处理时间
+    @TableField(value = "handle_time_")
+    private Date handleTime;
+
+    // 处理人
+    @TableField(value = "handle_by_")
+    private Long handleBy;
+
+    @TableField(value = "handle_attitude_")
+    private ESuggestionHandleAttitude handleAttitude;
+
+    // 是否需要反馈用户
+    @TableField(value = "feedback_")
+    private Boolean feedback;
+
+    // 反馈内容
+    @TableField(value = "feedback_content_")
+    private String feedbackContent;
+
+}

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java

@@ -135,6 +135,9 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     TEACHER_UNBIND_TENANT("老师解绑机构"),
 
     USER_TENANT_ALBUM_VIP("后台添加专辑时长"),
+
+    SYS_SUGGEST_FEEDBACK_STUDENT("意见反馈推送"),
+    SYS_SUGGEST_FEEDBACK_TEACHER("意见反馈推送"),
     ;
 
     MessageTypeEnum(String msg) {

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

@@ -1,11 +1,13 @@
 package com.yonge.cooleshow.biz.dal.enums;
 
+import com.baomidou.mybatisplus.annotation.EnumValue;
 import com.yonge.toolset.base.enums.BaseEnum;
 
 public enum SuggestionType implements BaseEnum<String, SuggestionType> {
     APP("软件反馈"),
     SMART_PRACTICE("智能陪练");
 
+    @EnumValue
     private String code;
 
     private String msg;

+ 27 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/SysSuggestionTypeMapper.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionType;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionTypeWrapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 平台建议类型表
+ * 2023-08-30 11:26:33
+ */
+@Repository
+public interface SysSuggestionTypeMapper extends BaseMapper<SysSuggestionType> {
+
+    /**
+     * 分页查询
+     * @param page IPage<SysSuggestionTypeWrapper.SysSuggestionType>
+     * @param param SysSuggestionTypeWrapper.SysSuggestionTypeQuery
+     * @return List<SysSuggestionTypeWrapper.SysSuggestionType>
+     */
+    List<SysSuggestionType> selectPage(@Param("page") IPage<SysSuggestionType> page, @Param("param") SysSuggestionTypeWrapper.SysSuggestionTypeQuery param);
+
+}

+ 25 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/SysSuggestionV2Mapper.java

@@ -0,0 +1,25 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionWrapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 平台建议表
+ * 2022-11-15 17:59:45
+ */
+public interface SysSuggestionV2Mapper extends BaseMapper<SysSuggestionV2> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<SysSuggestionWrapper.SysSuggestionList>
+	 * @param param SysSuggestionWrapper.SysSuggestionQuery
+	 * @return List<SysSuggestionWrapper.SysSuggestion>
+	 */
+	List<SysSuggestionWrapper.SysSuggestion> selectPage(@Param("page") IPage<SysSuggestionWrapper.SysSuggestion> page, @Param("param") SysSuggestionWrapper.SysSuggestionQuery param);
+
+}

+ 7 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMessageService.java

@@ -9,6 +9,7 @@ import com.yonge.cooleshow.biz.dal.dto.SysMessageDto;
 import com.yonge.cooleshow.biz.dal.entity.SysMessage;
 import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
 import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.base.page.QueryInfo;
 import com.yonge.cooleshow.common.entity.Mapper;
@@ -29,10 +30,10 @@ public interface SysMessageService extends BaseService<Long, SysMessage> {
 	 */
 	public void batchSendMessage(MessageSender messageSender, MessageTypeEnum messageType, Map<Long, String> receivers, Date triggerTime,
 			Integer readStatus, String url,String jpushType, Object... args);
-	
-	
+
+
 	public void batchSendMessage(MessageSender messageSender, String title, String content, Map<Long, String> receivers, Date triggerTime,
-			Integer readStatus, String url,String jpushType, Object... args);
+								 Integer readStatus, String url, String jpushType, Object... args);
 
 
 	/**
@@ -85,7 +86,7 @@ public interface SysMessageService extends BaseService<Long, SysMessage> {
 	 * @param status 状态/1 已读,0未读
 	 * @return
 	 */
-	public int updateStatus(Long userId, int status,String jpushType);
+	public int updateStatus(Long userId, int status,String jpushType,MessageTypeEnum messageType);
 
 	/**
 	 * 修改单条消息状态
@@ -97,4 +98,6 @@ public interface SysMessageService extends BaseService<Long, SysMessage> {
 	String selectConfigUrl(String messageType,Object ...param);
 
 	String selectConfigUrlJumpType(String messageType, String jumpType, Object... param);
+
+	List<SysMessageWrapper.MessageUnreadStat> userMessageUnreadStat(SysMessageWrapper.SysMessageQuery query);
 }

+ 44 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysSuggestionTypeService.java

@@ -0,0 +1,44 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionType;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionTypeWrapper;
+
+/**
+ * 平台建议类型表
+ * 2023-08-30 11:26:33
+ */
+public interface SysSuggestionTypeService extends IService<SysSuggestionType> {
+
+    /**
+     * 查询详情
+     * @param id 详情ID
+     * @return SysSuggestionType
+     */
+    SysSuggestionType detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<SysSuggestionType>
+     * @param query SysSuggestionTypeWrapper.SysSuggestionTypeQuery
+     * @return IPage<SysSuggestionType>
+     */
+    IPage<SysSuggestionType> selectPage(IPage<SysSuggestionType> page, SysSuggestionTypeWrapper.SysSuggestionTypeQuery query);
+
+    /**
+     * 添加
+     * @param sysSuggestionType SysSuggestionTypeWrapper.SysSuggestionType
+     * @return Boolean
+     */
+    Boolean add(SysSuggestionTypeWrapper.SysSuggestionType sysSuggestionType);
+
+    /**
+     * 更新
+     * @param sysSuggestionType SysSuggestionTypeWrapper.SysSuggestionType
+     * @return Boolean
+     */
+    Boolean update(SysSuggestionTypeWrapper.SysSuggestionType sysSuggestionType);
+
+}

+ 47 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysSuggestionV2Service.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionWrapper;
+
+/**
+ * 平台建议表
+ * 2022-11-15 17:59:45
+ */
+public interface SysSuggestionV2Service extends IService<SysSuggestionV2> {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return SysSuggestionWrapper.SysSuggestion
+     */
+    SysSuggestionV2 detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<SysSuggestionWrapper.SysSuggestionList>
+     * @param query SysSuggestionWrapper.SysSuggestionQuery
+     * @return IPage<SysSuggestionWrapper.SysSuggestion>
+     */
+    IPage<SysSuggestionWrapper.SysSuggestion> selectPage(IPage<SysSuggestionWrapper.SysSuggestion> page, SysSuggestionWrapper.SysSuggestionQuery query);
+
+    /**
+     * 添加
+     * @param SysSuggestion SysSuggestionWrapper.SysSuggestion
+     * @return Boolean
+     */
+     Boolean add(SysSuggestionV2 SysSuggestion);
+
+    /**
+     * 更新
+     * @param SysSuggestion SysSuggestionWrapper.SysSuggestion
+     * @return Boolean
+     */
+     Boolean update(SysSuggestionV2 SysSuggestion);
+
+
+    Boolean handleSuggestion(SysSuggestionWrapper.HandleSuggestion handleSuggestion);
+}

+ 25 - 12
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMessageServiceImpl.java

@@ -13,6 +13,7 @@ import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.SendStatusEnum;
 import com.yonge.cooleshow.biz.dal.service.SysMessageConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
 import com.yonge.cooleshow.common.entity.Mapper;
 import com.yonge.cooleshow.common.redis.service.RedisCache;
 import com.yonge.toolset.base.exception.BizException;
@@ -131,7 +132,7 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
 
 	@Override
 	public void batchSendMessage(MessageSender messageSender, MessageTypeEnum type, Map<Long, String> receivers, Date triggerTime, Integer readStatus,
-			String url,String jpushType, Object... args) {
+								 String url,String jpushType, Object... args) {
 		LOGGER.info("batchSendMessage msgSender {}, type {}, receivers {} ", messageSender, type, receivers);
 		if (receivers == null || receivers.size() == 0) {
 			LOGGER.error("接收地址不能为空");
@@ -145,10 +146,10 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
 		if(messageSender.getSendMode().equals(MessageSender.JIGUANG.getSendMode())) {
 			tos= new String[receivers.size()];
 			tos = receivers.entrySet()
-						   .stream()
-						   .map(longStringEntry -> String.valueOf(longStringEntry.getKey()))
-						   .collect(Collectors.toList())
-						   .toArray(tos);
+					.stream()
+					.map(longStringEntry -> String.valueOf(longStringEntry.getKey()))
+					.collect(Collectors.toList())
+					.toArray(tos);
 		} else {
 			tos = receivers.values().toArray(new String[receivers.size()]);
 		}
@@ -166,10 +167,9 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
 		if (triggerTime == null || date.after(triggerTime)) {
 			status = SendStatusEnum.SENDING;
 			try {
-
 				if (isSendRemoteMessage(messageSender)) {
 					errorMsg = messageSenderPluginContext.batchSend(messageSender, messageConfig.getDescription(),
-														 MessageFormatter.arrayFormat(messageConfig.getContent(), args), tos, url,jpushType,"default",null);
+							MessageFormatter.arrayFormat(messageConfig.getContent(), args), tos, url,jpushType,"default",null);
 					if (StringUtils.isEmpty(errorMsg)) {
 						status = SendStatusEnum.SUCCESSED;
 					}  else {
@@ -189,9 +189,9 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
 		} else if (messageSender.getSendMode().equals("EMAIL")) {
 			mode = MessageSendMode.EMAIL;
 		}
-        if (ClientEnum.TENANT_STUDENT.getCode().equals(jpushType)) {
-            jpushType = ClientEnum.STUDENT.getCode();
-        }
+		if (ClientEnum.TENANT_STUDENT.getCode().equals(jpushType)) {
+			jpushType = ClientEnum.STUDENT.getCode();
+		}
 		addMessage(receivers, messageConfig.getDescription(), MessageFormatter.arrayFormat(messageConfig.getContent(), args), triggerTime, mode, status, errorMsg, readStatus,
 				url, messageConfig.getGroup(),jpushType,messageConfig.getId());
 	}
@@ -360,8 +360,16 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
 	 */
 	@Override
 	@Transactional(rollbackFor = Exception.class)
-	public int updateStatus(Long userId, int status,String jpushType) {
-		return sysMessageDao.updateStatus(userId, status,jpushType);
+	public int updateStatus(Long userId, int status,String jpushType,MessageTypeEnum messageType) {
+		// 按照类型设置一键已读
+		Long messageConfigId = null;
+		if (messageType != null) {
+			SysMessageConfig sysMessageConfig = sysMessageConfigService.queryByType(messageType.getCode());
+			if (sysMessageConfig != null) {
+				messageConfigId = sysMessageConfig.getId();
+			}
+		}
+		return sysMessageDao.updateStatus(userId, status,jpushType,messageConfigId);
 	}
 
 	@Override
@@ -406,4 +414,9 @@ public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> imp
         }
 		return JSON.toJSONString(jumpUrlDto);
 	}
+
+	@Override
+	public List<SysMessageWrapper.MessageUnreadStat> userMessageUnreadStat(SysMessageWrapper.SysMessageQuery query) {
+		return sysMessageDao.selectMessageUnreadStat(query);
+	}
 }

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

@@ -0,0 +1,69 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionType;
+import com.yonge.cooleshow.biz.dal.mapper.SysSuggestionTypeMapper;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionTypeService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionTypeWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 平台建议类型表
+ * 2023-08-30 11:26:33
+ */
+@Slf4j
+@Service
+public class SysSuggestionTypeServiceImpl extends ServiceImpl<SysSuggestionTypeMapper, SysSuggestionType> implements SysSuggestionTypeService {
+
+    /**
+     * 查询详情
+     *
+     * @param id 详情ID
+     * @return SysSuggestionType
+     */
+    @Override
+    public SysSuggestionType detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     *
+     * @param page  IPage<SysSuggestionType>
+     * @param query SysSuggestionTypeWrapper.SysSuggestionTypeQuery
+     * @return IPage<SysSuggestionType>
+     */
+    @Override
+    public IPage<SysSuggestionType> selectPage(IPage<SysSuggestionType> page, SysSuggestionTypeWrapper.SysSuggestionTypeQuery query) {
+
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+
+    /**
+     * 添加
+     *
+     * @param sysSuggestionType SysSuggestionTypeWrapper.SysSuggestionType
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(SysSuggestionTypeWrapper.SysSuggestionType sysSuggestionType) {
+
+        return this.save(JSON.parseObject(sysSuggestionType.jsonString(), SysSuggestionType.class));
+    }
+
+    /**
+     * 更新
+     *
+     * @param sysSuggestionType SysSuggestionTypeWrapper.SysSuggestionType
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(SysSuggestionTypeWrapper.SysSuggestionType sysSuggestionType) {
+
+        return this.updateById(JSON.parseObject(sysSuggestionType.jsonString(), SysSuggestionType.class));
+    }
+}

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

@@ -0,0 +1,140 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionType;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.mapper.SysSuggestionTypeMapper;
+import com.yonge.cooleshow.biz.dal.mapper.SysSuggestionV2Mapper;
+import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionTypeService;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionV2Service;
+import com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionWrapper;
+import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * 平台建议表
+ * 2022-11-15 17:59:45
+ */
+@Slf4j
+@Service
+public class SysSuggestionV2ServiceImpl extends ServiceImpl<SysSuggestionV2Mapper, SysSuggestionV2> implements SysSuggestionV2Service {
+
+    @Autowired
+    private SysMessageService sysMessageService;
+
+    @Autowired
+    private SysSuggestionTypeMapper sysSuggestionTypeMapper;
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return SysSuggestionWrapper.SysSuggestion
+     */
+	@Override
+    public SysSuggestionV2 detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     * @param page IPage<SysSuggestionWrapper.SysSuggestionList>
+     * @param query SysSuggestionWrapper.SysSuggestionQuery
+     * @return IPage<SysSuggestionWrapper.SysSuggestion>
+     */
+    @Override
+    public IPage<SysSuggestionWrapper.SysSuggestion> selectPage(IPage<SysSuggestionWrapper.SysSuggestion> page,
+                                                                SysSuggestionWrapper.SysSuggestionQuery query){
+
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+
+    /**
+     * 添加
+     * @param SysSuggestion SysSuggestionWrapper.SysSuggestion
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(SysSuggestionV2 SysSuggestion) {
+
+        return this.save(SysSuggestion);
+    }
+
+    /**
+     * 更新
+     * @param SysSuggestion SysSuggestionWrapper.SysSuggestion
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(SysSuggestionV2 SysSuggestion){
+
+        return this.updateById(SysSuggestion);
+    }
+
+    /**
+     * 处理反馈意见
+     * @param handleSuggestion handleSuggestion
+     * @return true/false
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public Boolean handleSuggestion(SysSuggestionWrapper.HandleSuggestion handleSuggestion) {
+        Long id = handleSuggestion.getId();
+        SysSuggestionV2 suggestion = this.getById(id);
+        if (suggestion == null) {
+            throw new BizException("反馈意见不存在");
+        }
+        Boolean handleStatus = suggestion.getHandleStatus();
+        if (Boolean.TRUE.equals(handleStatus)) {
+            throw new BizException("反馈意见已经处理");
+        }
+
+        Date handTime = new Date();
+        this.lambdaUpdate()
+            .set(SysSuggestionV2::getHandleStatus, true)
+            .set(SysSuggestionV2::getHandleTime, handTime)
+            .set(SysSuggestionV2::getFeedback, handleSuggestion.getFeedback())
+            .set(SysSuggestionV2::getFeedbackContent, handleSuggestion.getFeedbackContent())
+            .set(SysSuggestionV2::getHandleBy,handleSuggestion.getHandleBy())
+            .set(SysSuggestionV2::getHandleAttitude, handleSuggestion.getHandleAttitude())
+            .eq(SysSuggestionV2::getId, handleSuggestion.getId())
+            .eq(SysSuggestionV2::getHandleStatus, false)
+            .update();
+
+        Boolean feedback = handleSuggestion.getFeedback();
+        if (feedback && StringUtils.isNotEmpty(handleSuggestion.getFeedbackContent())) {
+            // 推送消息
+            try {
+                Map<Long, String> receivers = new HashMap<>();
+                receivers.put(suggestion.getUserId(), suggestion.getMobileNo());
+                MessageTypeEnum messageType = MessageTypeEnum.SYS_SUGGEST_FEEDBACK_STUDENT;
+                if (ClientEnum.TEACHER.equals(suggestion.getClientType())) {
+                    messageType = MessageTypeEnum.SYS_SUGGEST_FEEDBACK_TEACHER;
+                }
+                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, messageType,
+                        receivers, null, 0, null, null, handleSuggestion.getFeedbackContent());
+            } catch (Exception e) {
+                log.warn("意见反馈推送发送失败,{}", e.getMessage());
+            }
+        }
+        return true;
+    }
+}

+ 105 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysMessageWrapper.java

@@ -0,0 +1,105 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.SendStatusEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 系统消息表
+ * 2022-11-15 17:59:45
+ */
+public class SysMessageWrapper {
+
+    /**
+     * 消息查询条件
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class SysMessageQuery {
+
+        // 关键字匹配
+        private String keyword;
+
+        // 发送人编号
+        private Long userId;
+
+        // 用户类型
+        private ClientEnum clientType;
+
+        // 状态,0,待发送;1,发送中;2,发送完成
+        private SendStatusEnum status;
+
+        // 接收人编号
+        private String receiver;
+
+        // 标题
+        private String title;
+
+        // 消息类型;1,表示短信;2,表示邮件; 3,app推送消息
+        private MessageSendMode type;
+
+        // 客户端STUDENT,TEACHER,BACKEND,SCHOOL
+        private ClientEnum clientId;
+
+        // 0:未读,1:已读
+        private Boolean readStatus;
+
+        // 发送时间
+        private Date sendTime;
+
+        private Long messageConfigId;
+
+        public static SysMessageQuery from(String json) {
+            return JSON.parseObject(json, SysMessageQuery.class);
+        }
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String getReceiver() {
+            return Optional.ofNullable(receiver).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String getTitle() {
+            return Optional.ofNullable(title).filter(StringUtils::isNotBlank).orElse(null);
+        }
+    }
+
+
+    @Data
+    @ApiModel("未读消息统计")
+    public static class MessageUnreadStat implements Serializable {
+
+        @ApiModelProperty("消息分组")
+        private String group;
+
+        @ApiModelProperty("未读消息数")
+        private Integer number;
+    }
+
+    /**
+     * 消息设置一键读取条件
+     */
+    @Data
+    public static class MessageRead {
+
+        private MessageTypeEnum messageType;
+    }
+
+}

+ 89 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysSuggestionTypeWrapper.java

@@ -0,0 +1,89 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 平台建议类型表
+ * 2023-08-30 11:26:33
+ */
+@ApiModel(value = "SysSuggestionTypeWrapper对象", description = "平台建议类型表查询对象")
+public class SysSuggestionTypeWrapper {
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" SysSuggestionTypeQuery-平台建议类型表")
+    public static class SysSuggestionTypeQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+        private String keyword;
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static SysSuggestionTypeQuery from(String json) {
+            return JSON.parseObject(json, SysSuggestionTypeQuery.class);
+        }
+    }
+
+    @Data
+    @ApiModel(" SysSuggestionType-平台建议类型表")
+    public static class SysSuggestionType {
+
+        @ApiModelProperty("编号")
+        private Long id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("删除标识(0-正常,1-删除)")
+        private Boolean delFlag;
+
+        @ApiModelProperty("创建人")
+        private Long createBy;
+
+        @ApiModelProperty("修改人")
+        private Long updateBy;
+
+        @ApiModelProperty("修改人名称")
+        private String operator;
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static SysSuggestionType from(String json) {
+            return JSON.parseObject(json, SysSuggestionType.class);
+        }
+    }
+
+}

+ 206 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysSuggestionWrapper.java

@@ -0,0 +1,206 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SuggestionType;
+import com.yonge.cooleshow.common.enums.ESuggestionHandleAttitude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 平台建议表
+ * 2022-11-15 17:59:45
+ */
+public class SysSuggestionWrapper {
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class SysSuggestionQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字")
+        private String keyword;
+
+        @ApiModelProperty("客户端类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("建议类型")
+        private SuggestionType type;
+
+        @TableId(value = "建议类型ID")
+        private Long suggestionTypeId;
+
+        @ApiModelProperty("建议类型")
+        private String suggestionType;
+
+        @ApiModelProperty("建议类型名称")
+        private String suggestionTypeName;
+
+        @ApiModelProperty("开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("结束时间")
+        private Date endTime;
+
+        @ApiModelProperty("处理状态,true:是,false:否")
+        private Boolean handleStatus;
+
+        @ApiModelProperty("处理人")
+        private Long handleBy;
+
+        @ApiModelProperty("处理人")
+        private String handleName;
+
+        @ApiModelProperty("是否反馈用户,true:是,false:否")
+        private Boolean feedback;
+
+        @ApiModelProperty("开始处理时间")
+        private Date handStartTime;
+
+        @ApiModelProperty("结束处理时间")
+        private Date handEndTime;
+
+        @ApiModelProperty("处理态度,NEED:需要处理,NO:不予处理")
+        private ESuggestionHandleAttitude handleAttitude;
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("客户端类型,多个用逗号隔开")
+        private String clientTypes;
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class SysSuggestion {
+
+        @ApiModelProperty("编号")
+        private Long id;
+
+        @ApiModelProperty("建议类型ID")
+        private Long suggestionTypeId;
+
+        @ApiModelProperty("建议类型名称")
+        private String suggestionTypeName;
+
+        @ApiModelProperty("联系方式")
+        private String mobileNo;
+
+        @ApiModelProperty("建议类型")
+        private SuggestionType type;
+
+        @ApiModelProperty("标题")
+        private String title;
+
+        @ApiModelProperty("内容")
+        private String content;
+
+        @ApiModelProperty("附件信息, 多个,隔开")
+        private String attachmentUrls;
+
+        @ApiModelProperty("用户编号")
+        private Long userId;
+
+        @ApiModelProperty("客户端类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("客户端信息")
+        private String userAgent;
+
+        @ApiModelProperty("提交时间")
+        private Date createTime;
+
+        @ApiModelProperty("用户名")
+        private String nickname;
+
+        @ApiModelProperty("处理状态:true:已处理,false:待处理")
+        private Boolean handleStatus;
+
+        @ApiModelProperty("处理时间")
+        private Date handleTime;
+
+        @ApiModelProperty("处理人")
+        private Long handleBy;
+
+        @ApiModelProperty("处理态度")
+        private ESuggestionHandleAttitude handleAttitude;
+
+        @ApiModelProperty("处理人姓名")
+        private String handleName;
+
+        @ApiModelProperty("是否反馈用户,true:是,false:否")
+        private Boolean feedback;
+
+        @ApiModelProperty("反馈内容")
+        private String feedbackContent;
+
+        @ApiModelProperty("学校ID")
+        private Long schoolId;
+
+        @ApiModelProperty("学校名称")
+        private String schoolName;
+
+        public static SysSuggestion from(String json) {
+            return JSON.parseObject(json, SysSuggestion.class);
+        }
+
+    }
+
+    /**
+     * 客服
+     */
+    @Data
+    public static class CustomerServiceContact {
+
+        @ApiModelProperty("客服电话")
+        private String phone;
+
+        @ApiModelProperty("客服邮箱")
+        private String email;
+    }
+
+    @ApiModel("处理反馈意见模型")
+    @Data
+    public static class HandleSuggestion {
+
+        @ApiModelProperty(value = "id", required = true)
+        @NotNull
+        private Long id;
+
+        @ApiModelProperty(value = "是否反馈用户,true:是,false:否", required = true)
+        @NotNull
+        private Boolean feedback;
+
+        @ApiModelProperty(value = "反馈内容", required = true)
+        @NotNull
+        private String feedbackContent;
+
+        @ApiModelProperty(value = "处理态度", required = true)
+        @NotNull
+        private ESuggestionHandleAttitude handleAttitude;
+
+        @ApiModelProperty(value = "处理人", hidden = true)
+        private Long handleBy;
+
+
+    }
+
+}

+ 37 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMessageMapper.xml

@@ -159,7 +159,12 @@
 	</update>
 	<update id="updateStatus">
 		update sys_message set read_status_=#{status}
-		where user_id_ = #{userId} AND (client_id_ = #{jpushType} OR client_id_ IS NULL)
+			<where>
+				user_id_ = #{userId} AND (client_id_ = #{jpushType} OR client_id_ IS NULL)
+				<if test="messageConfigId != null">
+					AND message_config_id_ = #{messageConfigId}
+				</if>
+			</where>
 	</update>
 
     <update id="updateOneStatus">
@@ -214,4 +219,35 @@
 	<select id="selectConfigUrl" resultType="java.lang.String" parameterType="java.lang.String">
 		SELECT url_ FROM sys_message_config WHERE message_type_=#{messageType}
 	</select>
+
+	<!--用户未读消息统计-->
+	<select id="selectMessageUnreadStat"
+			resultType="com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper$MessageUnreadStat">
+		SELECT group_, COUNT(t.id_) AS number FROM sys_message t
+		<where>
+			t.group_ is not null
+			<if test="param.userId != null">
+				AND t.user_id_ = #{param.userId}
+			</if>
+			<if test="param.clientType != null">
+				AND t.client_type_ = #{param.clientType}
+			</if>
+			<if test="param.status != null">
+				AND t.status_ = #{param.status}
+			</if>
+			<if test="param.type != null">
+				AND t.type_ = #{param.type}
+			</if>
+			<if test="param.readStatus != null">
+				AND t.read_status_ = #{param.readStatus}
+			</if>
+			<if test="param.sendTime != null">
+				AND t.send_time_ &lt;= #{param.sendTime}
+			</if>
+			<if test="param.messageConfigId != null">
+				AND t.message_config_id_ = #{param.messageConfigId}
+			</if>
+		</where>
+		GROUP BY group_
+	</select>
 </mapper>

+ 24 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysSuggestionTypeMapper.xml

@@ -0,0 +1,24 @@
+<?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.mapper.SysSuggestionTypeMapper">
+
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+        t.id_ AS id
+        , t.name_ AS `name`
+        , t.del_flag_ AS delFlag
+        , t.create_by_ AS createBy
+        , t.update_by_ AS updateBy
+        , t.update_time_ AS updateTime
+        , t.create_time_ AS createTime
+    </sql>
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.entity.SysSuggestionType">
+        SELECT
+        <include refid="baseColumns"/>
+        FROM sys_suggestion_type t
+        where del_flag_ = 0
+        order by t.create_time_ desc
+    </select>
+
+</mapper>

+ 112 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysSuggestionV2Mapper.xml

@@ -0,0 +1,112 @@
+<?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.mapper.SysSuggestionV2Mapper">
+
+	<resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2">
+        <result column="id_" property="id" />
+        <result column="suggestion_type_id_" property="suggestionTypeId" />
+        <result column="mobile_no_" property="mobileNo" />
+        <result column="type_" property="type" />
+        <result column="title_" property="title" />
+        <result column="content_" property="content" />
+        <result column="attachment_urls_" property="attachmentUrls" />
+        <result column="user_id_" property="userId" />
+        <result column="client_type_" property="clientType" />
+        <result column="user_agent_" property="userAgent" />
+        <result column="create_time_" property="createTime" />
+        <result column="handle_status_" property="handleStatus" />
+        <result column="handle_time_" property="handleTime" />
+        <result column="handle_by_" property="handleBy" />
+        <result column="handle_attitude_" property="handleAttitude" />
+        <result column="feedback_" property="feedback" />
+        <result column="feedback_content_" property="feedbackContent" />
+    </resultMap>
+
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id_ as id
+        ,t.suggestion_type_id_ as suggestionTypeId
+        , t.mobile_no_ as mobileNo
+        , t.type_ as type
+        , t.title_ as title
+        , t.content_ as content
+        , t.attachment_urls_ as attachmentUrls
+        , t.user_id_ as userId
+        , t.client_type_ as clientType
+        , t.user_agent_ as userAgent
+        , t.create_time_ as createTime
+        , t.handle_status_ as handleStatus
+        , t.handle_time_ as handleTime
+        , t.handle_by_ as handleBy
+        , t.handle_attitude_ as handleAttitude
+        , t.feedback_ as feedback
+        , t.feedback_content_ as feedbackContent
+    </sql>
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.SysSuggestionWrapper$SysSuggestion">
+		SELECT
+        	<include refid="baseColumns" />,
+        sst.name_ as suggestionTypeName
+		FROM sys_suggestion t
+        LEFT JOIN sys_suggestion_type sst on t.suggestion_type_id_ = sst.id_
+        <if test="param.keyword!=null and param.keyword.trim()!=''">
+            LEFT JOIN sys_user su2 ON su2.id_ = t.user_id_
+        </if>
+        <if test="param.handleName != null and param.handleName.trim() != ''">
+            LEFT JOIN sys_user su ON su.id_ = t.handle_by_
+        </if>
+        <where>
+            <if test="param.keyword!=null and param.keyword.trim()!=''">
+                AND (
+                su2.username_ LIKE CONCAT('%', #{param.keyword}, '%')
+                or
+                su2.phone_ LIKE CONCAT('%', #{param.keyword}, '%')
+                )
+            </if>
+            <if test="param.type != null">
+                AND t.type_ = #{param.type}
+            </if>
+		    <if test="param.clientType != null">
+                AND t.client_type_ = #{param.clientType}
+            </if>
+            <if test="param.startTime!=null">
+                AND t.create_time_ >= #{param.startTime}
+            </if>
+            <if test="param.endTime!=null">
+                AND #{param.endTime} >= t.create_time_
+            </if>
+            <if test="param.suggestionTypeId != null">
+                AND t.suggestion_type_id_ = #{param.suggestionTypeId}
+            </if>
+            <if test="param.suggestionTypeName != null and param.suggestionTypeName.trim() != ''">
+                AND sst.name_ = #{param.suggestionTypeName}
+            </if>
+            <if test="param.handleStatus != null">
+                AND t.handle_status_ = #{param.handleStatus}
+            </if>
+            <if test="param.handleBy != null">
+                AND t.handle_by_ = #{param.handleBy}
+            </if>
+            <if test="param.handleName != null and param.handleName.trim() != ''">
+                AND su.username_ LIKE CONCAT('%', #{param.handleName}, '%')
+            </if>
+            <if test="param.handStartTime != null">
+                AND t.handle_time_ >= #{param.handStartTime}
+            </if>
+            <if test="param.handEndTime != null">
+                AND #{param.handEndTime} >= t.handle_time_
+            </if>
+            <if test="param.handleAttitude != null">
+                AND t.handle_attitude_ = #{param.handleAttitude}
+            </if>
+            <if test="param.feedback != null">
+                AND t.feedback_ = #{param.feedback}
+            </if>
+            <if test="param.userId != null">
+                AND t.user_id_ = #{param.userId}
+            </if>
+        </where>
+        ORDER BY t.id_ DESC
+	</select>
+
+</mapper>

+ 4 - 2
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SysMessageController.java

@@ -6,7 +6,9 @@ import com.yonge.cooleshow.biz.dal.dao.AppVersionInfoDao;
 import com.yonge.cooleshow.biz.dal.dto.search.SysMessageQueryInfo;
 import com.yonge.cooleshow.biz.dal.entity.SysMessage;
 import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.Mapper;
@@ -75,13 +77,13 @@ public class SysMessageController extends BaseController {
 
 	@ApiOperation("一键已读")
 	@PostMapping("batchSetRead")
-	public Object batchSetRead() {
+	public Object batchSetRead(@RequestParam(value = "messageType", required = false) MessageTypeEnum messageType) {
 		int status = 1;
 		SysUser sysUser = sysUserFeignService.queryUserInfo();
 		if (sysUser == null) {
 			return failed(HttpStatus.FORBIDDEN, "请登录");
 		}
-		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"STUDENT") > 0 );
+		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"STUDENT",messageType) > 0 );
 	}
 
 	@ApiOperation("设置已读")

+ 4 - 2
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/SysMessageController.java

@@ -6,7 +6,9 @@ import com.yonge.cooleshow.biz.dal.dao.AppVersionInfoDao;
 import com.yonge.cooleshow.biz.dal.dto.search.SysMessageQueryInfo;
 import com.yonge.cooleshow.biz.dal.entity.SysMessage;
 import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysMessageWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.Mapper;
@@ -75,13 +77,13 @@ public class SysMessageController extends BaseController {
 
 	@ApiOperation("一键已读")
 	@PostMapping("batchSetRead")
-	public Object batchSetRead() {
+	public Object batchSetRead(@RequestParam(value = "messageType", required = false) MessageTypeEnum messageType) {
 		int status = 1;
 		SysUser sysUser = sysUserFeignService.queryUserInfo();
 		if (sysUser == null) {
 			return failed(HttpStatus.FORBIDDEN, "请登录");
 		}
-		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"TEACHER") > 0 );
+		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"TEACHER",messageType) > 0 );
 	}
 
 	@ApiOperation("设置已读")