diff --git a/pom.xml b/pom.xml index d6e0cee..5cc39e0 100644 --- a/pom.xml +++ b/pom.xml @@ -8,10 +8,6 @@ ruoyi 3.8.3 - ruoyi - http://www.ruoyi.vip - 若依管理系统 - 3.8.3 UTF-8 @@ -151,44 +147,40 @@ ${kaptcha.version} - + com.ruoyi - ruoyi-quartz + ruoyi-framework ${ruoyi.version} - + com.ruoyi - ruoyi-generator + ruoyi-system ${ruoyi.version} - + com.ruoyi - ruoyi-framework + ruoyi-common ${ruoyi.version} - com.ruoyi - ruoyi-system + ruoyi-app-domain ${ruoyi.version} - - com.ruoyi - ruoyi-common + ruoyi-im-client ${ruoyi.version} - com.ruoyi - ruoyi-app-domain + ruoyi-im-server ${ruoyi.version} @@ -199,9 +191,10 @@ ruoyi-admin ruoyi-framework ruoyi-system - ruoyi-quartz - ruoyi-generator ruoyi-common + ruoyi-im-client + ruoyi-im-server + pom diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index cd76956..e683ad3 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -18,19 +18,11 @@ - - org.springframework.boot - spring-boot-devtools - true - - - - - - - mysql - mysql-connector-java - + + + + + @@ -38,16 +30,7 @@ ruoyi-framework - - - com.ruoyi - ruoyi-quartz - - - - com.ruoyi - ruoyi-generator - + @@ -59,23 +42,13 @@ - - - com.github.wechatpay-apiv3 - wechatpay-apache-httpclient - 0.4.8 - - - junit - junit - 4.12 - - - com.squareup.okhttp3 - okhttp-android-support - 3.13.1 - + + + + + + @@ -98,16 +71,16 @@ - - org.apache.maven.plugins - maven-war-plugin - 3.1.0 + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 false ${project.artifactId} - - + + ${project.artifactId} - \ No newline at end of file + diff --git a/ruoyi-admin/ruoyi-admin.iml b/ruoyi-admin/ruoyi-admin.iml new file mode 100644 index 0000000..541cb8b --- /dev/null +++ b/ruoyi-admin/ruoyi-admin.iml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java index 32eb6f1..57a0406 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java @@ -3,12 +3,14 @@ package com.ruoyi; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; /** * 启动程序 - * + * * @author ruoyi */ + @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) public class RuoYiApplication { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/AppointmentAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/AppointmentAppController.java deleted file mode 100644 index ce8d18e..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/AppointmentAppController.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.ruoyi.web.controller.app_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.Appointment; -import com.ruoyi.course.domain.AppointmentVo; -import com.ruoyi.course.mapper.AppointmentMapper; -import com.ruoyi.course.service.AppointmentServiceImpl; -import io.swagger.annotations.Api; -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 javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - *

- * 课程 前端控制器 - *

- * - * @author xhj - * @since 2022-09-22 - */ -@Api(tags = "课程", description = "提供课程相关的API") -@RestController -@RequestMapping("/api/appointment") -public class AppointmentAppController extends BaseController { - - @Autowired - AppointmentServiceImpl appointmentService; - - @Autowired - AppointmentMapper mapper; - - -// @PostMapping("/getAppointmentList") - public RestResponse getAppointmentList(@RequestBody Map map) { -// List list = appointmentService.getList(map); -// return new RestResponse().setData(list); - return RestResponse.success().setData(appointmentService.findList(map)); - } - -// @PostMapping("/updateAppointment") - public RestResponse updateAppointment(@RequestBody Appointment appointment) { - String username = SecurityUtils.getUsername(); - appointment.setUpdateUser(username); -// LocalDateTime now= ; - appointment.setUpdateTime(DateUtil.parseLocalDateTime(DateUtil.now(),"yyyy-MM-dd HH:mm:ss")); - appointmentService.updateById(appointment); - return RestResponse.success(); - } - - /** - * 预约课程 - * @param appointment - * @return - */ -// @PostMapping("/yy") - public RestResponse yy(@RequestBody Appointment appointment) { - appointment.setCreateTime(DateUtil.parseLocalDateTime(DateUtil.now(),"yyyy-MM-dd HH:mm:ss")); - appointmentService.save(appointment); - return RestResponse.success(); - } - - //我的预约 - //预约成功 - //预约失败 - @PostMapping("/appointments") - public RestResponse appointments(HttpServletRequest request) { - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - Map map=new HashMap(); - map.put("consumerId",userId); - List list=appointmentService.findList(map); - List list1=new ArrayList<>();//预约中 - List list2=new ArrayList<>();//预约成功 - List list3=new ArrayList<>();//预约失败 - List list4=new ArrayList<>();//取消预约 - for (AppointmentVo a:list){ - if (a.getFlag()==0){ - list1.add(a); - continue; - } - if (a.getFlag()==1){ - list2.add(a); - continue; - } - if (a.getFlag()==2){ - list3.add(a); - continue; - } - if (a.getFlag()==3){ - list4.add(a); - } - } - map.clear(); - map.put("list1",list1); - map.put("list2",list2); - map.put("list3",list3); - map.put("list4",list4); - return RestResponse.success().setData(map); - } - - - //取消预约 - @PostMapping("/cancel") - public RestResponse cancel(@RequestBody Appointment appointment) { - appointment.setUpdateTime(DateUtil.parseLocalDateTime(DateUtil.now(),"yyyy-MM-dd HH:mm:ss")); - int i= mapper.cancel(appointment); - return RestResponse.success().setMessage(i==0?"修改失败,当前状态无法取消预约!":"成功!"); - } - - - - - -} - diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/ConsumerCourseController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/ConsumerCourseController.java deleted file mode 100644 index 5a3a806..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/ConsumerCourseController.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ruoyi.web.controller.app_course; - - -import com.ruoyi.RestResponse; -import com.ruoyi.course.domain.CourseLog; -import com.ruoyi.course.mapper.ConsumerCourseMapper; -import com.ruoyi.course.service.ConsumerCourseServiceImpl; -import com.ruoyi.course.service.CourseServiceImpl; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - *

- * 前端控制器 - *

- * - * @author xn - * @since 2022-12-29 - */ -@RestController -@RequestMapping("/api/consumerCourse") -public class ConsumerCourseController { - - @Resource - private CourseServiceImpl courseService; - @Resource - private ConsumerCourseServiceImpl consumerCourseService; - @Resource - private ConsumerCourseMapper mapper; - - //我的课程 (视频) - @PostMapping("/myCourse") - public RestResponse myCourse(HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - List list= mapper.myCourse(userId); - List list1=new ArrayList<>(); - List list2=new ArrayList<>(); - for (CourseLog l:list){ - if (l.getCourseType().equals("2")){ - list1.add(l); - } - if (l.getCourseType().equals("3")){ - list2.add(l); - } - } - Map map=new HashMap(); - map.put("list1",list1);//大咖课 - map.put("list2",list2);//教练培训 - return new RestResponse().setSuccess(true).setData(map); - } - - -} - diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/CourseAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/CourseAppController.java deleted file mode 100644 index e91a28c..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/CourseAppController.java +++ /dev/null @@ -1,406 +0,0 @@ -package com.ruoyi.web.controller.app_course; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.ObjectUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.entity.SysDictData; -import com.ruoyi.common.utils.JpushClientUtil; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.course.domain.*; -import com.ruoyi.course.service.ConsumerCourseServiceImpl; -import com.ruoyi.course.service.CourseLogServiceImpl; -import com.ruoyi.course.service.CourseServiceImpl; -import com.ruoyi.course.service.HistoryMessageServiceImpl; -import com.ruoyi.search.domain.MemberUser; -import com.ruoyi.search.service.MemberUserServicelmpl; -import com.ruoyi.shop.domain.ShopOrder; -import com.ruoyi.shop.domain.ShopOrderItem; -import com.ruoyi.shop.service.impl.ShopOrderItemServiceImpl; -import com.ruoyi.shop.service.impl.ShopOrderServiceImpl; -import com.ruoyi.system.domain.SysUserRole; -import com.ruoyi.system.mapper.SysUserRoleMapper; -import com.ruoyi.system.service.ISysDictDataService; -import com.ruoyi.web.util.PayUtil; -import com.ruoyi.web.util.SnowFlake; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.*; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - *

- * 课程 前端控制器 - *

- * - * @author xhj - * @since 2022-09-22 - */ -@RestController -@RequestMapping("/api/course") -public class CourseAppController extends BaseController { - - @Autowired - CourseServiceImpl courseService; - @Autowired - HistoryMessageServiceImpl historyMessageService; - @Autowired - CourseLogServiceImpl courseLogService; - @Autowired - ISysDictDataService iSysDictDataService; - @Autowired - MemberUserServicelmpl memberUserService; - @Resource - private ShopOrderServiceImpl orderService; - @Resource - private ShopOrderItemServiceImpl itemService; - @Resource - private ConsumerCourseServiceImpl consumerCourseService; - @Resource - private SysUserRoleMapper sysUserRoleMapper; - - - /** - * - * courseName 名字 - * courseType 课程分类 //1 传入1 - * memberType[] 会籍数组 - * @param map - * @return 显示得内容 是 courseType1 字典 - */ - @PostMapping("/list") - public RestResponse list(@RequestBody Map map) { - map.put("releases",1); - List list = courseService.getList(map); - return new RestResponse().setData(list); - } - - - /** - * 字典? - * @param map - * @return - */ - @PostMapping("/listByCourseType1") - public RestResponse listByCourseType1(@RequestBody Map map) { - SysDictData sysDictData= new SysDictData(); - sysDictData.setDictType("yj_source_pt_type"); - sysDictData.setMerchantId(SecurityUtils.getMerchanId()); - return RestResponse.success().setData(iSysDictDataService.selectDictDataList(sysDictData)); - - } - - - /** - * 预约课程 - * @param appointment - * @return - */ -// @PostMapping("/yyCourse") - public RestResponse yyCourse(@RequestBody Appointment appointment) { - courseService.yyCourse(appointment); - return RestResponse.success(); - } - - - /** - * courseId 课程id 会员课的id - * @param map - * @return userName 教练姓名 course_names课程名称(进修课提升) memberType 类型(小班课) course_picture 图片 - * memberType 必须传1 courseType1 = 会员/1对1 具体根据courseType 查询 - */ - @PostMapping("/listLog") - public RestResponse listLog(@RequestBody Map map) { - //todo - List list = courseService.getListLog(map); - return new RestResponse().setData(list); - } - - /** - * 显示课程表 - * - * @param map date 当天的日期 courseId 课程分类id - * @return - * 2022.11.30改(xn) - */ - @PostMapping("/listLogDate") - public RestResponse listLogDate(@RequestBody Map map) { -// Map map1 = courseService.listLogDate(map); - map.put("userId",null); - Map map1 = courseService.listLogDate1(map); - return new RestResponse().setData(map1); - } - - @PostMapping("/listLogDateForMember") - public RestResponse listLogDateForMember(@RequestBody Map map,HttpServletRequest request) { - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - // Map map1 = courseService.listLogDate(map); - map.put("userId",userId); - Map map1 = courseService.listLogDate1(map); - return new RestResponse().setData(map1); - } - - - @PostMapping("/getTeacherList") - public RestResponse getTeacherList(@RequestBody Map map) { -// sysUserService.selectUserList() - - List sysUserRoles = sysUserRoleMapper.selectALLByRole(map.get("merchantId").toString()); - if(sysUserRoles.size()==0){ - return RestResponse.failure("没有教练信息"); - } - return RestResponse.success().setData(sysUserRoles); - } - - - /** - * - * app服务-大咖课/教练培训 - * @param course - * @return - * @author xn - */ -// @PostMapping("/listForService") - public RestResponse listForService(@RequestBody Course course) { - course.setReleases(1); - List list = courseService.listForApp(course); - return new RestResponse().success().setData(list); - } - - /** - * - * app服务-特色课程详情 - * @param course - * @return - * @author xn - */ -// @PostMapping("/getOne") - public RestResponse getOne(@RequestBody Course course) { - Course c = courseService.listForApp(course).get(0); - return new RestResponse().success().setData(c); - } - - - /** - * 课程详情(未登录) - * @param courseLogVo - * @return - */ - @PostMapping("/getDetail") - public RestResponse getDetail(@RequestBody CourseLogVo courseLogVo) { - CourseLog courseLog =courseLogService.getById(courseLogVo.getId()); - Course course =courseService.getById(courseLog.getCourseId()); - courseLog.generateMemberNum(); - Map map=new HashMap(); - map.put("course",course); - courseLog.setVideoLong("1"); - map.put("courseLog",courseLog); - return new RestResponse().success().setData(map); - } - - /** - * 登录后,查看付费视频课 - * @param courseLogVo - * @param request - * @return - */ - @PostMapping("/watchLongVideo") - public RestResponse watchLongVideo(@RequestBody CourseLogVo courseLogVo, HttpServletRequest request) { - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - CourseLog courseLog =courseLogService.getById(courseLogVo.getId()); - Course course =courseService.getById(courseLog.getCourseId()); - Map map=new HashMap(); - map.put("course",course); - map.put("courseLog",courseLog); - //判断是否购买过 - Long l= consumerCourseService.count(new QueryWrapper() - .eq("consumer_id",userId) - .eq("course_log_id",courseLogVo.getId())); - if (l<1l){ - courseLog.setVideoLong("1"); //页面 - return new RestResponse().success().setData(map); - } - return new RestResponse().success().setData(map); - } - - /** - * 预约课程1 - * @param appointment - * @return - */ - @PostMapping("/yyCourse1") - @Transactional(rollbackFor = RuntimeException.class) - public RestResponse yyCourse1(@RequestBody Appointment appointment, HttpServletRequest request) { - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - //查看校验课程是否符合预约条件 - CourseLog log=courseLogService.getById(appointment.getCourseLogId()); - if ( DateUtil.parse(log.getStartDate()+" "+log.getStartTime(),"yyyy-MM-dd HH:mm").before(DateUtil.date())){ - return new RestResponse().setSuccess(false).setMessage("该课程已过期,请选择其他课程!"); - } - if (log.getNumber()==log.getAppointmentNum()){ - return new RestResponse().setSuccess(false).setMessage("该课程预约已满,请选择其他课程!"); - } - - log.generateMemberNum(); - if (ObjectUtil.isNotEmpty(log.getMemberNum())){ - - //判断是否为会员 - List memberUsers=memberUserService.list(new QueryWrapper().eq("consumer_id",userId)); - if (ObjectUtil.isEmpty(memberUsers)){ - return new RestResponse().setSuccess(false).setMessage("该课程为会员课,请加入相应会籍后预约!"); - } - - int flag=0; - for (Object memberId:log.getMemberNum()){ - int id=Integer.parseInt(memberId.toString()); - for (MemberUser user:memberUsers){ - //判断会员会籍与课程会籍是否相符 - if (user.getMemberId()==id){ - //如果上课日期在会员有效期之内 - if (DateUtil.parse(log.getStartDate(),"yyyy-MM-dd").before( - DateUtil.parse(user.getValidityTime(),"yyyy-MM-dd"))){ - flag=1; - } - } - } - } - if (flag==0){ - return new RestResponse().setSuccess(false).setMessage("该课程为会员课,您的会籍类型与课程不符,请加入相应会籍后预约!"); - } - } - appointment.setPhone(request.getAttribute("phone").toString()); - courseService.yyCourse1(appointment); - - //给教练发送消息,提醒确认 - Context context=courseService.getTeacherPhone(appointment.getCourseLogId()); - String notification_title=context.getUserName()+"教练,您有一条课程预约"; - String msg_content="学员:"+request.getAttribute("phone").toString()+"预约您的课程,请登录后台处理!"; - - try { - JpushClientUtil.sendMessage(context.getPhonenumber(),notification_title,msg_content); - } catch (Exception e) { - e.printStackTrace(); - } - - //消息记录 - HistoryMessage message=new HistoryMessage(); - message.setPhone(context.getPhonenumber()); - message.setNotificationTitle(notification_title); - message.setMsgContent(msg_content); - message.setSendTime(DateUtil.now()); - historyMessageService.save(message); - return RestResponse.success(); - } - - /** - * 购买课程 - * @param courseLogVo - * @param request - * @return - * @throws Exception - */ - @PostMapping("/createOrderForCourse") - @Transactional(rollbackFor = RuntimeException.class) - public RestResponse createOrderForCourse(@RequestBody CourseLogVo courseLogVo, HttpServletRequest request) throws Exception{ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - //判断是否购买过 - long count= consumerCourseService.count(new QueryWrapper() - .eq("consumer_id",userId) - .eq("course_log_id",courseLogVo.getId())); - if (count>0l){ - return new RestResponse().setSuccess(false).setMessage("课程已购买过,请到 我的->我的课程 中查看!"); - } - - - //生成订单(支付中) - ShopOrder order=new ShopOrder(); - order.setOrderSn(SnowFlake.getOrder()+"");//订单号 - order.setBusinessId(courseLogVo.getStroreId());//商户 - order.setIdUser(userId);//客户id - order.setMobile(request.getAttribute("phone").toString());//收件人电话(客户电话) - order.setCreateTime(DateUtil.parseLocalDateTime(DateUtil.now(),"yyyy-MM-dd HH:mm:ss")); - order.setOrderType(3);//订单类型:1.商品 2.会籍 3.课程 - order.setPayType("微信支付"); - order.setTradeAmount(courseLogVo.getCoursePrice());//TradeAmount交易金额 MemberPrice价格 - - orderService.save(order); - - //生成订单详情 - ShopOrderItem item=new ShopOrderItem(); - item.setIdOrder(order.getId());//订单id - item.setIdSouseLog(courseLogVo.getId());//开课记录id - item.setTotalPrice(courseLogVo.getCoursePrice());//总价 - item.setThumbnail(courseLogVo.getCoursePicture());//缩略图 - item.setType("3");//1 商品 2 会籍 3 课程 - item.setCourseContext(courseLogVo.getCourseContext());//课程内容 - item.setCourseType(courseLogVo.getCourseType());//2大咖课 3教练培训 - item.setCourseNames(courseLogVo.getCourseNames()); - itemService.save(item); - - //单位: 元 转换成 分 - BigDecimal total=courseLogVo.getCoursePrice().multiply(new BigDecimal(100)); - Map map=new HashMap(); - - //0元 - if (total.equals(BigDecimal.ZERO)){ - //支付成功 给用户添加课程 TODO - - map.put("timeStamp","1"); - return new RestResponse().setSuccess(true).setMessage("成功").setData(map); - } - map= PayUtil.creatOrder(total.setScale(1, RoundingMode.HALF_UP).intValue(),order.getOrderSn()); - return new RestResponse().setSuccess(true).setMessage("成功").setData(map); - } - - - //视频以流的方式播放 -// @RequestMapping(value = "/longView", method = {RequestMethod.GET}) - @GetMapping("/longView") - public void imageView1(HttpServletRequest request, HttpServletResponse httpServletResponse){ - String fileName="/profile/upload/2022/11/10/WeChat_20221110133401_20221110133433A027.mp4"; - - byte[] bytes = file2byte("../ruoyi/uploadPath"+fileName.substring(8)); - - httpServletResponse.setContentType("application/octet-stream"); - httpServletResponse.setContentLength(bytes.length); - try { - httpServletResponse.getOutputStream().write(bytes); - } catch (IOException e) { - System.out.println("IO异常----"); - } - } - - public byte[] file2byte(String filePath) { - byte[] buffer = null; - try { - File file = new File(filePath); - FileInputStream fis = new FileInputStream(file); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - byte[] b = new byte[1024]; - int n; - while ((n = fis.read(b)) != -1) { - bos.write(b, 0, n); - } - fis.close(); - bos.close(); - buffer = bos.toByteArray(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return buffer; - } - -} - diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/HistoryMessageController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/HistoryMessageController.java deleted file mode 100644 index 48609ce..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/HistoryMessageController.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.ruoyi.web.controller.app_course; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.course.domain.HistoryMessage; -import com.ruoyi.course.service.HistoryMessageServiceImpl; -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 javax.servlet.http.HttpServletRequest; -import java.util.List; - -/** - * 我的消息 - */ -@Api(tags = "我的消息", description = "提供我的消息相关的API") -@RestController -@RequestMapping("/api/historyMessage") -public class HistoryMessageController { - - - @Autowired - HistoryMessageServiceImpl historyMessageService; - - @ApiOperation("我的消息列表") - @PostMapping("/getMessages") - public RestResponse getMessages(HttpServletRequest request){ - List list= historyMessageService.list(new QueryWrapper() - .eq("phone",request.getAttribute("phone").toString()) - .eq("releases",true)); - return new RestResponse().setSuccess(true).setData(list); - } - - @ApiOperation("消息详情") - @PostMapping("/getOne") - public RestResponse getOne(@RequestBody HistoryMessage message){ - HistoryMessage historyMessage= historyMessageService.getById(message.getId()); - return new RestResponse().setSuccess(true).setData(historyMessage); - } - - @ApiOperation("删除消息") - @PostMapping("/remove") - public RestResponse remove(@RequestBody HistoryMessage message){ - message.setReleases(false); - historyMessageService.updateById(message); - return new RestResponse().setSuccess(true); - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/MemberAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/MemberAppController.java deleted file mode 100644 index 2ebd086..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/MemberAppController.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.ruoyi.web.controller.app_course; - - -import cn.hutool.core.date.DateUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.course.domain.Member; -import com.ruoyi.course.service.ConsumerCourseServiceImpl; -import com.ruoyi.course.service.MemberServiceImpl; -import com.ruoyi.search.domain.MemberUser; -import com.ruoyi.search.service.MemberUserServicelmpl; -import com.ruoyi.shop.domain.ShopOrder; -import com.ruoyi.shop.domain.ShopOrderItem; -import com.ruoyi.shop.service.impl.ShopOrderItemServiceImpl; -import com.ruoyi.shop.service.impl.ShopOrderServiceImpl; -import com.ruoyi.web.util.PayUtil; -import com.ruoyi.web.util.SnowFlake; -import io.swagger.annotations.Api; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; -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 javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.time.LocalDateTime; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - *

- * 前端控制器 - *

- * - * @author xhj - * @since 2022-09-23 - */ -@Api(tags = "会籍", description = "提供会籍相关的API") -@RestController -@RequestMapping("/api/member") -public class -MemberAppController { - - @Autowired - private MemberServiceImpl memberService; - @Autowired - private MemberUserServicelmpl memberUserServicel; - @Resource - private ShopOrderServiceImpl orderService; - @Resource - private ShopOrderItemServiceImpl itemService; - @Resource - private ConsumerCourseServiceImpl consumerCourseService; - - /** - * app服务-本店会籍类型列表 - * @param member - * @return - * @author xn - */ -// @ApiOperation("获取本店会籍列表") - @PostMapping("/getMembers") - public RestResponse getMembers(@RequestBody Member member) { - List list = memberService.list(new QueryWrapper() - .eq("strore_id",member.getStroreId()) - .eq("releases",1) - ); - return new RestResponse().setData(list); - } - - /** - * app服务-会籍详情 - * @param member - * @return - * @author xn - */ -// @ApiOperation("会籍详情") - @PostMapping("/getOne") - public RestResponse getOne(@RequestBody Member member) { - Member m = memberService.getById(member.getMemberId()); - return new RestResponse().setData(m); - } - - /** - * 数据字典 - * @param member - * @return - */ -// @ApiOperation("会籍数据字典") - @PostMapping(value = "/getList") - public RestResponse findList1(@RequestBody Member member) { - List list =memberService.findList(member); - return new RestResponse().setSuccess(true).setMessage("成功").setData(list); - } - - /** - * 购买会籍下订单 - * @param memberUser - * @param request - * @return - */ -// @ApiOperation("购买会籍") - @PostMapping("/createOrderForMember") - @Transactional(rollbackFor = RuntimeException.class) - public RestResponse createOrderForMember(@RequestBody MemberUser memberUser, HttpServletRequest request) throws Exception{ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - //判断是否已经在籍 - LocalDateTime dateTime= DateUtil.parseLocalDateTime(DateUtil.format(DateUtil.tomorrow(),"yyyy-MM-dd 00:00:00")); - List list=memberUserServicel.list(new QueryWrapper()//DateUtil.now() - .eq("member_id",memberUser.getMemberId()) - .eq("consumer_id",userId) - .last(" and (validity_time > now() or come_time ='"+dateTime+"')"));//截止日期为今天之后(未到期) 或 开始日期在明天(今天办的) - if (list.size()>0){ - if (list.get(0).getComeTime().equals(dateTime)){ - return new RestResponse().setSuccess(false).setMessage("您已成功办理会籍,生效时间为"+DateUtil.tomorrow().toString("yyyy-MM-dd 00:00:00")+"!请勿重复办理!"); - }else { - return new RestResponse().setSuccess(false).setMessage("会籍存续中,请勿重复办理!"); - } - } - //价格/月 * 有效期(月) - BigDecimal price= memberUser.getMemberPrice().multiply(new BigDecimal(memberUser.getValidity())); - //生成订单(支付中) - ShopOrder order=new ShopOrder(); - order.setOrderSn(SnowFlake.getOrder()+"");//订单号 - order.setBusinessId(memberUser.getStroreId());//商户 - order.setIdUser(userId);//客户id - order.setMobile(request.getAttribute("phone").toString());//收件人电话(客户电话) - order.setCreateTime(DateUtil.parseLocalDateTime(DateUtil.now(),"yyyy-MM-dd HH:mm:ss")); - order.setOrderType(2);//订单类型:1.商品 2.会籍 3.课程 - order.setPayType("微信支付"); - order.setTradeAmount(price);//TradeAmount交易金额 - - orderService.save(order); - - //生成订单详情 - ShopOrderItem item=new ShopOrderItem(); - item.setIdOrder(order.getId());//订单id - item.setIdMember(memberUser.getMemberId());//会员id - item.setTotalPrice(price);//总价 - item.setThumbnail(memberUser.getMemberPicture());//缩略图 - item.setType("2");//1 商品 2 会籍 3 课程 - item.setMemberType(memberUser.getMemberName());//会籍类型=会籍名称 - item.setMemberValidity(memberUser.getValidity());//会籍有效期(月) - item.setBrief(memberUser.getMemberContext());//简介=会籍内容 - item.setMemberRecommend(memberUser.getRecommend());//推荐人 - itemService.save(item); - //单位: 元 转换成 分 - BigDecimal total=price.multiply(new BigDecimal(100)); - Map map=new HashMap(); - - //0元 - if (total.equals(BigDecimal.ZERO)){ - //支付成功 生成会籍 - - map.put("timeStamp","1"); - return new RestResponse().setSuccess(true).setMessage("成功").setData(map); - } - map= PayUtil.creatOrder(total.setScale(1, RoundingMode.HALF_UP).intValue(),order.getOrderSn()); - return new RestResponse().setSuccess(true).setMessage("成功").setData(map); - } - - /** - * 我的会籍 - * 存续的 - * @return - */ -// @ApiOperation("我的会籍") - @PostMapping("/myMembers") - public RestResponse myMembers(HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - List list=memberUserServicel.list(new QueryWrapper() - .eq("consumer_id",userId) - .last("and validity_time > now()")); - return new RestResponse().setSuccess(true).setData(list); - } - - //课程表与会籍相关联 - - -} - diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/CourceLpController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/CourceLpController.java deleted file mode 100644 index 811aa22..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/CourceLpController.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.ruoyi.web.controller.app_shop; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.course.domain.CourseLog; -import com.ruoyi.course.service.CourseLogServiceImpl; -import com.ruoyi.shop.domain.YjCourseLp; -import com.ruoyi.shop.service.impl.YjCourceLpMenuServiceImpl; -import com.ruoyi.shop.service.impl.YjCourceLpServiceImpl; -import com.ruoyi.shop.service.impl.YjMerchantServiceImpl; -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 javax.annotation.Resource; -import java.util.List; -@Api(tags = "瑜伽流派", description = "提供瑜伽流派相关的API") -@RestController -@RequestMapping("/api/courseLp") -public class CourceLpController { - @Resource - private YjCourceLpServiceImpl service; - @Resource - private YjMerchantServiceImpl merchantService; - @Resource - private YjCourceLpMenuServiceImpl menuService; - @Resource - private CourseLogServiceImpl courseLogService; - - /** - * 列表 - * @param lp - * @return - */ - @PostMapping("/list") - @ApiOperation("获取瑜伽流派 列表") - public RestResponse list(@RequestBody YjCourseLp lp){ - List list=service.list(new QueryWrapper() - .eq("merchant_id", lp.getMerchantId()) - .eq("enabled",true) - .orderByDesc("modify_time") - ); - return new RestResponse().setSuccess(true).setMessage("成功").setData(list); - } - - @ApiOperation("获取当前瑜伽流派下的课程") - @PostMapping("/courseList") - public RestResponse courseList(@RequestBody YjCourseLp lp){ -// 课程分类courseType 是否显示releases - List list=service.list(new QueryWrapper() - .eq("merchant_id", lp.getMerchantId()) - .eq("enabled",true) - .orderByDesc("modify_time") - ); - list.forEach(l->{ - l.setCourseType(lp.getCourseType()); - l.setReleases(true); - List courseList=courseLogService.list(new QueryWrapper() - .select("id","course_id","course_names","course_price","course_picture","course_type") - .eq("course_type",lp.getCourseType())//课程类型 2大咖课 3教练培训 - .eq("releases",true) //上架 - .eq("lp_id",l.getId())//流派 - ); - l.setCourseList(courseList); - }); - return new RestResponse().setSuccess(true).setMessage("成功").setData(list); - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/GoodsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/GoodsController.java deleted file mode 100644 index 317aa8b..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/GoodsController.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.ruoyi.web.controller.app_shop; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.shop.domain.ShopGoods; -import com.ruoyi.shop.domain.ShopGoodsCategory; -import com.ruoyi.shop.mapper.ShopGoodsMapper; -import com.ruoyi.shop.service.impl.ShopGoodsCategoryServiceImpl; -import com.ruoyi.shop.service.impl.ShopGoodsServiceImpl; -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 javax.annotation.Resource; -import java.util.List; - -@Api(tags = "商品", description = "提供商品相关的API") -@RestController -@RequestMapping("/api/goods") -public class GoodsController { - @Resource - private ShopGoodsServiceImpl service; - - @Resource - private ShopGoodsCategoryServiceImpl categoryService; - - @Resource - private ShopGoodsMapper goodsMapper; - - - @ApiOperation("商品类别") - @PostMapping("/getGoodsCategory") - public RestResponse getGoodsCategory(@RequestBody ShopGoodsCategory category){ - List categoryList=categoryService.list(new QueryWrapper() - .eq("business_id",category.getBusinessId()) - .eq("pid","0") - .eq("display",true) - .eq("is_delete",false)); - return new RestResponse().setSuccess(true).setMessage("成功").setData(categoryList); - } - - @ApiOperation("商品列表") - @PostMapping("/getGoods") - public RestResponse getGoods(@RequestBody ShopGoodsCategory category){ - List goods=goodsMapper.getByPid(category.getId()); - return new RestResponse().setSuccess(true).setMessage("成功").setData(goods); - } - - @ApiOperation("商品详情") - @PostMapping("/getOne") - public RestResponse getOne(@RequestBody ShopGoods goods){ - return new RestResponse().setSuccess(true).setMessage("成功").setData(service.getById(goods.getId())); - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/IndexController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/IndexController.java deleted file mode 100644 index e36b965..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/IndexController.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ruoyi.web.controller.app_shop; - -import cn.hutool.core.util.ObjectUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.shop.domain.YjIndex; -import com.ruoyi.shop.domain.YjMerchant; -import com.ruoyi.shop.service.impl.YjIndexServiceImpl; -import com.ruoyi.shop.service.impl.YjMerchantServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -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 javax.annotation.Resource; -import java.util.List; -@Api(tags = "首页", description = "提供首页信息相关的API") -@RestController -@RequestMapping("/api/index") -public class IndexController { - - @Resource - private YjIndexServiceImpl indexService; - @Resource - private YjMerchantServiceImpl merchantService; - - - //商户list - @ApiOperation("门店列表") - @PostMapping("/getMerchant") - public RestResponse getMerchant(){ - List list=merchantService.list(new QueryWrapper() - .select("address","enterprise_name","phone","banner","id") - .eq("status",2)); - return new RestResponse().setSuccess(true).setData(list); - } - - @ApiOperation("首页图标") - @ApiImplicitParam(name = "merchantId", value = "商户ID", required = true, dataType = "String", dataTypeClass = String.class) - @PostMapping("/getIndex") - public RestResponse getIndex(@RequestBody YjIndex yjIndex){ - YjIndex y= indexService.getOne(new QueryWrapper() - .eq("merchant_id",yjIndex.getMerchantId())); - - if (ObjectUtil.isNotEmpty(y)){ - return new RestResponse().setSuccess(true).setData(y); - }else { - return new RestResponse().setSuccess(false); - } - - - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/LoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/LoginController.java deleted file mode 100644 index 358c97a..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/LoginController.java +++ /dev/null @@ -1,315 +0,0 @@ -package com.ruoyi.web.controller.app_shop; - -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -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.SysUser; -import com.ruoyi.common.core.domain.model.LoginBody; -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.*; -import com.ruoyi.common.utils.ip.IpUtils; -import com.ruoyi.framework.config.JwtUtil1; -import com.ruoyi.framework.manager.AsyncManager; -import com.ruoyi.framework.manager.factory.AsyncFactory; -import com.ruoyi.framework.security.context.AuthenticationContextHolder; -import com.ruoyi.framework.web.service.TokenService; -import com.ruoyi.shop.domain.Consumer; -import com.ruoyi.shop.domain.YjMerchant; -import com.ruoyi.shop.service.ConsumerService; -import com.ruoyi.shop.service.impl.YjMerchantServiceImpl; -import com.ruoyi.system.service.ISysConfigService; -import com.ruoyi.system.service.ISysUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.RedisTemplate; -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.web.bind.annotation.*; - -import javax.annotation.Resource; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.TimeUnit; -@Api(tags = "登录与验证") -@RestController -@RequestMapping("/api") -public class LoginController { - - - @Resource - private ConsumerService service; - @Autowired - private ISysUserService userService; - @Resource - JwtUtil1 jwtUtil1; - @Autowired - private TokenService tokenService; - @Resource - RedisTemplate redisTemplate; - - @Autowired - private RedisCache redisCache; - @Autowired - private ISysConfigService configService; - @Resource - private AuthenticationManager authenticationManager; - - - @ApiOperation("登录") - @PostMapping("/login") - public AjaxResult login(@RequestBody LoginBody loginBody){ - - AjaxResult ajax = AjaxResult.success(); - if (StrUtil.isEmpty(loginBody.getRegisterId())){ - ajax.put(Constants.FAIL, "设备id异常"); - return ajax; - } - boolean captchaEnabled = configService.selectCaptchaEnabled(); - // 验证码开关 - if (captchaEnabled) - { - validateCaptcha(loginBody.getAccount(),loginBody.getCode(),loginBody.getUuid()); - } - - //用户名是否存在 - SysUser user = userService.selectUserByUserName(loginBody.getAccount()); - - //未注册 - if(ObjectUtil.isEmpty(user) ){ - //注册并登录 - //用户账号 昵称 门店 密码 头像 - // registerId 地址 - // 必填 user_name nick_name merchant_id - user=new SysUser(); - user.setUserName(loginBody.getAccount()); - user.setNickName("用户"+loginBody.getAccount()); - user.setPassword(SecurityUtils.encryptPassword(loginBody.getPassword())); - user.setRegisterId(loginBody.getRegisterId()); - user.setVisitStore(getIndex(user).get("id")); - Long[] ros={107l};//用户角色 - user.setRoleIds(ros); - userService.insertUser(user); - String token = validateUser(loginBody.getAccount(),loginBody.getPassword()); - //设置推送别名 - JpushClientUtil.bindAlias(loginBody.getRegisterId(),loginBody.getAccount()); - ajax.put(Constants.TOKEN, token); - return ajax; - } - - //已注册 直接登录 - String token = validateUser(loginBody.getAccount(),loginBody.getPassword()); - //设置推送别名 - JpushClientUtil.bindAlias(loginBody.getRegisterId(),loginBody.getAccount()); - if (!loginBody.getRegisterId().equals(user.getRegisterId())){ - //判断登录设备是否更换 todo -// userService.updateUser(); - } - //返回token - ajax.put(Constants.TOKEN, token); - return ajax; - } - - /** - * 校验验证码 - * - * @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(); - } - } - - //用户验证 - public String validateUser(String username,String password){ - // 用户验证 - Authentication authentication = null; - try - { - 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 - { - 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); - } - - - /** - * 获取用户信息 - * - * @return 用户信息 - */ - @GetMapping("/getInfo") - public AjaxResult getInfo() - { - SysUser user = SecurityUtils.getLoginUser().getUser(); - // 角色集合 -// Set roles = permissionService.getRolePermission(user); - // 权限集合 -// Set permissions = permissionService.getMenuPermission(user); - AjaxResult ajax = AjaxResult.success(); - ajax.put("user", user); - ajax.put("merchant",getIndex(user)); -// ajax.put("roles", roles); -// ajax.put("permissions", permissions); - return ajax; - } - /** - * 记录登录信息 - * - * @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); - } - -// ----------------------------------------------- - @ApiOperation("获取验证码") -// @PostMapping ("/getCode") - public RestResponse getCode(@RequestBody Consumer consumer){ - String captcha=(String) redisTemplate.opsForValue().get(consumer.getConsumerPhonenumber()); - if (StrUtil.isNotEmpty(captcha)){ - return new RestResponse().setSuccess(false).setMessage("请1分钟后重试"); - } - captcha =gen()+""; - - //发送成功 手机号存到redis 对应code 1分钟有效期 - redisTemplate.opsForValue().set(consumer.getConsumerPhonenumber(), - captcha, - 1, - TimeUnit.MINUTES); - return new RestResponse().setSuccess(true).setMessage("发送成功").setData(captcha); - } - - public int gen() { - Random r = new Random( System.currentTimeMillis() ); - return ((1 + r.nextInt(2)) * 100000 + r.nextInt(100000)); - } - - /** - * 短信验证码登录方式 - * @param map - * @return - */ - public RestResponse login(@RequestBody Map map){ - System.out.println("---------------------registerId"+map.get("registerId")); - String captcha=(String)redisTemplate.opsForValue().get(map.get("consumerPhonenumber")); - if(map.get("captcha").equals(captcha)){ - //登录成功 - redisTemplate.delete(map.get("consumerPhonenumber")); - Map dataMap = new HashMap<>(); - //查找数据库,判断是否为新用户: - //老用戶 - Consumer consumer=service.getOne(new QueryWrapper() - .eq("consumer_phonenumber",map.get("consumerPhonenumber"))); - if (ObjectUtil.isNotEmpty(consumer)){ - //老客户 - if (StrUtil.isNotEmpty(map.get("registerId"))){ - consumer.setRegisterId(map.get("registerId")); - service.updateById(consumer); - //设置推送别名 - JpushClientUtil.bindAlias(consumer.getRegisterId(),consumer.getConsumerPhonenumber()); - } - String token = jwtUtil1.generateToken(consumer.getConsumerId().toString(),consumer.getConsumerPhonenumber()); - dataMap.put("jwt",token); - dataMap.put("userInfo",consumer); - return new RestResponse().setSuccess(true).setMessage("成功").setData(dataMap); - } - //新用戶 - consumer=new Consumer(); - consumer.setConsumerPhonenumber(map.get("consumerPhonenumber")); - consumer.setConsumerName("用户"+map.get("consumerPhonenumber")); - consumer.setConsumerNickName("用户"+map.get("consumerPhonenumber")); - consumer.setRegisterId(map.get("registerId")); - consumer.setConsumerAvatar("/default.jpeg"); - service.save(consumer); - //设置推送别名 - JpushClientUtil.bindAlias(consumer.getRegisterId(),consumer.getConsumerPhonenumber()); - String token = jwtUtil1.generateToken(consumer.getConsumerId().toString(),consumer.getConsumerPhonenumber()); - dataMap.put("jwt",token); - dataMap.put("userInfo",consumer); -// dataMap.put("index",getIndex(consumer)); - - return new RestResponse().setSuccess(true).setMessage("成功").setData(dataMap); - } - - return new RestResponse().setSuccess(false).setMessage("失败"); - } - @Resource - private YjMerchantServiceImpl merchantService; - - public Map getIndex(SysUser c){ - YjMerchant merchant; - Map m=new HashMap(); - if (StrUtil.isNotEmpty(c.getVisitStore())){ - merchant=merchantService.getById(c.getVisitStore()); - }else { - merchant= merchantService.list().get(0); - } - m.put("address",merchant.getAddress()); - m.put("enterpriseName",merchant.getEnterpriseName()); - m.put("phone",merchant.getPhone()); - m.put("banner",merchant.getBanner()); - m.put("id",merchant.getId()); - return m; - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/OrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/OrderController.java deleted file mode 100644 index 954fd8b..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/OrderController.java +++ /dev/null @@ -1,323 +0,0 @@ -package com.ruoyi.web.controller.app_shop; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.shop.domain.ShopGoods; -import com.ruoyi.shop.domain.ShopOrder; -import com.ruoyi.shop.domain.ShopOrderItem; -import com.ruoyi.shop.service.impl.ShopCartServiceImpl; -import com.ruoyi.shop.service.impl.ShopGoodsServiceImpl; -import com.ruoyi.shop.service.impl.ShopOrderItemServiceImpl; -import com.ruoyi.shop.service.impl.ShopOrderServiceImpl; -import com.ruoyi.web.controller.app_shop.dto.ShopOrderDto; -import com.ruoyi.web.util.PayUtil; -import com.ruoyi.web.util.SnowFlake; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.transaction.annotation.Transactional; -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 javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Api(tags = "订单信息", description = "提供订单信息相关的API") -@RestController -@RequestMapping("/api/order") -public class OrderController { - - @Resource - private ShopGoodsServiceImpl goodsService; - @Resource - private ShopCartServiceImpl cartService; - @Resource - private ShopOrderServiceImpl orderService; - @Resource - private ShopOrderItemServiceImpl itemService; - - - /** - * 提交订单 - * @param orderDto - * @param request - * @return - * ①按商品所属商户生成订单 - * ②生成订单详情 - * ③删除对应购物车 - * ④修改商品库存 - */ - @ApiOperation("提交订单-生成预付单") - @PostMapping("/createOrder") - @Transactional(rollbackFor = RuntimeException.class) - public RestResponse createOrder(@RequestBody ShopOrderDto orderDto, HttpServletRequest request) throws Exception{ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - - //商户:商品list - Map> goodsMap=orderDto.getList().stream().collect(Collectors.groupingBy(ShopGoods::getBusinessId)); - String OrderSn=SnowFlake.getOrder()+""; - BigDecimal total=new BigDecimal(0);//微信支付金额 - - for (String key:goodsMap.keySet()){ - //生成订单 - ShopOrder order=new ShopOrder(); - order.setBusinessId(key);//商户 - order.setIdUser(userId); - order.setConsignee(orderDto.getName());//收件人 - order.setConsigneeAddress(orderDto.getProvince()+" "+ - orderDto.getCity()+" "+ - orderDto.getAddress());//收件地址 - order.setMobile(orderDto.getPhone());//收件人电话 - order.setCreateTime(DateUtil.parseLocalDateTime(DateUtil.now(),"yyyy-MM-dd HH:mm:ss")); - order.setOrderSn(OrderSn);//订单号 - order.setPayType("微信支付"); - order.setOrderType(1);//订单类型:1.商品 2.会籍 3.课程 - orderService.save(order); - BigDecimal totalPrice=new BigDecimal(0);//总金额 - BigDecimal tradeAmount=new BigDecimal(0);//交易金额 - - for (ShopGoods goods:goodsMap.get(key)){ - ShopOrderItem item=new ShopOrderItem(); - item.setGoodsName(goods.getName());//* 商品名称 - item.setIdGoods(goods.getId());//* 商品名称 - item.setThumbnail(goods.getThumbnail());//* 商品缩略图 - item.setBrief(goods.getBrief());//* 商品简介 - item.setAttribute(goods.getAttribute());//* 规格 - item.setCount(goods.getCount());//数量 - item.setPrice(goods.getPrice());//单价 - item.setIdOrder(order.getId());//订单id - item.setType("1");//1 商品 2 会籍 3 课程 - BigDecimal to=goods.getPrice().multiply(new BigDecimal(goods.getCount())); - item.setTotalPrice(to);//总金额 - //商品库存更改 - Boolean isEnough= goodsService.update(new UpdateWrapper() - .setSql("stock=stock-"+goods.getCount()) - .eq("id",goods.getId()) - .ge("stock",goods.getCount())); - if(!isEnough){ - throw new RuntimeException("商品["+goods.getName()+"]库存不足!"); -// return new RestResponse().setSuccess(false).setMessage("商品["+goods.getName()+"]库存不足!"); - } - itemService.save(item); - if (StrUtil.isNotEmpty(goods.getCartId())){ - cartService.removeById(goods.getCartId()); - } - tradeAmount=tradeAmount.add(to);//实际需要支付的金额 - totalPrice=totalPrice.add(goods.getMarketPrice().multiply(new BigDecimal(goods.getCount()))); - } - order.setTotalPrice(totalPrice); - order.setTradeAmount( tradeAmount);//实际需要支付的金额 - orderService.updateById(order); - // - total=total.add(order.getTradeAmount()); - } - - total=total.multiply(new BigDecimal(100)); - Map map=new HashMap(); - if (total.equals(BigDecimal.ZERO)){ - //0元,直接支付成功 无需调用微信支付 - orderService.paySuccess(OrderSn,DateUtil.now(),"","0"); - map.put("timeStamp","1"); - return new RestResponse().setSuccess(true).setMessage("成功").setData(map); - } - - //调用微信支付 生成预付单 - map= PayUtil.creatOrder(total.setScale(1, RoundingMode.HALF_UP).intValue(),OrderSn); - return new RestResponse().setSuccess(true).setMessage("成功").setData(map); - - } - -// public RestResponse createOrder(@RequestBody ShopOrderDto orderDto, HttpServletRequest request){ -// Long userId= Long.parseLong(request.getAttribute("userId").toString()); -// -//// List goodsIds = orderDto.getList().stream().map(ShopGoods::getId).collect(Collectors.toList()); -//// List goodsList = goodsMapper.selectBatchIds(goodsIds); -// Map> goodsMap=orderDto.getList().stream().collect(Collectors.groupingBy(ShopGoods::getBusinessId)); -// -// for (String key:goodsMap.keySet()){ -// //生成订单 -// ShopOrder order=new ShopOrder(); -// order.setBusinessId(key);//商户 -// order.setIdUser(userId); -// order.setConsignee(orderDto.getName());//收件人 -// order.setConsigneeAddress(orderDto.getProvince()+" "+ -// orderDto.getCity()+" "+ -// orderDto.getAddress());//收件地址 -// order.setMobile(orderDto.getPhone());//收件人电话 -// order.setCreateTime(DateUtil.parseLocalDateTime(DateUtil.now(),"yyyy-MM-dd HH:mm:ss")); -// order.setOrderSn(SnowFlake.getOrder()+""); -// orderService.save(order); -// BigDecimal totalPrice=new BigDecimal(0);//总金额 -// BigDecimal tradeAmount=new BigDecimal(0);//交易金额 -// -// for (ShopGoods goods:goodsMap.get(key)){ -// ShopOrderItem item=new ShopOrderItem(); -// item.setGoodsName(goods.getName());//* 商品名称 -// item.setIdGoods(goods.getId());//* 商品名称 -// item.setThumbnail(goods.getThumbnail());//* 商品缩略图 -// item.setBrief(goods.getBrief());//* 商品简介 -// item.setAttribute(goods.getAttribute());//* 规格 -// item.setCount(goods.getCount());//数量 -// item.setPrice(goods.getPrice());//单价 -// item.setIdOrder(order.getId());//订单id -// BigDecimal To=goods.getPrice().multiply(new BigDecimal(goods.getCount())); -// item.setTotalPrice(To);//总金额 -// //商品库存更改 -// Boolean isEnough= goodsService.update(new UpdateWrapper() -// .setSql("stock=stock-"+goods.getCount()) -// .eq("id",goods.getId()) -// .ge("stock",goods.getCount())); -// if(!isEnough){ -// throw new RuntimeException("商品["+goods.getName()+"]库存不足!"); -//// return new RestResponse().setSuccess(false).setMessage("商品["+goods.getName()+"]库存不足!"); -// } -// itemService.save(item); -// if (StrUtil.isNotEmpty(goods.getCartId())){ -// cartService.removeById(goods.getCartId()); -// } -// totalPrice=totalPrice.add(To); -// tradeAmount=tradeAmount.add(goods.getMarketPrice().multiply(new BigDecimal(goods.getCount()))); -// } -// order.setTotalPrice(tradeAmount); -// order.setTradeAmount(totalPrice);// -// orderService.updateById(order); -// } -// return new RestResponse().setSuccess(true).setMessage("成功"); -// } - - /** - * 取消订单(订单状态为“1已下单/待付款”) - * ①更改订单状态 - * ②加回产品库存 - * @param order - * @return - */ -// @PostMapping("/cancelOrder") - @Transactional(rollbackFor = RuntimeException.class) - public RestResponse cancelOrder(@RequestBody ShopOrder order){ - //更改订单状态 - //查询对应订单详情 - //根据订单详情数量 更改商品库存 - Boolean isUpdate= orderService.update(new UpdateWrapper() - .set("status",2) - .eq("id",order.getId()) - .eq("status",1)); - if (isUpdate){ - List itemList=itemService.list(new QueryWrapper() - .eq("id_order",order.getId())); - for (ShopOrderItem item:itemList){ - goodsService.update(new UpdateWrapper() - .setSql("stock=stock+"+item.getCount()) - .eq("id",item.getIdGoods())); - } - return new RestResponse().setSuccess(true).setMessage("订单取消成功"); - } - - return new RestResponse().setSuccess(false).setMessage("该订单无法取消"); - } - - /** - * 付款 - * @param order - * @return - */ -// @PostMapping("/pay") - public RestResponse pay(@RequestBody ShopOrder order){ - if(orderService.getById(order.getId()).getPayStatus()==2){ - return new RestResponse().setSuccess(true).setMessage("该订单已支付成功,请勿重复支付!"); - } - ShopOrder o=orderService.getById(order); - order.setStatus(3); - order.setPayStatus(2); - order.setPayTime(DateUtil.now()); - order.setRealPrice(o.getTradeAmount()); - orderService.updateById(order); - return new RestResponse().setSuccess(true).setMessage("订单支付成功"); - } - - /** - * 签收 - * @param order - * @return - */ - @ApiOperation("确认收货") - @PostMapping("/received") - public RestResponse received(@RequestBody ShopOrder order){ - order.setStatus(6); - orderService.updateById(order); - return new RestResponse().setSuccess(true).setMessage("成功"); - } - - /** - * 订单列表 - * @param request - * @return - */ - @ApiOperation(value = "获取订单列表", notes = "我的订单") - @PostMapping("/orderList") - public RestResponse orderList(HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - List list=orderService.list(new QueryWrapper() - .eq("id_user",userId)); - List list1=new ArrayList<>(); - List list2=new ArrayList<>(); - List list3=new ArrayList<>(); - List list4=new ArrayList<>(); - List list6=new ArrayList<>(); - for (ShopOrder order:list){ - order.setItemList(getItemList(order.getId())); - if (order.getStatus()==1){ - list1.add(order); - } - if (order.getStatus()==2){ - list2.add(order); - } - if (order.getStatus()==3){ - list3.add(order); - } - if (order.getStatus()==4){ - list4.add(order); - } - if (order.getStatus()==6){ - list6.add(order); - } - } - Map> map=new HashMap<>(); - map.put("list",list);//全部订单 - map.put("list1",list1);//未付款 - map.put("list2",list2);//2已取消 - map.put("list3",list3);//3已付款/待发货 - map.put("list4",list4);//4已发货/待收货 - map.put("list6",list6);//6已签收 - return new RestResponse().setSuccess(true).setMessage("成功").setData(map); - } - - /** - * 订单详情 - * @param order - * @return - */ - @ApiOperation("订单详情") - @PostMapping("/getOrder") - public RestResponse getOrder(@RequestBody ShopOrder order){ - ShopOrder o= orderService.getById(order.getId()); - o.setItemList(getItemList(order.getId())); - return new RestResponse().setSuccess(true).setMessage("成功").setData(o); - } - - public List getItemList(String orderId){ - return itemService.list(new QueryWrapper().eq("id_order",orderId)); - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/PayController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/PayController.java deleted file mode 100644 index 840ee88..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/PayController.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.ruoyi.web.controller.app_shop; - -import cn.hutool.core.date.DateTime; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ruoyi.shop.domain.ShopOrder; -import com.ruoyi.shop.service.impl.ShopOrderServiceImpl; -import com.ruoyi.web.util.PayConstants; -import com.ruoyi.web.util.PayUtil; -import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; -import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; -import com.wechat.pay.contrib.apache.httpclient.auth.Verifier; -import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials; -import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator; -import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager; -import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; -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 javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.PrivateKey; -import java.text.SimpleDateFormat; -import java.util.*; - -@RestController -@RequestMapping("/api") -public class PayController { - @Resource - private ShopOrderServiceImpl orderService; - - /** - * 付款前 - * @param amount - * @return - * @throws Exception - */ -// @PostMapping("/creat_order") -// private Map creatOrder(int amount) throws Exception{ -// return PayUtil.creatOrder("三朵兰",amount,"123"); -// } - - - /** - * - * @return - * https://www.test.com/callback - */ - @PostMapping("/callback") - public Map callback(HttpServletRequest request) { - - System.out.println("Wechatpay-Timestamp:"+ request.getHeader("Wechatpay-Timestamp")); - System.out.println("Wechatpay-Nonce:"+ request.getHeader("Wechatpay-Nonce")); - System.out.println("Wechatpay-Signature:"+ request.getHeader("Wechatpay-Signature")); - System.out.println("Wechatpay-Serial:"+ request.getHeader("Wechatpay-Serial")); - Map result=new HashMap(); - result.put("code","FAIL"); - - try { - StringBuilder signStr=new StringBuilder(); - signStr.append( request.getHeader("Wechatpay-Timestamp")).append("\n"); - signStr.append( request.getHeader("Wechatpay-Nonce")).append("\n"); - - BufferedReader br=request.getReader(); - String str=null; - StringBuilder builder=new StringBuilder(); - while ((str=br.readLine())!=null){ - builder.append(str); - } - System.out.println(builder); - - signStr.append( builder.toString()).append("\n"); - //验证签名 - if (!PayUtil.signVerify(request.getHeader("Wechatpay-Serial"),signStr.toString(),request.getHeader("Wechatpay-Signature"))){ - result.put("message","sign error"); - return result; - } - //解密密文 - String ciphertext=PayUtil.decryptOrder(builder.toString()); - System.out.println(ciphertext); - //验证订单 - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode node=objectMapper.readTree(ciphertext); - JsonNode amount=node.get("amount");//订单金额信息 - String payer_total=amount.get("payer_total").textValue();//用户支付金额,单位为分 - String payer_currency=amount.get("payer_currency").textValue();//用户支付币种 示例值:CNY - String trade_state=node.get("trade_state").textValue();//交易状态 SUCCESS - String out_trade_no=node.get("out_trade_no").textValue();//商户订单号 - String success_time=node.get("success_time").textValue();//支付完成时间 - String transaction_id=node.get("transaction_id").textValue();//支付完成时间 - - List list = orderService.list(new QueryWrapper().eq("orderSn",out_trade_no)); - //判断交易状态 可能是多次 SUCCESS; 也可能是 多次不同状态 ; - // 现只处理支付成功与支付失败两种状态 - //判断是否处理过 - if (list.get(0).getPayStatus()==1){ - System.out.println("处理订单:"+out_trade_no+" 交易状态:"+trade_state); - //支付失败 - if (trade_state.equals("PAYERROR")){ - System.out.println("取消订单+关单"); - orderService.cancelOrder(out_trade_no); - try { - PayUtil.closeOrder(out_trade_no);//关单 - } catch (Exception e) { - e.printStackTrace(); - } - } - //支付成功 - if (trade_state.equals("SUCCESS")){ - System.out.println("支付成功"); - orderService.paySuccess(out_trade_no - ,getStringByRFC3339(success_time) - ,transaction_id - ,payer_total); - - result.put("code","SUCCESS"); - - } - } - - }catch (IOException e){ - e.printStackTrace(); - } - return result; - } - - - public void a(@RequestBody Map map){ - String out_trade_no=map.get("out_trade_no"); - String trade_state=map.get("trade_state"); - String success_time="2022-12-31T10:34:56+08:00"; - String transaction_id="微信支付订单号"; - String payer_total="0.1"; - - List list = orderService.list(new QueryWrapper().eq("order_sn",out_trade_no)); - //判断交易状态 可能是多次 SUCCESS; 也可能是 多次不同状态 ; - // 现只处理支付成功与支付失败两种状态 - //判断是否处理过 - if (list.get(0).getPayStatus()==1){ - //支付失败 - if (trade_state.equals("PAYERROR")){ - System.out.println("取消订单+关单"); - orderService.cancelOrder(out_trade_no); - try { - PayUtil.closeOrder(out_trade_no);//关单 - System.out.println("code,***"); - } catch (Exception e) { - e.printStackTrace(); - } - } - //支付成功 - if (trade_state.equals("SUCCESS")){ - System.out.println("支付成功"); - orderService.paySuccess(out_trade_no - ,getStringByRFC3339(success_time) - ,transaction_id - ,payer_total); - - System.out.println("code,SUCCESS"); - - } - } - } - - //查询订单 - public void queryOrder() throws Exception{ - PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PayConstants.PRIVATE_KEY); - // 获取证书管理器实例 - CertificatesManager certificatesManager = CertificatesManager.getInstance(); - // 向证书管理器增加需要自动更新平台证书的商户信息 - certificatesManager.putMerchant(PayConstants.MCH_ID, new WechatPay2Credentials(PayConstants.MCH_ID, - new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)), - PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8)); - // 从证书管理器中获取verifier - Verifier verifier = certificatesManager.getVerifier(PayConstants.MCH_ID); - CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create() - .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey) - .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(PayConstants.MCH_ID))) - .build(); -//*********************** - URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/id/"+"订单号"+"?mchid="+PayConstants.MCH_ID); - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.addHeader("Accept", "application/json"); - - CloseableHttpResponse response = httpClient.execute(httpGet); - - String bodyAsString = EntityUtils.toString(response.getEntity()); - System.out.println(bodyAsString); - } - - /** - * 支付成功时间格式化 - * - * 遵循rfc3339标准格式 - * 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE - * 示例值:2018-06-08T10:34:56+08:00 - * @param dateStr - * @return - */ - public static String getStringByRFC3339(String dateStr){ - DateTime dateTime = new DateTime(dateStr); - long timeInMillis = dateTime.toCalendar(Locale.getDefault()).getTimeInMillis(); - Date date = new Date(timeInMillis); - - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String time = format.format(date); - return time; - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/ShopCartController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/ShopCartController.java deleted file mode 100644 index adf45a8..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/ShopCartController.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.ruoyi.web.controller.app_shop; - -import cn.hutool.core.util.ObjectUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.RestResponse; -import com.ruoyi.shop.domain.ShopCart; -import com.ruoyi.shop.domain.ShopGoods; -import com.ruoyi.shop.mapper.ShopCartMapper; -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 javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.Map; -@Api(tags = "购物车", description = "提供购物车相关的API") -@RestController -@RequestMapping("/api/shopCart") -public class ShopCartController { - - @Resource - private ShopCartMapper shopCartMapper; - - @ApiOperation("加入购物车") - @PostMapping("/addShopCart") - public RestResponse addShopCart(@RequestBody ShopCart shopCart, HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - ShopCart s=shopCartMapper.selectOne(new QueryWrapper() - .eq("id_user",userId) - .eq("id_goods",shopCart.getIdGoods())); - if (ObjectUtil.isNotEmpty(s)){ - s.setCount(s.getCount()+1); - shopCartMapper.updateById(s); - return new RestResponse().setSuccess(true).setMessage("成功"); - } - shopCart.setIdUser(userId); - shopCartMapper.insert(shopCart); - return new RestResponse().setSuccess(true).setMessage("成功"); - } - - @ApiOperation("购物车删除商品") - @PostMapping("/removeShopCart") - public RestResponse removeShopCart(@RequestBody Map> map){ - List ids=map.get("ids"); - shopCartMapper.deleteBatchIds(ids); - return new RestResponse().setSuccess(true).setMessage("成功"); - } - - @ApiOperation("购物车商品列表") - @PostMapping("/shopCartList") - public RestResponse shopCartList(HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); - List list=shopCartMapper.cartList(userId); - return new RestResponse().setSuccess(true).setMessage("成功").setData(list); - } - - @ApiOperation("购物车修改商品数量") - @PostMapping("/changeCount") - public RestResponse changeCount(@RequestBody ShopCart shopCart){ - shopCartMapper.updateById(shopCart); - return new RestResponse().setSuccess(true).setMessage("成功"); - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/dto/ShopOrderDto.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/dto/ShopOrderDto.java deleted file mode 100644 index 98a9217..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/dto/ShopOrderDto.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.ruoyi.web.controller.app_shop.dto; - -import com.ruoyi.shop.domain.ShopGoods; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -@Data -public class ShopOrderDto { - - /** - * 省 - */ - @ApiModelProperty("省") - private String province; - - /** - * 市 - */ - private String city; - - /** - * 详细地址 - */ - private String address; - /** - * 电话 - */ - private String phone; - - /** - * 收货人名称 - */ - private String name; - - private String message; - private List list; - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/AppreciateController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/AppreciateController.java similarity index 83% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/AppreciateController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/AppreciateController.java index a142c68..cf2bf80 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/AppreciateController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/AppreciateController.java @@ -1,10 +1,10 @@ -package com.ruoyi.web.controller.app_shop; +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.shop.domain.YjAppreciate; -import com.ruoyi.shop.service.impl.YjAppreciateServiceImpl; +import com.ruoyi.basic.domain.YjAppreciate; +import com.ruoyi.basic.service.impl.YjAppreciateServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; @@ -18,7 +18,7 @@ import java.util.List; /** * 瑜伽欣赏 */ -@Api(tags = "瑜伽欣赏", description = "提供瑜伽欣赏相关的API") +@Api(tags = "034-瑜伽欣赏", description = "提供瑜伽欣赏相关的API") @RestController @RequestMapping("/api/appreciate") public class AppreciateController { @@ -35,7 +35,8 @@ public class AppreciateController { @PostMapping("/getList") public RestResponse getList(@RequestBody YjAppreciate appreciate){ List list= service.list(new QueryWrapper() - .eq("merchan_id",appreciate.getMerchanId()) + .select("id,title,image,read_num,start_time") + .eq("visit_store",appreciate.getVisitStore()) .eq("status",true) .orderByDesc("modify_time")); return new RestResponse().setSuccess(true).setMessage("成功").setData(list); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/ContextAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/ContextAppController.java similarity index 64% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/ContextAppController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/ContextAppController.java index 5db3ef4..030bcf5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_course/ContextAppController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/ContextAppController.java @@ -1,9 +1,12 @@ -package com.ruoyi.web.controller.app_course; +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.service.ContextServicelmpl; +import com.ruoyi.course.domain.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 io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -16,7 +19,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.Map; -@Api(tags = "教练", description = "获取教练信息") +@Api(tags = "022-教练", description = "获取教练信息") @RestController @RequestMapping("/api/context") public class ContextAppController extends BaseController { @@ -24,11 +27,12 @@ public class ContextAppController extends BaseController { ContextServicelmpl contextService; @Autowired SysUserServiceImpl userService; + @Autowired + ScClaTimeService scClaTimeService; @ApiOperation("教练列表") @PostMapping(value = "/getList") public RestResponse findList1(@RequestBody Map params) { - params.put("releases",true); List list =contextService.getList(params); return new RestResponse().setSuccess(true).setMessage("成功").setData(list); } @@ -36,7 +40,14 @@ public class ContextAppController extends BaseController { @ApiOperation("教练详细信息") @PostMapping("/getOne") public RestResponse update(@RequestBody Map params) { - Context c =contextService.getList(params).get(0); + Context c =contextService.getOne(params); + return RestResponse.success().setData(c); + } + @ApiOperation("教练课程表") + @PostMapping("/searchListForCalendar") + public RestResponse update(@RequestBody ReqSearchClaTime reqSearchClaTime) { + RespBusinessClaTimeCalendar c =scClaTimeService.searchListForCalendar(reqSearchClaTime); return RestResponse.success().setData(c); } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/HealthyController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/HealthyController.java similarity index 83% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/HealthyController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/HealthyController.java index adfb36e..997033f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/HealthyController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/HealthyController.java @@ -1,10 +1,10 @@ -package com.ruoyi.web.controller.app_shop; +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.shop.domain.YjHealthy; -import com.ruoyi.shop.service.impl.YjHealthyServiceImpl; +import com.ruoyi.basic.domain.YjHealthy; +import com.ruoyi.basic.service.impl.YjHealthyServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; @@ -18,7 +18,7 @@ import java.util.List; /** * 健康饮食 */ -@Api(tags = "健康饮食", description = "提供健康饮食相关的API") +@Api(tags = "036-健康饮食", description = "提供健康饮食相关的API") @RestController @RequestMapping("/api/healthy") public class HealthyController { @@ -34,7 +34,8 @@ public class HealthyController { @PostMapping("/getList") public RestResponse getList(@RequestBody YjHealthy healthy){ List list= service.list(new QueryWrapper() - .eq("merchan_id",healthy.getMerchanId()) + .select("id,title,image,read_num,start_time") + .eq("visit_store",healthy.getVisitStore()) .eq("status",true) .orderByDesc("modify_time")); return new RestResponse().setSuccess(true).setMessage("成功").setData(list); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/IndexController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/IndexController.java new file mode 100644 index 0000000..8fe7087 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/IndexController.java @@ -0,0 +1,77 @@ +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.service.YjAppUserService; +import com.ruoyi.common.core.domain.entity.AppUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.basic.domain.YjStore; +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 javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Api(tags = "021-首页", description = "提供首页信息相关的API") +@RestController +@RequestMapping("/api/index") +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().select("tenant_id").eq("id",appUser.getVisitStore())); + List list= storeService.list(new QueryWrapper() + .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); + } + + @ApiOperation("切换门店") + @PostMapping("/changeStore") + public RestResponse changeStore(@RequestBody Map map){ + String visitStoreId =map.get("visitStoreId"); + //登录用户的访问门店字段修改 + AppUser appUser = SecurityUtils.getAppLoginUser().getAppUser(); + appUserService.update(new UpdateWrapper() + .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); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/InheritController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/InheritController.java similarity index 83% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/InheritController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/InheritController.java index 34d425a..62c5b3a 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/InheritController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/InheritController.java @@ -1,10 +1,10 @@ -package com.ruoyi.web.controller.app_shop; +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.shop.domain.YjInherit; -import com.ruoyi.shop.service.impl.YjInheritServiceImpl; +import com.ruoyi.basic.domain.YjInherit; +import com.ruoyi.basic.service.impl.YjInheritServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; @@ -18,7 +18,7 @@ import java.util.List; /** * 瑜伽传承 */ -@Api(tags = "瑜伽传承", description = "提供瑜伽传承相关的API") +@Api(tags = "031-瑜伽传承", description = "提供瑜伽传承相关的API") @RestController @RequestMapping("/api/inherit") public class InheritController { @@ -35,7 +35,8 @@ public class InheritController { @PostMapping("/getList") public RestResponse getList(@RequestBody YjInherit inherit){ List list= inheritService.list(new QueryWrapper() - .eq("merchan_id",inherit.getMerchanId()) + .select("id,title,image,read_num,start_time") + .eq("visit_store",inherit.getVisitStore()) .eq("status",true) .orderByDesc("modify_time")); return new RestResponse().setSuccess(true).setMessage("成功").setData(list); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/PracticeMomentsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/PracticeMomentsController.java similarity index 82% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/PracticeMomentsController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/PracticeMomentsController.java index 42d1ca3..4977b1b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/PracticeMomentsController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/PracticeMomentsController.java @@ -1,9 +1,9 @@ -package com.ruoyi.web.controller.app_shop; +package com.ruoyi.web.controller.basic; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ruoyi.RestResponse; -import com.ruoyi.shop.domain.YjPracticeMoments; -import com.ruoyi.shop.service.impl.YjPracticeMomentsServiceImpl; +import com.ruoyi.basic.domain.YjPracticeMoments; +import com.ruoyi.basic.service.impl.YjPracticeMomentsServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; @@ -17,7 +17,7 @@ import java.util.List; /** * 练习瞬间 */ -@Api(tags = "练习瞬间", description = "提供练习瞬间相关的API") +@Api(tags = "033-练习瞬间", description = "提供练习瞬间相关的API") @RestController @RequestMapping("/api/moments") public class PracticeMomentsController { @@ -34,7 +34,8 @@ public class PracticeMomentsController { @PostMapping("/getList") public RestResponse getList(@RequestBody YjPracticeMoments moments){ List list=momentsService.list(new QueryWrapper() - .eq("merchan_id",moments.getMerchanId()) + .select("id,title,image,read_num,start_time") + .eq("visit_store",moments.getVisitStore()) .eq("status",true) .orderByDesc("modify_time")); return new RestResponse().setSuccess(true).setMessage("成功").setData(list); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/SenseController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/SenseController.java similarity index 83% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/SenseController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/SenseController.java index 594ff24..b8c27d3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/SenseController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/SenseController.java @@ -1,10 +1,10 @@ -package com.ruoyi.web.controller.app_shop; +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.shop.domain.YjSense; -import com.ruoyi.shop.service.impl.YjSenseServiceImpl; +import com.ruoyi.basic.domain.YjSense; +import com.ruoyi.basic.service.impl.YjSenseServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; @@ -18,7 +18,7 @@ import java.util.List; /** * 瑜伽常识 */ -@Api(tags = "瑜伽常识", description = "提供瑜伽常识相关的API") +@Api(tags = "035-瑜伽常识", description = "提供瑜伽常识相关的API") @RestController @RequestMapping("/api/sense") public class SenseController { @@ -34,7 +34,8 @@ public class SenseController { @PostMapping("/getList") public RestResponse getList(@RequestBody YjSense sense){ List list= service.list(new QueryWrapper() - .eq("merchan_id",sense.getMerchanId()) + .select("id,title,image,read_num,start_time") + .eq("visit_store",sense.getVisitStore()) .eq("status",true) .orderByDesc("modify_time")); return new RestResponse().setSuccess(true).setMessage("成功").setData(list); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/MerchantController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/StoreController.java similarity index 61% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/MerchantController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/StoreController.java index af5b312..f0eae7f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/MerchantController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/StoreController.java @@ -1,9 +1,9 @@ -package com.ruoyi.web.controller.app_shop; +package com.ruoyi.web.controller.basic; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ruoyi.RestResponse; -import com.ruoyi.shop.domain.YjMerchant; -import com.ruoyi.shop.service.impl.YjMerchantServiceImpl; +import com.ruoyi.basic.domain.YjStore; +import com.ruoyi.basic.service.impl.YjStoreServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; @@ -12,28 +12,29 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.Map; /** * 门店 */ -@Api(tags = "门店", description = "提供门店相关的API") +@Api(tags = "032-了解场馆", description = "提供门店相关的API") @RestController -@RequestMapping("/api/merchan") -public class MerchantController { +@RequestMapping("/api/store") +public class StoreController { @Resource - private YjMerchantServiceImpl merchantService; + private YjStoreServiceImpl merchantService; /** * 企业简介+门店列表 - * @param merchan + * @param map * @return */ @ApiOperation(value = "创始人+企业简介+门店列表") @PostMapping("/getList") - public RestResponse getList(@RequestBody YjMerchant merchan){ - YjMerchant m=merchantService.getOne(new QueryWrapper() + public RestResponse getList(@RequestBody Map map){ + YjStore m=merchantService.getOne(new QueryWrapper() .select("id,enterprise_name,address,phone,founder,profile") - .eq("id",merchan.getId())); + .eq("id",map.get("visitStore"))); return new RestResponse().setSuccess(true).setMessage("成功").setData(m); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/WeChatController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/WeChatController.java new file mode 100644 index 0000000..f353700 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/WeChatController.java @@ -0,0 +1,46 @@ +package com.ruoyi.web.controller.basic; + +import cn.hutool.crypto.SecureUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; + +@RestController +public class WeChatController { + @Value("${wechat.token}") + String TOKEN; + + + /** + * + * @param signature + * @param timestamp + * @param nonce + * @param echostr + * @return + */ + @GetMapping("") + public String check(@RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestParam("echostr") String echostr){ + return this.check1(signature,timestamp,nonce,echostr); + } + + public String check1(String signature,String timestamp,String nonce,String echostr) { + String[] arr = new String[]{TOKEN,timestamp,nonce}; + Arrays.sort(arr); + StringBuilder content = new StringBuilder(); + for (String s : arr) { + content.append(s); + } + String temp = SecureUtil.sha1(content.toString()); + if (temp.equals(signature)){ + return echostr; + } + return null; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/dto/AppLoginUser.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/dto/AppLoginUser.java new file mode 100644 index 0000000..0f82022 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/basic/dto/AppLoginUser.java @@ -0,0 +1,62 @@ +package com.ruoyi.web.controller.basic.dto; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@ApiModel(value = "AppLoginUser", description = "app登录用户信息") +@Data +public class AppLoginUser +{ + private static final long serialVersionUID = 1L; + + /** 用户ID */ + @ApiModelProperty("用户ID") + @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号") + private Long userId; + + /** 用户账号 */ + @ApiModelProperty("用户昵称") + @Excel(name = "登录名称") + private String userName; + + /** 用户昵称 */ + @ApiModelProperty("用户名称") + @Excel(name = "用户名称") + private String nickName; + + /** 用户邮箱 */ + @ApiModelProperty("用户邮箱") + @Excel(name = "用户邮箱") + private String email; + + /** 手机号码 */ + @ApiModelProperty("手机号码") + @Excel(name = "手机号码") + private String phonenumber; + + /** 用户性别 */ + @ApiModelProperty("用户性别;0=男,1=女,2=未知") + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String sex; + + /** 用户头像 */ + @ApiModelProperty("用户头像") + private String avatar; + + /** 角色ID */ + @ApiModelProperty("角色ID;顾问:103 ;教练:104 ;店长:105 ;普通用户:107;") + private Long roleId; + + /** 所属门店id */ + @ApiModelProperty("所属门店id") + private String venId; + + @ApiModelProperty("设备id") + private String registerId; + @ApiModelProperty("访问/浏览门店id") + private String visitStore; + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java deleted file mode 100644 index e882775..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.ruoyi.web.controller.common; - -import com.ruoyi.common.config.RuoYiConfig; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.file.FileUploadUtils; -import com.ruoyi.common.utils.file.FileUtils; -import com.ruoyi.framework.config.ServerConfig; -import com.ruoyi.shop.service.impl.YjLinkServiceImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.List; - -/** - * 通用请求处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/common") -public class CommonController -{ - private static final Logger log = LoggerFactory.getLogger(CommonController.class); - - @Autowired - private ServerConfig serverConfig; - @Autowired - private YjLinkServiceImpl yjLinkService; - - private static final String FILE_DELIMETER = ","; - - /** - * 通用下载请求 - * - * @param fileName 文件名称 - * @param delete 是否删除 - */ - @GetMapping("/download") - public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) - { - try - { - if (!FileUtils.checkAllowDownload(fileName)) - { - throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); - } - String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); - String filePath = RuoYiConfig.getDownloadPath() + fileName; - - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); - FileUtils.setAttachmentResponseHeader(response, realFileName); - FileUtils.writeBytes(filePath, response.getOutputStream()); - if (delete) - { - FileUtils.deleteFile(filePath); - } - } - catch (Exception e) - { - log.error("下载文件失败", e); - } - } - - /** - * 通用上传请求(单个) - */ - @PostMapping("/upload") - public AjaxResult uploadFile(MultipartFile file) throws Exception - { - try - { - // 上传文件路径 - String filePath = RuoYiConfig.getUploadPath(); - // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file); - - yjLinkService.add(fileName,"picture"); - - String url = serverConfig.getUrl() + fileName; - AjaxResult ajax = AjaxResult.success(); - ajax.put("url", url); - ajax.put("fileName", fileName); - ajax.put("newFileName", FileUtils.getName(fileName)); - ajax.put("originalFilename", file.getOriginalFilename()); - return ajax; - } - catch (Exception e) - { - return AjaxResult.error(e.getMessage()); - } - } - @PostMapping("/uploadVideo") - public AjaxResult uploadVideo(MultipartFile file) throws Exception - { - try - { - // 上传文件路径 - String filePath = RuoYiConfig.getUploadPath(); - // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file); - - yjLinkService.add(fileName,"video"); - - String url = serverConfig.getUrl() + fileName; - AjaxResult ajax = AjaxResult.success(); - ajax.put("url", url); - ajax.put("fileName", fileName); - ajax.put("newFileName", FileUtils.getName(fileName)); - ajax.put("originalFilename", file.getOriginalFilename()); - return ajax; - } - catch (Exception e) - { - return AjaxResult.error(e.getMessage()); - } - } - @PostMapping("/uploadSp") - public AjaxResult uploadFileSp(MultipartFile file) throws Exception - { - try - { - // 上传文件路径 - String filePath = RuoYiConfig.getUploadPath(); - // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file); - - yjLinkService.add(fileName,"video"); - - String url = serverConfig.getUrl() + fileName; - AjaxResult ajax = AjaxResult.success(); - ajax.put("url", url); - ajax.put("fileName", fileName); - ajax.put("newFileName", FileUtils.getName(fileName)); - ajax.put("originalFilename", file.getOriginalFilename()); - return ajax; - } - catch (Exception e) - { - return AjaxResult.error(e.getMessage()); - } - } - - /** - * 通用上传请求(多个) - */ - @PostMapping("/uploads") - public AjaxResult uploadFiles(List files) throws Exception - { - try - { - // 上传文件路径 - String filePath = RuoYiConfig.getUploadPath(); - List urls = new ArrayList(); - List fileNames = new ArrayList(); - List newFileNames = new ArrayList(); - List originalFilenames = new ArrayList(); - for (MultipartFile file : files) - { - // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file); - - yjLinkService.add(fileName,"picture"); - - String url = serverConfig.getUrl() + fileName; - urls.add(url); - fileNames.add(fileName); - newFileNames.add(FileUtils.getName(fileName)); - originalFilenames.add(file.getOriginalFilename()); - } - AjaxResult ajax = AjaxResult.success(); - ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); - ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); - ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); - ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); - return ajax; - } - catch (Exception e) - { - return AjaxResult.error(e.getMessage()); - } - } - - /** - * 本地资源通用下载 - */ - @GetMapping("/download/resource") - public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) - throws Exception - { - try - { - if (!FileUtils.checkAllowDownload(resource)) - { - throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); - } - // 本地资源路径 - String localPath = RuoYiConfig.getProfile(); - // 数据库资源地址 - String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); - // 下载名称 - String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); - FileUtils.setAttachmentResponseHeader(response, downloadName); - FileUtils.writeBytes(downloadPath, response.getOutputStream()); - } - catch (Exception e) - { - log.error("下载文件失败", e); - } - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/course/CourseController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/course/CourseController.java new file mode 100644 index 0000000..ad7687e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/course/CourseController.java @@ -0,0 +1,32 @@ +package com.ruoyi.web.controller.course; + +import com.ruoyi.RestResponse; +import com.ruoyi.common.core.controller.BaseController; +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 java.util.Map; + +@Api(tags = "040-教练", description = "获取商品及课程分类") +@RestController +@RequestMapping("/api/course/category") +public class CourseController extends BaseController { +// @Autowired +// ContextServicelmpl contextService; +// @Autowired +// SysUserServiceImpl userService; + + @ApiOperation("商品及课程类型列表") + @PostMapping(value = "/getList") + public RestResponse findList(@RequestBody Map params) { +// List list =contextService.getList(params); + return new RestResponse().setSuccess(true).setMessage("成功"); + } + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/FileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/FileController.java new file mode 100644 index 0000000..8b1b520 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/FileController.java @@ -0,0 +1,40 @@ +package com.ruoyi.web.controller.im; + +import com.ruoyi.im.domain.vo.UploadImageVO; +import com.ruoyi.im.service.FileService; +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 lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.util.Strings; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@Slf4j +@RestController +@Tag(name = "文件上传") +@RequiredArgsConstructor +@RequestMapping("/api") +public class FileController { + + private final FileService fileService; + + @Operation(summary = "上传图片", description = "上传图片,上传后返回原图和缩略图的url") + @PostMapping("/image/upload") + public Result uploadImage(@RequestParam("file") MultipartFile file, + @RequestParam(defaultValue = "true") Boolean isPermanent) { + return ResultUtils.success(fileService.uploadImage(file,isPermanent)); + } + + @Operation(summary = "上传文件", description = "上传文件,上传后返回文件url") + @PostMapping("/file/upload") + public Result uploadFile(@RequestParam("file") MultipartFile file) { + return ResultUtils.success(fileService.uploadFile(file), Strings.EMPTY); + } + +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/FriendController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/FriendController.java new file mode 100644 index 0000000..ebcd8e7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/FriendController.java @@ -0,0 +1,65 @@ +package com.ruoyi.web.controller.im; + +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.im.domain.vo.FriendVO; +import com.ruoyi.im.domain.vo.UserVO; +import com.ruoyi.im.service.FriendService; +import com.ruoyi.web.controller.im.result.Result; +import com.ruoyi.web.controller.im.result.ResultUtils; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotNull; +import java.util.List; + + +@RestController +@RequestMapping("/api/friend") +@RequiredArgsConstructor +public class FriendController { + + private final FriendService friendService; + private final YjAppUserService appUserService; + @GetMapping("/list") + @Operation(summary = "好友列表", description = "获取好友列表") + public Result> findFriends() { + return ResultUtils.success(friendService.findFriends()); + } + + @GetMapping("/find/{phonenumber}") + @Operation(summary = "查找用户", description = "根据电话查找用户") + public Result findById(@NotNull @PathVariable("phonenumber") String phonenumber) { + //权限:课程顾问 店长 教练 查询客户信息 + //todo + AppUser appUser=appUserService.getOne(new QueryWrapper().eq("phoneNumber",phonenumber)); + ResultUtils.success(appUser); + return null; + } + + @RepeatSubmit + @PostMapping("/add") + @Operation(summary = "添加好友", description = "双方建立好友关系") + public Result addFriend(@NotNull(message = "好友id不可为空") @RequestParam Long friendId) { + friendService.addFriend(friendId); + return ResultUtils.success(); + } + + @GetMapping("/find/{friendId}") + @Operation(summary = "查找好友信息", description = "查找好友信息") + public Result findFriend(@NotNull(message = "好友id不可为空") @PathVariable Long friendId) { + return ResultUtils.success(friendService.findFriend(friendId)); + } + + + @DeleteMapping("/delete/{friendId}") + @Operation(summary = "删除好友", description = "解除好友关系") + public Result delFriend(@NotNull(message = "好友id不可为空") @PathVariable Long friendId) { + friendService.delFriend(friendId); + return ResultUtils.success(); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/PrivateMessageController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/PrivateMessageController.java new file mode 100644 index 0000000..7b58497 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/PrivateMessageController.java @@ -0,0 +1,73 @@ +package com.ruoyi.web.controller.im; + + +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.web.controller.im.result.Result; +import com.ruoyi.web.controller.im.result.ResultUtils; +import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.io.IOException; +import java.util.List; + +@Tag(name = "私聊消息") +@RestController +@RequestMapping("/api/message/private") +@RequiredArgsConstructor +public class PrivateMessageController { + + private final PrivateMessageService privateMessageService; + + @PostMapping("/send") + @Operation(summary = "发送消息", description = "发送私聊消息") + public Result sendMessage(@Valid @RequestBody PrivateMessageDTO vo) { + return ResultUtils.success(privateMessageService.sendMessage(vo)); + } + + /** + * + * @param minId 最大已读消息的id + * @return + */ + @GetMapping("/pullOfflineMessage") + @Operation(summary = "拉取离线消息", description = "拉取离线消息,消息将通过webscoket异步推送") + public Result pullOfflineMessage(@RequestParam Long minId) { + privateMessageService.pullOfflineMessage(minId); + return ResultUtils.success(); + } + + @PutMapping("/readed") + @Operation(summary = "消息已读", description = "将会话中接收的消息状态置为已读") + public Result readedMessage(@RequestParam Long friendId) { + privateMessageService.readedMessage(friendId); + return ResultUtils.success(); + } + @GetMapping("/maxReadedId") + @Operation(summary = "获取最大已读消息的id", description = "获取某个会话中已读消息的最大id") + public Result getMaxReadedId(@RequestParam Long friendId) { + return ResultUtils.success(privateMessageService.getMaxReadedId(friendId)); + } + +// @GetMapping("/history") + @Operation(summary = "查询聊天记录", description = "查询聊天记录") + public Result> recallMessage( + @NotNull(message = "好友id不能为空") @RequestParam Long friendId, + @NotNull(message = "页码不能为空") @RequestParam Long page, + @NotNull(message = "size不能为空") @RequestParam Long size) { + return ResultUtils.success(privateMessageService.findHistoryMessage(friendId, page, size)); + } + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/SystemController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/SystemController.java new file mode 100644 index 0000000..c2496df --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/SystemController.java @@ -0,0 +1,34 @@ +package com.ruoyi.web.controller.im; + + +import com.ruoyi.common.config.WebrtcConfig; +import com.ruoyi.im.domain.vo.SystemConfigVO; +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.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") +@RequiredArgsConstructor +public class SystemController { + + private final WebrtcConfig webrtcConfig; + + @GetMapping("/config") + @Operation(summary = "加载系统配置", description = "加载系统配置") + public Result loadConfig() { + return ResultUtils.success(new SystemConfigVO(webrtcConfig)); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/WebrtcPrivateController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/WebrtcPrivateController.java new file mode 100644 index 0000000..b09cdfd --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/WebrtcPrivateController.java @@ -0,0 +1,76 @@ +package com.ruoyi.web.controller.im; + +import com.ruoyi.im.service.WebrtcPrivateService; +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 com.ruoyi.web.controller.im.result.Result; + +@Tag(name = "单人通话") +@RestController +@RequestMapping("/webrtc/private") +@RequiredArgsConstructor +public class WebrtcPrivateController { + + private final WebrtcPrivateService webrtcPrivateService; + + + @Operation(summary = "呼叫视频通话") + @PostMapping("/call") + public Result call(@RequestParam Long uid, @RequestParam(defaultValue = "video") String mode, + @RequestBody String offer) { + webrtcPrivateService.call(uid, mode, offer); + return ResultUtils.success(); + } + + @Operation(summary = "接受视频通话") + @PostMapping("/accept") + public Result accept(@RequestParam Long uid, @RequestBody String answer) { + webrtcPrivateService.accept(uid, answer); + return ResultUtils.success(); + } + + @Operation(summary = "拒绝视频通话") + @PostMapping("/reject") + public Result reject(@RequestParam Long uid) { + webrtcPrivateService.reject(uid); + return ResultUtils.success(); + } + + @Operation(summary = "取消呼叫") + @PostMapping("/cancel") + public Result cancel(@RequestParam Long uid) { + webrtcPrivateService.cancel(uid); + return ResultUtils.success(); + } + + @Operation(summary = "呼叫失败") + @PostMapping("/failed") + public Result failed(@RequestParam Long uid, @RequestParam String reason) { + webrtcPrivateService.failed(uid, reason); + return ResultUtils.success(); + } + + @Operation(summary = "挂断") + @PostMapping("/handup") + public Result handup(@RequestParam Long uid) { + webrtcPrivateService.handup(uid); + return ResultUtils.success(); + } + + @PostMapping("/candidate") + @Operation(summary = "同步candidate") + public Result candidate(@RequestParam Long uid, @RequestBody String candidate) { + webrtcPrivateService.candidate(uid, candidate); + return ResultUtils.success(); + } + + @Operation(summary = "心跳") + @PostMapping("/heartbeat") + public Result heartbeat(@RequestParam Long uid) { + webrtcPrivateService.heartbeat(uid); + return ResultUtils.success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/result/Result.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/result/Result.java new file mode 100644 index 0000000..8d3ff74 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/result/Result.java @@ -0,0 +1,14 @@ +package com.ruoyi.web.controller.im.result; + +import lombok.Data; + +@Data +public class Result { + + private int code; + + private String message; + + private T data; + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/result/ResultUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/result/ResultUtils.java new file mode 100644 index 0000000..1ea96d7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/result/ResultUtils.java @@ -0,0 +1,64 @@ +package com.ruoyi.web.controller.im.result; + + +import com.ruoyi.common.im.enums.ResultCode; + +public final class ResultUtils { + + private ResultUtils() { + } + + public static Result success() { + Result result = new Result<>(); + result.setCode(ResultCode.SUCCESS.getCode()); + result.setMessage(ResultCode.SUCCESS.getMsg()); + return result; + } + + public static Result success(T data) { + Result result = new Result<>(); + result.setCode(ResultCode.SUCCESS.getCode()); + result.setMessage(ResultCode.SUCCESS.getMsg()); + result.setData(data); + return result; + } + + public static Result success(T data, String messsage) { + Result result = new Result<>(); + result.setCode(ResultCode.SUCCESS.getCode()); + result.setMessage(messsage); + result.setData(data); + return result; + } + + public static Result success(String messsage) { + Result result = new Result<>(); + result.setCode(ResultCode.SUCCESS.getCode()); + result.setMessage(messsage); + return result; + } + + public static Result error(Integer code, String messsage) { + Result result = new Result<>(); + result.setCode(code); + result.setMessage(messsage); + return result; + } + + + public static Result error(ResultCode resultCode, String messsage) { + Result result = new Result<>(); + result.setCode(resultCode.getCode()); + result.setMessage(messsage); + return result; + } + + public static Result error(ResultCode resultCode) { + Result result = new Result<>(); + result.setCode(resultCode.getCode()); + result.setMessage(resultCode.getMsg()); + return result; + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/UserSession.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/UserSession.java new file mode 100644 index 0000000..de9cad1 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/UserSession.java @@ -0,0 +1,21 @@ +package com.ruoyi.web.controller.im.session; + + +import com.ruoyi.common.im.model.IMSessionInfo; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class UserSession extends IMSessionInfo { + + /** + * 用户名称 + */ + private String userName; + + /** + * 用户昵称 + */ + private String nickName; +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcGroupSession.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcGroupSession.java new file mode 100644 index 0000000..d13dabd --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcGroupSession.java @@ -0,0 +1,34 @@ +package com.ruoyi.web.controller.im.session; + + +import com.ruoyi.common.im.model.IMUserInfo; +import lombok.Data; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author: Blue + * @date: 2024-06-01 + * @version: 1.0 + */ +@Data +public class WebrtcGroupSession { + + /** + * 通话发起者 + */ + private IMUserInfo host; + + /** + * 所有被邀请的用户列表 + */ + private List userInfos; + + /** + * 已经进入通话的用户列表 + */ + private List inChatUsers = new LinkedList<>(); + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcPrivateSession.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcPrivateSession.java new file mode 100644 index 0000000..215de50 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcPrivateSession.java @@ -0,0 +1,39 @@ +package com.ruoyi.web.controller.im.session; + +import lombok.Data; + +/* + * webrtc 会话信息 + * @Author Blue + * @Date 2022/10/21 + */ +@Data +public class WebrtcPrivateSession { + /** + * 发起者id + */ + private Long callerId; + /** + * 发起者终端类型 + */ + private Integer callerTerminal; + + /** + * 接受者id + */ + private Long acceptorId; + + /** + * 接受者终端类型 + */ + private Integer acceptorTerminal; + + /** + * 通话模式 + */ + private String mode; + /** + * 开始聊天时间戳 + */ + private Long chatTimeStamp; +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcUserInfo.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcUserInfo.java new file mode 100644 index 0000000..4fcb20a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/im/session/WebrtcUserInfo.java @@ -0,0 +1,28 @@ +package com.ruoyi.web.controller.im.session; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author: Blue + * @date: 2024-06-02 + * @version: 1.0 + */ +@Data +@Schema(description = "用户信息") +public class WebrtcUserInfo { + @Schema(description = "用户id") + private Long id; + + @Schema(description = "用户昵称") + private String nickName; + + @Schema(description = "用户头像") + private String headImage; + + @Schema(description = "是否开启摄像头") + private Boolean isCamera; + + @Schema(description = "是否开启麦克风") + private Boolean isMicroPhone; +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/login/AppLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/login/AppLoginController.java new file mode 100644 index 0000000..36dec11 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/login/AppLoginController.java @@ -0,0 +1,143 @@ +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.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.basic.domain.dto.StoreDto; +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.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 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") +public class AppLoginController { + + @Autowired + private AppLoginService appLoginService; + + @Autowired + private YjAppUserServiceImpl appUserService; + + @Autowired + private YjStoreMapper storeMapper; + + + /** + * 注册 + * @param loginBody + * @return + */ + @PostMapping("/register") + public AjaxResult register(@RequestBody AppUserLoginBody loginBody){ + AppUser appUser=new AppUser(); + appUser.setPhoneNumber("15004070930"); + appUser.setPassword(SecurityUtils.encryptPassword(loginBody.getPassword())); + appUser.setStatus(1); + appUser.setVisitStore("14b8471ff004e074e928d795053b4233"); + + appUserService.save(appUser); + //todo 默认visitstore + //todo openid + + return null; + } + + /** + * 账号密码注册 手机号+验证码+密码 + * @param loginBody + * @return + */ + @ApiOperation("登录") + @PostMapping("/login") + public AjaxResult login(@RequestBody AppUserLoginBody loginBody){ + AjaxResult ajax = AjaxResult.success(); + String token=appLoginService.login(loginBody.getPhonenumber(),loginBody.getPassword(),loginBody.getCode(),loginBody.getUuid(),loginBody.getRegisterId(),loginBody.getMiniAppCode()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @ApiOperation(value = "获取用户信息") + @GetMapping("/getInfo") + public AjaxResult getInfo() + { + AppUser user = SecurityUtils.getAppLoginUser().getAppUser(); + AjaxResult ajax = AjaxResult.success(); + + ajax.put("appLoginUser", user); + ajax.put("visitStore",getIndex(user.getVisitStore())); + return ajax; + } + + + @Resource + private YjStoreServiceImpl merchantService; + + + public Map getIndex(String visitStore){ + YjStore yjStore; + Map m=new HashMap(); + if (StrUtil.isNotEmpty(visitStore)){ + yjStore=merchantService.getById(visitStore); + }else { + yjStore= merchantService.list().get(0); + } + 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 m; + } + + + + /** + * 用户当前经纬度 用来查附近门店 + * @param address(未使用,获取全部门店) + * @return + */ + @GetMapping("/getStoreList") + public AjaxResult getStoreList(String address) { + + AjaxResult ajax = AjaxResult.success(); + List dtoList= storeMapper.getListForLogin(); + dtoList.forEach(l->{ + l.setChildList(storeMapper.getChilds(l.getId())); + }); + ajax.put("storeList",dtoList); + return ajax; + } + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/login/CaptchaController.java similarity index 91% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/login/CaptchaController.java index 6b03f19..b7acbbc 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/login/CaptchaController.java @@ -1,6 +1,9 @@ -package com.ruoyi.web.controller.common; +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; import com.ruoyi.common.constant.Constants; @@ -16,14 +19,15 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.imageio.ImageIO; -import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; /** * 验证码操作处理 - * + * * @author ruoyi */ @RestController @@ -37,14 +41,16 @@ public class CaptchaController @Autowired private RedisCache redisCache; - + @Autowired private ISysConfigService configService; + + /** * 生成验证码 */ @GetMapping("/captchaImage") - public AjaxResult getCode(HttpServletResponse response) throws IOException + public AjaxResult getCode() throws IOException { AjaxResult ajax = AjaxResult.success(); boolean captchaEnabled = configService.selectCaptchaEnabled(); @@ -92,4 +98,6 @@ public class CaptchaController ajax.put("img", Base64.encode(os.toByteArray())); return ajax; } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/ShopAddressController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/MemberAddressController.java similarity index 56% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/ShopAddressController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/MemberAddressController.java index 6bb5cee..bc21359 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/app_shop/ShopAddressController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/MemberAddressController.java @@ -1,21 +1,18 @@ -package com.ruoyi.web.controller.app_shop; +package com.ruoyi.web.controller.mall; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.ruoyi.RestResponse; -import com.ruoyi.shop.domain.ShopAddress; -import com.ruoyi.shop.mapper.ShopAddressMapper; -import com.ruoyi.shop.service.ShopAddressService; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.mall.domain.MemberAddress; +import com.ruoyi.mall.mapper.MemberAddressMapper; +import com.ruoyi.mall.service.MemberAddressService; 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.web.bind.annotation.*; import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; @@ -30,17 +27,22 @@ import java.util.List; @Api(tags = "用户地址", description = "提供用户地址相关的API") @RestController @RequestMapping("/api/address") -public class ShopAddressController { +public class MemberAddressController { @Resource - private ShopAddressMapper mapper; + private MemberAddressMapper mapper; @Resource - private ShopAddressService service; + private MemberAddressService service; + @ApiOperation("地址list") + @GetMapping("/addressList") + public RestResponse getAddressList(){ + return new RestResponse().setSuccess(true).setData(service.getAddressList()); + } @ApiOperation("新增收货地址") @PostMapping("/add") - public RestResponse add(@RequestBody ShopAddress address, HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); + public RestResponse add(@RequestBody MemberAddress address){ + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); address.setUserId(userId); if (address.getIsDefault()){ changeDefault(userId); @@ -50,13 +52,13 @@ public class ShopAddressController { } @ApiOperation("收货地址列表") - @PostMapping("/list") - public RestResponse list(HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); + @PostMapping("/memberAddressList") + public RestResponse list(){ + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); List columns=new ArrayList<>(); columns.add("add_time"); columns.add("is_default"); - List list=mapper.selectList(new QueryWrapper() + List list=mapper.selectList(new QueryWrapper() .eq("user_id",userId) .orderByDesc(columns)); return new RestResponse().setSuccess(true).setMessage("成功").setData(list); @@ -64,8 +66,8 @@ public class ShopAddressController { @ApiOperation("修改收货地址") @PostMapping("/edit") - public RestResponse edit(@RequestBody ShopAddress address, HttpServletRequest request){ - Long userId= Long.parseLong(request.getAttribute("userId").toString()); + public RestResponse edit(@RequestBody MemberAddress address){ + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); if (address.getIsDefault()){ changeDefault(userId); } @@ -75,13 +77,16 @@ public class ShopAddressController { @ApiOperation("删除收货地址") @PostMapping("/del") - public RestResponse del(@RequestBody ShopAddress address){ + public RestResponse del(@RequestBody MemberAddress address){ mapper.deleteById(address.getId()); return new RestResponse().setSuccess(true).setMessage("成功"); } public void changeDefault(Long userId){ - service.update(new UpdateWrapper().set("is_default",false).eq("user_id",userId)); + service.update(new UpdateWrapper().set("is_default",false).eq("user_id",userId)); } + + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/MemberCartController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/MemberCartController.java new file mode 100644 index 0000000..c52f79e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/MemberCartController.java @@ -0,0 +1,88 @@ +package com.ruoyi.web.controller.mall; + +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.mall.domain.MemberCart; +import com.ruoyi.mall.domain.query.MemberCartQuery; +import com.ruoyi.mall.domain.vo.MemberCartVO; +import com.ruoyi.mall.service.impl.MemberCartService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api/cart") +public class MemberCartController { + @Autowired + private MemberCartService memberCartService; + + /** + * 添加购物车 + * + * @return 购物车商品 + */ + @PostMapping("add") + public ResponseEntity add(@RequestBody MemberCart memberCart) { + return ResponseEntity.ok(memberCartService.insert(memberCart)); + } + + /** + * 购物车列表 + * + * @return 购物车列表 + */ + @GetMapping("list") + public ResponseEntity> list() { + MemberCartQuery query = new MemberCartQuery(); + query.setMemberId(SecurityUtils.getAppLoginUser().getAppUserId()); + return ResponseEntity.ok(memberCartService.selectList(query, null)); + } + + /** + * 当前用户的购物车商品数量 + * + * @return + */ + @GetMapping("goodscount") + public ResponseEntity goodscount() { + return ResponseEntity.ok(memberCartService.mineCartNum()); + } + /** + * 当前用户的购物车商品id列表 + * + * @return + */ + @GetMapping("cart-ids") + public ResponseEntity> cartIds() { + return ResponseEntity.ok(memberCartService.mineCartIds()); + } + + + + /** + * 修改购物车 + * + * @return 是否修改 + */ + @PostMapping("modify") + public ResponseEntity modify(@Valid @RequestBody MemberCart memberCart) { + return ResponseEntity.ok(memberCartService.update(memberCart)); + } + + /** + * 删除购物车商品 + * + * @return + */ + @DeleteMapping("remove") + public ResponseEntity remove(@RequestBody Map> map) { + List ids=map.get("ids"); + return ResponseEntity.ok(memberCartService.deleteByIds(ids)); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/OrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/OrderController.java new file mode 100644 index 0000000..b7c8a24 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/OrderController.java @@ -0,0 +1,246 @@ +package com.ruoyi.web.controller.mall; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.redis.RedisService; +import com.ruoyi.common.enums.AftersaleStatus; +import com.ruoyi.common.enums.OrderStatus; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.mall.domain.dto.DeliveryReq; +import com.ruoyi.mall.domain.form.*; +import com.ruoyi.mall.domain.order.Aftersale; +import com.ruoyi.mall.domain.order.Order; +import com.ruoyi.mall.domain.vo.*; +import com.ruoyi.mall.service.impl.AftersaleService; +import com.ruoyi.mall.service.impl.OrderService; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@RestController +@RequestMapping("/api/order") +@Slf4j +public class OrderController { + @Autowired + private RedisService redisService; + @Autowired + private OrderService service; + @Autowired + private AftersaleService aftersaleService; + + @ApiOperation("下单") + @PostMapping("/add") + public ResponseEntity submit(@RequestBody OrderSubmitForm form) { + Long memberId = SecurityUtils.getAppLoginUser().getAppUserId(); + String redisKey = "app_order_add" + memberId; + String redisValue = memberId + "_" + System.currentTimeMillis(); + try{ + redisService.lock(redisKey, redisValue, 60); + return ResponseEntity.ok(service.submit(form)); + }catch (Exception e){ + log.info("创建订单方法异常", e); + throw new RuntimeException(e.getMessage()); + }finally { + try { + redisService.unLock(redisKey, redisValue); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @ApiOperation("下单前校验") + @PostMapping("/addOrderCheck") + public ResponseEntity addOrderCheck(@RequestBody OrderCreateForm orderCreateForm){ + return ResponseEntity.ok(service.addOrderCheck(orderCreateForm)); + } + + @ApiOperation("订单支付") + @PostMapping("/orderPay") + public ResponseEntity orderPay(@RequestBody OrderPayForm req){ + log.info("订单支付","提交的数据:"+ JSONObject.toJSONString(req)); + String redisKey = "app_oms_order_pay_"+req.getPayId(); + String redisValue = req.getPayId()+"_"+System.currentTimeMillis(); + try { + redisService.lock(redisKey, redisValue, 60); + + req.setMemberId(SecurityUtils.getAppLoginUser().getAppUserId()); + return ResponseEntity.ok(service.orderPay(req)); + }catch (Exception e){ + log.error("支付方法异常", e); + throw new RuntimeException(e.getMessage()); + }finally { + try{ + redisService.unLock(redisKey,redisValue); + }catch (Exception e){ + log.error("",e); + } + } + } + + @ApiOperation("订单列表") + @GetMapping("/page") + public ResponseEntity> orderPage(Integer status, Pageable pageable){ + return ResponseEntity.ok(service.orderPage(status, SecurityUtils.getAppLoginUser().getAppUserId(), pageable)); + } + + @ApiOperation("订单详情") + @GetMapping("/orderDetail") + public ResponseEntity orderDetail(@RequestParam(required = false) Long orderId){ + if (orderId == null){ + throw new RuntimeException("系统繁忙"); + } + return ResponseEntity.ok(service.orderDetail(orderId)); + } + + @ApiOperation("确认收货") + @GetMapping("/orderComplete") + public ResponseEntity orderComplete(Long orderId) { + log.info("确认收货,订单id:"+orderId); + String redisKey = "app_oms_order_complete_"+orderId; + String redisValue = orderId+"_"+System.currentTimeMillis(); + try{ + redisService.lock(redisKey,redisValue,60); + return ResponseEntity.ok(service.orderComplete(orderId)); + }catch (Exception e){ + log.error("确认收货异常",e); + throw new RuntimeException(e.getMessage()); + }finally { + try{ + redisService.unLock(redisKey,redisValue); + }catch (Exception e){ + log.error("",e); + } + } + } + + @ApiOperation("订单数量统计") + @GetMapping("/countOrder") + public ResponseEntity orderNumCount(){ + Long memberId = SecurityUtils.getAppLoginUser().getAppUserId(); + return ResponseEntity.ok(service.orderNumCount(memberId)); + } + + @ApiOperation("取消订单") + @PostMapping("/orderCancel") + public ResponseEntity orderCancel(@RequestBody CancelOrderForm request){ + String redisKey = "app_oms_order_cancel_"+ request.getIdList().get(0); + String redisValue = request.getIdList().get(0)+"_"+System.currentTimeMillis(); + try{ + redisService.lock(redisKey,redisValue,60); + return ResponseEntity.ok(service.orderBatchCancel(request, SecurityUtils.getAppLoginUser().getAppUserId())); + }catch (Exception e){ + log.error("订单取消方法异常",e); + throw new RuntimeException("订单取消失败"); + }finally { + try { + redisService.unLock(redisKey,redisValue); + }catch (Exception e){ + log.error("",e); + } + } + } + + + + @ApiOperation("申请售后") + @PostMapping("/applyRefund") + public ResponseEntity applyRefund(@RequestBody ApplyRefundForm applyRefundForm){ + String redisKey = "app_oms_order_applyRefund_" + applyRefundForm.getOrderId(); + String redisValue = applyRefundForm.getOrderId() + "_" + System.currentTimeMillis(); + try{ + redisService.lock(redisKey, redisValue, 60); + Order order = service.applyRefund(applyRefundForm); + // 如果是未发货,系统自动退款 + if (order.getStatus().equals(OrderStatus.NOT_DELIVERED.getType())) { + DealWithAftersaleForm req = new DealWithAftersaleForm(); + req.setOrderId(applyRefundForm.getOrderId()); + req.setOptType(1); + aftersaleService.dealWith(req, order.getMemberId(), "直接发起退款"); + } + return ResponseEntity.ok(true); + }catch (Exception e){ + log.error("申请售后发生异常",e); + throw new RuntimeException(e.getMessage()); + }finally { + try { + redisService.unLock(redisKey, redisValue); + } catch (Exception e) { + log.error("", e); + } + } + } + + @ApiOperation("取消售后") + @GetMapping("/cancelRefund") + public ResponseEntity cancelRefund(Long orderId){ + log.info("【取消售后】订单id:" + orderId); + String redisKey = "app_oms_order_cancelRefund_" + orderId; + String redisValue = orderId + "_" + System.currentTimeMillis(); + try{ + redisService.lock(redisKey, redisValue, 60); + return ResponseEntity.ok(service.cancelRefund(orderId)); + }catch (Exception e){ + log.error("取消售后发生异常",e); + throw new RuntimeException(e.getMessage()); + }finally { + try { + redisService.unLock(redisKey, redisValue); + } catch (Exception e) { + log.error("", e); + } + } + } + + @ApiOperation("售后订单详情") + @GetMapping("/refundOrderDetail") + public ResponseEntity refundOrderDetail(@RequestParam Long orderId){ + return ResponseEntity.ok(service.refundOrderDetail(orderId)); + } + + @ApiOperation("用户提交退货单号") + @PostMapping("/aftersale/delivery") + public AjaxResult delivery(@RequestBody @Valid DeliveryReq req){ + log.info("用户提交退货单号","提交的数据:"+JSONObject.toJSONString(req)); + String redisKey = "app_oms_order_delivery_"+req.getOrderId(); + String redisValue = req.getOrderId()+"_"+System.currentTimeMillis(); + try { + redisService.lock(redisKey, redisValue, 60); + Order order = service.selectById(req.getOrderId()); + Aftersale aftersale = aftersaleService.queryAfterSale(req.getOrderId()); + if(order == null || aftersale == null){ + return AjaxResult.error("未查询到订单信息"); + } + //仅退款不需要退货 + if(aftersale.getType() == 1){ + return AjaxResult.error("仅退款不需要退货"); + } + if(aftersale.getStatus() != AftersaleStatus.WAIT.getType()){ + return AjaxResult.error("当前状态不可退货"); + } + //更新退款单 + aftersale.setRefundWpCode(req.getDeliveryCompanyCode()); + aftersale.setRefundWaybillCode(req.getDeliverySn()); + aftersaleService.update(aftersale); + + return AjaxResult.success(); + }catch (Exception e){ + log.error("用户提交退货单号异常", e); + return AjaxResult.error("提交发货信息失败"); + }finally { + try{ + redisService.unLock(redisKey,redisValue); + }catch (Exception e){ + log.error("",e); + } + } + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/PayNotifyController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/PayNotifyController.java new file mode 100644 index 0000000..11577eb --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/PayNotifyController.java @@ -0,0 +1,143 @@ +package com.ruoyi.web.controller.mall; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.mall.domain.dto.PayNotifyMessageDTO; +import com.ruoyi.mall.service.impl.OrderService; +import com.ruoyi.web.core.config.WechatPayConfig; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; +import com.wechat.pay.java.service.refund.model.RefundNotification; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 订单表Controller + * + * @author sjm + * @date 2023-04-05 + */ +@Api(description ="微信回调接口列表") +@RestController +@RequestMapping("/no-auth/wechat") +public class PayNotifyController { + private static final Logger log = LoggerFactory.getLogger(PayNotifyController.class); + + @Autowired + private OrderService OrderService; +// @Autowired +// private AftersaleService aftersaleService; + + private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + + /** + * 微信支付回调 + * @param request + * @throws IOException + */ + @PostMapping("/notify") + public void weChatPayNotify(HttpServletRequest request) throws Exception { + log.info("收到了微信支付回调"); + // 从请求头中获取信息 + String timestamp = request.getHeader("Wechatpay-Timestamp"); + String nonce = request.getHeader("Wechatpay-Nonce"); + String signature = request.getHeader("Wechatpay-Signature"); + String singType = request.getHeader("Wechatpay-Signature-Type"); + String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial"); + // 拿到请求体body + StringBuilder requestBody = new StringBuilder(); + String line; + BufferedReader reader; + reader = request.getReader(); + while (null != (line = reader.readLine())) { + requestBody.append(line); + } + // 构造 RequestParam + RequestParam requestParam = new RequestParam.Builder() + .serialNumber(wechatPayCertificateSerialNumber) + .nonce(nonce) + .signature(signature) + .timestamp(timestamp) + .body(requestBody.toString()) + .build(); +// log.info("【requestParam】" + JSONObject.toJSON(requestParam)); + //初始化了 RSAAutoCertificateConfig + Config config = WechatPayConfig.getInstance(); + // 初始化解析器 NotificationParser + NotificationParser parser = new NotificationParser((NotificationConfig) config); + // 以支付通知回调为例,验签、解密并转换成 Transaction + Transaction transaction = parser.parse(requestParam, Transaction.class); +// log.info("【transaction】" + JSONObject.toJSON(transaction)); + PayNotifyMessageDTO message = new PayNotifyMessageDTO(); + message.setOutTradeNo(Long.valueOf(transaction.getOutTradeNo())); + message.setMemberId(Long.valueOf(transaction.getAttach())); + message.setTradeStatus(transaction.getTradeState()); + 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); + } + + +// @ApiOperation(value = "微信退款回调") +// @PostMapping("/weChatRefundNotify") +// public void weChatRefundNotify(HttpServletRequest request) throws IOException { +// log.info("收到了微信支付退款回调"); +// // 从请求头中获取信息 +// String timestamp = request.getHeader("Wechatpay-Timestamp"); +// String nonce = request.getHeader("Wechatpay-Nonce"); +// String signature = request.getHeader("Wechatpay-Signature"); +// String singType = request.getHeader("Wechatpay-Signature-Type"); +// String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial"); +// // 拿到请求体body +// StringBuilder requestBody = new StringBuilder(); +// String line; +// BufferedReader reader; +// reader = request.getReader(); +// while (null != (line = reader.readLine())) { +// requestBody.append(line); +// } +// // 构造 RequestParam +// RequestParam requestParam = new RequestParam.Builder() +// .serialNumber(wechatPayCertificateSerialNumber) +// .nonce(nonce) +// .signature(signature) +// .timestamp(timestamp) +// .body(requestBody.toString()) +// .build(); +// +// log.info("【requestParam】" + JSONObject.toJSON(requestParam)); +// //初始化了 RSAAutoCertificateConfig +// Config config = WechatPayConfig.getInstance(); +// // 初始化解析器 NotificationParser +// NotificationParser parser = new NotificationParser((NotificationConfig) config); +// +// //获取退款回调的信息 +// RefundNotification refundInfo = parser.parse(requestParam, RefundNotification.class); +// aftersaleService.refundOrderExc(refundInfo); +// } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/ProductController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/ProductController.java new file mode 100644 index 0000000..0b94721 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mall/ProductController.java @@ -0,0 +1,86 @@ +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.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 io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +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.List; +import java.util.Map; + +/** + *

+ * 用户地址 前端控制器 + *

+ * + * @author xn + * @since 2022-09-29 + */ +@Api(tags = "app商品信息") +@RestController +@RequestMapping("/api/product") +public class ProductController { + + @Autowired + private ProductCategoryService categoryService; + @Autowired + private ProductService productService; + + /** + * 商品页分类list + * @return + */ + @ApiOperation("商品类别") + @PostMapping("/categoryList") + public RestResponse getAddressList(@RequestBody Map params){ + return new RestResponse().setSuccess(true).setData(categoryService.getProductCategorys(params)); + } + + /** + * 商品搜索 + * @param query {categoryId:分类;search:名称;} null:全部商品 + * @param page + * @return + */ + @PostMapping("/list") + public ResponseEntity> queryGoodByPage(@RequestBody ProductQuery query, Pageable page) { + List pageRes = productService.selectList(query, page); + return ResponseEntity.ok(new PageImpl<>(BeanUtil.copyToList(pageRes,AppProductVO.class), page, ((com.github.pagehelper.Page) pageRes).getTotal())); + } + + /** + * 商品详情 + * @param id + * @return + */ + @GetMapping("/detail/{id}") + public ResponseEntity queryDetail(@PathVariable Long id) { + ProductDetailVO detail = productService.queryDetail(id); + return ResponseEntity.ok(detail); + } + + +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java deleted file mode 100644 index 69470d0..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.ruoyi.web.controller.monitor; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.RedisCallback; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.constant.CacheConstants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.system.domain.SysCache; - -/** - * 缓存监控 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/cache") -public class CacheController -{ - @Autowired - private RedisTemplate redisTemplate; - - private final static List caches = new ArrayList(); - { - caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); - caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息")); - caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典")); - caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); - caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); - caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); - caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); - } - - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @GetMapping() - public AjaxResult getInfo() throws Exception - { - Properties info = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info()); - Properties commandStats = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info("commandstats")); - Object dbSize = redisTemplate.execute((RedisCallback) connection -> connection.dbSize()); - - Map result = new HashMap<>(3); - result.put("info", info); - result.put("dbSize", dbSize); - - List> pieList = new ArrayList<>(); - commandStats.stringPropertyNames().forEach(key -> { - Map data = new HashMap<>(2); - String property = commandStats.getProperty(key); - data.put("name", StringUtils.removeStart(key, "cmdstat_")); - data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); - pieList.add(data); - }); - result.put("commandStats", pieList); - return AjaxResult.success(result); - } - - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @GetMapping("/getNames") - public AjaxResult cache() - { - return AjaxResult.success(caches); - } - - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @GetMapping("/getKeys/{cacheName}") - public AjaxResult getCacheKeys(@PathVariable String cacheName) - { - Set cacheKeys = redisTemplate.keys(cacheName + "*"); - return AjaxResult.success(cacheKeys); - } - - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @GetMapping("/getValue/{cacheName}/{cacheKey}") - public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) - { - String cacheValue = redisTemplate.opsForValue().get(cacheKey); - SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue); - return AjaxResult.success(sysCache); - } - - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @DeleteMapping("/clearCacheName/{cacheName}") - public AjaxResult clearCacheName(@PathVariable String cacheName) - { - Collection cacheKeys = redisTemplate.keys(cacheName + "*"); - redisTemplate.delete(cacheKeys); - return AjaxResult.success(); - } - - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @DeleteMapping("/clearCacheKey/{cacheKey}") - public AjaxResult clearCacheKey(@PathVariable String cacheKey) - { - redisTemplate.delete(cacheKey); - return AjaxResult.success(); - } - - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @DeleteMapping("/clearCacheAll") - public AjaxResult clearCacheAll() - { - Collection cacheKeys = redisTemplate.keys("*"); - redisTemplate.delete(cacheKeys); - return AjaxResult.success(); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java deleted file mode 100644 index cc805ad..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ruoyi.web.controller.monitor; - -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.framework.web.domain.Server; - -/** - * 服务器监控 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/server") -public class ServerController -{ - @PreAuthorize("@ss.hasPermi('monitor:server:list')") - @GetMapping() - public AjaxResult getInfo() throws Exception - { - Server server = new Server(); - server.copyTo(); - return AjaxResult.success(server); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java deleted file mode 100644 index e0175f4..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.ruoyi.web.controller.monitor; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.framework.web.service.SysPasswordService; -import com.ruoyi.system.domain.SysLogininfor; -import com.ruoyi.system.service.ISysLogininforService; - -/** - * 系统访问记录 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/logininfor") -public class SysLogininforController extends BaseController -{ - @Autowired - private ISysLogininforService logininforService; - - @Autowired - private SysPasswordService passwordService; - - @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") - @GetMapping("/list") - public TableDataInfo list(SysLogininfor logininfor) - { - startPage(); - List list = logininforService.selectLogininforList(logininfor); - return getDataTable(list); - } - - @Log(title = "登录日志", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysLogininfor logininfor) - { - List list = logininforService.selectLogininforList(logininfor); - ExcelUtil util = new ExcelUtil(SysLogininfor.class); - util.exportExcel(response, list, "登录日志"); - } - - @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") - @Log(title = "登录日志", businessType = BusinessType.DELETE) - @DeleteMapping("/{infoIds}") - public AjaxResult remove(@PathVariable Long[] infoIds) - { - return toAjax(logininforService.deleteLogininforByIds(infoIds)); - } - - @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") - @Log(title = "登录日志", businessType = BusinessType.CLEAN) - @DeleteMapping("/clean") - public AjaxResult clean() - { - logininforService.cleanLogininfor(); - return success(); - } - - @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") - @Log(title = "账户解锁", businessType = BusinessType.OTHER) - @GetMapping("/unlock/{userName}") - public AjaxResult unlock(@PathVariable("userName") String userName) - { - passwordService.clearLoginRecordCache(userName); - return success(); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java deleted file mode 100644 index b6ba56b..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ruoyi.web.controller.monitor; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.system.domain.SysOperLog; -import com.ruoyi.system.service.ISysOperLogService; - -/** - * 操作日志记录 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/operlog") -public class SysOperlogController extends BaseController -{ - @Autowired - private ISysOperLogService operLogService; - - @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") - @GetMapping("/list") - public TableDataInfo list(SysOperLog operLog) - { - startPage(); - List list = operLogService.selectOperLogList(operLog); - return getDataTable(list); - } - - @Log(title = "操作日志", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysOperLog operLog) - { - List list = operLogService.selectOperLogList(operLog); - ExcelUtil util = new ExcelUtil(SysOperLog.class); - util.exportExcel(response, list, "操作日志"); - } - - @Log(title = "操作日志", businessType = BusinessType.DELETE) - @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") - @DeleteMapping("/{operIds}") - public AjaxResult remove(@PathVariable Long[] operIds) - { - return toAjax(operLogService.deleteOperLogByIds(operIds)); - } - - @Log(title = "操作日志", businessType = BusinessType.CLEAN) - @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") - @DeleteMapping("/clean") - public AjaxResult clean() - { - operLogService.cleanOperLog(); - return AjaxResult.success(); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java deleted file mode 100644 index 294318d..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.ruoyi.web.controller.monitor; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.CacheConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.core.redis.RedisCache; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.system.domain.SysUserOnline; -import com.ruoyi.system.service.ISysUserOnlineService; - -/** - * 在线用户监控 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/online") -public class SysUserOnlineController extends BaseController -{ - @Autowired - private ISysUserOnlineService userOnlineService; - - @Autowired - private RedisCache redisCache; - - @PreAuthorize("@ss.hasPermi('monitor:online:list')") - @GetMapping("/list") - public TableDataInfo list(String ipaddr, String userName) - { - Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); - List userOnlineList = new ArrayList(); - for (String key : keys) - { - LoginUser user = redisCache.getCacheObject(key); - if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) - { - if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) - { - userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); - } - } - else if (StringUtils.isNotEmpty(ipaddr)) - { - if (StringUtils.equals(ipaddr, user.getIpaddr())) - { - userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); - } - } - else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) - { - if (StringUtils.equals(userName, user.getUsername())) - { - userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); - } - } - else - { - userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); - } - } - Collections.reverse(userOnlineList); - userOnlineList.removeAll(Collections.singleton(null)); - return getDataTable(userOnlineList); - } - - /** - * 强退用户 - */ - @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") - @Log(title = "在线用户", businessType = BusinessType.FORCE) - @DeleteMapping("/{tokenId}") - public AjaxResult forceLogout(@PathVariable String tokenId) - { - redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); - return AjaxResult.success(); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/search/MemberUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/search/MemberUserController.java deleted file mode 100644 index 9e7fb3a..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/search/MemberUserController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ruoyi.web.controller.search; - -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.search.domain.MemberUserWo; -import com.ruoyi.search.service.MemberUserServicelmpl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; -import java.util.Map; - -@RestController -@RequestMapping("/member_user") -public class MemberUserController extends BaseController { - @Autowired - MemberUserServicelmpl memberuserService; - - @GetMapping("/list") - public TableDataInfo list(@RequestParam Map map) { - startPage(); - map.put("stroreId", SecurityUtils.getMerchanId()); - List list = memberuserService.getList(map); - return getDataTable(list); - } - - -// @PostMapping(value = "/getList") -// public RestResponse findList1(@RequestBody Map params) { -// List list =memberuserService.findList((String) params.get("memberName")); -// return new RestResponse().setSuccess(true).setMessage("成功").setData(list); -// -// } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java deleted file mode 100644 index b6f0518..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.ruoyi.web.controller.system; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.system.domain.SysConfig; -import com.ruoyi.system.service.ISysConfigService; - -/** - * 参数配置 信息操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/config") -public class SysConfigController extends BaseController -{ - @Autowired - private ISysConfigService configService; - - /** - * 获取参数配置列表 - */ - @PreAuthorize("@ss.hasPermi('system:config:list')") - @GetMapping("/list") - public TableDataInfo list(SysConfig config) - { - startPage(); - List list = configService.selectConfigList(config); - return getDataTable(list); - } - - @Log(title = "参数管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:config:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysConfig config) - { - List list = configService.selectConfigList(config); - ExcelUtil util = new ExcelUtil(SysConfig.class); - util.exportExcel(response, list, "参数数据"); - } - - /** - * 根据参数编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:config:query')") - @GetMapping(value = "/{configId}") - public AjaxResult getInfo(@PathVariable Long configId) - { - return AjaxResult.success(configService.selectConfigById(configId)); - } - - /** - * 根据参数键名查询参数值 - */ - @GetMapping(value = "/configKey/{configKey}") - public AjaxResult getConfigKey(@PathVariable String configKey) - { - return AjaxResult.success(configService.selectConfigByKey(configKey)); - } - - /** - * 新增参数配置 - */ - @PreAuthorize("@ss.hasPermi('system:config:add')") - @Log(title = "参数管理", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysConfig config) - { - if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) - { - return AjaxResult.error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); - } - config.setCreateBy(getUsername()); - return toAjax(configService.insertConfig(config)); - } - - /** - * 修改参数配置 - */ - @PreAuthorize("@ss.hasPermi('system:config:edit')") - @Log(title = "参数管理", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysConfig config) - { - if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) - { - return AjaxResult.error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); - } - config.setUpdateBy(getUsername()); - return toAjax(configService.updateConfig(config)); - } - - /** - * 删除参数配置 - */ - @PreAuthorize("@ss.hasPermi('system:config:remove')") - @Log(title = "参数管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{configIds}") - public AjaxResult remove(@PathVariable Long[] configIds) - { - configService.deleteConfigByIds(configIds); - return success(); - } - - /** - * 刷新参数缓存 - */ - @PreAuthorize("@ss.hasPermi('system:config:remove')") - @Log(title = "参数管理", businessType = BusinessType.CLEAN) - @DeleteMapping("/refreshCache") - public AjaxResult refreshCache() - { - configService.resetConfigCache(); - return AjaxResult.success(); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java deleted file mode 100644 index 7fba1ae..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysDept; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.framework.web.service.TokenService; -import com.ruoyi.system.service.ISysDeptService; -import org.apache.commons.lang3.ArrayUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.stream.Collectors; - -/** - * 部门信息 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/dept") -public class SysDeptController extends BaseController -{ - @Autowired - private ISysDeptService deptService; - - @Resource - private TokenService tokenService; - - /** - * 获取部门列表 - */ - @PreAuthorize("@ss.hasPermi('system:dept:list')") - @GetMapping("/list") - public AjaxResult list(SysDept dept, HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - dept.setMerchanId(loginUser.getMerchantId()); - List depts = deptService.selectDeptList(dept); - if (!loginUser.isAdmin()){ - depts=depts.stream().filter(d->d.getParentId() !=0l).collect(Collectors.toList()); - } - return AjaxResult.success(depts); - } - - - /** - * 查询部门列表(排除节点) - */ - @PreAuthorize("@ss.hasPermi('system:dept:list')") - @GetMapping("/list/exclude/{deptId}") - public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId, HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - SysDept dept=new SysDept(); - dept.setMerchanId(loginUser.getMerchantId()); - List depts = deptService.selectDeptList(dept); - depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); - return AjaxResult.success(depts); - } - - /** - * 根据部门编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:dept:query')") - @GetMapping(value = "/{deptId}") - public AjaxResult getInfo(@PathVariable Long deptId) - { - deptService.checkDeptDataScope(deptId); - return AjaxResult.success(deptService.selectDeptById(deptId)); - } - - /** - * 新增部门 - */ - @PreAuthorize("@ss.hasPermi('system:dept:add')") - @Log(title = "部门管理", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysDept dept){ - SysDept d=new SysDept(); - d.setParentId(0l); - d.setMerchanId(SecurityUtils.getMerchanId()); - dept.setParentId(deptService.selectDeptList(d).get(0).getDeptId()); - dept.setMerchanId(SecurityUtils.getMerchanId()); - if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) - { - return AjaxResult.error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); - } - - dept.setCreateBy(getUsername()); - return toAjax(deptService.insertDept(dept)); - } - - /** - * 修改部门 - */ - @PreAuthorize("@ss.hasPermi('system:dept:edit')") - @Log(title = "部门管理", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysDept dept) - { - Long deptId = dept.getDeptId(); - deptService.checkDeptDataScope(deptId); - if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) - { - return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); - } - else if (dept.getParentId().equals(deptId)) - { - return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); - } - else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) - { - return AjaxResult.error("该部门包含未停用的子部门!"); - } - dept.setUpdateBy(getUsername()); - return toAjax(deptService.updateDept(dept)); - } - - /** - * 删除部门 - */ - @PreAuthorize("@ss.hasPermi('system:dept:remove')") - @Log(title = "部门管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{deptId}") - public AjaxResult remove(@PathVariable Long deptId) - { - if (deptService.hasChildByDeptId(deptId)) - { - return AjaxResult.error("存在下级部门,不允许删除"); - } - if (deptService.checkDeptExistUser(deptId)) - { - return AjaxResult.error("部门存在用户,不允许删除"); - } - deptService.checkDeptDataScope(deptId); - return toAjax(deptService.deleteDeptById(deptId)); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java deleted file mode 100644 index c5b8c03..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysDictData; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.shop.domain.YjMerchant; -import com.ruoyi.shop.service.impl.YjMerchantServiceImpl; -import com.ruoyi.system.service.ISysDictDataService; -import com.ruoyi.system.service.ISysDictTypeService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.List; - -/** - * 数据字典信息 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/dict/data") -public class SysDictDataController extends BaseController -{ - @Autowired - private ISysDictDataService dictDataService; - - @Autowired - private ISysDictTypeService dictTypeService; - - @Resource - private YjMerchantServiceImpl merchantService; - - @PreAuthorize("@ss.hasPermi('system:dict:list')") - @GetMapping("/list") - public TableDataInfo list(SysDictData dictData) - { - dictData.setMerchantId(SecurityUtils.getMerchanId()); - startPage(); - List list = dictDataService.selectDictDataList(dictData); - return getDataTable(list); - } - - @Log(title = "字典数据", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:dict:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysDictData dictData) - { - dictData.setMerchantId(SecurityUtils.getMerchanId()); - List list = dictDataService.selectDictDataList(dictData); - ExcelUtil util = new ExcelUtil(SysDictData.class); - util.exportExcel(response, list, "字典数据"); - } - - /** - * 查询字典数据详细 - */ -// @PreAuthorize("@ss.hasPermi('system:dict:query')") - @PreAuthorize("@ss.hasPermi('system:dict:list')") - @GetMapping(value = "/{dictCode}") - public AjaxResult getInfo(@PathVariable Long dictCode) - { - return AjaxResult.success(dictDataService.selectDictDataById(dictCode)); - } - - /** - * 根据字典类型查询字典数据信息 - */ - @GetMapping(value = "/type/{dictType}") - public AjaxResult dictType(@PathVariable String dictType) - { - List data = dictTypeService.selectDictDataByType(dictType); - if (StringUtils.isNull(data)) - { - data = new ArrayList(); - } - return AjaxResult.success(data); - } - - /** - * 新增字典类型 - */ -// @PreAuthorize("@ss.hasPermi('system:dict:add')") -// @Log(title = "字典数据", businessType = BusinessType.INSERT) - @PreAuthorize("@ss.hasPermi('system:dict:list')") - @PostMapping - public AjaxResult add(@Validated @RequestBody SysDictData dict) - { - dict.setCreateBy(getUsername()); - List list= merchantService.list(); - for (YjMerchant m:list){ - dict.setMerchantId(m.getId()); - dictDataService.insertDictData(dict); - } - return toAjax(1); - } - - /** - * 修改保存字典类型 - */ -// @PreAuthorize("@ss.hasPermi('system:dict:edit')") -// @Log(title = "字典数据", businessType = BusinessType.UPDATE) - @PreAuthorize("@ss.hasPermi('system:dict:list')") - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysDictData dict) - { - if (!SecurityUtils.getUserId().equals(1)) { - SysDictData d=new SysDictData(); - d.setDictCode(dict.getDictCode()); - d.setDictLabel(dict.getDictLabel()); - return toAjax(dictDataService.updateDictData(d)); - } - dict.setUpdateBy(getUsername()); - return toAjax(dictDataService.updateDictData(dict)); - } - - /** - * 删除字典类型 - */ -// @PreAuthorize("@ss.hasPermi('system:dict:remove')") -// @Log(title = "字典类型", businessType = BusinessType.DELETE) - @PreAuthorize("@ss.hasPermi('system:dict:list')") - @DeleteMapping("/{dictCodes}") - public AjaxResult remove(@PathVariable Long[] dictCodes) - { - dictDataService.deleteDictDataByIds(dictCodes); - return success(); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java deleted file mode 100644 index 4dce80b..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysDictType; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.system.mapper.SysDictTypeMapper; -import com.ruoyi.system.service.ISysDictTypeService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** - * 数据字典信息 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/dict/type") -public class SysDictTypeController extends BaseController -{ - @Autowired - private ISysDictTypeService dictTypeService; - @Resource - private SysDictTypeMapper dictTypeMapper; - - @PreAuthorize("@ss.hasPermi('system:dict:list')") - @GetMapping("/list") - public TableDataInfo list(SysDictType dictType){ - startPage(); - List list ; - if (SecurityUtils.getMerchanId().equals("1")){ - list = dictTypeService.selectDictTypeList(dictType); - }else { - list = dictTypeMapper.selectDictTypeList1(dictType); - } - return getDataTable(list); - } - - @Log(title = "字典类型", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:dict:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysDictType dictType) - { - List list = dictTypeService.selectDictTypeList(dictType); - ExcelUtil util = new ExcelUtil(SysDictType.class); - util.exportExcel(response, list, "字典类型"); - } - - /** - * 查询字典类型详细 - */ - @PreAuthorize("@ss.hasPermi('system:dict:query')") - @GetMapping(value = "/{dictId}") - public AjaxResult getInfo(@PathVariable Long dictId) - { - return AjaxResult.success(dictTypeService.selectDictTypeById(dictId)); - } - - /** - * 新增字典类型 - */ - @PreAuthorize("@ss.hasPermi('system:dict:add')") - @Log(title = "字典类型", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysDictType dict){ - if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) - { - return AjaxResult.error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); - } - dict.setCreateBy(getUsername()); - return toAjax(dictTypeService.insertDictType(dict)); - } - - /** - * 修改字典类型 - */ - @PreAuthorize("@ss.hasPermi('system:dict:edit')") - @Log(title = "字典类型", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysDictType dict) - { - if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) - { - return AjaxResult.error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); - } - dict.setUpdateBy(getUsername()); - return toAjax(dictTypeService.updateDictType(dict)); - } - - /** - * 删除字典类型 - */ - @PreAuthorize("@ss.hasPermi('system:dict:remove')") - @Log(title = "字典类型", businessType = BusinessType.DELETE) - @DeleteMapping("/{dictIds}") - public AjaxResult remove(@PathVariable Long[] dictIds) - { - dictTypeService.deleteDictTypeByIds(dictIds); - return success(); - } - - /** - * 刷新字典缓存 - */ - @PreAuthorize("@ss.hasPermi('system:dict:remove')") - @Log(title = "字典类型", businessType = BusinessType.CLEAN) - @DeleteMapping("/refreshCache") - public AjaxResult refreshCache() - { - dictTypeService.resetDictCache(); - return AjaxResult.success(); - } - - /** - * 获取字典选择框列表 - */ - @GetMapping("/optionselect") - public AjaxResult optionselect() - { - List dictTypes = dictTypeService.selectDictTypeAll(); - return AjaxResult.success(dictTypes); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java deleted file mode 100644 index 13007eb..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ruoyi.web.controller.system; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.config.RuoYiConfig; -import com.ruoyi.common.utils.StringUtils; - -/** - * 首页 - * - * @author ruoyi - */ -@RestController -public class SysIndexController -{ - /** 系统基础配置 */ - @Autowired - private RuoYiConfig ruoyiConfig; - - /** - * 访问首页,提示语 - */ - @RequestMapping("/") - public String index() - { - return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java deleted file mode 100644 index d959a17..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.ruoyi.web.controller.system; - -import java.util.List; -import java.util.Set; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysMenu; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginBody; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.framework.web.service.SysLoginService; -import com.ruoyi.framework.web.service.SysPermissionService; -import com.ruoyi.system.service.ISysMenuService; - -/** - * 登录验证 - * - * @author ruoyi - */ -@RestController -public class SysLoginController -{ - @Autowired - private SysLoginService loginService; - - @Autowired - private ISysMenuService menuService; - - @Autowired - private SysPermissionService permissionService; - - /** - * 登录方法 - * - * @param loginBody 登录信息 - * @return 结果 - */ - @PostMapping("/login") - public AjaxResult login(@RequestBody LoginBody loginBody) - { - AjaxResult ajax = AjaxResult.success(); - // 生成令牌 - String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), - loginBody.getUuid()); - ajax.put(Constants.TOKEN, token); - return ajax; - } - - /** - * 获取用户信息 - * - * @return 用户信息 - */ - @GetMapping("getInfo") - public AjaxResult getInfo() - { - SysUser user = SecurityUtils.getLoginUser().getUser(); - // 角色集合 - Set roles = permissionService.getRolePermission(user); - // 权限集合 - Set permissions = permissionService.getMenuPermission(user); - AjaxResult ajax = AjaxResult.success(); - ajax.put("user", user); - ajax.put("roles", roles); - ajax.put("permissions", permissions); - return ajax; - } - - /** - * 获取路由信息 - * - * @return 路由信息 - */ - @GetMapping("getRouters") - public AjaxResult getRouters() - { - Long userId = SecurityUtils.getUserId(); - List menus = menuService.selectMenuTreeByUserId(userId); - return AjaxResult.success(menuService.buildMenus(menus)); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java deleted file mode 100644 index 4a9f73f..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.ruoyi.web.controller.system; - -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysMenu; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.system.service.ISysMenuService; - -/** - * 菜单信息 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/menu") -public class SysMenuController extends BaseController -{ - @Autowired - private ISysMenuService menuService; - - /** - * 获取菜单列表 - */ - @PreAuthorize("@ss.hasPermi('system:menu:list')") - @GetMapping("/list") - public AjaxResult list(SysMenu menu) - { - List menus = menuService.selectMenuList(menu, getUserId()); - return AjaxResult.success(menus); - } - - /** - * 根据菜单编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:menu:query')") - @GetMapping(value = "/{menuId}") - public AjaxResult getInfo(@PathVariable Long menuId) - { - return AjaxResult.success(menuService.selectMenuById(menuId)); - } - - /** - * 获取菜单下拉树列表 - */ - @GetMapping("/treeselect") - public AjaxResult treeselect(SysMenu menu) - { - List menus = menuService.selectMenuList(menu, getUserId()); - return AjaxResult.success(menuService.buildMenuTreeSelect(menus)); - } - - /** - * 加载对应角色菜单列表树 - */ - @GetMapping(value = "/roleMenuTreeselect/{roleId}") - public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) - { - List menus = menuService.selectMenuList(getUserId()); - AjaxResult ajax = AjaxResult.success(); - ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); - ajax.put("menus", menuService.buildMenuTreeSelect(menus)); - return ajax; - } - - /** - * 新增菜单 - */ - @PreAuthorize("@ss.hasPermi('system:menu:add')") - @Log(title = "菜单管理", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysMenu menu) - { - if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) - { - return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); - } - else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) - { - return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); - } - menu.setCreateBy(getUsername()); - return toAjax(menuService.insertMenu(menu)); - } - - /** - * 修改菜单 - */ - @PreAuthorize("@ss.hasPermi('system:menu:edit')") - @Log(title = "菜单管理", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysMenu menu) - { - if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) - { - return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); - } - else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) - { - return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); - } - else if (menu.getMenuId().equals(menu.getParentId())) - { - return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); - } - menu.setUpdateBy(getUsername()); - return toAjax(menuService.updateMenu(menu)); - } - - /** - * 删除菜单 - */ - @PreAuthorize("@ss.hasPermi('system:menu:remove')") - @Log(title = "菜单管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{menuId}") - public AjaxResult remove(@PathVariable("menuId") Long menuId) - { - if (menuService.hasChildByMenuId(menuId)) - { - return AjaxResult.error("存在子菜单,不允许删除"); - } - if (menuService.checkMenuExistRole(menuId)) - { - return AjaxResult.error("菜单已分配,不允许删除"); - } - return toAjax(menuService.deleteMenuById(menuId)); - } -} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java deleted file mode 100644 index 4da9f04..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.ruoyi.web.controller.system; - -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.system.domain.SysNotice; -import com.ruoyi.system.service.ISysNoticeService; - -/** - * 公告 信息操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/notice") -public class SysNoticeController extends BaseController -{ - @Autowired - private ISysNoticeService noticeService; - - /** - * 获取通知公告列表 - */ - @PreAuthorize("@ss.hasPermi('system:notice:list')") - @GetMapping("/list") - public TableDataInfo list(SysNotice notice) - { - startPage(); - List list = noticeService.selectNoticeList(notice); - return getDataTable(list); - } - - /** - * 根据通知公告编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:notice:query')") - @GetMapping(value = "/{noticeId}") - public AjaxResult getInfo(@PathVariable Long noticeId) - { - return AjaxResult.success(noticeService.selectNoticeById(noticeId)); - } - - /** - * 新增通知公告 - */ - @PreAuthorize("@ss.hasPermi('system:notice:add')") - @Log(title = "通知公告", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysNotice notice) - { - notice.setCreateBy(getUsername()); - return toAjax(noticeService.insertNotice(notice)); - } - - /** - * 修改通知公告 - */ - @PreAuthorize("@ss.hasPermi('system:notice:edit')") - @Log(title = "通知公告", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysNotice notice) - { - notice.setUpdateBy(getUsername()); - return toAjax(noticeService.updateNotice(notice)); - } - - /** - * 删除通知公告 - */ - @PreAuthorize("@ss.hasPermi('system:notice:remove')") - @Log(title = "通知公告", businessType = BusinessType.DELETE) - @DeleteMapping("/{noticeIds}") - public AjaxResult remove(@PathVariable Long[] noticeIds) - { - return toAjax(noticeService.deleteNoticeByIds(noticeIds)); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java deleted file mode 100644 index dca84de..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.framework.web.service.TokenService; -import com.ruoyi.system.domain.SysPost; -import com.ruoyi.system.service.ISysPostService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** - * 岗位信息操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/post") -public class SysPostController extends BaseController -{ - @Autowired - private ISysPostService postService; - @Resource - private TokenService tokenService; - - /** - * 获取岗位列表 - */ - @PreAuthorize("@ss.hasPermi('system:post:list')") - @GetMapping("/list") - public TableDataInfo list(SysPost post, HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - post.setMerchanId(loginUser.getMerchantId()); - startPage(); - List list = postService.selectPostList(post); - return getDataTable(list); - } - - @Log(title = "岗位管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:post:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysPost post) - { - List list = postService.selectPostList(post); - ExcelUtil util = new ExcelUtil(SysPost.class); - util.exportExcel(response, list, "岗位数据"); - } - - /** - * 根据岗位编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:post:query')") - @GetMapping(value = "/{postId}") - public AjaxResult getInfo(@PathVariable Long postId) - { - return AjaxResult.success(postService.selectPostById(postId)); - } - - /** - * 新增岗位 - */ - @PreAuthorize("@ss.hasPermi('system:post:add')") - @Log(title = "岗位管理", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysPost post, HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - post.setMerchanId(loginUser.getMerchantId()); - - if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) - { - return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); - } - else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) - { - return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); - } - post.setCreateBy(getUsername()); - return toAjax(postService.insertPost(post)); - } - - /** - * 修改岗位 - */ - @PreAuthorize("@ss.hasPermi('system:post:edit')") - @Log(title = "岗位管理", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysPost post) - { - if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) - { - return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); - } - else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) - { - return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); - } - post.setUpdateBy(getUsername()); - return toAjax(postService.updatePost(post)); - } - - /** - * 删除岗位 - */ - @PreAuthorize("@ss.hasPermi('system:post:remove')") - @Log(title = "岗位管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{postIds}") - public AjaxResult remove(@PathVariable Long[] postIds) - { - return toAjax(postService.deletePostByIds(postIds)); - } - - /** - * 获取岗位选择框列表 - */ - @GetMapping("/optionselect") - public AjaxResult optionselect(HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - List posts = postService.selectPostAll(loginUser.getMerchantId()); - return AjaxResult.success(posts); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java deleted file mode 100644 index 7b34da2..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.ruoyi.web.controller.system; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.config.RuoYiConfig; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.file.FileUploadUtils; -import com.ruoyi.common.utils.file.MimeTypeUtils; -import com.ruoyi.framework.web.service.TokenService; -import com.ruoyi.system.service.ISysUserService; - -/** - * 个人信息 业务处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/user/profile") -public class SysProfileController extends BaseController -{ - @Autowired - private ISysUserService userService; - - @Autowired - private TokenService tokenService; - - /** - * 个人信息 - */ - @GetMapping - public AjaxResult profile() - { - LoginUser loginUser = getLoginUser(); - SysUser user = loginUser.getUser(); - AjaxResult ajax = AjaxResult.success(user); - ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); - ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); - return ajax; - } - - /** - * 修改用户 - */ - @Log(title = "个人信息", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult updateProfile(@RequestBody SysUser user) - { - LoginUser loginUser = getLoginUser(); - SysUser sysUser = loginUser.getUser(); - user.setUserName(sysUser.getUserName()); - if (StringUtils.isNotEmpty(user.getPhonenumber()) - && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) - { - return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); - } - if (StringUtils.isNotEmpty(user.getEmail()) - && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) - { - return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); - } - user.setUserId(sysUser.getUserId()); - user.setPassword(null); - user.setAvatar(null); - user.setDeptId(null); - if (userService.updateUserProfile(user) > 0) - { - // 更新缓存用户信息 - sysUser.setNickName(user.getNickName()); - sysUser.setPhonenumber(user.getPhonenumber()); - sysUser.setEmail(user.getEmail()); - sysUser.setSex(user.getSex()); - tokenService.setLoginUser(loginUser); - return AjaxResult.success(); - } - return AjaxResult.error("修改个人信息异常,请联系管理员"); - } - - /** - * 重置密码 - */ - @Log(title = "个人信息", businessType = BusinessType.UPDATE) - @PutMapping("/updatePwd") - public AjaxResult updatePwd(String oldPassword, String newPassword) - { - LoginUser loginUser = getLoginUser(); - String userName = loginUser.getUsername(); - String password = loginUser.getPassword(); - if (!SecurityUtils.matchesPassword(oldPassword, password)) - { - return AjaxResult.error("修改密码失败,旧密码错误"); - } - if (SecurityUtils.matchesPassword(newPassword, password)) - { - return AjaxResult.error("新密码不能与旧密码相同"); - } - if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) - { - // 更新缓存用户密码 - loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword)); - tokenService.setLoginUser(loginUser); - return AjaxResult.success(); - } - return AjaxResult.error("修改密码异常,请联系管理员"); - } - - /** - * 头像上传 - */ - @Log(title = "用户头像", businessType = BusinessType.UPDATE) - @PostMapping("/avatar") - public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception - { - if (!file.isEmpty()) - { - LoginUser loginUser = getLoginUser(); - String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); - if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) - { - AjaxResult ajax = AjaxResult.success(); - ajax.put("imgUrl", avatar); - // 更新缓存用户头像 - loginUser.getUser().setAvatar(avatar); - tokenService.setLoginUser(loginUser); - return ajax; - } - } - return AjaxResult.error("上传图片异常,请联系管理员"); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java deleted file mode 100644 index fe19249..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ruoyi.web.controller.system; - -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.RestController; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.model.RegisterBody; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.framework.web.service.SysRegisterService; -import com.ruoyi.system.service.ISysConfigService; - -/** - * 注册验证 - * - * @author ruoyi - */ -@RestController -public class SysRegisterController extends BaseController -{ - @Autowired - private SysRegisterService registerService; - - @Autowired - private ISysConfigService configService; - - @PostMapping("/register") - public AjaxResult register(@RequestBody RegisterBody user) - { - if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) - { - return error("当前系统没有开启注册功能!"); - } - String msg = registerService.register(user); - return StringUtils.isEmpty(msg) ? success() : error(msg); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java deleted file mode 100644 index 4e9422a..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysDept; -import com.ruoyi.common.core.domain.entity.SysRole; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.framework.web.service.SysPermissionService; -import com.ruoyi.framework.web.service.TokenService; -import com.ruoyi.system.domain.SysUserRole; -import com.ruoyi.system.service.ISysDeptService; -import com.ruoyi.system.service.ISysRoleService; -import com.ruoyi.system.service.ISysUserService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** - * 角色信息 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/role") -public class SysRoleController extends BaseController -{ - @Autowired - private ISysRoleService roleService; - - @Autowired - private TokenService tokenService; - - @Autowired - private SysPermissionService permissionService; - - @Autowired - private ISysUserService userService; - - @Autowired - private ISysDeptService deptService; - - @PreAuthorize("@ss.hasPermi('system:role:list')") - @GetMapping("/list") - public TableDataInfo list(SysRole role) - { - startPage(); - List list = roleService.selectRoleList(role); - return getDataTable(list); - } - - @Log(title = "角色管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:role:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysRole role) - { - List list = roleService.selectRoleList(role); - ExcelUtil util = new ExcelUtil(SysRole.class); - util.exportExcel(response, list, "角色数据"); - } - - /** - * 根据角色编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:role:query')") - @GetMapping(value = "/{roleId}") - public AjaxResult getInfo(@PathVariable Long roleId) - { - roleService.checkRoleDataScope(roleId); - return AjaxResult.success(roleService.selectRoleById(roleId)); - } - - /** - * 新增角色 - */ - @PreAuthorize("@ss.hasPermi('system:role:add')") - @Log(title = "角色管理", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysRole role) - { - if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) - { - return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); - } - else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) - { - return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); - } - role.setCreateBy(getUsername()); - return toAjax(roleService.insertRole(role)); - - } - - /** - * 修改保存角色 - */ - @PreAuthorize("@ss.hasPermi('system:role:edit')") - @Log(title = "角色管理", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysRole role) - { - roleService.checkRoleAllowed(role); - roleService.checkRoleDataScope(role.getRoleId()); - if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) - { - return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); - } - else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) - { - return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); - } - role.setUpdateBy(getUsername()); - - if (roleService.updateRole(role) > 0) - { - // 更新缓存用户权限 - LoginUser loginUser = getLoginUser(); - if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) - { - loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); - loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); - tokenService.setLoginUser(loginUser); - } - return AjaxResult.success(); - } - return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); - } - - /** - * 修改保存数据权限 - */ - @PreAuthorize("@ss.hasPermi('system:role:edit')") - @Log(title = "角色管理", businessType = BusinessType.UPDATE) - @PutMapping("/dataScope") - public AjaxResult dataScope(@RequestBody SysRole role) - { - roleService.checkRoleAllowed(role); - roleService.checkRoleDataScope(role.getRoleId()); - return toAjax(roleService.authDataScope(role)); - } - - /** - * 状态修改 - */ - @PreAuthorize("@ss.hasPermi('system:role:edit')") - @Log(title = "角色管理", businessType = BusinessType.UPDATE) - @PutMapping("/changeStatus") - public AjaxResult changeStatus(@RequestBody SysRole role) - { - roleService.checkRoleAllowed(role); - roleService.checkRoleDataScope(role.getRoleId()); - role.setUpdateBy(getUsername()); - return toAjax(roleService.updateRoleStatus(role)); - } - - /** - * 删除角色 - */ - @PreAuthorize("@ss.hasPermi('system:role:remove')") - @Log(title = "角色管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{roleIds}") - public AjaxResult remove(@PathVariable Long[] roleIds) - { - return toAjax(roleService.deleteRoleByIds(roleIds)); - } - - /** - * 获取角色选择框列表 - */ - @PreAuthorize("@ss.hasPermi('system:role:query')") - @GetMapping("/optionselect") - public AjaxResult optionselect() - { - return AjaxResult.success(roleService.selectRoleAll()); - } - - /** - * 查询已分配用户角色列表 - */ - @PreAuthorize("@ss.hasPermi('system:role:list')") - @GetMapping("/authUser/allocatedList") - public TableDataInfo allocatedList(SysUser user) - { - startPage(); - List list = userService.selectAllocatedList(user); - return getDataTable(list); - } - - /** - * 查询未分配用户角色列表 - */ - @PreAuthorize("@ss.hasPermi('system:role:list')") - @GetMapping("/authUser/unallocatedList") - public TableDataInfo unallocatedList(SysUser user) - { - startPage(); - List list = userService.selectUnallocatedList(user); - return getDataTable(list); - } - - /** - * 取消授权用户 - */ - @PreAuthorize("@ss.hasPermi('system:role:edit')") - @Log(title = "角色管理", businessType = BusinessType.GRANT) - @PutMapping("/authUser/cancel") - public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) - { - return toAjax(roleService.deleteAuthUser(userRole)); - } - - /** - * 批量取消授权用户 - */ - @PreAuthorize("@ss.hasPermi('system:role:edit')") - @Log(title = "角色管理", businessType = BusinessType.GRANT) - @PutMapping("/authUser/cancelAll") - public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) - { - return toAjax(roleService.deleteAuthUsers(roleId, userIds)); - } - - /** - * 批量选择用户授权 - */ - @PreAuthorize("@ss.hasPermi('system:role:edit')") - @Log(title = "角色管理", businessType = BusinessType.GRANT) - @PutMapping("/authUser/selectAll") - public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) - { - roleService.checkRoleDataScope(roleId); - return toAjax(roleService.insertAuthUsers(roleId, userIds)); - } - - /** - * 获取对应角色部门树列表 - */ - @PreAuthorize("@ss.hasPermi('system:role:query')") - @GetMapping(value = "/deptTree/{roleId}") - public AjaxResult deptTree(@PathVariable("roleId") Long roleId, HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - SysDept dept=new SysDept(); - dept.setMerchanId(loginUser.getMerchantId()); - AjaxResult ajax = AjaxResult.success(); - ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); - ajax.put("depts", deptService.selectDeptTreeList(dept)); - return ajax; - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java deleted file mode 100644 index 8e17ac9..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ /dev/null @@ -1,290 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysDept; -import com.ruoyi.common.core.domain.entity.SysRole; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.framework.web.service.TokenService; -import com.ruoyi.system.mapper.SysRoleMapper; -import com.ruoyi.system.service.ISysDeptService; -import com.ruoyi.system.service.ISysPostService; -import com.ruoyi.system.service.ISysRoleService; -import com.ruoyi.system.service.ISysUserService; -import org.apache.commons.lang3.ArrayUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.List; -import java.util.stream.Collectors; - -/** - * 用户信息 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/system/user") -public class SysUserController extends BaseController -{ - @Autowired - private ISysUserService userService; - - @Autowired - private ISysRoleService roleService; - @Autowired - private SysRoleMapper roleMapper; - - @Autowired - private ISysDeptService deptService; - - @Autowired - private ISysPostService postService; - - @Resource - private TokenService tokenService; - /** - * 获取用户列表 - */ - @PreAuthorize("@ss.hasPermi('system:user:list')") - @GetMapping("/list") - public TableDataInfo list(SysUser user){ - if (!SecurityUtils.getMerchanId().equals("1")){ - user.setMerchantId(SecurityUtils.getMerchanId()); - } - startPage(); - List list = userService.selectUserList(user); - if (!SecurityUtils.getMerchanId().equals("1")){ - list.forEach(u->{ - for (SysRole role:u.getRoles()){ - if(role.isMerchant()){ - u.setResponsible(true); - break; - } - } - }); - }else { - list.forEach(u->{ - for (SysRole role:u.getRoles()){ - if(role.getRoleId() != null && 1L ==role.getRoleId()){ - u.setResponsible(true); - break; - } - } - }); - } - return getDataTable(list); - } - - @Log(title = "用户管理", businessType = BusinessType.EXPORT) - @PreAuthorize("@ss.hasPermi('system:user:export')") - @PostMapping("/export") - public void export(HttpServletResponse response, SysUser user) - { - List list = userService.selectUserList(user); - ExcelUtil util = new ExcelUtil(SysUser.class); - util.exportExcel(response, list, "用户数据"); - } - - @Log(title = "用户管理", businessType = BusinessType.IMPORT) - @PreAuthorize("@ss.hasPermi('system:user:import')") -// @PostMapping("/importData") - public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception - { - ExcelUtil util = new ExcelUtil(SysUser.class); - List userList = util.importExcel(file.getInputStream()); - String operName = getUsername(); - String message = userService.importUser(userList, updateSupport, operName); - return AjaxResult.success(message); - } - - @PostMapping("/importTemplate") - public void importTemplate(HttpServletResponse response) - { - ExcelUtil util = new ExcelUtil(SysUser.class); - util.importTemplateExcel(response, "用户数据"); - } - - /** - * 根据用户编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('system:user:query')") - @GetMapping(value = { "/", "/{userId}" }) - public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId,HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - - userService.checkUserDataScope(userId); - AjaxResult ajax = AjaxResult.success(); - - //todo 角色 -// List roles = roleService.selectRoleAll(); - List roles = roleMapper.selectRoleAll(); -// ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); - ajax.put("roles", SysUser.isAdmin(SecurityUtils.getUserId())? - roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()) - : - roles.stream().filter(r -> !r.isMerchant()).collect(Collectors.toList())); - - //todo - // 岗位 - ajax.put("posts", postService.selectPostAll(loginUser.getMerchantId())); - if (StringUtils.isNotNull(userId)) - { - SysUser sysUser = userService.selectUserById(userId); - ajax.put(AjaxResult.DATA_TAG, sysUser); - ajax.put("postIds", postService.selectPostListByUserId(userId)); - ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); - } - return ajax; - } - - /** - * 新增用户 - */ - @PreAuthorize("@ss.hasPermi('system:user:add')") - @Log(title = "用户管理", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysUser user, HttpServletRequest request){ - SysUser loginUser=tokenService.getLoginUser(request).getUser(); - user.setMerchantId(loginUser.getMerchantId()); - if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) - { - return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); - } - else if (StringUtils.isNotEmpty(user.getPhonenumber()) - && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) - { - return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); - } - else if (StringUtils.isNotEmpty(user.getEmail()) - && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) - { - return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); - } - - user.setCreateBy(getUsername()); - user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); - return toAjax(userService.insertUser(user)); - } - - /** - * 修改用户 - */ - @PreAuthorize("@ss.hasPermi('system:user:edit')") - @Log(title = "用户管理", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysUser user) - { - userService.checkUserAllowed(user); - userService.checkUserDataScope(user.getUserId()); - if (StringUtils.isNotEmpty(user.getPhonenumber()) - && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) - { - return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); - } - else if (StringUtils.isNotEmpty(user.getEmail()) - && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) - { - return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); - } - user.setUpdateBy(getUsername()); - return toAjax(userService.updateUser(user)); - } - - /** - * 删除用户 - */ - @PreAuthorize("@ss.hasPermi('system:user:remove')") - @Log(title = "用户管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{userIds}") - public AjaxResult remove(@PathVariable Long[] userIds) - { - if (ArrayUtils.contains(userIds, getUserId())) - { - return error("当前用户不能删除"); - } - return toAjax(userService.deleteUserByIds(userIds)); - } - - /** - * 重置密码 - */ - @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") - @Log(title = "用户管理", businessType = BusinessType.UPDATE) - @PutMapping("/resetPwd") - public AjaxResult resetPwd(@RequestBody SysUser user) - { - userService.checkUserAllowed(user); - userService.checkUserDataScope(user.getUserId()); - user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); - user.setUpdateBy(getUsername()); - return toAjax(userService.resetPwd(user)); - } - - /** - * 状态修改 - */ - @PreAuthorize("@ss.hasPermi('system:user:edit')") - @Log(title = "用户管理", businessType = BusinessType.UPDATE) - @PutMapping("/changeStatus") - public AjaxResult changeStatus(@RequestBody SysUser user) - { - userService.checkUserAllowed(user); - userService.checkUserDataScope(user.getUserId()); - user.setUpdateBy(getUsername()); - return toAjax(userService.updateUserStatus(user)); - } - - /** - * 根据用户编号获取授权角色 - */ - @PreAuthorize("@ss.hasPermi('system:user:query')") - @GetMapping("/authRole/{userId}") - public AjaxResult authRole(@PathVariable("userId") Long userId) - { - AjaxResult ajax = AjaxResult.success(); - SysUser user = userService.selectUserById(userId); - List roles = roleService.selectRolesByUserId(userId); - ajax.put("user", user); - ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); - return ajax; - } - - /** - * 用户授权角色 - */ - @PreAuthorize("@ss.hasPermi('system:user:edit')") - @Log(title = "用户管理", businessType = BusinessType.GRANT) - @PutMapping("/authRole") - public AjaxResult insertAuthRole(Long userId, Long[] roleIds) - { - userService.checkUserDataScope(userId); - userService.insertUserAuth(userId, roleIds); - return success(); - } - - /** - * 获取部门树列表 - */ - @PreAuthorize("@ss.hasPermi('system:user:list')") - @GetMapping("/deptTree") - public AjaxResult deptTree(SysDept dept){ - if (!SecurityUtils.getMerchanId().equals("1")){ - dept.setMerchanId(SecurityUtils.getMerchanId()); - } - return AjaxResult.success(deptService.selectDeptTreeList(dept)); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java deleted file mode 100644 index b4f6bac..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.ruoyi.web.controller.tool; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.R; -import com.ruoyi.common.utils.StringUtils; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import io.swagger.annotations.ApiOperation; - -/** - * swagger 用户测试方法 - * - * @author ruoyi - */ -@Api("用户信息管理") -@RestController -@RequestMapping("/test/user") -public class TestController extends BaseController -{ - private final static Map users = new LinkedHashMap(); - { - users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); - users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); - } - - @ApiOperation("获取用户列表") - @GetMapping("/list") - public R> userList() - { - List userList = new ArrayList(users.values()); - return R.ok(userList); - } - - @ApiOperation("获取用户详细") - @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) - @GetMapping("/{userId}") - public R getUser(@PathVariable Integer userId) - { - if (!users.isEmpty() && users.containsKey(userId)) - { - return R.ok(users.get(userId)); - } - else - { - return R.fail("用户不存在"); - } - } - - @ApiOperation("新增用户") - @ApiImplicitParams({ - @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), - @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), - @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), - @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) - }) - @PostMapping("/save") - public R save(UserEntity user) - { - if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) - { - return R.fail("用户ID不能为空"); - } - users.put(user.getUserId(), user); - return R.ok(); - } - - @ApiOperation("更新用户") - @PutMapping("/update") - public R update(@RequestBody UserEntity user) - { - if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) - { - return R.fail("用户ID不能为空"); - } - if (users.isEmpty() || !users.containsKey(user.getUserId())) - { - return R.fail("用户不存在"); - } - users.remove(user.getUserId()); - users.put(user.getUserId(), user); - return R.ok(); - } - - @ApiOperation("删除用户信息") - @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) - @DeleteMapping("/{userId}") - public R delete(@PathVariable Integer userId) - { - if (!users.isEmpty() && users.containsKey(userId)) - { - users.remove(userId); - return R.ok(); - } - else - { - return R.fail("用户不存在"); - } - } -} - -@ApiModel(value = "UserEntity", description = "用户实体") -class UserEntity -{ - @ApiModelProperty("用户ID") - private Integer userId; - - @ApiModelProperty("用户名称") - private String username; - - @ApiModelProperty("用户密码") - private String password; - - @ApiModelProperty("用户手机") - private String mobile; - - public UserEntity() - { - - } - - public UserEntity(Integer userId, String username, String password, String mobile) - { - this.userId = userId; - this.username = username; - this.password = password; - this.mobile = mobile; - } - - public Integer getUserId() - { - return userId; - } - - public void setUserId(Integer userId) - { - this.userId = userId; - } - - public String getUsername() - { - return username; - } - - public void setUsername(String username) - { - this.username = username; - } - - public String getPassword() - { - return password; - } - - public void setPassword(String password) - { - this.password = password; - } - - public String getMobile() - { - return mobile; - } - - public void setMobile(String mobile) - { - this.mobile = mobile; - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WechatPayConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WechatPayConfig.java new file mode 100644 index 0000000..cfbff3a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WechatPayConfig.java @@ -0,0 +1,26 @@ +package com.ruoyi.web.core.config; + +import com.ruoyi.mall.util.PayConstants; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; + +public class WechatPayConfig { + + private static Config wechatPayConfig; + + private WechatPayConfig(){} + + public static Config getInstance() { + + + if (wechatPayConfig == null) { + wechatPayConfig = new RSAAutoCertificateConfig.Builder() + .merchantId(PayConstants.MCH_ID) + .privateKeyFromPath(PayConstants.PRIVATE_KEY_FILE_PATH) + .merchantSerialNumber(PayConstants.MCH_SERIAL_NO) + .apiV3Key(PayConstants.API_V3KEY) + .build(); + } + return wechatPayConfig; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/Base64.java b/ruoyi-admin/src/main/java/com/ruoyi/web/util/Base64.java deleted file mode 100644 index 548e2be..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/Base64.java +++ /dev/null @@ -1,291 +0,0 @@ -package com.ruoyi.web.util; - -/** - * Base64工具类 - * - */ -public final class Base64 -{ - static private final int BASELENGTH = 128; - static private final int LOOKUPLENGTH = 64; - static private final int TWENTYFOURBITGROUP = 24; - static private final int EIGHTBIT = 8; - static private final int SIXTEENBIT = 16; - static private final int FOURBYTE = 4; - static private final int SIGN = -128; - static private final char PAD = '='; - static final private byte[] base64Alphabet = new byte[BASELENGTH]; - static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; - - static - { - for (int i = 0; i < BASELENGTH; ++i) - { - base64Alphabet[i] = -1; - } - for (int i = 'Z'; i >= 'A'; i--) - { - base64Alphabet[i] = (byte) (i - 'A'); - } - for (int i = 'z'; i >= 'a'; i--) - { - base64Alphabet[i] = (byte) (i - 'a' + 26); - } - - for (int i = '9'; i >= '0'; i--) - { - base64Alphabet[i] = (byte) (i - '0' + 52); - } - - base64Alphabet['+'] = 62; - base64Alphabet['/'] = 63; - - for (int i = 0; i <= 25; i++) - { - lookUpBase64Alphabet[i] = (char) ('A' + i); - } - - for (int i = 26, j = 0; i <= 51; i++, j++) - { - lookUpBase64Alphabet[i] = (char) ('a' + j); - } - - for (int i = 52, j = 0; i <= 61; i++, j++) - { - lookUpBase64Alphabet[i] = (char) ('0' + j); - } - lookUpBase64Alphabet[62] = (char) '+'; - lookUpBase64Alphabet[63] = (char) '/'; - } - - private static boolean isWhiteSpace(char octect) - { - return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); - } - - private static boolean isPad(char octect) - { - return (octect == PAD); - } - - private static boolean isData(char octect) - { - return (octect < BASELENGTH && base64Alphabet[octect] != -1); - } - - /** - * Encodes hex octects into Base64 - * - * @param binaryData Array containing binaryData - * @return Encoded Base64 array - */ - public static String encode(byte[] binaryData) - { - if (binaryData == null) - { - return null; - } - - int lengthDataBits = binaryData.length * EIGHTBIT; - if (lengthDataBits == 0) - { - return ""; - } - - int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; - int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; - int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; - char encodedData[] = null; - - encodedData = new char[numberQuartet * 4]; - - byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; - - int encodedIndex = 0; - int dataIndex = 0; - - for (int i = 0; i < numberTriplets; i++) - { - b1 = binaryData[dataIndex++]; - b2 = binaryData[dataIndex++]; - b3 = binaryData[dataIndex++]; - - l = (byte) (b2 & 0x0f); - k = (byte) (b1 & 0x03); - - byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); - byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); - byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); - - encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; - encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; - encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; - encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; - } - - // form integral number of 6-bit groups - if (fewerThan24bits == EIGHTBIT) - { - b1 = binaryData[dataIndex]; - k = (byte) (b1 & 0x03); - byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); - encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; - encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; - encodedData[encodedIndex++] = PAD; - encodedData[encodedIndex++] = PAD; - } - else if (fewerThan24bits == SIXTEENBIT) - { - b1 = binaryData[dataIndex]; - b2 = binaryData[dataIndex + 1]; - l = (byte) (b2 & 0x0f); - k = (byte) (b1 & 0x03); - - byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); - byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); - - encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; - encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; - encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; - encodedData[encodedIndex++] = PAD; - } - return new String(encodedData); - } - - /** - * Decodes Base64 data into octects - * - * @param encoded string containing Base64 data - * @return Array containind decoded data. - */ - public static byte[] decode(String encoded) - { - if (encoded == null) - { - return null; - } - - char[] base64Data = encoded.toCharArray(); - // remove white spaces - int len = removeWhiteSpace(base64Data); - - if (len % FOURBYTE != 0) - { - return null;// should be divisible by four - } - - int numberQuadruple = (len / FOURBYTE); - - if (numberQuadruple == 0) - { - return new byte[0]; - } - - byte decodedData[] = null; - byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; - char d1 = 0, d2 = 0, d3 = 0, d4 = 0; - - int i = 0; - int encodedIndex = 0; - int dataIndex = 0; - decodedData = new byte[(numberQuadruple) * 3]; - - for (; i < numberQuadruple - 1; i++) - { - - if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) - || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) - { - return null; - } // if found "no data" just return null - - b1 = base64Alphabet[d1]; - b2 = base64Alphabet[d2]; - b3 = base64Alphabet[d3]; - b4 = base64Alphabet[d4]; - - decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); - } - - if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) - { - return null;// if found "no data" just return null - } - - b1 = base64Alphabet[d1]; - b2 = base64Alphabet[d2]; - - d3 = base64Data[dataIndex++]; - d4 = base64Data[dataIndex++]; - if (!isData((d3)) || !isData((d4))) - {// Check if they are PAD characters - if (isPad(d3) && isPad(d4)) - { - if ((b2 & 0xf) != 0)// last 4 bits should be zero - { - return null; - } - byte[] tmp = new byte[i * 3 + 1]; - System.arraycopy(decodedData, 0, tmp, 0, i * 3); - tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - return tmp; - } - else if (!isPad(d3) && isPad(d4)) - { - b3 = base64Alphabet[d3]; - if ((b3 & 0x3) != 0)// last 2 bits should be zero - { - return null; - } - byte[] tmp = new byte[i * 3 + 2]; - System.arraycopy(decodedData, 0, tmp, 0, i * 3); - tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); - tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - return tmp; - } - else - { - return null; - } - } - else - { // No PAD e.g 3cQl - b3 = base64Alphabet[d3]; - b4 = base64Alphabet[d4]; - decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); - - } - return decodedData; - } - - /** - * remove WhiteSpace from MIME containing encoded Base64 data. - * - * @param data the byte array of base64 data (with WS) - * @return the new length - */ - private static int removeWhiteSpace(char[] data) - { - if (data == null) - { - return 0; - } - - // count characters that's not whitespace - int newSize = 0; - int len = data.length; - for (int i = 0; i < len; i++) - { - if (!isWhiteSpace(data[i])) - { - data[newSize++] = data[i]; - } - } - return newSize; - } -} - diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/MD5Util.java b/ruoyi-admin/src/main/java/com/ruoyi/web/util/MD5Util.java deleted file mode 100644 index ab019cf..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/MD5Util.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.ruoyi.web.util; - -import java.security.MessageDigest; - - -public class MD5Util { - - private static String byteArrayToHexString(byte b[]) { - StringBuffer resultSb = new StringBuffer(); - for (int i = 0; i < b.length; i++) - resultSb.append(byteToHexString(b[i])); - - return resultSb.toString(); - } - - private static String byteToHexString(byte b) { - int n = b; - if (n < 0) - n += 256; - int d1 = n / 16; - int d2 = n % 16; - return hexDigits[d1] + hexDigits[d2]; - } - - public static String MD5Encode(String origin, String charsetname) { - String resultString = null; - try { - resultString = new String(origin); - MessageDigest md = MessageDigest.getInstance("MD5"); - if (charsetname == null || "".equals(charsetname)) - resultString = byteArrayToHexString(md.digest(resultString - .getBytes())); - else - resultString = byteArrayToHexString(md.digest(resultString - .getBytes(charsetname))); - } catch (Exception exception) { - } - return resultString; - } - - private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; -} - diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/PayUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/util/PayUtil.java deleted file mode 100644 index f2ca4cb..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/PayUtil.java +++ /dev/null @@ -1,360 +0,0 @@ -package com.ruoyi.web.util; - -import cn.hutool.core.util.RandomUtil; -import cn.hutool.json.JSONUtil; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; -import com.wechat.pay.contrib.apache.httpclient.auth.*; -import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager; -import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException; -import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException; -import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; -import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.util.Base64; -import java.util.*; - -public class PayUtil { - -// String schema = "WECHATPAY2-SHA256-RSA2048"; -// HttpUrl httpurl = HttpUrl.parse(url); - /** - * 预支付订单 - * @param amount 金额 - * @param orderSn 订单号 - * @return - * @throws Exception - */ - public static Map creatOrder(int amount,String orderSn) throws Exception{ - - PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey( - new ByteArrayInputStream(PayConstants.PRIVATE_KEY.getBytes(StandardCharsets.UTF_8))); - - //使用自动更新的签名验证器,不需要传入证书 - Verifier verifier = new AutoUpdateCertificatesVerifier( - new WechatPay2Credentials(PayConstants.MCH_ID, - new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)), - PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8)); - - CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create() - .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey) - .withValidator(new WechatPay2Validator(verifier)) - .build(); - String url="https://api.mch.weixin.qq.com/v3/pay/transactions/app"; - HttpPost httpPost = new HttpPost(url); - httpPost.addHeader("Accept", "application/json"); - httpPost.addHeader("Content-type","application/json; charset=utf-8"); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectMapper objectMapper = new ObjectMapper(); - - ObjectNode rootNode = objectMapper.createObjectNode(); - rootNode.put("mchid", PayConstants.MCH_ID) - .put("appid", PayConstants.APP_ID) - .put("notify_url", PayConstants.NOTIFY_URL) - .put("description", "三朵兰瑜伽") - .put("out_trade_no",orderSn);//订单号 目前是时间戳System.currentTimeMillis() - rootNode.putObject("amount") - .put("total", amount)//订单金额 int类型单位为分 - .put("currency", "CNY");//CNY:人民币,境内商户号仅支持人民币。 - - objectMapper.writeValue(bos, rootNode); - - httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8")); - CloseableHttpResponse response = httpClient.execute(httpPost); -//----------------------------------------------------------------------------------------- - String bodyAsString = EntityUtils.toString(response.getEntity()); - System.out.println(bodyAsString); - Map json=(Map)JSONUtil.parse(bodyAsString); - - Long timestamp= System.currentTimeMillis();//时间戳 - String nonce= RandomUtil.randomString(32);//随机字符串 - StringBuilder builder=new StringBuilder(); - //应用id - builder.append(PayConstants.APP_ID).append("\n"); - //时间戳 - builder.append(timestamp).append("\n"); - //随机字符串 - builder.append(nonce).append("\n"); - //预支付交易会话ID - builder.append(json.get("prepay_id")).append("\n"); - - //生成签名 RSA - String ciphertext = sign(builder.toString().getBytes(StandardCharsets.UTF_8)); - System.out.println(ciphertext); -//--------------------------------------------------------------------------------------------- - //生成签名 MD5 -// SortedMap sort=new TreeMap(); -// sort.put("appid",PayConstants.APP_ID); -// sort.put("timestamp",timestamp.toString()); -// sort.put("noncestr",nonce); -// sort.put("prepayid",node.get("prepay_id").toString()); -// String ciphertext = createSign(sort).toUpperCase(); - -// String stringA= -// "appid="+PayConstants.APP_ID -// +"&noncestr="+nonce -//// +"&package="+PayConstants.PACKAGE -// +"&partnerid="+PayConstants.MCH_ID -// +"&prepayid="+json.get("prepay_id").toString() -// +"×tamp="+timestamp; -// -// System.out.println(stringA); -// String stringSignTemp = stringA+"&key="+PayConstants.API_V3KEY; -// String ciphertext = MD5Util.MD5Encode(stringSignTemp,"UTF-8").toUpperCase(); - System.out.println(ciphertext); - Map map=new HashMap(); - map.put("appid",PayConstants.APP_ID); - map.put("partnerid",PayConstants.MCH_ID); - map.put("prepayid",json.get("prepay_id").toString());//有效期为2小时,超过2小时,商户需要使用原下单参数重新请求下单接口,获取新的prepay_id - map.put("package",PayConstants.PACKAGE); - map.put("noncestr",nonce); - map.put("timestamp",timestamp); - map.put("sign",ciphertext); - - return map; - } - - /** - * 生成签名RSA - * @param message - * @return - */ - /*message为appId、timeStamp、nonceStr、package拼接成的字符串 计算得出paySign*/ - static String sign(byte[] message) { - try { - PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PayConstants.PRIVATE_KEY); - Signature sign = Signature.getInstance("SHA256withRSA"); - sign.initSign(merchantPrivateKey); - sign.update(message); - - return Base64.getEncoder().encodeToString(sign.sign()); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (SignatureException e) { - e.printStackTrace(); - } - return null; - } - - /** - * 生成签名MD5 - * @param parameters - * @return - */ - public static String createSign(SortedMap parameters){ - StringBuffer sb = new StringBuffer(); - Set es = parameters.entrySet();//全部参与传参的参数按照accsii排序(升序) - Iterator it = es.iterator(); - - while(it.hasNext()) { - Map.Entry entry = (Map.Entry)it.next(); - String k = (String)entry.getKey(); - Object v = entry.getValue(); - if(null != v && !"".equals(v) - && !"sign".equals(k) && !"key".equals(k)) { - sb.append(k + "=" + v + "&"); - } - } - sb.append("key=" + PayConstants.API_V3KEY);//这里是商户那里设置的key - System.out.println("签名字符串:"+sb.toString()); - String sign =MD5Util.MD5Encode(sb.toString(),"UTF-8"); - return sign; - - } - - - - /** - * - * @param serialNumber 请求头携带的序列号 - * @param message 报文 - * @param signature 签名 - * @return - */ - public static boolean signVerify(String serialNumber,String message,String signature){ - - try { - PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PayConstants.PRIVATE_KEY); - // 获取证书管理器实例 - CertificatesManager certificatesManager = CertificatesManager.getInstance(); - // 向证书管理器增加需要自动更新平台证书的商户信息 - certificatesManager.putMerchant(PayConstants.MCH_ID, new WechatPay2Credentials(PayConstants.MCH_ID, - new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)), - PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8)); - // 从证书管理器中获取verifier - Verifier verifier = certificatesManager.getVerifier(PayConstants.MCH_ID); - - return verifier.verify(serialNumber, message.getBytes(StandardCharsets.UTF_8), signature); - } catch (IOException e) { - e.printStackTrace(); - } catch (GeneralSecurityException e) { - e.printStackTrace(); - } catch (HttpCodeException e) { - e.printStackTrace(); - } catch (NotFoundException e) { - e.printStackTrace(); - } - - return false; - } - - /** - * 关单时使用 - * @param body - * @return - */ - public static String decryptOrder(String body){ - - try { - AesUtil util=new AesUtil(PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8)); - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode node=objectMapper.readTree(body); - JsonNode resource=node.get("resource"); - String ciphertext=resource.get("ciphertext").textValue(); - String associatedData=resource.get("associated_data").textValue(); - String nonce=resource.get("nonce").textValue(); - - return util.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8) - ,nonce.getBytes(StandardCharsets.UTF_8) - ,ciphertext); - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - //关单 - public static void closeOrder(String outTradeNo) throws Exception{ - PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey( - new ByteArrayInputStream(PayConstants.PRIVATE_KEY.getBytes(StandardCharsets.UTF_8))); - - //使用自动更新的签名验证器,不需要传入证书 - Verifier verifier = new AutoUpdateCertificatesVerifier( - new WechatPay2Credentials(PayConstants.MCH_ID, - new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)), - PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8)); - - CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create() - .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey) - .withValidator(new WechatPay2Validator(verifier)) - .build(); -//************************************************ - HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"+outTradeNo+"/close"); - httpPost.addHeader("Accept", "application/json"); - httpPost.addHeader("Content-type","application/json; charset=utf-8"); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectMapper objectMapper = new ObjectMapper(); - - ObjectNode rootNode = objectMapper.createObjectNode(); - rootNode.put("mchid",PayConstants.MCH_ID); - - objectMapper.writeValue(bos, rootNode); - - httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8")); - CloseableHttpResponse response = httpClient.execute(httpPost); - - //204关单成功 - System.out.println(response.getStatusLine().getStatusCode()+"----204关单成功"); - -// String bodyAsString = EntityUtils.toString(response.getEntity()); -// System.out.println(bodyAsString); - } - - /** - * 合并订单支付(无用) - * @param amount - * @param orderSn - * @return - * @throws Exception - */ - public static Map creatMergeOrder(int amount,String orderSn) throws Exception{ - - PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey( - new ByteArrayInputStream(PayConstants.PRIVATE_KEY.getBytes(StandardCharsets.UTF_8))); - - //使用自动更新的签名验证器,不需要传入证书 - Verifier verifier = new AutoUpdateCertificatesVerifier( - new WechatPay2Credentials(PayConstants.MCH_ID, - new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)), - PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8)); - - CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create() - .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey) - .withValidator(new WechatPay2Validator(verifier)) - .build(); - - HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/combine-transactions/app"); - httpPost.addHeader("Accept", "application/json"); - httpPost.addHeader("Content-type","application/json; charset=utf-8"); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectMapper objectMapper = new ObjectMapper(); - - ObjectNode rootNode = objectMapper.createObjectNode(); - rootNode.put("combine_mchid", PayConstants.MCH_ID) - .put("combine_appid", PayConstants.APP_ID) - .put("notify_url", PayConstants.NOTIFY_URL) - .put("combine_out_trade_no",orderSn);//订单号// 目前是时间戳System.currentTimeMillis() - rootNode.putArray("sub_orders") - .addObject() - .put("total", amount)//订单金额 int类型单位为分 - .put("currency", "CNY");//CNY:人民币,境内商户号仅支持人民币。 - - objectMapper.writeValue(bos, rootNode); - - httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8")); - CloseableHttpResponse response = httpClient.execute(httpPost); - - String bodyAsString = EntityUtils.toString(response.getEntity()); - System.out.println(bodyAsString); - - String timestamp=System.currentTimeMillis()+"";//时间戳 - String nonce= RandomUtil.randomString(32);//随机字符串 - StringBuilder builder=new StringBuilder(); - //应用id - builder.append(PayConstants.APP_ID).append("\n"); - //时间戳 - builder.append(timestamp).append("\n"); - //随机字符串 - builder.append(nonce).append("\n"); - - JsonNode node=objectMapper.readTree(bodyAsString); - //预支付交易会话ID - builder.append(node.get("prepay_id")).append("\n"); - -// String cirphertext= RsaCryptoUtil.encryptOAEP(builder.toString(),verifier.getValidCertificate()); - String ciphertext = sign(builder.toString().getBytes(StandardCharsets.UTF_8)); - System.out.println(ciphertext); - - Map map=new HashMap(); - map.put("noncestr",nonce); - map.put("package",PayConstants.PACKAGE); - map.put("timeStamp",timestamp); - map.put("signType","RSA"); - map.put("paySign",ciphertext); - - return map; - } - - - - - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/SnowFlake.java b/ruoyi-admin/src/main/java/com/ruoyi/web/util/SnowFlake.java deleted file mode 100644 index 3bc59ea..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/SnowFlake.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.ruoyi.web.util; - -public class SnowFlake { - - // ==============================Fields=========================================== - /** - * 开始时间截 (2018-07-03) - */ - - private final Long twepoch = 1530607760000L; - - /** - * 机器id所占的位数 - */ - private final Long workerIdBits = 5L; - - /** - * 数据标识id所占的位数 - */ - private final Long datacenterIdBits = 5L; - - /** - * 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) - */ - private final Long maxWorkerId = -1L ^ (-1L << workerIdBits); - - /** - * 支持的最大数据标识id,结果是31 - */ - private final Long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); - - /** - * 序列在id中占的位数 - */ - private final Long sequenceBits = 12L; - - /** - * 机器ID向左移12位 - */ - private final Long workerIdShift = sequenceBits; - - /** - * 数据标识id向左移17位(12+5) - */ - private final Long datacenterIdShift = sequenceBits + workerIdBits; - - /** - * 时间截向左移22位(5+5+12) - */ - private final Long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; - - /** - * 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) - */ - private final Long sequenceMask = -1L ^ (-1L << sequenceBits); - - /** - * 工作机器ID(0~31) - */ - private Long workerId; - - /** - * 数据中心ID(0~31) - */ - private Long datacenterId; - - /** - * 毫秒内序列(0~4095) - */ - private Long sequence = 0L; - - /** - * 上次生成ID的时间截 - */ - private Long lastTimestamp = -1L; - - //==============================Constructors===================================== - - /** - * 构造函数 - * - * @param workerId 工作ID (0~31) - * @param datacenterId 数据中心ID (0~31) - */ - public SnowFlake(Long workerId, Long datacenterId) { - if (workerId > maxWorkerId || workerId < 0) { - throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); - } - if (datacenterId > maxDatacenterId || datacenterId < 0) { - throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); - } - this.workerId = workerId; - this.datacenterId = datacenterId; - } - - // ==============================Methods========================================== - - /** - * 获得下一个ID (该方法是线程安全的) - * - * @return SnowflakeId - */ - public synchronized Long nextId() { - Long timestamp = timeGen(); - - //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 - if (timestamp < lastTimestamp) { - throw new RuntimeException( - String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); - } - - //如果是同一时间生成的,则进行毫秒内序列 - if (lastTimestamp == timestamp) { - sequence = (sequence + 1) & sequenceMask; - //毫秒内序列溢出 - if (sequence == 0) { - //阻塞到下一个毫秒,获得新的时间戳 - timestamp = tilNextMillis(lastTimestamp); - } - } - //时间戳改变,毫秒内序列重置 - else { - sequence = 0L; - } - - //上次生成ID的时间截 - lastTimestamp = timestamp; - - //移位并通过或运算拼到一起组成64位的ID - return (((timestamp - twepoch) << timestampLeftShift) - | (datacenterId << datacenterIdShift) - | (workerId << workerIdShift) - | sequence); - } - - /** - * 阻塞到下一个毫秒,直到获得新的时间戳 - * - * @param lastTimestamp 上次生成ID的时间截 - * @return 当前时间戳 - */ - protected Long tilNextMillis(Long lastTimestamp) { - Long timestamp = timeGen(); - while (timestamp <= lastTimestamp) { - timestamp = timeGen(); - } - return timestamp; - } - - /** - * 返回以毫秒为单位的当前时间 - * - * @return 当前时间(毫秒) - */ - protected Long timeGen() { - return System.currentTimeMillis(); - } - - //==============================Test============================================= - - /** - * 测试 - */ -// public static void main(String[] args) { -// SnowFlake idWorker = new SnowFlake(0l, 0l); -// Long id = idWorker.nextId(); -// System.out.println(id); -// } - public static Long getOrder() { - SnowFlake idWorker = new SnowFlake(0l, 0l); - Long id = idWorker.nextId(); - return id; - } -// public String getOrder() { -// Long startTime = System.currentTimeMillis(); -// SnowFlake idWorker = new SnowFlake(0, 0); -// Long id = idWorker.nextId(); -// Set set = new HashSet(); -// for (int i = 0; i < 10000000; i++) { -// Long id = idWorker.nextId(); -// set.add(id); -// System.out.println("id----"+i+":"+id); -// } -// Long endTime = System.currentTimeMillis(); -// System.out.println("set.size():" + set.size()); -// System.out.println("endTime-startTime:" + (endTime - startTime)); -// } -} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/UUID.java b/ruoyi-admin/src/main/java/com/ruoyi/web/util/UUID.java deleted file mode 100644 index f22965c..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/UUID.java +++ /dev/null @@ -1,486 +0,0 @@ -package com.ruoyi.web.util; - - -import cn.hutool.core.exceptions.UtilException; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; - -/** - * 提供通用唯一识别码(universally unique identifier)(UUID)实现 - * - */ -public final class UUID implements java.io.Serializable, Comparable -{ - private static final long serialVersionUID = -1185015143654744140L; - - /** - * SecureRandom 的单例 - * - */ - private static class Holder - { - static final SecureRandom numberGenerator = getSecureRandom(); - } - - /** 此UUID的最高64有效位 */ - private final long mostSigBits; - - /** 此UUID的最低64有效位 */ - private final long leastSigBits; - - /** - * 私有构造 - * - * @param data 数据 - */ - private UUID(byte[] data) - { - long msb = 0; - long lsb = 0; - assert data.length == 16 : "data must be 16 bytes in length"; - for (int i = 0; i < 8; i++) - { - msb = (msb << 8) | (data[i] & 0xff); - } - for (int i = 8; i < 16; i++) - { - lsb = (lsb << 8) | (data[i] & 0xff); - } - this.mostSigBits = msb; - this.leastSigBits = lsb; - } - - /** - * 使用指定的数据构造新的 UUID。 - * - * @param mostSigBits 用于 {@code UUID} 的最高有效 64 位 - * @param leastSigBits 用于 {@code UUID} 的最低有效 64 位 - */ - public UUID(long mostSigBits, long leastSigBits) - { - this.mostSigBits = mostSigBits; - this.leastSigBits = leastSigBits; - } - - /** - * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。 - * - * @return 随机生成的 {@code UUID} - */ - public static UUID fastUUID() - { - return randomUUID(false); - } - - /** - * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 - * - * @return 随机生成的 {@code UUID} - */ - public static UUID randomUUID() - { - return randomUUID(true); - } - - /** - * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 - * - * @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能 - * @return 随机生成的 {@code UUID} - */ - public static UUID randomUUID(boolean isSecure) - { - final Random ng = isSecure ? Holder.numberGenerator : getSecureRandom(); - - byte[] randomBytes = new byte[16]; - ng.nextBytes(randomBytes); - randomBytes[6] &= 0x0f; /* clear version */ - randomBytes[6] |= 0x40; /* set to version 4 */ - randomBytes[8] &= 0x3f; /* clear variant */ - randomBytes[8] |= 0x80; /* set to IETF variant */ - return new UUID(randomBytes); - } - - /** - * 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。 - * - * @param name 用于构造 UUID 的字节数组。 - * - * @return 根据指定数组生成的 {@code UUID} - */ - public static UUID nameUUIDFromBytes(byte[] name) - { - MessageDigest md; - try - { - md = MessageDigest.getInstance("MD5"); - } - catch (NoSuchAlgorithmException nsae) - { - throw new InternalError("MD5 not supported"); - } - byte[] md5Bytes = md.digest(name); - md5Bytes[6] &= 0x0f; /* clear version */ - md5Bytes[6] |= 0x30; /* set to version 3 */ - md5Bytes[8] &= 0x3f; /* clear variant */ - md5Bytes[8] |= 0x80; /* set to IETF variant */ - return new UUID(md5Bytes); - } - - /** - * 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。 - * - * @param name 指定 {@code UUID} 字符串 - * @return 具有指定值的 {@code UUID} - * @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常 - * - */ - public static UUID fromString(String name) - { - String[] components = name.split("-"); - if (components.length != 5) - { - throw new IllegalArgumentException("Invalid UUID string: " + name); - } - for (int i = 0; i < 5; i++) - { - components[i] = "0x" + components[i]; - } - - long mostSigBits = Long.decode(components[0]).longValue(); - mostSigBits <<= 16; - mostSigBits |= Long.decode(components[1]).longValue(); - mostSigBits <<= 16; - mostSigBits |= Long.decode(components[2]).longValue(); - - long leastSigBits = Long.decode(components[3]).longValue(); - leastSigBits <<= 48; - leastSigBits |= Long.decode(components[4]).longValue(); - - return new UUID(mostSigBits, leastSigBits); - } - - /** - * 返回此 UUID 的 128 位值中的最低有效 64 位。 - * - * @return 此 UUID 的 128 位值中的最低有效 64 位。 - */ - public long getLeastSignificantBits() - { - return leastSigBits; - } - - /** - * 返回此 UUID 的 128 位值中的最高有效 64 位。 - * - * @return 此 UUID 的 128 位值中最高有效 64 位。 - */ - public long getMostSignificantBits() - { - return mostSigBits; - } - - /** - * 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。 - *

- * 版本号具有以下含意: - *

    - *
  • 1 基于时间的 UUID - *
  • 2 DCE 安全 UUID - *
  • 3 基于名称的 UUID - *
  • 4 随机生成的 UUID - *
- * - * @return 此 {@code UUID} 的版本号 - */ - public int version() - { - // Version is bits masked by 0x000000000000F000 in MS long - return (int) ((mostSigBits >> 12) & 0x0f); - } - - /** - * 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。 - *

- * 变体号具有以下含意: - *

    - *
  • 0 为 NCS 向后兼容保留 - *
  • 2 IETF RFC 4122(Leach-Salz), 用于此类 - *
  • 6 保留,微软向后兼容 - *
  • 7 保留供以后定义使用 - *
- * - * @return 此 {@code UUID} 相关联的变体号 - */ - public int variant() - { - // This field is composed of a varying number of bits. - // 0 - - Reserved for NCS backward compatibility - // 1 0 - The IETF aka Leach-Salz variant (used by this class) - // 1 1 0 Reserved, Microsoft backward compatibility - // 1 1 1 Reserved for future definition. - return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63)); - } - - /** - * 与此 UUID 相关联的时间戳值。 - * - *

- * 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。
- * 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。 - * - *

- * 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。
- * 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 - * - * @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。 - */ - public long timestamp() throws UnsupportedOperationException - { - checkTimeBase(); - return (mostSigBits & 0x0FFFL) << 48// - | ((mostSigBits >> 16) & 0x0FFFFL) << 32// - | mostSigBits >>> 32; - } - - /** - * 与此 UUID 相关联的时钟序列值。 - * - *

- * 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。 - *

- * {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出 - * UnsupportedOperationException。 - * - * @return 此 {@code UUID} 的时钟序列 - * - * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 - */ - public int clockSequence() throws UnsupportedOperationException - { - checkTimeBase(); - return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); - } - - /** - * 与此 UUID 相关的节点值。 - * - *

- * 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。 - *

- * 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。
- * 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 - * - * @return 此 {@code UUID} 的节点值 - * - * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 - */ - public long node() throws UnsupportedOperationException - { - checkTimeBase(); - return leastSigBits & 0x0000FFFFFFFFFFFFL; - } - - /** - * 返回此{@code UUID} 的字符串表现形式。 - * - *

- * UUID 的字符串表示形式由此 BNF 描述: - * - *

-     * {@code
-     * UUID                   = ----
-     * time_low               = 4*
-     * time_mid               = 2*
-     * time_high_and_version  = 2*
-     * variant_and_sequence   = 2*
-     * node                   = 6*
-     * hexOctet               = 
-     * hexDigit               = [0-9a-fA-F]
-     * }
-     * 
- * - * - * - * @return 此{@code UUID} 的字符串表现形式 - * @see #toString(boolean) - */ - @Override - public String toString() - { - return toString(false); - } - - /** - * 返回此{@code UUID} 的字符串表现形式。 - * - *

- * UUID 的字符串表示形式由此 BNF 描述: - * - *

-     * {@code
-     * UUID                   = ----
-     * time_low               = 4*
-     * time_mid               = 2*
-     * time_high_and_version  = 2*
-     * variant_and_sequence   = 2*
-     * node                   = 6*
-     * hexOctet               = 
-     * hexDigit               = [0-9a-fA-F]
-     * }
-     * 
- * - * - * - * @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串 - * @return 此{@code UUID} 的字符串表现形式 - */ - public String toString(boolean isSimple) - { - final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); - // time_low - builder.append(digits(mostSigBits >> 32, 8)); - if (false == isSimple) - { - builder.append('-'); - } - // time_mid - builder.append(digits(mostSigBits >> 16, 4)); - if (false == isSimple) - { - builder.append('-'); - } - // time_high_and_version - builder.append(digits(mostSigBits, 4)); - if (false == isSimple) - { - builder.append('-'); - } - // variant_and_sequence - builder.append(digits(leastSigBits >> 48, 4)); - if (false == isSimple) - { - builder.append('-'); - } - // node - builder.append(digits(leastSigBits, 12)); - - return builder.toString(); - } - - /** - * 返回此 UUID 的哈希码。 - * - * @return UUID 的哈希码值。 - */ - @Override - public int hashCode() - { - long hilo = mostSigBits ^ leastSigBits; - return ((int) (hilo >> 32)) ^ (int) hilo; - } - - /** - * 将此对象与指定对象比较。 - *

- * 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。 - * - * @param obj 要与之比较的对象 - * - * @return 如果对象相同,则返回 {@code true};否则返回 {@code false} - */ - @Override - public boolean equals(Object obj) - { - if ((null == obj) || (obj.getClass() != UUID.class)) - { - return false; - } - UUID id = (UUID) obj; - return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits); - } - - // Comparison Operations - - /** - * 将此 UUID 与指定的 UUID 比较。 - * - *

- * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 - * - * @param val 与此 UUID 比较的 UUID - * - * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 - * - */ - @Override - public int compareTo(UUID val) - { - // The ordering is intentionally set up so that the UUIDs - // can simply be numerically compared as two numbers - return (this.mostSigBits < val.mostSigBits ? -1 : // - (this.mostSigBits > val.mostSigBits ? 1 : // - (this.leastSigBits < val.leastSigBits ? -1 : // - (this.leastSigBits > val.leastSigBits ? 1 : // - 0)))); - } - - // ------------------------------------------------------------------------------------------------------------------- - // Private method start - /** - * 返回指定数字对应的hex值 - * - * @param val 值 - * @param digits 位 - * @return 值 - */ - private static String digits(long val, int digits) - { - long hi = 1L << (digits * 4); - return Long.toHexString(hi | (val & (hi - 1))).substring(1); - } - - /** - * 检查是否为time-based版本UUID - */ - private void checkTimeBase() - { - if (version() != 1) - { - throw new UnsupportedOperationException("Not a time-based UUID"); - } - } - - /** - * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) - * - * @return {@link SecureRandom} - */ - public static SecureRandom getSecureRandom() - { - try - { - return SecureRandom.getInstance("SHA1PRNG"); - } - catch (NoSuchAlgorithmException e) - { - throw new UtilException(e); - } - } - - /** - * 获取随机数生成器对象
- * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。 - * - * @return {@link ThreadLocalRandom} - */ - public static ThreadLocalRandom getRandom() - { - return ThreadLocalRandom.current(); - } -} - diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/VerifyCodeUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/web/util/VerifyCodeUtils.java deleted file mode 100644 index 593720c..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/VerifyCodeUtils.java +++ /dev/null @@ -1,225 +0,0 @@ -package com.ruoyi.web.util; - - -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.OutputStream; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Random; - -/** - * 验证码工具类 - * - */ -public class VerifyCodeUtils -{ - // 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符 - public static final String VERIFY_CODES = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ"; - - private static Random random = new SecureRandom(); - - /** - * 使用系统默认字符源生成验证码 - * - * @param verifySize 验证码长度 - * @return - */ - public static String generateVerifyCode(int verifySize) - { - return generateVerifyCode(verifySize, VERIFY_CODES); - } - - /** - * 使用指定源生成验证码 - * - * @param verifySize 验证码长度 - * @param sources 验证码字符源 - * @return - */ - public static String generateVerifyCode(int verifySize, String sources) - { - if (sources == null || sources.length() == 0) - { - sources = VERIFY_CODES; - } - int codesLen = sources.length(); - Random rand = new Random(System.currentTimeMillis()); - StringBuilder verifyCode = new StringBuilder(verifySize); - for (int i = 0; i < verifySize; i++) - { - verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1))); - } - return verifyCode.toString(); - } - - /** - * 输出指定验证码图片流 - * - * @param w - * @param h - * @param os - * @param code - * @throws IOException - */ - public static void outputImage(int w, int h, OutputStream os, String code) throws IOException - { - int verifySize = code.length(); - BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); - Random rand = new Random(); - Graphics2D g2 = image.createGraphics(); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - Color[] colors = new Color[5]; - Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, - Color.ORANGE, Color.PINK, Color.YELLOW }; - float[] fractions = new float[colors.length]; - for (int i = 0; i < colors.length; i++) - { - colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; - fractions[i] = rand.nextFloat(); - } - Arrays.sort(fractions); - - g2.setColor(Color.GRAY);// 设置边框色 - g2.fillRect(0, 0, w, h); - - Color c = getRandColor(200, 250); - g2.setColor(c);// 设置背景色 - g2.fillRect(0, 2, w, h - 4); - - // 绘制干扰线 - Random random = new Random(); - g2.setColor(getRandColor(160, 200));// 设置线条的颜色 - for (int i = 0; i < 20; i++) - { - int x = random.nextInt(w - 1); - int y = random.nextInt(h - 1); - int xl = random.nextInt(6) + 1; - int yl = random.nextInt(12) + 1; - g2.drawLine(x, y, x + xl + 40, y + yl + 20); - } - - // 添加噪点 - float yawpRate = 0.05f;// 噪声率 - int area = (int) (yawpRate * w * h); - for (int i = 0; i < area; i++) - { - int x = random.nextInt(w); - int y = random.nextInt(h); - int rgb = getRandomIntColor(); - image.setRGB(x, y, rgb); - } - - shear(g2, w, h, c);// 使图片扭曲 - - g2.setColor(getRandColor(100, 160)); - int fontSize = h - 4; - Font font = new Font("Algerian", Font.ITALIC, fontSize); - g2.setFont(font); - char[] chars = code.toCharArray(); - for (int i = 0; i < verifySize; i++) - { - AffineTransform affine = new AffineTransform(); - affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), - (w / verifySize) * i + fontSize / 2, h / 2); - g2.setTransform(affine); - g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10); - } - - g2.dispose(); - ImageIO.write(image, "jpg", os); - } - - private static Color getRandColor(int fc, int bc) - { - if (fc > 255) { - fc = 255; - } - if (bc > 255) { - bc = 255; - } - int r = fc + random.nextInt(bc - fc); - int g = fc + random.nextInt(bc - fc); - int b = fc + random.nextInt(bc - fc); - return new Color(r, g, b); - } - - private static int getRandomIntColor() - { - int[] rgb = getRandomRgb(); - int color = 0; - for (int c : rgb) - { - color = color << 8; - color = color | c; - } - return color; - } - - private static int[] getRandomRgb() - { - int[] rgb = new int[3]; - for (int i = 0; i < 3; i++) - { - rgb[i] = random.nextInt(255); - } - return rgb; - } - - private static void shear(Graphics g, int w1, int h1, Color color) - { - shearX(g, w1, h1, color); - shearY(g, w1, h1, color); - } - - private static void shearX(Graphics g, int w1, int h1, Color color) - { - - int period = random.nextInt(2); - - boolean borderGap = true; - int frames = 1; - int phase = random.nextInt(2); - - for (int i = 0; i < h1; i++) - { - double d = (double) (period >> 1) - * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); - g.copyArea(0, i, w1, 1, (int) d, 0); - if (borderGap) - { - g.setColor(color); - g.drawLine((int) d, i, 0, i); - g.drawLine((int) d + w1, i, w1, i); - } - } - - } - - private static void shearY(Graphics g, int w1, int h1, Color color) - { - - int period = random.nextInt(40) + 10; // 50; - - boolean borderGap = true; - int frames = 20; - int phase = 7; - for (int i = 0; i < w1; i++) - { - double d = (double) (period >> 1) - * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); - g.copyArea(i, 0, 1, h1, 0, (int) d); - if (borderGap) - { - g.setColor(color); - g.drawLine(i, (int) d, i, 0); - g.drawLine(i, (int) d + h1, i, h1); - } - - } - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/clientServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/web/util/clientServiceImpl.java deleted file mode 100644 index e0b9268..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/clientServiceImpl.java +++ /dev/null @@ -1,7 +0,0 @@ - package com.ruoyi.web.util; - - public class clientServiceImpl { - - - - } \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml new file mode 100644 index 0000000..f7d4895 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -0,0 +1,75 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + 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 + username: root +# password: '!Runpeng888' + password: 123456 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + 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 # 文件过期时间,单位:天 + +webrtc: + max-channel: 9 # 多人通话最大通道数量,最大不能超过16,建议值:4,9,16 + iceServers: + - urls: stun:stun.l.google.com:19302 diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml new file mode 100644 index 0000000..da4e0eb --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -0,0 +1,74 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + 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 + username: root + password: '!Runpeng888' +# password: 123456 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +minio: + endpoint: http://101.43.111.159:9000 #内网地址 + accessKey: KHuC4x81wQNGtDHC1dnS + secretKey: jCA4JpAJIIPXfIUJCWn0dZXKs2QCv5007dEhU1KB + bucketName: yoga-im + imagePath: image + filePath: file + videoPath: video + expireIn: 180 # 文件过期时间,单位:天 + +webrtc: + max-channel: 9 # 多人通话最大通道数量,最大不能超过16,建议值:4,9,16 + iceServers: + - urls: stun:stun.l.google.com:19302 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index a17e765..4e01751 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -1,7 +1,7 @@ # 项目相关配置 ruoyi: # 名称 - name: RuoYi + name: yoga # 版本 version: 3.8.3 # 版权年份 @@ -10,7 +10,7 @@ ruoyi: demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) # profile: D:/ruoyi/uploadPath - profile: ../ruoyi/uploadPath + profile: /workspace/project/yoga/uploadPath # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数组计算 char 字符验证 @@ -20,7 +20,6 @@ ruoyi: server: # 服务器的HTTP端口,默认为8080 port: 8083 -# port: 8083 servlet: # 应用的访问路径 context-path: / @@ -51,12 +50,15 @@ user: # Spring配置 spring: + jackson: + parser: + allow-numeric-leading-zeros: true # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: - active: druid + active: dev # 文件上传 servlet: multipart: @@ -91,24 +93,32 @@ spring: max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms - + mvc: + pathmatch: + matching-strategy: ant_path_matcher # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 - secret: abcdefghijklmnopqrstuvwxyz + secret: 4b5c4d8cc1a5d54afac74291c8f43dc6 # 令牌有效期( 3000分钟) - expireTime: 3000 + expireTime: 1800 + appuserExpireTime: 1800 + +mybatis-plus: + # 搜索指定包别名 + typeAliasesPackage: com.ruoyi.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + global-config: + db-config: + id-type: AUTO # ID自增 # MyBatis配置 -mybatis: - # 搜索指定包别名 - typeAliasesPackage: com.ruoyi.**.domain - # 配置mapper的扫描,找到所有的mapper.xml映射文件 - mapperLocations: classpath*:mapper/**/*Mapper.xml - # 加载全局的配置文件 - configLocation: classpath:mybatis/mybatis-config.xml + # PageHelper分页插件 pagehelper: @@ -130,12 +140,8 @@ xss: # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 - urlPatterns: /system/*,/monitor/*,/tool/* + urlPatterns: /api/*,/tool/* + +wechat: + token: runpeng -mybatis-plus: - # 搜索指定包别名 - typeAliasesPackage: com.ruoyi.**.domain - # 配置mapper的扫描,找到所有的mapper.xml映射文件 - mapperLocations: classpath*:mapper/**/*Mapper.xml - # 加载全局的配置文件 - configLocation: classpath:mybatis/mybatis-config.xml diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 07eddab..f922679 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -64,7 +64,6 @@ com.alibaba.fastjson2 fastjson2 - commons-io @@ -170,6 +169,32 @@ swagger-models 1.6.2 + + + org.springframework + spring-beans + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + + + + org.slf4j + slf4j-api + + + + org.springframework.boot + spring-boot-starter-websocket + + + + com.auth0 + java-jwt + 3.11.0 + + diff --git a/ruoyi-common/ruoyi-common.iml b/ruoyi-common/ruoyi-common.iml new file mode 100644 index 0000000..3c7f462 --- /dev/null +++ b/ruoyi-common/ruoyi-common.iml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/OnlineCheck.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/OnlineCheck.java new file mode 100644 index 0000000..a991bd7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/OnlineCheck.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 在线校验,标注此注解的接口用户必须保持长连接,否则将抛异常 + */ +@Retention(RetentionPolicy.RUNTIME)//运行时生效 +@Target(ElementType.METHOD)//作用在方法上 +public @interface OnlineCheck { + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/FastJson2JsonRedisSerializer.java similarity index 97% rename from ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java rename to ruoyi-common/src/main/java/com/ruoyi/common/config/FastJson2JsonRedisSerializer.java index b6d6110..0ccbaa1 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/FastJson2JsonRedisSerializer.java @@ -1,4 +1,4 @@ -package com.ruoyi.framework.config; +package com.ruoyi.common.config; import java.nio.charset.Charset; import org.springframework.data.redis.serializer.RedisSerializer; @@ -18,6 +18,7 @@ public class FastJson2JsonRedisSerializer implements RedisSerializer private Class clazz; + public FastJson2JsonRedisSerializer(Class clazz) { super(); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/ICEServer.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/ICEServer.java new file mode 100644 index 0000000..c94ec3b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/ICEServer.java @@ -0,0 +1,11 @@ +package com.ruoyi.common.config; + +import lombok.Data; + +@Data +public class ICEServer { + private String urls; + private String username; + private String credential; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/WebSocketConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/WebSocketConfig.java new file mode 100644 index 0000000..e261f7a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/WebSocketConfig.java @@ -0,0 +1,22 @@ +package com.ruoyi.common.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * WebSocket配置类。开启WebSocket的支持 + */ +@Configuration +public class WebSocketConfig { + + /** + * bean注册:会自动扫描带有@ServerEndpoint注解声明的Websocket Endpoint(端点),注册成为Websocket bean。 + * 要注意,如果项目使用外置的servlet容器,而不是直接使用springboot内置容器的话,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。 + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/WebrtcConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/WebrtcConfig.java new file mode 100644 index 0000000..dffb7c7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/WebrtcConfig.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Data +@Component +@ConfigurationProperties(prefix = "webrtc") +public class WebrtcConfig { + + private Integer maxChannel = 9; + + private List iceServers = new ArrayList<>(); + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java index 0080343..2d5e123 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java @@ -2,7 +2,7 @@ package com.ruoyi.common.constant; /** * 缓存的key 常量 - * + * * @author ruoyi */ public class CacheConstants @@ -11,6 +11,8 @@ public class CacheConstants * 登录用户 redis key */ public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + public static final String LOGIN_APPUSER_TOKEN_KEY = "login_appUser_tokens:"; + public static final String APPUSER_INFO = "appUser_info"; /** * 验证码 redis key diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 0e9125f..25a2ee8 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -2,9 +2,12 @@ package com.ruoyi.common.constant; import io.jsonwebtoken.Claims; +import java.util.HashMap; +import java.util.Map; + /** * 通用常量信息 - * + * * @author ruoyi */ public class Constants @@ -63,7 +66,7 @@ public class Constants * 登录失败 */ public static final String LOGIN_FAIL = "Error"; - + /** * 验证码有效期(分钟) */ @@ -83,6 +86,7 @@ public class Constants * 令牌前缀 */ public static final String LOGIN_USER_KEY = "login_user_key"; + public static final String LOGIN_APPUSER_KEY = "login_appUser_key"; /** * 用户ID @@ -139,4 +143,133 @@ public class Constants */ public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", "org.springframework", "org.apache", "com.ruoyi.common.utils.file" }; + + /** + * 登录提示信息 + */ + public static class LOGIN_INFO { + public static final String WRONG = "账号或密码错误"; + public static final String FORBIDDEN = "您的账号被禁用,请联系管理员"; + public static final String SUCCESS = "登录成功"; + public static final String TO_REGISTER = "请先注册"; + } + /** + * 验证码相关提示信息 + */ + public static class VERIFY_CODE_INFO { + public static final String EXPIRED = "验证码已过期"; + public static final String WRONG = "验证码错误"; + } + /** + * appUser账号状态 + */ + public static class MEMBER_ACCOUNT_STATUS { + public static final Integer FORBIDDEN = 0; + public static final Integer NORMAL = 1; + } + + /** + * 星期 与 中文 对应关系 + */ + public static final Map WEEK_DAY_MAP = new HashMap<>(); + + /** + * 上课时间 + * key:小时 + * value: 时间段 + */ + public static final Map CLA_TIME_MAP = new HashMap<>(); + + static { + WEEK_DAY_MAP.clear(); + WEEK_DAY_MAP.put(2, "星期一"); + WEEK_DAY_MAP.put(3, "星期二"); + WEEK_DAY_MAP.put(4, "星期三"); + WEEK_DAY_MAP.put(5, "星期四"); + WEEK_DAY_MAP.put(6, "星期五"); + WEEK_DAY_MAP.put(7, "星期六"); + 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"); + } + /** + * 上架状态:0->下架;1->上架 + */ + public static class PublishStatus { + public static final Integer GROUNDING = 1; + public static final Integer UNDERCARRIAGE = 0; + } + /** + * 0->未支付;1->支付宝;2->微信 + */ + public static class PayType { + public static final Integer NO_PAY = 0; + public static final Integer ALIPAY = 1; + public static final Integer WECHAT = 2; + } + /** + * 订单状态 0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单 + */ + public static class OrderStatus { + public static final Integer NOTPAID = 0; + public static final Integer SEND = 1; + public static final Integer GET = 2; + public static final Integer CONFIRM = 3; + public static final Integer CLOSED = 4; + public static final Integer UNVAILD = 5; + } + + /** + * 订单来源 购物车:cart + */ + public static class OrderFrom { + public static final String CART = "cart"; + } + + /** + * app订单查询状态 + * -1->全部 0->待付款;1->待发货;2->待收货/使用;3->已完成;4->已关闭;5->无效订单 -2->售后单 + */ + public static class AppOrderStatus{ + public static final Integer ALL = -1; + public static final Integer UN_PAY = 0; + public static final Integer NOT_DELIVERED = 1; + public static final Integer DELIVERED = 2; + public static final Integer COMPLETED = 3; + public static final Integer CLOSED = 4; + public static final Integer INVALID = 5; + public static final Integer REFUND = -2; + } + + /** + * 交易类型(1为支付 2为提现 3为退款) + */ + public static class PaymentOpType { + public static final Integer PAY = 1; + public static final Integer WITHDRAWAL = 2; + public static final Integer REFUND = 3; + } + + /** + * 状态(0:未完成交易 1:完成关键交易) + */ + public static class PaymentStatus { + public static final Integer INCOMPLETE = 0; + public static final Integer COMPLETE = 1; + } + + public static class OptType { + public static final Integer AGREE = 1; + public static final Integer REFUSE = 2; + public static final Integer GIVING = 3; + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java index 80e31cb..b889d7e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java @@ -3,6 +3,8 @@ package com.ruoyi.common.core.controller; import java.beans.PropertyEditorSupport; import java.util.Date; import java.util.List; + +import com.ruoyi.common.core.domain.model.LoginUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.WebDataBinder; @@ -11,7 +13,7 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.AppLoginUser; import com.ruoyi.common.core.page.PageDomain; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableSupport; @@ -23,7 +25,7 @@ import com.ruoyi.common.utils.sql.SqlUtil; /** * web层通用数据处理 - * + * * @author ruoyi */ public class BaseController @@ -124,7 +126,7 @@ public class BaseController /** * 响应返回结果 - * + * * @param rows 影响行数 * @return 操作结果 */ @@ -135,7 +137,7 @@ public class BaseController /** * 响应返回结果 - * + * * @param result 结果 * @return 操作结果 */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java deleted file mode 100644 index c3df6ae..0000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/R.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.ruoyi.common.core.domain; - -import java.io.Serializable; -import com.ruoyi.common.constant.HttpStatus; - -/** - * 响应信息主体 - * - * @author ruoyi - */ -public class R implements Serializable -{ - private static final long serialVersionUID = 1L; - - /** 成功 */ - public static final int SUCCESS = HttpStatus.SUCCESS; - - /** 失败 */ - public static final int FAIL = HttpStatus.ERROR; - - private int code; - - private String msg; - - private T data; - - public static R ok() - { - return restResult(null, SUCCESS, "操作成功"); - } - - public static R ok(T data) - { - return restResult(data, SUCCESS, "操作成功"); - } - - public static R ok(T data, String msg) - { - return restResult(data, SUCCESS, msg); - } - - public static R fail() - { - return restResult(null, FAIL, "操作失败"); - } - - public static R fail(String msg) - { - return restResult(null, FAIL, msg); - } - - public static R fail(T data) - { - return restResult(data, FAIL, "操作失败"); - } - - public static R fail(T data, String msg) - { - return restResult(data, FAIL, msg); - } - - public static R fail(int code, String msg) - { - return restResult(null, code, msg); - } - - private static R restResult(T data, int code, String msg) - { - R apiResult = new R<>(); - apiResult.setCode(code); - apiResult.setData(data); - apiResult.setMsg(msg); - return apiResult; - } - - public int getCode() - { - return code; - } - - public void setCode(int code) - { - this.code = code; - } - - public String getMsg() - { - return msg; - } - - public void setMsg(String msg) - { - this.msg = msg; - } - - public T getData() - { - return data; - } - - public void setData(T data) - { - this.data = data; - } -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/AppUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/AppUser.java new file mode 100644 index 0000000..e665c9b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/AppUser.java @@ -0,0 +1,90 @@ +package com.ruoyi.common.core.domain.entity; + +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 io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.data.annotation.Id; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; + +/** + * app登录对象 yj_app_user + * + * @author zcc + */ +@ApiModel(description="会员信息对象") +@Data +@TableName("yj_app_user") +public class AppUser{ + private static final long serialVersionUID = 1L; + + + @ApiModelProperty("ID") + @TableId(value = "app_user_id") + private Long id; + + @ApiModelProperty("昵称") + private String nickName; + + @ApiModelProperty("名称") + private String userName; + + @ApiModelProperty("密码") + private String password; + + @ApiModelProperty("手机号") + private String phoneNumber; + + @ApiModelProperty("帐号启用状态:0->禁用;1->启用") + private Integer status; + + @ApiModelProperty("头像") + private String avatar; + + @ApiModelProperty("性别:0->未知;1->男;2->女") + private Integer gender; + + @ApiModelProperty("用户所在城市") + private String city; + + @ApiModelProperty("用户所在省份") + private String province; + + @ApiModelProperty("用户所在国家") + private String country; + + @ApiModelProperty("生日") + @Excel(name = "生日", width = 30, dateFormat = "yyyy-MM-dd") + private LocalDate birthday; + + @ApiModelProperty("设备id") + private String registerId; + + @ApiModelProperty("访问/浏览门店id") + private String visitStore; + @ApiModelProperty("小程序unionid") + private String unionid; + + @ApiModelProperty("小程序openid") + private String openid; + + /** 员工所属门店id */ + private String storeId; + + /** 员工所属商户id */ + private String tenantId; + + + /** 最后登录IP */ + private String loginIp; + + /** 最后登录时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date loginDate; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/AppLoginUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/AppLoginUser.java new file mode 100644 index 0000000..58ec33f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/AppLoginUser.java @@ -0,0 +1,112 @@ +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; + +/** + * 登录用户身份权限 + * + * @author ruoyi + */ +@Data +public class AppLoginUser implements UserDetails +{ + + private static final long serialVersionUID = 1L; + private Long appUserId; + private String token; + private Long loginTime; + private Long expireTime; + /** + * 用户信息 + */ + private AppUser appUser; + + public AppLoginUser(Long appUserId, String token, Long loginTime, Long expireTime, AppUser appUser) { + this.appUserId = appUserId; + this.token = token; + this.loginTime = loginTime; + this.expireTime = expireTime; + this.appUser = appUser; + } + public AppLoginUser() { + + } + + public AppLoginUser(Long appUserId,AppUser appUser) { + this.appUserId = appUserId; + this.appUser = appUser; + } + + @JSONField(serialize = false) + @Override + public String getPassword() + { + return appUser.getPassword(); + } + + @Override + public String getUsername() + { + return appUser.getUserName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() + { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() + { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() + { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isEnabled() + { + return true; + } + + @Override + public Collection getAuthorities() + { + return null; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/AppUserLoginBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/AppUserLoginBody.java new file mode 100644 index 0000000..ee4f414 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/AppUserLoginBody.java @@ -0,0 +1,68 @@ +package com.ruoyi.common.core.domain.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * 用户登录对象 + * + * @author ruoyi + */ +@Data +public class AppUserLoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 电话 + */ + private String phonenumber; + + /** + * 短信验证码 + */ + private String smsCode; + + /** + * 用户密码 + */ + private String password; + + /** + * 图片验证码 + */ + private String code; + /** + * 设备id + */ + private String registerId; + + /** + * 小程序登录code 用以获取openID + */ + private String miniAppCode; + + @Max(value = 2, message = "登录终端类型取值范围:0,2") + @Min(value = 1, message = "登录终端类型取值范围:0,2") + @NotNull(message = "登录终端类型不可为空") + @Schema(description = "登录终端 1:app 2:小程序") + private Integer terminal; + + /** + * 唯一标识 + */ + private String uuid; + + /** + * 访问的门店 + */ + private String visitStoreId; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java index 8eea852..586d132 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginBody.java @@ -1,12 +1,13 @@ package com.ruoyi.common.core.domain.model; -import io.swagger.annotations.ApiModelProperty; +import lombok.Data; /** * 用户登录对象 * * @author ruoyi */ +@Data public class LoginBody { /** @@ -14,11 +15,6 @@ public class LoginBody */ private String username; - /** - * 用户名 - */ - private String phonenumber; - private String account; /** * 用户密码 */ @@ -29,75 +25,8 @@ public class LoginBody */ private String code; - @ApiModelProperty("设备id") - private String registerId; - /** * 唯一标识 */ - private String uuid; - - public String getAccount() { - return account; - } - - public void setAccount(String account) { - this.account = account; - } - - public String getRegisterId() { - return registerId; - } - - public void setRegisterId(String registerId) { - this.registerId = registerId; - } - - public String getPhonenumber() { - return phonenumber; - } - - public void setPhonenumber(String phonenumber) { - this.phonenumber = phonenumber; - } - - public String getUsername() - { - return username; - } - - public void setUsername(String username) - { - this.username = username; - } - - public String getPassword() - { - return password; - } - - public void setPassword(String password) - { - this.password = password; - } - - public String getCode() - { - return code; - } - - public void setCode(String code) - { - this.code = code; - } - - public String getUuid() - { - return uuid; - } - - public void setUuid(String uuid) - { - this.uuid = uuid; - } + private String uuid = ""; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java index e485384..85b3c67 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java @@ -1,15 +1,16 @@ package com.ruoyi.common.core.domain.model; -import java.util.Collection; -import java.util.Set; -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; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.Set; /** * 登录用户身份权限 - * + * * @author ruoyi */ public class LoginUser implements UserDetails @@ -144,7 +145,7 @@ public class LoginUser implements UserDetails /** * 指定用户是否解锁,锁定的用户无法进行身份验证 - * + * * @return */ @JSONField(serialize = false) @@ -156,7 +157,7 @@ public class LoginUser implements UserDetails /** * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 - * + * * @return */ @JSONField(serialize = false) @@ -168,7 +169,7 @@ public class LoginUser implements UserDetails /** * 是否可用 ,禁用的用户不能身份验证 - * + * * @return */ @JSONField(serialize = false) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java index 868a1fc..0c8a7c4 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/RegisterBody.java @@ -2,10 +2,10 @@ package com.ruoyi.common.core.domain.model; /** * 用户注册对象 - * + * * @author ruoyi */ -public class RegisterBody extends LoginBody +public class RegisterBody extends AppUserLoginBody { } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisService.java new file mode 100644 index 0000000..e00775b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisService.java @@ -0,0 +1,110 @@ +package com.ruoyi.common.core.redis; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Service +@Slf4j +public class RedisService { + @Autowired + private RedisCache redisCache; + + public void setMatchList(Long userId, List userIds) { + String key = RedisKeys.MATCH_LIST_OF + userId; + redisCache.setCacheList(key, userIds); + redisCache.expire(key, 7, TimeUnit.DAYS); + } + + public List getMatchList(Long userId) { + String key = RedisKeys.MATCH_LIST_OF + userId; + return redisCache.getCacheList(key); + } + + public String getAddressList() { + String key = RedisKeys.ADDRESS_LIST_KEY; + return redisCache.getCacheObject(key); + } + + public void setAddressList(String list) { + String key = RedisKeys.ADDRESS_LIST_KEY; + redisCache.setCacheObject(key,list); + } + + public void setVerifyCode(String code) { + String key = RedisKeys.VERIFY_CODE + code; + redisCache.setCacheObject(key, code); + redisCache.expire(key, 5, TimeUnit.MINUTES); + } + + public void deleteVerifyCode(String code) { + redisCache.deleteObject(RedisKeys.VERIFY_CODE + code); + } + + public String getVerifyCode(String code) { + return redisCache.getCacheObject(RedisKeys.VERIFY_CODE + code); + } + + public String getWechatToken() { + return redisCache.getCacheObject(RedisKeys.WECHAT_ACCESS_TOKEN); + } + + public void setWechatToken(String token) { + redisCache.setCacheObject(RedisKeys.WECHAT_ACCESS_TOKEN, token, 100, TimeUnit.MINUTES); + } + + public void setQrCode(String code, String scene) { + redisCache.setCacheObject(RedisKeys.WECHAT_QR_CODE + scene, code, 30, TimeUnit.DAYS); + } + + public String getQrCode(String scene) { + return redisCache.getCacheObject(RedisKeys.WECHAT_QR_CODE + scene); + } + + interface RedisKeys { + String MATCH_LIST_OF = "MATCH_LIST_OF_"; + String ADDRESS_LIST_KEY = "ADDRESS_LIST_KEY_"; + + String WECHAT_ACCESS_TOKEN = "WECHAT_ACCESS_TOKEN_"; + String WECHAT_QR_CODE = "WECHAT_QR_CODE_"; + String VERIFY_CODE = "VERIFY_CODE:"; + } + + /** + * redis实现分布式锁 --- 上锁 + * + * @param key + * @param jobInfo + * @param lockSecond + * @return + * @throws Exception + */ + public void lock(String key, String jobInfo, Integer lockSecond) throws Exception { + String existJobInfo = redisCache.getCacheObject(key); + if (StringUtils.isNotEmpty(existJobInfo)) { + log.info("获取锁失败: redisKey: {}, existJobInfo: {}", key, existJobInfo); + throw new Exception("请不要反复提交订单!"); + } + redisCache.setCacheObject(key, jobInfo, lockSecond, TimeUnit.SECONDS); + } + + /** + * redis实现分布式锁 --- 解锁 + * + * @param key + * @param jobInfo + * @throws Exception + */ + public void unLock(String key, String jobInfo) throws Exception { + String existJobInfo = redisCache.getCacheObject(key); + if (jobInfo.equals(existJobInfo)) { + redisCache.deleteObject(key); + } else { + throw new Exception(String.format("释放锁异常: redisKey: %s, existJobInfo: %s, jobInfo: %s", key, existJobInfo, jobInfo)); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/AftersaleStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AftersaleStatus.java new file mode 100644 index 0000000..c18c799 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AftersaleStatus.java @@ -0,0 +1,31 @@ +package com.ruoyi.common.enums; + +/** + * 售后状态 + * + * @author ruoyi + */ +public enum AftersaleStatus +{ + APPLY(0, "待处理"), + WAIT(1, "退货中"), + SUCCESS(2, "已完成"), + REJECT(3, "已拒绝"), + CANCEL(4,"用户取消"); + + private final Integer type; + private final String msg; + + private AftersaleStatus(Integer type, String msg) { + this.type = type; + this.msg = msg; + } + + public Integer getType() { + return this.type; + } + + public String getMsg() { + return this.msg; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderRefundStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderRefundStatus.java new file mode 100644 index 0000000..e765205 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderRefundStatus.java @@ -0,0 +1,31 @@ +package com.ruoyi.common.enums; + +/** + * 状态 + * + * @author ruoyi + */ +public enum OrderRefundStatus +{ + NO_REFUND(1, "无售后"), + APPLY(2, "申请中"), + WAIT(3, "退款中"), + SUCCESS(4, "退款成功"), + FAIL(5,"退款失败"); + + private final Integer type; + private final String msg; + + private OrderRefundStatus(Integer type, String msg) { + this.type = type; + this.msg = msg; + } + + public Integer getType() { + return this.type; + } + + public String getMsg() { + return this.msg; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderStatus.java new file mode 100644 index 0000000..221b777 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderStatus.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.enums; + +/** + * 订单状态 + * + * @author ruoyi + */ +public enum OrderStatus +{ + ALL_DATA(-1,"全部订单"), + UN_PAY(0, "待付款"), + NOT_DELIVERED(1, "待发货"), + DELIVERED(2, "待收货"), + COMPLETE(3, "已完成"), + CLOSED(4, "已关闭"), + INVALID(5, "无效订单"), + REFUUND(-2, "售后订单"); + + private final Integer type; + private final String msg; + + private OrderStatus(Integer type, String msg) { + this.type = type; + this.msg = msg; + } + + public Integer getType() { + return this.type; + } + + public String getMsg() { + return this.msg; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java index 81a71b5..f19efaf 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/GlobalException.java @@ -1,14 +1,21 @@ package com.ruoyi.common.exception; +import com.ruoyi.common.im.enums.ResultCode; +import lombok.Data; + +import java.io.Serializable; + /** * 全局异常 * * @author ruoyi */ -public class GlobalException extends RuntimeException +@Data +public class GlobalException extends RuntimeException implements Serializable { private static final long serialVersionUID = 1L; + private Integer code; /** * 错误提示 */ @@ -33,26 +40,21 @@ public class GlobalException extends RuntimeException this.message = message; } - public String getDetailMessage() - { - return detailMessage; - } - public GlobalException setDetailMessage(String detailMessage) - { - this.detailMessage = detailMessage; - return this; + public GlobalException(Integer code, String message) { + this.code = code; + this.message = message; } - @Override - public String getMessage() - { - return message; + public GlobalException(ResultCode resultCode, String message) { + this.code = resultCode.getCode(); + this.message = message; } - public GlobalException setMessage(String message) - { - this.message = message; - return this; + public GlobalException(ResultCode resultCode) { + this.code = resultCode.getCode(); + this.message = resultCode.getMsg(); } + + } \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/Constant_im.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/Constant_im.java new file mode 100644 index 0000000..b608e6f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/Constant_im.java @@ -0,0 +1,28 @@ +package com.ruoyi.common.im.constant; + +public final class Constant_im { + + /** + * 系统用户id + */ + public static final Long SYS_USER_ID = 0L; + /** + * 最大图片上传大小 + */ + public static final Long MAX_IMAGE_SIZE = 20 * 1024 * 1024L; + /** + * 最大上传文件大小 + */ + public static final Long MAX_FILE_SIZE = 20 * 1024 * 1024L; + + /** + * 大群人数上限 + */ + public static final Long MAX_LARGE_GROUP_MEMBER = 10000L; + + /** + * 普通群人数上限 + */ + public static final Long MAX_NORMAL_GROUP_MEMBER = 500L; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/IMConstant.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/IMConstant.java new file mode 100644 index 0000000..c8f798e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/IMConstant.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.im.constant; + +public final class IMConstant { + + private IMConstant() { + } + + /** + * 在线状态过期时间 600s + */ + public static final long ONLINE_TIMEOUT_SECOND = 600; + /** + * 消息允许撤回时间 300s + */ + public static final long ALLOW_RECALL_SECOND = 300; + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/IMRedisKey.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/IMRedisKey.java new file mode 100644 index 0000000..34aca16 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/IMRedisKey.java @@ -0,0 +1,40 @@ +package com.ruoyi.common.im.constant; + +public final class IMRedisKey { + + + /** + * im-server最大id,从0开始递增 + */ + public static final String IM_MAX_SERVER_ID = "im:max_server_id"; + /** + * 用户ID所连接的IM-server的ID + */ + public static final String IM_USER_SERVER_ID = "im:user:server_id"; + /** + * 系统消息队列 + */ + public static final String IM_MESSAGE_SYSTEM_QUEUE = "im:message:system"; + /** + * 私聊消息队列 + */ + public static final String IM_MESSAGE_PRIVATE_QUEUE = "im:message:private"; + /** + * 群聊消息队列 + */ + public static final String IM_MESSAGE_GROUP_QUEUE = "im:message:group"; + + /** + * 系统消息发送结果队列 + */ + public static final String IM_RESULT_SYSTEM_QUEUE = "im:result:system"; + /** + * 私聊消息发送结果队列 + */ + public static final String IM_RESULT_PRIVATE_QUEUE = "im:result:private"; + /** + * 群聊消息发送结果队列 + */ + public static final String IM_RESULT_GROUP_QUEUE = "im:result:group"; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/RedisKey.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/RedisKey.java new file mode 100644 index 0000000..54905cc --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/constant/RedisKey.java @@ -0,0 +1,68 @@ +package com.ruoyi.common.im.constant; + +/** + * im + */ +public final class RedisKey { + + /** + * 用户状态 无值:空闲 1:正在忙 + */ + public static final String IM_USER_STATE = "im:user:state"; + /** + * 已读群聊消息位置(已读最大id) + */ + public static final String IM_GROUP_READED_POSITION = "im:readed:group:position"; + /** + * webrtc 单人通话 + */ + public static final String IM_WEBRTC_PRIVATE_SESSION = "im:webrtc:private:session"; + /** + * webrtc 群通话 + */ + public static final String IM_WEBRTC_GROUP_SESSION = "im:webrtc:group:session"; + + /** + * 用户被封禁消息队列 + */ + public static final String IM_QUEUE_USER_BANNED = "im:queue:user:banned"; + + /** + * 群聊被封禁消息队列 + */ + public static final String IM_QUEUE_GROUP_BANNED = "im:queue:group:banned"; + + /** + * 群聊解封消息队列 + */ + public static final String IM_QUEUE_GROUP_UNBAN = "im:queue:group:unban"; + + + /** + * 缓存是否好友:bool + */ + public static final String IM_CACHE_FRIEND = "im:cache:friend"; + /** + * 缓存群聊信息 + */ + public static final String IM_CACHE_GROUP = "im:cache:group"; + /** + * 缓存群聊成员id + */ + public static final String IM_CACHE_GROUP_MEMBER_ID = "im:cache:group_member_ids"; + + /** + * 重复提交 + */ + public static final String IM_REPEAT_SUBMIT = "im:repeat:submit"; + + /** + * 分布式锁-清理过期文件 + */ + public static final String IM_LOCK_FILE_TASK = "im:lock:task:file"; + + /** + * 缓存当前访问门店id + */ + public static final String MALL_MEMBER_VISITSTORE = "mall:member:visitstore"; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/FileType.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/FileType.java new file mode 100644 index 0000000..789e17a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/FileType.java @@ -0,0 +1,32 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum FileType { + + /** + * 文件 + */ + FILE(0, "文件"), + /** + * 图片 + */ + IMAGE(1, "图片"), + /** + * 视频 + */ + VIDEO(2, "视频"); + + private final Integer code; + + private final String desc; + + + public Integer code() { + return this.code; + } + + +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMCmdType.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMCmdType.java new file mode 100644 index 0000000..edb30ea --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMCmdType.java @@ -0,0 +1,55 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum IMCmdType { + + /** + * 登录 + */ + LOGIN(0, "登录"), + /** + * 心跳 + */ + HEART_BEAT(1, "心跳"), + /** + * 强制下线 + */ + FORCE_LOGUT(2, "强制下线"), + /** + * 私聊消息 + */ + PRIVATE_MESSAGE(3, "私聊消息"), + /** + * 群发消息 + */ + GROUP_MESSAGE(4, "群发消息"), + /** + * 系统消息 + */ + SYSTEM_MESSAGE(5,"系统消息"); + + + private final Integer code; + + private final String desc; + + + public static IMCmdType fromCode(Integer code) { + for (IMCmdType typeEnum : values()) { + if (typeEnum.code.equals(code)) { + return typeEnum; + } + } + return null; + } + + + public Integer code() { + return this.code; + } + + +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMListenerType.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMListenerType.java new file mode 100644 index 0000000..292abda --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMListenerType.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum IMListenerType { + /** + * 全部消息 + */ + ALL(0, "全部消息"), + /** + * 私聊消息 + */ + PRIVATE_MESSAGE(1, "私聊消息"), + /** + * 群聊消息 + */ + GROUP_MESSAGE(2, "群聊消息"), + /** + * 系统消息 + */ + SYSTEM_MESSAGE(3, "群聊消息"); + + + + private final Integer code; + + private final String desc; + + public Integer code() { + return this.code; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMSendCode.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMSendCode.java new file mode 100644 index 0000000..14998ff --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMSendCode.java @@ -0,0 +1,32 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum IMSendCode { + + /** + * 发送成功 + */ + SUCCESS(0, "发送成功"), + /** + * 对方当前不在线 + */ + NOT_ONLINE(1, "对方当前不在线"), + /** + * 未找到对方的channel + */ + NOT_FIND_CHANNEL(2, "未找到对方的channel"), + /** + * 未知异常 + */ + UNKONW_ERROR(9999, "未知异常"); + + private final Integer code; + private final String desc; + + public Integer code() { + return this.code; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMTerminalType.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMTerminalType.java new file mode 100644 index 0000000..ec69c55 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/IMTerminalType.java @@ -0,0 +1,51 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@AllArgsConstructor +public enum IMTerminalType { + + /** + * web + */ + WEB(0, "web"), + /** + * app + */ + APP(1, "app"), + /** + * pc + */ + PC(2, "pc"), + /** + * 未知 + */ + UNKNOW(-1, "未知"); + + private final Integer code; + + private final String desc; + + + public static IMTerminalType fromCode(Integer code) { + for (IMTerminalType typeEnum : values()) { + if (typeEnum.code.equals(code)) { + return typeEnum; + } + } + return null; + } + + public static List codes() { + return Arrays.stream(values()).map(IMTerminalType::code).collect(Collectors.toList()); + } + + public Integer code() { + return this.code; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/MessageStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/MessageStatus.java new file mode 100644 index 0000000..47dc0cc --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/MessageStatus.java @@ -0,0 +1,33 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum MessageStatus { + + /** + * 文件 + */ + UNSEND(0, "未送达"), + /** + * 文件 + */ + SENDED(1, "送达"), + /** + * 撤回 + */ + RECALL(2, "撤回"), + /** + * 已读 + */ + READED(3, "已读"); + + private final Integer code; + + private final String desc; + + + public Integer code() { + return this.code; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/MessageType.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/MessageType.java new file mode 100644 index 0000000..224ec67 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/MessageType.java @@ -0,0 +1,72 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; + + +/** + * 0-9: 真正的消息,需要存储到数据库 + * 10-19: 状态类消息: 撤回、已读、回执 + * 20-29: 提示类消息: 在会话中间显示的提示 + * 30-39: UI交互类消息: 显示加载状态等 + * 40-49: 操作交互类消息: 语音通话、视频通话消息等 + * 50-60: 后台操作类消息: 用户封禁、群组封禁等 + * 80-89: 好友变化消息 + * 90-99: 群聊变化消息 + * 100-199: 单人语音通话rtc信令 + * 200-299: 多人语音通话rtc信令 + * + */ +@AllArgsConstructor +public enum MessageType { + + TEXT(0, "文字消息"), + IMAGE(1, "图片消息"), + FILE(2, "文件消息"), + AUDIO(3, "语音消息"), + VIDEO(4, "视频消息"), + RECALL(10, "撤回"), + READED(11, "已读"), + RECEIPT(12, "消息已读回执"), + TIP_TIME(20,"时间提示"), + TIP_TEXT(21,"文字提示"), + LOADING(30,"加载中标记"), + ACT_RT_VOICE(40,"语音通话"), + ACT_RT_VIDEO(41,"视频通话"), + USER_BANNED(50,"用户封禁"), + GROUP_BANNED(51,"群聊封禁"), + GROUP_UNBAN(52,"群聊解封"), + FRIEND_NEW(80, "新增好友"), + FRIEND_DEL(81, "删除好友"), + GROUP_NEW(90, "新增群聊"), + GROUP_DEL(91, "删除群聊"), + RTC_CALL_VOICE(100, "语音呼叫"), + RTC_CALL_VIDEO(101, "视频呼叫"), + RTC_ACCEPT(102, "接受"), + RTC_REJECT(103, "拒绝"), + RTC_CANCEL(104, "取消呼叫"), + RTC_FAILED(105, "呼叫失败"), + RTC_HANDUP(106, "挂断"), + RTC_CANDIDATE(107, "同步candidate"), + RTC_GROUP_SETUP(200,"发起群视频通话"), + RTC_GROUP_ACCEPT(201,"接受通话呼叫"), + RTC_GROUP_REJECT(202,"拒绝通话呼叫"), + RTC_GROUP_FAILED(203,"拒绝通话呼叫"), + RTC_GROUP_CANCEL(204,"取消通话呼叫"), + RTC_GROUP_QUIT(205,"退出通话"), + RTC_GROUP_INVITE(206,"邀请进入通话"), + RTC_GROUP_JOIN(207,"主动进入通话"), + RTC_GROUP_OFFER(208,"推送offer信息"), + RTC_GROUP_ANSWER(209,"推送answer信息"), + RTC_GROUP_CANDIDATE(210,"同步candidate"), + RTC_GROUP_DEVICE(211,"设备操作"), + ; + + private final Integer code; + + private final String desc; + + + public Integer code() { + return this.code; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/ResultCode.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/ResultCode.java new file mode 100644 index 0000000..32ca8a7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/ResultCode.java @@ -0,0 +1,50 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 响应码枚举 + * + * @author Blue + * @date 2020/10/19 + **/ +@Getter +@AllArgsConstructor +public enum ResultCode { + /** + * 成功 + */ + SUCCESS(200, "成功"), + /** + * 未登录 + */ + NO_LOGIN(400, "未登录"), + /** + * token无效或已过期 + */ + INVALID_TOKEN(401, "token无效或已过期"), + /** + * 系统繁忙,请稍后再试 + */ + PROGRAM_ERROR(500, "系统繁忙,请稍后再试"), + /** + * 密码不正确 + */ + PASSWOR_ERROR(10001, "密码不正确"), + /** + * 该用户名已注册 + */ + USERNAME_ALREADY_REGISTER(10003, "该用户名已注册"), + /** + * 请不要输入非法内容 + */ + XSS_PARAM_ERROR(10004, "请不要输入非法内容"); + + + private final int code; + private final String msg; + + +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/WebrtcMode.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/WebrtcMode.java new file mode 100644 index 0000000..80a90c8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/enums/WebrtcMode.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.im.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author: Blue + * @date: 2024-06-01 + * @version: 1.0 + */ +@Getter +@AllArgsConstructor +public enum WebrtcMode { + + /** + * 视频通话 + */ + VIDEO( "video"), + + /** + * 语音通话 + */ + VOICE( "voice"); + + private final String value; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMGroupMessage.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMGroupMessage.java new file mode 100644 index 0000000..4ed43ea --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMGroupMessage.java @@ -0,0 +1,45 @@ +package com.ruoyi.common.im.model; + + +import com.ruoyi.common.im.enums.IMTerminalType; +import lombok.Data; + +import java.util.LinkedList; +import java.util.List; + +@Data +public class IMGroupMessage { + + /** + * 发送方 + */ + private IMUserInfo sender; + + /** + * 接收者id列表(群成员列表,为空则不会推送) + */ + private List recvIds = new LinkedList<>(); + + + /** + * 接收者终端类型,默认全部 + */ + private List recvTerminals = IMTerminalType.codes(); + + /** + * 是否发送给自己的其他终端,默认true + */ + private Boolean sendToSelf = true; + + /** + * 是否需要回推发送结果,默认true + */ + private Boolean sendResult = true; + + /** + * 消息内容 + */ + private T data; + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMHeartbeatInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMHeartbeatInfo.java new file mode 100644 index 0000000..aec8f39 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMHeartbeatInfo.java @@ -0,0 +1,7 @@ +package com.ruoyi.common.im.model; + +import lombok.Data; + +@Data +public class IMHeartbeatInfo { +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMLoginInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMLoginInfo.java new file mode 100644 index 0000000..1cfdb09 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMLoginInfo.java @@ -0,0 +1,9 @@ +package com.ruoyi.common.im.model; + +import lombok.Data; + +@Data +public class IMLoginInfo { + + private String accessToken; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMPrivateMessage.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMPrivateMessage.java new file mode 100644 index 0000000..9800e46 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMPrivateMessage.java @@ -0,0 +1,44 @@ +package com.ruoyi.common.im.model; + + +import com.ruoyi.common.im.enums.IMTerminalType; +import lombok.Data; + +import java.util.List; + +@Data +public class IMPrivateMessage { + + /** + * 发送方 + */ + private IMUserInfo sender; + + /** + * 接收者id + */ + private Long recvId; + + + /** + * 接收者终端类型,默认全部 + */ + private List recvTerminals = IMTerminalType.codes(); + + /** + * 是否同步消息给自己的其他终端,默认true + */ + private Boolean sendToSelf = true; + + /** + * 是否需要回推发送结果,默认true + */ + private Boolean sendResult = true; + + /** + * 消息内容 + */ + private T data; + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMRecvInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMRecvInfo.java new file mode 100644 index 0000000..f6da694 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMRecvInfo.java @@ -0,0 +1,40 @@ +package com.ruoyi.common.im.model; + +import lombok.Data; + +import java.util.List; + +@Data +public class IMRecvInfo { + + /** + * 命令类型 IMCmdType + */ + private Integer cmd; + + /** + * 发送方 + */ + private IMUserInfo sender; + + /** + * 接收方用户列表 + */ + List receivers; + + /** + * 是否需要回调发送结果 + */ + private Boolean sendResult; + + /** + * 当前服务名(回调发送结果使用) + */ + private String serviceName; + /** + * 推送消息体 + */ + private Object data; +} + + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSendInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSendInfo.java new file mode 100644 index 0000000..0d5bfc3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSendInfo.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.im.model; + +import lombok.Data; + +@Data +public class IMSendInfo { + + /** + * 命令 + */ + private Integer cmd; + + /** + * 推送消息体 + */ + private T data; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSendResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSendResult.java new file mode 100644 index 0000000..c3a99d9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSendResult.java @@ -0,0 +1,28 @@ +package com.ruoyi.common.im.model; + +import lombok.Data; + +@Data +public class IMSendResult { + + /** + * 发送方 + */ + private IMUserInfo sender; + + /** + * 接收方 + */ + private IMUserInfo receiver; + + /** + * 发送状态编码 IMSendCode + */ + private Integer code; + + /** + * 消息内容 + */ + private T data; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSessionInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSessionInfo.java new file mode 100644 index 0000000..f009c4f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSessionInfo.java @@ -0,0 +1,17 @@ +package com.ruoyi.common.im.model; + +import lombok.Data; + +@Data +public class IMSessionInfo { + /** + * 用户id + */ + private Long userId; + + /** + * 终端类型 + */ + private Integer terminal; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSystemMessage.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSystemMessage.java new file mode 100644 index 0000000..b35e332 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMSystemMessage.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.im.model; + +import com.ruoyi.common.im.enums.IMTerminalType; +import lombok.Data; + +import java.util.LinkedList; +import java.util.List; + +@Data +public class IMSystemMessage { + + + /** + * 接收者id列表,为空表示向所有在线用户广播 + */ + private List recvIds = new LinkedList<>(); + + /** + * 接收者终端类型,默认全部 + */ + private List recvTerminals = IMTerminalType.codes(); + + /** + * 是否需要回推发送结果,默认true + */ + private Boolean sendResult = true; + + /** + * 消息内容 + */ + private T data; + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMUserInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMUserInfo.java new file mode 100644 index 0000000..a999afc --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/model/IMUserInfo.java @@ -0,0 +1,28 @@ +package com.ruoyi.common.im.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author: Blue + * @date: 2023-09-24 09:23:11 + * @version: 1.0 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class IMUserInfo { + + /** + * 用户id + */ + private Long id; + + /** + * 用户终端类型 IMTerminalType + */ + private Integer terminal; + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQConfig.java new file mode 100644 index 0000000..275345a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQConfig.java @@ -0,0 +1,40 @@ +package com.ruoyi.common.im.mq; + +import com.alibaba.fastjson2.JSON; +import com.ruoyi.common.config.FastJson2JsonRedisSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.nio.charset.StandardCharsets; + + +@Configuration +public class RedisMQConfig { + + @Bean + public RedisMQTemplate redisMQTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisMQTemplate redisMQTemplate = new RedisMQTemplate(); + redisMQTemplate.setConnectionFactory(redisConnectionFactory); + + // 设置值(value)的序列化采用FastJsonRedisSerializer + redisMQTemplate.setValueSerializer(fastJsonRedisSerializer()); + redisMQTemplate.setHashValueSerializer(fastJsonRedisSerializer()); + + // 设置键(key)的序列化采用StringRedisSerializer。 + redisMQTemplate.setKeySerializer(new StringRedisSerializer()); + redisMQTemplate.setHashKeySerializer(new StringRedisSerializer()); + + redisMQTemplate.afterPropertiesSet(); + return redisMQTemplate; + } + + @Bean + public FastJson2JsonRedisSerializer fastJsonRedisSerializer() { + return new FastJson2JsonRedisSerializer(Object.class); + } +} + + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQConsumer.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQConsumer.java new file mode 100644 index 0000000..2dbc318 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQConsumer.java @@ -0,0 +1,35 @@ +package com.ruoyi.common.im.mq; + +import java.util.List; + +/** + * redis 队列消费者抽象类 + */ +public abstract class RedisMQConsumer { + + /** + * 消费消息回调(单条) + */ + public void onMessage(T data){} + + /** + * 消费消息回调(批量) + */ + public void onMessage(List datas){} + + /** + * 生成redis队列完整key + */ + public String generateKey(){ + // 默认队列名就是redis的key + RedisMQListener annotation = this.getClass().getAnnotation(RedisMQListener.class); + return annotation.queue(); + } + + /** + * 队列是否就绪,返回true才会开始消费 + */ + public Boolean isReady(){ + return true; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQListener.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQListener.java new file mode 100644 index 0000000..7d064f4 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQListener.java @@ -0,0 +1,29 @@ +package com.ruoyi.common.im.mq; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * redis 队列消费监听注解 + */ +@Retention(RetentionPolicy.RUNTIME)//修饰注解,用来表示注解的生命周期 +@Target(ElementType.TYPE)//元注解,用于指定自定义注解可以被应用的程序元素类型 ElementType.TYPE 注解可以应用于类、接口(包括注解类型)或枚举声明 +public @interface RedisMQListener { + + /** + * 队列,也是redis的key + */ + String queue(); + + /** + * 一次性拉取的数据数量 + */ + int batchSize() default 1; + + /** + * 拉取间隔周期,单位:ms + */ + int period() default 100; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQPullTask.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQPullTask.java new file mode 100644 index 0000000..18607d7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQPullTask.java @@ -0,0 +1,124 @@ +package com.ruoyi.common.im.mq; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.im.util.ThreadPoolExecutorFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * reids 队列拉取定时任务 + * + * @author: Blue + * @date: 2024-07-15 + * @version: 1.0 + */ +@Slf4j +@Component +public class RedisMQPullTask implements CommandLineRunner {//用于在应用程序启动后执行初始化逻辑 + + private static final ScheduledThreadPoolExecutor EXECUTOR = ThreadPoolExecutorFactory.getThreadPoolExecutor(); + + @Autowired(required = false) + private List consumers = Collections.emptyList(); + + @Autowired + private RedisMQTemplate redisMQTemplate; + + @Override + public void run(String... args) { + consumers.forEach((consumer -> { + // 注解参数 + RedisMQListener annotation = consumer.getClass().getAnnotation(RedisMQListener.class); + String queue = annotation.queue(); + int batchSize = annotation.batchSize(); + int period = annotation.period(); + // 获取泛型类型 + Type superClass = consumer.getClass().getGenericSuperclass(); + Type type = ((ParameterizedType)superClass).getActualTypeArguments()[0]; + EXECUTOR.execute(new Runnable() { + @Override + public void run() { + List datas = new LinkedList<>(); + try { + if (consumer.isReady()) { + String key = consumer.generateKey(); + // 拉取一个批次的数据 + List objects = pullBatch(key, batchSize); + if (objects.size()>0){ + for (Object obj : objects) { +// if (obj instanceof JSONObject) { +// JSONObject jsonObject = (JSONObject)obj; +// Object data = jsonObject.toJavaObject(type); + consumer.onMessage(obj); +// datas.add(data); + datas.add(obj); +// } + } + } + + if (!datas.isEmpty()) { + consumer.onMessage(datas); + } + } + } catch (Exception e) { + log.error("数据消费异常,队列:{}", queue, e); + // 出现异常,10s后再重新尝试消费 + EXECUTOR.schedule(this, 10, TimeUnit.SECONDS); + return; + } + // 继续消费数据 + if (!EXECUTOR.isShutdown()) { + if (datas.size() < batchSize) { + // 数据已经消费完,等待下一个周期继续拉取 + EXECUTOR.schedule(this, period, TimeUnit.MILLISECONDS); + } else { + // 数据没有消费完,直接开启下一个消费周期 + EXECUTOR.execute(this); + } + } + } + }); + })); + } + + private List pullBatch(String key, Integer batchSize) { + List objects = new LinkedList<>(); +// if (redisMQTemplate.isSupportBatchPull()) { +// // 版本大于6.2,支持批量拉取 +// objects = redisMQTemplate.opsForList().leftPop(key, batchSize); +// } else { + // 版本小于6.2,只能逐条拉取 + + Object obj = redisMQTemplate.opsForList().leftPop(key); + while (!Objects.isNull(obj) && objects.size() < batchSize) { + objects.add(obj); + obj = redisMQTemplate.opsForList().leftPop(key); + } + if (!Objects.isNull(obj)){ + objects.add(obj); + } +// } + return objects; + } + + @PreDestroy + public void destory() { + log.info("消费线程停止..."); + ThreadPoolExecutorFactory.shutDown(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQTemplate.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQTemplate.java new file mode 100644 index 0000000..487ffb6 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/mq/RedisMQTemplate.java @@ -0,0 +1,44 @@ +package com.ruoyi.common.im.mq; + +import org.apache.logging.log4j.util.Strings; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.core.RedisConnectionUtils; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.Properties; + +/** + * @author: Blue + * @date: 2024-07-16 + * @version: 1.0 + */ +public class RedisMQTemplate extends RedisTemplate { + + private String version = Strings.EMPTY; + + public String getVersion() { + if (version.isEmpty()) { + RedisConnection connection = RedisConnectionUtils.getConnection(getConnectionFactory()); + Properties properties = connection.info(); + version = properties.getProperty("redis_version"); + RedisConnectionUtils.releaseConnection(connection,getConnectionFactory()); + } + return version; + } + + /** + * 是否支持批量拉取,redis版本大于6.2支持批量拉取 + * @return + */ + Boolean isSupportBatchPull() { + String version = getVersion(); + String[] arr = version.split("\\."); + if (arr.length < 2) { + return false; + } + Integer firVersion = Integer.valueOf(arr[0]); + Integer secVersion = Integer.valueOf(arr[1]); + return firVersion > 6 || (firVersion == 6 && secVersion >= 2); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/session/WebrtcPrivateSession.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/session/WebrtcPrivateSession.java new file mode 100644 index 0000000..b3417d8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/session/WebrtcPrivateSession.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.im.session; + +import lombok.Data; + +/* + * webrtc 会话信息 + * @Author Blue + * @Date 2022/10/21 + */ +@Data +public class WebrtcPrivateSession { + /** + * 发起者id + */ + private Long callerId; + /** + * 发起者终端类型 + */ + private Integer callerTerminal; + + /** + * 接受者id + */ + private Long acceptorId; + + /** + * 接受者终端类型 + */ + private Integer acceptorTerminal; + + /** + * 通话模式 + */ + private String mode; + /** + * 开始聊天时间戳 + */ + private Long chatTimeStamp; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/util/BeanUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/util/BeanUtils.java new file mode 100644 index 0000000..503042a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/util/BeanUtils.java @@ -0,0 +1,45 @@ +package com.ruoyi.common.im.util; + +import org.springframework.util.ReflectionUtils; + +public final class BeanUtils { + + private BeanUtils() { + } + + private static void handleReflectionException(Exception e) { + ReflectionUtils.handleReflectionException(e); + } + + + /** + * 属性拷贝 + * + * @param orig 源对象 + * @param destClass 目标 + * @return T + */ + public static T copyProperties(Object orig, Class destClass) { + try { + T target = destClass.newInstance(); + if (orig == null) { + return null; + } + copyProperties(orig, target); + return target; + } catch (Exception e) { + handleReflectionException(e); + return null; + } + } + + + public static void copyProperties(Object orig, Object dest) { + try { + org.springframework.beans.BeanUtils.copyProperties(orig, dest); + } catch (Exception e) { + handleReflectionException(e); + } + } + +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/util/CommaTextUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/util/CommaTextUtils.java new file mode 100644 index 0000000..d2a3e4e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/util/CommaTextUtils.java @@ -0,0 +1,89 @@ +package com.ruoyi.common.im.util; + + + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; + +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 逗号分格文本处理工具类 + * + * @author: blue + * @date: 2023-11-09 09:52:49 + * @version: 1.0 + */ +public class CommaTextUtils { + + /** + * 文本转列表 + * + * @param strText 文件 + * @return 列表 + */ + public static List asList(String strText) { + if (StrUtil.isEmpty(strText)) { + return new LinkedList<>(); + } + return new LinkedList<>(Arrays.asList(strText.split(","))); + + } + + /** + * 列表转字符串,并且自动清空、去重、排序 + * + * @param texts 列表 + * @return 文本 + */ + public static String asText(Collection texts) { + if (CollUtil.isEmpty(texts)) { + return StrUtil.EMPTY; + } + return texts.stream().map(text -> StrUtil.toString(text)).filter(StrUtil::isNotEmpty).distinct().sorted().collect(Collectors.joining(",")); + } + + /** + * 追加一个单词 + * + * @param strText 文本 + * @param word 单词 + * @return 文本 + */ + public static String appendWord(String strText, T word) { + List texts = asList(strText); + texts.add(StrUtil.toString(word)); + return asText(texts); + } + + /** + * 删除一个单词 + * + * @param strText 文本 + * @param word 单词 + * @return 文本 + */ + public static String removeWord(String strText, T word) { + List texts = asList(strText); + texts.remove(StrUtil.toString(word)); + return asText(texts); + } + + /** + * 合并 + * + * @param strText1 文本1 + * @param strText2 文本2 + * @return 文本 + */ + public static String merge(String strText1, String strText2) { + List texts = asList(strText1); + texts.addAll(asList(strText2)); + return asText(texts); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/im/util/ThreadPoolExecutorFactory.java b/ruoyi-common/src/main/java/com/ruoyi/common/im/util/ThreadPoolExecutorFactory.java new file mode 100644 index 0000000..722798e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/im/util/ThreadPoolExecutorFactory.java @@ -0,0 +1,87 @@ +package com.ruoyi.common.im.util; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 创建单例线程池 + * + * @author Andrews + * @date 2023/11/30 11:12 + */ +@Slf4j +public final class ThreadPoolExecutorFactory { + /** + * 机器的CPU核数:Runtime.getRuntime().availableProcessors() + * corePoolSize 池中所保存的线程数,包括空闲线程。 + * CPU 密集型:核心线程数 = CPU核数 + 1 + * IO 密集型:核心线程数 = CPU核数 * 2 + */ + private static final int CORE_POOL_SIZE = + Math.min(ThreadPoolExecutorFactory.MAX_IMUM_POOL_SIZE, Runtime.getRuntime().availableProcessors() * 2); + /** + * maximumPoolSize - 池中允许的最大线程数(采用LinkedBlockingQueue时没有作用)。 + */ + private static final int MAX_IMUM_POOL_SIZE = 100; + /** + * keepAliveTime -当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间,线程池维护线程所允许的空闲时间 + */ + private static final int KEEP_ALIVE_TIME = 1000; + /** + * 等待队列的大小。默认是无界的,性能损耗的关键 + */ + private static final int QUEUE_SIZE = 200; + + /** + * 线程池对象 + */ + private static volatile ScheduledThreadPoolExecutor threadPoolExecutor = null; + + /** + * 构造方法私有化 + */ + private ThreadPoolExecutorFactory() { + if (null == threadPoolExecutor) { + threadPoolExecutor = ThreadPoolExecutorFactory.getThreadPoolExecutor(); + } + } + + + /** + * 双检锁创建线程安全的单例 + */ + public static ScheduledThreadPoolExecutor getThreadPoolExecutor() { + if (null == threadPoolExecutor) { + synchronized (ThreadPoolExecutorFactory.class) { + if (null == threadPoolExecutor) { + threadPoolExecutor = new ScheduledThreadPoolExecutor( + //核心线程数 + CORE_POOL_SIZE, + //拒绝策略 + new ThreadPoolExecutor.CallerRunsPolicy() + ); + } + } + } + return threadPoolExecutor; + } + + /** + * 关闭线程池 + */ + public static void shutDown() { + if (threadPoolExecutor != null) { + threadPoolExecutor.shutdown(); + } + } + + public static void execute(Runnable runnable) { + if (runnable == null) { + return; + } + threadPoolExecutor.execute(runnable); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 491dbc1..e8f0fa1 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -8,6 +8,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; import java.util.Date; import com.github.pagehelper.util.StringUtil; @@ -196,4 +197,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils } return formatDate; } + + /** + * 获取2个时间间隔天数 + * @param beginTime + * @param endTime + * @return + */ + public static Long betweenDay(LocalDateTime beginTime, LocalDateTime endTime){ + return ChronoUnit.DAYS.between(beginTime.toLocalDate().atStartOfDay(),endTime.toLocalDate().atStartOfDay()); + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/IDGenerator.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/IDGenerator.java new file mode 100644 index 0000000..133ce2e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/IDGenerator.java @@ -0,0 +1,104 @@ +package com.ruoyi.common.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by yangyincong on 15/8/16. + * ID生成器 workId (1~4) + */ +public class IDGenerator { + private final static Logger logger = LoggerFactory.getLogger(IDGenerator.class); + private final static long twepoch = 1361753741828L; + private final static long workerIdBits = 4L; + private final static long maxWorkerId = -1L ^ -1L << workerIdBits; + private final static long sequenceBits = 10L; + private long workerId; + private long sequence = 0L; + + private final static long workerIdShift = sequenceBits; + private final static long timestampLeftShift = sequenceBits + workerIdBits; + private final static long sequenceMask = -1L ^ -1L << sequenceBits; + + private long lastTimestamp = -1L; + + private IDGenerator(final long workerId) { + super(); + this.workerId = workerId; + } + + public static long generateMinId(int wid, long time) { + return (time - twepoch << timestampLeftShift) | (wid << workerIdShift); + } + + public synchronized long nextId() { + long timestamp = this.timeGen(); + if (this.lastTimestamp == timestamp) { + this.sequence = (this.sequence + 1) & sequenceMask; + if (this.sequence == 0) { + timestamp = this.tilNextMillis(this.lastTimestamp); + } + } else { + this.sequence = 0; + } + if (timestamp < this.lastTimestamp) { + try { + throw new Exception( + String.format( + "Clock moved backwards. Refusing to generate id for %d milliseconds", + this.lastTimestamp - timestamp)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + this.lastTimestamp = timestamp; + long nextId = ((timestamp - twepoch << timestampLeftShift)) + | (this.workerId << workerIdShift) | (this.sequence); + return nextId; + } + + public static long generateMaxId(long wid, long time) { + return (time - twepoch << timestampLeftShift) | (wid << workerIdShift) | sequenceMask; + } + + private long tilNextMillis(final long lastTimestamp) { + long timestamp = this.timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = this.timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + private static IDGenerator generator; + + public static synchronized void init(Long workerId) throws Exception { + workerId = workerId % maxWorkerId; + logger.info("程序中init的workid为:{}", workerId); + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException(String.format( + "worker Id can't be greater than %d or less than 0", + IDGenerator.maxWorkerId)); + } + generator = new IDGenerator(workerId); + } + + public static Long generateId() { + if (null == generator) { + synchronized (IDGenerator.class) { + if (null == generator) { + try { + init(2L); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + return generator.nextId(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/JwtUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JwtUtil.java new file mode 100644 index 0000000..f0ca8e3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JwtUtil.java @@ -0,0 +1,90 @@ +package com.ruoyi.common.utils; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTDecodeException; +import com.auth0.jwt.exceptions.JWTVerificationException; + +import java.util.Date; + +public final class JwtUtil { + + private JwtUtil() { + } + + /** + * 生成jwt字符串 JWT(json web token) + * + * @param userId 用户id + * @param info 用户细腻系 + * @param expireIn 过期时间 + * @param secret 秘钥 + * @return token + */ + public static String sign(Long userId, String info, long expireIn, String secret) { + try { + Date date = new Date(System.currentTimeMillis() + expireIn * 1000); + Algorithm algorithm = Algorithm.HMAC256(secret); + return JWT.create() + //将userId保存到token里面 + .withAudience(userId.toString()) + //存放自定义数据 + .withClaim("info", info) + //过期时间 + .withExpiresAt(date) + //token的密钥 + .sign(algorithm); + } catch (Exception e) { + return null; + } + } + + /** + * 根据token获取userId + * + * @param token 登录token + * @return 用户id + */ + public static Long getUserId(String token) { + try { + String userId = JWT.decode(token).getAudience().get(0); + return Long.parseLong(userId); + } catch (JWTDecodeException e) { + return null; + } + } + + /** + * 根据token获取用户数据 + * + * @param token 用户登录token + * @return 用户数据 + */ + public static String getInfo(String token) { + try { + return JWT.decode(token).getClaim("info").asString(); + } catch (JWTDecodeException e) { + return null; + } + } + + /** + * 校验token + * + * @param token 用户登录token + * @param secret 秘钥 + * @return true/false + */ + public static Boolean checkSign(String token, String secret) { + + try { + Algorithm algorithm = Algorithm.HMAC256(secret); + JWTVerifier verifier = JWT.require(algorithm).build(); + verifier.verify(token); + return true; + } catch (JWTVerificationException e) { + return false; + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java index cd4dcc2..5d002d6 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java @@ -1,5 +1,7 @@ package com.ruoyi.common.utils; +import com.ruoyi.common.core.domain.model.AppLoginUser; +import com.ruoyi.common.core.domain.model.LoginUser; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -68,6 +70,17 @@ public class SecurityUtils { } } + /** + * 获取app用户 + **/ + public static AppLoginUser getAppLoginUser() { + try { + return (AppLoginUser) getAuthentication().getPrincipal(); + } catch (Exception e) { + throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED); + } + } + /** * 获取Authentication */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SortUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SortUtil.java new file mode 100644 index 0000000..537ffc0 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SortUtil.java @@ -0,0 +1,56 @@ +package com.ruoyi.common.utils; + +import com.ruoyi.common.exception.base.BaseException; +import org.springframework.data.domain.Sort; + +import java.util.*; +import java.util.regex.Pattern; + +public class SortUtil { + private static final Pattern COLUMN_REG = Pattern.compile("^[\\w\\_\\d]+$"); + + public static String sort2string(Sort sort) { + return sort2string(sort, Collections.emptyMap()); + } + + public static String sort2stringOrDefault(Sort sort) { + return sort2string(sort, "id desc"); + } + + public static String sort2string(Sort sort, String defaultSort) { + String o = sort2string(sort, Collections.emptyMap()); + return !StringUtils.isEmpty(o) ? o : defaultSort; + } + + public static String sort2string(Sort sort, Map sortColumns) { + Iterator orders = sort.stream().iterator(); + Set cols = new HashSet<>(); + StringBuilder sb = new StringBuilder(); + while (orders.hasNext()) { + Sort.Order it = orders.next(); + String prop = it.getProperty(); + if (!cols.add(prop)) { + continue; + } + if (!COLUMN_REG.matcher(prop).find()) { + throw new BaseException("排序字段错误"); + } + if (sortColumns == null || sortColumns.size() == 0) { + sb.append(prop) + .append(" ") + .append(it.getDirection()) + .append(","); + continue; + } + if (!sortColumns.containsKey(prop)) { + throw new BaseException("排序字段错误"); + } + sb.append(sortColumns.get(prop)) + .append(" ") + .append(it.getDirection()) + .append(","); + } + return sb.length() > 0 ? sb.substring(0, sb.length() - 1) : null; + } +} + diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml index 6c6de57..8053d42 100644 --- a/ruoyi-framework/pom.xml +++ b/ruoyi-framework/pom.xml @@ -47,12 +47,12 @@ + com.github.oshi oshi-core - com.ruoyi diff --git a/ruoyi-framework/ruoyi-framework.iml b/ruoyi-framework/ruoyi-framework.iml new file mode 100644 index 0000000..da56c9e --- /dev/null +++ b/ruoyi-framework/ruoyi-framework.iml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java index 912684d..1224d39 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -30,7 +30,7 @@ import com.ruoyi.system.domain.SysOperLog; /** * 操作日志记录处理 - * + * * @author ruoyi */ @Aspect @@ -55,7 +55,7 @@ public class LogAspect /** * 拦截异常操作 - * + * * @param joinPoint 切点 * @param e 异常 */ @@ -111,7 +111,7 @@ public class LogAspect /** * 获取注解中对方法的描述信息 用于Controller层注解 - * + * * @param log 日志 * @param operLog 操作日志 * @throws Exception @@ -139,7 +139,7 @@ public class LogAspect /** * 获取请求的参数,放到log中 - * + * * @param operLog 操作日志 * @throws Exception 异常 */ @@ -194,7 +194,7 @@ public class LogAspect /** * 判断是否需要过滤的对象。 - * + * * @param o 对象信息。 * @return 如果是需要过滤的对象,则返回true;否则返回false。 */ diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JwtUtil1.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JwtUtil1.java deleted file mode 100644 index 2362411..0000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JwtUtil1.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.ruoyi.framework.config; - -import cn.hutool.core.date.DateTime; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -import java.util.Date; - -@ConfigurationProperties(prefix = "token") -@Component -@Qualifier("JwtUtil1") -public class JwtUtil1 { - - - private String secret; - private String appId; - private String header; - - /** - * 生成jwt token - */ - public String generateToken(String userId,String phone) { - Date nowDate = new DateTime(); - //过期时间 7天 - return Jwts.builder() - .setId(userId) - .claim("phone",phone) - .setIssuedAt(nowDate) - .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, secret) - .compact(); - } - - public Claims getClaimByToken(String token) { - try { - return Jwts.parser() - .setSigningKey(secret) - .parseClaimsJws(token) - .getBody(); - } catch (Exception e) { - return null; - } - } - - /** - * token是否过期 - * - * @return true:过期 - */ - - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public String getHeader() { - return header; - } - - public void setHeader(String header) { - this.header = header; - } - - public String getAppId() { - return appId; - } - - public void setAppId(String appId) { - this.appId = appId; - } -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/LoginInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/LoginInterceptor.java deleted file mode 100644 index f2f3fc7..0000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/LoginInterceptor.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ruoyi.framework.config; - -import io.jsonwebtoken.Claims; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.ModelAndView; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - -//拦截器 - -public class LoginInterceptor implements HandlerInterceptor { - - @Autowired - private JwtUtil1 jwtUtil1; - - //加载时机:处理器拦截用的,该方法将在Controller处理之前进行调用 - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - String token = request.getHeader("token"); - if (token==null||token.equals("")) { - response.setStatus(401); - return false; - } - Claims claims = jwtUtil1.getClaimByToken(token); - //token失效 - if (claims == null ) { - response.setStatus(401);//|| jwtUtil.isTokenExpired(claims.getExpiration()) - return false; - } - request.setAttribute("userId",claims.getId()); - request.setAttribute("phone",claims.get("phone")); - return true; - } - - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { - - } - - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - - } - -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java index 3f4f485..511923c 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java @@ -1,5 +1,6 @@ package com.ruoyi.framework.config; +import com.ruoyi.common.config.FastJson2JsonRedisSerializer; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java index cdec79d..3661783 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java @@ -20,13 +20,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class ResourcesConfig implements WebMvcConfigurer { - @Autowired - private RepeatSubmitInterceptor repeatSubmitInterceptor; - - @Bean - LoginInterceptor loginInterceptor(){ - return new LoginInterceptor(); - } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) @@ -40,45 +33,7 @@ public class ResourcesConfig implements WebMvcConfigurer .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); } - /** - * 自定义拦截规则 - */ -// @Override -// public void addInterceptors(InterceptorRegistry registry) -// { -// registry.addInterceptor(loginInterceptor()) -// .addPathPatterns( -// "/api/**" -// ,"/api/course/yyCourse1" -// ) -// .excludePathPatterns( -// "/api/login" -// ,"/api/getCode" -// ,"/api/index/**" -// ,"/api/goods/**" -// ,"/api/venue/**" -// ,"/api/inherit/**" -// ,"/api/moments/**" -// ,"/api/sense/**" -// ,"/api/healthy/**" -// ,"/api/appreciate/**" -// ,"/api/member/getMembers" -// ,"/api/member/getOne" -// ,"/api/member/getList" -// ,"/api/course/listForService" -// ,"/api/course/getOne" -// ,"/api/context/**" -// ,"/api/courseLp/**" -// ,"/api/course/listLogDate" -// ,"/api/course/list" -// ,"/api/course/listLog" -// ,"/api/course/getDetail" -// ,"/api/course/longView" -// ,"/api/course/getTeacherList" -// ,"/api/callback" -// ); -// registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); -// } + /** * 跨域配置 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index 1b1c510..c732532 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -1,9 +1,13 @@ package com.ruoyi.framework.config; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -12,6 +16,7 @@ import org.springframework.security.config.annotation.web.configurers.Expression import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.web.filter.CorsFilter; @@ -20,9 +25,13 @@ import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter; import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl; import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import java.security.NoSuchAlgorithmException; + /** * spring security配置 - * + * * @author ruoyi */ @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @@ -33,7 +42,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter */ @Autowired private UserDetailsService userDetailsService; - + /** * 认证失败处理类 */ @@ -51,7 +60,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter */ @Autowired private JwtAuthenticationTokenFilter authenticationTokenFilter; - + /** * 跨域过滤器 */ @@ -72,11 +81,31 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter */ @Bean @Override + @Primary public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } + /** + * + */ + @Autowired + @Qualifier("AppUserDetailsServiceImpl") + private UserDetailsService appUserDetailsService; + + /** + * + */ + @Bean("AppUseAuthenticationManager") + public AuthenticationManager AppUseAuthenticationManagerBean() throws Exception + { + DaoAuthenticationProvider authenticationProvider=new DaoAuthenticationProvider(); + authenticationProvider.setUserDetailsService(appUserDetailsService); + authenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); + return new ProviderManager(authenticationProvider); + } + /** * anyRequest | 匹配所有请求路径 * access | SpringEl表达式结果为true时可以访问 @@ -109,7 +138,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter // 过滤请求 .authorizeRequests() // 对于登录login 注册register 验证码captchaImage 允许匿名访问 - .antMatchers("/login", "/register", "/captchaImage", "/api/login").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() @@ -121,6 +150,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); // 添加JWT filter httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); + // 添加CORS filter httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class); httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class); @@ -143,4 +173,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } + + } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java index 3eb2495..aeed993 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -5,20 +5,22 @@ import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.core.domain.model.LoginUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.AppLoginUser; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.service.TokenService; /** * token过滤器 验证token有效性 - * + * * @author ruoyi */ @Component @@ -31,13 +33,30 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { - LoginUser loginUser = tokenService.getLoginUser(request); - if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) - { - tokenService.verifyToken(loginUser); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); - authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authenticationToken); + String url=request.getRequestURL().toString(); + if (url.indexOf("/api/")!=-1){ + AppLoginUser loginUser = tokenService.getLoginAppUser(request); + + + if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) + { + tokenService.verifyAppUserToken(loginUser); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + }else { + + LoginUser loginUser = tokenService.getLoginUser(request); + + + if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) + { + tokenService.verifyToken(loginUser); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } } chain.doFilter(request, response); } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java index 059f519..ac28ed5 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -4,6 +4,8 @@ import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.core.domain.model.LoginUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.Authentication; @@ -12,7 +14,7 @@ import com.alibaba.fastjson2.JSON; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.AppLoginUser; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.manager.AsyncManager; @@ -21,7 +23,7 @@ import com.ruoyi.framework.web.service.TokenService; /** * 自定义退出处理类 返回成功 - * + * * @author ruoyi */ @Configuration @@ -32,7 +34,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler /** * 退出处理 - * + * * @return */ @Override diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppLoginService.java new file mode 100644 index 0000000..a49b719 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppLoginService.java @@ -0,0 +1,198 @@ +package com.ruoyi.framework.web.service; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.ruoyi.basic.service.YjAppUserService; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +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.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.mall.util.PayConstants; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +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 javax.annotation.Resource; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 登录校验方法 + * + * @author ruoyi + */ +@Component +public class AppLoginService +{ + @Autowired + private TokenService tokenService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private YjAppUserService appUserService; + + @Autowired + private ISysConfigService configService; + @Autowired + @Qualifier("AppUseAuthenticationManager") + private AuthenticationManager appUserAuthenticationManager; + + /** + * 登录验证 + * + * @param phoneNumber 手机号 + * @param password 密码 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public String login(String phoneNumber, String password, String code, String uuid,String registerId,String miniAppCode) + { + boolean captchaEnabled = configService.selectCaptchaEnabled(); + // 验证码开关 + if (captchaEnabled) + { + validateCaptcha(code, uuid); + } + // 用户验证 + Authentication authentication = null; + + //UsernamePasswordAuthenticationToken是Authenticatiion的实现类 + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(phoneNumber, password); + + //这里设置成上下文的意图是在身份验证过程中, + //其他组件或方法可以获取到该对象,以便进行相关的操作, + //比如记录登录日志、获取用户信息等。 + AuthenticationContextHolder.setContext(authenticationToken); + + // 该方法会去调用AppUserDetailsServiceImpl.loadUserByUsername + authentication = appUserAuthenticationManager.authenticate(authenticationToken); + +// AuthenticationContextHolder.clearContext(); + AppLoginUser loginUser = (AppLoginUser) authentication.getPrincipal(); + + boolean update=false; + UpdateWrapper wrapper=new UpdateWrapper().eq("app_user_id",loginUser.getAppUserId()); + + if (!loginUser.getAppUser().getRegisterId().equals(registerId)){ + wrapper.set("register_id",registerId); + update=true; + } + + if (StrUtil.isNotEmpty(miniAppCode) && StrUtil.isEmpty(loginUser.getAppUser().getOpenid())){ + + HashMap map=getOpenId(miniAppCode); + wrapper.set(ObjectUtil.isNotEmpty(map.get("openId")),"openid",map.get("openId").toString()); + wrapper.set(ObjectUtil.isNotEmpty(map.get("unionId")),"unionid",map.get("unionId").toString()); + update=true; + } + if (update){ + appUserService.update(wrapper); + } + + //将登录信息存入到数据库 + recordLoginInfo(loginUser.getAppUserId()); + + // 生成token + return tokenService.createAppToken(loginUser); + } + + /** + * 校验验证码 + * + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(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(); + } + } + + + /** + * 记录登录信息 + * + * @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 getOpenId(String code) { + //appid secret 配置到application里 + String url="https://api.weixin.qq.com/sns/jscode2session?appid="+ PayConstants.MINI_APP_ID +"&secret="+PayConstants.MINI_APP_SECRET+"&js_code="+code+"&grant_type=authorization_code"; + OkHttpClient client=new OkHttpClient(); + Request request=new Request.Builder().url(url).build(); + Response response= null; + HashMap userInfoMap = new HashMap<>(); + + try { + response = client.newCall(request).execute(); + + if(response.isSuccessful()){//请求成功 + String body=response.body().string(); + Map mapTypes = JSON.parseObject(body); +// String session_key = mapTypes.get("session_key").toString(); + String openId=mapTypes.get("openid").toString(); +// userInfoMap.put("session_key",session_key); + userInfoMap.put("openId",openId); + if(ObjectUtil.isNotEmpty(mapTypes.get("unionid"))){ + String unionId=mapTypes.get("unionid").toString(); + userInfoMap.put("unionId",unionId); + } + return userInfoMap; + } + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppUserDetailsServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppUserDetailsServiceImpl.java new file mode 100644 index 0000000..6053ebe --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AppUserDetailsServiceImpl.java @@ -0,0 +1,66 @@ +package com.ruoyi.framework.web.service; + +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.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.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; + +/** + * 用户验证处理 + * + * @author ruoyi + */ + +@Component("AppUserDetailsServiceImpl") +public class AppUserDetailsServiceImpl implements UserDetailsService +{ + private static final Logger log = LoggerFactory.getLogger(AppUserDetailsServiceImpl.class); + + @Autowired + private YjAppUserServiceImpl userService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException + { + AppUser user = userService.selectAppUserByPhone(username); + if (StringUtils.isNull(user)) + { + log.info("登录用户:{} 不存在.", username); + throw new ServiceException("登录用户:" + username + " 不存在"); + } + else if (user.getStatus() == 0) + { + log.info("登录用户:{} 已被停用.", username); + throw new ServiceException("对不起,您的账号:" + username + " 已停用"); + } +// 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); + } + + public UserDetails createLoginUser(AppUser user) + { + return new AppLoginUser(user.getId(), user); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java index c2f97a1..3deb8ff 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PermissionService.java @@ -1,17 +1,19 @@ package com.ruoyi.framework.web.service; import java.util.Set; + +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.LoginUser; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import com.ruoyi.common.core.domain.entity.SysRole; -import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.security.context.PermissionContextHolder; /** * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 - * + * * @author ruoyi */ @Service("ss") @@ -29,7 +31,7 @@ public class PermissionService /** * 验证用户是否具备某权限 - * + * * @param permission 权限字符串 * @return 用户是否具备某权限 */ @@ -90,7 +92,7 @@ public class PermissionService /** * 判断用户是否拥有某个角色 - * + * * @param role 角色字符串 * @return 用户是否具备某角色 */ @@ -156,7 +158,7 @@ public class PermissionService /** * 判断是否包含权限 - * + * * @param permissions 权限列表 * @param permission 权限字符串 * @return 用户是否具备某权限 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 4f7be26..f12d18d 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -4,6 +4,7 @@ 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; @@ -21,17 +22,19 @@ 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 @@ -43,9 +46,11 @@ public class SysLoginService @Resource private AuthenticationManager authenticationManager; + + @Autowired private RedisCache redisCache; - + @Autowired private ISysUserService userService; @@ -54,7 +59,7 @@ public class SysLoginService /** * 登录验证 - * + * * @param username 用户名 * @param password 密码 * @param code 验证码 @@ -73,7 +78,11 @@ public class SysLoginService Authentication authentication = null; try { + //UsernamePasswordAuthenticationToken是Authenticatiion的实现类 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); + //这里设置成上下文的意图是在身份验证过程中, + //其他组件或方法可以获取到该对象,以便进行相关的操作, + //比如记录登录日志、获取用户信息等。 AuthenticationContextHolder.setContext(authenticationToken); // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername authentication = authenticationManager.authenticate(authenticationToken); @@ -93,13 +102,16 @@ public class SysLoginService } 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); @@ -107,7 +119,7 @@ public class SysLoginService /** * 校验验证码 - * + * * @param username 用户名 * @param code 验证码 * @param uuid 唯一标识 @@ -143,4 +155,22 @@ public class SysLoginService 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); + } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java index 3d41241..db9dde9 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java @@ -4,12 +4,15 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; + +import com.ruoyi.common.core.domain.model.LoginUser; +import io.jsonwebtoken.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.AppLoginUser; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; @@ -17,9 +20,6 @@ import com.ruoyi.common.utils.ip.AddressUtils; import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.uuid.IdUtils; import eu.bitwalker.useragentutils.UserAgent; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; /** * token验证处理 @@ -41,6 +41,8 @@ public class TokenService @Value("${token.expireTime}") private int expireTime; + + protected static final long MILLIS_SECOND = 1000; protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; @@ -77,29 +79,6 @@ public class TokenService return null; } - /** - * 设置用户身份信息 - */ - public void setLoginUser(LoginUser loginUser) - { - if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) - { - refreshToken(loginUser); - } - } - - /** - * 删除用户身份信息 - */ - public void delLoginUser(String token) - { - if (StringUtils.isNotEmpty(token)) - { - String userKey = getTokenKey(token); - redisCache.deleteObject(userKey); - } - } - /** * 创建令牌 * @@ -115,9 +94,9 @@ public class TokenService Map claims = new HashMap<>(); claims.put(Constants.LOGIN_USER_KEY, token); + claims.put(Constants.JWT_USERID,loginUser.getUserId()); return createToken(claims); } - /** * 验证令牌有效期,相差不足20分钟,自动刷新缓存 * @@ -147,7 +126,10 @@ public class TokenService String userKey = getTokenKey(loginUser.getToken()); redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); } - + private String getTokenKey(String uuid) + { + return CacheConstants.LOGIN_TOKEN_KEY + uuid; + } /** * 设置用户代理信息 * @@ -163,6 +145,29 @@ public class TokenService loginUser.setOs(userAgent.getOperatingSystem().getName()); } + /** + * 设置用户身份信息 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + refreshToken(loginUser); + } + } + + /** + * 删除用户身份信息() + */ + public void delLoginUser(String token) + { + if (StringUtils.isNotEmpty(token)) + { + String userKey = getTokenKey(token); + redisCache.deleteObject(userKey); + } + } + /** * 从数据声明生成令牌 * @@ -177,6 +182,7 @@ public class TokenService return token; } + /** * 从令牌中获取数据声明 * @@ -219,8 +225,57 @@ public class TokenService return token; } - private String getTokenKey(String uuid) - { - return CacheConstants.LOGIN_TOKEN_KEY + uuid; + + + /** + * 以下app + */ + + @Value("${token.appuserExpireTime}") + private int appuserExpireTime; + public AppLoginUser getLoginAppUser(HttpServletRequest request) { + // 获取请求携带的令牌 + String token = getToken(request); + if (StringUtils.isNotEmpty(token)) { + try { + Claims claims = parseToken(token); + // 解析对应的权限以及用户信息 + String uuid = (String) claims.get(Constants.LOGIN_APPUSER_KEY); + String userKey = CacheConstants.LOGIN_APPUSER_TOKEN_KEY + uuid; + return redisCache.getCacheObject(userKey); + } catch (Exception e) { + } + } + return null; + } + /** + * app用户token + * @param loginUser + * @return + */ + public String createAppToken(AppLoginUser loginUser){ + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + refreshAppToken(loginUser); + Map claims = new HashMap<>(); + claims.put(Constants.LOGIN_APPUSER_KEY, token); + return createToken(claims); + } + + public void verifyAppUserToken(AppLoginUser loginUser) { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { + refreshAppToken(loginUser); + } } + + public void refreshAppToken(AppLoginUser loginUser) { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + appuserExpireTime * 24 * 60 * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = CacheConstants.LOGIN_APPUSER_TOKEN_KEY + loginUser.getToken(); + redisCache.setCacheObject(userKey, loginUser, appuserExpireTime, TimeUnit.DAYS); + } + } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java index 1950cb7..88b2ea5 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java @@ -1,14 +1,16 @@ package com.ruoyi.framework.web.service; +import com.ruoyi.common.core.domain.model.LoginUser; 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.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.AppLoginUser; import com.ruoyi.common.enums.UserStatus; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; @@ -20,13 +22,14 @@ import com.ruoyi.system.service.ISysUserService; * @author ruoyi */ @Service +@Primary public class UserDetailsServiceImpl implements UserDetailsService { private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); @Autowired private ISysUserService userService; - + @Autowired private SysPasswordService passwordService; diff --git a/ruoyi-generator/pom.xml b/ruoyi-generator/pom.xml deleted file mode 100644 index b065d91..0000000 --- a/ruoyi-generator/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - ruoyi - com.ruoyi - 3.8.3 - - 4.0.0 - - ruoyi-generator - - - generator代码生成 - - - - - - - org.apache.velocity - velocity-engine-core - - - - - commons-collections - commons-collections - - - - - com.ruoyi - ruoyi-common - - - - - \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java deleted file mode 100644 index cc4cd14..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/config/GenConfig.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.ruoyi.generator.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Component; - -/** - * 读取代码生成相关配置 - * - * @author ruoyi - */ -@Component -@ConfigurationProperties(prefix = "gen") -@PropertySource(value = { "classpath:generator.yml" }) -public class GenConfig -{ - /** 作者 */ - public static String author; - - /** 生成包路径 */ - public static String packageName; - - /** 自动去除表前缀,默认是false */ - public static boolean autoRemovePre; - - /** 表前缀(类名不会包含表前缀) */ - public static String tablePrefix; - - public static String getAuthor() - { - return author; - } - - @Value("${author}") - public void setAuthor(String author) - { - GenConfig.author = author; - } - - public static String getPackageName() - { - return packageName; - } - - @Value("${packageName}") - public void setPackageName(String packageName) - { - GenConfig.packageName = packageName; - } - - public static boolean getAutoRemovePre() - { - return autoRemovePre; - } - - @Value("${autoRemovePre}") - public void setAutoRemovePre(boolean autoRemovePre) - { - GenConfig.autoRemovePre = autoRemovePre; - } - - public static String getTablePrefix() - { - return tablePrefix; - } - - @Value("${tablePrefix}") - public void setTablePrefix(String tablePrefix) - { - GenConfig.tablePrefix = tablePrefix; - } -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java deleted file mode 100644 index 8521b53..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java +++ /dev/null @@ -1,214 +0,0 @@ -package com.ruoyi.generator.controller; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.io.IOUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.core.text.Convert; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.generator.domain.GenTable; -import com.ruoyi.generator.domain.GenTableColumn; -import com.ruoyi.generator.service.IGenTableColumnService; -import com.ruoyi.generator.service.IGenTableService; - -/** - * 代码生成 操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/tool/gen") -public class GenController extends BaseController -{ - @Autowired - private IGenTableService genTableService; - - @Autowired - private IGenTableColumnService genTableColumnService; - - /** - * 查询代码生成列表 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:list')") - @GetMapping("/list") - public TableDataInfo genList(GenTable genTable) - { - startPage(); - List list = genTableService.selectGenTableList(genTable); - return getDataTable(list); - } - - /** - * 修改代码生成业务 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:query')") - @GetMapping(value = "/{tableId}") - public AjaxResult getInfo(@PathVariable Long tableId) - { - GenTable table = genTableService.selectGenTableById(tableId); - List tables = genTableService.selectGenTableAll(); - List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); - Map map = new HashMap(); - map.put("info", table); - map.put("rows", list); - map.put("tables", tables); - return AjaxResult.success(map); - } - - /** - * 查询数据库列表 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:list')") - @GetMapping("/db/list") - public TableDataInfo dataList(GenTable genTable) - { - startPage(); - List list = genTableService.selectDbTableList(genTable); - return getDataTable(list); - } - - /** - * 查询数据表字段列表 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:list')") - @GetMapping(value = "/column/{tableId}") - public TableDataInfo columnList(Long tableId) - { - TableDataInfo dataInfo = new TableDataInfo(); - List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); - dataInfo.setRows(list); - dataInfo.setTotal(list.size()); - return dataInfo; - } - - /** - * 导入表结构(保存) - */ - @PreAuthorize("@ss.hasPermi('tool:gen:import')") - @Log(title = "代码生成", businessType = BusinessType.IMPORT) - @PostMapping("/importTable") - public AjaxResult importTableSave(String tables) - { - String[] tableNames = Convert.toStrArray(tables); - // 查询表信息 - List tableList = genTableService.selectDbTableListByNames(tableNames); - genTableService.importGenTable(tableList); - return AjaxResult.success(); - } - - /** - * 修改保存代码生成业务 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:edit')") - @Log(title = "代码生成", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult editSave(@Validated @RequestBody GenTable genTable) - { - genTableService.validateEdit(genTable); - genTableService.updateGenTable(genTable); - return AjaxResult.success(); - } - - /** - * 删除代码生成 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:remove')") - @Log(title = "代码生成", businessType = BusinessType.DELETE) - @DeleteMapping("/{tableIds}") - public AjaxResult remove(@PathVariable Long[] tableIds) - { - genTableService.deleteGenTableByIds(tableIds); - return AjaxResult.success(); - } - - /** - * 预览代码 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:preview')") - @GetMapping("/preview/{tableId}") - public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException - { - Map dataMap = genTableService.previewCode(tableId); - return AjaxResult.success(dataMap); - } - - /** - * 生成代码(下载方式) - */ - @PreAuthorize("@ss.hasPermi('tool:gen:code')") - @Log(title = "代码生成", businessType = BusinessType.GENCODE) - @GetMapping("/download/{tableName}") - public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException - { - byte[] data = genTableService.downloadCode(tableName); - genCode(response, data); - } - - /** - * 生成代码(自定义路径) - */ - @PreAuthorize("@ss.hasPermi('tool:gen:code')") - @Log(title = "代码生成", businessType = BusinessType.GENCODE) - @GetMapping("/genCode/{tableName}") - public AjaxResult genCode(@PathVariable("tableName") String tableName) - { - genTableService.generatorCode(tableName); - return AjaxResult.success(); - } - - /** - * 同步数据库 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:edit')") - @Log(title = "代码生成", businessType = BusinessType.UPDATE) - @GetMapping("/synchDb/{tableName}") - public AjaxResult synchDb(@PathVariable("tableName") String tableName) - { - genTableService.synchDb(tableName); - return AjaxResult.success(); - } - - /** - * 批量生成代码 - */ - @PreAuthorize("@ss.hasPermi('tool:gen:code')") - @Log(title = "代码生成", businessType = BusinessType.GENCODE) - @GetMapping("/batchGenCode") - public void batchGenCode(HttpServletResponse response, String tables) throws IOException - { - String[] tableNames = Convert.toStrArray(tables); - byte[] data = genTableService.downloadCode(tableNames); - genCode(response, data); - } - - /** - * 生成zip文件 - */ - private void genCode(HttpServletResponse response, byte[] data) throws IOException - { - response.reset(); - response.addHeader("Access-Control-Allow-Origin", "*"); - response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); - response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); - response.addHeader("Content-Length", "" + data.length); - response.setContentType("application/octet-stream; charset=UTF-8"); - IOUtils.write(data, response.getOutputStream()); - } -} \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java deleted file mode 100644 index 269779c..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTable.java +++ /dev/null @@ -1,372 +0,0 @@ -package com.ruoyi.generator.domain; - -import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import org.apache.commons.lang3.ArrayUtils; -import com.ruoyi.common.constant.GenConstants; -import com.ruoyi.common.core.domain.BaseEntity; -import com.ruoyi.common.utils.StringUtils; - -/** - * 业务表 gen_table - * - * @author ruoyi - */ -public class GenTable extends BaseEntity -{ - private static final long serialVersionUID = 1L; - - /** 编号 */ - private Long tableId; - - /** 表名称 */ - @NotBlank(message = "表名称不能为空") - private String tableName; - - /** 表描述 */ - @NotBlank(message = "表描述不能为空") - private String tableComment; - - /** 关联父表的表名 */ - private String subTableName; - - /** 本表关联父表的外键名 */ - private String subTableFkName; - - /** 实体类名称(首字母大写) */ - @NotBlank(message = "实体类名称不能为空") - private String className; - - /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ - private String tplCategory; - - /** 生成包路径 */ - @NotBlank(message = "生成包路径不能为空") - private String packageName; - - /** 生成模块名 */ - @NotBlank(message = "生成模块名不能为空") - private String moduleName; - - /** 生成业务名 */ - @NotBlank(message = "生成业务名不能为空") - private String businessName; - - /** 生成功能名 */ - @NotBlank(message = "生成功能名不能为空") - private String functionName; - - /** 生成作者 */ - @NotBlank(message = "作者不能为空") - private String functionAuthor; - - /** 生成代码方式(0zip压缩包 1自定义路径) */ - private String genType; - - /** 生成路径(不填默认项目路径) */ - private String genPath; - - /** 主键信息 */ - private GenTableColumn pkColumn; - - /** 子表信息 */ - private GenTable subTable; - - /** 表列信息 */ - @Valid - private List columns; - - /** 其它生成选项 */ - private String options; - - /** 树编码字段 */ - private String treeCode; - - /** 树父编码字段 */ - private String treeParentCode; - - /** 树名称字段 */ - private String treeName; - - /** 上级菜单ID字段 */ - private String parentMenuId; - - /** 上级菜单名称字段 */ - private String parentMenuName; - - public Long getTableId() - { - return tableId; - } - - public void setTableId(Long tableId) - { - this.tableId = tableId; - } - - public String getTableName() - { - return tableName; - } - - public void setTableName(String tableName) - { - this.tableName = tableName; - } - - public String getTableComment() - { - return tableComment; - } - - public void setTableComment(String tableComment) - { - this.tableComment = tableComment; - } - - public String getSubTableName() - { - return subTableName; - } - - public void setSubTableName(String subTableName) - { - this.subTableName = subTableName; - } - - public String getSubTableFkName() - { - return subTableFkName; - } - - public void setSubTableFkName(String subTableFkName) - { - this.subTableFkName = subTableFkName; - } - - public String getClassName() - { - return className; - } - - public void setClassName(String className) - { - this.className = className; - } - - public String getTplCategory() - { - return tplCategory; - } - - public void setTplCategory(String tplCategory) - { - this.tplCategory = tplCategory; - } - - public String getPackageName() - { - return packageName; - } - - public void setPackageName(String packageName) - { - this.packageName = packageName; - } - - public String getModuleName() - { - return moduleName; - } - - public void setModuleName(String moduleName) - { - this.moduleName = moduleName; - } - - public String getBusinessName() - { - return businessName; - } - - public void setBusinessName(String businessName) - { - this.businessName = businessName; - } - - public String getFunctionName() - { - return functionName; - } - - public void setFunctionName(String functionName) - { - this.functionName = functionName; - } - - public String getFunctionAuthor() - { - return functionAuthor; - } - - public void setFunctionAuthor(String functionAuthor) - { - this.functionAuthor = functionAuthor; - } - - public String getGenType() - { - return genType; - } - - public void setGenType(String genType) - { - this.genType = genType; - } - - public String getGenPath() - { - return genPath; - } - - public void setGenPath(String genPath) - { - this.genPath = genPath; - } - - public GenTableColumn getPkColumn() - { - return pkColumn; - } - - public void setPkColumn(GenTableColumn pkColumn) - { - this.pkColumn = pkColumn; - } - - public GenTable getSubTable() - { - return subTable; - } - - public void setSubTable(GenTable subTable) - { - this.subTable = subTable; - } - - public List getColumns() - { - return columns; - } - - public void setColumns(List columns) - { - this.columns = columns; - } - - public String getOptions() - { - return options; - } - - public void setOptions(String options) - { - this.options = options; - } - - public String getTreeCode() - { - return treeCode; - } - - public void setTreeCode(String treeCode) - { - this.treeCode = treeCode; - } - - public String getTreeParentCode() - { - return treeParentCode; - } - - public void setTreeParentCode(String treeParentCode) - { - this.treeParentCode = treeParentCode; - } - - public String getTreeName() - { - return treeName; - } - - public void setTreeName(String treeName) - { - this.treeName = treeName; - } - - public String getParentMenuId() - { - return parentMenuId; - } - - public void setParentMenuId(String parentMenuId) - { - this.parentMenuId = parentMenuId; - } - - public String getParentMenuName() - { - return parentMenuName; - } - - public void setParentMenuName(String parentMenuName) - { - this.parentMenuName = parentMenuName; - } - - public boolean isSub() - { - return isSub(this.tplCategory); - } - - public static boolean isSub(String tplCategory) - { - return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); - } - - public boolean isTree() - { - return isTree(this.tplCategory); - } - - public static boolean isTree(String tplCategory) - { - return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); - } - - public boolean isCrud() - { - return isCrud(this.tplCategory); - } - - public static boolean isCrud(String tplCategory) - { - return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); - } - - public boolean isSuperColumn(String javaField) - { - return isSuperColumn(this.tplCategory, javaField); - } - - public static boolean isSuperColumn(String tplCategory, String javaField) - { - if (isTree(tplCategory)) - { - return StringUtils.equalsAnyIgnoreCase(javaField, - ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); - } - return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); - } -} \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java deleted file mode 100644 index d1733b6..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/GenTableColumn.java +++ /dev/null @@ -1,373 +0,0 @@ -package com.ruoyi.generator.domain; - -import javax.validation.constraints.NotBlank; -import com.ruoyi.common.core.domain.BaseEntity; -import com.ruoyi.common.utils.StringUtils; - -/** - * 代码生成业务字段表 gen_table_column - * - * @author ruoyi - */ -public class GenTableColumn extends BaseEntity -{ - private static final long serialVersionUID = 1L; - - /** 编号 */ - private Long columnId; - - /** 归属表编号 */ - private Long tableId; - - /** 列名称 */ - private String columnName; - - /** 列描述 */ - private String columnComment; - - /** 列类型 */ - private String columnType; - - /** JAVA类型 */ - private String javaType; - - /** JAVA字段名 */ - @NotBlank(message = "Java属性不能为空") - private String javaField; - - /** 是否主键(1是) */ - private String isPk; - - /** 是否自增(1是) */ - private String isIncrement; - - /** 是否必填(1是) */ - private String isRequired; - - /** 是否为插入字段(1是) */ - private String isInsert; - - /** 是否编辑字段(1是) */ - private String isEdit; - - /** 是否列表字段(1是) */ - private String isList; - - /** 是否查询字段(1是) */ - private String isQuery; - - /** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */ - private String queryType; - - /** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */ - private String htmlType; - - /** 字典类型 */ - private String dictType; - - /** 排序 */ - private Integer sort; - - public void setColumnId(Long columnId) - { - this.columnId = columnId; - } - - public Long getColumnId() - { - return columnId; - } - - public void setTableId(Long tableId) - { - this.tableId = tableId; - } - - public Long getTableId() - { - return tableId; - } - - public void setColumnName(String columnName) - { - this.columnName = columnName; - } - - public String getColumnName() - { - return columnName; - } - - public void setColumnComment(String columnComment) - { - this.columnComment = columnComment; - } - - public String getColumnComment() - { - return columnComment; - } - - public void setColumnType(String columnType) - { - this.columnType = columnType; - } - - public String getColumnType() - { - return columnType; - } - - public void setJavaType(String javaType) - { - this.javaType = javaType; - } - - public String getJavaType() - { - return javaType; - } - - public void setJavaField(String javaField) - { - this.javaField = javaField; - } - - public String getJavaField() - { - return javaField; - } - - public String getCapJavaField() - { - return StringUtils.capitalize(javaField); - } - - public void setIsPk(String isPk) - { - this.isPk = isPk; - } - - public String getIsPk() - { - return isPk; - } - - public boolean isPk() - { - return isPk(this.isPk); - } - - public boolean isPk(String isPk) - { - return isPk != null && StringUtils.equals("1", isPk); - } - - public String getIsIncrement() - { - return isIncrement; - } - - public void setIsIncrement(String isIncrement) - { - this.isIncrement = isIncrement; - } - - public boolean isIncrement() - { - return isIncrement(this.isIncrement); - } - - public boolean isIncrement(String isIncrement) - { - return isIncrement != null && StringUtils.equals("1", isIncrement); - } - - public void setIsRequired(String isRequired) - { - this.isRequired = isRequired; - } - - public String getIsRequired() - { - return isRequired; - } - - public boolean isRequired() - { - return isRequired(this.isRequired); - } - - public boolean isRequired(String isRequired) - { - return isRequired != null && StringUtils.equals("1", isRequired); - } - - public void setIsInsert(String isInsert) - { - this.isInsert = isInsert; - } - - public String getIsInsert() - { - return isInsert; - } - - public boolean isInsert() - { - return isInsert(this.isInsert); - } - - public boolean isInsert(String isInsert) - { - return isInsert != null && StringUtils.equals("1", isInsert); - } - - public void setIsEdit(String isEdit) - { - this.isEdit = isEdit; - } - - public String getIsEdit() - { - return isEdit; - } - - public boolean isEdit() - { - return isInsert(this.isEdit); - } - - public boolean isEdit(String isEdit) - { - return isEdit != null && StringUtils.equals("1", isEdit); - } - - public void setIsList(String isList) - { - this.isList = isList; - } - - public String getIsList() - { - return isList; - } - - public boolean isList() - { - return isList(this.isList); - } - - public boolean isList(String isList) - { - return isList != null && StringUtils.equals("1", isList); - } - - public void setIsQuery(String isQuery) - { - this.isQuery = isQuery; - } - - public String getIsQuery() - { - return isQuery; - } - - public boolean isQuery() - { - return isQuery(this.isQuery); - } - - public boolean isQuery(String isQuery) - { - return isQuery != null && StringUtils.equals("1", isQuery); - } - - public void setQueryType(String queryType) - { - this.queryType = queryType; - } - - public String getQueryType() - { - return queryType; - } - - public String getHtmlType() - { - return htmlType; - } - - public void setHtmlType(String htmlType) - { - this.htmlType = htmlType; - } - - public void setDictType(String dictType) - { - this.dictType = dictType; - } - - public String getDictType() - { - return dictType; - } - - public void setSort(Integer sort) - { - this.sort = sort; - } - - public Integer getSort() - { - return sort; - } - - public boolean isSuperColumn() - { - return isSuperColumn(this.javaField); - } - - public static boolean isSuperColumn(String javaField) - { - return StringUtils.equalsAnyIgnoreCase(javaField, - // BaseEntity - "createBy", "createTime", "updateBy", "updateTime", "remark", - // TreeEntity - "parentName", "parentId", "orderNum", "ancestors"); - } - - public boolean isUsableColumn() - { - return isUsableColumn(javaField); - } - - public static boolean isUsableColumn(String javaField) - { - // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 - return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); - } - - public String readConverterExp() - { - String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); - StringBuffer sb = new StringBuffer(); - if (StringUtils.isNotEmpty(remarks)) - { - for (String value : remarks.split(" ")) - { - if (StringUtils.isNotEmpty(value)) - { - Object startStr = value.subSequence(0, 1); - String endStr = value.substring(1); - sb.append("").append(startStr).append("=").append(endStr).append(","); - } - } - return sb.deleteCharAt(sb.length() - 1).toString(); - } - else - { - return this.columnComment; - } - } -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java deleted file mode 100644 index 951e166..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.ruoyi.generator.mapper; - -import java.util.List; -import com.ruoyi.generator.domain.GenTableColumn; - -/** - * 业务字段 数据层 - * - * @author ruoyi - */ -public interface GenTableColumnMapper -{ - /** - * 根据表名称查询列信息 - * - * @param tableName 表名称 - * @return 列信息 - */ - public List selectDbTableColumnsByName(String tableName); - - /** - * 查询业务字段列表 - * - * @param tableId 业务字段编号 - * @return 业务字段集合 - */ - public List selectGenTableColumnListByTableId(Long tableId); - - /** - * 新增业务字段 - * - * @param genTableColumn 业务字段信息 - * @return 结果 - */ - public int insertGenTableColumn(GenTableColumn genTableColumn); - - /** - * 修改业务字段 - * - * @param genTableColumn 业务字段信息 - * @return 结果 - */ - public int updateGenTableColumn(GenTableColumn genTableColumn); - - /** - * 删除业务字段 - * - * @param genTableColumns 列数据 - * @return 结果 - */ - public int deleteGenTableColumns(List genTableColumns); - - /** - * 批量删除业务字段 - * - * @param ids 需要删除的数据ID - * @return 结果 - */ - public int deleteGenTableColumnByIds(Long[] ids); -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java deleted file mode 100644 index 9b330df..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.ruoyi.generator.mapper; - -import java.util.List; -import com.ruoyi.generator.domain.GenTable; - -/** - * 业务 数据层 - * - * @author ruoyi - */ -public interface GenTableMapper -{ - /** - * 查询业务列表 - * - * @param genTable 业务信息 - * @return 业务集合 - */ - public List selectGenTableList(GenTable genTable); - - /** - * 查询据库列表 - * - * @param genTable 业务信息 - * @return 数据库表集合 - */ - public List selectDbTableList(GenTable genTable); - - /** - * 查询据库列表 - * - * @param tableNames 表名称组 - * @return 数据库表集合 - */ - public List selectDbTableListByNames(String[] tableNames); - - /** - * 查询所有表信息 - * - * @return 表信息集合 - */ - public List selectGenTableAll(); - - /** - * 查询表ID业务信息 - * - * @param id 业务ID - * @return 业务信息 - */ - public GenTable selectGenTableById(Long id); - - /** - * 查询表名称业务信息 - * - * @param tableName 表名称 - * @return 业务信息 - */ - public GenTable selectGenTableByName(String tableName); - - /** - * 新增业务 - * - * @param genTable 业务信息 - * @return 结果 - */ - public int insertGenTable(GenTable genTable); - - /** - * 修改业务 - * - * @param genTable 业务信息 - * @return 结果 - */ - public int updateGenTable(GenTable genTable); - - /** - * 批量删除业务 - * - * @param ids 需要删除的数据ID - * @return 结果 - */ - public int deleteGenTableByIds(Long[] ids); -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java deleted file mode 100644 index 0679689..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.ruoyi.generator.service; - -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.ruoyi.common.core.text.Convert; -import com.ruoyi.generator.domain.GenTableColumn; -import com.ruoyi.generator.mapper.GenTableColumnMapper; - -/** - * 业务字段 服务层实现 - * - * @author ruoyi - */ -@Service -public class GenTableColumnServiceImpl implements IGenTableColumnService -{ - @Autowired - private GenTableColumnMapper genTableColumnMapper; - - /** - * 查询业务字段列表 - * - * @param tableId 业务字段编号 - * @return 业务字段集合 - */ - @Override - public List selectGenTableColumnListByTableId(Long tableId) - { - return genTableColumnMapper.selectGenTableColumnListByTableId(tableId); - } - - /** - * 新增业务字段 - * - * @param genTableColumn 业务字段信息 - * @return 结果 - */ - @Override - public int insertGenTableColumn(GenTableColumn genTableColumn) - { - return genTableColumnMapper.insertGenTableColumn(genTableColumn); - } - - /** - * 修改业务字段 - * - * @param genTableColumn 业务字段信息 - * @return 结果 - */ - @Override - public int updateGenTableColumn(GenTableColumn genTableColumn) - { - return genTableColumnMapper.updateGenTableColumn(genTableColumn); - } - - /** - * 删除业务字段对象 - * - * @param ids 需要删除的数据ID - * @return 结果 - */ - @Override - public int deleteGenTableColumnByIds(String ids) - { - return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids)); - } -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java deleted file mode 100644 index 4889f81..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java +++ /dev/null @@ -1,521 +0,0 @@ -package com.ruoyi.generator.service; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.StringWriter; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.velocity.Template; -import org.apache.velocity.VelocityContext; -import org.apache.velocity.app.Velocity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.GenConstants; -import com.ruoyi.common.core.text.CharsetKit; -import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.generator.domain.GenTable; -import com.ruoyi.generator.domain.GenTableColumn; -import com.ruoyi.generator.mapper.GenTableColumnMapper; -import com.ruoyi.generator.mapper.GenTableMapper; -import com.ruoyi.generator.util.GenUtils; -import com.ruoyi.generator.util.VelocityInitializer; -import com.ruoyi.generator.util.VelocityUtils; - -/** - * 业务 服务层实现 - * - * @author ruoyi - */ -@Service -public class GenTableServiceImpl implements IGenTableService -{ - private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class); - - @Autowired - private GenTableMapper genTableMapper; - - @Autowired - private GenTableColumnMapper genTableColumnMapper; - - /** - * 查询业务信息 - * - * @param id 业务ID - * @return 业务信息 - */ - @Override - public GenTable selectGenTableById(Long id) - { - GenTable genTable = genTableMapper.selectGenTableById(id); - setTableFromOptions(genTable); - return genTable; - } - - /** - * 查询业务列表 - * - * @param genTable 业务信息 - * @return 业务集合 - */ - @Override - public List selectGenTableList(GenTable genTable) - { - return genTableMapper.selectGenTableList(genTable); - } - - /** - * 查询据库列表 - * - * @param genTable 业务信息 - * @return 数据库表集合 - */ - @Override - public List selectDbTableList(GenTable genTable) - { - return genTableMapper.selectDbTableList(genTable); - } - - /** - * 查询据库列表 - * - * @param tableNames 表名称组 - * @return 数据库表集合 - */ - @Override - public List selectDbTableListByNames(String[] tableNames) - { - return genTableMapper.selectDbTableListByNames(tableNames); - } - - /** - * 查询所有表信息 - * - * @return 表信息集合 - */ - @Override - public List selectGenTableAll() - { - return genTableMapper.selectGenTableAll(); - } - - /** - * 修改业务 - * - * @param genTable 业务信息 - * @return 结果 - */ - @Override - @Transactional - public void updateGenTable(GenTable genTable) - { - String options = JSON.toJSONString(genTable.getParams()); - genTable.setOptions(options); - int row = genTableMapper.updateGenTable(genTable); - if (row > 0) - { - for (GenTableColumn cenTableColumn : genTable.getColumns()) - { - genTableColumnMapper.updateGenTableColumn(cenTableColumn); - } - } - } - - /** - * 删除业务对象 - * - * @param tableIds 需要删除的数据ID - * @return 结果 - */ - @Override - @Transactional - public void deleteGenTableByIds(Long[] tableIds) - { - genTableMapper.deleteGenTableByIds(tableIds); - genTableColumnMapper.deleteGenTableColumnByIds(tableIds); - } - - /** - * 导入表结构 - * - * @param tableList 导入表列表 - */ - @Override - @Transactional - public void importGenTable(List tableList) - { - String operName = SecurityUtils.getUsername(); - try - { - for (GenTable table : tableList) - { - String tableName = table.getTableName(); - GenUtils.initTable(table, operName); - int row = genTableMapper.insertGenTable(table); - if (row > 0) - { - // 保存列信息 - List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); - for (GenTableColumn column : genTableColumns) - { - GenUtils.initColumnField(column, table); - genTableColumnMapper.insertGenTableColumn(column); - } - } - } - } - catch (Exception e) - { - throw new ServiceException("导入失败:" + e.getMessage()); - } - } - - /** - * 预览代码 - * - * @param tableId 表编号 - * @return 预览数据列表 - */ - @Override - public Map previewCode(Long tableId) - { - Map dataMap = new LinkedHashMap<>(); - // 查询表信息 - GenTable table = genTableMapper.selectGenTableById(tableId); - // 设置主子表信息 - setSubTable(table); - // 设置主键列信息 - setPkColumn(table); - VelocityInitializer.initVelocity(); - - VelocityContext context = VelocityUtils.prepareContext(table); - - // 获取模板列表 - List templates = VelocityUtils.getTemplateList(table.getTplCategory()); - for (String template : templates) - { - // 渲染模板 - StringWriter sw = new StringWriter(); - Template tpl = Velocity.getTemplate(template, Constants.UTF8); - tpl.merge(context, sw); - dataMap.put(template, sw.toString()); - } - return dataMap; - } - - /** - * 生成代码(下载方式) - * - * @param tableName 表名称 - * @return 数据 - */ - @Override - public byte[] downloadCode(String tableName) - { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - ZipOutputStream zip = new ZipOutputStream(outputStream); - generatorCode(tableName, zip); - IOUtils.closeQuietly(zip); - return outputStream.toByteArray(); - } - - /** - * 生成代码(自定义路径) - * - * @param tableName 表名称 - */ - @Override - public void generatorCode(String tableName) - { - // 查询表信息 - GenTable table = genTableMapper.selectGenTableByName(tableName); - // 设置主子表信息 - setSubTable(table); - // 设置主键列信息 - setPkColumn(table); - - VelocityInitializer.initVelocity(); - - VelocityContext context = VelocityUtils.prepareContext(table); - - // 获取模板列表 - List templates = VelocityUtils.getTemplateList(table.getTplCategory()); - for (String template : templates) - { - if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) - { - // 渲染模板 - StringWriter sw = new StringWriter(); - Template tpl = Velocity.getTemplate(template, Constants.UTF8); - tpl.merge(context, sw); - try - { - String path = getGenPath(table, template); - FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8); - } - catch (IOException e) - { - throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); - } - } - } - } - - /** - * 同步数据库 - * - * @param tableName 表名称 - */ - @Override - @Transactional - public void synchDb(String tableName) - { - GenTable table = genTableMapper.selectGenTableByName(tableName); - List tableColumns = table.getColumns(); - Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); - - List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); - if (StringUtils.isEmpty(dbTableColumns)) - { - throw new ServiceException("同步数据失败,原表结构不存在"); - } - List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); - - dbTableColumns.forEach(column -> { - GenUtils.initColumnField(column, table); - if (tableColumnMap.containsKey(column.getColumnName())) - { - GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); - column.setColumnId(prevColumn.getColumnId()); - if (column.isList()) - { - // 如果是列表,继续保留查询方式/字典类型选项 - column.setDictType(prevColumn.getDictType()); - column.setQueryType(prevColumn.getQueryType()); - } - if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() - && (column.isInsert() || column.isEdit()) - && ((column.isUsableColumn()) || (!column.isSuperColumn()))) - { - // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 - column.setIsRequired(prevColumn.getIsRequired()); - column.setHtmlType(prevColumn.getHtmlType()); - } - genTableColumnMapper.updateGenTableColumn(column); - } - else - { - genTableColumnMapper.insertGenTableColumn(column); - } - }); - - List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); - if (StringUtils.isNotEmpty(delColumns)) - { - genTableColumnMapper.deleteGenTableColumns(delColumns); - } - } - - /** - * 批量生成代码(下载方式) - * - * @param tableNames 表数组 - * @return 数据 - */ - @Override - public byte[] downloadCode(String[] tableNames) - { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - ZipOutputStream zip = new ZipOutputStream(outputStream); - for (String tableName : tableNames) - { - generatorCode(tableName, zip); - } - IOUtils.closeQuietly(zip); - return outputStream.toByteArray(); - } - - /** - * 查询表信息并生成代码 - */ - private void generatorCode(String tableName, ZipOutputStream zip) - { - // 查询表信息 - GenTable table = genTableMapper.selectGenTableByName(tableName); - // 设置主子表信息 - setSubTable(table); - // 设置主键列信息 - setPkColumn(table); - - VelocityInitializer.initVelocity(); - - VelocityContext context = VelocityUtils.prepareContext(table); - - // 获取模板列表 - List templates = VelocityUtils.getTemplateList(table.getTplCategory()); - for (String template : templates) - { - // 渲染模板 - StringWriter sw = new StringWriter(); - Template tpl = Velocity.getTemplate(template, Constants.UTF8); - tpl.merge(context, sw); - try - { - // 添加到zip - zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); - IOUtils.write(sw.toString(), zip, Constants.UTF8); - IOUtils.closeQuietly(sw); - zip.flush(); - zip.closeEntry(); - } - catch (IOException e) - { - log.error("渲染模板失败,表名:" + table.getTableName(), e); - } - } - } - - /** - * 修改保存参数校验 - * - * @param genTable 业务信息 - */ - @Override - public void validateEdit(GenTable genTable) - { - if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) - { - String options = JSON.toJSONString(genTable.getParams()); - JSONObject paramsObj = JSON.parseObject(options); - if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) - { - throw new ServiceException("树编码字段不能为空"); - } - else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) - { - throw new ServiceException("树父编码字段不能为空"); - } - else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) - { - throw new ServiceException("树名称字段不能为空"); - } - else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) - { - if (StringUtils.isEmpty(genTable.getSubTableName())) - { - throw new ServiceException("关联子表的表名不能为空"); - } - else if (StringUtils.isEmpty(genTable.getSubTableFkName())) - { - throw new ServiceException("子表关联的外键名不能为空"); - } - } - } - } - - /** - * 设置主键列信息 - * - * @param table 业务表信息 - */ - public void setPkColumn(GenTable table) - { - for (GenTableColumn column : table.getColumns()) - { - if (column.isPk()) - { - table.setPkColumn(column); - break; - } - } - if (StringUtils.isNull(table.getPkColumn())) - { - table.setPkColumn(table.getColumns().get(0)); - } - if (GenConstants.TPL_SUB.equals(table.getTplCategory())) - { - for (GenTableColumn column : table.getSubTable().getColumns()) - { - if (column.isPk()) - { - table.getSubTable().setPkColumn(column); - break; - } - } - if (StringUtils.isNull(table.getSubTable().getPkColumn())) - { - table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); - } - } - } - - /** - * 设置主子表信息 - * - * @param table 业务表信息 - */ - public void setSubTable(GenTable table) - { - String subTableName = table.getSubTableName(); - if (StringUtils.isNotEmpty(subTableName)) - { - table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); - } - } - - /** - * 设置代码生成其他选项值 - * - * @param genTable 设置后的生成对象 - */ - public void setTableFromOptions(GenTable genTable) - { - JSONObject paramsObj = JSON.parseObject(genTable.getOptions()); - if (StringUtils.isNotNull(paramsObj)) - { - String treeCode = paramsObj.getString(GenConstants.TREE_CODE); - String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE); - String treeName = paramsObj.getString(GenConstants.TREE_NAME); - String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID); - String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME); - - genTable.setTreeCode(treeCode); - genTable.setTreeParentCode(treeParentCode); - genTable.setTreeName(treeName); - genTable.setParentMenuId(parentMenuId); - genTable.setParentMenuName(parentMenuName); - } - } - - /** - * 获取代码生成地址 - * - * @param table 业务表信息 - * @param template 模板文件路径 - * @return 生成地址 - */ - public static String getGenPath(GenTable table, String template) - { - String genPath = table.getGenPath(); - if (StringUtils.equals(genPath, "/")) - { - return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); - } - return genPath + File.separator + VelocityUtils.getFileName(template, table); - } -} \ No newline at end of file diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java deleted file mode 100644 index 3037f70..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.ruoyi.generator.service; - -import java.util.List; -import com.ruoyi.generator.domain.GenTableColumn; - -/** - * 业务字段 服务层 - * - * @author ruoyi - */ -public interface IGenTableColumnService -{ - /** - * 查询业务字段列表 - * - * @param tableId 业务字段编号 - * @return 业务字段集合 - */ - public List selectGenTableColumnListByTableId(Long tableId); - - /** - * 新增业务字段 - * - * @param genTableColumn 业务字段信息 - * @return 结果 - */ - public int insertGenTableColumn(GenTableColumn genTableColumn); - - /** - * 修改业务字段 - * - * @param genTableColumn 业务字段信息 - * @return 结果 - */ - public int updateGenTableColumn(GenTableColumn genTableColumn); - - /** - * 删除业务字段信息 - * - * @param ids 需要删除的数据ID - * @return 结果 - */ - public int deleteGenTableColumnByIds(String ids); -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java deleted file mode 100644 index 9d53f95..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.ruoyi.generator.service; - -import java.util.List; -import java.util.Map; -import com.ruoyi.generator.domain.GenTable; - -/** - * 业务 服务层 - * - * @author ruoyi - */ -public interface IGenTableService -{ - /** - * 查询业务列表 - * - * @param genTable 业务信息 - * @return 业务集合 - */ - public List selectGenTableList(GenTable genTable); - - /** - * 查询据库列表 - * - * @param genTable 业务信息 - * @return 数据库表集合 - */ - public List selectDbTableList(GenTable genTable); - - /** - * 查询据库列表 - * - * @param tableNames 表名称组 - * @return 数据库表集合 - */ - public List selectDbTableListByNames(String[] tableNames); - - /** - * 查询所有表信息 - * - * @return 表信息集合 - */ - public List selectGenTableAll(); - - /** - * 查询业务信息 - * - * @param id 业务ID - * @return 业务信息 - */ - public GenTable selectGenTableById(Long id); - - /** - * 修改业务 - * - * @param genTable 业务信息 - * @return 结果 - */ - public void updateGenTable(GenTable genTable); - - /** - * 删除业务信息 - * - * @param tableIds 需要删除的表数据ID - * @return 结果 - */ - public void deleteGenTableByIds(Long[] tableIds); - - /** - * 导入表结构 - * - * @param tableList 导入表列表 - */ - public void importGenTable(List tableList); - - /** - * 预览代码 - * - * @param tableId 表编号 - * @return 预览数据列表 - */ - public Map previewCode(Long tableId); - - /** - * 生成代码(下载方式) - * - * @param tableName 表名称 - * @return 数据 - */ - public byte[] downloadCode(String tableName); - - /** - * 生成代码(自定义路径) - * - * @param tableName 表名称 - * @return 数据 - */ - public void generatorCode(String tableName); - - /** - * 同步数据库 - * - * @param tableName 表名称 - */ - public void synchDb(String tableName); - - /** - * 批量生成代码(下载方式) - * - * @param tableNames 表数组 - * @return 数据 - */ - public byte[] downloadCode(String[] tableNames); - - /** - * 修改保存参数校验 - * - * @param genTable 业务信息 - */ - public void validateEdit(GenTable genTable); -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java deleted file mode 100644 index e7ebc20..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.ruoyi.generator.util; - -import java.util.Arrays; -import org.apache.commons.lang3.RegExUtils; -import com.ruoyi.common.constant.GenConstants; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.generator.config.GenConfig; -import com.ruoyi.generator.domain.GenTable; -import com.ruoyi.generator.domain.GenTableColumn; - -/** - * 代码生成器 工具类 - * - * @author ruoyi - */ -public class GenUtils -{ - /** - * 初始化表信息 - */ - public static void initTable(GenTable genTable, String operName) - { - genTable.setClassName(convertClassName(genTable.getTableName())); - genTable.setPackageName(GenConfig.getPackageName()); - genTable.setModuleName(getModuleName(GenConfig.getPackageName())); - genTable.setBusinessName(getBusinessName(genTable.getTableName())); - genTable.setFunctionName(replaceText(genTable.getTableComment())); - genTable.setFunctionAuthor(GenConfig.getAuthor()); - genTable.setCreateBy(operName); - } - - /** - * 初始化列属性字段 - */ - public static void initColumnField(GenTableColumn column, GenTable table) - { - String dataType = getDbType(column.getColumnType()); - String columnName = column.getColumnName(); - column.setTableId(table.getTableId()); - column.setCreateBy(table.getCreateBy()); - // 设置java字段名 - column.setJavaField(StringUtils.toCamelCase(columnName)); - // 设置默认类型 - column.setJavaType(GenConstants.TYPE_STRING); - column.setQueryType(GenConstants.QUERY_EQ); - - if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) - { - // 字符串长度超过500设置为文本域 - Integer columnLength = getColumnLength(column.getColumnType()); - String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; - column.setHtmlType(htmlType); - } - else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) - { - column.setJavaType(GenConstants.TYPE_DATE); - column.setHtmlType(GenConstants.HTML_DATETIME); - } - else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) - { - column.setHtmlType(GenConstants.HTML_INPUT); - - // 如果是浮点型 统一用BigDecimal - String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); - if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) - { - column.setJavaType(GenConstants.TYPE_BIGDECIMAL); - } - // 如果是整形 - else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) - { - column.setJavaType(GenConstants.TYPE_INTEGER); - } - // 长整形 - else - { - column.setJavaType(GenConstants.TYPE_LONG); - } - } - - // 插入字段(默认所有字段都需要插入) - column.setIsInsert(GenConstants.REQUIRE); - - // 编辑字段 - if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) - { - column.setIsEdit(GenConstants.REQUIRE); - } - // 列表字段 - if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) - { - column.setIsList(GenConstants.REQUIRE); - } - // 查询字段 - if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) - { - column.setIsQuery(GenConstants.REQUIRE); - } - - // 查询字段类型 - if (StringUtils.endsWithIgnoreCase(columnName, "name")) - { - column.setQueryType(GenConstants.QUERY_LIKE); - } - // 状态字段设置单选框 - if (StringUtils.endsWithIgnoreCase(columnName, "status")) - { - column.setHtmlType(GenConstants.HTML_RADIO); - } - // 类型&性别字段设置下拉框 - else if (StringUtils.endsWithIgnoreCase(columnName, "type") - || StringUtils.endsWithIgnoreCase(columnName, "sex")) - { - column.setHtmlType(GenConstants.HTML_SELECT); - } - // 图片字段设置图片上传控件 - else if (StringUtils.endsWithIgnoreCase(columnName, "image")) - { - column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); - } - // 文件字段设置文件上传控件 - else if (StringUtils.endsWithIgnoreCase(columnName, "file")) - { - column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); - } - // 内容字段设置富文本控件 - else if (StringUtils.endsWithIgnoreCase(columnName, "content")) - { - column.setHtmlType(GenConstants.HTML_EDITOR); - } - } - - /** - * 校验数组是否包含指定值 - * - * @param arr 数组 - * @param targetValue 值 - * @return 是否包含 - */ - public static boolean arraysContains(String[] arr, String targetValue) - { - return Arrays.asList(arr).contains(targetValue); - } - - /** - * 获取模块名 - * - * @param packageName 包名 - * @return 模块名 - */ - public static String getModuleName(String packageName) - { - int lastIndex = packageName.lastIndexOf("."); - int nameLength = packageName.length(); - return StringUtils.substring(packageName, lastIndex + 1, nameLength); - } - - /** - * 获取业务名 - * - * @param tableName 表名 - * @return 业务名 - */ - public static String getBusinessName(String tableName) - { - int lastIndex = tableName.lastIndexOf("_"); - int nameLength = tableName.length(); - return StringUtils.substring(tableName, lastIndex + 1, nameLength); - } - - /** - * 表名转换成Java类名 - * - * @param tableName 表名称 - * @return 类名 - */ - public static String convertClassName(String tableName) - { - boolean autoRemovePre = GenConfig.getAutoRemovePre(); - String tablePrefix = GenConfig.getTablePrefix(); - if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) - { - String[] searchList = StringUtils.split(tablePrefix, ","); - tableName = replaceFirst(tableName, searchList); - } - return StringUtils.convertToCamelCase(tableName); - } - - /** - * 批量替换前缀 - * - * @param replacementm 替换值 - * @param searchList 替换列表 - * @return - */ - public static String replaceFirst(String replacementm, String[] searchList) - { - String text = replacementm; - for (String searchString : searchList) - { - if (replacementm.startsWith(searchString)) - { - text = replacementm.replaceFirst(searchString, ""); - break; - } - } - return text; - } - - /** - * 关键字替换 - * - * @param text 需要被替换的名字 - * @return 替换后的名字 - */ - public static String replaceText(String text) - { - return RegExUtils.replaceAll(text, "(?:表|若依)", ""); - } - - /** - * 获取数据库类型字段 - * - * @param columnType 列类型 - * @return 截取后的列类型 - */ - public static String getDbType(String columnType) - { - if (StringUtils.indexOf(columnType, "(") > 0) - { - return StringUtils.substringBefore(columnType, "("); - } - else - { - return columnType; - } - } - - /** - * 获取字段长度 - * - * @param columnType 列类型 - * @return 截取后的列类型 - */ - public static Integer getColumnLength(String columnType) - { - if (StringUtils.indexOf(columnType, "(") > 0) - { - String length = StringUtils.substringBetween(columnType, "(", ")"); - return Integer.valueOf(length); - } - else - { - return 0; - } - } -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java deleted file mode 100644 index 9f69403..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.ruoyi.generator.util; - -import java.util.Properties; -import org.apache.velocity.app.Velocity; -import com.ruoyi.common.constant.Constants; - -/** - * VelocityEngine工厂 - * - * @author ruoyi - */ -public class VelocityInitializer -{ - /** - * 初始化vm方法 - */ - public static void initVelocity() - { - Properties p = new Properties(); - try - { - // 加载classpath目录下的vm文件 - p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); - // 定义字符集 - p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); - // 初始化Velocity引擎,指定配置Properties - Velocity.init(p); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } -} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java deleted file mode 100644 index 7ede02d..0000000 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java +++ /dev/null @@ -1,402 +0,0 @@ -package com.ruoyi.generator.util; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.apache.velocity.VelocityContext; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; -import com.ruoyi.common.constant.GenConstants; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.generator.domain.GenTable; -import com.ruoyi.generator.domain.GenTableColumn; - -/** - * 模板处理工具类 - * - * @author ruoyi - */ -public class VelocityUtils -{ - /** 项目空间路径 */ - private static final String PROJECT_PATH = "main/java"; - - /** mybatis空间路径 */ - private static final String MYBATIS_PATH = "main/resources/mapper"; - - /** 默认上级菜单,系统工具 */ - private static final String DEFAULT_PARENT_MENU_ID = "3"; - - /** - * 设置模板变量信息 - * - * @return 模板列表 - */ - public static VelocityContext prepareContext(GenTable genTable) - { - String moduleName = genTable.getModuleName(); - String businessName = genTable.getBusinessName(); - String packageName = genTable.getPackageName(); - String tplCategory = genTable.getTplCategory(); - String functionName = genTable.getFunctionName(); - - VelocityContext velocityContext = new VelocityContext(); - velocityContext.put("tplCategory", genTable.getTplCategory()); - velocityContext.put("tableName", genTable.getTableName()); - velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); - velocityContext.put("ClassName", genTable.getClassName()); - velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); - velocityContext.put("moduleName", genTable.getModuleName()); - velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); - velocityContext.put("businessName", genTable.getBusinessName()); - velocityContext.put("basePackage", getPackagePrefix(packageName)); - velocityContext.put("packageName", packageName); - velocityContext.put("author", genTable.getFunctionAuthor()); - velocityContext.put("datetime", DateUtils.getDate()); - velocityContext.put("pkColumn", genTable.getPkColumn()); - velocityContext.put("importList", getImportList(genTable)); - velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); - velocityContext.put("columns", genTable.getColumns()); - velocityContext.put("table", genTable); - velocityContext.put("dicts", getDicts(genTable)); - setMenuVelocityContext(velocityContext, genTable); - if (GenConstants.TPL_TREE.equals(tplCategory)) - { - setTreeVelocityContext(velocityContext, genTable); - } - if (GenConstants.TPL_SUB.equals(tplCategory)) - { - setSubVelocityContext(velocityContext, genTable); - } - return velocityContext; - } - - public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) - { - String options = genTable.getOptions(); - JSONObject paramsObj = JSON.parseObject(options); - String parentMenuId = getParentMenuId(paramsObj); - context.put("parentMenuId", parentMenuId); - } - - public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) - { - String options = genTable.getOptions(); - JSONObject paramsObj = JSON.parseObject(options); - String treeCode = getTreecode(paramsObj); - String treeParentCode = getTreeParentCode(paramsObj); - String treeName = getTreeName(paramsObj); - - context.put("treeCode", treeCode); - context.put("treeParentCode", treeParentCode); - context.put("treeName", treeName); - context.put("expandColumn", getExpandColumn(genTable)); - if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) - { - context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE)); - } - if (paramsObj.containsKey(GenConstants.TREE_NAME)) - { - context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME)); - } - } - - public static void setSubVelocityContext(VelocityContext context, GenTable genTable) - { - GenTable subTable = genTable.getSubTable(); - String subTableName = genTable.getSubTableName(); - String subTableFkName = genTable.getSubTableFkName(); - String subClassName = genTable.getSubTable().getClassName(); - String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); - - context.put("subTable", subTable); - context.put("subTableName", subTableName); - context.put("subTableFkName", subTableFkName); - context.put("subTableFkClassName", subTableFkClassName); - context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); - context.put("subClassName", subClassName); - context.put("subclassName", StringUtils.uncapitalize(subClassName)); - context.put("subImportList", getImportList(genTable.getSubTable())); - } - - /** - * 获取模板信息 - * - * @return 模板列表 - */ - public static List getTemplateList(String tplCategory) - { - List templates = new ArrayList(); - templates.add("vm/java/domain.java.vm"); - templates.add("vm/java/mapper.java.vm"); - templates.add("vm/java/service.java.vm"); - templates.add("vm/java/serviceImpl.java.vm"); - templates.add("vm/java/controller.java.vm"); - templates.add("vm/xml/mapper.xml.vm"); - templates.add("vm/sql/sql.vm"); - templates.add("vm/js/api.js.vm"); - if (GenConstants.TPL_CRUD.equals(tplCategory)) - { - templates.add("vm/vue/index.vue.vm"); - } - else if (GenConstants.TPL_TREE.equals(tplCategory)) - { - templates.add("vm/vue/index-tree.vue.vm"); - } - else if (GenConstants.TPL_SUB.equals(tplCategory)) - { - templates.add("vm/vue/index.vue.vm"); - templates.add("vm/java/sub-domain.java.vm"); - } - return templates; - } - - /** - * 获取文件名 - */ - public static String getFileName(String template, GenTable genTable) - { - // 文件名称 - String fileName = ""; - // 包路径 - String packageName = genTable.getPackageName(); - // 模块名 - String moduleName = genTable.getModuleName(); - // 大写类名 - String className = genTable.getClassName(); - // 业务名称 - String businessName = genTable.getBusinessName(); - - String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); - String mybatisPath = MYBATIS_PATH + "/" + moduleName; - String vuePath = "vue"; - - if (template.contains("domain.java.vm")) - { - fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); - } - if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) - { - fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); - } - else if (template.contains("mapper.java.vm")) - { - fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); - } - else if (template.contains("service.java.vm")) - { - fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); - } - else if (template.contains("serviceImpl.java.vm")) - { - fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); - } - else if (template.contains("controller.java.vm")) - { - fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); - } - else if (template.contains("mapper.xml.vm")) - { - fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); - } - else if (template.contains("sql.vm")) - { - fileName = businessName + "Menu.sql"; - } - else if (template.contains("api.js.vm")) - { - fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); - } - else if (template.contains("index.vue.vm")) - { - fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); - } - else if (template.contains("index-tree.vue.vm")) - { - fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); - } - return fileName; - } - - /** - * 获取包前缀 - * - * @param packageName 包名称 - * @return 包前缀名称 - */ - public static String getPackagePrefix(String packageName) - { - int lastIndex = packageName.lastIndexOf("."); - return StringUtils.substring(packageName, 0, lastIndex); - } - - /** - * 根据列类型获取导入包 - * - * @param genTable 业务表对象 - * @return 返回需要导入的包列表 - */ - public static HashSet getImportList(GenTable genTable) - { - List columns = genTable.getColumns(); - GenTable subGenTable = genTable.getSubTable(); - HashSet importList = new HashSet(); - if (StringUtils.isNotNull(subGenTable)) - { - importList.add("java.util.List"); - } - for (GenTableColumn column : columns) - { - if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) - { - importList.add("java.util.Date"); - importList.add("com.fasterxml.jackson.annotation.JsonFormat"); - } - else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) - { - importList.add("java.math.BigDecimal"); - } - } - return importList; - } - - /** - * 根据列类型获取字典组 - * - * @param genTable 业务表对象 - * @return 返回字典组 - */ - public static String getDicts(GenTable genTable) - { - List columns = genTable.getColumns(); - Set dicts = new HashSet(); - addDicts(dicts, columns); - if (StringUtils.isNotNull(genTable.getSubTable())) - { - List subColumns = genTable.getSubTable().getColumns(); - addDicts(dicts, subColumns); - } - return StringUtils.join(dicts, ", "); - } - - /** - * 添加字典列表 - * - * @param dicts 字典列表 - * @param columns 列集合 - */ - public static void addDicts(Set dicts, List columns) - { - for (GenTableColumn column : columns) - { - if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( - column.getHtmlType(), - new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) - { - dicts.add("'" + column.getDictType() + "'"); - } - } - } - - /** - * 获取权限前缀 - * - * @param moduleName 模块名称 - * @param businessName 业务名称 - * @return 返回权限前缀 - */ - public static String getPermissionPrefix(String moduleName, String businessName) - { - return StringUtils.format("{}:{}", moduleName, businessName); - } - - /** - * 获取上级菜单ID字段 - * - * @param paramsObj 生成其他选项 - * @return 上级菜单ID字段 - */ - public static String getParentMenuId(JSONObject paramsObj) - { - if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) - && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) - { - return paramsObj.getString(GenConstants.PARENT_MENU_ID); - } - return DEFAULT_PARENT_MENU_ID; - } - - /** - * 获取树编码 - * - * @param paramsObj 生成其他选项 - * @return 树编码 - */ - public static String getTreecode(JSONObject paramsObj) - { - if (paramsObj.containsKey(GenConstants.TREE_CODE)) - { - return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); - } - return StringUtils.EMPTY; - } - - /** - * 获取树父编码 - * - * @param paramsObj 生成其他选项 - * @return 树父编码 - */ - public static String getTreeParentCode(JSONObject paramsObj) - { - if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) - { - return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); - } - return StringUtils.EMPTY; - } - - /** - * 获取树名称 - * - * @param paramsObj 生成其他选项 - * @return 树名称 - */ - public static String getTreeName(JSONObject paramsObj) - { - if (paramsObj.containsKey(GenConstants.TREE_NAME)) - { - return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); - } - return StringUtils.EMPTY; - } - - /** - * 获取需要在哪一列上面显示展开按钮 - * - * @param genTable 业务表对象 - * @return 展开按钮列序号 - */ - public static int getExpandColumn(GenTable genTable) - { - String options = genTable.getOptions(); - JSONObject paramsObj = JSON.parseObject(options); - String treeName = paramsObj.getString(GenConstants.TREE_NAME); - int num = 0; - for (GenTableColumn column : genTable.getColumns()) - { - if (column.isList()) - { - num++; - String columnName = column.getColumnName(); - if (columnName.equals(treeName)) - { - break; - } - } - } - return num; - } -} diff --git a/ruoyi-generator/src/main/resources/generator.yml b/ruoyi-generator/src/main/resources/generator.yml deleted file mode 100644 index 5bd3dd6..0000000 --- a/ruoyi-generator/src/main/resources/generator.yml +++ /dev/null @@ -1,10 +0,0 @@ -# 代码生成 -gen: - # 作者 - author: ruoyi - # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool - packageName: com.ruoyi.system - # 自动去除表前缀,默认是false - autoRemovePre: false - # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) - tablePrefix: sys_ \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml deleted file mode 100644 index 5fa790f..0000000 --- a/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column - - - - - - - - insert into gen_table_column ( - table_id, - column_name, - column_comment, - column_type, - java_type, - java_field, - is_pk, - is_increment, - is_required, - is_insert, - is_edit, - is_list, - is_query, - query_type, - html_type, - dict_type, - sort, - create_by, - create_time - )values( - #{tableId}, - #{columnName}, - #{columnComment}, - #{columnType}, - #{javaType}, - #{javaField}, - #{isPk}, - #{isIncrement}, - #{isRequired}, - #{isInsert}, - #{isEdit}, - #{isList}, - #{isQuery}, - #{queryType}, - #{htmlType}, - #{dictType}, - #{sort}, - #{createBy}, - sysdate() - ) - - - - update gen_table_column - - column_comment = #{columnComment}, - java_type = #{javaType}, - java_field = #{javaField}, - is_insert = #{isInsert}, - is_edit = #{isEdit}, - is_list = #{isList}, - is_query = #{isQuery}, - is_required = #{isRequired}, - query_type = #{queryType}, - html_type = #{htmlType}, - dict_type = #{dictType}, - sort = #{sort}, - update_by = #{updateBy}, - update_time = sysdate() - - where column_id = #{columnId} - - - - delete from gen_table_column where table_id in - - #{tableId} - - - - - delete from gen_table_column where column_id in - - #{item.columnId} - - - - \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml deleted file mode 100644 index b605e90..0000000 --- a/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table - - - - - - - - - - - - - - - - - - insert into gen_table ( - table_name, - table_comment, - class_name, - tpl_category, - package_name, - module_name, - business_name, - function_name, - function_author, - gen_type, - gen_path, - remark, - create_by, - create_time - )values( - #{tableName}, - #{tableComment}, - #{className}, - #{tplCategory}, - #{packageName}, - #{moduleName}, - #{businessName}, - #{functionName}, - #{functionAuthor}, - #{genType}, - #{genPath}, - #{remark}, - #{createBy}, - sysdate() - ) - - - - update gen_table - - table_name = #{tableName}, - table_comment = #{tableComment}, - sub_table_name = #{subTableName}, - sub_table_fk_name = #{subTableFkName}, - class_name = #{className}, - function_author = #{functionAuthor}, - gen_type = #{genType}, - gen_path = #{genPath}, - tpl_category = #{tplCategory}, - package_name = #{packageName}, - module_name = #{moduleName}, - business_name = #{businessName}, - function_name = #{functionName}, - options = #{options}, - update_by = #{updateBy}, - remark = #{remark}, - update_time = sysdate() - - where table_id = #{tableId} - - - - delete from gen_table where table_id in - - #{tableId} - - - - \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm deleted file mode 100644 index ab19cf5..0000000 --- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm +++ /dev/null @@ -1,115 +0,0 @@ -package ${packageName}.controller; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; -import ${packageName}.domain.${ClassName}; -import ${packageName}.service.I${ClassName}Service; -import com.ruoyi.common.utils.poi.ExcelUtil; -#if($table.crud || $table.sub) -import com.ruoyi.common.core.page.TableDataInfo; -#elseif($table.tree) -#end - -/** - * ${functionName}Controller - * - * @author ${author} - * @date ${datetime} - */ -@RestController -@RequestMapping("/${moduleName}/${businessName}") -public class ${ClassName}Controller extends BaseController -{ - @Autowired - private I${ClassName}Service ${className}Service; - - /** - * 查询${functionName}列表 - */ - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") - @GetMapping("/list") -#if($table.crud || $table.sub) - public TableDataInfo list(${ClassName} ${className}) - { - startPage(); - List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); - return getDataTable(list); - } -#elseif($table.tree) - public AjaxResult list(${ClassName} ${className}) - { - List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); - return AjaxResult.success(list); - } -#end - - /** - * 导出${functionName}列表 - */ - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") - @Log(title = "${functionName}", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, ${ClassName} ${className}) - { - List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); - ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); - util.exportExcel(response, list, "${functionName}数据"); - } - - /** - * 获取${functionName}详细信息 - */ - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") - @GetMapping(value = "/{${pkColumn.javaField}}") - public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) - { - return AjaxResult.success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); - } - - /** - * 新增${functionName} - */ - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") - @Log(title = "${functionName}", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody ${ClassName} ${className}) - { - return toAjax(${className}Service.insert${ClassName}(${className})); - } - - /** - * 修改${functionName} - */ - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") - @Log(title = "${functionName}", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody ${ClassName} ${className}) - { - return toAjax(${className}Service.update${ClassName}(${className})); - } - - /** - * 删除${functionName} - */ - @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") - @Log(title = "${functionName}", businessType = BusinessType.DELETE) - @DeleteMapping("/{${pkColumn.javaField}s}") - public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) - { - return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); - } -} diff --git a/ruoyi-generator/src/main/resources/vm/java/domain.java.vm b/ruoyi-generator/src/main/resources/vm/java/domain.java.vm deleted file mode 100644 index bd51c17..0000000 --- a/ruoyi-generator/src/main/resources/vm/java/domain.java.vm +++ /dev/null @@ -1,105 +0,0 @@ -package ${packageName}.domain; - -#foreach ($import in $importList) -import ${import}; -#end -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import com.ruoyi.common.annotation.Excel; -#if($table.crud || $table.sub) -import com.ruoyi.common.core.domain.BaseEntity; -#elseif($table.tree) -import com.ruoyi.common.core.domain.TreeEntity; -#end - -/** - * ${functionName}对象 ${tableName} - * - * @author ${author} - * @date ${datetime} - */ -#if($table.crud || $table.sub) -#set($Entity="BaseEntity") -#elseif($table.tree) -#set($Entity="TreeEntity") -#end -public class ${ClassName} extends ${Entity} -{ - private static final long serialVersionUID = 1L; - -#foreach ($column in $columns) -#if(!$table.isSuperColumn($column.javaField)) - /** $column.columnComment */ -#if($column.list) -#set($parentheseIndex=$column.columnComment.indexOf("(")) -#if($parentheseIndex != -1) -#set($comment=$column.columnComment.substring(0, $parentheseIndex)) -#else -#set($comment=$column.columnComment) -#end -#if($parentheseIndex != -1) - @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") -#elseif($column.javaType == 'Date') - @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") -#else - @Excel(name = "${comment}") -#end -#end - private $column.javaType $column.javaField; - -#end -#end -#if($table.sub) - /** $table.subTable.functionName信息 */ - private List<${subClassName}> ${subclassName}List; - -#end -#foreach ($column in $columns) -#if(!$table.isSuperColumn($column.javaField)) -#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) -#set($AttrName=$column.javaField) -#else -#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) -#end - public void set${AttrName}($column.javaType $column.javaField) - { - this.$column.javaField = $column.javaField; - } - - public $column.javaType get${AttrName}() - { - return $column.javaField; - } -#end -#end - -#if($table.sub) - public List<${subClassName}> get${subClassName}List() - { - return ${subclassName}List; - } - - public void set${subClassName}List(List<${subClassName}> ${subclassName}List) - { - this.${subclassName}List = ${subclassName}List; - } - -#end - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) -#foreach ($column in $columns) -#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) -#set($AttrName=$column.javaField) -#else -#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) -#end - .append("${column.javaField}", get${AttrName}()) -#end -#if($table.sub) - .append("${subclassName}List", get${subClassName}List()) -#end - .toString(); - } -} diff --git a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm deleted file mode 100644 index 7e7d7c2..0000000 --- a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm +++ /dev/null @@ -1,91 +0,0 @@ -package ${packageName}.mapper; - -import java.util.List; -import ${packageName}.domain.${ClassName}; -#if($table.sub) -import ${packageName}.domain.${subClassName}; -#end - -/** - * ${functionName}Mapper接口 - * - * @author ${author} - * @date ${datetime} - */ -public interface ${ClassName}Mapper -{ - /** - * 查询${functionName} - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return ${functionName} - */ - public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); - - /** - * 查询${functionName}列表 - * - * @param ${className} ${functionName} - * @return ${functionName}集合 - */ - public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); - - /** - * 新增${functionName} - * - * @param ${className} ${functionName} - * @return 结果 - */ - public int insert${ClassName}(${ClassName} ${className}); - - /** - * 修改${functionName} - * - * @param ${className} ${functionName} - * @return 结果 - */ - public int update${ClassName}(${ClassName} ${className}); - - /** - * 删除${functionName} - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return 结果 - */ - public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); - - /** - * 批量删除${functionName} - * - * @param ${pkColumn.javaField}s 需要删除的数据主键集合 - * @return 结果 - */ - public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); -#if($table.sub) - - /** - * 批量删除${subTable.functionName} - * - * @param ${pkColumn.javaField}s 需要删除的数据主键集合 - * @return 结果 - */ - public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); - - /** - * 批量新增${subTable.functionName} - * - * @param ${subclassName}List ${subTable.functionName}列表 - * @return 结果 - */ - public int batch${subClassName}(List<${subClassName}> ${subclassName}List); - - - /** - * 通过${functionName}主键删除${subTable.functionName}信息 - * - * @param ${pkColumn.javaField} ${functionName}ID - * @return 结果 - */ - public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); -#end -} diff --git a/ruoyi-generator/src/main/resources/vm/java/service.java.vm b/ruoyi-generator/src/main/resources/vm/java/service.java.vm deleted file mode 100644 index 264882b..0000000 --- a/ruoyi-generator/src/main/resources/vm/java/service.java.vm +++ /dev/null @@ -1,61 +0,0 @@ -package ${packageName}.service; - -import java.util.List; -import ${packageName}.domain.${ClassName}; - -/** - * ${functionName}Service接口 - * - * @author ${author} - * @date ${datetime} - */ -public interface I${ClassName}Service -{ - /** - * 查询${functionName} - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return ${functionName} - */ - public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); - - /** - * 查询${functionName}列表 - * - * @param ${className} ${functionName} - * @return ${functionName}集合 - */ - public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); - - /** - * 新增${functionName} - * - * @param ${className} ${functionName} - * @return 结果 - */ - public int insert${ClassName}(${ClassName} ${className}); - - /** - * 修改${functionName} - * - * @param ${className} ${functionName} - * @return 结果 - */ - public int update${ClassName}(${ClassName} ${className}); - - /** - * 批量删除${functionName} - * - * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 - * @return 结果 - */ - public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); - - /** - * 删除${functionName}信息 - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return 结果 - */ - public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); -} diff --git a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm deleted file mode 100644 index 14746e1..0000000 --- a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm +++ /dev/null @@ -1,169 +0,0 @@ -package ${packageName}.service.impl; - -import java.util.List; -#foreach ($column in $columns) -#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') -import com.ruoyi.common.utils.DateUtils; -#break -#end -#end -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -#if($table.sub) -import java.util.ArrayList; -import com.ruoyi.common.utils.StringUtils; -import org.springframework.transaction.annotation.Transactional; -import ${packageName}.domain.${subClassName}; -#end -import ${packageName}.mapper.${ClassName}Mapper; -import ${packageName}.domain.${ClassName}; -import ${packageName}.service.I${ClassName}Service; - -/** - * ${functionName}Service业务层处理 - * - * @author ${author} - * @date ${datetime} - */ -@Service -public class ${ClassName}ServiceImpl implements I${ClassName}Service -{ - @Autowired - private ${ClassName}Mapper ${className}Mapper; - - /** - * 查询${functionName} - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return ${functionName} - */ - @Override - public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) - { - return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); - } - - /** - * 查询${functionName}列表 - * - * @param ${className} ${functionName} - * @return ${functionName} - */ - @Override - public List<${ClassName}> select${ClassName}List(${ClassName} ${className}) - { - return ${className}Mapper.select${ClassName}List(${className}); - } - - /** - * 新增${functionName} - * - * @param ${className} ${functionName} - * @return 结果 - */ -#if($table.sub) - @Transactional -#end - @Override - public int insert${ClassName}(${ClassName} ${className}) - { -#foreach ($column in $columns) -#if($column.javaField == 'createTime') - ${className}.setCreateTime(DateUtils.getNowDate()); -#end -#end -#if($table.sub) - int rows = ${className}Mapper.insert${ClassName}(${className}); - insert${subClassName}(${className}); - return rows; -#else - return ${className}Mapper.insert${ClassName}(${className}); -#end - } - - /** - * 修改${functionName} - * - * @param ${className} ${functionName} - * @return 结果 - */ -#if($table.sub) - @Transactional -#end - @Override - public int update${ClassName}(${ClassName} ${className}) - { -#foreach ($column in $columns) -#if($column.javaField == 'updateTime') - ${className}.setUpdateTime(DateUtils.getNowDate()); -#end -#end -#if($table.sub) - ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); - insert${subClassName}(${className}); -#end - return ${className}Mapper.update${ClassName}(${className}); - } - - /** - * 批量删除${functionName} - * - * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 - * @return 结果 - */ -#if($table.sub) - @Transactional -#end - @Override - public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) - { -#if($table.sub) - ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); -#end - return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); - } - - /** - * 删除${functionName}信息 - * - * @param ${pkColumn.javaField} ${functionName}主键 - * @return 结果 - */ -#if($table.sub) - @Transactional -#end - @Override - public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) - { -#if($table.sub) - ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); -#end - return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); - } -#if($table.sub) - - /** - * 新增${subTable.functionName}信息 - * - * @param ${className} ${functionName}对象 - */ - public void insert${subClassName}(${ClassName} ${className}) - { - List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); - ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); - if (StringUtils.isNotNull(${subclassName}List)) - { - List<${subClassName}> list = new ArrayList<${subClassName}>(); - for (${subClassName} ${subclassName} : ${subclassName}List) - { - ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); - list.add(${subclassName}); - } - if (list.size() > 0) - { - ${className}Mapper.batch${subClassName}(list); - } - } - } -#end -} diff --git a/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm b/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm deleted file mode 100644 index a3f53eb..0000000 --- a/ruoyi-generator/src/main/resources/vm/java/sub-domain.java.vm +++ /dev/null @@ -1,76 +0,0 @@ -package ${packageName}.domain; - -#foreach ($import in $subImportList) -import ${import}; -#end -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import com.ruoyi.common.annotation.Excel; -import com.ruoyi.common.core.domain.BaseEntity; - -/** - * ${subTable.functionName}对象 ${subTableName} - * - * @author ${author} - * @date ${datetime} - */ -public class ${subClassName} extends BaseEntity -{ - private static final long serialVersionUID = 1L; - -#foreach ($column in $subTable.columns) -#if(!$table.isSuperColumn($column.javaField)) - /** $column.columnComment */ -#if($column.list) -#set($parentheseIndex=$column.columnComment.indexOf("(")) -#if($parentheseIndex != -1) -#set($comment=$column.columnComment.substring(0, $parentheseIndex)) -#else -#set($comment=$column.columnComment) -#end -#if($parentheseIndex != -1) - @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") -#elseif($column.javaType == 'Date') - @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") -#else - @Excel(name = "${comment}") -#end -#end - private $column.javaType $column.javaField; - -#end -#end -#foreach ($column in $subTable.columns) -#if(!$table.isSuperColumn($column.javaField)) -#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) -#set($AttrName=$column.javaField) -#else -#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) -#end - public void set${AttrName}($column.javaType $column.javaField) - { - this.$column.javaField = $column.javaField; - } - - public $column.javaType get${AttrName}() - { - return $column.javaField; - } -#end -#end - - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) -#foreach ($column in $subTable.columns) -#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) -#set($AttrName=$column.javaField) -#else -#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) -#end - .append("${column.javaField}", get${AttrName}()) -#end - .toString(); - } -} diff --git a/ruoyi-generator/src/main/resources/vm/js/api.js.vm b/ruoyi-generator/src/main/resources/vm/js/api.js.vm deleted file mode 100644 index 9295524..0000000 --- a/ruoyi-generator/src/main/resources/vm/js/api.js.vm +++ /dev/null @@ -1,44 +0,0 @@ -import request from '@/utils/request' - -// 查询${functionName}列表 -export function list${BusinessName}(query) { - return request({ - url: '/${moduleName}/${businessName}/list', - method: 'get', - params: query - }) -} - -// 查询${functionName}详细 -export function get${BusinessName}(${pkColumn.javaField}) { - return request({ - url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, - method: 'get' - }) -} - -// 新增${functionName} -export function add${BusinessName}(data) { - return request({ - url: '/${moduleName}/${businessName}', - method: 'post', - data: data - }) -} - -// 修改${functionName} -export function update${BusinessName}(data) { - return request({ - url: '/${moduleName}/${businessName}', - method: 'put', - data: data - }) -} - -// 删除${functionName} -export function del${BusinessName}(${pkColumn.javaField}) { - return request({ - url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, - method: 'delete' - }) -} diff --git a/ruoyi-generator/src/main/resources/vm/sql/sql.vm b/ruoyi-generator/src/main/resources/vm/sql/sql.vm deleted file mode 100644 index 0575583..0000000 --- a/ruoyi-generator/src/main/resources/vm/sql/sql.vm +++ /dev/null @@ -1,22 +0,0 @@ --- 菜单 SQL -insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) -values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单'); - --- 按钮父菜单ID -SELECT @parentId := LAST_INSERT_ID(); - --- 按钮 SQL -insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) -values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', sysdate(), '', null, ''); - -insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) -values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', sysdate(), '', null, ''); - -insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) -values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', sysdate(), '', null, ''); - -insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) -values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', sysdate(), '', null, ''); - -insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) -values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', sysdate(), '', null, ''); \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm deleted file mode 100644 index 3def704..0000000 --- a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm +++ /dev/null @@ -1,502 +0,0 @@ - - - diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm deleted file mode 100644 index e9a1fae..0000000 --- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ /dev/null @@ -1,598 +0,0 @@ - - - diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm deleted file mode 100644 index 862297c..0000000 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm +++ /dev/null @@ -1,486 +0,0 @@ - - - diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm deleted file mode 100644 index f66cc3b..0000000 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm +++ /dev/null @@ -1,596 +0,0 @@ - - - diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt b/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt deleted file mode 100644 index 99239bb..0000000 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt +++ /dev/null @@ -1 +0,0 @@ -ʹõRuoYi-Vue3ǰˣôҪһ´Ŀ¼ģindex.vue.vmindex-tree.vue.vmļϼvueĿ¼ \ No newline at end of file diff --git a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm deleted file mode 100644 index 0ceb3d8..0000000 --- a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm +++ /dev/null @@ -1,135 +0,0 @@ - - - - - -#foreach ($column in $columns) - -#end - -#if($table.sub) - - - - - - -#foreach ($column in $subTable.columns) - -#end - -#end - - - select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} - - - - - - - - insert into ${tableName} - -#foreach($column in $columns) -#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) - $column.columnName, -#end -#end - - -#foreach($column in $columns) -#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) - #{$column.javaField}, -#end -#end - - - - - update ${tableName} - -#foreach($column in $columns) -#if($column.columnName != $pkColumn.columnName) - $column.columnName = #{$column.javaField}, -#end -#end - - where ${pkColumn.columnName} = #{${pkColumn.javaField}} - - - - delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} - - - - delete from ${tableName} where ${pkColumn.columnName} in - - #{${pkColumn.javaField}} - - -#if($table.sub) - - - delete from ${subTableName} where ${subTableFkName} in - - #{${subTableFkclassName}} - - - - - delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} - - - - insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values - - (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) - - -#end - \ No newline at end of file diff --git a/ruoyi-quartz/pom.xml b/ruoyi-im-client/pom.xml similarity index 53% rename from ruoyi-quartz/pom.xml rename to ruoyi-im-client/pom.xml index 090c0e2..31e25bf 100644 --- a/ruoyi-quartz/pom.xml +++ b/ruoyi-im-client/pom.xml @@ -9,32 +9,12 @@ 4.0.0 - ruoyi-quartz - - - quartz定时任务 - + ruoyi-im-client - - - - org.quartz-scheduler - quartz - - - com.mchange - c3p0 - - - - - com.ruoyi ruoyi-common - - \ No newline at end of file diff --git a/ruoyi-im-client/ruoyi-im-client.iml b/ruoyi-im-client/ruoyi-im-client.iml new file mode 100644 index 0000000..e9a0a10 --- /dev/null +++ b/ruoyi-im-client/ruoyi-im-client.iml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/IMAutoConfiguration.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/IMAutoConfiguration.java new file mode 100644 index 0000000..6f8e6f3 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/IMAutoConfiguration.java @@ -0,0 +1,13 @@ +package com.ruoyi.imclient; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + + +@Slf4j +@Configuration +@ComponentScan(basePackages = {"com.ruoyi.imclient", "com.ruoyi.common"}) +public class IMAutoConfiguration { + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/IMClient.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/IMClient.java new file mode 100644 index 0000000..4dce6ec --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/IMClient.java @@ -0,0 +1,81 @@ +package com.ruoyi.imclient; + +import com.ruoyi.common.im.model.IMGroupMessage; +import com.ruoyi.common.im.model.IMPrivateMessage; +import com.ruoyi.common.im.model.IMSystemMessage; +import com.ruoyi.common.im.enums.IMTerminalType; +import com.ruoyi.imclient.sender.IMSender; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Configuration; + +import java.util.List; +import java.util.Map; + +@Configuration +@AllArgsConstructor +public class IMClient { + + private final IMSender imSender; + + /** + * 判断用户是否在线 + * + * @param userId 用户id + */ + public Boolean isOnline(Long userId){ + return imSender.isOnline(userId); + } + + /** + * 判断多个用户是否在线 + * + * @param userIds 用户id列表 + * @return 在线的用户列表 + */ + public List getOnlineUser(List userIds){ + return imSender.getOnlineUser(userIds); + } + + + /** + * 判断多个用户是否在线 + * + * @param userIds 用户id列表 + * @return 在线的用户终端 + */ + public Map> getOnlineTerminal(List userIds){ + return imSender.getOnlineTerminal(userIds); + } + + /** + * 发送系统消息(发送结果通过MessageListener接收) + * + * @param message 私有消息 + */ + public void sendSystemMessage(IMSystemMessage message){ + imSender.sendSystemMessage(message); + } + + + /** + * 发送私聊消息(发送结果通过MessageListener接收) + * + * @param message 私有消息 + */ + public void sendPrivateMessage(IMPrivateMessage message){ + imSender.sendPrivateMessage(message); + } + + /** + * 发送群聊消息(发送结果通过MessageListener接收) + * + * @param message 群聊消息 + */ + public void sendGroupMessage(IMGroupMessage message){ + imSender.sendGroupMessage(message); + } + + + + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/annotation/IMListener.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/annotation/IMListener.java new file mode 100644 index 0000000..2cdcc00 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/annotation/IMListener.java @@ -0,0 +1,18 @@ +package com.ruoyi.imclient.annotation; + +import com.ruoyi.common.im.enums.IMListenerType; +import org.springframework.stereotype.Component; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE,ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Component +public @interface IMListener { + + IMListenerType type(); + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/listener/MessageListener.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/listener/MessageListener.java new file mode 100644 index 0000000..67f8673 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/listener/MessageListener.java @@ -0,0 +1,13 @@ +package com.ruoyi.imclient.listener; + + + +import com.ruoyi.common.im.model.IMSendResult; + +import java.util.List; + +public interface MessageListener { + + void process(List> result); + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/listener/MessageListenerMulticaster.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/listener/MessageListenerMulticaster.java new file mode 100644 index 0000000..73f6a48 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/listener/MessageListenerMulticaster.java @@ -0,0 +1,46 @@ +package com.ruoyi.imclient.listener; + + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.im.enums.IMListenerType; +import com.ruoyi.common.im.model.IMSendResult; +import com.ruoyi.imclient.annotation.IMListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.List; + +@Component +public class MessageListenerMulticaster { + + @Autowired(required = false) + private List messageListeners = Collections.emptyList(); + + public void multicast(IMListenerType listenerType, List results){ + if(CollUtil.isEmpty(results)){ + return; + } + for(MessageListener listener:messageListeners){ + IMListener annotation = listener.getClass().getAnnotation(IMListener.class); + if(annotation!=null && (annotation.type().equals(IMListenerType.ALL) || annotation.type().equals(listenerType))){ + results.forEach(result->{ + // 将data转回对象类型 + if(result.getData() instanceof JSONObject){ + Type superClass = listener.getClass().getGenericInterfaces()[0]; + Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; + JSONObject data = (JSONObject)result.getData(); + result.setData(data.toJavaObject(type)); + } + }); + // 回调到调用方处理 + listener.process(results); + } + } + } + + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/sender/IMSender.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/sender/IMSender.java new file mode 100644 index 0000000..953e9f7 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/sender/IMSender.java @@ -0,0 +1,262 @@ +package com.ruoyi.imclient.sender; + + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.enums.IMListenerType; +import com.ruoyi.common.im.enums.IMSendCode; +import com.ruoyi.common.im.enums.IMTerminalType; +import com.ruoyi.common.im.model.*; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import com.ruoyi.imclient.listener.MessageListenerMulticaster; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +@RequiredArgsConstructor +public class IMSender { + + @Autowired + private RedisMQTemplate redisMQTemplate; + + @Value("${ruoyi.name}") + private String appName; + + private final MessageListenerMulticaster listenerMulticaster; + + + public void sendSystemMessage(IMSystemMessage message){ + // 根据群聊每个成员所连的IM-server,进行分组 + Map sendMap = new HashMap<>(); + for (Integer terminal : message.getRecvTerminals()) { + message.getRecvIds().forEach(id -> { + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, id.toString(), terminal.toString()); + sendMap.put(key,new IMUserInfo(id, terminal)); + }); + } + // 批量拉取 + List serverIds = redisMQTemplate.opsForValue().multiGet(sendMap.keySet()); + // 格式:map<服务器id,list<接收方>> + Map> serverMap = new HashMap<>(); + List offLineUsers = new LinkedList<>(); + int idx = 0; + for (Map.Entry entry : sendMap.entrySet()) { + Integer serverId = (Integer)serverIds.get(idx++); + if (!Objects.isNull(serverId)) { + List list = serverMap.computeIfAbsent(serverId, o -> new LinkedList<>()); + list.add(entry.getValue()); + } else { + // 加入离线列表 + offLineUsers.add(entry.getValue()); + } + } + // 逐个server发送 + for (Map.Entry> entry : serverMap.entrySet()) { + IMRecvInfo recvInfo = new IMRecvInfo(); + recvInfo.setCmd(IMCmdType.SYSTEM_MESSAGE.code()); + recvInfo.setReceivers(new LinkedList<>(entry.getValue())); + recvInfo.setServiceName(appName); + recvInfo.setSendResult(message.getSendResult()); + recvInfo.setData(message.getData()); + // 推送至队列 + String key = String.join(":", IMRedisKey.IM_MESSAGE_SYSTEM_QUEUE, entry.getKey().toString()); + redisMQTemplate.opsForList().rightPush(key, recvInfo); + } + // 对离线用户回复消息状态 + if(message.getSendResult() && !offLineUsers.isEmpty()){ + List results = new LinkedList<>(); + for (IMUserInfo offLineUser : offLineUsers) { + IMSendResult result = new IMSendResult(); + result.setReceiver(offLineUser); + result.setCode(IMSendCode.NOT_ONLINE.code()); + result.setData(message.getData()); + results.add(result); + } + listenerMulticaster.multicast(IMListenerType.SYSTEM_MESSAGE, results); + } + } + + + public void sendPrivateMessage(IMPrivateMessage message) { + List results = new LinkedList<>(); + if(!Objects.isNull(message.getRecvId())){ + for (Integer terminal : message.getRecvTerminals()) { + // 获取对方连接的channelId + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, message.getRecvId().toString(), terminal.toString()); + Long serverId = (Long)redisMQTemplate.opsForValue().get(key); + // 如果对方在线,将数据存储至redis,等待拉取推送 + if (serverId != null) { + String sendKey = String.join(":", IMRedisKey.IM_MESSAGE_PRIVATE_QUEUE, serverId.toString()); + IMRecvInfo recvInfo = new IMRecvInfo(); + recvInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code()); + recvInfo.setSendResult(message.getSendResult()); + recvInfo.setServiceName(appName); + recvInfo.setSender(message.getSender()); + recvInfo.setReceivers(Collections.singletonList(new IMUserInfo(message.getRecvId(), terminal))); + recvInfo.setData(message.getData()); + + redisMQTemplate.opsForList().rightPush(sendKey, recvInfo); + + } else { + IMSendResult result = new IMSendResult(); + result.setSender(message.getSender()); + result.setReceiver(new IMUserInfo(message.getRecvId(), terminal)); + result.setCode(IMSendCode.NOT_ONLINE.code()); + result.setData(message.getData()); + results.add(result); + } + } + } + + // 推送给自己的其他终端 + if(message.getSendToSelf()){ + for (Integer terminal : IMTerminalType.codes()) { + if (message.getSender().getTerminal().equals(terminal)) { + continue; + } + // 获取终端连接的channelId + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, message.getSender().getId().toString(), terminal.toString()); + Integer serverId = (Integer)redisMQTemplate.opsForValue().get(key); + // 如果终端在线,将数据存储至redis,等待拉取推送 + if (serverId != null) { + String sendKey = String.join(":", IMRedisKey.IM_MESSAGE_PRIVATE_QUEUE, serverId.toString()); + IMRecvInfo recvInfo = new IMRecvInfo(); + // 自己的消息不需要回推消息结果 + recvInfo.setSendResult(false); + recvInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code()); + recvInfo.setSender(message.getSender()); + recvInfo.setReceivers(Collections.singletonList(new IMUserInfo(message.getSender().getId(), terminal))); + recvInfo.setData(message.getData()); + redisMQTemplate.opsForList().rightPush(sendKey, recvInfo); + } + } + } + // 对离线用户回复消息状态 + if(message.getSendResult() && !results.isEmpty()){ + listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, results); + } + + } + + public void sendGroupMessage(IMGroupMessage message) { + // 根据群聊每个成员所连的IM-server,进行分组 + Map sendMap = new HashMap<>(); + for (Integer terminal : message.getRecvTerminals()) { + message.getRecvIds().forEach(id -> { + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, id.toString(), terminal.toString()); + sendMap.put(key,new IMUserInfo(id, terminal)); + }); + } + // 批量拉取 + List serverIds = redisMQTemplate.opsForValue().multiGet(sendMap.keySet()); + // 格式:map<服务器id,list<接收方>> + Map> serverMap = new HashMap<>(); + List offLineUsers = new LinkedList<>(); + int idx = 0; + for (Map.Entry entry : sendMap.entrySet()) { + Integer serverId = (Integer)serverIds.get(idx++); + if (!Objects.isNull(serverId)) { + List list = serverMap.computeIfAbsent(serverId, o -> new LinkedList<>()); + list.add(entry.getValue()); + } else { + // 加入离线列表 + offLineUsers.add(entry.getValue()); + } + } + // 逐个server发送 + for (Map.Entry> entry : serverMap.entrySet()) { + IMRecvInfo recvInfo = new IMRecvInfo(); + recvInfo.setCmd(IMCmdType.GROUP_MESSAGE.code()); + recvInfo.setReceivers(new LinkedList<>(entry.getValue())); + recvInfo.setSender(message.getSender()); + recvInfo.setServiceName(appName); + recvInfo.setSendResult(message.getSendResult()); + recvInfo.setData(message.getData()); + // 推送至队列 + String key = String.join(":", IMRedisKey.IM_MESSAGE_GROUP_QUEUE, entry.getKey().toString()); + redisMQTemplate.opsForList().rightPush(key, recvInfo); + } + + // 推送给自己的其他终端 + if (message.getSendToSelf()) { + for (Integer terminal : IMTerminalType.codes()) { + if (terminal.equals(message.getSender().getTerminal())) { + continue; + } + // 获取终端连接的channelId + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, message.getSender().getId().toString(), terminal.toString()); + Integer serverId = (Integer)redisMQTemplate.opsForValue().get(key); + // 如果终端在线,将数据存储至redis,等待拉取推送 + if (!Objects.isNull(serverId)) { + IMRecvInfo recvInfo = new IMRecvInfo(); + recvInfo.setCmd(IMCmdType.GROUP_MESSAGE.code()); + recvInfo.setSender(message.getSender()); + recvInfo.setReceivers(Collections.singletonList(new IMUserInfo(message.getSender().getId(), terminal))); + // 自己的消息不需要回推消息结果 + recvInfo.setSendResult(false); + recvInfo.setData(message.getData()); + String sendKey = String.join(":", IMRedisKey.IM_MESSAGE_GROUP_QUEUE, serverId.toString()); + redisMQTemplate.opsForList().rightPush(sendKey, recvInfo); + } + } + } + // 对离线用户回复消息状态 + if(message.getSendResult() && !offLineUsers.isEmpty()){ + List results = new LinkedList<>(); + for (IMUserInfo offLineUser : offLineUsers) { + IMSendResult result = new IMSendResult(); + result.setSender(message.getSender()); + result.setReceiver(offLineUser); + result.setCode(IMSendCode.NOT_ONLINE.code()); + result.setData(message.getData()); + results.add(result); + } + listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, results); + } + + } + + public Map> getOnlineTerminal(List userIds){ + if(CollUtil.isEmpty(userIds)){ + return Collections.emptyMap(); + } + // 把所有用户的key都存起来 + Map userMap = new HashMap<>(); + for(Long id:userIds){ + for (Integer terminal : IMTerminalType.codes()) { + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, id.toString(), terminal.toString()); + userMap.put(key,new IMUserInfo(id,terminal)); + } + } + // 批量拉取 + List serverIds = redisMQTemplate.opsForValue().multiGet(userMap.keySet()); + int idx = 0; + Map> onlineMap = new HashMap<>(); + for (Map.Entry entry : userMap.entrySet()) { + // serverid有值表示用户在线 + if(serverIds.get(idx++) != null){ + IMUserInfo userInfo = entry.getValue(); + List terminals = onlineMap.computeIfAbsent(userInfo.getId(), o -> new LinkedList<>()); + terminals.add(IMTerminalType.fromCode(userInfo.getTerminal())); + } + } + // 去重并返回 + return onlineMap; + } + + public Boolean isOnline(Long userId) { + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), "*"); + return !Objects.requireNonNull(redisMQTemplate.keys(key)).isEmpty(); + } + + public List getOnlineUser(List userIds){ + return new LinkedList<>(getOnlineTerminal(userIds).keySet()); + } +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/AbstractMessageResultTask.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/AbstractMessageResultTask.java new file mode 100644 index 0000000..ee1e075 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/AbstractMessageResultTask.java @@ -0,0 +1,21 @@ +package com.ruoyi.imclient.task; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.im.mq.RedisMQConsumer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; + +@Slf4j +public abstract class AbstractMessageResultTask extends RedisMQConsumer { + + @Value("${ruoyi.name}") + private String appName; + + @Override + public String generateKey() { + return StrUtil.join(":", super.generateKey(), appName); + } + + + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/GroupMessageResultResultTask.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/GroupMessageResultResultTask.java new file mode 100644 index 0000000..1f4f345 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/GroupMessageResultResultTask.java @@ -0,0 +1,27 @@ +package com.ruoyi.imclient.task; + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMListenerType; +import com.ruoyi.common.im.model.IMSendResult; +import com.ruoyi.common.im.mq.RedisMQListener; +import com.ruoyi.imclient.listener.MessageListenerMulticaster; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + + +@Component +@RequiredArgsConstructor +@RedisMQListener(queue = IMRedisKey.IM_RESULT_GROUP_QUEUE, batchSize = 100) +public class GroupMessageResultResultTask extends AbstractMessageResultTask { + + private final MessageListenerMulticaster listenerMulticaster; + + @Override + public void onMessage(List results) { + listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, results); + } + + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/PrivateMessageResultResultTask.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/PrivateMessageResultResultTask.java new file mode 100644 index 0000000..5268773 --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/PrivateMessageResultResultTask.java @@ -0,0 +1,26 @@ +package com.ruoyi.imclient.task; + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMListenerType; +import com.ruoyi.common.im.model.IMSendResult; +import com.ruoyi.common.im.mq.RedisMQListener; +import com.ruoyi.imclient.listener.MessageListenerMulticaster; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + + +@Component +@RequiredArgsConstructor +@RedisMQListener(queue = IMRedisKey.IM_RESULT_PRIVATE_QUEUE, batchSize = 100) +public class PrivateMessageResultResultTask extends AbstractMessageResultTask { + + private final MessageListenerMulticaster listenerMulticaster; + + @Override + public void onMessage(List results) { + listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, results); + } + +} diff --git a/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/SystemMessageResultResultTask.java b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/SystemMessageResultResultTask.java new file mode 100644 index 0000000..610a35d --- /dev/null +++ b/ruoyi-im-client/src/main/java/com/ruoyi/imclient/task/SystemMessageResultResultTask.java @@ -0,0 +1,25 @@ +package com.ruoyi.imclient.task; + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMListenerType; +import com.ruoyi.common.im.model.IMSendResult; +import com.ruoyi.common.im.mq.RedisMQListener; +import com.ruoyi.imclient.listener.MessageListenerMulticaster; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +@RedisMQListener(queue = IMRedisKey.IM_RESULT_SYSTEM_QUEUE, batchSize = 100) +public class SystemMessageResultResultTask extends AbstractMessageResultTask { + + private final MessageListenerMulticaster listenerMulticaster; + + @Override + public void onMessage(List results) { + listenerMulticaster.multicast(IMListenerType.SYSTEM_MESSAGE, results); + } + +} diff --git a/ruoyi-im-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-im-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..e1485b3 --- /dev/null +++ b/ruoyi-im-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.ruoyi.imclient.IMAutoConfiguration \ No newline at end of file diff --git a/ruoyi-im-client/target/classes/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-im-client/target/classes/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..e1485b3 --- /dev/null +++ b/ruoyi-im-client/target/classes/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.ruoyi.imclient.IMAutoConfiguration \ No newline at end of file diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/IMAutoConfiguration.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/IMAutoConfiguration.class new file mode 100644 index 0000000..cb77e5e Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/IMAutoConfiguration.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/IMClient.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/IMClient.class new file mode 100644 index 0000000..2d0adb5 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/IMClient.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/annotation/IMListener.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/annotation/IMListener.class new file mode 100644 index 0000000..e5900c9 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/annotation/IMListener.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/listener/MessageListener.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/listener/MessageListener.class new file mode 100644 index 0000000..8803038 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/listener/MessageListener.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/listener/MessageListenerMulticaster.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/listener/MessageListenerMulticaster.class new file mode 100644 index 0000000..ecc0e01 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/listener/MessageListenerMulticaster.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/sender/IMSender.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/sender/IMSender.class new file mode 100644 index 0000000..6579197 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/sender/IMSender.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/AbstractMessageResultTask.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/AbstractMessageResultTask.class new file mode 100644 index 0000000..ffabcbd Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/AbstractMessageResultTask.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/GroupMessageResultResultTask.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/GroupMessageResultResultTask.class new file mode 100644 index 0000000..27c1184 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/GroupMessageResultResultTask.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/PrivateMessageResultResultTask.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/PrivateMessageResultResultTask.class new file mode 100644 index 0000000..874fb80 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/PrivateMessageResultResultTask.class differ diff --git a/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/SystemMessageResultResultTask.class b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/SystemMessageResultResultTask.class new file mode 100644 index 0000000..14e3ce3 Binary files /dev/null and b/ruoyi-im-client/target/classes/com/ruoyi/imclient/task/SystemMessageResultResultTask.class differ diff --git a/ruoyi-im-server/pom.xml b/ruoyi-im-server/pom.xml new file mode 100644 index 0000000..bbd9fae --- /dev/null +++ b/ruoyi-im-server/pom.xml @@ -0,0 +1,57 @@ + + + + ruoyi + com.ruoyi + 3.8.3 + + 4.0.0 + + ruoyi-im-server + + + + + com.ruoyi + ruoyi-common + + + io.netty + netty-all + 4.1.42.Final + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.1.1.RELEASE + + true + + + + + repackage + + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + ${project.artifactId} + + + + ${project.artifactId} + + \ No newline at end of file diff --git a/ruoyi-im-server/ruoyi-im-server.iml b/ruoyi-im-server/ruoyi-im-server.iml new file mode 100644 index 0000000..3274637 --- /dev/null +++ b/ruoyi-im-server/ruoyi-im-server.iml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/IMServerApp.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/IMServerApp.java new file mode 100644 index 0000000..d30a512 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/IMServerApp.java @@ -0,0 +1,21 @@ +package com.ruoyi.imserver; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableAsync +@EnableScheduling +@ComponentScan(basePackages = {"com.ruoyi"}) +@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) +public class IMServerApp { + + public static void main(String[] args) { + SpringApplication.run(IMServerApp.class, args); + } + +} + diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/constant/ChannelAttrKey.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/constant/ChannelAttrKey.java new file mode 100644 index 0000000..9f53e13 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/constant/ChannelAttrKey.java @@ -0,0 +1,21 @@ +package com.ruoyi.imserver.constant; + +public final class ChannelAttrKey { + + private ChannelAttrKey() { + } + + /** + * 用户ID + */ + public static final String USER_ID = "USER_ID"; + /** + * 终端类型 + */ + public static final String TERMINAL_TYPE = "TERMINAL_TYPE"; + /** + * 心跳次数 + */ + public static final String HEARTBEAT_TIMES = "HEARTBEAT_TIMES"; + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMChannelHandler.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMChannelHandler.java new file mode 100644 index 0000000..447ba5d --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMChannelHandler.java @@ -0,0 +1,100 @@ +package com.ruoyi.imserver.netty; + + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.model.IMSendInfo; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import com.ruoyi.imserver.constant.ChannelAttrKey; +import com.ruoyi.imserver.netty.processor.AbstractMessageProcessor; +import com.ruoyi.imserver.netty.processor.ProcessorFactory; +import com.ruoyi.imserver.util.SpringContextHolder; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import io.netty.util.AttributeKey; +import lombok.extern.slf4j.Slf4j; + +/** + * WebSocket 长连接下 文本帧的处理器 + * 实现浏览器发送文本回写 + * 浏览器连接状态监控 + */ +@Slf4j +public class IMChannelHandler extends SimpleChannelInboundHandler { + + /** + * 读取到消息后进行处理 + * + * @param ctx channel上下文 + * @param sendInfo 发送消息 + */ + @Override + protected void channelRead0(ChannelHandlerContext ctx, IMSendInfo sendInfo) { + // 创建处理器进行处理 + AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.fromCode(sendInfo.getCmd())); + processor.process(ctx, processor.transForm(sendInfo.getData())); + } + + /** + * 出现异常的处理 打印报错日志 + * + * @param ctx channel上下文 + * @param cause 异常信息 + */ + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + log.error(cause.getMessage()); + //关闭上下文 + //ctx.close(); + } + + /** + * 监控浏览器上线 + * + * @param ctx channel上下文 + */ + @Override + public void handlerAdded(ChannelHandlerContext ctx) { + log.info(ctx.channel().id().asLongText() + "连接"); + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) { + AttributeKey userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID); + Long userId = ctx.channel().attr(userIdAttr).get(); + AttributeKey terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE); + Integer terminal = ctx.channel().attr(terminalAttr).get(); + ChannelHandlerContext context = UserChannelCtxMap.getChannelCtx(userId, terminal); + // 判断一下,避免异地登录导致的误删 + if (context != null && ctx.channel().id().equals(context.channel().id())) { + // 移除channel + UserChannelCtxMap.removeChannelCtx(userId, terminal); + // 用户下线 + RedisMQTemplate redisTemplate = SpringContextHolder.getBean(RedisMQTemplate.class); + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), terminal.toString()); + redisTemplate.delete(key); + log.info("断开连接,userId:{},终端类型:{},{}", userId, terminal, ctx.channel().id().asLongText()); + } + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof IdleStateEvent) { + IdleState state = ((IdleStateEvent) evt).state(); + if (state == IdleState.READER_IDLE) { + // 在规定时间内没有收到客户端的上行数据, 主动断开连接 + AttributeKey attr = AttributeKey.valueOf("USER_ID"); + Long userId = ctx.channel().attr(attr).get(); + AttributeKey terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE); + Integer terminal = ctx.channel().attr(terminalAttr).get(); + log.info("心跳超时,即将断开连接,用户id:{},终端类型:{} ", userId, terminal); + ctx.channel().close(); + } + } else { + super.userEventTriggered(ctx, evt); + } + + } +} \ No newline at end of file diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMServer.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMServer.java new file mode 100644 index 0000000..0aa7229 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMServer.java @@ -0,0 +1,10 @@ +package com.ruoyi.imserver.netty; + +public interface IMServer { + + boolean isReady(); + + void start(); + + void stop(); +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMServerGroup.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMServerGroup.java new file mode 100644 index 0000000..34085be --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/IMServerGroup.java @@ -0,0 +1,56 @@ +package com.ruoyi.imserver.netty; + + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; +import java.util.List; + +@Slf4j +@Component +@AllArgsConstructor +public class IMServerGroup implements CommandLineRunner { + + public static volatile long serverId = 0; + + private final RedisMQTemplate redisMQTemplate; + + private final List imServers; + + /*** + * 判断服务器是否就绪 + * + **/ + public boolean isReady() { + for (IMServer imServer : imServers) { + if (!imServer.isReady()) { + return false; + } + } + return true; + } + + @Override + public void run(String... args) { + // 初始化SERVER_ID + String key = IMRedisKey.IM_MAX_SERVER_ID; + serverId = redisMQTemplate.opsForValue().increment(key, 1); + // 启动服务 + for (IMServer imServer : imServers) { + imServer.start(); + } + } + + @PreDestroy + public void destroy() { + // 停止服务 + for (IMServer imServer : imServers) { + imServer.stop(); + } + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/UserChannelCtxMap.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/UserChannelCtxMap.java new file mode 100644 index 0000000..b26bfdc --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/UserChannelCtxMap.java @@ -0,0 +1,46 @@ +package com.ruoyi.imserver.netty; + +import io.netty.channel.ChannelHandlerContext; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class UserChannelCtxMap { + + /** + * 维护userId和ctx的关联关系,格式:Map> + */ + private static Map> channelMap = new ConcurrentHashMap(); + + public static void addChannelCtx(Long userId, Integer channel, ChannelHandlerContext ctx) { + channelMap.computeIfAbsent(userId, key -> new ConcurrentHashMap()).put(channel, ctx); + } + + public static void removeChannelCtx(Long userId, Integer terminal) { + if (userId != null && terminal != null && channelMap.containsKey(userId)) { + Map userChannelMap = channelMap.get(userId); + userChannelMap.remove(terminal); + if (userChannelMap.isEmpty()) { + channelMap.remove(userId); + } + } + } + + public static ChannelHandlerContext getChannelCtx(Long userId, Integer terminal) { + if (userId != null && terminal != null && channelMap.containsKey(userId)) { + Map userChannelMap = channelMap.get(userId); + if (userChannelMap.containsKey(terminal)) { + return userChannelMap.get(terminal); + } + } + return null; + } + + public static Map getChannelCtx(Long userId) { + if (userId == null) { + return null; + } + return channelMap.get(userId); + } + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/AbstractMessageProcessor.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/AbstractMessageProcessor.java new file mode 100644 index 0000000..158fd8d --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/AbstractMessageProcessor.java @@ -0,0 +1,18 @@ +package com.ruoyi.imserver.netty.processor; + +import io.netty.channel.ChannelHandlerContext; + +public abstract class AbstractMessageProcessor { + + public void process(ChannelHandlerContext ctx, T data) { + } + + public void process(T data) { + } + + public T transForm(Object o) { + return (T) o; + } + + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/GroupMessageProcessor.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/GroupMessageProcessor.java new file mode 100644 index 0000000..2bb6c3d --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/GroupMessageProcessor.java @@ -0,0 +1,71 @@ +package com.ruoyi.imserver.netty.processor; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.enums.IMSendCode; +import com.ruoyi.common.im.model.IMRecvInfo; +import com.ruoyi.common.im.model.IMSendInfo; +import com.ruoyi.common.im.model.IMSendResult; +import com.ruoyi.common.im.model.IMUserInfo; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import com.ruoyi.imserver.netty.UserChannelCtxMap; +import io.netty.channel.ChannelHandlerContext; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Objects; + +@Slf4j +@Component +@RequiredArgsConstructor +public class GroupMessageProcessor extends AbstractMessageProcessor { + + private final RedisMQTemplate redisMQTemplate; + + @Override + public void process(IMRecvInfo recvInfo) { + IMUserInfo sender = recvInfo.getSender(); + List receivers = recvInfo.getReceivers(); + log.info("接收到群消息,发送者:{},接收用户数量:{},内容:{}", sender.getId(), receivers.size(), recvInfo.getData()); + for (IMUserInfo receiver : receivers) { + try { + ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(receiver.getId(), receiver.getTerminal()); + if (!Objects.isNull(channelCtx)) { + // 推送消息到用户 + IMSendInfo sendInfo = new IMSendInfo<>(); + sendInfo.setCmd(IMCmdType.GROUP_MESSAGE.code()); + sendInfo.setData(recvInfo.getData()); + channelCtx.channel().writeAndFlush(sendInfo); + // 消息发送成功确认 + sendResult(recvInfo, receiver, IMSendCode.SUCCESS); + + } else { + // 消息发送成功确认 + sendResult(recvInfo, receiver, IMSendCode.NOT_FIND_CHANNEL); + log.error("未找到channel,发送者:{},接收id:{},内容:{}", sender.getId(), receiver.getId(), recvInfo.getData()); + } + } catch (Exception e) { + // 消息发送失败确认 + sendResult(recvInfo, receiver, IMSendCode.UNKONW_ERROR); + log.error("发送消息异常,发送者:{},接收id:{},内容:{}", sender.getId(), receiver.getId(), recvInfo.getData()); + } + } + } + + + private void sendResult(IMRecvInfo recvInfo, IMUserInfo receiver, IMSendCode sendCode) { + if (recvInfo.getSendResult()) { + IMSendResult result = new IMSendResult<>(); + result.setSender(recvInfo.getSender()); + result.setReceiver(receiver); + result.setCode(sendCode.code()); + result.setData(recvInfo.getData()); + // 推送到结果队列 + String key = StrUtil.join(":", IMRedisKey.IM_RESULT_GROUP_QUEUE,recvInfo.getServiceName()); + redisMQTemplate.opsForList().rightPush(key, result); + } + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/HeartbeatProcessor.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/HeartbeatProcessor.java new file mode 100644 index 0000000..a61f709 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/HeartbeatProcessor.java @@ -0,0 +1,57 @@ +package com.ruoyi.imserver.netty.processor; + + +import cn.hutool.core.bean.BeanUtil; +import com.ruoyi.common.im.constant.IMConstant; +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.model.IMHeartbeatInfo; +import com.ruoyi.common.im.model.IMSendInfo; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import com.ruoyi.imserver.constant.ChannelAttrKey; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.AttributeKey; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +@RequiredArgsConstructor +public class HeartbeatProcessor extends AbstractMessageProcessor { + + private final RedisMQTemplate redisMQTemplate; + + @Override + public void process(ChannelHandlerContext ctx, IMHeartbeatInfo beatInfo) { + // 响应ws + IMSendInfo sendInfo = new IMSendInfo<>(); + sendInfo.setCmd(IMCmdType.HEART_BEAT.code()); + ctx.channel().writeAndFlush(sendInfo); + // 设置属性 + AttributeKey heartBeatAttr = AttributeKey.valueOf(ChannelAttrKey.HEARTBEAT_TIMES); + Long heartbeatTimes = ctx.channel().attr(heartBeatAttr).get(); + ctx.channel().attr(heartBeatAttr).set(++heartbeatTimes); + if (heartbeatTimes % 10 == 0) { + // 每心跳10次,用户在线状态续一次命 + AttributeKey userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID); + Long userId = ctx.channel().attr(userIdAttr).get(); + AttributeKey terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE); + Integer terminal = ctx.channel().attr(terminalAttr).get(); + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), terminal.toString()); + redisMQTemplate.expire(key, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); + } + AttributeKey userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID); + Long userId = ctx.channel().attr(userIdAttr).get(); + log.debug("心跳,userId:{},{}",userId,ctx.channel().id().asLongText()); + } + + @Override + public IMHeartbeatInfo transForm(Object o) { + HashMap map = (HashMap) o; + return BeanUtil.fillBeanWithMap(map, new IMHeartbeatInfo(), false); + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/LoginProcessor.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/LoginProcessor.java new file mode 100644 index 0000000..daf7aca --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/LoginProcessor.java @@ -0,0 +1,115 @@ +package com.ruoyi.imserver.netty.processor; + +import cn.hutool.core.bean.BeanUtil; +import com.ruoyi.common.im.constant.IMConstant; +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.model.IMLoginInfo; +import com.ruoyi.common.im.model.IMSendInfo; +import com.ruoyi.common.im.model.IMSessionInfo; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import com.ruoyi.common.utils.JwtUtil; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.imserver.constant.ChannelAttrKey; +import com.ruoyi.imserver.netty.IMServerGroup; +import com.ruoyi.imserver.netty.UserChannelCtxMap; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.Jwts; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.AttributeKey; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +@RequiredArgsConstructor +public class LoginProcessor extends AbstractMessageProcessor { + + private final RedisMQTemplate redisMQTemplate; + @Value("${token.secret}") + private String accessTokenSecret; + + @Override + public void process(ChannelHandlerContext ctx, IMLoginInfo loginInfo) { + if (!checkSign(loginInfo.getAccessToken())) { + ctx.channel().close(); + log.warn("用户token校验不通过,强制下线,token:{}", loginInfo.getAccessToken()); + return; + } + Claims claims= getClaims(loginInfo.getAccessToken()); + Long userId= claims.get("userid",Long.class); +// String strInfo = JwtUtil.getInfo(loginInfo.getAccessToken()); +// IMSessionInfo sessionInfo = JSON.parseObject(strInfo, IMSessionInfo.class); +// Long userId= SecurityUtils.getLoginUser().getUser().getUserId();//todo 获取用户信息有误 + Integer terminal = 1; + log.info("用户登录,userId:{}", userId); + ChannelHandlerContext context = UserChannelCtxMap.getChannelCtx(userId, terminal); + if (context != null && !ctx.channel().id().equals(context.channel().id())) { + // 不允许多地登录,强制下线 + IMSendInfo sendInfo = new IMSendInfo<>(); + sendInfo.setCmd(IMCmdType.FORCE_LOGUT.code()); + sendInfo.setData("您已在其他地方登录,将被强制下线"); + context.channel().writeAndFlush(sendInfo); + log.info("异地登录,强制下线,userId:{}", userId); + } + // 绑定用户和channel + UserChannelCtxMap.addChannelCtx(userId, terminal, ctx); + // 设置用户id属性 + AttributeKey userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID); + ctx.channel().attr(userIdAttr).set(userId); + // 设置用户终端类型 + AttributeKey terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE); + ctx.channel().attr(terminalAttr).set(terminal); + // 初始化心跳次数 + AttributeKey heartBeatAttr = AttributeKey.valueOf(ChannelAttrKey.HEARTBEAT_TIMES); + ctx.channel().attr(heartBeatAttr).set(0L); + // 在redis上记录每个user的channelId,15秒没有心跳,则自动过期 + String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), terminal.toString()); + redisMQTemplate.opsForValue().set(key, IMServerGroup.serverId, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); + // 响应ws + IMSendInfo sendInfo = new IMSendInfo<>(); + sendInfo.setCmd(IMCmdType.LOGIN.code()); + ctx.channel().writeAndFlush(sendInfo); + } + + + @Override + public IMLoginInfo transForm(Object o) { + HashMap map = (HashMap) o; + return BeanUtil.fillBeanWithMap(map, new IMLoginInfo(), false); + } + + private boolean checkSign(String accessToken){ + try { + // 关键步骤:解析Token并自动验证签名(使用相同的SECRET) + Jwts.parser() + .setSigningKey(accessTokenSecret) + .parseClaimsJws(accessToken) + .getBody(); + return true; + } catch (JwtException e) { + return false; + } + + } + + private Claims getClaims(String accessToken){ + try { + // 关键步骤:解析Token并自动验证签名(使用相同的SECRET) + return Jwts.parser() + .setSigningKey(accessTokenSecret) + .parseClaimsJws(accessToken) + .getBody(); + + } catch (JwtException e) { + } + return null; + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/PrivateMessageProcessor.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/PrivateMessageProcessor.java new file mode 100644 index 0000000..e932175 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/PrivateMessageProcessor.java @@ -0,0 +1,68 @@ +package com.ruoyi.imserver.netty.processor; + + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.enums.IMSendCode; +import com.ruoyi.common.im.model.IMRecvInfo; +import com.ruoyi.common.im.model.IMSendInfo; +import com.ruoyi.common.im.model.IMSendResult; +import com.ruoyi.common.im.model.IMUserInfo; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import com.ruoyi.imserver.netty.UserChannelCtxMap; +import io.netty.channel.ChannelHandlerContext; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +@Slf4j +@Component +@RequiredArgsConstructor +public class PrivateMessageProcessor extends AbstractMessageProcessor { + + private final RedisMQTemplate redisMQTemplate; + + @Override + public void process(IMRecvInfo recvInfo) { + IMUserInfo sender = recvInfo.getSender(); + IMUserInfo receiver = recvInfo.getReceivers().get(0); + log.info("接收到私聊消息,发送者:{},接收者:{},内容:{}", sender.getId(), receiver.getId(), recvInfo.getData()); + try { + ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(receiver.getId(), receiver.getTerminal()); + if (!Objects.isNull(channelCtx)) { + // 推送消息到用户 + IMSendInfo sendInfo = new IMSendInfo<>(); + sendInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code()); + sendInfo.setData(recvInfo.getData()); + channelCtx.channel().writeAndFlush(sendInfo); + // 消息发送成功确认 + sendResult(recvInfo, IMSendCode.SUCCESS); + } else { + // 消息推送失败确认 + sendResult(recvInfo, IMSendCode.NOT_FIND_CHANNEL); + log.error("未找到channel,发送者:{},接收者:{},内容:{}", sender.getId(), receiver.getId(), recvInfo.getData()); + } + } catch (Exception e) { + // 消息推送失败确认 + sendResult(recvInfo, IMSendCode.UNKONW_ERROR); + log.error("发送异常,发送者:{},接收者:{},内容:{}", sender.getId(), receiver.getId(), recvInfo.getData(), e); + } + + } + + private void sendResult(IMRecvInfo recvInfo, IMSendCode sendCode) { + if (recvInfo.getSendResult()) { + IMSendResult result = new IMSendResult<>(); + result.setSender(recvInfo.getSender()); + result.setReceiver(recvInfo.getReceivers().get(0)); + result.setCode(sendCode.code()); + result.setData(recvInfo.getData()); + // 推送到结果队列 + String key = StrUtil.join(":", IMRedisKey.IM_RESULT_PRIVATE_QUEUE,recvInfo.getServiceName()); + redisMQTemplate.opsForList().rightPush(key, result); + } + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/ProcessorFactory.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/ProcessorFactory.java new file mode 100644 index 0000000..a58dc25 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/ProcessorFactory.java @@ -0,0 +1,27 @@ +package com.ruoyi.imserver.netty.processor; + + +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.imserver.util.SpringContextHolder; + +public class ProcessorFactory { + + public static AbstractMessageProcessor createProcessor(IMCmdType cmd) { + + switch (cmd) { + case LOGIN: + return SpringContextHolder.getApplicationContext().getBean(LoginProcessor.class); + case HEART_BEAT: + return SpringContextHolder.getApplicationContext().getBean(HeartbeatProcessor.class); + case PRIVATE_MESSAGE: + return SpringContextHolder.getApplicationContext().getBean(PrivateMessageProcessor.class); + case GROUP_MESSAGE: + return SpringContextHolder.getApplicationContext().getBean(GroupMessageProcessor.class); + case SYSTEM_MESSAGE: + return SpringContextHolder.getApplicationContext().getBean(SystemMessageProcessor.class); + default: + return null; + } + } + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/SystemMessageProcessor.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/SystemMessageProcessor.java new file mode 100644 index 0000000..af654b8 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/processor/SystemMessageProcessor.java @@ -0,0 +1,68 @@ +package com.ruoyi.imserver.netty.processor; + + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.enums.IMSendCode; +import com.ruoyi.common.im.model.IMRecvInfo; +import com.ruoyi.common.im.model.IMSendInfo; +import com.ruoyi.common.im.model.IMSendResult; +import com.ruoyi.common.im.model.IMUserInfo; +import com.ruoyi.common.im.mq.RedisMQTemplate; +import com.ruoyi.imserver.netty.UserChannelCtxMap; +import io.netty.channel.ChannelHandlerContext; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +@Slf4j +@Component +@RequiredArgsConstructor +public class SystemMessageProcessor extends AbstractMessageProcessor { + + private final RedisMQTemplate redisMQTemplate; + + @Override + public void process(IMRecvInfo recvInfo) { + log.info("接收到系统消息,接收用户数量:{},内容:{}", recvInfo.getReceivers().size(), recvInfo.getData()); + for (IMUserInfo receiver : recvInfo.getReceivers()) { + try { + ChannelHandlerContext channelCtx = + UserChannelCtxMap.getChannelCtx(receiver.getId(), receiver.getTerminal()); + if (!Objects.isNull(channelCtx)) { + // 推送消息到用户 + IMSendInfo sendInfo = new IMSendInfo<>(); + sendInfo.setCmd(IMCmdType.SYSTEM_MESSAGE.code()); + sendInfo.setData(recvInfo.getData()); + channelCtx.channel().writeAndFlush(sendInfo); + // 消息发送成功确认 + sendResult(recvInfo, IMSendCode.SUCCESS); + } else { + // 消息推送失败确认 + sendResult(recvInfo, IMSendCode.NOT_FIND_CHANNEL); + log.error("未找到channel,接收者:{},内容:{}", receiver.getId(), recvInfo.getData()); + } + } catch (Exception e) { + // 消息推送失败确认 + sendResult(recvInfo, IMSendCode.UNKONW_ERROR); + log.error("发送异常,,接收者:{},内容:{}", receiver.getId(), recvInfo.getData(), e); + } + } + + } + + private void sendResult(IMRecvInfo recvInfo, IMSendCode sendCode) { + if (recvInfo.getSendResult()) { + IMSendResult result = new IMSendResult<>(); + result.setReceiver(recvInfo.getReceivers().get(0)); + result.setCode(sendCode.code()); + result.setData(recvInfo.getData()); + // 推送到结果队列 + String key = StrUtil.join(":", IMRedisKey.IM_RESULT_SYSTEM_QUEUE,recvInfo.getServiceName()); + redisMQTemplate.opsForList().rightPush(key, result); + } + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/TcpSocketServer.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/TcpSocketServer.java new file mode 100644 index 0000000..6b3b255 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/TcpSocketServer.java @@ -0,0 +1,98 @@ +package com.ruoyi.imserver.netty.tcp; + +import com.ruoyi.imserver.netty.IMChannelHandler; +import com.ruoyi.imserver.netty.IMServer; +import com.ruoyi.imserver.netty.tcp.endecode.MessageProtocolDecoder; +import com.ruoyi.imserver.netty.tcp.endecode.MessageProtocolEncoder; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.timeout.IdleStateHandler; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * TCP服务器,用于连接非网页的客户端,协议格式: 8字节内容的长度+IMSendInfo的JSON序列化 + * + * @author Blue + * @date 2022-11-20 + */ +@Slf4j +@Component +@ConditionalOnProperty(prefix = "tcpsocket", value = "enable", havingValue = "true", matchIfMissing = false) +public class TcpSocketServer implements IMServer { + + private volatile boolean ready = false; + + @Value("${tcpsocket.port}") + private int port; + + private EventLoopGroup bossGroup; + private EventLoopGroup workGroup; + + @Override + public boolean isReady() { + return ready; + } + + @Override + public void start() { + ServerBootstrap bootstrap = new ServerBootstrap(); + bossGroup = new NioEventLoopGroup(); + workGroup = new NioEventLoopGroup(); + // 设置为主从线程模型 + bootstrap.group(bossGroup, workGroup) + // 设置服务端NIO通信类型 + .channel(NioServerSocketChannel.class) + // 设置ChannelPipeline,也就是业务职责链,由处理的Handler串联而成,由从线程池处理 + .childHandler(new ChannelInitializer() { + // 添加处理的Handler,通常包括消息编解码、业务处理,也可以是日志、权限、过滤等 + @Override + protected void initChannel(Channel ch) throws Exception { + // 获取职责链 + ChannelPipeline pipeline = ch.pipeline(); + pipeline.addLast(new IdleStateHandler(120, 0, 0, TimeUnit.SECONDS)); + pipeline.addLast("encode", new MessageProtocolEncoder()); + pipeline.addLast("decode", new MessageProtocolDecoder()); + pipeline.addLast("handler", new IMChannelHandler()); + } + }) + // bootstrap 还可以设置TCP参数,根据需要可以分别设置主线程池和从线程池参数,来优化服务端性能。 + // 其中主线程池使用option方法来设置,从线程池使用childOption方法设置。 + // backlog表示主线程池中在套接口排队的最大数量,队列由未连接队列(三次握手未完成的)和已连接队列 + .option(ChannelOption.SO_BACKLOG, 5) + // 表示连接保活,相当于心跳机制,默认为7200s + .childOption(ChannelOption.SO_KEEPALIVE, true); + + try { + // 绑定端口,启动select线程,轮询监听channel事件,监听到事件之后就会交给从线程池处理 + Channel channel = bootstrap.bind(port).sync().channel(); + // 就绪标志 + this.ready = true; + log.info("tcp server 初始化完成,端口:{}", port); + // 等待服务端口关闭 + //channel.closeFuture().sync(); + } catch (InterruptedException e) { + log.info("tcp server 初始化异常", e); + } + } + + @Override + public void stop() { + if (bossGroup != null && !bossGroup.isShuttingDown() && !bossGroup.isShutdown()) { + bossGroup.shutdownGracefully(); + } + if (workGroup != null && !workGroup.isShuttingDown() && !workGroup.isShutdown()) { + workGroup.shutdownGracefully(); + } + this.ready = false; + log.info("tcp server 停止"); + } + + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/endecode/MessageProtocolDecoder.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/endecode/MessageProtocolDecoder.java new file mode 100644 index 0000000..944436d --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/endecode/MessageProtocolDecoder.java @@ -0,0 +1,31 @@ +package com.ruoyi.imserver.netty.tcp.endecode; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.im.model.IMSendInfo; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ReplayingDecoder; +import io.netty.util.CharsetUtil; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class MessageProtocolDecoder extends ReplayingDecoder { + + @Override + protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) throws Exception { + if (byteBuf.readableBytes() < 4) { + return; + } + // 获取到包的长度 + long length = byteBuf.readLong(); + // 转成IMSendInfo + ByteBuf contentBuf = byteBuf.readBytes((int) length); + String content = contentBuf.toString(CharsetUtil.UTF_8); + ObjectMapper objectMapper = new ObjectMapper(); + IMSendInfo sendInfo = objectMapper.readValue(content, IMSendInfo.class); + list.add(sendInfo); + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/endecode/MessageProtocolEncoder.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/endecode/MessageProtocolEncoder.java new file mode 100644 index 0000000..b14d5f8 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/tcp/endecode/MessageProtocolEncoder.java @@ -0,0 +1,25 @@ +package com.ruoyi.imserver.netty.tcp.endecode; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.im.model.IMSendInfo; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +import java.nio.charset.StandardCharsets; + +public class MessageProtocolEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext channelHandlerContext, IMSendInfo sendInfo, ByteBuf byteBuf) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + String content = objectMapper.writeValueAsString(sendInfo); + byte[] bytes = content.getBytes(StandardCharsets.UTF_8); + // 写入长度 + byteBuf.writeLong(bytes.length); + // 写入命令体 + byteBuf.writeBytes(bytes); + } + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/WebSocketServer.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/WebSocketServer.java new file mode 100644 index 0000000..42c72b0 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/WebSocketServer.java @@ -0,0 +1,107 @@ +package com.ruoyi.imserver.netty.ws; + +import com.ruoyi.imserver.netty.IMChannelHandler; +import com.ruoyi.imserver.netty.IMServer; +import com.ruoyi.imserver.netty.ws.endecode.MessageProtocolDecoder; +import com.ruoyi.imserver.netty.ws.endecode.MessageProtocolEncoder; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; +import io.netty.handler.stream.ChunkedWriteHandler; +import io.netty.handler.timeout.IdleStateHandler; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * WS服务器,用于连接网页的客户端,协议格式: 直接IMSendInfo的JSON序列化 + * + * @author Blue + * @date 2022-11-20 + */ +@Slf4j +@Component +@ConditionalOnProperty(prefix = "websocket", value = "enable", havingValue = "true", matchIfMissing = false) +public class WebSocketServer implements IMServer { + + @Value("${websocket.port}") + private int port; + + private volatile boolean ready = false; + + private EventLoopGroup bossGroup; + private EventLoopGroup workGroup; + + + @Override + public boolean isReady() { + return ready; + } + + @Override + public void start() { + ServerBootstrap bootstrap = new ServerBootstrap(); + bossGroup = new NioEventLoopGroup(); + workGroup = new NioEventLoopGroup(); + // 设置为主从线程模型 + bootstrap.group(bossGroup, workGroup) + // 设置服务端NIO通信类型 + .channel(NioServerSocketChannel.class) + // 设置ChannelPipeline,也就是业务职责链,由处理的Handler串联而成,由从线程池处理 + .childHandler(new ChannelInitializer() { + // 添加处理的Handler,通常包括消息编解码、业务处理,也可以是日志、权限、过滤等 + @Override + protected void initChannel(Channel ch) { + // 获取职责链 + ChannelPipeline pipeline = ch.pipeline(); + pipeline.addLast(new IdleStateHandler(60, 0, 0, TimeUnit.SECONDS)); + pipeline.addLast("http-codec", new HttpServerCodec()); + pipeline.addLast("aggregator", new HttpObjectAggregator(65535)); + pipeline.addLast("http-chunked", new ChunkedWriteHandler()); + pipeline.addLast(new WebSocketServerProtocolHandler("/im")); + pipeline.addLast("encode", new MessageProtocolEncoder()); + pipeline.addLast("decode", new MessageProtocolDecoder()); + pipeline.addLast("handler", new IMChannelHandler()); + } + }) + // bootstrap 还可以设置TCP参数,根据需要可以分别设置主线程池和从线程池参数,来优化服务端性能。 + // 其中主线程池使用option方法来设置,从线程池使用childOption方法设置。 + // backlog表示主线程池中在套接口排队的最大数量,队列由未连接队列(三次握手未完成的)和已连接队列 + .option(ChannelOption.SO_BACKLOG, 5) + // 表示连接保活,相当于心跳机制,默认为7200s + .childOption(ChannelOption.SO_KEEPALIVE, true); + + try { + // 绑定端口,启动select线程,轮询监听channel事件,监听到事件之后就会交给从线程池处理 + bootstrap.bind(port).sync().channel(); + // 就绪标志 + this.ready = true; + log.info("websocket server 初始化完成,端口:{}", port); + // 等待服务端口关闭 + //channel.closeFuture().sync(); + } catch (InterruptedException e) { + log.info("websocket server 初始化异常", e); + } + } + + @Override + public void stop() { + if (bossGroup != null && !bossGroup.isShuttingDown() && !bossGroup.isShutdown()) { + bossGroup.shutdownGracefully(); + } + if (workGroup != null && !workGroup.isShuttingDown() && !workGroup.isShutdown()) { + workGroup.shutdownGracefully(); + } + this.ready = false; + log.info("websocket server 停止"); + } + + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/endecode/MessageProtocolDecoder.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/endecode/MessageProtocolDecoder.java new file mode 100644 index 0000000..12b7b6b --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/endecode/MessageProtocolDecoder.java @@ -0,0 +1,19 @@ +package com.ruoyi.imserver.netty.ws.endecode; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.im.model.IMSendInfo; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; + +import java.util.List; + +public class MessageProtocolDecoder extends MessageToMessageDecoder { + + @Override + protected void decode(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame, List list) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + IMSendInfo sendInfo = objectMapper.readValue(textWebSocketFrame.text(), IMSendInfo.class); + list.add(sendInfo); + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/endecode/MessageProtocolEncoder.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/endecode/MessageProtocolEncoder.java new file mode 100644 index 0000000..0addb2c --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/netty/ws/endecode/MessageProtocolEncoder.java @@ -0,0 +1,21 @@ +package com.ruoyi.imserver.netty.ws.endecode; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.im.model.IMSendInfo; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageEncoder; +import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; + +import java.util.List; + +public class MessageProtocolEncoder extends MessageToMessageEncoder { + + @Override + protected void encode(ChannelHandlerContext channelHandlerContext, IMSendInfo sendInfo, List list) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + String text = objectMapper.writeValueAsString(sendInfo); + TextWebSocketFrame frame = new TextWebSocketFrame(text); + list.add(frame); + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/AbstractPullMessageTask.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/AbstractPullMessageTask.java new file mode 100644 index 0000000..54fb746 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/AbstractPullMessageTask.java @@ -0,0 +1,23 @@ +package com.ruoyi.imserver.task; + +import com.ruoyi.common.im.mq.RedisMQConsumer; +import com.ruoyi.imserver.netty.IMServerGroup; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; + +@Slf4j +public abstract class AbstractPullMessageTask extends RedisMQConsumer { + + @Autowired + private IMServerGroup serverGroup; + + @Override + public String generateKey() { + return String.join(":", super.generateKey(), IMServerGroup.serverId + ""); + } + + @Override + public Boolean isReady() { + return serverGroup.isReady(); + } +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullGroupMessageTask.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullGroupMessageTask.java new file mode 100644 index 0000000..b075fe2 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullGroupMessageTask.java @@ -0,0 +1,26 @@ +package com.ruoyi.imserver.task; + + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.model.IMRecvInfo; +import com.ruoyi.common.im.mq.RedisMQListener; +import com.ruoyi.imserver.netty.processor.AbstractMessageProcessor; +import com.ruoyi.imserver.netty.processor.ProcessorFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +@RedisMQListener(queue = IMRedisKey.IM_MESSAGE_GROUP_QUEUE, batchSize = 10) +public class PullGroupMessageTask extends AbstractPullMessageTask { + + @Override + public void onMessage(IMRecvInfo recvInfo) { + AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.GROUP_MESSAGE); + processor.process(recvInfo); + } + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullPrivateMessageTask.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullPrivateMessageTask.java new file mode 100644 index 0000000..db71775 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullPrivateMessageTask.java @@ -0,0 +1,26 @@ +package com.ruoyi.imserver.task; + + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.model.IMRecvInfo; +import com.ruoyi.common.im.mq.RedisMQListener; +import com.ruoyi.imserver.netty.processor.AbstractMessageProcessor; +import com.ruoyi.imserver.netty.processor.ProcessorFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +@RedisMQListener(queue = IMRedisKey.IM_MESSAGE_PRIVATE_QUEUE, batchSize = 10) +public class PullPrivateMessageTask extends AbstractPullMessageTask { + + @Override + public void onMessage(IMRecvInfo recvInfo) { + AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.PRIVATE_MESSAGE); + processor.process(recvInfo); + } + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullSystemMessageTask.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullSystemMessageTask.java new file mode 100644 index 0000000..cd0b4fa --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/task/PullSystemMessageTask.java @@ -0,0 +1,28 @@ +package com.ruoyi.imserver.task; + +import com.ruoyi.common.im.constant.IMRedisKey; +import com.ruoyi.common.im.enums.IMCmdType; +import com.ruoyi.common.im.model.IMRecvInfo; +import com.ruoyi.common.im.mq.RedisMQListener; +import com.ruoyi.imserver.netty.processor.AbstractMessageProcessor; +import com.ruoyi.imserver.netty.processor.ProcessorFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @author: Blue + * @date: 2024-07-16 + * @version: 1.0 + */ +@Slf4j +@Component +@RedisMQListener(queue = IMRedisKey.IM_MESSAGE_SYSTEM_QUEUE,batchSize = 10) +public class PullSystemMessageTask extends AbstractPullMessageTask { + + @Override + public void onMessage(IMRecvInfo recvInfo) { + AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.SYSTEM_MESSAGE); + processor.process(recvInfo); + } + +} diff --git a/ruoyi-im-server/src/main/java/com/ruoyi/imserver/util/SpringContextHolder.java b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/util/SpringContextHolder.java new file mode 100644 index 0000000..d96dfb4 --- /dev/null +++ b/ruoyi-im-server/src/main/java/com/ruoyi/imserver/util/SpringContextHolder.java @@ -0,0 +1,39 @@ +package com.ruoyi.imserver.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +@Component +public class SpringContextHolder implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringContextHolder.applicationContext = applicationContext; + } + + public static ApplicationContext getApplicationContext() { + assertApplicationContext(); + return applicationContext; + } + + public static T getBean(String beanName) { + assertApplicationContext(); + return (T) applicationContext.getBean(beanName); + } + + public static T getBean(Class requiredType) { + assertApplicationContext(); + return applicationContext.getBean(requiredType); + } + + private static void assertApplicationContext() { + if (SpringContextHolder.applicationContext == null) { + throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!"); + } + } + +} diff --git a/ruoyi-im-server/src/main/resources/application-dev.yml b/ruoyi-im-server/src/main/resources/application-dev.yml new file mode 100644 index 0000000..875a1ea --- /dev/null +++ b/ruoyi-im-server/src/main/resources/application-dev.yml @@ -0,0 +1,5 @@ +spring: + data: + redis: + host: 127.0.0.1 + port: 6379 diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-im-server/src/main/resources/application-druid.yml similarity index 100% rename from ruoyi-admin/src/main/resources/application-druid.yml rename to ruoyi-im-server/src/main/resources/application-druid.yml diff --git a/ruoyi-im-server/src/main/resources/application-prod.yml b/ruoyi-im-server/src/main/resources/application-prod.yml new file mode 100644 index 0000000..79724c4 --- /dev/null +++ b/ruoyi-im-server/src/main/resources/application-prod.yml @@ -0,0 +1,6 @@ +spring: + data: + redis: + host: 127.0.0.1 + port: 6379 + password: PmEpfRjpBnTN6CgW \ No newline at end of file diff --git a/ruoyi-im-server/src/main/resources/application-test.yml b/ruoyi-im-server/src/main/resources/application-test.yml new file mode 100644 index 0000000..79724c4 --- /dev/null +++ b/ruoyi-im-server/src/main/resources/application-test.yml @@ -0,0 +1,6 @@ +spring: + data: + redis: + host: 127.0.0.1 + port: 6379 + password: PmEpfRjpBnTN6CgW \ No newline at end of file diff --git a/ruoyi-im-server/src/main/resources/application.yml b/ruoyi-im-server/src/main/resources/application.yml new file mode 100644 index 0000000..2579829 --- /dev/null +++ b/ruoyi-im-server/src/main/resources/application.yml @@ -0,0 +1,31 @@ +spring: + profiles: + active: dev + application: + name: ruoyi-im-server + +websocket: + enable: true + port: 8528 + +tcpsocket: + enable: false # 暂时不开启 + port: 8879 + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: 4b5c4d8cc1a5d54afac74291c8f43dc6 + # 令牌有效期( 3000分钟) + expireTime: 1800 + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /api/*,/tool/* diff --git a/ruoyi-im-server/src/main/resources/logback.xml b/ruoyi-im-server/src/main/resources/logback.xml new file mode 100644 index 0000000..ede4d60 --- /dev/null +++ b/ruoyi-im-server/src/main/resources/logback.xml @@ -0,0 +1,48 @@ + + + + + + + + info + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${LOG_PATH}/${APP_NAME}.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${LOG_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.%i.log + 100MB + 60 + 20GB + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java deleted file mode 100644 index a558170..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java +++ /dev/null @@ -1,57 +0,0 @@ -//package com.ruoyi.quartz.config; -// -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.scheduling.quartz.SchedulerFactoryBean; -//import javax.sql.DataSource; -//import java.util.Properties; -// -///** -// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) -// * -// * @author ruoyi -// */ -//@Configuration -//public class ScheduleConfig -//{ -// @Bean -// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) -// { -// SchedulerFactoryBean factory = new SchedulerFactoryBean(); -// factory.setDataSource(dataSource); -// -// // quartz参数 -// Properties prop = new Properties(); -// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); -// prop.put("org.quartz.scheduler.instanceId", "AUTO"); -// // 线程池配置 -// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); -// prop.put("org.quartz.threadPool.threadCount", "20"); -// prop.put("org.quartz.threadPool.threadPriority", "5"); -// // JobStore配置 -// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); -// // 集群配置 -// prop.put("org.quartz.jobStore.isClustered", "true"); -// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); -// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); -// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); -// -// // sqlserver 启用 -// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); -// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); -// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); -// factory.setQuartzProperties(prop); -// -// factory.setSchedulerName("RuoyiScheduler"); -// // 延时启动 -// factory.setStartupDelay(1); -// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); -// // 可选,QuartzScheduler -// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -// factory.setOverwriteExistingJobs(true); -// // 设置自动启动,默认为true -// factory.setAutoStartup(true); -// -// return factory; -// } -//} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java deleted file mode 100644 index bae3c53..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.ruoyi.quartz.controller; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.quartz.SchedulerException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.service.ISysJobService; -import com.ruoyi.quartz.util.CronUtils; -import com.ruoyi.quartz.util.ScheduleUtils; - -/** - * 调度任务信息操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/job") -public class SysJobController extends BaseController -{ - @Autowired - private ISysJobService jobService; - - /** - * 查询定时任务列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:list')") - @GetMapping("/list") - public TableDataInfo list(SysJob sysJob) - { - startPage(); - List list = jobService.selectJobList(sysJob); - return getDataTable(list); - } - - /** - * 导出定时任务列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:export')") - @Log(title = "定时任务", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, SysJob sysJob) - { - List list = jobService.selectJobList(sysJob); - ExcelUtil util = new ExcelUtil(SysJob.class); - util.exportExcel(response, list, "定时任务"); - } - - /** - * 获取定时任务详细信息 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:query')") - @GetMapping(value = "/{jobId}") - public AjaxResult getInfo(@PathVariable("jobId") Long jobId) - { - return AjaxResult.success(jobService.selectJobById(jobId)); - } - - /** - * 新增定时任务 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:add')") - @Log(title = "定时任务", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException - { - if (!CronUtils.isValid(job.getCronExpression())) - { - return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); - } - else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); - } - else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) - { - return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); - } - job.setCreateBy(getUsername()); - return toAjax(jobService.insertJob(job)); - } - - /** - * 修改定时任务 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:edit')") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException - { - if (!CronUtils.isValid(job.getCronExpression())) - { - return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); - } - else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); - } - else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); - } - else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) - { - return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); - } - job.setUpdateBy(getUsername()); - return toAjax(jobService.updateJob(job)); - } - - /** - * 定时任务状态修改 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping("/changeStatus") - public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException - { - SysJob newJob = jobService.selectJobById(job.getJobId()); - newJob.setStatus(job.getStatus()); - return toAjax(jobService.changeStatus(newJob)); - } - - /** - * 定时任务立即执行一次 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping("/run") - public AjaxResult run(@RequestBody SysJob job) throws SchedulerException - { - boolean result = jobService.run(job); - return result ? success() : error("任务不存在或已过期!"); - } - - /** - * 删除定时任务 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:remove')") - @Log(title = "定时任务", businessType = BusinessType.DELETE) - @DeleteMapping("/{jobIds}") - public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException - { - jobService.deleteJobByIds(jobIds); - return success(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java deleted file mode 100644 index d27100d..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.ruoyi.quartz.controller; - -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.service.ISysJobLogService; - -/** - * 调度日志操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/jobLog") -public class SysJobLogController extends BaseController -{ - @Autowired - private ISysJobLogService jobLogService; - - /** - * 查询定时任务调度日志列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:list')") - @GetMapping("/list") - public TableDataInfo list(SysJobLog sysJobLog) - { - startPage(); - List list = jobLogService.selectJobLogList(sysJobLog); - return getDataTable(list); - } - - /** - * 导出定时任务调度日志列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:export')") - @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, SysJobLog sysJobLog) - { - List list = jobLogService.selectJobLogList(sysJobLog); - ExcelUtil util = new ExcelUtil(SysJobLog.class); - util.exportExcel(response, list, "调度日志"); - } - - /** - * 根据调度编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:query')") - @GetMapping(value = "/{configId}") - public AjaxResult getInfo(@PathVariable Long jobLogId) - { - return AjaxResult.success(jobLogService.selectJobLogById(jobLogId)); - } - - - /** - * 删除定时任务调度日志 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:remove')") - @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) - @DeleteMapping("/{jobLogIds}") - public AjaxResult remove(@PathVariable Long[] jobLogIds) - { - return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); - } - - /** - * 清空定时任务调度日志 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:remove')") - @Log(title = "调度日志", businessType = BusinessType.CLEAN) - @DeleteMapping("/clean") - public AjaxResult clean() - { - jobLogService.cleanJobLog(); - return AjaxResult.success(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java deleted file mode 100644 index 1f49695..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.ruoyi.quartz.domain; - -import java.util.Date; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.ruoyi.common.annotation.Excel; -import com.ruoyi.common.annotation.Excel.ColumnType; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.core.domain.BaseEntity; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.quartz.util.CronUtils; - -/** - * 定时任务调度表 sys_job - * - * @author ruoyi - */ -public class SysJob extends BaseEntity -{ - private static final long serialVersionUID = 1L; - - /** 任务ID */ - @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) - private Long jobId; - - /** 任务名称 */ - @Excel(name = "任务名称") - private String jobName; - - /** 任务组名 */ - @Excel(name = "任务组名") - private String jobGroup; - - /** 调用目标字符串 */ - @Excel(name = "调用目标字符串") - private String invokeTarget; - - /** cron执行表达式 */ - @Excel(name = "执行表达式 ") - private String cronExpression; - - /** cron计划策略 */ - @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") - private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; - - /** 是否并发执行(0允许 1禁止) */ - @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") - private String concurrent; - - /** 任务状态(0正常 1暂停) */ - @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") - private String status; - - public Long getJobId() - { - return jobId; - } - - public void setJobId(Long jobId) - { - this.jobId = jobId; - } - - @NotBlank(message = "任务名称不能为空") - @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") - public String getJobName() - { - return jobName; - } - - public void setJobName(String jobName) - { - this.jobName = jobName; - } - - public String getJobGroup() - { - return jobGroup; - } - - public void setJobGroup(String jobGroup) - { - this.jobGroup = jobGroup; - } - - @NotBlank(message = "调用目标字符串不能为空") - @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") - public String getInvokeTarget() - { - return invokeTarget; - } - - public void setInvokeTarget(String invokeTarget) - { - this.invokeTarget = invokeTarget; - } - - @NotBlank(message = "Cron执行表达式不能为空") - @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") - public String getCronExpression() - { - return cronExpression; - } - - public void setCronExpression(String cronExpression) - { - this.cronExpression = cronExpression; - } - - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - public Date getNextValidTime() - { - if (StringUtils.isNotEmpty(cronExpression)) - { - return CronUtils.getNextExecution(cronExpression); - } - return null; - } - - public String getMisfirePolicy() - { - return misfirePolicy; - } - - public void setMisfirePolicy(String misfirePolicy) - { - this.misfirePolicy = misfirePolicy; - } - - public String getConcurrent() - { - return concurrent; - } - - public void setConcurrent(String concurrent) - { - this.concurrent = concurrent; - } - - 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("jobId", getJobId()) - .append("jobName", getJobName()) - .append("jobGroup", getJobGroup()) - .append("cronExpression", getCronExpression()) - .append("nextValidTime", getNextValidTime()) - .append("misfirePolicy", getMisfirePolicy()) - .append("concurrent", getConcurrent()) - .append("status", getStatus()) - .append("createBy", getCreateBy()) - .append("createTime", getCreateTime()) - .append("updateBy", getUpdateBy()) - .append("updateTime", getUpdateTime()) - .append("remark", getRemark()) - .toString(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java deleted file mode 100644 index 121c035..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.ruoyi.quartz.domain; - -import java.util.Date; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import com.ruoyi.common.annotation.Excel; -import com.ruoyi.common.core.domain.BaseEntity; - -/** - * 定时任务调度日志表 sys_job_log - * - * @author ruoyi - */ -public class SysJobLog extends BaseEntity -{ - private static final long serialVersionUID = 1L; - - /** ID */ - @Excel(name = "日志序号") - private Long jobLogId; - - /** 任务名称 */ - @Excel(name = "任务名称") - private String jobName; - - /** 任务组名 */ - @Excel(name = "任务组名") - private String jobGroup; - - /** 调用目标字符串 */ - @Excel(name = "调用目标字符串") - private String invokeTarget; - - /** 日志信息 */ - @Excel(name = "日志信息") - private String jobMessage; - - /** 执行状态(0正常 1失败) */ - @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") - private String status; - - /** 异常信息 */ - @Excel(name = "异常信息") - private String exceptionInfo; - - /** 开始时间 */ - private Date startTime; - - /** 停止时间 */ - private Date stopTime; - - public Long getJobLogId() - { - return jobLogId; - } - - public void setJobLogId(Long jobLogId) - { - this.jobLogId = jobLogId; - } - - public String getJobName() - { - return jobName; - } - - public void setJobName(String jobName) - { - this.jobName = jobName; - } - - public String getJobGroup() - { - return jobGroup; - } - - public void setJobGroup(String jobGroup) - { - this.jobGroup = jobGroup; - } - - public String getInvokeTarget() - { - return invokeTarget; - } - - public void setInvokeTarget(String invokeTarget) - { - this.invokeTarget = invokeTarget; - } - - public String getJobMessage() - { - return jobMessage; - } - - public void setJobMessage(String jobMessage) - { - this.jobMessage = jobMessage; - } - - public String getStatus() - { - return status; - } - - public void setStatus(String status) - { - this.status = status; - } - - public String getExceptionInfo() - { - return exceptionInfo; - } - - public void setExceptionInfo(String exceptionInfo) - { - this.exceptionInfo = exceptionInfo; - } - - public Date getStartTime() - { - return startTime; - } - - public void setStartTime(Date startTime) - { - this.startTime = startTime; - } - - public Date getStopTime() - { - return stopTime; - } - - public void setStopTime(Date stopTime) - { - this.stopTime = stopTime; - } - - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("jobLogId", getJobLogId()) - .append("jobName", getJobName()) - .append("jobGroup", getJobGroup()) - .append("jobMessage", getJobMessage()) - .append("status", getStatus()) - .append("exceptionInfo", getExceptionInfo()) - .append("startTime", getStartTime()) - .append("stopTime", getStopTime()) - .toString(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java deleted file mode 100644 index 727d916..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ruoyi.quartz.mapper; - -import java.util.List; -import com.ruoyi.quartz.domain.SysJobLog; - -/** - * 调度任务日志信息 数据层 - * - * @author ruoyi - */ -public interface SysJobLogMapper -{ - /** - * 获取quartz调度器日志的计划任务 - * - * @param jobLog 调度日志信息 - * @return 调度任务日志集合 - */ - public List selectJobLogList(SysJobLog jobLog); - - /** - * 查询所有调度任务日志 - * - * @return 调度任务日志列表 - */ - public List selectJobLogAll(); - - /** - * 通过调度任务日志ID查询调度信息 - * - * @param jobLogId 调度任务日志ID - * @return 调度任务日志对象信息 - */ - public SysJobLog selectJobLogById(Long jobLogId); - - /** - * 新增任务日志 - * - * @param jobLog 调度日志信息 - * @return 结果 - */ - public int insertJobLog(SysJobLog jobLog); - - /** - * 批量删除调度日志信息 - * - * @param logIds 需要删除的数据ID - * @return 结果 - */ - public int deleteJobLogByIds(Long[] logIds); - - /** - * 删除任务日志 - * - * @param jobId 调度日志ID - * @return 结果 - */ - public int deleteJobLogById(Long jobId); - - /** - * 清空任务日志 - */ - public void cleanJobLog(); -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java deleted file mode 100644 index 20f45db..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ruoyi.quartz.mapper; - -import java.util.List; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 调度任务信息 数据层 - * - * @author ruoyi - */ -public interface SysJobMapper -{ - /** - * 查询调度任务日志集合 - * - * @param job 调度信息 - * @return 操作日志集合 - */ - public List selectJobList(SysJob job); - - /** - * 查询所有调度任务 - * - * @return 调度任务列表 - */ - public List selectJobAll(); - - /** - * 通过调度ID查询调度任务信息 - * - * @param jobId 调度ID - * @return 角色对象信息 - */ - public SysJob selectJobById(Long jobId); - - /** - * 通过调度ID删除调度任务信息 - * - * @param jobId 调度ID - * @return 结果 - */ - public int deleteJobById(Long jobId); - - /** - * 批量删除调度任务信息 - * - * @param ids 需要删除的数据ID - * @return 结果 - */ - public int deleteJobByIds(Long[] ids); - - /** - * 修改调度任务信息 - * - * @param job 调度任务信息 - * @return 结果 - */ - public int updateJob(SysJob job); - - /** - * 新增调度任务信息 - * - * @param job 调度任务信息 - * @return 结果 - */ - public int insertJob(SysJob job); -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java deleted file mode 100644 index 8546792..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ruoyi.quartz.service; - -import java.util.List; -import com.ruoyi.quartz.domain.SysJobLog; - -/** - * 定时任务调度日志信息信息 服务层 - * - * @author ruoyi - */ -public interface ISysJobLogService -{ - /** - * 获取quartz调度器日志的计划任务 - * - * @param jobLog 调度日志信息 - * @return 调度任务日志集合 - */ - public List selectJobLogList(SysJobLog jobLog); - - /** - * 通过调度任务日志ID查询调度信息 - * - * @param jobLogId 调度任务日志ID - * @return 调度任务日志对象信息 - */ - public SysJobLog selectJobLogById(Long jobLogId); - - /** - * 新增任务日志 - * - * @param jobLog 调度日志信息 - */ - public void addJobLog(SysJobLog jobLog); - - /** - * 批量删除调度日志信息 - * - * @param logIds 需要删除的日志ID - * @return 结果 - */ - public int deleteJobLogByIds(Long[] logIds); - - /** - * 删除任务日志 - * - * @param jobId 调度日志ID - * @return 结果 - */ - public int deleteJobLogById(Long jobId); - - /** - * 清空任务日志 - */ - public void cleanJobLog(); -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java deleted file mode 100644 index 437ade8..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.ruoyi.quartz.service; - -import java.util.List; -import org.quartz.SchedulerException; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务调度信息信息 服务层 - * - * @author ruoyi - */ -public interface ISysJobService -{ - /** - * 获取quartz调度器的计划任务 - * - * @param job 调度信息 - * @return 调度任务集合 - */ - public List selectJobList(SysJob job); - - /** - * 通过调度任务ID查询调度信息 - * - * @param jobId 调度任务ID - * @return 调度任务对象信息 - */ - public SysJob selectJobById(Long jobId); - - /** - * 暂停任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int pauseJob(SysJob job) throws SchedulerException; - - /** - * 恢复任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int resumeJob(SysJob job) throws SchedulerException; - - /** - * 删除任务后,所对应的trigger也将被删除 - * - * @param job 调度信息 - * @return 结果 - */ - public int deleteJob(SysJob job) throws SchedulerException; - - /** - * 批量删除调度信息 - * - * @param jobIds 需要删除的任务ID - * @return 结果 - */ - public void deleteJobByIds(Long[] jobIds) throws SchedulerException; - - /** - * 任务调度状态修改 - * - * @param job 调度信息 - * @return 结果 - */ - public int changeStatus(SysJob job) throws SchedulerException; - - /** - * 立即运行任务 - * - * @param job 调度信息 - * @return 结果 - */ - public boolean run(SysJob job) throws SchedulerException; - - /** - * 新增任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int insertJob(SysJob job) throws SchedulerException, TaskException; - - /** - * 更新任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int updateJob(SysJob job) throws SchedulerException, TaskException; - - /** - * 校验cron表达式是否有效 - * - * @param cronExpression 表达式 - * @return 结果 - */ - public boolean checkCronExpressionIsValid(String cronExpression); -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java deleted file mode 100644 index 812eed7..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.ruoyi.quartz.service.impl; - -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.mapper.SysJobLogMapper; -import com.ruoyi.quartz.service.ISysJobLogService; - -/** - * 定时任务调度日志信息 服务层 - * - * @author ruoyi - */ -@Service -public class SysJobLogServiceImpl implements ISysJobLogService -{ - @Autowired - private SysJobLogMapper jobLogMapper; - - /** - * 获取quartz调度器日志的计划任务 - * - * @param jobLog 调度日志信息 - * @return 调度任务日志集合 - */ - @Override - public List selectJobLogList(SysJobLog jobLog) - { - return jobLogMapper.selectJobLogList(jobLog); - } - - /** - * 通过调度任务日志ID查询调度信息 - * - * @param jobLogId 调度任务日志ID - * @return 调度任务日志对象信息 - */ - @Override - public SysJobLog selectJobLogById(Long jobLogId) - { - return jobLogMapper.selectJobLogById(jobLogId); - } - - /** - * 新增任务日志 - * - * @param jobLog 调度日志信息 - */ - @Override - public void addJobLog(SysJobLog jobLog) - { - jobLogMapper.insertJobLog(jobLog); - } - - /** - * 批量删除调度日志信息 - * - * @param logIds 需要删除的数据ID - * @return 结果 - */ - @Override - public int deleteJobLogByIds(Long[] logIds) - { - return jobLogMapper.deleteJobLogByIds(logIds); - } - - /** - * 删除任务日志 - * - * @param jobId 调度日志ID - */ - @Override - public int deleteJobLogById(Long jobId) - { - return jobLogMapper.deleteJobLogById(jobId); - } - - /** - * 清空任务日志 - */ - @Override - public void cleanJobLog() - { - jobLogMapper.cleanJobLog(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java deleted file mode 100644 index 77fdbb5..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java +++ /dev/null @@ -1,261 +0,0 @@ -package com.ruoyi.quartz.service.impl; - -import java.util.List; -import javax.annotation.PostConstruct; -import org.quartz.JobDataMap; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.mapper.SysJobMapper; -import com.ruoyi.quartz.service.ISysJobService; -import com.ruoyi.quartz.util.CronUtils; -import com.ruoyi.quartz.util.ScheduleUtils; - -/** - * 定时任务调度信息 服务层 - * - * @author ruoyi - */ -@Service -public class SysJobServiceImpl implements ISysJobService -{ - @Autowired - private Scheduler scheduler; - - @Autowired - private SysJobMapper jobMapper; - - /** - * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) - */ - @PostConstruct - public void init() throws SchedulerException, TaskException - { - scheduler.clear(); - List jobList = jobMapper.selectJobAll(); - for (SysJob job : jobList) - { - ScheduleUtils.createScheduleJob(scheduler, job); - } - } - - /** - * 获取quartz调度器的计划任务列表 - * - * @param job 调度信息 - * @return - */ - @Override - public List selectJobList(SysJob job) - { - return jobMapper.selectJobList(job); - } - - /** - * 通过调度任务ID查询调度信息 - * - * @param jobId 调度任务ID - * @return 调度任务对象信息 - */ - @Override - public SysJob selectJobById(Long jobId) - { - return jobMapper.selectJobById(jobId); - } - - /** - * 暂停任务 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int pauseJob(SysJob job) throws SchedulerException - { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); - int rows = jobMapper.updateJob(job); - if (rows > 0) - { - scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 恢复任务 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int resumeJob(SysJob job) throws SchedulerException - { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); - int rows = jobMapper.updateJob(job); - if (rows > 0) - { - scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 删除任务后,所对应的trigger也将被删除 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int deleteJob(SysJob job) throws SchedulerException - { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - int rows = jobMapper.deleteJobById(jobId); - if (rows > 0) - { - scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 批量删除调度信息 - * - * @param jobIds 需要删除的任务ID - * @return 结果 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void deleteJobByIds(Long[] jobIds) throws SchedulerException - { - for (Long jobId : jobIds) - { - SysJob job = jobMapper.selectJobById(jobId); - deleteJob(job); - } - } - - /** - * 任务调度状态修改 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int changeStatus(SysJob job) throws SchedulerException - { - int rows = 0; - String status = job.getStatus(); - if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) - { - rows = resumeJob(job); - } - else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) - { - rows = pauseJob(job); - } - return rows; - } - - /** - * 立即运行任务 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public boolean run(SysJob job) throws SchedulerException - { - boolean result = false; - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - SysJob properties = selectJobById(job.getJobId()); - // 参数 - JobDataMap dataMap = new JobDataMap(); - dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); - JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); - if (scheduler.checkExists(jobKey)) - { - result = true; - scheduler.triggerJob(jobKey, dataMap); - } - return result; - } - - /** - * 新增任务 - * - * @param job 调度信息 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int insertJob(SysJob job) throws SchedulerException, TaskException - { - job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); - int rows = jobMapper.insertJob(job); - if (rows > 0) - { - ScheduleUtils.createScheduleJob(scheduler, job); - } - return rows; - } - - /** - * 更新任务的时间表达式 - * - * @param job 调度信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int updateJob(SysJob job) throws SchedulerException, TaskException - { - SysJob properties = selectJobById(job.getJobId()); - int rows = jobMapper.updateJob(job); - if (rows > 0) - { - updateSchedulerJob(job, properties.getJobGroup()); - } - return rows; - } - - /** - * 更新任务 - * - * @param job 任务对象 - * @param jobGroup 任务组名 - */ - public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException - { - Long jobId = job.getJobId(); - // 判断是否存在 - JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); - if (scheduler.checkExists(jobKey)) - { - // 防止创建时存在数据问题 先移除,然后在执行创建操作 - scheduler.deleteJob(jobKey); - } - ScheduleUtils.createScheduleJob(scheduler, job); - } - - /** - * 校验cron表达式是否有效 - * - * @param cronExpression 表达式 - * @return 结果 - */ - @Override - public boolean checkCronExpressionIsValid(String cronExpression) - { - return CronUtils.isValid(cronExpression); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java deleted file mode 100644 index 853243b..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ruoyi.quartz.task; - -import org.springframework.stereotype.Component; -import com.ruoyi.common.utils.StringUtils; - -/** - * 定时任务调度测试 - * - * @author ruoyi - */ -@Component("ryTask") -public class RyTask -{ - public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) - { - System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); - } - - public void ryParams(String params) - { - System.out.println("执行有参方法:" + params); - } - - public void ryNoParams() - { - System.out.println("执行无参方法"); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java deleted file mode 100644 index 731a5eb..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.ruoyi.quartz.util; - -import java.util.Date; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.utils.ExceptionUtil; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.bean.BeanUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.service.ISysJobLogService; - -/** - * 抽象quartz调用 - * - * @author ruoyi - */ -public abstract class AbstractQuartzJob implements Job -{ - private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); - - /** - * 线程本地变量 - */ - private static ThreadLocal threadLocal = new ThreadLocal<>(); - - @Override - public void execute(JobExecutionContext context) throws JobExecutionException - { - SysJob sysJob = new SysJob(); - BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); - try - { - before(context, sysJob); - if (sysJob != null) - { - doExecute(context, sysJob); - } - after(context, sysJob, null); - } - catch (Exception e) - { - log.error("任务执行异常 - :", e); - after(context, sysJob, e); - } - } - - /** - * 执行前 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - */ - protected void before(JobExecutionContext context, SysJob sysJob) - { - threadLocal.set(new Date()); - } - - /** - * 执行后 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - */ - protected void after(JobExecutionContext context, SysJob sysJob, Exception e) - { - Date startTime = threadLocal.get(); - threadLocal.remove(); - - final SysJobLog sysJobLog = new SysJobLog(); - sysJobLog.setJobName(sysJob.getJobName()); - sysJobLog.setJobGroup(sysJob.getJobGroup()); - sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); - sysJobLog.setStartTime(startTime); - sysJobLog.setStopTime(new Date()); - long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); - sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); - if (e != null) - { - sysJobLog.setStatus(Constants.FAIL); - String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); - sysJobLog.setExceptionInfo(errorMsg); - } - else - { - sysJobLog.setStatus(Constants.SUCCESS); - } - - // 写入数据库当中 - SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); - } - - /** - * 执行方法,由子类重载 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - * @throws Exception 执行过程中的异常 - */ - protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java deleted file mode 100644 index dd53839..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.ruoyi.quartz.util; - -import java.text.ParseException; -import java.util.Date; -import org.quartz.CronExpression; - -/** - * cron表达式工具类 - * - * @author ruoyi - * - */ -public class CronUtils -{ - /** - * 返回一个布尔值代表一个给定的Cron表达式的有效性 - * - * @param cronExpression Cron表达式 - * @return boolean 表达式是否有效 - */ - public static boolean isValid(String cronExpression) - { - return CronExpression.isValidExpression(cronExpression); - } - - /** - * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 - * - * @param cronExpression Cron表达式 - * @return String 无效时返回表达式错误描述,如果有效返回null - */ - public static String getInvalidMessage(String cronExpression) - { - try - { - new CronExpression(cronExpression); - return null; - } - catch (ParseException pe) - { - return pe.getMessage(); - } - } - - /** - * 返回下一个执行时间根据给定的Cron表达式 - * - * @param cronExpression Cron表达式 - * @return Date 下次Cron表达式执行时间 - */ - public static Date getNextExecution(String cronExpression) - { - try - { - CronExpression cron = new CronExpression(cronExpression); - return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); - } - catch (ParseException e) - { - throw new IllegalArgumentException(e.getMessage()); - } - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java deleted file mode 100644 index 3da377a..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.ruoyi.quartz.util; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.LinkedList; -import java.util.List; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 任务执行工具 - * - * @author ruoyi - */ -public class JobInvokeUtil -{ - /** - * 执行方法 - * - * @param sysJob 系统任务 - */ - public static void invokeMethod(SysJob sysJob) throws Exception - { - String invokeTarget = sysJob.getInvokeTarget(); - String beanName = getBeanName(invokeTarget); - String methodName = getMethodName(invokeTarget); - List methodParams = getMethodParams(invokeTarget); - - if (!isValidClassName(beanName)) - { - Object bean = SpringUtils.getBean(beanName); - invokeMethod(bean, methodName, methodParams); - } - else - { - Object bean = Class.forName(beanName).newInstance(); - invokeMethod(bean, methodName, methodParams); - } - } - - /** - * 调用任务方法 - * - * @param bean 目标对象 - * @param methodName 方法名称 - * @param methodParams 方法参数 - */ - private static void invokeMethod(Object bean, String methodName, List methodParams) - throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException - { - if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) - { - Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); - method.invoke(bean, getMethodParamsValue(methodParams)); - } - else - { - Method method = bean.getClass().getMethod(methodName); - method.invoke(bean); - } - } - - /** - * 校验是否为为class包名 - * - * @param invokeTarget 名称 - * @return true是 false否 - */ - public static boolean isValidClassName(String invokeTarget) - { - return StringUtils.countMatches(invokeTarget, ".") > 1; - } - - /** - * 获取bean名称 - * - * @param invokeTarget 目标字符串 - * @return bean名称 - */ - public static String getBeanName(String invokeTarget) - { - String beanName = StringUtils.substringBefore(invokeTarget, "("); - return StringUtils.substringBeforeLast(beanName, "."); - } - - /** - * 获取bean方法 - * - * @param invokeTarget 目标字符串 - * @return method方法 - */ - public static String getMethodName(String invokeTarget) - { - String methodName = StringUtils.substringBefore(invokeTarget, "("); - return StringUtils.substringAfterLast(methodName, "."); - } - - /** - * 获取method方法参数相关列表 - * - * @param invokeTarget 目标字符串 - * @return method方法相关参数列表 - */ - public static List getMethodParams(String invokeTarget) - { - String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); - if (StringUtils.isEmpty(methodStr)) - { - return null; - } - String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); - List classs = new LinkedList<>(); - for (int i = 0; i < methodParams.length; i++) - { - String str = StringUtils.trimToEmpty(methodParams[i]); - // String字符串类型,以'或"开头 - if (StringUtils.startsWithAny(str, "'", "\"")) - { - classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); - } - // boolean布尔类型,等于true或者false - else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) - { - classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); - } - // long长整形,以L结尾 - else if (StringUtils.endsWith(str, "L")) - { - classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); - } - // double浮点类型,以D结尾 - else if (StringUtils.endsWith(str, "D")) - { - classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); - } - // 其他类型归类为整形 - else - { - classs.add(new Object[] { Integer.valueOf(str), Integer.class }); - } - } - return classs; - } - - /** - * 获取参数类型 - * - * @param methodParams 参数相关列表 - * @return 参数类型列表 - */ - public static Class[] getMethodParamsType(List methodParams) - { - Class[] classs = new Class[methodParams.size()]; - int index = 0; - for (Object[] os : methodParams) - { - classs[index] = (Class) os[1]; - index++; - } - return classs; - } - - /** - * 获取参数值 - * - * @param methodParams 参数相关列表 - * @return 参数值列表 - */ - public static Object[] getMethodParamsValue(List methodParams) - { - Object[] classs = new Object[methodParams.size()]; - int index = 0; - for (Object[] os : methodParams) - { - classs[index] = (Object) os[0]; - index++; - } - return classs; - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java deleted file mode 100644 index 5e13558..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.DisallowConcurrentExecution; -import org.quartz.JobExecutionContext; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务处理(禁止并发执行) - * - * @author ruoyi - * - */ -@DisallowConcurrentExecution -public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob -{ - @Override - protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception - { - JobInvokeUtil.invokeMethod(sysJob); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java deleted file mode 100644 index e975326..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.JobExecutionContext; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务处理(允许并发执行) - * - * @author ruoyi - * - */ -public class QuartzJobExecution extends AbstractQuartzJob -{ - @Override - protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception - { - JobInvokeUtil.invokeMethod(sysJob); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java deleted file mode 100644 index f885d42..0000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.CronScheduleBuilder; -import org.quartz.CronTrigger; -import org.quartz.Job; -import org.quartz.JobBuilder; -import org.quartz.JobDetail; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.TriggerBuilder; -import org.quartz.TriggerKey; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.common.exception.job.TaskException.Code; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务工具类 - * - * @author ruoyi - * - */ -public class ScheduleUtils -{ - /** - * 得到quartz任务类 - * - * @param sysJob 执行计划 - * @return 具体执行任务类 - */ - private static Class getQuartzJobClass(SysJob sysJob) - { - boolean isConcurrent = "0".equals(sysJob.getConcurrent()); - return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; - } - - /** - * 构建任务触发对象 - */ - public static TriggerKey getTriggerKey(Long jobId, String jobGroup) - { - return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); - } - - /** - * 构建任务键对象 - */ - public static JobKey getJobKey(Long jobId, String jobGroup) - { - return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); - } - - /** - * 创建定时任务 - */ - public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException - { - Class jobClass = getQuartzJobClass(job); - // 构建job信息 - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); - - // 表达式调度构建器 - CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); - cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); - - // 按新的cronExpression表达式构建一个新的trigger - CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) - .withSchedule(cronScheduleBuilder).build(); - - // 放入参数,运行时的方法可以获取 - jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); - - // 判断是否存在 - if (scheduler.checkExists(getJobKey(jobId, jobGroup))) - { - // 防止创建时存在数据问题 先移除,然后在执行创建操作 - scheduler.deleteJob(getJobKey(jobId, jobGroup)); - } - - // 判断任务是否过期 - if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) - { - // 执行调度任务 - scheduler.scheduleJob(jobDetail, trigger); - } - - // 暂停任务 - if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) - { - scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - } - - /** - * 设置定时任务策略 - */ - public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) - throws TaskException - { - switch (job.getMisfirePolicy()) - { - case ScheduleConstants.MISFIRE_DEFAULT: - return cb; - case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: - return cb.withMisfireHandlingInstructionIgnoreMisfires(); - case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: - return cb.withMisfireHandlingInstructionFireAndProceed(); - case ScheduleConstants.MISFIRE_DO_NOTHING: - return cb.withMisfireHandlingInstructionDoNothing(); - default: - throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() - + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); - } - } - - /** - * 检查包名是否为白名单配置 - * - * @param invokeTarget 目标字符串 - * @return 结果 - */ - public static boolean whiteList(String invokeTarget) - { - String packageName = StringUtils.substringBefore(invokeTarget, "("); - int count = StringUtils.countMatches(packageName, "."); - if (count > 1) - { - return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); - } - Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); - return StringUtils.containsAnyIgnoreCase(obj.getClass().getPackage().getName(), Constants.JOB_WHITELIST_STR); - } -} diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml deleted file mode 100644 index e608e42..0000000 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time - from sys_job_log - - - - - - - - - - delete from sys_job_log where job_log_id = #{jobLogId} - - - - delete from sys_job_log where job_log_id in - - #{jobLogId} - - - - - truncate table sys_job_log - - - - insert into sys_job_log( - job_log_id, - job_name, - job_group, - invoke_target, - job_message, - status, - exception_info, - create_time - )values( - #{jobLogId}, - #{jobName}, - #{jobGroup}, - #{invokeTarget}, - #{jobMessage}, - #{status}, - #{exceptionInfo}, - sysdate() - ) - - - \ No newline at end of file diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml deleted file mode 100644 index 5605c44..0000000 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark - from sys_job - - - - - - - - - - delete from sys_job where job_id = #{jobId} - - - - delete from sys_job where job_id in - - #{jobId} - - - - - update sys_job - - job_name = #{jobName}, - job_group = #{jobGroup}, - invoke_target = #{invokeTarget}, - cron_expression = #{cronExpression}, - misfire_policy = #{misfirePolicy}, - concurrent = #{concurrent}, - status = #{status}, - remark = #{remark}, - update_by = #{updateBy}, - update_time = sysdate() - - where job_id = #{jobId} - - - - insert into sys_job( - job_id, - job_name, - job_group, - invoke_target, - cron_expression, - misfire_policy, - concurrent, - status, - remark, - create_by, - create_time - )values( - #{jobId}, - #{jobName}, - #{jobGroup}, - #{invokeTarget}, - #{cronExpression}, - #{misfirePolicy}, - #{concurrent}, - #{status}, - #{remark}, - #{createBy}, - sysdate() - ) - - - \ No newline at end of file diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml index 7cd8dd0..a0a8db3 100644 --- a/ruoyi-system/pom.xml +++ b/ruoyi-system/pom.xml @@ -22,7 +22,57 @@ com.ruoyi ruoyi-common - + + + mysql + mysql-connector-java + + + + com.ruoyi + ruoyi-im-client + + + + com.squareup.okhttp3 + okhttp + 4.8.1 + compile + + + io.minio + minio + 8.2.1 + + + + net.coobird + thumbnailator + 0.4.8 + + + + + com.google.code.gson + gson + 2.9.0 + + + com.github.wechatpay-apiv3 + wechatpay-java + 0.2.9 + + + + com.github.wechatpay-apiv3 + wechatpay-apache-httpclient + 0.4.8 + + + junit + junit + 4.12 + - \ No newline at end of file + diff --git a/ruoyi-system/ruoyi-system.iml b/ruoyi-system/ruoyi-system.iml new file mode 100644 index 0000000..6d5841c --- /dev/null +++ b/ruoyi-system/ruoyi-system.iml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjAppreciate.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjAppreciate.java similarity index 94% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjAppreciate.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjAppreciate.java index f804778..525f549 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjAppreciate.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjAppreciate.java @@ -1,4 +1,4 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.basic.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -72,9 +72,9 @@ public class YjAppreciate implements Serializable { private LocalDateTime modifyTime; /** - * 所属商户id + * 所属门店id */ - private String merchanId; + private String visitStore; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjHealthy.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjHealthy.java similarity index 94% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjHealthy.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjHealthy.java index 30983ae..9bc1863 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjHealthy.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjHealthy.java @@ -1,4 +1,4 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.basic.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -72,9 +72,9 @@ public class YjHealthy implements Serializable { private LocalDateTime modifyTime; /** - * 所属商户id + * 所属门店id */ - private String merchanId; + private String visitStore; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjInherit.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjInherit.java similarity index 95% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjInherit.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjInherit.java index 1d4544b..cf64826 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjInherit.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjInherit.java @@ -1,4 +1,4 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.basic.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -72,9 +72,10 @@ public class YjInherit implements Serializable { private LocalDateTime modifyTime; /** + * * 所属商户id */ - private String merchanId; + private String visitStore; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjPracticeMoments.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjPracticeMoments.java similarity index 96% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjPracticeMoments.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjPracticeMoments.java index 06329e2..0d240be 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjPracticeMoments.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjPracticeMoments.java @@ -1,4 +1,4 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.basic.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -73,5 +73,5 @@ public class YjPracticeMoments implements Serializable { /** * 所属商户id */ - private String merchanId; + private String visitStore; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjSense.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjSense.java similarity index 94% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjSense.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjSense.java index 59cd6dd..00f1e9f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjSense.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjSense.java @@ -1,4 +1,4 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.basic.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -72,9 +72,9 @@ public class YjSense implements Serializable { private LocalDateTime modifyTime; /** - * 所属商户id + * 所属门店id */ - private String merchanId; + private String visitStore; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjStore.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjStore.java new file mode 100644 index 0000000..6b57003 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjStore.java @@ -0,0 +1,61 @@ +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; + +/** + *

+ * 门店表 + *

+ * + * @author xn + * @since 2022-09-28 + */ +@Data +@EqualsAndHashCode(callSuper = false) +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; + + @ApiModelProperty("banner图") + private String banner; + @ApiModelProperty("门店名称") + private String storeName; + //地址 + private String address; + //电话 + private String phone; + //创始人/店长简介(富文本) + private String founder; + // 企业/门店简介(富文本) + private String profile; + //租户id + private String tenantId; + //总店id + private String parentId; + + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjMerchant.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjTenant.java similarity index 87% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjMerchant.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjTenant.java index e8010d9..5f000f6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjMerchant.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/YjTenant.java @@ -1,4 +1,4 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.basic.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; @@ -20,7 +20,7 @@ import java.util.Date; */ @Data @EqualsAndHashCode(callSuper = false) -public class YjMerchant implements Serializable { +public class YjTenant implements Serializable { private static final long serialVersionUID=1L; @@ -67,14 +67,6 @@ public class YjMerchant implements Serializable { */ private Integer status;//状态 0申请,1审核中,2审核通过,3停止运营 - @ApiModelProperty("banner图") - private String banner;//banner图 - @ApiModelProperty("企业名称") - private String enterpriseName;//企业名称 - - private String address; - private String phone; - @TableField(exist = false) private String legalPersonCardPicturePositive1;//法人证件照片/扫描件正面 @@ -84,4 +76,5 @@ public class YjMerchant implements Serializable { @TableField(exist = false) private String businessLicensePicture1;//营业执照照片/扫描件 + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/domain/dto/StoreDto.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/dto/StoreDto.java new file mode 100644 index 0000000..ec35ac0 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/dto/StoreDto.java @@ -0,0 +1,34 @@ +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; + +/** + *

+ * 门店表 + *

+ * + * @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 childList; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjVenue.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/dto/YjVenueDto.java similarity index 92% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjVenue.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/domain/dto/YjVenueDto.java index 07c6b9a..e919c16 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjVenue.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/dto/YjVenueDto.java @@ -1,4 +1,4 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.basic.domain.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -14,14 +14,14 @@ import lombok.Data; */ @ApiModel(description= "场馆信息") @Data -public class YjVenue { +public class YjVenueDto { private Long deptId; /** * 商户id */ - private String merchantId; + private String storeId; /** * 地址 diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/domain/model/BaseAudit.java b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/model/BaseAudit.java new file mode 100644 index 0000000..401b8c2 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/domain/model/BaseAudit.java @@ -0,0 +1,31 @@ +package com.ruoyi.basic.domain.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class BaseAudit { + /** + * 创建者 + */ + private Long createBy; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + /** + * 更新者 + */ + private Long updateBy; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjAppUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjAppUserMapper.java new file mode 100644 index 0000000..72fa6b7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjAppUserMapper.java @@ -0,0 +1,18 @@ +package com.ruoyi.basic.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.common.core.domain.entity.AppUser; + +/** + *

+ * Mapper 接口 + *

+ * + * @author xn + * @since 2022-10-14 + */ +public interface YjAppUserMapper extends BaseMapper { + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjAppreciateMapper.java b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjAppreciateMapper.java similarity index 74% rename from ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjAppreciateMapper.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjAppreciateMapper.java index a30bc6d..7e39999 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjAppreciateMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjAppreciateMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.mapper; +package com.ruoyi.basic.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjAppreciate; +import com.ruoyi.basic.domain.YjAppreciate; /** *

diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjHealthyMapper.java b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjHealthyMapper.java similarity index 74% rename from ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjHealthyMapper.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjHealthyMapper.java index 3a26566..e76f6ae 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjHealthyMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjHealthyMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.mapper; +package com.ruoyi.basic.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjHealthy; +import com.ruoyi.basic.domain.YjHealthy; /** *

diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjInheritMapper.java b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjInheritMapper.java similarity index 74% rename from ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjInheritMapper.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjInheritMapper.java index 4c31753..063cacd 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjInheritMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjInheritMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.mapper; +package com.ruoyi.basic.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjInherit; +import com.ruoyi.basic.domain.YjInherit; /** *

diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjPracticeMomentsMapper.java b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjPracticeMomentsMapper.java similarity index 73% rename from ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjPracticeMomentsMapper.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjPracticeMomentsMapper.java index 1d6a738..83c5d0a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjPracticeMomentsMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjPracticeMomentsMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.mapper; +package com.ruoyi.basic.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjPracticeMoments; +import com.ruoyi.basic.domain.YjPracticeMoments; /** *

diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjSenseMapper.java b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjSenseMapper.java similarity index 75% rename from ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjSenseMapper.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjSenseMapper.java index 7203740..604d655 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjSenseMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjSenseMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.mapper; +package com.ruoyi.basic.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjSense; +import com.ruoyi.basic.domain.YjSense; /** *

diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjStoreMapper.java b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjStoreMapper.java new file mode 100644 index 0000000..1bdb2ea --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/mapper/YjStoreMapper.java @@ -0,0 +1,24 @@ +package com.ruoyi.basic.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.basic.domain.YjStore; +import com.ruoyi.basic.domain.dto.StoreDto; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 商户表 Mapper 接口 + *

+ * + * @author xn + * @since 2022-09-28 + */ +public interface YjStoreMapper extends BaseMapper { + + + List getListForLogin(); + List getChilds(String id); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjAppUserService.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjAppUserService.java new file mode 100644 index 0000000..c79c510 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjAppUserService.java @@ -0,0 +1,19 @@ +package com.ruoyi.basic.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.entity.AppUser; +import com.ruoyi.common.core.domain.entity.SysUser; + +/** + *

+ * 瑜伽传承 服务类 + *

+ * + * @author xn + * @since 2022-09-26 + */ +public interface YjAppUserService extends IService { + + AppUser selectAppUserByPhone(String phoneNumber); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjInheritService.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjInheritService.java similarity index 74% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/YjInheritService.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/YjInheritService.java index 25fe92a..59e5768 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjInheritService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjInheritService.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.service; +package com.ruoyi.basic.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.YjInherit; +import com.ruoyi.basic.domain.YjInherit; /** *

diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjPracticeMomentsService.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjPracticeMomentsService.java similarity index 72% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/YjPracticeMomentsService.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/YjPracticeMomentsService.java index a7bcb60..a3f1908 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjPracticeMomentsService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjPracticeMomentsService.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.service; +package com.ruoyi.basic.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.YjPracticeMoments; +import com.ruoyi.basic.domain.YjPracticeMoments; /** *

diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjMerchantService.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjStoreService.java similarity index 51% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/YjMerchantService.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/YjStoreService.java index f364d41..c7d42ea 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjMerchantService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/YjStoreService.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.service; +package com.ruoyi.basic.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.YjMerchant; +import com.ruoyi.basic.domain.YjStore; /** *

@@ -12,6 +12,6 @@ import com.ruoyi.shop.domain.YjMerchant; * @author xn * @since 2022-09-28 */ -public interface YjMerchantService extends IService { +public interface YjStoreService extends IService { } diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjAppUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjAppUserServiceImpl.java new file mode 100644 index 0000000..b9200a9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjAppUserServiceImpl.java @@ -0,0 +1,33 @@ +package com.ruoyi.basic.service.impl; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.entity.AppUser; +import com.ruoyi.basic.mapper.YjAppUserMapper; +import com.ruoyi.basic.service.YjAppUserService; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.im.constant.RedisKey; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.stereotype.Service; + +/** + *

+ * + *

+ * + * @author xn + * @since 2022-10-14 + */ +@Service +public class YjAppUserServiceImpl extends ServiceImpl implements YjAppUserService { + + + @Override + public AppUser selectAppUserByPhone(String phoneNumber) + { + return this.getOne(new QueryWrapper().eq("phone_number",phoneNumber)); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjAppreciateServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjAppreciateServiceImpl.java similarity index 70% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjAppreciateServiceImpl.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjAppreciateServiceImpl.java index 0366c5c..2fe2465 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjAppreciateServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjAppreciateServiceImpl.java @@ -1,9 +1,9 @@ -package com.ruoyi.shop.service.impl; +package com.ruoyi.basic.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjAppreciate; -import com.ruoyi.shop.mapper.YjAppreciateMapper; +import com.ruoyi.basic.domain.YjAppreciate; +import com.ruoyi.basic.mapper.YjAppreciateMapper; import org.springframework.stereotype.Service; /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjHealthyServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjHealthyServiceImpl.java similarity index 70% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjHealthyServiceImpl.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjHealthyServiceImpl.java index 83c7471..c390e69 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjHealthyServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjHealthyServiceImpl.java @@ -1,9 +1,9 @@ -package com.ruoyi.shop.service.impl; +package com.ruoyi.basic.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjHealthy; -import com.ruoyi.shop.mapper.YjHealthyMapper; +import com.ruoyi.basic.domain.YjHealthy; +import com.ruoyi.basic.mapper.YjHealthyMapper; import org.springframework.stereotype.Service; /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjInheritServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjInheritServiceImpl.java similarity index 65% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjInheritServiceImpl.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjInheritServiceImpl.java index fcb8b08..3b7c7df 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjInheritServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjInheritServiceImpl.java @@ -1,10 +1,10 @@ -package com.ruoyi.shop.service.impl; +package com.ruoyi.basic.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjInherit; -import com.ruoyi.shop.mapper.YjInheritMapper; -import com.ruoyi.shop.service.YjInheritService; +import com.ruoyi.basic.domain.YjInherit; +import com.ruoyi.basic.mapper.YjInheritMapper; +import com.ruoyi.basic.service.YjInheritService; import org.springframework.stereotype.Service; /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjPracticeMomentsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjPracticeMomentsServiceImpl.java similarity index 64% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjPracticeMomentsServiceImpl.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjPracticeMomentsServiceImpl.java index 153b478..fe4a2aa 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjPracticeMomentsServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjPracticeMomentsServiceImpl.java @@ -1,10 +1,10 @@ -package com.ruoyi.shop.service.impl; +package com.ruoyi.basic.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjPracticeMoments; -import com.ruoyi.shop.mapper.YjPracticeMomentsMapper; -import com.ruoyi.shop.service.YjPracticeMomentsService; +import com.ruoyi.basic.domain.YjPracticeMoments; +import com.ruoyi.basic.mapper.YjPracticeMomentsMapper; +import com.ruoyi.basic.service.YjPracticeMomentsService; import org.springframework.stereotype.Service; /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjSenseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjSenseServiceImpl.java similarity index 71% rename from ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjSenseServiceImpl.java rename to ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjSenseServiceImpl.java index bfb64ef..4b60dc9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjSenseServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjSenseServiceImpl.java @@ -1,9 +1,9 @@ -package com.ruoyi.shop.service.impl; +package com.ruoyi.basic.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjSense; -import com.ruoyi.shop.mapper.YjSenseMapper; +import com.ruoyi.basic.domain.YjSense; +import com.ruoyi.basic.mapper.YjSenseMapper; import org.springframework.stereotype.Service; /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjStoreServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjStoreServiceImpl.java new file mode 100644 index 0000000..9553698 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/basic/service/impl/YjStoreServiceImpl.java @@ -0,0 +1,21 @@ +package com.ruoyi.basic.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.basic.domain.YjStore; +import com.ruoyi.basic.mapper.YjStoreMapper; +import com.ruoyi.basic.service.YjStoreService; +import org.springframework.stereotype.Service; + +/** + *

+ * 商户表 服务实现类 + *

+ * + * @author xn + * @since 2022-09-28 + */ +@Service +public class YjStoreServiceImpl extends ServiceImpl implements YjStoreService { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/Appointment.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/Appointment.java deleted file mode 100644 index 70f2174..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/Appointment.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ruoyi.course.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - *

- * 预约表 - *

- * - * @author xhj - * @since 2022-09-27 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class Appointment implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - -// @ApiModelProperty(value = "消费者id") - private Long consumerId; - -// @ApiModelProperty(value = "课程记录id") - private Integer courseLogId; - -// @ApiModelProperty(value = "创建时间") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") - private LocalDateTime createTime; - -// @ApiModelProperty(value = "备注") - private String remark; - -// @ApiModelProperty(value = "电话") - private String phone; - -// @ApiModelProperty(value = "0 未完成1 已完成") - private Integer status; - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") -// @ApiModelProperty(value = "完成时间") - private LocalDateTime updateTime; - -// @ApiModelProperty(value = "操作人") - private String updateUser; - - private Integer flag;//0 预约中 1预约成功 2预约失败 3取消预约 - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/AppointmentVo.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/AppointmentVo.java deleted file mode 100644 index 72715ee..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/AppointmentVo.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.ruoyi.course.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - *

- * 预约表 - *

- * - * @author xhj - * @since 2022-09-27 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class AppointmentVo implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - -// @ApiModelProperty(value = "消费者id") - private Integer consumerId; - -// @ApiModelProperty(value = "课程记录id") - private Integer courseLogId; - -// @ApiModelProperty(value = "创建时间") - private String createTime; - -// @ApiModelProperty(value = "备注") - private String remark; - -// @ApiModelProperty(value = "电话") - private String phone; - -// @ApiModelProperty(value = "0 未完成1 已完成") - private Integer status; - -// @ApiModelProperty(value = "完成时间") - private String updateTime; - -// @ApiModelProperty(value = "操作人") - private String updateUser; - private String startDate; - private String startTime; - private String endTime; - private Integer number; - private Integer tearcher; - private String place; - private Integer appointmentNum; - private String courseName; - private String courseNames; - private String userName; - private String consumerName; - private String teacherName; - private Integer flag; - - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/ConsumerCourse.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/ConsumerCourse.java deleted file mode 100644 index 6aa843e..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/ConsumerCourse.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ruoyi.course.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - *

- * - *

- * - * @author xn - * @since 2022-12-29 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class ConsumerCourse implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - /** - * 客户id - */ - private Long consumerId; - - /** - * 课程id - */ - private Integer courseLogId; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/Course.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/Course.java deleted file mode 100644 index b241c44..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/Course.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.ruoyi.course.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.util.List; - -/** - *

- * 课程 - *

- * - * @author xhj - * @since 2022-09-22 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class Course implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "course_id", type = IdType.AUTO) - private Integer courseId; - - private String courseName; - - private String courseContext; - - private String coursePicture; - - private String courseExplain;//说明 - - private String memberType;//类型 大咖,普通 - - private String courseType;//大咖1 大咖 2 大咖3 - - private String courseType1;//具体分类 - - private Integer releases;//是否发布 - - private String stroreId;// - - private String data; - private String videoLong; - private String videoShort; - private BigDecimal coursePrice;//价格 - - @TableField(exist = false) - private List memberNum; - - - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/CourseLog.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/CourseLog.java deleted file mode 100644 index 15a9fc5..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/CourseLog.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.ruoyi.course.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 com.ruoyi.common.utils.StringUtils; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.List; - -/** - *

- * 课程记录 - *

- * - * @author xhj - * @since 2022-09-23 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class CourseLog implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - private Integer courseId; - - private String startDate; - - private String startTime; - - private String endTime; - - private Integer number; - - private Integer tearcher; - - private String place; - - private Integer appointmentNum; - - private LocalDateTime createTime; - - //价格") - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal coursePrice; - - //长视频") - private String videoLong; - - //短视频") - private String videoShort; - - //类型 大咖,普通") - private String memberType; - - //大咖1 大咖 2 大咖3 ") - private String courseType; - - //具体分类") - private String courseType1; - - //课程名字") - private String courseNames; - - //客程内容") - private String courseContext; - - //图片") - private String coursePicture; - - private String releases; - - private String sourceTime; - - -// private sourceLpId; - - @TableField(exist = false) - private String endDate;//结束日期 - - @TableField(exist = false) - private String week;//周几上课 周日1 周一2 - - @TableField(exist = false) - private List memberNum; - - //流派id - private Integer lpId; - - public void generateMemberNum(){ - - if (StringUtils.isNotBlank(memberType)) { - if (memberType.length() == 1) { - setMemberNum(Arrays.asList(memberType)); - } else { - String[] str = memberType.split(","); - setMemberNum(Arrays.asList(str)); - } - } - } - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/CourseLogVo.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/CourseLogVo.java deleted file mode 100644 index 44d29e4..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/CourseLogVo.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.ruoyi.course.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.ruoyi.common.utils.StringUtils; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.List; - -/** - *

- * 课程记录 - *

- * - * @author xhj - * @since 2022-09-23 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class CourseLogVo implements Serializable { - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - // 课程id - private Integer courseId; - - // 开始日期 - private String startDate; - - // 开始时间 - private String startTime; - - //结束时间 - private String endTime; - - // 数量 - private Integer number; - - // 老师 - private Integer tearcher; - - // 地点 - private String place; - - // 预约人数 - private Integer appointmentNum; - - // 创建啊时间 - private LocalDateTime createTime; - // 课程时间 - private String sourceTime; - - - - //价格") - private BigDecimal coursePrice; - - //长视频") - private String videoLong; - - //短视频") - private String videoShort; - - //类型 大咖,普通") - private String memberType; - - //大咖1 大咖 2 大咖3 ") - private String courseType; - - //具体分类") - private String courseType1; - - //课程名字") - private String courseNames; - - //客程内容") - private String courseContext; - - //图片") - private String coursePicture; - - private String releases; - //流派id - private Integer lpId; - - private String userName; - private List memberNum; - private String stroreId; - - private String week;//周几上课 星期一(1)、星期二(2)、星期三(3)、星期四((4)、星期五((5)、星期六(6)、星期日(7) - - // private String courseName; - public List getMembers(){ - if (StringUtils.isNotBlank(memberType)) { - if (memberType.length() == 1) { - setMemberNum(Arrays.asList(memberType)); - } else { - String[] str = memberType.split(","); - setMemberNum(Arrays.asList(str)); - } - } - return memberNum; - } - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/HistoryMessage.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/HistoryMessage.java deleted file mode 100644 index e096cd7..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/HistoryMessage.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.ruoyi.course.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - *

- * 消息记录 - *

- * - * @author xn - * @since 2022-12-03 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class HistoryMessage implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - private String phone; - - private String notificationTitle; - - private String msgContent; - - private Boolean releases; - - private String sendTime; - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/Member.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/Member.java deleted file mode 100644 index 1f52b1e..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/Member.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ruoyi.course.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; - -/** - *

- * - *

- * - * @author xhj - * @since 2022-09-23 - */ -@ApiModel(description= "会籍") -@Data -@EqualsAndHashCode(callSuper = false) -public class Member implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "member_id", type = IdType.AUTO) - private Integer memberId; - - // 会籍名 - @ApiModelProperty("会籍名") - private String memberName; - - // 会籍内容 - @ApiModelProperty("会籍内容") - private String memberContext; - - //图片 - @ApiModelProperty("图片") - private String memberPicture; - - - //有效期 - @ApiModelProperty("有效期") - private String validity; - - private String myType; - //价格 - @ApiModelProperty("价格") - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal memberPrice; - - - // 发布 - private Boolean releases; - - private String data; - - // 会籍 - private String stroreId; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/ReqClaTimeCount.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/ReqClaTimeCount.java new file mode 100644 index 0000000..bdc700c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/ReqClaTimeCount.java @@ -0,0 +1,21 @@ +package com.ruoyi.course.domain; + + +import com.ruoyi.course.domain.page.ReqDeptCondition; +import lombok.Builder; +import lombok.Data; + +/** + * @author :zhangbaoyu + * @date :Created in 2020/10/24 12:21 + */ +@Data +@Builder +public class ReqClaTimeCount extends ReqDeptCondition { + + private String beginDate; + private String endDate; + private Boolean hadBegin; + private Long teacherId; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/ReqSearchClaTime.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/ReqSearchClaTime.java new file mode 100644 index 0000000..5c4b74e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/ReqSearchClaTime.java @@ -0,0 +1,69 @@ +package com.ruoyi.course.domain; + + +import com.ruoyi.course.domain.page.ReqPageBase; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author :zhangbaoyu + * @date :Created in 2020/9/18 14:45 + */ +@Data +public class ReqSearchClaTime extends ReqPageBase implements Serializable { + + // 排课 编号 + private Long courseTimeId; + + // 课程 + private Long courseId; + + // 校区 + private Long deptId; + + // 当前登录用户 + private String userId; + + // 班级 + private Long claId; + + // 学生 + private Long studentId; + + private Long teacherId; + + // 开始时间 + private String beginDate; + + // 结束时间 + private String endDate; + + /** + * 与今天相隔几天 + * 如果设置了,将重置 beginDate、endDate + */ + private Integer diffNowDay; + + /** + * 是否已上课 + * true 已上课 + * false 未上课 + */ + private Boolean attended; + + /** + * 排序类型 + * claTimeAttend + */ + private String orderByType; + +// public void setDiffNowDay(Integer diffNowDay) { +// this.diffNowDay = diffNowDay; +// if(null != diffNowDay) { +// DateTime now = DateTime.now(); +// this.beginDate = now.minusDays(diffNowDay).toString("yyyy-MM-dd"); +// this.endDate = now.plusDays(diffNowDay).toString("yyyy-MM-dd"); +// } +// } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/RespClaTime.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/RespClaTime.java new file mode 100644 index 0000000..d856ca4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/RespClaTime.java @@ -0,0 +1,73 @@ +package com.ruoyi.course.domain; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 上课记录 + * @author :zhangbaoyu + * @date :Created in 2020/10/2 20:33 + */ +@Data +public class RespClaTime { + + private Long courseTimeId; + + private Long claId; + + private String claName; + + private Long courseId; + + private String courseName; + + private Long teacherId; + + private String staffName; + + /** + * 状态 1:待上课 2:已上课 + */ + private String status; + + private String claDate; + + private String startTime; + + private String endTime; + + private String realClaDate; + + private String realStartTime; + + private String realEndTime; + + // 应到 + private Integer needAttendCnt; + + // 实到 + private Integer realAttendCnt; + + private Integer leaveCnt; + + private Integer outCnt; + + private BigDecimal payHour; + + private BigDecimal payTotalHour; + + private BigDecimal payTotalFee; + + private String roomName; + + private String classTheme; + + private String memo; + + // 最后变更时间 记录上课时间 + private Date lastUpdateTime; + // 记录人 + private String lastUpdateUserName; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/RespClaTimeCalendar.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/RespClaTimeCalendar.java new file mode 100644 index 0000000..c6ea51e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/RespClaTimeCalendar.java @@ -0,0 +1,27 @@ +package com.ruoyi.course.domain; + +import lombok.Data; + +/** + * 排课信息(课表) + * @author :zhangbaoyu + * @date :Created in 2020/9/18 14:50 + */ +@Data +public class RespClaTimeCalendar extends ScClaTime { + + private String claColor; + + private String staffName; + + // 上课星期 + private Integer weekDay; + + // 上课 开始小时 + private Integer startHour; + + private Integer studentCount; + + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/ScClaTime.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/ScClaTime.java new file mode 100644 index 0000000..4ed2dff --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/ScClaTime.java @@ -0,0 +1,231 @@ +package com.ruoyi.course.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 lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 排课信息 + *

+ * + * @author zhangby + * @since 2020-09-16 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("sc_cla_time") +public class ScClaTime implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 排课编号 + */ + @TableId(value = "course_time_id", type = IdType.ASSIGN_ID) + private Long courseTimeId; + + /** + * 规则编号 + */ + @TableField("rule_id") + private Long ruleId; + + /** + * 班级id + */ + @TableField("cla_id") + private Long claId; + + /** + * 任课教师 + */ + @TableField("teacher_id") + private Long teacherId; + + /** + * 上课教室 + */ + @TableField("room_id") + private Long roomId; + + /** + * 上课教室 + */ + @TableField("room_name") + private String roomName; + + /** + * 上课主题 + */ + @TableField("class_theme") + private String classTheme; + + /** + * 上课日期 如:2020-02-05 + */ + @TableField("cla_date") + private String claDate; + + /** + * 上课开始时间 + */ + @TableField("start_time") + private String startTime; + + /** + * 上课结束时间 + */ + @TableField("end_time") + private String endTime; + + /** + * 实际上课时间 + */ + @TableField("real_cla_date") + private String realClaDate; + + /** + * 实际开始时间 + */ + @TableField("real_start_time") + private String realStartTime; + + /** + * 实际结束时间 + */ + @TableField("real_end_time") + private String realEndTime; + + /** + * 课时变更数量 + */ + @TableField("pay_hour") + private BigDecimal payHour; + + /** + * 总课时消耗 + */ + @TableField("pay_total_hour") + private BigDecimal payTotalHour; + + /** + * 总学费消耗 + */ + @TableField("pay_total_fee") + private BigDecimal payTotalFee; + + /** + * 来源 1:重复排课 2:未排课上课 3:单个新增 + */ + @TableField("source") + private String source; + + /** + * 状态 1:待上课 2:已上课 + */ + @TableField("status") + private String status; + + /** + * 应到人数 + */ + @TableField("need_attend_cnt") + private Integer needAttendCnt; + + /** + * 实到人数 + */ + @TableField("real_attend_cnt") + private Integer realAttendCnt; + + /** + * 到课人数 + */ + @TableField("at_class_cnt") + private Integer atClassCnt; + + /** + * 请假人数 + */ + @TableField("leave_cnt") + private Integer leaveCnt; + + /** + * 缺勤人数 + */ + @TableField("out_cnt") + private Integer outCnt; + + /** + * 备注 + */ + @TableField("memo") + private String memo; + + /** + * 创建者 + */ + @TableField("create_user") + private String createUser; + + /** + * 创建时间 + */ + @TableField("create_time") + private Date createTime; + + /** + * 更新者 + */ + @TableField("last_update_user") + private String lastUpdateUser; + + /** + * 更新时间 + */ + @TableField("last_update_time") + private Date lastUpdateTime; + + @TableField(exist = false) + private Long deptId; + @TableField(exist = false) + private String courseName; + @TableField(exist = false) + private String claName; + @TableField(exist = false) + private String deptName; + + public boolean checkUpdateParam() { + if (StringUtils.isAnyEmpty(claDate, startTime, endTime)) { + return false; + } + if (null == teacherId) { + return false; + } + return true; + } + + public boolean checkAddParam() { + if(null == claId || null == teacherId) { + return false; + } + if (StringUtils.isAnyEmpty(claDate, startTime, endTime)) { + return false; + } + return true; + } + + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/appReq/BuyCourseReq.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/appReq/BuyCourseReq.java deleted file mode 100644 index f626080..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/domain/appReq/BuyCourseReq.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.ruoyi.course.domain.appReq; - -import lombok.Data; - -import java.math.BigDecimal; - -/** - * @version V1.0.0 - * @Title: BuyCourseReq - * @Package com.ruoyi.domain.course - * @Description: 购买课程实体 - * @author: xhj - * @date: 2022/9/29 14:32 - */ -@Data -public class BuyCourseReq { - - // 课程 id - private Integer id; - - private String courseName; - - private String courseContext; - -// course_explain -// member_type -// course_type -// course_type1 -// start_date -// start_time -// source_time -// place - - - - - - - - - // 消费者id - private Long idUser; - // 消费者备注 - private String message; - - private String payId; - private String payStatus; - private String payTime; - private String payType; - private BigDecimal realPrice; - private BigDecimal totalPrice; - private BigDecimal tradeAmount; - private Long businessId; - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/page/ReqDeptCondition.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/page/ReqDeptCondition.java new file mode 100644 index 0000000..9103f1a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/page/ReqDeptCondition.java @@ -0,0 +1,17 @@ +package com.ruoyi.course.domain.page; + +import lombok.Data; + +/** + * 校区查询条件 + * @author :zhangbaoyu + * @date :Created in 2020/10/24 09:25 + */ +@Data +public class ReqDeptCondition { + + private Long deptId; + + private String userId; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/page/ReqPageBase.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/page/ReqPageBase.java new file mode 100644 index 0000000..6682174 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/page/ReqPageBase.java @@ -0,0 +1,18 @@ +package com.ruoyi.course.domain.page; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 分页请求 + * @author :zhangbaoyu + * @date :Created in 2020-01-15 21:41 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ReqPageBase extends ReqDeptCondition{ + + private long pageNum = 1; + + private long pageSize = 10; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeCalendarItem.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeCalendarItem.java new file mode 100644 index 0000000..a8743ad --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeCalendarItem.java @@ -0,0 +1,60 @@ +package com.ruoyi.course.domain.time; + + +import com.ruoyi.common.constant.Constants; +import com.ruoyi.course.domain.RespClaTimeCalendar; +import lombok.Data; + +/** + * 单节排课信息 + * @author :zhangbaoyu + * @date :Created in 2020/9/23 18:54 + */ +@Data +public class ClaTimeCalendarItem { + + private Long courseTimeId; + + private String claName; + + private String courseName; + + // 日期 + private String claDate; + + // 星期 + private String weekDay; + + private String startTime; + + private String endTime; + + private String staffName; + + private int studentCount; + + // 教室 + private String roomName; + + private String claColor; + + // 上课状态 + private String claTimeStatus; + + public ClaTimeCalendarItem transfer(RespClaTimeCalendar respClaTime) { + this.courseTimeId = respClaTime.getCourseTimeId(); + this.claName = respClaTime.getClaName(); + this.courseName = respClaTime.getCourseName(); + this.claDate = respClaTime.getClaDate(); + this.weekDay = Constants.WEEK_DAY_MAP.get(respClaTime.getWeekDay()); + this.startTime = respClaTime.getStartTime().substring(0,5); + this.endTime = respClaTime.getEndTime().substring(0,5); + this.staffName = respClaTime.getStaffName(); + this.studentCount = respClaTime.getStudentCount(); + this.roomName = respClaTime.getRoomName(); + this.claColor = respClaTime.getClaColor(); + this.claTimeStatus = respClaTime.getStatus(); + return this; + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeColumnTitle.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeColumnTitle.java new file mode 100644 index 0000000..2cda15e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeColumnTitle.java @@ -0,0 +1,22 @@ +package com.ruoyi.course.domain.time; + +import lombok.Data; + +/** + * 按时间 课表 title + * @author :zhangbaoyu + * @date :Created in 2020/9/23 17:16 + */ +@Data +public class ClaTimeColumnTitle { + + // 星期 + private String weekName; + + // 日期 + private String day; + + // 排课数量 + private int count; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeContainer.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeContainer.java new file mode 100644 index 0000000..4650e82 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/ClaTimeContainer.java @@ -0,0 +1,23 @@ +package com.ruoyi.course.domain.time; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * 具体排课数据 + * table 单行 + * @author :zhangbaoyu + * @date :Created in 2020/9/23 18:59 + */ +@Data +public class ClaTimeContainer { + + // 上课时间 + private String time; + + // 排课信息 + private Map> claTimeWeekDayMap; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/RespBusinessClaTimeCalendar.java b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/RespBusinessClaTimeCalendar.java new file mode 100644 index 0000000..440dd85 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/domain/time/RespBusinessClaTimeCalendar.java @@ -0,0 +1,21 @@ +package com.ruoyi.course.domain.time; + +import lombok.Data; + +import java.util.List; + +/** + * 按时间 课表 + * @author :zhangbaoyu + * @date :Created in 2020/9/23 17:15 + */ +@Data +public class RespBusinessClaTimeCalendar { + + // 标题 + private List columnTitles; + + // 行数据 + private List claTimeContainer; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/AppointmentMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/AppointmentMapper.java deleted file mode 100644 index 4d6eb05..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/AppointmentMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ruoyi.course.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.course.domain.Appointment; -import com.ruoyi.course.domain.AppointmentVo; - -import java.util.List; -import java.util.Map; - -/** - *

- * 预约表 Mapper 接口 - *

- * - * @author xhj - * @since 2022-09-27 - */ -public interface AppointmentMapper extends BaseMapper { - - ListfindList(Map map); - int cancel(Appointment appointment); - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ConsumerCourseMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ConsumerCourseMapper.java deleted file mode 100644 index 82b175c..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ConsumerCourseMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ruoyi.course.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.course.domain.ConsumerCourse; -import com.ruoyi.course.domain.CourseLog; - -import java.util.List; - -/** - *

- * Mapper 接口 - *

- * - * @author xn - * @since 2022-12-29 - */ -public interface ConsumerCourseMapper extends BaseMapper { - - List myCourse(Long consumerId); -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ContextMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ContextMapper.java index b201ee4..0e270b9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ContextMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ContextMapper.java @@ -2,12 +2,11 @@ package com.ruoyi.course.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.course.domain.Context; -import com.ruoyi.course.domain.Member; import java.util.List; import java.util.Map; public interface ContextMapper extends BaseMapper { - List findList(Context context ); - public List findList(Map map); + Context getOne(Map map); + List findList(Map map); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/CourseLogMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/CourseLogMapper.java deleted file mode 100644 index 84d0df3..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/CourseLogMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ruoyi.course.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.course.domain.CourseLog; - -/** - *

- * 课程记录 Mapper 接口 - *

- * - * @author xhj - * @since 2022-09-23 - */ -public interface CourseLogMapper extends BaseMapper { - - /** - * 增加预约人数 - * @param id - */ - void updateAppointmentNum(Integer id); - - int emptyLog(CourseLog log); -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/CourseMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/CourseMapper.java deleted file mode 100644 index b6054ac..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/CourseMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.ruoyi.course.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.course.domain.Context; -import com.ruoyi.course.domain.Course; -import com.ruoyi.course.domain.CourseLogVo; - -import java.util.List; -import java.util.Map; - -/** - *

- * 课程 Mapper 接口 - *

- * - * @author xhj - * @since 2022-09-22 - */ -public interface CourseMapper extends BaseMapper { - - public ListfindList(Map map); - - - public ListfindLog(Map map); - public ListfindLog1(Map map); - - List listForApp(Course course); - Context getTeacherPhone(Integer id); - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/HistoryMessageMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/HistoryMessageMapper.java deleted file mode 100644 index bc52f0c..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/HistoryMessageMapper.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.ruoyi.course.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.course.domain.HistoryMessage; - -public interface HistoryMessageMapper extends BaseMapper { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/MemberMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/MemberMapper.java deleted file mode 100644 index 60ef8a4..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/MemberMapper.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ruoyi.course.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.course.domain.Member; - -import java.util.List; -import java.util.Map; - -/** - *

- * Mapper 接口 - *

- * - * @author xhj - * @since 2022-09-23 - */ -public interface MemberMapper extends BaseMapper { - List findList(Member member); - public List findList(Map map); -// List findList(String memberName); - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ScClaTimeMapper.java b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ScClaTimeMapper.java new file mode 100644 index 0000000..b0c269e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/mapper/ScClaTimeMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.course.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.course.domain.*; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 排课信息 Mapper 接口 + *

+ * + * @author zhangby + * @since 2020-09-16 + */ +public interface ScClaTimeMapper extends BaseMapper { + + /** + * 获取排课信息 + * + * @param searchClaTime + * @return + */ + List selectListForCalendar(ReqSearchClaTime searchClaTime); + + /** + * 获取上课记录 + * + * @param searchClaTime + * @return + */ + List selectListForAttend(@Param("searchClaTime") ReqSearchClaTime searchClaTime, @Param("page") Page page); + + /** + * 数量 + * + * @param reqClaTimeCount + * @return + */ + Integer selectClaTimeCount(ReqClaTimeCount reqClaTimeCount); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/AppointmentServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/AppointmentServiceImpl.java deleted file mode 100644 index f483255..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/service/AppointmentServiceImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.ruoyi.course.service; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.course.domain.Appointment; -import com.ruoyi.course.domain.AppointmentVo; -import com.ruoyi.course.mapper.AppointmentMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Map; - -/** - *

- * 预约表 服务实现类 - *

- * - * @author xhj - * @since 2022-09-27 - */ -@Service -public class AppointmentServiceImpl extends ServiceImpl { - - @Autowired - AppointmentMapper appointmentMapper; - - public ListfindList(Map map){ - return appointmentMapper.findList(map); - } - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/ConsumerCourseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/ConsumerCourseServiceImpl.java deleted file mode 100644 index 1e45bc0..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/service/ConsumerCourseServiceImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.ruoyi.course.service; - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.course.domain.ConsumerCourse; -import com.ruoyi.course.mapper.ConsumerCourseMapper; -import org.springframework.stereotype.Service; - -/** - *

- * 服务实现类 - *

- * - * @author xn - * @since 2022-12-29 - */ -@Service -public class ConsumerCourseServiceImpl extends ServiceImpl { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/ContextServicelmpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/ContextServicelmpl.java deleted file mode 100644 index 8b21f77..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/service/ContextServicelmpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.ruoyi.course.service; - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.course.domain.Context; -import com.ruoyi.course.mapper.ContextMapper; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Map; - -@Service -public class ContextServicelmpl extends ServiceImpl { - public List getList(Map map){ - List list = baseMapper.findList(map); - return list; - } - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/CourseLogServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/CourseLogServiceImpl.java deleted file mode 100644 index 4f14efb..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/service/CourseLogServiceImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.ruoyi.course.service; - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.course.domain.CourseLog; -import com.ruoyi.course.mapper.CourseLogMapper; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; - -/** - *

- * 课程记录 服务实现类 - *

- * - * @author xhj - * @since 2022-09-23 - */ -@Service -public class CourseLogServiceImpl extends ServiceImpl { - - @Resource - private CourseLogMapper mapper; - - public void addLog(CourseLog courseLog){ - - mapper.emptyLog(courseLog);//清空 同一个教练+课程 今天之后的没人预约的课 - //开始时间 - String start=courseLog.getStartDate(); - //结束时间 - String end=courseLog.getEndDate(); - //周几 - String[] week= courseLog.getWeek().split(","); - - SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); - Calendar cal=Calendar.getInstance(); - try { - cal.setTime(sdf.parse(start)); - - while (sdf.parse(start).before(sdf.parse(end)) || sdf.parse(start).equals(sdf.parse(end))){ - for (String w:week){ - int i= cal.get(Calendar.DAY_OF_WEEK); - if (i==Integer.parseInt(w)){ - System.out.println(sdf.format(cal.getTime())); - courseLog.setStartDate(sdf.format(cal.getTime())); - save(courseLog); - courseLog.setId(null); - } - } - cal.add(Calendar.DATE,1); - start=sdf.format(cal.getTime()); - } - }catch (ParseException e){ - e.printStackTrace(); - } - } - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/CourseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/CourseServiceImpl.java deleted file mode 100644 index 175835f..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/service/CourseServiceImpl.java +++ /dev/null @@ -1,363 +0,0 @@ -package com.ruoyi.course.service; - -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.course.domain.*; -import com.ruoyi.course.mapper.CourseLogMapper; -import com.ruoyi.course.mapper.CourseMapper; -import com.ruoyi.search.domain.MemberUser; -import com.ruoyi.search.service.MemberUserServicelmpl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.*; - -@Service -public class CourseServiceImpl extends ServiceImpl { - - - @Autowired - CourseMapper courseMapper; - - @Autowired - CourseLogServiceImpl courseLogService; - - @Autowired - CourseLogMapper courseLogMapper; - - @Autowired - AppointmentServiceImpl appointmentService; - @Autowired - MemberUserServicelmpl memberUserService; - - public List getList(Map map) { - - List list = courseMapper.findList(map); - list.forEach(e -> { - if (StringUtils.isNotBlank(e.getMemberType())) { - if (e.getMemberType().length() == 1) { - e.setMemberNum(Arrays.asList(e.getMemberType())); - } else { - String[] str = e.getMemberType().split(","); - - e.setMemberNum(Arrays.asList(str)); - } - } - }); - - if (ObjectUtil.isEmpty(list)){ - System.out.println(); - } - return list; - } - - - - public List getListLog(Map map) { - - List list = courseMapper.findLog(map); - list.forEach(e -> { - if (StringUtils.isNotBlank(e.getMemberType())) { - if (e.getMemberType().length() == 1) { - e.setMemberNum(Arrays.asList(e.getMemberType())); - } else { - String[] str = e.getMemberType().split(","); - - e.setMemberNum(Arrays.asList(str)); - } - } - - - }); - return list; - - } - - - - /** - * 预约课程 - */ - public void yyCourse(Appointment appointment) { - appointment.setCreateTime(DateUtil.parseLocalDateTime(DateUtil.now(), "yyyy-MM-dd HH:mm:ss")); - CourseLog courseLog = new CourseLog(); - courseLogMapper.updateAppointmentNum(appointment.getCourseLogId()); - } - - - public void yyCourse1(Appointment appointment) { - appointment.setCreateTime(DateUtil.parseLocalDateTime(DateUtil.now(), "yyyy-MM-dd HH:mm:ss")); - appointmentService.save(appointment); - } - - /** - * 查询课程表内的课程 - * - * @param map - */ - public Map listLogDate(Map map) { - //获取本周日期 - String type = (String) map.get("type"); - String date = (String) map.get("date"); - Integer courseId = (Integer) map.get("courseId"); - String end = ""; - String start = ""; -// if ("now".equals(type)) { - DateTime starttime = DateUtil.beginOfWeek(DateUtil.date()); - DateTime endtime = DateUtil.endOfWeek(DateUtil.date()); - start = DateUtil.format(starttime, "yyyy-MM-dd"); - end = DateUtil.format(endtime, "yyyy-MM-dd"); -// } else if ("next".equals(type)) { -// -// } else if ("up".equals("type")) { -// -// } - - Map queryMap = new HashMap(); - queryMap.put("beginCreateTime", start); - queryMap.put("endCreateTime", end); - queryMap.put("courseType", "1"); - List logList = courseMapper.findLog(queryMap); - // 确定有几个时间短 通过开始时间 - QueryWrapper eq = new QueryWrapper().select("DISTINCT start_time,end_time").eq(!(null==courseId), "course_id", courseId).orderBy(true, true, "start_time"); - List list = courseLogService.list(eq); - List> timeList = new ArrayList<>(); - - int num = 1; - for (CourseLog courseLog : list) { - - Map mapTime = new HashMap(); - mapTime.put("index", num); - mapTime.put("name", courseLog.getStartTime() + "\\n" + courseLog.getEndTime()); - timeList.add(mapTime); -// temp.add(mapTime); - num++; - } - - List>> weeks = new ArrayList<>(); - - for (int i = 1; i <= 7; i++) { - List> courseName = new ArrayList<>(); -// -//// temp=timeList; -//// List> temp= new ArrayList<>(timeList); -// temp.addAll(timeList); - List> temp = new ArrayList<>(); - for (Map time : timeList) { - - Map map1= new HashMap(); - map1.put("index", time.get("index")); - map1.put("name", time.get("name")); - for (CourseLogVo courseLogVo : logList) { - int day = DateUtil.dayOfWeek(DateUtil.parse(courseLogVo.getStartDate())); - if (i == day) { - if (time.get("name").equals(courseLogVo.getStartTime() + "\\n" + courseLogVo.getEndTime())) { -// time.put("courseName",courseLogVo.getCourseNames()); - map1.put("courseName", courseLogVo.getCourseNames()); - } - System.out.println("i = " + i); - - } - - } - temp.add(map1); - - } - - weeks.add(temp); - - } - List index=new ArrayList<>(); - List>name = new ArrayList<>(); - for(List> item :weeks){ - ListitemList=new ArrayList<>(); - for(Map itemMap : item){ - if(StringUtils.isNotBlank((String)itemMap.get("courseName"))){ - itemList.add((String)itemMap.get("courseName")); - }else{ - itemList.add(""); - } - - } - name.add(itemList); - } - Map returnMap = new HashMap(); - returnMap.put("timeList", timeList); - returnMap.put("name", name); - return returnMap; - - - } - - /** - * 查询课程表内的课程 - * - * @param map - */ - public Map listLogDate1(Map map) { - //获取本周日期 - Integer courseId = (Integer) map.get("courseId"); - String end = (String) map.get("end"); - String start = (String) map.get("start"); - - //查询开始日期(start_date)在本周日期范围内的开课记录 - Map queryMap = new HashMap(); - queryMap.put("beginCreateTime", start); - queryMap.put("endCreateTime", end); - queryMap.put("courseType", "1"); - queryMap.put("courseId", courseId); - List logList = courseMapper.findLog1(queryMap); - - // 确定有几个时间段 通过上课时间 - QueryWrapper eq = new QueryWrapper().select("DISTINCT start_time,end_time").eq(!(null==courseId), "course_id", courseId) - .between("start_date",start,end) - .orderBy(true, true, "start_time"); - - List list = courseLogService.list(eq); - - //循环上课时间,加入index ,成为y轴 - List> timeList = new ArrayList<>(); - int num = 1; - for (CourseLog courseLog : list) { - Map mapTime = new HashMap(); - mapTime.put("index", num); - mapTime.put("name", courseLog.getStartTime() + "-" + courseLog.getEndTime()); - timeList.add(mapTime); - num++; - } - - //在本周填数据 - List>> weeks = new ArrayList<>(); - -//判断是否为会员 - if (ObjectUtil.isNotEmpty(map.get("userId"))){ - List memberUserList=getMembers( map.get("userId").toString()); - if (ObjectUtil.isNotEmpty(memberUserList)){ - for (int i = 1; i <= 7; i++) { - List> temp = new ArrayList<>(); - - //循环上课时间 - for (Map time : timeList) { - - Map map1= new HashMap(); - map1.put("index", time.get("index")); - map1.put("name", time.get("name")); - for (CourseLogVo courseLogVo : logList) { - int day = DateUtil.dayOfWeek(DateUtil.parse(courseLogVo.getStartDate())); - day=day-1==0?7:day-1; - if (i == day){ - if (time.get("name").equals(courseLogVo.getStartTime() + "-" + courseLogVo.getEndTime())) { - //判断会籍类型是否可以预约 - for (MemberUser memberUser:memberUserList){ - for (Object m:courseLogVo.getMembers()){ - if (memberUser.getMemberId()==Integer.parseInt(m.toString())){ - map1.put("courseName", "*"+courseLogVo.getCourseNames()+courseLogVo.getId()); - }else { - map1.put("courseName", courseLogVo.getCourseNames()+courseLogVo.getId()); - } - } - } - } - } - } - temp.add(map1); - } - weeks.add(temp); - } - }else { - for (int i = 1; i <= 7; i++) { - List> temp = new ArrayList<>(); - - //循环上课时间 - for (Map time : timeList) { - - Map map1= new HashMap(); - map1.put("index", time.get("index")); - map1.put("name", time.get("name")); - for (CourseLogVo courseLogVo : logList) { - int day = DateUtil.dayOfWeek(DateUtil.parse(courseLogVo.getStartDate())); - day=day-1==0?7:day-1; - if (i == day){ - if (time.get("name").equals(courseLogVo.getStartTime() + "-" + courseLogVo.getEndTime())) { - map1.put("courseName", courseLogVo.getCourseNames()+courseLogVo.getId()); - } - } - } - temp.add(map1); - } - weeks.add(temp); - } - } - }else { - for (int i = 1; i <= 7; i++) { - List> temp = new ArrayList<>(); - - //循环上课时间 - for (Map time : timeList) { - - Map map1= new HashMap(); - map1.put("index", time.get("index")); - map1.put("name", time.get("name")); - for (CourseLogVo courseLogVo : logList) { - int day = DateUtil.dayOfWeek(DateUtil.parse(courseLogVo.getStartDate())); - day=day-1==0?7:day-1; - if (i == day){ - if (time.get("name").equals(courseLogVo.getStartTime() + "-" + courseLogVo.getEndTime())) { - map1.put("courseName", courseLogVo.getCourseNames()+courseLogVo.getId()); - } - } - } - temp.add(map1); - } - weeks.add(temp); - } - } - -//将课程名称单拎出来 - List>name = new ArrayList<>(); - for(List> item :weeks){ - ListitemList=new ArrayList<>(); - for(Map itemMap : item){ - if(StrUtil.isNotBlank((String)itemMap.get("courseName"))){ - - itemList.add((String) itemMap.get("courseName")); - - }else{ - itemList.add(""); - } - } - name.add(itemList); - } - - Map returnMap = new HashMap(); - returnMap.put("timeList", timeList); - returnMap.put("name", name); - return returnMap; - - - } - - public List getMembers(String userId){ - List memberUserList= memberUserService.list(new QueryWrapper() - .select("member_id") - .eq("consumer_id",userId) - .last("and validity_time>now()")); - return memberUserList; - } - - public List listForApp(Course course){ - List list=courseMapper.listForApp(course); - return list; - } - - public Context getTeacherPhone(Integer logId){ - return courseMapper.getTeacherPhone(logId); - } - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/HistoryMessageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/HistoryMessageServiceImpl.java deleted file mode 100644 index 59b983a..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/service/HistoryMessageServiceImpl.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.ruoyi.course.service; - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.course.domain.HistoryMessage; -import com.ruoyi.course.mapper.HistoryMessageMapper; -import org.springframework.stereotype.Service; - -@Service -public class HistoryMessageServiceImpl extends ServiceImpl { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/MemberServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/MemberServiceImpl.java deleted file mode 100644 index b18edbd..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/course/service/MemberServiceImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ruoyi.course.service; - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.course.domain.Member; -import com.ruoyi.course.mapper.MemberMapper; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Map; - -/** - *

- * 服务实现类 - *

- * - * @author xhj - * @since 2022-09-23 - */ -@Service -public class MemberServiceImpl extends ServiceImpl { - - - public List getList(Map map){ - map.put("stroreId", SecurityUtils.getMerchanId()); - List list = baseMapper.findList(map); - return list; - } - -// public List getList(Member member){ -// List list = baseMapper.findList(member); -// return list; -// } - - public List findList(Member member){ - return baseMapper.findList(member); - } -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/ScClaTimeService.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/ScClaTimeService.java new file mode 100644 index 0000000..95efed5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/service/ScClaTimeService.java @@ -0,0 +1,11 @@ +package com.ruoyi.course.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.course.domain.ReqSearchClaTime; +import com.ruoyi.course.domain.ScClaTime; +import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar; +import com.ruoyi.mall.domain.ProductCategory; + +public interface ScClaTimeService extends IService { + RespBusinessClaTimeCalendar searchListForCalendar(ReqSearchClaTime reqSearchClaTime); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/impl/ContextServicelmpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/impl/ContextServicelmpl.java new file mode 100644 index 0000000..7b0248e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/service/impl/ContextServicelmpl.java @@ -0,0 +1,41 @@ +package com.ruoyi.course.service.impl; + +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.course.domain.Context; +import com.ruoyi.course.domain.ReqSearchClaTime; +import com.ruoyi.course.domain.RespClaTimeCalendar; +import com.ruoyi.course.domain.time.ClaTimeCalendarItem; +import com.ruoyi.course.domain.time.ClaTimeColumnTitle; +import com.ruoyi.course.domain.time.ClaTimeContainer; +import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar; +import com.ruoyi.course.mapper.ContextMapper; +import com.ruoyi.course.mapper.ScClaTimeMapper; +import org.apache.commons.compress.utils.Lists; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class ContextServicelmpl extends ServiceImpl { + + + + public List getList(Map map){ + List list = baseMapper.findList(map); + return list; + } + + public Context getOne(Map map){ + Context context = baseMapper.getOne(map); + return context; + } + + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/course/service/impl/ScClaTimeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/course/service/impl/ScClaTimeServiceImpl.java new file mode 100644 index 0000000..de1668b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/course/service/impl/ScClaTimeServiceImpl.java @@ -0,0 +1,138 @@ +package com.ruoyi.course.service.impl; + +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.course.domain.ReqSearchClaTime; +import com.ruoyi.course.domain.RespClaTimeCalendar; +import com.ruoyi.course.domain.ScClaTime; +import com.ruoyi.course.domain.time.ClaTimeCalendarItem; +import com.ruoyi.course.domain.time.ClaTimeColumnTitle; +import com.ruoyi.course.domain.time.ClaTimeContainer; +import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar; +import com.ruoyi.course.mapper.ScClaTimeMapper; +import com.ruoyi.course.service.ScClaTimeService; +import com.ruoyi.mall.domain.ProductCategory; +import com.ruoyi.mall.mapper.ProductCategoryMapper; +import com.ruoyi.mall.service.ProductCategoryService; +import org.apache.commons.compress.utils.Lists; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; +@Service +public class ScClaTimeServiceImpl extends ServiceImpl implements ScClaTimeService { + + @Autowired + private ScClaTimeMapper claTimeMapper; + /** + * 按周获取课表 + * @return + */ + @Override + public RespBusinessClaTimeCalendar searchListForCalendar(ReqSearchClaTime reqSearchClaTime) { + + Date cycleBegin = new Date();//开始时间 + Date cycleEnd = DateUtil.offsetDay(cycleBegin,14);//结束时间 +// reqSearchClaTime.setBeginDate(DateUtil.format(cycleBegin,"yyyy-MM-dd")); +// reqSearchClaTime.setEndDate(DateUtil.format(cycleEnd,"yyyy-MM-dd")); + List dateList=DateUtil.rangeToList(cycleBegin + , cycleEnd + , DateField.DAY_OF_YEAR); + //todo 表頭list + // time 07-17l + +// // 日历数据 格式为:时间->星期->课程 + Map>> claTimeCalendarMap = new HashMap(); + Constants.CLA_TIME_MAP.forEach((claTimeKey, claTimeValue) -> { + Map> weekDayMap = new HashMap(); + for (int i = 0; i < dateList.size(); i++) { + List claTimeArrayList = Lists.newArrayList(); + weekDayMap.put(i+1, claTimeArrayList); + } + claTimeCalendarMap.put(claTimeKey, weekDayMap); + }); + + // 获取排课信息 + List respClaTimeList = claTimeMapper.selectListForCalendar(reqSearchClaTime); + + // 将排课信息 入到 claTimeCalendarMap + respClaTimeList.forEach(item -> { + Integer weekDay = item.getWeekDay(); + Integer startHour = item.getStartHour(); + + if (claTimeCalendarMap.containsKey(startHour)) { + claTimeCalendarMap.get(startHour).get(weekDay).add(item); + } else if (claTimeCalendarMap.containsKey(startHour - 1)) { + // 每两个小时 一个上课时段,所以-1 + claTimeCalendarMap.get(startHour - 1).get(weekDay).add(item); + } + }); + + + RespBusinessClaTimeCalendar timeCalendar = new RespBusinessClaTimeCalendar(); + // 每行数据 + List claTimeContainerList = Lists.newArrayList(); + // 星期排课数量 + Map columnTitleTimeCountMap = new HashMap(); + + // 每行数据 + claTimeCalendarMap.forEach((claTimeKey, claTimeMap) -> { + ClaTimeContainer claTimeContainer = new ClaTimeContainer(); + claTimeContainer.setTime(Constants.CLA_TIME_MAP.get(claTimeKey)); + + Map> claTimeWeekDayMap = new HashMap(); + claTimeMap.forEach((weekDayKey, list) -> { + + // 排课数量 + if (columnTitleTimeCountMap.containsKey(weekDayKey)) { + columnTitleTimeCountMap.put(weekDayKey, columnTitleTimeCountMap.get(weekDayKey) + list.size()); + } else { + columnTitleTimeCountMap.put(weekDayKey, list.size()); + } + + List timeItemList = list.stream().map(item -> { + ClaTimeCalendarItem claTimeItem = new ClaTimeCalendarItem(); + claTimeItem.transfer(item); + return claTimeItem; + }).collect(Collectors.toList()); + claTimeWeekDayMap.put(weekDayKey, timeItemList); + }); + claTimeContainer.setClaTimeWeekDayMap(claTimeWeekDayMap); + claTimeContainerList.add(claTimeContainer); + }); + Collections.sort(claTimeContainerList, (o1, o2) -> { + int a = Integer.parseInt(o1.getTime().substring(0, 2)); + int b = Integer.parseInt(o2.getTime().substring(0, 2)); + if (a > b) { + return 1; + } else if (a < b) { + return -1; + } else { + return 0; + } + }); + timeCalendar.setClaTimeContainer(claTimeContainerList); + + + // 标题 + List columnTitles = Lists.newArrayList(); + while (cycleBegin.before(cycleEnd)) { + int dayOfWeek = DateUtil.dayOfWeek(cycleBegin); + + ClaTimeColumnTitle claTimeColumnTitle = new ClaTimeColumnTitle(); + claTimeColumnTitle.setWeekName(Constants.WEEK_DAY_MAP.get(dayOfWeek)); + claTimeColumnTitle.setDay(DateUtil.format(cycleBegin,"MM-dd")); + claTimeColumnTitle.setCount(columnTitleTimeCountMap.get(dayOfWeek)); + + columnTitles.add(claTimeColumnTitle); + cycleBegin = DateUtil.offsetDay(cycleBegin,1); + } + timeCalendar.setColumnTitles(columnTitles); + + return timeCalendar; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/FileInfo.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/FileInfo.java new file mode 100644 index 0000000..119cb00 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/FileInfo.java @@ -0,0 +1,67 @@ +package com.ruoyi.im.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * @author Blue + * @version 1.0 + */ +@Data +@TableName("im_file_info") +public class FileInfo { + + /** + * 文件ID + */ + @TableId + private Long id; + + /** + * 文件名 + */ + private String fileName; + + /** + * 原始文件存储路径 + */ + private String filePath; + + /** + * 压缩文件存储路径 + */ + private String compressedPath; + + /** + * 封面文件路径 + */ + private String coverPath; + + /** + * 原始文件大小(字节) + */ + private Long fileSize; + + /** + * 上传时间 + */ + private Date uploadTime; + + /** + * 文件类型,枚举: FileType + */ + private Integer fileType; + + /** + * 是否永久存储 + */ + private Boolean isPermanent; + + /** + * 文件MD5哈希值 + */ + private String md5; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/Friend.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/Friend.java new file mode 100644 index 0000000..2ab6d56 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/Friend.java @@ -0,0 +1,58 @@ +package com.ruoyi.im.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * 好友 + *

+ * + * @author blue + * @since 2022-10-22 + */ +@Data +@TableName("im_friend") +public class Friend { + + + /** + * id + */ + @TableId + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 好友id + */ + private Long friendId; + + /** + * 用户昵称 + */ + private String friendNickName; + + /** + * 用户头像 + */ + private String friendHeadImage; + + /** + * 是否已删除 + */ + private Boolean deleted; + + /** + * 创建时间 + */ + private Date createdTime; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/PrivateMessage.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/PrivateMessage.java new file mode 100644 index 0000000..75b5fc3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/PrivateMessage.java @@ -0,0 +1,57 @@ +package com.ruoyi.im.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * + *

+ * + * @author blue + * @since 2022-10-01 + */ +@Data +@TableName("im_private_message") +public class PrivateMessage { + + /** + * id + */ + private Long id; + + /** + * 发送用户id + */ + private Long sendId; + + /** + * 接收用户id + */ + private Long recvId; + + /** + * 发送内容 + */ + private String content; + + /** + * 消息类型 MessageType + */ + private Integer type; + + /** + * 状态 + */ + private Integer status; + + + /** + * 发送时间 + */ + private Date sendTime; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/SensitiveWord.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/SensitiveWord.java new file mode 100644 index 0000000..f3d5a98 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/SensitiveWord.java @@ -0,0 +1,50 @@ +package com.ruoyi.im.domain; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 敏感词 + * + * @author Blue + * @since 1.0.0 2024-07-20 + */ + +@Data +@TableName("im_sensitive_word") +public class SensitiveWord { + /** + * id + */ + @TableId + private Long id; + + /** + * 敏感词内容 + */ + private String content; + + /** + * 是否启用 + */ + private Boolean enabled; + + /** + * 创建者 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/dto/PrivateMessageDTO.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/dto/PrivateMessageDTO.java new file mode 100644 index 0000000..5bbd703 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/dto/PrivateMessageDTO.java @@ -0,0 +1,29 @@ +package com.ruoyi.im.domain.dto; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +@Schema(description = "私聊消息DTO") +public class PrivateMessageDTO { + + @NotNull(message = "接收用户id不可为空") + @Schema(description = "接收用户id") + private Long recvId; + + + @Length(max = 1024, message = "内容长度不得大于1024") + @NotEmpty(message = "发送内容不可为空") + @Schema(description = "发送内容") + private String content; + + @NotNull(message = "消息类型不可为空") + @Schema(description = "消息类型 0:文字 1:图片 2:文件 3:语音 4:视频") + private Integer type; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/FriendVO.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/FriendVO.java new file mode 100644 index 0000000..d98e14d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/FriendVO.java @@ -0,0 +1,26 @@ +package com.ruoyi.im.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +@Schema(description = "好友信息VO") +public class FriendVO { + + @NotNull(message = "好友id不可为空") + @Schema(description = "好友id") + private Long id; + + @NotNull(message = "好友昵称不可为空") + @Schema(description = "好友昵称") + private String nickName; + + + @Schema(description = "好友头像") + private String headImage; + + @Schema(description = "是否已删除") + private Boolean deleted; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/PrivateMessageVO.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/PrivateMessageVO.java new file mode 100644 index 0000000..5cbd71f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/PrivateMessageVO.java @@ -0,0 +1,36 @@ +package com.ruoyi.im.domain.vo; + + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.ruoyi.common.serializer.DateToLongSerializer; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Data +@Schema(description = "私聊消息VO") +public class PrivateMessageVO { + + @Schema(description = " 消息id") + private Long id; + + @Schema(description = " 发送者id") + private Long sendId; + + @Schema(description = " 接收者id") + private Long recvId; + + @Schema(description = " 发送内容") + private String content; + + @Schema(description = "消息内容类型 MessageType") + private Integer type; + + @Schema(description = " 状态") + private Integer status; + + @Schema(description = " 发送时间") + @JsonSerialize(using = DateToLongSerializer.class) + private Date sendTime; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/SystemConfigVO.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/SystemConfigVO.java new file mode 100644 index 0000000..8c01fcd --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/SystemConfigVO.java @@ -0,0 +1,21 @@ +package com.ruoyi.im.domain.vo; + +import com.ruoyi.common.config.WebrtcConfig; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author: blue + * @date: 2024-06-10 + * @version: 1.0 + */ +@Data +@Schema(description = "系统配置VO") +@AllArgsConstructor +public class SystemConfigVO { + + @Schema(description = "webrtc配置") + private WebrtcConfig webrtc; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/UploadImageVO.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/UploadImageVO.java new file mode 100644 index 0000000..bb7f3aa --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/UploadImageVO.java @@ -0,0 +1,15 @@ +package com.ruoyi.im.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "图片上传VO") +public class UploadImageVO { + + @Schema(description = "原图") + private String originUrl; + + @Schema(description = "缩略图") + private String thumbUrl; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/UserVO.java b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/UserVO.java new file mode 100644 index 0000000..38b47b5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/domain/vo/UserVO.java @@ -0,0 +1,52 @@ +package com.ruoyi.im.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +@Schema(description = "用户信息VO") +public class UserVO { + + @NotNull(message = "用户id不能为空") + @Schema(description = "id") + private Long id; + + @NotEmpty(message = "用户名不能为空") + @Length(max = 20, message = "用户名不能大于20字符") + @Schema(description = "用户名") + private String userName; + + @NotEmpty(message = "用户昵称不能为空") + @Length(max = 20, message = "昵称不能大于20字符") + @Schema(description = "用户昵称") + private String nickName; + + @Schema(description = "性别") + private Integer sex; + + @Schema(description = "用户类型 1:普通用户 2:审核账户") + private Integer type; + + @Length(max = 128, message = "个性签名不能大于128个字符") + @Schema(description = "个性签名") + private String signature; + + @Schema(description = "头像") + private String headImage; + + @Schema(description = "头像缩略图") + private String headImageThumb; + + @Schema(description = "是否在线") + private Boolean online; + + @Schema(description = "账号是否被封禁") + private Boolean isBanned; + + @Schema(description = "被封禁原因") + private String reason; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/mapper/FileInfoMapper.java b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/FileInfoMapper.java new file mode 100644 index 0000000..22228cb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/FileInfoMapper.java @@ -0,0 +1,9 @@ +package com.ruoyi.im.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.im.domain.FileInfo; + +public interface FileInfoMapper extends BaseMapper { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/mapper/FriendMapper.java b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/FriendMapper.java new file mode 100644 index 0000000..ebef85e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/FriendMapper.java @@ -0,0 +1,8 @@ +package com.ruoyi.im.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.im.domain.Friend; + +public interface FriendMapper extends BaseMapper { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/mapper/PrivateMessageMapper.java b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/PrivateMessageMapper.java new file mode 100644 index 0000000..cf0eb5b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/PrivateMessageMapper.java @@ -0,0 +1,9 @@ +package com.ruoyi.im.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.im.domain.PrivateMessage; + +public interface PrivateMessageMapper extends BaseMapper { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/mapper/SensitiveWordMapper.java b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/SensitiveWordMapper.java new file mode 100644 index 0000000..ab2084c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/mapper/SensitiveWordMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.im.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.im.domain.SensitiveWord; +import org.apache.ibatis.annotations.Mapper; + +/** +* 敏感词 +* +* @author Blue +* @since 1.0.0 2024-07-20 +*/ +@Mapper +public interface SensitiveWordMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/minioConfig/MinIoClientConfig.java b/ruoyi-system/src/main/java/com/ruoyi/im/minioConfig/MinIoClientConfig.java new file mode 100644 index 0000000..7d82a4e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/minioConfig/MinIoClientConfig.java @@ -0,0 +1,22 @@ +package com.ruoyi.im.minioConfig; + +import com.ruoyi.im.props.MinioProperties; +import io.minio.MinioClient; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.Resource; + +@Configuration +public class MinIoClientConfig { + + @Bean + public MinioClient minioClient(MinioProperties minioProps) { + // 注入minio 客户端 + return MinioClient.builder() + .endpoint(minioProps.getEndpoint()) + .credentials(minioProps.getAccessKey(), minioProps.getSecretKey()) + .build(); + } +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/props/MinioProperties.java b/ruoyi-system/src/main/java/com/ruoyi/im/props/MinioProperties.java new file mode 100644 index 0000000..607e8a9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/props/MinioProperties.java @@ -0,0 +1,34 @@ +package com.ruoyi.im.props; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author: Blue + * @date: 2024-09-28 + * @version: 1.0 + */ +@Data +@Component +@ConfigurationProperties(prefix = "minio") +public class MinioProperties { + + private String endpoint; + + private String accessKey; + + private String secretKey; + + private String domain; + + private String bucketName; + + private String imagePath; + + private String filePath; + + private String videoPath; + + private Integer expireIn; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/FileService.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/FileService.java new file mode 100644 index 0000000..1e24562 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/FileService.java @@ -0,0 +1,16 @@ +package com.ruoyi.im.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.im.domain.FileInfo; +import com.ruoyi.im.domain.vo.UploadImageVO; +import org.springframework.web.multipart.MultipartFile; + +public interface FileService extends IService { + + String uploadFile(MultipartFile file); + + UploadImageVO uploadImage(MultipartFile file, Boolean isPermanent); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/FriendService.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/FriendService.java new file mode 100644 index 0000000..e1fb77b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/FriendService.java @@ -0,0 +1,74 @@ +package com.ruoyi.im.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.im.domain.Friend; +import com.ruoyi.im.domain.vo.FriendVO; + +import java.util.List; + +public interface FriendService extends IService { + + /** + * 判断用户2是否用户1的好友 + * + * @param userId1 用户1的id + * @param userId2 用户2的id + * @return true/false + */ + Boolean isFriend(Long userId1, Long userId2); + + /** + * 查询用户的所有好友,包括已删除的 + * + * @return 好友列表 + */ + List findAllFriends(); + + /** + * 查询用户的所有好友 + * + * @param friendIds 好友id + * @return 好友列表 + */ + List findByFriendIds(List friendIds); + + /** + * 查询当前用户的所有好友 + * + * @return 好友列表 + */ + List findFriends(); + + /** + * 添加好友,互相建立好友关系 + * + * @param friendId 好友的用户id + */ + void addFriend(Long friendId); + + /** + * 删除好友,双方都会解除好友关系 + * + * @param friendId 好友的用户id + */ + void delFriend(Long friendId); + + /** + * 查询指定的某个好友信息 + * + * @param friendId 好友的用户id + * @return 好友信息 + */ + FriendVO findFriend(Long friendId); + + /** + * 绑定好友关系 + * + * @param userId 好友的id + * @param friendId 好友的用户id + * @return 好友信息 + */ + void bindFriend(Long userId, Long friendId); + + +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/PrivateMessageService.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/PrivateMessageService.java new file mode 100644 index 0000000..0397a84 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/PrivateMessageService.java @@ -0,0 +1,62 @@ +package com.ruoyi.im.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.im.domain.PrivateMessage; +import com.ruoyi.im.domain.dto.PrivateMessageDTO; +import com.ruoyi.im.domain.vo.PrivateMessageVO; + +import java.util.List; + +public interface PrivateMessageService extends IService { + + + /** + * 发送私聊消息(高并发接口,查询mysql接口都要进行缓存) + * + * @param dto 私聊消息 + * @return 消息id + */ + PrivateMessageVO sendMessage(PrivateMessageDTO dto); + + + /** + * 撤回消息 + * + * @param id 消息id + */ + PrivateMessageVO recallMessage(Long id); + + /** + * 拉取历史聊天记录 + * + * @param friendId 好友id + * @param page 页码 + * @param size 页码大小 + * @return 聊天记录列表 + */ + List findHistoryMessage(Long friendId, Long page, Long size); + + + /** + * 拉取离线消息,只能拉取最近1个月的消息,最多拉取1000条 + * + * @param minId 消息起始id + */ + void pullOfflineMessage(Long minId); + + /** + * 消息已读,将整个会话的消息都置为已读状态 + * + * @param friendId 好友id + */ + void readedMessage(Long friendId); + + /** + * 获取某个会话中已读消息的最大id + * + * @param friendId 好友id + */ + Long getMaxReadedId(Long friendId); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/SensitiveWordService.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/SensitiveWordService.java new file mode 100644 index 0000000..c660521 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/SensitiveWordService.java @@ -0,0 +1,16 @@ +package com.ruoyi.im.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.im.domain.SensitiveWord; + +import java.util.List; + +public interface SensitiveWordService extends IService { + + /** + * 查询所有开启的敏感词 + * @return + */ + List findAllEnabledWords(); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/WebrtcPrivateService.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/WebrtcPrivateService.java new file mode 100644 index 0000000..6c130a7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/WebrtcPrivateService.java @@ -0,0 +1,26 @@ +package com.ruoyi.im.service; + +/** + * webrtc 通信服务 + * + * @author + */ +public interface WebrtcPrivateService { + + void call(Long uid, String mode,String offer); + + void accept(Long uid, String answer); + + void reject(Long uid); + + void cancel(Long uid); + + void failed(Long uid, String reason); + + void handup(Long uid); + + void candidate(Long uid, String candidate); + + void heartbeat(Long uid); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/FileServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..1fe0543 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/FileServiceImpl.java @@ -0,0 +1,194 @@ +package com.ruoyi.im.service.impl; + + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.im.constant.Constant_im; +import com.ruoyi.common.im.enums.FileType; +import com.ruoyi.common.im.enums.ResultCode; +import com.ruoyi.im.util.FileUtil; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.im.domain.FileInfo; +import com.ruoyi.im.domain.vo.UploadImageVO; +import com.ruoyi.im.mapper.FileInfoMapper; +import com.ruoyi.im.props.MinioProperties; +import com.ruoyi.im.service.FileService; +import com.ruoyi.im.thirdparty.MinioService; +import com.ruoyi.im.util.ImageUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.DigestUtils; +import org.springframework.web.multipart.MultipartFile; +import org.apache.commons.lang3.StringUtils; +import java.util.Date; +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.util.Objects; + +/** + * 文件上传服务 + * + * author: Blue date: 2024-09-28 version: 1.0 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class FileServiceImpl extends ServiceImpl implements FileService { + + private final MinioService minioSerivce; + + private final MinioProperties minioProps; + + @PostConstruct + public void init() { + if (!minioSerivce.bucketExists(minioProps.getBucketName())) { + // 创建bucket + minioSerivce.makeBucket(minioProps.getBucketName()); + // 公开bucket + minioSerivce.setBucketPublic(minioProps.getBucketName()); + } + } + + @Override + public String uploadFile(MultipartFile file) { + try { + Long userId = SecurityUtils.getUserId(); + // 大小校验 + if (file.getSize() > Constant_im.MAX_FILE_SIZE) { + throw new GlobalException(ResultCode.PROGRAM_ERROR, "文件大小不能超过20M"); + } + // 如果文件已存在,直接复用 + String md5 = DigestUtils.md5DigestAsHex(file.getInputStream()); + FileInfo fileInfo = findByMd5(md5); + if (!Objects.isNull(fileInfo)) { + // 更新上传时间 + fileInfo.setUploadTime(new Date()); + this.updateById(fileInfo); + // 返回 + return fileInfo.getFilePath(); + } + // 上传 + String fileName = minioSerivce.upload(minioProps.getBucketName(), minioProps.getFilePath(), file); + if (StringUtils.isEmpty(fileName)) { + throw new GlobalException(ResultCode.PROGRAM_ERROR, "文件上传失败"); + } + String url = generUrl(FileType.FILE, fileName); + // 保存文件 + saveFileInfo(file, md5, url); + log.info("文件文件成功,用户id:{},url:{}", userId, url); + return url; + } catch (IOException e) { + log.error("上传图片失败,{}", e.getMessage(), e); + throw new GlobalException(ResultCode.PROGRAM_ERROR, "上传图片失败"); + } + } + + @Transactional + @Override + public UploadImageVO uploadImage(MultipartFile file, Boolean isPermanent) { + try { + Long userId = SecurityUtils.getUserId(); + // 大小校验 + if (file.getSize() > Constant_im.MAX_IMAGE_SIZE) { + throw new GlobalException(ResultCode.PROGRAM_ERROR, "图片大小不能超过20M"); + } + // 图片格式校验 + if (!FileUtil.isImage(file.getOriginalFilename())) { + throw new GlobalException(ResultCode.PROGRAM_ERROR, "图片格式不合法"); + } + UploadImageVO vo = new UploadImageVO(); + // 如果文件已存在,直接复用 + String md5 = DigestUtils.md5DigestAsHex(file.getInputStream()); + FileInfo fileInfo = findByMd5(md5); + if (!Objects.isNull(fileInfo)) { + // 更新上传时间和持久化标记 + fileInfo.setIsPermanent(isPermanent || fileInfo.getIsPermanent()); + fileInfo.setUploadTime(new Date()); + this.updateById(fileInfo); + // 返回 + vo.setOriginUrl(fileInfo.getFilePath()); + vo.setThumbUrl(fileInfo.getCompressedPath()); + return vo; + } + // 上传原图 + String fileName = minioSerivce.upload(minioProps.getBucketName(), minioProps.getImagePath(), file); + if (StringUtils.isEmpty(fileName)) { + throw new GlobalException(ResultCode.PROGRAM_ERROR, "图片上传失败"); + } + vo.setOriginUrl(generUrl(FileType.IMAGE, fileName)); + if (file.getSize() > 50 * 1024) { + // 大于50K的文件需上传缩略图 + byte[] imageByte = ImageUtil.compressForScale(file.getBytes(), 30); + String thumbFileName = minioSerivce.upload(minioProps.getBucketName(), minioProps.getImagePath(), + file.getOriginalFilename(), imageByte, file.getContentType()); + if (StringUtils.isEmpty(thumbFileName)) { + throw new GlobalException(ResultCode.PROGRAM_ERROR, "图片上传失败"); + } + vo.setThumbUrl(generUrl(FileType.IMAGE, thumbFileName)); + // 保存文件信息 + saveImageFileInfo(file, md5, vo.getOriginUrl(), vo.getThumbUrl(), isPermanent); + }else{ + // 小于50k,用原图充当缩略图 + vo.setThumbUrl(generUrl(FileType.IMAGE, fileName)); + // 保存文件信息,由于缩略图不允许删除,此时原图也不允许删除 + saveImageFileInfo(file, md5, vo.getOriginUrl(), vo.getThumbUrl(), true); + } + log.info("文件图片成功,用户id:{},url:{}", userId, vo.getOriginUrl()); + return vo; + } catch (IOException e) { + log.error("上传图片失败,{}", e.getMessage(), e); + throw new GlobalException(ResultCode.PROGRAM_ERROR, "图片上传失败"); + } + } + + private String generUrl(FileType fileType, String fileName) { + return StrUtil.join("/", minioProps.getDomain(), minioProps.getBucketName(), getBucketPath(fileType), fileName); + } + + private String getBucketPath(FileType fileType) { + switch (fileType) { + case FILE : return minioProps.getFilePath(); + case IMAGE : return minioProps.getImagePath(); + case VIDEO : return minioProps.getVideoPath(); + default:return null; + } + } + + private FileInfo findByMd5(String md5) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(FileInfo::getMd5, md5); + return getOne(wrapper); + } + + private void saveImageFileInfo(MultipartFile file, String md5, String filePath, String compressedPath, + Boolean isPermanent) throws IOException { + FileInfo fileInfo = new FileInfo(); + fileInfo.setFileName(file.getOriginalFilename()); + fileInfo.setFileSize(file.getSize()); + fileInfo.setFileType(FileType.IMAGE.code()); + fileInfo.setFilePath(filePath); + fileInfo.setCompressedPath(compressedPath); + fileInfo.setMd5(md5); + fileInfo.setIsPermanent(isPermanent); + fileInfo.setUploadTime(new Date()); + this.save(fileInfo); + } + + private void saveFileInfo(MultipartFile file, String md5, String filePath) throws IOException { + FileInfo fileInfo = new FileInfo(); + fileInfo.setFileName(file.getOriginalFilename()); + fileInfo.setFileSize(file.getSize()); + fileInfo.setFileType(FileType.FILE.code()); + fileInfo.setFilePath(filePath); + fileInfo.setMd5(md5); + fileInfo.setIsPermanent(false); + fileInfo.setUploadTime(new Date()); + this.save(fileInfo); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/FriendServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/FriendServiceImpl.java new file mode 100644 index 0000000..3d1659f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/FriendServiceImpl.java @@ -0,0 +1,245 @@ +package com.ruoyi.im.service.impl; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.im.constant.RedisKey; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.im.domain.Friend; +import com.ruoyi.im.domain.vo.FriendVO; +import com.ruoyi.im.service.FriendService; +import com.ruoyi.im.mapper.PrivateMessageMapper; +import com.ruoyi.im.mapper.FriendMapper; +import com.ruoyi.imclient.IMClient; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.framework.AopContext; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = RedisKey.IM_CACHE_FRIEND) +public class FriendServiceImpl extends ServiceImpl implements FriendService { + private final PrivateMessageMapper privateMessageMapper; +// private final UserMapper userMapper; + private final IMClient imClient; + + @Override + public List findAllFriends() { + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(Friend::getUserId, userId); + return this.list(wrapper); + } + + @Override + public List findByFriendIds(List friendIds) { + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(Friend::getUserId, userId); + wrapper.in(Friend::getFriendId, friendIds); + wrapper.eq(Friend::getDeleted,false); + return this.list(wrapper); + } + + @Override + public List findFriends() { + List friends = this.findAllFriends(); + return friends.stream().map(this::conver).collect(Collectors.toList()); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void addFriend(Long friendId) { + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); + if (friendId.equals(userId)) { + throw new GlobalException("不允许添加自己为好友"); + } + // 互相绑定好友关系 + FriendServiceImpl proxy = (FriendServiceImpl)AopContext.currentProxy(); + proxy.bindFriend(userId, friendId); + proxy.bindFriend(friendId, userId); + // 推送添加好友提示 + sendAddTipMessage(friendId); + log.info("添加好友,用户id:{},好友id:{}", userId, friendId); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delFriend(Long friendId) { + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); + // 互相解除好友关系,走代理清理缓存 + FriendServiceImpl proxy = (FriendServiceImpl)AopContext.currentProxy(); + proxy.unbindFriend(userId, friendId); + proxy.unbindFriend(friendId, userId); + // 推送解除好友提示 + sendDelTipMessage(friendId); + log.info("删除好友,用户id:{},好友id:{}", userId, friendId); + } + + @Cacheable(key = "#userId1+':'+#userId2") + @Override + public Boolean isFriend(Long userId1, Long userId2) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(Friend::getUserId, userId1); + wrapper.eq(Friend::getFriendId, userId2); + wrapper.eq(Friend::getDeleted,false); + + return this.count(wrapper)==0l?false:true; + } + + /** + * 单向绑定好友关系 + * + * @param userId 用户id + * @param friendId 好友的用户id + */ + @CacheEvict(key = "#userId+':'+#friendId") + public void bindFriend(Long userId, Long friendId) { +// QueryWrapper wrapper = new QueryWrapper<>(); +// wrapper.lambda().eq(Friend::getUserId, userId).eq(Friend::getFriendId, friendId); +// Friend friend = this.getOne(wrapper); +// if (Objects.isNull(friend)) { +// friend = new Friend(); +// } +// friend.setUserId(userId); +// friend.setFriendId(friendId); +// User friendInfo = userMapper.selectById(friendId); +// friend.setFriendHeadImage(friendInfo.getHeadImage()); +// friend.setFriendNickName(friendInfo.getNickName()); +// friend.setDeleted(false); +// this.saveOrUpdate(friend); +// // 推送好友变化信息s +// sendAddFriendMessage(userId, friendId, friend); + } + + /** + * 单向解除好友关系 + * + * @param userId 用户id + * @param friendId 好友的用户id + */ + @CacheEvict(key = "#userId+':'+#friendId") + public void unbindFriend(Long userId, Long friendId) { + // 逻辑删除 + LambdaUpdateWrapper wrapper = Wrappers.lambdaUpdate(); + wrapper.eq(Friend::getUserId, userId); + wrapper.eq(Friend::getFriendId, friendId); + wrapper.set(Friend::getDeleted,true); + this.update(wrapper); + // 推送好友变化信息 + sendDelFriendMessage(userId, friendId); + } + + @Override + public FriendVO findFriend(Long friendId) { + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(Friend::getUserId, userId); + wrapper.eq(Friend::getFriendId, friendId); + Friend friend = this.getOne(wrapper); + if (Objects.isNull(friend)) { + throw new GlobalException("对方不是您的好友"); + } + return conver(friend); + } + + private FriendVO conver(Friend f) { + FriendVO vo = new FriendVO(); + vo.setId(f.getFriendId()); + vo.setHeadImage(f.getFriendHeadImage()); + vo.setNickName(f.getFriendNickName()); + vo.setDeleted(f.getDeleted()); + return vo; + } + + void sendAddFriendMessage(Long userId, Long friendId, Friend friend) { + // 推送好友状态信息 +// PrivateMessageVO msgInfo = new PrivateMessageVO(); +// msgInfo.setSendId(friendId); +// msgInfo.setRecvId(userId); +// msgInfo.setSendTime(new Date()); +// msgInfo.setType(MessageType.FRIEND_NEW.code()); +// FriendVO vo = conver(friend); +// msgInfo.setContent(JSON.toJSONString(vo)); +// IMPrivateMessage sendMessage = new IMPrivateMessage<>(); +// sendMessage.setSender(new IMUserInfo(friendId, IMTerminalType.UNKNOW.code())); +// sendMessage.setRecvId(userId); +// sendMessage.setData(msgInfo); +// sendMessage.setSendToSelf(false); +// sendMessage.setSendResult(false); +// imClient.sendPrivateMessage(sendMessage); + } + + void sendDelFriendMessage(Long userId, Long friendId) { + // 推送好友状态信息 +// PrivateMessageVO msgInfo = new PrivateMessageVO(); +// msgInfo.setSendId(friendId); +// msgInfo.setRecvId(userId); +// msgInfo.setSendTime(new Date()); +// msgInfo.setType(MessageType.FRIEND_DEL.code()); +// IMPrivateMessage sendMessage = new IMPrivateMessage<>(); +// sendMessage.setSender(new IMUserInfo(friendId, IMTerminalType.UNKNOW.code())); +// sendMessage.setRecvId(userId); +// sendMessage.setData(msgInfo); +// sendMessage.setSendToSelf(false); +// sendMessage.setSendResult(false); +// imClient.sendPrivateMessage(sendMessage); + } + + void sendAddTipMessage(Long friendId) { +// UserSession session = SessionContext.getSession(); +// PrivateMessage msg = new PrivateMessage(); +// msg.setSendId(session.getUserId()); +// msg.setRecvId(friendId); +// msg.setContent("你们已成为好友,现在可以开始聊天了"); +// msg.setSendTime(new Date()); +// msg.setStatus(MessageStatus.UNSEND.code()); +// msg.setType(MessageType.TIP_TEXT.code()); +// privateMessageMapper.insert(msg); +// // 推给对方 +// PrivateMessageVO messageInfo = BeanUtils.copyProperties(msg, PrivateMessageVO.class); +// IMPrivateMessage sendMessage = new IMPrivateMessage<>(); +// sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal())); +// sendMessage.setRecvId(friendId); +// sendMessage.setSendToSelf(false); +// sendMessage.setData(messageInfo); +// imClient.sendPrivateMessage(sendMessage); +// // 推给自己 +// sendMessage.setRecvId(session.getUserId()); +// imClient.sendPrivateMessage(sendMessage); + } + + void sendDelTipMessage(Long friendId){ +// UserSession session = SessionContext.getSession(); +// // 推送好友状态信息 +// PrivateMessage msg = new PrivateMessage(); +// msg.setSendId(session.getUserId()); +// msg.setRecvId(friendId); +// msg.setSendTime(new Date()); +// msg.setType(MessageType.TIP_TEXT.code()); +// msg.setStatus(MessageStatus.UNSEND.code()); +// msg.setContent("你们的好友关系已被解除"); +// privateMessageMapper.insert(msg); +// // 推送 +// PrivateMessageVO messageInfo = BeanUtils.copyProperties(msg, PrivateMessageVO.class); +// IMPrivateMessage sendMessage = new IMPrivateMessage<>(); +// sendMessage.setSender(new IMUserInfo(friendId, IMTerminalType.UNKNOW.code())); +// sendMessage.setRecvId(friendId); +// sendMessage.setData(messageInfo); +// imClient.sendPrivateMessage(sendMessage); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/PrivateMessageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/PrivateMessageServiceImpl.java new file mode 100644 index 0000000..17e7b91 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/PrivateMessageServiceImpl.java @@ -0,0 +1,245 @@ +package com.ruoyi.im.service.impl; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.domain.entity.AppUser; +import com.ruoyi.common.im.constant.IMConstant; +import com.ruoyi.common.im.enums.IMTerminalType; +import com.ruoyi.common.im.model.IMPrivateMessage; +import com.ruoyi.common.im.model.IMUserInfo; +import com.ruoyi.common.im.enums.MessageStatus; +import com.ruoyi.common.im.enums.MessageType; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.im.util.BeanUtils; +import com.ruoyi.common.im.util.ThreadPoolExecutorFactory; +import com.ruoyi.im.domain.PrivateMessage; +import com.ruoyi.im.domain.dto.PrivateMessageDTO; +import com.ruoyi.im.domain.vo.PrivateMessageVO; +import com.ruoyi.im.mapper.PrivateMessageMapper; +import com.ruoyi.im.service.FriendService; +import com.ruoyi.im.service.PrivateMessageService; +import com.ruoyi.im.util.SensitiveFilterUtil; +import com.ruoyi.imclient.IMClient; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class PrivateMessageServiceImpl extends ServiceImpl + implements PrivateMessageService { + + private final FriendService friendService; + private final IMClient imClient; + private final SensitiveFilterUtil sensitiveFilterUtil; + private static final ScheduledThreadPoolExecutor EXECUTOR = ThreadPoolExecutorFactory.getThreadPoolExecutor(); + + @Override + public PrivateMessageVO sendMessage(PrivateMessageDTO dto) { + Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId(); + Boolean isFriends = friendService.isFriend(userId, dto.getRecvId()); + if (Boolean.FALSE.equals(isFriends)) { + throw new GlobalException("您已不是对方好友,无法发送消息"); + } + // 保存消息 + PrivateMessage msg = BeanUtils.copyProperties(dto, PrivateMessage.class); + msg.setSendId(userId); + msg.setStatus(MessageStatus.UNSEND.code()); + msg.setSendTime(new Date()); + // 过滤内容中的敏感词 + if (MessageType.TEXT.code().equals(dto.getType())) { + msg.setContent(sensitiveFilterUtil.filter(dto.getContent())); + } + this.save(msg); + // 推送消息 + PrivateMessageVO msgInfo = BeanUtils.copyProperties(msg, PrivateMessageVO.class); + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId,1)); + sendMessage.setRecvId(msgInfo.getRecvId()); + sendMessage.setSendToSelf(true); + sendMessage.setData(msgInfo); + sendMessage.setSendResult(true); + imClient.sendPrivateMessage(sendMessage); + log.info("发送私聊消息,发送id:{},接收id:{},内容:{}", userId, dto.getRecvId(), dto.getContent()); + return msgInfo; + } + + @Transactional + @Override + public PrivateMessageVO recallMessage(Long id) { + AppUser session = SecurityUtils.getAppLoginUser().getAppUser(); + PrivateMessage msg = this.getById(id); + if (Objects.isNull(msg)) { + throw new GlobalException("消息不存在"); + } + if (!msg.getSendId().equals(session.getId())) { + throw new GlobalException("这条消息不是由您发送,无法撤回"); + } + if (System.currentTimeMillis() - msg.getSendTime().getTime() > IMConstant.ALLOW_RECALL_SECOND * 1000) { + throw new GlobalException("消息已发送超过5分钟,无法撤回"); + } + // 修改消息状态 + msg.setStatus(MessageStatus.RECALL.code()); + this.updateById(msg); + // 生成一条撤回消息 + PrivateMessage recallMsg = new PrivateMessage(); + recallMsg.setSendId(session.getId()); + recallMsg.setStatus(MessageStatus.UNSEND.code()); + recallMsg.setSendTime(new Date()); + recallMsg.setRecvId(msg.getRecvId()); + recallMsg.setType(MessageType.RECALL.code()); + recallMsg.setContent(id.toString()); + this.save(recallMsg); + // 推送消息 + PrivateMessageVO msgInfo = BeanUtils.copyProperties(recallMsg, PrivateMessageVO.class); + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(session.getId(), 1));//终端类型 1:app + sendMessage.setRecvId(msgInfo.getRecvId()); + sendMessage.setData(msgInfo); + imClient.sendPrivateMessage(sendMessage); + log.info("撤回私聊消息,发送id:{},接收id:{},内容:{}", msg.getSendId(), msg.getRecvId(), msg.getContent()); + return msgInfo; + } + @Override + public void pullOfflineMessage(Long minId) { + AppUser session=SecurityUtils.getAppLoginUser().getAppUser(); + // 获取当前用户的消息 + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + // 只能拉取最近3个月的消息,移动端只拉取一个月消息 +// int months = session.getTerminal().equals(IMTerminalType.APP.code()) ? 1 : 3; + int months = new Integer(1).equals(IMTerminalType.APP.code()) ? 1 : 3; + Date minDate = DateUtils.addMonths(new Date(), -months); + wrapper.gt(PrivateMessage::getId, minId); + wrapper.ge(PrivateMessage::getSendTime, minDate); + wrapper.and(wp -> wp.eq(PrivateMessage::getSendId, session.getId()).or() + .eq(PrivateMessage::getRecvId, session.getId())); + wrapper.orderByAsc(PrivateMessage::getId); + List messages = this.list(wrapper); + // 异步推送消息 + EXECUTOR.execute(() -> { + // 开启加载中标志 + this.sendLoadingMessage(true, session); + for (PrivateMessage m : messages) { + PrivateMessageVO vo = BeanUtils.copyProperties(m, PrivateMessageVO.class); + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(m.getSendId(), IMTerminalType.WEB.code())); + sendMessage.setRecvId(session.getId()); + List list=new ArrayList<>(); + list.add(1); + sendMessage.setRecvTerminals(list); + sendMessage.setSendToSelf(false); + sendMessage.setData(vo); + sendMessage.setSendResult(true); + imClient.sendPrivateMessage(sendMessage); + } + // 关闭加载中标志 + this.sendLoadingMessage(false, session); + log.info("拉取私聊消息,用户id:{},数量:{}", session.getId(), messages.size()); + }); + } + + @Override + public List findHistoryMessage(Long friendId, Long page, Long size) { + page = page > 0 ? page : 1; + size = size > 0 ? size : 10; + Long userId = SecurityUtils.getUserId(); + long stIdx = (page - 1) * size; + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.lambda().and( + wrap -> wrap.and(wp -> wp.eq(PrivateMessage::getSendId, userId).eq(PrivateMessage::getRecvId, friendId)) + .or(wp -> wp.eq(PrivateMessage::getRecvId, userId).eq(PrivateMessage::getSendId, friendId))) + .ne(PrivateMessage::getStatus, MessageStatus.RECALL.code()).orderByDesc(PrivateMessage::getId) + .last("limit " + stIdx + "," + size); + + List messages = this.list(wrapper); + List messageInfos = + messages.stream().map(m -> BeanUtils.copyProperties(m, PrivateMessageVO.class)) + .collect(Collectors.toList()); + log.info("拉取聊天记录,用户id:{},好友id:{},数量:{}", userId, friendId, messageInfos.size()); + return messageInfos; + } + @Transactional(rollbackFor = Exception.class) + @Override + public void readedMessage(Long friendId) { + AppUser session = SecurityUtils.getAppLoginUser().getAppUser(); + // 推送消息给自己,清空会话列表上的已读数量 + PrivateMessageVO msgInfo = new PrivateMessageVO(); + msgInfo.setType(MessageType.READED.code()); + msgInfo.setSendId(session.getId()); + msgInfo.setRecvId(friendId); + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setData(msgInfo); + sendMessage.setSender(new IMUserInfo(session.getId(), 1)); + sendMessage.setSendToSelf(true); + sendMessage.setSendResult(false); + imClient.sendPrivateMessage(sendMessage); + // 推送回执消息给对方,更新已读状态 + msgInfo = new PrivateMessageVO(); + msgInfo.setType(MessageType.RECEIPT.code()); + msgInfo.setSendId(session.getId()); + msgInfo.setRecvId(friendId); + sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(session.getId(), 1)); + sendMessage.setRecvId(friendId); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(false); + sendMessage.setData(msgInfo); + imClient.sendPrivateMessage(sendMessage); + // 修改消息状态为已读 + LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(); + updateWrapper.eq(PrivateMessage::getSendId, friendId).eq(PrivateMessage::getRecvId, session.getId()) + .eq(PrivateMessage::getStatus, MessageStatus.SENDED.code()) + .set(PrivateMessage::getStatus, MessageStatus.READED.code()); + this.update(updateWrapper); + log.info("消息已读,接收方id:{},发送方id:{}", session.getId(), friendId); + } + + @Override + public Long getMaxReadedId(Long friendId) { + AppUser session=SecurityUtils.getAppLoginUser().getAppUser(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(PrivateMessage::getSendId, session.getId()).eq(PrivateMessage::getRecvId, friendId) + .eq(PrivateMessage::getStatus, MessageStatus.READED.code()).orderByDesc(PrivateMessage::getId) + .select(PrivateMessage::getId).last("limit 1"); + PrivateMessage message = this.getOne(wrapper); + if (Objects.isNull(message)) { + return -1L; + } + return message.getId(); + } + private void sendLoadingMessage(Boolean isLoadding, AppUser session) { + + PrivateMessageVO msgInfo = new PrivateMessageVO(); + msgInfo.setType(MessageType.LOADING.code()); + msgInfo.setContent(isLoadding.toString()); + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(session.getId(),1)); + sendMessage.setRecvId(session.getId()); + List list=new ArrayList<>(); + list.add(1); + sendMessage.setRecvTerminals(list); + sendMessage.setData(msgInfo); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(false); + imClient.sendPrivateMessage(sendMessage); + } + + + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/SensitiveWordServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/SensitiveWordServiceImpl.java new file mode 100644 index 0000000..7fa262b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/SensitiveWordServiceImpl.java @@ -0,0 +1,31 @@ +package com.ruoyi.im.service.impl; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.im.domain.SensitiveWord; +import com.ruoyi.im.mapper.SensitiveWordMapper; +import com.ruoyi.im.service.SensitiveWordService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SensitiveWordServiceImpl extends ServiceImpl implements + SensitiveWordService { + + @Override + public List findAllEnabledWords() { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(SensitiveWord::getEnabled,true); + wrapper.select(SensitiveWord::getContent); + List words = this.list(wrapper); + return words.stream().map(SensitiveWord::getContent).collect(Collectors.toList()); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/WebrtcPrivateServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/WebrtcPrivateServiceImpl.java new file mode 100644 index 0000000..d7cf26f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/service/impl/WebrtcPrivateServiceImpl.java @@ -0,0 +1,337 @@ +package com.ruoyi.im.service.impl; + + +import com.ruoyi.common.annotation.OnlineCheck; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.im.constant.RedisKey; +import com.ruoyi.common.im.enums.MessageStatus; +import com.ruoyi.common.im.enums.MessageType; +import com.ruoyi.common.im.enums.WebrtcMode; +import com.ruoyi.common.im.model.IMPrivateMessage; +import com.ruoyi.common.im.model.IMUserInfo; +import com.ruoyi.common.im.session.WebrtcPrivateSession; +import com.ruoyi.common.im.util.BeanUtils; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.im.domain.PrivateMessage; +import com.ruoyi.im.domain.vo.PrivateMessageVO; +import com.ruoyi.im.service.PrivateMessageService; +import com.ruoyi.im.service.WebrtcPrivateService; +import com.ruoyi.im.util.UserStateUtils; +import com.ruoyi.imclient.IMClient; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.Collections; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service +@RequiredArgsConstructor +public class WebrtcPrivateServiceImpl implements WebrtcPrivateService { + + private final IMClient imClient; + private final RedisTemplate redisTemplate; + private final PrivateMessageService privateMessageService; + private final UserStateUtils userStateUtils; + + @OnlineCheck + @Override + public void call(Long uid, String mode, String offer) { + Long userId = SecurityUtils.getUserId(); + log.info("发起呼叫,sid:{},uid:{}", userId, uid); + // 创建webrtc会话 + WebrtcPrivateSession webrtcSession = new WebrtcPrivateSession(); + webrtcSession.setCallerId(userId); + webrtcSession.setCallerTerminal(1); + webrtcSession.setAcceptorId(uid); + webrtcSession.setMode(mode); + // 校验 + if (!imClient.isOnline(uid)) { + this.sendActMessage(webrtcSession, MessageStatus.UNSEND, "未接通"); + log.info("对方不在线,uid:{}", uid); + throw new GlobalException("对方目前不在线"); + } + if (userStateUtils.isBusy(uid)) { + this.sendActMessage(webrtcSession, MessageStatus.UNSEND, "未接通"); + log.info("对方正忙,uid:{}", uid); + throw new GlobalException("对方正忙"); + } + // 保存rtc session + String key = getWebRtcSessionKey(userId, uid); + redisTemplate.opsForValue().set(key, webrtcSession, 60, TimeUnit.SECONDS); + // 设置用户忙线状态 + userStateUtils.setBusy(uid); + userStateUtils.setBusy(userId); + // 向对方所有终端发起呼叫 + PrivateMessageVO messageInfo = new PrivateMessageVO(); + MessageType messageType = + mode.equals(WebrtcMode.VIDEO.getValue()) ? MessageType.RTC_CALL_VIDEO : MessageType.RTC_CALL_VOICE; + messageInfo.setType(messageType.code()); + messageInfo.setRecvId(uid); + messageInfo.setSendId(userId); + messageInfo.setContent(offer); + + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId, 1)); + sendMessage.setRecvId(uid); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(false); + sendMessage.setData(messageInfo); + imClient.sendPrivateMessage(sendMessage); + + } + + @Override + public void accept(Long uid, @RequestBody String answer) { + Long userId = SecurityUtils.getUserId(); + log.info("接受通话,sid:{},uid:{}",userId, uid); + // 查询webrtc会话 + WebrtcPrivateSession webrtcSession = getWebrtcSession(userId, uid); + // 更新接受者信息 + webrtcSession.setAcceptorId(userId); + webrtcSession.setAcceptorTerminal(1); + webrtcSession.setChatTimeStamp(System.currentTimeMillis()); + String key = getWebRtcSessionKey(userId, uid); + redisTemplate.opsForValue().set(key, webrtcSession, 60, TimeUnit.SECONDS); + // 向发起人推送接受通话信令 + PrivateMessageVO messageInfo = new PrivateMessageVO(); + messageInfo.setType(MessageType.RTC_ACCEPT.code()); + messageInfo.setRecvId(uid); + messageInfo.setSendId(userId); + messageInfo.setContent(answer); + + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId, 1)); + sendMessage.setRecvId(uid); + // 告知其他终端已经接受会话,中止呼叫 + sendMessage.setSendToSelf(true); + sendMessage.setSendResult(false); + sendMessage.setRecvTerminals((Collections.singletonList(webrtcSession.getCallerTerminal()))); + sendMessage.setData(messageInfo); + imClient.sendPrivateMessage(sendMessage); + } + + @Override + public void reject(Long uid) { + Long userId = SecurityUtils.getUserId(); + log.info("拒绝通话,sid:{},uid:{}", userId, uid); + // 查询webrtc会话 + WebrtcPrivateSession webrtcSession = getWebrtcSession(userId, uid); + // 删除会话信息 + removeWebrtcSession(uid, userId); + // 设置用户空闲状态 + userStateUtils.setFree(uid); + userStateUtils.setFree(userId); + // 向发起人推送拒绝通话信令 + PrivateMessageVO messageInfo = new PrivateMessageVO(); + messageInfo.setType(MessageType.RTC_REJECT.code()); + messageInfo.setRecvId(uid); + messageInfo.setSendId(userId); + + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId, 1)); + sendMessage.setRecvId(uid); + // 告知其他终端已经拒绝会话,中止呼叫 + sendMessage.setSendToSelf(true); + sendMessage.setSendResult(false); + sendMessage.setRecvTerminals(Collections.singletonList(webrtcSession.getCallerTerminal())); + sendMessage.setData(messageInfo); + imClient.sendPrivateMessage(sendMessage); + // 生成通话消息 + sendActMessage(webrtcSession, MessageStatus.READED, "已拒绝"); + } + + @Override + public void cancel(Long uid) { + Long userId = SecurityUtils.getUserId(); + log.info("取消通话,sid:{},uid:{}", userId, uid); + // 查询webrtc会话 + WebrtcPrivateSession webrtcSession = getWebrtcSession(userId, uid); + // 删除会话信息 + removeWebrtcSession(userId, uid); + // 设置用户空闲状态 + userStateUtils.setFree(uid); + userStateUtils.setFree(userId); + // 向对方所有终端推送取消通话信令 + PrivateMessageVO messageInfo = new PrivateMessageVO(); + messageInfo.setType(MessageType.RTC_CANCEL.code()); + messageInfo.setRecvId(uid); + messageInfo.setSendId(userId); + + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId, 1)); + sendMessage.setRecvId(uid); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(false); + sendMessage.setData(messageInfo); + // 通知对方取消会话 + imClient.sendPrivateMessage(sendMessage); + // 生成通话消息 + sendActMessage(webrtcSession, MessageStatus.UNSEND, "已取消"); + } + + @Override + public void failed(Long uid, String reason) { + Long userId = SecurityUtils.getUserId(); + log.info("通话失败,sid:{},uid:{},reason:{}", userId, uid, reason); + // 查询webrtc会话 + WebrtcPrivateSession webrtcSession = getWebrtcSession(userId, uid); + // 删除会话信息 + removeWebrtcSession(uid, userId); + // 设置用户空闲状态 + userStateUtils.setFree(uid); + userStateUtils.setFree(userId); + // 向发起方推送通话失败信令 + PrivateMessageVO messageInfo = new PrivateMessageVO(); + messageInfo.setType(MessageType.RTC_FAILED.code()); + messageInfo.setRecvId(uid); + messageInfo.setSendId(userId); + messageInfo.setContent(reason); + + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId,1)); + sendMessage.setRecvId(uid); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(false); + sendMessage.setRecvTerminals(Collections.singletonList(webrtcSession.getCallerTerminal())); + sendMessage.setData(messageInfo); + // 通知对方取消会话 + imClient.sendPrivateMessage(sendMessage); + // 生成消息 + sendActMessage(webrtcSession, MessageStatus.READED, "未接通"); + } + + @Override + public void handup(Long uid) { + Long userId = SecurityUtils.getUserId(); + log.info("挂断通话,sid:{},uid:{}", userId, uid); + // 查询webrtc会话 + WebrtcPrivateSession webrtcSession = getWebrtcSession(userId, uid); + // 删除会话信息 + removeWebrtcSession(uid, userId); + // 设置用户空闲状态 + userStateUtils.setFree(uid); + userStateUtils.setFree(userId); + // 向对方推送挂断通话信令 + PrivateMessageVO messageInfo = new PrivateMessageVO(); + messageInfo.setType(MessageType.RTC_HANDUP.code()); + messageInfo.setRecvId(uid); + messageInfo.setSendId(userId); + + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId, 1)); + sendMessage.setRecvId(uid); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(false); + Integer terminal = getTerminalType(uid, webrtcSession); + sendMessage.setRecvTerminals(Collections.singletonList(terminal)); + sendMessage.setData(messageInfo); + // 通知对方取消会话 + imClient.sendPrivateMessage(sendMessage); + // 生成通话消息 + sendActMessage(webrtcSession, MessageStatus.READED, "通话时长 " + chatTimeText(webrtcSession)); + } + + @Override + public void candidate(Long uid, String candidate) { + Long userId = SecurityUtils.getUserId(); + // 查询webrtc会话 + WebrtcPrivateSession webrtcSession = getWebrtcSession(userId, uid); + // 向发起方推送同步candidate信令 + PrivateMessageVO messageInfo = new PrivateMessageVO(); + messageInfo.setType(MessageType.RTC_CANDIDATE.code()); + messageInfo.setRecvId(uid); + messageInfo.setSendId(userId); + messageInfo.setContent(candidate); + + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(userId, 1)); + sendMessage.setRecvId(uid); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(false); + Integer terminal = getTerminalType(uid, webrtcSession); + sendMessage.setRecvTerminals(Collections.singletonList(terminal)); + sendMessage.setData(messageInfo); + imClient.sendPrivateMessage(sendMessage); + } + + @Override + public void heartbeat(Long uid) { + Long userId = SecurityUtils.getUserId(); + // 会话续命 + String key = getWebRtcSessionKey(userId, uid); + redisTemplate.expire(key, 60, TimeUnit.SECONDS); + // 用户状态续命 + userStateUtils.expire(userId); + } + + private WebrtcPrivateSession getWebrtcSession(Long userId, Long uid) { + String key = getWebRtcSessionKey(userId, uid); + WebrtcPrivateSession webrtcSession = (WebrtcPrivateSession)redisTemplate.opsForValue().get(key); + if (webrtcSession == null) { + throw new GlobalException("通话已结束"); + } + return webrtcSession; + } + + private void removeWebrtcSession(Long userId, Long uid) { + String key = getWebRtcSessionKey(userId, uid); + redisTemplate.delete(key); + } + + private String getWebRtcSessionKey(Long id1, Long id2) { + Long minId = id1 > id2 ? id2 : id1; + Long maxId = id1 > id2 ? id1 : id2; + return String.join(":", RedisKey.IM_WEBRTC_PRIVATE_SESSION, minId.toString(), maxId.toString()); + } + + private Integer getTerminalType(Long uid, WebrtcPrivateSession webrtcSession) { + if (uid.equals(webrtcSession.getCallerId())) { + return webrtcSession.getCallerTerminal(); + } + return webrtcSession.getAcceptorTerminal(); + } + + private void sendActMessage(WebrtcPrivateSession rtcSession, MessageStatus status, String content) { + // 保存消息 + PrivateMessage msg = new PrivateMessage(); + msg.setSendId(rtcSession.getCallerId()); + msg.setRecvId(rtcSession.getAcceptorId()); + msg.setContent(content); + msg.setSendTime(new Date()); + msg.setStatus(status.code()); + MessageType type = rtcSession.getMode().equals(WebrtcMode.VIDEO.getValue()) ? MessageType.ACT_RT_VIDEO + : MessageType.ACT_RT_VOICE; + msg.setType(type.code()); + privateMessageService.save(msg); + // 推给发起人 + PrivateMessageVO messageInfo = BeanUtils.copyProperties(msg, PrivateMessageVO.class); + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(rtcSession.getCallerId(), rtcSession.getCallerTerminal())); + sendMessage.setRecvId(rtcSession.getCallerId()); + sendMessage.setSendToSelf(false); + sendMessage.setSendResult(true); + sendMessage.setData(messageInfo); + imClient.sendPrivateMessage(sendMessage); + // 推给接听方 + sendMessage.setRecvId(rtcSession.getAcceptorId()); + imClient.sendPrivateMessage(sendMessage); + } + + private String chatTimeText(WebrtcPrivateSession rtcSession) { + long chatTime = (System.currentTimeMillis() - rtcSession.getChatTimeStamp()) / 1000; + int min = Math.abs((int)chatTime / 60); + int sec = Math.abs((int)chatTime % 60); + String strTime = min < 10 ? "0" : ""; + strTime += min; + strTime += ":"; + strTime += sec < 10 ? "0" : ""; + strTime += sec; + return strTime; + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/thirdparty/MinioService.java b/ruoyi-system/src/main/java/com/ruoyi/im/thirdparty/MinioService.java new file mode 100644 index 0000000..7078a7e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/thirdparty/MinioService.java @@ -0,0 +1,167 @@ +package com.ruoyi.im.thirdparty; + +import com.ruoyi.im.util.DateTimeUtils; +import io.minio.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Date; + +@Slf4j +@Component +@RequiredArgsConstructor +public class MinioService { + + + private final MinioClient minioClient; + + /** + * 查看存储bucket是否存在 + * + * @return boolean + */ + public Boolean bucketExists(String bucketName) { + try { + return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + } catch (Exception e) { + log.error("查询bucket失败", e); + return false; + } + } + + /** + * 创建存储bucket + */ + public void makeBucket(String bucketName) { + try { + minioClient.makeBucket(MakeBucketArgs.builder() + .bucket(bucketName) + .build()); + } catch (Exception e) { + log.error("创建bucket失败,", e); + } + } + + /** + * 设置bucket权限为public + */ + public void setBucketPublic(String bucketName) { + try { + // 设置公开 + String sb = "{\"Version\":\"2012-10-17\"," + + "\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":" + + "{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"," + + "\"s3:GetBucketLocation\"],\"Resource\":[\"arn:aws:s3:::" + bucketName + + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\"],\"Resource\":[\"arn:aws:s3:::" + + bucketName + + "/*\"]}]}"; + minioClient.setBucketPolicy( + SetBucketPolicyArgs.builder() + .bucket(bucketName) + .config(sb) + .build()); + } catch (Exception e) { + log.error("创建bucket失败,", e); + } + } + + /** + * 文件上传 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param file 文件 + * @return Boolean + */ + public String upload(String bucketName, String path, MultipartFile file) { + String originalFilename = file.getOriginalFilename(); + if (StringUtils.isBlank(originalFilename)) { + throw new RuntimeException(); + } + String fileName = System.currentTimeMillis() + ""; + if (originalFilename.lastIndexOf(".") >= 0) { + fileName += originalFilename.substring(originalFilename.lastIndexOf(".")); + } + String objectName = DateTimeUtils.getFormatDate(new Date(), DateTimeUtils.PARTDATEFORMAT) + "/" + fileName; + try { + InputStream stream = new ByteArrayInputStream(file.getBytes()); + PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(path + "/" + objectName) + .stream(stream, file.getSize(), -1).contentType(file.getContentType()).build(); + //文件名称相同会覆盖 + minioClient.putObject(objectArgs); + } catch (Exception e) { + log.error("上传图片失败,", e); + return null; + } + return objectName; + } + + /** + * 文件上传 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param name 文件名 + * @param fileByte 文件内容 + * @param contentType contentType + * @return objectName + */ + public String upload(String bucketName, String path, String name, byte[] fileByte, String contentType) { + + String fileName = System.currentTimeMillis() + name.substring(name.lastIndexOf(".")); + String objectName = DateTimeUtils.getFormatDate(new Date(), DateTimeUtils.PARTDATEFORMAT) + "/" + fileName; + try { + InputStream stream = new ByteArrayInputStream(fileByte); + PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(path + "/" + objectName) + .stream(stream, fileByte.length, -1).contentType(contentType).build(); + //文件名称相同会覆盖 + minioClient.putObject(objectArgs); + } catch (Exception e) { + log.error("上传文件失败,", e); + return null; + } + return objectName; + } + + + /** + * 删除 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param fileName 文件名 + * @return true/false + */ + public boolean remove(String bucketName, String path, String fileName) { + try { + minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(path + "/" + fileName).build()); + } catch (Exception e) { + log.error("删除文件失败,", e); + return false; + } + return true; + } + + /** + * 判断文件是否存在 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param fileName 文件名 + * @return + */ + public Boolean isExist(String bucketName, String path, String fileName) { + try { + minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(path + "/" + fileName).build()); + } catch (Exception e) { + return false; + } + return true; + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/util/DateTimeUtils.java b/ruoyi-system/src/main/java/com/ruoyi/im/util/DateTimeUtils.java new file mode 100644 index 0000000..2567ee1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/util/DateTimeUtils.java @@ -0,0 +1,35 @@ +package com.ruoyi.im.util; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 日期处理工具类 + * + * @version 1.0 + */ +public final class DateTimeUtils extends DateUtils { + + public static final String FULL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final String PARTDATEFORMAT = "yyyyMMdd"; + + + /** + * 将日期类型转换为字符串 + * + * @param date 日期 + * @param xFormat 格式 + * @return 日期 + */ + public static String getFormatDate(Date date, String xFormat) { + date = date == null ? new Date() : date; + xFormat = StringUtils.isNotEmpty(xFormat) ? xFormat : FULL_DATE_FORMAT; + SimpleDateFormat sdf = new SimpleDateFormat(xFormat); + return sdf.format(date); + } + + +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/util/FileUtil.java b/ruoyi-system/src/main/java/com/ruoyi/im/util/FileUtil.java new file mode 100644 index 0000000..cd03aed --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/util/FileUtil.java @@ -0,0 +1,33 @@ +package com.ruoyi.im.util; + +public final class FileUtil { + + + /** + * 获取文件后缀 + * + * @param fileName 文件名 + * @return boolean + */ + public static String getFileExtension(String fileName) { + return fileName.substring(fileName.lastIndexOf(".") + 1); + } + + /** + * 判断文件是否图片类型 + * + * @param fileName 文件名 + * @return boolean + */ + public static boolean isImage(String fileName) { + String extension = getFileExtension(fileName); + String[] imageExtension = new String[]{"jpeg", "jpg", "bmp", "png", "webp", "gif"}; + for (String e : imageExtension) { + if (extension.toLowerCase().equals(e)) { + return true; + } + } + + return false; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/util/ImageUtil.java b/ruoyi-system/src/main/java/com/ruoyi/im/util/ImageUtil.java new file mode 100644 index 0000000..33ca810 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/util/ImageUtil.java @@ -0,0 +1,78 @@ +package com.ruoyi.im.util; + +import lombok.extern.slf4j.Slf4j; +import net.coobird.thumbnailator.Thumbnails; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +@Slf4j +public final class ImageUtil { + + //以下是常量,按照阿里代码开发规范,不允许代码中出现魔法值 + private static final Integer ZERO = 0; + private static final Integer ONE_ZERO_TWO_FOUR = 1024; + private static final Integer NINE_ZERO_ZERO = 900; + private static final Integer THREE_TWO_SEVEN_FIVE = 3275; + private static final Integer TWO_ZERO_FOUR_SEVEN = 2047; + private static final Double ZERO_EIGHT_FIVE = 0.85; + private static final Double ZERO_SIX = 0.6; + private static final Double ZERO_FOUR_FOUR = 0.44; + private static final Double ZERO_FOUR = 0.4; + + /** + * 根据指定大小压缩图片 + * + * @param imageBytes 源图片字节数组 + * @param desFileSize 指定图片大小,单位kb + * @return 压缩质量后的图片字节数组 + */ + public static byte[] compressForScale(byte[] imageBytes, long desFileSize) { + if (imageBytes == null || imageBytes.length <= ZERO || imageBytes.length < desFileSize * ONE_ZERO_TWO_FOUR) { + return imageBytes; + } + long srcSize = imageBytes.length; + double accuracy = getAccuracy(srcSize / ONE_ZERO_TWO_FOUR); + try { + while (imageBytes.length > desFileSize * ONE_ZERO_TWO_FOUR) { + ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length); + Thumbnails.of(inputStream) + .scale(accuracy) + .outputQuality(accuracy) + .toOutputStream(outputStream); + imageBytes = outputStream.toByteArray(); + } + log.info("图片原大小={}kb | 压缩后大小={}kb", + srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR); + } catch (Exception e) { + log.error("【图片压缩】msg=图片压缩失败!", e); + } + return imageBytes; + } + + + /** + * 自动调节精度(经验数值) + * + * @param size 源图片大小 + * @return 图片压缩质量比 + */ + private static double getAccuracy(long size) { + double accuracy; + if (size < NINE_ZERO_ZERO) { + accuracy = ZERO_EIGHT_FIVE; + } else if (size < TWO_ZERO_FOUR_SEVEN) { + accuracy = ZERO_SIX; + } else if (size < THREE_TWO_SEVEN_FIVE) { + accuracy = ZERO_FOUR_FOUR; + } else { + accuracy = ZERO_FOUR; + } + return accuracy; + } + +} + + + diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/util/SensitiveFilterUtil.java b/ruoyi-system/src/main/java/com/ruoyi/im/util/SensitiveFilterUtil.java new file mode 100644 index 0000000..8906f31 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/util/SensitiveFilterUtil.java @@ -0,0 +1,208 @@ +package com.ruoyi.im.util; + + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.im.util.ThreadPoolExecutorFactory; +import com.ruoyi.im.service.SensitiveWordService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.CharUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledThreadPoolExecutor; + +/** + * 敏感词过滤器——SensitiveFilter + * + * @author Andrews + * @date 2023/12/4 11:12 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public final class SensitiveFilterUtil { + + /** + * 替换符 + */ + private static final String REPLACE_MENT = "***"; + + /** + * 根节点 + */ + private static TrieNode ROOT_NODE = new TrieNode(); + + /** + * 线程池 + */ + private static final ScheduledThreadPoolExecutor EXECUTOR_SERVICE = + ThreadPoolExecutorFactory.getThreadPoolExecutor(); + + private final SensitiveWordService sensitiveWordService; + + /** + * 1、 前缀树 前缀树某一个节点 + * + * @author NXY + * @date 2023/12/4 11:17 + */ + private static class TrieNode { + // 关键词结束标识 + private boolean isKeywordEnd = false; + + // 子节点(key是下级字符,value是下级节点) + // 当前节点的子节点 + private final Map subNodes = new HashMap<>(); + + public boolean isKeywordEnd() { + return isKeywordEnd; + } + + public void setKeywordEnd(boolean keywordEnd) { + isKeywordEnd = keywordEnd; + } + + // 添加子节点 + public void addSubNode(Character c, TrieNode node) { + subNodes.put(c, node); + } + + // 获取子节点 + public TrieNode getSubNode(Character c) { + return subNodes.get(c); + } + + } + + /** + * 2、初始化方法,服务器启动时初始化 + * + * @author NXY + * @date 2023/12/4 11:18 + */ + @PostConstruct + public void reload() { + // 使用copy on write的方式,防止出现并发问题 + TrieNode newNode = new TrieNode(); + List keywords = sensitiveWordService.findAllEnabledWords(); + keywords.forEach(keyword -> { + if (StrUtil.isNotEmpty(keyword)) { + // 添加到前缀树 + addKeyword(newNode,keyword); + } + }); + ROOT_NODE = newNode; + } + + /** + * 3、将一个敏感词添加到前缀树中 + * + * @param node + * @param keyword + * @author NXY + * @date 2023/12/4 11:15 + */ + private void addKeyword(TrieNode node, String keyword) { + for (int i = 0; i < keyword.length(); i++) { + char c = keyword.charAt(i); + TrieNode subNode = node.getSubNode(c); + if (subNode == null) { + // 初始化子节点 + subNode = new TrieNode(); + node.addSubNode(c, subNode); + } + // 指向子节点,进入下一轮循环 + node = subNode; + // 设置结束标识 + if (i == keyword.length() - 1) { + node.setKeywordEnd(true); + } + } + } + + /** + * 过滤敏感词 + * + * @param text 待过滤的文本 + * @return 过滤后的文本 + */ + public String filter(String text) { + if (StringUtils.isBlank(text)) { + return null; + } + // 结果 + StringBuilder sb = new StringBuilder(); + try { + // 指针1 + TrieNode tempNode = ROOT_NODE; + // 指针2 + int begin = 0; + // 指针3 + int position = 0; + while (begin < text.length()) { + if (position < text.length()) { + char c = text.charAt(position); + // 跳过符号 + if (isSymbol(c)) { + // 若指针1处于根节点,将此符号计入结果,让指针2向下走一步 + if (tempNode == ROOT_NODE) { + sb.append(c); + begin++; + } + // 无论符号在开头或中间,指针3都向下走一步 + position++; + continue; + } + // 检查下级节点 + tempNode = tempNode.getSubNode(c); + if (tempNode == null) { + // 以begin开头的字符串不是敏感词 + sb.append(text.charAt(begin)); + // 进入下一个位置 + position = ++begin; + // 重新指向根节点 + tempNode = ROOT_NODE; + } else if (tempNode.isKeywordEnd()) { + // 发现敏感词,将begin~position字符串替换掉 + sb.append(REPLACE_MENT); + // 进入下一个位置 + begin = ++position; + // 重新指向根节点 + tempNode = ROOT_NODE; + } else { + // 检查下一个字符 + position++; + } + } + // position遍历越界仍未匹配到敏感词 + else { + sb.append(text.charAt(begin)); + position = ++begin; + tempNode = ROOT_NODE; + } + } + } catch (Exception e) { + sb = new StringBuilder(text); + } + return sb.toString(); + } + + /** + * 判断是否为符号 ——特殊符号 + * + * @return boolean + * @author NXY + * @date 2023/12/4 11:17 + */ + private boolean isSymbol(Character c) { + // 0x2E80~0x9FFF 是东亚文字范围 + return !CharUtils.isAsciiAlphanumeric(c) && (c < 0x2E80 || c > 0x9FFF); + } +} + + diff --git a/ruoyi-system/src/main/java/com/ruoyi/im/util/UserStateUtils.java b/ruoyi-system/src/main/java/com/ruoyi/im/util/UserStateUtils.java new file mode 100644 index 0000000..56dc3e1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/im/util/UserStateUtils.java @@ -0,0 +1,44 @@ +package com.ruoyi.im.util; + +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.im.constant.RedisKey; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * @author: Blue + * @date: 2024-06-10 + * @version: 1.0 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class UserStateUtils { + + private final RedisTemplate redisTemplate; + + public void setBusy(Long userId){ + String key = StrUtil.join(":", RedisKey.IM_USER_STATE,userId); + redisTemplate.opsForValue().set(key,1,30, TimeUnit.SECONDS); + } + + public void expire(Long userId){ + String key = StrUtil.join(":", RedisKey.IM_USER_STATE,userId); + redisTemplate.expire(key,30, TimeUnit.SECONDS); + } + + public void setFree(Long userId){ + String key = StrUtil.join(":", RedisKey.IM_USER_STATE,userId); + redisTemplate.delete(key); + } + + public Boolean isBusy(Long userId){ + String key = StrUtil.join(":", RedisKey.IM_USER_STATE,userId); + return redisTemplate.hasKey(key); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/MemberWechat.java b/ruoyi-system/src/main/java/com/ruoyi/mall/MemberWechat.java new file mode 100644 index 0000000..80f9f58 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/MemberWechat.java @@ -0,0 +1,78 @@ +package com.ruoyi.mall; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 用户微信信息对象 ums_member_wechat + * + * @author zcc + */ +@ApiModel(description="用户微信信息对象") +@Data +@TableName("ums_member_wechat") +public class MemberWechat extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("MEMBER_ID") + @Excel(name = "MEMBER_ID") + private Long memberId; + + @ApiModelProperty("只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段") + @Excel(name = "只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段") + private String unionid; + + @ApiModelProperty("用户的标识,对当前公众号唯一") + @Excel(name = "用户的标识,对当前公众号唯一") + private String openid; + + @ApiModelProperty("小程序唯一身份ID") + @Excel(name = "小程序唯一身份ID") + private String routineOpenid; + + @ApiModelProperty("用户所在的分组ID(兼容旧的用户分组接口)") + @Excel(name = "用户所在的分组ID", readConverterExp = "兼=容旧的用户分组接口") + private Integer groupid; + + @ApiModelProperty("用户被打上的标签ID列表") + @Excel(name = "用户被打上的标签ID列表") + private String tagidList; + + @ApiModelProperty("用户是否订阅该公众号标识") + @Excel(name = "用户是否订阅该公众号标识") + private Integer subscribe; + + @ApiModelProperty("关注公众号时间") + @Excel(name = "关注公众号时间") + private Integer subscribeTime; + + @ApiModelProperty("小程序用户会话密匙") + @Excel(name = "小程序用户会话密匙") + private String sessionKey; + + @ApiModelProperty("token") + @Excel(name = "token") + private String accessToken; + + @ApiModelProperty("过期时间") + @Excel(name = "过期时间") + private Integer expiresIn; + + @ApiModelProperty("刷新token") + @Excel(name = "刷新token") + private String refreshToken; + + @ApiModelProperty("过期时间") + @Excel(name = "过期时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime expireTime; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Address.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Address.java new file mode 100644 index 0000000..5d7d439 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Address.java @@ -0,0 +1,50 @@ +package com.ruoyi.mall.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 地址对象 + * + */ +@ApiModel(description="地址对象") +@Data +@TableName("address") +public class Address { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Integer id; + + @ApiModelProperty("地区邮编") + @Excel(name = "地区邮编") + private Long code; + + @ApiModelProperty("父地区邮编") + @Excel(name = "父地区邮编") + private Long parentCode; + + @ApiModelProperty("地区名") + @Excel(name = "地区名") + private String name; + + @ApiModelProperty("地区层级") + @Excel(name = "地区层级") + private Integer level; + + @ApiModelProperty("CREATED_AT") + @Excel(name = "CREATED_AT") + private String createdAt; + + @ApiModelProperty("UPDATED_AT") + @Excel(name = "UPDATED_AT") + private String updatedAt; + + @ApiModelProperty("DELETED_AT") + @Excel(name = "DELETED_AT") + private String deletedAt; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Brand.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Brand.java new file mode 100644 index 0000000..ed8d966 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Brand.java @@ -0,0 +1,40 @@ +package com.ruoyi.mall.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 品牌管理对象 pms_brand + * + * @author zcc + */ +@ApiModel(description="品牌管理对象") +@Data +@TableName("mall_brand") +public class Brand extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("NAME") + @Excel(name = "NAME") + private String name; + + @ApiModelProperty("SORT") + @Excel(name = "SORT") + private Integer sort; + + @ApiModelProperty("SHOW_STATUS") + @Excel(name = "SHOW_STATUS") + private Integer showStatus; + + @ApiModelProperty("品牌logo") + @Excel(name = "品牌logo") + private String logo; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopAddress.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/MemberAddress.java similarity index 66% rename from ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopAddress.java rename to ruoyi-system/src/main/java/com/ruoyi/mall/domain/MemberAddress.java index c767d1e..b9d7a28 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopAddress.java +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/MemberAddress.java @@ -1,8 +1,11 @@ -package com.ruoyi.shop.domain; +package com.ruoyi.mall.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; @@ -20,56 +23,62 @@ import java.time.LocalDateTime; */ @Data @EqualsAndHashCode(callSuper = false) -public class ShopAddress implements Serializable { +@TableName("mall_member_address") +public class MemberAddress extends BaseAudit implements Serializable { private static final long serialVersionUID=1L; - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; /** * 用户id */ private Long userId; + /** + * 收货人名称 + */ + @ApiModelProperty("收货人名称") + private String name; + + /** + * 是否默认 + */ + @ApiModelProperty("是否默认") + private Boolean isDefault; + + @ApiModelProperty("邮政编码") + private String postCode; + /** * 省 */ - @ApiModelProperty("商品简介") + @ApiModelProperty("省") private String province; /** * 市 */ - @ApiModelProperty("商品简介") + @ApiModelProperty("市") private String city; + @ApiModelProperty("区") + private String district; + /** * 详细地址 */ @ApiModelProperty("详细地址") private String address; - /** - * 是否默认 - */ - @ApiModelProperty("是否默认") - private Boolean isDefault; - - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime addTime; - /** * 电话 */ @ApiModelProperty("电话") private String phone; - /** - * 收货人名称 - */ - @ApiModelProperty("收货人名称") - private String name; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/MemberCart.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/MemberCart.java new file mode 100644 index 0000000..b47e709 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/MemberCart.java @@ -0,0 +1,59 @@ +package com.ruoyi.mall.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 购物车对象 ums_member_cart + * + * @author zcc + */ +@ApiModel(description="购物车对象") +@Data +@TableName("mall_member_cart") +public class MemberCart extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("购物车表ID") + private Long id; + + @ApiModelProperty("0->失效;1->有效") + @Excel(name = "0->失效;1->有效") + private Integer status; + + @ApiModelProperty("用户ID") + @Excel(name = "用户ID") + private Long memberId; + + @ApiModelProperty("商品ID") + @Excel(name = "商品ID") + private Long productId; + + @ApiModelProperty("展示图片") + @Excel(name = "展示图片") + private String pic; + + @ApiModelProperty("SKU ID") + @Excel(name = "SKU ID") + private Long skuId; + + @ApiModelProperty("PRODUCT_NAME") + @Excel(name = "PRODUCT_NAME") + private String productName; + + @ApiModelProperty("商品属性") + @Excel(name = "商品属性") + private String spData; + + @ApiModelProperty("商品数量") + @Excel(name = "商品数量") + private Integer quantity; + + // 0->商品;1->课程 + private Integer isCourse; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Product.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Product.java new file mode 100644 index 0000000..b9a8858 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Product.java @@ -0,0 +1,79 @@ +package com.ruoyi.mall.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 商品信息对象 pms_product + * + * @author zcc + */ +@ApiModel(description="商品信息对象") +@Data +@TableName("mall_product") +public class Product extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("BRAND_ID") + private Long brandId; + + @ApiModelProperty("CATEGORY_ID") + private Long categoryId; + + @ApiModelProperty("商品编码") + private String outProductId; + + @ApiModelProperty("NAME") + private String name; + + @ApiModelProperty("主图") + private String pic; + + @ApiModelProperty("画册图片,连产品图片限制为5张,以逗号分割") + private String albumPics; + + @ApiModelProperty("上架状态:0->下架;1->上架") + private Integer publishStatus; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("PRICE") + private BigDecimal price; + + @ApiModelProperty("单位") + private String unit; + + @ApiModelProperty("商品重量,默认为克") + private BigDecimal weight; + + @ApiModelProperty("商品销售属性,json格式") + private String productAttr; + + @ApiModelProperty("产品详情网页内容") + private String detailHtml; + + @ApiModelProperty("移动端网页详情") + private String detailMobileHtml; + + @ApiModelProperty("品牌名称") + private String brandName; + + @ApiModelProperty("商品分类名称") + private String productCategoryName; + + // 0->商品;1->课程 + private Integer isCourse; + + private Long courseId; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/ProductCategory.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/ProductCategory.java new file mode 100644 index 0000000..de53e94 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/ProductCategory.java @@ -0,0 +1,45 @@ +package com.ruoyi.mall.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商品分类对象 mall_sc_category + * + * @author zcc + */ +@ApiModel(description="商品分类对象") +@Data +@TableName("mall_product_category") +public class ProductCategory extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("上级分类的编号:0表示一级分类") + private Long parentId; + + + private String typeName; + + @ApiModelProperty("分类级别:0->1级;1->2级") + private Integer level; + + @ApiModelProperty("显示状态:0->不显示;1->显示") + private Integer showStatus; + + @ApiModelProperty("SORT") + private Integer sort; + + @ApiModelProperty("图标") + private String icon; + +// 0->商品分类;1->课程分类 + private Integer isCourse; + private String storeId;//门店id + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Sku.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Sku.java new file mode 100644 index 0000000..c54f5df --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Sku.java @@ -0,0 +1,44 @@ +package com.ruoyi.mall.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * sku信息对象 mall_sku + * + * @author zcc + */ +@ApiModel(description="sku信息对象") +@Data +@TableName("mall_sku") +public class Sku extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("PRODUCT_ID") + private Long productId; + + @ApiModelProperty("sku编码") + private String outSkuId; + + @ApiModelProperty("PRICE") + private BigDecimal price; + + @ApiModelProperty("展示图片") + private String pic; + + @ApiModelProperty("商品销售属性,json格式") + private String spData; + + @ApiModelProperty("库存数") + private Integer stock; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/AddressDTO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/AddressDTO.java new file mode 100644 index 0000000..cf5174a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/AddressDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.mall.domain.dto; + +import lombok.Data; + +import java.util.List; + +/** + * 【请填写功能名称】 DTO 对象 + * + * @author sjm + */ +@Data +public class AddressDTO { + private Long id; + private Long pid; + private String name; + private String level; + private List children; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/DeliveryReq.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/DeliveryReq.java new file mode 100644 index 0000000..6c98f50 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/DeliveryReq.java @@ -0,0 +1,30 @@ + package com.ruoyi.mall.domain.dto; + + import io.swagger.annotations.ApiModel; + import io.swagger.annotations.ApiModelProperty; + import lombok.Data; + + import javax.validation.constraints.NotBlank; + import javax.validation.constraints.NotNull; + + /** + * 发货记录 + * @author Jinxin + * + */ + @Data + @ApiModel(value = "发货记录") + public class DeliveryReq { + + @ApiModelProperty(value = "订单id", required = true) + @NotNull(message = "订单id不能为空") + private Long orderId; + + @ApiModelProperty(value = "物流单号", required = true) + @NotBlank(message = "物流单号不能为空") + private String deliverySn; + + @ApiModelProperty(value = "快递公司Code", required = true) + @NotBlank(message = "快递公司Code不能为空") + private String deliveryCompanyCode; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/OrderProductListDTO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/OrderProductListDTO.java new file mode 100644 index 0000000..3c761d4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/OrderProductListDTO.java @@ -0,0 +1,42 @@ + package com.ruoyi.mall.domain.dto; + + import com.ruoyi.mall.domain.Product; + import com.ruoyi.mall.domain.Sku; + import io.swagger.annotations.ApiModel; + import io.swagger.annotations.ApiModelProperty; + import lombok.Data; + + import javax.validation.constraints.Min; + import javax.validation.constraints.NotNull; + import java.math.BigDecimal; + + + /** + * 创建订单请求VO + * @author Jinxin + * + */ + @Data + @ApiModel(value = "创建订单请求VO") + public class OrderProductListDTO { + @ApiModelProperty(value = "商品skuId", required = true) + @NotNull(message = "商品skuId不能为空") + private Long skuId; + + @ApiModelProperty(value = "数量", required = true) + @NotNull(message = "数量不能为空") + @Min(value = 1, message = "数量不能小于1") + private Integer quantity; + + @ApiModelProperty(value = "消费金", hidden = true) + private BigDecimal consumption; + + @ApiModelProperty(value = "运费", hidden = true) + private BigDecimal freightAmount; + + @ApiModelProperty(value = "隐藏 业务过程中的数据", hidden = true) + private Sku sku; + + @ApiModelProperty(value = "隐藏 业务过程中的数据", hidden = true) + private Product product; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/PayNotifyMessageDTO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/PayNotifyMessageDTO.java new file mode 100644 index 0000000..23bc161 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/dto/PayNotifyMessageDTO.java @@ -0,0 +1,34 @@ +package com.ruoyi.mall.domain.dto; + +import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; +import lombok.Data; + +import java.util.Date; + +@Data +public class PayNotifyMessageDTO { + + /**主订单号**/ + private Long outTradeNo; + + /**第三方订单号**/ + private String tradeNo; + + /** + * 交易状态,枚举值: + * SUCCESS:支付成功 + * REFUND:转入退款 + * NOTPAY:未支付 + * CLOSED:已关闭 + * REVOKED:已撤销(仅付款码支付会返回) + * USERPAYING:用户支付中(仅付款码支付会返回) + * PAYERROR:支付失败(仅付款码支付会返回) + */ + private Transaction.TradeStateEnum tradeStatus; + + /**支付时间**/ + private Date payTime; + + /**用户id**/ + private Long memberId; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/ApplyRefundForm.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/ApplyRefundForm.java new file mode 100644 index 0000000..096646b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/ApplyRefundForm.java @@ -0,0 +1,34 @@ +package com.ruoyi.mall.domain.form; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@ApiModel("申请售后对象") +public class ApplyRefundForm { + + @ApiModelProperty(value = "订单id", required = true) + private Long orderId; + + @ApiModelProperty(value = "申请售后类型 1:仅退款 2:退货退款", required = true) + private Integer applyRefundType; + + @ApiModelProperty(value = "退款原因", required = true) + private String reason; + + @ApiModelProperty(value = "申请退货数量", required = true) + private Integer quantity; + + @ApiModelProperty(value = "退款金额") + private BigDecimal refundAmount; + + @ApiModelProperty(value = "描述") + private String description; + + @ApiModelProperty("凭证图片以逗号隔开") + private String proofPics; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/CancelOrderForm.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/CancelOrderForm.java new file mode 100644 index 0000000..8eff190 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/CancelOrderForm.java @@ -0,0 +1,14 @@ +package com.ruoyi.mall.domain.form; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel("取消订单请求") +public class CancelOrderForm { + @ApiModelProperty("要取消的订单id集合") + private List idList; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/DealWithAftersaleForm.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/DealWithAftersaleForm.java new file mode 100644 index 0000000..05f34ac --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/DealWithAftersaleForm.java @@ -0,0 +1,23 @@ + package com.ruoyi.mall.domain.form; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + + + @Data + @ApiModel(value = "商城售后订单处理操作请求体") + public class DealWithAftersaleForm { + @ApiModelProperty(name = "orderId",value = "订单id",required = true,dataType = "Long") + @NotBlank(message = "订单id不能为空") + private Long orderId; + + @ApiModelProperty(name = "optType",value = "操作类型 1同意 2拒绝 3确认收货",required = true,dataType = "String") + @NotNull(message = "操作类型不能为空") + private Integer optType; + + @ApiModelProperty(name = "remark",value = "拒绝理由 操作类型为2时必填",required = true,dataType = "String") + private String remark; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderCreateForm.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderCreateForm.java new file mode 100644 index 0000000..c5029d1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderCreateForm.java @@ -0,0 +1,37 @@ + package com.ruoyi.mall.domain.form; + + import com.ruoyi.mall.domain.dto.OrderProductListDTO; + import io.swagger.annotations.ApiModel; + import io.swagger.annotations.ApiModelProperty; + import lombok.Data; + + import java.util.List; + + + /** + * 创建订单请求VO + * @author Jinxin + * + */ + @Data + @ApiModel(value = "创建订单请求VO") + public class OrderCreateForm { + @ApiModelProperty(value = "商品购买明细",required = true) + private List skuList; + + @ApiModelProperty(value = "收货地址id") + private Long receiveAddressId; + + @ApiModelProperty(value = "收货方式 1:快递 2:自提 代理商只有1", required = false) + private Integer deliveryType = 1; + + @ApiModelProperty(value = "支付方式:1-支付宝,2-微信(默认)", required = false, allowableValues = "1,2") +// @NotNull(message = "支付方式不能为空") + private Integer payType; + + @ApiModelProperty(value = "订单备注") + private String note; + + @ApiModelProperty(value = "订单来源 购物车是 cart") + private String from; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderPayForm.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderPayForm.java new file mode 100644 index 0000000..5d46650 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderPayForm.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.domain.form; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("订单支付请求体") +public class OrderPayForm { + @ApiModelProperty(value = "支付id", required = true) + private Long payId; + + @ApiModelProperty(value = "支付方式: 1-支付宝 2-微信(默认)", required = true) + private Integer type; + + @ApiModelProperty(value = "用户id", hidden = true) + private Long memberId; + + @ApiModelProperty(value = "微信支付方式 1:app 2:小程序") + private Integer wechatType; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderSubmitForm.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderSubmitForm.java new file mode 100644 index 0000000..d57467a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/OrderSubmitForm.java @@ -0,0 +1,27 @@ +package com.ruoyi.mall.domain.form; + +import com.ruoyi.mall.domain.dto.OrderProductListDTO; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class OrderSubmitForm { + @NotNull + private Long addressId; + private String note; + /** 支付方式 0:未支付 1:支付宝 2:微信 默认微信 */ + private Integer payType = 2; + /** 订单来源,购物车则为cart */ + private String from; + private Long memberCouponId; + @NotEmpty + private List skuList; + @Data + public static class SkuParam { + private Long skuId; + private Integer quantity; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/UpdateMemberCartForm.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/UpdateMemberCartForm.java new file mode 100644 index 0000000..ccd002a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/form/UpdateMemberCartForm.java @@ -0,0 +1,18 @@ +package com.ruoyi.mall.domain.form; + +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@Data +public class UpdateMemberCartForm { + @NotNull(message = "id 不能为空") + private Long id; + + @NotNull(message = "数量必填") + @Min(value = 0, message = "数量不小于0") + @Max(value = Integer.MAX_VALUE, message = "数量不大于" + Integer.MAX_VALUE) + private Integer num; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/Aftersale.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/Aftersale.java new file mode 100644 index 0000000..ebe984c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/Aftersale.java @@ -0,0 +1,85 @@ +package com.ruoyi.mall.domain.order; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +/** + * 订单售后对象 oms_aftersale + * + * @author zcc + */ +@ApiModel(description="订单售后对象") +@Data +@TableName("oms_aftersale") +public class Aftersale extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + @ApiModelProperty("MEMBER_ID") + @Excel(name = "MEMBER_ID") + private Long memberId; + + @ApiModelProperty("订单id") + @Excel(name = "订单id") + private Long orderId; + + @ApiModelProperty("退款金额") + @Excel(name = "退款金额") + private BigDecimal returnAmount; + + @ApiModelProperty("售后类型:1:退款,2:退货退款") + @Excel(name = "售后类型:1:退款,2:退货退款") + private Integer type; + + @ApiModelProperty("申请状态:0->待处理;1->退货中;2->已完成;3->已拒绝") + @Excel(name = "申请状态:0->待处理;1->退货中;2->已完成;3->已拒绝") + private Integer status; + + @ApiModelProperty("处理时间") + @Excel(name = "处理时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime handleTime; + + @ApiModelProperty("退货数量") + @Excel(name = "退货数量") + private Integer quantity; + + @ApiModelProperty("原因") + @Excel(name = "原因") + private String reason; + + @ApiModelProperty("描述") + @Excel(name = "描述") + private String description; + + @ApiModelProperty("凭证图片,以逗号隔开") + @Excel(name = "凭证图片,以逗号隔开") + private String proofPics; + + @ApiModelProperty("处理备注") + @Excel(name = "处理备注") + private String handleNote; + + @ApiModelProperty("处理人员") + @Excel(name = "处理人员") + private String handleMan; + + @ApiModelProperty("退款快递公司") + @Excel(name = "退款快递公司") + private String refundWpCode; + + @ApiModelProperty("退货快递号") + @Excel(name = "退货快递号") + private String refundWaybillCode; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/AftersaleItem.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/AftersaleItem.java new file mode 100644 index 0000000..fd2cac2 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/AftersaleItem.java @@ -0,0 +1,49 @@ +package com.ruoyi.mall.domain.order; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +/** + * 订单售后对象 oms_aftersale_item + * + * @author zcc + */ +@ApiModel(description="订单售后对象") +@Data +@TableName("oms_aftersale_item") +public class AftersaleItem extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("MEMBER_ID") + @Excel(name = "MEMBER_ID") + private Long memberId; + + @ApiModelProperty("售后单id") + @Excel(name = "售后单id") + private Long aftersaleId; + + @ApiModelProperty("订单id") + @Excel(name = "订单id") + private Long orderId; + + @ApiModelProperty("子订单id") + @Excel(name = "子订单id") + private Long orderItemId; + + @ApiModelProperty("退款金额") + @Excel(name = "退款金额") + private BigDecimal returnAmount; + + @ApiModelProperty("退货数量") + @Excel(name = "退货数量") + private Integer quantity; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/Order.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/Order.java new file mode 100644 index 0000000..0dbe434 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/Order.java @@ -0,0 +1,162 @@ +package com.ruoyi.mall.domain.order; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +/** + * 订单表对象 oms_order + * + * @author zcc + */ +@ApiModel(description="订单表对象") +@Data +@TableName("oms_order") +public class Order extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("订单id") + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + @ApiModelProperty("支付id") + private Long payId; + + @ApiModelProperty("订单编号") + @Excel(name = "订单编号") + private String orderSn; + + @ApiModelProperty("MEMBER_ID") + @Excel(name = "MEMBER_ID") + private Long memberId; + + @ApiModelProperty("用户帐号") + @Excel(name = "用户帐号") + private String memberUsername; + + @ApiModelProperty("订单总金额") + @Excel(name = "订单总金额") + private BigDecimal totalAmount; + + @ApiModelProperty("采购价") + @Excel(name = "采购价") + private BigDecimal purchasePrice; + + @ApiModelProperty("应付金额(实际支付金额)") + @Excel(name = "应付金额", readConverterExp = "实=际支付金额") + private BigDecimal payAmount; + + @ApiModelProperty("运费金额") + @Excel(name = "运费金额") + private BigDecimal freightAmount; + + @ApiModelProperty("支付方式:0->未支付;1->支付宝;2->微信") + @Excel(name = "支付方式:0->未支付;1->支付宝;2->微信") + private Integer payType; + + @ApiModelProperty("订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单") + @Excel(name = "订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单") + private Integer status; + + @ApiModelProperty("退款状态,枚举值:1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功") + @Excel(name = "退款状态,枚举值:1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功") + private Integer aftersaleStatus; + + @ApiModelProperty("物流公司(配送方式)") + @Excel(name = "物流公司(配送方式)") + private String deliveryCompany; + + @ApiModelProperty("物流单号") + @Excel(name = "物流单号") + private String deliverySn; + + @ApiModelProperty("自动确认时间(天)") + @Excel(name = "自动确认时间", readConverterExp = "天=") + private Integer autoConfirmDay; + + @ApiModelProperty("收货人姓名") + @Excel(name = "收货人姓名") + private String receiverName; + + @ApiModelProperty("收货人电话") + @Excel(name = "收货人电话") + private String receiverPhone; + + @ApiModelProperty("加密的手机号") + @Excel(name = "加密的手机号") + private String receiverPhoneEncrypted; + + @ApiModelProperty("收货人邮编") + @Excel(name = "收货人邮编") + private String receiverPostCode; + + @ApiModelProperty("省份/直辖市") + @Excel(name = "省份/直辖市") + private String receiverProvince; + + @ApiModelProperty("城市") + @Excel(name = "城市") + private String receiverCity; + + @ApiModelProperty("区") + @Excel(name = "区") + private String receiverDistrict; + + @ApiModelProperty("省份/直辖市id") + @Excel(name = "省份/直辖市id") + private Long receiverProvinceId; + + @ApiModelProperty("城市id") + @Excel(name = "城市id") + private Long receiverCityId; + + @ApiModelProperty("区id") + @Excel(name = "区id") + private Long receiverDistrictId; + + @ApiModelProperty("详细地址") + @Excel(name = "详细地址") + private String receiverDetailAddress; + + @ApiModelProperty("订单备注") + @Excel(name = "订单备注") + private String note; + + @ApiModelProperty("商家备注") + @Excel(name = "商家备注") + private String merchantNote; + + @ApiModelProperty("确认收货状态:0->未确认;1->已确认") + @Excel(name = "确认收货状态:0->未确认;1->已确认") + private Integer confirmStatus; + + @ApiModelProperty("删除状态:0->未删除;1->已删除") + @Excel(name = "删除状态:0->未删除;1->已删除") + private Integer deleteStatus; + + @ApiModelProperty("支付时间") + @Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime paymentTime; + + @ApiModelProperty("发货时间") + @Excel(name = "发货时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime deliveryTime; + + @ApiModelProperty("确认收货时间") + @Excel(name = "确认收货时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime receiveTime; + + @ApiModelProperty("优惠券ID") + private Long memberCouponId; + + @ApiModelProperty("优惠券金额") + private BigDecimal couponAmount; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderDeliveryHistory.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderDeliveryHistory.java new file mode 100644 index 0000000..d26e6b2 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderDeliveryHistory.java @@ -0,0 +1,35 @@ +package com.ruoyi.mall.domain.order; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +/** + * 订单发货记录对象 oms_order_delivery_history + * + * @author zcc + */ +@ApiModel(description="订单发货记录对象") +@Data +@TableName("oms_order_delivery_history") +public class OrderDeliveryHistory extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("订单id") + @Excel(name = "订单id") + private Long orderId; + + @ApiModelProperty("物流公司(配送方式)") + @Excel(name = "物流公司(配送方式)") + private String deliveryCompany; + + @ApiModelProperty("物流单号") + @Excel(name = "物流单号") + private String deliverySn; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderItem.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderItem.java new file mode 100644 index 0000000..68f1902 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderItem.java @@ -0,0 +1,84 @@ +package com.ruoyi.mall.domain.order; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +/** + * 订单中所包含的商品对象 oms_order_item + * + * @author zcc + */ +@ApiModel(description="订单中所包含的商品对象") +@Data +@TableName("oms_order_item") +public class OrderItem extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + @ApiModelProperty("订单id") + @Excel(name = "订单id") + private Long orderId; + + @ApiModelProperty("PRODUCT_ID") + @Excel(name = "PRODUCT_ID") + private Long productId; + + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + private String outProductId; + + @ApiModelProperty("商品sku id") + @Excel(name = "商品sku id") + private Long skuId; + + @ApiModelProperty("sku编码") + @Excel(name = "sku编码") + private String outSkuId; + + @ApiModelProperty("商品快照id") + @Excel(name = "商品快照id") + private Long productSnapshotId; + + @ApiModelProperty("sku快照id") + @Excel(name = "sku快照id") + private Long skuSnapshotId; + + @ApiModelProperty("展示图片") + @Excel(name = "展示图片") + private String pic; + + @ApiModelProperty("PRODUCT_NAME") + @Excel(name = "PRODUCT_NAME") + private String productName; + + @ApiModelProperty("销售价格") + @Excel(name = "销售价格") + private BigDecimal salePrice; + + @ApiModelProperty("采购价") + @Excel(name = "采购价") + private BigDecimal purchasePrice; + + @ApiModelProperty("购买数量") + @Excel(name = "购买数量") + private Integer quantity; + + @ApiModelProperty("商品分类id") + @Excel(name = "商品分类id") + private Long productCategoryId; + + @ApiModelProperty("商品sku属性:[{\"key\":\"颜色\",\"value\":\"颜色\"},{\"key\":\"容量\",\"value\":\"4G\"}]") + @Excel(name = "商品sku属性:[{\"key\":\"颜色\",\"value\":\"颜色\"},{\"key\":\"容量\",\"value\":\"4G\"}]") + private String spData; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderOperateHistory.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderOperateHistory.java new file mode 100644 index 0000000..4628ff0 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/OrderOperateHistory.java @@ -0,0 +1,43 @@ +package com.ruoyi.mall.domain.order; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +/** + * 订单操作历史记录对象 oms_order_operate_history + * + * @author zcc + */ +@ApiModel(description="订单操作历史记录对象") +@Data +@TableName("oms_order_operate_history") +public class OrderOperateHistory extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("订单id") + @Excel(name = "订单id") + private Long orderId; + + @ApiModelProperty("订单号") + @Excel(name = "订单号") + private String orderSn; + + @ApiModelProperty("操作人:用户;系统;后台管理员") + @Excel(name = "操作人:用户;系统;后台管理员") + private String operateMan; + + @ApiModelProperty("订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单") + @Excel(name = "订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单") + private Integer orderStatus; + + @ApiModelProperty("备注") + @Excel(name = "备注") + private String note; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/WechatPaymentHistory.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/WechatPaymentHistory.java new file mode 100644 index 0000000..bd83254 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/order/WechatPaymentHistory.java @@ -0,0 +1,73 @@ +package com.ruoyi.mall.domain.order; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +/** + * 微信订单表对象 oms_wechat_payment_history + * + * @author zcc + */ +@ApiModel(description="微信订单表对象") +@Data +@TableName("oms_wechat_payment_history") +public class WechatPaymentHistory extends BaseAudit { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("payment_id") + @Excel(name = "payment_id") + private String paymentId; + + @ApiModelProperty("用户 ID") + @Excel(name = "用户 ID") + private Long memberId; + + @ApiModelProperty("OPENID") + @Excel(name = "OPENID") + private String openid; + + @ApiModelProperty("真实姓名,提现需要") + @Excel(name = "真实姓名,提现需要") + private String realName; + + @ApiModelProperty("标题|商品名称") + @Excel(name = "标题|商品名称") + private String title; + + @ApiModelProperty("订单号 支付时是payId 其他为orderId") + @Excel(name = "订单号 支付时是payId 其他为orderId") + private Long orderId; + + @ApiModelProperty("金额,单位分") + @Excel(name = "金额,单位分") + private BigDecimal money; + + @ApiModelProperty("交易类型(1为支付 2为提现 3为退款)") + @Excel(name = "交易类型", readConverterExp = "1=为支付,2=为提现,3=为退款") + private Integer opType; + + @ApiModelProperty("状态(0:未完成交易 1:完成关键交易)") + @Excel(name = "状态", readConverterExp = "0=:未完成交易,1=:完成关键交易") + private Integer paymentStatus; + + @ApiModelProperty("备注") + @Excel(name = "备注") + private String remark; + + @ApiModelProperty("附加数据") + @Excel(name = "附加数据") + private String attach; + + @ApiModelProperty("响应内容") + @Excel(name = "响应内容") + private String responseBody; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/BrandQuery.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/BrandQuery.java new file mode 100644 index 0000000..2a53665 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/BrandQuery.java @@ -0,0 +1,27 @@ +package com.ruoyi.mall.domain.query; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 品牌管理 查询 对象 + * + * @author zcc + */ +@ApiModel(description="品牌管理 查询 对象") +@Data +public class BrandQuery { + @ApiModelProperty("NAME 精确匹配") + private String nameLike; + + @ApiModelProperty("SORT 精确匹配") + private Integer sort; + + @ApiModelProperty("SHOW_STATUS 精确匹配") + private Integer showStatus; + + @ApiModelProperty("品牌logo 精确匹配") + private String logo; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/MemberCartQuery.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/MemberCartQuery.java new file mode 100644 index 0000000..eaed48d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/MemberCartQuery.java @@ -0,0 +1,42 @@ +package com.ruoyi.mall.domain.query; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 购物车 查询 对象 + * + * @author zcc + */ +@ApiModel(description="购物车 查询 对象") +@Data +public class MemberCartQuery { + @ApiModelProperty("0->失效;1->有效 精确匹配") + private Integer status; + + @ApiModelProperty("用户ID 精确匹配") + private Long memberId; + + @ApiModelProperty("商品ID 精确匹配") + private Long productId; + + @ApiModelProperty("展示图片 精确匹配") + private String pic; + + @ApiModelProperty("SKU ID 精确匹配") + private Long skuId; + + @ApiModelProperty("商品名称 精确匹配") + private String productName; + + @ApiModelProperty("商品属性 精确匹配") + private String spData; + + @ApiModelProperty("商品数量 精确匹配") + private Integer quantity; + + @ApiModelProperty("用户手机号") + private String phone; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/ProductCategoryQuery.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/ProductCategoryQuery.java new file mode 100644 index 0000000..910bc2c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/ProductCategoryQuery.java @@ -0,0 +1,33 @@ +package com.ruoyi.mall.domain.query; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商品分类 查询 对象 + * + * @author zcc + */ +@ApiModel(description="商品分类 查询 对象") +@Data +public class ProductCategoryQuery { + @ApiModelProperty("上级分类的编号:0表示一级分类 精确匹配") + private Long parentId; + + @ApiModelProperty("NAME 精确匹配") + private String nameLike; + + @ApiModelProperty("分类级别:0->1级;1->2级 精确匹配") + private Integer level; + + @ApiModelProperty("显示状态:0->不显示;1->显示 精确匹配") + private Integer showStatus; + + @ApiModelProperty("SORT 精确匹配") + private Integer sort; + + @ApiModelProperty("图标 精确匹配") + private String icon; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/ProductQuery.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/ProductQuery.java new file mode 100644 index 0000000..5230e71 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/ProductQuery.java @@ -0,0 +1,81 @@ +package com.ruoyi.mall.domain.query; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 商品信息 查询 对象 + * + * @author zcc + */ +@ApiModel(description="商品信息 查询 对象") +@Data +public class ProductQuery { + @ApiModelProperty("BRAND_ID 精确匹配") + private Long brandId; + + @ApiModelProperty("CATEGORY_ID 精确匹配") + private Long categoryId; + + @ApiModelProperty("商品编码 精确匹配") + private String outProductId; + + @ApiModelProperty("NAME 精确匹配") + private String nameLike; + + @ApiModelProperty("主图 精确匹配") + private String pic; + + @ApiModelProperty("画册图片,连产品图片限制为5张,以逗号分割 精确匹配") + private String albumPics; + + @ApiModelProperty("上架状态:0->下架;1->上架 精确匹配") + private Integer publishStatus; + + @ApiModelProperty("排序 精确匹配") + private Integer sort; + + @ApiModelProperty("PRICE 精确匹配") + private BigDecimal price; + + @ApiModelProperty("单位 精确匹配") + private String unit; + + @ApiModelProperty(name = "商品销售属性,json格式") + private String productAttr; + + @ApiModelProperty("商品重量,默认为克 精确匹配") + private BigDecimal weight; + + @ApiModelProperty("产品详情网页内容 精确匹配") + private String detailHtml; + + @ApiModelProperty("移动端网页详情 精确匹配") + private String detailMobileHtml; + + @ApiModelProperty("品牌名称 精确匹配") + private String brandNameLike; + + @ApiModelProperty("商品分类名称 精确匹配") + private String productCategoryNameLike; + + @ApiModelProperty("排序字段") + private String orderField = "sort"; + + @ApiModelProperty("排序规则") + private String orderSort = "desc"; + + @ApiModelProperty("搜索关键字") + private String search; + private String storeId; + + //排查的id + private List excludeProductIds; + + private List ids; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/SkuQuery.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/SkuQuery.java new file mode 100644 index 0000000..f6a4a83 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/query/SkuQuery.java @@ -0,0 +1,32 @@ +package com.ruoyi.mall.domain.query; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * sku信息 查询 对象 + * + * @author zcc + */ +@ApiModel(description="sku信息 查询 对象") +@Data +public class SkuQuery { + @ApiModelProperty("PRODUCT_ID 精确匹配") + private Long productId; + + @ApiModelProperty("sku编码 精确匹配") + private String outSkuId; + + @ApiModelProperty("PRICE 精确匹配") + private BigDecimal price; + + @ApiModelProperty("展示图片 精确匹配") + private String pic; + + @ApiModelProperty("商品销售属性,json格式 精确匹配") + private String spData; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AftersaleItemVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AftersaleItemVO.java new file mode 100644 index 0000000..c1f8053 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AftersaleItemVO.java @@ -0,0 +1,36 @@ +package com.ruoyi.mall.domain.vo; + +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 订单售后 数据视图对象 + * + * @author zcc + */ +@Data +public class AftersaleItemVO extends BaseAudit { + /** ID */ + private Long id; + /** MEMBER_ID */ + @Excel(name = "MEMBER_ID") + private Long memberId; + /** 售后单id */ + @Excel(name = "售后单id") + private Long aftersaleId; + /** 订单id */ + @Excel(name = "订单id") + private Long orderId; + /** 子订单id */ + @Excel(name = "子订单id") + private Long orderItemId; + /** 退款金额 */ + @Excel(name = "退款金额") + private BigDecimal returnAmount; + /** 退货数量 */ + @Excel(name = "退货数量") + private Integer quantity; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AftersaleRefundInfoVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AftersaleRefundInfoVO.java new file mode 100644 index 0000000..49152fc --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AftersaleRefundInfoVO.java @@ -0,0 +1,70 @@ +package com.ruoyi.mall.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 订单售后 数据视图对象 + * + * @author sjm + */ +@Data +public class AftersaleRefundInfoVO extends BaseAudit { + /** ID */ + private Long id; + /** MEMBER_ID */ + @Excel(name = "MEMBER_ID") + private Long memberId; + /** 订单id */ + @Excel(name = "订单id") + private Long orderId; + /** 退款金额 */ + @Excel(name = "退款金额") + private BigDecimal returnAmount; + /** 售后类型:1:退款,2:退货退款 */ + @Excel(name = "售后类型:1:退款,2:退货退款") + private Integer type; + /** 申请状态:0->待处理;1->退货中;2->已完成;3->已拒绝 */ + @Excel(name = "申请状态:0->待处理;1->退货中;2->已完成;3->已拒绝") + private Integer status; + /** 处理时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "处理时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime handleTime; + /** 退款快递公司 */ + @Excel(name = "退款快递公司") + private String refundWpCode; + /** 退货快递号 */ + @Excel(name = "退货快递号") + private String refundWaybillCode; + /** 退货数量 */ + @Excel(name = "退货数量") + private Integer quantity; + /** 原因 */ + @Excel(name = "原因") + private String reason; + /** 描述 */ + @Excel(name = "描述") + private String description; + /** 凭证图片,以逗号隔开 */ + @Excel(name = "凭证图片,以逗号隔开") + private String proofPics; + /** 处理备注 */ + @Excel(name = "处理备注") + private String handleNote; + /** 处理人员 */ + @Excel(name = "处理人员") + private String handleMan; + + /** + * item + */ + private List aftersaleItemList; + private List orderItemList; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AppOrderVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AppOrderVO.java new file mode 100644 index 0000000..f05dc76 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AppOrderVO.java @@ -0,0 +1,78 @@ +package com.ruoyi.mall.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.mall.domain.order.OrderItem; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class AppOrderVO { + + @ApiModelProperty("订单id") + private Long orderId; + + @ApiModelProperty("支付id") + private Long payId; + + @ApiModelProperty("订单编号") + private String orderSn; + + @ApiModelProperty("会员id") + private Long memberId; + + @ApiModelProperty("订单总金额") + private BigDecimal totalAmount; + + @ApiModelProperty("应付金额") + private BigDecimal payAmount; + + private BigDecimal couponAmount; + + @ApiModelProperty("订单状态 0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭") + private Integer status; + + @ApiModelProperty("售后状态") + private Integer aftersaleStatus; + + @ApiModelProperty("订单Item") + private List orderItemList; + + @ApiModelProperty("订单备注") + private String note; + + @ApiModelProperty("物流单号") + private String deliverySn; + + @ApiModelProperty("下单时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("支付时间") + private LocalDateTime paymentTime; + + @ApiModelProperty("收货人姓名") + private String receiverName; + + @ApiModelProperty("收货人手机号") + private String receiverPhone; + + @ApiModelProperty("省份/直辖市") + private String receiverProvince; + + @ApiModelProperty("城市") + private String receiverCity; + + @ApiModelProperty("区") + private String receiverDistrict; + + @ApiModelProperty("详细地址") + private String receiverDetailAddress; + + @ApiModelProperty("支付倒计时") + private Long timeToPay; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AppProductVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AppProductVO.java new file mode 100644 index 0000000..76302b9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/AppProductVO.java @@ -0,0 +1,13 @@ +package com.ruoyi.mall.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class AppProductVO { + private Long id; + private String pic; + private String name; + private BigDecimal price; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/CountOrderVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/CountOrderVO.java new file mode 100644 index 0000000..5f1b03c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/CountOrderVO.java @@ -0,0 +1,22 @@ +package com.ruoyi.mall.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("统计订单数量VO") +public class CountOrderVO { + + @ApiModelProperty(value = "待付款订单数量", dataType = "Integer") + private Integer unpaid; + + @ApiModelProperty(value = "待发货订单数量", dataType = "Integer") + private Integer nosend; + + @ApiModelProperty(value = "待收货订单数量", dataType = "Integer") + private Integer noget; + + @ApiModelProperty(value = "售后订单数量", dataType = "Integer") + private Integer aftersale; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/MemberCartVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/MemberCartVO.java new file mode 100644 index 0000000..d5b1e70 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/MemberCartVO.java @@ -0,0 +1,53 @@ +package com.ruoyi.mall.domain.vo; + +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 购物车 数据视图对象 + * + * @author zcc + */ +@Data +public class MemberCartVO extends BaseAudit { + /** 购物车表ID */ + private Long id; + /** 0->失效;1->有效 */ + @Excel(name = "0->失效;1->有效") + private Integer status; + /** 用户ID */ + @Excel(name = "用户ID") + private Long memberId; + private String nickname; + private String mark; + /** 商品ID */ + @Excel(name = "商品ID") + private Long productId; + /** 展示图片 */ + @Excel(name = "展示图片") + private String pic; + /** SKU ID */ + @Excel(name = "SKU ID") + private Long skuId; + /** PRODUCT_NAME */ + @Excel(name = "PRODUCT_NAME") + private String productName; + /** 商品属性 */ + @Excel(name = "商品属性") + private String spData; + /** 商品数量 */ + @Excel(name = "商品数量") + private Integer quantity; + /** 加入时间 */ + private LocalDateTime createTime; + /** sku价格 */ + private BigDecimal price; + /** sku是否存在 */ + private Integer skuIfExist; + /** 隐藏四位的手机号 */ + private String phoneHidden; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderCalcVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderCalcVO.java new file mode 100644 index 0000000..3844947 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderCalcVO.java @@ -0,0 +1,20 @@ +package com.ruoyi.mall.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +@ApiModel("下单前校验返回数据") +public class OrderCalcVO { + @ApiModelProperty("sku数据") + private List skuList; + @ApiModelProperty("商品总金额") + private BigDecimal productTotalAmount; + @ApiModelProperty("订单总金额") + private BigDecimal orderTotalAmount; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderItemVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderItemVO.java new file mode 100644 index 0000000..ba526cb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderItemVO.java @@ -0,0 +1,60 @@ +package com.ruoyi.mall.domain.vo; + +import com.ruoyi.basic.domain.model.BaseAudit; +import com.ruoyi.common.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 订单中所包含的商品 数据视图对象 + * + * @author zcc + */ +@Data +public class OrderItemVO extends BaseAudit { + /** ID */ + private Long id; + /** 订单id */ + @Excel(name = "订单id") + private Long orderId; + /** PRODUCT_ID */ + @Excel(name = "PRODUCT_ID") + private Long productId; + /** 商品编码 */ + @Excel(name = "商品编码") + private String outProductId; + /** 商品sku id */ + @Excel(name = "商品sku id") + private Long skuId; + /** sku编码 */ + @Excel(name = "sku编码") + private String outSkuId; + /** 商品快照id */ + @Excel(name = "商品快照id") + private Long productSnapshotId; + /** sku快照id */ + @Excel(name = "sku快照id") + private Long skuSnapshotId; + /** 展示图片 */ + @Excel(name = "展示图片") + private String pic; + /** PRODUCT_NAME */ + @Excel(name = "PRODUCT_NAME") + private String productName; + /** 销售价格 */ + @Excel(name = "销售价格") + private BigDecimal salePrice; + /** 采购价 */ + @Excel(name = "采购价") + private BigDecimal purchasePrice; + /** 购买数量 */ + @Excel(name = "购买数量") + private Integer quantity; + /** 商品分类id */ + @Excel(name = "商品分类id") + private Long productCategoryId; + /** 商品sku属性:[{\"key\":\"颜色\",\"value\":\"颜色\"},{\"key\":\"容量\",\"value\":\"4G\"}] */ + @Excel(name = "商品sku属性:[{\"key\":\"颜色\",\"value\":\"颜色\"},{\"key\":\"容量\",\"value\":\"4G\"}]") + private String spData; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderPayVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderPayVO.java new file mode 100644 index 0000000..b635659 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/OrderPayVO.java @@ -0,0 +1,43 @@ +package com.ruoyi.mall.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author 86199 + */ +@Data +@ApiModel("支付响应") +public class OrderPayVO { + @ApiModelProperty(value = "支付方式:1-支付宝,2-微信(默认)", dataType = "Integer") + private Integer payType; + + @ApiModelProperty("nonceStr") + private String nonceStr; + + private String timeStamp; + + @ApiModelProperty("packageValue") + private String packageValue; + + //app + @ApiModelProperty("appId") + private String appId; + + @ApiModelProperty("partnerId") + private String partnerId; + + @ApiModelProperty("prepayId") + private String prepayId; + + @ApiModelProperty("签名") + private String sign; + + //小程序 + @ApiModelProperty("signType") + private String signType; + + @ApiModelProperty("签名") + private String paySign; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/ProductDetailVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/ProductDetailVO.java new file mode 100644 index 0000000..bc49a93 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/ProductDetailVO.java @@ -0,0 +1,18 @@ +package com.ruoyi.mall.domain.vo; + +import com.ruoyi.course.domain.time.RespBusinessClaTimeCalendar; +import com.ruoyi.mall.domain.Brand; +import com.ruoyi.mall.domain.Product; +import com.ruoyi.mall.domain.Sku; +import lombok.Data; + +import java.util.List; + +@Data +public class ProductDetailVO { + private Product product; + private List skus; + private Brand brand; + + private RespBusinessClaTimeCalendar claTimeCalendar; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/ProductVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/ProductVO.java new file mode 100644 index 0000000..0e66708 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/ProductVO.java @@ -0,0 +1,67 @@ +package com.ruoyi.mall.domain.vo; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.mall.domain.Sku; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 商品信息 数据视图对象 + * + * @author zcc + */ +@Data +public class ProductVO { + /** ID */ + private Long id; + /** BRAND_ID */ + @Excel(name = "BRAND_ID") + private Long brandId; + /** CATEGORY_ID */ + @Excel(name = "CATEGORY_ID") + private Long categoryId; + /** 商品编码 */ + @Excel(name = "商品编码") + private String outProductId; + /** NAME */ + @Excel(name = "NAME") + private String name; + /** 主图 */ + @Excel(name = "主图") + private String pic; + /** 画册图片,连产品图片限制为5张,以逗号分割 */ + @Excel(name = "画册图片,连产品图片限制为5张,以逗号分割") + private String albumPics; + /** 上架状态:0->下架;1->上架 */ + @Excel(name = "上架状态:0->下架;1->上架") + private Integer publishStatus; + /** 排序 */ + @Excel(name = "排序") + private Integer sort; + /** PRICE */ + @Excel(name = "PRICE") + private BigDecimal price; + /** 单位 */ + @Excel(name = "单位") + private String unit; + /** 商品重量,默认为克 */ + @Excel(name = "商品重量,默认为克") + private BigDecimal weight; + /** 产品详情网页内容 */ + @Excel(name = "产品详情网页内容") + private String detailHtml; + /** 移动端网页详情 */ + @Excel(name = "移动端网页详情") + private String detailMobileHtml; + /** 品牌名称 */ + @Excel(name = "品牌名称") + private String brandName; + /** 商品分类名称 */ + @Excel(name = "商品分类名称") + private String productCategoryName; + @Excel(name = "商品销售属性,json格式") + private String productAttr; + private List skuList; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/SkuViewVO.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/SkuViewVO.java new file mode 100644 index 0000000..b7918b8 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/vo/SkuViewVO.java @@ -0,0 +1,32 @@ +package com.ruoyi.mall.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * sku渲染详情 + * + * @author Jinxin + */ +@Data +@ApiModel(value = "sku渲染详情") +public class SkuViewVO { + private Long productId; + private Long skuId; + @ApiModelProperty(value = "商品名称") + private String productName; + @ApiModelProperty(value = "销售属性") + private String spData; + @ApiModelProperty(value = "购买数量") + private Integer quantity; + @ApiModelProperty(value = "主图") + private String pic; + @ApiModelProperty(value = "售价") + private BigDecimal price; + @ApiModelProperty(value = "库存数") + private Integer stock; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AddressMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AddressMapper.java new file mode 100644 index 0000000..f56897f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AddressMapper.java @@ -0,0 +1,14 @@ +package com.ruoyi.mall.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.Address; + +import java.util.List; + + +public interface AddressMapper extends BaseMapper
{ + + List
selectByEntity(Address address); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AftersaleItemMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AftersaleItemMapper.java new file mode 100644 index 0000000..af9485a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AftersaleItemMapper.java @@ -0,0 +1,25 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.order.AftersaleItem; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 订单售后Mapper接口 + * + * @author zcc + */ +public interface AftersaleItemMapper extends BaseMapper { + /** + * 查询订单售后列表 + * + * @param aftersaleItem 订单售后 + * @return 订单售后集合 + */ + List selectByEntity(AftersaleItem aftersaleItem); + + Integer insertBatch(@Param("list") List list); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AftersaleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AftersaleMapper.java new file mode 100644 index 0000000..de6c24b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/AftersaleMapper.java @@ -0,0 +1,23 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.order.Aftersale; + +import java.util.List; + +/** + * 订单售后Mapper接口 + * + * @author zcc + */ +public interface AftersaleMapper extends BaseMapper { + /** + * 查询订单售后列表 + * + * @param aftersale 订单售后 + * @return 订单售后集合 + */ + List selectByEntity(Aftersale aftersale); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/BrandMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/BrandMapper.java new file mode 100644 index 0000000..4233411 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/BrandMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.Brand; + +import java.util.List; + +/** + * 品牌管理Mapper接口 + * + * @author zcc + */ +public interface BrandMapper extends BaseMapper { + /** + * 查询品牌管理列表 + * + * @param brand 品牌管理 + * @return 品牌管理集合 + */ + List selectByEntity(Brand brand); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopAddressMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberAddressMapper.java similarity index 50% rename from ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopAddressMapper.java rename to ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberAddressMapper.java index 4b421fc..bf2824f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopAddressMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberAddressMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.shop.mapper; +package com.ruoyi.mall.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.ShopAddress; +import com.ruoyi.mall.domain.MemberAddress; /** *

@@ -12,6 +12,6 @@ import com.ruoyi.shop.domain.ShopAddress; * @author xn * @since 2022-09-29 */ -public interface ShopAddressMapper extends BaseMapper { +public interface MemberAddressMapper extends BaseMapper { } diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberCartMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberCartMapper.java new file mode 100644 index 0000000..169f481 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberCartMapper.java @@ -0,0 +1,32 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.MemberCart; +import com.ruoyi.mall.domain.query.MemberCartQuery; +import com.ruoyi.mall.domain.vo.MemberCartVO; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 购物车Mapper接口 + * + * @author zcc + */ +public interface MemberCartMapper extends BaseMapper { + /** + * 查询购物车列表 + * + * @param memberCart 购物车 + * @return 购物车集合 + */ + List selectByEntity(MemberCart memberCart); + + /** + * + */ + List selectByPage(MemberCartQuery query); + + int statAddCount(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberWechatMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberWechatMapper.java new file mode 100644 index 0000000..0922c2f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/MemberWechatMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.MemberWechat; + +import java.util.List; + +/** + * 用户微信信息Mapper接口 + * + * @author zcc + */ +public interface MemberWechatMapper extends BaseMapper { + /** + * 查询用户微信信息列表 + * + * @param memberWechat 用户微信信息 + * @return 用户微信信息集合 + */ + List selectByEntity(MemberWechat memberWechat); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderItemMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderItemMapper.java new file mode 100644 index 0000000..f07cdc5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderItemMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.order.OrderItem; + +import java.util.List; + +/** + * 订单中所包含的商品Mapper接口 + * + * @author zcc + */ +public interface OrderItemMapper extends BaseMapper { + /** + * 查询订单中所包含的商品列表 + * + * @param orderItem 订单中所包含的商品 + * @return 订单中所包含的商品集合 + */ + List selectByEntity(OrderItem orderItem); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderMapper.java new file mode 100644 index 0000000..ff3281b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderMapper.java @@ -0,0 +1,41 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.order.Order; +import com.ruoyi.mall.domain.vo.AppOrderVO; +import com.ruoyi.mall.domain.vo.CountOrderVO; +import org.apache.ibatis.annotations.Param; +import org.checkerframework.checker.units.qual.A; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 订单表Mapper接口 + * + * @author zcc + */ +public interface OrderMapper extends BaseMapper { + /** + * 查询订单表列表 + * + * @param order 订单表 + * @return 订单表集合 + */ + List selectByEntity(Order order); + + + List orderPage(@Param("status") Integer status, @Param("memberId")Long memberId); + + AppOrderVO selectOrderDetail(Long orderId); + + CountOrderVO countByStatusAndMemberId(Long memberId); + + Integer cancelBatch(@Param("list") List orderList); + + + + Integer statWaitDelivered(); + + int statDealMember(@Param("startTime") LocalDateTime startTime,@Param("endTime") LocalDateTime endTime); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderOperateHistoryMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderOperateHistoryMapper.java new file mode 100644 index 0000000..246e7e8 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/OrderOperateHistoryMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.order.OrderOperateHistory; + +import java.util.List; + +/** + * 订单操作历史记录Mapper接口 + * + * @author zcc + */ +public interface OrderOperateHistoryMapper extends BaseMapper { + /** + * 查询订单操作历史记录列表 + * + * @param orderOperateHistory 订单操作历史记录 + * @return 订单操作历史记录集合 + */ + List selectByEntity(OrderOperateHistory orderOperateHistory); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/ProductCategoryMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/ProductCategoryMapper.java new file mode 100644 index 0000000..4976d5a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/ProductCategoryMapper.java @@ -0,0 +1,27 @@ +package com.ruoyi.mall.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.MemberAddress; +import com.ruoyi.mall.domain.ProductCategory; + +import java.util.List; + +/** + *

+ * 用户地址 Mapper 接口 + *

+ * + * @author xn + * @since 2022-09-29 + */ +public interface ProductCategoryMapper extends BaseMapper { + + /** + * 查询商品分类列表 + * + * @param productCategory 商品分类 + * @return 商品分类集合 + */ + List selectByEntity(ProductCategory productCategory); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/ProductMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/ProductMapper.java new file mode 100644 index 0000000..bd03d9d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/ProductMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.Product; + +import java.util.List; + +/** + * 商品信息Mapper接口 + * + * @author zcc + */ +public interface ProductMapper extends BaseMapper { + /** + * 查询商品信息列表 + * + * @param product 商品信息 + * @return 商品信息集合 + */ + List selectByEntity(Product product); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/SkuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/SkuMapper.java new file mode 100644 index 0000000..2056db5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/SkuMapper.java @@ -0,0 +1,25 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.Sku; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * sku信息Mapper接口 + * + * @author zcc + */ +public interface SkuMapper extends BaseMapper { + /** + * 查询sku信息列表 + * + * @param sku sku信息 + * @return sku信息集合 + */ + List selectByEntity(Sku sku); + + int updateStockById(@Param("skuId")Long skuId, @Param("optDate")LocalDateTime optDate, @Param("quantity")Integer quantity); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/WechatPaymentHistoryMapper.java b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/WechatPaymentHistoryMapper.java new file mode 100644 index 0000000..528d2d8 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/mapper/WechatPaymentHistoryMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.mall.domain.order.WechatPaymentHistory; + +import java.util.List; + +/** + * 微信订单表Mapper接口 + * + * @author zcc + */ +public interface WechatPaymentHistoryMapper extends BaseMapper { + /** + * 查询微信订单表列表 + * + * @param wechatPaymentHistory 微信订单表 + * @return 微信订单表集合 + */ + List selectByEntity(WechatPaymentHistory wechatPaymentHistory); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/MemberAddressService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/MemberAddressService.java new file mode 100644 index 0000000..469cdf9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/MemberAddressService.java @@ -0,0 +1,21 @@ +package com.ruoyi.mall.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.mall.domain.MemberAddress; +import com.ruoyi.mall.domain.dto.AddressDTO; + +import java.util.List; + +/** + *

+ * 用户地址 服务类 + *

+ * + * @author xn + * @since 2022-09-29 + */ +public interface MemberAddressService extends IService { + + List getAddressList(); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/ProductCategoryService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/ProductCategoryService.java new file mode 100644 index 0000000..7938748 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/ProductCategoryService.java @@ -0,0 +1,14 @@ +package com.ruoyi.mall.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.mall.domain.MemberAddress; +import com.ruoyi.mall.domain.ProductCategory; +import com.ruoyi.mall.domain.dto.AddressDTO; + +import java.util.List; +import java.util.Map; + +public interface ProductCategoryService extends IService { + + List getProductCategorys(Map params); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/AftersaleService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/AftersaleService.java new file mode 100644 index 0000000..21b04cb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/AftersaleService.java @@ -0,0 +1,315 @@ +package com.ruoyi.mall.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.enums.AftersaleStatus; +import com.ruoyi.common.enums.OrderRefundStatus; +import com.ruoyi.mall.MemberWechat; +import com.ruoyi.mall.domain.form.DealWithAftersaleForm; +import com.ruoyi.mall.domain.order.*; +import com.ruoyi.mall.mapper.*; +import com.wechat.pay.java.service.refund.model.Refund; +import com.wechat.pay.java.service.refund.model.RefundNotification; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 订单售后Service业务层处理 + * + * @author zcc + */ +@Service +@Slf4j +public class AftersaleService { + @Autowired + private AftersaleMapper aftersaleMapper; + + @Autowired + private OrderMapper orderMapper; + + @Autowired + private OrderItemMapper orderItemMapper; + + @Autowired + private OrderOperateHistoryMapper orderOperateHistoryMapper; + + @Autowired + private SkuMapper skuMapper; + + @Autowired + private WechatPaymentHistoryMapper wechatPaymentHistoryMapper; + @Autowired + private MemberWechatMapper memberWechatMapper; + @Autowired(required = false) + private WechatPayService wechatPayService; + @Autowired + private OrderOperateHistoryMapper operateHistoryMapper; + + + /** + * 新增订单售后 + * + * @param aftersale 订单售后 + * @return 结果 + */ + public int insert(Aftersale aftersale) { + aftersale.setCreateTime(LocalDateTime.now()); + return aftersaleMapper.insert(aftersale); + } + + /** + * 修改订单售后 + * + * @param aftersale 订单售后 + * @return 结果 + */ + public int update(Aftersale aftersale) { + return aftersaleMapper.updateById(aftersale); + } + + + /** + * 售后处理 + * + * @param request 请求体 + * @param userId 操作人 + * @return + */ + @Transactional(rollbackFor = Exception.class) + public void dealWith(DealWithAftersaleForm request, Long userId, String optUserName) { + Order order = orderMapper.selectById(request.getOrderId()); + if (order == null) { + throw new RuntimeException("无该订单"); + } + QueryWrapper aftersaleQw = new QueryWrapper<>(); + aftersaleQw.eq("order_id", request.getOrderId()); + if (request.getOptType() == 3) { + aftersaleQw.eq("status", 1); + } else { + aftersaleQw.eq("status", 0); + } + Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw); + if (aftersale == null) { + throw new RuntimeException("没有售后单"); + } + //售后状态与售后类型是否对应 + if (Constants.OptType.AGREE.equals(request.getOptType()) || Constants.OptType.REFUSE.equals(request.getOptType())) { + if (!AftersaleStatus.APPLY.getType().equals(aftersale.getStatus())) { + throw new RuntimeException("订单状态错误,请刷新页面后重试!"); + } + } else { + if (!AftersaleStatus.WAIT.getType().equals(aftersale.getStatus())) { + throw new RuntimeException("订单状态错误,请刷新页面后重试!"); + } + } + //拒绝则理由必填 + if (Constants.OptType.REFUSE.equals(request.getOptType()) && StrUtil.isBlank(request.getRemark())) { + throw new RuntimeException("请填写拒绝理由"); + } + LocalDateTime optDate = LocalDateTime.now(); + //要创建的订单操作记录,status后续判断再设置 + OrderOperateHistory optHistory = new OrderOperateHistory(); + optHistory.setOrderId(order.getId()); + optHistory.setOrderSn(order.getOrderSn()); + optHistory.setOperateMan("后台管理员"); + optHistory.setCreateTime(optDate); + optHistory.setCreateBy(userId); + optHistory.setUpdateBy(userId); + optHistory.setUpdateTime(optDate); + //封装售后wrapper + UpdateWrapper aftersaleWrapper = new UpdateWrapper<>(); + aftersaleWrapper.eq("order_id", request.getOrderId()); + aftersaleWrapper.eq("status", AftersaleStatus.APPLY.getType()); + aftersaleWrapper.set("handle_man", optUserName); + aftersaleWrapper.set("update_time", optDate); + aftersaleWrapper.set("handle_time", optDate); + aftersaleWrapper.set("update_by", userId); + //封装订单wrapper + UpdateWrapper orderWrapper = new UpdateWrapper<>(); + orderWrapper.eq("id", request.getOrderId()); + orderWrapper.set("update_time", optDate); + orderWrapper.set("update_by", userId); + //更新订单、售后单,创建操作记录 + if (request.getOptType().equals(Constants.OptType.REFUSE)) { + aftersaleWrapper.set("status", AftersaleStatus.REJECT.getType()); + aftersaleWrapper.set("handle_note", request.getRemark()); + orderWrapper.set("aftersale_status", OrderRefundStatus.NO_REFUND.getType()); + optHistory.setOrderStatus(14); + } else if (request.getOptType().equals(Constants.OptType.AGREE)) { + aftersaleWrapper.set("status", AftersaleStatus.WAIT.getType()); + orderWrapper.set("aftersale_status", Objects.equals(aftersale.getType(), 1) ? 3 : 2); + optHistory.setOrderStatus(12); + } else { + //如果是退货退款 order身上的售后状态应该是保持不变的 仅退款的话就进入退款了 + orderWrapper.set("aftersale_status", 3); + int row = orderMapper.update(null, orderWrapper); + if (row != 1) { + throw new RuntimeException("修改订单状态失败"); + } + } + int rows = aftersaleMapper.update(null, aftersaleWrapper); +// if (rows < 1) { +// throw new RuntimeException("更新售后单失败"); +// } + rows = orderMapper.update(null, orderWrapper); + if (rows < 1) { + throw new RuntimeException("更新订单失败"); + } + rows = orderOperateHistoryMapper.insert(optHistory); + if (rows < 1) { + throw new RuntimeException("创建订单操作记录失败"); + } + // 是否需要发起退款 + if ((request.getOptType() == Constants.OptType.GIVING || (request.getOptType() == Constants.OptType.AGREE && aftersale.getType() == 1))) { +// tradeRefund(aftersale, order, optDate, userId); + } + } + + public void tradeRefund(Aftersale returnApply, Order order, LocalDateTime optDate, Long userId) { + //查一下微信订单 + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("order_id", order.getPayId()).eq("op_type", 1); + WechatPaymentHistory history = wechatPaymentHistoryMapper.selectOne(qw); + //查用户的微信信息 + QueryWrapper wechatQw = new QueryWrapper<>(); + wechatQw.eq("member_id", order.getMemberId()); +// MemberWechat memberWechat = memberWechatMapper.selectOne(wechatQw); + //查订单item + QueryWrapper itemQw = new QueryWrapper<>(); + itemQw.eq("order_id", order.getId()); + OrderItem orderItem = orderItemMapper.selectList(itemQw).get(0); + //开始退款 + Refund wechatResponse = wechatPayService.refundPay(returnApply.getId() + "", + order.getPayId() + "", + "https://mall.ichengle.top/api/no-auth/wechat/weChatRefundNotify", + returnApply.getReturnAmount().multiply(new BigDecimal("100")).longValue(), + history.getMoney().multiply(new BigDecimal("100")).longValue(), returnApply.getReason()); + log.info("发起微信退款返回信息,tradeRefund:{}", JSONObject.toJSONString(wechatResponse == null ? "" : wechatResponse)); + + if (wechatResponse != null && Arrays.asList("PROCESSING", "SUCCESS").contains(wechatResponse.getStatus().name())) { + qw = new QueryWrapper<>(); + qw.eq("order_id", order.getId()).eq("op_type", 3); + WechatPaymentHistory refundHistory = wechatPaymentHistoryMapper.selectOne(qw); + if (refundHistory == null) { + WechatPaymentHistory wechatPaymentHistory = new WechatPaymentHistory(); + wechatPaymentHistory.setPaymentId(wechatResponse.getRefundId()); + wechatPaymentHistory.setMemberId(order.getMemberId()); + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(WechatPaymentHistory::getOrderId, order.getPayId()); + queryWrapper.eq(WechatPaymentHistory::getOpType, Constants.PaymentOpType.PAY); + WechatPaymentHistory payHistory = wechatPaymentHistoryMapper.selectOne(queryWrapper); + wechatPaymentHistory.setOpenid(payHistory.getOpenid()); + wechatPaymentHistory.setTitle(orderItem.getProductName()); + wechatPaymentHistory.setOrderId(order.getId()); + wechatPaymentHistory.setMoney(returnApply.getReturnAmount().multiply(new BigDecimal("100"))); + wechatPaymentHistory.setOpType(3); + wechatPaymentHistory.setPaymentStatus(0); + wechatPaymentHistory.setResponseBody(JSON.toJSONString(wechatResponse)); + wechatPaymentHistory.setCreateTime(optDate); + wechatPaymentHistory.setUpdateTime(optDate); + wechatPaymentHistory.setCreateBy(userId); + wechatPaymentHistory.setUpdateBy(userId); + wechatPaymentHistoryMapper.insert(wechatPaymentHistory); + } else { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", refundHistory.getId()) + .set("payment_id", wechatResponse.getRefundId()).set("update_time", optDate); + wechatPaymentHistoryMapper.update(null, updateWrapper); + } + } + } + + /** + * 订单退款回调MQ + * + * @param weChatRefundNotify + */ + @Transactional + public void refundOrderExc(RefundNotification weChatRefundNotify) { + log.info("收到订单回调MQ:" + JSONObject.toJSONString(weChatRefundNotify)); + if ("PROCESSING".equals(weChatRefundNotify.getRefundStatus().name())) { + return; + } + //查一下微信订单 + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("payment_id", weChatRefundNotify.getRefundId()).eq("op_type", 3); + WechatPaymentHistory history = wechatPaymentHistoryMapper.selectOne(qw); + if (history == null) { + log.info("未找到退款单"); + throw new RuntimeException(); + } + LocalDateTime optDate = LocalDateTime.now(); + QueryWrapper orderQw = new QueryWrapper<>(); + orderQw.eq("id", history.getOrderId()); + Order order = orderMapper.selectOne(orderQw); + if (order.getStatus() == OrderRefundStatus.SUCCESS.getType()) { + log.info("订单已经是退款成功状态"); + throw new RuntimeException(); + } + QueryWrapper aftersaleQw = new QueryWrapper<>(); + aftersaleQw.eq("order_id", history.getOrderId()).eq("status", AftersaleStatus.WAIT.getType()); + if ("SUCCESS".equals(weChatRefundNotify.getRefundStatus().name())) { + //更改订单表 + UpdateWrapper orderUpdateWrapper = new UpdateWrapper<>(); + orderUpdateWrapper.eq("id", history.getOrderId()) + .set("aftersale_status", OrderRefundStatus.SUCCESS.getType()); + orderMapper.update(null, orderUpdateWrapper); + + //更改 售后表 + UpdateWrapper aftersaleWrapper = new UpdateWrapper<>(); + aftersaleWrapper.eq("order_id", history.getOrderId()).set("status", AftersaleStatus.SUCCESS.getType()); + aftersaleMapper.update(null, aftersaleWrapper); + + //更改 微信表 + UpdateWrapper paymentWrapper = new UpdateWrapper<>(); + paymentWrapper.eq("payment_id", weChatRefundNotify.getRefundId()).eq("op_type", 3) + .set("payment_status", 1); + wechatPaymentHistoryMapper.update(null, paymentWrapper); + OrderOperateHistory optHistory = new OrderOperateHistory(); + optHistory.setOrderId(order.getId()); + optHistory.setOperateMan("系统"); + optHistory.setCreateTime(optDate); + optHistory.setCreateBy(order.getMemberId()); + optHistory.setUpdateBy(order.getMemberId()); + optHistory.setUpdateTime(optDate); + optHistory.setOrderStatus(13); + operateHistoryMapper.insert(optHistory); + // 回滚商品和sku销量 + OrderItem orderItem = orderItemMapper.selectOne(new QueryWrapper().eq("order_id", order.getId())); + skuMapper.updateStockById(orderItem.getSkuId(), LocalDateTime.now(), -1 * orderItem.getQuantity()); + //退还优惠券 +// if (order.getMemberCouponId() != null) { +// memberCouponService.backCoupon(Arrays.asList(order.getMemberCouponId())); +// } + } else { + //更改订单表 + UpdateWrapper orderUpdateWrapper = new UpdateWrapper<>(); + orderUpdateWrapper.eq("id", history.getOrderId()) + .set("aftersale_status", OrderRefundStatus.FAIL.getType()); + orderMapper.update(null, orderUpdateWrapper); + } + } + + public Aftersale queryAfterSale(Long orderId) { + QueryWrapper itemQw = new QueryWrapper<>(); + itemQw.eq("order_id",orderId); + itemQw.in("status",Arrays.asList(AftersaleStatus.APPLY.getType(),AftersaleStatus.WAIT.getType())); + return aftersaleMapper.selectOne(itemQw); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/MemberCartService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/MemberCartService.java new file mode 100644 index 0000000..0a0376b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/MemberCartService.java @@ -0,0 +1,196 @@ +package com.ruoyi.mall.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.exception.base.BaseException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.SortUtil; +import com.ruoyi.mall.domain.MemberCart; +import com.ruoyi.mall.domain.Sku; +import com.ruoyi.mall.domain.form.UpdateMemberCartForm; +import com.ruoyi.mall.domain.query.MemberCartQuery; +import com.ruoyi.mall.domain.vo.MemberCartVO; +import com.ruoyi.mall.mapper.MemberCartMapper; +import com.ruoyi.mall.mapper.ProductMapper; +import com.ruoyi.mall.mapper.SkuMapper; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 购物车Service业务层处理 + * + * @author zcc + */ +@Service +public class MemberCartService { + @Autowired + private MemberCartMapper memberCartMapper; + @Autowired + private SkuMapper skuMapper; + @Autowired + private ProductMapper productMapper; + + + /** + * 查询购物车 + * + * @param id 购物车主键 + * @return 购物车 + */ + public MemberCart selectById(Long id) { + return memberCartMapper.selectById(id); + } + + /** + * 查询购物车列表 + * + * @param query 查询条件 + * @param page 分页条件 + * @return 购物车 + */ + public List selectList(MemberCartQuery query, Pageable page) { + if (page != null) { + PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize(), SortUtil.sort2string(page.getSort(),"id desc")); + } + QueryWrapper qw = new QueryWrapper<>(); + if (query.getMemberId() != null){ + qw.eq("member_id", query.getMemberId()); + } + List memberCartList = memberCartMapper.selectList(qw); + if (CollectionUtil.isEmpty(memberCartList)){ + return Collections.emptyList(); + } + //查sku + List skuIdList = memberCartList.stream().map(MemberCart::getSkuId).collect(Collectors.toList()); + QueryWrapper skuQw = new QueryWrapper<>(); + skuQw.in("id", skuIdList); + Map skuMap = skuMapper.selectList(skuQw).stream().collect(Collectors.toMap(Sku::getId, it -> it)); + List resList = new ArrayList<>(); + memberCartList.forEach(item -> { + MemberCartVO memberCartVO = new MemberCartVO(); + BeanUtils.copyProperties(item, memberCartVO); + if (!skuMap.containsKey(item.getSkuId())){ + memberCartVO.setStatus(0); + memberCartVO.setSkuIfExist(0); + }else { + Sku sku = skuMap.get(item.getSkuId()); + memberCartVO.setPrice(sku.getPrice()); + memberCartVO.setSkuIfExist(1); + } + resList.add(memberCartVO); + }); + return resList; + } + + /** + * 新增购物车 + * + * @param memberCart 购物车 + * @return 结果 + */ + public int insert(MemberCart memberCart) { + + memberCart.setMemberId(SecurityUtils.getAppLoginUser().getAppUserId()); + //判断cart是否存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("member_id",SecurityUtils.getAppLoginUser().getAppUserId()); + queryWrapper.eq("sku_id",memberCart.getSkuId()); + queryWrapper.eq("product_id",memberCart.getProductId()); + List memberCarts = memberCartMapper.selectList(queryWrapper); + if (CollectionUtils.isEmpty(memberCarts)) { + memberCart.setStatus(1); + memberCart.setCreateTime(LocalDateTime.now()); + memberCart.setCreateBy(SecurityUtils.getAppLoginUser().getAppUserId()); + return memberCartMapper.insert(memberCart); + } + MemberCart dbCart = memberCarts.get(0); + dbCart.setUpdateTime(LocalDateTime.now()); + dbCart.setQuantity(dbCart.getQuantity() + memberCart.getQuantity()); + return memberCartMapper.updateById(dbCart); + } + + /** + * 修改购物车 + * + * @param memberCart 购物车 + * @return 结果 + */ + public int update(MemberCart memberCart) { + MemberCart cart = memberCartMapper.selectById(memberCart.getId()); + if (cart == null){ + return 0; + } + cart.setQuantity(memberCart.getQuantity()); + cart.setUpdateTime(LocalDateTime.now()); + cart.setUpdateBy(SecurityUtils.getAppLoginUser().getAppUserId()); + return memberCartMapper.updateById(cart); + } + public int update(UpdateMemberCartForm form) { + if (form.getNum() == null || form.getId() == null) { + throw new BaseException("参数错误"); + } + Long userId = SecurityUtils.getAppLoginUser().getAppUserId(); + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(MemberCart::getMemberId, userId); + qw.eq(MemberCart::getId, form.getId()); + if (form.getNum() <= 0) { + return memberCartMapper.delete(qw); + } + MemberCart e = new MemberCart(); + e.setQuantity(form.getNum()); + return memberCartMapper.update(e, qw); + } + + /** + * 删除购物车信息 + * + * @param id 购物车主键 + * @return 结果 + */ + public int deleteById(Long id) { + return memberCartMapper.deleteById(id); + } + + /** + * 删除购物车信息 + * + * @param ids 购物车主键 + * @return 结果 + */ + public int deleteByIds(List ids) { +// List idList = Arrays.stream(ids.split(",")).map(it -> Long.parseLong(it)).collect(Collectors.toList()); + return memberCartMapper.deleteBatchIds(ids); + } + + public Integer mineCartNum() { + Long userId = SecurityUtils.getAppLoginUser().getAppUserId(); + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("member_id", userId); + qw.eq("status", 1); + qw.select("count(quantity) quantity"); + MemberCart c = memberCartMapper.selectOne(qw); + if (c == null) { + return 0; + } + return c.getQuantity(); + } + + public List mineCartIds() { + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("member_id", SecurityUtils.getAppLoginUser().getAppUserId()); + qw.eq("status", 1); + qw.select("id"); + List list = memberCartMapper.selectList(qw); + return list.stream().map(MemberCart::getId).collect(Collectors.toList()); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderItemService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderItemService.java new file mode 100644 index 0000000..10ff99a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderItemService.java @@ -0,0 +1,62 @@ +package com.ruoyi.mall.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.core.domain.entity.AppUser; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.IDGenerator; +import com.ruoyi.mall.domain.dto.OrderProductListDTO; +import com.ruoyi.mall.domain.order.OrderItem; +import com.ruoyi.mall.mapper.OrderItemMapper; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * 订单中所包含的商品Service业务层处理 + * + * + * @author zcc + */ +@Service +public class OrderItemService extends ServiceImpl { + + + + + @Transactional + public void saveOrderItem(AppUser member, LocalDateTime optTime, + Long orderId, List list){ + List addOrderItemList = new ArrayList<>(); + list.forEach(item -> { + OrderItem orderItem = new OrderItem(); + orderItem.setId(IDGenerator.generateId()); + orderItem.setOrderId(orderId); + orderItem.setProductId(item.getProduct().getId()); + orderItem.setOutProductId(item.getProduct().getOutProductId()); + orderItem.setSkuId(item.getSku().getId()); + orderItem.setOutSkuId(item.getSku().getOutSkuId()); + orderItem.setPic(item.getSku().getPic()); + orderItem.setProductName(item.getProduct().getName()); + orderItem.setSalePrice(item.getSku().getPrice()); + orderItem.setQuantity(item.getQuantity()); + orderItem.setProductCategoryId(item.getProduct().getCategoryId()); + orderItem.setSpData(item.getSku().getSpData()); + orderItem.setCreateBy(member.getId()); + orderItem.setCreateTime(optTime); + addOrderItemList.add(orderItem); + }); + boolean flag = saveBatch(addOrderItemList); + if (!flag){ + throw new RuntimeException("新增订单item失败"); + } + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderOperateHistoryService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderOperateHistoryService.java new file mode 100644 index 0000000..e3a97f7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderOperateHistoryService.java @@ -0,0 +1,27 @@ +package com.ruoyi.mall.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageHelper; +import com.ruoyi.mall.domain.order.OrderOperateHistory; +import com.ruoyi.mall.mapper.OrderOperateHistoryMapper; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 订单操作历史记录Service业务层处理 + * + * + * @author zcc + */ +@Service +public class OrderOperateHistoryService extends ServiceImpl { + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderService.java new file mode 100644 index 0000000..b784df7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/OrderService.java @@ -0,0 +1,841 @@ +package com.ruoyi.mall.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.entity.AppUser; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.redis.RedisService; +import com.ruoyi.common.enums.AftersaleStatus; +import com.ruoyi.common.enums.OrderRefundStatus; +import com.ruoyi.common.enums.OrderStatus; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.IDGenerator; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.mall.MemberWechat; +import com.ruoyi.mall.domain.MemberAddress; +import com.ruoyi.mall.domain.MemberCart; +import com.ruoyi.mall.domain.Product; +import com.ruoyi.mall.domain.Sku; +import com.ruoyi.mall.domain.dto.OrderProductListDTO; +import com.ruoyi.mall.domain.dto.PayNotifyMessageDTO; +import com.ruoyi.mall.domain.form.*; +import com.ruoyi.mall.domain.order.*; +import com.ruoyi.mall.domain.vo.*; +import com.ruoyi.mall.mapper.*; +import com.ruoyi.mall.util.AppPrepay; +import com.ruoyi.mall.util.PayConstants; +import com.ruoyi.mall.util.WechatPayUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Service +@Slf4j +public class OrderService { + + @Autowired + private MemberAddressMapper memberAddressMapper; + + @Autowired + private SkuMapper skuMapper; + + @Autowired + private ProductMapper productMapper; + + @Autowired + private MemberCartMapper memberCartMapper; + + @Autowired + private OrderMapper orderMapper; + @Autowired + private OrderItemService orderItemService; + + @Autowired + private OrderOperateHistoryMapper orderOperateHistoryMapper; + + @Autowired + private OrderItemMapper orderItemMapper; + @Autowired + private WechatPaymentHistoryMapper wechatPaymentHistoryMapper; + @Autowired + private OrderOperateHistoryService orderOperateHistoryService; + @Autowired + private AftersaleMapper aftersaleMapper; + @Autowired + private AftersaleItemMapper aftersaleItemMapper; + + @Autowired + private RedisService redisService; + + @Transactional + public Long submit(OrderSubmitForm form) { + AppUser member = SecurityUtils.getAppLoginUser().getAppUser(); + //只支持快递 + Long addressId = form.getAddressId(); + if (addressId == null) { + throw new RuntimeException("收获地址不能为空"); + } + MemberAddress memberAddress = memberAddressMapper.selectById(addressId); + if (memberAddress == null) { + throw new RuntimeException("收货地址不能为空"); + } + //sku不能为空 + List skuList = form.getSkuList(); + if (CollectionUtil.isEmpty(skuList)) { + throw new RuntimeException("商品SKU信息不能为空"); + } + //将sku信息转换为 key:skuId ,value:购买数量 + Map skuQuantityMap = skuList.stream().collect(Collectors.toMap(OrderProductListDTO::getSkuId, OrderProductListDTO::getQuantity)); + //查询所有sku信息 + Map querySkuMap = skuMapper + .selectBatchIds(skuList.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toList())) + .stream().collect(Collectors.toMap(Sku::getId, it -> it)); + + //计算商品总额、订单总额(订单总金额=商品总金额,因为暂时没有运费等概念) + BigDecimal productTotalAmount = BigDecimal.ZERO; + BigDecimal orderTotalAmount = BigDecimal.ZERO; + for (OrderProductListDTO dto : skuList) { + if (!querySkuMap.containsKey(dto.getSkuId())) { + throw new RuntimeException("商品SKU不存在"); + } + Sku sku = querySkuMap.get(dto.getSkuId()); + Product product = productMapper.selectById(sku.getProductId()); + if (product == null) { + throw new RuntimeException("商品不存在"); + } + if (Constants.PublishStatus.UNDERCARRIAGE.equals(product.getPublishStatus())) { + throw new RuntimeException("商品" + product.getName() + "已下架"); + } + if (sku.getStock() < skuQuantityMap.get(sku.getId())) { + throw new RuntimeException("库存不足"); + } + productTotalAmount = productTotalAmount.add(sku.getPrice().multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId())))); + orderTotalAmount = orderTotalAmount.add(sku.getPrice().multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId())))); + dto.setSku(sku); + dto.setProduct(product); + } + LocalDateTime optTime = LocalDateTime.now(); + + //生成一个统一的订单号 + Long orderId = IDGenerator.generateId(); + //生产一个payId + Long payId = IDGenerator.generateId(); + //创建订单 + Order order = new Order(); + order.setPayId(payId); + order.setId(orderId); + order.setOrderSn(this.getOrderIdPrefix() + orderId); + order.setMemberId(member.getId()); + order.setMemberUsername(member.getNickName()); + +// order.setPayType(Constants.PayType.WECHAT); +// order.setMemberCouponId(form.getMemberCouponId()); + order.setTotalAmount(orderTotalAmount); + order.setPurchasePrice(BigDecimal.ZERO); + order.setFreightAmount(BigDecimal.ZERO); + order.setPayAmount(orderTotalAmount.compareTo(BigDecimal.ZERO) > 0 ? orderTotalAmount : BigDecimal.ZERO); + if (order.getPayAmount().compareTo(BigDecimal.ZERO) == 0) { + order.setStatus(Constants.OrderStatus.SEND); + } else { + order.setStatus(Constants.OrderStatus.NOTPAID); + } + order.setAftersaleStatus(1); + order.setReceiverName(memberAddress.getName()); + order.setReceiverPostCode(memberAddress.getPostCode()); + order.setReceiverProvince(memberAddress.getProvince()); + order.setReceiverCity(memberAddress.getCity()); + order.setReceiverDistrict(memberAddress.getDistrict()); + order.setReceiverPhone(memberAddress.getPhone()); + order.setReceiverDetailAddress(memberAddress.getAddress()); + order.setNote(form.getNote()); + order.setConfirmStatus(0); + order.setDeleteStatus(0); +// order.setPaymentTime(optTime); + order.setCreateTime(optTime); + order.setCreateBy(member.getId()); + int rows = orderMapper.insert(order); + if (rows < 1) { + throw new RuntimeException("订单新增失败"); + } + // 保存orderItem + orderItemService.saveOrderItem(member, optTime, orderId, skuList); + skuList.forEach(item -> { + //减少sku的库存 + skuMapper.updateStockById(item.getSkuId(), LocalDateTime.now(), item.getQuantity()); + }); + // 保存订单操作记录 + OrderOperateHistory orderOperateHistory = new OrderOperateHistory(); + orderOperateHistory.setOrderId(orderId); + orderOperateHistory.setOrderSn(order.getOrderSn()); + orderOperateHistory.setOperateMan(member.getNickName()); + orderOperateHistory.setOrderStatus(Constants.OrderStatus.NOTPAID); + orderOperateHistory.setCreateTime(optTime); + orderOperateHistory.setCreateBy(member.getId()); + rows = orderOperateHistoryMapper.insert(orderOperateHistory); + if (rows < 1) { + throw new RuntimeException("保存订单操作记录失败"); + } + //若来源为购物车,删除购物车 + if (Constants.OrderFrom.CART.equals(form.getFrom())) { + List skuIdList = skuList.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toList()); + LambdaUpdateWrapper wrapper = Wrappers.lambdaUpdate(); + wrapper.eq(MemberCart::getMemberId, member.getId()); + wrapper.in(MemberCart::getSkuId, skuIdList); + rows = memberCartMapper.delete(wrapper); + if (rows < 1) { + throw new RuntimeException("删除购物车失败"); + } + } + //当前订单id,接入支付后可返回payId + return payId; + } + + private String getOrderIdPrefix() { + LocalDateTime time = LocalDateTime.now(); + return time.format(DateTimeFormatter.ofPattern("yyMMdd")) + "-"; + } + + public OrderCalcVO addOrderCheck(OrderCreateForm orderCreateForm) { + OrderCalcVO res = new OrderCalcVO(); + List skuList = new ArrayList<>(); + List list = orderCreateForm.getSkuList(); + if (CollectionUtil.isEmpty(list)) { + throw new RuntimeException("商品SKU信息不能为空"); + } + //将购买的sku信息转化为key:skuId value:数量 + Map quantityMap = list.stream(). + collect(Collectors.toMap(OrderProductListDTO::getSkuId, OrderProductListDTO::getQuantity, (v1, v2) -> v2)); + //查询所有sku信息 + Set collect = list.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toSet()); + Map querySkuMap = skuMapper.selectBatchIds(collect).stream().collect(Collectors.toMap(Sku::getId, it -> it)); + //计算商品总金额、订单总金额 + BigDecimal productTotalAmount = BigDecimal.ZERO; + BigDecimal orderTotalAmount = BigDecimal.ZERO; + for (OrderProductListDTO dto : list) { + if (!querySkuMap.containsKey(dto.getSkuId())) { + throw new RuntimeException("商品SKU不存在"); + } + Sku sku = querySkuMap.get(dto.getSkuId()); + //查product + Product product = productMapper.selectById(sku.getProductId()); + if (product == null) { + throw new RuntimeException("商品不存在"); + } + if (Constants.PublishStatus.UNDERCARRIAGE.equals(product.getPublishStatus())) { + throw new RuntimeException("商品" + product.getName() + "已下架"); + } + if (sku.getStock() < quantityMap.get(sku.getId())) { + throw new RuntimeException("库存不足"); + } + BigDecimal addAmount = sku.getPrice().multiply(BigDecimal.valueOf(dto.getQuantity())); + //由于目前没有运费等数据,暂时订单总金额=商品总金额了 + productTotalAmount = productTotalAmount.add(addAmount); + orderTotalAmount = orderTotalAmount.add(addAmount); + //封装sku信息 + SkuViewVO skuViewVO = new SkuViewVO(); + skuViewVO.setPic(product.getPic()); + skuViewVO.setPrice(sku.getPrice()); + skuViewVO.setProductId(product.getId()); + skuViewVO.setProductName(product.getName()); + skuViewVO.setQuantity(quantityMap.get(sku.getId())); + skuViewVO.setSkuId(sku.getId()); + skuViewVO.setSpData(sku.getSpData()); + skuList.add(skuViewVO); + } + res.setSkuList(skuList); + res.setOrderTotalAmount(orderTotalAmount); + res.setProductTotalAmount(productTotalAmount); + //获取能使用的优惠券列表 + Map products = new HashMap<>(); + querySkuMap.forEach((k, v) -> { + Integer count = quantityMap.get(k); + Long productId = v.getProductId(); + Product product; + BigDecimal amount = v.getPrice().multiply(BigDecimal.valueOf(count)); + if (products.containsKey(k)) { + product = products.get(k); + product.setPrice(amount.add(product.getPrice())); + } else { + product = new Product(); + product.setId(productId); + product.setPrice(amount); + } + products.put(k, product); + }); + return res; + } + + + + + /** + * app订单分页查询 + * + * @param status 订单状态 -1->全部;0->待付款;1->待发货;2->待收货;-2->售后单 + * @param memberId 会员id + * @param pageable 分页 + * @return 结果 + */ + public PageImpl orderPage(Integer status, Long memberId, Pageable pageable) { + // 如果全部且页数为1,看看有无待付款单 + List unpaidOrderList = new ArrayList<>(); + if (Constants.AppOrderStatus.ALL.equals(status) && pageable.getPageNumber() == 0) { + unpaidOrderList = orderMapper.orderPage(Constants.AppOrderStatus.UN_PAY, memberId); + } + if (pageable != null) { + PageHelper.startPage(pageable.getPageNumber() + 1, pageable.getPageSize()); + } + List orderList = orderMapper.orderPage(status, memberId); + long total = ((com.github.pagehelper.Page) orderList).getTotal(); + // 两个list都没数据那肯定返回空了 + if (CollectionUtil.isEmpty(unpaidOrderList) && CollectionUtil.isEmpty(orderList)) { + return new PageImpl<>(Collections.EMPTY_LIST, pageable, total); + } + // 开始组装item了 + // 拿出所有orderId,查item,然后分组 by orderId + List idList = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(unpaidOrderList)) { + idList.addAll(unpaidOrderList.stream().map(AppOrderVO::getOrderId).collect(Collectors.toList())); + } + if (CollectionUtil.isNotEmpty(orderList)) { + idList.addAll(orderList.stream().map(AppOrderVO::getOrderId).collect(Collectors.toList())); + } + QueryWrapper orderItemQw = new QueryWrapper<>(); + orderItemQw.in("order_id", idList); + Map> orderItemMap = + orderItemMapper.selectList(orderItemQw).stream().collect(Collectors.groupingBy(OrderItem::getOrderId)); + orderList.addAll(0, unpaidOrderList); + orderList.forEach(item -> { + item.setOrderItemList(orderItemMap.get(item.getOrderId())); + }); + return new PageImpl<>(orderList, pageable, total); + } + + public AppOrderVO orderDetail(Long orderId) { + AppOrderVO order = orderMapper.selectOrderDetail(orderId); + if (order == null) { + throw new RuntimeException("未查询到该订单"); + } + // 组装item + QueryWrapper orderItemQw = new QueryWrapper<>(); + orderItemQw.eq("order_id", orderId); + List orderItemList = orderItemMapper.selectList(orderItemQw); + order.setOrderItemList(orderItemList); + // 如果未付款,计算倒计时 + if (Constants.OrderStatus.NOTPAID.equals(order.getStatus())) { + // 订单超时时间900s,后面可以配置到字典等 + Integer time = 900; + Date addDate = Date.from(order.getCreateTime().plusSeconds(time).atZone(ZoneId.systemDefault()).toInstant()); + if (addDate.after(new Date())) { + order.setTimeToPay(addDate.getTime()); + } + } + return order; + } + + @Transactional + public void orderCompleteByJob(List idList) { + idList.forEach(order -> { + LocalDateTime optDate = LocalDateTime.now(); + OrderItem queryOrderItem = new OrderItem(); + queryOrderItem.setOrderId(order.getId()); + //更新订单 + order.setStatus(Constants.AppOrderStatus.COMPLETED); + order.setReceiveTime(optDate); + order.setConfirmStatus(1); + order.setUpdateTime(optDate); + order.setUpdateBy(null); + orderMapper.updateById(order); + //创建订单操作记录 + OrderOperateHistory optHistory = new OrderOperateHistory(); + optHistory.setOrderId(order.getId()); + optHistory.setOrderSn(order.getOrderSn()); + optHistory.setOperateMan("后台管理员"); + optHistory.setOrderStatus(Constants.AppOrderStatus.COMPLETED); + optHistory.setCreateTime(optDate); + optHistory.setUpdateTime(optDate); + orderOperateHistoryMapper.insert(optHistory); + }); + } + + @Transactional + public String orderComplete(Long orderId) { + LocalDateTime optDate = LocalDateTime.now(); + Order order = orderMapper.selectById(orderId); + OrderItem queryOrderItem = new OrderItem(); + queryOrderItem.setOrderId(orderId); + List orderItemList = orderItemMapper.selectByEntity(queryOrderItem); + if (order == null || CollectionUtil.isEmpty(orderItemList)) { + throw new RuntimeException("未查询到订单信息"); + } + // 只有【待收货】状态才能确认 + if (!order.getStatus().equals(Constants.AppOrderStatus.DELIVERED)) { + throw new RuntimeException("订单状态已改变,请刷新"); + } + order.setStatus(Constants.AppOrderStatus.COMPLETED); + order.setReceiveTime(optDate); + order.setConfirmStatus(1); + order.setUpdateTime(optDate); + order.setUpdateBy(SecurityUtils.getAppLoginUser().getAppUserId()); + orderMapper.updateById(order); + //创建订单操作记录 + OrderOperateHistory optHistory = new OrderOperateHistory(); + optHistory.setOrderId(order.getId()); + optHistory.setOrderSn(order.getOrderSn()); + optHistory.setOperateMan("" + order.getMemberId()); + optHistory.setOrderStatus(Constants.AppOrderStatus.COMPLETED); + optHistory.setCreateTime(optDate); + optHistory.setCreateBy(order.getMemberId()); + optHistory.setUpdateBy(order.getMemberId()); + optHistory.setUpdateTime(optDate); + orderOperateHistoryMapper.insert(optHistory); + return order.getOrderSn(); + } + + /** + * 统计待付款、待发货、待收货和售后订单数量 + * + * @param memberId + * @return + */ + public CountOrderVO orderNumCount(Long memberId) { + return orderMapper.countByStatusAndMemberId(memberId); + } + + @Transactional + public String orderBatchCancel(CancelOrderForm request, Long userId) { + LocalDateTime optDate = LocalDateTime.now(); + if (CollectionUtil.isEmpty(request.getIdList())) { + throw new RuntimeException("未指定需要取消的订单号"); + } + QueryWrapper orderQw = new QueryWrapper<>(); + orderQw.in("id", request.getIdList()); + List orderList = orderMapper.selectList(orderQw); + if (orderList.size() < request.getIdList().size()) { + throw new RuntimeException("未查询到订单信息"); + } + //查orderItem + QueryWrapper qw = new QueryWrapper<>(); + qw.in("order_id", request.getIdList()); + List orderItem = orderItemMapper.selectList(qw); + if (CollectionUtil.isEmpty(orderItem)) { + throw new RuntimeException("未查询到订单信息"); + } + long count = orderList.stream().filter(it -> !Constants.AppOrderStatus.UN_PAY.equals(it.getStatus())).count(); + if (count > 0) { + throw new RuntimeException("订单状态已更新,请刷新页面"); + } + List addHistoryList = new ArrayList<>(); + orderList.forEach(item -> { + item.setStatus(Constants.AppOrderStatus.CLOSED); + item.setUpdateTime(optDate); + item.setUpdateBy(userId); + OrderOperateHistory history = new OrderOperateHistory(); + history.setOrderId(item.getId()); + history.setOrderSn(item.getOrderSn()); + history.setOperateMan(userId == null ? "后台管理员" : "" + item.getMemberId()); + history.setOrderStatus(Constants.AppOrderStatus.CLOSED); + history.setCreateTime(optDate); + history.setCreateBy(userId); + history.setUpdateBy(userId); + history.setUpdateTime(optDate); + addHistoryList.add(history); + + }); + //取消订单 +// int rows = orderMapper.cancelBatch(orderList); + int rows =0; + for (Order order : orderList) { + rows=rows+orderMapper.update(order,new UpdateWrapper() + .set("status",order.getStatus()) + .set("update_by",order.getUpdateBy()) + .set("update_time",order.getUpdateTime()) + .eq("id",order.getId())); + } + if (rows < 1) { + throw new RuntimeException("更改订单状态失败"); + } + orderItem.stream().collect(Collectors.groupingBy(it -> it.getSkuId())).forEach((k, v) -> { + AtomicReference totalCount = new AtomicReference<>(0); + v.forEach(it -> totalCount.updateAndGet(v1 -> v1 + it.getQuantity())); + skuMapper.updateStockById(k, optDate, -1 * totalCount.get()); + }); + + //创建订单操作记录 + boolean flag = orderOperateHistoryService.saveBatch(addHistoryList); + if (!flag) { + throw new RuntimeException("创建订单操作记录失败"); + } + //判断是否使用优惠券,有的话,把优惠券还回去 + + return "取消订单成功"; + } + + /** + * 订单支付 + * + * @param req 支付请求 + * @return + */ + //app支付 + public OrderPayVO orderPay(OrderPayForm req) { + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("pay_id", req.getPayId()); + qw.eq("status", 0);//未支付 + List orderList = orderMapper.selectList(qw); + if (CollectionUtil.isEmpty(orderList)) { + throw new RuntimeException("没有待支付的订单"); + } + + String openId = null; + String appId = PayConstants.APP_ID; + //app支付 + if (req.getWechatType() == 1) { + appId = PayConstants.APP_ID; + } + if (req.getWechatType() == 2) { + openId="";//TODO + appId = PayConstants.MINI_APP_ID; + } + QueryWrapper orderItemQw = new QueryWrapper<>(); + orderItemQw.eq("order_id", orderList.get(0).getId()); + List orderItemList = orderItemMapper.selectList(orderItemQw); + String orderDesc = orderItemList.get(0).getProductName().substring(0, Math.min(40, orderItemList.get(0).getProductName().length())); + //保存微信支付历史 + LocalDateTime optDate = LocalDateTime.now(); + QueryWrapper wxPaymentQw = new QueryWrapper<>(); + wxPaymentQw.eq("order_id", orderList.get(0).getPayId()); + wxPaymentQw.eq("op_type", Constants.PaymentOpType.PAY); + WechatPaymentHistory wechatPaymentHistory = wechatPaymentHistoryMapper.selectOne(wxPaymentQw); + if (wechatPaymentHistory == null) { + wechatPaymentHistory = new WechatPaymentHistory(); + wechatPaymentHistory.setOrderId(orderList.get(0).getPayId()); + wechatPaymentHistory.setMemberId(SecurityUtils.getAppLoginUser().getAppUserId()); + wechatPaymentHistory.setOpenid(openId); + wechatPaymentHistory.setTitle(orderItemList.get(0).getProductName()); + wechatPaymentHistory.setMoney(orderList.get(0).getPayAmount()); + wechatPaymentHistory.setOpType(Constants.PaymentOpType.PAY); + wechatPaymentHistory.setPaymentStatus(0); + wechatPaymentHistory.setCreateBy(SecurityUtils.getAppLoginUser().getAppUserId()); + wechatPaymentHistory.setCreateTime(optDate); + wechatPaymentHistory.setUpdateBy(SecurityUtils.getAppLoginUser().getAppUserId()); + wechatPaymentHistory.setUpdateTime(optDate); + wechatPaymentHistoryMapper.insert(wechatPaymentHistory); + } else { + wechatPaymentHistory.setMoney(orderList.get(0).getPayAmount()); + wechatPaymentHistoryMapper.updateById(wechatPaymentHistory); + } + //调用wx的AppPrepay拿prepayId,返回签名等信息 + String prepayId = AppPrepay.creatOrder( + orderDesc,String.valueOf(req.getPayId()),Long.valueOf(orderList.stream().map(Order::getPayAmount). + reduce(BigDecimal.ZERO, BigDecimal::add).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString()) + ).prepayId; + + OrderPayVO response = new OrderPayVO(); + response.setPayType(2);//1 支付宝 2 微信 + String nonceStr = WechatPayUtil.generateNonceStr(); + long timeStamp = WechatPayUtil.getCurrentTimestamp(); + String paySign = null; + String signatureStr = Stream.of(appId, String.valueOf(timeStamp), nonceStr, prepayId) + .collect(Collectors.joining("\n", "", "\n")); + try { + paySign = WechatPayUtil.getSign(signatureStr, PayConstants.PRIVATE_KEY_FILE_PATH); + } catch (Exception e) { + throw new RuntimeException("支付失败"); + } + response.setAppId(appId); + response.setPartnerId(PayConstants.MCH_ID); + response.setPrepayId(prepayId); + response.setPackageValue(PayConstants.PACKAGE); + response.setNonceStr(nonceStr); + response.setTimeStamp(String.valueOf(timeStamp)); + response.setSign(paySign); + return response; + } + + //jsapi支付 + public OrderPayVO orderPay_old(OrderPayForm req) { + return new OrderPayVO(); + } + + /** + * 支付回调方法 + * + * @param messageDTO + * @return + */ +// @Transactional +// public ResponseEntity payCallBack(PayNotifyMessageDTO messageDTO) { +//// log.info("【订单支付回调】" + JSONObject.toJSON(messageDTO)); +// String redisKey = "app_oms_order_pay_notify_" + messageDTO.getOutTradeNo(); +// String redisValue = messageDTO.getOutTradeNo() + "_" + System.currentTimeMillis(); +// LocalDateTime optDate = LocalDateTime.now(); +// try { +// redisService.lock(redisKey, redisValue, 60); +// //先判断回信回调的是否未success +// if (!Transaction.TradeStateEnum.SUCCESS.equals(messageDTO.getTradeStatus())) { +// log.error("【订单支付回调】订单状态不是支付成功状态" + messageDTO.getTradeStatus()); +// throw new RuntimeException(); +// } +// QueryWrapper paymentWrapper = new QueryWrapper<>(); +// paymentWrapper.eq("order_id", messageDTO.getOutTradeNo()); +// paymentWrapper.eq("op_type", Constants.PaymentOpType.PAY); +// WechatPaymentHistory paymentHistory = wechatPaymentHistoryMapper.selectOne(paymentWrapper); +// if (paymentHistory.getPaymentStatus() != Constants.PaymentStatus.INCOMPLETE) { +// log.info("【订单支付回调】支付订单不是未支付状态,不再处理" + "orderId" + paymentHistory.getOrderId() + "status" + paymentHistory.getPaymentStatus()); +// throw new RuntimeException(); +// } +// QueryWrapper orderQw = new QueryWrapper<>(); +// orderQw.eq("pay_id", messageDTO.getOutTradeNo()); +// orderQw.eq("status", OrderStatus.UN_PAY.getType()); +// List orderList = orderMapper.selectList(orderQw); +// orderList.forEach(order -> { +// order.setPaymentTime(messageDTO.getPayTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()); +// order.setStatus(OrderStatus.NOT_DELIVERED.getType()); +// orderMapper.updateById(order); +// +// OrderOperateHistory optHistory = new OrderOperateHistory(); +// optHistory.setOrderId(order.getId()); +// optHistory.setOrderSn(order.getOrderSn()); +// optHistory.setOperateMan("" + order.getMemberId()); +// optHistory.setOrderStatus(OrderStatus.NOT_DELIVERED.getType()); +// optHistory.setCreateTime(optDate); +// optHistory.setCreateBy(order.getMemberId()); +// optHistory.setUpdateBy(order.getMemberId()); +// optHistory.setUpdateTime(optDate); +// orderOperateHistoryMapper.insert(optHistory); +// +// //处理积分 +//// integralHistoryService.handleIntegral(order.getId(), order.getPayAmount(), order.getMemberId()); +// }); +// UpdateWrapper paymentHistoryUpdateWrapper = new UpdateWrapper<>(); +// paymentHistoryUpdateWrapper.eq("order_id", messageDTO.getOutTradeNo()).set("payment_id", messageDTO.getTradeNo()) +// .set("payment_status", Constants.PaymentStatus.COMPLETE).set("update_time", optDate); +// wechatPaymentHistoryMapper.update(null, paymentHistoryUpdateWrapper); +// } catch (Exception e) { +// log.error("订单支付回调异常", e); +// throw new RuntimeException("订单支付回调异常"); +// } finally { +// try { +// redisService.unLock(redisKey, redisValue); +// } catch (Exception e) { +// log.error("", e); +// } +// } +// return ResponseEntity.ok("订单支付回调成功"); +// } + + /** + * 申请售后 + * + * @param applyRefundForm + * @return + */ + @Transactional + public Order applyRefund(ApplyRefundForm applyRefundForm) { + Order order = orderMapper.selectById(applyRefundForm.getOrderId()); + //是否符合售后条件 + this.checkIfCanApplyRefund(order); + LocalDateTime optDate = LocalDateTime.now(); + Long memberId = order.getMemberId(); + //创建售后单aftersale + Aftersale addAftersale = new Aftersale(); + addAftersale.setId(IDGenerator.generateId()); + addAftersale.setMemberId(order.getMemberId()); + addAftersale.setOrderId(order.getId()); + addAftersale.setReturnAmount(order.getPayAmount()); + addAftersale.setType(applyRefundForm.getApplyRefundType()); + addAftersale.setStatus(AftersaleStatus.APPLY.getType()); + addAftersale.setReason(applyRefundForm.getReason()); + addAftersale.setQuantity(applyRefundForm.getQuantity()); + addAftersale.setReason(applyRefundForm.getReason()); + addAftersale.setDescription(applyRefundForm.getDescription()); + addAftersale.setProofPics(applyRefundForm.getProofPics()); + addAftersale.setCreateTime(optDate); + addAftersale.setCreateBy(memberId); + addAftersale.setUpdateTime(optDate); + addAftersale.setUpdateBy(memberId); + int rows = aftersaleMapper.insert(addAftersale); + if (rows != 1) { + throw new RuntimeException("插入订单售后失败"); + } + //创建aftersale item + QueryWrapper orderItemQw = new QueryWrapper<>(); + orderItemQw.eq("order_id", order.getId()); + List orderItemList = orderItemMapper.selectList(orderItemQw); + List addAftersaleItemList = new ArrayList<>(); + orderItemList.forEach(orderItem -> { + AftersaleItem aftersaleItem = new AftersaleItem(); + aftersaleItem.setMemberId(memberId); + aftersaleItem.setAftersaleId(addAftersale.getId()); + aftersaleItem.setOrderId(orderItem.getOrderId()); + aftersaleItem.setOrderItemId(orderItem.getId()); + aftersaleItem.setReturnAmount(orderItem.getSalePrice().multiply(BigDecimal.valueOf(orderItem.getQuantity()))); + aftersaleItem.setQuantity(orderItem.getQuantity()); + aftersaleItem.setCreateTime(optDate); + aftersaleItem.setCreateBy(memberId); + aftersaleItem.setUpdateTime(optDate); + aftersaleItem.setUpdateBy(memberId); + addAftersaleItemList.add(aftersaleItem); + }); + rows = aftersaleItemMapper.insertBatch(addAftersaleItemList); + if (rows < 1) { + throw new RuntimeException("创建售后订单item失败"); + } + //更新订单 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", order.getId()).set("aftersale_status", OrderRefundStatus.APPLY.getType()) + .set("update_time", optDate) + .set("update_by", memberId); + rows = orderMapper.update(null, updateWrapper); + if (rows < 1) { + throw new RuntimeException("修改订单状态失败"); + } + //创建订单操作记录 + OrderOperateHistory optHistory = new OrderOperateHistory(); + optHistory.setOrderId(order.getId()); + optHistory.setOrderSn(order.getOrderSn()); + optHistory.setOperateMan("" + memberId); + optHistory.setOrderStatus(11); + optHistory.setCreateTime(optDate); + optHistory.setCreateBy(memberId); + optHistory.setUpdateBy(memberId); + optHistory.setUpdateTime(optDate); + rows = orderOperateHistoryMapper.insert(optHistory); + if (rows < 1) { + throw new RuntimeException("创建订单操作记录失败"); + } + return order; + } + + /** + * check是否能售后 可售后的状态为:待发货、待收货、已完成 + * + * @param order 订单 + */ + private void checkIfCanApplyRefund(Order order) { + if (order == null) { + throw new RuntimeException("未查询到订单信息"); + } + Integer status = order.getStatus(); + boolean flag = OrderStatus.NOT_DELIVERED.getType().equals(status) + || OrderStatus.DELIVERED.getType().equals(status) + || OrderStatus.COMPLETE.getType().equals(status); + if (!flag) { + throw new RuntimeException("该订单无法申请售后"); + } + if (OrderStatus.COMPLETE.getType().equals(order.getStatus()) && + DateUtils.betweenDay(LocalDateTime.now(), order.getReceiveTime()) > 7) { + throw new RuntimeException("订单确认收货时间已超过7天,无法申请售后"); + } + if (OrderRefundStatus.APPLY.getType().equals(order.getAftersaleStatus()) + || OrderRefundStatus.WAIT.getType().equals(order.getAftersaleStatus())) { + throw new RuntimeException("售后正在处理中"); + } + } + + /** + * 取消售后 + * + * @param orderId 订单id + * @return + */ + @Transactional + public String cancelRefund(Long orderId) { + Order order = orderMapper.selectById(orderId); + if (order == null) { + throw new RuntimeException("未查询到该订单"); + } + //查询是否有(待处理和退货中)售后单 + QueryWrapper aftersaleQw = new QueryWrapper<>(); + aftersaleQw.eq("order_id", orderId); + aftersaleQw.in("status", Arrays.asList(AftersaleStatus.APPLY.getType(), AftersaleStatus.WAIT.getType())); + Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw); + if (aftersale == null) { + throw new RuntimeException("无售后单"); + } + if (OrderRefundStatus.SUCCESS.getType().equals(order.getAftersaleStatus())) { + throw new RuntimeException("已退款成功"); + } + LocalDateTime optDate = LocalDateTime.now(); + //更新售后单状态 + UpdateWrapper aftersaleUpdateWrapper = new UpdateWrapper<>(); + aftersaleUpdateWrapper.eq("id", aftersale.getId()); + aftersaleUpdateWrapper.set("status", AftersaleStatus.CANCEL.getType()); + aftersaleUpdateWrapper.set("update_time", optDate); + aftersaleUpdateWrapper.set("update_by", SecurityUtils.getAppLoginUser().getAppUserId()); + int rows = aftersaleMapper.update(null, aftersaleUpdateWrapper); + if (rows < 1) { + throw new RuntimeException("更新售后单失败"); + } + //更新订单售后状态 + // 更新订单 + UpdateWrapper updateOrderWrapper = new UpdateWrapper<>(); + updateOrderWrapper.eq("id", orderId) + .set("aftersale_status", OrderRefundStatus.NO_REFUND.getType()).set("update_time", optDate) + .set("update_by", SecurityUtils.getAppLoginUser().getAppUserId()); + rows = orderMapper.update(null, updateOrderWrapper); + if (rows != 1) { + throw new RuntimeException("更新订单状态失败"); + } + return "售后取消成功"; + } + + /** + * 售后订单详情 + * + * @param orderId 订单id + * @return + */ + public AftersaleRefundInfoVO refundOrderDetail(Long orderId) { + QueryWrapper aftersaleQw = new QueryWrapper<>(); + aftersaleQw.eq("order_id", orderId); + aftersaleQw.orderByDesc("create_time"); + aftersaleQw.last("limit 1"); + Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw); + if (aftersale == null) { + throw new RuntimeException("未查询到售后订单"); + } + //查一下售后订单item + QueryWrapper aftersaleItemQw = new QueryWrapper<>(); + aftersaleItemQw.eq("aftersale_id", aftersale.getId()); + List aftersaleItemList = aftersaleItemMapper.selectList(aftersaleItemQw); + List orderItemIdList = aftersaleItemList.stream().map(AftersaleItem::getOrderItemId).collect(Collectors.toList()); + //再去查orderItem + QueryWrapper orderItemQw = new QueryWrapper<>(); + orderItemQw.in("id", orderItemIdList); + List orderItemList = orderItemMapper.selectList(orderItemQw); + AftersaleRefundInfoVO vo = new AftersaleRefundInfoVO(); + BeanUtils.copyProperties(aftersale, vo); + vo.setAftersaleItemList(BeanUtil.copyToList(aftersaleItemList,AftersaleItemVO.class)); + vo.setOrderItemList(BeanUtil.copyToList(orderItemList,OrderItemVO.class)); + return vo; + } + + public Order selectById(Long orderId) { + return orderMapper.selectById(orderId); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ProductCategoryServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ProductCategoryServiceImpl.java new file mode 100644 index 0000000..b11b4b1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ProductCategoryServiceImpl.java @@ -0,0 +1,50 @@ +package com.ruoyi.mall.service.impl; + + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.redis.RedisService; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.mall.domain.Address; +import com.ruoyi.mall.domain.MemberAddress; +import com.ruoyi.mall.domain.ProductCategory; +import com.ruoyi.mall.domain.dto.AddressDTO; +import com.ruoyi.mall.mapper.AddressMapper; +import com.ruoyi.mall.mapper.MemberAddressMapper; +import com.ruoyi.mall.mapper.ProductCategoryMapper; +import com.ruoyi.mall.service.MemberAddressService; +import com.ruoyi.mall.service.ProductCategoryService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * 用户地址 服务实现类 + *

+ * + * @author xn + * @since 2022-09-29 + */ +@Service +public class ProductCategoryServiceImpl extends ServiceImpl implements ProductCategoryService { + + @Autowired + private ProductCategoryMapper mapper; + + + @Override + public List getProductCategorys(Map params){ + + QueryWrapper qw = new QueryWrapper<>(); + qw.select("id", "parent_id", "name", "level", "sort", "icon"); + qw.eq("show_status", 1);//展示 + qw.eq("store_id", params.get("storeId"));//门店id +// qw.le("level", 2); + return mapper.selectList(qw); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ProductService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ProductService.java new file mode 100644 index 0000000..0b5195b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ProductService.java @@ -0,0 +1,110 @@ +package com.ruoyi.mall.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.course.domain.ReqSearchClaTime; +import com.ruoyi.course.service.ScClaTimeService; +import com.ruoyi.mall.domain.Product; +import com.ruoyi.mall.domain.Sku; +import com.ruoyi.mall.domain.query.ProductQuery; +import com.ruoyi.mall.domain.vo.ProductDetailVO; +import com.ruoyi.mall.domain.vo.ProductVO; +import com.ruoyi.mall.mapper.BrandMapper; +import com.ruoyi.mall.mapper.ProductMapper; +import com.ruoyi.mall.mapper.SkuMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 商品信息Service业务层处理 + * + * + * @author zcc + */ +@Service +@Slf4j +public class ProductService { + @Autowired + private ProductMapper productMapper; + @Autowired + private SkuMapper skuMapper; + @Autowired + private BrandMapper brandMapper; + @Autowired + private ScClaTimeService scClaTimeService; + + /** + * 查询商品信息 + * + * @param id 商品信息主键 + * @return 商品信息 + */ + public ProductVO selectById(Long id) { + Product product = productMapper.selectById(id); + ProductVO productVO = BeanUtil.toBean(product,ProductVO.class); + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("product_id", product.getId()); + List skus = skuMapper.selectList(qw); + productVO.setSkuList(skus); + return productVO; + } + + /** + * 查询商品信息列表 + * + * @param query 查询条件 + * @param page 分页条件 + * @return 商品信息 + */ + public List selectList(ProductQuery query, Pageable page) { + if (page != null) { + PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize()); + } + QueryWrapper qw = new QueryWrapper<>(); + qw.orderByDesc("publish_status"); + qw.orderByAsc("sort"); + Long categoryId = query.getCategoryId(); + if (categoryId != null) { + qw.eq("category_id", categoryId); + } + String search = query.getSearch(); + if (StringUtils.isNoneEmpty(search)){ + qw.like("name", "%".concat(query.getSearch().trim()).concat("%")); + } + qw.eq("store_id", query.getStoreId());//门店id + return productMapper.selectList(qw); + } + + public ProductDetailVO queryDetail(Long id) { + ProductDetailVO res = new ProductDetailVO(); + Product d = productMapper.selectById(id); + res.setProduct(d); + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(Sku::getProductId, id); + res.setSkus(skuMapper.selectList(qw)); + if (d.getBrandId() != null) { + res.setBrand(brandMapper.selectById(d.getBrandId())); + } + if(d.getIsCourse()==1){ + ReqSearchClaTime r=new ReqSearchClaTime(); + r.setCourseId(d.getCourseId()); + res.setClaTimeCalendar( scClaTimeService.searchListForCalendar(r)); + } + return res; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ShopAddressServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ShopAddressServiceImpl.java new file mode 100644 index 0000000..798188f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/ShopAddressServiceImpl.java @@ -0,0 +1,88 @@ +package com.ruoyi.mall.service.impl; + + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.redis.RedisService; +import com.ruoyi.common.utils.ip.AddressUtils; +import com.ruoyi.mall.domain.MemberAddress; +import com.ruoyi.mall.domain.dto.AddressDTO; +import com.ruoyi.mall.mapper.AddressMapper; +import com.ruoyi.mall.mapper.MemberAddressMapper; +import com.ruoyi.mall.service.MemberAddressService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.mall.domain.Address; + +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * 用户地址 服务实现类 + *

+ * + * @author xn + * @since 2022-09-29 + */ +@Service +public class ShopAddressServiceImpl extends ServiceImpl implements MemberAddressService { + + @Autowired + private AddressMapper addressMapper; + @Autowired + private RedisService redisService; + + @Override + public List getAddressList(){ + String addresses = redisService.getAddressList(); + if (StringUtils.isNotEmpty(addresses)) { + List addressDTOList = JSON.parseArray(addresses, AddressDTO.class); + if(addressDTOList.size()>0){ + return addressDTOList; + } + } + QueryWrapper
addressQueryWrapper = new QueryWrapper<>(); + addressQueryWrapper.in("level", Arrays.asList(0,1,2)); + List
addressList = addressMapper.selectList(addressQueryWrapper); + Map> cityMap = addressList.stream().filter(it -> it.getLevel() == 1).collect(Collectors.groupingBy(it -> it.getParentCode())); + Map> districtMap = addressList.stream().filter(it -> it.getLevel() == 2).collect(Collectors.groupingBy(it -> it.getParentCode())); + List result = new ArrayList<>(); + addressList.stream().filter(it -> it.getLevel() == 0).forEach(it -> { + AddressDTO dto = new AddressDTO(); + dto.setId(it.getCode()); + dto.setLevel("province"); + dto.setName(it.getName()); + dto.setPid(0L); + //获取城市列表 + List child = new ArrayList<>(); + if (cityMap.containsKey(it.getCode())) { + cityMap.get(it.getCode()).forEach(city -> { + AddressDTO cityDto = new AddressDTO(); + cityDto.setId(city.getCode()); + cityDto.setLevel("city"); + cityDto.setName(city.getName()); + cityDto.setPid(city.getParentCode()); + cityDto.setChildren(districtMap.containsKey(city.getCode()) ? + districtMap.get(city.getCode()).stream().map(district -> { + AddressDTO districtDto = new AddressDTO(); + districtDto.setId(district.getCode()); + districtDto.setLevel("district"); + districtDto.setName(district.getName()); + districtDto.setPid(district.getParentCode()); + return districtDto; + }).collect(Collectors.toList()) : Collections.EMPTY_LIST); + child.add(cityDto); + }); + } + dto.setChildren(child); + result.add(dto); + }); + redisService.setAddressList(JSON.toJSONString(result)); + return result; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/WechatPayService.java b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/WechatPayService.java new file mode 100644 index 0000000..ca4fc42 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/service/impl/WechatPayService.java @@ -0,0 +1,76 @@ +package com.ruoyi.mall.service.impl; + +import com.ruoyi.mall.util.PayConstants; +import com.wechat.pay.java.service.payments.jsapi.JsapiService; +import com.wechat.pay.java.service.payments.jsapi.model.Amount; +import com.wechat.pay.java.service.payments.jsapi.model.Payer; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse; +import com.wechat.pay.java.service.refund.RefundService; +import com.wechat.pay.java.service.refund.model.AmountReq; +import com.wechat.pay.java.service.refund.model.CreateRequest; +import com.wechat.pay.java.service.refund.model.Refund; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; + + +@Service +@Slf4j +@ConditionalOnProperty(prefix = "wechat", name = "enabled", havingValue = "true") +public class WechatPayService { + + @Autowired + private JsapiService jsapiService; + @Autowired + private RefundService refundService; + + /** + * jsapi下单 + * @param orderNo 订单号 + * @param desc 订单描述 + * @param totalAmount 总金额,单位:分 + * @param openId 用户openid + * @return prepay_id + */ + public String jsapiPay(String orderNo,String desc,Integer totalAmount,String openId, Long memberId,String appId){ + PrepayRequest prepayRequest = new PrepayRequest(); + prepayRequest.setAppid(appId); + prepayRequest.setMchid(PayConstants.MCH_ID); + prepayRequest.setDescription(desc); + prepayRequest.setOutTradeNo(orderNo); + prepayRequest.setAttach(String.valueOf(memberId)); + prepayRequest.setNotifyUrl(PayConstants.NOTIFY_URL); + Amount amount = new Amount(); + amount.setTotal(totalAmount); + prepayRequest.setAmount(amount); + Payer payer = new Payer(); + payer.setOpenid(openId); + prepayRequest.setPayer(payer); + PrepayResponse response = jsapiService.prepay(prepayRequest); + return response.getPrepayId(); + } + + + + public Refund refundPay(String refundId,String payId,String notifyUrl,Long refundAmount, Long totalAmount,String reason) { + //请求参数 + CreateRequest request = new CreateRequest(); + request.setReason(reason); + //设置退款金额 根据自己的实际业务自行填写 + AmountReq amountReq = new AmountReq(); + amountReq.setRefund(refundAmount); + amountReq.setTotal(totalAmount); + amountReq.setCurrency("CNY"); + request.setAmount(amountReq); + //支付成功后回调回来的transactionId 按照实际情况填写 + request.setOutTradeNo(payId); + //支付成功后回调回来的transactionId 按照实际情况填写 + request.setOutRefundNo(refundId); + //退款成功的回调地址 + request.setNotifyUrl(notifyUrl); + //发起请求,申请退款 + return refundService.create(request); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/util/AppPrepay.java b/ruoyi-system/src/main/java/com/ruoyi/mall/util/AppPrepay.java new file mode 100644 index 0000000..f5e5a65 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/util/AppPrepay.java @@ -0,0 +1,249 @@ +package com.ruoyi.mall.util; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +/** + * App下单 + * 用户在商户APP端选择微信支付后,商户需调用该接口在微信支付下单,生成用于调起支付的预支付交易会话标识(prepay_id)。 + * https://pay.weixin.qq.com/doc/v3/merchant/4013070347 + */ +public class AppPrepay { + private static String HOST = "https://api.mch.weixin.qq.com"; + private static String METHOD = "POST"; + private static String PATH = "/v3/pay/transactions/app"; + + public static DirectAPIv3AppPrepayResponse creatOrder( + String description,String outTradeNo,Long total + ) { + // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/merchant/4013070756 + AppPrepay client = new AppPrepay( + PayConstants.MCH_ID, // mchid 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/merchant/4013070756 + PayConstants.MCH_SERIAL_NO, // certificateSerialNo 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013053053 + PayConstants.PRIVATE_KEY_FILE_PATH, // privateKeyFilePath 商户API证书私钥文件路径,本地文件路径 + PayConstants.PUBLIC_KEY, // wechatPayPublicKeyId,如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013038816 + PayConstants.PUBLIC_KEY_FILE_PATH // wechatPayPublicKeyFilePath 微信支付公钥文件路径,本地文件路径 + ); + + CommonPrepayRequest request = new CommonPrepayRequest(); + request.appid = PayConstants.APP_ID;//必填 + request.mchid = PayConstants.MCH_ID;//必填 + request.notifyUrl = PayConstants.NOTIFY_URL;//必填【商户回调地址】商户接收支付成功回调通知的地址,需按照notify_url填写注意事项规范填写。 + + request.description = description;//必填 【商品描述】商品信息描述,不能超过127个字符。 + request.outTradeNo = outTradeNo;//必填【商户订单号】商户系统内部订单号,要求6-32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一。 + request.amount = new CommonAmountInfo();//必填【订单金额】订单金额信息 + request.amount.total = total;//必填【总金额】 订单总金额,单位为分,整型。示例:1元应填写 100 +// request.timeExpire = "2018-06-08T10:34:56+08:00";//选填 支付结束时间 +// request.attach = "自定义数据说明";//选填 创建订单时可传入自定义数据包,该数据对用户不可见,用于存储订单相关的商户自定义信息,其总长度限制在128字符以内。 +// request.goodsTag = "WXG";//选填【订单优惠标记】 +// request.supportFapiao = false;//选填 电子发票入口开放标识; 传入true时,支付成功消息和支付详情页将出现开票入口。 +// request.amount.currency = "CNY";//选填 货币类型;固定传:CNY,代表人民币。 +// request.detail = new CouponInfo();//选填 优惠功能 +// request.detail.costPrice = 1L;//选填 订单原价 +// request.detail.invoiceId = "wx123";//选填 商品小票ID +// request.detail.goodsDetail = new ArrayList<>();//单品列表 选填 +// { +// GoodsDetail item0 = new GoodsDetail(); +// item0.merchantGoodsId = "1246464644";//商户侧商品编码 必填 +// item0.wechatpayGoodsId = "1001";//微信支付商品编码 +// item0.goodsName = "iPhone6s 16G";//商品名称 +// item0.quantity = 1L;//商品数量 必填 +// item0.unitPrice = 528800L;//商品单价 必填 +// request.detail.goodsDetail.add(item0); +// }; +// request.sceneInfo = new CommonSceneInfo();//选填 场景信息 +// request.sceneInfo.payerClientIp = "14.23.150.211";//必填 用户终端IP +// request.sceneInfo.deviceId = "013467007045764";//选填 【商户端设备号】 商户端设备号(门店号或收银设备ID) +// request.sceneInfo.storeInfo = new StoreInfo();//商户门店信息 +// request.sceneInfo.storeInfo.id = "0001";//必填 门店编号 +// request.sceneInfo.storeInfo.name = "腾讯大厦分店";//选填 门店名称 +// request.sceneInfo.storeInfo.areaCode = "440305";//选填 地区编码 +// request.sceneInfo.storeInfo.address = "广东省深圳市南山区科技中一道10000号";//选填 【详细地址】 详细的商户门店地址 +// request.settleInfo = new SettleInfo();// 选填 结算信息 +// request.settleInfo.profitSharing = false;//选填 分账标识 + DirectAPIv3AppPrepayResponse response =new DirectAPIv3AppPrepayResponse(); + try { + response = client.run(request); + + // TODO: 请求成功,继续业务逻辑 + System.out.println(response); + return response; + } catch (WXPayUtility.ApiException e) { + // TODO: 请求失败,根据状态码执行不同的逻辑 + e.printStackTrace(); + } + return response; + } + + public DirectAPIv3AppPrepayResponse run(CommonPrepayRequest request) { + String uri = PATH; + String reqBody = WXPayUtility.toJson(request); + + Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); + reqBuilder.addHeader("Accept", "application/json"); + reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); + reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, reqBody)); + reqBuilder.addHeader("Content-Type", "application/json"); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody); + reqBuilder.method(METHOD, requestBody); + Request httpRequest = reqBuilder.build(); + + // 发送HTTP请求 + OkHttpClient client = new OkHttpClient.Builder().build(); + try (Response httpResponse = client.newCall(httpRequest).execute()) { + String respBody = WXPayUtility.extractBody(httpResponse); + if (httpResponse.code() >= 200 && httpResponse.code() < 300) { + // 2XX 成功,验证应答签名 + WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, + httpResponse.headers(), respBody); + + // 从HTTP应答报文构建返回数据 + return WXPayUtility.fromJson(respBody, DirectAPIv3AppPrepayResponse.class); + } else { + throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); + } + } catch (IOException e) { + throw new UncheckedIOException("Sending request to " + uri + " failed.", e); + } + } + + private final String mchid; + private final String certificateSerialNo; + private final PrivateKey privateKey; + private final String wechatPayPublicKeyId; + private final PublicKey wechatPayPublicKey; + + public AppPrepay(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { + this.mchid = mchid; + this.certificateSerialNo = certificateSerialNo; + this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath); + this.wechatPayPublicKeyId = wechatPayPublicKeyId; + this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); + } + + public static class SettleInfo { + @SerializedName("profit_sharing") + public Boolean profitSharing; + } + + public static class CommonAmountInfo { + @SerializedName("total") + public Long total; + + @SerializedName("currency") + public String currency; + } + + public static class CommonSceneInfo { + @SerializedName("payer_client_ip") + public String payerClientIp; + + @SerializedName("device_id") + public String deviceId; + + @SerializedName("store_info") + public StoreInfo storeInfo; + } + + public static class DirectAPIv3AppPrepayResponse { + @SerializedName("prepay_id") + public String prepayId; + } + + public static class GoodsDetail { + @SerializedName("merchant_goods_id") + public String merchantGoodsId; + + @SerializedName("wechatpay_goods_id") + public String wechatpayGoodsId; + + @SerializedName("goods_name") + public String goodsName; + + @SerializedName("quantity") + public Long quantity; + + @SerializedName("unit_price") + public Long unitPrice; + } + + public static class CouponInfo { + @SerializedName("cost_price") + public Long costPrice; + + @SerializedName("invoice_id") + public String invoiceId; + + @SerializedName("goods_detail") + public List goodsDetail; + } + + public static class StoreInfo { + @SerializedName("id") + public String id; + + @SerializedName("name") + public String name; + + @SerializedName("area_code") + public String areaCode; + + @SerializedName("address") + public String address; + } + + public static class CommonPrepayRequest { + @SerializedName("appid") + public String appid; + + @SerializedName("mchid") + public String mchid; + + @SerializedName("description") + public String description; + + @SerializedName("out_trade_no") + public String outTradeNo; + + @SerializedName("time_expire") + public String timeExpire; + + @SerializedName("attach") + public String attach; + + @SerializedName("notify_url") + public String notifyUrl; + + @SerializedName("goods_tag") + public String goodsTag; + + @SerializedName("support_fapiao") + public Boolean supportFapiao; + + @SerializedName("amount") + public CommonAmountInfo amount; + + @SerializedName("detail") + public CouponInfo detail; + + @SerializedName("scene_info") + public CommonSceneInfo sceneInfo; + + @SerializedName("settle_info") + public SettleInfo settleInfo; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/util/PayConstants.java b/ruoyi-system/src/main/java/com/ruoyi/mall/util/PayConstants.java similarity index 83% rename from ruoyi-admin/src/main/java/com/ruoyi/web/util/PayConstants.java rename to ruoyi-system/src/main/java/com/ruoyi/mall/util/PayConstants.java index be1ca51..8e6d552 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/util/PayConstants.java +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/util/PayConstants.java @@ -1,4 +1,4 @@ -package com.ruoyi.web.util; +package com.ruoyi.mall.util; public interface PayConstants { @@ -6,9 +6,16 @@ public interface PayConstants { String NOTIFY_URL = "https://www.sanduolantoyoga.com/yoja/api/callback";//支付成功回调地址 String MCH_ID = "1636033352"; // 商户号 String APP_ID = "wx4f58086f54744e4a"; // appid - String MCH_SERIAL_NO = "3C9964908256A4D1D035B1F0E52BC69D0A27FB0A"; // 商户证书序列号 + String MINI_APP_ID="";//小程序apppid + String MINI_APP_SECRET="";//小程序secret 用来获取openid + String MCH_SERIAL_NO = "3C9964908256A4D1D035B1F0E52BC69D0A27FB0A"; // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013053053 + + String PRIVATE_KEY_FILE_PATH="";//商户API证书私钥文件路径,本地文件路径 + String PUBLIC_KEY="";//如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013038816 + String PUBLIC_KEY_FILE_PATH="";//微信支付公钥文件路径,本地文件路径 String API_V3KEY = "f99afc35b3af45998dea239a21644c5f"; // API V3密钥 (API key) String PACKAGE = "Sign=WXPay"; // 签名固定字符串(微信要求的) 06838cc840093b9d4689fc419ba1a3f3 + // 你的商户私钥 String PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----" + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCgLVT3XOIoENW5" + diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/util/WXPayUtility.java b/ruoyi-system/src/main/java/com/ruoyi/mall/util/WXPayUtility.java new file mode 100644 index 0000000..773f724 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/util/WXPayUtility.java @@ -0,0 +1,686 @@ +package com.ruoyi.mall.util; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import okhttp3.Headers; +import okhttp3.Response; +import okio.BufferedSource; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.time.DateTimeException; +import java.time.Duration; +import java.time.Instant; +import java.util.Base64; +import java.util.Map; +import java.util.Objects; +//微信支付工具库 参考:https://pay.weixin.qq.com/doc/v3/merchant/4014931831 +public class WXPayUtility { + private static final Gson gson = new GsonBuilder() + .disableHtmlEscaping() + .addSerializationExclusionStrategy(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes fieldAttributes) { + final Expose expose = fieldAttributes.getAnnotation(Expose.class); + return expose != null && !expose.serialize(); + } + + @Override + public boolean shouldSkipClass(Class aClass) { + return false; + } + }) + .addDeserializationExclusionStrategy(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes fieldAttributes) { + final Expose expose = fieldAttributes.getAnnotation(Expose.class); + return expose != null && !expose.deserialize(); + } + + @Override + public boolean shouldSkipClass(Class aClass) { + return false; + } + }) + .create(); + private static final char[] SYMBOLS = + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + private static final SecureRandom random = new SecureRandom(); + + /** + * 将 Object 转换为 JSON 字符串 + */ + public static String toJson(Object object) { + return gson.toJson(object); + } + + /** + * 将 JSON 字符串解析为特定类型的实例 + */ + public static T fromJson(String json, Class classOfT) throws JsonSyntaxException { + return gson.fromJson(json, classOfT); + } + + /** + * 从公私钥文件路径中读取文件内容 + * + * @param keyPath 文件路径 + * @return 文件内容 + */ + private static String readKeyStringFromPath(String keyPath) { + try { + return new String(Files.readAllBytes(Paths.get(keyPath)), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * 读取 PKCS#8 格式的私钥字符串并加载为私钥对象 + * + * @param keyString 私钥文件内容,以 -----BEGIN PRIVATE KEY----- 开头 + * @return PrivateKey 对象 + */ + public static PrivateKey loadPrivateKeyFromString(String keyString) { + try { + keyString = keyString.replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replaceAll("\\s+", ""); + return KeyFactory.getInstance("RSA").generatePrivate( + new PKCS8EncodedKeySpec(Base64.getDecoder().decode(keyString))); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException(e); + } catch (InvalidKeySpecException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 从 PKCS#8 格式的私钥文件中加载私钥 + * + * @param keyPath 私钥文件路径 + * @return PrivateKey 对象 + */ + public static PrivateKey loadPrivateKeyFromPath(String keyPath) { + return loadPrivateKeyFromString(readKeyStringFromPath(keyPath)); + } + + /** + * 读取 PKCS#8 格式的公钥字符串并加载为公钥对象 + * + * @param keyString 公钥文件内容,以 -----BEGIN PUBLIC KEY----- 开头 + * @return PublicKey 对象 + */ + public static PublicKey loadPublicKeyFromString(String keyString) { + try { + keyString = keyString.replace("-----BEGIN PUBLIC KEY-----", "") + .replace("-----END PUBLIC KEY-----", "") + .replaceAll("\\s+", ""); + return KeyFactory.getInstance("RSA").generatePublic( + new X509EncodedKeySpec(Base64.getDecoder().decode(keyString))); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException(e); + } catch (InvalidKeySpecException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * 从 PKCS#8 格式的公钥文件中加载公钥 + * + * @param keyPath 公钥文件路径 + * @return PublicKey 对象 + */ + public static PublicKey loadPublicKeyFromPath(String keyPath) { + return loadPublicKeyFromString(readKeyStringFromPath(keyPath)); + } + + /** + * 创建指定长度的随机字符串,字符集为[0-9a-zA-Z],可用于安全相关用途 + */ + public static String createNonce(int length) { + char[] buf = new char[length]; + for (int i = 0; i < length; ++i) { + buf[i] = SYMBOLS[random.nextInt(SYMBOLS.length)]; + } + return new String(buf); + } + + /** + * 使用公钥按照 RSA_PKCS1_OAEP_PADDING 算法进行加密 + * + * @param publicKey 加密用公钥对象 + * @param plaintext 待加密明文 + * @return 加密后密文 + */ + public static String encrypt(PublicKey publicKey, String plaintext) { + final String transformation = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"; + + try { + Cipher cipher = Cipher.getInstance(transformation); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + return Base64.getEncoder().encodeToString(cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8))); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new IllegalArgumentException("The current Java environment does not support " + transformation, e); + } catch (InvalidKeyException e) { + throw new IllegalArgumentException("RSA encryption using an illegal publicKey", e); + } catch (BadPaddingException | IllegalBlockSizeException e) { + throw new IllegalArgumentException("Plaintext is too long", e); + } + } + + public static String aesAeadDecrypt(byte[] key, byte[] associatedData, byte[] nonce, + byte[] ciphertext) { + final String transformation = "AES/GCM/NoPadding"; + final String algorithm = "AES"; + final int tagLengthBit = 128; + + try { + Cipher cipher = Cipher.getInstance(transformation); + cipher.init( + Cipher.DECRYPT_MODE, + new SecretKeySpec(key, algorithm), + new GCMParameterSpec(tagLengthBit, nonce)); + if (associatedData != null) { + cipher.updateAAD(associatedData); + } + return new String(cipher.doFinal(ciphertext), StandardCharsets.UTF_8); + } catch (InvalidKeyException + | InvalidAlgorithmParameterException + | BadPaddingException + | IllegalBlockSizeException + | NoSuchAlgorithmException + | NoSuchPaddingException e) { + throw new IllegalArgumentException(String.format("AesAeadDecrypt with %s Failed", + transformation), e); + } + } + + /** + * 使用私钥按照指定算法进行签名 + * + * @param message 待签名串 + * @param algorithm 签名算法,如 SHA256withRSA + * @param privateKey 签名用私钥对象 + * @return 签名结果 + */ + public static String sign(String message, String algorithm, PrivateKey privateKey) { + byte[] sign; + try { + Signature signature = Signature.getInstance(algorithm); + signature.initSign(privateKey); + signature.update(message.getBytes(StandardCharsets.UTF_8)); + sign = signature.sign(); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException("The current Java environment does not support " + algorithm, e); + } catch (InvalidKeyException e) { + throw new IllegalArgumentException(algorithm + " signature uses an illegal privateKey.", e); + } catch (SignatureException e) { + throw new RuntimeException("An error occurred during the sign process.", e); + } + return Base64.getEncoder().encodeToString(sign); + } + + /** + * 使用公钥按照特定算法验证签名 + * + * @param message 待签名串 + * @param signature 待验证的签名内容 + * @param algorithm 签名算法,如:SHA256withRSA + * @param publicKey 验签用公钥对象 + * @return 签名验证是否通过 + */ + public static boolean verify(String message, String signature, String algorithm, + PublicKey publicKey) { + try { + Signature sign = Signature.getInstance(algorithm); + sign.initVerify(publicKey); + sign.update(message.getBytes(StandardCharsets.UTF_8)); + return sign.verify(Base64.getDecoder().decode(signature)); + } catch (SignatureException e) { + return false; + } catch (InvalidKeyException e) { + throw new IllegalArgumentException("verify uses an illegal publickey.", e); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException("The current Java environment does not support" + algorithm, e); + } + } + + /** + * 根据微信支付APIv3请求签名规则构造 Authorization 签名 + * + * @param mchid 商户号 + * @param certificateSerialNo 商户API证书序列号 + * @param privateKey 商户API证书私钥 + * @param method 请求接口的HTTP方法,请使用全大写表述,如 GET、POST、PUT、DELETE + * @param uri 请求接口的URL + * @param body 请求接口的Body + * @return 构造好的微信支付APIv3 Authorization 头 + */ + public static String buildAuthorization(String mchid, String certificateSerialNo, + PrivateKey privateKey, + String method, String uri, String body) { + String nonce = createNonce(32); + long timestamp = Instant.now().getEpochSecond(); + + String message = String.format("%s\n%s\n%d\n%s\n%s\n", method, uri, timestamp, nonce, + body == null ? "" : body); + + String signature = sign(message, "SHA256withRSA", privateKey); + + return String.format( + "WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\"," + + "timestamp=\"%d\",serial_no=\"%s\"", + mchid, nonce, signature, timestamp, certificateSerialNo); + } + + /** + * 对参数进行 URL 编码 + * + * @param content 参数内容 + * @return 编码后的内容 + */ + public static String urlEncode(String content) { + try { + return URLEncoder.encode(content, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + /** + * 对参数Map进行 URL 编码,生成 QueryString + * + * @param params Query参数Map + * @return QueryString + */ + public static String urlEncode(Map params) { + if (params == null || params.isEmpty()) { + return ""; + } + + int index = 0; + StringBuilder result = new StringBuilder(); + for (Map.Entry entry : params.entrySet()) { + result.append(entry.getKey()) + .append("=") + .append(urlEncode(entry.getValue().toString())); + index++; + if (index < params.size()) { + result.append("&"); + } + } + return result.toString(); + } + + /** + * 从应答中提取 Body + * + * @param response HTTP 请求应答对象 + * @return 应答中的Body内容,Body为空时返回空字符串 + */ + public static String extractBody(Response response) { + if (response.body() == null) { + return ""; + } + + try { + BufferedSource source = response.body().source(); + return source.readUtf8(); + } catch (IOException e) { + throw new RuntimeException(String.format("An error occurred during reading response body. " + + "Status: %d", response.code()), e); + } + } + + /** + * 根据微信支付APIv3应答验签规则对应答签名进行验证,验证不通过时抛出异常 + * + * @param wechatpayPublicKeyId 微信支付公钥ID + * @param wechatpayPublicKey 微信支付公钥对象 + * @param headers 微信支付应答 Header 列表 + * @param body 微信支付应答 Body + */ + public static void validateResponse(String wechatpayPublicKeyId, PublicKey wechatpayPublicKey, + Headers headers, + String body) { + String timestamp = headers.get("Wechatpay-Timestamp"); + String requestId = headers.get("Request-ID"); + try { + Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestamp)); + // 拒绝过期请求 + if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= 5) { + throw new IllegalArgumentException( + String.format("Validate response failed, timestamp[%s] is expired, request-id[%s]", + timestamp, requestId)); + } + } catch (DateTimeException | NumberFormatException e) { + throw new IllegalArgumentException( + String.format("Validate response failed, timestamp[%s] is invalid, request-id[%s]", + timestamp, requestId)); + } + String serialNumber = headers.get("Wechatpay-Serial"); + if (!Objects.equals(serialNumber, wechatpayPublicKeyId)) { + throw new IllegalArgumentException( + String.format("Validate response failed, Invalid Wechatpay-Serial, Local: %s, Remote: " + + "%s", wechatpayPublicKeyId, serialNumber)); + } + + String signature = headers.get("Wechatpay-Signature"); + String message = String.format("%s\n%s\n%s\n", timestamp, headers.get("Wechatpay-Nonce"), + body == null ? "" : body); + + boolean success = verify(message, signature, "SHA256withRSA", wechatpayPublicKey); + if (!success) { + throw new IllegalArgumentException( + String.format("Validate response failed,the WechatPay signature is incorrect.%n" + + "Request-ID[%s]\tresponseHeader[%s]\tresponseBody[%.1024s]", + headers.get("Request-ID"), headers, body)); + } + } + + /** + * 根据微信支付APIv3通知验签规则对通知签名进行验证,验证不通过时抛出异常 + * @param wechatpayPublicKeyId 微信支付公钥ID + * @param wechatpayPublicKey 微信支付公钥对象 + * @param headers 微信支付通知 Header 列表 + * @param body 微信支付通知 Body + */ + public static void validateNotification(String wechatpayPublicKeyId, + PublicKey wechatpayPublicKey, Headers headers, + String body) { + String timestamp = headers.get("Wechatpay-Timestamp"); + try { + Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestamp)); + // 拒绝过期请求 + if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= 5) { + throw new IllegalArgumentException( + String.format("Validate notification failed, timestamp[%s] is expired", timestamp)); + } + } catch (DateTimeException | NumberFormatException e) { + throw new IllegalArgumentException( + String.format("Validate notification failed, timestamp[%s] is invalid", timestamp)); + } + String serialNumber = headers.get("Wechatpay-Serial"); + if (!Objects.equals(serialNumber, wechatpayPublicKeyId)) { + throw new IllegalArgumentException( + String.format("Validate notification failed, Invalid Wechatpay-Serial, Local: %s, " + + "Remote: %s", + wechatpayPublicKeyId, + serialNumber)); + } + + String signature = headers.get("Wechatpay-Signature"); + String message = String.format("%s\n%s\n%s\n", timestamp, headers.get("Wechatpay-Nonce"), + body == null ? "" : body); + + boolean success = verify(message, signature, "SHA256withRSA", wechatpayPublicKey); + if (!success) { + throw new IllegalArgumentException( + String.format("Validate notification failed, WechatPay signature is incorrect.\n" + + "responseHeader[%s]\tresponseBody[%.1024s]", + headers, body)); + } + } + + /** + * 对微信支付通知进行签名验证、解析,同时将业务数据解密。验签名失败、解析失败、解密失败时抛出异常 + * @param apiv3Key 商户的 APIv3 Key + * @param wechatpayPublicKeyId 微信支付公钥ID + * @param wechatpayPublicKey 微信支付公钥对象 + * @param headers 微信支付应答 Header 列表 + * @param body 微信支付应答 Body + * @return 解析后的通知内容,解密后的业务数据可以使用 Notification.getPlaintext() 访问 + */ + public static Notification parseNotification(String apiv3Key, String wechatpayPublicKeyId, + PublicKey wechatpayPublicKey, Headers headers, + String body) { + validateNotification(wechatpayPublicKeyId, wechatpayPublicKey, headers, body); + Notification notification = gson.fromJson(body, Notification.class); + notification.decrypt(apiv3Key); + return notification; + } + + /** + * 微信支付API错误异常,发送HTTP请求成功,但返回状态码不是 2XX 时抛出本异常 + */ + public static class ApiException extends RuntimeException { + private static final long serialVersionUID = 2261086748874802175L; + + private final int statusCode; + private final String body; + private final Headers headers; + private final String errorCode; + private final String errorMessage; + + public ApiException(int statusCode, String body, Headers headers) { + super(String.format("微信支付API访问失败,StatusCode: [%s], Body: [%s], Headers: [%s]", statusCode, + body, headers)); + this.statusCode = statusCode; + this.body = body; + this.headers = headers; + + if (body != null && !body.isEmpty()) { + JsonElement code; + JsonElement message; + + try { + JsonObject jsonObject = gson.fromJson(body, JsonObject.class); + code = jsonObject.get("code"); + message = jsonObject.get("message"); + } catch (JsonSyntaxException ignored) { + code = null; + message = null; + } + this.errorCode = code == null ? null : code.getAsString(); + this.errorMessage = message == null ? null : message.getAsString(); + } else { + this.errorCode = null; + this.errorMessage = null; + } + } + + /** + * 获取 HTTP 应答状态码 + */ + public int getStatusCode() { + return statusCode; + } + + /** + * 获取 HTTP 应答包体内容 + */ + public String getBody() { + return body; + } + + /** + * 获取 HTTP 应答 Header + */ + public Headers getHeaders() { + return headers; + } + + /** + * 获取 错误码 (错误应答中的 code 字段) + */ + public String getErrorCode() { + return errorCode; + } + + /** + * 获取 错误消息 (错误应答中的 message 字段) + */ + public String getErrorMessage() { + return errorMessage; + } + } + + public static class Notification { + @SerializedName("id") + private String id; + @SerializedName("create_time") + private String createTime; + @SerializedName("event_type") + private String eventType; + @SerializedName("resource_type") + private String resourceType; + @SerializedName("summary") + private String summary; + @SerializedName("resource") + private Resource resource; + private String plaintext; + + public String getId() { + return id; + } + + public String getCreateTime() { + return createTime; + } + + public String getEventType() { + return eventType; + } + + public String getResourceType() { + return resourceType; + } + + public String getSummary() { + return summary; + } + + public Resource getResource() { + return resource; + } + + /** + * 获取解密后的业务数据(JSON字符串,需要自行解析) + */ + public String getPlaintext() { + return plaintext; + } + + private void validate() { + if (resource == null) { + throw new IllegalArgumentException("Missing required field `resource` in notification"); + } + resource.validate(); + } + + /** + * 使用 APIv3Key 对通知中的业务数据解密,解密结果可以通过 getPlainText 访问。 + * 外部拿到的 Notification 一定是解密过的,因此本方法没有设置为 public + * @param apiv3Key 商户APIv3 Key + */ + private void decrypt(String apiv3Key) { + validate(); + + plaintext = aesAeadDecrypt( + apiv3Key.getBytes(StandardCharsets.UTF_8), + resource.associatedData.getBytes(StandardCharsets.UTF_8), + resource.nonce.getBytes(StandardCharsets.UTF_8), + Base64.getDecoder().decode(resource.ciphertext) + ); + } + + public static class Resource { + @SerializedName("algorithm") + private String algorithm; + + @SerializedName("ciphertext") + private String ciphertext; + + @SerializedName("associated_data") + private String associatedData; + + @SerializedName("nonce") + private String nonce; + + @SerializedName("original_type") + private String originalType; + + public String getAlgorithm() { + return algorithm; + } + + public String getCiphertext() { + return ciphertext; + } + + public String getAssociatedData() { + return associatedData; + } + + public String getNonce() { + return nonce; + } + + public String getOriginalType() { + return originalType; + } + + private void validate() { + if (algorithm == null || algorithm.isEmpty()) { + throw new IllegalArgumentException("Missing required field `algorithm` in Notification" + + ".Resource"); + } + if (!Objects.equals(algorithm, "AEAD_AES_256_GCM")) { + throw new IllegalArgumentException(String.format("Unsupported `algorithm`[%s] in " + + "Notification.Resource", algorithm)); + } + + if (ciphertext == null || ciphertext.isEmpty()) { + throw new IllegalArgumentException("Missing required field `ciphertext` in Notification" + + ".Resource"); + } + + if (associatedData == null || associatedData.isEmpty()) { + throw new IllegalArgumentException("Missing required field `associatedData` in " + + "Notification.Resource"); + } + + if (nonce == null || nonce.isEmpty()) { + throw new IllegalArgumentException("Missing required field `nonce` in Notification" + + ".Resource"); + } + + if (originalType == null || originalType.isEmpty()) { + throw new IllegalArgumentException("Missing required field `originalType` in " + + "Notification.Resource"); + } + } + } + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/util/WechatPayUtil.java b/ruoyi-system/src/main/java/com/ruoyi/mall/util/WechatPayUtil.java new file mode 100644 index 0000000..b95a26f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/mall/util/WechatPayUtil.java @@ -0,0 +1,76 @@ +package com.ruoyi.mall.util; + + +import cn.hutool.crypto.PemUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.Base64Utils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.*; +import java.util.Random; + + +public class WechatPayUtil { + + private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + private static final Random RANDOM = new SecureRandom(); + + + public static String getSign(String signatureStr,String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException { + //replace 根据实际情况,不一定都需要 + String replace = privateKey.replace("\\n", "\n"); + InputStream certStream = Files.newInputStream(Paths.get(privateKey)); + PrivateKey merchantPrivateKey = PemUtil.readPemPrivateKey(certStream); + Signature sign = Signature.getInstance("SHA256withRSA"); + sign.initSign(merchantPrivateKey); + sign.update(signatureStr.getBytes(StandardCharsets.UTF_8)); + return Base64Utils.encodeToString(sign.sign()); + } + + /** + * 获取随机字符串 Nonce Str + * + * @return String 随机字符串 + */ + public static String generateNonceStr() { + char[] nonceChars = new char[32]; + for (int index = 0; index < nonceChars.length; ++index) { + nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + return new String(nonceChars); + } + + + /** + * 日志 + * @return + */ + public static Logger getLogger() { + Logger logger = LoggerFactory.getLogger("wxpay java sdk"); + return logger; + } + + /** + * 获取当前时间戳,单位秒 + * @return + */ + public static long getCurrentTimestamp() { + return System.currentTimeMillis()/1000; + } + + /** + * 获取当前时间戳,单位毫秒 + * @return + */ + public static long getCurrentTimestampMs() { + return System.currentTimeMillis(); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/search/domain/MemberUser.java b/ruoyi-system/src/main/java/com/ruoyi/search/domain/MemberUser.java deleted file mode 100644 index c295567..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/search/domain/MemberUser.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.ruoyi.search.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -@Data -@EqualsAndHashCode(callSuper = false) -public class MemberUser implements Serializable{ - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - private Integer memberId; - - private String memberName; - - private String memberContext; - - private String memberPicture; - - private Integer validity; - - private String myType; - - private BigDecimal memberPrice; - - private Boolean releases; - - private String data; - - private Long consumerId; - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime comeTime; - - private String validityTime; - - private BigDecimal price; - - private String recommend; - - private String stroreId ; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/search/domain/MemberUserWo.java b/ruoyi-system/src/main/java/com/ruoyi/search/domain/MemberUserWo.java deleted file mode 100644 index 699a039..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/search/domain/MemberUserWo.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ruoyi.search.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Data; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; -@Data -public class MemberUserWo implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - private Integer memberId; - - private String memberName; - - private String memberContext; - - private String memberPicture; - - private Integer validity; - - private String myType; - - private BigDecimal memberPrice; - - - private Boolean releases; - - private String data; - - private Integer consumerId; - - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime comeTime; - - private String validityTime; - - private BigDecimal price; - - private String recommend; - - private String consumerName; - - private String consumerPhonenumber; - - private String userName; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/search/mapper/MemberUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/search/mapper/MemberUserMapper.java deleted file mode 100644 index 78f5513..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/search/mapper/MemberUserMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ruoyi.search.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.search.domain.MemberUser; -import com.ruoyi.search.domain.MemberUserWo; - -import java.util.List; -import java.util.Map; - -public interface MemberUserMapper extends BaseMapper { -// List findList(String memberName); - public List findList(Map map); -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/search/service/MemberUserServicelmpl.java b/ruoyi-system/src/main/java/com/ruoyi/search/service/MemberUserServicelmpl.java deleted file mode 100644 index d2fd730..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/search/service/MemberUserServicelmpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ruoyi.search.service; - -import cn.hutool.core.date.DateUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.search.domain.MemberUser; -import com.ruoyi.search.domain.MemberUserWo; -import com.ruoyi.search.mapper.MemberUserMapper; -import org.springframework.stereotype.Service; - -import java.time.LocalDateTime; -import java.util.Calendar; -import java.util.List; -import java.util.Map; - -@Service -public class MemberUserServicelmpl extends ServiceImpl { - - - public List getList(Map map){ - List list = baseMapper.findList(map); - return list; - } - - public Boolean handleMember(MemberUser memberUser) { - LocalDateTime dateTime= DateUtil.parseLocalDateTime(DateUtil.format(DateUtil.tomorrow(),"yyyy-MM-dd 00:00:00")); - List list=this.list(new QueryWrapper() - .eq("member_id",memberUser.getMemberId()) - .eq("consumer_id",memberUser.getConsumerId()) - .last(" and (validity_time > now() or come_time ='"+dateTime+"')"));//截止日期为今天之后(未到期) 或 开始日期在明天(今天办的) - if (list.size()>0){ - System.out.println("会籍存续中,请勿重复办理!"); - return false; - } - - //入会时间 次日生效 - memberUser.setComeTime(dateTime); - - //截止日期 - Calendar cal = Calendar.getInstance(); - cal.setTime(DateUtil.tomorrow()); - cal.add(Calendar.MONTH,memberUser.getValidity()); - memberUser.setValidityTime(DateUtil.format(cal.getTime(),"yyyy-MM-dd")); - return this.save(memberUser); - } - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/Consumer.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/Consumer.java deleted file mode 100644 index 7a6f35d..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/Consumer.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.ruoyi.shop.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - *

- * 消费者用户表 - *

- * - * @since 2022-09-27 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class Consumer implements Serializable { - - private static final long serialVersionUID=1L; - - /** - * 用户ID - */ - @TableId(value = "consumer_id", type = IdType.AUTO) - private Long consumerId; - - /** - * 用户账号 - */ - @ApiModelProperty("用户账号") - private String consumerName; - - /** - * 用户昵称 - */ - @ApiModelProperty("用户昵称") - private String consumerNickName; - - /** - * 用户类型(00系统用户) - */ - private String consumerType; - - /** - * 用户邮箱 - */ - private String consumerEmail; - - /** - * 手机号码 - */ - @ApiModelProperty("手机号码") - private String consumerPhonenumber; - - /** - * 用户性别(0男 1女 2未知) - */ - @ApiModelProperty("用户性别(0男 1女 2未知)") - private String consumerSex; - - /** - * 头像地址 - */ - @ApiModelProperty("头像") - private String consumerAvatar; - - /** - * 密码 - */ - @ApiModelProperty("密码") - private String consumerPassword; - - /** - * 帐号状态(0正常 1停用) - */ - private String consumerStatus; - - /** - * 删除标志(0代表存在 2代表删除) - */ - private String consumerDelFlag; - - /** - * 推荐人id - */ - @ApiModelProperty("推荐人id") - private String recommendId; - - /** - * 创建者 - */ - private String createBy; - - /** - * 创建时间 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime createTime; - - /** - * 更新者 - */ - private String updateBy; - - /** - * 更新时间 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime updateTime; - - /** - * 备注 - */ - @ApiModelProperty("备注") - private String remark; - - /** - * 设备id - */ - @ApiModelProperty("设备id") - private String registerId; - - @ApiModelProperty("角色,0顾客 103会籍顾问 104教练 105店长") - private String role; - - @ApiModelProperty("当前门店id") - private String merchantId; -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopCart.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopCart.java deleted file mode 100644 index 7466ffe..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopCart.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.ruoyi.shop.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - *

- * 购物车 - *

- * - * @author xn - * @since 2022-09-23 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class ShopCart implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; - - /** - * 数量 - */ - @ApiModelProperty("数量") - private Integer count; - - /** - * 商品id - */ - @ApiModelProperty("商品id") - private String idGoods; - - /** - * 用户id - */ - @ApiModelProperty("用户id") - private Long idUser; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopGoods.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopGoods.java deleted file mode 100644 index 1fb1b51..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopGoods.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.ruoyi.shop.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.ApiModelProperty; -import lombok.Data; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -/** - *

- * 商品表 - *

- * - * @author xn - * @since 2022-09-22 - */ -@Data -public class ShopGoods implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; - - /** - * 商品名称 - */ - @ApiModelProperty("商品名称") - private String name; - - /** - * 商品缩略图 - */ - @ApiModelProperty("商品缩略图") - private String thumbnail; - - /** - * 类别id,二级类别 - */ - @ApiModelProperty("类别id,二级类别") - private String categoryId; - - /** - * 商品简介 - */ - @ApiModelProperty("商品简介") - private String brief; - - /** - * 是否上架 - */ - private Boolean isSale; - - /** - * 是否推荐 - */ - @ApiModelProperty("类别名称") - private Boolean recommend; - - /** - * 商品相册,多张图片url,用逗号间隔 - */ - @ApiModelProperty("商品相册") - private String album; - - /** - * 商品详情,富文本 - */ - @ApiModelProperty("商品详情") - private String detail; - - /** - * 库存 - */ - @ApiModelProperty("库存") - private Integer stock; - - /** - * 销售数量 - */ - @ApiModelProperty("销售数量") - private Integer salesNum; - - /** - * 保底价格 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal minimumPrice; - - /** - * 市场价 - */ - @ApiModelProperty("市场价") - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal marketPrice; - - /** - * 售价 - */ - @ApiModelProperty("售价") - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal price; - - /** - * 创建时间 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime createTime; - - /** - * 创建人id - */ - private Long createBy; - - /** - * 最后修改人id - */ - private Long modifyBy; - - /** - * 最后修改时间 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime modifyTime; - - /** - * 规格 - */ - @ApiModelProperty("规格") - private String attribute; - - /** - * 所属商户id - */ - private String businessId; - - @TableField(exist = false) - private String cartId; - - @TableField(exist = false) - private String count; -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopGoodsCategory.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopGoodsCategory.java deleted file mode 100644 index d102478..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopGoodsCategory.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.ruoyi.shop.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.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.time.LocalDateTime; -import java.util.List; - -/** - *

- * 商品类别表 - *

- * - * @author xn - * @since 2022-09-22 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class ShopGoodsCategory implements Serializable { - - private static final long serialVersionUID=1L; - - - - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; - - /** - * 父类别id,一级默认值0 - */ - - private String pid; - - /** - * 类别名称 - */ - @ApiModelProperty("类别名称") - private String name; - - - - /** - * 描述 - */ - @ApiModelProperty("描述") - private String detail; - - /** - * 图片 - */ - @ApiModelProperty("图片") - private String picture; - - /** - * 顺序 - */ - @ApiModelProperty("顺序") - private Integer sort; - - /** - * 是否页面显示 - */ - @ApiModelProperty("是否页面显示") - private Boolean display; - - /** - * 创建时间 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime createTime; - - /** - * 创建人id - */ - private Long createBy; - - /** - * 最后更新人id - */ - private Long modifyBy; - - /** - * 最后更新时间 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime modifyTime; - - /** - * 是否已删除 - */ - private Boolean isDelete; - - /** - * 所属商户id - */ - @ApiModelProperty("所属商户id") - private String businessId; - - @TableField(exist = false) - private List child; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopOrder.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopOrder.java deleted file mode 100644 index ef89ed0..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopOrder.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.ruoyi.shop.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; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.List; - -/** - *

- * 订单 - *

- * - * @author xn - * @since 2022-09-23 - */ -@ApiModel(description= "返回订单信息") -@Data -@EqualsAndHashCode(callSuper = false) -public class ShopOrder implements Serializable { - - private static final long serialVersionUID=1L; - - - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; - - /** - * 创建时间/注册时间 - */ - @ApiModelProperty("创建时间") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime createTime; - - /** - * 最后更新时间 - */ - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime modifyTime; - - /** - * 管理员备注 - */ - private String adminMessage; - - /** - * 收件人 - */ - @ApiModelProperty("收件人") - private String consignee; - - /** - * 收件地址 - */ - @ApiModelProperty("收件地址") - private String consigneeAddress; - - /** - * 收件人电话 - */ - @ApiModelProperty("收件人电话") - private String mobile; - - /** - * 优惠券抵扣金额 - */ - @ApiModelProperty("优惠券抵扣金额") - private String couponPrice; - - /** - * 快递公司 - */ - @ApiModelProperty("快递公司") - private String express; - - /** - * 消费者id - */ - private Long idUser; - - /** - * 订单备注 - */ - @ApiModelProperty("订单备注") - private String message; - - /** - * 订单号 - */ - @ApiModelProperty("订单号") - private String orderSn; - - /** - * 支付流水号 - */ - @ApiModelProperty("支付流水号") - private String payId; - - /** - * 支付状态1:支付中;2:已付款,3:支付失败 - */ - @ApiModelProperty("支付状态1:支付中;2:已付款,3:支付失败") - private Integer payStatus; - - /** - * 支付成功时间 - */ - @ApiModelProperty("支付成功时间") - private String payTime; - - /** - * 实付类型:alipay,wechat - */ - @ApiModelProperty("实付类型") - private String payType; - - /** - * 实付金额 - */ - @ApiModelProperty("实付金额") - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal realPrice; - - - /** - * 快递单号 - */ - @ApiModelProperty("快递单号") - private String shippingSn; - - /** - * 出库时间 - */ - @ApiModelProperty("出库时间") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime shippingTime; - - /** - * 状态 - * 1已下单/待付款 - * 2取消订单 - * 3已付款/待发货 - * 4已发货/待收货 - * 5拒收 - * 6已签收 - */ - @ApiModelProperty(" * 状态\n" + - " * 1已下单/待付款\n" + - " * 2取消订单\n" + - " * 3已付款/待发货\n" + - " * 4已发货/待收货\n" + - " * 5拒收\n" + - " * 6已签收") - private Integer status; - - /** - * 总金额 - */ - @ApiModelProperty("总金额") - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal totalPrice; - - /** - * 交易金额 - */ - @ApiModelProperty("交易金额") - @JsonFormat(shape = JsonFormat.Shape.STRING) - private BigDecimal tradeAmount; - - /** - * 所属商户id - */ - @ApiModelProperty("所属商户id") - private String businessId; - - /** - * 订单类型:1.商品 2.会籍 3.课程 - */ - @ApiModelProperty("订单类型") - private Integer orderType; - - @ApiModelProperty("订单明细") - @TableField(exist = false) - private List itemList; - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopOrderItem.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopOrderItem.java deleted file mode 100644 index dd3e6d3..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/ShopOrderItem.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.ruoyi.shop.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.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -/** - *

- * 订单明细 - *

- * - * @author xn - * @since 2022-09-23 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class ShopOrderItem implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; - - /** - * 最后更新时间 - */ - @ApiModelProperty("最后更新时间") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime modifyTime; - - /** - * 数量 - */ - @ApiModelProperty("数量") - private String count; - - /** - * 商品id - */ - @ApiModelProperty("商品id") - private String idGoods; - - /** - * 所属订单id - */ - @ApiModelProperty("所属订单id") - private String idOrder; - - /** - * 单价 - */ - @ApiModelProperty("单价") - private BigDecimal price; - - /** - * 合计 - */ - @ApiModelProperty("合计") - private BigDecimal totalPrice; - //* 缩略图 - @ApiModelProperty("缩略图") - private String thumbnail; - //* 商品简介 - @ApiModelProperty("商品简介") - private String brief; - //* 规格 - @ApiModelProperty("规格") - private String attribute; - - - // 开课记录id - private Integer idSouseLog; - - // "会员id - private Integer idMember; - - // "商品名称 - private String goodsName; - - // "1 商品 2 会籍 3 课程 - private String type; - - // "会籍有效期 - private Integer memberValidity; - - // "课程内容 - private String courseContext; - - //课程说明") - private String courseExplain; - - //会籍类型") - private String memberType; - - //课程类型 2大咖 3教练培训") - private String courseType; - - //大咖1 大咖 2 大咖3 具体分类") - private String courseType1; - // 上课日期 - private String startDate; - // 上课时间 - private String startTime; - //上课时长 - private String sourceTime; - //上课地点 - private String place; - //课程名称 - private String courseNames; - //会籍推荐人 电话号 - private String memberRecommend; - @TableField(exist = false) - private ShopGoods goods; - - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/VenueDto.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/VenueDto.java deleted file mode 100644 index 03d7793..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/VenueDto.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.ruoyi.shop.domain; - -import lombok.Data; - -@Data -public class VenueDto { - private String name;//课程名称(简介) - private String picture;//封面图片 - private String text;//课程介绍 富文本 -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjCourseLp.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjCourseLp.java deleted file mode 100644 index 1f4c2e8..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjCourseLp.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ruoyi.shop.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.ruoyi.course.domain.CourseLog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.util.List; - -/** - *

- * 瑜伽流派 - *

- * - * @author xn - * @since 2022-10-31 - */ -@ApiModel(description= "瑜伽流派及对应课程") -@Data -@EqualsAndHashCode(callSuper = false) -public class YjCourseLp implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - /** - * 流派名称 - */ - @ApiModelProperty("流派名称") - private String name; - - /** - * 图标 - */ - @ApiModelProperty("图标") - private String img; - - /** - * 商户id - */ - private String merchantId; - - private Boolean enabled; - - @ApiModelProperty("当前流派下的课程") - @TableField(exist = false) - private List courseList; - - @ApiModelProperty("课程分类 2大咖课 3教练培训") - @TableField(exist = false) - private String courseType;//课程分类 2大咖课 3教练培训 - - @TableField(exist = false) - private Boolean releases; - /** - * 简介 - */ - @ApiModelProperty("简介") - private String context; -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjCourseLpMenu.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjCourseLpMenu.java deleted file mode 100644 index 78dbe49..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjCourseLpMenu.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.ruoyi.shop.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; - -/** - *

- * - *

- * - * @author xn - * @since 2022-10-31 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class YjCourseLpMenu implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "course_id", type = IdType.ASSIGN_UUID) - private Integer courseId; - - private int lpId; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjIndex.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjIndex.java deleted file mode 100644 index 1875fee..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjIndex.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ruoyi.shop.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 com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.util.List; - -/** - *

- * - *

- * - * @author xn - * @since 2022-09-26 - */ -@Data -@EqualsAndHashCode(callSuper = false) -@TableName(value = "yj_index",autoResultMap = true) -public class YjIndex implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; - - /** - * 商户id - */ - @ApiModelProperty("商户id") - private String merchantId; - - /** - * 首页图文内容 - */ - @ApiModelProperty("首页图标list") - @TableField(typeHandler = JacksonTypeHandler.class) - private List indexList; - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjIndexDto.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjIndexDto.java deleted file mode 100644 index 9aa37e0..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjIndexDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ruoyi.shop.domain; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@Data -public class YjIndexDto { - @ApiModelProperty("首页图标名称") - private String name;//名称 - @ApiModelProperty("首页图标") - private String picture;//图片 - private String code; -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjLink.java b/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjLink.java deleted file mode 100644 index f479ec3..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/domain/YjLink.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ruoyi.shop.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - *

- * - *

- * - * @author xn - * @since 2022-09-23 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class YjLink implements Serializable { - - private static final long serialVersionUID=1L; - - @TableId(value = "id", type = IdType.ASSIGN_UUID) - private String id; - - private String url; - - private String name; - - /** - * 资源类型(图片/视频) - */ - private String type; - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") - private LocalDateTime addTime;//添加时间 - private Boolean isDelete;//是否被删除 - /** - * 所属商户id - */ - private String merchantId; - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ConsumerMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ConsumerMapper.java deleted file mode 100644 index 4de3bf5..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ConsumerMapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.Consumer; - -/** - *

- * 消费者用户表 Mapper 接口 - *

- * - * @author xn - * @since 2022-09-27 - */ -public interface ConsumerMapper extends BaseMapper { - - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopCartMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopCartMapper.java deleted file mode 100644 index 2d67c7a..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopCartMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.ShopCart; -import com.ruoyi.shop.domain.ShopGoods; - - -import java.util.List; - -/** - *

- * 购物车 Mapper 接口 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface ShopCartMapper extends BaseMapper { - - List cartList(Long userId); - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopGoodsCategoryMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopGoodsCategoryMapper.java deleted file mode 100644 index 8120cba..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopGoodsCategoryMapper.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.shop.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.ShopGoodsCategory; - -import java.util.List; - -/** - *

- * 商品类别表 Mapper 接口 - *

- * - * @author xn - * @since 2022-09-22 - */ -public interface ShopGoodsCategoryMapper extends BaseMapper { - - List getList(ShopGoodsCategory category); - List getList2(ShopGoodsCategory category); - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopGoodsMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopGoodsMapper.java deleted file mode 100644 index 2a934a3..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopGoodsMapper.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.shop.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.ShopGoods; - - -import java.util.List; - -/** - *

- * 商品表 Mapper 接口 - *

- * - * @author xn - * @since 2022-09-22 - */ -public interface ShopGoodsMapper extends BaseMapper { - - List getList(ShopGoods goods); - List getByPid(String pid); -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopOrderItemMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopOrderItemMapper.java deleted file mode 100644 index 3f62370..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopOrderItemMapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.ruoyi.shop.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.ShopOrderItem; - -/** - *

- * 订单明细 Mapper 接口 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface ShopOrderItemMapper extends BaseMapper { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopOrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopOrderMapper.java deleted file mode 100644 index 25f8f1b..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/ShopOrderMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.ShopOrder; - -/** - *

- * 订单 Mapper 接口 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface ShopOrderMapper extends BaseMapper { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjCourceLpMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjCourceLpMapper.java deleted file mode 100644 index 041746d..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjCourceLpMapper.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.course.domain.CourseLog; -import com.ruoyi.shop.domain.YjCourseLp; - -import java.util.List; - -/** - *

- * 瑜伽流派 Mapper 接口 - *

- * - * @author xn - * @since 2022-10-31 - */ -public interface YjCourceLpMapper extends BaseMapper { - - int newMerchant(YjCourseLp lp); -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjIndexMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjIndexMapper.java deleted file mode 100644 index 314f20f..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjIndexMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjIndex; - -/** - *

- * Mapper 接口 - *

- * - * @author xn - * @since 2022-09-26 - */ -public interface YjIndexMapper extends BaseMapper { - - /** - * 新商户的app页面初始化 - * @param - * @return - */ - int newMerchant(YjIndex index); -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjLinkMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjLinkMapper.java deleted file mode 100644 index 1418634..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjLinkMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjLink; - -/** - *

- * Mapper 接口 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface YjLinkMapper extends BaseMapper { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjMerchantMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjMerchantMapper.java deleted file mode 100644 index b3da528..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjMerchantMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjMerchant; - -/** - *

- * 商户表 Mapper 接口 - *

- * - * @author xn - * @since 2022-09-28 - */ -public interface YjMerchantMapper extends BaseMapper { - - int deleteMerchant(YjMerchant merchant); - int deleteData(YjMerchant merchant); - int deleteEnterprise(YjMerchant merchant); - int deleteIndex(YjMerchant merchant); - int deleteCourseLp(YjMerchant merchant); - int deleteDept(YjMerchant merchant); - int updateUser(YjMerchant merchant); -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjSourceLpMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjSourceLpMenuMapper.java deleted file mode 100644 index 505e5ca..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/mapper/YjSourceLpMenuMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.shop.domain.YjCourseLpMenu; - -/** - *

- * Mapper 接口 - *

- * - * @author xn - * @since 2022-10-31 - */ -public interface YjSourceLpMenuMapper extends BaseMapper { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ConsumerService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/ConsumerService.java deleted file mode 100644 index 40a54b3..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ConsumerService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.ruoyi.shop.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.Consumer; - -/** - *

- * 消费者用户表 服务类 - *

- * - * @since 2022-09-27 - */ -public interface ConsumerService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopAddressService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopAddressService.java deleted file mode 100644 index e3ed2dc..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopAddressService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.ShopAddress; - -/** - *

- * 用户地址 服务类 - *

- * - * @author xn - * @since 2022-09-29 - */ -public interface ShopAddressService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopCartService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopCartService.java deleted file mode 100644 index 4c6083e..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopCartService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.ShopCart; - -/** - *

- * 购物车 服务类 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface ShopCartService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopGoodsCategoryService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopGoodsCategoryService.java deleted file mode 100644 index 5df5fb8..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopGoodsCategoryService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.ruoyi.shop.service; - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.ShopGoodsCategory; - -/** - *

- * 商品类别表 服务类 - *

- * - * @author xn - * @since 2022-09-22 - */ -public interface ShopGoodsCategoryService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopGoodsService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopGoodsService.java deleted file mode 100644 index 700245c..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopGoodsService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.ruoyi.shop.service; - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.ShopGoods; - -/** - *

- * 商品表 服务类 - *

- * - * @author xn - * @since 2022-09-22 - */ -public interface ShopGoodsService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopOrderItemService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopOrderItemService.java deleted file mode 100644 index 7dc78a0..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopOrderItemService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.ShopOrderItem; - -/** - *

- * 订单明细 服务类 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface ShopOrderItemService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopOrderService.java deleted file mode 100644 index 53b3ff7..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/ShopOrderService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.ShopOrder; - -/** - *

- * 订单 服务类 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface ShopOrderService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjIndexService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjIndexService.java deleted file mode 100644 index f4d8e37..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjIndexService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.YjIndex; - -/** - *

- * 服务类 - *

- * - * @author xn - * @since 2022-09-26 - */ -public interface YjIndexService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjLinkService.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjLinkService.java deleted file mode 100644 index dd77ef9..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/YjLinkService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ruoyi.shop.service; - - -import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.shop.domain.YjLink; - -/** - *

- * 服务类 - *

- * - * @author xn - * @since 2022-09-23 - */ -public interface YjLinkService extends IService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ConsumerServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ConsumerServiceImpl.java deleted file mode 100644 index d2bb1f3..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ConsumerServiceImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - -import com.ruoyi.shop.domain.Consumer; -import com.ruoyi.shop.mapper.ConsumerMapper; -import com.ruoyi.shop.service.ConsumerService; -import org.springframework.stereotype.Service; - -/** - *

- * 消费者用户表 服务实现类 - *

- * - * @since 2022-09-27 - */ -@Service -public class ConsumerServiceImpl extends ServiceImpl implements ConsumerService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopAddressServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopAddressServiceImpl.java deleted file mode 100644 index fab6b79..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopAddressServiceImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - -import com.ruoyi.shop.domain.ShopAddress; -import com.ruoyi.shop.mapper.ShopAddressMapper; -import com.ruoyi.shop.service.ShopAddressService; -import org.springframework.stereotype.Service; - -/** - *

- * 用户地址 服务实现类 - *

- * - * @author xn - * @since 2022-09-29 - */ -@Service -public class ShopAddressServiceImpl extends ServiceImpl implements ShopAddressService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopCartServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopCartServiceImpl.java deleted file mode 100644 index 64a14f5..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopCartServiceImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - -import com.ruoyi.shop.domain.ShopCart; -import com.ruoyi.shop.mapper.ShopCartMapper; -import com.ruoyi.shop.service.ShopCartService; -import org.springframework.stereotype.Service; - -/** - *

- * 购物车 服务实现类 - *

- * - * @author xn - * @since 2022-09-23 - */ -@Service -public class ShopCartServiceImpl extends ServiceImpl implements ShopCartService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopGoodsCategoryServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopGoodsCategoryServiceImpl.java deleted file mode 100644 index 74fc17e..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopGoodsCategoryServiceImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.ShopGoodsCategory; -import com.ruoyi.shop.mapper.ShopGoodsCategoryMapper; -import com.ruoyi.shop.service.ShopGoodsCategoryService; -import org.springframework.stereotype.Service; - -/** - *

- * 商品类别表 服务实现类 - *

- * - * @author xn - * @since 2022-09-22 - */ -@Service -public class ShopGoodsCategoryServiceImpl extends ServiceImpl implements ShopGoodsCategoryService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopGoodsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopGoodsServiceImpl.java deleted file mode 100644 index e2b3959..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopGoodsServiceImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - -import com.ruoyi.shop.domain.ShopGoods; -import com.ruoyi.shop.mapper.ShopGoodsMapper; -import com.ruoyi.shop.service.ShopGoodsService; -import org.springframework.stereotype.Service; - -/** - *

- * 商品表 服务实现类 - *

- * - * @author xn - * @since 2022-09-22 - */ -@Service -public class ShopGoodsServiceImpl extends ServiceImpl implements ShopGoodsService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopOrderItemServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopOrderItemServiceImpl.java deleted file mode 100644 index be823dc..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopOrderItemServiceImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - -import com.ruoyi.shop.domain.ShopOrderItem; -import com.ruoyi.shop.mapper.ShopOrderItemMapper; -import com.ruoyi.shop.service.ShopOrderItemService; -import org.springframework.stereotype.Service; - -/** - *

- * 订单明细 服务实现类 - *

- * - * @author xn - * @since 2022-09-23 - */ -@Service -public class ShopOrderItemServiceImpl extends ServiceImpl implements ShopOrderItemService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopOrderServiceImpl.java deleted file mode 100644 index 85c9cb5..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/ShopOrderServiceImpl.java +++ /dev/null @@ -1,224 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import cn.hutool.core.date.DateUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.common.utils.JpushClientUtil; -import com.ruoyi.course.domain.ConsumerCourse; -import com.ruoyi.course.domain.HistoryMessage; -import com.ruoyi.course.service.ConsumerCourseServiceImpl; -import com.ruoyi.course.service.HistoryMessageServiceImpl; -import com.ruoyi.search.domain.MemberUser; -import com.ruoyi.search.service.MemberUserServicelmpl; -import com.ruoyi.shop.domain.ShopGoods; -import com.ruoyi.shop.domain.ShopOrder; -import com.ruoyi.shop.domain.ShopOrderItem; -import com.ruoyi.shop.mapper.ShopOrderMapper; -import com.ruoyi.shop.service.ShopOrderService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import java.math.BigDecimal; -import java.util.List; - -/** - *

- * 订单 服务实现类 - *

- * - * @author xn - * @since 2022-09-23 - */ -@Service -public class ShopOrderServiceImpl extends ServiceImpl implements ShopOrderService { - - @Resource - private ShopOrderItemServiceImpl itemService; - @Resource - private ShopGoodsServiceImpl goodsService; - @Resource - private HistoryMessageServiceImpl historyMessageService; - @Resource - private MemberUserServicelmpl memberUserServicelmpl; - @Resource - private ConsumerCourseServiceImpl consumerCourseService; - - /** - * 取消订单 - * @param out_trade_no 订单号 - * @return - */ - @Transactional(rollbackFor = RuntimeException.class) - public void cancelOrder(String out_trade_no){ - List list = this.list(new QueryWrapper().eq("order_sn",out_trade_no)); - ShopOrder order=list.get(0); - //1.商品订单 - // ①更改订单状态 - // ②查询对应订单详情 - // ③根据订单详情数量 更改商品库存 - if (order.getOrderType()==1){ - - for (ShopOrder o:list){ - Boolean isUpdate= this.update(new UpdateWrapper() - .set("status",2)//2取消订单 - .set("pay_status",3)//支付状态1:支付中;2:已付款,3:支付失败 - .eq("id",o.getId()) - .eq("status",1) - .eq("pay_status",1)); - - if (isUpdate){ - List itemList=itemService.list(new QueryWrapper() - .eq("id_order",o.getId())); - for (ShopOrderItem item:itemList){ - goodsService.update(new UpdateWrapper() - .setSql("stock=stock+"+item.getCount()) - .eq("id",item.getIdGoods())); - } - } - } - } - - else { - this.update(new UpdateWrapper() - .set("status",2)//2取消订单 - .set("pay_status",3)//支付状态1:支付中;2:已付款,3:支付失败 - .eq("id",order.getId()) - .eq("status",1) - .eq("pay_status",1)); - } - //推送 客户 try catch - try { - sendM(order.getMobile(),"订单: "+order.getOrderSn()+" 支付失败!"); - } catch (Exception e) { - e.printStackTrace(); - } - - System.out.println("订单支付失败"); - } - - /** - * 付款成功 - * @param out_trade_no 订单号 - * @param success_time 支付成功时间 yyyy-MM-dd HH:mm:ss - * @param transaction_id 支付流水号=微信支付订单号 - * @param realPrice 实际支付金额(分) - * @return - */ - public void paySuccess(String out_trade_no,String success_time,String transaction_id,String realPrice){ - //根据订单号查找订单list - List list = this.list(new QueryWrapper().eq("order_sn",out_trade_no)); - ShopOrder order=list.get(0); - BigDecimal payPrice= new BigDecimal(realPrice).divide(new BigDecimal(100));//实际支付金额 - //根据订单类型 分别为: - //1. 商品 - //① 更改订单状态 - //② 推送客户 try catch - //③ 生成消息记录 - if (order.getOrderType()==1){ - for (ShopOrder o:list){ - o.setStatus(3);//已付款/待发货 - o.setPayStatus(2);//支付状态 支付成功 - o.setPayTime(success_time);//支付成功时间 - o.setRealPrice(o.getTradeAmount());//实际支付金额 - o.setPayId(transaction_id);//支付流水号=微信支付订单号 - this.updateById(o); - } - //推送 客户 try catch "订单: "+orderSn - try { - sendM(order.getMobile(),"订单: "+order.getOrderSn()+"支付成功"); - } catch (Exception e) { - e.printStackTrace(); - } - } - - //2. 会籍 - // ①更改订单状态 - // ②办理会籍 - // ③推送客户+会籍顾问 try catch - // ④生成消息记录 - if (order.getOrderType()==2){ - - ShopOrderItem item=itemService.getOne(new QueryWrapper() - .eq("id_order",order.getId())); - MemberUser memberUser=new MemberUser(); - memberUser.setValidity(item.getMemberValidity()); - memberUser.setMemberId(item.getIdMember()); - memberUser.setMemberName(item.getMemberType()); - memberUser.setMemberContext(item.getBrief()); - memberUser.setMemberPrice(item.getTotalPrice()); - memberUser.setMemberPicture(item.getThumbnail()); - memberUser.setConsumerId(order.getIdUser()); - memberUser.setPrice(payPrice);//实付金额 - memberUser.setStroreId(order.getBusinessId()); - memberUser.setRecommend(item.getMemberRecommend());//推荐人 电话 - if (memberUserServicelmpl.handleMember(memberUser)) { - throw new RuntimeException(); - } - - order.setPayStatus(2);//支付状态 支付成功 - order.setPayTime(success_time);//支付成功时间 - order.setRealPrice(payPrice);//实际支付金额 - order.setPayId(transaction_id);//支付流水号=微信支付订单号 - this.updateById(order); - - try { - sendM(order.getMobile(),"订单: "+order.getOrderSn()+"支付成功");//推送客户消息 - sendM(item.getMemberRecommend(),"您推荐的订单: "+order.getOrderSn()+"支付成功");//推送推荐人消息 - } catch (Exception e) { - e.printStackTrace(); - } - } - - //3. 大咖/教练培训课 - // ① 更改订单状态 - // ② 给客户添加课程 - // ③ 推送客户 try catch - if (order.getOrderType()==3){ - - ShopOrderItem item=itemService.getOne(new QueryWrapper() - .eq("id_order",order.getId())); - ConsumerCourse consumerCourse=new ConsumerCourse(); - consumerCourse.setConsumerId(order.getIdUser()); - consumerCourse.setCourseLogId(item.getIdSouseLog()); - consumerCourseService.save(consumerCourse); - - order.setPayStatus(2);//支付状态 支付成功 - order.setPayTime(success_time);//支付成功时间 - order.setRealPrice(payPrice);//实际支付金额 - order.setPayId(transaction_id);//支付流水号=微信支付订单号 - this.updateById(order); - - //推送 客户 try catch - try { - sendM(order.getMobile(),"订单: "+order.getOrderSn()+"支付成功");//推送客户消息 - } catch (Exception e) { - e.printStackTrace(); - } - } - - System.out.println("订单支付成功"); - } - - /** - * 推送消息 - * @param - * @param phone 手机号 - */ - public void sendM(String phone,String notification_title){ - - String msg_content="点击查看!"; - JpushClientUtil.sendMessage(phone,notification_title,msg_content); - - //消息记录 - HistoryMessage message=new HistoryMessage(); - message.setPhone(phone); - message.setNotificationTitle(notification_title); - message.setMsgContent(msg_content); - message.setSendTime(DateUtil.now()); - historyMessageService.save(message); - } - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjCourceLpMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjCourceLpMenuServiceImpl.java deleted file mode 100644 index 8290fcb..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjCourceLpMenuServiceImpl.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjCourseLpMenu; -import com.ruoyi.shop.mapper.YjSourceLpMenuMapper; -import org.springframework.stereotype.Service; - -/** - *

- * 服务实现类 - *

- * - * @author xn - * @since 2022-10-31 - */ -@Service -public class YjCourceLpMenuServiceImpl extends ServiceImpl { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjCourceLpServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjCourceLpServiceImpl.java deleted file mode 100644 index b8a1672..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjCourceLpServiceImpl.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjCourseLp; -import com.ruoyi.shop.mapper.YjCourceLpMapper; -import org.springframework.stereotype.Service; - -/** - *

- * 瑜伽流派 服务实现类 - *

- * - * @author xn - * @since 2022-10-31 - */ -@Service -public class YjCourceLpServiceImpl extends ServiceImpl { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjIndexServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjIndexServiceImpl.java deleted file mode 100644 index 99ff4b5..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjIndexServiceImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjIndex; -import com.ruoyi.shop.mapper.YjIndexMapper; -import com.ruoyi.shop.service.YjIndexService; -import org.springframework.stereotype.Service; - -/** - *

- * 服务实现类 - *

- * - * @author xn - * @since 2022-09-26 - */ -@Service -public class YjIndexServiceImpl extends ServiceImpl implements YjIndexService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjLinkServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjLinkServiceImpl.java deleted file mode 100644 index cad9036..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjLinkServiceImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.shop.domain.YjLink; -import com.ruoyi.shop.mapper.YjLinkMapper; -import com.ruoyi.shop.service.YjLinkService; -import org.springframework.stereotype.Service; - -/** - *

- * 服务实现类 - *

- * - * @author xn - * @since 2022-09-23 - */ -@Service -public class YjLinkServiceImpl extends ServiceImpl implements YjLinkService { - - public void add(String url,String type){ - YjLink yjLink=new YjLink(); - yjLink.setUrl(url); - yjLink.setType(type); - yjLink.setMerchantId(SecurityUtils.getMerchanId()); - this.save(yjLink); - } -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjMerchantServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjMerchantServiceImpl.java deleted file mode 100644 index be180ea..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/shop/service/impl/YjMerchantServiceImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ruoyi.shop.service.impl; - - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.shop.domain.YjMerchant; -import com.ruoyi.shop.mapper.YjMerchantMapper; -import com.ruoyi.shop.service.YjMerchantService; -import org.springframework.stereotype.Service; - -/** - *

- * 商户表 服务实现类 - *

- * - * @author xn - * @since 2022-09-28 - */ -@Service -public class YjMerchantServiceImpl extends ServiceImpl implements YjMerchantService { - -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java deleted file mode 100644 index 83f0703..0000000 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.ruoyi.system.domain; - -import com.ruoyi.common.utils.StringUtils; - -/** - * 缓存信息 - * - * @author ruoyi - */ -public class SysCache -{ - /** 缓存名称 */ - private String cacheName = ""; - - /** 缓存键名 */ - private String cacheKey = ""; - - /** 缓存内容 */ - private String cacheValue = ""; - - /** 备注 */ - private String remark = ""; - - public SysCache() - { - - } - - public SysCache(String cacheName, String remark) - { - this.cacheName = cacheName; - this.remark = remark; - } - - public SysCache(String cacheName, String cacheKey, String cacheValue) - { - this.cacheName = StringUtils.replace(cacheName, ":", ""); - this.cacheKey = StringUtils.replace(cacheKey, cacheName, ""); - this.cacheValue = cacheValue; - } - - public String getCacheName() - { - return cacheName; - } - - public void setCacheName(String cacheName) - { - this.cacheName = cacheName; - } - - public String getCacheKey() - { - return cacheKey; - } - - public void setCacheKey(String cacheKey) - { - this.cacheKey = cacheKey; - } - - public String getCacheValue() - { - return cacheValue; - } - - public void setCacheValue(String cacheValue) - { - this.cacheValue = cacheValue; - } - - public String getRemark() - { - return remark; - } - - public void setRemark(String remark) - { - this.remark = remark; - } -} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java index c988bdf..99d0bf1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java @@ -1,26 +1,26 @@ package com.ruoyi.system.mapper; import com.ruoyi.common.core.domain.entity.SysDept; -import com.ruoyi.shop.domain.YjVenue; +import com.ruoyi.basic.domain.dto.YjVenueDto; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 部门管理 数据层 - * + * * @author ruoyi */ public interface SysDeptMapper { - List selectForVenue(SysDept dept); + List selectForVenue(SysDept dept); int updateForVenue(SysDept dept); - YjVenue getOneForVenue(SysDept dept); + YjVenueDto getOneForVenue(SysDept dept); /** * 查询部门管理数据 - * + * * @param dept 部门信息 * @return 部门信息集合 */ @@ -28,7 +28,7 @@ public interface SysDeptMapper /** * 根据角色ID查询部门树信息 - * + * * @param roleId 角色ID * @param deptCheckStrictly 部门树选择项是否关联显示 * @return 选中部门列表 @@ -37,7 +37,7 @@ public interface SysDeptMapper /** * 根据部门ID查询信息 - * + * * @param deptId 部门ID * @return 部门信息 */ @@ -45,7 +45,7 @@ public interface SysDeptMapper /** * 根据ID查询所有子部门 - * + * * @param deptId 部门ID * @return 部门列表 */ @@ -53,7 +53,7 @@ public interface SysDeptMapper /** * 根据ID查询所有子部门(正常状态) - * + * * @param deptId 部门ID * @return 子部门数 */ @@ -61,7 +61,7 @@ public interface SysDeptMapper /** * 是否存在子节点 - * + * * @param deptId 部门ID * @return 结果 */ @@ -69,7 +69,7 @@ public interface SysDeptMapper /** * 查询部门是否存在用户 - * + * * @param deptId 部门ID * @return 结果 */ @@ -77,7 +77,7 @@ public interface SysDeptMapper /** * 校验部门名称是否唯一 - * + * * @param deptName 部门名称 * @param parentId 父部门ID * @return 结果 @@ -86,7 +86,7 @@ public interface SysDeptMapper /** * 新增部门信息 - * + * * @param dept 部门信息 * @return 结果 */ @@ -94,7 +94,7 @@ public interface SysDeptMapper /** * 修改部门信息 - * + * * @param dept 部门信息 * @return 结果 */ @@ -102,14 +102,14 @@ public interface SysDeptMapper /** * 修改所在部门正常状态 - * + * * @param deptIds 部门ID组 */ public void updateDeptStatusNormal(Long[] deptIds); /** * 修改子元素关系 - * + * * @param depts 子元素 * @return 结果 */ @@ -117,7 +117,7 @@ public interface SysDeptMapper /** * 删除部门管理信息 - * + * * @param deptId 部门ID * @return 结果 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java index 8eb5448..cd89549 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java @@ -5,14 +5,14 @@ import com.ruoyi.system.domain.SysUserOnline; /** * 在线用户 服务层 - * + * * @author ruoyi */ public interface ISysUserOnlineService { /** * 通过登录地址查询信息 - * + * * @param ipaddr 登录地址 * @param user 用户信息 * @return 在线用户信息 @@ -21,7 +21,7 @@ public interface ISysUserOnlineService /** * 通过用户名称查询信息 - * + * * @param userName 用户名称 * @param user 用户信息 * @return 在线用户信息 @@ -30,7 +30,7 @@ public interface ISysUserOnlineService /** * 通过登录地址/用户名称查询信息 - * + * * @param ipaddr 登录地址 * @param userName 用户名称 * @param user 用户信息 @@ -40,7 +40,7 @@ public interface ISysUserOnlineService /** * 设置在线用户信息 - * + * * @param user 用户信息 * @return 在线用户 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java index 442cfe2..98a10ee 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java @@ -11,7 +11,7 @@ import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.shop.domain.YjVenue; +import com.ruoyi.basic.domain.dto.YjVenueDto; import com.ruoyi.system.mapper.SysDeptMapper; import com.ruoyi.system.mapper.SysRoleMapper; import com.ruoyi.system.service.ISysDeptService; @@ -25,7 +25,7 @@ import java.util.stream.Collectors; /** * 部门管理 服务实现 - * + * * @author ruoyi */ @Service @@ -37,7 +37,7 @@ public class SysDeptServiceImpl implements ISysDeptService @Autowired private SysRoleMapper roleMapper; - public List selectForVenue(SysDept dept) + public List selectForVenue(SysDept dept) { return deptMapper.selectForVenue(dept); } @@ -49,7 +49,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 查询部门管理数据 - * + * * @param dept 部门信息 * @return 部门信息集合 */ @@ -62,7 +62,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 查询部门树结构信息 - * + * * @param dept 部门信息 * @return 部门树信息集合 */ @@ -75,7 +75,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 构建前端所需要树结构 - * + * * @param depts 部门列表 * @return 树结构列表 */ @@ -106,7 +106,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 构建前端所需要下拉树结构 - * + * * @param depts 部门列表 * @return 下拉树结构列表 */ @@ -119,7 +119,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 根据角色ID查询部门树信息 - * + * * @param roleId 角色ID * @return 选中部门列表 */ @@ -132,7 +132,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 根据部门ID查询信息 - * + * * @param deptId 部门ID * @return 部门信息 */ @@ -144,7 +144,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 根据ID查询所有子部门(正常状态) - * + * * @param deptId 部门ID * @return 子部门数 */ @@ -156,7 +156,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 是否存在子节点 - * + * * @param deptId 部门ID * @return 结果 */ @@ -169,7 +169,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 查询部门是否存在用户 - * + * * @param deptId 部门ID * @return 结果 true 存在 false 不存在 */ @@ -182,7 +182,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 校验部门名称是否唯一 - * + * * @param dept 部门信息 * @return 结果 */ @@ -200,7 +200,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 校验部门是否有数据权限 - * + * * @param deptId 部门id */ @Override @@ -220,7 +220,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 新增保存部门信息 - * + * * @param dept 部门信息 * @return 结果 */ @@ -241,7 +241,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 修改保存部门信息 - * + * * @param dept 部门信息 * @return 结果 */ @@ -269,7 +269,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 修改该部门的父级部门状态 - * + * * @param dept 当前部门 */ private void updateParentDeptStatusNormal(SysDept dept) @@ -281,7 +281,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 修改子元素关系 - * + * * @param deptId 被修改的部门ID * @param newAncestors 新的父ID集合 * @param oldAncestors 旧的父ID集合 @@ -301,7 +301,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 删除部门管理信息 - * + * * @param deptId 部门ID * @return 结果 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java index f80a877..179ccda 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.system.service.impl; +import com.ruoyi.common.core.domain.model.LoginUser; import org.springframework.stereotype.Service; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.utils.StringUtils; @@ -8,7 +9,7 @@ import com.ruoyi.system.service.ISysUserOnlineService; /** * 在线用户 服务层处理 - * + * * @author ruoyi */ @Service @@ -16,7 +17,7 @@ public class SysUserOnlineServiceImpl implements ISysUserOnlineService { /** * 通过登录地址查询信息 - * + * * @param ipaddr 登录地址 * @param user 用户信息 * @return 在线用户信息 @@ -33,7 +34,7 @@ public class SysUserOnlineServiceImpl implements ISysUserOnlineService /** * 通过用户名称查询信息 - * + * * @param userName 用户名称 * @param user 用户信息 * @return 在线用户信息 @@ -50,7 +51,7 @@ public class SysUserOnlineServiceImpl implements ISysUserOnlineService /** * 通过登录地址/用户名称查询信息 - * + * * @param ipaddr 登录地址 * @param userName 用户名称 * @param user 用户信息 @@ -68,7 +69,7 @@ public class SysUserOnlineServiceImpl implements ISysUserOnlineService /** * 设置在线用户信息 - * + * * @param user 用户信息 * @return 在线用户 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 19748d6..643f13e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -259,14 +259,15 @@ public class SysUserServiceImpl implements ISysUserService @Transactional public int insertUser(SysUser user) { - Long[] roleIds= user.getRoleIds(); - if (roleIds.length>0){ - for (Long l:roleIds){ - if (l==100l){ - user.setMerchantId(""); +// Long[] roleIds= user.getRoleIds(); +// if (roleIds.length>0){ +// for (Long l:roleIds){ +// if (l==100l){//原商家(租户) + if (StringUtils.isNotNull(user.getRoleId())&&user.getRoleId()==107l){//app注册的用户 + user.setMerchantId("-1"); } - } - } +// } +// } // 新增用户信息 int rows = userMapper.insertUser(user); // 新增用户岗位关联 diff --git a/ruoyi-system/src/main/resources/mapper/basic/YjAppUserMapper.xml b/ruoyi-system/src/main/resources/mapper/basic/YjAppUserMapper.xml new file mode 100644 index 0000000..55eb08f --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/basic/YjAppUserMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/basic/YjAppreciateMapper.xml b/ruoyi-system/src/main/resources/mapper/basic/YjAppreciateMapper.xml new file mode 100644 index 0000000..5d77375 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/basic/YjAppreciateMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/source/HistoryMessageMapper.xml b/ruoyi-system/src/main/resources/mapper/basic/YjHealthyMapper.xml similarity index 70% rename from ruoyi-system/src/main/resources/mapper/source/HistoryMessageMapper.xml rename to ruoyi-system/src/main/resources/mapper/basic/YjHealthyMapper.xml index 699aae3..d36ccaa 100644 --- a/ruoyi-system/src/main/resources/mapper/source/HistoryMessageMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/basic/YjHealthyMapper.xml @@ -1,6 +1,6 @@ - + diff --git a/ruoyi-system/src/main/resources/mapper/basic/YjInheritMapper.xml b/ruoyi-system/src/main/resources/mapper/basic/YjInheritMapper.xml new file mode 100644 index 0000000..42a538c --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/basic/YjInheritMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/basic/YjPracticeMomentsMapper.xml b/ruoyi-system/src/main/resources/mapper/basic/YjPracticeMomentsMapper.xml new file mode 100644 index 0000000..b00c470 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/basic/YjPracticeMomentsMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/basic/YjSenseMapper.xml b/ruoyi-system/src/main/resources/mapper/basic/YjSenseMapper.xml new file mode 100644 index 0000000..4bdef44 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/basic/YjSenseMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/basic/YjStoreMapper.xml b/ruoyi-system/src/main/resources/mapper/basic/YjStoreMapper.xml new file mode 100644 index 0000000..f373021 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/basic/YjStoreMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/source/ContextMapper.xml b/ruoyi-system/src/main/resources/mapper/cource/ContextMapper.xml similarity index 74% rename from ruoyi-system/src/main/resources/mapper/source/ContextMapper.xml rename to ruoyi-system/src/main/resources/mapper/cource/ContextMapper.xml index dbe60ee..bd934d6 100644 --- a/ruoyi-system/src/main/resources/mapper/source/ContextMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/cource/ContextMapper.xml @@ -19,20 +19,15 @@ user_id, user_name, sex, phonenumber, avatar,context,releases,url,intro + + diff --git a/ruoyi-system/src/main/resources/mapper/cource/ScClaTimeMapper.xml b/ruoyi-system/src/main/resources/mapper/cource/ScClaTimeMapper.xml new file mode 100644 index 0000000..eaa02b8 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/cource/ScClaTimeMapper.xml @@ -0,0 +1,129 @@ + + + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/shop/ConsumerMapper.xml b/ruoyi-system/src/main/resources/mapper/im/FriendMapper.xml similarity index 73% rename from ruoyi-system/src/main/resources/mapper/shop/ConsumerMapper.xml rename to ruoyi-system/src/main/resources/mapper/im/FriendMapper.xml index 019b1ee..219dd2b 100644 --- a/ruoyi-system/src/main/resources/mapper/shop/ConsumerMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/im/FriendMapper.xml @@ -1,5 +1,6 @@ - + + diff --git a/ruoyi-system/src/main/resources/mapper/im/PrivateMessageMapper.xml b/ruoyi-system/src/main/resources/mapper/im/PrivateMessageMapper.xml new file mode 100644 index 0000000..75983dd --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/im/PrivateMessageMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/im/SensitiveWordMapper.xml b/ruoyi-system/src/main/resources/mapper/im/SensitiveWordMapper.xml new file mode 100644 index 0000000..9eb7ef7 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/im/SensitiveWordMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/AddressMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/AddressMapper.xml new file mode 100644 index 0000000..825b246 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/AddressMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + select id, code, parent_code, name, level, created_at, updated_at, deleted_at from address + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/AftersaleItemMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/AftersaleItemMapper.xml new file mode 100644 index 0000000..4064774 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/AftersaleItemMapper.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, member_id, order_id, order_item_id, return_amount, quantity, create_by, create_time, update_by, update_time from oms_aftersale_item + + + + insert into oms_aftersale_item + (member_id,order_id,aftersale_id,order_item_id,return_amount,quantity,create_by,create_time,update_by,update_time) + values + + + #{item.memberId,jdbcType=BIGINT}, + #{item.orderId,jdbcType=BIGINT}, + #{item.aftersaleId,jdbcType=BIGINT}, + #{item.orderItemId,jdbcType=BIGINT}, + #{item.returnAmount,jdbcType=DECIMAL}, + #{item.quantity,jdbcType=BIGINT}, + #{item.createBy,jdbcType=BIGINT}, + #{item.createTime,jdbcType=DATE}, + #{item.updateBy,jdbcType=BIGINT}, + #{item.updateTime,jdbcType=DATE} + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/AftersaleMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/AftersaleMapper.xml new file mode 100644 index 0000000..b14ab9e --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/AftersaleMapper.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, member_id, order_id, return_amount, type, status, handle_time, quantity, reason, description, proof_pics, handle_note, handle_man, create_by, create_time, update_by, update_time from oms_aftersale + + + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/BrandMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/BrandMapper.xml new file mode 100644 index 0000000..4678604 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/BrandMapper.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + select id, name, sort, show_status, logo, create_by, create_time, update_by, update_time from mall_brand + + + + diff --git a/ruoyi-system/src/main/resources/mapper/shop/ShopAddressMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/MemberAddressMapper.xml similarity index 82% rename from ruoyi-system/src/main/resources/mapper/shop/ShopAddressMapper.xml rename to ruoyi-system/src/main/resources/mapper/mall/MemberAddressMapper.xml index c71ea0e..265bb36 100644 --- a/ruoyi-system/src/main/resources/mapper/shop/ShopAddressMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/mall/MemberAddressMapper.xml @@ -1,9 +1,9 @@ - + - + diff --git a/ruoyi-system/src/main/resources/mapper/mall/MemberCartMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/MemberCartMapper.xml new file mode 100644 index 0000000..46aebc4 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/MemberCartMapper.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select id, status, member_id, product_id, pic, sku_id, product_name, sp_data, quantity, create_by, create_time, update_by, update_time from ums_member_cart + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/MemberWechatMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/MemberWechatMapper.xml new file mode 100644 index 0000000..f6c0b4b --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/MemberWechatMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, member_id, unionid, openid, routine_openid, groupid, tagid_list, subscribe, subscribe_time, session_key, access_token, expires_in, refresh_token, expire_time, create_by, create_time, update_by, update_time from ums_member_wechat + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/OrderItemMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/OrderItemMapper.xml new file mode 100644 index 0000000..221aec8 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/OrderItemMapper.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, order_id, product_id, out_product_id, sku_id, out_sku_id, product_snapshot_id, sku_snapshot_id, pic, product_name, sale_price, purchase_price, quantity, product_category_id, sp_data, create_by, create_time, update_by, update_time from oms_order_item + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/OrderMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/OrderMapper.xml new file mode 100644 index 0000000..6d13cdc --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/OrderMapper.xml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, member_id, member_username, total_amount, purchase_price, pay_amount, freight_amount, pay_type, status, aftersale_status, delivery_company, delivery_sn, auto_confirm_day, receiver_name, receiver_phone, receiver_post_code, receiver_province, receiver_city, receiver_district, receiver_province_id, receiver_city_id, receiver_district_id, receiver_detail_address, note, confirm_status, delete_status, payment_time, delivery_time, receive_time, create_by, create_time, update_by, update_time from oms_order + + + + update oms_order + set + status=#{item.status}, + update_by=#{item.updateBy}, + update_time=#{item.updateTime} + where id=#{item.id} + + + + + + + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/OrderOperateHistoryMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/OrderOperateHistoryMapper.xml new file mode 100644 index 0000000..79ca22c --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/OrderOperateHistoryMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, order_id, operate_man, order_status, note, create_by, create_time, update_by, update_time from oms_order_operate_history + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/ProductCategoryMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/ProductCategoryMapper.xml new file mode 100644 index 0000000..c24190d --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/ProductCategoryMapper.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + select id, parent_id, name, level, show_status, sort, icon, create_by, create_time, update_by, update_time from mall_product_category + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/ProductMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/ProductMapper.xml new file mode 100644 index 0000000..39c2dcd --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/ProductMapper.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, brand_id, category_id, out_product_id, name, pic, album_pics, publish_status, sort, price, unit, weight, detail_html, detail_mobile_html, brand_name, product_category_name, create_by, create_time, update_by, update_time from mall_product + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/SkuMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/SkuMapper.xml new file mode 100644 index 0000000..a6f5d28 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/SkuMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, product_id, out_sku_id, price, pic, sp_data, create_by, create_time, update_by, update_time from mall_sku + + + update + mall_sku + set + stock = stock - #{quantity}, + update_time = #{optDate} + where id = #{skuId} + + + + diff --git a/ruoyi-system/src/main/resources/mapper/mall/WechatPaymentHistoryMapper.xml b/ruoyi-system/src/main/resources/mapper/mall/WechatPaymentHistoryMapper.xml new file mode 100644 index 0000000..156f730 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/mall/WechatPaymentHistoryMapper.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, payment_id, member_id, openid, real_name, title, order_id, money, op_type, payment_status, remark, attach, response_body, create_by, create_time, update_by, update_time from oms_wechat_payment_history + + + + diff --git a/ruoyi-system/src/main/resources/mapper/search/MemberUserMapper.xml b/ruoyi-system/src/main/resources/mapper/search/MemberUserMapper.xml deleted file mode 100644 index 986f8d4..0000000 --- a/ruoyi-system/src/main/resources/mapper/search/MemberUserMapper.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/ShopCartMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/ShopCartMapper.xml deleted file mode 100644 index 8e5de65..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/ShopCartMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/ShopGoodsCategoryMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/ShopGoodsCategoryMapper.xml deleted file mode 100644 index 8cf13b2..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/ShopGoodsCategoryMapper.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/ShopGoodsMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/ShopGoodsMapper.xml deleted file mode 100644 index ac17ca2..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/ShopGoodsMapper.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/ShopOrderItemMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/ShopOrderItemMapper.xml deleted file mode 100644 index 1f4e5f0..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/ShopOrderItemMapper.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - id, modify_time, count, id_goods, id_order, price, total_price, id_souse_log, id_member, goods_name, type, member_validity, course_context, start_date, start_time, number, tearcher, place - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/ShopOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/ShopOrderMapper.xml deleted file mode 100644 index 8cf1877..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/ShopOrderMapper.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjAppreciateMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjAppreciateMapper.xml deleted file mode 100644 index 177b708..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjAppreciateMapper.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjCourceLpMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjCourceLpMapper.xml deleted file mode 100644 index 226104e..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjCourceLpMapper.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - INSERT INTO yj_course_lp(name,img, merchant_id) - SELECT name,img,#{merchantId} as merchant_id - FROM yj_course_lp - WHERE merchant_id='1'; - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjHealthyMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjHealthyMapper.xml deleted file mode 100644 index a4e2c7c..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjHealthyMapper.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjIndexMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjIndexMapper.xml deleted file mode 100644 index 5541d6f..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjIndexMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - INSERT INTO yj_index(id,merchant_id,index_list) - SELECT #{id} as id, #{merchantId} as merchant_id,index_list - FROM yj_index - WHERE merchant_id='1'; - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjInheritMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjInheritMapper.xml deleted file mode 100644 index 4bedd37..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjInheritMapper.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjLinkMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjLinkMapper.xml deleted file mode 100644 index 3b05d95..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjLinkMapper.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjMerchantMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjMerchantMapper.xml deleted file mode 100644 index f163825..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjMerchantMapper.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - DELETE FROM sys_dict_data WHERE merchant_id=#{id}; - - - DELETE FROM yj_enterprise WHERE merchant_id=#{id}; - - - DELETE FROM yj_index WHERE merchant_id=#{id}; - - - DELETE FROM yj_course_lp WHERE merchant_id=#{id}; - - - DELETE FROM sys_dept WHERE merchan_id=#{id}; - - - DELETE FROM yj_merchant WHERE id=#{id}; - - - UPDATE sys_user set merchant_id='',dept_id='110' WHERE user_id=#{responsibleId}; - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjPracticeMomentsMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjPracticeMomentsMapper.xml deleted file mode 100644 index 0838e57..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjPracticeMomentsMapper.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjSenseMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjSenseMapper.xml deleted file mode 100644 index 8dec7e5..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjSenseMapper.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/shop/YjSourceLpMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/shop/YjSourceLpMenuMapper.xml deleted file mode 100644 index 1b90357..0000000 --- a/ruoyi-system/src/main/resources/mapper/shop/YjSourceLpMenuMapper.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/source/AppointmentMapper.xml b/ruoyi-system/src/main/resources/mapper/source/AppointmentMapper.xml deleted file mode 100644 index a4a8300..0000000 --- a/ruoyi-system/src/main/resources/mapper/source/AppointmentMapper.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - id, consumer_id, course_log_id, create_time, remark, phone, status, update_time, update_user - - - - - - - - update appointment set flag=3,update_time=#{updateTime} where id=#{id} and flag=0 - - diff --git a/ruoyi-system/src/main/resources/mapper/source/ConsumerCourseMapper.xml b/ruoyi-system/src/main/resources/mapper/source/ConsumerCourseMapper.xml deleted file mode 100644 index 8e449b7..0000000 --- a/ruoyi-system/src/main/resources/mapper/source/ConsumerCourseMapper.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/source/CourseLogMapper.xml b/ruoyi-system/src/main/resources/mapper/source/CourseLogMapper.xml deleted file mode 100644 index 6c4370d..0000000 --- a/ruoyi-system/src/main/resources/mapper/source/CourseLogMapper.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - update course_log set appointment_num=appointment_num+1 where id=#{id} - - - - delete FROM course_log WHERE - tearcher=#{tearcher} - and course_id=#{courseId} - and appointment_num=0 - and start_date>now() - - diff --git a/ruoyi-system/src/main/resources/mapper/source/CourseMapper.xml b/ruoyi-system/src/main/resources/mapper/source/CourseMapper.xml deleted file mode 100644 index 2d7b5f3..0000000 --- a/ruoyi-system/src/main/resources/mapper/source/CourseMapper.xml +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - course_id, course_name, course_context, course_picture, course_explain, member_type, course_type, releases, strore_id, data,course_Type1,course_price,video_long,video_short - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/source/MemberMapper.xml b/ruoyi-system/src/main/resources/mapper/source/MemberMapper.xml deleted file mode 100644 index 22bd792..0000000 --- a/ruoyi-system/src/main/resources/mapper/source/MemberMapper.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml index 312d6cf..e00dc4a 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -21,14 +21,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + - select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time from sys_dept d - select * from sys_dept where del_flag = '0' AND parent_id ]]> 0 @@ -57,7 +57,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where dept_id = #{deptId} - select * from sys_dept where dept_id = #{deptId} @@ -84,7 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" -- ${params.dataScope} 2022.10.14注释 order by d.parent_id, d.order_num - + - + select count(1) from sys_user where dept_id = #{deptId} and del_flag = '0' - + - + - + - + - + insert into sys_dept( dept_id, @@ -153,7 +153,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sysdate() ) - + update sys_dept @@ -170,7 +170,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where dept_id = #{deptId} - + update sys_dept set ancestors = - + - update sys_dept set status = '0' where dept_id in + update sys_dept set status = '0' where dept_id in #{deptId} - + update sys_dept set del_flag = '2' where dept_id = #{deptId} - \ No newline at end of file + diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 7530283..fcade54 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -39,6 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -73,7 +74,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.ven_id,u.merchant_id, + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.ven_id,u.visit_store, d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status from sys_user u @@ -237,6 +238,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" login_date = #{loginDate}, update_by = #{updateBy}, remark = #{remark}, + visit_store = #{visitStore}, + register_id = #{registerId}, update_time = sysdate() where user_id = #{userId}