店铺API

This commit is contained in:
墨大叔 2024-04-29 15:03:18 +08:00
parent b6209a326d
commit 9932c98745
35 changed files with 1034 additions and 308 deletions

View File

@ -1,5 +1,12 @@
package com.ruoyi.common.core.domain;
import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author wjh
* 2024/4/16
@ -31,7 +38,4 @@ public class BaseValidator {
}
return success();
}
}

View File

@ -5,7 +5,10 @@ package com.ruoyi.common.core.domain;
* 2024/4/15
*/
public interface JsonViewProfile {
interface Admin{} // 后台
interface App{} // 前台
interface Base{}
interface Admin extends Base {} // 后台
interface App extends Base {} // 前台
}

View File

@ -1,5 +1,7 @@
package com.ruoyi.common.core.domain;
import javax.validation.groups.Default;
/**
* Spring validate group
* @author
@ -8,19 +10,19 @@ package com.ruoyi.common.core.domain;
public interface ValidGroup {
// 新增
interface Create {}
interface Create extends Default {}
// 修改
interface Update {}
interface Update extends Default {}
// 查询
interface Query {}
interface Query extends Default {}
// 前台新增
interface FrontCreate {}
interface FrontCreate extends Default {}
// 前台更新
interface FrontUpdate {}
interface FrontUpdate extends Default {}
// 充值
interface Recharge {}

View File

@ -1,11 +1,14 @@
package com.ruoyi.common.core.page;
import com.fasterxml.jackson.annotation.JsonView;
import com.ruoyi.common.core.domain.JsonViewProfile;
import java.io.Serializable;
import java.util.List;
/**
* 表格分页数据对象
*
*
* @author ruoyi
*/
public class TableDataInfo implements Serializable
@ -13,15 +16,19 @@ public class TableDataInfo implements Serializable
private static final long serialVersionUID = 1L;
/** 总记录数 */
@JsonView(JsonViewProfile.Base.class)
private long total;
/** 列表数据 */
@JsonView(JsonViewProfile.Base.class)
private List<?> rows;
/** 消息状态码 */
@JsonView(JsonViewProfile.Base.class)
private int code;
/** 消息内容 */
@JsonView(JsonViewProfile.Base.class)
private String msg;
/**
@ -33,7 +40,7 @@ public class TableDataInfo implements Serializable
/**
* 分页
*
*
* @param list 列表数据
* @param total 总记录数
*/

View File

@ -0,0 +1,27 @@
package com.ruoyi.common.utils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author wjh
* 2024/4/29
*/
public class CollectionUtils extends org.springframework.util.CollectionUtils {
/**
* 是否为空包括空集合空元素
* @param list
* @return
*/
public static boolean isEmptyElement(List<?> list) {
if (list == null) {
return true;
}
// 过滤空元素
List<?> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
return org.springframework.util.CollectionUtils.isEmpty(collect);
}
}

View File

@ -0,0 +1,13 @@
package com.ruoyi.ss.device.domain;
import lombok.Data;
/**
* @author wjh
* 2024/4/29
*/
@Data
public class SmDeviceCountVO {
private Long storeId;
private Integer count;
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.ss.device.mapper;
import com.ruoyi.ss.device.domain.SmDevice;
import com.ruoyi.ss.device.domain.SmDeviceCountVO;
import com.ruoyi.ss.device.domain.SmDeviceQuery;
import com.ruoyi.ss.device.domain.SmDeviceVo;
import org.apache.ibatis.annotations.Param;
@ -109,4 +110,10 @@ public interface SmDeviceMapper
* @return
*/
SmDeviceVo selectSimpleSmDeviceByMac(String mac);
/**
* 根据店铺id列表查询设备数量
* @param storeIds 店铺id列表
*/
List<SmDeviceCountVO> selectCountByStoreIds(@Param("storeIds") List<Long> storeIds);
}

View File

@ -26,7 +26,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="tenantId != null"> and sdt.tenant_id = #{tenantId}</if>
<if test="isDefault != null"> and sdt.is_default = #{isDefault}</if>
<if test="tenantName != null">and su.nick_name like concat('%', #{tenantName}, '%')</if>
<if test="deleted != null">and sd.deleted = #{deleted}</if>
<if test="expireDay != null">and sd.expire_day = #{expireDay}</if>
<if test="deviceIds != null and deviceIds.size() > 0">
and sd.device_id in
@ -48,6 +47,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item}
</foreach>
</if>
<if test="deleted == null">and sd.deleted = false</if>
<if test="deleted != null">and sd.deleted = #{deleted}</if>
</sql>
<select id="selectTenantIds" resultType="java.lang.Long">
@ -87,7 +88,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join sm_store ss on ss.store_id = sd.store_id
<where>
<include refid="searchCondition"/>
and sd.deleted = false
</where>
group by sd.device_id
order by sd.create_time desc
@ -112,7 +112,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from sm_device sd
<where>
<include refid="searchCondition"/>
and sd.deleted = false
</where>
</select>
@ -130,6 +129,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where sd.mac = #{mac} and sd.deleted = false
</select>
<select id="selectCountByStoreIds" resultType="SmDeviceCountVO">
select
sd.store_id,
count(sd.device_id) as count
from sm_device sd
where sd.store_id in
<foreach collection="storeIds" open="(" close=")" separator="," item="item">
#{item}
</foreach>
and sd.deleted = false
</select>
<insert id="insertSmDevice" parameterType="SmDevice" useGeneratedKeys="true" keyProperty="deviceId">
<selectKey resultType="Long" order="AFTER" keyProperty="deviceId">
select LAST_INSERT_ID()

View File

