Compare commits

..

2 Commits

Author SHA1 Message Date
15004070936 dc0bd6288e 修改
1 week ago
15004070936 98d710435a 测试并修改
2 months ago

@ -200,7 +200,11 @@
<dependencies>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
</dependencies>
<build>

@ -15,14 +15,7 @@
web服务入口
</description>
<dependencies>
<!-- spring-boot-devtools -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <optional>true</optional> &lt;!&ndash; 表示依赖不会传递 &ndash;&gt;-->
<!-- </dependency>-->
<dependencies>
<!-- 核心模块-->
<dependency>
@ -30,6 +23,32 @@
<artifactId>ruoyi-framework</artifactId>
</dependency>
<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!--极光推送-->
<!-- <dependency>-->

@ -15,6 +15,8 @@
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<content url="file://$MODULE_DIR$">
@ -26,18 +28,6 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="ruoyi-framework" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.5.14" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.5.14" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.5.14" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.5.14" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.20" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.20" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.28" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.5.14" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.12.6.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.6" level="project" />
@ -123,7 +113,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.14" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.20" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.1" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.22" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:core:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:javase:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.82" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.github.jai-imageio:jai-imageio-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" name="Maven: cn.jpush.api:jiguang-common:1.1.7" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.60" level="project" />
@ -166,7 +160,6 @@
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
@ -214,6 +207,46 @@
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.httpcomponents:httpmime:4.5.13" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.13.2" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.5.14" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.5.14" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.5.14" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.5.14" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.28" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.5.14" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.5.14" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.4.8" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:2.4.8" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:9.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.19.0" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.20" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.20" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.3.20" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.8.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:3.9.0" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.10.22" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:3.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.9.0" level="project" />
<orderEntry type="library" name="Maven: com.jcraft:jsch:0.1.55" level="project" />
</component>
</module>

