Compare commits
24 Commits
e7d892f8a2
...
0f67c55892
Author | SHA1 | Date |
---|---|---|
|
0f67c55892 | |
|
14ee89c4af | |
|
d8c76f97af | |
|
67d943af61 | |
|
dbbd3922f9 | |
|
0548238a18 | |
|
1c136ed302 | |
|
8c7a441662 | |
|
b94f7d3f44 | |
|
d7066714e5 | |
|
a49d01d23a | |
|
351c8e0d8e | |
|
50c343402b | |
|
141c95f63e | |
|
944681f334 | |
|
14428ca9ae | |
|
b188cbd181 | |
|
f84e1b5aa8 | |
|
9723dc0390 | |
|
35fdcf14f6 | |
|
7dbadc7378 | |
|
849754b6c6 | |
|
6e4c96b404 | |
|
4ac2b4314c |
|
@ -59,6 +59,8 @@ public interface Converts {
|
|||
|
||||
List<RoleResp> toRoleResp(List<RoleEntity> list);
|
||||
|
||||
List<UserResp> toUserResp(List<UserEntity> list);
|
||||
|
||||
RoleEntity toRoleEntity(RoleReq req);
|
||||
|
||||
MenuEntity toMenuEntity(MenuReq req);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
|||
package com.dite.znpt.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ApiModel("接受文件夹参数")
|
||||
public class FolderDto {
|
||||
private String name = "tom";
|
||||
private Long parentId = 0L;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.dite.znpt.domain.entity;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("business_data_part")
|
||||
@ApiModel(value="商务资料文件夹对象")
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BusinessDataEntity {
|
||||
|
||||
// 主键
|
||||
private Long folderId = null;
|
||||
// 文件夹名称
|
||||
private String folderName = null;
|
||||
// 父级文件夹
|
||||
private Long parentId = null;
|
||||
// 创建人
|
||||
private Long creatorId = null;
|
||||
// 创建时间
|
||||
private LocalDateTime createTime = null;
|
||||
// 更新时间
|
||||
private LocalDateTime updateTime = null;
|
||||
// 是否删除
|
||||
private Boolean isDeleted = false;
|
||||
// 文件夹路径
|
||||
private String folderPath = null;
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.dite.znpt.domain.entity;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("business_data_part_file")
|
||||
@ApiModel(value="商务资料对象")
|
||||
|
||||
public class BusinessDataFileEntity {
|
||||
|
||||
//文件id
|
||||
private Long fileId = null;
|
||||
//文件夹id
|
||||
private Long folderId = null;
|
||||
//文件名
|
||||
private String fileName = null;
|
||||
//文件路径
|
||||
private String filePath = null;
|
||||
//文件类型
|
||||
private String fileType = "unknown";
|
||||
//文件大小
|
||||
private Long fileSize = null;
|
||||
//上传时间
|
||||
private Date uploadTime = null;
|
||||
//上传人id
|
||||
private Long uploaderId = null;
|
||||
//是否删除
|
||||
private Boolean isDeleted = false;
|
||||
|
||||
}
|
|
@ -13,6 +13,7 @@ import lombok.EqualsAndHashCode;
|
|||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author Bear.G
|
||||
|
@ -50,4 +51,32 @@ public class PostEntity extends AuditableEntity implements Serializable {
|
|||
@ApiModelProperty("备注")
|
||||
@TableField("remark")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@ApiModelProperty("岗位说明")
|
||||
@TableField("statement")
|
||||
private String statement;
|
||||
|
||||
@ApiModelProperty("岗位任务")
|
||||
@TableField("responsibilities_task")
|
||||
private String responsibilitiesTask;
|
||||
|
||||
@ApiModelProperty("岗位任职资格")
|
||||
@TableField("qualifications")
|
||||
private String qualifications;
|
||||
|
||||
@ApiModelProperty("岗位工作条件")
|
||||
@TableField("working_conditions")
|
||||
private String workingConditions;
|
||||
|
||||
@ApiModelProperty("岗位薪资")
|
||||
@TableField("salary")
|
||||
private Double salary;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class ProjectBudgetInfoEntity extends AuditableEntity implements Serializ
|
|||
|
||||
@ExcelProperty("主键")
|
||||
@ApiModelProperty("主键")
|
||||
@TableId(value = "budget_id", type = IdType.ASSIGN_ID)
|
||||
@TableId(value = "budget_id", type = IdType.AUTO)
|
||||
private String budgetId;
|
||||
|
||||
@ExcelProperty("项目id")
|
||||
|
@ -43,8 +43,8 @@ public class ProjectBudgetInfoEntity extends AuditableEntity implements Serializ
|
|||
@TableField("budget_name")
|
||||
private String budgetName;
|
||||
|
||||
@ExcelProperty("预算金额(万元)")
|
||||
@ApiModelProperty("预算金额(万元)")
|
||||
@ExcelProperty("预算花费金额")
|
||||
@ApiModelProperty("预算花费金额")
|
||||
@TableField("budget_amount")
|
||||
private Double budgetAmount;
|
||||
|
||||
|
@ -52,5 +52,10 @@ public class ProjectBudgetInfoEntity extends AuditableEntity implements Serializ
|
|||
@ApiModelProperty("预算说明")
|
||||
@TableField("budget_desc")
|
||||
private String budgetDesc;
|
||||
|
||||
@ExcelProperty("附件")
|
||||
@ApiModelProperty("附件")
|
||||
@TableField("attach")
|
||||
private String attach;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,16 @@ public class ProjectEntity extends AuditableEntity implements Serializable {
|
|||
@TableId(value = "project_id", type = IdType.ASSIGN_UUID)
|
||||
private String projectId;
|
||||
|
||||
@ExcelProperty("项目来源")
|
||||
@ApiModelProperty("项目来源")
|
||||
@TableField("project_origin")
|
||||
private String projectOrigin;
|
||||
|
||||
@ExcelProperty("项目预算")
|
||||
@ApiModelProperty("项目预算")
|
||||
@TableField("project_budget")
|
||||
private Integer projectBudget;
|
||||
|
||||
@ExcelProperty("项目名称")
|
||||
@ApiModelProperty("项目名称")
|
||||
@TableField("project_name")
|
||||
|
@ -169,5 +179,35 @@ public class ProjectEntity extends AuditableEntity implements Serializable {
|
|||
// 施工人员,安全经理,项目经理,商务,财务,高级管理员,项目远程顾问外部协作者,质量经理、现场经理及工作组长。
|
||||
@ApiModelProperty(value = "结束时间")
|
||||
private LocalDate endDate;
|
||||
|
||||
@ApiModelProperty("人工成本")
|
||||
private Double laborCost;
|
||||
|
||||
@ApiModelProperty("设备摊销")
|
||||
private Double equipmentAmortization;
|
||||
|
||||
@ApiModelProperty("奖金预提")
|
||||
private Double bonusProvision;
|
||||
|
||||
@ApiModelProperty("交通食宿")
|
||||
private Double transAccomMeals;
|
||||
|
||||
@ApiModelProperty("其他杂费")
|
||||
private Double othersCost;
|
||||
|
||||
@ApiModelProperty("已用人工成本")
|
||||
private Double useLaborCost;
|
||||
|
||||
@ApiModelProperty("已用设备摊销")
|
||||
private Double useEquipmentAmortization;
|
||||
|
||||
@ApiModelProperty("已用奖金预提")
|
||||
private Double useBonusProvision;
|
||||
|
||||
@ApiModelProperty("已用交通食宿")
|
||||
private Double useTransAccomMeals;
|
||||
|
||||
@ApiModelProperty("已用其他杂费")
|
||||
private Double useOthersCost;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.dite.znpt.domain.page;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PageBean {
|
||||
private Long total;
|
||||
private List<?> rows;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.dite.znpt.domain.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.dite.znpt.util.ValidationGroup;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
@ -33,9 +34,24 @@ public class PostReq implements Serializable {
|
|||
@ApiModelProperty("显示顺序")
|
||||
private Integer postSort;
|
||||
|
||||
@ApiModelProperty("状态(0正常 1停用)")
|
||||
@ApiModelProperty("状态(0停用 1正常)")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty("岗位说明")
|
||||
private String statement;
|
||||
|
||||
@ApiModelProperty("岗位任务")
|
||||
private String responsibilitiesTask;
|
||||
|
||||
@ApiModelProperty("岗位任职资格")
|
||||
private String qualifications;
|
||||
|
||||
@ApiModelProperty("岗位工作条件")
|
||||
private String workingConditions;
|
||||
|
||||
@ApiModelProperty("岗位薪资")
|
||||
private Double salary;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.dite.znpt.domain.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
@ -7,6 +8,7 @@ import lombok.Data;
|
|||
import javax.validation.constraints.Size;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author Bear.G
|
||||
|
@ -41,4 +43,25 @@ public class PostResp implements Serializable {
|
|||
@ApiModelProperty("备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@ApiModelProperty("岗位说明")
|
||||
private String statement;
|
||||
|
||||
@ApiModelProperty("岗位任务")
|
||||
private String responsibilitiesTask;
|
||||
|
||||
@ApiModelProperty("岗位任职资格")
|
||||
private String qualifications;
|
||||
|
||||
@ApiModelProperty("岗位工作条件")
|
||||
private String workingConditions;
|
||||
|
||||
@ApiModelProperty("岗位薪资")
|
||||
private Double salary;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package com.dite.znpt.domain.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@ApiModel("项目预算信息详情")
|
||||
public class ProjectBudgetInfoDetailResp implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 766154886845694269L;
|
||||
|
||||
@ApiModelProperty("项目id")
|
||||
private String projectId;
|
||||
|
||||
@ApiModelProperty("项目名称")
|
||||
private String projectName;
|
||||
|
||||
@ApiModelProperty("项目预算")
|
||||
private Double projectBudget;
|
||||
|
||||
@ApiModelProperty("人工成本")
|
||||
private Double laborCost;
|
||||
|
||||
@ApiModelProperty("设备摊销")
|
||||
private Double equipmentAmortization;
|
||||
|
||||
@ApiModelProperty("奖金预提")
|
||||
private Double bonusProvision;
|
||||
|
||||
@ApiModelProperty("交通食宿")
|
||||
private Double transAccomMeals;
|
||||
|
||||
@ApiModelProperty("其他杂费")
|
||||
private Double othersCost;
|
||||
|
||||
@ApiModelProperty("已用人工成本")
|
||||
private Double useLaborCost;
|
||||
|
||||
@ApiModelProperty("已用设备摊销")
|
||||
private Double useEquipmentAmortization;
|
||||
|
||||
@ApiModelProperty("已用奖金预提")
|
||||
private Double useBonusProvision;
|
||||
|
||||
@ApiModelProperty("已用交通食宿")
|
||||
private Double useTransAccomMeals;
|
||||
|
||||
@ApiModelProperty("已用其他杂费")
|
||||
private Double useOthersCost;
|
||||
|
||||
@ApiModelProperty("剩余预算")
|
||||
private Double restBudget;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.dite.znpt.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
/**
|
||||
* @author huise23
|
||||
* @date 2025/07/17 21:58
|
||||
* @Description: 项目预算信息表导入请求类
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ApiModel(value="ProjectBudgetInfo导入请求对象", description="项目预算信息表")
|
||||
public class ProjectBudgetInfoImportReq implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 580212651388155611L;
|
||||
|
||||
@ExcelProperty(value = "项目Id")
|
||||
private String projectId;
|
||||
|
||||
@ExcelProperty(value = "预算名称")
|
||||
private String budgetName;
|
||||
|
||||
@ExcelProperty(value = "预算花费金额")
|
||||
private Double budgetAmount;
|
||||
|
||||
@ExcelProperty(value = "预算说明")
|
||||
private String budgetDesc;
|
||||
|
||||
@ExcelProperty(value = "附件")
|
||||
private String attach;
|
||||
}
|
|
@ -22,7 +22,7 @@ public class ProjectBudgetInfoListReq implements Serializable {
|
|||
@ApiModelProperty("查询关键字")
|
||||
private String keyword;
|
||||
|
||||
@ApiModelProperty("项目预算信息Id")
|
||||
@ApiModelProperty("项目预算单Id")
|
||||
private String budgetId;
|
||||
|
||||
@ApiModelProperty("项目id")
|
||||
|
@ -31,14 +31,10 @@ public class ProjectBudgetInfoListReq implements Serializable {
|
|||
@ApiModelProperty("预算名称")
|
||||
private String budgetName;
|
||||
|
||||
@ApiModelProperty("预算类型")
|
||||
private String budgetType;
|
||||
|
||||
@ApiModelProperty("预算金额(万元)")
|
||||
@ApiModelProperty("预算花费金额")
|
||||
private Double budgetAmount;
|
||||
|
||||
@ApiModelProperty("预算说明")
|
||||
private String budgetDesc;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.dite.znpt.domain.vo;
|
|||
|
||||
import com.dite.znpt.domain.entity.ProjectBudgetInfoEntity;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
@ -14,6 +15,7 @@ import lombok.EqualsAndHashCode;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel("项目预算信息列表响应实体")
|
||||
public class ProjectBudgetInfoListResp extends ProjectBudgetInfoEntity {
|
||||
|
||||
@ApiModelProperty("项目名称")
|
||||
private String projectName;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,13 +26,13 @@ public class ProjectBudgetInfoReq implements Serializable {
|
|||
@ApiModelProperty("预算名称")
|
||||
private String budgetName;
|
||||
|
||||
@ApiModelProperty("预算金额(万元)")
|
||||
@ApiModelProperty("预算花费金额")
|
||||
private Double budgetAmount;
|
||||
|
||||
@ApiModelProperty("预算说明")
|
||||
private String budgetDesc;
|
||||
|
||||
@ApiModelProperty("附件id")
|
||||
private String attachId;
|
||||
@ApiModelProperty("附件")
|
||||
private String attach;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import lombok.EqualsAndHashCode;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel("项目预算信息响应实体")
|
||||
public class ProjectBudgetInfoResp extends ProjectBudgetInfoEntity {
|
||||
|
||||
@ApiModelProperty("项目名称")
|
||||
private String projectName;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,12 @@ public class ProjectListReq implements Serializable {
|
|||
@ApiModelProperty("项目名称")
|
||||
private String projectName;
|
||||
|
||||
@ApiModelProperty(value = "项目来源")
|
||||
private String projectOrigin;
|
||||
|
||||
@ApiModelProperty(value = "项目预算")
|
||||
private Integer projectBudget;
|
||||
|
||||
@ApiModelProperty("风场名称")
|
||||
private String farmName;
|
||||
|
||||
|
|
|
@ -31,6 +31,12 @@ public class ProjectListResp implements Serializable {
|
|||
@ApiModelProperty("项目名称")
|
||||
private String projectName;
|
||||
|
||||
@ApiModelProperty(value = "项目来源")
|
||||
private String projectOrigin;
|
||||
|
||||
@ApiModelProperty(value = "项目预算")
|
||||
private Integer projectBudget;
|
||||
|
||||
@ApiModelProperty("风场名称")
|
||||
private String farmName;
|
||||
|
||||
|
|
|
@ -28,6 +28,14 @@ public class ProjectReq implements Serializable {
|
|||
@ApiModelProperty("项目id")
|
||||
private String projectId;
|
||||
|
||||
@NotBlank(groups = {ValidationGroup.Insert.class, ValidationGroup.Update.class}, message = "项目来源不能为空")
|
||||
@ApiModelProperty("项目来源")
|
||||
private String projectOrigin;
|
||||
|
||||
@NotBlank(groups = {ValidationGroup.Insert.class, ValidationGroup.Update.class}, message = "项目预算不能为空")
|
||||
@ApiModelProperty("项目预算")
|
||||
private Integer projectBudget;
|
||||
|
||||
@NotBlank(groups = {ValidationGroup.Insert.class, ValidationGroup.Update.class}, message = "项目名称不能为空")
|
||||
@Size(groups = {ValidationGroup.Insert.class, ValidationGroup.Update.class}, max = 50, message = "项目名称长度不能超过50字符")
|
||||
@ApiModelProperty("项目名称")
|
||||
|
@ -105,4 +113,19 @@ public class ProjectReq implements Serializable {
|
|||
|
||||
@ApiModelProperty(value = "结束时间")
|
||||
private LocalDate endDate;
|
||||
|
||||
@ApiModelProperty("人工成本")
|
||||
private Double laborCost;
|
||||
|
||||
@ApiModelProperty("设备摊销")
|
||||
private Double equipmentAmortization;
|
||||
|
||||
@ApiModelProperty("奖金预提")
|
||||
private Double bonusProvision;
|
||||
|
||||
@ApiModelProperty("交通食宿")
|
||||
private Double transAccomMeals;
|
||||
|
||||
@ApiModelProperty("其他杂费")
|
||||
private Double othersCost;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,15 @@ public class ProjectResp extends ProjectReq implements Serializable {
|
|||
@Serial
|
||||
private static final long serialVersionUID = -1883901559600186726L;
|
||||
|
||||
@ApiModelProperty("项目ID")
|
||||
private String projectId;
|
||||
|
||||
@ApiModelProperty("项目来源")
|
||||
private String projectOrigin;
|
||||
|
||||
@ApiModelProperty("项目预算")
|
||||
private Integer projectBudget;
|
||||
|
||||
@ApiModelProperty("施工人员")
|
||||
private String constructorName;
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package com.dite.znpt.mapper;
|
||||
|
||||
import com.dite.znpt.domain.entity.BusinessDataFileEntity;
|
||||
import com.dite.znpt.domain.entity.BusinessDataEntity;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiOperation("商务资料文件对象")
|
||||
public interface BusinessDataFileMapper {
|
||||
public List<BusinessDataFileEntity> List(@Param("folderId") Long folderId, @Param("fileName") String fileName);
|
||||
void delete(@Param("fileId") Long fileId,@Param("folderId") Long folderId);
|
||||
|
||||
void add(BusinessDataFileEntity businessDataFileEntity);
|
||||
|
||||
String getPath(Long fileId);
|
||||
|
||||
// 在接口中添加重命名方法
|
||||
void reName(@Param("fileId") Long fileId, @Param("newFileName") String newFileName, @Param("newFilePath") String newFilePath);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.dite.znpt.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.injector.methods.SelectList;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.dite.znpt.domain.entity.BusinessDataEntity;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import com.dite.znpt.domain.entity.BusinessDataEntity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ApiOperation("商务资料文件夹对象")
|
||||
public interface BusinessDataMapper {
|
||||
public String getPath(Long parentId);
|
||||
|
||||
public List<BusinessDataEntity> List();
|
||||
|
||||
void insert(BusinessDataEntity businessDataEntity);
|
||||
|
||||
void delete(Long folderId);
|
||||
|
||||
void reName(BusinessDataEntity businessDataEntity);
|
||||
|
||||
public List<BusinessDataEntity> ListWithCondition(@Param("folderName") String folderName);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.dite.znpt.service;
|
||||
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.entity.BusinessDataFileEntity;
|
||||
import com.dite.znpt.domain.page.PageBean;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@ApiOperation("商务资料文件service")
|
||||
@Service
|
||||
public interface BusinessDataFileService {
|
||||
|
||||
PageBean pageSelect(Integer page, Integer pageSize, Long folderId, String fileName);
|
||||
|
||||
Result delete(@RequestParam(value = "fileId", required = false) Long fileId,@RequestParam(value = "foldelId", required = false) Long folderId);
|
||||
|
||||
void add(BusinessDataFileEntity businessDataFileEntity);
|
||||
|
||||
String getPath(Long fileId);
|
||||
|
||||
// 在接口中添加重命名方法
|
||||
Result reName(Long fileId, String newFileName);
|
||||
|
||||
// 在接口中添加预览方法
|
||||
// Result preview(Long fileId, HttpServletResponse response);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.dite.znpt.service;
|
||||
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.page.PageBean;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
@ApiOperation("商务资料文件夹service")
|
||||
public interface BusinessDataService {
|
||||
|
||||
PageBean pageSelect(Integer page, Integer pageSize, String folderName);
|
||||
Result createFolder(String folderName, Long parentId);
|
||||
String getPath(Long parentId);
|
||||
Result delete(Long folderId);
|
||||
Result reName(Long folderId, String newName);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.dite.znpt.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public interface EmailService {
|
||||
/**
|
||||
* 发送邮箱验证码
|
||||
* @param email
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public boolean sendVerificationCode(String email, String code);
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
* @param email
|
||||
* @return
|
||||
*/
|
||||
public String generateCode(String email);
|
||||
|
||||
/**
|
||||
* 验证邮箱验证码
|
||||
* @param email
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public boolean verifyCode(String email, String code);
|
||||
|
||||
}
|
|
@ -2,10 +2,8 @@ package com.dite.znpt.service;
|
|||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.dite.znpt.domain.entity.ProjectBudgetInfoEntity;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoListReq;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoListResp;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoReq;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoResp;
|
||||
import com.dite.znpt.domain.vo.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -15,34 +13,16 @@ import java.util.List;
|
|||
* @Description: 项目预算信息表服务接口
|
||||
*/
|
||||
public interface ProjectBudgetInfoService extends IService<ProjectBudgetInfoEntity> {
|
||||
List<ProjectBudgetInfoListResp> list(ProjectBudgetInfoListReq projectBudgetInfoListReq);
|
||||
|
||||
/**
|
||||
* 功能描述:查询项目预算信息列表
|
||||
*
|
||||
* @param projectBudgetInfoReq 项目预算信息
|
||||
* @return {@link List }<{@link ProjectBudgetInfoListResp }>
|
||||
* @author huise23
|
||||
* @date 2025/07/17 21:58
|
||||
**/
|
||||
List<ProjectBudgetInfoListResp> selectList(ProjectBudgetInfoListReq projectBudgetInfoReq);
|
||||
List<ProjectBudgetInfoListResp> page(ProjectBudgetInfoListReq projectBudgetInfoListReq);
|
||||
|
||||
/**
|
||||
* 功能描述:根据项目id获取项目预算信息列表
|
||||
*
|
||||
* @param projectId 项目id
|
||||
* @return {@link List }<{@link ProjectBudgetInfoListResp }>
|
||||
* @author huise23
|
||||
* @date 2025/07/17 21:58
|
||||
**/
|
||||
List<ProjectBudgetInfoResp> detailByProjectId(String projectId);
|
||||
void saveData(ProjectBudgetInfoImportReq req);
|
||||
|
||||
/**
|
||||
* 功能描述:新增项目预算信息
|
||||
*
|
||||
* @param projectBudgetInfoReq 项目预算信息
|
||||
* @author huise23
|
||||
* @date 2025/07/17 21:58
|
||||
**/
|
||||
void saveData(List<ProjectBudgetInfoReq> projectBudgetInfoReq);
|
||||
void saveData(ProjectBudgetInfoImportReq req, MultipartFile[] files);
|
||||
|
||||
ProjectBudgetInfoDetailResp detailByProjectId(String projectId);
|
||||
|
||||
void delete(String budgetId);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||
import com.dite.znpt.domain.entity.PostEntity;
|
||||
import com.dite.znpt.domain.entity.UserPostEntity;
|
||||
import com.dite.znpt.domain.vo.PostResp;
|
||||
import com.dite.znpt.domain.vo.UserResp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -16,4 +17,5 @@ public interface UserPostService extends IService<UserPostEntity> {
|
|||
List<PostResp> getPostsByUserId(String userId);
|
||||
void bindUserPost(String userId, List<String> postIds);
|
||||
void bindPostUser(String postId, List<String> userIds);
|
||||
List<UserResp> getUsersByPostId(String postId);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package com.dite.znpt.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.dite.znpt.domain.entity.UserEntity;
|
||||
import com.dite.znpt.domain.entity.UserRoleEntity;
|
||||
import com.dite.znpt.domain.vo.RoleResp;
|
||||
import com.dite.znpt.domain.vo.UserResp;
|
||||
import com.dite.znpt.domain.vo.UserRoleReq;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -19,4 +21,6 @@ public interface UserRoleService extends IService<UserRoleEntity> {
|
|||
void bindUserRole(UserRoleReq req);
|
||||
|
||||
void bindRoleUser(String roleId, List<String> userIds);
|
||||
|
||||
List<UserResp> getUsersByRoleId(String roleId);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
package com.dite.znpt.service.impl;
|
||||
|
||||
|
||||
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.entity.BusinessDataFileEntity;
|
||||
import com.dite.znpt.domain.page.PageBean;
|
||||
import com.dite.znpt.mapper.BusinessDataFileMapper;
|
||||
import com.dite.znpt.service.BusinessDataFileService;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static jodd.io.FileUtil.deleteFile;
|
||||
import static org.apache.tomcat.util.http.fileupload.FileUtils.deleteDirectory;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
@ApiOperation("商务资料文件service实现类")
|
||||
public class BusinessDataFileServiceImpl implements BusinessDataFileService {
|
||||
@Resource
|
||||
private BusinessDataFileMapper businessDataFileMapper;
|
||||
|
||||
|
||||
@ApiOperation("分页查询文件")
|
||||
@Override
|
||||
public PageBean pageSelect(Integer page, Integer pageSize, Long folderId, String fileName) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
List<BusinessDataFileEntity> list = businessDataFileMapper.List(folderId, fileName);
|
||||
Page<BusinessDataFileEntity> p = (Page<BusinessDataFileEntity>) list;
|
||||
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
|
||||
return pageBean;
|
||||
}
|
||||
@ApiOperation("删除文件")
|
||||
public Result delete(Long fileId, Long folderId) {
|
||||
//删除数据库数据
|
||||
if (folderId != null){
|
||||
businessDataFileMapper.delete(null,folderId);
|
||||
System.out.println("888888888走对了");
|
||||
|
||||
return Result.okM("删除,走对了,成功");
|
||||
}
|
||||
|
||||
//删除文件
|
||||
String sPath = businessDataFileMapper.getPath(fileId);
|
||||
|
||||
businessDataFileMapper.delete(fileId,null);
|
||||
|
||||
boolean flag = false;
|
||||
File file = new File(sPath);
|
||||
// 判断目录或文件是否存在
|
||||
if (!file.exists()) { // 不存在返回 false
|
||||
return Result.error("文件不存在");
|
||||
} else {
|
||||
// 判断是否为文件
|
||||
if (file.isFile()) { // 为文件时调用删除文件方法
|
||||
try {
|
||||
deleteFile(file);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Result.okM("删除成功");
|
||||
} else { // 为目录时调用删除目录方法
|
||||
try {
|
||||
deleteDirectory(file);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Result.okM("删除成功");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ApiOperation("增加文件")
|
||||
public void add(BusinessDataFileEntity businessDataFileEntity) {
|
||||
businessDataFileMapper.add(businessDataFileEntity);
|
||||
}
|
||||
|
||||
@ApiOperation("获取文件路径")
|
||||
public String getPath(Long fileId) {
|
||||
return businessDataFileMapper.getPath(fileId);
|
||||
}
|
||||
|
||||
@ApiOperation("重命名文件")
|
||||
@Override
|
||||
public Result reName(Long fileId, String newFileName) {
|
||||
// 参数校验
|
||||
if (fileId == null) {
|
||||
return Result.error("文件ID不能为空");
|
||||
}
|
||||
if (newFileName == null || newFileName.trim().isEmpty()) {
|
||||
return Result.error("新文件名不能为空");
|
||||
}
|
||||
if (newFileName.length() > 100) {
|
||||
return Result.error("文件名过长");
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取原文件信息
|
||||
String oldFilePath = businessDataFileMapper.getPath(fileId);
|
||||
if (oldFilePath == null) {
|
||||
return Result.error("文件不存在");
|
||||
}
|
||||
|
||||
// 创建原文件对象
|
||||
File oldFile = new File(oldFilePath);
|
||||
if (!oldFile.exists()) {
|
||||
return Result.error("文件不存在");
|
||||
}
|
||||
|
||||
// 构建新文件路径
|
||||
String parentPath = oldFile.getParent();
|
||||
String fileExtension = "";
|
||||
String fileNameWithoutExt = newFileName;
|
||||
|
||||
// 获取原文件扩展名
|
||||
int lastDotIndex = oldFile.getName().lastIndexOf('.');
|
||||
if (lastDotIndex > 0) {
|
||||
fileExtension = oldFile.getName().substring(lastDotIndex);
|
||||
}
|
||||
|
||||
// 如果新文件名没有扩展名,则添加原文件扩展名
|
||||
if (!newFileName.contains(".")) {
|
||||
newFileName = newFileName + fileExtension;
|
||||
}
|
||||
|
||||
// 构建新文件路径
|
||||
String newFilePath = parentPath + File.separator + newFileName;
|
||||
File newFile = new File(newFilePath);
|
||||
|
||||
// 检查新文件名是否已存在
|
||||
if (newFile.exists()) {
|
||||
return Result.error("文件名已存在");
|
||||
}
|
||||
|
||||
// 重命名实际文件
|
||||
boolean renameSuccess = oldFile.renameTo(newFile);
|
||||
if (!renameSuccess) {
|
||||
return Result.error("文件重命名失败");
|
||||
}
|
||||
|
||||
// 更新数据库中的文件信息
|
||||
businessDataFileMapper.reName(fileId, newFileName, newFilePath);
|
||||
|
||||
return Result.okM("文件重命名成功");
|
||||
|
||||
} catch (Exception e) {
|
||||
return Result.error("文件重命名失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
package com.dite.znpt.service.impl;
|
||||
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.entity.BusinessDataEntity;
|
||||
import com.dite.znpt.domain.page.PageBean;
|
||||
import com.dite.znpt.mapper.BusinessDataMapper;
|
||||
import com.dite.znpt.service.BusinessDataFileService;
|
||||
import com.dite.znpt.service.BusinessDataService;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商务资料文件夹实现类
|
||||
*/
|
||||
@Service
|
||||
@ApiOperation("商务资料文件夹service实现类")
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BusinessDataServiceImpl implements BusinessDataService {
|
||||
@Resource
|
||||
private BusinessDataMapper businessDataMapper;
|
||||
@Resource
|
||||
private BusinessDataFileService businessDataFileService;
|
||||
|
||||
// 从配置文件中读取基础路径(默认值:D:/upload/businessData)
|
||||
// ,新建文件夹的时候,如果没指定父文件夹Id,就用这个
|
||||
@Value("${file.upload.businessDataPath:D:/upload/businessData}")
|
||||
private String businessDataPath;
|
||||
|
||||
@ApiOperation(value = "分页查询")
|
||||
@Override
|
||||
public PageBean pageSelect(Integer page, Integer pageSize, String folderName) {
|
||||
PageHelper.startPage(page, pageSize);
|
||||
List<BusinessDataEntity> businessDataEntityList = businessDataMapper.ListWithCondition(folderName);
|
||||
Page<BusinessDataEntity> p = (Page<BusinessDataEntity>) businessDataEntityList;
|
||||
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
|
||||
return pageBean;
|
||||
}
|
||||
|
||||
@ApiOperation(value = "创建文件夹")
|
||||
@Override
|
||||
public Result createFolder(String folderName, Long parentId) {
|
||||
//获取ID
|
||||
Long loginIdAsLong = 888L;
|
||||
// loginIdAsLong = StpUtil.getLoginIdAsLong();
|
||||
//
|
||||
// 文件夹名称不能为空
|
||||
//TODO: 添加文件夹名称校验,后续最好更规范些,写个工具类专门校验,用正则表达式
|
||||
if (folderName == null || folderName.trim().isEmpty()) {
|
||||
return Result.error("文件夹名称不能为空");
|
||||
}
|
||||
if (folderName.length() > 50) {
|
||||
return Result.error("文件夹名称过长");
|
||||
}
|
||||
|
||||
// 文件夹名称前置一个/
|
||||
String folderName1 = "/" + folderName;
|
||||
// 目标文件夹
|
||||
File targetDir=Paths.get(businessDataPath, folderName1).toFile();
|
||||
if(parentId != 0L){
|
||||
// 获取父文件夹路径
|
||||
targetDir = Paths.get(businessDataMapper.getPath(parentId), folderName1).toFile();
|
||||
}
|
||||
// 创建文件夹和新增文件夹路径
|
||||
if (!targetDir.exists()) {
|
||||
// 创建文件夹
|
||||
boolean created = targetDir.mkdirs();
|
||||
if (!created) {
|
||||
throw new RuntimeException("文件夹创建失败: " + targetDir.getAbsolutePath());
|
||||
}
|
||||
//上面是新增文件夹功能,但没有往数据库插入文件夹相关数据,所以下面新增
|
||||
// 创建BusinessDataEntity对象并设置属性
|
||||
BusinessDataEntity businessDataEntity = new BusinessDataEntity(
|
||||
null,
|
||||
folderName,
|
||||
parentId,
|
||||
loginIdAsLong,
|
||||
LocalDateTime.now(),
|
||||
LocalDateTime.now(),
|
||||
false,
|
||||
targetDir.getAbsolutePath()
|
||||
);
|
||||
// 插入到数据库
|
||||
businessDataMapper.insert(businessDataEntity);
|
||||
return Result.okM( "文件夹创建成功");
|
||||
} else {
|
||||
return Result.error("文件夹已存在: ");
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("获取文件夹路径")
|
||||
public String getPath(Long parentId) {
|
||||
return businessDataMapper.getPath(parentId);
|
||||
}
|
||||
|
||||
// @ApiOperation("删除文件夹")
|
||||
// @Override
|
||||
// public Result delete(Long folderId) {
|
||||
// // 获取文件夹路径
|
||||
// String folderPath = businessDataMapper.getPath(folderId);
|
||||
//
|
||||
// // 创建File对象并删除文件夹
|
||||
// File folder = new File(folderPath);
|
||||
// if (folder.exists()) {
|
||||
// boolean deleted = folder.delete();
|
||||
// if (!deleted) {
|
||||
// // throw new RuntimeException("文件夹删除失败: " + folderPath);
|
||||
// // TODO: 以后可以用全局异常处理器捕获,或者用try catch捕获
|
||||
// return Result.error("文件夹删除失败: " + folderPath);
|
||||
// }
|
||||
// //删除数据库中文件夹的数据
|
||||
// businessDataMapper.delete(folderId);
|
||||
// //删除文件夹下文件的数据
|
||||
// businessDataFileService.delete(folderId);
|
||||
// return Result.okM("删除成功");
|
||||
// } else {
|
||||
// // throw new RuntimeException("文件夹不存在: " + folderPath);
|
||||
// return Result.error("文件夹不存在: " + folderPath);
|
||||
// }
|
||||
// }
|
||||
@ApiOperation("删除文件夹")
|
||||
@Override
|
||||
public Result delete(Long folderId) {
|
||||
// 获取文件夹路径
|
||||
String folderPath = businessDataMapper.getPath(folderId);
|
||||
|
||||
// 创建Path对象并删除文件夹
|
||||
Path folder = Paths.get(folderPath);
|
||||
if (Files.exists(folder)) {
|
||||
try {
|
||||
// 使用Files.walk获取所有文件和目录,按深度排序后删除
|
||||
java.util.stream.Stream<Path> filePaths = Files.walk(folder);
|
||||
filePaths.sorted(Comparator.reverseOrder())
|
||||
.map(Path::toFile)
|
||||
.forEach(File::delete);
|
||||
filePaths.close();
|
||||
|
||||
//删除数据库中文件夹的数据
|
||||
businessDataMapper.delete(folderId);
|
||||
//删除文件夹下文件的数据
|
||||
businessDataFileService.delete(null , folderId);
|
||||
return Result.okM("删除成功");
|
||||
} catch (Exception e) {
|
||||
return Result.okM("删除成功");
|
||||
}
|
||||
} else {
|
||||
return Result.error("文件夹不存在: " + folderPath);
|
||||
}
|
||||
}
|
||||
@ApiOperation("重命名文件夹")
|
||||
@Override
|
||||
public Result reName(Long folderId, String newName) {
|
||||
// 获取文件夹路径
|
||||
String folderPath = businessDataMapper.getPath(folderId);
|
||||
String newPath = folderPath.substring(0, folderPath.lastIndexOf('\\'))+"\\" + newName;
|
||||
System.out.printf("7777777"+newPath);
|
||||
//
|
||||
// //想命名的原文件的路径
|
||||
// File file = new File("f:/a/a.xlsx");
|
||||
// //将原文件更改为f:\a\b.xlsx,其中路径是必要的。注意
|
||||
// file.renameTo(new File("f:/a/b.xlsx"));
|
||||
//想命名的原文件夹的路径
|
||||
File file1 = new File(folderPath);
|
||||
//将原文件夹更改为A,其中路径是必要的。注意
|
||||
file1.renameTo(new File(newPath));
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
BusinessDataEntity businessDataEntity = new BusinessDataEntity(
|
||||
folderId,
|
||||
newName,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
now,
|
||||
null,
|
||||
newPath
|
||||
);
|
||||
System.out.println(businessDataEntity);
|
||||
businessDataMapper.reName(businessDataEntity);
|
||||
return Result.okM("重命名成功");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.dite.znpt.service.impl;
|
||||
|
||||
import com.dite.znpt.service.EmailService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class EmailServiceImpl implements EmailService {
|
||||
|
||||
@Autowired
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
@Autowired
|
||||
private InMemoryVerificationCodeStore codeStore;
|
||||
|
||||
@Value("${email.verification.from}")
|
||||
private String from;
|
||||
@Value("${email.verification.subject}")
|
||||
private String subject;
|
||||
@Value("${email.verification.template}")
|
||||
private String template;
|
||||
|
||||
@Override
|
||||
public boolean sendVerificationCode(String email, String code) {
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(from);
|
||||
message.setSubject(subject);
|
||||
message.setTo(email);
|
||||
message.setText(String.format(template,code));
|
||||
try{
|
||||
mailSender.send(message);
|
||||
return true;
|
||||
}catch (Exception e){
|
||||
log.error("发送邮件失败:",e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateCode(String email) {
|
||||
if (!codeStore.canSend(email)) {
|
||||
throw new ResponseStatusException(
|
||||
HttpStatus.TOO_MANY_REQUESTS, // 429 状态码
|
||||
"验证码发送过于频繁,请稍后再试"
|
||||
);
|
||||
}
|
||||
|
||||
String code = String.format("%04d", new Random().nextInt(9999));
|
||||
codeStore.save(email, code);
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyCode(String email, String code) {
|
||||
return codeStore.validate(email, code);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.dite.znpt.service.impl;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Component
|
||||
public class InMemoryVerificationCodeStore {
|
||||
|
||||
// 存储邮箱验证码的map
|
||||
private final Map<String,codeInfo> emailCodeMap = new ConcurrentHashMap<>();
|
||||
|
||||
public void save(String email, String code){
|
||||
// 设置五分钟过期
|
||||
emailCodeMap.put(email,new codeInfo(code, LocalDateTime.now().plusMinutes(5)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证验证码
|
||||
* @param email
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public boolean validate(String email, String code){
|
||||
codeInfo codeInfo = emailCodeMap.get(email);
|
||||
if(codeInfo == null){
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isValid = false;
|
||||
if(code.equals(codeInfo.getCode()) && LocalDateTime.now().isBefore(codeInfo.getExpireTime())){
|
||||
isValid = true;
|
||||
}
|
||||
if(isValid){
|
||||
emailCodeMap.remove(email);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断邮箱是否可发送验证码
|
||||
* @param email
|
||||
* @return
|
||||
*/
|
||||
public boolean canSend(String email){
|
||||
codeInfo codeInfo = emailCodeMap.get(email);
|
||||
if(codeInfo != null && LocalDateTime.now().isBefore(codeInfo.getExpireTime())){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class codeInfo {
|
||||
// 验证码
|
||||
private String code;
|
||||
|
||||
// 过期时间
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
// 上一次发送时间
|
||||
private LocalDateTime lastSendTime;
|
||||
|
||||
public codeInfo(String code, LocalDateTime expireTime){
|
||||
this.code = code;
|
||||
this.expireTime = expireTime;
|
||||
this.lastSendTime = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +1,21 @@
|
|||
package com.dite.znpt.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.dite.znpt.domain.entity.ProjectBudgetInfoEntity;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoListReq;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoListResp;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoReq;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoResp;
|
||||
import com.dite.znpt.enums.AttachBusinessTypeEnum;
|
||||
import com.dite.znpt.enums.BudgeTypeEnum;
|
||||
import com.dite.znpt.domain.entity.ProjectEntity;
|
||||
import com.dite.znpt.domain.vo.*;
|
||||
import com.dite.znpt.mapper.ProjectBudgetInfoMapper;
|
||||
import com.dite.znpt.service.AttachInfoService;
|
||||
import com.dite.znpt.service.ProjectBudgetInfoService;
|
||||
import com.dite.znpt.service.ProjectService;
|
||||
import com.dite.znpt.util.PageUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -30,60 +26,98 @@ import java.util.List;
|
|||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProjectBudgetInfoServiceImpl extends ServiceImpl<ProjectBudgetInfoMapper, ProjectBudgetInfoEntity> implements ProjectBudgetInfoService {
|
||||
@Resource
|
||||
ProjectService projectService;
|
||||
|
||||
private final AttachInfoService attachInfoService;
|
||||
@Resource
|
||||
AttachInfoServiceImpl attachInfoService;
|
||||
|
||||
/**
|
||||
* 功能描述:查询项目预算信息列表
|
||||
*
|
||||
* @param projectBudgetInfoReq 项目预算信息信息
|
||||
* @return {@link List }<{@link ProjectBudgetInfoResp }>
|
||||
* @author huise23
|
||||
* @date 2025/07/17 21:58
|
||||
**/
|
||||
@Override
|
||||
public List<ProjectBudgetInfoListResp> selectList(ProjectBudgetInfoListReq projectBudgetInfoReq) {
|
||||
PageUtil.startPage();
|
||||
List<ProjectBudgetInfoListResp> projectBudgetInfoList= this.baseMapper.queryBySelective(projectBudgetInfoReq);
|
||||
projectBudgetInfoList.forEach(resp -> {
|
||||
|
||||
});
|
||||
return projectBudgetInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能描述:根据项目id获取项目预算信息列表
|
||||
*
|
||||
* @param projectId 项目id
|
||||
* @return {@link List }<{@link ProjectBudgetInfoListResp }>
|
||||
* @author huise23
|
||||
* @date 2025/07/17 21:58
|
||||
**/
|
||||
@Override
|
||||
public List<ProjectBudgetInfoResp> detailByProjectId(String projectId) {
|
||||
List<ProjectBudgetInfoResp> projectBudgetInfoList= this.baseMapper.detailByProjectId(projectId);
|
||||
return projectBudgetInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能描述:新增项目预算信息
|
||||
*
|
||||
* @param projectBudgetInfoReq 项目预算信息
|
||||
* @author huise23
|
||||
* @date 2025/07/17 21:58
|
||||
**/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveData(List<ProjectBudgetInfoReq> projectBudgetInfoReq) {
|
||||
List<ProjectBudgetInfoEntity> list = new ArrayList<>();
|
||||
for (ProjectBudgetInfoReq req : projectBudgetInfoReq) {
|
||||
ProjectBudgetInfoEntity info = BeanUtil.copyProperties(req, ProjectBudgetInfoEntity.class);
|
||||
info.setBudgetId(IdUtil.simpleUUID());
|
||||
attachInfoService.updateBusinessIdByAttachIds(info.getBudgetId(), ListUtil.of(req.getAttachId()), AttachBusinessTypeEnum.PROJECT_BUDGE);
|
||||
list.add(info);
|
||||
public List<ProjectBudgetInfoListResp> list(ProjectBudgetInfoListReq req) {
|
||||
List<ProjectBudgetInfoListResp> list = this.baseMapper.queryBySelective(req);
|
||||
if (CollectionUtil.isEmpty(list)) {
|
||||
return Collections.emptyList(); // 返回不可修改的空集合
|
||||
}
|
||||
lambdaUpdate().eq(ProjectBudgetInfoEntity::getProjectId, list.get(0).getProjectId()).remove();
|
||||
baseMapper.insert(list);
|
||||
list.forEach(item -> {
|
||||
item.setProjectName(projectService.getById(item.getProjectId()).getProjectName());
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectBudgetInfoListResp> page(ProjectBudgetInfoListReq req) {
|
||||
PageUtil.startPage();
|
||||
return this.list(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData(ProjectBudgetInfoImportReq req) {
|
||||
ProjectBudgetInfoEntity entity = BeanUtil.copyProperties(req, ProjectBudgetInfoEntity.class);
|
||||
ProjectEntity projectEntity = projectService.getById(req.getProjectId());
|
||||
switch (req.getBudgetName()) {
|
||||
case "人工成本":
|
||||
projectEntity.setUseLaborCost(projectEntity.getUseLaborCost() + req.getBudgetAmount());
|
||||
break;
|
||||
case "设备摊销":
|
||||
projectEntity.setUseEquipmentAmortization(projectEntity.getUseEquipmentAmortization() + req.getBudgetAmount());
|
||||
break;
|
||||
case "奖金预提":
|
||||
projectEntity.setUseBonusProvision(projectEntity.getUseBonusProvision() + req.getBudgetAmount());
|
||||
break;
|
||||
case "交通食宿":
|
||||
projectEntity.setUseTransAccomMeals(projectEntity.getUseTransAccomMeals() + req.getBudgetAmount());
|
||||
break;
|
||||
case "其他杂费":
|
||||
projectEntity.setUseOthersCost(projectEntity.getUseOthersCost() + req.getBudgetAmount());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
projectService.updateById(projectEntity);
|
||||
this.baseMapper.insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData(ProjectBudgetInfoImportReq req, MultipartFile[] files) {
|
||||
ProjectBudgetInfoEntity entity = BeanUtil.copyProperties(req, ProjectBudgetInfoEntity.class);
|
||||
// 把附件存起来,使用已有的附件上传逻辑就行,但我看不懂,pass
|
||||
this.baseMapper.insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectBudgetInfoDetailResp detailByProjectId(String projectId) {
|
||||
ProjectEntity projectEntity = projectService.getById(projectId);
|
||||
ProjectBudgetInfoDetailResp resp = new ProjectBudgetInfoDetailResp();
|
||||
BeanUtil.copyProperties(projectEntity, resp);
|
||||
resp.setRestBudget(resp.getProjectBudget() - resp.getUseLaborCost() - resp.getUseEquipmentAmortization() - resp.getUseBonusProvision() - resp.getUseTransAccomMeals() - resp.getUseOthersCost());
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String budgetId) {
|
||||
ProjectBudgetInfoEntity entity = this.baseMapper.selectById(budgetId);
|
||||
ProjectEntity projectEntity = projectService.getById(entity.getProjectId());
|
||||
switch (entity.getBudgetName()) {
|
||||
case "人工成本":
|
||||
projectEntity.setUseLaborCost(projectEntity.getUseLaborCost() - entity.getBudgetAmount());
|
||||
break;
|
||||
case "设备摊销":
|
||||
projectEntity.setUseEquipmentAmortization(projectEntity.getUseEquipmentAmortization() - entity.getBudgetAmount());
|
||||
break;
|
||||
case "奖金预提":
|
||||
projectEntity.setUseBonusProvision(projectEntity.getUseBonusProvision() - entity.getBudgetAmount());
|
||||
break;
|
||||
case "交通食宿":
|
||||
projectEntity.setUseTransAccomMeals(projectEntity.getUseTransAccomMeals() - entity.getBudgetAmount());
|
||||
break;
|
||||
case "其他杂费":
|
||||
projectEntity.setUseOthersCost(projectEntity.getUseOthersCost() - entity.getBudgetAmount());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
projectService.updateById(projectEntity);
|
||||
this.baseMapper.deleteById(budgetId);
|
||||
// 删除附件
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ import com.dite.znpt.converts.Converts;
|
|||
import com.dite.znpt.domain.entity.PostEntity;
|
||||
import com.dite.znpt.domain.entity.UserEntity;
|
||||
import com.dite.znpt.domain.entity.UserPostEntity;
|
||||
import com.dite.znpt.domain.entity.UserRoleEntity;
|
||||
import com.dite.znpt.domain.vo.PostResp;
|
||||
import com.dite.znpt.domain.vo.UserResp;
|
||||
import com.dite.znpt.exception.ServiceException;
|
||||
import com.dite.znpt.mapper.UserPostMapper;
|
||||
import com.dite.znpt.service.PostService;
|
||||
|
@ -88,4 +90,14 @@ public class UserPostServiceImpl extends ServiceImpl<UserPostMapper, UserPostEnt
|
|||
});
|
||||
this.saveBatch(userPostList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserResp> getUsersByPostId(String postId) {
|
||||
List<String> userIds = this.list(Wrappers.lambdaQuery(UserPostEntity.class).eq(UserPostEntity::getPostId, postId)).stream().map(UserPostEntity::getUserId).toList();
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<UserEntity> users = userService.listByIds(userIds).stream().filter(user -> Constants.DEL_FLAG_0.equals(user.getDelFlag()) && Constants.STATUS_0.equals(user.getStatus())).toList();
|
||||
return Converts.INSTANCE.toUserResp(users);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.dite.znpt.domain.entity.RoleEntity;
|
|||
import com.dite.znpt.domain.entity.UserEntity;
|
||||
import com.dite.znpt.domain.entity.UserRoleEntity;
|
||||
import com.dite.znpt.domain.vo.RoleResp;
|
||||
import com.dite.znpt.domain.vo.UserResp;
|
||||
import com.dite.znpt.domain.vo.UserRoleReq;
|
||||
import com.dite.znpt.exception.ServiceException;
|
||||
import com.dite.znpt.mapper.UserRoleMapper;
|
||||
|
@ -88,4 +89,14 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRoleEnt
|
|||
});
|
||||
this.saveBatch(userRoleList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserResp> getUsersByRoleId(String roleId) {
|
||||
List<String> userIds = this.list(Wrappers.lambdaQuery(UserRoleEntity.class).eq(UserRoleEntity::getRoleId, roleId)).stream().map(UserRoleEntity::getUserId).toList();
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<UserEntity> users = userService.listByIds(userIds).stream().filter(user -> Constants.DEL_FLAG_0.equals(user.getDelFlag()) && Constants.STATUS_0.equals(user.getStatus())).toList();
|
||||
return Converts.INSTANCE.toUserResp(users);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> impleme
|
|||
UserEntity entity = this.getById(userId);
|
||||
UserResp userResp= Converts.INSTANCE.toUserResp(entity);
|
||||
if(StrUtil.isNotBlank(userResp.getDeptId())){
|
||||
userResp.setUserName(entity.getName());
|
||||
userResp.setName(entity.getName());
|
||||
userResp.setDeptName(deptService.getById(userResp.getDeptId()).getDeptName());
|
||||
}
|
||||
userResp.setUserTypeLabel(UserTypeEnum.getDescByCode(userResp.getUserType()));
|
||||
|
@ -198,6 +198,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> impleme
|
|||
if(CollUtil.isNotEmpty(req.getPostIds())){
|
||||
userPostService.bindUserPost(userId, req.getPostIds());
|
||||
}
|
||||
if(CollUtil.isNotEmpty(req.getRoleIds())){
|
||||
userRoleService.bindUserRole(new UserRoleReq().setUserId(userId).setRoleIds(req.getRoleIds()));
|
||||
}
|
||||
this.updateById(entity);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?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="com.dite.znpt.mapper.BusinessDataFileMapper">
|
||||
<select id="List" resultType="com.dite.znpt.domain.entity.BusinessDataFileEntity">
|
||||
select * from business_data_part_file
|
||||
<where>
|
||||
<if test="folderId != null">
|
||||
and folder_id = #{folderId}
|
||||
</if>
|
||||
<if test="fileName != null and fileName != ''">
|
||||
and file_name like concat('%', #{fileName}, '%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<delete id="delete" parameterType="com.dite.znpt.domain.entity.BusinessDataFileEntity" >
|
||||
delete from business_data_part_file
|
||||
<where>
|
||||
<if test="fileId != null">
|
||||
and file_id = #{fileId}
|
||||
</if>
|
||||
<if test="folderId != null ">
|
||||
and folder_id = #{folderId}
|
||||
</if>
|
||||
|
||||
</where>
|
||||
|
||||
</delete>
|
||||
<insert id="add" parameterType="com.dite.znpt.domain.entity.BusinessDataFileEntity">
|
||||
insert into business_data_part_file (file_id, folder_id, file_name, file_path, file_type, file_size, upload_time, uploader_id, is_deleted)
|
||||
values (#{fileId}, #{folderId}, #{fileName}, #{filePath}, #{fileType}, #{fileSize}, #{uploadTime}, #{uploaderId}, #{isDeleted})
|
||||
</insert>
|
||||
<select id="getPath" parameterType="java.lang.Long" resultType="java.lang.String">
|
||||
select file_path from business_data_part_file
|
||||
<where>
|
||||
<if test="fileId != null">
|
||||
and file_id = #{param1}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<!-- 在mapper中添加重命名SQL -->
|
||||
<update id="reName">
|
||||
update business_data_part_file
|
||||
<set>
|
||||
<if test="newFileName != null">file_name = #{newFileName},</if>
|
||||
<if test="newFilePath != null">file_path = #{newFilePath},</if>
|
||||
</set>
|
||||
where file_id = #{fileId}
|
||||
</update>
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?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="com.dite.znpt.mapper.BusinessDataMapper">
|
||||
<insert id="insert" parameterType="com.dite.znpt.domain.entity.BusinessDataEntity">
|
||||
insert into business_data_part
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="folderName != null">folder_name,</if>
|
||||
<if test="parentId != null">parent_id,</if>
|
||||
<if test="creatorId != null">creator_id,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="isDeleted != null">is_deleted,</if>
|
||||
<if test="folderPath != null">folder_path,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="folderName != null">#{folderName},</if>
|
||||
<if test="parentId != null">#{parentId},</if>
|
||||
<if test="creatorId != null">#{creatorId},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="isDeleted != null">#{isDeleted},</if>
|
||||
<if test="folderPath != null">#{folderPath},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<select id="List" resultType="com.dite.znpt.domain.entity.BusinessDataEntity">
|
||||
select * from business_data_part
|
||||
</select>
|
||||
|
||||
<select id="getPath" resultType="java.lang.String">
|
||||
select folder_path from business_data_part where folder_id = #{parentId}
|
||||
</select>
|
||||
|
||||
<delete id="delete">
|
||||
delete from business_data_part where folder_id = #{folderId}
|
||||
</delete>
|
||||
<update id="reName">
|
||||
update business_data_part
|
||||
<set>
|
||||
<if test="folderName != null">folder_name = #{folderName},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="folderPath != null">folder_path = #{folderPath},</if>
|
||||
</set>
|
||||
where folder_id = #{folderId}
|
||||
</update>
|
||||
<select id="ListWithCondition" resultType="com.dite.znpt.domain.entity.BusinessDataEntity">
|
||||
select * from business_data_part
|
||||
<where>
|
||||
<if test="folderName != null and folderName != ''">
|
||||
folder_name like concat('%', #{folderName}, '%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -3,44 +3,24 @@
|
|||
<mapper namespace="com.dite.znpt.mapper.ProjectBudgetInfoMapper">
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
a.budget_id, a.project_id, a.budget_name,
|
||||
a.budget_amount, a.budget_desc, a.update_by, a.create_time,
|
||||
a.create_by, a.update_time
|
||||
a.budget_id, a.project_id, a.budget_name,
|
||||
a.budget_amount, a.budget_desc, a.attach
|
||||
</sql>
|
||||
|
||||
<select id="queryBySelective" resultType="com.dite.znpt.domain.vo.ProjectBudgetInfoListResp">
|
||||
select
|
||||
<include refid="Base_Column_List"/>, p.*
|
||||
<include refid="Base_Column_List"/>, p.*
|
||||
from project_budget_info a
|
||||
left join project p on a.project_id = p.project_id
|
||||
<where>
|
||||
<if test="budgetId != null and budgetId != ''">
|
||||
and a.budget_id like concat ('%', #{budgetId}, '%')
|
||||
</if>
|
||||
<if test="projectId != null and projectId != ''">
|
||||
and a.project_id like concat ('%', #{projectId}, '%')
|
||||
and a.project_id = #{projectId}
|
||||
</if>
|
||||
<if test="budgetName != null and budgetName != ''">
|
||||
and a.budget_name like concat ('%', #{budgetName}, '%')
|
||||
</if>
|
||||
<if test="budgetAmount != null">
|
||||
and a.budget_amount = #{budgetAmount}
|
||||
</if>
|
||||
<if test="budgetDesc != null and budgetDesc != ''">
|
||||
and a.budget_desc like concat ('%', #{budgetDesc}, '%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="detailByProjectId" resultType="com.dite.znpt.domain.vo.ProjectBudgetInfoResp">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from project_budget_info a
|
||||
<where>
|
||||
<if test="_parameter != null and _parameter != ''">
|
||||
and a.project_id like concat ('%', #{projectId}, '%')
|
||||
and a.budget_name = #{budgetName}
|
||||
</if>
|
||||
</where>
|
||||
order by a.project_id, a.budget_name
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
GROUP BY prj.project_id
|
||||
)
|
||||
SELECT
|
||||
prj.project_id, prj.project_name, prj.farm_name, prj.status, prj.cover_url, prj.farm_address, prj.client, prj.client_contact, prj.client_phone, prj.inspection_unit,
|
||||
prj.project_id, prj.project_origin, prj.project_budget, prj.project_name, prj.farm_name, prj.status, prj.cover_url, prj.farm_address, prj.client, prj.client_contact, prj.client_phone, prj.inspection_unit,
|
||||
prj.inspection_contact, prj.inspection_phone, prj.scale, prj.turbine_model, prj.project_manager_id, pm.name AS project_manager_name, prj.constructor_ids,
|
||||
prj.start_date, prj.end_date, con.constructor_name, tp.taskPendingCount, tp.task_progress_count, tp.task_complete_count, tp.task_count, prj.auditor_id,
|
||||
prj.construct_team_leader_id, prj.quality_officer_id
|
||||
|
|
|
@ -8,37 +8,55 @@
|
|||
</sql>
|
||||
|
||||
<select id="queryBySelective" resultType="com.dite.znpt.domain.vo.UserListResp">
|
||||
SELECT u.user_id, u.account, u.status, u.name, u.user_code, u.user_type, u.user_status, d.dept_name, u.mobile, u.create_time,
|
||||
GROUP_CONCAT(r.role_name) AS role_name,GROUP_CONCAT(p.post_name) AS post_name
|
||||
SELECT
|
||||
u.user_id,
|
||||
u.account,
|
||||
u.status,
|
||||
u.name,
|
||||
u.user_code,
|
||||
u.user_type,
|
||||
u.user_status,
|
||||
d.dept_name,
|
||||
u.mobile,
|
||||
u.create_time,
|
||||
(
|
||||
SELECT GROUP_CONCAT(DISTINCT r.role_name)
|
||||
FROM user_role ur
|
||||
JOIN role r ON ur.role_id = r.role_id
|
||||
WHERE ur.user_id = u.user_id
|
||||
) AS role_name,
|
||||
(
|
||||
SELECT GROUP_CONCAT(DISTINCT p.post_name)
|
||||
FROM user_post up
|
||||
JOIN post p ON up.post_id = p.post_id
|
||||
WHERE up.user_id = u.user_id
|
||||
) AS post_name
|
||||
FROM user u
|
||||
LEFT JOIN dept d ON u.dept_id = d.dept_id
|
||||
LEFT JOIN user_role ur ON u.user_id = ur.user_id
|
||||
LEFT JOIN role r ON ur.role_id = r.role_id
|
||||
LEFT JOIN user_post up ON up.user_id = u.user_id
|
||||
LEFT JOIN post p ON p.post_id = up.post_id
|
||||
WHERE u.del_flag = '0'
|
||||
<where>
|
||||
<if test="userCode != null and userCode != ''">
|
||||
AND u.user_code LIKE concat ('%', #{userCode}, '%')
|
||||
AND u.user_code LIKE CONCAT('%', #{userCode}, '%')
|
||||
</if>
|
||||
<if test="account != null and account != ''">
|
||||
AND u.account LIKE concat ('%', #{account}, '%')
|
||||
AND u.account LIKE CONCAT('%', #{account}, '%')
|
||||
</if>
|
||||
<if test="name != null and name != ''">
|
||||
AND u.name LIKE concat ('%', #{name}, '%')
|
||||
AND u.name LIKE CONCAT('%', #{name}, '%')
|
||||
</if>
|
||||
<if test="mobile != null and mobile != ''">
|
||||
AND u.mobile LIKE concat ('%', #{mobile}, '%')
|
||||
AND u.mobile LIKE CONCAT('%', #{mobile}, '%')
|
||||
</if>
|
||||
<if test="deptId != null and deptId != ''">
|
||||
AND d.dept_id = #{deptId}
|
||||
</if>
|
||||
<if test="userStatus != null and userStatus!=''">
|
||||
<if test="userStatus != null and userStatus != ''">
|
||||
AND u.user_status = #{userStatus}
|
||||
</if>
|
||||
<if test="userType != null and userType!=''">
|
||||
<if test="userType != null and userType != ''">
|
||||
AND u.user_Type = #{userType}
|
||||
</if>
|
||||
GROUP BY u.user_id, u.account, u.status, u.name, u.user_code, u.user_type, u.user_status, d.dept_name, u.mobile, u.create_time
|
||||
</where>
|
||||
<!-- 移除了 GROUP BY -->
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
|
|
459
doc/aesDemo.html
459
doc/aesDemo.html
|
@ -1,459 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>AES加密解密工具</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#3b82f6',
|
||||
secondary: '#10b981',
|
||||
accent: '#6366f1',
|
||||
dark: '#1e293b',
|
||||
light: '#f8fafc'
|
||||
},
|
||||
fontFamily: {
|
||||
inter: ['Inter', 'system-ui', 'sans-serif'],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style type="text/tailwindcss">
|
||||
@layer utilities {
|
||||
.content-auto {
|
||||
content-visibility: auto;
|
||||
}
|
||||
.text-shadow {
|
||||
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.card-shadow {
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.transition-custom {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="font-inter bg-gradient-to-br from-light to-blue-50 min-h-screen">
|
||||
<div class="container mx-auto px-4 py-8 max-w-5xl">
|
||||
<!-- 标题区域 -->
|
||||
<header class="mb-12 text-center">
|
||||
<h1 class="text-[clamp(2rem,5vw,3.5rem)] font-bold text-dark mb-3 text-shadow">
|
||||
<i class="fa-solid fa-lock text-primary mr-3"></i>AES加密解密工具
|
||||
</h1>
|
||||
<p class="text-gray-600 text-lg max-w-2xl mx-auto">
|
||||
使用先进的AES加密算法保护您的数据安全,支持多种加密模式和密钥长度
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<main class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<!-- 加密区域 -->
|
||||
<section class="bg-white rounded-2xl p-6 card-shadow transition-custom hover:shadow-xl">
|
||||
<h2 class="text-2xl font-bold text-dark mb-6 flex items-center">
|
||||
<i class="fa-solid fa-shield-lock text-primary mr-2"></i>加密
|
||||
</h2>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label for="plaintext" class="block text-sm font-medium text-gray-700 mb-1">明文</label>
|
||||
<textarea id="plaintext" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary/50 focus:border-primary transition-custom resize-none" rows="4" placeholder="请输入要加密的文本..."></textarea>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="encrypt-key" class="block text-sm font-medium text-gray-700 mb-1">密钥</label>
|
||||
<div class="relative">
|
||||
<input type="text" id="encrypt-key" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary/50 focus:border-primary transition-custom" placeholder="请输入16/24/32字节密钥..." value="1234567890123456">
|
||||
<button type="button" id="generate-key" class="absolute right-2 top-1/2 -translate-y-1/2 text-primary hover:text-primary/80 transition-custom">
|
||||
<i class="fa-solid fa-refresh"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">加密选项</label>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="encrypt-mode" class="block text-xs text-gray-500 mb-1">加密模式</label>
|
||||
<select id="encrypt-mode" class="w-full px-3 py-2 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary/50 focus:border-primary transition-custom">
|
||||
<option value="ECB">ECB</option>
|
||||
<option value="CBC">CBC</option>
|
||||
<option value="CFB">CFB</option>
|
||||
<option value="OFB">OFB</option>
|
||||
<option value="CTR">CTR</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="encrypt-padding" class="block text-xs text-gray-500 mb-1">填充方式</label>
|
||||
<select id="encrypt-padding" class="w-full px-3 py-2 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary/50 focus:border-primary transition-custom">
|
||||
<option value="Pkcs7">PKCS#7</option>
|
||||
<option value="Iso97971">ISO 9797-1</option>
|
||||
<option value="AnsiX923">ANSI X.923</option>
|
||||
<option value="Iso10126">ISO 10126</option>
|
||||
<option value="ZeroPadding">Zero Padding</option>
|
||||
<option value="NoPadding">No Padding</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="iv-container" class="hidden">
|
||||
<label for="encrypt-iv" class="block text-sm font-medium text-gray-700 mb-1">初始化向量(IV)</label>
|
||||
<input type="text" id="encrypt-iv" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary/50 focus:border-primary transition-custom" placeholder="请输入16字节初始化向量...">
|
||||
</div>
|
||||
|
||||
<button id="encrypt-btn" class="w-full bg-primary hover:bg-primary/90 text-white font-medium py-3 px-4 rounded-lg transition-custom transform hover:scale-[1.02] flex items-center justify-center">
|
||||
<i class="fa-solid fa-lock mr-2"></i>加密
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 解密区域 -->
|
||||
<section class="bg-white rounded-2xl p-6 card-shadow transition-custom hover:shadow-xl">
|
||||
<h2 class="text-2xl font-bold text-dark mb-6 flex items-center">
|
||||
<i class="fa-solid fa-unlock text-secondary mr-2"></i>解密
|
||||
</h2>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label for="ciphertext" class="block text-sm font-medium text-gray-700 mb-1">密文</label>
|
||||
<textarea id="ciphertext" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-secondary/50 focus:border-secondary transition-custom resize-none" rows="4" placeholder="请输入要解密的文本..."></textarea>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="decrypt-key" class="block text-sm font-medium text-gray-700 mb-1">密钥</label>
|
||||
<input type="text" id="decrypt-key" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-secondary/50 focus:border-secondary transition-custom" placeholder="请输入16/24/32字节密钥..." value="1234567890123456">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">解密选项</label>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="decrypt-mode" class="block text-xs text-gray-500 mb-1">解密模式</label>
|
||||
<select id="decrypt-mode" class="w-full px-3 py-2 rounded-lg border border-gray-300 focus:ring-2 focus:ring-secondary/50 focus:border-secondary transition-custom">
|
||||
<option value="ECB">ECB</option>
|
||||
<option value="CBC">CBC</option>
|
||||
<option value="CFB">CFB</option>
|
||||
<option value="OFB">OFB</option>
|
||||
<option value="CTR">CTR</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="decrypt-padding" class="block text-xs text-gray-500 mb-1">填充方式</label>
|
||||
<select id="decrypt-padding" class="w-full px-3 py-2 rounded-lg border border-gray-300 focus:ring-2 focus:ring-secondary/50 focus:border-secondary transition-custom">
|
||||
<option value="Pkcs7">PKCS#7</option>
|
||||
<option value="Iso97971">ISO 9797-1</option>
|
||||
<option value="AnsiX923">ANSI X.923</option>
|
||||
<option value="Iso10126">ISO 10126</option>
|
||||
<option value="ZeroPadding">Zero Padding</option>
|
||||
<option value="NoPadding">No Padding</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="decrypt-iv-container" class="hidden">
|
||||
<label for="decrypt-iv" class="block text-sm font-medium text-gray-700 mb-1">初始化向量(IV)</label>
|
||||
<input type="text" id="decrypt-iv" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-secondary/50 focus:border-secondary transition-custom" placeholder="请输入16字节初始化向量...">
|
||||
</div>
|
||||
|
||||
<button id="decrypt-btn" class="w-full bg-secondary hover:bg-secondary/90 text-white font-medium py-3 px-4 rounded-lg transition-custom transform hover:scale-[1.02] flex items-center justify-center">
|
||||
<i class="fa-solid fa-unlock mr-2"></i>解密
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!-- 结果展示区 -->
|
||||
<section class="mt-8 bg-white rounded-2xl p-6 card-shadow">
|
||||
<h2 class="text-2xl font-bold text-dark mb-4 flex items-center">
|
||||
<i class="fa-solid fa-file-text text-accent mr-2"></i>结果
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">加密结果</label>
|
||||
<div class="relative">
|
||||
<textarea id="encrypt-result" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-accent/50 focus:border-accent transition-custom resize-none" rows="4" readonly placeholder="加密结果将显示在这里..."></textarea>
|
||||
<button id="copy-encrypt" class="absolute right-2 top-2 text-gray-500 hover:text-accent transition-custom">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">解密结果</label>
|
||||
<div class="relative">
|
||||
<textarea id="decrypt-result" class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-accent/50 focus:border-accent transition-custom resize-none" rows="4" readonly placeholder="解密结果将显示在这里..."></textarea>
|
||||
<button id="copy-decrypt" class="absolute right-2 top-2 text-gray-500 hover:text-accent transition-custom">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 信息提示区 -->
|
||||
<div id="notification" class="fixed bottom-4 right-4 bg-dark text-white px-6 py-3 rounded-lg shadow-lg transform translate-y-20 opacity-0 transition-all duration-300 flex items-center">
|
||||
<i id="notification-icon" class="fa-solid fa-info-circle mr-2"></i>
|
||||
<span id="notification-message">操作成功</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 加密函数
|
||||
function encrypt() {
|
||||
const plaintext = document.getElementById('plaintext').value.trim();
|
||||
const key = document.getElementById('encrypt-key').value.trim();
|
||||
const mode = document.getElementById('encrypt-mode').value;
|
||||
const padding = document.getElementById('encrypt-padding').value;
|
||||
const iv = document.getElementById('encrypt-iv').value.trim();
|
||||
|
||||
if (!plaintext) {
|
||||
showNotification('请输入明文', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
showNotification('请输入密钥', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取加密模式
|
||||
const modeObj = getModeObject(mode);
|
||||
|
||||
// 获取填充方式
|
||||
const paddingObj = getPaddingObject(padding);
|
||||
|
||||
// 准备加密参数
|
||||
const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
|
||||
let encrypted;
|
||||
|
||||
// 根据模式是否需要IV
|
||||
if (mode === 'ECB') {
|
||||
encrypted = CryptoJS.AES.encrypt(plaintext, keyUtf8, {
|
||||
mode: modeObj,
|
||||
padding: paddingObj
|
||||
});
|
||||
} else {
|
||||
if (!iv) {
|
||||
showNotification('使用该模式需要输入初始化向量(IV)', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const ivUtf8 = CryptoJS.enc.Utf8.parse(iv);
|
||||
encrypted = CryptoJS.AES.encrypt(plaintext, keyUtf8, {
|
||||
iv: ivUtf8,
|
||||
mode: modeObj,
|
||||
padding: paddingObj
|
||||
});
|
||||
}
|
||||
|
||||
// 显示加密结果
|
||||
const encryptedResult = encrypted.toString();
|
||||
document.getElementById('encrypt-result').value = encryptedResult;
|
||||
document.getElementById('ciphertext').value = encryptedResult;
|
||||
|
||||
showNotification('加密成功', 'success');
|
||||
} catch (error) {
|
||||
console.error('加密错误:', error);
|
||||
showNotification('加密失败: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 解密函数
|
||||
function decrypt() {
|
||||
const ciphertext = document.getElementById('ciphertext').value.trim();
|
||||
const key = document.getElementById('decrypt-key').value.trim();
|
||||
const mode = document.getElementById('decrypt-mode').value;
|
||||
const padding = document.getElementById('decrypt-padding').value;
|
||||
const iv = document.getElementById('decrypt-iv').value.trim();
|
||||
|
||||
if (!ciphertext) {
|
||||
showNotification('请输入密文', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
showNotification('请输入密钥', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取解密模式
|
||||
const modeObj = getModeObject(mode);
|
||||
|
||||
// 获取填充方式
|
||||
const paddingObj = getPaddingObject(padding);
|
||||
|
||||
// 准备解密参数
|
||||
const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
|
||||
|
||||
// 根据模式是否需要IV
|
||||
let decrypted;
|
||||
if (mode === 'ECB') {
|
||||
decrypted = CryptoJS.AES.decrypt(ciphertext, keyUtf8, {
|
||||
mode: modeObj,
|
||||
padding: paddingObj
|
||||
});
|
||||
} else {
|
||||
if (!iv) {
|
||||
showNotification('使用该模式需要输入初始化向量(IV)', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const ivUtf8 = CryptoJS.enc.Utf8.parse(iv);
|
||||
decrypted = CryptoJS.AES.decrypt(ciphertext, keyUtf8, {
|
||||
iv: ivUtf8,
|
||||
mode: modeObj,
|
||||
padding: paddingObj
|
||||
});
|
||||
}
|
||||
|
||||
// 显示解密结果
|
||||
const decryptedResult = decrypted.toString(CryptoJS.enc.Utf8);
|
||||
document.getElementById('decrypt-result').value = decryptedResult;
|
||||
|
||||
showNotification('解密成功', 'success');
|
||||
} catch (error) {
|
||||
console.error('解密错误:', error);
|
||||
showNotification('解密失败: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 根据名称获取加密/解密模式对象
|
||||
function getModeObject(modeName) {
|
||||
switch (modeName) {
|
||||
case 'ECB': return CryptoJS.mode.ECB;
|
||||
case 'CBC': return CryptoJS.mode.CBC;
|
||||
case 'CFB': return CryptoJS.mode.CFB;
|
||||
case 'OFB': return CryptoJS.mode.OFB;
|
||||
case 'CTR': return CryptoJS.mode.CTR;
|
||||
default: return CryptoJS.mode.ECB;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据名称获取填充方式对象
|
||||
function getPaddingObject(paddingName) {
|
||||
switch (paddingName) {
|
||||
case 'Pkcs7': return CryptoJS.pad.Pkcs7;
|
||||
case 'Iso97971': return CryptoJS.pad.Iso97971;
|
||||
case 'AnsiX923': return CryptoJS.pad.AnsiX923;
|
||||
case 'Iso10126': return CryptoJS.pad.Iso10126;
|
||||
case 'ZeroPadding': return CryptoJS.pad.ZeroPadding;
|
||||
case 'NoPadding': return CryptoJS.pad.NoPadding;
|
||||
default: return CryptoJS.pad.Pkcs7;
|
||||
}
|
||||
}
|
||||
|
||||
// 生成随机密钥
|
||||
function generateRandomKey(length = 16) {
|
||||
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
let key = "";
|
||||
for (let i = 0; i < length; i++) {
|
||||
key += charset.charAt(Math.floor(Math.random() * charset.length));
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// 显示通知
|
||||
function showNotification(message, type = 'info') {
|
||||
const notification = document.getElementById('notification');
|
||||
const notificationIcon = document.getElementById('notification-icon');
|
||||
const notificationMessage = document.getElementById('notification-message');
|
||||
|
||||
// 设置通知类型
|
||||
notification.className = 'fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg transform translate-y-20 opacity-0 transition-all duration-300 flex items-center';
|
||||
|
||||
if (type === 'success') {
|
||||
notification.classList.add('bg-green-500', 'text-white');
|
||||
notificationIcon.className = 'fa-solid fa-check-circle mr-2';
|
||||
} else if (type === 'error') {
|
||||
notification.classList.add('bg-red-500', 'text-white');
|
||||
notificationIcon.className = 'fa-solid fa-exclamation-circle mr-2';
|
||||
} else {
|
||||
notification.classList.add('bg-dark', 'text-white');
|
||||
notificationIcon.className = 'fa-solid fa-info-circle mr-2';
|
||||
}
|
||||
|
||||
// 设置通知消息
|
||||
notificationMessage.textContent = message;
|
||||
|
||||
// 显示通知
|
||||
setTimeout(() => {
|
||||
notification.classList.remove('translate-y-20', 'opacity-0');
|
||||
}, 10);
|
||||
|
||||
// 3秒后隐藏通知
|
||||
setTimeout(() => {
|
||||
notification.classList.add('translate-y-20', 'opacity-0');
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// 复制到剪贴板
|
||||
function copyToClipboard(elementId) {
|
||||
const element = document.getElementById(elementId);
|
||||
element.select();
|
||||
document.execCommand('copy');
|
||||
showNotification('已复制到剪贴板', 'success');
|
||||
}
|
||||
|
||||
// 模式变更事件处理
|
||||
function handleModeChange() {
|
||||
const encryptMode = document.getElementById('encrypt-mode').value;
|
||||
const decryptMode = document.getElementById('decrypt-mode').value;
|
||||
|
||||
// 显示或隐藏加密IV输入框
|
||||
const encryptIvContainer = document.getElementById('iv-container');
|
||||
if (encryptMode === 'ECB') {
|
||||
encryptIvContainer.classList.add('hidden');
|
||||
} else {
|
||||
encryptIvContainer.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 显示或隐藏解密IV输入框
|
||||
const decryptIvContainer = document.getElementById('decrypt-iv-container');
|
||||
if (decryptMode === 'ECB') {
|
||||
decryptIvContainer.classList.add('hidden');
|
||||
} else {
|
||||
decryptIvContainer.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
// 生成随机密钥
|
||||
document.getElementById('generate-key').addEventListener('click', () => {
|
||||
document.getElementById('encrypt-key').value = generateRandomKey(16);
|
||||
document.getElementById('decrypt-key').value = document.getElementById('encrypt-key').value;
|
||||
showNotification('已生成随机密钥', 'success');
|
||||
});
|
||||
|
||||
// 加密按钮点击事件
|
||||
document.getElementById('encrypt-btn').addEventListener('click', encrypt);
|
||||
|
||||
// 解密按钮点击事件
|
||||
document.getElementById('decrypt-btn').addEventListener('click', decrypt);
|
||||
|
||||
// 复制加密结果
|
||||
document.getElementById('copy-encrypt').addEventListener('click', () => copyToClipboard('encrypt-result'));
|
||||
|
||||
// 复制解密结果
|
||||
document.getElementById('copy-decrypt').addEventListener('click', () => copyToClipboard('decrypt-result'));
|
||||
|
||||
// 模式变更事件
|
||||
document.getElementById('encrypt-mode').addEventListener('change', handleModeChange);
|
||||
document.getElementById('decrypt-mode').addEventListener('change', handleModeChange);
|
||||
|
||||
// 初始化
|
||||
handleModeChange();
|
||||
|
||||
// 添加示例数据
|
||||
document.getElementById('plaintext').value = '这是一个使用AES加密的示例文本,您可以替换为自己的内容。';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
141
pom.xml
141
pom.xml
|
@ -1,53 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.dite.znpt</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>web</module>
|
||||
<module>flowable</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.18</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.24</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.dite.znpt</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>sip</module>
|
||||
<module>web</module>
|
||||
<module>flowable</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- JavaMail邮件依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云短信核心库 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId>
|
||||
<version>4.6.3</version> <!-- 建议使用最新版本 -->
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云短信服务 SDK -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
|
||||
<version>2.1.0</version> <!-- 建议使用最新版本 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Java 11+ 需要额外添加的依赖 -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.18</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.24</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package com.dite.znpt.web.controller;
|
||||
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.dto.FolderDto;
|
||||
import com.dite.znpt.domain.page.PageBean;
|
||||
import com.dite.znpt.service.BusinessDataService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/*
|
||||
* @Description: 商务资料管理,文件夹层
|
||||
* 虽然文件夹本质也是文件,但我们页面上很多地方,光查文件信息,根据文件夹ID
|
||||
* 获取文件列表,如果文件夹和文件都放一张表,不好区分,接口也不好区分,这样分开写方便
|
||||
*/
|
||||
@Api(tags = "文件夹接口")
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("/businessData/folder")
|
||||
@ApiOperation("商务资料管理,文件夹contrller层")
|
||||
public class BusinessDataController {
|
||||
@Resource
|
||||
private BusinessDataService businessDataService;
|
||||
|
||||
@ApiOperation(value = "分页查询文件夹", httpMethod = "GET")
|
||||
@GetMapping("/list")
|
||||
public Result pageSelect(@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String folderName) {
|
||||
PageBean pageBean = businessDataService.pageSelect(page, pageSize, folderName);
|
||||
return Result.ok(pageBean);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "增加文件夹", httpMethod = "POST")
|
||||
@PostMapping("/creatFolder")
|
||||
public Result createFolder(@RequestBody FolderDto folderDto) {
|
||||
return businessDataService.createFolder(folderDto.getName(), folderDto.getParentId());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "删除文件夹", httpMethod = "DELETE")
|
||||
@DeleteMapping("/delete")
|
||||
public Result delete(@RequestParam Long folderId) {
|
||||
|
||||
return businessDataService.delete(folderId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "重命名文件夹", httpMethod = "PUT")
|
||||
@PutMapping("/rename")
|
||||
public Result Rename(@RequestParam Long folderId, @RequestParam String newName) {
|
||||
|
||||
return businessDataService.reName(folderId, newName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
package com.dite.znpt.web.controller;
|
||||
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.entity.BusinessDataFileEntity;
|
||||
import com.dite.znpt.domain.page.PageBean;
|
||||
import com.dite.znpt.mapper.BusinessDataFileMapper;
|
||||
import com.dite.znpt.mapper.BusinessDataMapper;
|
||||
import com.dite.znpt.service.BusinessDataFileService;
|
||||
import com.dite.znpt.service.BusinessDataService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/*
|
||||
* @Description: 商务资料管理,文件夹层
|
||||
*/
|
||||
|
||||
@Api(tags = "文件接口")
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("/businessData/file")
|
||||
@ApiOperation("商务资料管理,文件层")
|
||||
public class BusinessDataFileController {
|
||||
@Resource
|
||||
private BusinessDataFileService businessDataFileService;
|
||||
@Resource
|
||||
private BusinessDataService businessDataService;
|
||||
@Resource
|
||||
private BusinessDataFileMapper businessDataFileMapper;
|
||||
|
||||
@ApiOperation(value = "分页查询文件", httpMethod = "GET")
|
||||
@GetMapping("/list")
|
||||
public Result pageSelect(@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(defaultValue = "0") Long folderId,
|
||||
@RequestParam(required = false) String fileName) {
|
||||
PageBean pageBean = businessDataFileService.pageSelect(page, pageSize, folderId, fileName);
|
||||
return Result.ok(pageBean);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "增加文件")
|
||||
@PostMapping("/add")
|
||||
public Result add(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam Long folderId) {
|
||||
|
||||
if (file.isEmpty()) {
|
||||
return Result.error("上传文件为空");
|
||||
}
|
||||
// TODO 以后可以优化,就算文件名一样,加个(1),(2)这种
|
||||
|
||||
try {
|
||||
byte[] bytes = file.getBytes();
|
||||
String uploadDir = businessDataService.getPath(folderId);
|
||||
|
||||
File uploadedFile = new File(uploadDir + "\\" + file.getOriginalFilename());
|
||||
if (uploadedFile.exists()) {
|
||||
return Result.error("文件已存在");
|
||||
}
|
||||
file.transferTo(uploadedFile);
|
||||
|
||||
// 保存文件信息到数据
|
||||
BusinessDataFileEntity fileEntity = new BusinessDataFileEntity();
|
||||
fileEntity.setFolderId(folderId);
|
||||
fileEntity.setFileName(file.getOriginalFilename());
|
||||
fileEntity.setFilePath(uploadDir + "\\" + file.getOriginalFilename());
|
||||
fileEntity.setFileType(file.getContentType());
|
||||
fileEntity.setFileSize(file.getSize());
|
||||
fileEntity.setUploadTime(new Date());
|
||||
fileEntity.setUploaderId(0L);
|
||||
System.out.println(uploadDir + "\\" + file.getOriginalFilename());
|
||||
businessDataFileService.add(fileEntity);
|
||||
|
||||
return Result.okM("上传成功");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return Result.error("上传失败");
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "删除文件")
|
||||
@DeleteMapping("/delete")
|
||||
public Result delete(@RequestParam Long fileId) {
|
||||
businessDataFileService.delete(fileId, null);
|
||||
return Result.okM("删除成功");
|
||||
}
|
||||
|
||||
@ApiOperation(value = "下载文件")
|
||||
@GetMapping("/download")
|
||||
public void download(@RequestParam("fileId") Long fileId, HttpServletResponse response) {
|
||||
String path = businessDataFileService.getPath(fileId);
|
||||
try {
|
||||
// path是指想要下载的文件的路径
|
||||
File file = new File(path);
|
||||
log.info(file.getPath());
|
||||
// 获取文件名
|
||||
String filename = file.getName();
|
||||
// 获取文件后缀名
|
||||
String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
|
||||
log.info("文件后缀名:" + ext);
|
||||
|
||||
// 将文件写入输入流
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
InputStream fis = new BufferedInputStream(fileInputStream);
|
||||
byte[] buffer = new byte[fis.available()];
|
||||
fis.read(buffer);
|
||||
fis.close();
|
||||
|
||||
// 清空response
|
||||
response.reset();
|
||||
// 设置response的Header
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
|
||||
// 告知浏览器文件的大小
|
||||
response.addHeader("Content-Length", "" + file.length());
|
||||
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
|
||||
response.setContentType("application/octet-stream");
|
||||
outputStream.write(buffer);
|
||||
outputStream.flush();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "重命名文件", httpMethod = "PUT")
|
||||
@PutMapping("/rename")
|
||||
public Result reName(@RequestParam Long fileId, @RequestParam String newFileName) {
|
||||
return businessDataFileService.reName(fileId, newFileName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.dite.znpt.web.controller;
|
||||
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.entity.UserEntity;
|
||||
import com.dite.znpt.service.EmailService;
|
||||
import com.dite.znpt.service.UserService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Api(tags = "邮件")
|
||||
@RestController("/email")
|
||||
public class EmailController {
|
||||
@Resource
|
||||
private EmailService emailService;
|
||||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@ApiOperation(value = "发送邮箱验证码", httpMethod = "POST")
|
||||
@PostMapping("/send")
|
||||
public Result<?> send(@RequestParam("email") String email) {
|
||||
boolean send = emailService.sendVerificationCode(email, emailService.generateCode(email));
|
||||
if (send) {
|
||||
return Result.ok("发送成功");
|
||||
}
|
||||
return Result.error("发送失败");
|
||||
}
|
||||
|
||||
@ApiOperation(value = "验证邮箱验证码", httpMethod = "POST")
|
||||
@PostMapping("/verify")
|
||||
public Result<?> verify(@RequestParam("userId") String userId, @RequestParam("email") String email, @RequestParam("code") String code) {
|
||||
boolean verify = emailService.verifyCode(email, code);
|
||||
if (verify) {
|
||||
UserEntity userEntity = userService.getById(userId);
|
||||
userEntity.setEmail(email);
|
||||
userService.updateById(userEntity);
|
||||
return Result.ok("验证成功");
|
||||
}
|
||||
return Result.error("验证失败");
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
package com.dite.znpt.web.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.dite.znpt.domain.PageResult;
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.vo.PostListReq;
|
||||
import com.dite.znpt.domain.entity.UserPostEntity;
|
||||
import com.dite.znpt.domain.vo.PostReq;
|
||||
import com.dite.znpt.domain.vo.PostResp;
|
||||
import com.dite.znpt.domain.vo.UserResp;
|
||||
import com.dite.znpt.service.PostService;
|
||||
import com.dite.znpt.service.UserPostService;
|
||||
import com.dite.znpt.util.ValidationGroup;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
@ -27,16 +30,19 @@ public class PostController {
|
|||
@Resource
|
||||
private PostService postService;
|
||||
|
||||
@Resource
|
||||
private UserPostService userPostService;
|
||||
|
||||
@ApiOperation(value = "分页查询岗位信息列表", httpMethod = "GET")
|
||||
@GetMapping("/page")
|
||||
public PageResult<PostResp> page(PostListReq req){
|
||||
return PageResult.ok(postService.page(req));
|
||||
public PageResult<PostResp> page(@RequestParam(value = "postName", required = false) String postName){
|
||||
return PageResult.ok(postService.page(postName));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查询岗位信息列表", httpMethod = "GET")
|
||||
@GetMapping("/list")
|
||||
public Result<List<PostResp>> list(PostListReq req){
|
||||
return Result.ok(postService.list(req));
|
||||
public Result<List<PostResp>> list(@RequestParam(value = "postName", required = false) String postName){
|
||||
return Result.ok(postService.list(postName));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查询岗位信息详情", httpMethod = "GET")
|
||||
|
@ -62,8 +68,14 @@ public class PostController {
|
|||
@ApiOperation(value = "删除岗位信息", httpMethod = "DELETE")
|
||||
@DeleteMapping("/{postId}")
|
||||
public Result<?> remove(@PathVariable String postId){
|
||||
userPostService.remove(new QueryWrapper<UserPostEntity>().eq("post_id", postId));
|
||||
postService.deleteById(postId);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@ApiOperation(value="查询属于该岗位的用户", httpMethod = "GET")
|
||||
@GetMapping("/{postId}/user")
|
||||
public Result<List<UserResp>> listUser(@PathVariable String postId){
|
||||
return Result.ok(userPostService.getUsersByPostId(postId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,7 @@ package com.dite.znpt.web.controller;
|
|||
|
||||
import com.dite.znpt.domain.PageResult;
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoListReq;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoListResp;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoReq;
|
||||
import com.dite.znpt.domain.vo.ProjectBudgetInfoResp;
|
||||
import com.dite.znpt.domain.vo.*;
|
||||
import com.dite.znpt.service.ProjectBudgetInfoService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
@ -26,22 +23,35 @@ public class ProjectBudgetInfoController {
|
|||
@Resource
|
||||
private ProjectBudgetInfoService projectBudgetInfoService;
|
||||
|
||||
@ApiOperation(value = "获取项目预算信息列表", httpMethod = "GET")
|
||||
@ApiOperation(value = "筛选项目预算信息列表", httpMethod = "GET")
|
||||
@GetMapping("/list")
|
||||
public PageResult<ProjectBudgetInfoListResp> list(ProjectBudgetInfoListReq projectBudgetInfoReq) {
|
||||
return PageResult.ok(projectBudgetInfoService.selectList(projectBudgetInfoReq));
|
||||
public Result<List<ProjectBudgetInfoListResp>> list(ProjectBudgetInfoListReq projectBudgetInfoListReq) {
|
||||
return Result.ok(projectBudgetInfoService.list(projectBudgetInfoListReq));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "根据项目id获取项目预算信息列表", httpMethod = "GET")
|
||||
@GetMapping("/detail/{projectId}")
|
||||
public PageResult<ProjectBudgetInfoResp> detailByProjectId(@PathVariable String projectId) {
|
||||
return PageResult.ok(projectBudgetInfoService.detailByProjectId(projectId));
|
||||
@ApiOperation(value = "分页筛选项目预算信息列表", httpMethod = "GET")
|
||||
@GetMapping("/page")
|
||||
public PageResult<ProjectBudgetInfoListResp> page(ProjectBudgetInfoListReq projectBudgetInfoListReq) {
|
||||
return PageResult.ok(projectBudgetInfoService.page(projectBudgetInfoListReq));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "保存项目预算信息", httpMethod = "POST")
|
||||
@PostMapping
|
||||
public Result<Object> add(@RequestBody List<ProjectBudgetInfoReq> projectBudgetInfoReq) {
|
||||
projectBudgetInfoService.saveData(projectBudgetInfoReq);
|
||||
@ApiOperation(value = "新增项目预算信息", httpMethod = "POST")
|
||||
@PostMapping("/save")
|
||||
public Result<Void> save(@RequestBody ProjectBudgetInfoImportReq req) {
|
||||
projectBudgetInfoService.saveData(req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "项目预算信息详情", httpMethod = "GET")
|
||||
@GetMapping("/{projectId}/detail")
|
||||
public Result<ProjectBudgetInfoDetailResp> detail(@PathVariable String projectId) {
|
||||
return Result.ok(projectBudgetInfoService.detailByProjectId(projectId));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "删除项目预算信息", httpMethod = "DELETE")
|
||||
@DeleteMapping("/{budgetId}")
|
||||
public Result<Void> delete(@PathVariable String budgetId) {
|
||||
projectBudgetInfoService.delete(budgetId);
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package com.dite.znpt.web.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.dite.znpt.domain.PageResult;
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.entity.UserRoleEntity;
|
||||
import com.dite.znpt.domain.vo.RoleMenuReq;
|
||||
import com.dite.znpt.domain.vo.RoleReq;
|
||||
import com.dite.znpt.domain.vo.RoleResp;
|
||||
import com.dite.znpt.domain.vo.UserResp;
|
||||
import com.dite.znpt.service.RoleMenuService;
|
||||
import com.dite.znpt.service.RoleService;
|
||||
import com.dite.znpt.service.UserRoleService;
|
||||
|
@ -34,6 +37,9 @@ public class RoleController {
|
|||
@Resource
|
||||
private RoleMenuService roleMenuService;
|
||||
|
||||
@Resource
|
||||
private UserRoleService userRoleService;
|
||||
|
||||
@ApiOperation(value = "分页查询角色信息列表", httpMethod = "GET")
|
||||
@GetMapping("/page")
|
||||
public PageResult<RoleResp> page(@RequestParam(value = "roleName", required = false) String roleName){
|
||||
|
@ -69,6 +75,7 @@ public class RoleController {
|
|||
@ApiOperation(value = "删除角色信息", httpMethod = "DELETE")
|
||||
@DeleteMapping("/{roleId}")
|
||||
public Result<?> delete(@PathVariable String roleId){
|
||||
userRoleService.remove(new QueryWrapper<UserRoleEntity>().eq("role_id", roleId));
|
||||
roleService.deleteById(roleId);
|
||||
return Result.ok();
|
||||
}
|
||||
|
@ -79,4 +86,10 @@ public class RoleController {
|
|||
roleMenuService.bindRoleMenu(req);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@ApiOperation(value="查询属于该角色的用户", httpMethod = "GET")
|
||||
@GetMapping("/{roleId}/user")
|
||||
public Result<List<UserResp>> listUser(@PathVariable String roleId){
|
||||
return Result.ok(userRoleService.getUsersByRoleId(roleId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package com.dite.znpt.web.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.dite.znpt.domain.PageResult;
|
||||
import com.dite.znpt.domain.Result;
|
||||
import com.dite.znpt.domain.entity.UserPostEntity;
|
||||
import com.dite.znpt.domain.entity.UserRoleEntity;
|
||||
import com.dite.znpt.domain.vo.*;
|
||||
import com.dite.znpt.service.UserPostService;
|
||||
import com.dite.znpt.service.UserRoleService;
|
||||
import com.dite.znpt.service.UserService;
|
||||
import com.dite.znpt.util.ValidationGroup;
|
||||
|
@ -26,6 +30,8 @@ public class UserController {
|
|||
private UserService userService;
|
||||
@Resource
|
||||
private UserRoleService userRoleService;
|
||||
@Resource
|
||||
private UserPostService userPostService;
|
||||
|
||||
@ApiOperation(value = "分页查询用户信息列表", httpMethod = "GET")
|
||||
@GetMapping("/page")
|
||||
|
@ -68,6 +74,8 @@ public class UserController {
|
|||
@ApiOperation(value = "删除用户信息", httpMethod = "DELETE")
|
||||
@DeleteMapping("/{userId}")
|
||||
public Result<?> remove(@PathVariable String userId) {
|
||||
userRoleService.remove(new QueryWrapper<UserRoleEntity>().eq("user_id", userId));
|
||||
userPostService.remove(new QueryWrapper<UserPostEntity>().eq("user_id", userId));
|
||||
userService.deleteById(userId);
|
||||
return Result.ok();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
|
||||
port: 8888
|
||||
address : 0.0.0.0 # 监听所有网络接口
|
||||
servlet:
|
||||
|
@ -11,6 +12,21 @@ server:
|
|||
|
||||
# 数据源配置
|
||||
spring:
|
||||
mail:
|
||||
host: smtp.qq.com
|
||||
port: 587
|
||||
# 网易邮箱配置
|
||||
# host: smtp.163.com
|
||||
# port: 465
|
||||
username: 2838879363@qq.com
|
||||
password: vtccznivtjrndfci
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
required: true
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
|
@ -88,6 +104,12 @@ spring:
|
|||
# domain:
|
||||
# prefix: /minio/
|
||||
|
||||
email:
|
||||
verification:
|
||||
from: 2838879363@qq.com
|
||||
subject: "注册验证码"
|
||||
template: "您的验证码为:%s,有效期为5分钟。请不要将验证码泄露给他人。"
|
||||
|
||||
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
|
||||
sa-token:
|
||||
# token 名称(同时也是 cookie 名称)
|
||||
|
|
Loading…
Reference in New Issue