产线管理

This commit is contained in:
zc
2026-06-18 14:26:55 +08:00
parent ee01b284ee
commit 71cf559a19
41 changed files with 2865 additions and 31 deletions

View File

@@ -0,0 +1,22 @@
package top.mes.admin.peopleBranch.mapper;
import org.springframework.stereotype.Repository;
import top.continew.starter.data.mp.base.BaseMapper;
import top.mes.admin.peopleBranch.model.entity.BranchDO;
import top.mes.admin.peopleBranch.model.resp.BranchResp;
import java.util.List;
/**
* 部门管理 Mapper
*
* @author zc
* @since 2025/03/19 17:46
*/
@Repository
public interface BranchMapper extends BaseMapper<BranchDO> {
List<BranchResp> queryJuniorBranch(String branchId);
}

View File

@@ -0,0 +1,42 @@
package top.mes.admin.peopleBranch.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import top.continew.starter.data.mp.base.BaseMapper;
import top.mes.admin.peopleBranch.model.entity.PeopleDO;
import top.mes.admin.peopleBranch.model.resp.PeopleResp;
import java.util.List;
/**
* 人员管理业 Mapper
*
* @author zc
* @since 2025/03/19 17:46
*/
@Repository
public interface PeopleMapper extends BaseMapper<PeopleDO> {
/**
* 导出人员列表
*
* @param queryWrapper
* @return
*/
List<PeopleResp> selectExportPeople(@Param(Constants.WRAPPER) QueryWrapper<PeopleDO> queryWrapper);
/**
* 分页查询人员充值列表
*
* @param objectPage
* @param queryWrapper
* @return
*/
IPage<PeopleResp> selectPeoplePage(@Param("page") Page<Object> objectPage,
@Param(Constants.WRAPPER) QueryWrapper<PeopleDO> queryWrapper);
List<PeopleDO> selectPeopleList();
}

View File

@@ -0,0 +1,18 @@
package top.mes.admin.peopleBranch.mapstruct;
import org.mapstruct.Mapper;
import top.mes.admin.peopleBranch.model.entity.BranchDO;
import top.mes.admin.peopleBranch.model.req.BranchReq;
import top.mes.admin.peopleBranch.model.resp.BranchResp;
import java.util.List;
@Mapper(componentModel = "spring")
public interface BranchConvert {
BranchResp branchDOToResp(BranchDO branchDO);
BranchDO branchReqToDO(BranchReq branchReq);
List<BranchResp> ListDOToResp(List<BranchDO> branchDOS);
}

View File

@@ -0,0 +1,22 @@
package top.mes.admin.peopleBranch.mapstruct;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.mes.admin.peopleBranch.model.entity.PeopleDO;
import java.util.List;
@Mapper(componentModel = "spring")
public interface PeopleConvert {
List<LabelValueResp> labelValueList(List<PeopleDO> peopleDOS);
@Mapping(source = "id", target = "value")
@Mapping(target = "label", expression = "java(nameGh(peopleDO))")
LabelValueResp labelValueResp(PeopleDO peopleDO);
default String nameGh(PeopleDO peopleDO) {
return peopleDO.getName() + "" + (peopleDO.getGh() == null ? "" : peopleDO.getGh()) + "";
}
}

View File

@@ -0,0 +1,55 @@
package top.mes.admin.peopleBranch.mapstruct;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.util.HashMap;
import java.util.Map;
public class SexConverter implements Converter<Integer> {
private static final Map<Integer, String> SEX_MAP = new HashMap<>();
static {
SEX_MAP.put(1, "");
SEX_MAP.put(2, "");
SEX_MAP.put(4, "保密");
}
@Override
public Class<?> supportJavaTypeKey() {
return Integer.class; // 支持的 Java 类型
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING; // 写入 Excel 时用字符串
}
@Override
public WriteCellData<String> convertToExcelData(Integer value,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
if (value == null) {
return new WriteCellData<>("未知");
}
String label = SEX_MAP.getOrDefault(value, "未知");
return new WriteCellData<>(label);
}
@Override
public Integer convertToJavaData(ReadCellData<?> cellData,
ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String stringValue = cellData.getStringValue();
for (Map.Entry<Integer, String> entry : SEX_MAP.entrySet()) {
if (entry.getValue().equals(stringValue)) {
return entry.getKey();
}
}
return null;
}
}

View File

@@ -0,0 +1,81 @@
package top.mes.admin.peopleBranch.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import top.mes.admin.common.model.entity.BaseStrIdDO;
import java.io.Serial;
/**
* 部门管理实体
*
* @author zc
* @since 2025/03/19 17:40
*/
@Data
@TableName("sys_branch")
public class BranchDO extends BaseStrIdDO {
@Serial
private static final long serialVersionUID = 1L;
/**
* 部门名称
*/
private String name;
/**
* 部门负责人
*/
private String leader;
/**
* 联系电话
*/
private String phone;
/**
* 父级Id
*/
private String parentId;
/**
* 祖级列表
*/
private String ancestors;
/**
* 所属空间
*/
private Long spaceId;
/**
* 备注
*/
private String remark;
/**
* 关联部门
*/
private Long deptId;
/**
*
*/
private String level;
/**
* 部门code
*/
private String deptCode;
/**
* 梯控规则id
*/
private String ladderRuleId;
/**
* 访客是否审核 0 否1 是
*/
private String isExamine;
}

View File

@@ -0,0 +1,148 @@
package top.mes.admin.peopleBranch.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import top.mes.admin.common.model.entity.BaseDO;
import java.io.Serial;
import java.math.BigDecimal;
import java.util.Date;
/**
* 人员管理实体
*
* @author zc
* @since 2025/03/21 18:10
*/
@Data
@TableName("sys_people")
public class PeopleDO extends BaseDO {
@Serial
private static final long serialVersionUID = 1L;
/**
* 人员名称
*/
private String name;
/**
* 联系电话
*/
private String phone;
/**
* 用户性别1男 2女 4保密
*/
private Integer sex;
/**
* 头像地址
*/
private String avatar;
/**
* 所在部门
*/
private String branchId;
/**
* 职位标签
*/
private String position;
/**
* 身份证号码
*/
private String idcard;
/**
* 门卡号码
*/
private String doorNo;
/**
* 人员编号对接
*/
private String guid;
/**
* 人像对接
*/
private String faceGuid;
/**
* 关联用户
*/
private Long userId;
/**
* 备注
*/
private String remark;
/**
* 工号
*/
private String gh;
/**
* 指纹特征值
*/
private String fingerprint;
/**
* 入职时间
*/
private Date joinTime;
/**
* 下发次数
*/
private Long down;
/**
*
*/
private String delFlag;
/**
* 微信公众号id
*/
private String openid;
/**
* 消费标志0未同步 1已同步 2删除同步
*/
private Integer xfFlag;
/**
* 充值金额
*/
private BigDecimal czje;
/**
* 补贴金额
*/
private BigDecimal btje;
/**
* 是否消费 01
*/
private Integer isConsume;
/**
* 消费金额
*/
private BigDecimal xfje;
/**
* 消费次数
*/
private Integer xfcs;
/**
* 是否冻结 01
*/
private Integer freeze;
}

View File

@@ -0,0 +1,37 @@
package top.mes.admin.peopleBranch.model.query;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.continew.starter.data.core.annotation.Query;
import top.continew.starter.data.core.enums.QueryType;
import java.io.Serial;
import java.io.Serializable;
/**
* 部门管理查询条件
*
* @author zc
* @since 2025/03/19 17:40
*/
@Data
@Schema(description = "部门管理查询条件")
public class BranchQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 部门名称
*/
@Schema(description = "部门名称")
@Query(type = QueryType.EQ)
private String name;
/**
* 部门负责人
*/
@Schema(description = "部门负责人")
@Query(type = QueryType.EQ)
private String leader;
}

View File

@@ -0,0 +1,116 @@
package top.mes.admin.peopleBranch.model.query;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import top.continew.starter.data.core.annotation.Query;
import top.continew.starter.data.core.enums.QueryType;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 人员管理查询条件
*
* @author zc
* @since 2025/03/21 18:10
*/
@Data
@Schema(description = "人员管理查询条件")
@Builder
public class PeopleQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private String id;
/**
* 主键ids
*/
@Query(columns = {"id"}, type = QueryType.IN)
private List<Long> ids;
/**
* 人员名称
*/
@Schema(description = "人员名称")
private String name;
/**
* 部门
*/
@Schema(description = "部门")
private String branchId;
/**
* 父部门id
*/
@Schema(description = "父部门id")
private String branchParentId;
/**
* 联系电话
*/
@Schema(description = "联系电话")
private String phone;
/**
* 身份证号码
*/
@Schema(description = "身份证号码")
private String idcard;
/**
* 是否注册
*/
@Schema(description = "是否注册")
private String guidFlag;
/**
* 是否下发
*/
@Schema(description = "是否下发")
private String downFlag;
/**
* 人脸注册
*/
@Schema(description = "人脸注册")
private String faceFlag;
/**
* 卡号注册
*/
@Schema(description = "卡号注册")
private String cardFlag;
/**
* 卡号
*/
@Schema(description = "卡号")
private String doorNo;
/**
* 工号
*/
@Schema(description = "工号")
private String gh;
/**
* 是否消费 01
*/
@Schema(description = "是否消费 01")
private Integer isConsume;
/**
* 是否冻结 01
*/
@Schema(description = "是否冻结 01")
private Integer freeze;
}

