Compare commits

...
10 Commits
Author SHA1 Message Date
yan.y 8b12ac44ee 修改查询条件 2025-05-24 21:20:07 +08:00
yan.y 7032513f7f 更新 2025-04-08 11:53:31 +08:00
yan.y 7f87d06ca8 更新 2025-03-14 14:56:58 +08:00
yan.y a982953513 修改系列接口 2025-03-13 17:08:25 +08:00
yan.y 3ba58dc671 新增自动下线逻辑 2025-02-18 18:13:06 +08:00
yan.y 00f9642f2b 后台功能更新 2025-01-06 19:24:56 +08:00
yan.y 4e81ac3a92 新增后台配置项 2024-12-17 19:01:59 +08:00
yiyan 6b383f087d fixed query 2024-12-15 21:07:32 +08:00
yan.y 9529abd9ea update 2024-12-15 19:58:06 +08:00
yan.y 9f91bff410 update 2024-07-08 15:00:26 +08:00
80 changed files with 2783 additions and 177 deletions
+1 -77
View File
@@ -1,77 +1 @@
# Timo v2.0.3
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![加入QQ群①](https://img.shields.io/badge/QQ%E7%BE%A4%E2%91%A0-941209502(%E5%B7%B2%E6%BB%A1)-red)](https://jq.qq.com/?_wv=1027&k=5RCnDCO) [![加入QQ群②](https://img.shields.io/badge/QQ%E7%BE%A4②-545633945-brightgreen.svg)](https://jq.qq.com/?_wv=1027&k=5AIEf1E) [![star](https://gitee.com/aun/Timo/badge/star.svg?theme=dark)](https://gitee.com/aun/Timo/stargazers) [![fork](https://gitee.com/aun/Timo/badge/fork.svg?theme=dark)](https://gitee.com/aun/Timo/members)
#### 项目介绍
gion后台管理系统,基于SpringBoot2.0 + Spring Data Jpa + Thymeleaf + Shiro 开发的后台管理系统,采用分模块的方式便于开发和维护,支持前后台模块分别部署,目前支持的功能有:权限管理、部门管理、字典管理、日志记录、文件上传、代码生成等,为快速开发后台系统而生的脚手架!
#### 技术选型
- 后端技术:SpringBoot + Spring Data Jpa + Thymeleaf + Shiro + Jwt + EhCache
- 前端技术:Layui + Jquery + zTree + Font-awesome
#### 全新的项目结构
![项目结构图](https://oscimg.oschina.net/oscnet/4e8e47b3801ba98767dc25a1a6efbb522fe.jpg)
#### 功能列表
- 用户管理:用于管理后台系统的用户,可进行增删改查等操作。
- 角色管理:分配权限的最小单元,通过角色给用户分配权限。
- 菜单管理:用于配置系统菜单,同时也作为权限资源。
- 部门管理:通过不同的部门来管理和区分用户。
- 字典管理:对一些需要转换的数据进行统一管理,如:男、女等。
- 行为日志:用于记录用户对系统的操作,同时监视系统运行时发生的错误。
- 文件上传:内置了文件上传接口,方便开发者使用文件上传功能。
- 代码生成:可以帮助开发者快速开发项目,减少不必要的重复操作,花更多精力注重业务实现。
- 表单构建:通过拖拽的方式快速构建一个表单模块。
- 数据接口:根据业务代码自动生成相关的api接口文档
#### 安装教程
- ##### 环境及插件要求
- Jdk8+
- Mysql5.5+
- Maven
- Lombok<font color="red">(重要)</font>
- ##### 导入项目
- IntelliJ IDEAImport Project -> Import Project from external model -> Maven
- EclipseImport -> Exising Mavne Project
- ##### 运行项目
- 通过Java应用方式运行admin模块下的com.linln.admin.BootApplication文件
- 数据库配置:数据库名称timo 用户root 密码root
- 访问地址:http://localhost:8080/
- 默认帐号密码:admin/123456
#### 使用说明
1. 使用文档:sdoc/使用文档.docx
2. 开发手册:[gion开发文档](http://42.194.205.137/docs)、[看云文档](https://www.kancloud.cn/timo/timo-doc)
3. SQL文件:sdoc/timo.sql
#### 演示地址
演示地址: [http://42.194.205.137](http://42.194.205.137)
#### 预览图
![项目结构图](https://oscimg.oschina.net/oscnet/584b70844227ad813eb8f10bd452fad015c.jpg)
![登录页面](https://oscimg.oschina.net/oscnet/55b1a88090da20735b67ec91a9bcbafc48a.jpg)
![用户管理](https://oscimg.oschina.net/oscnet/91d2f63ac18b34773ddb7f20b25d0c9c539.jpg)
![菜单管理](https://oscimg.oschina.net/oscnet/ac6c1a0521acb2c22c76130057bd97dfd3f.jpg)
![字典管理](https://oscimg.oschina.net/oscnet/ce428dc1a62c6d591ac6bb5ed10e32caf39.jpg)
![行为日志](https://oscimg.oschina.net/oscnet/8b41f93fad654f81349d9572c1630f6fe1f.jpg)
![代码生成](https://oscimg.oschina.net/oscnet/f355fa74868080440299fa4453e9b7ea399.jpg)
后台
+5
View File
@@ -51,6 +51,11 @@
<artifactId>fileUpload</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
</dependencies>
<build>
@@ -2,6 +2,10 @@ package com.linln.admin.config;
import com.linln.admin.orders.domain.*;
import com.linln.admin.orders.repository.*;
import com.linln.admin.users.domain.UserCoupons;
import com.linln.admin.users.repository.UsersCouponsRepository;
import com.linln.admin.users.repository.UsersRepository;
import com.linln.common.enums.StatusEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.availability.ApplicationAvailabilityBean;
@@ -11,10 +15,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -23,16 +24,18 @@ import java.util.stream.Collectors;
* @Date: Created in 22:40 2023/7/3
* @Modified by:
*/
@Data
@Slf4j
@Component
public class InitLoadDataService extends ApplicationAvailabilityBean {
public static final Map<Long, Goods> GOODS_MAP = new HashMap<>();
public static final Map<Long, Car> CAR_MAP = new HashMap<>();
public static final Map<Long, CarUser> CAR_USER_MAP = new HashMap<>();
public static final Map<Long, PetBaseInfo> PET_BASE_INFO_MAP = new HashMap<>();
public static final Map<String, List<Goods>> PET_GOODS_MAP = new HashMap<>();
public static final List<ServiceAddrs> SERVICE_ADDRS = new ArrayList<>();
public static final Map<Long, Coupons> COUPONS_MAP = new HashMap<>();
@Resource
private PetBaseInfoRepository petBaseInfoRepository;
@@ -43,11 +46,27 @@ public class InitLoadDataService extends ApplicationAvailabilityBean {
@Resource
private CarRepository carRepository;
@Resource
private CarUserRepository carUserRepository;
@Resource
private UsersRepository usersRepository;
@Resource
private PetGoodsRepository petGoodsRepository;
@Resource
private ServiceAddrsRepository servicesRepository;
@Resource
private UsersCouponsRepository usersCouponsRepository;
@Resource
private CouponsRepository couponsRepository;
@Resource
private CarConfigRepository carConfigRepository;
@Override
public void onApplicationEvent(AvailabilityChangeEvent<?> event) {
super.onApplicationEvent(event);
@@ -67,6 +86,12 @@ public class InitLoadDataService extends ApplicationAvailabilityBean {
List<Car> carList = carRepository.findAll();
CAR_MAP.clear();
CAR_MAP.putAll(carList.stream().collect(Collectors.toMap(Car::getId, car -> car)));
List<CarUser> carUserList = carUserRepository.findAll();
for (CarUser carUser : carUserList) {
carUser.setUsers(usersRepository.findById(carUser.getUid()).get());
}
CAR_USER_MAP.clear();
CAR_USER_MAP.putAll(carUserList.stream().collect(Collectors.toMap(CarUser::getId, carUser -> carUser)));
List<PetGoods> petGoodsList = petGoodsRepository.findAll();
Map<String, List<Goods>> petGoodsMap = new HashMap<>();
for (PetGoods petGoods : petGoodsList) {
@@ -84,11 +109,50 @@ public class InitLoadDataService extends ApplicationAvailabilityBean {
List<ServiceAddrs> serviceAddrs = servicesRepository.findAll();
SERVICE_ADDRS.clear();
SERVICE_ADDRS.addAll(serviceAddrs);
List<Coupons> couponsList = couponsRepository.findAll();
COUPONS_MAP.clear();
COUPONS_MAP.putAll(couponsList.stream().collect(Collectors.toMap(Coupons::getId, coupons -> coupons)));
log.info("goods load all as : {}", GOODS_MAP);
log.info("petBaseInfos load all as : {}", PET_BASE_INFO_MAP);
log.info("carList load all as : {}", CAR_MAP);
log.info("petGoodsList load all as : {}", PET_GOODS_MAP);
log.info("serviceAddrs load all as : {}", serviceAddrs);
}
/**
* 优惠券过期逻辑
*/
@Scheduled(cron = "0 0/5 * * * ?")
public void couponsExpire() {
List<UserCoupons> userCouponsList = usersCouponsRepository.findUserCouponsByLastExpireTimeLessThan(new Date());
for (UserCoupons userCoupons : userCouponsList) {
userCoupons.setCouponsStatus(3);
}
usersCouponsRepository.saveAllAndFlush(userCouponsList);
List<Coupons> couponsList = couponsRepository.findAllByExpireTimeLessThan(System.currentTimeMillis());
for (Coupons coupons : couponsList) {
coupons.setStatus(StatusEnum.DELETE.getCode());
}
couponsRepository.saveAllAndFlush(couponsList);
List<CarConfig> carConfigs = carConfigRepository.findAll();
for (CarConfig carConfig : carConfigs) {
if (carConfig.getStartDownTime() == null && carConfig.getEndDownTime() == null
&& CAR_MAP.get(carConfig.getCarId()).getCarStatus() == 2) {
Car car = CAR_MAP.get(carConfig.getCarId());
car.setCarStatus(1);
carRepository.save(car);
} else if (System.currentTimeMillis() >= carConfig.getStartDownTime().getTime() && System.currentTimeMillis() < carConfig.getEndDownTime().getTime()
&& CAR_MAP.get(carConfig.getCarId()).getCarStatus() == 1) {
Car car = CAR_MAP.get(carConfig.getCarId());
car.setCarStatus(2);
carRepository.save(car);
} else if (System.currentTimeMillis() >= carConfig.getEndDownTime().getTime()
&& CAR_MAP.get(carConfig.getCarId()).getCarStatus() == 2) {
Car car = CAR_MAP.get(carConfig.getCarId());
car.setCarStatus(1);
carRepository.save(car);
}
}
}
}
@@ -1,6 +1,8 @@
package com.linln.admin.orders.controller;
import cn.hutool.core.date.DateUtil;
import com.linln.admin.orders.domain.Car;
import com.linln.admin.orders.domain.CarConfig;
import com.linln.admin.orders.domain.CarUser;
import com.linln.admin.orders.domain.OrderMain;
import com.linln.admin.orders.service.CarService;
@@ -54,6 +56,12 @@ public class CarController {
// 获取数据列表
Example<Car> example = Example.of(car, matcher);
Page<Car> list = carService.getPageList(example);
for (Car car1 : list) {
CarConfig carConfig = carService.getCarConfig(car1.getId());
if (carConfig != null) {
car1.setInfo(DateUtil.formatDateTime(carConfig.getStartDownTime()) + " ~ " + DateUtil.formatDateTime(carConfig.getEndDownTime()) );
}
}
// 封装数据
model.addAttribute("list", list.getContent());
@@ -91,6 +99,22 @@ public class CarController {
return "/orders/car/toAddCarUserInfos";
}
/**
* 跳转添加信息页面
*/
@GetMapping("/toCarDownInfos/{id}")
@RequiresPermissions("orders:car:edit")
public String toCarDownInfos(@PathVariable("id") Car car, Model model) {
car = carService.getById(car.getId());
CarConfig carConfig = carService.getCarConfig(car.getId());
if (carConfig != null) {
car.setStartDownTime(DateUtil.formatDateTime(carConfig.getStartDownTime()));
car.setEndDownTime(DateUtil.formatDateTime(carConfig.getEndDownTime()));
}
model.addAttribute("car", car);
return "/orders/car/toCarDownInfos";
}
/**
* 跳转添加信息页面
*/
@@ -137,6 +161,16 @@ public class CarController {
carService.saveCarUser(carUser);
return ResultVoUtil.SAVE_SUCCESS;
}
/**
* 保存添加/修改的数据
*/
@PostMapping("/saveCarDownInfo")
@RequiresPermissions({"orders:car:add", "orders:car:edit"})
@ResponseBody
public ResultVo saveCarDownInfo(Car car) {
carService.saveCarDownInfo(car);
return ResultVoUtil.SAVE_SUCCESS;
}
/**
* 保存添加/修改的数据
@@ -0,0 +1,186 @@
package com.linln.admin.orders.controller;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.linln.admin.config.InitLoadDataService;
import com.linln.admin.orders.domain.Coupons;
import com.linln.admin.orders.service.CouponsService;
import com.linln.admin.orders.validator.CouponsValid;
import com.linln.admin.users.domain.UserCoupons;
import com.linln.admin.users.domain.Users;
import com.linln.admin.users.service.UsersService;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.EntityBeanUtil;
import com.linln.common.utils.ResultVoUtil;
import com.linln.common.utils.StatusUtil;
import com.linln.common.vo.ResultVo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
/**
* @author gion
* @date 2024/08/14
*/
@Controller
@RequestMapping("/orders/coupons")
public class CouponsController {
@Resource
private CouponsService couponsService;
@Resource
private UsersService usersService;
/**
* 列表页面
*/
@GetMapping("/index")
@RequiresPermissions("orders:coupons:index")
public String index(Model model, Coupons coupons) {
// 创建匹配器,进行动态查询匹配
ExampleMatcher matcher = ExampleMatcher.matching();
// 获取数据列表
Example<Coupons> example = Example.of(coupons, matcher);
Page<Coupons> list = couponsService.getPageList(example);
// 封装数据
model.addAttribute("list", list.getContent());
model.addAttribute("page", list);
return "/orders/coupons/index";
}
/**
* 跳转到添加页面
*/
@GetMapping("/add")
@RequiresPermissions("orders:coupons:add")
public String toAdd() {
return "/orders/coupons/add";
}
/**
* 跳转到编辑页面
*/
@GetMapping("/edit/{id}")
@RequiresPermissions("orders:coupons:edit")
public String toEdit(@PathVariable("id") Coupons coupons, Model model) {
model.addAttribute("coupons", coupons);
return "/orders/coupons/add";
}
/**
* 保存添加/修改的数据
* @param valid 验证对象
*/
@PostMapping("/save")
@RequiresPermissions({"orders:coupons:add", "orders:coupons:edit"})
@ResponseBody
public ResultVo save(@Validated CouponsValid valid, Coupons coupons) {
// 复制保留无需修改的数据
if (coupons.getId() != null) {
Coupons beCoupons = couponsService.getById(coupons.getId());
EntityBeanUtil.copyProperties(beCoupons, coupons);
}
coupons.setExpireTime(DateUtil.parse(coupons.getExpireTimeStr(), DatePattern.NORM_DATETIME_PATTERN).getTime());
coupons.setCreateDate(new Date());
coupons.setCreateTime(new Date());
// 保存数据
couponsService.save(coupons);
return ResultVoUtil.SAVE_SUCCESS;
}
/**
* 跳转到详细页面
*/
@GetMapping("/detail/{id}")
@RequiresPermissions("orders:coupons:detail")
public String toDetail(@PathVariable("id") Coupons coupons, Model model) {
model.addAttribute("coupons",coupons);
return "/orders/coupons/detail";
}
/**
* 跳转到下发页面
*/
@GetMapping("/toSend/{id}")
@RequiresPermissions("orders:coupons:edit")
public String toSend(@PathVariable("id") Coupons coupons, Model model) {
model.addAttribute("coupons", coupons);
return "/orders/coupons/send";
}
/**
* 一键下发所有用户
*/
@RequestMapping("/send")
@RequiresPermissions("orders:coupons:status")
@ResponseBody
public ResultVo send(Coupons couponsParam) {
Coupons coupons = couponsService.getById(couponsParam.getId());
Date lastExpireTime = DateUtil.offsetDay(new Date(), coupons.getDrawDay());
if (couponsParam.getSendType() == 1) {
Users users = usersService.getById(couponsParam.getUid());
usersService.sendUserCoupons(Collections.singletonList(new UserCoupons(users.getId(), coupons.getId().intValue(), 1, lastExpireTime)));
} else {
List<Users> allUser = usersService.getAllUser();
List<List<Users>> lists = ListUtil.split(allUser, 50);
for (List<Users> list : lists) {
List<UserCoupons> userCouponsList = new ArrayList<>(list.size());
userCouponsList.addAll(list.stream().map(m -> new UserCoupons(m.getId(), coupons.getId().intValue(), 1, lastExpireTime)).collect(Collectors.toList()));
usersService.sendUserCoupons(userCouponsList);
}
}
return ResultVoUtil.success("成功");
}
/*@RequestMapping("/send")
@RequiresPermissions("orders:coupons:status")
@ResponseBody
public ResultVo send(@RequestParam(value = "ids", required = false) List<Long> ids) {
List<Users> allUser = usersService.getAllUser();
List<List<Users>> lists = ListUtil.split(allUser, 50);
for (List<Users> list : lists) {
List<UserCoupons> userCouponsList = new ArrayList<>(list.size() * ids.size());
for (Long cid : ids) {
Coupons coupons = couponsService.getById(cid);
Date lastExpireTime = DateUtil.offsetDay(new Date(), coupons.getDrawDay());
userCouponsList.addAll(list.stream().map(m -> new UserCoupons(m.getId(), coupons.getId().intValue(), 1, lastExpireTime)).collect(Collectors.toList()));
}
usersService.sendUserCoupons(userCouponsList);
}
return ResultVoUtil.success("成功");
}*/
/**
* 设置一条或者多条数据的状态
*/
@RequestMapping("/status/{param}")
@RequiresPermissions("orders:coupons:status")
@ResponseBody
public ResultVo status(
@PathVariable("param") String param,
@RequestParam(value = "ids", required = false) List<Long> ids) {
// 更新状态
StatusEnum statusEnum = StatusUtil.getStatusEnum(param);
if (couponsService.updateStatus(statusEnum, ids)) {
return ResultVoUtil.success(statusEnum.getMessage() + "成功");
} else {
return ResultVoUtil.error(statusEnum.getMessage() + "失败,请重新操作");
}
}
}
@@ -7,6 +7,8 @@ import com.linln.admin.orders.domain.PetGoods;
import com.linln.admin.orders.service.GoodsService;
import com.linln.admin.orders.service.PetGoodsService;
import com.linln.admin.orders.validator.GoodsValid;
import com.linln.admin.users.service.PetBaseInfoService;
import com.linln.admin.users.service.PetService;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.EntityBeanUtil;
import com.linln.common.utils.ResultVoUtil;
@@ -39,6 +41,9 @@ public class GoodsController {
@Resource
private PetGoodsService petGoodsService;
@Resource
private PetBaseInfoService petBaseInfoService;
/**
* 列表页面
*/
@@ -91,8 +96,12 @@ public class GoodsController {
petList.add(cat);
PetBaseInfo dog = new PetBaseInfo();
dog.setPetType(2);
List<PetBaseInfo> catPetBaseList = petBaseInfoService.findPetBaseList(1);
List<PetBaseInfo> dogPetBaseList = petBaseInfoService.findPetBaseList(2);
model.addAttribute("goods", goods);
model.addAttribute("petList", petList);
model.addAttribute("cats", catPetBaseList);
model.addAttribute("dogs", dogPetBaseList);
return "/orders/goods/goodsToLinkPet";
}
@@ -106,16 +115,19 @@ public class GoodsController {
int petType = goods.getPetType();
int catWeight = goods.getCatWeight() == null ? 0 : goods.getCatWeight();
int dogWeight = goods.getDogWeight() == null ? 0 : goods.getDogWeight();
int catPzId = goods.getCatWeight() == null ? 0 : goods.getCatPz();
int dogPzId = goods.getDogWeight() == null ? 0 : goods.getDogPz();
int hair = goods.getHair();
goods = goodsService.getById(goods.getId());
PetGoods petGoods = new PetGoods();
petGoods.setAssortment(0);
petGoods.setSize(0);
petGoods.setPetType(petType);
if (petType == 1) {
petGoods.setWeight(catWeight);
petGoods.setAssortment(catPzId);
} else {
petGoods.setWeight(dogWeight);
petGoods.setAssortment(dogPzId);
}
petGoods.setHair(hair);
petGoods.setGoodsId(goods.getId());
@@ -5,11 +5,14 @@ import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.linln.admin.config.InitLoadDataService;
import com.linln.admin.orders.domain.*;
import com.linln.admin.orders.service.OrderMainService;
import com.linln.admin.orders.validator.OrderMainValid;
import com.linln.admin.users.service.PetService;
import com.linln.admin.users.service.UsersService;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.EntityBeanUtil;
import com.linln.common.utils.ResultVoUtil;
@@ -46,6 +49,9 @@ public class OrderMainController {
@Resource
private PetService petService;
@Resource
private UsersService usersService;
/**
* 列表页面
*/
@@ -64,6 +70,24 @@ public class OrderMainController {
model.addAttribute("page", list);
return "/orders/orderMain/index";
}
/**
* 列表页面
*/
@GetMapping("/pay/index")
@RequiresPermissions("orders:orderMain:index")
public String payIndex(Model model, PayOrder payOrder) {
// 创建匹配器,进行动态查询匹配
ExampleMatcher matcher = ExampleMatcher.matching();
// 获取数据列表
Example<PayOrder> example = Example.of(payOrder, matcher);
Page<PayOrder> list = orderMainService.getPayOrderPageList(example);
// 封装数据
model.addAttribute("list", list.getContent());
model.addAttribute("page", list);
return "/orders/pay/index";
}
/**
* 跳转到添加页面
@@ -132,6 +156,8 @@ public class OrderMainController {
@RequiresPermissions("orders:orderMain:edit")
public String toEdit(@PathVariable("id") OrderMain orderMain, Model model) {
orderMain = orderMainService.getById(orderMain.getId());
List<Car> cars = orderMainService.getCars();
model.addAttribute("cars", cars);
model.addAttribute("orderMain", orderMain);
return "/orders/orderMain/add";
}
@@ -152,6 +178,17 @@ public class OrderMainController {
orderMain.setServiceTime(carOrder.getServiceTime());
orderMainService.save(orderMain);
if (StrUtil.isNotBlank(carOrder.getAddr())) {
UserServiceAddr userServiceAddrInfo = usersService.getAddrById(carOrder.getAddrId());
if (!userServiceAddrInfo.getAddr().equals(carOrder.getAddr())) {
String result = HttpUtil.get("https://apis.map.qq.com/ws/geocoder/v1/?address=" + carOrder.getAddr() + "&key=MWWBZ-5YT6Q-LVC5S-4DE4D-ZU7Q6-ECFCL&poi_options=policy=2");
JSONObject resultJson = JSONObject.parseObject(result);
if (resultJson.getIntValue("status") == 0) {
JSONObject data = resultJson.getJSONObject("result");
userServiceAddrInfo.setLatitude(data.getJSONObject("location").getString("lat"));
userServiceAddrInfo.setLongitude(data.getJSONObject("location").getString("lng"));
usersService.updateUserServiceAddr(userServiceAddrInfo);
}
}
orderMainService.updateUserAddr(carOrder.getAddrId(), carOrder.getAddr());
}
return ResultVoUtil.SAVE_SUCCESS;
@@ -187,15 +224,16 @@ public class OrderMainController {
@ResponseBody
public ResultVo save(@Validated OrderMainValid valid, OrderMain orderMain) {
// 复制保留无需修改的数据
if (orderMain.getId() != null) {
OrderMain beOrderMain = orderMainService.getById(orderMain.getId());
EntityBeanUtil.copyProperties(beOrderMain, orderMain);
}
OrderMain beOrderMain = orderMainService.getById(orderMain.getId());
if (StrUtil.isNotBlank(orderMain.getAddr())) {
orderMainService.updateUserAddr(orderMain.getAddrId(), orderMain.getAddr());
}
// 保存数据
orderMainService.save(orderMain);
beOrderMain.setServiceTime(orderMain.getServiceTime());
if (StrUtil.isNotBlank(orderMain.getRemark())) {
beOrderMain.setRemark(orderMain.getRemark());
}
orderMainService.save(beOrderMain);
orderMainService.updateCarOrder(beOrderMain.getOrderId(), orderMain.getCarId());
return ResultVoUtil.SAVE_SUCCESS;
}
@@ -250,24 +288,37 @@ public class OrderMainController {
orderMain.setUid(pet.getUid());
orderMain.setOrderStatus(Byte.valueOf("1"));
orderMain.setPayType(Byte.valueOf("1"));
orderMain.setServiceTime(serviceTime);
String formatServiceTime = DateUtil.format(DateUtil.parse(serviceTime, DatePattern.NORM_DATETIME_MINUTE_FORMAT), DatePattern.NORM_DATETIME_MINUTE_FORMAT);
orderMain.setServiceTime(formatServiceTime);
orderMain.setServiceAddrId(Long.parseLong(userServiceAddr));
orderMain.setProjectionServiceTime(0);
orderMain.setPayTotalAmount(0);
orderMain.setTotalAmount(0);
orderMain.setPayDiscount(0);
orderMain.setPayStatus(Byte.valueOf("0"));
orderMain.setServiceAddrId(Long.parseLong(userServiceAddr));
orderMain.setCreateTime(new Date());
orderMain.setDispatchStatus(Byte.valueOf("0"));
}
UserServiceAddr userServiceAddrInfo = usersService.getAddrById(Long.parseLong(userServiceAddr));
String result = HttpUtil.get("https://apis.map.qq.com/ws/geocoder/v1/?address=" + userServiceAddrInfo.getAddr() + "&key=MWWBZ-5YT6Q-LVC5S-4DE4D-ZU7Q6-ECFCL");
JSONObject resultJson = JSONObject.parseObject(result);
if (resultJson.getIntValue("status") == 0) {
JSONObject data = resultJson.getJSONObject("result");
userServiceAddrInfo.setLatitude(data.getJSONObject("location").getString("lat"));
userServiceAddrInfo.setLongitude(data.getJSONObject("location").getString("lng"));
usersService.updateUserServiceAddr(userServiceAddrInfo);
}
List<String> goodsIds = new ArrayList<>();
goodsIds.addAll(goodsId1);
goodsIds.addAll(goodsId2);
goodsIds.addAll(goodsId3);
goodsIds.addAll(goodsId4);
long subOrderId = IdUtil.getSnowflakeNextId();
List<OrderDetail> orderDetails = new ArrayList<>();
Integer totalAmount = 0;
int projectServiceTime = 0;
@@ -302,12 +353,15 @@ public class OrderMainController {
orderSub.setPayType(Byte.valueOf("1"));
orderSub.setDiscount(100);
orderSub.setTotalAmount(totalAmount);
orderSub.setPayAmount(totalAmount);
orderSub.setPayAmount(totalAmount * 10);
orderSub.setCreateTime(new Date());
orderSub.setProjectionServiceTime(projectServiceTime);
PetBaseInfo petBaseInfo = InitLoadDataService.PET_BASE_INFO_MAP.get(pet.getPetId());
String petInfo = "宠物名称:" + pet.getNickName() + "</br>品种:" + petBaseInfo.getAssortment() + "</br>服务项目:" + goodsName;
orderSub.setPetInfo(petInfo);
orderSub.setCid(0);
orderSub.setUcid(0);
orderSub.setGoodsDiscountAmount(0);
orderMainService.createOrder(orderDetails, orderSub, orderMain);
return ResultVoUtil.success("成功");
}
@@ -0,0 +1,111 @@
package com.linln.admin.orders.controller;
import com.linln.admin.orders.domain.RechargeInfos;
import com.linln.admin.orders.service.RechargeService;
import com.linln.admin.orders.validator.RechargeValid;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.EntityBeanUtil;
import com.linln.common.utils.ResultVoUtil;
import com.linln.common.utils.StatusUtil;
import com.linln.common.vo.ResultVo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* @author gion
* @date 2024/08/14
*/
@Controller
@RequestMapping("/orders/recharge")
public class RechargeController {
@Resource
private RechargeService rechargeService;
/**
* 列表页面
*/
@GetMapping("/index")
@RequiresPermissions("orders:recharge:index")
public String index(Model model, RechargeInfos rechargeInfos) {
// 创建匹配器,进行动态查询匹配
ExampleMatcher matcher = ExampleMatcher.matching();
// 获取数据列表
Example<RechargeInfos> example = Example.of(rechargeInfos, matcher);
Page<RechargeInfos> list = rechargeService.getPageList(example);
// 封装数据
model.addAttribute("list", list.getContent());
model.addAttribute("page", list);
return "/orders/recharge/index";
}
/**
* 跳转到添加页面
*/
@GetMapping("/add")
@RequiresPermissions("orders:recharge:add")
public String toAdd() {
return "/orders/recharge/add";
}
/**
* 跳转到编辑页面
*/
@GetMapping("/edit/{id}")
@RequiresPermissions("orders:recharge:edit")
public String toEdit(@PathVariable("id") RechargeInfos rechargeInfos, Model model) {
model.addAttribute("recharge", rechargeInfos);
return "/orders/recharge/add";
}
/**
* 保存添加/修改的数据
* @param valid 验证对象
*/
@PostMapping("/save")
@RequiresPermissions({"orders:recharge:add", "orders:recharge:edit"})
@ResponseBody
public ResultVo save(@Validated RechargeValid valid, RechargeInfos rechargeInfos) {
// 复制保留无需修改的数据
if (rechargeInfos.getId() != null) {
RechargeInfos beRechargeInfos = rechargeService.getById(rechargeInfos.getId());
EntityBeanUtil.copyProperties(beRechargeInfos, rechargeInfos);
}
rechargeInfos.setCreateTime(new Date());
rechargeInfos.setUpdateTime(new Date());
// 保存数据
rechargeService.save(rechargeInfos);
return ResultVoUtil.SAVE_SUCCESS;
}
/**
* 设置一条或者多条数据的状态
*/
@RequestMapping("/status/{param}")
@RequiresPermissions("orders:recharge:status")
@ResponseBody
public ResultVo status(
@PathVariable("param") String param,
@RequestParam(value = "ids", required = false) List<Long> ids) {
// 更新状态
StatusEnum statusEnum = StatusUtil.getStatusEnum(param);
if (rechargeService.updateStatus(statusEnum, ids)) {
return ResultVoUtil.success(statusEnum.getMessage() + "成功");
} else {
return ResultVoUtil.error(statusEnum.getMessage() + "失败,请重新操作");
}
}
}
@@ -43,6 +43,21 @@ public class Car implements Serializable {
// 数据状态
private Byte status = StatusEnum.OK.getCode();
//车辆状态 1在线 2下线
private Integer carStatus;
@Transient
private String info;
@Transient
private String startDownTime;
@Transient
private String endDownTime;
//护理人员列表
@Transient
private List<Users> users;
@@ -0,0 +1,45 @@
package com.linln.admin.orders.domain;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import lombok.Data;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author gion
* @date 2024/04/29
*/
@Data
@Entity
@Table(name="car_config")
@EntityListeners(AuditingEntityListener.class)
@Where(clause = StatusUtil.NOT_DELETE)
public class CarConfig implements Serializable {
// 主键ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
// 车牌号
private Long carId;
// 开始下线时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date startDownTime;
// 结束下线时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date endDownTime;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date updateDate;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
}
@@ -0,0 +1,61 @@
package com.linln.admin.orders.domain;
import com.linln.common.enums.StatusEnum;
import lombok.Data;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author gion
* @date 2024/08/14
*/
@Data
@Entity
@Table(name="coupons")
@EntityListeners(AuditingEntityListener.class)
public class Coupons implements Serializable {
// 主键ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
// 有效商品子类型
private Integer goodsSubType;
// 折扣
private Integer discount;
// 来源
private String source;
// 使用限制
private Integer periodType;
// 使用限制信息
private String period;
// 过期时间戳
private Long expireTime;
@Transient
private String expireTimeStr;
// 下发类型 1领取 2新用户注册赠送 3邀请新用户赠送
private Integer sendStatus;
// 创建时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
// 创建时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createDate;
// 更新时间
@LastModifiedDate
private Date updateDate;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
// 领取后过期天数
private Integer drawDay;
@Transient
private Integer sendType;
@Transient
private Long uid;
}
@@ -53,6 +53,9 @@ public class Goods implements Serializable {
// 数据状态
private Byte status = StatusEnum.OK.getCode();
//商品子类型 1:洗护 2:美容 3:SPA 4:驱虫 5:洁牙
private Integer goodsSubType;
@Transient
private Integer petType;
@Transient
@@ -60,5 +63,9 @@ public class Goods implements Serializable {
@Transient
private Integer catWeight;
@Transient
private Integer catPz;
@Transient
private Integer dogWeight;
@Transient
private Integer dogPz;
}
@@ -40,6 +40,8 @@ public class OrderDetail implements Serializable {
private Date createDate;
@LastModifiedDate
private Date updateDate;
private Integer discountAmount;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
}
@@ -31,6 +31,8 @@ public class OrderMain implements Serializable {
private Long id;
// 订单ID
private String orderId;
// 支付订单ID
private String payOrderId;
// 用户ID
private Long uid;
// 订单状态
@@ -73,6 +75,17 @@ public class OrderMain implements Serializable {
@Transient
private Integer payAmount;
@Transient
private Integer goodsDiscountAmount;
@Transient
private Integer vipDiscountAmount;
@Transient
private Integer cid;
@Transient
private Integer ucid;
@Transient
private Coupons coupons;
@Transient
private List<OrderSub> orderSubs;
@@ -96,7 +109,14 @@ public class OrderMain implements Serializable {
@Transient
private Long addrId;
@Transient
private Long carId;
@Transient
private String addr;
@Transient
private String payDj;
@Transient
private String carInfo;
private String remark;
public OrderMain() {
}
@@ -12,7 +12,6 @@ import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author gion
@@ -67,4 +66,13 @@ public class OrderSub implements Serializable {
private String petInfo;
private Integer cid;
private Integer ucid;
private Integer goodsDiscountAmount;
private Integer goodsOriginAmount;
@Transient
private int vipAmount;
}
@@ -0,0 +1,56 @@
package com.linln.admin.orders.domain;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import lombok.Data;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author gion
* @date 2024/04/29
*/
@Data
@Entity
@Table(name="pay_orders")
@EntityListeners(AuditingEntityListener.class)
@Where(clause = StatusUtil.NOT_DELETE)
public class PayOrder implements Serializable {
// 主键ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
// 订单ID
private String orderId;
// 订单名称
private String orderName;
//订单价格
private Double orderPrice;
//订单状态
private Byte orderStatus;
//三方支付ID
private String payId;
//充值ID
private Integer rechargeId;
//用户ID
private Long uid;
// 订单创建时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
// 订单更新时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date updateDate;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
}
@@ -20,7 +20,6 @@ import java.util.*;
@Data
@Entity
@Table(name="pets")
@Where(clause = StatusUtil.NOT_DELETE)
@EntityListeners(AuditingEntityListener.class)
public class Pet implements Serializable {
// 主键ID
@@ -29,7 +29,7 @@ public class PetBaseInfo implements Serializable {
private Long id;
// 宠物类型
private Integer petType;
// 宠物名称
// 宠物品种
private String assortment;
// 长毛短毛 1长毛 2短毛
private Integer hair;
@@ -28,12 +28,16 @@ public class PetGoods implements Serializable {
private Long id;
// 品种ID
private Integer assortment;
//品种描述
@Transient
private String assortmentDesc;
// 宠物类型
private Integer petType;
// 宠物体重
private Integer weight;
// 宠物毛发
private Integer hair;
@Transient
private Integer size;
// 商品ID
private Long goodsId;
@@ -0,0 +1,59 @@
package com.linln.admin.orders.domain;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import lombok.Data;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author gion
* @date 2024/04/29
*/
@Data
@Entity
@Table(name="recharge_infos")
@EntityListeners(AuditingEntityListener.class)
@Where(clause = StatusUtil.NOT_DELETE)
public class RechargeInfos implements Serializable {
// 主键ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
//名称
private String name;
//描述
@Column(name = "`desc`")
private String desc;
//支付金额
private String price;
//赠送金额
private String givePrice;
//类型 1储值 2押金
private Integer type;
//赠送描述
private String give;
//到账金额
private String rechargePrice;
// 订单创建时间
@CreatedDate
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date updateDate;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
}
@@ -44,4 +44,7 @@ public class UserServiceAddr implements Serializable {
private Date updateDate;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
private String longitude;
private String latitude;
}
@@ -0,0 +1,14 @@
package com.linln.admin.orders.repository;
import com.linln.admin.orders.domain.CarConfig;
import com.linln.modules.system.repository.BaseRepository;
/**
* @author gion
* @date 2024/04/29
*/
public interface CarConfigRepository extends BaseRepository<CarConfig, Long> {
CarConfig findFirstByCarId(Long carId);
}
@@ -8,4 +8,7 @@ import com.linln.modules.system.repository.BaseRepository;
* @date 2024/04/29
*/
public interface CarOrderRepository extends BaseRepository<CarOrder, Long> {
CarOrder findFirstByOrderId(String orderId);
}
@@ -0,0 +1,20 @@
package com.linln.admin.orders.repository;
import com.linln.admin.orders.domain.Coupons;
import com.linln.modules.system.repository.BaseRepository;
import java.util.List;
/**
* @author gion
* @date 2024/08/14
*/
public interface CouponsRepository extends BaseRepository<Coupons, Long> {
List<Coupons> findAllByExpireTimeLessThan(long expireTime);
Coupons findFirstById(long id);
List<Coupons> findByStatusAndSendStatusAndExpireTimeGreaterThanOrderByExpireTimeAsc(byte status, int sendStatus, long expireTime);
}
@@ -0,0 +1,15 @@
package com.linln.admin.orders.repository;
import com.linln.admin.orders.domain.CarOrder;
import com.linln.admin.orders.domain.PayOrder;
import com.linln.modules.system.repository.BaseRepository;
/**
* @author gion
* @date 2024/04/29
*/
public interface PayOrderRepository extends BaseRepository<PayOrder, Long> {
PayOrder getPayOrdersByOrderId(String orderId);
}
@@ -3,9 +3,14 @@ package com.linln.admin.orders.repository;
import com.linln.admin.orders.domain.PetBaseInfo;
import com.linln.modules.system.repository.BaseRepository;
import java.util.List;
/**
* @author gion
* @date 2024/04/29
*/
public interface PetBaseInfoRepository extends BaseRepository<PetBaseInfo, Long> {
List<PetBaseInfo> findAllByPetType(Integer petType);
}
@@ -1,7 +1,9 @@
package com.linln.admin.orders.repository;
import com.linln.admin.orders.domain.Pet;
import com.linln.modules.system.domain.User;
import com.linln.modules.system.repository.BaseRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
@@ -9,8 +11,10 @@ import java.util.List;
* @author gion
* @date 2024/04/29
*/
public interface PetRepository extends BaseRepository<Pet, Long> {
public interface PetRepository extends BaseRepository<Pet, Long>, JpaSpecificationExecutor<Pet> {
List<Pet> findAllByUid(long uid);
Pet findFirstById(Long id);
Pet findFirstByIdAndStatusIn(Long id, List<Byte> statusList);
}
@@ -0,0 +1,11 @@
package com.linln.admin.orders.repository;
import com.linln.admin.orders.domain.RechargeInfos;
import com.linln.modules.system.repository.BaseRepository;
/**
* @author gion
* @date 2024/04/29
*/
public interface RechargeInfosRepository extends BaseRepository<RechargeInfos, Long> {
}
@@ -1,6 +1,7 @@
package com.linln.admin.orders.service;
import com.linln.admin.orders.domain.Car;
import com.linln.admin.orders.domain.CarConfig;
import com.linln.admin.orders.domain.CarUser;
import com.linln.admin.users.domain.Users;
import com.linln.common.enums.StatusEnum;
@@ -46,4 +47,8 @@ public interface CarService {
void delCarUser(long carId, long uid);
void saveCarUser(CarUser carUser);
void saveCarDownInfo(Car car);
CarConfig getCarConfig(Long id);
}
@@ -0,0 +1,41 @@
package com.linln.admin.orders.service;
import com.linln.admin.orders.domain.Coupons;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author gion
* @date 2024/08/14
*/
public interface CouponsService {
/**
* 获取分页列表数据
* @param example 查询实例
* @return 返回分页数据
*/
Page<Coupons> getPageList(Example<Coupons> example);
/**
* 根据ID查询数据
* @param id 主键ID
*/
Coupons getById(Long id);
/**
* 保存数据
* @param coupons 实体对象
*/
Coupons save(Coupons coupons);
/**
* 状态(启用,冻结,删除)/批量状态处理
*/
@Transactional(rollbackFor = Exception.class)
Boolean updateStatus(StatusEnum statusEnum, List<Long> idList);
}
@@ -1,9 +1,6 @@
package com.linln.admin.orders.service;
import com.linln.admin.orders.domain.Car;
import com.linln.admin.orders.domain.OrderDetail;
import com.linln.admin.orders.domain.OrderMain;
import com.linln.admin.orders.domain.OrderSub;
import com.linln.admin.orders.domain.*;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
@@ -25,6 +22,7 @@ public interface OrderMainService {
* @return 返回分页数据
*/
Page<OrderMain> getPageList(Example<OrderMain> example);
Page<PayOrder> getPayOrderPageList(Example<PayOrder> example);
/**
* 根据ID查询数据
@@ -45,6 +43,7 @@ public interface OrderMainService {
OrderMain save(OrderMain orderMain);
void dispatchOrder(String orderId, Long carId);
void updateCarOrder(String orderId, Long carId);
List<Car> getCars();
@@ -0,0 +1,41 @@
package com.linln.admin.orders.service;
import com.linln.admin.orders.domain.RechargeInfos;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author gion
* @date 2024/08/14
*/
public interface RechargeService {
/**
* 获取分页列表数据
* @param example 查询实例
* @return 返回分页数据
*/
Page<RechargeInfos> getPageList(Example<RechargeInfos> example);
/**
* 根据ID查询数据
* @param id 主键ID
*/
RechargeInfos getById(Long id);
/**
* 保存数据
* @param coupons 实体对象
*/
RechargeInfos save(RechargeInfos coupons);
/**
* 状态(启用,冻结,删除)/批量状态处理
*/
@Transactional(rollbackFor = Exception.class)
Boolean updateStatus(StatusEnum statusEnum, List<Long> idList);
}
@@ -1,7 +1,11 @@
package com.linln.admin.orders.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.linln.admin.orders.domain.Car;
import com.linln.admin.orders.domain.CarConfig;
import com.linln.admin.orders.domain.CarUser;
import com.linln.admin.orders.repository.CarConfigRepository;
import com.linln.admin.orders.repository.CarRepository;
import com.linln.admin.orders.repository.CarUserRepository;
import com.linln.admin.orders.service.CarService;
@@ -17,6 +21,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -36,6 +41,9 @@ public class CarServiceImpl implements CarService {
@Resource
private UsersRepository usersRepository;
@Resource
private CarConfigRepository carConfigRepository;
/**
* 根据ID查询数据
* @param id 主键ID
@@ -99,4 +107,40 @@ public class CarServiceImpl implements CarService {
public void saveCarUser(CarUser carUser) {
carUserRepository.save(carUser);
}
@Override
public CarConfig getCarConfig(Long id) {
return carConfigRepository.findFirstByCarId(id);
}
@Override
public void saveCarDownInfo(Car car) {
CarConfig carConfig = carConfigRepository.findFirstByCarId(car.getId());
if (carConfig == null) {
carConfig = new CarConfig();
carConfig.setStatus((byte) 1);
if (StrUtil.isNotBlank(car.getStartDownTime())) {
carConfig.setStartDownTime(DateUtil.parse(car.getStartDownTime()));
}
if (StrUtil.isNotBlank(car.getEndDownTime())) {
carConfig.setEndDownTime(DateUtil.parse(car.getEndDownTime()));
}
carConfig.setCarId(car.getId());
carConfig.setCreateDate(new Date());
carConfig.setUpdateDate(new Date());
} else {
if (StrUtil.isNotBlank(car.getStartDownTime())) {
carConfig.setStartDownTime(DateUtil.parse(car.getStartDownTime()));
} else {
carConfig.setStartDownTime(null);
}
if (StrUtil.isNotBlank(car.getEndDownTime())) {
carConfig.setEndDownTime(DateUtil.parse(car.getEndDownTime()));
} else {
carConfig.setStartDownTime(null);
}
carConfig.setUpdateDate(new Date());
}
carConfigRepository.save(carConfig);
}
}
@@ -0,0 +1,65 @@
package com.linln.admin.orders.service.impl;
import com.linln.admin.orders.domain.Coupons;
import com.linln.admin.orders.repository.CouponsRepository;
import com.linln.admin.orders.service.CouponsService;
import com.linln.common.data.PageSort;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import javax.annotation.Resource;
/**
* @author gion
* @date 2024/08/14
*/
@Service
public class CouponsServiceImpl implements CouponsService {
@Resource
private CouponsRepository couponsRepository;
/**
* 根据ID查询数据
* @param id 主键ID
*/
@Override
public Coupons getById(Long id) {
return couponsRepository.findById(id).orElse(null);
}
/**
* 获取分页列表数据
* @param example 查询实例
* @return 返回分页数据
*/
@Override
public Page<Coupons> getPageList(Example<Coupons> example) {
// 创建分页对象
PageRequest page = PageSort.pageRequest();
return couponsRepository.findAll(example, page);
}
/**
* 保存数据
* @param coupons 实体对象
*/
@Override
public Coupons save(Coupons coupons) {
return couponsRepository.save(coupons);
}
/**
* 状态(启用,冻结,删除)/批量状态处理
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateStatus(StatusEnum statusEnum, List<Long> idList) {
return couponsRepository.updateStatus(statusEnum.getCode(), idList) > 0;
}
}
@@ -13,6 +13,8 @@ import com.linln.admin.users.service.UsersAmountRecordsService;
import com.linln.admin.users.service.UsersService;
import com.linln.common.data.PageSort;
import com.linln.common.enums.StatusEnum;
import com.linln.component.thymeleaf.utility.DictUtil;
import org.apache.shiro.config.Ini;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@@ -58,6 +60,9 @@ public class OrderMainServiceImpl implements OrderMainService {
@Resource
private UsersAmountRecordsService usersAmountRecordsService;
@Resource
private PayOrderRepository payOrderRepository;
/**
* 根据ID查询数据
* @param id 主键ID
@@ -94,6 +99,13 @@ public class OrderMainServiceImpl implements OrderMainService {
return orderMainPage;
}
@Override
public Page<PayOrder> getPayOrderPageList(Example<PayOrder> example) {
// 创建分页对象
PageRequest page = PageSort.pageRequest("createTime", Sort.Direction.DESC);
return payOrderRepository.findAll(example, page);
}
private void getOrderMainInfo(OrderMain orderMain) {
if (StrUtil.isNotBlank(orderMain.getPetInfos())) {
return;
@@ -103,12 +115,16 @@ public class OrderMainServiceImpl implements OrderMainService {
List<OrderSub> orderSubs = orderSubRepository.findAllByMainOrderId(orderMain.getOrderId());
orderMain.setOrderSubs(orderSubs);
orderMain.setTotalAmount(orderSubs.stream().map(OrderSub::getTotalAmount).reduce(0, Integer::sum));
orderMain.setCid(orderSubs.get(0).getCid());
orderMain.setUcid(orderSubs.get(0).getUcid());
if (orderMain.getPayTotalAmount() != null && orderMain.getPayTotalAmount() > 0) {
orderMain.setPayAmount(orderMain.getPayTotalAmount());
} else {
orderMain.setPayAmount(orderSubs.stream().map(OrderSub::getPayAmount).filter(Objects::nonNull).reduce(0, Integer::sum));
orderMain.setPayTotalAmount(0);
}
int couponsOriginPrice = 0;
for (OrderSub orderSub : orderSubs) {
OrderDetail exampleOrderDetail = new OrderDetail();
exampleOrderDetail.setSubOrderId(orderSub.getOrderId());
@@ -121,19 +137,67 @@ public class OrderMainServiceImpl implements OrderMainService {
str = "" + orderSub.getGoods();
}
orderSub.setGoods(goods.getName() + str);
if (orderSub.getCid() != null && orderSub.getCid() > 0) {
Coupons coupons = InitLoadDataService.COUPONS_MAP.get(orderSub.getCid().longValue());
if (coupons.getGoodsSubType() != goods.getGoodsSubType()) {
orderSub.setVipAmount(orderSub.getVipAmount() + goods.getPrice());
} else {
couponsOriginPrice = couponsOriginPrice + goods.getPrice();
}
orderMain.setCoupons(coupons);
}
}
Pet pet = petRepository.findFirstById(orderSub.getPetId());
try {
String petInfo = "宠物名称:" + pet.getNickName() + "</br>品种:" + InitLoadDataService.PET_BASE_INFO_MAP.get(pet.getPetId()).getAssortment() + "</br>体重:" + (InitLoadDataService.PET_BASE_INFO_MAP.get(pet.getPetId()).getPetType() == 1 ? DictUtil.petCatWeight(Byte.valueOf(pet.getWeight().toString())) : DictUtil.petDogWeight(Byte.valueOf(pet.getWeight().toString()))) + "</br>服务项目:" + orderSub.getGoods();
orderSub.setPetInfo(petInfo);
} catch (Exception e) {
e.printStackTrace();
}
String str = "";
if (orderSubs.size() > 1) {
str = "<br><br>";
}
Optional<Pet> petOptional = petRepository.findById(orderSub.getPetId());
if (petOptional.isPresent()) {
Pet pet = petOptional.get();
PetBaseInfo petBaseInfo = InitLoadDataService.PET_BASE_INFO_MAP.get(pet.getPetId());
orderSub.setPetInfo("宠物名称:" + pet.getNickName() + "<br>品种:" + petBaseInfo.getAssortment() + "<br>服务项目:" + orderSub.getGoods());
}
orderMain.setPetInfos(orderSub.getPetInfo() + str + (orderMain.getPetInfos() == null ? "" : orderMain.getPetInfos()));
}
if (orderMain.getPayStatus() == 0 || orderMain.getPayDiscount() == 0) {
orderMain.setVipDiscountAmount(0);
} else {
Integer originPrice = orderSubs.stream().map(OrderSub::getVipAmount).reduce(0, Integer::sum);
int vipDiscountAmount = 0;
if (originPrice > 0) {
vipDiscountAmount = ((orderSubs.stream().map(OrderSub::getGoodsOriginAmount).reduce(0, Integer::sum) * 10) - (int) (originPrice * (orderMain.getPayDiscount() / 100.0) * 10));
} else {
vipDiscountAmount = ((orderSubs.stream().map(OrderSub::getGoodsOriginAmount).reduce(0, Integer::sum) * 10) - (int) (orderSubs.stream().map(OrderSub::getGoodsOriginAmount).reduce(0, Integer::sum) * (orderMain.getPayDiscount() / 100.0) * 10));
}
orderMain.setVipDiscountAmount(Math.max(vipDiscountAmount, 0));
}
if (orderMain.getPayOrderId() != null) {
PayOrder payOrder = payOrderRepository.getPayOrdersByOrderId(orderMain.getOrderId());
if (payOrder != null) {
if (payOrder.getOrderStatus() == 1) {
orderMain.setPayDj("已支付");
} else if (payOrder.getOrderStatus() == 2) {
orderMain.setPayDj("已退款");
} else {
orderMain.setPayDj("未支付");
}
} else {
orderMain.setPayDj("未支付");
}
} else {
orderMain.setPayDj("未支付");
}
//已派单
if (orderMain.getDispatchStatus() == 1) {
CarOrder carOrder = carOrderRepository.findFirstByOrderId(orderMain.getOrderId());
Car car = InitLoadDataService.CAR_MAP.get(carOrder.getCarId());
List<String> userNames = InitLoadDataService.CAR_USER_MAP.values().stream().filter(f -> f.getCarId().longValue() == car.getId().longValue()).collect(Collectors.toList()).stream().map(m -> m.getUsers().getNickName()).collect(Collectors.toList());
String name = String.join("</br>", userNames);
String carInfo = car.getCarNo() + "</br>" + name;
orderMain.setCarInfo(carInfo);
}
orderMain.setGoodsDiscountAmount(couponsOriginPrice * 10 - orderSubs.stream().map(OrderSub::getGoodsDiscountAmount).reduce(0, Integer::sum));
orderMain.setUserServiceAddr("姓名:" + userServiceAddr.getName() + "<br>联系电话:" + userServiceAddr.getMobile() + "<br>地址:" + userServiceAddr.getAddr());
}
@@ -148,7 +212,10 @@ public class OrderMainServiceImpl implements OrderMainService {
@Override
public void dispatchOrder(String orderId, Long carId) {
CarOrder carOrder = new CarOrder();
CarOrder carOrder = carOrderRepository.findFirstByOrderId(orderId);
if (carOrder == null) {
carOrder = new CarOrder();
}
carOrder.setCarId(carId);
carOrder.setOrderId(orderId);
carOrderRepository.save(carOrder);
@@ -162,6 +229,18 @@ public class OrderMainServiceImpl implements OrderMainService {
}
}
@Override
public void updateCarOrder(String orderId, Long carId) {
if (carId == 0) return;
CarOrder carOrder = carOrderRepository.findFirstByOrderId(orderId);
if (carOrder == null) {
carOrder = new CarOrder();
carOrder.setOrderId(orderId);
}
carOrder.setCarId(carId);
carOrderRepository.save(carOrder);
}
@Override
public List<Car> getCars() {
return carRepository.findAll();
@@ -189,7 +268,6 @@ public class OrderMainServiceImpl implements OrderMainService {
usersAmountRecords.setOrderId(orderMain.getOrderId());
usersAmountRecordsService.save(usersAmountRecords);
usersService.save(users);
}
orderMain.setPayTotalAmount(0);
orderMain.setPayStatus((byte) 0);
@@ -198,6 +276,10 @@ public class OrderMainServiceImpl implements OrderMainService {
List<OrderSub> orderSubs = orderSubRepository.findAllByMainOrderId(orderMain.getOrderId());
for (OrderSub orderSub : orderSubs) {
orderSub.setOrderStatus(Byte.valueOf("4"));
if (orderSub.getCid() > 0) {
//返还优惠券
usersService.returnUserCoupons(orderMain.getUid(), orderSub.getCid());
}
}
orderSubRepository.saveAll(orderSubs);
orderMainRepository.save(orderMain);
@@ -330,6 +412,16 @@ public class OrderMainServiceImpl implements OrderMainService {
orderMainRepository.save(orderMain);
orderSubRepository.saveAll(orderSubs);
usersService.save(users);
} else {
UsersAmountRecords usersAmountRecords = new UsersAmountRecords();
usersAmountRecords.setUserId(users.getId());
usersAmountRecords.setType(3);
usersAmountRecords.setOriginAmount(0);
usersAmountRecords.setProAmount(discountAmount);
usersAmountRecords.setCurrAmount(0);
usersAmountRecords.setProScene("后台下单");
usersAmountRecords.setOrderId(orderMain.getOrderId());
usersAmountRecordsService.save(usersAmountRecords);
}
}
}
@@ -47,6 +47,10 @@ public class PetGoodsServiceImpl implements PetGoodsService {
Page<PetGoods> petGoodsPage = petGoodsRepository.findAll(example, page);
List<PetGoods> content = petGoodsPage.getContent();
for (PetGoods petGoods : content) {
petGoods.setAssortmentDesc(petGoods.getAssortment() == 0 ? "" : InitLoadDataService.PET_BASE_INFO_MAP.get(Long.parseLong(petGoods.getAssortment().toString())).getAssortment());
if (!InitLoadDataService.GOODS_MAP.containsKey(petGoods.getGoodsId())) {
System.out.println(petGoods.getId());
}
petGoods.setGoods(InitLoadDataService.GOODS_MAP.get(petGoods.getGoodsId()));
}
return petGoodsPage;
@@ -0,0 +1,66 @@
package com.linln.admin.orders.service.impl;
import com.linln.admin.orders.domain.RechargeInfos;
import com.linln.admin.orders.repository.RechargeInfosRepository;
import com.linln.admin.orders.service.RechargeService;
import com.linln.common.data.PageSort;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* @author gion
* @date 2024/08/14
*/
@Service
public class RechargeServiceImpl implements RechargeService {
@Resource
private RechargeInfosRepository rechargeInfosRepository;
/**
* 根据ID查询数据
* @param id 主键ID
*/
@Override
public RechargeInfos getById(Long id) {
return rechargeInfosRepository.findById(id).orElse(null);
}
/**
* 获取分页列表数据
* @param example 查询实例
* @return 返回分页数据
*/
@Override
public Page<RechargeInfos> getPageList(Example<RechargeInfos> example) {
// 创建分页对象
PageRequest page = PageSort.pageRequest("createTime", Sort.Direction.DESC);
return rechargeInfosRepository.findAll(example, page);
}
/**
* 保存数据
* @param rechargeInfos 实体对象
*/
@Override
public RechargeInfos save(RechargeInfos rechargeInfos) {
return rechargeInfosRepository.save(rechargeInfos);
}
/**
* 状态(启用,冻结,删除)/批量状态处理
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateStatus(StatusEnum statusEnum, List<Long> idList) {
return rechargeInfosRepository.updateStatus(statusEnum.getCode(), idList) > 0;
}
}
@@ -0,0 +1,29 @@
package com.linln.admin.orders.validator;
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* @author gion
* @date 2024/08/14
*/
@Data
public class CouponsValid implements Serializable {
@NotEmpty(message = "优惠券名称不能为空")
private String name;
@NotNull(message = "有效商品子类型不能为空")
private Integer goodsSubType;
@NotNull(message = "折扣不能为空")
private Integer discount;
@NotEmpty(message = "来源不能为空")
private String source;
@NotNull(message = "使用限制不能为空")
private Integer periodType;
@NotNull(message = "过期时间不能为空")
private String expireTimeStr;
@NotNull(message = "下发类型不能为空")
private Integer sendStatus;
}
@@ -0,0 +1,22 @@
package com.linln.admin.orders.validator;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
/**
* @author gion
* @date 2024/08/14
*/
@Data
public class RechargeValid implements Serializable {
@NotEmpty(message = "充值活动名称不能为空")
private String name;
@NotEmpty(message = "充值活动描述不能为空")
private String desc;
@NotEmpty(message = "支付金额不能为空")
private String price;
@NotEmpty(message = "到账金额不能为空")
private String rechargePrice;
}
@@ -0,0 +1,119 @@
package com.linln.admin.users.controller;
import com.linln.admin.users.domain.Configs;
import com.linln.admin.users.service.ConfigsService;
import com.linln.admin.users.validator.ConfigsValid;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.EntityBeanUtil;
import com.linln.common.utils.ResultVoUtil;
import com.linln.common.utils.StatusUtil;
import com.linln.common.vo.ResultVo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import javax.annotation.Resource;
/**
* @author gion
* @date 2024/12/17
*/
@Controller
@RequestMapping("/users/configs")
public class ConfigsController {
@Resource
private ConfigsService configsService;
/**
* 列表页面
*/
@GetMapping("/index")
@RequiresPermissions("users:configs:index")
public String index(Model model, Configs configs) {
// 创建匹配器,进行动态查询匹配
ExampleMatcher matcher = ExampleMatcher.matching();
// 获取数据列表
Example<Configs> example = Example.of(configs, matcher);
Page<Configs> list = configsService.getPageList(example);
// 封装数据
model.addAttribute("list", list.getContent());
model.addAttribute("page", list);
return "/users/configs/index";
}
/**
* 跳转到添加页面
*/
@GetMapping("/add")
@RequiresPermissions("users:configs:add")
public String toAdd() {
return "/users/configs/add";
}
/**
* 跳转到编辑页面
*/
@GetMapping("/edit/{id}")
@RequiresPermissions("users:configs:edit")
public String toEdit(@PathVariable("id") Configs configs, Model model) {
model.addAttribute("configs", configs);
return "/users/configs/add";
}
/**
* 保存添加/修改的数据
* @param valid 验证对象
*/
@PostMapping("/save")
@RequiresPermissions({"users:configs:add", "users:configs:edit"})
@ResponseBody
public ResultVo save(@Validated ConfigsValid valid, Configs configs) {
// 复制保留无需修改的数据
if (configs.getId() != null) {
Configs beConfigs = configsService.getById(configs.getId());
EntityBeanUtil.copyProperties(beConfigs, configs);
}
// 保存数据
configsService.save(configs);
return ResultVoUtil.SAVE_SUCCESS;
}
/**
* 跳转到详细页面
*/
@GetMapping("/detail/{id}")
@RequiresPermissions("users:configs:detail")
public String toDetail(@PathVariable("id") Configs configs, Model model) {
model.addAttribute("configs",configs);
return "/users/configs/detail";
}
/**
* 设置一条或者多条数据的状态
*/
@RequestMapping("/status/{param}")
@RequiresPermissions("users:configs:status")
@ResponseBody
public ResultVo status(
@PathVariable("param") String param,
@RequestParam(value = "ids", required = false) List<Long> ids) {
// 更新状态
StatusEnum statusEnum = StatusUtil.getStatusEnum(param);
if (configsService.updateStatus(statusEnum, ids)) {
return ResultVoUtil.success(statusEnum.getMessage() + "成功");
} else {
return ResultVoUtil.error(statusEnum.getMessage() + "失败,请重新操作");
}
}
}
@@ -1,10 +1,13 @@
package com.linln.admin.users.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import com.linln.admin.config.InitLoadDataService;
import com.linln.admin.orders.domain.Coupons;
import com.linln.admin.orders.domain.Goods;
import com.linln.admin.orders.domain.Pet;
import com.linln.admin.users.domain.UserCoupons;
import com.linln.admin.users.domain.Users;
import com.linln.admin.users.domain.UsersAmountRecords;
import com.linln.admin.users.service.PetService;
@@ -30,10 +33,8 @@ import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author gion
@@ -131,6 +132,7 @@ public class UsersController {
goodsList.addAll(goodsList5);
}
for (Goods goods : goodsList) {
if (goods == null) continue;
if (goodsMap.containsKey(goods.getGoodsType())) {
goodsMap.get(goods.getGoodsType()).add(goods);
} else {
@@ -150,6 +152,18 @@ public class UsersController {
return "/users/users/petInfos";
}
/**
* 跳转到宠物信息页面
*/
@GetMapping("/toCouponsInfos/{id}")
@RequiresPermissions("users:users:add")
public String toCouponsInfos(@PathVariable("id") Users users, Model model) {
List<UserCoupons> userCouponsList = usersService.getUserCouponsList(users.getId());
model.addAttribute("userCouponsList", userCouponsList);
return "/users/users/userCoupons";
}
/**
* 跳转到编辑页面
*/
@@ -215,6 +229,9 @@ public class UsersController {
usersAmountRecordsService.save(usersAmountRecords);
User user = ShiroUtil.getSubject();
log.info("充值\t用户 : {}\t充值前金额 : {}\t充值金额 : {}\t充值后金额 : {}\t操作用户 : {}", user.getId(), amount, payAmount, payedAmount, user.getId());
List<Coupons> rechargeCoupons = usersService.findRechargeCoupons();
Users finalUsers = users;
usersService.sendUserCoupons(rechargeCoupons.stream().map(m -> new UserCoupons(finalUsers.getId(), m.getId().intValue(), 1, DateUtil.offsetDay(new Date(), m.getDrawDay()))).collect(Collectors.toList()));
return ResultVoUtil.SAVE_SUCCESS;
}
@@ -0,0 +1,70 @@
package com.linln.admin.users.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import com.linln.modules.system.domain.User;
import lombok.Data;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* @author gion
* @date 2024/12/17
*/
@Data
@Entity
@Table(name="system_configs")
@EntityListeners(AuditingEntityListener.class)
@Where(clause = StatusUtil.NOT_DELETE)
public class Configs implements Serializable {
// 主键ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
// 配置类型
private String configType;
// 内容
private String content;
// 排序
private Integer sort;
// 内容类型
private Integer contentType;
// 更新者
@LastModifiedBy
@ManyToOne(fetch=FetchType.LAZY)
@NotFound(action=NotFoundAction.IGNORE)
@JoinColumn(name="update_by")
@JsonIgnore
private User updateBy;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
// 跳转类型
private Integer jumpType;
// 跳转URL
private String jumpUrl;
// 创建时间
@CreatedDate
private Date createDate;
// 更新时间
@LastModifiedDate
private Date updateDate;
}
@@ -0,0 +1,68 @@
package com.linln.admin.users.domain;
import com.linln.admin.orders.domain.Coupons;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import lombok.Data;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.util.Date;
/**
* @author: yan.y
* @Description:
* @Date: Created in 16:40 2024/8/14
* @Modified by:
*/
@Data
@Entity
@Table(name="user_coupons")
@EntityListeners(AuditingEntityListener.class)
@Where(clause = StatusUtil.NOT_DELETE)
public class UserCoupons {
// 主键ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private Long uid;
private Integer cid;
//状态 1未使用 2已使用 3已过期
private Integer couponsStatus;
// 订单创建时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
@CreatedDate
private Date createDate;
@LastModifiedDate
private Date updateDate;
private Date updateTime;
// 数据状态
private Byte status = StatusEnum.OK.getCode();
// 最后过期时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date lastExpireTime;
@Transient
private Coupons coupons;
public UserCoupons() {
}
public UserCoupons(Long uid, Integer cid, Integer couponsStatus, Date lastExpireTime) {
this.uid = uid;
this.cid = cid;
this.couponsStatus = couponsStatus;
this.lastExpireTime = lastExpireTime;
}
}
@@ -57,6 +57,8 @@ public class Users implements Serializable {
@LastModifiedDate
private Date updateDate;
private Long inviteUserId;
private Byte status = StatusEnum.OK.getCode();
@Transient
@@ -0,0 +1,11 @@
package com.linln.admin.users.repository;
import com.linln.admin.users.domain.Configs;
import com.linln.modules.system.repository.BaseRepository;
/**
* @author gion
* @date 2024/12/17
*/
public interface ConfigsRepository extends BaseRepository<Configs, Long> {
}
@@ -0,0 +1,27 @@
package com.linln.admin.users.repository;
import com.linln.admin.users.domain.UserCoupons;
import com.linln.modules.system.repository.BaseRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.Date;
import java.util.List;
/**
* @author gion
* @date 2024/04/28
*/
public interface UsersCouponsRepository extends BaseRepository<UserCoupons, Integer> {
List<UserCoupons> findUserCouponsByLastExpireTimeLessThan(Date date);
List<UserCoupons> findUserCouponsByUidAndCidAndCouponsStatusOrderByUpdateTimeDesc(long uid, int cid, int couponsStatus);
List<UserCoupons> findUserCouponsByUid(long uid);
List<UserCoupons> findUserCouponsByUidIn(List<Long> uids);
@Query(nativeQuery = true, value = "select uid from user_coupons where cid = :cid and coupons_status = 1 group by uid,cid having count(1) > 0")
List<Long> findUserCouponsGtCidCount(int cid);
}
@@ -0,0 +1,41 @@
package com.linln.admin.users.service;
import com.linln.admin.users.domain.Configs;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author gion
* @date 2024/12/17
*/
public interface ConfigsService {
/**
* 获取分页列表数据
* @param example 查询实例
* @return 返回分页数据
*/
Page<Configs> getPageList(Example<Configs> example);
/**
* 根据ID查询数据
* @param id 主键ID
*/
Configs getById(Long id);
/**
* 保存数据
* @param configs 实体对象
*/
Configs save(Configs configs);
/**
* 状态(启用,冻结,删除)/批量状态处理
*/
@Transactional(rollbackFor = Exception.class)
Boolean updateStatus(StatusEnum statusEnum, List<Long> idList);
}
@@ -21,6 +21,8 @@ public interface PetBaseInfoService {
*/
Page<PetBaseInfo> getPageList(Example<PetBaseInfo> example);
List<PetBaseInfo> findPetBaseList(Integer petType);
/**
* 根据ID查询数据
* @param id 主键ID
@@ -1,7 +1,8 @@
package com.linln.admin.users.service;
import com.linln.admin.orders.domain.ServiceAddrs;
import com.linln.admin.orders.domain.Coupons;
import com.linln.admin.orders.domain.UserServiceAddr;
import com.linln.admin.users.domain.UserCoupons;
import com.linln.admin.users.domain.Users;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
@@ -46,4 +47,22 @@ public interface UsersService {
void updateAmountAndDiscount(long id, long discount, int amount);
List<UserServiceAddr> getUserAddrList(long uid);
UserServiceAddr getAddrById(long userServerAddrId);
List<Users> getAllUser();
void sendUserCoupons(List<UserCoupons> userCoupons);
void returnUserCoupons(long id, int cid);
List<UserCoupons> getUserCouponsList(long uid);
List<UserCoupons> getUserCouponsList(List<Long> uids);
List<Long> getUserCouponsGtCid(int cid);
void updateUserServiceAddr(UserServiceAddr userServiceAddr);
List<Coupons> findRechargeCoupons();
}
@@ -0,0 +1,65 @@
package com.linln.admin.users.service.impl;
import com.linln.admin.users.domain.Configs;
import com.linln.admin.users.repository.ConfigsRepository;
import com.linln.admin.users.service.ConfigsService;
import com.linln.common.data.PageSort;
import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import javax.annotation.Resource;
/**
* @author gion
* @date 2024/12/17
*/
@Service
public class ConfigsServiceImpl implements ConfigsService {
@Resource
private ConfigsRepository configsRepository;
/**
* 根据ID查询数据
* @param id 主键ID
*/
@Override
public Configs getById(Long id) {
return configsRepository.findById(id).orElse(null);
}
/**
* 获取分页列表数据
* @param example 查询实例
* @return 返回分页数据
*/
@Override
public Page<Configs> getPageList(Example<Configs> example) {
// 创建分页对象
PageRequest page = PageSort.pageRequest();
return configsRepository.findAll(example, page);
}
/**
* 保存数据
* @param configs 实体对象
*/
@Override
public Configs save(Configs configs) {
return configsRepository.save(configs);
}
/**
* 状态(启用,冻结,删除)/批量状态处理
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateStatus(StatusEnum statusEnum, List<Long> idList) {
return configsRepository.updateStatus(statusEnum.getCode(), idList) > 0;
}
}
@@ -1,5 +1,6 @@
package com.linln.admin.users.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.linln.admin.orders.domain.PetBaseInfo;
import com.linln.admin.orders.repository.PetBaseInfoRepository;
import com.linln.admin.users.service.PetBaseInfoService;
@@ -8,6 +9,7 @@ import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -41,10 +43,15 @@ public class PetBaseInfoServiceImpl implements PetBaseInfoService {
@Override
public Page<PetBaseInfo> getPageList(Example<PetBaseInfo> example) {
// 创建分页对象
PageRequest page = PageSort.pageRequest();
PageRequest page = PageSort.pageRequest("id", Sort.Direction.DESC);
return petBaseInfoRepository.findAll(example, page);
}
@Override
public List<PetBaseInfo> findPetBaseList(Integer petType) {
return petBaseInfoRepository.findAllByPetType(petType);
}
/**
* 保存数据
* @param petBaseInfo 实体对象
@@ -1,5 +1,6 @@
package com.linln.admin.users.service.impl;
import cn.hutool.core.util.StrUtil;
import com.linln.admin.config.InitLoadDataService;
import com.linln.admin.orders.domain.Pet;
import com.linln.admin.orders.repository.PetRepository;
@@ -9,10 +10,13 @@ import com.linln.common.enums.StatusEnum;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
/**
@@ -43,7 +47,19 @@ public class PetServiceImpl implements PetService {
public Page<Pet> getPageList(Example<Pet> example) {
// 创建分页对象
PageRequest page = PageSort.pageRequest();
Page<Pet> pets = petsRepository.findAll(example, page);
Page<Pet> pets = petsRepository.findAll((Specification<Pet>) (root, query, cb) -> {
List<Predicate> preList = new ArrayList<>();
if (example.getProbe().getUid() != null) {
preList.add(cb.equal(root.get("uid").as(Long.class), example.getProbe().getUid()));
}
if (StrUtil.isNotBlank(example.getProbe().getBirthday())) {
preList.add(cb.like(root.get("birthday").as(String.class), "%-" + example.getProbe().getBirthday() + "-%"));
}
Predicate[] pres = new Predicate[preList.size()];
return query.where(preList.toArray(pres)).getRestriction();
}, page);
List<Pet> content = pets.getContent();
for (Pet pet : content) {
pet.setPetBaseInfo(InitLoadDataService.PET_BASE_INFO_MAP.get(pet.getPetId()));
@@ -1,8 +1,14 @@
package com.linln.admin.users.service.impl;
import com.linln.admin.orders.domain.Coupons;
import com.linln.admin.orders.domain.ServiceAddrs;
import com.linln.admin.orders.domain.UserServiceAddr;
import com.linln.admin.orders.repository.CouponsRepository;
import com.linln.admin.orders.repository.ServiceAddrsRepository;
import com.linln.admin.orders.repository.UserServiceAddrRepository;
import com.linln.admin.users.domain.UserCoupons;
import com.linln.admin.users.domain.Users;
import com.linln.admin.users.repository.UsersCouponsRepository;
import com.linln.admin.users.repository.UsersRepository;
import com.linln.admin.users.service.UsersService;
import com.linln.common.data.PageSort;
@@ -31,6 +37,15 @@ public class UsersServiceImpl implements UsersService {
@Resource
private UserServiceAddrRepository userServiceAddrRepository;
@Resource
private UsersCouponsRepository usersCouponsRepository;
@Resource
private CouponsRepository couponsRepository;
@Resource
private ServiceAddrsRepository serviceAddrsRepository;
/**
* 根据ID查询数据
* @param id 主键ID
@@ -81,4 +96,58 @@ public class UsersServiceImpl implements UsersService {
userServiceAddrFind.setUid(uid);
return userServiceAddrRepository.findAll(Example.of(userServiceAddrFind));
}
@Override
public UserServiceAddr getAddrById(long userServerAddrId) {
return userServiceAddrRepository.getById(userServerAddrId);
}
@Override
public List<Users> getAllUser() {
return usersRepository.findAll();
}
@Override
public void sendUserCoupons(List<UserCoupons> userCoupons) {
usersCouponsRepository.saveAllAndFlush(userCoupons);
}
@Override
public void returnUserCoupons(long id, int cid) {
List<UserCoupons> userCouponsList = usersCouponsRepository.findUserCouponsByUidAndCidAndCouponsStatusOrderByUpdateTimeDesc(id, cid, 2);
if (!userCouponsList.isEmpty()) {
UserCoupons userCoupons = userCouponsList.get(0);
userCoupons.setCouponsStatus(1);
usersCouponsRepository.saveAndFlush(userCoupons);
}
}
@Override
public List<UserCoupons> getUserCouponsList(long uid) {
List<UserCoupons> userCouponsList = usersCouponsRepository.findUserCouponsByUid(uid);
for (UserCoupons userCoupons : userCouponsList) {
userCoupons.setCoupons(couponsRepository.findFirstById(userCoupons.getCid().longValue()));
}
return userCouponsList;
}
@Override
public List<UserCoupons> getUserCouponsList(List<Long> uids) {
return usersCouponsRepository.findUserCouponsByUidIn(uids);
}
@Override
public List<Long> getUserCouponsGtCid(int cid) {
return usersCouponsRepository.findUserCouponsGtCidCount(cid);
}
@Override
public void updateUserServiceAddr(UserServiceAddr userServiceAddr) {
userServiceAddrRepository.save(userServiceAddr);
}
@Override
public List<Coupons> findRechargeCoupons() {
return couponsRepository.findByStatusAndSendStatusAndExpireTimeGreaterThanOrderByExpireTimeAsc((byte) 1, 4, System.currentTimeMillis());
}
}
@@ -0,0 +1,18 @@
package com.linln.admin.users.validator;
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
/**
* @author gion
* @date 2024/12/17
*/
@Data
public class ConfigsValid implements Serializable {
@NotEmpty(message = "配置名称不能为空")
private String name;
@NotEmpty(message = "配置类型不能为空")
private String configType;
}
@@ -478,7 +478,25 @@ a{
left: 0;
}
}
::-webkit-scrollbar {
width: 10px; /* 滚动条宽度 */
height: 10px;
}
::-webkit-scrollbar-track {
background: #eee;
border-radius: 6px;
}
::-webkit-scrollbar-thumb {
background: #666;
border-radius: 6px;
cursor: pointer;
}
::-webkit-scrollbar-thumb:hover {
background: #999;
}
/* 页面通用样式 */
.timo-layout-page{
background-color: #eeeeee;
@@ -53,9 +53,12 @@
</th>
<th>主键ID</th>
<th>车牌号</th>
<th>车辆状态</th>
<th>下线时间段</th>
<th>护理人员信息</th>
<th>车辆排单列表</th>
<th>添加护理人员</th>
<th>车辆下线设置</th>
<th>操作</th>
</tr>
</thead>
@@ -65,6 +68,9 @@
<i class="layui-icon layui-icon-ok"></i></label></td>
<td th:text="${item.id}">主键ID</td>
<td th:text="${item.carNo}">车牌号</td>
<td th:if="${item.carStatus == 1 || item.carStatus == null}">上线</td>
<td th:if="${item.carStatus == 2}">下线</td>
<td th:text="${item.info}">下线时间段</td>
<td>
<a class="open-popup" data-title="护理人员信息" th:attr="data-url=@{'/orders/car/toCarUserInfos/'+${item.id}}" data-size="auto" href="#">护理人员信息</a>
</td>
@@ -75,6 +81,9 @@
<a class="open-popup" data-title="添加护理人员" th:attr="data-url=@{'/orders/car/toAddCarUserInfos/'+${item.id}}" data-size="auto" href="#">添加护理人员</a>
</td>
<td>
<a class="open-popup" data-title="车辆下线管理" th:attr="data-url=@{'/orders/car/toCarDownInfos/'+${item.id}}" data-size="auto" href="#">车辆下线管理</a>
</td>
<td>
<!-- <a class="open-popup" data-title="设置区域服务时间" th:attr="data-url=@{'/orders/car/toUpdateAreaTime/'+${item.id}}" data-size="auto" href="#">设置区域服务时间</a>-->
<a class="open-popup" data-title="编辑车辆" th:attr="data-url=@{'/orders/car/edit/'+${item.id}}" data-size="auto" href="#">编辑</a>
<a class="open-popup" data-title="详细信息" th:attr="data-url=@{'/orders/car/detail/'+${item.id}}" data-size="800,600" href="#">详细</a>
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body>
<div class="layui-form timo-compile">
<form th:action="@{/orders/car/saveCarDownInfo}">
<input type="hidden" name="id" th:if="${car}" th:value="${car.id}">
<div class="layui-form-item">
<label class="layui-form-label">车牌号</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="carNo" readonly th:value="${car?.carNo}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下线开始时间</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" id="startDownTime" name="startDownTime" placeholder="请输入下线开始时间" th:value="${car?.startDownTime}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下线结束时间</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" id="endDownTime" name="endDownTime" placeholder="请输入下线结束时间" th:value="${car?.endDownTime}">
</div>
</div>
<div class="layui-form-item timo-finally">
<button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
<button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
</div>
</form>
</div>
<script th:replace="/common/template :: script"></script>
<script>
layui.use(['laydate'], function () {
var laydate = layui.laydate;
// 渲染
laydate.render({
elem: '#startDownTime',
type: 'datetime'
});
laydate.render({
elem: '#endDownTime',
type: 'datetime'
});
})
</script>
</body>
</html>
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body>
<div class="layui-form timo-compile">
<form th:action="@{/orders/coupons/save}">
<input type="hidden" name="id" th:if="${coupons}" th:value="${coupons.id}">
<div class="layui-form-item">
<label class="layui-form-label">优惠券名称</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="name" placeholder="请输入优惠券名称" th:value="${coupons?.name}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">有效商品子类型(子类型商品可使用)</label>
<div class="layui-input-inline">
<select class="timo-search-select" name="goodsSubType" mo:dict="GOODS_SUB_TYPE"
mo-selected="${coupons?.goodsSubType}"></select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">折扣(10-100</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="discount" placeholder="请输入折扣" th:value="${coupons?.discount}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">来源</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="source" placeholder="请输入来源" th:value="${coupons?.source}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">使用限制</label>
<div class="layui-input-inline">
<div class="layui-input-inline">
<select class="timo-search-select" name="periodType" mo:dict="PERIOD_TYPE"
mo-selected="${coupons?.periodType}"></select>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">使用限制信息</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="period" placeholder="请输入使用限制信息" th:value="${coupons?.period}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">领取过期时间</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" id="expireTime" name="expireTimeStr" placeholder="请输入过期时间" th:value="${coupons?.expireTimeStr}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下发类型</label>
<div class="layui-input-inline">
<div class="layui-input-inline">
<select class="timo-search-select" name="sendStatus" mo:dict="COUPONS_SEND_STATUS"
mo-selected="${coupons?.sendStatus}"></select>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">领取后过期天数</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="drawDay" placeholder="领取后过期天数" th:value="${coupons?.drawDay}">
</div>
</div>
<div class="layui-form-item timo-finally">
<button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
<button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
</div>
</form>
</div>
<script th:replace="/common/template :: script"></script>
<script>
layui.use(['laydate'], function () {
var laydate = layui.laydate;
// 渲染
laydate.render({
elem: '#expireTime',
type: 'datetime'
});
})
</script>
</body>
</html>
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body>
<div class="timo-detail-page">
<div class="timo-detail-title">基本信息</div>
<table class="layui-table timo-detail-table">
<colgroup>
<col width="100px"><col>
<col width="100px"><col>
</colgroup>
<tbody>
<tr>
<th>主键ID</th>
<td th:text="${coupons.id}"></td>
<th>优惠券名称</th>
<td th:text="${coupons.name}"></td>
</tr>
<tr>
<th>有效商品子类型</th>
<td th:text="${coupons.goodsSubType}"></td>
<th>折扣</th>
<td th:text="${coupons.discount}"></td>
</tr>
<tr>
<th>来源</th>
<td th:text="${coupons.source}"></td>
<th>使用限制</th>
<td th:text="${coupons.periodType}"></td>
</tr>
<tr>
<th>使用限制信息</th>
<td th:text="${coupons.period}"></td>
<th>过期时间戳</th>
<td th:text="${coupons.expireTime}"></td>
</tr>
<tr>
<th>下发类型</th>
<td th:text="${coupons.sendStatus}"></td>
<th>创建时间</th>
<td th:text="${coupons.createTime}"></td>
</tr>
<tr>
<th>更新时间</th>
<td th:text="${#dates.format(coupons.updateDate, 'yyyy-MM-dd HH:mm:ss')}" colspan="3"></td>
</tr>
</tbody>
</table>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:mo="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body class="timo-layout-page">
<div class="layui-card">
<div class="layui-card-header timo-card-header">
<span><i class="fa fa-bars"></i> 优惠券管理</span>
<i class="layui-icon layui-icon-refresh refresh-btn"></i>
</div>
<div class="layui-card-body">
<div class="layui-row timo-card-screen">
<div class="pull-right screen-btn-group">
<button class="layui-btn open-popup" data-title="添加优惠券" th:attr="data-url=@{/orders/coupons/add}" data-size="auto">
<i class="fa fa-plus"></i> 添加</button>
<div class="btn-group">
<button class="layui-btn">操作<span class="caret"></span></button>
<dl class="layui-nav-child layui-anim layui-anim-upbit">
<dd><a class="ajax-status" th:href="@{/orders/coupons/status/ok}">启用</a></dd>
<dd><a class="ajax-status" th:href="@{/orders/coupons/status/freezed}">冻结</a></dd>
<dd><a class="ajax-status" th:href="@{/orders/coupons/status/delete}">删除</a></dd>
</dl>
</div>
</div>
</div>
<div class="timo-table-wrap">
<table class="layui-table timo-table">
<thead>
<tr>
<th class="timo-table-checkbox">
<label class="timo-checkbox"><input type="checkbox">
<i class="layui-icon layui-icon-ok"></i></label>
</th>
<th>优惠券ID</th>
<th>优惠券名称</th>
<th>有效商品子类型</th>
<th>折扣</th>
<th>来源</th>
<th>使用限制</th>
<th>使用限制信息</th>
<th>可领取过期时间</th>
<th>下发类型</th>
<th>领取后过期天数</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="item:${list}">
<td><label class="timo-checkbox"><input type="checkbox" th:value="${item.id}">
<i class="layui-icon layui-icon-ok"></i></label></td>
<td th:text="${item.id}">优惠券ID</td>
<td th:text="${item.name}">优惠券名称</td>
<td th:text="${#dicts.goodsSubType(item.goodsSubType)}">有效商品子类型(子类型商品可使用)</td>
<td th:text="${item.discount}">折扣(10-100</td>
<td th:text="${item.source}">来源</td>
<td th:text="${#dicts.periodType(item.periodType)}">使用限制</td>
<td th:text="${item.period}">使用限制信息</td>
<td th:text="${#dates.format(new java.util.Date(item.expireTime), 'yyyy-MM-dd HH:mm:ss')}">过期时间</td>
<td th:text="${#dicts.couponsSendStatus(item.sendStatus)}">下发类型</td>
<td th:text="${item.drawDay}">领取后过期天数</td>
<td th:text="${item.createTime}">创建时间</td>
<td>
<!-- <a class="ajax-get" data-msg="一键下发所有用户" th:href="@{/orders/coupons/send(ids=${item.id})}">一键下发</a>&nbsp;&nbsp;-->
<a class="open-popup" data-title="下发优惠券" th:if="${item.sendStatus == 5}" th:attr="data-url=@{'/orders/coupons/toSend/'+${item.id}}" data-size="auto" href="#">下发优惠券</a>
<a class="open-popup" data-title="编辑优惠券" th:attr="data-url=@{'/orders/coupons/edit/'+${item.id}}" data-size="auto" href="#">编辑</a>
<a class="ajax-get" data-msg="您是否确认删除" th:href="@{/orders/coupons/status/delete(ids=${item.id})}">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<div th:replace="/common/fragment :: page"></div>
</div>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body>
<div class="layui-form timo-compile">
<form th:action="@{/orders/coupons/send}">
<input type="hidden" name="id" th:if="${coupons}" th:value="${coupons.id}">
<div class="layui-form-item">
<label class="layui-form-label">下发类型</label>
<div class="layui-input-inline">
<select class="timo-search-select" name="sendType">
<option value="1">指定用户</option>
<option value="2">所有用户</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户ID(指定用户必须传入)</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="uid" placeholder="请输入用户">
</div>
</div>
<div class="layui-form-item timo-finally">
<button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
<button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
</div>
</form>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -20,6 +20,13 @@
mo-selected="${goods?.goodsType}"></select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">商品子类型</label>
<div class="layui-input-inline">
<select class="timo-search-select" name="goodsSubType" mo:dict="GOODS_SUB_TYPE"
mo-selected="${goods?.goodsSubType}"></select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">商品服务时间</label>
<div class="layui-input-inline">
@@ -51,6 +51,24 @@
</select>
</div>
</div>
<div class="layui-form-item" id="catPz">
<label class="layui-form-label">宠物品种</label>
<div class="layui-input-inline">
<select class="timo-search-select" name="catPz" mo-selected="0">
<option value="0"></option>
<option th:each="c,PetBaseInfo:${cats}" th:value="${c.id}" th:text="${c.assortment}"></option>
</select>
</div>
</div>
<div class="layui-form-item" id="dogPz" style="display: none">
<label class="layui-form-label">宠物品种</label>
<div class="layui-input-inline">
<select class="timo-search-select" name="dogPz" o-selected="0">
<option value="0"></option>
<option th:each="c,PetBaseInfo:${dogs}" th:value="${c.id}" th:text="${c.assortment}"></option>
</select>
</div>
</div>
<div class="layui-form-item timo-finally">
<button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
<button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
@@ -67,10 +85,14 @@
var petType = data.value
if (petType === "1") {
$("#catWeight").show()
$("#catPz").show()
$("#dogWeight").hide()
$("#dogPz").hide()
} else {
$("#catWeight").hide()
$("#catPz").hide()
$("#dogWeight").show()
$("#dogPz").show()
}
});
});
@@ -42,6 +42,7 @@
<th>商品ID</th>
<th>商品名称</th>
<th>商品类型</th>
<th>商品子类型</th>
<th>商品服务时间</th>
<th>商品价格</th>
<th>是否可购买多个</th>
@@ -55,6 +56,7 @@
<td th:text="${item.id}">商品ID</td>
<td th:text="${item.name}">商品名称</td>
<td th:text="${#dicts.goodsType(item.goodsType)}">商品类型</td>
<td th:text="${#dicts.goodsSubType(item.goodsSubType)}">商品子类型</td>
<td th:text="${item.time}">商品服务时间</td>
<td th:text="${item.price}">商品价格</td>
<td th:text="${#dicts.goodsBuyMany(item.buyMany)}">是否可购买多个</td>
@@ -21,24 +21,39 @@
<div class="layui-form-item">
<label class="layui-form-label">订单服务时长</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="projectionServiceTime"
<input class="layui-input" type="text" name="projectionServiceTime" disabled
th:value="${orderMain.projectionServiceTime}"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">服务时间</label>
<label class="layui-form-label">备注</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="serviceTime"
th:value="${orderMain.serviceTime}"/>
<textarea name="remark" th:value="${orderMain.remark}"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">详细地址信息</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="addr" th:value="${orderMain.userServiceAddrInfo.addr}"/>
<input class="layui-input" type="text" name="addr" th:value="${orderMain.userServiceAddrInfo.addr}" disabled/>
<input type="hidden" name="addrId" th:value="${orderMain.userServiceAddrInfo.id}"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">服务时间</label>
<div class="layui-input-inline">
<input class="layui-input" id="serviceTime" type="text" name="serviceTime"
th:value="${orderMain.serviceTime}"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">服务车辆</label>
<div class="layui-input-inline">
<select class="timo-search-select" id="carId" name="carId">
<option th:text="无" value="0"></option>
<option th:each="c,Car:${cars}" th:value="${c.id}" th:text="${c.carNo}"></option>
</select>
</div>
</div>
<div class="layui-form-item timo-finally">
<button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
<button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
@@ -47,4 +62,15 @@
</div>
<script th:replace="/common/template :: script"></script>
</body>
<script>
layui.use(['laydate'], function () {
var laydate = layui.laydate;
// 渲染
laydate.render({
elem: '#serviceTime',
type: 'datetime',
format: 'yyyy-MM-dd HH:mm'
});
})
</script>
</html>
@@ -57,7 +57,10 @@
<option value="1" th:selected="${#strings.equals(param.payStatus, '1')}">已支付</option>
</select>
</div>
<label class="layui-form-label">服务时间</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" id="serviceTime" name="serviceTime" placeholder="请输入服务时间" th:value="${param?.serviceTime}" lay-key="1" >
</div>
<button class="layui-btn timo-search-btn">
<i class="fa fa-search"></i>
</button>
@@ -71,21 +74,28 @@
<tr>
<th>操作</th>
<th>用户ID</th>
<th>备注</th>
<th>用户余额</th>
<th>订单创建时间</th>
<th>服务时间</th>
<th>订单状态</th>
<th>派单状态</th>
<th>派单信息</th>
<th>地址信息</th>
<th>宠物信息</th>
<th>优惠券名称</th>
<th>洗护时长</th>
<th>付款状态</th>
<th>支付类型</th>
<th>定金付款状态</th>
<th>总金额</th>
<th>支付金额</th>
<th>会员折扣支付金额</th>
<th>折扣</th>
<th>会员折扣金额</th>
<th>会员折扣</th>
<th>优惠券折扣金额</th>
<th>优惠券ID</th>
<th>订单ID</th>
<th>订单创建时间</th>
<th>支付订单号</th>
</tr>
</thead>
<tbody>
@@ -95,28 +105,34 @@
th:attr="data-url=@{'/orders/orderMain/toDispatchPage/'+${item.id}}" data-size="auto"
href="#">派单</a>
<a th:if="${item.orderStatus == 1}" class="ajax-get" data-msg="您是否确认取消订单" th:href="@{/orders/orderMain/orderCancel(ids=${item.id})}">取消订单</a>
<a class="open-popup" data-title="编辑订单"
<a class="open-popup" data-title="编辑"
th:attr="data-url=@{'/orders/orderMain/edit/'+${item.id}}" data-size="auto"
href="#">编辑</a>
<a th:if="${item.orderStatus == 3 || item.orderStatus == 4}" class="ajax-get" data-msg="您是否确认删除" th:href="@{/orders/orderMain/status/delete(ids=${item.id})}">删除</a>
</td>
<td th:text="${item.uid}">用户ID</td>
<td style="white-space: pre-wrap; width: 100px;" th:text="${item.remark}">备注</td>
<td th:text="${item.orderUser.amount == null ? 0 : item.orderUser.amount / 10.0}">用户余额</td>
<td th:text="${item.createTime}">订单创建时间</td>
<td th:text="${item.serviceTime}">服务时间</td>
<td th:text="${#dicts.orderStatus(item.orderStatus)}">订单状态</td>
<td th:text="${#dicts.dispatchStatus(item.dispatchStatus)}">派单状态</td>
<td th:utext="${item.userServiceAddr}">地址信息</td>
<td style="white-space: pre-wrap; width: 100px;" th:utext="${item.carInfo}">派单信息</td>
<td style="white-space: pre-wrap; width: 100px;" th:utext="${item.userServiceAddr}">地址信息</td>
<td th:utext="${item.petInfos}">宠物信息</td>
<td th:text="${item.coupons?.name}">优惠券名称</td>
<td th:text="${item.projectionServiceTime}">洗护时长</td>
<td th:text="${#dicts.payStatus(item.payStatus)}">付款状态</td>
<td th:text="${#dicts.payType(item.payType)}">支付类型</td>
<td th:text="${item.payDj}">定金付款状态</td>
<td th:text="${item.totalAmount}">总金额</td>
<td th:text="${item.payTotalAmount > 0 ? item.payAmount / 10.0 : item.payTotalAmount}">支付金额</td>
<td th:text="${item.payTotalAmount / 10.0}">会员折扣支付金额</td>
<td th:text="${item.payDiscount / 100.0}">折扣</td>
<td th:text="${item.payAmount / 10.0}">支付金额</td>
<td th:text="${item.vipDiscountAmount / 10.0}">会员折扣金额</td>
<td th:text="${item.payDiscount / 100.0}">会员折扣</td>
<td th:text="${item.goodsDiscountAmount / 10.0}">优惠券折扣金额</td>
<td th:text="${item.ucid}">优惠券ID</td>
<td th:text="${item.orderId}">订单ID</td>
<td th:text="${item.createTime}">订单创建时间</td>
<td th:text="${item.payOrderId}">支付订单号</td>
<!--<td>
<a class="open-popup" data-title="编辑订单" th:attr="data-url=@{'/orders/orderMain/edit/'+${item.id}}" data-size="auto" href="#">编辑</a>
@@ -131,5 +147,16 @@
</div>
</div>
<script th:replace="/common/template :: script"></script>
<script type="text/javascript">
layui.use(['laydate','form'], function () {
var laydate = layui.laydate;
// 渲染
laydate.render({
elem: '#serviceTime',
type: 'datetime',
format: 'yyyy-MM-dd HH:mm'
});
})
</script>
</body>
</html>
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
>
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body class="timo-layout-page">
<div class="layui-card">
<div class="layui-card-header timo-card-header">
<span><i class="fa fa-bars"></i> 支付订单管理</span>
<i class="layui-icon layui-icon-refresh refresh-btn"></i>
</div>
<div class="layui-card-body">
<div class="layui-row timo-card-screen">
<div class="pull-left layui-form-pane timo-search-box">
<div class="layui-form timo-compile layui-form-item">
<!--<label class="layui-form-label">状态</label>
<div class="layui-input-block timo-search-status">
<select class="timo-search-select" name="status" mo:dict="SEARCH_STATUS"
mo-selected="${param.status}"></select>
</div>-->
<label class="layui-form-label">订单ID</label>
<div class="layui-input-block">
<input type="text" name="orderId" th:value="${param.orderId}" placeholder="请输入订单ID"
autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">用户ID</label>
<div class="layui-input-block">
<input type="text" name="uid" th:value="${param.uid}" placeholder="请输入用户ID"
autocomplete="off" class="layui-input">
</div>
<button class="layui-btn timo-search-btn">
<i class="fa fa-search"></i>
</button>
</div>
</div>
</div>
<div class="timo-table-wrap">
<table class="layui-table timo-table">
<thead>
<tr>
<th>订单ID</th>
<th>用户ID</th>
<th>订单名称</th>
<th>订单金额</th>
<th>订单状态</th>
<th>支付ID</th>
<th>充值商品ID</th>
<th>创建时间</th>
</tr>
</thead>
<tbody>
<tr th:each="item:${list}">
<td th:text="${item.orderId}">订单ID</td>
<td th:text="${item.uid}">用户ID</td>
<td th:text="${item.orderName}">订单名称</td>
<td th:text="${item.orderStatus == 3 ? item.orderPrice / 10.0 : item.orderPrice}">订单金额</td>
<td th:text="${#dicts.payOrderStatus(item.orderStatus)}">订单状态</td>
<td th:text="${item.payId}">订单名称</td>
<td th:text="${item.rechargeId}">充值商品ID</td>
<td th:text="${item.createTime}">订单创建时间</td>
</tr>
</tbody>
</table>
</div>
<div th:replace="/common/fragment :: page"></div>
</div>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -21,7 +21,7 @@
<div class="layui-form-item">
<label class="layui-form-label">宠物大小</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="size" placeholder="请输入宠物大小" th:value="${petGoods?.size}">
<input class="layui-input" type="text" name="petSize" placeholder="请输入宠物大小" th:value="${petGoods?.petSize}">
</div>
</div>
<div class="layui-form-item">
@@ -21,7 +21,7 @@
<th>宠物类型</th>
<td th:text="${petGoods.petType}"></td>
<th>宠物大小</th>
<td th:text="${petGoods.size}"></td>
<td th:text="${petGoods.petSize}"></td>
</tr>
<tr>
<th>宠物体重</th>
@@ -43,6 +43,7 @@
<i class="layui-icon layui-icon-ok"></i></label>
</th>
<th>id</th>
<th>宠物品种</th>
<th>宠物类型</th>
<th>宠物体重</th>
<th>宠物毛发</th>
@@ -59,6 +60,7 @@
<td><label class="timo-checkbox"><input type="checkbox" th:value="${item.id}">
<i class="layui-icon layui-icon-ok"></i></label></td>
<td th:text="${item.id}">id</td>
<td th:text="${item.assortmentDesc}">宠物品种</td>
<td th:text="${#dicts.petType(item.petType)}">宠物类型</td>
<td th:if="${item.petType == 1}" th:text="${#dicts.petCatWeight(item.weight)}">宠物体重</td>
<td th:if="${item.petType == 2}" th:text="${#dicts.petDogWeight(item.weight)}">宠物体重</td>
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body>
<div class="layui-form timo-compile">
<form th:action="@{/orders/recharge/save}">
<input type="hidden" name="id" th:if="${recharge}" th:value="${recharge.id}">
<div class="layui-form-item">
<label class="layui-form-label">充值活动名称</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="name" placeholder="请输入充值活动名称" th:value="${recharge?.name}" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">充值活动描述</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="desc" placeholder="请输入充值活动描述" th:value="${recharge?.desc}" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">支付金额</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="price" placeholder="请输入支付金额" th:value="${recharge?.price}" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">赠送金额</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" value="0" name="givePrice" placeholder="请输入赠送金额" th:value="${recharge?.givePrice}" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">充值到账金额</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="rechargePrice" placeholder="请输入充值到账金额" th:value="${recharge?.rechargePrice}" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">充值类型</label>
<div class="layui-input-inline">
<select class="timo-search-select" name="type" mo:dict="RECHARGE_TYPE" mo-selected="${recharge?.type}"></select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">赠送描述</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" value="无" name="give" placeholder="赠送描述" th:value="${recharge?.give}">
</div>
</div>
<div class="layui-form-item timo-finally">
<button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
<button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
</div>
</form>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:mo="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body class="timo-layout-page">
<div class="layui-card">
<div class="layui-card-header timo-card-header">
<span><i class="fa fa-bars"></i> 充值管理</span>
<i class="layui-icon layui-icon-refresh refresh-btn"></i>
</div>
<div class="layui-card-body">
<div class="layui-row timo-card-screen">
<div class="pull-right screen-btn-group">
<button class="layui-btn open-popup" data-title="添加充值商品" th:attr="data-url=@{/orders/recharge/add}" data-size="auto">
<i class="fa fa-plus"></i> 添加</button>
<div class="btn-group">
<button class="layui-btn">操作<span class="caret"></span></button>
<dl class="layui-nav-child layui-anim layui-anim-upbit">
<dd><a class="ajax-status" th:href="@{/orders/coupons/status/delete}">删除</a></dd>
</dl>
</div>
</div>
</div>
<div class="timo-table-wrap">
<table class="layui-table timo-table">
<thead>
<tr>
<th class="timo-table-checkbox">
<label class="timo-checkbox"><input type="checkbox">
<i class="layui-icon layui-icon-ok"></i></label>
</th>
<th>充值ID</th>
<th>充值名称</th>
<th>充值描述</th>
<th>金额</th>
<th>赠送金额</th>
<th>充值到账金额</th>
<th>类型</th>
<th>赠送描述</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="item:${list}">
<td><label class="timo-checkbox"><input type="checkbox" th:value="${item.id}">
<i class="layui-icon layui-icon-ok"></i></label></td>
<td th:text="${item.id}">充值ID</td>
<td th:text="${item.name}">充值名称</td>
<td th:text="${item.desc}">充值描述</td>
<td th:text="${item.price}">金额</td>
<td th:text="${item.givePrice}">赠送金额</td>
<td th:text="${item.rechargePrice}">充值到账金额</td>
<td th:text="${#dicts.rechargeType(item.type)}">类型</td>
<td th:text="${item.give}">赠送描述</td>
<td th:text="${item.createTime}">创建时间</td>
<td>
<a class="open-popup" data-title="编辑优惠券" th:attr="data-url=@{'/orders/recharge/edit/'+${item.id}}" data-size="auto" href="#">编辑</a>
<a class="ajax-get" data-msg="您是否确认删除" th:href="@{/orders/recharge/status/delete(ids=${item.id})}">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<div th:replace="/common/fragment :: page"></div>
</div>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body>
<div class="layui-form timo-compile">
<form th:action="@{/users/configs/save}">
<input type="hidden" name="id" th:if="${configs}" th:value="${configs.id}">
<div class="layui-form-item">
<label class="layui-form-label">配置名称</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="name" placeholder="请输入配置名称" th:value="${configs?.name}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">配置类型</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="configType" placeholder="请输入配置类型" th:value="${configs?.configType}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="content" placeholder="请输入内容" th:value="${configs?.content}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="sort" placeholder="请输入排序" th:value="${configs?.sort}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容类型</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="contentType" placeholder="请输入内容类型" th:value="${configs?.contentType}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">跳转类型</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="jumpType" placeholder="请输入跳转类型" th:value="${configs?.jumpType}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">跳转URL</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="jumpUrl" placeholder="请输入跳转URL" th:value="${configs?.jumpUrl}">
</div>
</div>
<div class="layui-form-item timo-finally">
<button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
<button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
</div>
</form>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body>
<div class="timo-detail-page">
<div class="timo-detail-title">基本信息</div>
<table class="layui-table timo-detail-table">
<colgroup>
<col width="100px"><col>
<col width="100px"><col>
</colgroup>
<tbody>
<tr>
<th>主键ID</th>
<td th:text="${configs.id}"></td>
<th>配置名称</th>
<td th:text="${configs.name}"></td>
</tr>
<tr>
<th>配置类型</th>
<td th:text="${configs.configType}"></td>
<th>内容</th>
<td th:text="${configs.content}"></td>
</tr>
<tr>
<th>排序</th>
<td th:text="${configs.sort}"></td>
<th>内容类型</th>
<td th:text="${configs.contentType}"></td>
</tr>
<tr>
<th>跳转类型</th>
<td th:text="${configs.jumpType}"></td>
<th>跳转URL</th>
<td th:text="${configs.jumpUrl}"></td>
</tr>
<tr>
<th>创建时间</th>
<td th:text="${#dates.format(configs.createDate, 'yyyy-MM-dd HH:mm:ss')}"></td>
<th>更新时间</th>
<td th:text="${#dates.format(configs.updateDate, 'yyyy-MM-dd HH:mm:ss')}"></td>
</tr>
</tbody>
</table>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:mo="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body class="timo-layout-page">
<div class="layui-card">
<div class="layui-card-header timo-card-header">
<span><i class="fa fa-bars"></i> systemConfig管理</span>
<i class="layui-icon layui-icon-refresh refresh-btn"></i>
</div>
<div class="layui-card-body">
<div class="layui-row timo-card-screen">
<div class="pull-left layui-form-pane timo-search-box">
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-block timo-search-status">
<select class="timo-search-select" name="status" mo:dict="SEARCH_STATUS" mo-selected="${param.status}"></select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">配置名称</label>
<div class="layui-input-block">
<input type="text" name="name" th:value="${param.name}" placeholder="请输入配置名称" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button class="layui-btn timo-search-btn">
<i class="fa fa-search"></i>
</button>
</div>
</div>
<div class="pull-right screen-btn-group">
<button class="layui-btn open-popup" data-title="添加systemConfig" th:attr="data-url=@{/users/configs/add}" data-size="auto">
<i class="fa fa-plus"></i> 添加</button>
<div class="btn-group">
<button class="layui-btn">操作<span class="caret"></span></button>
<dl class="layui-nav-child layui-anim layui-anim-upbit">
<dd><a class="ajax-status" th:href="@{/users/configs/status/ok}">启用</a></dd>
<dd><a class="ajax-status" th:href="@{/users/configs/status/freezed}">冻结</a></dd>
<dd><a class="ajax-status" th:href="@{/users/configs/status/delete}">删除</a></dd>
</dl>
</div>
</div>
</div>
<div class="timo-table-wrap">
<table class="layui-table timo-table">
<thead>
<tr>
<th class="timo-table-checkbox">
<label class="timo-checkbox"><input type="checkbox">
<i class="layui-icon layui-icon-ok"></i></label>
</th>
<th>主键ID</th>
<th>配置名称</th>
<th>配置类型</th>
<th>内容</th>
<th>排序</th>
<th>内容类型</th>
<th>跳转类型</th>
<th>跳转URL</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="item:${list}">
<td><label class="timo-checkbox"><input type="checkbox" th:value="${item.id}">
<i class="layui-icon layui-icon-ok"></i></label></td>
<td th:text="${item.id}">主键ID</td>
<td th:text="${item.name}">配置名称</td>
<td th:text="${item.configType}">配置类型</td>
<td th:text="${item.content}">内容</td>
<td th:text="${item.sort}">排序</td>
<td th:text="${item.contentType}">内容类型</td>
<td th:text="${item.jumpType}">跳转类型</td>
<td th:text="${item.jumpUrl}">跳转URL</td>
<td>
<a class="open-popup" data-title="编辑systemConfig" th:attr="data-url=@{'/users/configs/edit/'+${item.id}}" data-size="auto" href="#">编辑</a>
<a class="open-popup" data-title="详细信息" th:attr="data-url=@{'/users/configs/detail/'+${item.id}}" data-size="800,600" href="#">详细</a>
<a class="ajax-get" data-msg="您是否确认删除" th:href="@{/users/configs/status/delete(ids=${item.id})}">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<div th:replace="/common/fragment :: page"></div>
</div>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -84,14 +84,16 @@
</div>
</div>
<script th:replace="/common/template :: script"></script>
<script type="text/javascript">
layui.use(['laydate','form'], function () {
var laydate = layui.laydate;
// 渲染
laydate.render({
elem: '#birthday'
});
})
</script>
<script type="text/javascript">
layui.use(['laydate','form'], function () {
var laydate = layui.laydate;
// 渲染
laydate.render({
elem: '#birthday',
type: 'month',
format: 'MM'
});
})
</script>
</body>
</html>
@@ -60,6 +60,7 @@
<thead>
<tr>
<th>用户ID</th>
<th>邀请人ID</th>
<th>昵称</th>
<th>头像地址</th>
<th>余额</th>
@@ -68,6 +69,7 @@
<th>手机号</th>
<th>角色</th>
<th>用户宠物</th>
<th>优惠券</th>
<th>创建时间</th>
<th>用户操作</th>
</tr>
@@ -75,6 +77,7 @@
<tbody>
<tr th:each="item:${list}">
<td th:text="${item.id}">用户ID</td>
<td th:text="${item.inviteUserId}">邀请人ID</td>
<td th:text="${item.nickName}">昵称</td>
<td><img th:src="${item.headImgUrl}" alt="url" style="width: 100px; height: auto;"/> </td>
<td th:text="${item.amount == null ? 0 : item.amount / 10.0}">余额</td>
@@ -85,6 +88,9 @@
<td>
<a class="open-popup" data-title="宠物下单" th:attr="data-url=@{'/users/users/toPetInfos/'+${item.id}}" data-size="auto" href="#">宠物下单</a>
</td>
<td>
<a class="open-popup" data-title="优惠券列表" th:attr="data-url=@{'/users/users/toCouponsInfos/'+${item.id}}" data-size="auto" href="#">优惠券列表</a>
</td>
<td th:text="${item.createTime}">创建时间</td>
<td>
<a class="open-popup" data-title="充值" th:attr="data-url=@{'/users/users/toRecharge/'+${item.id}}" data-size="auto" href="#">充值</a>
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:mo="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
</head>
<body class="timo-layout-page">
<div class="layui-card">
<div class="layui-card-body">
<div class="timo-table-wrap">
<table class="layui-table timo-table">
<thead>
<tr>
<th>优惠券ID</th>
<th>优惠券名称</th>
<th>优惠券折扣</th>
<th>优惠券状态</th>
<th>过期时间</th>
<th>最后更新时间</th>
</tr>
</thead>
<tbody>
<tr th:each="item:${userCouponsList}">
<td th:text="${item.id}">优惠券ID</td>
<td th:text="${item.coupons.name}">优惠券名称</td>
<td th:text="${item.coupons.discount / 10.0}">优惠券折扣</td>
<td th:text="${#dicts.userCouponsStatus(item.couponsStatus)}">优惠券状态</td>
<td th:text="${item.lastExpireTime}">过期时间</td>
<td th:text="${item.updateTime}">最后更新时间</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<script th:replace="/common/template :: script"></script>
</body>
</html>
@@ -210,6 +210,54 @@ public class DictUtil {
String label = "GOODS_BUY_MANY";
return DictUtil.keyValue(label, String.valueOf(status));
}
/**
* 封装数据状态字典
* @param status 状态
*/
public static String goodsSubType(Byte status){
String label = "GOODS_SUB_TYPE";
return DictUtil.keyValue(label, String.valueOf(status));
}
/**
* 封装数据状态字典
* @param status 状态
*/
public static String periodType(Byte status){
String label = "PERIOD_TYPE";
return DictUtil.keyValue(label, String.valueOf(status));
}
/**
* 封装数据状态字典
* @param status 状态
*/
public static String couponsSendStatus(Byte status){
String label = "COUPONS_SEND_STATUS";
return DictUtil.keyValue(label, String.valueOf(status));
}
/**
* 封装数据状态字典
* @param status 状态
*/
public static String userCouponsStatus(Byte status){
String label = "USER_COUPONS_STATUS";
return DictUtil.keyValue(label, String.valueOf(status));
}
/**
* 封装数据状态字典
* @param status 状态
*/
public static String payOrderStatus(Byte status){
String label = "PAY_ORDER_STATUS";
return DictUtil.keyValue(label, String.valueOf(status));
}
/**
* 封装数据状态字典
* @param status 状态
*/
public static String rechargeType(Byte status){
String label = "RECHARGE_TYPE";
return DictUtil.keyValue(label, String.valueOf(status));
}
/**
* 清除缓存中指定的数据
@@ -74,43 +74,38 @@ public class UserServiceImpl implements UserService {
PageRequest page = PageSort.pageRequest(Sort.Direction.ASC);
// 使用Specification复杂查询
return userRepository.findAll(new Specification<User>(){
return userRepository.findAll((Specification<User>) (root, query, cb) -> {
List<Predicate> preList = new ArrayList<>();
if(user.getId() != null){
preList.add(cb.equal(root.get("id").as(Long.class), user.getId()));
}
if(user.getUsername() != null){
preList.add(cb.equal(root.get("username").as(String.class), user.getUsername()));
}
if(user.getNickname() != null){
preList.add(cb.like(root.get("nickname").as(String.class), "%"+ user.getNickname() + "%"));
}
if(user.getDept() != null){
// 联级查询部门
Dept dept = user.getDept();
List<Long> deptIn = new ArrayList<>();
deptIn.add(dept.getId());
List<Dept> deptList = deptService.getListByPidLikeOk(dept.getId());
deptList.forEach(item -> deptIn.add(item.getId()));
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> preList = new ArrayList<>();
if(user.getId() != null){
preList.add(cb.equal(root.get("id").as(Long.class), user.getId()));
}
if(user.getUsername() != null){
preList.add(cb.equal(root.get("username").as(String.class), user.getUsername()));
}
if(user.getNickname() != null){
preList.add(cb.like(root.get("nickname").as(String.class), "%"+ user.getNickname() + "%"));
}
if(user.getDept() != null){
// 联级查询部门
Dept dept = user.getDept();
List<Long> deptIn = new ArrayList<>();
deptIn.add(dept.getId());
List<Dept> deptList = deptService.getListByPidLikeOk(dept.getId());
deptList.forEach(item -> deptIn.add(item.getId()));
Join<User, Dept> join = root.join("dept", JoinType.INNER);
CriteriaBuilder.In<Long> in = cb.in(join.get("id").as(Long.class));
deptIn.forEach(in::value);
preList.add(in);
}
// 数据状态
if(user.getStatus() != null){
preList.add(cb.equal(root.get("status").as(Byte.class), user.getStatus()));
}
Predicate[] pres = new Predicate[preList.size()];
return query.where(preList.toArray(pres)).getRestriction();
Join<User, Dept> join = root.join("dept", JoinType.INNER);
CriteriaBuilder.In<Long> in = cb.in(join.get("id").as(Long.class));
deptIn.forEach(in::value);
preList.add(in);
}
// 数据状态
if(user.getStatus() != null){
preList.add(cb.equal(root.get("status").as(Byte.class), user.getStatus()));
}
Predicate[] pres = new Predicate[preList.size()];
return query.where(preList.toArray(pres)).getRestriction();
}, page);
}