@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
*
@ -28,15 +29,16 @@ public class AppreciateController {
/**
*
* @param appreciate
* @param visitStore
* @return
*/
@ApiOperation("获取瑜伽欣赏 列表")
@PostMapping("/getList")
public RestResponse getList(@RequestBody YjAppreciate appreciate){
public RestResponse getList(@RequestBody Map map){
Long visitStore=Long.parseLong(map.get("visitStore").toString());
List<YjAppreciate> list= service.list(new QueryWrapper<YjAppreciate>()
.select("id,title,image,read_num,start_time")
.eq("visit_store",appreciate.getVisitStore())
.eq("dept_id",visitStore)
.eq("status",true)
.orderByDesc("modify_time"));
return new RestResponse().setSuccess(true).setMessage("成功").setData(list);

@ -2,12 +2,11 @@ package com.ruoyi.web.controller.basic;
import com.ruoyi.RestResponse;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.course.domain.Context;
import com.ruoyi.course.domain.ReqSearchClaTime;
import com.ruoyi.course.domain.req.ReqSearchClaTime;
import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar;
import com.ruoyi.course.service.ScClaTimeService;
import com.ruoyi.course.service.impl.ContextServicelmpl;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import com.ruoyi.system.domain.SysTeacher;
import com.ruoyi.system.service.SysTeacherService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@ -24,28 +23,34 @@ import java.util.Map;
@RequestMapping("/api/context")
public class ContextAppController extends BaseController {
@Autowired
ContextServicelmpl contextService;
private SysTeacherService teacherService;
@Autowired
SysUserServiceImpl userService;
private ScClaTimeService scClaTimeService;
@Autowired
ScClaTimeService scClaTimeService;
private SysTeacherService staffService;
/**
* visitStore
* @param params
* @return
*/
@ApiOperation("教练列表")
@PostMapping(value = "/getList")
public RestResponse findList1(@RequestBody Map<String, Object> params) {
List<Context> list =contextService.getList(params);
List<SysTeacher> list = teacherService.getList(Long.parseLong(params.get("visitStore").toString()));
return new RestResponse().setSuccess(true).setMessage("成功").setData(list);
}
@ApiOperation("教练详细信息")
@PostMapping("/getOne")
public RestResponse update(@RequestBody Map<String, Object> params) {
Context c =contextService.getOne(params);
public RestResponse update(@RequestBody Map<String, String> params) {
SysTeacher c = teacherService.getByUserId(params.get("userId").toString());
return RestResponse.success().setData(c);
}
@ApiOperation("教练课程表")
@PostMapping("/searchListForCalendar")
public RestResponse update(@RequestBody ReqSearchClaTime reqSearchClaTime) {
public RestResponse searchListForCalendar(@RequestBody ReqSearchClaTime reqSearchClaTime) {
RespBusinessClaTimeCalendar c =scClaTimeService.searchListForCalendar(reqSearchClaTime);
return RestResponse.success().setData(c);
}

@ -13,7 +13,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
/**
*
@ -27,15 +30,16 @@ public class HealthyController {
/**
*
* @param healthy
* @param visitStore
* @return
*/
@ApiOperation(value = "获取健康饮食列表")
@PostMapping("/getList")
public RestResponse getList(@RequestBody YjHealthy healthy){
public RestResponse getList(@RequestBody Map map){
Long visitStore=Long.parseLong(map.get("visitStore").toString());
List<YjHealthy> list= service.list(new QueryWrapper<YjHealthy>()
.select("id,title,image,read_num,start_time")
.eq("visit_store",healthy.getVisitStore())
.eq("dept_id",visitStore)
.eq("status",true)
.orderByDesc("modify_time"));
return new RestResponse().setSuccess(true).setMessage("成功").setData(list);
@ -55,4 +59,82 @@ public class HealthyController {
YjHealthy i=service.getById(healthy.getId());
return new RestResponse().setSuccess(true).setMessage("成功").setData(i);
}
@ApiOperation(value = "计算BIM")
@PostMapping("/calculateBim")
public RestResponse calculateBim(@RequestBody Map map){
try {
map.get("gender");//male男性 female女性
map.get("age");
BigDecimal height= checkAndFormatNum(map.get("height"));
BigDecimal weight= checkAndFormatNum(map.get("weight"));
// 公式BMI = 体重 ÷ (身高 × 身高)
height=height.divide(new BigDecimal(100));
BigDecimal heightSquare = height.multiply(height); // 身高平方
BigDecimal bim=weight.divide(heightSquare,2,RoundingMode.HALF_UP);
BigDecimal num185 = new BigDecimal("18.5");
BigDecimal num239 = new BigDecimal("23.9");
BigDecimal num279 = new BigDecimal("27.9");
if (bim.compareTo(num185) < 0) {
return new RestResponse()
.setSuccess(true)
.setMessage("您的体重过轻请联系馆主或教练领取A方案")
.setData(bim);
}
else if (bim.compareTo(num185) > 0 && bim.compareTo(num239) < 0) {
return new RestResponse()
.setSuccess(true)
.setMessage("太棒了您的体重非常健康请联系馆主或教练领取B方案保持")
.setData(bim);
}
else if (bim.compareTo(num239) > 0 && bim.compareTo(num279) < 0) {
return new RestResponse()
.setSuccess(true)
.setMessage("您的体重超重请联系馆主或教练领取C方案")
.setData(bim);
}else {
return new RestResponse()
.setSuccess(true)
.setMessage("您的体重肥胖请联系馆主或教练领取D方案")
.setData(bim);
}
}catch (IllegalArgumentException e){
return RestResponse.failure(e.getMessage());
}
}
/**
* height
* @return height1
* @throws IllegalArgumentException
*/
public static BigDecimal checkAndFormatNum(Object obj) {
// 1. 非空校验
if (obj == null || obj.toString().trim().isEmpty()) {
throw new IllegalArgumentException("身高/体重不能为空");
}
String heightStr = obj.toString().trim();
BigDecimal heightNum;
try {
// 2. 校验是否为有效数字(整数/小数都支持)
heightNum = new BigDecimal(heightStr);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("身高/体重必须是有效数字,当前值:" + heightStr);
}
// 3. 保留1位小数四舍五入银行家舍入法最常用
BigDecimal formattedHeight = heightNum.setScale(1, RoundingMode.HALF_UP);
// 4. 返回字符串格式结果(也可返回 BigDecimal 类型)
return formattedHeight;
}
}

@ -0,0 +1,40 @@
package com.ruoyi.web.controller.basic;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.service.impl.BusinessSysDictDataService;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.system.service.ISysDictDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author zhangby
* @since 2020-01-15
*/
@RestController
@RequestMapping("/api/dict/data")
public class ISysDictDataController {
@Autowired
private BusinessSysDictDataService sysDictDataService;
/**
*
* @param dictType
* @return
*/
@GetMapping("/list/dictType/{dictType}")
public RestResponse dictTypeDataList(@PathVariable("dictType") String dictType){
List<SysDictData> dictDataList = sysDictDataService.dictTypeDataList(dictType);
return RestResponse.success().setData(dictDataList);
}
}

@ -11,10 +11,7 @@ import com.ruoyi.basic.service.impl.YjStoreServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
@ -28,50 +25,27 @@ import java.util.Map;
public class IndexController {
@Resource
private YjStoreServiceImpl storeService;
@Autowired
private YjAppUserService appUserService;
@ApiOperation("门店列表")
@PostMapping("/getStores")
public RestResponse getStores(){
Long userId = SecurityUtils.getAppLoginUser().getAppUser().getId();
AppUser appUser =appUserService.getById(userId);
YjStore s=storeService.getOne(new QueryWrapper<YjStore>().select("tenant_id").eq("id",appUser.getVisitStore()));
List<YjStore> list= storeService.list(new QueryWrapper<YjStore>()
.select("address","" +
"store_name","phone","id","parent_id")
.eq("status",2)
.eq("tenant_id",s.getTenantId())
.orderByAsc("tenant_id")
);
list.forEach(l->{
if (l.getParentId().equals("0")){
l.setStoreName(l.getStoreName()+"(总店)");
}
});
return new RestResponse().setSuccess(true).setData(list);
public RestResponse getStoreList(){
return storeService.storesTree();
}
@ApiOperation("切换门店")
@PostMapping("/changeStore")
public RestResponse changeStore(@RequestBody Map<String,String> map){
String visitStoreId =map.get("visitStoreId");
public RestResponse changeStore(@RequestBody Map<String,Long> map){
Long visitStoreId =map.get("visitStoreId");
//登录用户的访问门店字段修改
AppUser appUser = SecurityUtils.getAppLoginUser().getAppUser();
appUserService.update(new UpdateWrapper<AppUser>()
.eq("app_user_id",appUser)
.set("visit_store",visitStoreId));
//返回新切换的门店信息
YjStore yjStore= storeService.getById(visitStoreId);
Map m=new HashMap();
m.put("address",yjStore.getAddress());
m.put("storeName",yjStore.getStoreName());
m.put("phone",yjStore.getPhone());
m.put("banner",yjStore.getBanner());
m.put("id",yjStore.getId());
return new RestResponse().setSuccess(true).setData(m);
return storeService.changeStore(visitStoreId);
}
@ApiOperation("获取首页及分类页菜单")
@GetMapping("/getIndex")
public RestResponse getIndex(){
return storeService.getIndex();
}
}

@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
*
@ -28,15 +29,16 @@ public class InheritController {
/**
*
* @param inherit
* @param visitStore
* @return
*/
@ApiOperation(value = "获取瑜伽传承列表")
@PostMapping("/getList")
public RestResponse getList(@RequestBody YjInherit inherit){
public RestResponse getList(@RequestBody Map map){
Long visitStore=Long.parseLong(map.get("visitStore").toString());
List<YjInherit> list= inheritService.list(new QueryWrapper<YjInherit>()
.select("id,title,image,read_num,start_time")
.eq("visit_store",inherit.getVisitStore())
.eq("dept_id",visitStore)
.eq("status",true)
.orderByDesc("modify_time"));
return new RestResponse().setSuccess(true).setMessage("成功").setData(list);

@ -0,0 +1,246 @@
package com.ruoyi.web.controller.basic;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.service.YjAppUserService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.course.domain.req.ReqSearchClaTime;
import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar;
import com.ruoyi.course.service.ScClaTimeService;
import com.ruoyi.im.service.FileService;
import com.sun.org.apache.regexp.internal.RE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Map;
@RestController
@RequestMapping("/api/my")
public class MyController extends BaseController {
@Autowired
private ScClaTimeService scClaTimeService;
@Autowired
private YjAppUserService appUserService;
@Autowired
private FileService fileService;
@GetMapping("/myInformation")
public RestResponse myInformation(){
AppUser user= appUserService.getById(SecurityUtils.getAppLoginUser().getAppUserId());
return new RestResponse().setSuccess(true).setData(user);
}
//上传头像
@PostMapping("/avatarUpload")
public RestResponse avatarUpload(@RequestParam("file") MultipartFile file,
@RequestParam(defaultValue = "true") Boolean isPermanent){
String url= fileService.uploadImage(file,"app_avatar",isPermanent).getOriginUrl();
return new RestResponse().setSuccess(true).setData(url);
}
@PostMapping("/modifyMyInformation")
public RestResponse modifyMyInformation(@RequestBody AppUser user){
AppUser dbUser= appUserService.getById(SecurityUtils.getAppLoginUser().getAppUserId());
AppUser modifyUser=new AppUser();
modifyUser.setId(dbUser.getId());
if (StrUtil.isNotEmpty(user.getPassword())
&&SecurityUtils.matchesPassword(user.getPassword(),dbUser.getPassword())){
modifyUser.setPassword(SecurityUtils.encryptPassword(user.getNewPassword()));
return new RestResponse().setSuccess(appUserService.updateById(modifyUser));
}
modifyUser.setSex(user.getSex());
modifyUser.setAvatar(user.getAvatar());
modifyUser.setNickName(user.getNickName());
modifyUser.setSignature(user.getSignature());
appUserService.updateById(modifyUser);
return new RestResponse().setSuccess(true).setData(modifyUser);
}
/**
* -
* @return
*/
@GetMapping("/getCourseList")
public RestResponse getCourseList(){
Long[] roleId=SecurityUtils.getAppLoginUser().getRoles();
//104 教师 105店长 103 会籍顾问
if (!ArrayUtil.containsAny(roleId,104l)){
return new RestResponse().setSuccess(false).setMessage("当前登录人无权限!");
}
Long teacherId=SecurityUtils.getAppLoginUser().getManageAccountId();
ReqSearchClaTime reqSearchClaTime=new ReqSearchClaTime();
reqSearchClaTime.setTeacherId(teacherId);//teacherId
RespBusinessClaTimeCalendar c =scClaTimeService.searchListForCalendar(reqSearchClaTime);
return new RestResponse().setSuccess(true).setMessage("成功").setData(c);
}
/**
*
* @param map
* @return
*/
@PostMapping("/courseTimeDetail")
public RestResponse courseTimeDetail(@RequestBody Map<String,Long> map){
Long courseTimeId=map.get("courseTimeId");
return scClaTimeService.courseTimeDetail(courseTimeId);
}
/**
* ()
* @param
* @return
*/
@GetMapping("/appointmentListForTeacher")
public RestResponse appointmentListForTeacher(){
return scClaTimeService.appointmentListForTeacher();
}
/**
* ()
* @param
* @return
*/
@GetMapping("/appointmentListForManager")
public RestResponse appointmentListForManager(){
return scClaTimeService.appointmentListForManager();
}
/**
* / /
* bookId id
* bookStatus 1->2->// 5- >
* @param map
* @return
*/
@PostMapping("/checkAppointment")
public RestResponse checkAppointment(@RequestBody Map map){
Long courseTimeId=Long.parseLong(map.get("bookId").toString());
int bookStatus=Integer.parseInt(map.get("bookStatus").toString());
return scClaTimeService.checkAppointment(courseTimeId,bookStatus);
}
/**
* ()
* @param map courseTimeId
* startTime //HH:mm:ss 24小时制
* endTime //HH:mm:ss 24小时制
* @return
*/
@PostMapping("/confirmClass")
public RestResponse confirmClass(@RequestBody Map map){
Long courseTimeId=(Long)map.get("courseTimeId");
String startTime=map.get("startTime").toString();//HH:mm:ss
String endTime=map.get("endTime").toString();//HH:mm:ss
if (StrUtil.hasEmpty(startTime,endTime)){
throw new RuntimeException("请输入具体上下课时间!");
}
return scClaTimeService.confirmClass(courseTimeId,startTime,endTime);
}
/**
* ()
* @param map code bookId
* @return
*/
@PostMapping("/checkIn")
public RestResponse checkIn(@RequestBody Map map){
return scClaTimeService.checkIn(map);
}
/**
*
* @param
* @return
* today
* yesterday
* thisMonth
* lastMonth
*/
@PostMapping("/teacherClaTotal")
public RestResponse teacherClaTotal(@RequestBody Map<String,String> map){
String time=map.get("time").toString();
return scClaTimeService.teacherClaTotal(time);
}
/**
*
* @param
* @return
* today
* yesterday
* thisMonth
* lastMonth
*/
@PostMapping("/teacherFeeTotal")
public RestResponse teacherFeeTotal(@RequestBody Map<String,String> map){
String time=map.get("time").toString();
return scClaTimeService.teacherFeeTotal(time);
}
/**
* -
* @return
*/
@GetMapping("/myClient")
public RestResponse myClient(){
return scClaTimeService.myClient();
}
/**
* /
* @param
* @return
* today
* thisMonth
* lastMonth
*/
@PostMapping("/commissionTotal")
public RestResponse commissionTotal(@RequestBody Map<String,String> map){
String time=map.get("time").toString();
return scClaTimeService.commissionTotal(time);
}
/**
*
* @param
* @return
* today
* yesterday
* thisMonth
* lastMonth
*/
@PostMapping("/salesInformation")
public RestResponse salesInformation(@RequestBody Map<String,String> map){
String time=map.get("time").toString();
return scClaTimeService.salesInformation(time);
}
/**
*
* @param
* @return
* today
* thisMonth
* lastMonth
*/
@PostMapping("/claRoomFee")
public RestResponse claRoomFee(@RequestBody Map<String,String> map){
String time=map.get("time").toString();
return scClaTimeService.claRoomFee(time);
}
}

@ -1,7 +1,9 @@
package com.ruoyi.web.controller.basic;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.domain.YjInherit;
import com.ruoyi.basic.domain.YjPracticeMoments;
import com.ruoyi.basic.service.impl.YjPracticeMomentsServiceImpl;
import io.swagger.annotations.Api;
@ -13,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
*
@ -27,15 +30,16 @@ public class PracticeMomentsController {
/**
*
* @param moments
* @param visitStore
* @return
*/
@ApiOperation(value = "获取练习瞬间列表")
@PostMapping("/getList")
public RestResponse getList(@RequestBody YjPracticeMoments moments){
public RestResponse getList(@RequestBody Map map){
Long visitStore=Long.parseLong(map.get("visitStore").toString());
List<YjPracticeMoments> list=momentsService.list(new QueryWrapper<YjPracticeMoments>()
.select("id,title,image,read_num,start_time")
.eq("visit_store",moments.getVisitStore())
.eq("dept_id",visitStore)
.eq("status",true)
.orderByDesc("modify_time"));
return new RestResponse().setSuccess(true).setMessage("成功").setData(list);
@ -49,6 +53,9 @@ public class PracticeMomentsController {
@ApiOperation(value = "获取练习瞬间详情")
@PostMapping("/getOne")
public RestResponse getOne(@RequestBody YjPracticeMoments moments){
momentsService.update(new UpdateWrapper<YjPracticeMoments>()
.setSql("read_num=read_num+1")
.eq("id",moments.getId()));//阅读量
YjPracticeMoments m=momentsService.getOne(new QueryWrapper<YjPracticeMoments>()
.eq("id",moments.getId()));
return new RestResponse().setSuccess(true).setMessage("成功").setData(m);

@ -0,0 +1,106 @@
package com.ruoyi.web.controller.basic;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.domain.dto.AnswerSubmitDTO;
import com.ruoyi.basic.domain.model.AnswerResultVO;
import com.ruoyi.basic.domain.model.QuestionnaireVO;
import com.ruoyi.basic.domain.question.QuestionSurvey;
import com.ruoyi.basic.mapper.QuestionSurveyMapper;
import com.ruoyi.basic.service.QuestionnaireService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@RestController
@RequestMapping("/api/questionnaire")
@RequiredArgsConstructor
@Validated
public class QuestionnaireController {
private final QuestionnaireService questionnaireService;
private final QuestionSurveyMapper surveyMapper;
/**
*
* @return
*/
@GetMapping("/list")
public RestResponse listSurveys() {
List<QuestionSurvey> surveys = surveyMapper.selectList(
new LambdaQueryWrapper<QuestionSurvey>()
.eq(QuestionSurvey::getStatus, 1) // 只返回已发布的
.orderByDesc(QuestionSurvey::getCreateTime)
);
List<QuestionSurveyBriefVO> briefList = surveys.stream()
.map(s -> new QuestionSurveyBriefVO(s.getId(), s.getTitle(), s.getDescription()))
.collect(Collectors.toList());
return RestResponse.success().setData(briefList);
}
/**
*
* @return
*/
@GetMapping("/getOne")
public RestResponse getQuestionnaire() {
QuestionnaireVO vo = questionnaireService.getQuestionnaire();
if (vo == null) {
return RestResponse.failure("问卷不存在或未发布");
}
return RestResponse.success().setData(vo);
}
/**
*
* @param dto
* @param request HttpIP
* @return
*/
@PostMapping("/submit")
public RestResponse submit(@Valid @RequestBody AnswerSubmitDTO dto,
HttpServletRequest request) {
try {
AnswerResultVO result = questionnaireService.submitAnswers(dto, request);
return RestResponse.success().setData(result);
} catch (IllegalArgumentException e) {
log.warn("参数校验失败: {}", e.getMessage());
return RestResponse.failure(e.getMessage());
} catch (Exception e) {
log.error("提交答案失败", e);
return RestResponse.failure("提交失败,请稍后重试");
}
}
/**
* ID
* @return
*/
@GetMapping("/result")
public RestResponse getResult() {
AnswerResultVO result = questionnaireService.getResultBySheetId();
if (result == null) {
return RestResponse.failure("答卷不存在");
}
return RestResponse.success().setData(result);
}
/**
*
*/
@lombok.Data
@lombok.AllArgsConstructor
public static class QuestionSurveyBriefVO {
private Long id;
private String title;
private String description;
}
}

@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
*
@ -27,15 +28,16 @@ public class SenseController {
/**
*
* @param sense
* @param visitStore
* @return
*/
@ApiOperation(value = "获取瑜伽常识列表")
@PostMapping("/getList")
public RestResponse getList(@RequestBody YjSense sense){
public RestResponse getList(@RequestBody Map map){
Long visitStore=Long.parseLong(map.get("visitStore").toString());
List<YjSense> list= service.list(new QueryWrapper<YjSense>()
.select("id,title,image,read_num,start_time")
.eq("visit_store",sense.getVisitStore())
.eq("dept_id",visitStore)
.eq("status",true)
.orderByDesc("modify_time"));
return new RestResponse().setSuccess(true).setMessage("成功").setData(list);

@ -3,7 +3,10 @@ package com.ruoyi.web.controller.basic;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.domain.YjStore;
import com.ruoyi.basic.service.YjStoreService;
import com.ruoyi.basic.service.impl.YjStoreServiceImpl;
import com.ruoyi.system.domain.SysTeacher;
import com.ruoyi.system.service.SysTeacherService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
@ -12,6 +15,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -23,7 +29,10 @@ import java.util.Map;
public class StoreController {
@Resource
private YjStoreServiceImpl merchantService;
private YjStoreService storeService;
@Resource
private SysTeacherService teacherService;
/**
* +
* @param map
@ -32,10 +41,22 @@ public class StoreController {
@ApiOperation(value = "创始人+企业简介+门店列表")
@PostMapping("/getList")
public RestResponse getList(@RequestBody Map map){
YjStore m=merchantService.getOne(new QueryWrapper<YjStore>()
.select("id,enterprise_name,address,phone,founder,profile")
.eq("id",map.get("visitStore")));
return new RestResponse().setSuccess(true).setMessage("成功").setData(m);
Map map1=new HashMap();
YjStore store=storeService.getOne(Long.parseLong(map.get("visitStore").toString()));
String tenantId=store.getTenantId();
List<YjStore> list= storeService.getStoreListByTenantId(tenantId);
List<YjStore> list1=new ArrayList<>();
list.forEach(l->{
if (l.getParentId()==0l){
l.setStoreName(l.getStoreName()+"(总店)");
}
list1.add(l);
});
map1.put("companyIntroduction",store);
map1.put("storeList",list1);
return new RestResponse().setSuccess(true).setMessage("成功").setData(map1);
}

@ -1,5 +1,7 @@
package com.ruoyi.web.controller.basic.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import io.swagger.annotations.ApiModel;
@ -8,13 +10,14 @@ import lombok.Data;
@ApiModel(value = "AppLoginUser", description = "app登录用户信息")
@Data
public class AppLoginUser
public class AppLoginUserForGetInfor
{
private static final long serialVersionUID = 1L;
/** 用户ID */
@ApiModelProperty("用户ID")
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/** 用户账号 */
@ -38,9 +41,9 @@ public class AppLoginUser
private String phonenumber;
/** 用户性别 */
@ApiModelProperty("用户性别0=男,1=女,2=未知")
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
@ApiModelProperty("性别0->未知1->女2->男")
@Excel(name = "用户性别", readConverterExp = "0->未知1->女2->男")
private Integer sex;
/** 用户头像 */
@ApiModelProperty("用户头像")
@ -48,15 +51,15 @@ public class AppLoginUser
/** 角色ID */
@ApiModelProperty("角色ID顾问103 教练104 店长105 普通用户107")
private Long roleId;
private Long[] roleId;
/** 所属门店id */
@ApiModelProperty("所属门店id")
private String venId;
private Long venId;
@ApiModelProperty("设备id")
private String registerId;
@ApiModelProperty("访问/浏览门店id")
private String visitStore;
private Long visitStore;
}

@ -1,31 +1,101 @@
package com.ruoyi.web.controller.course;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.RestResponse;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.course.domain.req.ReqSearchClaTime;
import com.ruoyi.course.domain.time.ClaTimeCalendarItem;
import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar;
import com.ruoyi.course.mapper.ScClaTimeMapper;
import com.ruoyi.course.service.ScClaTimeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.Map;
@Api(tags = "040-教练", description = "获取商品及课程分类")
@RestController
@RequestMapping("/api/course/category")
@RequestMapping("/api/course")
public class CourseController extends BaseController {
// @Autowired
// ContextServicelmpl contextService;
// @Autowired
// SysUserServiceImpl userService;
@ApiOperation("商品及课程类型列表")
@PostMapping(value = "/getList")
public RestResponse findList(@RequestBody Map<String, Object> params) {
// List<Context> list =contextService.getList(params);
return new RestResponse().setSuccess(true).setMessage("成功");
@Autowired
private ScClaTimeService scClaTimeService;
/**
* -
* @return
*/
@GetMapping("/getCourseList")
public RestResponse getCourseList(){
ReqSearchClaTime reqSearchClaTime=new ReqSearchClaTime();
RespBusinessClaTimeCalendar c =scClaTimeService.searchListForCalendar(reqSearchClaTime);
return new RestResponse().setSuccess(true).setMessage("成功").setData(c);
}
/**
*
* @return
*/
@PostMapping("/getCourseListByDate")
public RestResponse getCourseListByDate(@RequestBody Map map){
String dateStr= map.get("date").toString();
// Date date= DateUtil.parse(dateStr,"yyyy-MM-dd");
return scClaTimeService.getCourseListByDate(dateStr);
}
@PostMapping("/getCourseDetail")
public RestResponse getCourseDetail(@RequestBody Map<String,Long> map){
Long courseTimeId=map.get("courseTimeId");
return scClaTimeService.getCourseDetail(courseTimeId);
}
/**
*
* @param searchClaTime
* @return
*/
@PostMapping("/bookCourse")
public RestResponse bookCourse(@RequestBody ReqSearchClaTime searchClaTime){
return scClaTimeService.bookCourse(searchClaTime);
}
/**
*
* @param
* @return
*/
@GetMapping("/bookCourseList")
public RestResponse bookCourseList(){
return new RestResponse().setData(scClaTimeService.bookCourseList());
}
/**
*
* @param map
* @return
*/
@PostMapping("/bookCourseDetail")
public RestResponse bookCourseDetail(@RequestBody Map map){
Long bookId =Long.parseLong(map.get("bookId").toString());
return scClaTimeService.bookCourseDetail(bookId);
}
/**
*
* @return
*/
@PostMapping("/cancelCourse")
public RestResponse cancelCourse(@RequestBody Map map){
Long courseTimeId =(Long)map.get("courseTimeId");
return scClaTimeService.cancelCourse(courseTimeId);
}

@ -28,7 +28,7 @@ public class FileController {
@PostMapping("/image/upload")
public Result<UploadImageVO> uploadImage(@RequestParam("file") MultipartFile file,
@RequestParam(defaultValue = "true") Boolean isPermanent) {
return ResultUtils.success(fileService.uploadImage(file,isPermanent));
return ResultUtils.success(fileService.uploadImage(file,"im",isPermanent));
}
@Operation(summary = "上传文件", description = "上传文件上传后返回文件url")
@ -37,4 +37,4 @@ public class FileController {
return ResultUtils.success(fileService.uploadFile(file), Strings.EMPTY);
}
}
}

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.basic.service.YjAppUserService;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.im.domain.vo.FriendVO;
import com.ruoyi.im.domain.vo.UserVO;
import com.ruoyi.im.service.FriendService;
@ -15,6 +16,7 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
@RestController
@ -26,11 +28,11 @@ public class FriendController {
private final YjAppUserService appUserService;
@GetMapping("/list")
@Operation(summary = "好友列表", description = "获取好友列表")
public Result<List<FriendVO>> findFriends() {
return ResultUtils.success(friendService.findFriends());
public Result<Map> findFriends() {
return ResultUtils.success(friendService.findAllFriends());
}
@GetMapping("/find/{phonenumber}")
// @GetMapping("/find/{phonenumber}")
@Operation(summary = "查找用户", description = "根据电话查找用户")
public Result<UserVO> findById(@NotNull @PathVariable("phonenumber") String phonenumber) {
//权限:课程顾问 店长 教练 查询客户信息
@ -44,6 +46,7 @@ public class FriendController {
@PostMapping("/add")
@Operation(summary = "添加好友", description = "双方建立好友关系")
public Result addFriend(@NotNull(message = "好友id不可为空") @RequestParam Long friendId) {
friendService.addFriend(friendId);
return ResultUtils.success();
}
@ -51,7 +54,11 @@ public class FriendController {
@GetMapping("/find/{friendId}")
@Operation(summary = "查找好友信息", description = "查找好友信息")
public Result<FriendVO> findFriend(@NotNull(message = "好友id不可为空") @PathVariable Long friendId) {
return ResultUtils.success(friendService.findFriend(friendId));
Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId();
if (friendId.equals(userId)) {
return null;
}
return ResultUtils.success(friendService.findFriend(userId,friendId));
}

@ -0,0 +1,47 @@
package com.ruoyi.web.controller.im;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.im.domain.vo.GroupVO;
import com.ruoyi.im.service.GroupService;
import com.ruoyi.web.controller.im.result.Result;
import com.ruoyi.web.controller.im.result.ResultUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@Tag(name = "群聊")
@RestController
@RequestMapping("/api/group")
@RequiredArgsConstructor
public class GroupController {
private final GroupService groupService;
@RepeatSubmit
@Operation(summary = "创建群聊", description = "创建群聊")
@PostMapping("/create")
public Result<GroupVO> createGroup(@Valid @RequestBody GroupVO vo) {
return ResultUtils.success(groupService.createGroup(vo));
}
@Operation(summary = "查询群聊", description = "查询单个群聊信息")
@GetMapping("/find/{groupId}")
public Result<GroupVO> findGroup(@NotNull(message = "群聊id不能为空") @PathVariable Long groupId) {
return ResultUtils.success(groupService.findById(groupId));
}
@Operation(summary = "查询群聊列表", description = "查询群聊列表")
@GetMapping("/list")
public Result<List<GroupVO>> findGroups() {
return ResultUtils.success(groupService.findGroups());
}
}

@ -0,0 +1,67 @@
package com.ruoyi.web.controller.im;
import com.ruoyi.im.domain.dto.GroupMessageDTO;
import com.ruoyi.im.domain.vo.GroupMessageVO;
import com.ruoyi.im.service.GroupMessageService;
import com.ruoyi.web.controller.im.result.Result;
import com.ruoyi.web.controller.im.result.ResultUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@Tag(name = "群聊消息")
@RestController
@RequestMapping("/api/message/group")
@RequiredArgsConstructor
public class GroupMessageController {
private final GroupMessageService groupMessageService;
@PostMapping("/send")
@Operation(summary = "发送群聊消息", description = "发送群聊消息")
public Result<GroupMessageVO> sendMessage(@Valid @RequestBody GroupMessageDTO vo) {
return ResultUtils.success(groupMessageService.sendMessage(vo));
}
@GetMapping("/maxReadedId")
@Operation(summary = "获取最大已读消息的id", description = "获取某个会话中已读消息的最大id")
public Result<String> getMaxReadedId(@RequestParam Long groupId) {
return ResultUtils.success(groupMessageService.getMaxReadedId(groupId),"成功");
}
@GetMapping("/pullOfflineMessage")
@Operation(summary = "拉取离线消息", description = "拉取离线消息,消息将通过webscoket异步推送")
public Result pullOfflineMessage(@RequestParam Long minId) {
groupMessageService.pullOfflineMessage(minId);
return ResultUtils.success();
}
@PutMapping("/readed")
@Operation(summary = "消息已读", description = "将群聊中的消息状态置为已读")
public Result readedMessage(@RequestParam Long groupId) {
groupMessageService.readedMessage(groupId);
return ResultUtils.success();
}
@GetMapping("/findReadedUsers")
@Operation(summary = "获取已读用户id", description = "获取消息已读用户列表")
public Result<List<Long>> findReadedUsers(@RequestParam Long groupId,
@RequestParam Long messageId) {
return ResultUtils.success(groupMessageService.findReadedUsers(groupId, messageId));
}
@GetMapping("/history")
@Operation(summary = "查询聊天记录", description = "查询聊天记录")
public Result<List<GroupMessageVO>> recallMessage(@NotNull(message = "群聊id不能为空") @RequestParam Long groupId,
@NotNull(message = "页码不能为空") @RequestParam Long page,
@NotNull(message = "size不能为空") @RequestParam Long size) {
return ResultUtils.success(groupMessageService.findHistoryMessage(groupId, page, size));
}
}

@ -1,11 +1,17 @@
package com.ruoyi.web.controller.im;
import com.ruoyi.im.domain.Friend;
import com.ruoyi.im.domain.dto.PrivateMessageDTO;
import com.ruoyi.im.domain.vo.FriendVO;
import com.ruoyi.im.domain.vo.PrivateMessageVO;
import com.ruoyi.im.service.FriendService;
import com.ruoyi.im.service.PrivateMessageService;
import com.ruoyi.mall.domain.Product;
import com.ruoyi.mall.domain.order.OrderItem;
import com.ruoyi.mall.service.ProductService;
import com.ruoyi.mall.service.impl.OrderItemService;
import com.ruoyi.mall.service.impl.OrderService;
import com.ruoyi.web.controller.im.result.Result;
import com.ruoyi.web.controller.im.result.ResultUtils;
import io.swagger.annotations.ApiOperation;
@ -21,6 +27,7 @@ import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@Tag(name = "私聊消息")
@RestController
@ -30,6 +37,11 @@ public class PrivateMessageController {
private final PrivateMessageService privateMessageService;
private final ProductService productService;
private final OrderService orderService;
private final OrderItemService orderItemService;
@PostMapping("/send")
@Operation(summary = "发送消息", description = "发送私聊消息")
public Result<PrivateMessageVO> sendMessage(@Valid @RequestBody PrivateMessageDTO vo) {
@ -54,6 +66,8 @@ public class PrivateMessageController {
privateMessageService.readedMessage(friendId);
return ResultUtils.success();
}
@GetMapping("/maxReadedId")
@Operation(summary = "获取最大已读消息的id", description = "获取某个会话中已读消息的最大id")
public Result<Long> getMaxReadedId(@RequestParam Long friendId) {
@ -69,5 +83,25 @@ public class PrivateMessageController {
return ResultUtils.success(privateMessageService.findHistoryMessage(friendId, page, size));
}
// 选择咨询商品/订单
@PostMapping("/getConsultProduct")
public Result getConsultProduct(@RequestBody Friend friend) {
Long storeId= friend.getStoreId();
return ResultUtils.success(privateMessageService.getConsultProduct(storeId));
}
//商品信息
@PostMapping("/getProductForIm")
public Result getProduct(@RequestBody Map map) {
Long productId= Long.parseLong(map.get("productId").toString());
return ResultUtils.success(productService.getById(productId));
}
//订单信息
@PostMapping("/getOrderForIm")
public Result getOrder(@RequestBody Map map) {
Long orderItemId= Long.parseLong(map.get("orderItemId").toString());
return ResultUtils.success(orderItemService.getById(orderItemId));
}
}

@ -11,11 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.web.controller.im.result.Result;
/**
* @author: blue
* @date: 2024-06-10
* @version: 1.0
*/
@Tag(name = "系统相关")
@RestController
@RequestMapping("/system")

@ -1,36 +1,34 @@
package com.ruoyi.web.controller.login;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.im.util.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.basic.domain.dto.StoreDto;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.mapper.YjStoreMapper;
import com.ruoyi.basic.service.impl.YjAppUserServiceImpl;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AppLoginUser;
import com.ruoyi.common.core.domain.model.AppUserLoginBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.AppLoginService;
import com.ruoyi.basic.domain.YjStore;
import com.ruoyi.basic.service.impl.YjStoreServiceImpl;
import com.ruoyi.mall.util.PayConstants;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.controller.basic.dto.AppLoginUserForGetInfor;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Api(tags = "01-登录与验证")
@RestController
@RequestMapping("/api")
@ -39,12 +37,16 @@ public class AppLoginController {
@Autowired
private AppLoginService appLoginService;
@Autowired
private ISysUserService userService;
@Autowired
private YjAppUserServiceImpl appUserService;
@Autowired
private YjStoreMapper storeMapper;
@Autowired
private SysPermissionService permissionService;
/**
*
@ -52,18 +54,22 @@ public class AppLoginController {
* @return
*/
@PostMapping("/register")
public AjaxResult register(@RequestBody AppUserLoginBody loginBody){
public RestResponse register(@RequestBody AppUserLoginBody loginBody){
appLoginService.validateCaptcha(loginBody.getCode(), loginBody.getUuid());
if (!loginBody.getPassword().equals(loginBody.getPasswordSecond())){
throw new RuntimeException("密码不一致!");
}
Long haveUser=appUserService.count(new QueryWrapper<AppUser>().eq("phone_number",loginBody.getPhonenumber()));
if (haveUser>0){
throw new RuntimeException("手机号已被注册!");
}
AppUser appUser=new AppUser();
appUser.setPhoneNumber("15004070930");
appUser.setPhoneNumber(loginBody.getPhonenumber());
appUser.setPassword(SecurityUtils.encryptPassword(loginBody.getPassword()));
appUser.setStatus(1);
appUser.setVisitStore("14b8471ff004e074e928d795053b4233");
appUserService.save(appUser);
//todo 默认visitstore
//todo openid
return null;
return new RestResponse().setSuccess(true).setMessage("注册成功!");
}
/**
@ -80,6 +86,7 @@ public class AppLoginController {
return ajax;
}
/**
*
*
@ -89,26 +96,37 @@ public class AppLoginController {
@GetMapping("/getInfo")
public AjaxResult getInfo()
{
AppUser user = SecurityUtils.getAppLoginUser().getAppUser();
AppLoginUser user = SecurityUtils.getAppLoginUser();
AppLoginUserForGetInfor appUser=
BeanUtils.copyProperties(user.getAppUser(),AppLoginUserForGetInfor.class);
appUser.setUserId(user.getAppUserId());
appUser.setPhonenumber(user.getAppUser().getPhoneNumber());
// 角色集合
appUser.setRoleId(user.getRoles());
//管理人员(教练、店长、顾问)默认访问门店
// if (ObjectUtil.isNotEmpty(user.getManageAccountId())&&ObjectUtil.isNotEmpty(appUser.getVisitStore())){
// Long deptId= userService.selectUserById(user.getManageAccountId()).getDeptId();
// appUser.setVisitStore(deptId);
// }
AjaxResult ajax = AjaxResult.success();
ajax.put("appLoginUser", user);
ajax.put("visitStore",getIndex(user.getVisitStore()));
ajax.put("appLoginUser", appUser);
ajax.put("visitStore",getIndex(appUser.getVisitStore()));
return ajax;
}
@Resource
private YjStoreServiceImpl merchantService;
private YjStoreServiceImpl storeService;
public Map<String,String> getIndex(String visitStore){
public Map<String,String> getIndex(Long visitStore){
YjStore yjStore;
Map m=new HashMap();
if (StrUtil.isNotEmpty(visitStore)){
yjStore=merchantService.getById(visitStore);
if (ObjectUtil.isNotEmpty(visitStore)){
yjStore=storeService.getById(visitStore);
}else {
yjStore= merchantService.list().get(0);
yjStore= storeService.list().get(0);
}
m.put("address",yjStore.getAddress());
m.put("storeName",yjStore.getStoreName());
@ -129,8 +147,9 @@ public class AppLoginController {
public AjaxResult getStoreList(String address) {
AjaxResult ajax = AjaxResult.success();
List<StoreDto> dtoList= storeMapper.getListForLogin();
List<YjStore> dtoList= storeMapper.getStoreList();
dtoList.forEach(l->{
l.setStoreName(l.getStoreName()+"(总店)");
l.setChildList(storeMapper.getChilds(l.getId()));
});
ajax.put("storeList",dtoList);

@ -2,7 +2,6 @@ package com.ruoyi.web.controller.login;
import com.google.code.kaptcha.Producer;
import com.ruoyi.basic.domain.YjStore;
import com.ruoyi.basic.domain.dto.StoreDto;
import com.ruoyi.basic.mapper.YjStoreMapper;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.CacheConstants;
@ -74,6 +73,7 @@ public class CaptchaController
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(captchaType))
@ -81,7 +81,6 @@ public class CaptchaController
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
}
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();

@ -34,7 +34,7 @@ public class MemberAddressController {
@Resource
private MemberAddressService service;
@ApiOperation("地址list")
@ApiOperation("全国省市区list")
@GetMapping("/addressList")
public RestResponse getAddressList(){
return new RestResponse().setSuccess(true).setData(service.getAddressList());
@ -52,7 +52,7 @@ public class MemberAddressController {
}
@ApiOperation("收货地址列表")
@PostMapping("/memberAddressList")
@PostMapping("/list")
public RestResponse list(){
Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId();
List<String> columns=new ArrayList<>();

@ -36,7 +36,7 @@ public class MemberCartController {
* @return
*/
@GetMapping("list")
public ResponseEntity<List<MemberCartVO>> list() {
public ResponseEntity<List<Map>> list() {
MemberCartQuery query = new MemberCartQuery();
query.setMemberId(SecurityUtils.getAppLoginUser().getAppUserId());
return ResponseEntity.ok(memberCartService.selectList(query, null));

@ -23,6 +23,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Map;
@RestController
@RequestMapping("/api/order")
@ -37,7 +38,7 @@ public class OrderController {
@ApiOperation("下单")
@PostMapping("/add")
public ResponseEntity<Long> submit(@RequestBody OrderSubmitForm form) {
public ResponseEntity<Map> submit(@RequestBody OrderSubmitForm form) {
Long memberId = SecurityUtils.getAppLoginUser().getAppUserId();
String redisKey = "app_order_add" + memberId;
String redisValue = memberId + "_" + System.currentTimeMillis();

@ -91,13 +91,13 @@ public class PayNotifyController {
PayNotifyMessageDTO message = new PayNotifyMessageDTO();
message.setOutTradeNo(Long.valueOf(transaction.getOutTradeNo()));
message.setMemberId(Long.valueOf(transaction.getAttach()));
message.setTradeStatus(transaction.getTradeState());
message.setTradeStatus(transaction.getTradeState().toString());
if (StrUtil.isEmpty(transaction.getSuccessTime())){
throw new RuntimeException("微信支付回调失败");
}
message.setPayTime(formatter.parse(transaction.getSuccessTime().substring(0, transaction.getSuccessTime().indexOf("+"))));
message.setTradeNo(transaction.getTransactionId());
// OrderService.payCallBack(message);
OrderService.payCallBack(message);
}

@ -2,20 +2,16 @@ package com.ruoyi.web.controller.mall;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.RestResponse;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.mall.domain.MemberAddress;
import com.ruoyi.course.domain.req.ReqSearchClaTime;
import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar;
import com.ruoyi.course.service.ScClaTimeService;
import com.ruoyi.mall.domain.Product;
import com.ruoyi.mall.domain.query.ProductQuery;
import com.ruoyi.mall.domain.vo.AppProductVO;
import com.ruoyi.mall.domain.vo.ProductDetailVO;
import com.ruoyi.mall.domain.vo.ProductVO;
import com.ruoyi.mall.mapper.MemberAddressMapper;
import com.ruoyi.mall.service.MemberAddressService;
import com.ruoyi.mall.service.ProductCategoryService;
import com.ruoyi.mall.service.impl.ProductService;
import com.ruoyi.mall.service.impl.ProductServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@ -25,8 +21,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -46,7 +41,10 @@ public class ProductController {
@Autowired
private ProductCategoryService categoryService;
@Autowired
private ProductService productService;
private ProductServiceImpl productService;
@Autowired
private ScClaTimeService scClaTimeService;
/**
* list
@ -81,6 +79,32 @@ public class ProductController {
return ResponseEntity.ok(detail);
}
/**
* -
* @param id
* @return
*/
@GetMapping("/detail/calendar/{id}")
public ResponseEntity<RespBusinessClaTimeCalendar> queryDetailCalendar(@PathVariable Long id) {
ReqSearchClaTime reqSearchClaTime=new ReqSearchClaTime();
HashSet<Long> courseIds= new HashSet<>();
reqSearchClaTime.setCourseId(id);
RespBusinessClaTimeCalendar c =scClaTimeService.searchListForCalendar(reqSearchClaTime);
return ResponseEntity.ok(c);
}
/**
*
*
* @return
*/
@PostMapping("/getGoodStuff")
public ResponseEntity<Map> getGoodStuff(@RequestBody Map map) {
Map map1 = productService.selectByGoodStuff(map.get("storeId").toString());
return ResponseEntity.ok(map1);
}
}

@ -0,0 +1,74 @@
package com.ruoyi.web.controller.mall;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.RestResponse;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.mall.domain.UserFavorite;
import com.ruoyi.mall.service.UserFavoriteService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@Api(tags = "app商品收藏")
@RestController
@RequestMapping("/api/userFavorite")
public class UserFavoriteController {
@Autowired
private UserFavoriteService service;
/**
*
* @return
*/
@ApiOperation("收藏")
@PostMapping("/add")
public RestResponse addFavorite(@RequestBody UserFavorite favorite){
return new RestResponse().setSuccess(true).setData(service.addFavorite(favorite.getProductId()));
}
/**
*
* @return
*/
@ApiOperation("判断商品是否收藏")
@PostMapping("/existsByProductId")
public RestResponse existsByProductId(@RequestBody UserFavorite favorite){
Long userId=SecurityUtils.getAppLoginUser().getAppUserId();;
return new RestResponse().setSuccess(true).setData(service.existsByUserIdAndProductId(userId,favorite.getProductId()));
}
/**
*
*/
@ApiOperation("取消收藏")
@PostMapping("/removeFavorite")
public RestResponse removeFavorite(@RequestBody UserFavorite favorite) {
Long userId=SecurityUtils.getAppLoginUser().getAppUserId();;
return new RestResponse().setSuccess(true).setData(service.removeFavorite(userId,favorite.getProductId()));
}
/**
*
*/
@ApiOperation("获取用户的收藏列表")
@GetMapping("/getUserFavorites")
public RestResponse getUserFavorites() {
return new RestResponse().setSuccess(true).setData(service.getUserFavorites());
}
/**
*
*/
@ApiOperation("获取用户的收藏数量")
@GetMapping("/getUserFavoriteCount")
public RestResponse getUserFavoriteCount() {
return new RestResponse().setSuccess(true).setData(service.getUserFavoriteCount());
}
}

@ -7,10 +7,11 @@ spring:
# 主库数据源
master:
# url: jdbc:mysql://101.43.111.159:3306/yoga?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://localhost:3306/yj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# url: jdbc:mysql://localhost:3306/yj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://127.0.0.1:32768/yoga?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
username: root
# password: '!Runpeng888'
password: 123456
password: '!Runpeng888'
# password: 123456
# 从库数据源
slave:
# 从数据源开关/默认关闭
@ -58,12 +59,21 @@ spring:
config:
multi-statement-allow: true
#minio:
# endpoint: http://127.0.0.1:9000 #内网地址
# domain: http://127.0.0.1:9000 #外网访问地址
# accessKey: minioadmin
# secretKey: minioadmin
# bucketName: box-im
# imagePath: image
# filePath: file
# videoPath: video
# expireIn: 180 # 文件过期时间,单位:天
minio:
endpoint: http://127.0.0.1:9000 #内网地址
domain: http://127.0.0.1:9000 #外网访问地址
accessKey: minioadmin
secretKey: minioadmin
bucketName: box-im
endpoint: http://62.234.183.14:9000
accessKey: IvostdowO3hTkXuaa392
secretKey: wZCLColkVlNMYrxczzdvEC2VyK3lLh5DCb8yrFhE
bucketName: yoga-chatcontent
imagePath: image
filePath: file
videoPath: video

@ -6,11 +6,9 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://101.43.111.159:3306/yoga?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# url: jdbc:mysql://localhost:3306/yj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://127.0.0.1:32768/yoga?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: '!Runpeng888'
# password: 123456
# 从库数据源
slave:
# 从数据源开关/默认关闭
@ -59,10 +57,10 @@ spring:
multi-statement-allow: true
minio:
endpoint: http://101.43.111.159:9000 #内网地址
accessKey: KHuC4x81wQNGtDHC1dnS
secretKey: jCA4JpAJIIPXfIUJCWn0dZXKs2QCv5007dEhU1KB
bucketName: yoga-im
endpoint: http://62.234.183.14:9000
accessKey: IvostdowO3hTkXuaa392
secretKey: wZCLColkVlNMYrxczzdvEC2VyK3lLh5DCb8yrFhE
bucketName: yoga-chatcontent
imagePath: image
filePath: file
videoPath: video

@ -39,6 +39,7 @@ logging:
level:
com.ruoyi: debug
org.springframework: warn
config: classpath:logback.xml
# 用户配置
user:

@ -0,0 +1,430 @@
package com.ruoyi.web.controller.basic;
import com.ruoyi.RestResponse;
import com.ruoyi.basic.domain.dto.AnswerSubmitDTO;
import com.ruoyi.basic.domain.model.AnswerResultVO;
import com.ruoyi.basic.service.QuestionnaireService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(MockitoExtension.class)
@DisplayName("QuestionnaireController单元测试")
class QuestionnaireControllerTest {
private MockMvc mockMvc;
@Mock
private QuestionnaireService questionnaireService;
@InjectMocks
private QuestionnaireController questionnaireController;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(questionnaireController).build();
}
/**
*
* AnswerResultVO
*/
@Test
@DisplayName("提交答案成功 - 返回评估结果")
void submit_Success_ReturnsResult() throws Exception {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(1L);
dto.setSessionId("test-session-123");
AnswerSubmitDTO.AnswerItem item1 = new AnswerSubmitDTO.AnswerItem();
item1.setQuestionId(1L);
item1.setOptionId(1L);
AnswerSubmitDTO.AnswerItem item2 = new AnswerSubmitDTO.AnswerItem();
item2.setQuestionId(2L);
item2.setOptionId(2L);
dto.setAnswers(Arrays.asList(item1, item2));
AnswerResultVO resultVO = new AnswerResultVO();
resultVO.setResultType("pinghe");
resultVO.setResultText("恭喜您,您的体质为平和体质");
resultVO.setConstitutionScores(new ArrayList<>());
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenReturn(resultVO);
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"sessionId\":\"test-session-123\",\"answers\":[{\"questionId\":1,\"optionId\":1},{\"questionId\":2,\"optionId\":2}]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data.resultType").value("pinghe"))
.andExpect(jsonPath("$.data.resultText").value("恭喜您,您的体质为平和体质"));
verify(questionnaireService, times(1)).submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class));
}
/**
*
* IllegalArgumentException
*/
@Test
@DisplayName("提交答案失败 - 参数校验失败")
void submit_ValidationFailure_ReturnsFailure() throws Exception {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(null); // 故意设置为null触发校验失败
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenThrow(new IllegalArgumentException("问卷ID不能为空"));
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":null,\"answers\":[]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.message").value("问卷ID不能为空"));
verify(questionnaireService, times(1)).submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class));
}
/**
*
* Exception"提交失败,请稍后重试"
*/
@Test
@DisplayName("提交答案失败 - 系统异常")
void submit_SystemException_ReturnsFailure() throws Exception {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(1L);
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenThrow(new RuntimeException("数据库连接失败"));
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"answers\":[]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.message").value("提交失败,请稍后重试"));
verify(questionnaireService, times(1)).submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class));
}
/**
*
* answers
*/
@Test
@DisplayName("提交答案成功 - 空答案列表")
void submit_EmptyAnswersList_ReturnsResult() throws Exception {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(1L);
dto.setSessionId(null); // 测试sessionId为null的情况
dto.setAnswers(Collections.emptyList());
AnswerResultVO resultVO = new AnswerResultVO();
resultVO.setResultType("unknown");
resultVO.setResultText("无法判定体质类型");
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenReturn(resultVO);
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"answers\":[]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data.resultType").value("unknown"));
}
/**
*
* RuntimeException
*/
@Test
@DisplayName("提交答案失败 - 问卷不存在异常")
void submit_SurveyNotFound_ReturnsFailure() throws Exception {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(999L);
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenThrow(new RuntimeException("问卷不存在或未发布"));
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":999,\"answers\":[{\"questionId\":1,\"optionId\":1}]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.message").value("提交失败,请稍后重试"));
}
/**
*
* constitutionScores
*/
@DisplayName("提交答案成功 - 返回包含体质得分的评估结果")
@Test
void submit_Success_ReturnsResultWithScores() throws Exception {
// Arrange
com.ruoyi.basic.domain.dto.ConstitutionScoreDTO scoreDTO = new com.ruoyi.basic.domain.dto.ConstitutionScoreDTO();
scoreDTO.setConstitutionAlias("pinghe");
scoreDTO.setConstitutionName("平和体质");
scoreDTO.setTotalScore(10);
AnswerResultVO resultVO = new AnswerResultVO();
resultVO.setResultType("pinghe");
resultVO.setResultText("恭喜您,您的体质为平和体质");
resultVO.setConstitutionScores(Collections.singletonList(scoreDTO));
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenReturn(resultVO);
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"answers\":[{\"questionId\":1,\"optionId\":1}]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data.constitutionScores[0].constitutionAlias").value("pinghe"))
.andExpect(jsonPath("$.data.constitutionScores[0].totalScore").value(10));
}
/**
*
* resultType"multiple"
*/
@Test
@DisplayName("提交答案成功 - 复合型体质结果")
void submit_MultipleType_ReturnsResult() throws Exception {
// Arrange
AnswerResultVO resultVO = new AnswerResultVO();
resultVO.setResultType("multiple");
resultVO.setResultText("亲爱的伽人您好,您的体质为复合型体质典型,建议综合调理。");
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenReturn(resultVO);
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"answers\":[{\"questionId\":1,\"optionId\":1}]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data.resultType").value("multiple"));
}
/**
*
* resultType"qixu"
*/
@Test
@DisplayName("提交答案成功 - 偏颇体质结果")
void submit_BiasedType_ReturnsResult() throws Exception {
// Arrange
AnswerResultVO resultVO = new AnswerResultVO();
resultVO.setResultType("qixu");
resultVO.setResultText("亲爱的伽人您好,您的体质为典型气虚体质。");
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenReturn(resultVO);
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"answers\":[{\"questionId\":1,\"optionId\":1}]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data.resultType").value("qixu"));
}
/**
*
* resultType"qixu_tendency"
*/
@Test
@DisplayName("提交答案成功 - 倾向体质结果")
void submit_TendencyType_ReturnsResult() throws Exception {
// Arrange
AnswerResultVO resultVO = new AnswerResultVO();
resultVO.setResultType("qixu_tendency");
resultVO.setResultText("亲爱的伽人您好,您的体质为气虚倾向体质。");
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenReturn(resultVO);
// Act & Assert
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"answers\":[{\"questionId\":1,\"optionId\":1}]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data.resultType").value("qixu_tendency"));
}
/**
* controller -
*/
@Test
@DisplayName("直接调用submit方法 - 成功场景")
void submit_DirectCall_Success() {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(1L);
dto.setSessionId("session-123");
AnswerSubmitDTO.AnswerItem item = new AnswerSubmitDTO.AnswerItem();
item.setQuestionId(1L);
item.setOptionId(1L);
dto.setAnswers(Collections.singletonList(item));
AnswerResultVO expectedResult = new AnswerResultVO();
expectedResult.setResultType("pinghe");
expectedResult.setResultText("测试结果");
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(eq(dto), any(HttpServletRequest.class)))
.thenReturn(expectedResult);
// Act
RestResponse response = questionnaireController.submit(dto, request);
// Assert
assertNotNull(response);
assertTrue(response.getSuccess());
assertEquals("成功", response.getMessage());
assertNotNull(response.get("data"));
AnswerResultVO result = (AnswerResultVO) response.get("data");
assertEquals("pinghe", result.getResultType());
assertEquals("测试结果", result.getResultText());
}
/**
* controller -
*/
@Test
@DisplayName("直接调用submit方法 - 参数校验失败场景")
void submit_DirectCall_ValidationFailure() {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(null); // 触发校验失败
dto.setAnswers(Collections.emptyList());
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenThrow(new IllegalArgumentException("问卷ID不能为空"));
// Act
RestResponse response = questionnaireController.submit(dto, request);
// Assert
assertNotNull(response);
assertEquals(false, response.getSuccess());
assertEquals("问卷ID不能为空", response.getMessage());
}
/**
* controller -
*/
@Test
@DisplayName("直接调用submit方法 - 系统异常场景")
void submit_DirectCall_SystemException() {
// Arrange
AnswerSubmitDTO dto = new AnswerSubmitDTO();
dto.setSurveyId(1L);
dto.setAnswers(Collections.emptyList());
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenThrow(new RuntimeException("数据库异常"));
// Act
RestResponse response = questionnaireController.submit(dto, request);
// Assert
assertNotNull(response);
assertEquals(false, response.getSuccess());
assertEquals("提交失败,请稍后重试", response.getMessage());
}
/**
*
*
*/
@Test
@DisplayName("提交多题目答案 - 正常场景")
void submit_MultipleQuestions_Success() throws Exception {
// Arrange
List<AnswerSubmitDTO.AnswerItem> answers = new ArrayList<>();
for (long i = 1; i <= 10; i++) {
AnswerSubmitDTO.AnswerItem item = new AnswerSubmitDTO.AnswerItem();
item.setQuestionId(i);
item.setOptionId(i);
answers.add(item);
}
AnswerResultVO resultVO = new AnswerResultVO();
resultVO.setResultType("qixu");
resultVO.setResultText("气虚体质");
HttpServletRequest request = mock(HttpServletRequest.class);
when(questionnaireService.submitAnswers(any(AnswerSubmitDTO.class), any(HttpServletRequest.class)))
.thenReturn(resultVO);
// Act & Assert - 使用MockMvc直接测试
mockMvc.perform(post("/api/questionnaire/submit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"surveyId\":1,\"answers\":[{\"questionId\":1,\"optionId\":1},{\"questionId\":2,\"optionId\":2},{\"questionId\":3,\"optionId\":3},{\"questionId\":4,\"optionId\":4},{\"questionId\":5,\"optionId\":5}]}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true));
}
}

@ -135,7 +135,19 @@
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.1</version>
<version>5.8.22</version>
</dependency>
<!-- ZXing 核心Hutool 二维码依赖,需显式引入以避免版本冲突) -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.1</version>
</dependency>
<!-- lombok-->

@ -4,9 +4,6 @@
<facet type="web" name="Web">
<configuration>
<webroots />
<sourceRoots>
<root url="file://$MODULE_DIR$/src/main/java" />
</sourceRoots>
</configuration>
</facet>
<facet type="Spring" name="Spring">
@ -21,7 +18,6 @@
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
@ -104,7 +100,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.14" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.20" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.1" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.22" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:core:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:javase:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.82" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.github.jai-imageio:jai-imageio-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.12" level="project" />
<orderEntry type="library" name="Maven: cn.jpush.api:jiguang-common:1.1.7" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.60" level="project" />
@ -184,5 +184,6 @@
<orderEntry type="library" name="Maven: org.springframework:spring-websocket:5.3.20" level="project" />
<orderEntry type="library" name="Maven: com.auth0:java-jwt:3.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: com.jcraft:jsch:0.1.55" level="project" />
</component>
</module>

@ -191,15 +191,12 @@ public class Constants
WEEK_DAY_MAP.put(1, "星期日");
CLA_TIME_MAP.clear();
CLA_TIME_MAP.put(8, "08:30");
CLA_TIME_MAP.put(9, "10:00");
CLA_TIME_MAP.put(10, "11:00");
CLA_TIME_MAP.put(11, "14:00");
CLA_TIME_MAP.put(12, "15:00");
CLA_TIME_MAP.put(13, "16:00");
CLA_TIME_MAP.put(14, "17:00");
CLA_TIME_MAP.put(15, "18:00");
CLA_TIME_MAP.put(16, "19:30");
CLA_TIME_MAP.put(8, "08:00");
CLA_TIME_MAP.put(10, "10:00");
CLA_TIME_MAP.put(12, "12:00");
CLA_TIME_MAP.put(14, "14:00");
CLA_TIME_MAP.put(16, "16:00");
CLA_TIME_MAP.put(18, "18:00");
}
/**
* 0->1->

@ -8,7 +8,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
/**
* Entity
*
*
* @author ruoyi
*/
public class BaseEntity implements Serializable
@ -19,14 +19,14 @@ public class BaseEntity implements Serializable
private String searchValue;
/** 创建者 */
private String createBy;
private Long createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
private String updateBy;
private Long updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ -48,12 +48,12 @@ public class BaseEntity implements Serializable
this.searchValue = searchValue;
}
public String getCreateBy()
public Long getCreateBy()
{
return createBy;
}
public void setCreateBy(String createBy)
public void setCreateBy(Long createBy)
{
this.createBy = createBy;
}
@ -68,12 +68,12 @@ public class BaseEntity implements Serializable
this.createTime = createTime;
}
public String getUpdateBy()
public Long getUpdateBy()
{
return updateBy;
}
public void setUpdateBy(String updateBy)
public void setUpdateBy(Long updateBy)
{
this.updateBy = updateBy;
}

@ -1,9 +1,12 @@
package com.ruoyi.common.core.domain.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.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.utils.SecurityUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -26,7 +29,7 @@ public class AppUser{
@ApiModelProperty("ID")
@TableId(value = "app_user_id")
@TableId(value = "app_user_id",type = IdType.AUTO)
private Long id;
@ApiModelProperty("昵称")
@ -47,8 +50,8 @@ public class AppUser{
@ApiModelProperty("头像")
private String avatar;
@ApiModelProperty("性别0->未知1->2->女")
private Integer gender;
@ApiModelProperty("性别0->未知1->2->男")
private Integer sex;
@ApiModelProperty("用户所在城市")
private String city;
@ -67,24 +70,32 @@ public class AppUser{
private String registerId;
@ApiModelProperty("访问/浏览门店id")
private String visitStore;
private Long visitStore;
@ApiModelProperty("小程序unionid")
private String unionid;
@ApiModelProperty("小程序openid")
private String openid;
/** 员工所属门店id */
private String storeId;
/** 员工所属商户id */
private String tenantId;
/** 最后登录IP */
private String loginIp;
//个性签名140字
private String signature;
/** 最后登录时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date loginDate;
/**后台账户`sys_user`的user_id*/
@TableField("manage_account_id")
private Long manageAccountId;
@TableField(exist = false)
private String newPassword;
}

@ -1,31 +1,34 @@
package com.ruoyi.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
/**
* sys_dept
*
*
* @author ruoyi
*/
public class SysDept extends BaseEntity
@Data
@TableName("sys_dept")
public class SysDept
{
private static final long serialVersionUID = 1L;
/** 部门ID */
@TableId
private Long deptId;
/** 父部门ID */
private Long parentId;
private String deptType;
/** 祖级列表 */
private String ancestors;
@ -36,10 +39,11 @@ public class SysDept extends BaseEntity
private Integer orderNum;
/** 负责人 */
private String leader;
private Long leaderId;
/** 联系电话 */
private String phone;
private String leader;
/** 邮箱 */
private String email;
@ -48,249 +52,45 @@ public class SysDept extends BaseEntity
private String status;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
private String deleteFlag;
/** 父部门名称 */
@TableField(exist = false)
private String parentName;
/**商户id*/
private String merchanId;
private String TenantId;
/**
*
*/
@TableField(exist = false)
private String address;
/**
*
*/
@TableField(exist = false)
private String detail;
/**
*
*/
@TableField(exist = false)
private String brief;
/**
*
*/
@TableField(exist = false)
private String picture;
/**
* */
private Boolean display;
@TableField(exist = false)
private String dimension;//纬度
@TableField(exist = false)
private String longitude;//经度
public String getDimension() {
return dimension;
}
public void setDimension(String dimension) {
this.dimension = dimension;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public Boolean getDisplay() {
return display;
}
public void setDisplay(Boolean display) {
this.display = display;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getBrief() {
return brief;
}
public void setBrief(String brief) {
this.brief = brief;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getMerchanId() {
return merchanId;
}
public void setMerchanId(String merchanId) {
this.merchanId = merchanId;
}
/** 子部门 */
@TableField(exist = false)
private List<SysDept> children = new ArrayList<SysDept>();
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
public String getAncestors()
{
return ancestors;
}
public void setAncestors(String ancestors)
{
this.ancestors = ancestors;
}
@NotBlank(message = "部门名称不能为空")
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
public String getDeptName()
{
return deptName;
}
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
@NotNull(message = "显示顺序不能为空")
public Integer getOrderNum()
{
return orderNum;
}
public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
public String getLeader()
{
return leader;
}
public void setLeader(String leader)
{
this.leader = leader;
}
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
public String getPhone()
{
return phone;
}
public void setPhone(String phone)
{
this.phone = phone;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getParentName()
{
return parentName;
}
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public List<SysDept> getChildren()
{
return children;
}
public void setChildren(List<SysDept> children)
{
this.children = children;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("deptId", getDeptId())
.append("parentId", getParentId())
.append("ancestors", getAncestors())
.append("deptName", getDeptName())
.append("orderNum", getOrderNum())
.append("leader", getLeader())
.append("phone", getPhone())
.append("email", getEmail())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

@ -4,6 +4,7 @@ import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -12,10 +13,11 @@ import javax.validation.constraints.Size;
/**
* sys_dict_data
*
*
* @author ruoyi
*/
public class SysDictData extends BaseEntity
@Data
public class SysDictData
{
private static final long serialVersionUID = 1L;
@ -54,134 +56,8 @@ public class SysDictData extends BaseEntity
private String status;
/**商户id*/
private String merchantId;
public String getMerchantId() {
return merchantId;
}
public void setMerchantId(String merchantId) {
this.merchantId = merchantId;
}
public Long getDictCode()
{
return dictCode;
}
public void setDictCode(Long dictCode)
{
this.dictCode = dictCode;
}
public Long getDictSort()
{
return dictSort;
}
public void setDictSort(Long dictSort)
{
this.dictSort = dictSort;
}
@NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
public String getDictLabel()
{
return dictLabel;
}
public void setDictLabel(String dictLabel)
{
this.dictLabel = dictLabel;
}
@NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
public String getDictValue()
{
return dictValue;
}
public void setDictValue(String dictValue)
{
this.dictValue = dictValue;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
public String getCssClass()
{
return cssClass;
}
public void setCssClass(String cssClass)
{
this.cssClass = cssClass;
}
public String getListClass()
{
return listClass;
}
public void setListClass(String listClass)
{
this.listClass = listClass;
}
public boolean getDefault()
{
return UserConstants.YES.equals(this.isDefault);
}
public String getIsDefault()
{
return isDefault;
}
public void setIsDefault(String isDefault)
{
this.isDefault = isDefault;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictCode", getDictCode())
.append("dictSort", getDictSort())
.append("dictLabel", getDictLabel())
.append("dictValue", getDictValue())
.append("dictType", getDictType())
.append("cssClass", getCssClass())
.append("listClass", getListClass())
.append("isDefault", getIsDefault())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
private String tenantId;
}

@ -3,6 +3,7 @@ package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -12,10 +13,11 @@ import javax.validation.constraints.Size;
/**
* sys_dict_type
*
*
* @author ruoyi
*/
public class SysDictType extends BaseEntity
@Data
public class SysDictType
{
private static final long serialVersionUID = 1L;
@ -35,63 +37,4 @@ public class SysDictType extends BaseEntity
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictId()
{
return dictId;
}
public void setDictId(Long dictId)
{
this.dictId = dictId;
}
@NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
public String getDictName()
{
return dictName;
}
public void setDictName(String dictName)
{
this.dictName = dictName;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictId", getDictId())
.append("dictName", getDictName())
.append("dictType", getDictType())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

@ -5,15 +5,18 @@ import java.util.List;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* sys_menu
*
*
* @author ruoyi
*/
@Data
public class SysMenu extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -53,7 +56,7 @@ public class SysMenu extends BaseEntity
/** 显示状态0显示 1隐藏 */
private String visible;
/** 菜单状态0显示 1隐藏 */
private String status;
@ -66,194 +69,4 @@ public class SysMenu extends BaseEntity
/** 子菜单 */
private List<SysMenu> children = new ArrayList<SysMenu>();
public Long getMenuId()
{
return menuId;
}
public void setMenuId(Long menuId)
{
this.menuId = menuId;
}
@NotBlank(message = "菜单名称不能为空")
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
public String getMenuName()
{
return menuName;
}
public void setMenuName(String menuName)
{
this.menuName = menuName;
}
public String getParentName()
{
return parentName;
}
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
@NotNull(message = "显示顺序不能为空")
public Integer getOrderNum()
{
return orderNum;
}
public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
public String getPath()
{
return path;
}
public void setPath(String path)
{
this.path = path;
}
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
public String getComponent()
{
return component;
}
public void setComponent(String component)
{
this.component = component;
}
public String getQuery()
{
return query;
}
public void setQuery(String query)
{
this.query = query;
}
public String getIsFrame()
{
return isFrame;
}
public void setIsFrame(String isFrame)
{
this.isFrame = isFrame;
}
public String getIsCache()
{
return isCache;
}
public void setIsCache(String isCache)
{
this.isCache = isCache;
}
@NotBlank(message = "菜单类型不能为空")
public String getMenuType()
{
return menuType;
}
public void setMenuType(String menuType)
{
this.menuType = menuType;
}
public String getVisible()
{
return visible;
}
public void setVisible(String visible)
{
this.visible = visible;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
public String getPerms()
{
return perms;
}
public void setPerms(String perms)
{
this.perms = perms;
}
public String getIcon()
{
return icon;
}
public void setIcon(String icon)
{
this.icon = icon;
}
public List<SysMenu> getChildren()
{
return children;
}
public void setChildren(List<SysMenu> children)
{
this.children = children;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("menuId", getMenuId())
.append("menuName", getMenuName())
.append("parentId", getParentId())
.append("orderNum", getOrderNum())
.append("path", getPath())
.append("component", getComponent())
.append("isFrame", getIsFrame())
.append("IsCache", getIsCache())
.append("menuType", getMenuType())
.append("visible", getVisible())
.append("status ", getStatus())
.append("perms", getPerms())
.append("icon", getIcon())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

@ -3,6 +3,7 @@ package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -12,11 +13,13 @@ import java.util.Set;
/**
* sys_role
*
*
* @author ruoyi
*/
public class SysRole extends BaseEntity
@Data
public class SysRole
{
private static final long serialVersionUID = 1L;
/** 角色ID */
@ -46,7 +49,7 @@ public class SysRole extends BaseEntity
private boolean deptCheckStrictly;
/** 角色状态0正常 1停用 */
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
@Excel(name = "角色状态", readConverterExp = "0=停用,1=正常")
private String status;
/** 删除标志0代表存在 2代表删除 */
@ -64,25 +67,6 @@ public class SysRole extends BaseEntity
/** 角色菜单权限 */
private Set<String> permissions;
public SysRole()
{
}
public SysRole(Long roleId)
{
this.roleId = roleId;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
public boolean isAdmin()
{
@ -93,156 +77,11 @@ public class SysRole extends BaseEntity
{
return roleId != null && 1L == roleId;
}
public boolean isMerchant()
{
return isMerchant(this.roleId);
}
public static boolean isMerchant(Long roleId)
{
return roleId != null && (1L == roleId || 100L == roleId);
}
@NotBlank(message = "角色名称不能为空")
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
public String getRoleName()
{
return roleName;
}
public void setRoleName(String roleName)
{
this.roleName = roleName;
}
@NotBlank(message = "权限字符不能为空")
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
public String getRoleKey()
{
return roleKey;
}
public void setRoleKey(String roleKey)
{
this.roleKey = roleKey;
}
@NotBlank(message = "显示顺序不能为空")
public String getRoleSort()
{
return roleSort;
}
public void setRoleSort(String roleSort)
{
this.roleSort = roleSort;
}
public String getDataScope()
{
return dataScope;
}
public void setDataScope(String dataScope)
{
this.dataScope = dataScope;
}
public boolean isMenuCheckStrictly()
{
return menuCheckStrictly;
}
public void setMenuCheckStrictly(boolean menuCheckStrictly)
{
this.menuCheckStrictly = menuCheckStrictly;
}
public boolean isDeptCheckStrictly()
{
return deptCheckStrictly;
}
public void setDeptCheckStrictly(boolean deptCheckStrictly)
{
this.deptCheckStrictly = deptCheckStrictly;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public boolean isFlag()
{
return flag;
}
public void setFlag(boolean flag)
{
this.flag = flag;
}
public Long[] getMenuIds()
{
return menuIds;
}
public void setMenuIds(Long[] menuIds)
{
this.menuIds = menuIds;
}
public Long[] getDeptIds()
{
return deptIds;
}
public void setDeptIds(Long[] deptIds)
{
this.deptIds = deptIds;
}
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
public SysRole(Long roleId)
{
this.permissions = permissions;
this.roleId = roleId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("roleId", getRoleId())
.append("roleName", getRoleName())
.append("roleKey", getRoleKey())
.append("roleSort", getRoleSort())
.append("dataScope", getDataScope())
.append("menuCheckStrictly", isMenuCheckStrictly())
.append("deptCheckStrictly", isDeptCheckStrictly())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
public SysRole() {
}
}

@ -8,6 +8,7 @@ import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -22,7 +23,8 @@ import java.util.List;
*
* @author ruoyi
*/
public class SysUser extends BaseEntity
@Data
public class SysUser
{
private static final long serialVersionUID = 1L;
@ -34,6 +36,9 @@ public class SysUser extends BaseEntity
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
/** 员工所属租户id */
private String tenantId;
/** 用户账号 */
@Excel(name = "登录名称")
private String userName;
@ -50,8 +55,8 @@ public class SysUser extends BaseEntity
@Excel(name = "手机号码")
private String phonenumber;
/** 用户性别 */
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
/** 用户性别 0未知 1女 2男*/
private String sex;
/** 用户头像 */
@ -61,7 +66,7 @@ public class SysUser extends BaseEntity
private String password;
/** 帐号状态0正常 1停用 */
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
@Excel(name = "帐号状态", readConverterExp = "0正常 1停用")
private String status;
/** 删除标志0代表存在 2代表删除 */
@ -76,135 +81,29 @@ public class SysUser extends BaseEntity
private Date loginDate;
/** 部门对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
@TableField(exist = false)
private SysDept dept;
/** 角色对象 */
@TableField(exist = false)
private List<SysRole> roles;
/** 角色组 */
@TableField(exist = false)
private Long[] roleIds;
/** 岗位组 */
@TableField(exist = false)
private Long[] postIds;
/** 角色ID */
@TableField(exist = false)
private Long roleId;
/** 员工所属门店id */
private String venId;
/** 员工所属商户id */
private String merchantId;
private String context;
private Boolean releases;//教练风采是否显示
//教练风采简短介绍
private String intro;
@ApiModelProperty("设备id")
private String registerId;
@ApiModelProperty("访问/浏览门店id")
private String visitStore;
@TableField(exist = false)
private Boolean responsible;
public String getVisitStore() {
return visitStore;
}
public void setVisitStore(String visitStore) {
this.visitStore = visitStore;
}
public String getRegisterId() {
return registerId;
}
public void setRegisterId(String registerId) {
this.registerId = registerId;
}
public Boolean getResponsible() {
return responsible;
}
public void setResponsible(Boolean responsible) {
this.responsible = responsible;
}
public String getIntro() {
return intro;
}
public void setIntro(String intro) {
this.intro = intro;
}
//教练风采相册
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Boolean getReleases() {
return releases;
}
public void setReleases(Boolean releases) {
this.releases = releases;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
public void setVenId(String venId) {
this.venId = venId;
}
public String getVenId() {
return venId;
}
public SysUser()
{
}
public String getMerchantId() {
return merchantId;
}
public void setMerchantId(String merchantId) {
this.merchantId = merchantId;
}
public SysUser(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public boolean isAdmin()
{
@ -216,206 +115,11 @@ public class SysUser extends BaseEntity
return userId != null && 1L == userId;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName()
{
return nickName;
}
public void setNickName(String nickName)
{
this.nickName = nickName;
}
@Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
public String getPhonenumber()
{
return phonenumber;
}
public void setPhonenumber(String phonenumber)
{
this.phonenumber = phonenumber;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getAvatar()
{
return avatar;
}
public void setAvatar(String avatar)
{
this.avatar = avatar;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getLoginIp()
{
return loginIp;
}
public void setLoginIp(String loginIp)
{
this.loginIp = loginIp;
}
public Date getLoginDate()
{
return loginDate;
}
public void setLoginDate(Date loginDate)
{
this.loginDate = loginDate;
}
public SysDept getDept()
{
return dept;
}
public void setDept(SysDept dept)
{
this.dept = dept;
}
public List<SysRole> getRoles()
{
return roles;
}
public void setRoles(List<SysRole> roles)
{
this.roles = roles;
}
public Long[] getRoleIds()
{
return roleIds;
}
public void setRoleIds(Long[] roleIds)
{
this.roleIds = roleIds;
}
public Long[] getPostIds()
{
return postIds;
}
public void setPostIds(Long[] postIds)
{
this.postIds = postIds;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
public SysUser(Long userId)
{
this.roleId = roleId;
this.userId = userId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getUserName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.toString();
public SysUser() {
}
}

@ -1,14 +1,12 @@
package com.ruoyi.common.core.domain.model;
import java.util.Collection;
import java.util.Set;
import com.ruoyi.common.core.domain.entity.AppUser;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.alibaba.fastjson2.annotation.JSONField;
import com.ruoyi.common.core.domain.entity.SysUser;
/**
*
@ -21,6 +19,11 @@ public class AppLoginUser implements UserDetails
private static final long serialVersionUID = 1L;
private Long appUserId;
private Long[] roles;
private Long manageAccountId;
private Long studentId;
private String userName;
private String token;
private Long loginTime;
private Long expireTime;
@ -29,22 +32,39 @@ public class AppLoginUser implements UserDetails
*/
private AppUser appUser;
public AppLoginUser(Long appUserId, String token, Long loginTime, Long expireTime, AppUser appUser) {
public AppLoginUser(Long appUserId, Long[] roleId, Long studentId, String userName, Long manageAccountId, String token, Long loginTime, Long expireTime, AppUser appUser) {
this.appUserId = appUserId;
this.roles = roleId;
this.studentId = studentId;
this.userName = userName;
this.manageAccountId = manageAccountId;
this.token = token;
this.loginTime = loginTime;
this.expireTime = expireTime;
this.appUser = appUser;
}
public AppLoginUser() {
}
public AppLoginUser(Long appUserId,AppUser appUser) {
public AppLoginUser(Long appUserId,String userName,Long manageAccountId,Long[] roles,Long studentId,AppUser appUser) {
this.appUserId = appUserId;
this.userName = userName;
this.manageAccountId = manageAccountId;
this.roles =roles;
this.studentId = studentId;
this.appUser = appUser;
}
public Long getAppUserId() {
return appUserId;
}
public void setAppUserId(Long appUserId) {
this.appUserId = appUserId;
}
@JSONField(serialize = false)
@Override
public String getPassword()

@ -34,6 +34,7 @@ public class AppUserLoginBody
*
*/
private String password;
private String passwordSecond;
/**
*

@ -0,0 +1,37 @@
package com.ruoyi.common.db;
import org.springframework.stereotype.Component;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@Component//尽量加上这个
@WebListener//声明为监听器 implements ServletContextListener
public class SshContextListener implements ServletContextListener{
private SshTunnelConfig sshConnectionConfig;
public SshContextListener() {
super();
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Context initialized ... !");
try {
sshConnectionConfig = new SshTunnelConfig();
sshConnectionConfig.createSshTunnel();
} catch (Throwable e) {
e.printStackTrace(); // 连接失败
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Context destroyed ... !");
sshConnectionConfig.closeSshTunnel();//断开ssh连接
}
}

@ -0,0 +1,55 @@
package com.ruoyi.common.db;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
//@Component
public class SshTunnelConfig {
private Session session;
//@Value("${ssh.host}")
private String sshHost="62.234.183.14";
// @Value("${ssh.port}")
private int sshPort=22;
// @Value("${ssh.user}")
private String sshUser="root";
// @Value("${ssh.identity}")
private String sshIdentity="E:\\runpeng\\runpeng20250915.pem";
// @Value("${ssh.remote.db.host}")
private String remoteDbHost="127.0.0.1";
// @Value("${ssh.local.port}")
private int localPort=32768;
// @Value("${ssh.remote.db.port}")
private int remoteDbPort=19116;
public void createSshTunnel() throws Exception {
JSch jsch = new JSch();
jsch.addIdentity(sshIdentity);
session = jsch.getSession(sshUser, sshHost, sshPort);
// session.setPassword(sshPassword);
// 避免检查已知主机,生产环境应考虑更安全的方式
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
// 设置本地端口转发
session.setPortForwardingL(localPort, remoteDbHost, remoteDbPort);
System.out.println("SSH隧道已建立本地端口" + localPort);
}
// @PreDestroy
public void closeSshTunnel() {
if (session != null && session.isConnected()) {
session.disconnect();
System.out.println("SSH隧道已关闭");
}
}
}

@ -24,6 +24,8 @@ public enum MessageType {
FILE(2, "文件消息"),
AUDIO(3, "语音消息"),
VIDEO(4, "视频消息"),
ORDER(5, "订单消息"),
PRODUCT(6, "商品消息"),
RECALL(10, "撤回"),
READED(11, "已读"),
RECEIPT(12, "消息已读回执"),

@ -17,17 +17,21 @@ public class RedisMQConfig {
@Bean
public RedisMQTemplate redisMQTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisMQTemplate redisMQTemplate = new RedisMQTemplate();
redisMQTemplate.setConnectionFactory(redisConnectionFactory);
try{
redisMQTemplate.setConnectionFactory(redisConnectionFactory);
// 设置值value的序列化采用FastJsonRedisSerializer
redisMQTemplate.setValueSerializer(fastJsonRedisSerializer());
redisMQTemplate.setHashValueSerializer(fastJsonRedisSerializer());
// 设置值value的序列化采用FastJsonRedisSerializer
redisMQTemplate.setValueSerializer(fastJsonRedisSerializer());
redisMQTemplate.setHashValueSerializer(fastJsonRedisSerializer());
// 设置键key的序列化采用StringRedisSerializer。
redisMQTemplate.setKeySerializer(new StringRedisSerializer());
redisMQTemplate.setHashKeySerializer(new StringRedisSerializer());
// 设置键key的序列化采用StringRedisSerializer。
redisMQTemplate.setKeySerializer(new StringRedisSerializer());
redisMQTemplate.setHashKeySerializer(new StringRedisSerializer());
redisMQTemplate.afterPropertiesSet();
redisMQTemplate.afterPropertiesSet();
}catch (Exception e){
System.out.println(e);
}
return redisMQTemplate;
}

@ -0,0 +1,53 @@
package com.ruoyi.common.utils;
import cn.hutool.core.io.IoUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.extra.qrcode.QrCodeException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Hutool + ZXingJava8 + SpringBoot
* code
*/
public class CodeUtil {
// 二维码默认配置宽度300px高度300px边距1编码UTF-8
private static final QrConfig DEFAULT_QR_CONFIG = new QrConfig(300, 300)
.setMargin(1)
.setCharset(Charset.forName("UTF-8"));
/**
* SpringBoot
* @param code
* @return PNG
* @throws QrCodeException
* @throws IOException
*/
public static byte[] generateQrCodeBytes(String code) throws QrCodeException, IOException {
if (code == null || code.trim().isEmpty()) {
throw new IllegalArgumentException("二维码内容code不能为空");
}
// 字节输出流,用于存储二维码图片字节
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
// Hutool核心方法生成二维码并写入字节流
QrCodeUtil.generate(
code, // 二维码内容
DEFAULT_QR_CONFIG, // 配置(宽高、边距、编码)
"PNG", // 图片格式PNG/JPG
outputStream // 输出流
);
return outputStream.toByteArray();
} finally {
// 关闭流避免资源泄漏Java8 try-finally 规范)
IoUtil.close(outputStream);
}
}
}

@ -6,7 +6,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
/**
@ -18,11 +17,11 @@ public class SecurityUtils {
/**
*
*/
public static String getMerchanId() {
public static String getTenantId() {
try {
return getLoginUser().getUser().getMerchantId();
return getLoginUser().getUser().getTenantId();
} catch (Exception e) {
throw new ServiceException("获取户id失败", HttpStatus.UNAUTHORIZED);
throw new ServiceException("获取户id失败", HttpStatus.UNAUTHORIZED);
}
}

@ -0,0 +1,227 @@
package com.ruoyi.common.utils;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.Locale;
/**
*
* /// & yyyy-MM-dd HH:mm:ss
*/
public class TimeCycleUtil {
// 时间格式化器(全局复用,线程安全)
private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 定义周的起始(中国标准:周一为一周第一天)
private static final WeekFields WEEK_FIELDS = WeekFields.of(Locale.CHINA);
/**
*
*/
public enum CycleType {
DAILY("每天"),
WEEKLY("每周"),
HALF_MONTH("半月"),
MONTHLY("每月");
private final String desc;
CycleType(String desc) {
this.desc = desc;
}
// 根据输入字符串匹配枚举(忽略大小写)
public static CycleType match(String input) {
if (input == null || input.trim().isEmpty()) {
throw new IllegalArgumentException("周期类型不能为空");
}
String trimInput = input.trim();
for (CycleType type : CycleType.values()) {
if (type.desc.equals(trimInput) || type.name().equalsIgnoreCase(trimInput)) {
return type;
}
}
throw new IllegalArgumentException("不支持的周期类型:" + input + ",仅支持:每天、每周、半月、每月");
}
}
/**
*
*/
public static class TimeRange {
private String startTime; // 开始时间yyyy-MM-dd HH:mm:ss
private String endTime; // 结束时间yyyy-MM-dd HH:mm:ss
public TimeRange(String startTime, String endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
// getter & setter
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
@Override
public String toString() {
return "TimeRange{" +
"开始时间='" + startTime + '\'' +
", 结束时间='" + endTime + '\'' +
'}';
}
}
/**
*
* @param cycle ///
* @return startTime + endTime
*/
public static TimeRange getCycleTimeRange(String cycle) {
CycleType cycleType = CycleType.match(cycle);
LocalDate today = LocalDate.now(); // 当前日期(系统默认时区)
LocalDateTime startTime;
LocalDateTime endTime;
switch (cycleType) {
case DAILY:
// 每天:当前日期 00:00:00 到 23:59:59
startTime = today.atStartOfDay();
endTime = today.atTime(23, 59, 59);
break;
case WEEKLY:
// 每周向前推1周 → 前一周的周一00:00:00 到 前一周的周日23:59:59
// 步骤1当前日期往前推7天得到前一周的同天日期
LocalDate lastWeekSameDay = today.minusWeeks(1);
// 步骤2找到该日期所在周的周一中国周周一为第一天
LocalDate lastWeekMonday = lastWeekSameDay.with(TemporalAdjusters.previousOrSame(WEEK_FIELDS.getFirstDayOfWeek()));
// 步骤3前一周的周日 = 周一 + 6天
LocalDate lastWeekSunday = lastWeekMonday.plusDays(6);
startTime = lastWeekMonday.atStartOfDay();
endTime = lastWeekSunday.atTime(23, 59, 59);
break;
case HALF_MONTH:
// 半月向前推1个半月周期 → 规则:
// 1. 当前日期≤15号上半月→ 前一个半月是「上个月的16号 ~ 上个月最后一天」
// 2. 当前日期>15号下半月→ 前一个半月是「本月的1号 ~ 本月15号」
int currentDay = today.getDayOfMonth();
if (currentDay <= 15) {
// 场景1当前是上半月如2026-02-10→ 前半月=2026-01-16 ~ 2026-01-31
LocalDate lastMonth = today.minusMonths(1);
startTime = lastMonth.withDayOfMonth(16).atStartOfDay();
LocalDate lastMonthLastDay = lastMonth.with(TemporalAdjusters.lastDayOfMonth());
endTime = lastMonthLastDay.atTime(23, 59, 59);
} else {
// 场景2当前是下半月如2026-02-18→ 前半月=2026-02-01 ~ 2026-02-15
startTime = today.withDayOfMonth(1).atStartOfDay();
endTime = today.withDayOfMonth(15).atTime(23, 59, 59);
}
break;
case MONTHLY:
// 每月向前推1个月 → 上个月的第一天00:00:00 到 上个月最后一天23:59:59
LocalDate lastMonth = today.minusMonths(1);
LocalDate lastMonthFirstDay = lastMonth.with(TemporalAdjusters.firstDayOfMonth());
LocalDate lastMonthLastDay = lastMonth.with(TemporalAdjusters.lastDayOfMonth());
startTime = lastMonthFirstDay.atStartOfDay();
endTime = lastMonthLastDay.atTime(23, 59, 59);
break;
default:
throw new IllegalArgumentException("未实现的周期类型:" + cycleType);
}
// 格式化时间为指定格式
return new TimeRange(
startTime.format(DATETIME_FORMATTER),
endTime.format(DATETIME_FORMATTER)
);
}
/**
*
* @param cycle
* @param zoneId ZoneId.of("Asia/Shanghai")
* @return
*/
public static TimeRange getCycleTimeRange(String cycle, ZoneId zoneId) {
LocalDate today = LocalDate.now(zoneId);
LocalDateTime startTime;
LocalDateTime endTime;
CycleType cycleType = CycleType.match(cycle);
switch (cycleType) {
case DAILY:
startTime = today.atStartOfDay();
endTime = today.atTime(23, 59, 59);
break;
case WEEKLY:
LocalDate monday = today.with(TemporalAdjusters.previousOrSame(WEEK_FIELDS.getFirstDayOfWeek()));
LocalDate sunday = monday.plusDays(6);
startTime = monday.atStartOfDay();
endTime = sunday.atTime(23, 59, 59);
break;
case HALF_MONTH:
int dayOfMonth = today.getDayOfMonth();
if (dayOfMonth <= 15) {
startTime = today.withDayOfMonth(1).atStartOfDay();
endTime = today.withDayOfMonth(15).atTime(23, 59, 59);
} else {
startTime = today.withDayOfMonth(16).atStartOfDay();
LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
endTime = lastDayOfMonth.atTime(23, 59, 59);
}
break;
case MONTHLY:
LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
startTime = firstDayOfMonth.atStartOfDay();
endTime = lastDayOfMonth.atTime(23, 59, 59);
break;
default:
throw new IllegalArgumentException("未实现的周期类型:" + cycleType);
}
return new TimeRange(
startTime.format(DATETIME_FORMATTER),
endTime.format(DATETIME_FORMATTER)
);
}
// 测试示例
// public static void main(String[] args) {
// // 测试1每天当前日期2026-02-10
// TimeRange dailyRange = getCycleTimeRange("每天");
// System.out.println("每天:" + dailyRange); // 输出:开始时间='2026-02-10 00:00:00', 结束时间='2026-02-10 23:59:59'
//
// // 测试2每周假设今天是2026-02-10周二 → 本周一2026-02-09 到 周日2026-02-15
// TimeRange weeklyRange = getCycleTimeRange("每周");
// System.out.println("每周:" + weeklyRange);
//
// // 测试3半月2026-02-10 属于上半月 → 2026-02-01 到 2026-02-15
// TimeRange halfMonthRange = getCycleTimeRange("半月");
// System.out.println("半月:" + halfMonthRange);
//
// // 测试4每月2026-02月 → 2026-02-01 到 2026-02-28
// TimeRange monthlyRange = getCycleTimeRange("每月");
// System.out.println("每月:" + monthlyRange);
//
// // 测试5指定时区上海时区
// TimeRange shanghaiRange = getCycleTimeRange("每天", ZoneId.of("Asia/Shanghai"));
// System.out.println("每天(上海时区):" + shanghaiRange);
// }
}

@ -4,6 +4,7 @@
<facet type="web" name="Web">
<configuration>
<webroots />
<sourceRoots />
</configuration>
</facet>
<facet type="Spring" name="Spring">
@ -14,10 +15,10 @@
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
@ -120,7 +121,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.14" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.20" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.1" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.22" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:core:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:javase:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.82" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.github.jai-imageio:jai-imageio-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" name="Maven: cn.jpush.api:jiguang-common:1.1.7" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.60" level="project" />
@ -212,5 +217,6 @@
<orderEntry type="library" name="Maven: junit:junit:4.13.2" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:2.2" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
<orderEntry type="library" name="Maven: com.jcraft:jsch:0.1.55" level="project" />
</component>
</module>

@ -1,17 +1,26 @@
package com.ruoyi.framework.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
import com.ruoyi.framework.config.converter.CustomMappingJackson2HttpMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.math.BigInteger;
import java.util.List;
/**
*
*
@ -20,6 +29,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
@Autowired
private ObjectMapper objectMapper;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
@ -57,4 +68,25 @@ public class ResourcesConfig implements WebMvcConfigurer
// 返回新的CorsFilter
return new CorsFilter(source);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(getMappingJackson2HttpMessageConverter());
}
/**
* jsLongBigIntegerstring
*
* @return
*/
public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
CustomMappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new CustomMappingJackson2HttpMessageConverter();
SimpleModule simpleModule = new SimpleModule();
// 序列换成json时,将所有的long变成string 因为js中得数字类型不能包含所有的java long值
simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
return jackson2HttpMessageConverter;
}
}

@ -138,10 +138,18 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage","/getStoreList", "/api/login", "/api/register").anonymous()
.antMatchers("/login",
"/register",
"/captchaImage",
"/getStoreList",
"/api/login",
"/api/register" ).anonymous()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
.antMatchers("/api/appreciate/**","/api/context/**","/api/healthy/**","/api/index/**","/api/context/searchListForCalendar",
"/api/inherit/**", "/api/moments/**", "/api/sense/**", "/api/store/**", "/api/product/**","/api/questionnaire/list"
,"/api/questionnaire/list","/api/questionnaire/getOne").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and()

@ -0,0 +1,61 @@
package com.ruoyi.framework.config.converter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Type;
/**
* jsonweb api(/web/controller)
*
* @author zhangby
*
*/
public class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
private final static Logger logger = LoggerFactory.getLogger(CustomMappingJackson2HttpMessageConverter.class);
/**
* Java
*/
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
// 不需要反序列化
return false;
}
/**
* Java
*/
@Override
public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
// 不需要反序列化
return false;
}
/**
* Java .
* web api(/web/xxxx)
*/
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
if (super.canWrite(clazz, mediaType)) {
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (null != ra) { // web请求
HttpServletRequest request = ra.getRequest();
String uri = request.getRequestURI();
/*if (uri.startsWith("/api/")) {
return true;
}*/
return true;
}
}
return false;
}
}

@ -104,11 +104,12 @@ public class AppLoginService
boolean update=false;
UpdateWrapper wrapper=new UpdateWrapper<AppUser>().eq("app_user_id",loginUser.getAppUserId());
if (!loginUser.getAppUser().getRegisterId().equals(registerId)){
//设备id
if (StrUtil.isNotEmpty(loginUser.getAppUser().getRegisterId())&&!loginUser.getAppUser().getRegisterId().equals(registerId)){
wrapper.set("register_id",registerId);
update=true;
}
//小程序登录
if (StrUtil.isNotEmpty(miniAppCode) && StrUtil.isEmpty(loginUser.getAppUser().getOpenid())){
HashMap<String, Object> map=getOpenId(miniAppCode);
@ -121,7 +122,9 @@ public class AppLoginService
}
//将登录信息存入到数据库
recordLoginInfo(loginUser.getAppUserId());
wrapper.set("login_ip",IpUtils.getIpAddr(ServletUtils.getRequest()));
wrapper.set("login_date",DateUtils.getNowDate());
appUserService.update(wrapper);
// 生成token
return tokenService.createAppToken(loginUser);
@ -150,19 +153,7 @@ public class AppLoginService
}
/**
*
*
* @param userId ID
*/
public void recordLoginInfo(Long userId)
{
AppUser appUser = new AppUser();
appUser.setId(userId);
appUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
appUser.setLoginDate(DateUtils.getNowDate());
appUserService.updateById(appUser);
}
//获取openid
public HashMap<String, Object> getOpenId(String code) {

@ -1,27 +1,27 @@
package com.ruoyi.framework.web.service;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.basic.service.impl.YjAppUserServiceImpl;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AppLoginUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.course.service.IScStudentService;
import com.ruoyi.system.service.SysTeacherService;
import com.ruoyi.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
*
@ -37,6 +37,13 @@ public class AppUserDetailsServiceImpl implements UserDetailsService
@Autowired
private YjAppUserServiceImpl userService;
@Autowired
private ISysUserService sysUserService;
@Autowired
private SysPasswordService passwordService;
@Autowired
private IScStudentService studentService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
@ -51,16 +58,37 @@ public class AppUserDetailsServiceImpl implements UserDetailsService
log.info("登录用户:{} 已被停用.", username);
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
}
List<Long> roles=new ArrayList<>();
roles.add(107l);
if (ObjectUtil.isNotEmpty(user.getManageAccountId())){
//todo 角色ID顾问103 教练104 店长105 普通用户107
SysUser sysUser= sysUserService.selectUserById(user.getManageAccountId());
if (ObjectUtil.isEmpty(sysUser)){
log.info("登录用户:{} 已被停用.", username);
throw new ServiceException("对不起,您的账号:" + username + " 所属租户异常,请联系管理员!");
}
List<SysRole> roles1=sysUser.getRoles();
for (SysRole sysRole : roles1) {
roles.add(sysRole.getRoleId());
}
}
Long studentId=studentService.getStudentByAppUserId(user.getId());
// Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
// String password = usernamePasswordAuthenticationToken.getCredentials().toString();
// if (!SecurityUtils.matchesPassword(password,user.getPassword())){
// throw new RuntimeException(Constants.LOGIN_INFO.WRONG);
// }
return createLoginUser(user);
SysUser user1=new SysUser();
user1.setPassword(user.getPassword());
passwordService.validate(user1);
return createLoginUser(user,roles.toArray(new Long[roles.size()]) ,studentId);
}
public UserDetails createLoginUser(AppUser user)
public UserDetails createLoginUser(AppUser user, Long[] roles,Long studentId)
{
return new AppLoginUser(user.getId(), user);
return new AppLoginUser(user.getId(),user.getUserName(), user.getManageAccountId(),roles,studentId, user);
}
}

@ -1,176 +0,0 @@
package com.ruoyi.framework.web.service;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AppLoginUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import javax.annotation.Resource;
/**
*
*
* @author ruoyi
*/
@Component
public class SysLoginService
{
@Autowired
private TokenService tokenService;
@Resource
private AuthenticationManager authenticationManager;
@Autowired
private RedisCache redisCache;
@Autowired
private ISysUserService userService;
@Autowired
private ISysConfigService configService;
/**
*
*
* @param username
* @param password
* @param code
* @param uuid
* @return
*/
public String login(String username, String password, String code, String uuid)
{
boolean captchaEnabled = configService.selectCaptchaEnabled();
// 验证码开关
if (captchaEnabled)
{
validateCaptcha(username, code, uuid);
}
// 用户验证
Authentication authentication = null;
try
{
//UsernamePasswordAuthenticationToken是Authenticatiion的实现类
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
//这里设置成上下文的意图是在身份验证过程中,
//其他组件或方法可以获取到该对象,以便进行相关的操作,
//比如记录登录日志、获取用户信息等。
AuthenticationContextHolder.setContext(authenticationToken);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(authenticationToken);
}
catch (Exception e)
{
if (e instanceof BadCredentialsException)
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
}
else
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
throw new ServiceException(e.getMessage());
}
}
finally
{
//最后要在对应操作完成之后清理Context
AuthenticationContextHolder.clearContext();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
//这里就是拿到自定义封装的用户信息
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
if (StrUtil.isEmpty(loginUser.getUser().getMerchantId())){
throw new RuntimeException("未建商户无法登录");
}
//将登录信息存入到数据库
recordLoginInfo(loginUser.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}
/**
*
*
* @param username
* @param code
* @param uuid
* @return
*/
public void validateCaptcha(String username, String code, String uuid)
{
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null)
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
throw new CaptchaException();
}
}
/**
*
*
* @param userId ID
*/
public void recordLoginInfo(Long userId)
{
SysUser sysUser = new SysUser();
sysUser.setUserId(userId);
sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
sysUser.setLoginDate(DateUtils.getNowDate());
userService.updateUserProfile(sysUser);
}
/**
*
* @param uuid
* @param phone
* @param inputCode
*/
private void validateVerifyCode(String uuid, String phone, String inputCode){
String key = uuid + "_" + phone;
String redisCode = redisCache.getCacheObject(key);
if (redisCode == null){
throw new RuntimeException(Constants.VERIFY_CODE_INFO.EXPIRED);
}else if (!redisCode.equals(inputCode)){
throw new RuntimeException(Constants.VERIFY_CODE_INFO.WRONG);
}
//删除缓存
redisCache.deleteObject(key);
}
}

@ -1,116 +0,0 @@
package com.ruoyi.framework.web.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
/**
*
*
* @author ruoyi
*/
@Component
public class SysRegisterService
{
@Autowired
private ISysUserService userService;
@Autowired
private ISysConfigService configService;
@Autowired
private RedisCache redisCache;
/**
*
*/
public String register(RegisterBody registerBody)
{
String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword();
boolean captchaEnabled = configService.selectCaptchaEnabled();
// 验证码开关
if (captchaEnabled)
{
validateCaptcha(username, registerBody.getCode(), registerBody.getUuid());
}
if (StringUtils.isEmpty(username))
{
msg = "用户名不能为空";
}
else if (StringUtils.isEmpty(password))
{
msg = "用户密码不能为空";
}
else if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
msg = "账户长度必须在2到20个字符之间";
}
else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
msg = "密码长度必须在5到20个字符之间";
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(username)))
{
msg = "保存用户'" + username + "'失败,注册账号已存在";
}
else
{
SysUser sysUser = new SysUser();
sysUser.setUserName(username);
sysUser.setNickName(username);
sysUser.setPassword(SecurityUtils.encryptPassword(registerBody.getPassword()));
boolean regFlag = userService.registerUser(sysUser);
if (!regFlag)
{
msg = "注册失败,请联系系统管理人员";
}
else
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER,
MessageUtils.message("user.register.success")));
}
}
return msg;
}
/**
*
*
* @param username
* @param code
* @param uuid
* @return
*/
public void validateCaptcha(String username, String code, String uuid)
{
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null)
{
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha))
{
throw new CaptchaException();
}
}
}

@ -259,6 +259,7 @@ public class TokenService
refreshAppToken(loginUser);
Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_APPUSER_KEY, token);
claims.put(Constants.JWT_USERID,loginUser.getAppUserId());
return createToken(claims);
}

@ -99,7 +99,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.14" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.20" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.1" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.22" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:core:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:javase:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.82" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.github.jai-imageio:jai-imageio-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" name="Maven: cn.jpush.api:jiguang-common:1.1.7" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.60" level="project" />
@ -179,5 +183,6 @@
<orderEntry type="library" name="Maven: org.springframework:spring-websocket:5.3.20" level="project" />
<orderEntry type="library" name="Maven: com.auth0:java-jwt:3.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: com.jcraft:jsch:0.1.55" level="project" />
</component>
</module>

@ -156,14 +156,18 @@ public class IMSender {
}
// 批量拉取
List<Object> serverIds = redisMQTemplate.opsForValue().multiGet(sendMap.keySet());
// 格式:map<服务器id,list<接收方>>
Map<Integer, List<IMUserInfo>> serverMap = new HashMap<>();
List<IMUserInfo> offLineUsers = new LinkedList<>();
int idx = 0;
for (Map.Entry<String,IMUserInfo> entry : sendMap.entrySet()) {
Integer serverId = (Integer)serverIds.get(idx++);
Long serverId = (Long) serverIds.get(idx++);
// 如果对方在线将数据存储至redis等待拉取推送
if (!Objects.isNull(serverId)) {
List<IMUserInfo> list = serverMap.computeIfAbsent(serverId, o -> new LinkedList<>());
List<IMUserInfo> list = serverMap.computeIfAbsent(Integer.parseInt(serverId.toString()), o -> new LinkedList<>());
list.add(entry.getValue());
} else {
// 加入离线列表

@ -54,4 +54,4 @@
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>
</project>

@ -102,7 +102,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.14" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.20" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.1" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.22" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:core:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:javase:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.82" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.github.jai-imageio:jai-imageio-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" name="Maven: cn.jpush.api:jiguang-common:1.1.7" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.60" level="project" />
@ -153,5 +157,6 @@
<orderEntry type="library" name="Maven: com.auth0:java-jwt:3.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-all:4.1.42.Final" level="project" />
<orderEntry type="library" name="Maven: com.jcraft:jsch:0.1.55" level="project" />
</component>
</module>

@ -3,9 +3,12 @@ package com.ruoyi.imserver.netty;
import com.ruoyi.common.im.constant.IMRedisKey;
import com.ruoyi.common.im.mq.RedisMQTemplate;
import io.netty.channel.EventLoopGroup;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.SmartLifecycle;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
@ -37,18 +40,52 @@ public class IMServerGroup implements CommandLineRunner {
@Override
public void run(String... args) {
// 初始化SERVER_ID
try {
System.out.println("========== IMServerGroup 开始初始化 ==========");
// 1. 先验证Redis连接
if (!testRedisConnection()) {
// 不要直接退出,记录错误,让应用继续启动(如果需要)
System.err.println("严重Redis连接失败但应用将继续启动部分功能可能不可用");
// 根据业务决定如果Redis是必须的可以抛出异常
// throw new RuntimeException("Redis连接失败应用启动中止");
}
String key = IMRedisKey.IM_MAX_SERVER_ID;
serverId = redisMQTemplate.opsForValue().increment(key, 1);
// 启动服务
for (IMServer imServer : imServers) {
imServer.start();
}
System.out.println("========== IMServerGroup 初始化完成 ==========");
}catch (Exception e) {
// 捕获所有异常,打印详细信息,但可以选择不向上抛出,防止应用退出
System.err.println("IMServerGroup 初始化过程中发生严重错误:");
e.printStackTrace(); // 打印完整的堆栈跟踪,这能帮你定位到具体行号
// 重要决策:是否重新抛出异常?
// 如果希望应用继续运行比如Redis失败但想先看其他功能就注释掉下一行
// 如果希望应用停止,就保留下一行
// throw new RuntimeException("IMServerGroup启动失败", e);
}
}
private boolean testRedisConnection() {
try {
// 使用你之前编写的连接测试代码
// 例如String pong = redisTemplate.getConnectionFactory().getConnection().ping();
String pong = redisMQTemplate.getConnectionFactory().getConnection().ping();
System.out.println("Redis连接测试成功 "+pong);
return true;
} catch (Exception e) {
System.err.println("Redis连接测试失败: " + e.getClass().getName() + " - " + e.getMessage());
return false;
}
}
@PreDestroy
public void destroy() {
// 停止服务
log.info("消费线程停止12...");
for (IMServer imServer : imServers) {
imServer.stop();
}

@ -1,6 +1,9 @@
package com.ruoyi.imserver.netty.processor;
import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.AppLoginUser;
import com.ruoyi.common.im.constant.IMConstant;
import com.ruoyi.common.im.constant.IMRedisKey;
import com.ruoyi.common.im.enums.IMCmdType;

@ -6,8 +6,8 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://101.43.111.159:3306/yoga?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# url: jdbc:mysql://localhost:3306/yj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://127.0.0.1:32769/yoga?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# url: jdbc:mysql://127.0.0.1:3306/yj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: '!Runpeng888'
# password: 123456

@ -12,6 +12,15 @@ tcpsocket:
enable: false # 暂时不开启
port: 8879
logging:
level:
org:
springframework:
data:
redis: TRACE # 查看Redis操作细节
io.lettuce.core: DEBUG # 如果使用Lettuce关注WARN以上错误
com.ruoyi: DEBUG
# token配置
token:
# 令牌自定义标识

@ -27,6 +27,11 @@
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.46</version>
</dependency>
<!-- im-->
<dependency>
<groupId>com.ruoyi</groupId>

@ -101,7 +101,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.14" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.20" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.1" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.22" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:core:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:javase:3.5.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.82" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.github.jai-imageio:jai-imageio-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" name="Maven: cn.jpush.api:jiguang-common:1.1.7" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.60" level="project" />
@ -179,6 +183,7 @@
<orderEntry type="library" name="Maven: com.auth0:java-jwt:3.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.29" level="project" />
<orderEntry type="library" name="Maven: com.jcraft:jsch:0.1.46" level="project" />
<orderEntry type="module" module-name="ruoyi-im-client" />
<orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:4.8.1" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okio:okio:2.7.0" level="project" />

@ -0,0 +1,39 @@
package com.ruoyi.basic.domain;
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.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author xn
* @since 2022-09-28
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_app_index")
public class SysAppIndex implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private Long id;
private String name;
private String img;
private String color;
private String sort;
private String url;
}

@ -1,6 +1,7 @@
package com.ruoyi.basic.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
@ -74,7 +75,8 @@ public class YjAppreciate implements Serializable {
/**
* id
*/
private String visitStore;
@TableField("dept_id")
private String deptId;
}

@ -1,6 +1,7 @@
package com.ruoyi.basic.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
@ -74,7 +75,8 @@ public class YjHealthy implements Serializable {
/**
* id
*/
private String visitStore;
@TableField("dept_id")
private String deptId;
}

@ -75,7 +75,7 @@ public class YjInherit implements Serializable {
*
* id
*/
private String visitStore;
private String deptId;
}

@ -73,5 +73,5 @@ public class YjPracticeMoments implements Serializable {
/**
* id
*/
private String visitStore;
private String deptId;
}

@ -74,7 +74,7 @@ public class YjSense implements Serializable {
/**
* id
*/
private String visitStore;
private String deptId;
}

@ -3,12 +3,14 @@ package com.ruoyi.basic.domain;
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.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* <p>
@ -20,24 +22,19 @@ import java.util.Date;
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("yj_store")
public class YjStore implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* id
*/
private Long responsibleId;//负责人id
//有效期至,终身/长期用户不判断
private Date validUntil;
/**
*
* 0,1,2,3
*/
private Integer status;
@TableId(value = "dept_id", type = IdType.ASSIGN_UUID)
private Long id;
//总店id
@TableField(exist = false)
private Long parentId;
//租户id
@TableField(exist = false)
private String tenantId;
@ApiModelProperty("banner图")
private String banner;
@ -51,10 +48,11 @@ public class YjStore implements Serializable {
private String founder;
// 企业/门店简介(富文本)
private String profile;
//租户id
private String tenantId;
//总店id
private String parentId;
@TableField(exist = false)
private List<YjStore> childList;

@ -1,80 +0,0 @@
package com.ruoyi.basic.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author xn
* @since 2022-09-28
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class YjTenant implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* id
*/
private Long responsibleId;//负责人id
private String businessLicense;//营业执照编号/统一信用编码
private byte[] businessLicensePicture;//营业执照照片/扫描件
private String legalPerson;//法人姓名
private String legalPersonTel;//法人联系方式
private String legalPersonCard;//法人证件号码
private byte[] legalPersonCardPicturePositive;//法人证件照片/扫描件正面
private byte[] legalPersonCardPictureBack;//法人证件照片/扫描件背面
private String vip;//付费级别
private String vipPrice;//付费金额
private String vipPriceType;//付费方式,试用,年付,终身/长期
private String vipPayType;//支付方式,支付宝,微信,转账银行
private String bankCardId;//银行转账账号
private Date validUntil;//有效期至,终身/长期用户不判断
private Date reminderDate;//年付用户预付款提醒开始日期,提醒截止日期到宽限期结束
private Integer gracePeriod;//宽限期
/**
*
*/
private Integer status;//状态 0申请,1审核中,2审核通过,3停止运营
@TableField(exist = false)
private String legalPersonCardPicturePositive1;//法人证件照片/扫描件正面
@TableField(exist = false)
private String legalPersonCardPictureBack1;//法人证件照片/扫描件背面
@TableField(exist = false)
private String businessLicensePicture1;//营业执照照片/扫描件
}

@ -0,0 +1,22 @@
package com.ruoyi.basic.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
public class AnswerSubmitDTO {
@NotNull(message = "问卷ID不能为空")
private Long surveyId;
private String sessionId; // 可选,为空时自动生成
@NotNull(message = "答案列表不能为空")
private List<AnswerItem> answers;
@Data
public static class AnswerItem {
@NotNull
private Long questionId;
@NotNull
private Long optionId;
}
}

@ -0,0 +1,10 @@
package com.ruoyi.basic.domain.dto;
import lombok.Data;
@Data
public class ConstitutionScoreDTO {
private String constitutionAlias;
private String constitutionName;
private Integer totalScore;
}

@ -1,34 +0,0 @@
package com.ruoyi.basic.domain.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.ruoyi.basic.domain.YjStore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author xn
* @since 2022-09-28
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class StoreDto implements Serializable {
private static final long serialVersionUID=1L;
private String id;
@ApiModelProperty("企业名称")
private String storeName;
//总店id
private String parentId;
private List<StoreDto> childList;
}

@ -19,7 +19,7 @@ public class YjVenueDto {
private Long deptId;
/**
* id
* id
*/
private String storeId;

@ -0,0 +1,14 @@
package com.ruoyi.basic.domain.model;
import com.ruoyi.basic.domain.dto.ConstitutionScoreDTO;
import lombok.Data;
import java.util.List;
// 返回的结果视图
@Data
public class AnswerResultVO {
private String resultType; // pinghe, qixu, multiple 等
private String resultText; // 结果描述
private List<ConstitutionScoreDTO> constitutionScores; // 各体质得分
}

@ -0,0 +1,18 @@
package com.ruoyi.basic.domain.model;
import lombok.Data;
import java.util.List;
/**
*
*/
@Data
public class ConstitutionVO {
private Long constitutionId;
private String name; // 体质名称,如“平和体质”
private String alias; // 标识如“pinghe”
private String description; // 体质描述
private Integer sortOrder;
private List<QuestionVO> questions; // 该体质下的题目列表
}

@ -0,0 +1,14 @@
package com.ruoyi.basic.domain.model;
import lombok.Data;
/**
*
*/
@Data
public class OptionVO {
private Long optionId;
private String optionText; // 完全符合 / 偶尔有 / 完全不符合
private Integer score; // 2 / 1 / 0
private Integer sortOrder;
}

@ -0,0 +1,17 @@
package com.ruoyi.basic.domain.model;
import lombok.Data;
import java.util.List;
/**
*
*/
@Data
public class QuestionVO {
private Long questionId;
private Integer serialNumber; // 序号1-5
private String content; // 题目描述
private Integer fullScore; // 满分固定2
private List<OptionVO> options; // 选项列表
}

@ -0,0 +1,45 @@
package com.ruoyi.basic.domain.model;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* VO
*/
@Data
public class QuestionnaireVO implements Serializable {
private Long surveyId; // 问卷ID
private String title; // 问卷标题
private String description; // 问卷说明
private List<ConstitutionVO> constitutions; // 体质列表(含题目)
@Data
public static class ConstitutionVO implements Serializable{ // 必须是 static
private Long constitutionId;
private String name;
private String alias;
private String description;
private Integer sortOrder;
private List<QuestionVO> questions;
}
@Data
public static class QuestionVO implements Serializable{
private Long questionId;
private Integer serialNumber;
private String content;
private Integer fullScore;
private List<OptionVO> options;
}
@Data
public static class OptionVO implements Serializable{
private Long optionId;
private String optionText;
private Integer score;
private Integer sortOrder;
}
}

@ -0,0 +1,16 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
@TableName("question_answer_detail")
public class QuestionAnswerDetail {
@TableId(type = IdType.AUTO)
private Long id;
private Long sheetId;
private Long questionId;
private Long optionId;
@TableField(exist = false)
private Integer score;
}

@ -0,0 +1,20 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("question_answer_sheet")
public class QuestionAnswerSheet {
@TableId(type = IdType.AUTO)
private Long id;
private Long surveyId;
@TableField("app_user_id")
private Long userId;
private String sessionId;
private LocalDateTime submitTime;
private String ipAddress;
private String resultType;
private String resultText;
}

@ -0,0 +1,14 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
@TableName("question_constitution_score")
public class QuestionConstitutionScore {
@TableId(type = IdType.AUTO)
private Long id;
private Long sheetId;
private Long constitutionId;
private Integer totalScore;
}

@ -0,0 +1,16 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
@TableName("question_constitution_type")
public class QuestionConstitutionType {
@TableId(type = IdType.AUTO)
private Long id;
private Long surveyId;
private String name;
private String alias;
private String description;
private Integer sortOrder;
}

@ -0,0 +1,15 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
@TableName("question_option")
public class QuestionOption {
@TableId(type = IdType.AUTO)
private Long id;
private Long questionId;
private String optionText;
private Integer score;
private Integer sortOrder;
}

@ -0,0 +1,15 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
@TableName("question_question")
public class QuestionQuestion {
@TableId(type = IdType.AUTO)
private Long id;
private Long constitutionId;
private Integer serialNumber;
private String content;
private Integer fullScore;
}

@ -0,0 +1,24 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("question_rule")
public class QuestionRule {
@TableId(type = IdType.AUTO)
private Long id;
private Long surveyId;
private String ruleName;
private Long targetConstitutionId; // 目标体质ID
private Integer minScore; // 得分下限(包含)
private Integer maxScore; // 得分上限(包含)
private Integer requireOtherMaxScore;// 其他体质最高分上限
private Integer requireOtherMinScore;// 其他体质最低分下限(预留)
private Integer priority;//优先级(数字越小越先匹配)
private Integer status;//状态0-启用 1-禁用
private String resultText;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

@ -0,0 +1,17 @@
package com.ruoyi.basic.domain.question;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("question_survey")
public class QuestionSurvey {
@TableId(type = IdType.AUTO)
private Long id;
private String title;
private String description;
private Integer status; // 0-草稿 1-发布 2-关闭
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
}

@ -0,0 +1,13 @@
package com.ruoyi.basic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.basic.domain.question.QuestionAnswerDetail;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface QuestionAnswerDetailMapper extends BaseMapper<QuestionAnswerDetail> {
void insertBatch(@Param("list") List<QuestionAnswerDetail> list);
List<QuestionAnswerDetail> getBySheetId(@Param("sheetId") Long sheetId);
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save