View File

@@ -0,0 +1,66 @@
package top.mes.admin.peopleBranch.model.req;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 创建或修改部门管理参数
*
* @author zc
* @since 2025/03/19 17:40
*/
@Data
@Schema(description = "创建或修改部门管理参数")
public class BranchReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 部门名称
*/
@Schema(description = "部门名称")
@NotBlank(message = "部门名称不能为空")
@Length(max = 50, message = "部门名称长度不能超过 {max} 个字符")
private String name;
/**
* 部门负责人
*/
@Schema(description = "部门负责人")
@Length(max = 50, message = "部门负责人长度不能超过 {max} 个字符")
private String leader;
/**
* 联系电话
*/
@Schema(description = "联系电话")
@Length(max = 50, message = "联系电话长度不能超过 {max} 个字符")
private String phone;
/**
* 父级Id
*/
@Schema(description = "父级Id")
@NotBlank(message = "父级Id不能为空")
@Length(max = 36, message = "父级Id长度不能超过 {max} 个字符")
private String parentId;
/**
* 关联部门
*/
@Schema(description = "关联部门")
private Long deptId;
/**
* 规则id
*/
@Schema(description = "规则ids")
private List<Long> ruleIdList;
}

View File

@@ -0,0 +1,51 @@
package top.mes.admin.peopleBranch.model.req;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import top.mes.admin.common.enums.DisEnableStatusEnum;
import top.mes.admin.system.enums.ImportPolicyEnum;
import java.io.Serial;
@Data
@Schema(description = "人员导入参数")
public class PeopleImportReq {
@Serial
private static final long serialVersionUID = 1L;
/**
* 导入会话KEY
*/
@Schema(description = "导入会话KEY", example = "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed")
@NotBlank(message = "导入已过期,请重新上传")
private String importKey;
/**
* 用户重复策略
*/
@Schema(description = "重复用户策略", example = "1")
@NotNull(message = "重复用户策略不能为空")
private ImportPolicyEnum duplicateUser;
/**
* 重复邮箱策略
*/
// @Schema(description = "重复邮箱策略", example = "1")
// @NotNull(message = "重复邮箱策略不能为空")
// private ImportPolicyEnum duplicateEmail;
/**
* 重复手机策略
*/
// @Schema(description = "重复手机策略", example = "1")
// @NotNull(message = "重复手机策略不能为空")
// private ImportPolicyEnum duplicatePhone;
/**
* 默认状态
*/
@Schema(description = "默认状态", example = "1")
private DisEnableStatusEnum defaultStatus;
}

View File

@@ -0,0 +1,65 @@
package top.mes.admin.peopleBranch.model.req;
import cn.hutool.core.lang.RegexPool;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import top.mes.admin.common.constant.RegexConstants;
import top.mes.admin.peopleBranch.mapstruct.SexConverter;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
@Data
@Schema(description = "人员导入行数据")
public class PeopleImportRowReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
@Pattern(regexp = RegexConstants.USERNAME, message = "用户名长度为 4-64 个字符,支持大小写字母、数字、下划线,以字母开头")
@ExcelProperty(value = "姓名", order = 2)
private String name;
/**
* 部门名称
*/
@NotBlank(message = "所属部门不能为空")
@ExcelProperty(value = "部门名称", order = 6)
private String branchName;
/**
* 性别
*/
@ExcelProperty(value = "性别", converter = SexConverter.class, order = 4)
private Integer sex;
/**
* 手机号码
*/
@Pattern(regexp = "^$|" + RegexPool.MOBILE, message = "手机号码格式错误")
@ExcelProperty(value = "联系电话", order = 3)
private String phone;
@ExcelProperty(value = "工号", order = 1)
private String gh;
@ExcelProperty(value = "职位标签", order = 7)
private String position;
@ExcelProperty(value = "身份证号码", order = 8)
private String idcard;
@ExcelProperty(value = "卡号", order = 9)
private String doorNo;
@ExcelProperty(value = "入职时间", order = 10)
private Date joinTime;
}

View File

@@ -0,0 +1,183 @@
package top.mes.admin.peopleBranch.model.req;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 创建或修改人员管理参数
*
* @author zc
* @since 2025/03/21 18:10
*/
@Data
@Schema(description = "创建或修改人员管理参数")
public class PeopleReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@Schema(description = "主键id")
private Long id;
/**
* 人员名称
*/
@Schema(description = "人员名称")
@NotBlank(message = "人员名称不能为空")
@Length(max = 25, message = "人员名称长度不能超过 {max} 个字符")
private String name;
/**
* 联系电话
*/
@Schema(description = "联系电话")
@Length(max = 50, message = "联系电话长度不能超过 {max} 个字符")
private String phone;
/**
* 用户性别0男 1女 2保密
*/
@Schema(description = "用户性别1男 2女 4保密")
private Integer sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
@Length(max = 500, message = "头像地址长度不能超过 {max} 个字符")
private String avatar;
/**
* 所在部门
*/
@Schema(description = "所在部门")
@NotNull(message = "所属部门不能为空")
@Length(max = 36, message = "所在部门长度不能超过 {max} 个字符")
private String branchId;
/**
* 职位标签
*/
@Schema(description = "职位标签")
@Length(max = 50, message = "职位标签长度不能超过 {max} 个字符")
private String position;
/**
* 身份证号码
*/
@Schema(description = "身份证号码")
@Length(max = 50, message = "身份证号码长度不能超过 {max} 个字符")
private String idcard;
/**
* 门卡号码
*/
@Schema(description = "门卡号码")
@Length(max = 50, message = "门卡号码长度不能超过 {max} 个字符")
private String doorNo;
/**
* 人员编号对接
*/
@Schema(description = "人员编号对接")
@Length(max = 200, message = "人员编号对接长度不能超过 {max} 个字符")
private String guid;
/**
* 人像对接
*/
@Schema(description = "人像对接")
@Length(max = 200, message = "人像对接长度不能超过 {max} 个字符")
private String faceGuid;
/**
* 关联用户
*/
@Schema(description = "关联用户")
private Long userId;
/**
* 备注
*/
@Schema(description = "备注")
@Length(max = 200, message = "备注长度不能超过 {max} 个字符")
private String remark;
/**
* 工号
*/
@Schema(description = "工号")
@NotNull(message = "工号不能为空")
@Length(max = 8, message = "工号长度不能超过 {max} 个字符")
private String gh;
/**
* 指纹特征值
*/
@Schema(description = "指纹特征值")
@Length(max = 255, message = "指纹特征值长度不能超过 {max} 个字符")
private String fingerprint;
/**
* 入职时间
*/
@Schema(description = "入职时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date joinTime;
/**
* 入职时间
*/
@Schema(description = "入职时间")
private Long down;
/**
* 是否需要下发设备(用于修改人员信息时,校验是否修改人员姓名,照片等需要下发的设备的参数)
*/
@Schema(description = "是否需要下发设备")
private Boolean needDown = false;
/**
* 人员id列表
*/
@Schema(description = "人员id列表")
private List<Long> ids;
/**
* 消费充值的金额or补贴的金额
*/
@Schema(description = "金额")
private BigDecimal money;
/**
* 是否消费 01
*/
@Schema(description = "是否消费 01")
private Integer isConsume;
/**
* 一键清零所有人 01
*/
@Schema(description = "一键清零所有人 01")
private Integer resetMoneyAll;
/**
* 一键清零金额种类 0全部1充值2补贴
*/
@Schema(description = "一键清零金额种类 0全部1充值2补贴")
private Integer resetMoneyType;
}

View File

@@ -0,0 +1,114 @@
package top.mes.admin.peopleBranch.model.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.mes.admin.common.model.resp.BaseStrIdResp;
import java.io.Serial;
import java.time.LocalDateTime;
import java.util.List;
/**
* 部门管理信息
*
* @author zc
* @since 2025/03/19 17:46
*/
@Data
@Schema(description = "部门管理信息")
public class BranchResp extends BaseStrIdResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 部门名称
*/
@Schema(description = "部门名称")
private String name;
/**
* 部门负责人
*/
@Schema(description = "部门负责人")
private String leader;
/**
* 联系电话
*/
@Schema(description = "联系电话")
private String phone;
/**
* 父级Id
*/
@Schema(description = "父级Id")
private String parentId;
/**
* 祖级列表
*/
@Schema(description = "祖级列表")
private String ancestors;
/**
* 所属空间
*/
@Schema(description = "所属空间")
private Long spaceId;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private LocalDateTime updateTime;
/**
* 关联部门
*/
@Schema(description = "关联部门")
private Long deptId;
/**
*
*/
@Schema(description = "")
private String level;
/**
* 部门code
*/
@Schema(description = "部门code")
private String deptCode;
/**
* 规则ids
*/
@Schema(description = "规则ids")
private List<Long> ruleIdList;
/**
* 规则名称
*/
@Schema(description = "规则名称")
private String ruleNames;
/**
* 梯控规则id
*/
@Schema(description = "梯控规则id")
private String ladderRuleId;
/**
* 访客是否审核 0 否1 是
*/
@Schema(description = "访客是否审核 0 否1 是")
private String isExamine;
}