@ -55,7 +55,7 @@ public class DeviceAssemblerImpl implements DeviceAssembler {
if (device.getUserId() != null && device.getStoreId() == null) {
StoreVo defaultStore = smDeviceGroupService.selectDefaultStore(device.getUserId());
if (defaultStore == null) {
defaultStore = smDeviceGroupService.insertDefaultStore(device.getUserId());
// defaultStore = smDeviceGroupService.insertDefaultStore(device.getUserId());
ServiceUtil.assertion(defaultStore == null, "该用户没有默认店铺");
}
device.setStoreId(defaultStore.getStoreId());

View File

@ -176,4 +176,10 @@ public interface ISmDeviceService
* ids查询列表
*/
List<SmDeviceVo> selectListByIds(List<Long> ids);
/**
* 查询各店铺的设备数量,并分组
* @param storeIds 店铺id
*/
Map<Long, Integer> selectCountMapByStoreIds(List<Long> storeIds);
}

View File

@ -6,6 +6,7 @@ import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.ss.device.domain.SmDevice;
import com.ruoyi.ss.device.domain.SmDeviceCountVO;
import com.ruoyi.ss.device.domain.SmDeviceQuery;
import com.ruoyi.ss.device.domain.SmDeviceVo;
import com.ruoyi.ss.device.domain.enums.DeviceOnlineStatus;
@ -32,7 +33,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.*;
@ -675,6 +675,23 @@ public class SmDeviceServiceImpl implements ISmDeviceService
return selectSmDeviceList(dto);
}
/**
* 查询各店铺的设备数量,并分组
*
* @param storeIds 店铺id
*/
@Override
public Map<Long, Integer> selectCountMapByStoreIds(List<Long> storeIds) {
if (CollectionUtils.isEmptyElement(storeIds)) {
return Collections.emptyMap();
}
List<SmDeviceCountVO> list = smDeviceMapper.selectCountByStoreIds(storeIds);
if (CollectionUtils.isEmpty(list)) {
return Collections.emptyMap();
}
return list.stream().collect(Collectors.toMap(SmDeviceCountVO::getStoreId, SmDeviceCountVO::getCount));
}
@Override
@Transactional
public boolean landlordUnbind(Long userId, Long deviceId) {

View File

@ -11,15 +11,18 @@ import com.ruoyi.ss.store.domain.enums.StoreType;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalTime;
/**
* 商户对象 sm_device_group
* 店铺对象 sm_device_group
*
* @author 邱贞招
* @date 2024-02-21
@ -30,14 +33,17 @@ public class Store extends BaseEntity
private static final long serialVersionUID = 1L;
/** id */
@ApiModelProperty("商户id")
@NotNull(message = "商户id不能为空", groups = {ValidGroup.Update.class})
@ApiModelProperty("店铺id")
@NotNull(message = "店铺id不能为空", groups = {ValidGroup.Update.class})
@JsonView({JsonViewProfile.App.class, StoreView.ListCount.class})
private Long storeId;
/** 商户名称 */
@Excel(name = "商户名称")
@ApiModelProperty("商户名称")
@NotNull(message = "商户名称不能为空", groups = {ValidGroup.Create.class})
/** 店铺名称 */
@Excel(name = "店铺名称")
@ApiModelProperty("店铺名称")
@NotNull(message = "店铺名称不能为空", groups = {ValidGroup.Create.class})
@Size(min = 1, max = 20, message = "店铺名称长度必须在1~60之间")
@JsonView({JsonViewProfile.App.class, StoreView.ListCount.class})
private String name;
/** 用户 */
@ -46,30 +52,39 @@ public class Store extends BaseEntity
@NotNull(message = "用户id不能为空", groups = {ValidGroup.Create.class})
private Long userId;
/** 商户图片 */
@Excel(name = "商户图片")
/** 店铺图片 */
@Excel(name = "店铺图片")
@JsonView(JsonViewProfile.App.class)
private String picture;
/** 门店地址 */
@Excel(name = "门店地址")
@NotNull(message = "门店地址不能为空", groups = {ValidGroup.Create.class})
@Size(min = 1, max = 200, message = "门店地址长度必须在1~200之间")
@JsonView(JsonViewProfile.App.class)
private String address;
/** 定位经度 */
@Excel(name = "定位经度")
@NotNull(message = "定位经度不能为空", groups = {ValidGroup.Create.class})
@Range(min = -180, max = 180, message = "定位经度必须在-180~180之间")
@JsonView(JsonViewProfile.App.class)
private BigDecimal lng;
/** 定位纬度 */
@Excel(name = "定位纬度")
@NotNull(message = "定位纬度不能为空", groups = {ValidGroup.Create.class})
@Range(min = -90, max = 90, message = "定位纬度必须在-90~90之间")
@JsonView(JsonViewProfile.App.class)
private BigDecimal lat;
/** 设备排序 */
@ApiModelProperty("设备排序,越小越靠前")
@ApiModelProperty("店铺排序,越小越靠前")
@JsonView(StoreView.ListCount.class)
private Integer groupSort;
@ApiModelProperty("是否默认")
@JsonView(StoreView.ListCount.class)
private Boolean isDefault;
/** 营业时间起始 */
@ -77,6 +92,7 @@ public class Store extends BaseEntity
@DateTimeFormat(pattern = "HH:mm")
@JsonFormat(pattern = "HH:mm", timezone = "GMT+8")
@NotNull(message = "营业时间起始不能为空", groups = {ValidGroup.Create.class})
@JsonView(JsonViewProfile.App.class)
private LocalTime businessTimeStart;
/** 营业时间结束 */
@ -84,26 +100,34 @@ public class Store extends BaseEntity
@DateTimeFormat(pattern = "HH:mm")
@JsonFormat(pattern = "HH:mm", timezone = "GMT+8")
@NotNull(message = "营业时间结束不能为空", groups = {ValidGroup.Create.class})
@JsonView(JsonViewProfile.App.class)
private LocalTime businessTimeEnd;
/** 省 */
@Excel(name = "")
@NotNull(message = "省不能为空", groups = {ValidGroup.Create.class})
@Size(min = 1, max = 30, message = "省长度必须在1~30之间")
@JsonView(JsonViewProfile.App.class)
private String province;
/** 市 */
@Excel(name = "")
@NotNull(message = "市不能为空", groups = {ValidGroup.Create.class})
@Size(min = 1, max = 60, message = "市长度必须在1~60之间")
@JsonView(JsonViewProfile.App.class)
private String city;
/** 区县 */
@Excel(name = "区县")
@NotNull(message = "区县不能为空", groups = {ValidGroup.Create.class})
@Size(min = 1, max = 60, message = "区县长度必须在1~60之间")
@JsonView(JsonViewProfile.App.class)
private String county;
/** 详细地址 */
@Excel(name = "详细地址")
@Size(max = 200, message = "详细地址长度不能超过200个字符")
@JsonView(JsonViewProfile.App.class)
private String specificAddress;
@Excel(name = "店铺类型")
@ -111,7 +135,8 @@ public class Store extends BaseEntity
@NotNull(message = "店铺类型不允许为空", groups = {ValidGroup.Create.class})
@EnumValid(
clazz = StoreType.class,
message = "非法的店铺类型"
message = "非法的店铺类型",
method = "getType"
)
private String type;

View File

@ -0,0 +1,80 @@
package com.ruoyi.ss.store.domain;
import java.math.BigDecimal;
import java.util.Date;
import java.time.LocalTime;
import com.google.common.collect.Maps;
import lombok.Data;
/**
* @author wjh
* 2024/4/29
*/
@Data
public class StoreBO extends Store {
/**
* 过滤前台更新字段
*/
public StoreBO filterUpdateByApp() {
StoreBO bo = new StoreBO();
bo.setStoreId(getStoreId());
bo.setName(getName());
bo.setPicture(getPicture());
bo.setAddress(getAddress());
bo.setLng(getLng());
bo.setLat(getLat());
bo.setBusinessTimeStart(getBusinessTimeStart());
bo.setBusinessTimeEnd(getBusinessTimeEnd());
bo.setProvince(getProvince());
bo.setCity(getCity());
bo.setCounty(getCounty());
bo.setSpecificAddress(getSpecificAddress());
bo.setType(getType());
return bo;
}
/**
* 过滤前台创建字段
*/
public StoreBO filterCreateByApp() {
StoreBO bo = new StoreBO();
bo.setStoreId(getStoreId());
bo.setName(getName());
bo.setPicture(getPicture());
bo.setAddress(getAddress());
bo.setLng(getLng());
bo.setLat(getLat());
bo.setBusinessTimeStart(getBusinessTimeStart());
bo.setBusinessTimeEnd(getBusinessTimeEnd());
bo.setProvince(getProvince());
bo.setCity(getCity());
bo.setCounty(getCounty());
bo.setSpecificAddress(getSpecificAddress());
bo.setType(getType());
return bo;
}
/**
* 过滤后台更新字段
*/
public StoreBO filterUpdate() {
StoreBO bo = new StoreBO();
bo.setStoreId(getStoreId());
bo.setName(getName());
bo.setUserId(getUserId());
bo.setPicture(getPicture());
bo.setAddress(getAddress());
bo.setLng(getLng());
bo.setLat(getLat());
bo.setBusinessTimeStart(getBusinessTimeStart());
bo.setBusinessTimeEnd(getBusinessTimeEnd());
bo.setProvince(getProvince());
bo.setCity(getCity());
bo.setCounty(getCounty());
bo.setSpecificAddress(getSpecificAddress());
bo.setType(getType());
return bo;
}
}

View File

@ -1,16 +1,33 @@
package com.ruoyi.ss.store.domain;
import com.ruoyi.common.core.domain.ValidGroup;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
import java.util.List;
/**
* 2024/4/27
*
* @author wjh
*/
@Data
public class StoreQuery extends Store{
public class StoreQuery extends Store {
@ApiModelProperty("用户名称")
private String userName;
@ApiModelProperty("当前所在位置")
@Size(min = 2, max = 2, message = "当前位置必须传入经度和纬度两个值", groups = {ValidGroup.Query.class})
private List<BigDecimal> center;
@ApiModelProperty("查询半径(米)")
@Min(value = 0, message = "半径不允许小于0", groups = {ValidGroup.Query.class})
private BigDecimal radius;
@ApiModelProperty("店铺id列表")
private List<Long> storeIds;
}

View File

@ -0,0 +1,11 @@
package com.ruoyi.ss.store.domain;
/**
* @author wjh
* 2024/4/29
*/
public interface StoreView {
interface ListCount {}
}

View File

@ -15,6 +15,7 @@ import lombok.EqualsAndHashCode;
public class StoreVo extends Store {
@ApiModelProperty("该店铺下的设备数量")
@JsonView(StoreView.ListCount.class)
private Integer deviceCount;
@ApiModelProperty("绑定用户名称")

View File

@ -1,6 +1,7 @@
package com.ruoyi.ss.store.mapper;
import com.ruoyi.ss.store.domain.Store;
import com.ruoyi.ss.store.domain.StoreQuery;
import com.ruoyi.ss.store.domain.StoreVo;
import org.apache.ibatis.annotations.Param;
@ -17,10 +18,10 @@ public interface StoreMapper
/**
* 查询商户
*
* @param groupId 商户主键
* @param storeId 商户主键
* @return 商户
*/
public StoreVo selectSmStoreById(Long groupId);
public StoreVo selectSmStoreById(Long storeId);
/**
* 查询商户列表
@ -49,18 +50,18 @@ public interface StoreMapper
/**
* 删除商户
*
* @param groupId 商户主键
* @param storeId 商户主键
* @return 结果
*/
public int deleteSmStoreById(Long groupId);
public int deleteSmStoreById(Long storeId);
/**
* 批量删除商户
*
* @param groupIds 需要删除的数据主键集合
* @param storeIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteSmStoreByIds(Long[] groupIds);
public int deleteSmStoreByIds(Long[] storeIds);
/**
* 修改数据的排序
@ -72,10 +73,10 @@ public interface StoreMapper
/**
* 根据id列表查询数据
* @param groupIds
* @param storeIds
* @return
*/
List<StoreVo> selectSmStoreByIds(@Param("groupIds") List<Long> groupIds);
List<StoreVo> selectSmStoreByIds(@Param("storeIds") List<Long> storeIds);
/**
* 批量更新
@ -90,4 +91,25 @@ public interface StoreMapper
* @return
*/
int logicDel(@Param("ids") List<Long> ids);
/**
* 查询数量
* @param query
* @return
*/
int selectCount(StoreQuery query);
/**
* 将店铺设为默认店铺
* @param userId 用户id
* @param storeId 店铺id
*/
void setDefault(@Param("userId") Long userId, @Param("storeId") Long storeId);
/**
* 查询一个
* @param query
* @return
*/
StoreVo selectOne(StoreQuery query);
}

View File

@ -44,6 +44,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deleted != null "> and ss.deleted = #{deleted}</if>
<if test="deleted == null "> and ss.deleted = false</if>
<if test="userName != null "> and su.user_name like concat('%', #{userName}, '%')</if>
<if test="center != null and center.size() == 2 and radius != null">
and #{radius} >= round(st_distance_sphere(point(#{center[0]}, #{center[1]}), point(ss.lng, ss.lat)))
</if>
<if test="storeIds != null and storeIds.size() > 0">
and ss.store_id in
<foreach collection="storeIds" close=")" item="item" open="(" separator=",">
#{item}
</foreach>
</if>
</sql>
<select id="selectSmStoreList" parameterType="StoreQuery" resultMap="SmStoreResult">
@ -68,8 +77,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and ss.deleted = false
</select>
<select id="selectCount" resultType="java.lang.Integer">
select count(ss.store_id)
from sm_store ss
<where>
<include refid="searchCondition"/>
</where>
</select>
<select id="selectOne" resultMap="SmStoreResult">
<include refid="selectSmStoreVo"/>
<where>
<include refid="searchCondition"/>
</where>
order by ss.group_sort asc, ss.create_time asc
limit 1
</select>
<insert id="insertSmStore" parameterType="Store" useGeneratedKeys="true" keyProperty="storeId">
<selectKey keyProperty="storeId" resultType="Long">
<selectKey keyProperty="storeId" resultType="Long" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
insert into sm_store
@ -188,6 +214,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</update>
<update id="setDefault">
update sm_store
set is_default = if(store_id = #{storeId}, true, false)
where user_id = #{userId}
</update>
<delete id="deleteSmStoreById" parameterType="Long">
delete from sm_store where store_id = #{storeId}
</delete>

View File

@ -28,7 +28,7 @@ public interface IStoreService
* @param store 商户
* @return 商户集合
*/
public List<StoreVo> selectSmStore(StoreQuery store);
public List<StoreVo> selectSmStoreList(StoreQuery store);
/**
* 新增商户
@ -46,22 +46,6 @@ public interface IStoreService
*/
public int updateSmStore(Store store);
/**
* 批量删除商户
*
* @param groupIds 需要删除的商户主键集合
* @return 结果
*/
public int deleteSmStoreByIds(Long[] groupIds);
/**
* 删除商户信息
*
* @param groupId 商户主键
* @return 结果
*/
public int deleteSmStoreById(Long groupId);
/**
* 调整商户位置
* @param list 调整后的商户列表
@ -73,7 +57,7 @@ public interface IStoreService
* @param store 查询条件
* @return 设备列表
*/
List<StoreVo> listCount(Store store);
List<StoreVo> listCount(StoreQuery store);
/**
* 查询用户的默认商户
@ -81,16 +65,29 @@ public interface IStoreService
*/
StoreVo selectDefaultStore(Long userId);
/**
* 为用户创建一个默认的商户
* @param userId
* @return
*/
StoreVo insertDefaultStore(Long userId);
/**
* ids逻辑删除
* @param ids id列表
*/
int logicDel(List<Long> ids);
/**
* 查询附近的店铺
* @param query
* @return
*/
List<StoreVo> listNearBy(StoreQuery query);
/**
* ids查询查询列表
* @param storeIds
* @return
*/
List<StoreVo> selectStoreByIds(List<Long> storeIds);
/**
* 查询数量
* @param query 查询条件
*/
int selectCount(StoreQuery query);
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.ss.store.service;
import com.ruoyi.ss.store.domain.Store;
import com.ruoyi.ss.store.domain.StoreVo;
import java.util.List;
/**
* @author wjh
* 2024/4/29
*/
public interface StoreAssembler {
/**
* 拼接设备数量
* @param list 店铺列表
*/
void assembleDeviceCount(List<StoreVo> list);
}

View File

@ -1,6 +1,8 @@
package com.ruoyi.ss.store.service;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.ss.store.domain.Store;
import com.ruoyi.ss.store.domain.StoreBO;
import java.util.List;
@ -17,9 +19,57 @@ public interface StoreValidator {
*/
ValidateResult preLogicDel(List<Long> ids);
/**
* 前台逻辑删除前校验
* @param storeIds 店铺id列表
*/
ValidateResult preLogicDelByApp(List<Long> storeIds);
/**
* 更新前校验
* @param data 数据
*/
ValidateResult preUpdate(Store data);
/**
* 创建前校验
* @param data 数据
*/
ValidateResult preCreate(Store data);
/**
* 前台创建前校验
* @param data 数据
*/
ValidateResult preCreateByApp(Store data);
/**
* 前台更新前校验
* @param data
* @return
*/
ValidateResult preUpdateByApp(Store data);
/**
* 排序前校验
* @param list 排序列表
*/
ValidateResult preChangeSortByApp(List<Store> list);
/**
* 判断店铺是否存在设备
* @param ids 店铺id列表
*/
boolean hasDevice(List<Long> ids);
/**
* 判断店铺是否属于用户
*/
boolean isStoreBelongUser(List<Long> storeId, Long userId);
/**
* 判断店铺是否存在
* @param storeIds
*/
boolean isExistStore(List<Long> storeIds);
}

View File

@ -0,0 +1,41 @@
package com.ruoyi.ss.store.service.impl;
import com.ruoyi.common.utils.CollectionUtils;
import com.ruoyi.ss.device.service.ISmDeviceService;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.service.StoreAssembler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author wjh
* 2024/4/29
*/
@Service
public class StoreAssemblerImpl implements StoreAssembler {
@Autowired
private ISmDeviceService deviceService;
/**
* 拼接设备数量
*
* @param list 店铺列表
*/
@Override
public void assembleDeviceCount(List<StoreVo> list) {
if (CollectionUtils.isEmptyElement(list)) {
return;
}
Map<Long, Integer> countMap = deviceService.selectCountMapByStoreIds(list.stream().map(StoreVo::getStoreId).collect(Collectors.toList()));
for (StoreVo store : list) {
Integer count = countMap.get(store.getStoreId());
store.setDeviceCount(count == null ? 0 : count);
}
}
}

View File

@ -1,33 +1,33 @@
package com.ruoyi.ss.store.service.impl;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.LoginType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.device.domain.SmDeviceQuery;
import com.ruoyi.ss.device.domain.SmDeviceVo;
import com.ruoyi.ss.device.service.ISmDeviceService;
import com.ruoyi.ss.store.domain.Store;
import com.ruoyi.ss.store.domain.StoreQuery;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.mapper.StoreMapper;
import com.ruoyi.ss.store.service.IStoreService;
import com.ruoyi.ss.store.service.StoreAssembler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.ruoyi.common.utils.CollectionUtils;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.*;
import java.util.stream.Collectors;
/**
* 设备分组Service业务层处理
* 店铺Service业务层处理
*
* @author 邱贞招
* @date 2024-02-21
*/
@Service
@Slf4j
public class StoreServiceImpl implements IStoreService
{
@Autowired
@ -36,11 +36,17 @@ public class StoreServiceImpl implements IStoreService
@Autowired
private ISmDeviceService smDeviceService;
@Autowired
private StoreAssembler storeAssembler;
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 查询设备分组
* 查询店铺
*
* @param storeId 设备分组主键
* @return 设备分组
* @param storeId 店铺主键
* @return 店铺
*/
@Override
public StoreVo selectSmStoreById(Long storeId)
@ -49,94 +55,64 @@ public class StoreServiceImpl implements IStoreService
}
/**
* 查询设备分组列表
* 查询店铺列表
*
* @param store 设备分组
* @return 设备分组
* @param store 店铺
* @return 店铺
*/
@Override
public List<StoreVo> selectSmStore(StoreQuery store)
public List<StoreVo> selectSmStoreList(StoreQuery store)
{
return storeMapper.selectSmStoreList(store);
}
/**
* 新增设备分组
* 新增店铺
*
* @param store 设备分组
* @param store 店铺
* @return 结果
*/
@Override
public int insertSmStore(Store store)
{
store.setCreateTime(DateUtils.getNowDate());
return storeMapper.insertSmStore(store);
}
store.setCreateBy(SecurityUtils.getUsername());
transactionTemplate.execute(status -> {
// 新增店铺
int i = storeMapper.insertSmStore(store);
ServiceUtil.assertion(i != 1, "新增店铺失败");
// 如果没有默认店铺则将其设为默认店铺
if (this.selectDefaultStore(store.getUserId()) == null) {
storeMapper.setDefault(store.getUserId(), store.getStoreId());
}
return Boolean.TRUE;
});
return 1;
}
/**
* 修改设备分组
* 修改店铺
*
* @param store 设备分组
* @param store 店铺
* @return 结果
*/
@Override
public int updateSmStore(Store store)
{
this.validate(Collections.singletonList(store), true);
store.setUpdateTime(DateUtils.getNowDate());
store.setUpdateBy(SecurityUtils.getUsername());
return storeMapper.updateSmStore(store);
}
/**
* 批量删除设备分组
*
* @param storeIds 需要删除的设备分组主键
* @return 结果
*/
@Override
public int deleteSmStoreByIds(Long[] storeIds)
{
this.validatePreDelete(Arrays.asList(storeIds));
return storeMapper.deleteSmStoreByIds(storeIds);
}
/**
* 删除设备分组信息
*
* @param storeId 设备分组主键
* @return 结果
*/
@Override
@Transactional
public int deleteSmStoreById(Long storeId) {
// 删除校验
this.validatePreDelete(storeId);
// 删除分组
return storeMapper.deleteSmStoreById(storeId);
}
/**
* 校验数据
*/
private void validate(List<Store> list, boolean update) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (LoginType.FRONT.equals(loginUser.getLoginType())) {
if (update) {
List<StoreVo> stores = storeMapper.selectSmStoreByIds(list.stream().map(Store::getStoreId).distinct().collect(Collectors.toList()));
Long userId = SecurityUtils.getUserId();
stores.forEach(item -> {
ServiceUtil.assertion(!Objects.equals(item.getUserId(), userId), String.format("存在不属于您的分组:%s", item.getName()));
});
}
}
}
@Override
@Transactional
public boolean changeSort(List<Store> list) {
ServiceUtil.assertion(CollectionUtils.isEmpty(list), "修改排序的列表不允许为空");
this.validate(list, true);
if (list == null) {
return true;
}
List<Store> updateList = new ArrayList<>();
for (Store item : list) {
Store store = new Store();
@ -149,20 +125,23 @@ public class StoreServiceImpl implements IStoreService
}
@Override
public List<StoreVo> listCount(Store store) {
public List<StoreVo> listCount(StoreQuery query) {
List<StoreVo> list = new ArrayList<>();
// 查询全部设备数据
SmDeviceQuery deviceDto = new SmDeviceQuery();
deviceDto.setUserId(store.getUserId());
deviceDto.setUserId(query.getUserId());
int count = smDeviceService.selectCount(deviceDto);
StoreVo all = new StoreVo();
all.setDeviceCount(count);
all.setName("全部");
list.add(all);
// 查询各各分组的设备数据
list.addAll(storeMapper.selectSmStoreList(store));
// 查询各各店铺的设备数据
List<StoreVo> storeList = storeMapper.selectSmStoreList(query);
storeAssembler.assembleDeviceCount(storeList);
list.addAll(storeList);
return list;
}
@ -174,26 +153,13 @@ public class StoreServiceImpl implements IStoreService
StoreQuery dto = new StoreQuery();
dto.setIsDefault(true);
dto.setUserId(userId);
List<StoreVo> list = selectSmStore(dto);
List<StoreVo> list = selectSmStoreList(dto);
if (CollectionUtils.isEmpty(list)) {
return null;
}
return list.get(0);
}
@Override
@Transactional
public StoreVo insertDefaultStore(Long userId) {
StoreVo store = new StoreVo();
store.setUserId(userId);
store.setName("未分组");
store.setGroupSort(1);
store.setIsDefault(true);
if (this.insertSmStore(store) == 1) {
return store;
}
return null;
}
/**
* ids逻辑删除
@ -202,32 +168,72 @@ public class StoreServiceImpl implements IStoreService
*/
@Override
public int logicDel(List<Long> ids) {
return storeMapper.logicDel(ids);
}
private void validatePreDelete(List<Long> storeIds) {
if (!CollectionUtils.isEmpty(storeIds)) {
for (Long storeId : storeIds) {
this.validatePreDelete(storeId);
if (CollectionUtils.isEmptyElement(ids)) {
log.warn("ids is empty");
return 0;
}
Integer result = transactionTemplate.execute(status -> {
// 若删除的包含默认店铺则将默认店铺设置为第一个店铺
StoreQuery query = new StoreQuery();
query.setStoreIds(ids);
query.setIsDefault(true);
List<StoreVo> defaultList = selectSmStoreList(query);
if (!CollectionUtils.isEmptyElement(defaultList)) {
// 包含默认店铺则查询第一个店铺
query = new StoreQuery();
query.setUserId(defaultList.get(0).getUserId());
StoreVo other = storeMapper.selectOne(query);
if (other != null) {
// 其他店铺不为空则设置为第一个店铺
storeMapper.setDefault(other.getUserId(), other.getStoreId());
}
}
}
// 执行逻辑删除
return storeMapper.logicDel(ids);
});
return result == null ? 0 : result;
}
// 删除校验
private void validatePreDelete(Long storeId) {
Store dto = new Store();
if (LoginType.FRONT.equals(SecurityUtils.getLoginType())) {
// 前台用户判断是不是他的分组
dto.setUserId(SecurityUtils.getUserId());
/**
* 查询附近的店铺
*
* @param query
* @return
*/
@Override
public List<StoreVo> listNearBy(StoreQuery query) {
if (query == null) {
return Collections.emptyList();
}
StoreVo store = storeMapper.selectSmStoreById(storeId);
ServiceUtil.assertion(store == null, "分组不存在,请刷新后重试");
ServiceUtil.assertion(store.getIsDefault(), "默认分组不允许删除");
// 查询分组下是否含有设备
List<SmDeviceVo> deviceList = smDeviceService.selectSmDeviceByStoreId(storeId);
ServiceUtil.assertion(!CollectionUtils.isEmpty(deviceList), "该分组下存在设备,不允许删除");
if (CollectionUtils.isEmpty(query.getCenter())) {
return Collections.emptyList();
}
return this.selectSmStoreList(query);
}
/**
* ids查询查询列表
*
* @param storeIds
* @return
*/
@Override
public List<StoreVo> selectStoreByIds(List<Long> storeIds) {
if (CollectionUtils.isEmpty(storeIds)) {
return Collections.emptyList();
}
return storeMapper.selectSmStoreByIds(storeIds);
}
/**
* 查询数量
*
* @param query 查询条件
*/
@Override
public int selectCount(StoreQuery query) {
return storeMapper.selectCount(query);
}
}

View File

@ -2,15 +2,25 @@ package com.ruoyi.ss.store.service.impl;
import com.ruoyi.common.core.domain.BaseValidator;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.common.utils.CollectionUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.ss.device.domain.SmDeviceQuery;
import com.ruoyi.ss.device.service.ISmDeviceService;
import com.ruoyi.ss.store.domain.Store;
import com.ruoyi.ss.store.domain.StoreQuery;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.service.IStoreService;
import com.ruoyi.ss.store.service.StoreValidator;
import com.ruoyi.ss.user.service.UserValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalTime;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 2024/4/27
@ -26,13 +36,16 @@ public class StoreValidatorImpl extends BaseValidator implements StoreValidator
@Autowired
private ISmDeviceService deviceService;
@Autowired
private UserValidator userValidator;
/**
* 逻辑删除前校验
* @param ids 店铺id列表
*/
@Override
public ValidateResult preLogicDel(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
if (CollectionUtils.isEmptyElement(ids)) {
return error("id列表不能为空");
}
@ -44,17 +57,195 @@ public class StoreValidatorImpl extends BaseValidator implements StoreValidator
return success();
}
/**
* 前台逻辑删除前校验
*
* @param storeIds 店铺id列表
*/
@Override
public ValidateResult preLogicDelByApp(List<Long> storeIds) {
// 基础校验
this.preLogicDel(storeIds);
if (!this.isStoreBelongUser(storeIds, SecurityUtils.getUserId())) {
return error("当前店铺不属于当前用户");
}
return success();
}
/**
* 更新前校验
*
* @param data 数据
*/
@Override
public ValidateResult preUpdate(Store data) {
if (data == null) {
return error("数据不能为空");
}
// 判断营业时间是否符合条件
ValidateResult validateBusinessTimeResult = this.validateBusinessTime(data.getBusinessTimeStart(), data.getBusinessTimeEnd());
if (validateBusinessTimeResult.isError()) {
return validateBusinessTimeResult;
}
if (!this.isExistStore(Collections.singletonList(data.getStoreId()))) {
return error("店铺不存在");
}
if (data.getUserId() != null && !userValidator.isExistUser(Collections.singletonList(data.getUserId()))) {
return error("用户不存在");
}
return success();
}
/**
* 创建前校验
*
* @param data 数据
*/
@Override
public ValidateResult preCreate(Store data) {
if (data == null) {
return error("数据不能为空");
}
// 判断营业时间是否符合条件
ValidateResult validateBusinessTimeResult = this.validateBusinessTime(data.getBusinessTimeStart(), data.getBusinessTimeEnd());
if (validateBusinessTimeResult.isError()) {
return validateBusinessTimeResult;
}
if (!userValidator.isExistUser(Collections.singletonList(data.getUserId()))) {
return error("用户不存在");
}
return success();
}
/**
* 前台创建前校验
*
* @param data 数据
*/
@Override
public ValidateResult preCreateByApp(Store data) {
ValidateResult result = this.preCreate(data);
if (result.isError()) {
return result;
}
return success();
}
/**
* 前台更新前校验
*
* @param data
* @return
*/
@Override
public ValidateResult preUpdateByApp(Store data) {
// 公共更新校验
ValidateResult result = this.preUpdate(data);
if (result.isError()) {
return result;
}
// 前台用户更新校验
// 判断是否是当前用户的店铺
if (!this.isStoreBelongUser(Collections.singletonList(data.getStoreId()), SecurityUtils.getUserId())) {
return error("当前店铺不属于当前用户");
}
return success();
}
/**
* 排序前校验
* @param list 排序列表
*/
@Override
public ValidateResult preChangeSortByApp(List<Store> list) {
if (CollectionUtils.isEmptyElement(list)) {
return error("数据不能为空");
}
List<Long> storeIds = list.stream().map(Store::getStoreId).collect(Collectors.toList());
if (!this.isExistStore(storeIds)) {
return error("店铺不存在,请刷新后重试");
}
if (!this.isStoreBelongUser(storeIds, SecurityUtils.getUserId())) {
return error("存在店铺不属于当前用户");
}
return success();
}
/**
* 判断店铺是否存在设备
* @param ids 店铺id列表
*/
@Override
public boolean hasDevice(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)) {
if (CollectionUtils.isEmptyElement(ids)) {
return false;
}
SmDeviceQuery query = new SmDeviceQuery();
query.setStoreIds(ids);
return deviceService.selectCount(query) > 0;
}
/**
* 判断店铺是否属于用户
*/
@Override
public boolean isStoreBelongUser(List<Long> storeIds, Long userId) {
List<StoreVo> stores = storeService.selectStoreByIds(storeIds);
for (StoreVo item : stores) {
if (!Objects.equals(item.getUserId(), userId)) {
return false;
}
}
return true;
}
/**
* 判断店铺是否存在
*
* @param storeIds
*/
@Override
public boolean isExistStore(List<Long> storeIds) {
if (CollectionUtils.isEmptyElement(storeIds)) {
return true;
}
StoreQuery query = new StoreQuery();
query.setStoreIds(storeIds);
int count = storeService.selectCount(query);
return count == new HashSet<Long>(storeIds).size();
}
/**
* 校验时间是符合规则
*/
private ValidateResult validateBusinessTime(LocalTime start, LocalTime end) {
if (start != null || end != null) {
// 不允许只传入一个值要么都有要么都没有
if (start == null || end == null) {
return error("不允许单独设置营业时间的起始或结束");
}
// 判断起始时间是否在结束时间前
if (start.isAfter(end)) {
return error("营业时间(起始)不允许晚于营业时间(结束)");
}
}
return success();
}
}

View File

@ -124,4 +124,7 @@ public class SmTransactionBill extends BaseEntity
@ApiModelProperty("设备充值状态0未充值1充值成功")
private String deviceRechargeStatus;
@ApiModelProperty("套餐id")
private String suitId;
}

View File

@ -12,11 +12,14 @@ import lombok.Data;
@Data
public class SmTransactionBillVo extends SmTransactionBill {
@ApiModelProperty("用户名称")
private String userName; // 用户名称
private String userName;
@ApiModelProperty("房东(到账用户)名称")
private String landlordName; // 房东到账用户名称
private String landlordName;
@ApiModelProperty("设备名称")
private String deviceName; // 设备名称
private String deviceName;
@ApiModelProperty("套餐名称")
private String suitName;
}

View File

@ -4,32 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.ss.transactionBill.mapper.SmTransactionBillMapper">
<resultMap type="SmTransactionBillVo" id="SmTransactionBillResult">
<result property="billId" column="bill_id" />
<result property="userId" column="user_id" />
<result property="type" column="type" />
<result property="deviceId" column="device_id" />
<result property="landlordId" column="landlord_id" />
<result property="money" column="money" />
<result property="arrivalAmount" column="arrival_amount" />
<result property="serviceCharge" column="service_charge" />
<result property="createTime" column="create_time" />
<result property="remark" column="remark" />
<result property="userName" column="user_name" />
<result property="unitPrice" column="unit_price" />
<result property="landlordName" column="landlord_name" />
<result property="deviceName" column="device_name"/>
<result property="status" column="status"/>
<result property="payType" column="pay_type"/>
<result property="afterBalance" column="after_balance"/>
<result property="payTime" column="pay_time"/>
<result property="billNo" column="bill_no"/>
<result property="deviceAmount" column="device_amount"/>
<result property="expireTime" column="expire_time"/>
<result property="accountNo" column="account_no"/>
<result property="payedAmount" column="payed_amount"/>
<result property="channelCost" column="channel_cost"/>
<result property="deviceRechargeStatus" column="device_recharge_status"/>
<resultMap type="SmTransactionBillVo" id="SmTransactionBillResult" autoMapping="true">
<result property="transferIds" column="transfer_ids" typeHandler="com.ruoyi.system.mapper.typehandler.StringListTypeHandler"/>
</resultMap>
@ -57,6 +32,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
stb.transfer_ids,
stb.channel_cost,
stb.device_recharge_status,
stb.suit_id,
ss.name as suit_name,
su.user_name user_name,
su1.user_name landlord_name,
sd.device_name device_name
@ -64,6 +41,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join sm_user su on su.user_id = stb.user_id
left join sm_user su1 on su1.user_id = stb.landlord_id
left join sm_device sd on sd.device_id = stb.device_id
left join sm_suit ss on ss.suit_id = stb.suit_id
</sql>
<sql id="searchCondition">
@ -84,6 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="startDate != null"> and date(stb.create_time) >= date(#{startDate}) </if>
<if test="endDate != null"> and date(stb.create_time) &lt;= date(#{endDate}) </if>
<if test="deviceRechargeStatus != null"> and stb.device_recharge_status = #{deviceRechargeStatus} </if>
<if test="suitId != null"> and stb.suit_id = #{suitId} </if>
</sql>
<select id="selectSmTransactionBillList" parameterType="SmTransactionBillQuery" resultMap="SmTransactionBillResult">
@ -166,7 +145,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createTime != null">create_time,</if>
<if test="remark != null">remark,</if>
<if test="unitPrice != null ">unit_price,</if>
<if test="status != null ">status,</if>
<if test="status != null ">`status`,</if>
<if test="payType != null ">pay_type,</if>
<if test="afterBalance != null ">after_balance,</if>
<if test="payTime != null ">pay_time,</if>
@ -177,6 +156,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="transferIds != null ">transfer_ids,</if>
<if test="channelCost != null ">channel_cost,</if>
<if test="deviceRechargeStatus != null ">device_recharge_status,</if>
<if test="suitId != null ">suit_id,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="billNo != null">#{billNo},</if>
@ -201,6 +181,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="transferIds != null">#{transferIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringListTypeHandler},</if>
<if test="channelCost != null">#{channelCost},</if>
<if test="deviceRechargeStatus != null">#{deviceRechargeStatus},</if>
<if test="suitId != null">#{suitId},</if>
</trim>
</insert>
@ -216,7 +197,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="serviceCharge != null">service_charge = #{serviceCharge},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="status != null">status = #{status},</if>
<if test="status != null">`status` = #{status},</if>
<if test="payType != null">pay_type = #{payType},</if>
<if test="afterBalance != null">after_balance = #{afterBalance},</if>
<if test="payTime != null">pay_time = #{payTime},</if>
@ -226,6 +207,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="payedAmount != null">payed_amount = #{payedAmount},</if>
<if test="transferIds != null">transfer_ids = #{transferIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringListTypeHandler},</if>
<if test="channelCost != null">channel_cost = #{channelCost},</if>
<if test="suitId != null">suit_id = #{suitId},</if>
</trim>
where bill_id = #{billId}
</update>

View File

@ -0,0 +1,17 @@
package com.ruoyi.ss.user.service;
import java.util.List;
/**
* @author wjh
* 2024/4/29
*/
public interface UserValidator {
/**
* 判断用户是否存在
* @param userIds 用户id列表
*/
boolean isExistUser(List<Long> userIds);
}

View File

@ -1,4 +1,4 @@
package com.ruoyi.ss.user.service;
package com.ruoyi.ss.user.service.impl;
import com.ruoyi.common.core.domain.entity.SmUser;
import com.ruoyi.common.enums.UserType;
@ -8,6 +8,7 @@ import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.user.domain.SmUserQuery;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.mapper.SmUserMapper;
import com.ruoyi.ss.user.service.ISmUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@ -0,0 +1,39 @@
package com.ruoyi.ss.user.service.impl;
import com.ruoyi.common.core.domain.BaseValidator;
import com.ruoyi.ss.user.domain.SmUserQuery;
import com.ruoyi.ss.user.service.ISmUserService;
import com.ruoyi.ss.user.service.UserValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.HashSet;
import java.util.List;
/**
* @author wjh
* 2024/4/29
*/
@Service
public class UserValidatorImpl extends BaseValidator implements UserValidator {
@Autowired
private ISmUserService userService;
/**
* 判断用户是否存在
*
* @param userIds 用户id列表
*/
@Override
public boolean isExistUser(List<Long> userIds) {
if (CollectionUtils.isEmpty(userIds)) {
return true;
}
SmUserQuery query = new SmUserQuery();
query.setUserIds(userIds);
Integer userCount = userService.selectCount(query);
return userCount == new HashSet<Long>(userIds).size();
}
}

View File

@ -1,100 +0,0 @@
package com.ruoyi.web.controller.app;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.ss.store.domain.Store;
import com.ruoyi.ss.store.domain.StoreQuery;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.service.IStoreService;
import com.ruoyi.web.core.annotation.UserTypePermission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 设备分组Controller
* @author
* 2024/3/5
*/
@Api(tags = "设备分组")
@RestController
@RequestMapping("/app/group")
public class AppDeviceGroupController extends BaseController {
@Autowired
private IStoreService smDeviceGroupService;
/**
* 查询设备分组列表
*/
@UserTypePermission({UserType.LANDLORD})
@ApiOperation("查询设备分组列表")
@GetMapping("/list")
public TableDataInfo list(StoreQuery store) {
startPage();
store.setUserId(getUserId());
List<StoreVo> list = smDeviceGroupService.selectSmStore(store);
return getDataTable(list);
}
/**
* 修改设备分组信息
* @param store
* @return
*/
@DataScope
@UserTypePermission({UserType.LANDLORD})
@ApiOperation("修改设备分组信息")
@PutMapping
public AjaxResult edit(@RequestBody Store store) {
store.setCreateTime(null);
store.setCreateBy(null);
store.setUserId(null);
return AjaxResult.success(smDeviceGroupService.updateSmStore(store));
}
/**
* 删除设备分组信息
* @param groupId
* @return
*/
@UserTypePermission({UserType.LANDLORD})
@ApiOperation("删除设备分组信息")
@DeleteMapping("/{groupId}")
public AjaxResult delete(@PathVariable Long groupId) {
return AjaxResult.success(smDeviceGroupService.deleteSmStoreById(groupId));
}
/**
* 新增设备分组
* @param store
* @return
*/
@UserTypePermission({UserType.LANDLORD})
@ApiOperation("新增设备分组")
@PostMapping
public AjaxResult add(@RequestBody Store store) {
store.setUserId(getUserId());
return AjaxResult.success(smDeviceGroupService.insertSmStore(store));
}
@UserTypePermission({UserType.LANDLORD})
@ApiOperation("调整分组位置")
@PutMapping("/changeSort")
public AjaxResult changeSort(@RequestBody List<Store> list) {
return AjaxResult.success(smDeviceGroupService.changeSort(list));
}
@ApiOperation("获取当前用户分组列表及其数量")
@GetMapping("/listCount")
public AjaxResult listCount(Store store) {
store.setUserId(getUserId());
return AjaxResult.success(smDeviceGroupService.listCount(store));
}
}

View File

@ -0,0 +1,122 @@
package com.ruoyi.web.controller.app;
import com.fasterxml.jackson.annotation.JsonView;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.JsonViewProfile;
import com.ruoyi.common.core.domain.ValidGroup;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.store.domain.*;
import com.ruoyi.ss.store.service.IStoreService;
import com.ruoyi.ss.store.service.StoreValidator;
import com.ruoyi.web.core.annotation.MchRequired;
import com.ruoyi.web.core.annotation.UserTypePermission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
/**
* 店铺Controller
* @author
* 2024/3/5
*/
@Api(tags = "店铺")
@RestController
@RequestMapping("/app/store")
public class AppStoreController extends BaseController {
@Autowired
private IStoreService storeService;
@Autowired
private StoreValidator storeValidator;
/**
* 查询本人店铺列表
*/
@MchRequired
@ApiOperation("查询本人店铺列表")
@GetMapping("/list")
public TableDataInfo list(@Validated(ValidGroup.Query.class) StoreQuery store) {
startPage();
store.setUserId(getUserId());
List<StoreVo> list = storeService.selectSmStoreList(store);
return getDataTable(list);
}
/**
* 修改店铺信息
* @param store
* @return
*/
@DataScope
@MchRequired
@ApiOperation("修改店铺信息")
@PutMapping
public AjaxResult edit(@RequestBody @Validated(ValidGroup.Update.class) StoreBO store) {
store = store.filterUpdateByApp();
ServiceUtil.assertion(storeValidator.preUpdateByApp(store));
return AjaxResult.success(storeService.updateSmStore(store));
}
/**
* 删除店铺信息
* @param storeId
* @return
*/
@MchRequired
@ApiOperation("删除店铺信息")
@DeleteMapping("/{storeId}")
public AjaxResult delete(@PathVariable Long storeId) {
List<Long> storeIds = Collections.singletonList(storeId);
ServiceUtil.assertion(storeValidator.preLogicDelByApp(storeIds));
return AjaxResult.success(storeService.logicDel(storeIds));
}
@MchRequired
@ApiOperation("新增店铺")
@PostMapping
public AjaxResult add(@RequestBody StoreBO store) {
store = store.filterCreateByApp();
store.setUserId(getUserId());
ServiceUtil.assertion(storeValidator.preCreateByApp(store));
return AjaxResult.success(storeService.insertSmStore(store));
}
@MchRequired
@ApiOperation("调整店铺排序")
@PutMapping("/changeSort")
public AjaxResult changeSort(@RequestBody List<Store> list) {
ServiceUtil.assertion(storeValidator.preChangeSortByApp(list));
return AjaxResult.success(storeService.changeSort(list));
}
@MchRequired
@ApiOperation("获取当前用户店铺列表及其数量")
@GetMapping("/listCount")
@JsonView(StoreView.ListCount.class)
public AjaxResult listCount() {
StoreQuery store = new StoreQuery();
store.setUserId(getUserId());
return AjaxResult.success(storeService.listCount(store));
}
@ApiOperation("获取附近的店铺")
@GetMapping("/listNearBy")
@JsonView(JsonViewProfile.App.class)
@Anonymous
public TableDataInfo listNearBy(@Validated(ValidGroup.Query.class) StoreQuery query) {
startPage();
List<StoreVo> list = storeService.listNearBy(query);
return getDataTable(list);
}
}

View File

@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.core.domain.ValidGroup;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.store.domain.StoreBO;
import com.ruoyi.ss.store.domain.StoreQuery;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.service.StoreValidator;
@ -53,7 +54,7 @@ public class StoreController extends BaseController
public TableDataInfo list(StoreQuery store)
{
startPage();
List<StoreVo> list = storeService.selectSmStore(store);
List<StoreVo> list = storeService.selectSmStoreList(store);
return getDataTable(list);
}
@ -65,7 +66,7 @@ public class StoreController extends BaseController
@PostMapping("/export")
public void export(HttpServletResponse response, StoreQuery store)
{
List<StoreVo> list = storeService.selectSmStore(store);
List<StoreVo> list = storeService.selectSmStoreList(store);
ExcelUtil<StoreVo> util = new ExcelUtil<StoreVo>(StoreVo.class);
util.exportExcel(response, list, "商户数据");
}
@ -97,8 +98,10 @@ public class StoreController extends BaseController
@PreAuthorize("@ss.hasPermi('ss.store:edit')")
@Log(title = "商户", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody @Validated(ValidGroup.Update.class) Store store)
public AjaxResult edit(@RequestBody @Validated(ValidGroup.Update.class) StoreBO store)
{
store = store.filterUpdate();
ServiceUtil.assertion(storeValidator.preUpdate(store));
return toAjax(storeService.updateSmStore(store));
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.web.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 商家权限注解注释方法必须是商家才可使用的方法
* @author wjh
* 2024/4/29
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MchRequired {
}

View File

@ -0,0 +1,50 @@
package com.ruoyi.web.core.aspectj;
import com.ruoyi.common.core.domain.entity.SmUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.service.ISmUserService;
import com.ruoyi.web.core.annotation.MchRequired;
import com.ruoyi.web.core.annotation.UserTypePermission;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户类型权限切面
* @author
* 2024/3/8
*/
@Aspect
@Component
public class MchRequiredAspect {
@Autowired
private ISmUserService smUserService;
@Value("${debug}")
private Boolean debug;
// 判断当前用户是否有权限访问
@Before("@annotation(mchRequired)")
public void doBefore(JoinPoint point, MchRequired mchRequired) {
if (debug) {
return;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
SmUser user = loginUser.getSmUser();
ServiceUtil.assertion(user == null || user.getIsMch() == null, "获取用户信息异常");
ServiceUtil.assertion(!user.getIsMch(), "仅商家可进行该操作,若您已成为商家,请重新登录后重试");
}
}