View File

@@ -0,0 +1,22 @@
package top.mes.admin.peopleBranch.model.resp;
import lombok.Data;
@Data
public class BranchRuleResp {
/**
* 部门id
*/
private String branchId;
/**
* 规则id
*/
private Long ruleId;
/**
* 规则名称
*/
private String ruleName;
}

View File

@@ -0,0 +1,39 @@
package top.mes.admin.peopleBranch.model.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "人员导入解析结果")
public class PeopleImportParseResp implements Serializable {
/**
* 导入会话 Key
*/
@Schema(description = "导入会话Key", example = "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed")
private String importKey;
/**
* 总计行数
*/
@Schema(description = "总计行数", example = "100")
private Integer totalRows;
/**
* 有效行数
*/
@Schema(description = "有效行数", example = "100")
private Integer validRows;
/**
* 已存在行数
*/
@Schema(description = "已存在行数", example = "100")
private Integer duplicatePeopleRows;
}

View File

@@ -0,0 +1,31 @@
package top.mes.admin.peopleBranch.model.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "人员导入结果")
public class PeopleImportResp {
private static final long serialVersionUID = 1L;
/**
* 总计行数
*/
@Schema(description = "总计行数", example = "100")
private Integer totalRows;
/**
* 新增行数
*/
@Schema(description = "新增行数", example = "100")
private Integer insertRows;
/**
* 修改行数
*/
@Schema(description = "修改行数", example = "100")
private Integer updateRows;
}

View File

@@ -0,0 +1,235 @@
package top.mes.admin.peopleBranch.model.resp;
import cn.crane4j.annotation.Assemble;
import cn.crane4j.core.executor.handler.ManyToManyAssembleOperationHandler;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.mes.admin.common.constant.ContainerConstants;
import top.mes.admin.common.model.resp.BaseDetailResp;
import top.mes.admin.peopleBranch.mapstruct.SexConverter;
import java.io.Serial;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 人员管理信息
*
* @author zc
* @since 2025/03/21 18:10
*/
@Data
@Schema(description = "人员管理信息")
public class PeopleResp extends BaseDetailResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 人员名称
*/
@Schema(description = "人员名称")
@ExcelProperty(value = "姓名", order = 2)
@ColumnWidth(10)
private String name;
/**
* 联系电话
*/
@Schema(description = "联系电话")
@ExcelProperty(value = "联系电话", order = 3)
@ColumnWidth(15)
private String phone;
/**
* 用户性别1男 2女 4保密
*/
@Schema(description = "用户性别1男 2女 4保密")
@ExcelProperty(value = "性别", converter = SexConverter.class, order = 4)
private Integer sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
@ExcelIgnore
private String avatar;
/**
* 所在部门
*/
@Schema(description = "所在部门")
@ExcelIgnore
@Assemble(prop = ":branchName", container = ContainerConstants.BRANCH_NAME, handlerType = ManyToManyAssembleOperationHandler.class)
private String branchId;
/**
* 所在部门名称
*/
@Schema(description = "所在部门名称")
@ExcelProperty(value = "部门名称", order = 5)
private String branchName;
/**
* 职位标签
*/
@Schema(description = "职位标签")
@ExcelProperty(value = "职位标签", order = 6)
private String position;
/**
* 身份证号码
*/
@Schema(description = "身份证号码")
@ExcelProperty(value = "身份证号码", order = 7)
@ColumnWidth(25)
private String idcard;
/**
* 门卡号码
*/
@Schema(description = "门卡号码")
@ExcelProperty(value = "卡号", order = 8)
@ColumnWidth(15)
private String doorNo;
/**
* 人员编号对接
*/
@Schema(description = "人员编号对接")
@ExcelIgnore
private String guid;
/**
* 人像对接
*/
@Schema(description = "人像对接")
@ExcelIgnore
private String faceGuid;
/**
* 关联用户
*/
@Schema(description = "关联用户")
@Assemble(prop = ":userName", container = ContainerConstants.USER_NAME, handlerType = ManyToManyAssembleOperationHandler.class)
@ExcelIgnore
private Long userId;
/**
* 关联用户
*/
@Schema(description = "关联用户")
@ExcelIgnore
private String userName;
/**
* 备注
*/
@Schema(description = "备注")
@ExcelIgnore
private String remark;
/**
* 更新时间
*/
@Schema(description = "更新时间")
@ExcelIgnore
private LocalDateTime updateTime;
/**
* 工号
*/
@Schema(description = "工号")
@ExcelProperty(value = "工号", order = 1)
@ColumnWidth(30)
private String gh;
/**
* 指纹特征值
*/
@Schema(description = "指纹特征值")
@ExcelIgnore
private String fingerprint;
/**
* 入职时间
*/
@Schema(description = "入职时间")
@ExcelProperty(value = "入职时间", order = 9)
@ColumnWidth(35)
private Date joinTime;
/**
* 下发次数
*/
@Schema(description = "下发次数")
@ExcelIgnore
private Long down;
/**
*
*/
@Schema(description = "")
@ExcelIgnore
private String delFlag;
/**
* 微信公众号id
*/
@Schema(description = "微信公众号id")
@ExcelIgnore
private String openid;
/**
* 消费标志0未同步 1已同步 2删除同步
*/
@Schema(description = "消费标志0未同步 1已同步 2删除同步")
@ExcelIgnore
private Integer xfFlag;
/**
* 充值金额
*/
@Schema(description = "充值金额")
@ExcelIgnore
private BigDecimal czje;
/**
* 补贴金额
*/
@Schema(description = "补贴金额")
@ExcelIgnore
private BigDecimal btje;
/**
* 是否消费 01
*/
@Schema(description = "是否消费 01")
@ExcelIgnore
private Integer isConsume;
/**
* 消费金额
*/
@Schema(description = "消费金额")
@ExcelIgnore
private BigDecimal xfje;
/**
* 消费次数
*/
@Schema(description = "消费次数")
@ExcelIgnore
private Integer xfcs;
/**
* 是否冻结 01
*/
@Schema(description = "是否冻结 01")
@ExcelIgnore
private Integer freeze;
}

View File

@@ -0,0 +1,35 @@
package top.mes.admin.peopleBranch.service;
import cn.hutool.core.lang.tree.Tree;
import top.continew.starter.data.mp.service.IService;
import top.mes.admin.peopleBranch.model.entity.BranchDO;
import top.mes.admin.peopleBranch.model.query.BranchQuery;
import top.mes.admin.peopleBranch.model.req.BranchReq;
import top.mes.admin.peopleBranch.model.resp.BranchResp;
import java.util.List;
/**
* 部门管理业务接口
*
* @author zc
* @since 2025/03/19 17:46
*/
public interface BranchService extends IService<BranchDO> {
List<Tree<String>> selectBranchTree(BranchQuery branchQuery);
BranchResp selectBranchById(String id);
String insertBranch(BranchReq branchReq);
void updateBranch(BranchReq branchReq, String id);
void deleteBranchById(String id);
List<Tree<String>> tree(BranchQuery query);
List<BranchDO> listByNames(List<String> list);
String branchNameById(Long id);
}

View File

@@ -0,0 +1,55 @@
package top.mes.admin.peopleBranch.service;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.extension.crud.service.BaseService;
import top.mes.admin.peopleBranch.model.entity.PeopleDO;
import top.mes.admin.peopleBranch.model.query.PeopleQuery;
import top.mes.admin.peopleBranch.model.req.PeopleImportReq;
import top.mes.admin.peopleBranch.model.req.PeopleReq;
import top.mes.admin.peopleBranch.model.resp.PeopleImportParseResp;
import top.mes.admin.peopleBranch.model.resp.PeopleImportResp;
import top.mes.admin.peopleBranch.model.resp.PeopleResp;
import java.util.List;
/**
* 人员管理业务接口
*
* @author zc
* @since 2025/03/21 18:22
*/
public interface PeopleService extends BaseService<PeopleResp, PeopleResp, PeopleQuery, PeopleReq> {
/**
* 解析导入数据
*
* @param file 导入文件
* @return 解析结果
*/
PeopleImportParseResp parseImport(MultipartFile file);
PeopleImportResp importPeople(PeopleImportReq req);
List<PeopleDO> getPeopleNameList();
List<PeopleDO> getIdNamePhoneList();
/**
* crane4j 容器方法根据人员ID查询人员名称
*
* @param id
* @return
*/
String getPeopleName(Long id);
/**
* 下拉框数据,人员名称
*
* @param peopleQuery
* @return
*/
List<LabelValueResp> getPeopleNameList(PeopleQuery peopleQuery);
}

View File

@@ -0,0 +1,122 @@
package top.mes.admin.peopleBranch.service.impl;
import cn.crane4j.annotation.ContainerMethod;
import cn.crane4j.annotation.MappingType;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.mes.admin.common.constant.ContainerConstants;
import top.mes.admin.peopleBranch.mapper.BranchMapper;
import top.mes.admin.peopleBranch.mapstruct.BranchConvert;
import top.mes.admin.peopleBranch.model.entity.BranchDO;
import top.mes.admin.peopleBranch.model.query.BranchQuery;
import top.mes.admin.peopleBranch.model.req.BranchReq;
import top.mes.admin.peopleBranch.model.resp.BranchResp;
import top.mes.admin.peopleBranch.service.BranchService;
import java.util.Collections;
import java.util.List;
/**
* 部门管理业务实现
*
* @author zc
* @since 2025/03/19 17:46
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class BranchServiceImpl extends ServiceImpl<BranchMapper, BranchDO> implements BranchService {
private final BranchConvert branchConvert;
@Override
public List<Tree<String>> selectBranchTree(BranchQuery branchQuery) {
LambdaQueryWrapper<BranchDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(branchQuery.getName()), BranchDO::getName, branchQuery.getName());
queryWrapper.eq(StrUtil.isNotBlank(branchQuery.getName()), BranchDO::getLeader, branchQuery.getLeader());
//查询部门列表
List<BranchDO> branchDOS = baseMapper.selectList(queryWrapper);
List<BranchResp> branchResps = branchConvert.ListDOToResp(branchDOS);
TreeNodeConfig config = new TreeNodeConfig();
return TreeUtil.build(branchResps, "0", config, (treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.setParentId(treeNode.getParentId());
tree.setName(treeNode.getName());
tree.putExtra("leader", treeNode.getLeader());
tree.putExtra("phone", treeNode.getPhone());
tree.putExtra("ruleNames", treeNode.getRuleNames());
tree.putExtra("deptId", treeNode.getDeptId());
});
}
@Override
public BranchResp selectBranchById(String id) {
return branchConvert.branchDOToResp(baseMapper.selectById(id));
}
@Override
public String insertBranch(BranchReq branchReq) {
BranchDO branchDO = branchConvert.branchReqToDO(branchReq);
baseMapper.insert(branchDO);
return branchDO.getId();
}
@Override
public void updateBranch(BranchReq branchReq, String id) {
BranchDO branchDO = branchConvert.branchReqToDO(branchReq);
branchDO.setId(id);
baseMapper.updateById(branchDO);
}
@Override
public void deleteBranchById(String id) {
baseMapper.deleteById(id);
}
@Override
public List<Tree<String>> tree(BranchQuery query) {
LambdaQueryWrapper<BranchDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(query.getName()), BranchDO::getName, query.getName());
queryWrapper.eq(StrUtil.isNotBlank(query.getLeader()), BranchDO::getLeader, query.getLeader());
List<BranchDO> branchDOS = baseMapper.selectList(queryWrapper);
TreeNodeConfig config = new TreeNodeConfig();
return TreeUtil.build(branchDOS, "0", config, (treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.putExtra("key", treeNode.getId());
tree.putExtra("title", treeNode.getName());
tree.setParentId(treeNode.getParentId());
});
}
@Override
public List<BranchDO> listByNames(List<String> list) {
if (CollUtil.isEmpty(list)) {
return Collections.emptyList();
}
return this.list(Wrappers.<BranchDO>lambdaQuery().in(BranchDO::getName, list));
}
@Override
@ContainerMethod(namespace = ContainerConstants.BRANCH_NAME, type = MappingType.ORDER_OF_KEYS)
public String branchNameById(Long id) {
if (null == id) {
return "";
}
BranchDO branchDO = baseMapper.selectById(id);
return branchDO != null ? branchDO.getName() : "";
}
}

View File

@@ -0,0 +1,490 @@
package top.mes.admin.peopleBranch.service.impl;
import cn.crane4j.annotation.ContainerMethod;
import cn.crane4j.annotation.MappingType;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.core.util.SpringUtils;
import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.query.SortQuery;
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.extension.crud.model.resp.PageResp;
import top.continew.starter.extension.crud.service.BaseServiceImpl;
import top.continew.starter.file.excel.util.ExcelUtils;
import top.mes.admin.common.constant.CacheConstants;
import top.mes.admin.common.constant.ContainerConstants;
import top.mes.admin.common.util.SecureUtils;
import top.mes.admin.peopleBranch.mapper.BranchMapper;
import top.mes.admin.peopleBranch.mapper.PeopleMapper;
import top.mes.admin.peopleBranch.mapstruct.PeopleConvert;
import top.mes.admin.peopleBranch.model.entity.BranchDO;
import top.mes.admin.peopleBranch.model.entity.PeopleDO;
import top.mes.admin.peopleBranch.model.query.PeopleQuery;
import top.mes.admin.peopleBranch.model.req.PeopleImportReq;
import top.mes.admin.peopleBranch.model.req.PeopleImportRowReq;
import top.mes.admin.peopleBranch.model.req.PeopleReq;
import top.mes.admin.peopleBranch.model.resp.BranchResp;
import top.mes.admin.peopleBranch.model.resp.PeopleImportParseResp;
import top.mes.admin.peopleBranch.model.resp.PeopleImportResp;
import top.mes.admin.peopleBranch.model.resp.PeopleResp;
import top.mes.admin.peopleBranch.service.BranchService;
import top.mes.admin.peopleBranch.service.PeopleService;
import java.time.Duration;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static top.mes.admin.system.enums.ImportPolicyEnum.*;
/**
* 人员管理业务实现
*
* @author zc
* @since 2025/03/21 18:22
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class PeopleServiceImpl extends BaseServiceImpl<PeopleMapper, PeopleDO, PeopleResp, PeopleResp, PeopleQuery, PeopleReq> implements PeopleService {
private final BranchMapper branchMapper;
private final PeopleConvert peopleConvert;
private final BranchService branchService;
private final FileStorageService fileStorageService;
@Override
public PageResp<PeopleResp> page(PeopleQuery query, PageQuery pageQuery) {
QueryWrapper<PeopleDO> queryWrapper = new QueryWrapper<>();
//初始部门不查询下级部门
if (StrUtil.isNotBlank(query.getBranchId()) && !StrUtil.equals(query.getBranchParentId(), "0")) {
List<BranchResp> branchResps = branchMapper.queryJuniorBranch(query.getBranchId());
List<String> branchList = branchResps.stream().map(BranchResp::getId).collect(Collectors.toList());
branchList.add(query.getBranchId());
queryWrapper.in("p.branch_id", branchList);
}
//查询条件
queryWrapper.like(StrUtil.isNotBlank(query.getName()), "p.name", query.getName());
queryWrapper.like(StrUtil.isNotBlank(query.getPhone()), "p.phone", query.getPhone());
queryWrapper.likeRight(StrUtil.isNotBlank(query.getIdcard()), "p.idcard", query.getIdcard());
if (StrUtil.isNotBlank(query.getFaceFlag())) {
if (StrUtil.equals(query.getFaceFlag(), "0")) {
queryWrapper.isNull("p.face_guid");
} else {
queryWrapper.isNotNull("p.face_guid");
}
}
if (StrUtil.isNotBlank(query.getGuidFlag())) {
if (StrUtil.equals(query.getGuidFlag(), "0")) {
queryWrapper.isNull("p.guid");
} else {
queryWrapper.isNotNull("p.guid");
}
}
if (StrUtil.isNotBlank(query.getDownFlag())) {
if (StrUtil.equals(query.getDownFlag(), "0")) {
queryWrapper.eq("p.down", 0);
} else {
queryWrapper.gt("p.down", 0);
}
}
if (StrUtil.isNotBlank(query.getCardFlag())) {
if (StrUtil.equals(query.getCardFlag(), "0")) {
queryWrapper.isNull("p.door_no");
} else {
queryWrapper.isNotNull("p.door_no");
}
}
queryWrapper.orderByDesc("p.id", "p.create_time");
IPage<PeopleResp> page = baseMapper.selectPeoplePage(new Page<>(pageQuery.getPage(), pageQuery
.getSize()), queryWrapper);
return PageResp.build(page);
}
@Override
public void export(PeopleQuery query, SortQuery sortQuery, HttpServletResponse response) {
QueryWrapper<PeopleDO> queryWrapper = new QueryWrapper<>();
//初始部门不查询下级部门
if (StrUtil.isNotBlank(query.getBranchId()) && !StrUtil.equals(query.getBranchId(), "1")) {
List<BranchResp> branchResps = branchMapper.queryJuniorBranch(query.getBranchId());
List<String> branchList = branchResps.stream().map(BranchResp::getId).collect(Collectors.toList());
branchList.add(query.getBranchId());
queryWrapper.in("p.branch_id", branchList);
}
//查询条件
queryWrapper.like(StrUtil.isNotBlank(query.getName()), "p.name", query.getName());
queryWrapper.like(StrUtil.isNotBlank(query.getPhone()), "p.phone", query.getPhone());
queryWrapper.likeRight(StrUtil.isNotBlank(query.getIdcard()), "p.idcard", query.getIdcard());
if (StrUtil.isNotBlank(query.getFaceFlag())) {
if (StrUtil.equals(query.getFaceFlag(), "0")) {
queryWrapper.isNull("p.face_guid");
} else {
queryWrapper.isNotNull("p.face_guid");
}
}
if (StrUtil.isNotBlank(query.getGuidFlag())) {
if (StrUtil.equals(query.getGuidFlag(), "0")) {
queryWrapper.isNull("p.guid");
} else {
queryWrapper.isNotNull("p.guid");
}
}
if (StrUtil.isNotBlank(query.getDownFlag())) {
if (StrUtil.equals(query.getDownFlag(), "0")) {
queryWrapper.eq("p.down", 0);
} else {
queryWrapper.gt("p.down", 0);
}
}
if (StrUtil.isNotBlank(query.getCardFlag())) {
if (StrUtil.equals(query.getCardFlag(), "0")) {
queryWrapper.isNull("p.door_no");
} else {
queryWrapper.isNotNull("p.door_no");
}
}
queryWrapper.orderByDesc("p.id", "p.create_time");
List<PeopleResp> peopleRespList = baseMapper.selectExportPeople(queryWrapper);
ExcelUtils.export(peopleRespList, "人员清单", this.getDetailClass(), response);
}
@Override
public void beforeAdd(PeopleReq req) {
//给新添加人员新增guid,用于设备注册
req.setGuid(IdUtil.simpleUUID());
//如果照片不为空 则生成faceguid
if (ObjectUtil.isNotEmpty(req.getAvatar())) {
req.setFaceGuid(IdUtil.simpleUUID());
}
//入参重复数据校验
CheckUtils.throwIf(isGhExists(req.getGh()), "新增失败,工号[{}] 已存在", req.getGh());
if (StrUtil.isNotBlank(req.getDoorNo())) {
CheckUtils.throwIf(isDoorNoExists(req.getDoorNo()), "新增失败,门禁卡号[{}] 已存在", req.getDoorNo());
}
}
/**
* 工号是否存在
*
* @param gh 工号
* @return 是否存在
*/
private boolean isGhExists(String gh) {
return baseMapper.lambdaQuery().eq(PeopleDO::getGh, gh).exists();
}
/**
* 门禁卡号是否存在
*
* @param doorNo 门禁卡号
* @return 是否存在
*/
private boolean isDoorNoExists(String doorNo) {
return baseMapper.lambdaQuery().eq(PeopleDO::getDoorNo, doorNo).exists();
}
@Override
public void beforeUpdate(PeopleReq req, Long id) {
if (ObjectUtil.isNotEmpty(req.getAvatar()) && ObjectUtil.isEmpty(req.getFaceGuid())) {
req.setFaceGuid(IdUtil.simpleUUID());
}
PeopleDO peopleDO = baseMapper.lambdaQuery().eq(PeopleDO::getId, req.getId()).select().one();
//入参重复数据校验
if (StrUtil.isNotBlank(req.getGh()) && !StrUtil.equals(peopleDO.getGh(), req.getGh())) {
CheckUtils.throwIf(isGhExists(req.getGh()), "修改失败,工号[{}] 已存在", req.getGh());
}
if (StrUtil.isNotBlank(req.getDoorNo()) && !StrUtil.equals(peopleDO.getDoorNo(), req.getDoorNo())) {
CheckUtils.throwIf(isDoorNoExists(req.getDoorNo()), "修改失败,门禁卡号[{}] 已存在", req.getDoorNo());
}
if (StrUtil.isNotBlank(req.getAvatar()) && !StrUtil.equals(peopleDO.getAvatar(), req.getAvatar())) {
try {
fileStorageService.delete(peopleDO.getAvatar());
} catch (Exception e) {
log.error("删除人员头像失败:{}", e.getMessage(), e);
// 继续执行,不影响人员修改
}
}
//如果修改了人员姓名,电话,照片,身份证号 则需要下发设备
if ((StrUtil.isNotBlank(req.getName()) && !StrUtil.equals(peopleDO.getName(), req.getName()) || StrUtil
.isNotBlank(req.getPhone()) && !StrUtil.equals(peopleDO.getPhone(), req.getPhone())) || StrUtil
.isNotBlank(req.getAvatar()) && !StrUtil.equals(peopleDO.getAvatar(), req.getAvatar()) || StrUtil
.isNotBlank(req.getIdcard()) && !StrUtil.equals(peopleDO.getIdcard(), req.getIdcard())) {
req.setNeedDown(true);
}
}
@Override
public void afterUpdate(PeopleReq sysPeople, PeopleDO peopleDO) {
}
@Override
public PeopleImportParseResp parseImport(MultipartFile file) {
PeopleImportParseResp peopleImportResp = new PeopleImportParseResp();
List<PeopleImportRowReq> importRowList;
// 读取表格数据
try {
importRowList = EasyExcel.read(file.getInputStream())
.head(PeopleImportRowReq.class)
.sheet()
.headRowNumber(1)
.doReadSync();
} catch (Exception e) {
log.error("用户导入数据文件解析异常:{}", e.getMessage(), e);
throw new BusinessException("数据文件解析异常");
}
// 总计行数
peopleImportResp.setTotalRows(importRowList.size());
CheckUtils.throwIfEqual(importRowList.size(), 0, "导入人员为空!");
// 有效行数:过滤无效数据,过滤重复(姓名+手机号重复)数据
List<PeopleImportRowReq> validRowList = this.filterImportData(importRowList);
CheckUtils.throwIfEqual(validRowList.size(), 0, "文件数据异常");
peopleImportResp.setValidRows(validRowList.size());
// 检测表格内数据是否合法
Set<String> seenGhs = new HashSet<>();
boolean hasDuplicateGh = importRowList.stream()
.map(PeopleImportRowReq::getGh)
.anyMatch(gh -> gh != null && !seenGhs.add(gh));
CheckUtils.throwIf(hasDuplicateGh, "存在重复工号,请检查数据");
Set<String> seenDNs = new HashSet<>();
boolean hasDuplicateDN = importRowList.stream()
.map(PeopleImportRowReq::getDoorNo)
.anyMatch(DN -> DN != null && !seenDNs.add(DN));
CheckUtils.throwIf(hasDuplicateDN, "存在重复卡号,请检查数据");
peopleImportResp
.setDuplicatePeopleRows(countExistByField(validRowList, PeopleImportRowReq::getIdcard, PeopleDO::getIdcard, false));
// 设置导入会话并缓存数据有效期10分钟
String importKey = UUID.fastUUID().toString(true);
RedisUtils.set(CacheConstants.DATA_IMPORT_KEY + importKey, JSONUtil.toJsonStr(importRowList), Duration
.ofMinutes(10));
peopleImportResp.setImportKey(importKey);
return peopleImportResp;
}
@Override
@Transactional(rollbackFor = Exception.class)
public PeopleImportResp importPeople(PeopleImportReq req) {
// 校验导入会话是否过期
List<PeopleImportRowReq> importUserList;
try {
String data = RedisUtils.get(CacheConstants.DATA_IMPORT_KEY + req.getImportKey());
importUserList = JSONUtil.toList(data, PeopleImportRowReq.class);
CheckUtils.throwIf(CollUtil.isEmpty(importUserList), "导入已过期,请重新上传");
} catch (Exception e) {
log.error("导入异常:", e);
throw new BusinessException("导入已过期,请重新上传");
}
//通过身份证获取重复人员 id,name,idcard
List<PeopleDO> existUserList = listByUsernames(importUserList.stream()
.map(PeopleImportRowReq::getIdcard)
.filter(Objects::nonNull)
.toList());
List<String> existPeopleIdCards = existUserList.stream().map(PeopleDO::getIdcard).toList();
CheckUtils.throwIf(isExitImportUser(req, importUserList, existPeopleIdCards), "数据不符合导入策略,已退出导入");
// 基础数据准备
//设置重复人员身份证与id的映射方便处理
Map<String, Long> peopleIdMap = existUserList.stream()
.collect(Collectors.toMap(PeopleDO::getIdcard, PeopleDO::getId));
List<BranchDO> branchList = branchService.listByNames(importUserList.stream()
.map(PeopleImportRowReq::getBranchName)
.distinct()
.toList());
Map<String, String> branchMap = branchList.stream()
.collect(Collectors.toMap(BranchDO::getName, BranchDO::getId));
// 批量操作数据库集合
List<PeopleDO> insertList = new ArrayList<>();
List<PeopleDO> updateList = new ArrayList<>();
for (PeopleImportRowReq row : importUserList) {
if (isSkipUserImport(req, row, existPeopleIdCards)) {
// 按规则跳过该行
continue;
}
PeopleDO peopleDO = BeanUtil.toBeanIgnoreError(row, PeopleDO.class);
peopleDO.setBranchId(branchMap.get(row.getBranchName()));
// 修改 or 新增
if (UPDATE.validate(req.getDuplicateUser(), row.getIdcard(), existPeopleIdCards)) {
peopleDO.setId(peopleIdMap.get(row.getIdcard()));
updateList.add(peopleDO);
} else {
insertList.add(peopleDO);
}
}
doImportUser(insertList, updateList);
RedisUtils.delete(CacheConstants.DATA_IMPORT_KEY + req.getImportKey());
return new PeopleImportResp(insertList.size() + updateList.size(), insertList.size(), updateList.size());
}
@Override
public List<PeopleDO> getPeopleNameList() {
QueryWrapper<PeopleDO> queryWrapper = new QueryWrapper<>();
List list = this.baseMapper.selectList(queryWrapper.select("id", "name"));
return list;
}
/**
* 过滤无效的导入用户数据(批量导入不严格校验数据)
*
* @param importRowList 导入数据
*/
private List<PeopleImportRowReq> filterImportData(List<PeopleImportRowReq> importRowList) {
// 校验过滤
// List<PeopleImportRowReq> list = importRowList.stream()
// .filter(row -> ValidationUtil.validate(row).isEmpty())
// .toList();
// 用户名+手机号去重
return importRowList.stream()
.collect(Collectors.toMap(row -> row.getName() + "_" + row.getPhone(), user -> user, (existing,
replacement) -> existing))
.values()
.stream()
.toList();
}
/**
* 按指定数据集获取数据库已存在的数量
*
* @param peopleRowList 导入的数据源
* @param rowField 导入数据的字段
* @param dbField 对比数据库的字段
* @return 存在的数量
*/
private int countExistByField(List<PeopleImportRowReq> peopleRowList,
Function<PeopleImportRowReq, String> rowField,
SFunction<PeopleDO, ?> dbField,
boolean fieldEncrypt) {
List<String> fieldValues = peopleRowList.stream().map(rowField).filter(Objects::nonNull).toList();
if (fieldValues.isEmpty()) {
return 0;
}
return (int)this.count(Wrappers.<PeopleDO>lambdaQuery()
.in(dbField, fieldEncrypt ? SecureUtils.encryptFieldByAes(fieldValues) : fieldValues));
}
/**
* 导入用户
*
* @param insertList 新增用户
* @param updateList 修改用户
*/
private void doImportUser(List<PeopleDO> insertList, List<PeopleDO> updateList) {
if (CollUtil.isNotEmpty(insertList)) {
for (PeopleDO peopleDO : insertList) {
peopleDO.setGuid(IdUtil.simpleUUID());
}
baseMapper.insert(insertList);
}
if (CollUtil.isNotEmpty(updateList)) {
SpringUtils.getProxy(this).updateBatchById(updateList);
}
}
/**
* 根据人员身份证获取用户列表
*
* @param peopleIdCards 人员身份证列表
* @return 用户列表
*/
private List<PeopleDO> listByUsernames(List<String> peopleIdCards) {
return this.list(Wrappers.<PeopleDO>lambdaQuery()
.in(PeopleDO::getIdcard, peopleIdCards)
.select(PeopleDO::getId, PeopleDO::getIdcard, PeopleDO::getId));
}
/**
* 判断是否退出导入
*
* @param req 导入参数
* @param list 导入数据
* @param existPeopleIdCards 导入数据中已存在的人员身份证
* @return 是否退出
*/
private boolean isExitImportUser(PeopleImportReq req,
List<PeopleImportRowReq> list,
List<String> existPeopleIdCards) {
return list.stream()
.anyMatch(row -> EXIT.validate(req.getDuplicateUser(), row.getIdcard(), existPeopleIdCards));
}
/**
* 判断是否跳过导入
*
* @param req 导入参数
* @param row 导入数据
* @param existPeopleIdCards 导入数据中已存在的用户名
* @return 是否跳过
*/
private boolean isSkipUserImport(PeopleImportReq req, PeopleImportRowReq row, List<String> existPeopleIdCards) {
return SKIP.validate(req.getDuplicateUser(), row.getIdcard(), existPeopleIdCards);
}
@Override
@ContainerMethod(namespace = ContainerConstants.PEOPLE_NAME, type = MappingType.ORDER_OF_KEYS)
public String getPeopleName(Long id) {
if (null == id) {
return "";
}
PeopleDO peopleDO = baseMapper.lambdaQuery().eq(PeopleDO::getId, id).one();
return peopleDO != null ? peopleDO.getName() : "";
}
@Override
public List<LabelValueResp> getPeopleNameList(PeopleQuery peopleQuery) {
LambdaQueryWrapper<PeopleDO> queryWrapper = new LambdaQueryWrapper<>();
if (StrUtil.isNotBlank(peopleQuery.getName())) {
queryWrapper.like(PeopleDO::getName, peopleQuery.getName());
} else {
queryWrapper.eq(StrUtil.isNotBlank(peopleQuery.getBranchId()), PeopleDO::getBranchId, peopleQuery
.getBranchId());
}
queryWrapper.or().in(CollUtil.isNotEmpty(peopleQuery.getIds()), PeopleDO::getId, peopleQuery.getIds());
queryWrapper.select(PeopleDO::getId, PeopleDO::getName, PeopleDO::getGh);
List<PeopleDO> peopleDOS = baseMapper.selectList(queryWrapper);
return peopleConvert.labelValueList(peopleDOS);
}
@Override
public List<PeopleDO> getIdNamePhoneList() {
return baseMapper.selectPeopleList();
}
}

View File

@@ -0,0 +1,23 @@
package top.mes.admin.production.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import top.continew.starter.data.mp.base.BaseMapper;
import top.mes.admin.production.model.entity.ProductionLineDO;
import org.springframework.stereotype.Repository;
import top.mes.admin.production.model.resp.ProductionLineResp;
/**
* 产线基础 Mapper
*
* @author zc
* @since 2026/06/17 14:07
*/
@Repository
public interface ProductionLineMapper extends BaseMapper<ProductionLineDO> {
IPage<ProductionLineResp> selectProductionLinePage(@Param("page") Page<Object> objectPage, @Param(Constants.WRAPPER) QueryWrapper<ProductionLineDO> queryWrapper);
}

View File

@@ -0,0 +1,68 @@
package top.mes.admin.production.model.entity;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import top.mes.admin.common.model.entity.BaseDO;
import java.io.Serial;
/**
* 产线基础实体
*
* @author zc
* @since 2026/06/17 14:07
*/
@Data
@TableName("sys_production_line")
public class ProductionLineDO extends BaseDO {
@Serial
private static final long serialVersionUID = 1L;
/**
* 产线编码(唯一)
*/
private String lineCode;
/**
* 产线名称
*/
private String lineName;
/**
* 产线类型(字典)
*/
private Integer lineType;
/**
* 所属车间
*/
private String workshop;
/**
* 产线主管人员ID
*/
private Long supervisor;
/**
* 每班产能(件/班)
*/
private Integer capacityPerShift;
/**
* 状态1-启用 0-停用
*/
private Integer status;
/**
* 排序号
*/
private Integer sortOrder;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,61 @@
package top.mes.admin.production.model.query;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import top.continew.starter.data.core.annotation.Query;
import top.continew.starter.data.core.enums.QueryType;
import java.io.Serial;
import java.io.Serializable;
import java.time.*;
/**
* 产线基础查询条件
*
* @author zc
* @since 2026/06/17 14:07
*/
@Data
@Schema(description = "产线基础查询条件")
public class ProductionLineQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 产线编码(唯一)
*/
@Schema(description = "产线编码(唯一)")
@Query(type = QueryType.EQ)
private String lineCode;
/**
* 产线名称
*/
@Schema(description = "产线名称")
@Query(type = QueryType.EQ)
private String lineName;
/**
* 产线类型(字典)
*/
@Schema(description = "产线类型(字典)")
@Query(type = QueryType.EQ)
private Integer lineType;
/**
* 状态1-启用 0-停用
*/
@Schema(description = "状态1-启用 0-停用")
@Query(type = QueryType.EQ)
private Integer status;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@Query(type = QueryType.EQ)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,89 @@
package top.mes.admin.production.model.req;
import jakarta.validation.constraints.*;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import org.hibernate.validator.constraints.Length;
import java.io.Serial;
import java.io.Serializable;
import java.time.*;
/**
* 创建或修改产线基础参数
*
* @author zc
* @since 2026/06/17 14:07
*/
@Data
@Schema(description = "创建或修改产线基础参数")
public class ProductionLineReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 产线编码(唯一)
*/
@Schema(description = "产线编码(唯一)")
@NotBlank(message = "产线编码(唯一)不能为空")
@Length(max = 32, message = "产线编码(唯一)长度不能超过 {max} 个字符")
private String lineCode;
/**
* 产线名称
*/
@Schema(description = "产线名称")
@NotBlank(message = "产线名称不能为空")
@Length(max = 64, message = "产线名称长度不能超过 {max} 个字符")
private String lineName;
/**
* 产线类型(字典)
*/
@Schema(description = "产线类型(字典)")
@NotNull(message = "产线类型(字典)不能为空")
private Integer lineType;
/**
* 所属车间
*/
@Schema(description = "所属车间")
@Length(max = 64, message = "所属车间长度不能超过 {max} 个字符")
private String workshop;
/**
* 产线主管人员ID
*/
@Schema(description = "产线主管人员ID")
private Long supervisor;
/**
* 每班产能(件/班)
*/
@Schema(description = "每班产能(件/班)")
private Integer capacityPerShift;
/**
* 状态1-启用 0-停用
*/
@Schema(description = "状态1-启用 0-停用")
@NotNull(message = "状态1-启用 0-停用不能为空")
private Integer status;
/**
* 排序号
*/
@Schema(description = "排序号")
private Integer sortOrder;
/**
* 备注
*/
@Schema(description = "备注")
@Length(max = 255, message = "备注长度不能超过 {max} 个字符")
private String remark;
}

View File

@@ -0,0 +1,91 @@
package top.mes.admin.production.model.resp;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import top.mes.admin.common.model.resp.BaseDetailResp;
import java.io.Serial;
import java.time.*;
/**
* 产线基础详情信息
*
* @author zc
* @since 2026/06/17 14:07
*/
@Data
@ExcelIgnoreUnannotated
@Schema(description = "产线基础详情信息")
public class ProductionLineDetailResp extends BaseDetailResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 产线编码(唯一)
*/
@Schema(description = "产线编码(唯一)")
@ExcelProperty(value = "产线编码(唯一)")
private String lineCode;
/**
* 产线名称
*/
@Schema(description = "产线名称")
@ExcelProperty(value = "产线名称")
private String lineName;
/**
* 产线类型(字典)
*/
@Schema(description = "产线类型(字典)")
@ExcelProperty(value = "产线类型(字典)")
private Integer lineType;
/**
* 所属车间
*/
@Schema(description = "所属车间")
@ExcelProperty(value = "所属车间")
private String workshop;
/**
* 产线主管人员ID
*/
@Schema(description = "产线主管人员ID")
@ExcelProperty(value = "产线主管人员ID")
private Long supervisor;
/**
* 每班产能(件/班)
*/
@Schema(description = "每班产能(件/班)")
@ExcelProperty(value = "每班产能(件/班)")
private Integer capacityPerShift;
/**
* 状态1-启用 0-停用
*/
@Schema(description = "状态1-启用 0-停用")
@ExcelProperty(value = "状态1-启用 0-停用")
private Integer status;
/**
* 排序号
*/
@Schema(description = "排序号")
@ExcelProperty(value = "排序号")
private Integer sortOrder;
/**
* 备注
*/
@Schema(description = "备注")
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,96 @@
package top.mes.admin.production.model.resp;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import top.mes.admin.common.model.resp.BaseDetailResp;
import java.io.Serial;
import java.time.*;
/**
* 产线基础信息
*
* @author zc
* @since 2026/06/17 14:07
*/
@Data
@Schema(description = "产线基础信息")
public class ProductionLineResp extends BaseDetailResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 产线编码(唯一)
*/
@Schema(description = "产线编码(唯一)")
private String lineCode;
/**
* 产线名称
*/
@Schema(description = "产线名称")
private String lineName;
/**
* 产线类型(字典)
*/
@Schema(description = "产线类型(字典)")
private String lineType;
/**
* 所属车间
*/
@Schema(description = "所属车间")
private String workshop;
/**
* 产线主管人员ID
*/
@Schema(description = "产线主管人员ID")
private Long supervisor;
/**
* 产线主管姓名
*/
@Schema(description = "产线主管姓名")
private String supervisorName;
/**
* 每班产能(件/班)
*/
@Schema(description = "每班产能(件/班)")
private Integer capacityPerShift;
/**
* 状态1-启用 0-停用
*/
@Schema(description = "状态1-启用 0-停用")
private String status;
/**
* 排序号
*/
@Schema(description = "排序号")
private Integer sortOrder;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
/**
* 修改人
*/
@Schema(description = "修改人")
private Long updateUser;
/**
* 修改时间
*/
@Schema(description = "修改时间")
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,17 @@
package top.mes.admin.production.service;
import top.continew.starter.extension.crud.service.BaseService;
import top.mes.admin.production.model.query.ProductionLineQuery;
import top.mes.admin.production.model.req.ProductionLineReq;
import top.mes.admin.production.model.resp.ProductionLineDetailResp;
import top.mes.admin.production.model.resp.ProductionLineResp;
/**
* 产线基础业务接口
*
* @author zc
* @since 2026/06/17 14:07
*/
public interface ProductionLineService extends BaseService<ProductionLineResp, ProductionLineResp, ProductionLineQuery, ProductionLineReq> {
}

View File

@@ -0,0 +1,47 @@
package top.mes.admin.production.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.resp.PageResp;
import top.continew.starter.extension.crud.service.BaseServiceImpl;
import top.mes.admin.production.mapper.ProductionLineMapper;
import top.mes.admin.production.model.entity.ProductionLineDO;
import top.mes.admin.production.model.query.ProductionLineQuery;
import top.mes.admin.production.model.req.ProductionLineReq;
import top.mes.admin.production.model.resp.ProductionLineResp;
import top.mes.admin.production.service.ProductionLineService;
/**
* 产线基础业务实现
*
* @author zc
* @since 2026/06/17 14:07
*/
@Service
@RequiredArgsConstructor
public class ProductionLineServiceImpl extends BaseServiceImpl<ProductionLineMapper, ProductionLineDO, ProductionLineResp, ProductionLineResp, ProductionLineQuery, ProductionLineReq> implements ProductionLineService {
@Override
public PageResp<ProductionLineResp> page(ProductionLineQuery query, PageQuery pageQuery) {
QueryWrapper<ProductionLineDO> queryWrapper = new QueryWrapper<>();
//查询条件
queryWrapper.eq(StrUtil.isNotBlank(query.getLineCode()), "pl.line_code", query.getLineCode());
queryWrapper.like(StrUtil.isNotBlank(query.getLineName()), "pl.line_name", query.getLineName());
queryWrapper.eq(query.getLineType() != null, "pl.line_type", query.getLineType());
queryWrapper.eq(query.getStatus() != null, "pl.status", query.getStatus());
this.sort(queryWrapper, pageQuery);
IPage<ProductionLineResp> page = baseMapper.selectProductionLinePage(new Page<>(pageQuery.getPage(), pageQuery
.getSize()), queryWrapper);
return PageResp.build(page);
}
}

View File

@@ -3,6 +3,7 @@ package top.mes.admin.system.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import top.mes.admin.system.model.entity.LogDO;
@@ -17,6 +18,7 @@ import java.util.List;
* @author Charles7c
* @since 2022/12/22 21:47
*/
@Mapper
public interface LogMapper extends BaseMapper<LogDO> {
/**

View File

@@ -87,9 +87,4 @@ public class UserDO extends BaseDO {
*/
private LocalDateTime pwdResetTime;
/**
* 设备ID
*/
@TableField(exist = false)
private Long equipmentId;
}

View File

@@ -110,12 +110,6 @@ public class UserDetailResp extends BaseDetailResp {
@Schema(description = "最后一次修改密码时间", example = "2023-08-08 08:08:08", type = "string")
private LocalDateTime pwdResetTime;
/**
* 设备ID
*/
@Schema(description = "设备ID")
private Long equipmentId;
@Override
public Boolean getDisabled() {
return this.getIsSystem() || Objects.equals(this.getId(), UserContextHolder.getUserId());

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.mes.admin.peopleBranch.mapper.BranchMapper">
<select id="queryJuniorBranch" resultType="top.mes.admin.peopleBranch.model.resp.BranchResp">
WITH RECURSIVE subdepartments AS (
SELECT id, name, parent_id
FROM sys_branch
WHERE parent_id = #{branchId}
UNION ALL
SELECT d.id, d.name, d.parent_id
FROM sys_branch d
JOIN subdepartments sd ON d.parent_id = sd.id
)
SELECT * FROM subdepartments;
</select>
</mapper>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.mes.admin.peopleBranch.mapper.PeopleMapper">
<resultMap type="PeopleDO" id="SysPeopleResult">
<result property="id" column="id" />
<result property="name" column="name" />
<result property="phone" column="phone" />
<result property="sex" column="sex" />
<result property="avatar" column="avatar" />
<result property="branchId" column="branch_id" />
<result property="position" column="position" />
<result property="idcard" column="idcard" />
<result property="carNo" column="car_no" />
<result property="doorNo" column="door_no" />
<result property="guid" column="guid" />
<result property="faceGuid" column="face_guid" />
<result property="userId" column="user_id" />
<result property="remark" column="remark" />
<result property="createUser" column="create_user" />
<result property="createTime" column="create_time" />
<result property="updateUser" column="update_user" />
<result property="updateTime" column="update_time" />
<result property="gh" column="gh" />
<result property="fingerprint" column="fingerprint" />
<result property="joinTime" column="join_time" />
<result property="down" column="down" />
<result property="openid" column="openid" />
</resultMap>
<select id="selectPeoplePage" resultType="top.mes.admin.peopleBranch.model.resp.PeopleResp">
select
p.*,
b.name as branch_name
from sys_people p
left join sys_branch b on p.branch_id = b.id
${ew.getCustomSqlSegment}
</select>
<select id="selectExportPeople" resultType="top.mes.admin.peopleBranch.model.resp.PeopleResp">
select
p.`name`,
p.phone,
p.gh,
p.sex,
p.position,
p.idcard,
p.door_no,
p.join_time,
b.`name` as branch_name
from sys_people p
left join sys_branch b on p.branch_id = b.id
${ew.getCustomSqlSegment}
</select>
<select id="selectPeopleList" resultMap="SysPeopleResult">
SELECT MIN(id) as id, name, phone
FROM sys_people
GROUP BY name, phone
ORDER BY MIN(create_time) DESC
</select>
</mapper>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.mes.admin.production.mapper.ProductionLineMapper">
<select id="selectProductionLinePage" resultType="top.mes.admin.production.model.resp.ProductionLineResp">
select
pl.*,
p.name supervisorName
from sys_production_line pl left join sys_people p on pl.supervisor = p.id
${ew.customSqlSegment}
</select>
</mapper>

View File

@@ -15,12 +15,12 @@
<script setup lang="ts">
import { useWindowSize } from '@vueuse/core'
import { type ${classNamePrefix}DetailResp, get${classNamePrefix} as getDetail } from '@/apis/${apiModuleName}/${apiName}'
import { type ${classNamePrefix}Resp, get${classNamePrefix} as getDetail } from '@/apis/${apiModuleName}/${apiName}'
const { width } = useWindowSize()
const dataId = ref('')
const dataDetail = ref<${classNamePrefix}DetailResp>()
const dataDetail = ref<${classNamePrefix}Resp>()
const visible = ref(false)
// 查询详情

View File

@@ -11,11 +11,16 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.x.file.storage.core.FileInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.core.exception.BusinessException;
import top.mes.admin.common.constant.CacheConstants;
import top.mes.admin.common.util.PictureUtils;
import top.mes.admin.peopleBranch.model.query.BranchQuery;
import top.mes.admin.peopleBranch.service.BranchService;
import top.mes.admin.system.enums.OptionCategoryEnum;
import top.mes.admin.system.model.query.*;
import top.mes.admin.system.model.resp.file.FileUploadResp;
@@ -43,11 +48,13 @@ import java.util.List;
@RequestMapping("/common")
public class CommonController {
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
private final FileService fileService;
private final DeptService deptService;
private final MenuService menuService;
private final UserService userService;
private final RoleService roleService;
private final BranchService branchService;
private final DictItemService dictItemService;
private final OptionService optionService;
@@ -57,11 +64,11 @@ public class CommonController {
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
FileInfo fileInfo = fileService.upload(file, true);
return FileUploadResp.builder()
.id(fileInfo.getId())
.url(fileInfo.getUrl())
.thUrl(fileInfo.getThUrl())
.metadata(fileInfo.getMetadata())
.build();
.id(fileInfo.getId())
.url(fileInfo.getUrl())
.thUrl(fileInfo.getThUrl())
.metadata(fileInfo.getMetadata())
.build();
}
@Operation(summary = "上传文件", description = "上传文件")
@@ -70,11 +77,11 @@ public class CommonController {
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
FileInfo fileInfo = fileService.upload(file, savePath, null, false, false);
return FileUploadResp.builder()
.id(fileInfo.getId())
.url(fileInfo.getUrl())
.thUrl(fileInfo.getThUrl())
.metadata(fileInfo.getMetadata())
.build();
.id(fileInfo.getId())
.url(fileInfo.getUrl())
.thUrl(fileInfo.getThUrl())
.metadata(fileInfo.getMetadata())
.build();
}
@Operation(summary = "上传文件", description = "上传文件")
@@ -98,17 +105,21 @@ public class CommonController {
// 直接在内存中压缩图片,避免使用临时文件
file = PictureUtils.compressImage(inputStream, file.getOriginalFilename(), quality);
} catch (IOException e) {
throw new RuntimeException(e);
throw new BusinessException("图片异常:压缩失败!");
}
}
FileInfo fileInfo = fileService.upload(file, savePath, null, false, false);
return FileUploadResp.builder()
.id(fileInfo.getId())
.url(fileInfo.getUrl())
.thUrl(fileInfo.getThUrl())
.metadata(fileInfo.getMetadata())
.build();
try {
FileInfo fileInfo = fileService.upload(file, savePath, null, true, true);
return FileUploadResp.builder()
.id(fileInfo.getId())
.url(fileInfo.getUrl())
.thUrl(fileInfo.getThUrl())
.metadata(fileInfo.getMetadata())
.build();
} catch (Exception e) {
throw new BusinessException("图片上传失败!");
}
}
@Operation(summary = "查询部门树", description = "查询树结构的部门列表")
@@ -117,6 +128,12 @@ public class CommonController {
return deptService.tree(query, sortQuery, true);
}
@Operation(summary = "查询部门树", description = "查询树结构的部门列表")
@GetMapping("/tree/branch")
public List<Tree<String>> listBranchTree(BranchQuery query) {
return branchService.tree(query);
}
@Operation(summary = "查询菜单树", description = "查询树结构的菜单列表")
@GetMapping("/tree/menu")
public List<Tree<Long>> listMenuTree(MenuQuery query, SortQuery sortQuery) {

View File

@@ -0,0 +1,82 @@
package top.mes.admin.controller.peopleBranch;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import top.continew.starter.log.annotation.Log;
import top.mes.admin.peopleBranch.model.query.BranchQuery;
import top.mes.admin.peopleBranch.model.req.BranchReq;
import top.mes.admin.peopleBranch.model.resp.BranchResp;
import top.mes.admin.peopleBranch.service.BranchService;
import java.util.List;
/**
* 部门管理管理 API
*
* @author zc
* @since 2025/03/19 17:46
*/
@Tag(name = "部门管理管理 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/sysPeople/branch")
public class BranchController {
private final BranchService branchService;
/**
* 查询部门树形结构
*
* @param branchQuery
* @return
*/
@Log(ignore = true)
@SaCheckPermission("sysPeople:branch:tree")
@GetMapping("/tree")
public List<Tree<String>> selectBranchTree(BranchQuery branchQuery) {
return branchService.selectBranchTree(branchQuery);
}
/**
* 获取部门管理详细信息
*/
@SaCheckPermission("sysPeople:branch:query")
@GetMapping(value = "/{id}")
public BranchResp getInfo(@PathVariable("id") String id) {
return branchService.selectBranchById(id);
}
/**
* 新增部门管理
*/
@SaCheckPermission("sysPeople:branch:add")
@Log(module = "新增部门")
@PostMapping
public String add(@RequestBody BranchReq branchReq) {
return branchService.insertBranch(branchReq);
}
/**
* 修改部门管理
*/
@SaCheckPermission("sysPeople:branch:edit")
@Log(module = "修改部门")
@PutMapping("/{id}")
public void edit(@PathVariable("id") String id, @RequestBody BranchReq branchReq) {
branchService.updateBranch(branchReq, id);
}
/**
* 删除部门管理
*/
@SaCheckPermission("sysPeople:branch:remove")
@Log(module = "删除部门")
@DeleteMapping("/{id}")
public void remove(@PathVariable("id") String id) {
branchService.deleteBranchById(id);
}
}

View File

@@ -0,0 +1,81 @@
package top.mes.admin.controller.peopleBranch;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import top.continew.starter.core.validation.ValidationUtils;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.continew.starter.extension.crud.enums.Api;
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.log.annotation.Log;
import top.mes.admin.common.controller.BaseController;
import top.mes.admin.peopleBranch.model.query.PeopleQuery;
import top.mes.admin.peopleBranch.model.req.PeopleImportReq;
import top.mes.admin.peopleBranch.model.req.PeopleReq;
import top.mes.admin.peopleBranch.model.resp.PeopleImportParseResp;
import top.mes.admin.peopleBranch.model.resp.PeopleImportResp;
import top.mes.admin.peopleBranch.model.resp.PeopleResp;
import top.mes.admin.peopleBranch.service.PeopleService;
import top.mes.admin.system.service.ImportExcelService;
import java.io.IOException;
import java.util.List;
/**
* 人员管理管理 API
*
* @author zc
* @since 2025/03/21 18:10
*/
@Tag(name = "人员管理管理 API")
@RequiredArgsConstructor
@RestController
@Slf4j
@CrudRequestMapping(value = "/sysPeople/people", api = {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
public class PeopleController extends BaseController<PeopleService, PeopleResp, PeopleResp, PeopleQuery, PeopleReq> {
private final ImportExcelService importExcelService;
@GetMapping(value = "/getPeopleNameList")
public List<LabelValueResp> getPeopleNameList(PeopleQuery peopleQuery) {
return baseService.getPeopleNameList(peopleQuery);
}
@Log(ignore = true)
@Operation(summary = "下载导入模板", description = "下载导入模板")
@SaCheckPermission("sysPeople:people:import")
@GetMapping(value = "/import/template", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void downloadImportTemplate(HttpServletResponse response) throws IOException {
importExcelService.downloadImportTemplate(response, "people.xlsx", "人员导入模板.xlsx");
}
//导入相关
@Log(ignore = true)
@Operation(summary = "解析导入数据", description = "解析导入数据")
@SaCheckPermission("sysPeople:people:import")
@PostMapping("/import/parse")
public PeopleImportParseResp parseImport(@NotNull(message = "文件不能为空") MultipartFile file) {
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
return baseService.parseImport(file);
}
@Log(ignore = true)
@Operation(summary = "导入数据", description = "导入数据")
@SaCheckPermission("sysPeople:people:import")
@PostMapping(value = "/import")
public PeopleImportResp importUser(@Validated @RequestBody PeopleImportReq req) {
return baseService.importPeople(req);
}
}

View File

@@ -0,0 +1,29 @@
package top.mes.admin.controller.production;
import top.continew.starter.extension.crud.enums.Api;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import lombok.RequiredArgsConstructor;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.mes.admin.common.controller.BaseController;
import top.mes.admin.production.model.query.ProductionLineQuery;
import top.mes.admin.production.model.req.ProductionLineReq;
import top.mes.admin.production.model.resp.ProductionLineResp;
import top.mes.admin.production.service.ProductionLineService;
/**
* 产线基础管理 API
*
* @author zc
* @since 2026/06/17 14:07
*/
@Tag(name = "产线基础管理 API")
@RestController
@RequiredArgsConstructor
@CrudRequestMapping(value = "/production/productionLine", api = {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
public class ProductionLineController extends BaseController<ProductionLineService, ProductionLineResp, ProductionLineResp, ProductionLineQuery, ProductionLineReq> {
}