feat: 品牌工作室初始化提交
This commit is contained in:
@@ -41,6 +41,8 @@ public enum BpmProcessConstant {
|
||||
|
||||
ARTICLE("新闻投稿"),
|
||||
|
||||
BRAND_STUDIO("品牌工作室"),
|
||||
|
||||
BRANCH_UNION_WEIYUAN_AUTHORIZATION("分工会委员授权")
|
||||
;
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.budwk.app.zhgh.brand.controller;
|
||||
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationAuditDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationRecallDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandApplicationFlowVO;
|
||||
import com.budwk.app.zhgh.brand.service.BrandApplicationFlowService;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@At("/platform/zhgh/brand/flow")
|
||||
public class BrandApplicationFlowController {
|
||||
|
||||
@Inject
|
||||
private BrandApplicationFlowService flowService;
|
||||
|
||||
@At("/process")
|
||||
public Result process(@Param("applicationId") String applicationId) {
|
||||
List<BrandApplicationFlowVO> flowList = flowService.getFlowList(applicationId);
|
||||
return Result.success(flowList);
|
||||
}
|
||||
|
||||
@At("/audit")
|
||||
public Result audit(@Param("..") @Valid BrandApplicationAuditDTO dto) {
|
||||
flowService.audit(dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/recall")
|
||||
public Result recall(@Param("..") BrandApplicationRecallDTO dto) {
|
||||
flowService.recall(dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.budwk.app.zhgh.brand.controller;
|
||||
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.ApplicationProgressVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.ApplicationWarnVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.UnionApplyStatsVO;
|
||||
import com.budwk.app.zhgh.brand.service.BrandApplicationStatisticsService;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@At("/platform/zhgh/brand/statistics")
|
||||
public class BrandApplicationStatisticsController {
|
||||
|
||||
@Inject
|
||||
private BrandApplicationStatisticsService statisticsService;
|
||||
|
||||
@At("/unionStats")
|
||||
public Result selectUnionApplyStats() {
|
||||
List<UnionApplyStatsVO> vos = statisticsService.selectUnionApplyStats();
|
||||
return Result.success(vos);
|
||||
}
|
||||
|
||||
@At("/applyProgress")
|
||||
public Result selectApplyProgressStats() {
|
||||
List<ApplicationProgressVO> vos = statisticsService.selectApplyProgressStats();
|
||||
return Result.success(vos);
|
||||
}
|
||||
|
||||
@At("/applyWarning")
|
||||
public Result selectApplyWarningStats() {
|
||||
List<ApplicationWarnVO> vos = statisticsService.selectApplyWarningStats();
|
||||
return Result.success(vos);
|
||||
}
|
||||
|
||||
@At("/applyCount")
|
||||
public Result selectApplyMapCount() {
|
||||
Map<String, Map<String, Long>> selectApplyMapCount = statisticsService.selectApplyMapCount();
|
||||
return Result.success(selectApplyMapCount);
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package com.budwk.app.zhgh.brand.controller;
|
||||
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.zhgh.brand.convert.BrandStudioApplicationConvert;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationAuditDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationCreateDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationPageDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationUpdateDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.*;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioApplication;
|
||||
import com.budwk.app.zhgh.brand.service.BrandStudioApplicationService;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@At("/platform/zhgh/brand/application")
|
||||
public class BrandStudioApplicationController {
|
||||
|
||||
@Inject
|
||||
private BrandStudioApplicationService applicationService;
|
||||
|
||||
@At("/leader")
|
||||
public Result queryLeaderHonor() {
|
||||
List<LeaderHonorGroupVO> leaderHonorVO = applicationService.queryLeaderHonor();
|
||||
return Result.success(leaderHonorVO);
|
||||
}
|
||||
|
||||
@At("/page")
|
||||
public Result page(@Valid BrandStudioApplicationPageDTO dto) {
|
||||
return Result.success(applicationService.page(dto));
|
||||
}
|
||||
|
||||
@At("/{id}")
|
||||
public Result get(@Param("id") String id) {
|
||||
BrandStudioApplicationVO applicationVO = applicationService.getDetailById(id);
|
||||
return Result.success(applicationVO);
|
||||
}
|
||||
|
||||
@At
|
||||
public Result save(@Param("..") @Valid BrandStudioApplicationCreateDTO dto) {
|
||||
applicationService.save(dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/submitApply")
|
||||
public Result submitApply(@Param("..") @Valid BrandApplicationAuditDTO dto) {
|
||||
applicationService.submitApply(dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/delete")
|
||||
public Result delete(@Param("..") NutMap request) {
|
||||
applicationService.delete((List<String>) request.get("data"));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/update")
|
||||
public Result update(@Param("..") @Valid BrandStudioApplicationUpdateDTO updateDTO) {
|
||||
applicationService.update(updateDTO);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/base")
|
||||
public Result updateBase(@Param("..") BrandStudioApplicationUpdateDTO updateDTO) {
|
||||
BrandStudioApplication entity = BrandStudioApplicationConvert.convert(updateDTO);
|
||||
applicationService.updateIgnoreNull(entity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/auditPage")
|
||||
public Result auditPage(@Valid BrandStudioApplicationPageDTO dto) {
|
||||
// PageResult<BrandStudioApplyFlowVO> page = applicationService.auditPage(dto);
|
||||
return Result.success(applicationService.flowAuditPage(dto));
|
||||
}
|
||||
|
||||
@At("/archive")
|
||||
public Result archive(@Param("ids") List<String> idList) {
|
||||
applicationService.archive(idList);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/honor/{id}")
|
||||
public Result honor(@Param("id") String id) {
|
||||
List<BrandStudioApplicationHonorVO> vos = applicationService.getHonorDetailById(id);
|
||||
return Result.success(vos);
|
||||
}
|
||||
|
||||
@At("/summaryPage")
|
||||
public Result summaryPage(@Valid BrandStudioApplicationPageDTO dto) {
|
||||
return Result.success(applicationService.summaryPage(dto));
|
||||
}
|
||||
|
||||
@At("/honor")
|
||||
public Result updateMemberOrHonor(@Param("..") @Valid BrandStudioApplicationUpdateDTO updateDTO) {
|
||||
applicationService.updateMemberOrHonor(updateDTO);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At("/export")
|
||||
public void export() {
|
||||
applicationService.export();
|
||||
}
|
||||
|
||||
@At("/export/docx/{id}")
|
||||
public void exportDocx(@Param("id") String id, HttpServletResponse response) {
|
||||
applicationService.exportDocx(id, response);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.budwk.app.zhgh.brand.controller;
|
||||
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
@IocBean
|
||||
@At("/platform/zhgh/brand")
|
||||
public class BrandStudioPageController {
|
||||
|
||||
/**
|
||||
* 品牌工作室申请列表页面
|
||||
*/
|
||||
@At("/application/index")
|
||||
@Ok("beetl:/platform/zhgh/brand/application/index.html")
|
||||
public void applicationIndex() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 品牌工作室申请填报页面
|
||||
*/
|
||||
@At("/apply/index")
|
||||
@Ok("beetl:/platform/zhgh/brand/apply/index.html")
|
||||
public void applyIndex() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 品牌工作室审批页面
|
||||
*/
|
||||
@At("/review/index")
|
||||
@Ok("beetl:/platform/zhgh/brand/review/index.html")
|
||||
public void reviewIndex() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 品牌工作室汇总页面
|
||||
*/
|
||||
@At("/summary/index")
|
||||
@Ok("beetl:/platform/zhgh/brand/summary/index.html")
|
||||
public void summaryIndex() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 品牌工作室管理页面
|
||||
*/
|
||||
@At("/office/index")
|
||||
@Ok("beetl:/platform/zhgh/brand/office/index.html")
|
||||
public void officeIndex() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.budwk.app.zhgh.brand.convert;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.budwk.app.zhgh.brand.models.BrandApplicationFlow;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandApplicationFlowVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BrandApplicationFlowConvert {
|
||||
|
||||
public static List<BrandApplicationFlowVO> convertList(List<BrandApplicationFlow> list) {
|
||||
return BeanUtil.copyToList(list, BrandApplicationFlowVO.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.budwk.app.zhgh.brand.convert;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationCreateDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationUpdateDTO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioApplication;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandStudioApplicationVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandStudioApplicationHonorVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BrandStudioApplicationConvert {
|
||||
|
||||
public static BrandStudioApplication convert(BrandStudioApplicationCreateDTO dto) {
|
||||
BrandStudioApplication brandStudioApplication = new BrandStudioApplication();
|
||||
BeanUtil.copyProperties(dto, brandStudioApplication);
|
||||
return brandStudioApplication;
|
||||
}
|
||||
|
||||
public static BrandStudioApplication convert(BrandStudioApplicationUpdateDTO dto) {
|
||||
BrandStudioApplication brandStudioApplication = new BrandStudioApplication();
|
||||
BeanUtil.copyProperties(dto, brandStudioApplication);
|
||||
return brandStudioApplication;
|
||||
}
|
||||
|
||||
public static BrandStudioApplicationVO convert(BrandStudioApplicationHonorVO application) {
|
||||
BrandStudioApplicationVO vo = new BrandStudioApplicationVO();
|
||||
BeanUtil.copyProperties(application, vo);
|
||||
return vo;
|
||||
}
|
||||
|
||||
public static BrandStudioApplicationVO convert(BrandStudioApplication application) {
|
||||
BrandStudioApplicationVO vo = new BrandStudioApplicationVO();
|
||||
BeanUtil.copyProperties(application, vo);
|
||||
return vo;
|
||||
}
|
||||
|
||||
public static List<BrandStudioApplicationVO> convertList(List<BrandStudioApplication> list) {
|
||||
return BeanUtil.copyToList(list, BrandStudioApplicationVO.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.budwk.app.zhgh.brand.convert;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioHonorCreateDTO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioHonor;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandStudioApplicationHonorVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandStudioHonorVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BrandStudioHonorConvert {
|
||||
|
||||
public static List<BrandStudioApplicationHonorVO> convertList(List<BrandStudioHonor> list) {
|
||||
return BeanUtil.copyToList(list, BrandStudioApplicationHonorVO.class);
|
||||
}
|
||||
|
||||
public static List<BrandStudioHonorVO> convertListVO(List<BrandStudioHonor> honorList) {
|
||||
return BeanUtil.copyToList(honorList, BrandStudioHonorVO.class);
|
||||
}
|
||||
|
||||
public static List<BrandStudioHonor> convertListDTO(List<BrandStudioHonorCreateDTO> honorList) {
|
||||
return BeanUtil.copyToList(honorList, BrandStudioHonor.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.budwk.app.zhgh.brand.convert;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioMemberCreateDTO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioMember;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandStudioMemberVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BrandStudioMemberConvert {
|
||||
|
||||
public static List<BrandStudioMember> convertList(List<BrandStudioMemberCreateDTO> list) {
|
||||
return BeanUtil.copyToList(list, BrandStudioMember.class);
|
||||
}
|
||||
|
||||
public static List<BrandStudioMemberVO> convertListVO(List<BrandStudioMember> list) {
|
||||
return BeanUtil.copyToList(list, BrandStudioMemberVO.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 品牌工作室申请审核
|
||||
*/
|
||||
@Data
|
||||
public class BrandApplicationAuditDTO {
|
||||
|
||||
/**
|
||||
* 申请 Id
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 待处理的 状态流 id
|
||||
*/
|
||||
private String flowId;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 流程实例ID
|
||||
*/
|
||||
private String processInstanceId;
|
||||
|
||||
/**
|
||||
* 流程业务ID
|
||||
*/
|
||||
private String processInstanceBusinessId;
|
||||
|
||||
/**
|
||||
* 流程任务ID
|
||||
*/
|
||||
private String processInstanceTaskId;
|
||||
|
||||
/**
|
||||
* 任务审批类型
|
||||
*/
|
||||
private String bpmTaskApprovalType;
|
||||
|
||||
/**
|
||||
* 下一个任务接收人
|
||||
*/
|
||||
private List<String> assignments;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 申请撤回
|
||||
*/
|
||||
@Data
|
||||
public class BrandApplicationFlowRecallDTO {
|
||||
|
||||
/**
|
||||
* 当前流程ID
|
||||
*/
|
||||
@NotBlank(message = "当前流程ID不能为空")
|
||||
private String curFlowId;
|
||||
|
||||
/**
|
||||
* 下个流程ID
|
||||
*/
|
||||
@NotBlank(message = "下个流程ID不能为空")
|
||||
private String nextFlowId;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 申请撤回
|
||||
*/
|
||||
@Data
|
||||
public class BrandApplicationRecallDTO {
|
||||
|
||||
/**
|
||||
* 操作流程 ID
|
||||
*/
|
||||
private String flowId;
|
||||
|
||||
/**
|
||||
* 当前申请 ID
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 流程任务ID
|
||||
*/
|
||||
private String processInstanceTaskId;
|
||||
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.*;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class BrandStudioApplicationCreateDTO {
|
||||
|
||||
/**
|
||||
* 工作室名称
|
||||
*/
|
||||
@NotBlank(message = "工作室名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 工会ID
|
||||
*/
|
||||
@NotBlank(message = "所属工会不能为空")
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 工会名称
|
||||
*/
|
||||
@NotBlank(message = "所属工会不能为空")
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 创建年份(格式:2025)
|
||||
*/
|
||||
@NotBlank(message = "创建年份不能为空")
|
||||
@Pattern(regexp = "^\\d{4}$", message = "创建年份格式必须为4位年份")
|
||||
private String createYear;
|
||||
|
||||
/**
|
||||
* 工作室领衔人
|
||||
*/
|
||||
@NotBlank(message = "领衔人不能为空")
|
||||
@Size(max = 20, message = "领衔人最多20个字符")
|
||||
private String leadPeople;
|
||||
|
||||
/**
|
||||
* 领衔人年龄
|
||||
*/
|
||||
@NotNull(message = "领衔人年龄不能为空")
|
||||
@Min(value = 0, message = "年龄不能小于0")
|
||||
@Max(value = 150, message = "年龄不能超过150")
|
||||
private Integer leadAge;
|
||||
|
||||
/**
|
||||
* 领衔人身份(多个用逗号分隔)
|
||||
*/
|
||||
@NotBlank(message = "领衔人身份不能为空")
|
||||
private String leadIdentity;
|
||||
|
||||
/**
|
||||
* 工作室类型
|
||||
*/
|
||||
@NotBlank(message = "工作室类型不能为空")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 所属赛道
|
||||
*/
|
||||
@NotBlank(message = "赛道不能为空")
|
||||
private String track;
|
||||
|
||||
/**
|
||||
* 工作室具体位置
|
||||
*/
|
||||
@NotBlank(message = "地址不能为空")
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 成员人数
|
||||
*/
|
||||
@NotNull(message = "成员人数不能为空")
|
||||
@Min(value = 1, message = "成员人数至少1人")
|
||||
private Integer memberNum;
|
||||
|
||||
/**
|
||||
* 工作室介绍
|
||||
*/
|
||||
@NotBlank(message = "工作室介绍不能为空")
|
||||
private String introduction;
|
||||
|
||||
/**
|
||||
* 申请状态
|
||||
*/
|
||||
@NotNull(message = "申请状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 是否归档(0-否,1-是)
|
||||
*/
|
||||
private Integer archive;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
private String createName;
|
||||
|
||||
/**
|
||||
* 所属机构ID
|
||||
*/
|
||||
@NotBlank(message = "所属机构不能为空")
|
||||
private String deptid;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
@NotBlank(message = "所属机构不能为空")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 所属领域
|
||||
*/
|
||||
@NotBlank(message = "所属领域不能为空")
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉称号
|
||||
*/
|
||||
@NotBlank(message = "领衔人荣誉不能为空")
|
||||
private String leadHonor;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 工作室成员列表
|
||||
*/
|
||||
@NotEmpty(message = "至少需要1位成员")
|
||||
@Valid
|
||||
private List<BrandStudioMemberCreateDTO> brandStudioMembers;
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 品牌工作室申请表
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
public class BrandStudioApplicationPageDTO extends PageForm {
|
||||
|
||||
private Integer page = 1;
|
||||
|
||||
private Integer limit = 10;
|
||||
|
||||
/**
|
||||
* 工作室ID,主键
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 申请人ID,唯一
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 申请人所属工会ID
|
||||
*/
|
||||
private String unionId;
|
||||
private List<String> unionIds;
|
||||
|
||||
/**
|
||||
* 工会名称
|
||||
*/
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 创建年份(格式如:2025)
|
||||
*/
|
||||
private String createYear;
|
||||
|
||||
/**
|
||||
* 工作室领衔人
|
||||
*/
|
||||
private String leadPeople;
|
||||
|
||||
/**
|
||||
* 领衔人年龄
|
||||
*/
|
||||
private Integer leadAge;
|
||||
|
||||
/**
|
||||
* 领衔人身份,多个身份用逗号分隔
|
||||
*/
|
||||
private String leadIdentity;
|
||||
|
||||
/**
|
||||
* 工作室类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 所属赛道
|
||||
*/
|
||||
private String track;
|
||||
|
||||
/**
|
||||
* 工作室具体位置
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 成员人数
|
||||
*/
|
||||
private Integer memberNum;
|
||||
|
||||
/**
|
||||
* 工作室介绍
|
||||
*/
|
||||
private String introduction;
|
||||
|
||||
/**
|
||||
* 申请进度
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 归档
|
||||
*/
|
||||
private Integer archive;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
private String createName;
|
||||
|
||||
/**
|
||||
* 所属机构
|
||||
*/
|
||||
private String deptid;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 所属领域
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉称号
|
||||
*/
|
||||
private String leadHonor;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 工作流状态
|
||||
*/
|
||||
private Integer processStatus;
|
||||
|
||||
@Override
|
||||
public Integer getPageNumber() {
|
||||
Integer pageNumber = super.getPageNumber();
|
||||
return pageNumber == null ? page : pageNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPageSize() {
|
||||
Integer pageSize = super.getPageSize();
|
||||
return pageSize == null ? limit : pageSize;
|
||||
}
|
||||
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class BrandStudioApplicationUpdateDTO {
|
||||
|
||||
/**
|
||||
* 工作室ID,主键
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 创建年份(格式如:2025)
|
||||
*/
|
||||
private String createYear;
|
||||
|
||||
/**
|
||||
* 工作室领衔人
|
||||
*/
|
||||
private String leadPeople;
|
||||
|
||||
/**
|
||||
* 领衔人年龄
|
||||
*/
|
||||
private Integer leadAge;
|
||||
|
||||
/**
|
||||
* 领衔人身份,多个身份用逗号分隔
|
||||
*/
|
||||
private String leadIdentity;
|
||||
|
||||
/**
|
||||
* 工作室类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 所属赛道
|
||||
*/
|
||||
private String track;
|
||||
|
||||
/**
|
||||
* 工作室具体位置
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 成员人数
|
||||
*/
|
||||
private Integer memberNum;
|
||||
|
||||
/**
|
||||
* 工作室介绍
|
||||
*/
|
||||
private String introduction;
|
||||
|
||||
/**
|
||||
* 申请进度
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 归档
|
||||
*/
|
||||
private Integer archive;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
private String createName;
|
||||
|
||||
/**
|
||||
* 所属机构
|
||||
*/
|
||||
private String deptid;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 所属领域
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉称号
|
||||
*/
|
||||
private String leadHonor;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 添加的成员
|
||||
* */
|
||||
private List<BrandStudioMemberCreateDTO> brandStudioMembers;
|
||||
|
||||
private List<BrandStudioHonorCreateDTO> brandStudioHonors;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BrandStudioHonorCreateDTO {
|
||||
|
||||
/**
|
||||
* 工作室申请ID
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 荣誉称号
|
||||
*/
|
||||
private String honorName;
|
||||
|
||||
/**
|
||||
* 级别
|
||||
*/
|
||||
private String honorGrade;
|
||||
|
||||
/**
|
||||
* 获取年份
|
||||
*/
|
||||
private String requireYear;
|
||||
|
||||
/**
|
||||
* 荣誉类别:外部荣誉,行内荣誉
|
||||
* 通常可定义为枚举或常量:
|
||||
* 例如:1 - 外部荣誉,2 - 行内荣誉
|
||||
*/
|
||||
private Short honorCategory;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 工作室成员信息表实体类
|
||||
*/
|
||||
@Data
|
||||
public class BrandStudioMemberCreateDTO {
|
||||
|
||||
/**
|
||||
* 工作室ID(外键,关联到 BrandStudioApplication)
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 用户 ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户 工号
|
||||
*/
|
||||
private String emplid;
|
||||
|
||||
/**
|
||||
* 成员姓名
|
||||
*/
|
||||
@NotBlank(message = "成员姓名不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 成员角色(如:核心成员、技术骨干、助理等)
|
||||
*/
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 成员出生年月(建议格式:yyyy-MM 或 yyyy,实际为字符串存储)
|
||||
*/
|
||||
@NotBlank(message = "成员出生年月不能为空")
|
||||
private String birthdate;
|
||||
|
||||
/**
|
||||
* 学历(如:本科、硕士、博士等)
|
||||
*/
|
||||
@NotBlank(message = "学历不能为空")
|
||||
private String grade;
|
||||
|
||||
/**
|
||||
* 职称(如:高级工程师、教授、技师等)
|
||||
*/
|
||||
@NotBlank(message = "职称不能为空")
|
||||
private String professional;
|
||||
|
||||
/**
|
||||
* 所在部门
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 加入日期
|
||||
*/
|
||||
private LocalDateTime joinDate;
|
||||
|
||||
/**
|
||||
* 离开日期(可为空,表示尚未离职)
|
||||
*/
|
||||
private LocalDateTime leaveDate;
|
||||
|
||||
/**
|
||||
* 成员状态:
|
||||
* 0 - 在职,
|
||||
* 1 - 离职
|
||||
*/
|
||||
private Integer status;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.budwk.app.zhgh.brand.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 工作室成员信息表实体类
|
||||
*/
|
||||
@Data
|
||||
public class BrandStudioMemberUpdateDTO {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室ID(外键,关联到 BrandStudioApplication)
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 用户 ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户 工号
|
||||
*/
|
||||
private String emplid;
|
||||
|
||||
/**
|
||||
* 成员姓名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 成员角色(如:核心成员、技术骨干、助理等)
|
||||
*/
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 成员出生年月(建议格式:yyyy-MM 或 yyyy,实际为字符串存储)
|
||||
*/
|
||||
private String birthdate;
|
||||
|
||||
/**
|
||||
* 学历(如:本科、硕士、博士等)
|
||||
*/
|
||||
private String grade;
|
||||
|
||||
/**
|
||||
* 职称(如:高级工程师、教授、技师等)
|
||||
*/
|
||||
private String professional;
|
||||
|
||||
/**
|
||||
* 所在部门
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 加入日期
|
||||
*/
|
||||
private LocalDateTime joinDate;
|
||||
|
||||
/**
|
||||
* 离开日期(可为空,表示尚未离职)
|
||||
*/
|
||||
private LocalDateTime leaveDate;
|
||||
|
||||
/**
|
||||
* 成员状态:
|
||||
* 0 - 在职,
|
||||
* 1 - 离职
|
||||
*/
|
||||
private Integer status;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.budwk.app.zhgh.brand.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 荣誉申请状态
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ApplicationFlowStatusEnum
|
||||
{
|
||||
/**
|
||||
* 等待审核
|
||||
*/
|
||||
WAIT_AUDIT(0),
|
||||
/**
|
||||
* 待审核/审核中
|
||||
*/
|
||||
TO_BE_AUDIT(1),
|
||||
/**
|
||||
* 驳回
|
||||
*/
|
||||
REJECT(2),
|
||||
/**
|
||||
* 撤销
|
||||
*/
|
||||
REPEAL(3),
|
||||
/**
|
||||
* 撤回 -> 取消
|
||||
*/
|
||||
RECALL(4),
|
||||
/**
|
||||
* 通过
|
||||
*/
|
||||
PASSED(5),
|
||||
;
|
||||
|
||||
private final int value;
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态码获取对应的枚举项
|
||||
*
|
||||
* @param value 状态码
|
||||
* @return 对应的枚举,若不存在则返回 null
|
||||
*/
|
||||
public static ApplicationFlowStatusEnum getStatusEnumByValue(int value) {
|
||||
for (ApplicationFlowStatusEnum status : values()) {
|
||||
if (status.value == value) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return null; // 未找到时返回 null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.budwk.app.zhgh.brand.domain.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 品牌工作室申请进度状态枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum BrandApplicationStatusEnums {
|
||||
|
||||
DRAFT(0, "草稿"),
|
||||
IN_REVIEW(1, "审核中/提交申请"),
|
||||
REJECT(2, "驳回"),
|
||||
REPEAL(3, "撤销"),
|
||||
RECALL(4, "撤回"),
|
||||
PASSED(5, "通过"),
|
||||
CREATING(6, "正在创建"),
|
||||
FAIL(7, "创建失败");
|
||||
|
||||
private final int code;
|
||||
private final String description;
|
||||
|
||||
BrandApplicationStatusEnums(int code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态码获取对应的枚举项
|
||||
*
|
||||
* @param code 状态码
|
||||
* @return 对应的枚举,若不存在则返回 null
|
||||
*/
|
||||
public static BrandApplicationStatusEnums getStatusByCode(int code) {
|
||||
for (BrandApplicationStatusEnums status : values()) {
|
||||
if (status.code == code) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return null; // 未找到时返回 null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class ApplicationProgressVO {
|
||||
|
||||
/** 申请单 ID */
|
||||
private Long applicationId;
|
||||
|
||||
/** 申请工作室名称 */
|
||||
private String applicationName;
|
||||
|
||||
/** 申请工会 ID */
|
||||
private String unionId;
|
||||
|
||||
/** 申请人直属工会名称 */
|
||||
private String unionName;
|
||||
|
||||
/** 用户ID */
|
||||
private Long userId;
|
||||
|
||||
/** 申请单状态 */
|
||||
private Integer status;
|
||||
|
||||
/** 牵头人 */
|
||||
private String leadPeople;
|
||||
|
||||
/** 申请时间 */
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 总节点数 */
|
||||
private Integer totalNodes;
|
||||
|
||||
/** 已通过的节点数 */
|
||||
private Integer passedNodes;
|
||||
|
||||
/** 进度百分比(0-100),保留两位小数 */
|
||||
private BigDecimal progressPct;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class ApplicationWarnVO {
|
||||
|
||||
private String applicationId;
|
||||
|
||||
private String name;
|
||||
private String leadPeople;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String unionId;
|
||||
|
||||
private String unionName;
|
||||
|
||||
private LocalDateTime receiveTime;
|
||||
|
||||
private BigDecimal pendingDays;
|
||||
|
||||
private Integer warnStatus;
|
||||
|
||||
private BigDecimal avgAuditDays;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 申请流程 VO
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
public class BrandApplicationFlowVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工会ID
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 工会
|
||||
*/
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 审核人ID
|
||||
*/
|
||||
private String auditorId;
|
||||
|
||||
/**
|
||||
* 审核人
|
||||
*/
|
||||
private String auditor;
|
||||
|
||||
/**
|
||||
* 申请ID
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 状态(0:待审核;1:驳回;2:撤回;3:撤销;4:通过)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 审批内容(意见描述)
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
private Integer sortNo;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BrandFlowUserVO {
|
||||
|
||||
/**
|
||||
* 申请人ID,唯一
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 流程 ID
|
||||
*/
|
||||
private String flowId;
|
||||
|
||||
/**
|
||||
* 流程 状态
|
||||
*/
|
||||
private Integer flowStatus;
|
||||
|
||||
/**
|
||||
* 流程 序号
|
||||
*/
|
||||
private Integer sortNo;
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 品牌工作室荣誉导出写死
|
||||
*/
|
||||
@Data
|
||||
public class BrandStudioApplicationHonorExport {
|
||||
|
||||
private Integer index;
|
||||
|
||||
/**
|
||||
* 工作室名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
|
||||
/**
|
||||
* 创建年份(格式如:2025)
|
||||
*/
|
||||
private String createYear;
|
||||
|
||||
/**
|
||||
* 工作室领衔人
|
||||
*/
|
||||
private String leadPeople;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 荣誉称号
|
||||
*/
|
||||
private String honorName;
|
||||
|
||||
/**
|
||||
* 所属赛道
|
||||
*/
|
||||
private String track;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉称号
|
||||
*/
|
||||
private String leadHonor;
|
||||
|
||||
/**
|
||||
* 成员人数
|
||||
*/
|
||||
private Integer memberNum;
|
||||
|
||||
/**
|
||||
* 工作室具体位置
|
||||
*/
|
||||
private String address;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
||||
/**
|
||||
* 品牌工作室荣誉
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
public class BrandStudioApplicationHonorVO extends BrandStudioApplicationVO {
|
||||
|
||||
/**
|
||||
* 工作室荣誉ID,主键
|
||||
*/
|
||||
private String honorId;
|
||||
|
||||
/**
|
||||
* 荣誉称号
|
||||
*/
|
||||
private String honorName;
|
||||
|
||||
/**
|
||||
* 级别
|
||||
*/
|
||||
private String honorGrade;
|
||||
|
||||
/**
|
||||
* 获取年份
|
||||
*/
|
||||
private String requireYear;
|
||||
|
||||
/**
|
||||
* 荣誉类别:外部荣誉,行内荣誉
|
||||
* 通常可定义为枚举或常量:
|
||||
* 例如:1 - 外部荣誉,2 - 行内荣誉
|
||||
*/
|
||||
private Short honorCategory;
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 品牌工作室
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
public class BrandStudioApplicationVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 工会ID
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 工会名称
|
||||
*/
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 创建年份(格式如:2025)
|
||||
*/
|
||||
private String createYear;
|
||||
|
||||
/**
|
||||
* 工作室领衔人
|
||||
*/
|
||||
private String leadPeople;
|
||||
|
||||
/**
|
||||
* 领衔人年龄
|
||||
*/
|
||||
private Integer leadAge;
|
||||
|
||||
/**
|
||||
* 领衔人身份,多个身份用逗号分隔
|
||||
*/
|
||||
private String leadIdentity;
|
||||
|
||||
/**
|
||||
* 工作室类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 所属赛道
|
||||
*/
|
||||
private String track;
|
||||
|
||||
/**
|
||||
* 工作室具体位置
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 成员人数
|
||||
*/
|
||||
private Integer memberNum;
|
||||
|
||||
/**
|
||||
* 工作室介绍
|
||||
*/
|
||||
private String introduction;
|
||||
|
||||
/**
|
||||
* 申请进度
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 归档
|
||||
*/
|
||||
private Integer archive;
|
||||
|
||||
/**
|
||||
* 流程 ID
|
||||
*/
|
||||
private String flowId;
|
||||
|
||||
/**
|
||||
* 流程 工会名称
|
||||
*/
|
||||
private String flowUnionName;
|
||||
|
||||
/**
|
||||
* 流程 状态
|
||||
*/
|
||||
private Integer flowStatus;
|
||||
|
||||
/**
|
||||
* 流程 序号
|
||||
*/
|
||||
private Integer flowSortNo;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
private String createName;
|
||||
|
||||
/**
|
||||
* 所属机构
|
||||
*/
|
||||
private String deptid;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 所属领域
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉称号
|
||||
*/
|
||||
private String leadHonor;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 添加的成员
|
||||
* */
|
||||
private List<BrandStudioMemberVO> brandStudioMembers;
|
||||
|
||||
/**
|
||||
* 荣誉相关信息
|
||||
* */
|
||||
private List<BrandStudioHonorVO> brandStudioHonors;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 审核返回数据
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
public class BrandStudioApplyFlowVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 工作室名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 工会ID
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 工会名称
|
||||
*/
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 创建年份(格式如:2025)
|
||||
*/
|
||||
private String createYear;
|
||||
|
||||
/**
|
||||
* 工作室领衔人
|
||||
*/
|
||||
private String leadPeople;
|
||||
|
||||
/**
|
||||
* 领衔人年龄
|
||||
*/
|
||||
private Integer leadAge;
|
||||
|
||||
/**
|
||||
* 领衔人身份,多个身份用逗号分隔
|
||||
*/
|
||||
private String leadIdentity;
|
||||
|
||||
/**
|
||||
* 工作室类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 所属赛道
|
||||
*/
|
||||
private String track;
|
||||
|
||||
/**
|
||||
* 工作室具体位置
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 成员人数
|
||||
*/
|
||||
private Integer memberNum;
|
||||
|
||||
/**
|
||||
* 工作室介绍
|
||||
*/
|
||||
private String introduction;
|
||||
|
||||
/**
|
||||
* 申请进度
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 归档
|
||||
*/
|
||||
private Integer archive;
|
||||
|
||||
/**
|
||||
* 流程 ID
|
||||
*/
|
||||
private String flowId;
|
||||
|
||||
/**
|
||||
* 流程 工会名称
|
||||
*/
|
||||
private String flowUnionName;
|
||||
|
||||
/**
|
||||
* 流程 状态
|
||||
*/
|
||||
private Integer flowStatus;
|
||||
|
||||
/**
|
||||
* 流程 序号
|
||||
*/
|
||||
private Integer flowSortNo;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
private String createName;
|
||||
|
||||
/**
|
||||
* 所属机构
|
||||
*/
|
||||
private String deptid;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 所属领域
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉称号
|
||||
*/
|
||||
private String leadHonor;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
private Integer processUserTaskStatus;
|
||||
|
||||
|
||||
private Date processTaskStartTime;
|
||||
|
||||
|
||||
private Date processTaskEndTime;
|
||||
|
||||
|
||||
private String processTaskReason;
|
||||
|
||||
|
||||
private String processTaskNode;
|
||||
|
||||
|
||||
private String processInstanceId;
|
||||
|
||||
|
||||
private String processInstanceTaskId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BrandStudioHonorVO {
|
||||
|
||||
/**
|
||||
* 工作室荣誉ID,主键
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室申请ID
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 荣誉称号
|
||||
*/
|
||||
private String honorName;
|
||||
|
||||
/**
|
||||
* 级别
|
||||
*/
|
||||
private String honorGrade;
|
||||
|
||||
/**
|
||||
* 获取年份
|
||||
*/
|
||||
private String requireYear;
|
||||
|
||||
/**
|
||||
* 荣誉类别:外部荣誉,行内荣誉
|
||||
* 通常可定义为枚举或常量:
|
||||
* 例如:1 - 外部荣誉,2 - 行内荣誉
|
||||
*/
|
||||
private Short honorCategory;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 工作室成员信息表实体类
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
public class BrandStudioMemberVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室ID(外键,关联到 BrandStudioApplication)
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 用户 ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户 工号
|
||||
*/
|
||||
private String emplid;
|
||||
|
||||
/**
|
||||
* 成员姓名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 成员角色(如:核心成员、技术骨干、助理等)
|
||||
*/
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 成员出生年月(建议格式:yyyy-MM 或 yyyy,实际为字符串存储)
|
||||
*/
|
||||
private String birthdate;
|
||||
|
||||
/**
|
||||
* 学历(如:本科、硕士、博士等)
|
||||
*/
|
||||
private String grade;
|
||||
|
||||
/**
|
||||
* 职称(如:高级工程师、教授、技师等)
|
||||
*/
|
||||
private String professional;
|
||||
|
||||
/**
|
||||
* 所在部门
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 加入日期
|
||||
*/
|
||||
private LocalDateTime joinDate;
|
||||
|
||||
/**
|
||||
* 离开日期(可为空,表示尚未离职)
|
||||
*/
|
||||
private LocalDateTime leaveDate;
|
||||
|
||||
/**
|
||||
* 成员状态:
|
||||
* 0 - 在职,
|
||||
* 1 - 离职
|
||||
*/
|
||||
private Integer status;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DeptInfoVO {
|
||||
|
||||
private String deptid;
|
||||
private String deptName;
|
||||
|
||||
private String topParentNextId;
|
||||
private String topParentNextName;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class LeaderHonorGroupVO {
|
||||
|
||||
private String emplid;
|
||||
private String userName;
|
||||
private Integer age;
|
||||
private List<String> honorNames;
|
||||
|
||||
public LeaderHonorGroupVO(String emplid, String userName, Integer age, List<String> honorNames) {
|
||||
this.emplid = emplid;
|
||||
this.userName = userName;
|
||||
this.age = age;
|
||||
this.honorNames = honorNames;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉
|
||||
*/
|
||||
@Data
|
||||
public class LeaderHonorVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
//@Excel(name = "姓名")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 年龄
|
||||
*/
|
||||
//@Excel(name = "年龄")
|
||||
private Integer age;
|
||||
|
||||
/**
|
||||
* 人员编号(工号)
|
||||
*/
|
||||
//@Excel(name = "人员编号(工号)")
|
||||
private String emplid;
|
||||
|
||||
/**
|
||||
* 机构
|
||||
*/
|
||||
//@Excel(name = "机构")
|
||||
private String deptid;
|
||||
|
||||
/**
|
||||
* 工会ID
|
||||
*/
|
||||
//@Excel(name = "工会ID")
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
//@Excel(name = "机构名称")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 年度
|
||||
*/
|
||||
//@Excel(name = "年度")
|
||||
private String year;
|
||||
|
||||
/**
|
||||
* 内外部荣誉
|
||||
*/
|
||||
//@Excel(name = "内外部荣誉")
|
||||
private String categoryName1;
|
||||
|
||||
/**
|
||||
* 内外部荣誉编号
|
||||
*/
|
||||
//@Excel(name = "内外部荣誉编号")
|
||||
private String categoryCode1;
|
||||
|
||||
/**
|
||||
* 荣誉级别名称
|
||||
*/
|
||||
//@Excel(name = "荣誉级别名称")
|
||||
private String categoryName2;
|
||||
|
||||
/**
|
||||
* 荣誉级别编号
|
||||
*/
|
||||
//@Excel(name = "荣誉级别编号")
|
||||
private String categoryCode2;
|
||||
|
||||
/**
|
||||
* 荣誉类别名称
|
||||
*/
|
||||
//@Excel(name = "荣誉类别名称")
|
||||
private String categoryName3;
|
||||
|
||||
/**
|
||||
* 荣誉类别编号
|
||||
*/
|
||||
//@Excel(name = "荣誉类别编号")
|
||||
private String categoryCode3;
|
||||
|
||||
/**
|
||||
* 荣誉名称
|
||||
*/
|
||||
//@Excel(name = "荣誉名称")
|
||||
private String honorName;
|
||||
|
||||
/**
|
||||
* 荣誉编号
|
||||
*/
|
||||
//@Excel(name = "荣誉编号")
|
||||
private String honorCode;
|
||||
|
||||
/**
|
||||
* 荣誉分类id
|
||||
*/
|
||||
private String categoryCode;
|
||||
|
||||
/**
|
||||
* 当前荣誉分类名称
|
||||
*/
|
||||
private String categoryName;
|
||||
|
||||
/**
|
||||
* 评选对象(机构/个人)
|
||||
*/
|
||||
//@Excel(name = "评选对象(机构/个人)")
|
||||
private String selectionType;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机构列表
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SysOrgVO {
|
||||
/**
|
||||
* 机构编号
|
||||
*/
|
||||
private String orgId;
|
||||
|
||||
/**
|
||||
* 上级编号
|
||||
*/
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 子节点
|
||||
*/
|
||||
private List<SysOrgVO> children;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String orgName;
|
||||
|
||||
/**
|
||||
* 机构代码
|
||||
*/
|
||||
private String orgCode;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 负责人ID
|
||||
*/
|
||||
private String leaderId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 上级名称
|
||||
*/
|
||||
private String parentName;
|
||||
|
||||
/** 分行ID */
|
||||
//@Excel(name = "分行ID")
|
||||
private String branchId;
|
||||
|
||||
/** 机构类型 */
|
||||
//@Excel(name = "机构类型")
|
||||
private String orgType;
|
||||
|
||||
/** 描述 */
|
||||
//@Excel(name = "描述")
|
||||
private String description;
|
||||
|
||||
/** 机构状态 */
|
||||
//@Excel(name = "机构状态")
|
||||
private String status;
|
||||
|
||||
/** 党组织md5 */
|
||||
//@Excel(name = "党组织md5")
|
||||
private String orgMd5;
|
||||
|
||||
/** 自定义属性 */
|
||||
//@Excel(name = "自定义属性")
|
||||
private String countryCode;
|
||||
|
||||
/** 工会ID */
|
||||
private String unionId;
|
||||
|
||||
/** 工会ID */
|
||||
private String childUnionId;
|
||||
|
||||
/** 机构中文全称 */
|
||||
private String gcDeptLdescr;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SysUnionDeptVO {
|
||||
|
||||
/**
|
||||
* userId
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* unionId
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 工会名称
|
||||
*/
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* deptId
|
||||
*/
|
||||
private String deptId;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 最上级工会 Id
|
||||
*/
|
||||
private String topUnionId;
|
||||
|
||||
/**
|
||||
* 最上级工会名称
|
||||
*/
|
||||
private String topUnionName;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.budwk.app.zhgh.brand.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 工会-用户 工作室申请统计视图对象
|
||||
* 按 union_id + user_id 聚合,统计每个用户在其所属工会下的所有申请单的状态分布。
|
||||
* 所有比例字段单位为 %,已乘以 100 并保留 2 位小数。
|
||||
* @author chen
|
||||
* @since 2026-01-08
|
||||
*/
|
||||
@Data
|
||||
public class UnionApplyStatsVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 工会ID */
|
||||
private String unionId;
|
||||
|
||||
/** 工会名称 */
|
||||
private String unionName;
|
||||
|
||||
/** 用户姓名(来自 sys_user) */
|
||||
private String username;
|
||||
|
||||
/** 申请单总量 */
|
||||
private Integer applyCnt;
|
||||
|
||||
/** 已通过数量(status = 5) */
|
||||
private Integer passedCnt;
|
||||
|
||||
/** 通过率(%) */
|
||||
private BigDecimal passRate;
|
||||
|
||||
/** 审核中数量(status = 1) */
|
||||
private Integer reviewCnt;
|
||||
|
||||
/** 审核中占比(%) */
|
||||
private BigDecimal reviewRate;
|
||||
|
||||
/** 已驳回数量(status = 2) */
|
||||
private Integer rejectCnt;
|
||||
|
||||
/** 驳回率(%) */
|
||||
private BigDecimal rejectRate;
|
||||
|
||||
/** 已撤销数量(status = 3) */
|
||||
private Integer repealCnt;
|
||||
|
||||
/** 撤销率(%) */
|
||||
private BigDecimal repealRate;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.budwk.app.zhgh.brand.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 品牌工作室申请流程表
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("brand_application_flow")
|
||||
@Comment("品牌工作室申请流程表")
|
||||
public class BrandApplicationFlow extends BaseModel implements Serializable {
|
||||
|
||||
/**
|
||||
* 审批记录ID,主键
|
||||
*/
|
||||
@Name
|
||||
@Column
|
||||
@Comment("审批记录ID,主键")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工会ID
|
||||
*/
|
||||
@Column
|
||||
@Comment("工会ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 工会
|
||||
*/
|
||||
@Column
|
||||
@Comment("工会")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 256)
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 审核人ID
|
||||
*/
|
||||
@Column
|
||||
@Comment("审核人ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String auditorId;
|
||||
|
||||
/**
|
||||
* 审核人
|
||||
*/
|
||||
@Column
|
||||
@Comment("审核人")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String auditor;
|
||||
|
||||
/**
|
||||
* 申请ID
|
||||
*/
|
||||
@Column
|
||||
@Comment("申请ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 状态(0:待审核;1:驳回;2:撤回;3:撤销;4:通过)
|
||||
*/
|
||||
@Column
|
||||
@Comment("状态")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 审批内容(意见描述)
|
||||
*/
|
||||
@Column
|
||||
@Comment("审批内容(意见描述)")
|
||||
@ColDefine(type = ColType.VARCHAR, customType = "text")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Column
|
||||
@Comment("备注")
|
||||
@ColDefine(type = ColType.VARCHAR, customType = "text")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
@Column
|
||||
@Comment("序号")
|
||||
private Integer sortNo;
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
package com.budwk.app.zhgh.brand.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 品牌工作室申请表实体类
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("brand_studio_application")
|
||||
@Comment("品牌工作室申请表")
|
||||
public class BrandStudioApplication extends BaseModel implements Serializable {
|
||||
|
||||
/**
|
||||
* 工作室ID,主键
|
||||
*/
|
||||
@Name
|
||||
@Column
|
||||
@Comment("工作室ID,主键")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室名称
|
||||
*/
|
||||
@Column
|
||||
@Comment("工作室名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 128)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 申请人ID,唯一
|
||||
*/
|
||||
@Column
|
||||
@Comment("申请人ID,唯一")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 申请人所属工会ID
|
||||
*/
|
||||
@Column
|
||||
@Comment("申请人所属工会ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 工会名称
|
||||
*/
|
||||
@Column
|
||||
@Comment("工会名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 256)
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 创建年份(格式如:2025)
|
||||
*/
|
||||
@Column
|
||||
@Comment("创建年份")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 10)
|
||||
private String createYear;
|
||||
|
||||
/**
|
||||
* 工作室领衔人
|
||||
*/
|
||||
@Column
|
||||
@Comment("工作室领衔人")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String leadPeople;
|
||||
|
||||
/**
|
||||
* 领衔人年龄
|
||||
*/
|
||||
@Column
|
||||
@Comment("领衔人年龄")
|
||||
private Integer leadAge;
|
||||
|
||||
/**
|
||||
* 领衔人身份,多个身份用逗号分隔
|
||||
*/
|
||||
@Column
|
||||
@Comment("领衔人身份,多个身份用逗号分隔")
|
||||
@ColDefine(type = ColType.VARCHAR, customType = "text")
|
||||
private String leadIdentity;
|
||||
|
||||
/**
|
||||
* 工作室类型
|
||||
*/
|
||||
@Column
|
||||
@Comment("工作室类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 128)
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 所属赛道
|
||||
*/
|
||||
@Column
|
||||
@Comment("所属赛道")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 128)
|
||||
private String track;
|
||||
|
||||
/**
|
||||
* 工作室具体位置
|
||||
*/
|
||||
@Column
|
||||
@Comment("工作室具体位置")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 256)
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 成员人数
|
||||
*/
|
||||
@Column
|
||||
@Comment("成员人数")
|
||||
private Integer memberNum;
|
||||
|
||||
/**
|
||||
* 工作室介绍
|
||||
*/
|
||||
@Column
|
||||
@Comment("工作室介绍")
|
||||
@ColDefine(type = ColType.VARCHAR, customType = "text")
|
||||
private String introduction;
|
||||
|
||||
/**
|
||||
* 申请进度
|
||||
*/
|
||||
@Column
|
||||
@Comment("申请进度")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 归档
|
||||
*/
|
||||
@Column
|
||||
@Comment("归档")
|
||||
private Integer archive;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
@Column
|
||||
@Comment("创建人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String createName;
|
||||
|
||||
/**
|
||||
* 所属机构
|
||||
*/
|
||||
@Column
|
||||
@Comment("所属机构")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String deptid;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
@Column
|
||||
@Comment("机构名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 256)
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 所属领域
|
||||
*/
|
||||
@Column
|
||||
@Comment("所属领域")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 128)
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 领衔人荣誉称号
|
||||
*/
|
||||
@Column
|
||||
@Comment("领衔人荣誉称号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String leadHonor;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Column
|
||||
@Comment("备注")
|
||||
@ColDefine(type = ColType.VARCHAR, customType = "text")
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.budwk.app.zhgh.brand.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 工作室荣誉信息实体类
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("brand_studio_honor")
|
||||
@Comment("品牌工作室荣誉信息表")
|
||||
public class BrandStudioHonor extends BaseModel implements Serializable {
|
||||
|
||||
/**
|
||||
* 工作室荣誉ID,主键
|
||||
*/
|
||||
@Name
|
||||
@Column
|
||||
@Comment("工作室荣誉ID,主键")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室申请ID
|
||||
*/
|
||||
@Column
|
||||
@Comment("工作室申请ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 荣誉称号
|
||||
*/
|
||||
@Column
|
||||
@Comment("荣誉称号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 128)
|
||||
private String honorName;
|
||||
|
||||
/**
|
||||
* 级别
|
||||
*/
|
||||
@Column
|
||||
@Comment("级别")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String honorGrade;
|
||||
|
||||
/**
|
||||
* 获取年份
|
||||
*/
|
||||
@Column
|
||||
@Comment("获取年份")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 10)
|
||||
private String requireYear;
|
||||
|
||||
/**
|
||||
* 荣誉类别:外部荣誉,行内荣誉
|
||||
* 通常可定义为枚举或常量:
|
||||
* 例如:1 - 外部荣誉,2 - 行内荣誉
|
||||
*/
|
||||
@Column
|
||||
@Comment("荣誉类别")
|
||||
private Short honorCategory;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.budwk.app.zhgh.brand.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 工作室成员信息表实体类
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("brand_studio_member")
|
||||
@Comment("品牌工作室成员信息表")
|
||||
public class BrandStudioMember extends BaseModel implements Serializable {
|
||||
|
||||
/**
|
||||
* 成员ID,主键
|
||||
*/
|
||||
@Name
|
||||
@Column
|
||||
@Comment("成员ID,主键")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 工作室ID(外键,关联到 BrandStudioApplication)
|
||||
*/
|
||||
@Column
|
||||
@Comment("工作室ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 用户 ID
|
||||
*/
|
||||
@Column
|
||||
@Comment("用户ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户 工号
|
||||
*/
|
||||
@Column
|
||||
@Comment("用户工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String emplid;
|
||||
|
||||
/**
|
||||
* 成员姓名
|
||||
*/
|
||||
@Column
|
||||
@Comment("成员姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 成员角色(如:核心成员、技术骨干、助理等)
|
||||
*/
|
||||
@Column
|
||||
@Comment("成员角色")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 成员出生年月(建议格式:yyyy-MM 或 yyyy,实际为字符串存储)
|
||||
*/
|
||||
@Column
|
||||
@Comment("成员出生年月")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String birthdate;
|
||||
|
||||
/**
|
||||
* 学历(如:本科、硕士、博士等)
|
||||
*/
|
||||
@Column
|
||||
@Comment("学历")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String grade;
|
||||
|
||||
/**
|
||||
* 职称(如:高级工程师、教授、技师等)
|
||||
*/
|
||||
@Column
|
||||
@Comment("职称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String professional;
|
||||
|
||||
/**
|
||||
* 所在部门
|
||||
*/
|
||||
@Column
|
||||
@Comment("所在部门")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 加入日期
|
||||
*/
|
||||
@Column
|
||||
@Comment("加入日期")
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
private Date joinDate;
|
||||
|
||||
/**
|
||||
* 离开日期(可为空,表示尚未离职)
|
||||
*/
|
||||
@Column
|
||||
@Comment("离开日期")
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
private Date leaveDate;
|
||||
|
||||
/**
|
||||
* 成员状态:
|
||||
* 0 - 在职,
|
||||
* 1 - 离职
|
||||
*/
|
||||
@Column
|
||||
@Comment("成员状态")
|
||||
private Integer status;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.budwk.app.zhgh.brand.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationAuditDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationRecallDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.enums.BrandApplicationStatusEnums;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandApplicationFlowVO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandApplicationFlow;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BrandApplicationFlowService extends BaseService<BrandApplicationFlow> {
|
||||
|
||||
void submitAudit(String applicationId, BrandApplicationStatusEnums statusEnums, Sys_user user);
|
||||
|
||||
void audit(BrandApplicationAuditDTO dto);
|
||||
|
||||
void recall(BrandApplicationRecallDTO dto);
|
||||
|
||||
List<BrandApplicationFlowVO> getFlowList(String applicationId);
|
||||
|
||||
void deleteByApplicationIds(List<String> ids);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.budwk.app.zhgh.brand.service;
|
||||
|
||||
import com.budwk.app.zhgh.brand.domain.vo.ApplicationProgressVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.ApplicationWarnVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.UnionApplyStatsVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface BrandApplicationStatisticsService {
|
||||
List<UnionApplyStatsVO> selectUnionApplyStats();
|
||||
|
||||
List<ApplicationProgressVO> selectApplyProgressStats();
|
||||
|
||||
List<ApplicationWarnVO> selectApplyWarningStats();
|
||||
|
||||
Map<String, Map<String, Long>> selectApplyMapCount();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.budwk.app.zhgh.brand.service;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationAuditDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationCreateDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationPageDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioApplicationUpdateDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.*;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioApplication;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
public interface BrandStudioApplicationService extends BaseService<BrandStudioApplication> {
|
||||
|
||||
Pagination<BrandStudioApplicationVO> page(BrandStudioApplicationPageDTO pageDTO);
|
||||
|
||||
void save(BrandStudioApplicationCreateDTO dto);
|
||||
|
||||
void submitApply(BrandApplicationAuditDTO dto);
|
||||
|
||||
void oaAuditUpdateStatus(String id, Integer status, String reason);
|
||||
|
||||
void update(BrandStudioApplicationUpdateDTO dto);
|
||||
|
||||
void updateMemberOrHonor(BrandStudioApplicationUpdateDTO dto);
|
||||
|
||||
void delete(List<String> ids);
|
||||
|
||||
SysUnionDeptVO queryUserUnion();
|
||||
|
||||
BrandStudioApplicationVO getDetailById(String id);
|
||||
|
||||
void archive(List<String> idList);
|
||||
|
||||
/// 之前的工作流逻辑,已废弃
|
||||
Pagination<BrandStudioApplyFlowVO> auditPage(@Valid BrandStudioApplicationPageDTO pageDTO);
|
||||
|
||||
/// 新的工作流逻辑
|
||||
Pagination<BrandStudioApplyFlowVO> flowAuditPage(BrandStudioApplicationPageDTO dto);
|
||||
|
||||
List<LeaderHonorGroupVO> queryLeaderHonor();
|
||||
|
||||
Pagination<BrandStudioApplicationHonorVO> summaryPage(@Valid BrandStudioApplicationPageDTO pageDTO);
|
||||
|
||||
List<BrandStudioApplicationHonorVO> getHonorDetailById(String id);
|
||||
|
||||
void export();
|
||||
|
||||
// 导出品牌工作室申请文档
|
||||
void exportDocx(String id, HttpServletResponse response);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.budwk.app.zhgh.brand.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioHonor;
|
||||
|
||||
|
||||
public interface BrandStudioHonorService extends BaseService<BrandStudioHonor> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.budwk.app.zhgh.brand.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioMemberCreateDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioMemberUpdateDTO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioMember;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BrandStudioMemberService extends BaseService<BrandStudioMember> {
|
||||
|
||||
void save(BrandStudioMemberCreateDTO dto);
|
||||
|
||||
void update(BrandStudioMemberUpdateDTO dto);
|
||||
|
||||
void delete(List<String> ids);
|
||||
}
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
package com.budwk.app.zhgh.brand.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.bpm.enums.BpmProcessInstanceStatusEnum;
|
||||
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
|
||||
import com.budwk.app.bpm.models.BpmProcessInstance;
|
||||
import com.budwk.app.bpm.service.BpmService;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.web.controllers.open.commons.service.CommonService;
|
||||
import com.budwk.app.zhgh.brand.convert.BrandApplicationFlowConvert;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationAuditDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandApplicationRecallDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.enums.ApplicationFlowStatusEnum;
|
||||
import com.budwk.app.zhgh.brand.domain.enums.BrandApplicationStatusEnums;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandApplicationFlowVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.BrandFlowUserVO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandApplicationFlow;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioApplication;
|
||||
import com.budwk.app.zhgh.brand.service.BrandApplicationFlowService;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class BrandApplicationFlowServiceImpl extends BaseServiceImpl<BrandApplicationFlow> implements BrandApplicationFlowService {
|
||||
|
||||
@Inject
|
||||
private BpmService bpmService;
|
||||
|
||||
@Inject
|
||||
private CommonService commonService;
|
||||
|
||||
public BrandApplicationFlowServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
/// 提交申请/待审核:插入审核流程记录表
|
||||
@Override
|
||||
public void submitAudit(String applicationId, BrandApplicationStatusEnums statusEnums, Sys_user user) {
|
||||
if (statusEnums != BrandApplicationStatusEnums.IN_REVIEW) {
|
||||
throw new RuntimeException("提交申请失败");
|
||||
}
|
||||
// 先获取用户所在工会的关系网 secondUnion -> firstUnion -> 0
|
||||
String unionId = SecurityUtil.getUnionId();
|
||||
|
||||
// 两种方案:先删除之前撤回的审核记录/修改之前的撤回审核记录的状态
|
||||
// 0.先删除 撤回审核记录 的 applicationId 记录,如果没有也无所谓
|
||||
dao().update(BrandApplicationFlow.class, Chain.make("delFlag", true), Cnd.where("applicationId", "=", applicationId));
|
||||
|
||||
// 1.先插入当前用户,表示已经通过提交阶段
|
||||
BrandApplicationFlow brandApplicationFlow = new BrandApplicationFlow();
|
||||
brandApplicationFlow.setApplicationId(applicationId);
|
||||
brandApplicationFlow.setAuditorId(user.getId());
|
||||
brandApplicationFlow.setAuditor(user.getUsername());
|
||||
brandApplicationFlow.setSortNo(0);
|
||||
brandApplicationFlow.setStatus(ApplicationFlowStatusEnum.PASSED.getValue());
|
||||
insert(brandApplicationFlow);
|
||||
|
||||
Sys_union union = dao().fetch(Sys_union.class, unionId);
|
||||
if (union != null) {
|
||||
BrandApplicationFlow flow = new BrandApplicationFlow();
|
||||
flow.setApplicationId(applicationId);
|
||||
flow.setUnionId(union.getId());
|
||||
flow.setUnionName(union.getName());
|
||||
flow.setStatus(ApplicationFlowStatusEnum.TO_BE_AUDIT.getValue());
|
||||
flow.setSortNo(1);
|
||||
insert(flow);
|
||||
}
|
||||
}
|
||||
|
||||
/// 审核
|
||||
@Override
|
||||
public void audit(BrandApplicationAuditDTO dto) {
|
||||
String applicationId = StrUtil.blankToDefault(dto.getApplicationId(), dto.getProcessInstanceBusinessId());
|
||||
if (StrUtil.isBlank(applicationId)) {
|
||||
throw new RuntimeException("申请 Id 不能为空");
|
||||
}
|
||||
String taskId = StrUtil.blankToDefault(dto.getProcessInstanceTaskId(), dto.getFlowId());
|
||||
if (StrUtil.isBlank(taskId)) {
|
||||
throw new RuntimeException("流程任务ID不能为空");
|
||||
}
|
||||
BpmTaskApprovalTypeEnum approvalTypeEnum = getBpmTaskApprovalTypeEnum(dto);
|
||||
HashMap<String, Object> variables = new HashMap<>(BeanUtil.beanToMap(dto));
|
||||
variables.put("bpmTaskApprovalType", approvalTypeEnum.name());
|
||||
variables.put("approvalOpinion", dto.getRemark());
|
||||
bpmService.completeTask(taskId, approvalTypeEnum, variables, getAssignments(dto, approvalTypeEnum));
|
||||
|
||||
BpmProcessInstance instance = dao().fetch(BpmProcessInstance.class, Cnd.where("processInstanceBusinessId", "=", applicationId));
|
||||
if (approvalTypeEnum == BpmTaskApprovalTypeEnum.REJECT) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.REJECT.getCode()),
|
||||
Cnd.where("id", "=", applicationId));
|
||||
} else if (approvalTypeEnum == BpmTaskApprovalTypeEnum.BACK || approvalTypeEnum == BpmTaskApprovalTypeEnum.BACK_OTHER_NODE) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.IN_REVIEW.getCode()),
|
||||
Cnd.where("id", "=", applicationId));
|
||||
} else if (instance != null && BpmProcessInstanceStatusEnum.COMPLETED.name().equals(instance.getProcessInstanceStatus())) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.PASSED.getCode()),
|
||||
Cnd.where("id", "=", applicationId));
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getAssignments(BrandApplicationAuditDTO dto, BpmTaskApprovalTypeEnum approvalTypeEnum) {
|
||||
if (dto.getAssignments() != null && !dto.getAssignments().isEmpty()) {
|
||||
return dto.getAssignments();
|
||||
}
|
||||
if (approvalTypeEnum == BpmTaskApprovalTypeEnum.PASS) {
|
||||
String approvalLoginName = commonService.findUserLoginNameByRoleCode(RoleConstant.SCHOOL_UNION_ADMIN);
|
||||
if (StrUtil.isBlank(approvalLoginName)) {
|
||||
throw new RuntimeException("校工会未配置审批人,请联系管理员");
|
||||
}
|
||||
return List.of(approvalLoginName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private BpmTaskApprovalTypeEnum getBpmTaskApprovalTypeEnum(BrandApplicationAuditDTO dto) {
|
||||
if (StrUtil.isNotBlank(dto.getBpmTaskApprovalType())) {
|
||||
return BpmTaskApprovalTypeEnum.valueOf(dto.getBpmTaskApprovalType());
|
||||
}
|
||||
if (dto.getStatus() == null) {
|
||||
throw new RuntimeException("任务审批类型错误,请传入正确的任务审批类型。");
|
||||
}
|
||||
ApplicationFlowStatusEnum statusEnum = ApplicationFlowStatusEnum.getStatusEnumByValue(dto.getStatus());
|
||||
if (statusEnum == ApplicationFlowStatusEnum.PASSED) {
|
||||
return BpmTaskApprovalTypeEnum.PASS;
|
||||
} else if (statusEnum == ApplicationFlowStatusEnum.REJECT) {
|
||||
return BpmTaskApprovalTypeEnum.REJECT;
|
||||
} else if (statusEnum == ApplicationFlowStatusEnum.RECALL) {
|
||||
return BpmTaskApprovalTypeEnum.BACK;
|
||||
}
|
||||
throw new RuntimeException("任务审批类型错误,请传入正确的任务审批类型。");
|
||||
}
|
||||
|
||||
/// 审核
|
||||
public void auditOld(BrandApplicationAuditDTO dto) {
|
||||
BrandApplicationFlow applicationFlow = dao().fetch(BrandApplicationFlow.class, Cnd.where("applicationId", "=", dto.getApplicationId())
|
||||
.and("id", "=", dto.getFlowId())
|
||||
.and("status", "=", ApplicationFlowStatusEnum.TO_BE_AUDIT.getValue())
|
||||
.and("delFlag", "=", false));
|
||||
if (applicationFlow == null) {
|
||||
throw new RuntimeException("待操作记录不存在");
|
||||
}
|
||||
Sys_user user = getCurrentUser();
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户信息过期,请重新登录");
|
||||
}
|
||||
// 先更新
|
||||
applicationFlow.setStatus(dto.getStatus());
|
||||
applicationFlow.setAuditor(user.getUsername());
|
||||
applicationFlow.setAuditorId(user.getId());
|
||||
applicationFlow.setRemark(dto.getRemark());
|
||||
updateIgnoreNull(applicationFlow);
|
||||
|
||||
List<BrandApplicationFlow> flowList = dao().query(BrandApplicationFlow.class, Cnd.where("applicationId", "=", dto.getApplicationId()).and("delFlag", "=", false));
|
||||
if (flowList == null || flowList.isEmpty()) {
|
||||
throw new RuntimeException("流程记录为空");
|
||||
}
|
||||
|
||||
long count = flowList.stream().filter(item -> Objects.equals(item.getStatus(), ApplicationFlowStatusEnum.PASSED.getValue())).count();
|
||||
ApplicationFlowStatusEnum statusEnum = ApplicationFlowStatusEnum.getStatusEnumByValue(dto.getStatus());
|
||||
//流程审批通过
|
||||
if (statusEnum == ApplicationFlowStatusEnum.PASSED)
|
||||
{
|
||||
if (count == flowList.size()) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.PASSED.getCode()),
|
||||
Cnd.where("id", "=", dto.getApplicationId()));
|
||||
} else {
|
||||
Optional<BrandApplicationFlow> first = flowList.stream().filter(item -> item.getSortNo() == (applicationFlow.getSortNo() + 1)).findFirst();
|
||||
if (first.isPresent()) {
|
||||
BrandApplicationFlow flow = first.get();
|
||||
flow.setRemark(dto.getRemark());
|
||||
flow.setStatus(ApplicationFlowStatusEnum.TO_BE_AUDIT.getValue());
|
||||
updateIgnoreNull(flow);
|
||||
}
|
||||
}
|
||||
} else if (statusEnum == ApplicationFlowStatusEnum.REPEAL) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.REPEAL.getCode()),
|
||||
Cnd.where("id", "=", dto.getApplicationId()));
|
||||
} else if (statusEnum == ApplicationFlowStatusEnum.RECALL) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.IN_REVIEW.getCode()),
|
||||
Cnd.where("id", "=", dto.getApplicationId()));
|
||||
} else if (statusEnum == ApplicationFlowStatusEnum.REJECT) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.REJECT.getCode()),
|
||||
Cnd.where("id", "=", dto.getApplicationId()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recall(BrandApplicationRecallDTO dto) {
|
||||
String taskId = StrUtil.blankToDefault(dto.getProcessInstanceTaskId(), dto.getFlowId());
|
||||
if (StrUtil.isNotBlank(taskId)) {
|
||||
bpmService.revokeTask(taskId);
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.IN_REVIEW.getCode()),
|
||||
Cnd.where("id", "=", dto.getApplicationId()));
|
||||
return;
|
||||
}
|
||||
bpmService.revokeApply(dto.getApplicationId());
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.DRAFT.getCode()),
|
||||
Cnd.where("id", "=", dto.getApplicationId()));
|
||||
}
|
||||
|
||||
public void recallOld(BrandApplicationRecallDTO dto) {
|
||||
// 撤回分为 申请人撤回 和 审核人撤回
|
||||
// 如果是申请人,需要把 表单状态改为 DRAFT
|
||||
Sys_user user = getCurrentUser();
|
||||
// 查询 申请表单 在 flow 中的 curFlowId 和 nextFlowId
|
||||
String applicationId = dto.getApplicationId();
|
||||
List<BrandFlowUserVO> brandFlowUserVOS = selectApplicationTableVOById(applicationId);
|
||||
if (user == null || brandFlowUserVOS.isEmpty()) {
|
||||
throw new RuntimeException("撤回申请失败");
|
||||
}
|
||||
List<String> flowIds = brandFlowUserVOS.stream().map(BrandFlowUserVO::getFlowId).collect(Collectors.toList());
|
||||
// 如果 申请人撤回 和 撤回发起人 为同一人,且在 申请模块撤销,就更新 申请表 为 DRAFT
|
||||
// 如果是在 申请表中 撤回 时,dto.getFlowId() 是 null
|
||||
boolean isSameUser = brandFlowUserVOS.get(0).getUserId().equals(user.getId()) && dto.getFlowId() == null;
|
||||
if (isSameUser) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.DRAFT.getCode()),
|
||||
Cnd.where("id", "=", applicationId));
|
||||
dto.setFlowId(flowIds.get(0));
|
||||
// 把所有 审批流程 状态改为 WAIT_AUDIT 0
|
||||
updateStatusByApplicationId(applicationId, 0);
|
||||
} else {
|
||||
// 如果 是由上级人员撤回 审批 记录,且是在 审批表中操作, dto.getFlowId() 是 存在的
|
||||
// 先修改 申请表 为 待审核状态
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.IN_REVIEW.getCode()),
|
||||
Cnd.where("id", "=", applicationId));
|
||||
// 再把 审批流程 中的状态改为撤回,下级状态改成待审核
|
||||
int index = flowIds.indexOf(dto.getFlowId());
|
||||
dto.setFlowId(flowIds.get(index));
|
||||
Integer sortNo = brandFlowUserVOS.get(index).getSortNo();
|
||||
// 把 高于当前 组织的 流状态 置为 0
|
||||
updateStatusByApplicationId(applicationId, sortNo);
|
||||
}
|
||||
// 把当前记录改为 TO_BE_AUDIT
|
||||
BrandApplicationFlow brandApplicationFlow = new BrandApplicationFlow();
|
||||
brandApplicationFlow.setId(dto.getFlowId());
|
||||
brandApplicationFlow.setAuditorId(user.getId());
|
||||
brandApplicationFlow.setAuditor(user.getUsername());
|
||||
brandApplicationFlow.setStatus(ApplicationFlowStatusEnum.TO_BE_AUDIT.getValue());
|
||||
brandApplicationFlow.setRemark(isSameUser ? "申请人操作撤回" : "操作撤回");
|
||||
updateIgnoreNull(brandApplicationFlow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BrandApplicationFlowVO> getFlowList(String applicationId) {
|
||||
List<BrandApplicationFlow> applicationFlows = dao().query(BrandApplicationFlow.class,
|
||||
Cnd.where("applicationId", "=", applicationId).and("delFlag", "=", false).asc("sortNo"));
|
||||
return BrandApplicationFlowConvert.convertList(applicationFlows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByApplicationIds(List<String> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
dao().update(BrandApplicationFlow.class, Chain.make("delFlag", true), Cnd.where("applicationId", "in", ids));
|
||||
}
|
||||
|
||||
private void updateStatusByApplicationId(String applicationId, Integer sortNo) {
|
||||
dao().update(BrandApplicationFlow.class,
|
||||
Chain.make("status", 0).add("remark", "申请人操作撤回"),
|
||||
Cnd.where("applicationId", "=", applicationId).and("sortNo", ">", sortNo));
|
||||
}
|
||||
|
||||
private List<BrandFlowUserVO> selectApplicationTableVOById(String applicationId) {
|
||||
List<BrandApplicationFlow> flows = dao().query(BrandApplicationFlow.class,
|
||||
Cnd.where("applicationId", "=", applicationId).and("delFlag", "=", false).asc("sortNo"));
|
||||
BrandStudioApplication application = dao().fetch(BrandStudioApplication.class, applicationId);
|
||||
return flows.stream().map(flow -> {
|
||||
BrandFlowUserVO vo = BeanUtil.copyProperties(flow, BrandFlowUserVO.class);
|
||||
vo.setFlowId(flow.getId());
|
||||
vo.setSortNo(flow.getSortNo());
|
||||
vo.setUserId(application == null ? null : application.getUserId());
|
||||
return vo;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Sys_user getCurrentUser() {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
if (userId == null || userId.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return dao().fetch(Sys_user.class, userId);
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
package com.budwk.app.zhgh.brand.service.impl;
|
||||
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.ApplicationProgressVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.ApplicationWarnVO;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.UnionApplyStatsVO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioApplication;
|
||||
import com.budwk.app.zhgh.brand.service.BrandApplicationStatisticsService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class BrandApplicationStatisticsServiceImpl extends BaseServiceImpl<BrandStudioApplication> implements BrandApplicationStatisticsService {
|
||||
|
||||
public BrandApplicationStatisticsServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
// 管理员查看
|
||||
@Override
|
||||
public List<UnionApplyStatsVO> selectUnionApplyStats() {
|
||||
Sql sql = Sqls.create("""
|
||||
select unionId,
|
||||
unionName,
|
||||
createName as username,
|
||||
count(1) as applyCnt,
|
||||
sum(case when status = 5 then 1 else 0 end) as passedCnt,
|
||||
round(sum(case when status = 5 then 1 else 0 end) * 100 / count(1), 2) as passRate,
|
||||
sum(case when status = 1 then 1 else 0 end) as reviewCnt,
|
||||
round(sum(case when status = 1 then 1 else 0 end) * 100 / count(1), 2) as reviewRate,
|
||||
sum(case when status = 2 then 1 else 0 end) as rejectCnt,
|
||||
round(sum(case when status = 2 then 1 else 0 end) * 100 / count(1), 2) as rejectRate,
|
||||
sum(case when status = 3 then 1 else 0 end) as repealCnt,
|
||||
round(sum(case when status = 3 then 1 else 0 end) * 100 / count(1), 2) as repealRate
|
||||
from brand_studio_application
|
||||
where delFlag = 0
|
||||
group by unionId, unionName, createName
|
||||
order by unionName
|
||||
""");
|
||||
return listVO(sql, UnionApplyStatsVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ApplicationProgressVO> selectApplyProgressStats() {
|
||||
Sql sql = Sqls.create("""
|
||||
select bsa.id as applicationId,
|
||||
bsa.name as applicationName,
|
||||
bsa.unionId,
|
||||
bsa.unionName,
|
||||
bsa.userId,
|
||||
bsa.status,
|
||||
bsa.leadPeople,
|
||||
bsa.createdAt as createTime,
|
||||
count(baf.id) as totalNodes,
|
||||
sum(case when baf.status = 5 then 1 else 0 end) as passedNodes,
|
||||
case when count(baf.id) = 0 then 0 else round(sum(case when baf.status = 5 then 1 else 0 end) * 100 / count(baf.id), 2) end as progressPct
|
||||
from brand_studio_application bsa
|
||||
left join brand_application_flow baf on bsa.id = baf.applicationId and baf.delFlag = 0
|
||||
where bsa.delFlag = 0
|
||||
and bsa.userId = @userId
|
||||
group by bsa.id, bsa.name, bsa.unionId, bsa.unionName, bsa.userId, bsa.status, bsa.leadPeople, bsa.createdAt
|
||||
order by bsa.createdAt desc
|
||||
""");
|
||||
sql.setParam("userId", SecurityUtil.getUserId());
|
||||
return listVO(sql, ApplicationProgressVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ApplicationWarnVO> selectApplyWarningStats() {
|
||||
Sql sql = Sqls.create("""
|
||||
select bsa.id as applicationId,
|
||||
bsa.name,
|
||||
bsa.leadPeople,
|
||||
bsa.status,
|
||||
bsa.unionId,
|
||||
bsa.unionName,
|
||||
bsa.createdAt as receiveTime,
|
||||
round((unix_timestamp(now()) * 1000 - bsa.createdAt) / 86400000, 2) as pendingDays,
|
||||
case when (unix_timestamp(now()) * 1000 - bsa.createdAt) / 86400000 >= 7 then 1 else 0 end as warnStatus,
|
||||
round(avg((unix_timestamp(now()) * 1000 - bsa.createdAt) / 86400000), 2) as avgAuditDays
|
||||
from brand_studio_application bsa
|
||||
where bsa.delFlag = 0
|
||||
and bsa.status = 1
|
||||
and (bsa.unionId = @unionId or @unionId = '')
|
||||
group by bsa.id, bsa.name, bsa.leadPeople, bsa.status, bsa.unionId, bsa.unionName, bsa.createdAt
|
||||
order by pendingDays desc
|
||||
""");
|
||||
sql.setParam("unionId", SecurityUtil.getUnionId());
|
||||
return listVO(sql, ApplicationWarnVO.class);
|
||||
}
|
||||
|
||||
// 对申请单的 type,年龄等等字段分组
|
||||
public Map<String, Map<String, Long>> selectApplyMapCount() {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
List<BrandStudioApplication> applications = dao().query(BrandStudioApplication.class,
|
||||
Cnd.where("userId", "=", userId).and("delFlag", "=", false));
|
||||
Map<String, Long> createYearCount = applications.stream()
|
||||
.collect(Collectors.groupingBy(BrandStudioApplication::getCreateYear, Collectors.counting()))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByKey(
|
||||
Comparator.comparingInt(year -> {
|
||||
try {
|
||||
return Integer.parseInt(year);
|
||||
} catch (NumberFormatException e) {
|
||||
return Integer.MAX_VALUE; // 非法年份放最后
|
||||
}
|
||||
})
|
||||
))
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
Map.Entry::getValue,
|
||||
(e1, e2) -> e1,
|
||||
LinkedHashMap::new
|
||||
));
|
||||
Map<String, Long> leadPeopleCount = applications.stream()
|
||||
.collect(Collectors.groupingBy(BrandStudioApplication::getLeadPeople, Collectors.counting()));
|
||||
Map<String, Long> leadAgeCount = applications.stream()
|
||||
.collect(Collectors.groupingBy(app -> String.valueOf(app.getLeadAge()), Collectors.counting()));
|
||||
Map<String, Long> typeCount = applications.stream()
|
||||
.collect(Collectors.groupingBy(BrandStudioApplication::getType, Collectors.counting()));
|
||||
Map<String, Long> trackCount = applications.stream()
|
||||
.collect(Collectors.groupingBy(BrandStudioApplication::getTrack, Collectors.counting()));
|
||||
Map<String, Map<String, Long>> mapMap = new HashMap<>();
|
||||
mapMap.put("createYear", createYearCount);
|
||||
mapMap.put("leadPeople", leadPeopleCount);
|
||||
mapMap.put("leadAge", leadAgeCount);
|
||||
mapMap.put("type", typeCount);
|
||||
mapMap.put("track", trackCount);
|
||||
return mapMap;
|
||||
}
|
||||
}
|
||||
+446
@@ -0,0 +1,446 @@
|
||||
package com.budwk.app.zhgh.brand.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.BpmProcessConstant;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
||||
import com.budwk.app.bpm.service.BpmService;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.web.controllers.open.commons.service.CommonService;
|
||||
import com.budwk.app.zhgh.brand.convert.BrandStudioApplicationConvert;
|
||||
import com.budwk.app.zhgh.brand.convert.BrandStudioHonorConvert;
|
||||
import com.budwk.app.zhgh.brand.convert.BrandStudioMemberConvert;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.*;
|
||||
import com.budwk.app.zhgh.brand.domain.enums.BrandApplicationStatusEnums;
|
||||
import com.budwk.app.zhgh.brand.domain.vo.*;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioApplication;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioHonor;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioMember;
|
||||
import com.budwk.app.zhgh.brand.service.BrandApplicationFlowService;
|
||||
import com.budwk.app.zhgh.brand.service.BrandStudioApplicationService;
|
||||
import com.budwk.app.zhgh.brand.service.BrandStudioMemberService;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class BrandStudioApplicationServiceImpl extends BaseServiceImpl<BrandStudioApplication> implements BrandStudioApplicationService {
|
||||
|
||||
@Inject
|
||||
private BrandStudioMemberService studioMemberService;
|
||||
|
||||
@Inject
|
||||
private BrandApplicationFlowService flowService;
|
||||
|
||||
@Inject
|
||||
private BpmService bpmService;
|
||||
|
||||
@Inject
|
||||
private CommonService commonService;
|
||||
|
||||
public BrandStudioApplicationServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
// 分页查询申请表
|
||||
@Override
|
||||
public Pagination<BrandStudioApplicationVO> page(BrandStudioApplicationPageDTO pageDTO) {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
|
||||
Cnd cnd = Cnd.where("delFlag", "=", false);
|
||||
/// 2. 先写“普通筛选”这一整组
|
||||
if (StrUtil.isNotBlank(pageDTO.getName())) {
|
||||
cnd.and("name", "like", "%" + pageDTO.getName() + "%");
|
||||
}
|
||||
if (StrUtil.isNotBlank(userId)) {
|
||||
cnd.and("createdBy", "=", userId);
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageDTO.getCreateYear())) {
|
||||
cnd.and("createYear", "=", pageDTO.getCreateYear());
|
||||
}
|
||||
if (pageDTO.getStatus() != null) {
|
||||
cnd.and("status", "=", pageDTO.getStatus());
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageDTO.getLeadPeople())) {
|
||||
cnd.and("leadPeople", "like", "%" + pageDTO.getLeadPeople() + "%");
|
||||
}
|
||||
cnd.desc("createYear");
|
||||
cnd.desc("createdAt");
|
||||
Pagination<BrandStudioApplication> page = listPage(pageDTO.getPageNumber(), pageDTO.getPageSize(), BrandStudioApplication.class, cnd);
|
||||
List<BrandStudioApplicationVO> list = BrandStudioApplicationConvert.convertList(page.getList());
|
||||
return new Pagination<>(page.getPageNo(), page.getPageSize(), page.getTotalCount(), list);
|
||||
}
|
||||
|
||||
private Sys_user getCheckedUserDetail() {
|
||||
Sys_user user = getCurrentUser();
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户信息过期,请重新登录");
|
||||
}
|
||||
if (StrUtil.isEmpty(SecurityUtil.getUnionId())) {
|
||||
throw new RuntimeException("未关联工会");
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(BrandStudioApplicationCreateDTO dto) {
|
||||
Sys_user user = getCheckedUserDetail();
|
||||
BrandStudioApplication application = BrandStudioApplicationConvert.convert(dto);
|
||||
application.setUserId(user.getId());
|
||||
application.setDeptid(user.getUnitId());
|
||||
application.setCreateName(user.getUsername());
|
||||
Integer status = dto.getStatus();
|
||||
BrandApplicationStatusEnums statusByCode = BrandApplicationStatusEnums.getStatusByCode(status);
|
||||
if (statusByCode == null) {
|
||||
throw new RuntimeException("状态异常");
|
||||
}
|
||||
application.setStatus(statusByCode.getCode());
|
||||
insert(application);
|
||||
insertBatchBrandStudioMember(dto.getBrandStudioMembers(), application.getId());
|
||||
if (statusByCode == BrandApplicationStatusEnums.CREATING) {
|
||||
/// 提交审核的话会记录在审核流表中
|
||||
submitAudit(application, user);
|
||||
}
|
||||
}
|
||||
|
||||
/// 提交申请
|
||||
@Override
|
||||
public void submitApply(BrandApplicationAuditDTO dto) {
|
||||
String applicationId = dto.getApplicationId();
|
||||
BrandApplicationStatusEnums statusEnums = BrandApplicationStatusEnums.getStatusByCode(dto.getStatus());
|
||||
if (statusEnums == null) {
|
||||
throw new RuntimeException("提交申请失败");
|
||||
}
|
||||
Sys_user user = getCurrentUser();
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户信息过期,请重新登录");
|
||||
}
|
||||
/// 1.先更新工作室申请表的状态
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.CREATING.getCode()),
|
||||
Cnd.where("id", "=", applicationId));
|
||||
/// 2.插入待审批流程
|
||||
if (statusEnums == BrandApplicationStatusEnums.IN_REVIEW) {
|
||||
/// 提交审核的话会记录在审核流表中
|
||||
BrandStudioApplication application = fetch(applicationId);
|
||||
submitAudit(application, user);
|
||||
}
|
||||
}
|
||||
|
||||
private void submitAudit(BrandStudioApplication application, Sys_user user) {
|
||||
if (application == null) {
|
||||
throw new RuntimeException("提交申请失败");
|
||||
}
|
||||
String approvalLoginName = commonService.findUserLoginNameByRoleCode(RoleConstant.BRANCH_UNION_CHAIRMAN, Cnd.where(Sys_user_role::getUnionId, "=", application.getUnionId()));
|
||||
if (StrUtil.isBlank(approvalLoginName)) {
|
||||
throw new RuntimeException("分工会未配置审批人,请联系管理员");
|
||||
}
|
||||
try {
|
||||
HashMap<String, Object> variables = new HashMap<>();
|
||||
variables.put("applicationId", application.getId());
|
||||
variables.put("status", BrandApplicationStatusEnums.IN_REVIEW.getCode());
|
||||
variables.put("userId", user.getId());
|
||||
bpmService.startSubmitProcessInstance(BpmProcessConstant.BRAND_STUDIO.name(), application.getName(), application.getId(), List.of(approvalLoginName), variables);
|
||||
updateApplicationStatusToFail(application.getId(), true);
|
||||
} catch (RuntimeException e) {
|
||||
updateApplicationStatusToFail(application.getId(), false);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateApplicationStatusToFail(String businessId, Boolean success) {
|
||||
if (success) {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.IN_REVIEW.getCode()),
|
||||
Cnd.where("id", "=", businessId));
|
||||
} else {
|
||||
dao().update(BrandStudioApplication.class,
|
||||
Chain.make("status", BrandApplicationStatusEnums.FAIL.getCode()),
|
||||
Cnd.where("id", "=", businessId));
|
||||
}
|
||||
}
|
||||
|
||||
private void insertBatchBrandStudioMember(List<BrandStudioMemberCreateDTO> memberCreateDTOS, String id) {
|
||||
List<BrandStudioMember> brandStudioMembers = BrandStudioMemberConvert.convertList(memberCreateDTOS);
|
||||
if (brandStudioMembers != null && !brandStudioMembers.isEmpty()) {
|
||||
brandStudioMembers.forEach(member -> member.setApplicationId(id));
|
||||
dao().insert(brandStudioMembers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void oaAuditUpdateStatus(String id, Integer status, String reason) {
|
||||
this.update(Chain.make("status", status), Cnd.where("id", "=", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(BrandStudioApplicationUpdateDTO dto) {
|
||||
BrandStudioApplication entity = BrandStudioApplicationConvert.convert(dto);
|
||||
updateIgnoreNull(entity);
|
||||
/// 先删除成员信息
|
||||
List<String> ids = Collections.singletonList(dto.getId());
|
||||
((BrandStudioMemberServiceImpl) studioMemberService).deleteByApplicationIds(ids);
|
||||
BrandApplicationStatusEnums statusByCode = BrandApplicationStatusEnums.getStatusByCode(dto.getStatus());
|
||||
if (statusByCode == null) {
|
||||
throw new RuntimeException("状态异常");
|
||||
}
|
||||
/// 再插入新的成员信息
|
||||
insertBatchBrandStudioMember(dto.getBrandStudioMembers(), dto.getId());
|
||||
if (statusByCode == BrandApplicationStatusEnums.CREATING) {
|
||||
/// 提交审核的话会记录在审核流表中
|
||||
submitAudit(fetch(dto.getId()), getCheckedUserDetail());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMemberOrHonor(BrandStudioApplicationUpdateDTO dto) {
|
||||
dao().update(BrandStudioApplication.class, Chain.make("memberNum", dto.getMemberNum()), Cnd.where("id", "=", dto.getId()));
|
||||
/// 先删除成员信息
|
||||
List<String> ids = Collections.singletonList(dto.getId());
|
||||
((BrandStudioMemberServiceImpl) studioMemberService).deleteByApplicationIds(ids);
|
||||
/// 再插入新的成员信息
|
||||
insertBatchBrandStudioMember(dto.getBrandStudioMembers(), dto.getId());
|
||||
/// 修改荣誉信息
|
||||
dao().update(BrandStudioHonor.class, Chain.make("delFlag", true), Cnd.where("applicationId", "in", ids));
|
||||
List<BrandStudioHonorCreateDTO> honorCreateDTOS = dto.getBrandStudioHonors();
|
||||
List<BrandStudioHonor> honors = BrandStudioHonorConvert.convertListDTO(honorCreateDTOS);
|
||||
if (honors != null && !honors.isEmpty()) {
|
||||
honors.forEach(honor -> honor.setApplicationId(dto.getId()));
|
||||
dao().insert(honors);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(List<String> ids) {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
|
||||
List<String> validIds = dao().query(BrandStudioApplication.class, Cnd.where("id", "in", ids)
|
||||
.and("userId", "=", userId)
|
||||
.and("delFlag", "=", false))
|
||||
.stream().map(BrandStudioApplication::getId).collect(toList());
|
||||
|
||||
Set<String> inputSet = new HashSet<>(ids);
|
||||
Set<String> validSet = new HashSet<>(validIds);
|
||||
if (!validSet.equals(inputSet)) {
|
||||
throw new RuntimeException("存在不可操作数据,删除失败");
|
||||
}
|
||||
|
||||
dao().update(BrandStudioApplication.class, Chain.make("delFlag", true), Cnd.where("id", "in", validIds));
|
||||
((BrandStudioMemberServiceImpl) studioMemberService).deleteByApplicationIds(validIds);
|
||||
flowService.deleteByApplicationIds(validIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUnionDeptVO queryUserUnion() {
|
||||
Sys_user user = getCurrentUser();
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户信息过期,请重新登录");
|
||||
}
|
||||
String unionId = SecurityUtil.getUnionId();
|
||||
if (StrUtil.isEmpty(unionId)) {
|
||||
throw new RuntimeException("未关联工会");
|
||||
}
|
||||
/// 获取用户所属公会和机构名
|
||||
SysUnionDeptVO sysUnionDeptVO = new SysUnionDeptVO();
|
||||
sysUnionDeptVO.setUserId(user.getId());
|
||||
sysUnionDeptVO.setUnionId(unionId);
|
||||
Sys_union union = dao().fetch(Sys_union.class, unionId);
|
||||
if (union != null) {
|
||||
sysUnionDeptVO.setUnionName(union.getName());
|
||||
sysUnionDeptVO.setTopUnionId(union.getId());
|
||||
sysUnionDeptVO.setTopUnionName(union.getName());
|
||||
}
|
||||
sysUnionDeptVO.setDeptId(user.getUnitId());
|
||||
Sys_unit unit = dao().fetch(Sys_unit.class, user.getUnitId());
|
||||
sysUnionDeptVO.setDeptName(unit == null ? null : unit.getName());
|
||||
return sysUnionDeptVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LeaderHonorGroupVO> queryLeaderHonor() {
|
||||
List<LeaderHonorVO> leaderHonorVOS = selectLeaderHonor();
|
||||
Map<String, List<LeaderHonorVO>> grouped = leaderHonorVOS.stream()
|
||||
.collect(Collectors.groupingBy(LeaderHonorVO::getEmplid));
|
||||
|
||||
return grouped.entrySet().stream()
|
||||
.map(entry -> {
|
||||
String emplid = entry.getKey();
|
||||
List<LeaderHonorVO> list = entry.getValue();
|
||||
// 假设同一 emplid 的 userName 相同,取第一个
|
||||
String userName = list.get(0).getUserName();
|
||||
Integer age = list.get(0).getAge();
|
||||
List<String> honorNames = list.stream()
|
||||
.map(LeaderHonorVO::getHonorName)
|
||||
.collect(Collectors.toList());
|
||||
return new LeaderHonorGroupVO(emplid, userName, age, honorNames);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrandStudioApplicationVO getDetailById(String id) {
|
||||
BrandStudioApplication entity = fetch(id);
|
||||
if (entity == null || Boolean.TRUE.equals(entity.getDelFlag())) {
|
||||
throw new RuntimeException("未查询到该申请记录");
|
||||
}
|
||||
BrandStudioApplicationVO applicationVO = BrandStudioApplicationConvert.convert(entity);
|
||||
List<BrandStudioMember> brandStudioMembers = dao().query(BrandStudioMember.class, Cnd.where("applicationId", "=", id).and("delFlag", "=", false));
|
||||
if (brandStudioMembers != null && !brandStudioMembers.isEmpty()) {
|
||||
List<BrandStudioMemberVO> brandStudioMembersVO = BrandStudioMemberConvert.convertListVO(brandStudioMembers);
|
||||
applicationVO.setBrandStudioMembers(brandStudioMembersVO);
|
||||
}
|
||||
|
||||
List<BrandStudioHonor> honorList = dao().query(BrandStudioHonor.class, Cnd.where("applicationId", "=", id).and("delFlag", "=", false));
|
||||
if (honorList != null && !honorList.isEmpty()) {
|
||||
List<BrandStudioHonorVO> honorVOS = BrandStudioHonorConvert.convertListVO(honorList);
|
||||
applicationVO.setBrandStudioHonors(honorVOS);
|
||||
}
|
||||
|
||||
/// 查询当前工作流待审核 ID
|
||||
return applicationVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void archive(List<String> idList) {
|
||||
if (idList == null || idList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
dao().update(BrandStudioApplication.class, Chain.make("archive", 1), Cnd.where("id", "in", idList));
|
||||
}
|
||||
|
||||
/// 之前的工作流逻辑,已废弃
|
||||
@Override
|
||||
public Pagination<BrandStudioApplyFlowVO> auditPage(BrandStudioApplicationPageDTO pageDTO) {
|
||||
return flowAuditPage(pageDTO);
|
||||
}
|
||||
|
||||
/// 新的工作流逻辑
|
||||
@Override
|
||||
public Pagination<BrandStudioApplyFlowVO> flowAuditPage(BrandStudioApplicationPageDTO dto) {
|
||||
Sql sql = Sqls.create("""
|
||||
select bsa.*, inst.id as processInstanceId, inst.processInstanceNodeName as processTaskNode,
|
||||
task.id as flowId, task.id as processInstanceTaskId, task.taskStatus as processTaskReason,
|
||||
task.createdOn as processTaskStartTime, task.endOn as processTaskEndTime
|
||||
from brand_studio_application bsa
|
||||
inner join bpm_process_instance inst on bsa.id = inst.processInstanceBusinessId
|
||||
inner join bpm_process_task task on inst.id = task.processInstanceId and task.delFlag = 0
|
||||
inner join bpm_process_define def on inst.processDefineId = def.id and def.code = 'BRAND_STUDIO'
|
||||
where bsa.delFlag = 0
|
||||
$condition
|
||||
order by task.createdOn desc
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (StrUtil.isNotBlank(dto.getName())) {
|
||||
cnd.and("bsa.name", "like", "%" + dto.getName() + "%");
|
||||
}
|
||||
if (StrUtil.isNotBlank(dto.getCreateYear())) {
|
||||
cnd.and("bsa.createYear", "=", dto.getCreateYear());
|
||||
}
|
||||
if (StrUtil.isNotBlank(dto.getLeadPeople())) {
|
||||
cnd.and("bsa.leadPeople", "like", "%" + dto.getLeadPeople() + "%");
|
||||
}
|
||||
if (dto.getProcessStatus() != null) {
|
||||
cnd.and("task.taskStatus", "=", getProcessTaskStatus(dto.getProcessStatus()));
|
||||
}
|
||||
if (dto.getStatus() != null) {
|
||||
cnd.and("bsa.status", "=", dto.getStatus());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return listPageVO(dto, sql, BrandStudioApplyFlowVO.class);
|
||||
}
|
||||
|
||||
private String getProcessTaskStatus(Integer processStatus) {
|
||||
if (Objects.equals(processStatus, 1)) {
|
||||
return BpmProcessTaskStatusEnum.ACTIVE.name();
|
||||
}
|
||||
if (Objects.equals(processStatus, 5)) {
|
||||
return BpmProcessTaskStatusEnum.COMPLETE.name();
|
||||
}
|
||||
return String.valueOf(processStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination<BrandStudioApplicationHonorVO> summaryPage(BrandStudioApplicationPageDTO pageDTO) {
|
||||
Sql sql = Sqls.create("""
|
||||
select bsa.*, bsh.id as honorId, bsh.honorName, bsh.honorGrade, bsh.requireYear, bsh.honorCategory
|
||||
from brand_studio_application bsa
|
||||
left join brand_studio_honor bsh on bsa.id = bsh.applicationId and bsh.delFlag = 0
|
||||
where bsa.delFlag = 0
|
||||
$condition
|
||||
order by bsa.createYear desc, bsa.createdAt desc
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (StrUtil.isNotBlank(pageDTO.getName())) {
|
||||
cnd.and("bsa.name", "like", "%" + pageDTO.getName() + "%");
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageDTO.getCreateYear())) {
|
||||
cnd.and("bsa.createYear", "=", pageDTO.getCreateYear());
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageDTO.getLeadPeople())) {
|
||||
cnd.and("bsa.leadPeople", "like", "%" + pageDTO.getLeadPeople() + "%");
|
||||
}
|
||||
if (pageDTO.getStatus() != null) {
|
||||
cnd.and("bsa.status", "=", pageDTO.getStatus());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return listPageVO(pageDTO, sql, BrandStudioApplicationHonorVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BrandStudioApplicationHonorVO> getHonorDetailById(String id) {
|
||||
List<BrandStudioHonor> brandStudioHonors = dao().query(BrandStudioHonor.class, Cnd.where("applicationId", "=", id).and("delFlag", "=", false));
|
||||
return BrandStudioHonorConvert.convertList(brandStudioHonors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export() {
|
||||
throw new RuntimeException("当前项目未配置品牌工作室台账导出模板");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportDocx(String id, HttpServletResponse response) {
|
||||
throw new RuntimeException("当前项目未配置品牌工作室申请文档模板");
|
||||
}
|
||||
|
||||
private List<LeaderHonorVO> selectLeaderHonor() {
|
||||
Sql sql = Sqls.create("""
|
||||
select su.id,
|
||||
su.loginname as emplid,
|
||||
su.username as userName,
|
||||
su.unitId as deptid,
|
||||
su.unitId,
|
||||
su.birthday,
|
||||
su.professionalTitle as honorName,
|
||||
u.unionId as unionId
|
||||
from sys_user su
|
||||
left join sys_unit u on su.unitId = u.id
|
||||
where su.delFlag = 0
|
||||
and su.disabled = 0
|
||||
""");
|
||||
return listVO(sql, LeaderHonorVO.class);
|
||||
}
|
||||
|
||||
private Sys_user getCurrentUser() {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
if (userId == null || userId.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return dao().fetch(Sys_user.class, userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.budwk.app.zhgh.brand.service.impl;
|
||||
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioHonor;
|
||||
import com.budwk.app.zhgh.brand.service.BrandStudioHonorService;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class BrandStudioHonorServiceImpl extends BaseServiceImpl<BrandStudioHonor> implements BrandStudioHonorService {
|
||||
|
||||
public BrandStudioHonorServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.budwk.app.zhgh.brand.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioMemberCreateDTO;
|
||||
import com.budwk.app.zhgh.brand.domain.dto.BrandStudioMemberUpdateDTO;
|
||||
import com.budwk.app.zhgh.brand.models.BrandStudioMember;
|
||||
import com.budwk.app.zhgh.brand.service.BrandStudioMemberService;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class BrandStudioMemberServiceImpl extends BaseServiceImpl<BrandStudioMember> implements BrandStudioMemberService {
|
||||
|
||||
public BrandStudioMemberServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(BrandStudioMemberCreateDTO dto) {
|
||||
BrandStudioMember member = BeanUtil.copyProperties(dto, BrandStudioMember.class);
|
||||
insert(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(BrandStudioMemberUpdateDTO dto) {
|
||||
BrandStudioMember member = BeanUtil.copyProperties(dto, BrandStudioMember.class);
|
||||
updateIgnoreNull(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(List<String> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
dao().update(BrandStudioMember.class, Chain.make("delFlag", true), Cnd.where("id", "in", ids));
|
||||
}
|
||||
|
||||
public void deleteByApplicationIds(List<String> applicationIds) {
|
||||
if (applicationIds == null || applicationIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
dao().update(BrandStudioMember.class, Chain.make("delFlag", true), Cnd.where("applicationId", "in", applicationIds));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 根据id查询流程列表
|
||||
*/
|
||||
export async function getBrandApplyFlowListApi(params) {
|
||||
return await request.get('/act/application/flow/process', {
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核
|
||||
*/
|
||||
export async function auditApplicationApi(data) {
|
||||
return await request.put('/act/application/flow/audit', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回
|
||||
*/
|
||||
export async function recallApplicationApi(data) {
|
||||
return await request.put('/act/application/flow/recall', data);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 查询申请人工会和机构
|
||||
*/
|
||||
export async function getUserBelongUnionApi(params) {
|
||||
return request.get('/act/brand/application/union', { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询领衔人和荣誉
|
||||
*/
|
||||
export async function getLeaderHonorApi(params) {
|
||||
return request.get('/act/brand/application/leader', { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询品牌工作室列表
|
||||
*/
|
||||
export async function getBrandStudioApplicationPageApi(params) {
|
||||
return request.get('/act/brand/application/page', { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询品牌工作室申请信息
|
||||
*/
|
||||
export async function getBrandStudioApplicationApi(id) {
|
||||
return await request.get('/act/brand/application/' + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加品牌工作室
|
||||
*/
|
||||
export async function addBrandStudioApplicationApi(data) {
|
||||
return await request.post('/act/brand/application', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改品牌工作室信息
|
||||
*/
|
||||
export async function updateBrandStudioApplicationApi(data) {
|
||||
return await request.put('/act/brand/application', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改品牌工作室基础信息
|
||||
*/
|
||||
export async function updateBrandStudioBaseInfoApi(data) {
|
||||
return await request.put('/act/brand/application/base', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改品牌工作室成员和荣誉信息
|
||||
*/
|
||||
export async function updateBrandStudioMemberOrHonorApi(data) {
|
||||
return await request.post('/act/brand/application/honor', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除品牌工作室
|
||||
*/
|
||||
export async function removeBrandStudioApplicationsApi(ids) {
|
||||
return await request.post('/act/brand/application/delete', { data: ids });
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询品牌工作室 待审核 列表
|
||||
*/
|
||||
export async function getBrandApplicationAuditPageApi(params) {
|
||||
return request.get('/act/brand/application/auditPage', { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询品牌工作室+荣誉列表
|
||||
*/
|
||||
export async function getBrandStudioApplicationHonorPageApi(params) {
|
||||
return request.get('/act/brand/application/summaryPage', { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询品牌工作室荣誉信息
|
||||
*/
|
||||
export async function getBrandStudioHonorApi(id) {
|
||||
return await request.get('/act/brand/application/honor/' + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交申请
|
||||
*/
|
||||
export async function submitApplicationApi(data) {
|
||||
return await request.put('/act/brand/application/submitApply', data);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 查询工会审批统计表单
|
||||
*/
|
||||
export async function getUnionApplyStatsApi(params) {
|
||||
return await request.get('/act/application/statistics/unionStats', {
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 各申请表单进度情况
|
||||
*/
|
||||
export async function getApplyProgressStatsApi(params) {
|
||||
return await request.get('/act/application/statistics/applyProgress', {
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 工会申请预警
|
||||
*/
|
||||
export async function getApplyWarningStatsApi(params) {
|
||||
return await request.get('/act/application/statistics/applyWarning', {
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计用户申请的各字段分组
|
||||
*/
|
||||
export async function getApplyCountStatsApi(params) {
|
||||
return await request.get('/act/application/statistics/applyCount', {
|
||||
params: params
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<el-form :inline="true" :model="pageForm">
|
||||
<el-form-item label="工作室名称">
|
||||
<el-input v-model="pageForm.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建年份">
|
||||
<el-date-picker v-model="pageForm.createYear" type="year" value-format="yyyy"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="pageData">查询</el-button>
|
||||
<el-button @click="openApply()">新建</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="tableData" border>
|
||||
<el-table-column type="index" label="序号" width="60"></el-table-column>
|
||||
<el-table-column prop="name" label="工作室名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="createYear" label="创立年度" width="100"></el-table-column>
|
||||
<el-table-column prop="leadPeople" label="领衔人" width="120"></el-table-column>
|
||||
<el-table-column prop="deptName" label="所属机构" min-width="140"></el-table-column>
|
||||
<el-table-column prop="type" label="工作室类型" width="120"></el-table-column>
|
||||
<el-table-column prop="track" label="工作室赛道" width="120"></el-table-column>
|
||||
<el-table-column prop="memberNum" label="成员人数" width="90"></el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template slot-scope="{row}">
|
||||
<el-tag v-if="row.status===0" type="info">草稿</el-tag>
|
||||
<el-tag v-else-if="row.status===1" type="warning">审核中</el-tag>
|
||||
<el-tag v-else-if="row.status===2" type="danger">驳回</el-tag>
|
||||
<el-tag v-else-if="row.status===5" type="success">通过</el-tag>
|
||||
<el-tag v-else>{{row.status}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<template slot-scope="{row}">
|
||||
<el-button type="text" @click="openApply(row.id)">编辑</el-button>
|
||||
<el-button type="text" @click="submitApply(row)" v-if="row.status===0 || row.status===7">申请</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
createYear: String(new Date().getFullYear())
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData(res) {
|
||||
return res.data && res.data.data !== undefined ? res.data.data : res.data
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.get('/platform/zhgh/brand/application/page', {params: this.pageForm}).then((res) => {
|
||||
const data = this.getData(res) || {}
|
||||
this.tableData = data.list || data.data || []
|
||||
})
|
||||
},
|
||||
openApply(id) {
|
||||
window.location.href = '/platform/zhgh/brand/apply/index' + (id ? '?id=' + id : '')
|
||||
},
|
||||
submitApply(row) {
|
||||
this.$axios.post('/platform/zhgh/brand/application/submitApply', {
|
||||
applicationId: row.id,
|
||||
status: 1
|
||||
}).then(() => {
|
||||
this.$message.success('申请成功')
|
||||
this.pageData()
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,416 @@
|
||||
<template>
|
||||
<ele-page>
|
||||
<!-- 搜索表单 -->
|
||||
<param-search @search="reload" />
|
||||
<ele-card :body-style="{ paddingTop: '8px' }">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:show-overflow-tooltip="true"
|
||||
v-model:selections="selections"
|
||||
highlight-current-row
|
||||
:export-config="{ fileName: '参数设置' }"
|
||||
cache-key="systemConfigTable"
|
||||
:tools="false"
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
:icon="PlusOutlined"
|
||||
v-permission="'system:config:add'"
|
||||
@click="openEdit()"
|
||||
>
|
||||
新建
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
class="ele-btn-icon hidden-sm-and-down"
|
||||
:icon="DeleteOutlined"
|
||||
v-permission="'system:config:remove'"
|
||||
@click="removeBatch()"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #createTime="{ row }">
|
||||
{{ dayjs(row.createTime).format('YYYY-MM-DD') }}
|
||||
</template>
|
||||
|
||||
<template #leadIdentity="{ row }">
|
||||
<div
|
||||
style="display: flex"
|
||||
v-for="(item, index) in JSON.parse(row.leadIdentity)"
|
||||
:key="index"
|
||||
>
|
||||
<el-tag type="primary">
|
||||
{{ item.dictLabel }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #memberNum="{ row }">
|
||||
{{ row.memberNum + '人' }}
|
||||
</template>
|
||||
|
||||
<template #status="{ row }">
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 0" type="info">
|
||||
草稿箱
|
||||
</el-tag>
|
||||
<el-tag
|
||||
style="cursor: pointer"
|
||||
v-if="row.status === 1"
|
||||
type="warning"
|
||||
>
|
||||
审核中
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 2" type="danger">
|
||||
驳回
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 4" type="info">
|
||||
取消
|
||||
</el-tag>
|
||||
<el-tag
|
||||
style="cursor: pointer"
|
||||
v-if="row.status === 5"
|
||||
type="success"
|
||||
>
|
||||
通过
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 6">
|
||||
正在创建
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 7">
|
||||
创建失败
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-if="[0, 2, 4].includes(row.status)"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="openEdit(row)"
|
||||
:icon="EditOutlined"
|
||||
>
|
||||
修改
|
||||
</el-link>
|
||||
<el-divider
|
||||
v-if="[2, 4].includes(row.status)"
|
||||
v-permission="['system:config:edit', 'system:config:remove']"
|
||||
direction="vertical"
|
||||
/>
|
||||
<el-link
|
||||
v-if="row.status !== 0"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click.stop="handleProcessDetail(row)"
|
||||
:icon="View"
|
||||
:disabled="row.status === 6 || row.status === 7"
|
||||
>
|
||||
查看
|
||||
</el-link>
|
||||
<el-divider
|
||||
v-if="row.status === 0"
|
||||
v-permission="['system:config:edit', 'system:config:remove']"
|
||||
direction="vertical"
|
||||
/>
|
||||
<el-link
|
||||
v-if="row.status === 0 || row.status === 7"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="submitApply(row)"
|
||||
:icon="FileOutlined"
|
||||
>
|
||||
申请
|
||||
</el-link>
|
||||
|
||||
<!-- <el-divider
|
||||
v-if="row.status !== 0 && row.status !== 2"
|
||||
v-permission="['system:config:edit', 'system:config:remove']"
|
||||
direction="vertical"
|
||||
/>
|
||||
<el-link
|
||||
v-if="row.status !== 0 && row.status !== 2"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="exportDocx(row.id)"
|
||||
:icon="DownloadOutlined"
|
||||
>
|
||||
导出
|
||||
</el-link>-->
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { EleMessage } from 'ele-admin-plus';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
EditOutlined,
|
||||
PlusOutlined
|
||||
} from '@/components/icons';
|
||||
import ParamSearch from '../components/param-search.vue';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
getBrandStudioApplicationPageApi,
|
||||
removeBrandStudioApplicationsApi
|
||||
} from '@/api/office/brand/index.js';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { BRAND_APPLY_PATH } from '@/config/setting.js';
|
||||
const { push } = useRouter();
|
||||
import { usePageTab } from '@/utils/use-page-tab';
|
||||
import { View } from '@element-plus/icons-vue';
|
||||
import $enums from '@/utils/enums.js';
|
||||
import { FileOutlined, DownloadOutlined } from '@/components/icons/index.js';
|
||||
import { submitApplicationApi } from '@/api/office/brand/index.js';
|
||||
import request from '@/utils/request.js';
|
||||
const { addPageTab } = usePageTab();
|
||||
|
||||
defineOptions({ name: 'Application' });
|
||||
|
||||
/** 表格实例 */
|
||||
const tableRef = ref(null);
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
{
|
||||
type: 'selection',
|
||||
columnKey: 'selection',
|
||||
width: 50,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
type: 'index',
|
||||
columnKey: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
label: '序号'
|
||||
},
|
||||
{
|
||||
prop: 'name',
|
||||
label: '工作室名称',
|
||||
align: 'center',
|
||||
minWidth: 180
|
||||
},
|
||||
{
|
||||
prop: 'createYear',
|
||||
label: '创立年度',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'createYear'
|
||||
},
|
||||
{
|
||||
prop: 'leadPeople',
|
||||
label: '领衔人',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'leadPeople'
|
||||
},
|
||||
{
|
||||
prop: 'deptName',
|
||||
label: '所属单位机构',
|
||||
minWidth: 120,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'type',
|
||||
label: '工作室类型',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'type'
|
||||
},
|
||||
{
|
||||
prop: 'track',
|
||||
label: '工作室赛道',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'track'
|
||||
},
|
||||
{
|
||||
prop: 'memberNum',
|
||||
label: '成员人数',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'memberNum'
|
||||
},
|
||||
{
|
||||
prop: 'address',
|
||||
label: '工作室地址',
|
||||
minWidth: 140,
|
||||
align: 'center',
|
||||
slot: 'address'
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '申请时间',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'createTime'
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
minWidth: 80,
|
||||
align: 'center',
|
||||
slot: 'status'
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
hideInPrint: true,
|
||||
hideInExport: true,
|
||||
fixed: 'right'
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
/** 表格选中数据 */
|
||||
const selections = ref([]);
|
||||
|
||||
/** 当前编辑数据 */
|
||||
const current = ref(null);
|
||||
|
||||
/** 表格数据源 */
|
||||
const datasource = async ({ pages, where, filters }) => {
|
||||
where = {
|
||||
...where,
|
||||
createYear: new Date().getFullYear().toString()
|
||||
};
|
||||
const { data } = await getBrandStudioApplicationPageApi({
|
||||
...where,
|
||||
...filters,
|
||||
...pages
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
/** 搜索 */
|
||||
const reload = (where) => {
|
||||
tableRef.value?.reload?.({ page: 1, where });
|
||||
};
|
||||
|
||||
/** 打开编辑弹窗 */
|
||||
const openEdit = (row) => {
|
||||
current.value = row ?? null;
|
||||
|
||||
const path = row ? BRAND_APPLY_PATH + '/' + row.id : BRAND_APPLY_PATH;
|
||||
addPageTab({
|
||||
title: row ? `修改申请` : '创建申请',
|
||||
key: path,
|
||||
closable: true,
|
||||
meta: { icon: 'LinkOutlined' }
|
||||
});
|
||||
push(path);
|
||||
};
|
||||
|
||||
/** 批量删除 */
|
||||
const removeBatch = (row) => {
|
||||
const rows = row == null ? selections.value : [row];
|
||||
if (!rows.length) {
|
||||
EleMessage.error({ message: '请至少选择一条数据', plain: true });
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(
|
||||
`是否确认删除"${rows.map((d) => d.name).join()}"工作室?`,
|
||||
'系统提示',
|
||||
{ type: 'warning', draggable: true }
|
||||
)
|
||||
.then(() => {
|
||||
const loading = EleMessage.loading({
|
||||
message: '请求中..',
|
||||
plain: true
|
||||
});
|
||||
console.log(rows);
|
||||
removeBrandStudioApplicationsApi(rows.map((d) => d.id))
|
||||
.then(() => {
|
||||
loading.close();
|
||||
EleMessage.success({ message: '删除成功', plain: true });
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
EleMessage.error({ message: e.message, plain: true });
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交申请 id
|
||||
const submitApply = (row) => {
|
||||
console.log('submitApply');
|
||||
ElMessageBox.confirm(`确认申请「${row.name}」工作室?`, '系统提示', {
|
||||
type: 'warning',
|
||||
draggable: true
|
||||
})
|
||||
.then(() => {
|
||||
const loading = EleMessage.loading({
|
||||
message: '请求中..',
|
||||
plain: true
|
||||
});
|
||||
const params = {
|
||||
applicationId: row.id,
|
||||
status: 1
|
||||
};
|
||||
submitApplicationApi(params)
|
||||
.then(() => {
|
||||
loading.close();
|
||||
EleMessage.success({ message: '申请成功', plain: true });
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
EleMessage.error({ message: e.message, plain: true });
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
/** 审批进度 */
|
||||
const handleProcessDetail = (row) => {
|
||||
push({
|
||||
name: 'WorkflowProcessInstanceDetail',
|
||||
query: {
|
||||
businessId: row.id,
|
||||
businessType:
|
||||
$enums.BUSINESS_PROCESS_KEY_NUMBER.BRAND_OFFICE_USER_APPLY,
|
||||
processFormPath: encodeURI('/brand/components/flow-view.vue')
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
import { saveAs } from 'file-saver';
|
||||
/** 导出申请表格文档 */
|
||||
const exportDocx = async (id) => {
|
||||
const token = localStorage.getItem('token');
|
||||
const res = await request({
|
||||
url: `/act/brand/application/export/docx/${id}`,
|
||||
method: 'POST',
|
||||
responseType: 'blob',
|
||||
headers: { Authorization: token }
|
||||
});
|
||||
console.log('OK res=', res);
|
||||
// 处理返回的Blob数据
|
||||
const blob = new Blob([res.data], {
|
||||
type: res.data.type || 'application/docx'
|
||||
});
|
||||
const fileName = `上海浦东发展银行个人品牌工作室推荐表.docx`;
|
||||
saveAs(blob, fileName, null);
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,411 @@
|
||||
<template>
|
||||
<ele-page>
|
||||
<!-- 搜索表单 -->
|
||||
<param-search @search="reload" />
|
||||
<ele-card :body-style="{ paddingTop: '8px' }">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:show-overflow-tooltip="true"
|
||||
v-model:selections="selections"
|
||||
highlight-current-row
|
||||
:export-config="{ fileName: '参数设置' }"
|
||||
cache-key="systemConfigTable"
|
||||
:tools="false"
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
:icon="PlusOutlined"
|
||||
v-permission="'system:config:add'"
|
||||
@click="openEdit()"
|
||||
>
|
||||
新建
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
class="ele-btn-icon hidden-sm-and-down"
|
||||
:icon="DeleteOutlined"
|
||||
v-permission="'system:config:remove'"
|
||||
@click="removeBatch()"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #createTime="{ row }">
|
||||
{{ dayjs(row.createTime).format('YYYY-MM-DD') }}
|
||||
</template>
|
||||
|
||||
<template #leadIdentity="{ row }">
|
||||
<div
|
||||
style="display: flex"
|
||||
v-for="(item, index) in JSON.parse(row.leadIdentity)"
|
||||
:key="index"
|
||||
>
|
||||
<el-tag type="primary">
|
||||
{{ item.dictLabel }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #memberNum="{ row }">
|
||||
{{ row.memberNum + '人' }}
|
||||
</template>
|
||||
|
||||
<template #status="{ row }">
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 0" type="info">
|
||||
草稿箱
|
||||
</el-tag>
|
||||
<el-tag
|
||||
style="cursor: pointer"
|
||||
v-if="row.status === 1"
|
||||
type="warning"
|
||||
>
|
||||
审核中
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 2" type="danger">
|
||||
驳回
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.status === 3" type="info">
|
||||
撤销
|
||||
</el-tag>
|
||||
<el-tag
|
||||
style="cursor: pointer"
|
||||
v-if="row.status === 5"
|
||||
type="success"
|
||||
>
|
||||
通过
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-if="row.status !== 0"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="showFlow(row)"
|
||||
:icon="FileOutlined"
|
||||
>
|
||||
查看
|
||||
</el-link>
|
||||
<el-divider
|
||||
v-if="![0, 3, 5].includes(row.status)"
|
||||
v-permission="['system:config:edit', 'system:config:remove']"
|
||||
direction="vertical"
|
||||
/>
|
||||
<el-link
|
||||
v-if="row.status === 0 || row.status === 2"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="openEdit(row)"
|
||||
:icon="EditOutlined"
|
||||
>
|
||||
修改
|
||||
</el-link>
|
||||
<el-divider
|
||||
v-if="row.status === 0"
|
||||
v-permission="['system:config:edit', 'system:config:remove']"
|
||||
direction="vertical"
|
||||
/>
|
||||
<el-link
|
||||
v-if="row.status === 0"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="submitApply(row)"
|
||||
:icon="FileOutlined"
|
||||
>
|
||||
申请
|
||||
</el-link>
|
||||
<el-link
|
||||
v-if="row.status === 1"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click.stop="handleReturn(row)"
|
||||
:icon="ReloadOutlined"
|
||||
>
|
||||
撤回
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
<flow-audit
|
||||
v-model="showFlowCurrent"
|
||||
:data="current"
|
||||
:is-audit="false"
|
||||
@done="reload"
|
||||
/>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import {EleMessage} from 'ele-admin-plus';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
EditOutlined,
|
||||
PlusOutlined
|
||||
} from '@/components/icons';
|
||||
import ParamSearch from '../components/param-search.vue';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
getBrandStudioApplicationPageApi,
|
||||
removeBrandStudioApplicationsApi
|
||||
} from '@/api/office/brand/index.js';
|
||||
import { FileOutlined, ReloadOutlined } from '@/components/icons/index.js';
|
||||
import {
|
||||
recallApplicationApi,
|
||||
} from '@/api/office/application/index.js';
|
||||
import FlowAudit from '@/views/brand/components/flow-audit.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { BRAND_APPLY_PATH } from '@/config/setting.js';
|
||||
const { push } = useRouter();
|
||||
import { usePageTab } from '@/utils/use-page-tab';
|
||||
const { addPageTab } = usePageTab();
|
||||
|
||||
defineOptions({ name: 'Application' });
|
||||
|
||||
/** 表格实例 */
|
||||
const tableRef = ref(null);
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
{
|
||||
type: 'selection',
|
||||
columnKey: 'selection',
|
||||
width: 50,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
type: 'index',
|
||||
columnKey: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
label: '序号'
|
||||
},
|
||||
{
|
||||
prop: 'name',
|
||||
label: '工作室名称',
|
||||
align: 'center',
|
||||
minWidth: 180
|
||||
},
|
||||
{
|
||||
prop: 'createYear',
|
||||
label: '创立年度',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'createYear'
|
||||
},
|
||||
{
|
||||
prop: 'leadPeople',
|
||||
label: '领衔人',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'leadPeople'
|
||||
},
|
||||
{
|
||||
prop: 'deptName',
|
||||
label: '所属单位机构',
|
||||
minWidth: 120,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'type',
|
||||
label: '工作室类型',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'type'
|
||||
},
|
||||
{
|
||||
prop: 'track',
|
||||
label: '工作室赛道',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'track'
|
||||
},
|
||||
{
|
||||
prop: 'memberNum',
|
||||
label: '成员人数',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'memberNum'
|
||||
},
|
||||
{
|
||||
prop: 'address',
|
||||
label: '工作室地址',
|
||||
minWidth: 140,
|
||||
align: 'center',
|
||||
slot: 'address'
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '申请时间',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'createTime'
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
minWidth: 80,
|
||||
align: 'center',
|
||||
slot: 'status'
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
hideInPrint: true,
|
||||
hideInExport: true,
|
||||
fixed: 'right'
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
/** 表格选中数据 */
|
||||
const selections = ref([]);
|
||||
|
||||
/** 当前编辑数据 */
|
||||
const current = ref(null);
|
||||
|
||||
/** 表格数据源 */
|
||||
const datasource = async ({ pages, where, filters }) => {
|
||||
const { data } = await getBrandStudioApplicationPageApi({
|
||||
...where,
|
||||
...filters,
|
||||
...pages
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
/** 搜索 */
|
||||
const reload = (where) => {
|
||||
tableRef.value?.reload?.({ page: 1, where });
|
||||
};
|
||||
|
||||
/** 打开编辑弹窗 */
|
||||
const openEdit = (row) => {
|
||||
current.value = row ?? null;
|
||||
|
||||
const path = row ? BRAND_APPLY_PATH + '/' + row.id : BRAND_APPLY_PATH;
|
||||
addPageTab({
|
||||
title: row ? `修改申请` : '创建申请',
|
||||
key: path,
|
||||
closable: true,
|
||||
meta: { icon: 'LinkOutlined' }
|
||||
});
|
||||
push(path);
|
||||
};
|
||||
|
||||
/** 批量删除 */
|
||||
const removeBatch = (row) => {
|
||||
const rows = row == null ? selections.value : [row];
|
||||
if (!rows.length) {
|
||||
EleMessage.error({ message: '请至少选择一条数据', plain: true });
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(
|
||||
`是否确认删除"${rows.map((d) => d.name).join()}"工作室?`,
|
||||
'系统提示',
|
||||
{ type: 'warning', draggable: true }
|
||||
)
|
||||
.then(() => {
|
||||
const loading = EleMessage.loading({
|
||||
message: '请求中..',
|
||||
plain: true
|
||||
});
|
||||
console.log(rows);
|
||||
removeBrandStudioApplicationsApi(rows.map((d) => d.id))
|
||||
.then(() => {
|
||||
loading.close();
|
||||
EleMessage.success({ message: '删除成功', plain: true });
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
EleMessage.error({ message: e.message, plain: true });
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
const showFlowCurrent = ref(false);
|
||||
//查看流程列表
|
||||
const showFlow = (row) => {
|
||||
console.log('showFlow');
|
||||
current.value = row ?? null;
|
||||
showFlowCurrent.value = true;
|
||||
};
|
||||
|
||||
// 用户撤回申请
|
||||
const handleReturn = (row) => {
|
||||
console.log('handleReturn');
|
||||
console.log(row);
|
||||
ElMessageBox.confirm(`确认撤回"${row.name}"工作室申请吗?`, '系统提示', {
|
||||
type: 'warning',
|
||||
draggable: true
|
||||
})
|
||||
.then(() => {
|
||||
const loading = EleMessage.loading({
|
||||
message: '请求中..',
|
||||
plain: true
|
||||
});
|
||||
const params = {
|
||||
applicationId: row.id
|
||||
};
|
||||
recallApplicationApi(params)
|
||||
.then(() => {
|
||||
loading.close();
|
||||
EleMessage.success({ message: '撤回成功', plain: true });
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
EleMessage.error({ message: e.message, plain: true });
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交申请 id
|
||||
const submitApply = (row) => {
|
||||
console.log('submitApply');
|
||||
ElMessageBox.confirm(`确认申请"${row.name}"工作室?`, '系统提示', {
|
||||
type: 'warning',
|
||||
draggable: true
|
||||
})
|
||||
.then(() => {
|
||||
const loading = EleMessage.loading({
|
||||
message: '请求中..',
|
||||
plain: true
|
||||
});
|
||||
const params = {
|
||||
applicationId: row.id,
|
||||
status: 1
|
||||
};
|
||||
submitApplicationApi(params)
|
||||
.then(() => {
|
||||
loading.close();
|
||||
EleMessage.success({ message: '申请成功', plain: true });
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
EleMessage.error({ message: e.message, plain: true });
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,126 @@
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { BRAND_APPLICATION_PATH } from '@/config/setting';
|
||||
import {
|
||||
getBrandStudioApplicationApi,
|
||||
getUserBelongUnionApi,
|
||||
} from '@/api/office/brand/index.js';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import TableInfo from "@/views/brand/components/table-info.vue";
|
||||
|
||||
const { push } = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const childRef = ref()
|
||||
/** 是否是修改:针对整体 */
|
||||
const isUpdate = ref(false);
|
||||
|
||||
/** 提交状态 */
|
||||
const loading = ref(false);
|
||||
|
||||
const unionId = ref('');
|
||||
const topUnionId = ref('');
|
||||
|
||||
const handleCancel = () => {
|
||||
push(BRAND_APPLICATION_PATH);
|
||||
};
|
||||
|
||||
const save = (saveType) => {
|
||||
loading.value = true;
|
||||
// 调用子组件进行数据提交
|
||||
childRef.value.submit({
|
||||
saveType: saveType,
|
||||
isUpdate: isUpdate.value
|
||||
})
|
||||
};
|
||||
|
||||
// 编辑结束回调
|
||||
const editFinish = () => {
|
||||
push(BRAND_APPLICATION_PATH);
|
||||
}
|
||||
|
||||
const brandForm = ref({})
|
||||
const queryInfoById = (id) => {
|
||||
loading.value = true
|
||||
getBrandStudioApplicationApi(id)
|
||||
.then(({ data }) => {
|
||||
console.log(data)
|
||||
brandForm.value = data
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
});
|
||||
};
|
||||
|
||||
const userUnionInfo = ref({})
|
||||
// 获取成员当前所在工会
|
||||
const loadUserUnion = async () => {
|
||||
const { data } = await getUserBelongUnionApi();
|
||||
unionId.value = data.unionId;
|
||||
topUnionId.value = data.topUnionId;
|
||||
userUnionInfo.value = data
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('mounted');
|
||||
await loadUserUnion();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => {
|
||||
const id = route.params.id;
|
||||
if (id) {
|
||||
queryInfoById(id);
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ele-page>
|
||||
<ele-card
|
||||
:body-style="{ paddingTop: '30px' }"
|
||||
>
|
||||
<table-info
|
||||
ref="childRef"
|
||||
:edit-mode="true"
|
||||
v-model:loading="loading"
|
||||
:user-union-info="userUnionInfo"
|
||||
:brand-form="brandForm"
|
||||
@editFinish="editFinish"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="foot-btn">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button
|
||||
v-if="!isUpdate"
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
@click="save(0)"
|
||||
>
|
||||
保存草稿
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save(1)">
|
||||
提交申请
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</ele-card>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.foot-btn {
|
||||
padding-right: 60px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,209 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
<span>{{form.id ? '修改申请' : '创建申请'}}</span>
|
||||
</div>
|
||||
<el-form ref="form" :model="form" label-width="130px">
|
||||
<el-row :gutter="15">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室名称">
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建年份">
|
||||
<el-date-picker v-model="form.createYear" type="year" value-format="yyyy" style="width: 100%"></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属工会">
|
||||
<el-input v-model="form.unionName"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属机构">
|
||||
<el-input v-model="form.deptName"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人">
|
||||
<el-input v-model="form.leadPeople"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人年龄">
|
||||
<el-input-number v-model="form.leadAge" :min="0" :max="150" style="width: 100%"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人身份">
|
||||
<el-input v-model="form.leadIdentity"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人荣誉">
|
||||
<el-input v-model="form.leadHonor"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室类型">
|
||||
<el-input v-model="form.type"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属赛道">
|
||||
<el-input v-model="form.track"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属领域">
|
||||
<el-input v-model="form.domain"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="成员人数">
|
||||
<el-input-number v-model="form.memberNum" :min="1" style="width: 100%"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="工作室地址">
|
||||
<el-input v-model="form.address"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="工作室介绍">
|
||||
<el-input type="textarea" :rows="4" v-model="form.introduction"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input type="textarea" :rows="2" v-model="form.remark"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider content-position="left">工作室成员</el-divider>
|
||||
<el-table :data="form.brandStudioMembers" border size="small">
|
||||
<el-table-column label="姓名" min-width="120">
|
||||
<template slot-scope="{row}">
|
||||
<el-input v-model="row.name"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="角色" min-width="120">
|
||||
<template slot-scope="{row}">
|
||||
<el-input v-model="row.role"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出生年月" min-width="120">
|
||||
<template slot-scope="{row}">
|
||||
<el-input v-model="row.birthdate"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学历" min-width="120">
|
||||
<template slot-scope="{row}">
|
||||
<el-input v-model="row.grade"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="职称" min-width="120">
|
||||
<template slot-scope="{row}">
|
||||
<el-input v-model="row.professional"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click="removeMember(scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="margin-top: 10px">
|
||||
<el-button size="small" @click="addMember">添加成员</el-button>
|
||||
</div>
|
||||
|
||||
<el-form-item style="margin-top: 20px">
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save(0)">保存草稿</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save(6)">提交申请</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
form: {
|
||||
archive: 0,
|
||||
status: 0,
|
||||
brandStudioMembers: []
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getParam(name) {
|
||||
return new URLSearchParams(window.location.search).get(name)
|
||||
},
|
||||
getData(res) {
|
||||
return res.data && res.data.data !== undefined ? res.data.data : res.data
|
||||
},
|
||||
loadUserInfo() {
|
||||
const user = this.$store.state.user || {}
|
||||
const unit = user.unit || {}
|
||||
const union = user.union || {}
|
||||
this.form.unionId = union.id || unit.unionId
|
||||
this.form.unionName = union.name
|
||||
this.form.deptid = user.unitId || unit.id
|
||||
this.form.deptName = unit.name
|
||||
},
|
||||
loadDetail(id) {
|
||||
this.$axios.get('/platform/zhgh/brand/application/' + id).then((res) => {
|
||||
const data = this.getData(res) || {}
|
||||
data.brandStudioMembers = data.brandStudioMembers || []
|
||||
this.form = data
|
||||
})
|
||||
},
|
||||
addMember() {
|
||||
this.form.brandStudioMembers.push({})
|
||||
},
|
||||
removeMember(index) {
|
||||
this.form.brandStudioMembers.splice(index, 1)
|
||||
},
|
||||
save(status) {
|
||||
this.loading = true
|
||||
this.form.status = status
|
||||
const request = this.form.id
|
||||
? this.$axios.post('/platform/zhgh/brand/application/update', this.form)
|
||||
: this.$axios.post('/platform/zhgh/brand/application', this.form)
|
||||
request.then(() => {
|
||||
this.$message.success('保存成功')
|
||||
this.goBack()
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
goBack() {
|
||||
window.location.href = '/platform/zhgh/brand/application/index'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const id = this.getParam('id')
|
||||
if (id) {
|
||||
this.loadDetail(id)
|
||||
} else {
|
||||
this.loadUserInfo()
|
||||
this.addMember()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,149 @@
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { BRAND_APPLICATION_PATH } from '@/config/setting';
|
||||
import {
|
||||
getBrandStudioApplicationApi,
|
||||
getUserBelongUnionApi
|
||||
} from '@/api/office/brand/index.js';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import $enums from '@/utils/enums.js';
|
||||
import BusinessInstanceTimeLine from '@/components/BusinessInstanceTimeLine/index.vue';
|
||||
import ApplyInfo from '@/views/brand/components/apply-info.vue';
|
||||
|
||||
const { push } = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const childRef = ref();
|
||||
|
||||
/** 是否是修改:针对整体 */
|
||||
const isUpdate = ref(false);
|
||||
|
||||
/** 提交状态 */
|
||||
const loading = ref(false);
|
||||
|
||||
const handleCancel = () => {
|
||||
push(BRAND_APPLICATION_PATH);
|
||||
};
|
||||
|
||||
const save = (saveType) => {
|
||||
loading.value = true;
|
||||
childRef.value.submit({
|
||||
saveType: saveType,
|
||||
isUpdate: isUpdate.value
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑结束回调
|
||||
const editFinish = () => {
|
||||
push(BRAND_APPLICATION_PATH);
|
||||
};
|
||||
|
||||
const brandForm = ref({});
|
||||
const queryInfoById = (id) => {
|
||||
loading.value = true;
|
||||
getBrandStudioApplicationApi(id)
|
||||
.then(({ data }) => {
|
||||
brandForm.value = data;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const unionId = ref('');
|
||||
const topUnionId = ref('');
|
||||
const userUnionInfo = ref({});
|
||||
// 获取成员当前所在工会
|
||||
const loadUserUnion = async () => {
|
||||
const { data } = await getUserBelongUnionApi();
|
||||
unionId.value = data.unionId;
|
||||
topUnionId.value = data.topUnionId;
|
||||
userUnionInfo.value = data;
|
||||
};
|
||||
onMounted(async () => {
|
||||
console.log('mounted');
|
||||
await loadUserUnion();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => {
|
||||
const id = route.params.id;
|
||||
if (id) {
|
||||
queryInfoById(id);
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ele-page>
|
||||
<!-- :header="isUpdate ? '修改申请' : '创建申请'"-->
|
||||
<ele-card :body-style="{ paddingTop: '8px' }" v-loading="loading">
|
||||
<div class="container-fluid">
|
||||
<el-scrollbar style="height: 730px; flex: 1;min-width: 800px">
|
||||
<div style="padding: 0 40px 0 30px">
|
||||
<h3 style="color: black">{{
|
||||
isUpdate ? '修改申请' : '创建申请'
|
||||
}}</h3>
|
||||
<apply-info
|
||||
ref="childRef"
|
||||
:edit-mode="true"
|
||||
v-model:loading="loading"
|
||||
:user-union-info="userUnionInfo"
|
||||
:brand-form="brandForm"
|
||||
@editFinish="editFinish"
|
||||
/>
|
||||
<div class="foot-btn">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save(0)">
|
||||
保存草稿
|
||||
</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save(6)">
|
||||
提交申请
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<div class="border-left ml-10px mr-20px"></div>
|
||||
<div class="container-right">
|
||||
<h3 style="color: black">审批流程</h3>
|
||||
<BusinessInstanceTimeLine
|
||||
ref="businessInstanceTimeLine"
|
||||
v-model:business-data="userUnionInfo"
|
||||
:oa-key="$enums.BUSINESS_PROCESS_KEY.BRAND_OFFICE_USER_APPLY"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</ele-card>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@import url('@/styles/workflow.scss');
|
||||
.container-fluid {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
:deep(.el-scrollbar__bar.is-vertical) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.foot-btn {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 5px 0 30px 0;
|
||||
}
|
||||
|
||||
.container-right {
|
||||
min-width: 350px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,699 @@
|
||||
<script setup>
|
||||
|
||||
import {StrUtil} from "@/utils/toolkit.js";
|
||||
import {DeleteOutlined} from "@/components/icons/index.js";
|
||||
import SurveyTreeSelect from "@/views/survey/components/survey-tree-select.vue";
|
||||
import {QuestionFilled} from "@element-plus/icons-vue";
|
||||
import {computed, onMounted, reactive, ref, watch} from "vue";
|
||||
import {useDictData} from "@/utils/use-dict-data.js";
|
||||
import {useFormData} from "@/utils/use-form-data.js";
|
||||
import {ElMessageBox} from "element-plus";
|
||||
import {
|
||||
addBrandStudioApplicationApi,
|
||||
getLeaderHonorApi,
|
||||
updateBrandStudioApplicationApi
|
||||
} from "@/api/office/brand/index.js";
|
||||
import UnionUserSelect from "@/components/UnionUserSelect/index.vue";
|
||||
import {EleMessage} from "ele-admin-plus";
|
||||
import {withRequiredHeader} from "@/views/brand/js/common-brand.js";
|
||||
import {useUserStore} from "@/store/modules/user.js";
|
||||
|
||||
const props = defineProps({
|
||||
editMode: Boolean,
|
||||
loading: Boolean,
|
||||
userUnionInfo: Object, // 用户工会相关信息
|
||||
topUnionId: String, // 最上层工会ID
|
||||
brandForm: Object // 表格信息,修改时使用
|
||||
})
|
||||
const emit = defineEmits(['update:loading', 'editFinish'])
|
||||
/** 领衔人荣誉 */
|
||||
const leaderHonors = ref([]);
|
||||
const userStore = useUserStore()
|
||||
/** 表单实例 */
|
||||
const formRef = ref(null);
|
||||
|
||||
/** 字典数据 */
|
||||
const [
|
||||
leadPeopleDict,
|
||||
brandOfficeTypeDict,
|
||||
userEducationDict,
|
||||
brandOfficeDomainDict
|
||||
] = useDictData([
|
||||
'lead_people',
|
||||
'brand_office_type',
|
||||
'user_education',
|
||||
'brand_office_domain'
|
||||
]);
|
||||
|
||||
/** 表单数据 */
|
||||
const [form, resetFields, assignFields] = useFormData({
|
||||
id: '',
|
||||
unionName: '', // 所属单位工会
|
||||
deptName: '',
|
||||
name: '', // 工作室名称
|
||||
createYear: '', // 创建年度
|
||||
leadPeople: '', // 工作室领衔人
|
||||
leadAge: 0, // 领衔人年龄
|
||||
leadIdentity: [], // 领衔人身份
|
||||
leadHonor: '', // 领衔人荣誉称号
|
||||
memberNum: 0, // 成员人数
|
||||
type: '', // 工作室类型
|
||||
track: '', // 工作室赛道
|
||||
address: '', // 工作室具体位置
|
||||
introduction: '', // 工作室基本情况介绍
|
||||
brandStudioMembers: [] // 工作室成员 { name, birthday, grade, professional, unionName }
|
||||
});
|
||||
|
||||
/** 表单验证规则 */
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入工作室名称',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
unionName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入所属单位工会',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
deptName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入所属单位机构',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
createYear: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择创建年度',
|
||||
type: 'string',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
leadPeople: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择工作室领衔人',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{ type: 'string', max: 20, message: '领衔人最多 20 个字符', trigger: ['blur', 'change'] }
|
||||
],
|
||||
leadAge: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入领衔人年龄',
|
||||
type: 'number',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
min: 0,
|
||||
max: 150,
|
||||
message: '年龄必须在0-150岁之间',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
leadIdentity: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择领衔人身份',
|
||||
type: 'array',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
leadHonor: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入领衔人荣誉称号',
|
||||
type: 'string',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
memberNum: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入成员人数',
|
||||
type: 'number',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择工作室类型',
|
||||
type: 'string',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
track: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入工作室赛道',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
address: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入工作室具体位置',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
introduction: [
|
||||
{
|
||||
required: true,
|
||||
message: '请填写工作室基本情况介绍',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
brandStudioMembers: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
// 1. 必须是数组且长度 >= 3
|
||||
if (!Array.isArray(value) || value.length < 1) {
|
||||
ElMessageBox.alert(
|
||||
`请至少选择1位工作室成员!`,
|
||||
`系统提示`, {
|
||||
confirmButtonText: '确定',
|
||||
type: 'warning',
|
||||
});
|
||||
return callback(new Error('请至少选择1位工作室成员'));
|
||||
}
|
||||
|
||||
// 2. 检查每个成员的必填字段
|
||||
const requiredFields = columns.value
|
||||
.filter((col) => col.notRequired !== true)
|
||||
.map((col) => col.prop); // ['name', 'birthdate', ...]
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const item = value[i];
|
||||
for (const field of requiredFields) {
|
||||
const val = item?.[field];
|
||||
if (StrUtil.isEmpty(val)) {
|
||||
const label = fieldLabelMap[field] || field; // fallback to field name
|
||||
ElMessageBox.alert(
|
||||
`【${item.name}】成员的【${label}】不能为空!`,
|
||||
`系统提示`, {
|
||||
confirmButtonText: '确定',
|
||||
type: 'warning',
|
||||
});
|
||||
return callback(
|
||||
new Error(`${item.name} 的“${label}”不能为空`)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback(); // 校验通过
|
||||
},
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
/** 二级弹窗是否打开:选择用户 */
|
||||
const selectUserVisible = ref(false);
|
||||
/** beforeConfirm 为确定按钮点击钩子, 可以 return false 阻止确定 */
|
||||
const beforeConfirm = (data) => {
|
||||
if (!data?.length) {
|
||||
EleMessage.error('请至少选择一个用户');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => [
|
||||
withRequiredHeader({ prop: 'name', label: '姓名', align: 'center', minWidth: 80, slot: 'name' }),
|
||||
withRequiredHeader({ prop: 'birthdate', label: '出生年月', align: 'center', minWidth: 120, slot: 'birthdate', required: true }),
|
||||
withRequiredHeader({ prop: 'grade', label: '学历', align: 'center', minWidth: 80, slot: 'grade', required: true }),
|
||||
withRequiredHeader({ prop: 'professional', label: '职称', align: 'center', minWidth: 100, slot: 'professional', required: true }),
|
||||
withRequiredHeader({ prop: 'deptName', label: '所在部门', align: 'center', minWidth: 100, slot: 'deptName' }),
|
||||
withRequiredHeader({ columnKey: 'action', label: '操作', width: 80, align: 'center', slot: 'action', notRequired: true })
|
||||
]);
|
||||
// 自动生成映射:{ name: '姓名', birthdate: '出生年月', ... }
|
||||
const fieldLabelMap = {};
|
||||
columns.value.forEach((col) => {
|
||||
fieldLabelMap[col.prop] = col.label;
|
||||
});
|
||||
|
||||
const leaderChange = (emplid) => {
|
||||
console.log('emplid: ' + emplid);
|
||||
const matchedItem = leaderHonors.value.find(
|
||||
(item) => item.emplid === emplid
|
||||
);
|
||||
if (matchedItem) {
|
||||
form.leadHonor = matchedItem.honorNames?.join(',') || '';
|
||||
form.leadAge = matchedItem.age || 0;
|
||||
form.leadPeople = matchedItem.userName || '';
|
||||
} else {
|
||||
form.leadHonor = '';
|
||||
form.leadAge = 0;
|
||||
}
|
||||
};
|
||||
const unionAssign = (item) => {
|
||||
if (!item) {
|
||||
form.unionName = '';
|
||||
return;
|
||||
}
|
||||
form.unionName = item.name;
|
||||
}
|
||||
const showSelectUser = () => {
|
||||
selectUserVisible.value = true;
|
||||
};
|
||||
// 可编辑的副本(用于 v-model)
|
||||
const editableData = ref([]);
|
||||
const removeMember = (row) => {
|
||||
const index = editableData.value.findIndex(
|
||||
(item) => item.userId === row.userId
|
||||
);
|
||||
if (index !== -1) {
|
||||
userIds.value.splice(index, 1);
|
||||
editableData.value.splice(index, 1);
|
||||
form.memberNum--;
|
||||
}
|
||||
};
|
||||
|
||||
/** 表格实例 */
|
||||
const tableRef = ref(null);
|
||||
// 可选择的成员
|
||||
const userIds = ref([]);
|
||||
/** 选择成员 */
|
||||
// user-select 组件回调
|
||||
const handleSelect = (data) => {
|
||||
// orgEditableData 原来数据
|
||||
const orgEditableData = editableData.value;
|
||||
// 查找已经存在的用户
|
||||
const existingIds = new Set(
|
||||
orgEditableData.map((item) => item.userId || item.id)
|
||||
);
|
||||
// 过滤掉已经选择的用户,之前有的就不做处理
|
||||
const selectData = data
|
||||
.filter((item) => !existingIds.has(item.id))
|
||||
.map((item) => ({
|
||||
...item,
|
||||
userId: item.id,
|
||||
oldName: item.name,
|
||||
oldBirthdate: item.birthdate
|
||||
}));
|
||||
|
||||
editableData.value = [...orgEditableData, ...selectData];
|
||||
form.memberNum = editableData.value.length;
|
||||
// 选完情况组件中的用户
|
||||
userIds.value = [];
|
||||
};
|
||||
|
||||
// 获取成员当前所在工会和所有工会
|
||||
const assignUserUnion = (userUnionInfo) => {
|
||||
form.unionId = userUnionInfo.unionId;
|
||||
form.unionName = userUnionInfo.unionName;
|
||||
form.deptid = userUnionInfo.deptId;
|
||||
form.deptName = userUnionInfo.deptName;
|
||||
form.createYear = new Date().getFullYear().toString();
|
||||
}
|
||||
watch(() => props.userUnionInfo,
|
||||
(newVal, oldVal) => {
|
||||
if (StrUtil.isBlank(newVal?.unionId)) {
|
||||
return;
|
||||
}
|
||||
assignUserUnion(props.userUnionInfo);
|
||||
}, {immediate: true}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.brandForm,
|
||||
(newVal, oldVal) => {
|
||||
if (StrUtil.isBlank(newVal?.id)) {
|
||||
return
|
||||
}
|
||||
const data = {
|
||||
...newVal,
|
||||
leadIdentity: JSON.parse(newVal?.leadIdentity)
|
||||
}
|
||||
assignFields(data)
|
||||
editableData.value =
|
||||
data.brandStudioMembers.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
oldName: item.name,
|
||||
oldBirthdate: item.birthdate
|
||||
};
|
||||
}) || [];
|
||||
}, {immediate: true}
|
||||
)
|
||||
|
||||
const userUnionId = ref('')
|
||||
onMounted(async () => {
|
||||
console.log('mounted');
|
||||
// 调用接口获取所有工会列表并转为tree
|
||||
userUnionId.value = userStore.userUnionIdByRole || userStore.userUnionId || '0';
|
||||
console.log("=======", userUnionId.value)
|
||||
const res = await getLeaderHonorApi();
|
||||
leaderHonors.value = res.data.map((item, index) => {
|
||||
return {
|
||||
id: index,
|
||||
emplid: item.emplid,
|
||||
userName: item.userName,
|
||||
age: item.age,
|
||||
honorNames: item.honorNames
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// 提交数据/保存草稿
|
||||
const submit = (item) => {
|
||||
form.status = item.saveType;
|
||||
form.brandStudioMembers = editableData.value || [];
|
||||
const params = { ...form };
|
||||
params.leadIdentity = JSON.stringify(form.leadIdentity) || {};
|
||||
params.domain = params.track;
|
||||
formRef.value?.validate?.((valid) => {
|
||||
if (!valid) {
|
||||
emit('update:loading', false)
|
||||
return;
|
||||
}
|
||||
const saveOrUpdate = item.isUpdate
|
||||
? updateBrandStudioApplicationApi
|
||||
: addBrandStudioApplicationApi;
|
||||
saveOrUpdate(params)
|
||||
.then(() => {
|
||||
EleMessage.success({ message: '保存成功', plain: true });
|
||||
emit('editFinish')
|
||||
})
|
||||
.catch((err) => {
|
||||
EleMessage.error({ message: '服务错误', plain: true });
|
||||
console.warn(err);
|
||||
})
|
||||
.finally(() => {
|
||||
emit('update:loading', false)
|
||||
});
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
submit
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="110px"
|
||||
@submit.prevent=""
|
||||
:disabled="!editMode"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属单位工会" prop="unionName" required>
|
||||
<survey-tree-select class="ele-fluid" v-model="form.unionId" :union-id="userUnionId" placeholder="请选择所属工会" @unionAssign="unionAssign" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属单位机构" prop="deptName" required>
|
||||
<el-input
|
||||
v-model="form.deptName"
|
||||
placeholder="请输入所属单位机构"
|
||||
:disabled="true"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室名称" prop="name" required>
|
||||
<el-input
|
||||
v-model="form.name"
|
||||
placeholder="请输入工作室名称"
|
||||
maxlength="30"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建年度" required prop="createYear">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.createYear"
|
||||
type="year"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年度"
|
||||
:disabled="true"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室领衔人" prop="leadPeople" required>
|
||||
<el-select
|
||||
v-model="form.leadPeople"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请选择工作室领衔人"
|
||||
value-key="id"
|
||||
@change="leaderChange"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in leaderHonors"
|
||||
:key="item.emplid"
|
||||
:value="item.emplid"
|
||||
:label="`${item.emplid} - ${item.userName}`"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人年龄" required prop="leadAge">
|
||||
<el-input-number
|
||||
placeholder="请输入领衔人年龄"
|
||||
v-model="form.leadAge"
|
||||
:min="0"
|
||||
:max="150"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人身份" prop="leadIdentity">
|
||||
<el-select
|
||||
placeholder="请选择领衔人身份"
|
||||
v-model="form.leadIdentity"
|
||||
multiple
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in leadPeopleDict"
|
||||
:key="item.id"
|
||||
:value="{
|
||||
id: item.id,
|
||||
dictLabel: item.dictLabel,
|
||||
dictTypeId: item.dictTypeId
|
||||
}"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="荣誉称号" required prop="leadHonor">
|
||||
<el-input
|
||||
placeholder="请输入领衔人荣誉称号"
|
||||
v-model="form.leadHonor"
|
||||
maxlength="40"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室类型" prop="type">
|
||||
<el-select
|
||||
placeholder="请选择工作室类型"
|
||||
v-model="form.type"
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandOfficeTypeDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属赛道" prop="track" required>
|
||||
<el-select
|
||||
placeholder="请选择工作室赛道"
|
||||
v-model="form.track"
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandOfficeDomainDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="具体位置" prop="address" required>
|
||||
<el-input
|
||||
v-model="form.address"
|
||||
placeholder="请输入工作室具体位置"
|
||||
maxlength="80"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="基本情况介绍" required prop="introduction">
|
||||
<el-input
|
||||
:rows="8"
|
||||
type="textarea"
|
||||
v-model="form.introduction"
|
||||
placeholder="请输入基本情况介绍"
|
||||
clearable
|
||||
maxlength="1500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
label="工作室成员"
|
||||
required
|
||||
prop="brandStudioMembers"
|
||||
>
|
||||
<span>{{ form.memberNum }}人</span>
|
||||
<el-tooltip
|
||||
content="团队成员数量,根据选择成员人数自动变化"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon
|
||||
style="cursor: help; margin-left: 4px; color: #909399"
|
||||
>
|
||||
<QuestionFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" style="text-align: right">
|
||||
<el-button type="primary" @click="showSelectUser">
|
||||
选择工作室成员
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="editableData"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
:export-config="{ fileName: '用户数据' }"
|
||||
:style="{ paddingBottom: '16px' }"
|
||||
cache-key="systemUserTable"
|
||||
:tools="false"
|
||||
>
|
||||
<template #name="{ row }">
|
||||
<span v-if="StrUtil.isEmpty(row.oldName)">
|
||||
<el-input v-model="row.name" />
|
||||
</span>
|
||||
<span v-else>{{ row.name }}</span>
|
||||
</template>
|
||||
<template #birthdate="{ row }">
|
||||
<el-date-picker
|
||||
style="width: 160px; padding: 0 20px"
|
||||
v-model="row.birthdate"
|
||||
type="month"
|
||||
placeholder="选择年月"
|
||||
format="YYYY-MM"
|
||||
value-format="YYYY-MM"
|
||||
size="large"
|
||||
/>
|
||||
</template>
|
||||
<template #grade="{ row }">
|
||||
<span>
|
||||
<el-select
|
||||
placeholder="请选择学历类型"
|
||||
v-model="row.grade"
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userEducationDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</span>
|
||||
</template>
|
||||
<template #professional="{ row }">
|
||||
<span class="ipt-text">
|
||||
<el-input v-model="row.professional" maxlength="30" show-word-limit />
|
||||
</span>
|
||||
</template>
|
||||
<template #deptName="{ row }">
|
||||
<span v-if="StrUtil.isEmpty(row.deptName)">
|
||||
<el-input v-model="row.deptName" />
|
||||
</span>
|
||||
<span v-else>{{ row.deptName }}</span>
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-permission="'system:config:remove'"
|
||||
type="danger"
|
||||
underline="never"
|
||||
@click="removeMember(row)"
|
||||
:icon="DeleteOutlined"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-form>
|
||||
|
||||
<union-user-select
|
||||
clearable
|
||||
multiple
|
||||
view-type="picker"
|
||||
v-model:visible="selectUserVisible"
|
||||
v-model="userIds"
|
||||
placeholder="请选择用户"
|
||||
queryType="union"
|
||||
:union-id="topUnionId"
|
||||
@select="handleSelect"
|
||||
:before-confirm="beforeConfirm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,528 @@
|
||||
<!-- 审批弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:form="true"
|
||||
:destroy-on-close="true"
|
||||
:width="1200"
|
||||
v-model="visible"
|
||||
title="申请详情"
|
||||
>
|
||||
<el-row :gutter="24" style="padding-bottom: 16px">
|
||||
<el-col :span="24">
|
||||
<ele-timeline
|
||||
:data="flowItems"
|
||||
style="margin-top: 28px; font-size: 14px !important; width: 100%"
|
||||
placement="left"
|
||||
>
|
||||
<template #itemDescription="{ item }">
|
||||
<div class="flow-text">{{ item.auditor }}</div>
|
||||
<div v-if="item.time" class="flow-text">
|
||||
{{ item.key === 1 ? '申请时间' : '审批时间' }}:{{ item.time }}
|
||||
</div>
|
||||
<el-tooltip class="item" effect="dark" :content="item.remark" placement="top">
|
||||
<div
|
||||
v-if="item.remark && getStatusDesc(item.status) === 'PASSED'"
|
||||
class="flow-text"
|
||||
>审批意见:{{ item.remark }}
|
||||
</div>
|
||||
<div
|
||||
v-if="item.remark && getStatusDesc(item.status) === 'REJECT'"
|
||||
class="flow-text"
|
||||
>驳回原因:{{ item.remark }}
|
||||
</div>
|
||||
<div
|
||||
v-if="item.remark && getStatusDesc(item.status) === 'REPEAL'"
|
||||
class="flow-text"
|
||||
>
|
||||
撤销原因:{{ item.remark }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</ele-timeline>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24">
|
||||
<info-audit :data="current" disabled/>
|
||||
<!-- <el-card header="申请信息" shadow="never">-->
|
||||
<!-- <info-audit :data="current" disabled></info-audit>-->
|
||||
<!-- </el-card>-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div
|
||||
v-if="
|
||||
getStatusNameByCode(props.data.status) === 'IN_REVIEW' &&
|
||||
props.isAudit
|
||||
"
|
||||
>
|
||||
<el-button :loading="loading" @click="handleRepeal"> 撤销 </el-button>
|
||||
<el-button :loading="loading" @click="handleRefuse">驳回</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="handlePass">
|
||||
通过
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</ele-modal>
|
||||
<el-dialog
|
||||
v-model="passDialogVisible"
|
||||
title="审批意见"
|
||||
width="400px"
|
||||
:before-close="handlePassDialogClose"
|
||||
>
|
||||
<el-form :model="passForm" :rules="passRules" ref="passFormRef">
|
||||
<el-form-item label="审核意见" prop="reason">
|
||||
<el-input
|
||||
v-model="passForm.reason"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入审核意见(必填)"
|
||||
maxlength="80"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="passDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onAudit" :loading="loading"
|
||||
>确认</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 新增:拒绝原因弹窗 -->
|
||||
<el-dialog
|
||||
v-model="refuseDialogVisible"
|
||||
title="驳回原因"
|
||||
width="400px"
|
||||
:before-close="handleRefuseDialogClose"
|
||||
>
|
||||
<el-form :model="refuseForm" :rules="refuseRules" ref="refuseFormRef">
|
||||
<el-form-item label="驳回原因" prop="reason">
|
||||
<el-input
|
||||
v-model="refuseForm.reason"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入驳回原因(必填)"
|
||||
maxlength="80"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="refuseDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmRefuse" :loading="loading"
|
||||
>确认</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 新增:撤销原因弹窗 -->
|
||||
<el-dialog
|
||||
v-model="repealDialogVisible"
|
||||
title="撤销原因"
|
||||
width="400px"
|
||||
:before-close="handleRepealDialogClose"
|
||||
>
|
||||
<el-form :model="repealForm" :rules="repealRules" ref="repealFormRef">
|
||||
<el-form-item label="撤销原因" prop="reason">
|
||||
<el-input
|
||||
v-model="repealForm.reason"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入撤销原因(必填)"
|
||||
maxlength="80"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="repealDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmRepeal" :loading="loading"
|
||||
>确认</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { EleMessage } from 'ele-admin-plus';
|
||||
import { getBrandStudioApplicationApi } from '@/api/office/brand/index.js';
|
||||
import {
|
||||
auditApplicationApi,
|
||||
getBrandApplyFlowListApi
|
||||
} from '@/api/office/application/index.js';
|
||||
import InfoAudit from '@/views/brand/components/info-audit.vue';
|
||||
import { getStatusDesc, getStatusNameByCode } from '@/utils/toolkit.js';
|
||||
|
||||
const props = defineProps({
|
||||
/** 修改回显的数据 */
|
||||
data: Object,
|
||||
/** 查看/审批 */
|
||||
isAudit: Boolean
|
||||
});
|
||||
|
||||
const emit = defineEmits(['done']);
|
||||
|
||||
/** 弹窗是否打开 */
|
||||
const visible = defineModel({ type: Boolean });
|
||||
|
||||
/** 提交状态 */
|
||||
const loading = ref(false);
|
||||
|
||||
/** 工作流数组 */
|
||||
const flowItems = ref([]);
|
||||
|
||||
// ========== 新增:拒绝功能相关代码 ==========
|
||||
// 拒绝弹窗显示状态
|
||||
const refuseDialogVisible = ref(false);
|
||||
// 拒绝表单数据
|
||||
const refuseForm = ref({
|
||||
reason: '' // 拒绝原因
|
||||
});
|
||||
// 拒绝表单验证规则
|
||||
const refuseRules = reactive({
|
||||
reason: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入拒绝原因',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 2,
|
||||
max: 500,
|
||||
message: '拒绝原因长度在 2 到 500 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
});
|
||||
// 拒绝表单引用
|
||||
const refuseFormRef = ref();
|
||||
|
||||
// 打开驳回
|
||||
const handleRefuse = () => {
|
||||
// 清空之前的驳回原因
|
||||
refuseForm.value.reason = '';
|
||||
// 打开弹窗
|
||||
refuseDialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 关闭驳回弹窗时的处理
|
||||
const handleRefuseDialogClose = () => {
|
||||
refuseDialogVisible.value = false;
|
||||
};
|
||||
|
||||
// 确认驳回
|
||||
const confirmRefuse = () => {
|
||||
// 验证表单
|
||||
refuseFormRef.value.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
// 调用驳回接口
|
||||
const payload = {};
|
||||
payload.applicationId = props.data.id;
|
||||
payload.status = 2;
|
||||
payload.flowId = props.data.flowId;
|
||||
payload.remark = refuseForm.value.reason;
|
||||
auditApplicationApi(payload)
|
||||
.then(() => {
|
||||
EleMessage.success({ message: '驳回成功', plain: true });
|
||||
refuseDialogVisible.value = false;
|
||||
handleCancel();
|
||||
emit('done');
|
||||
})
|
||||
.catch(() => {
|
||||
EleMessage.error({ message: '拒绝失败', plain: true });
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const current = ref({});
|
||||
/** 关闭弹窗 */
|
||||
const handleCancel = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
//获取基本信息详细
|
||||
const getBrandApplicationDetail = () => {
|
||||
getBrandStudioApplicationApi(props.data.id)
|
||||
.then(({ data }) => {
|
||||
loading.value = false;
|
||||
current.value = data;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
// ========== 新增:通过功能相关代码 ==========
|
||||
const passFormRef = ref()
|
||||
const passDialogVisible = ref(false);
|
||||
// 撤销表单数据
|
||||
const passForm = ref({
|
||||
reason: '' // 通过原因
|
||||
});
|
||||
// 关闭通过弹窗时的处理
|
||||
const handlePassDialogClose = () => {
|
||||
passDialogVisible.value = false;
|
||||
};
|
||||
//审核通过
|
||||
const onAudit = () => {
|
||||
passFormRef.value.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
const payload = {};
|
||||
payload.flowId = props.data.flowId;
|
||||
payload.applicationId = props.data.id;
|
||||
payload.status = 5;
|
||||
payload.remark = passForm.value.reason;
|
||||
const loadingInstance = EleMessage.loading({
|
||||
message: '请求中...',
|
||||
plain: true,
|
||||
duration: 0 // 手动控制关闭,不自动消失
|
||||
});
|
||||
auditApplicationApi(payload)
|
||||
.then(() => {
|
||||
EleMessage.success({
|
||||
message: '审核通过',
|
||||
plain: true
|
||||
});
|
||||
passDialogVisible.value = false;
|
||||
handleCancel();
|
||||
emit('done');
|
||||
})
|
||||
.finally(() => {
|
||||
loadingInstance.close();
|
||||
});
|
||||
})
|
||||
// ElMessageBox.confirm(`是否通过审核?`, '系统提示', {
|
||||
// type: 'warning',
|
||||
// draggable: true
|
||||
// })
|
||||
// .then(() => {
|
||||
// const payload = {};
|
||||
// payload.flowId = props.data.flowId;
|
||||
// payload.applicationId = props.data.id;
|
||||
// payload.status = 5;
|
||||
// const loadingInstance = EleMessage.loading({
|
||||
// message: '请求中...',
|
||||
// plain: true,
|
||||
// duration: 0 // 手动控制关闭,不自动消失
|
||||
// });
|
||||
// auditApplicationApi(payload)
|
||||
// .then(({ message, data }) => {
|
||||
// EleMessage.success({
|
||||
// message: '审核通过',
|
||||
// plain: true
|
||||
// });
|
||||
// handleCancel();
|
||||
// emit('done');
|
||||
// })
|
||||
// .finally(() => {
|
||||
// loadingInstance.close();
|
||||
// });
|
||||
// })
|
||||
// .catch(() => {});
|
||||
};
|
||||
|
||||
// 打开撤销
|
||||
const handlePass = () => {
|
||||
// 清空之前的驳回原因
|
||||
passForm.value.reason = '';
|
||||
// 打开弹窗
|
||||
passDialogVisible.value = true;
|
||||
};
|
||||
// 撤销表单验证规则
|
||||
const passRules = reactive({
|
||||
reason: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入通过原因',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 2,
|
||||
max: 500,
|
||||
message: '通过原因长度在 2 到 500 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// ========== 新增:撤销功能相关代码 ==========
|
||||
// 撤销弹窗显示状态
|
||||
const repealDialogVisible = ref(false);
|
||||
// 撤销表单数据
|
||||
const repealForm = ref({
|
||||
reason: '' // 撤销原因
|
||||
});
|
||||
// 撤销表单验证规则
|
||||
const repealRules = reactive({
|
||||
reason: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入撤销原因',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 2,
|
||||
max: 500,
|
||||
message: '撤销原因长度在 2 到 500 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
});
|
||||
// 撤销表单引用
|
||||
const repealFormRef = ref(null);
|
||||
|
||||
// 打开撤销
|
||||
const handleRepeal = () => {
|
||||
// 清空之前的驳回原因
|
||||
repealForm.value.reason = '';
|
||||
// 打开弹窗
|
||||
repealDialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 关闭撤销弹窗时的处理
|
||||
const handleRepealDialogClose = () => {
|
||||
repealDialogVisible.value = false;
|
||||
};
|
||||
// 确认撤销
|
||||
const confirmRepeal = () => {
|
||||
// 验证表单
|
||||
repealFormRef.value.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
// 调用接口
|
||||
const payload = {};
|
||||
payload.status = 3;
|
||||
payload.flowId = props.data.flowId;
|
||||
payload.applicationId = props.data.id;
|
||||
payload.remark = repealForm.value.reason;
|
||||
auditApplicationApi(payload)
|
||||
.then(() => {
|
||||
EleMessage.success({ message: '撤销成功', plain: true });
|
||||
repealDialogVisible.value = false;
|
||||
handleCancel();
|
||||
emit('done');
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
//流程实例
|
||||
const getApplyFlowList = async () => {
|
||||
const requestParams = {
|
||||
applicationId: props.data.id // 关键Query参数:申请单ID
|
||||
};
|
||||
const { data } = await getBrandApplyFlowListApi(requestParams);
|
||||
if (data && data.length > 0) {
|
||||
const flowList = data.map((item, index) => {
|
||||
let type = '';
|
||||
// 定义不同状态的节点类型
|
||||
if (getStatusDesc(item.status) === 'PASSED') {
|
||||
type = 'primary';
|
||||
} else if (getStatusDesc(item.status) === 'REJECT') {
|
||||
type = 'danger';
|
||||
}
|
||||
return {
|
||||
key: index + 1,
|
||||
type: type,
|
||||
title: item.unionName,
|
||||
time:
|
||||
getStatusDesc(item.status) !== 'WAIT_AUDIT' &&
|
||||
getStatusDesc(item.status) !== 'TO_BE_AUDIT'
|
||||
? item.updateTime
|
||||
: '',
|
||||
remark: item.remark,
|
||||
auditor: item.auditor,
|
||||
sortNo: item.sortNo,
|
||||
status: item.status
|
||||
};
|
||||
});
|
||||
|
||||
flowItems.value = flowList.sort((a, b) => a.sortNo - b.sortNo);
|
||||
}
|
||||
};
|
||||
|
||||
/** 监听弹窗打开 */
|
||||
watch(visible, () => {
|
||||
if (visible.value && props.data) {
|
||||
getBrandApplicationDetail();
|
||||
getApplyFlowList();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-steps--vertical {
|
||||
height: 20% !important;
|
||||
}
|
||||
|
||||
.auditor-time-row {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.main-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.auditor-date-time {
|
||||
color: #9c9c9c;
|
||||
}
|
||||
|
||||
.ele-modal-body.is-form {
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
|
||||
:deep(.ele-time-line-list) {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.ele-time-line-item-title) {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
:deep(.ele-time-line-item-body) {
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
|
||||
:deep(.el-timeline-item .is-placeholder) {
|
||||
display: none !important; /* 直接隐藏占位 DOM */
|
||||
height: 0 !important; /* 兜底:清空高度 */
|
||||
margin: 0 !important; /* 清空边距 */
|
||||
}
|
||||
|
||||
:deep(.is-placeholder) {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.flow-text {
|
||||
display: -webkit-box; /* For flexbox-like behavior */
|
||||
-webkit-box-orient: vertical; /* Allow vertical box layout */
|
||||
-webkit-line-clamp: 3; /* Limit text to 3 lines */
|
||||
overflow: hidden; /* Hide overflow */
|
||||
text-overflow: ellipsis; /* Show ellipsis for overflow */
|
||||
white-space: normal; /* Allow text to wrap */
|
||||
font-size: 11px;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
padding-top: 3px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,50 @@
|
||||
<!-- 审批弹窗 -->
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<info-audio :data="current" :edit-mode="true"/>
|
||||
<!-- <table-info-->
|
||||
<!-- v-model:loading="loading"-->
|
||||
<!-- :edit-mode="false"-->
|
||||
<!-- :brand-form="current"-->
|
||||
<!-- />-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import InfoAudio from '@/views/brand/components/info-audit.vue';
|
||||
// import TableInfo from "@/views/brand/components/table-info.vue";
|
||||
import { useRoute } from 'vue-router';
|
||||
import {getBrandStudioApplicationApi} from "@/api/office/brand/index.js";
|
||||
|
||||
const loading = ref(false)
|
||||
const route = useRoute();
|
||||
const current = ref({});
|
||||
|
||||
//获取基本信息
|
||||
const getBrandApplicationDetail = async () => {
|
||||
// console.log("getBrandApplicationDetail", route.query)
|
||||
loading.value = true
|
||||
getBrandStudioApplicationApi(route.query.businessId)
|
||||
.then(({ data }) => {
|
||||
current.value = data;
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getBrandApplicationDetail();
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
<!-- 弹窗先进工作者 -->
|
||||
<template>
|
||||
<el-form ref="formRef" :model="form" label-width="120" @submit.prevent="" :disabled="editMode">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属单位工会" prop="unionName">
|
||||
<el-input
|
||||
v-model="form.unionName"
|
||||
placeholder="请输入所属单位工会"
|
||||
:disabled="true"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属单位机构" prop="deptName">
|
||||
<el-input
|
||||
v-model="form.deptName"
|
||||
placeholder="请输入所属单位机构"
|
||||
:disabled="true"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入工作室名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建年份" prop="createYear">
|
||||
<el-input v-model="form.createYear" placeholder="请选择年度"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室领衔人" prop="leadPeople">
|
||||
<el-input
|
||||
v-model="form.leadPeople"
|
||||
placeholder="请输入工作室领衔人"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人年龄" prop="leadAge">
|
||||
<el-input-number
|
||||
placeholder="请输入成员人数"
|
||||
v-model="form.leadAge"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人身份" prop="leadIdentity">
|
||||
<el-input
|
||||
placeholder="请选择领衔人身份"
|
||||
v-model="form.leadIdentity"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="荣誉称号" prop="leadHonor">
|
||||
<el-input
|
||||
placeholder="请输入领衔人荣誉称号"
|
||||
v-model="form.leadHonor"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室类型" prop="type">
|
||||
<el-select
|
||||
placeholder="请选择工作室类型"
|
||||
v-model="form.type"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in form.type"
|
||||
:key="index"
|
||||
:value="item"
|
||||
:label="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属赛道" prop="track">
|
||||
<el-input v-model="form.track" placeholder="请输入所属赛道" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="具体位置" prop="address">
|
||||
<el-input v-model="form.address" placeholder="请输入工作室具体位置" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="成员人数" prop="memberNum">
|
||||
<el-input v-model="form.memberNum" placeholder="请输入工作室成员人数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="基本情况介绍" prop="introduction">
|
||||
<span style="color: #999999; font-size: 12px"
|
||||
>(说明:事迹材料客观翔实、重点突出,不超过1500字。)</span
|
||||
>
|
||||
<el-input
|
||||
:rows="4"
|
||||
type="textarea"
|
||||
disabled
|
||||
v-model="form.introduction"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="tableData"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
:export-config="{ fileName: '用户数据' }"
|
||||
:style="{ paddingBottom: '16px' }"
|
||||
cache-key="systemUserTable"
|
||||
:tools="false"
|
||||
/>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import { useFormData } from '@/utils/use-form-data';
|
||||
|
||||
const props = defineProps({
|
||||
/** 修改回显的数据 */
|
||||
data: Object,
|
||||
editMode: Boolean,
|
||||
});
|
||||
|
||||
defineEmits(['done', 'back']);
|
||||
|
||||
/** 弹窗是否打开 */
|
||||
defineModel({ type: Boolean });
|
||||
|
||||
/** 表单实例 */
|
||||
const formRef = ref();
|
||||
|
||||
/** 表单数据 */
|
||||
const [form, resetFields, assignFields] = useFormData({
|
||||
id: '',
|
||||
unionName: '', // 所属单位工会
|
||||
deptName: '', // 所属单位工会
|
||||
name: '', // 工作室名称
|
||||
createYear: '', // 创建年份
|
||||
leadPeople: '', // 工作室领衔人
|
||||
leadAge: 25, // 领衔人年龄
|
||||
leadIdentity: '', // 领衔人身份
|
||||
leadHonor: '',
|
||||
memberNum: 0, // 成员人数
|
||||
type: '', // 工作室类型
|
||||
track: '', // 工作室赛道
|
||||
address: '', // 工作室具体位置
|
||||
introduction: '', // 工作室基本情况介绍
|
||||
unionUsers: [], // 工作室成员 { name, birthday, grade, professional, unionName }
|
||||
remark: ''
|
||||
});
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
{
|
||||
prop: 'name',
|
||||
label: '姓名',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'name'
|
||||
},
|
||||
{
|
||||
prop: 'birthdate',
|
||||
label: '出生年月',
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
slot: 'birthdate'
|
||||
},
|
||||
{
|
||||
prop: 'grade',
|
||||
label: '学历',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'grade'
|
||||
},
|
||||
{
|
||||
prop: 'professional',
|
||||
label: '职称',
|
||||
align: 'center',
|
||||
minWidth: 100,
|
||||
slot: 'professional'
|
||||
},
|
||||
{
|
||||
prop: 'deptName',
|
||||
label: '所在部门',
|
||||
align: 'center',
|
||||
minWidth: 100,
|
||||
slot: 'deptName'
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
const tableData = ref([]);
|
||||
|
||||
/** 监听弹窗打开 */
|
||||
watch(
|
||||
() => props.data,
|
||||
(newData) => {
|
||||
if (newData && Object.keys(newData).length) {
|
||||
// 深拷贝 newData,避免直接操作 props 原数据
|
||||
const dataCopy = JSON.parse(JSON.stringify(newData));
|
||||
const leadIdentity = JSON.parse(dataCopy['leadIdentity']);
|
||||
tableData.value = newData.brandStudioMembers || [];
|
||||
// 处理需要转换的字段
|
||||
const formData = {
|
||||
...dataCopy,
|
||||
id: '', // 强制置空 id
|
||||
leadIdentity: leadIdentity.map((item) => item.dictLabel).join(',')
|
||||
};
|
||||
// 用 assignFields 将处理后的数据赋值给 form(而非修改 props)
|
||||
assignFields(formData);
|
||||
} else {
|
||||
// 数据为空时重置表单
|
||||
resetFields();
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<ele-card :body-style="{ paddingBottom: '2px' }">
|
||||
<el-form label-width="72px" @keyup.enter="search" @submit.prevent="">
|
||||
<el-row :gutter="8">
|
||||
<el-col :lg="4" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label="工作室名称" label-width="100px">
|
||||
<el-input
|
||||
clearable
|
||||
v-model.trim="form.name"
|
||||
placeholder="请输入工作室名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="4" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label="创立年度">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.createYear"
|
||||
type="year"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择工作室创立年度"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="4" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label="工作室领衔人" label-width="100px">
|
||||
<el-input
|
||||
clearable
|
||||
v-model.trim="form.leadPeople"
|
||||
placeholder="请输入工作室领衔人"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label-width="20px">
|
||||
<el-button type="primary" @click="search">查询</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useFormData } from '@/utils/use-form-data.js';
|
||||
const emit = defineEmits(['search']);
|
||||
|
||||
/** 表单数据 */
|
||||
const [form, resetFields] = useFormData({
|
||||
name: '',
|
||||
leadPeople: '',
|
||||
createYear: new Date().getFullYear().toString()
|
||||
});
|
||||
|
||||
/** 搜索 */
|
||||
const search = () => {
|
||||
emit('search', { ...form, params: {} });
|
||||
};
|
||||
|
||||
/** 重置 */
|
||||
const reset = () => {
|
||||
resetFields();
|
||||
search();
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,103 @@
|
||||
<script setup>
|
||||
|
||||
import UnionUserSelect from "@/components/UnionUserSelect/index.vue";
|
||||
import {EleMessage} from "ele-admin-plus";
|
||||
import {ref, watch} from "vue";
|
||||
import {StrUtil} from "@/utils/toolkit.js";
|
||||
|
||||
const props = defineProps({
|
||||
unionMembers: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
topUnionId: {
|
||||
type: String
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:unionMembers'])
|
||||
|
||||
const selectUserVisible = ref(false)
|
||||
|
||||
// 可编辑的副本(用于 v-model)
|
||||
const editableData = ref([]);
|
||||
|
||||
watch(
|
||||
() => props.unionMembers,
|
||||
(val) => {
|
||||
editableData.value = val ? [...val] : []
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
|
||||
/** 打开弹窗 */
|
||||
const showSelectUser = () => {
|
||||
selectUserVisible.value = true;
|
||||
}
|
||||
// 可选择的成员
|
||||
const userIds = ref([]);
|
||||
/** 选择成员 */
|
||||
// user-select 组件回调
|
||||
const handleSelect = (data) => {
|
||||
// orgEditableData 原来数据
|
||||
const orgEditableData = editableData.value.filter(item => !StrUtil.isBlank(item.name));
|
||||
// 查找已经存在的用户
|
||||
const existingIds = new Set(
|
||||
orgEditableData.map((item) => item.userId || item.id)
|
||||
);
|
||||
// 过滤掉已经选择的用户,之前有的就不做处理
|
||||
const selectData = data
|
||||
.filter((item) => !existingIds.has(item.id))
|
||||
.map((item) => ({
|
||||
...item,
|
||||
userId: item.id,
|
||||
oldName: item.name,
|
||||
oldBirthdate: item.birthdate
|
||||
}));
|
||||
|
||||
editableData.value = [...orgEditableData, ...selectData];
|
||||
// 选完情况组件中的用户
|
||||
userIds.value = [];
|
||||
emit('update:unionMembers', editableData.value)
|
||||
};
|
||||
|
||||
/** beforeConfirm 为确定按钮点击钩子, 可以 return false 阻止确定 */
|
||||
const beforeConfirm = (data) => {
|
||||
if (!data?.length) {
|
||||
EleMessage.error('请至少选择一个用户');
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="default"
|
||||
:plain="true"
|
||||
:text="true"
|
||||
:bg="true"
|
||||
@click="showSelectUser"
|
||||
>
|
||||
选择工作室成员
|
||||
</el-button>
|
||||
<union-user-select
|
||||
clearable
|
||||
multiple
|
||||
view-type="picker"
|
||||
v-model:visible="selectUserVisible"
|
||||
v-model="userIds"
|
||||
placeholder="请选择用户"
|
||||
:query-type="'union'"
|
||||
:union-id="topUnionId"
|
||||
@select="handleSelect"
|
||||
:before-confirm="beforeConfirm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,823 @@
|
||||
<template>
|
||||
<div style="padding: 0 100px">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
:label-width="80"
|
||||
:inline-message="true"
|
||||
@submit.prevent=""
|
||||
:disabled="!editMode"
|
||||
v-loading="loading"
|
||||
>
|
||||
<ele-text
|
||||
size="xl"
|
||||
:strong="true"
|
||||
:style="{ textAlign: 'center', marginBottom: '12px' }"
|
||||
>
|
||||
上海浦东发展银行个人品牌工作室推荐表
|
||||
</ele-text>
|
||||
|
||||
<div style="padding: 10px 0">
|
||||
<el-form-item label="所属单位工会" prop="unionId" label-position="left" label-width="110px">
|
||||
<survey-tree-select class="ele-fluid" v-model="form.unionId" :union-id="userUnionId" placeholder="请选择所属工会" @unionAssign="unionAssign" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<ele-table
|
||||
:border="true"
|
||||
:has-header="false"
|
||||
:style="{
|
||||
'--ele-table-border-color': 'var(--el-text-color-secondary)',
|
||||
tableLayout: 'fixed',
|
||||
marginBottom: '28px'
|
||||
}"
|
||||
>
|
||||
<tr>
|
||||
<td :style="{ width: '140px' }" class="label-center">
|
||||
<ele-text tag="span" class="label-required">
|
||||
工作室名称
|
||||
</ele-text>
|
||||
</td>
|
||||
|
||||
<td :style="{ minWidth: '140px' }" :colspan="3">
|
||||
<el-form-item
|
||||
label=""
|
||||
prop="name"
|
||||
label-width="0px"
|
||||
label-position="left"
|
||||
:style="{ marginBottom: '0px' }"
|
||||
class="pro-form-error-popper"
|
||||
>
|
||||
<el-input
|
||||
:clearable="true"
|
||||
type="text"
|
||||
placeholder=""
|
||||
:maxlength="30"
|
||||
:show-word-limit="true"
|
||||
ref="nameRef"
|
||||
v-model="form.name"
|
||||
/>
|
||||
</el-form-item>
|
||||
</td>
|
||||
|
||||
<td :style="{ width: '120px' }" class="label-center">
|
||||
<ele-text tag="span" class="label-required">
|
||||
创建年度
|
||||
</ele-text>
|
||||
</td>
|
||||
|
||||
<td :colspan="2">
|
||||
<el-form-item label="" prop="createYear" label-width="0px">
|
||||
<el-date-picker
|
||||
class="ele-fluid"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择创建年度"
|
||||
:clearable="false"
|
||||
:editable="true"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
v-model="form.createYear"
|
||||
/>
|
||||
</el-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 工作室领衔人 </ele-text>
|
||||
</td>
|
||||
<td :colspan="3">
|
||||
<el-form-item prop="leadPeople" label-width="0px" label-position="left">
|
||||
<el-select
|
||||
v-model="form.leadPeople"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请选择工作室领衔人"
|
||||
value-key="id"
|
||||
class="ele-fluid"
|
||||
@change="leaderChange"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in leaderHonors"
|
||||
:key="item.emplid"
|
||||
:value="item.emplid"
|
||||
:label="`${item.emplid} - ${item.userName}`"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</td>
|
||||
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 年龄 </ele-text>
|
||||
</td>
|
||||
<td :colspan="2">
|
||||
<el-form-item label="" prop="leadAge" label-width="0px" label-position="left">
|
||||
<el-input-number
|
||||
class="ele-fluid"
|
||||
controls-position="right"
|
||||
placeholder="请输入年龄"
|
||||
:min="0"
|
||||
:max="150"
|
||||
:controls="false"
|
||||
v-model="form.leadAge"
|
||||
/>
|
||||
</el-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 领衔人身份 </ele-text>
|
||||
</td>
|
||||
<td :colspan="3">
|
||||
<el-form-item label="" prop="leadIdentity" label-width="0px" label-position="left">
|
||||
<el-checkbox-group
|
||||
:style="{ gap: '10px', display: 'flex', 'flex-wrap': 'wrap' }"
|
||||
class=""
|
||||
@change="(value) => {}"
|
||||
:disabled="false"
|
||||
:max="2"
|
||||
v-model="form.leadIdentity"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="item in leadPeopleDict"
|
||||
:key="item.id"
|
||||
:label="item.dictLabel"
|
||||
:value="{
|
||||
id: item.id,
|
||||
dictLabel: item.dictLabel,
|
||||
dictTypeId: item.dictTypeId
|
||||
}"
|
||||
/>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</td>
|
||||
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 成员人数 </ele-text>
|
||||
</td>
|
||||
<td :colspan="2">
|
||||
<el-form-item prop="memberNum" label-width="0px" label-position="left">
|
||||
<el-input-number
|
||||
class="ele-fluid"
|
||||
controls-position="right"
|
||||
placeholder="请输入成员人数"
|
||||
:min="0"
|
||||
:max="99999"
|
||||
:controls="false"
|
||||
v-model="form.memberNum"
|
||||
/>
|
||||
</el-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 工作室类型 </ele-text>
|
||||
</td>
|
||||
<td :colspan="3">
|
||||
<el-form-item prop="type" label-width="0px" label-position="left">
|
||||
<el-radio-group
|
||||
class="radio-as-checkbox"
|
||||
:style="{
|
||||
display: 'flex',
|
||||
gap: '10px',
|
||||
'flex-wrap': 'wrap'
|
||||
}"
|
||||
v-model="form.type"
|
||||
>
|
||||
<el-radio
|
||||
v-for="item in brandOfficeTypeDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
>
|
||||
<span>{{ item.dictLabel }}</span>
|
||||
<el-input
|
||||
v-if="item.dictLabel === '其他' && form.type === '其他'"
|
||||
v-model="form.type"
|
||||
placeholder="请输入工作室类型"
|
||||
style="width:150px;margin-left:20px"
|
||||
@click.stop
|
||||
/>
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</td>
|
||||
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 所属赛道 </ele-text>
|
||||
</td>
|
||||
<td :colspan="2">
|
||||
<el-form-item label="" prop="track" label-width="0px" label-position="left">
|
||||
<el-select
|
||||
class="ele-fluid"
|
||||
:clearable="false"
|
||||
placeholder="请选择所属赛道"
|
||||
v-model="form.track"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandOfficeDomainDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 工作室具体位置 </ele-text>
|
||||
</td>
|
||||
<td :colspan="6">
|
||||
<el-form-item
|
||||
label=""
|
||||
prop="address"
|
||||
label-width="0px"
|
||||
label-position="left"
|
||||
:style="{ marginBottom: '0px' }"
|
||||
class="pro-form-error-popper"
|
||||
>
|
||||
<el-input
|
||||
:clearable="true"
|
||||
type="text"
|
||||
placeholder=""
|
||||
:maxlength="80"
|
||||
:show-word-limit="true"
|
||||
:show-password="false"
|
||||
v-model="form.address"
|
||||
/>
|
||||
</el-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 工作室基本情况介绍 </ele-text>
|
||||
</td>
|
||||
<td :colspan="6">
|
||||
<el-form-item prop="introduction" label-width="0px" label-position="left">
|
||||
<el-input
|
||||
:rows="20"
|
||||
placeholder="请输入工作室基本情况介绍"
|
||||
:show-word-limit="true"
|
||||
:maxlength="1500"
|
||||
type="textarea"
|
||||
v-model="form.introduction"
|
||||
/>
|
||||
</el-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td :colspan="7" :style="{ 'text-align': 'center' }">
|
||||
<div
|
||||
:style="{
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
'align-items': 'center',
|
||||
'justify-content': 'center'
|
||||
}"
|
||||
>
|
||||
<ele-text tag="span" type="default">
|
||||
工作室成员基本情况
|
||||
</ele-text>
|
||||
<div v-if="editMode" :style="{ right: '0', position: 'absolute' }">
|
||||
<select-member-btn
|
||||
v-model:unionMembers="form.brandStudioMembers"
|
||||
:top-union-id="topUnionId"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<colgroup v-if="editMode">
|
||||
<col style="width: 120px" />
|
||||
<col style="width: 140px" />
|
||||
<col style="width: 150px" />
|
||||
<col style="width: 120px" />
|
||||
<col style="width: 120px" />
|
||||
<col style="width: 240px" />
|
||||
<col style="width: 80px" />
|
||||
</colgroup>
|
||||
|
||||
<colgroup v-if="!editMode">
|
||||
<col style="width: 180px" />
|
||||
<col style="width: 210px" />
|
||||
<col style="width: 230px" />
|
||||
<col style="width: 170px" />
|
||||
<col style="max-width: 180px" />
|
||||
</colgroup>
|
||||
|
||||
<el-form-item prop="brandStudioMembers" style="display: none;" />
|
||||
|
||||
<tr>
|
||||
<td class="label-center">
|
||||
<ele-text tag="span"> 姓名 </ele-text>
|
||||
</td>
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 出生年月 </ele-text>
|
||||
</td>
|
||||
<td class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 学历 </ele-text>
|
||||
</td>
|
||||
<td :colspan="2" :style="{ minWidth: '160px' }" class="label-center">
|
||||
<ele-text class="label-required" tag="span"> 职称 </ele-text>
|
||||
</td>
|
||||
<td :colspan="editMode ? 1 : 2" :style="{ width: '220px' }" class="label-center">
|
||||
<ele-text tag="span"> 所在部门 </ele-text>
|
||||
</td>
|
||||
<td v-if="editMode" :style="{ width: '70px' }" class="label-center">
|
||||
<ele-text tag="span"> 操作 </ele-text>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr
|
||||
v-for="(row, idx) in form.brandStudioMembers"
|
||||
:key="idx"
|
||||
>
|
||||
<td class="union-member">
|
||||
<ele-text tag="span"> {{ row.name }} </ele-text>
|
||||
</td>
|
||||
<td class="union-member">
|
||||
<el-form-item
|
||||
v-if="StrUtil.isNotBlank(row.name)"
|
||||
:prop="`brandStudioMembers.${idx}.birthdate`"
|
||||
label-width="0px"
|
||||
:rules="rulesMember.birthdate"
|
||||
>
|
||||
<el-date-picker
|
||||
value-format="YYYY-MM"
|
||||
placeholder="选择年月"
|
||||
format="YYYY-MM"
|
||||
v-model="row.birthdate"
|
||||
/>
|
||||
</el-form-item>
|
||||
<ele-text v-else tag="span"> {{ row.birthdate }} </ele-text>
|
||||
</td>
|
||||
<td class="union-member">
|
||||
<el-form-item
|
||||
v-if="StrUtil.isNotBlank(row.name)"
|
||||
:prop="`brandStudioMembers.${idx}.grade`"
|
||||
label-width="0px"
|
||||
:rules="rulesMember.grade"
|
||||
>
|
||||
<el-select
|
||||
class="ele-fluid"
|
||||
:clearable="true"
|
||||
placeholder="请选择学历类型"
|
||||
v-model="row.grade"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userEducationDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<ele-text v-else tag="span"> {{ row.grade }} </ele-text>
|
||||
</td>
|
||||
<td class="union-member" :colspan="2">
|
||||
<el-form-item
|
||||
v-if="StrUtil.isNotBlank(row.name)"
|
||||
:prop="`brandStudioMembers.${idx}.professional`"
|
||||
label-width="0px"
|
||||
label-position="right"
|
||||
:rules="rulesMember.professional"
|
||||
>
|
||||
<el-input
|
||||
:clearable="true"
|
||||
type="text"
|
||||
placeholder="请输入成员职称"
|
||||
:maxlength="30"
|
||||
:show-word-limit="true"
|
||||
v-model="row.professional"
|
||||
/>
|
||||
</el-form-item>
|
||||
<ele-text v-else tag="span"> {{ row.professional }} </ele-text>
|
||||
</td>
|
||||
<td class="union-member" :colspan="editMode ? 1 : 2" :style="{ minWidth: '220px' }">
|
||||
<ele-text tag="span"> {{ row.deptName }} </ele-text>
|
||||
</td>
|
||||
<td v-if="editMode" :style="{ minWidth: '70px', textAlign: 'center' }">
|
||||
<el-button
|
||||
type="danger"
|
||||
size="default"
|
||||
:plain="true"
|
||||
:text="false"
|
||||
:bg="false"
|
||||
@click="handleRemoveMember(idx)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</ele-table>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, reactive, nextTick, watch, onMounted, computed} from 'vue';
|
||||
import { useFormData } from '@/utils/use-form-data';
|
||||
import {get2union} from "@/api/club/apply/index.js";
|
||||
import {useDictData} from "@/utils/use-dict-data.js";
|
||||
import SurveyTreeSelect from "@/views/survey/components/survey-tree-select.vue";
|
||||
import {
|
||||
addBrandStudioApplicationApi,
|
||||
getLeaderHonorApi,
|
||||
updateBrandStudioApplicationApi
|
||||
} from "@/api/office/brand/index.js";
|
||||
import {EleMessage, EleTable} from "ele-admin-plus";
|
||||
import SelectMemberBtn from "@/views/brand/components/select-member-btn.vue";
|
||||
import {StrUtil} from "@/utils/toolkit.js";
|
||||
import dayjs from "dayjs";
|
||||
import {ElMessageBox} from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
editMode: Boolean,
|
||||
loading: Boolean,
|
||||
userUnionInfo: Object, // 用户工会相关信息
|
||||
topUnionId: String, // 最上层工会ID
|
||||
brandForm: Object // 表格信息,修改时使用
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:loading', 'editFinish'])
|
||||
|
||||
/** 字典数据 */
|
||||
const [
|
||||
leadPeopleDict,
|
||||
brandOfficeTypeDict,
|
||||
userEducationDict,
|
||||
brandOfficeDomainDict
|
||||
] = useDictData([
|
||||
'lead_people',
|
||||
'brand_office_type',
|
||||
'user_education',
|
||||
'brand_office_domain'
|
||||
]);
|
||||
|
||||
/** 表单组件 */
|
||||
const formRef = ref(null);
|
||||
|
||||
/** 表单数据(只改字段命名) */
|
||||
const [form, resetFields, assignFields] = useFormData({
|
||||
// 基本信息
|
||||
id: '',
|
||||
unionId: void 0, // 所属单位工会
|
||||
unionName: void 0, // 所属单位工会
|
||||
deptId: void 0,
|
||||
deptName: void 0,
|
||||
name: void 0, // 工作室名称
|
||||
createYear: void 0, // 创建年度
|
||||
leadPeople: void 0, // 工作室领衔人
|
||||
leadAge: 0, // 领衔人年龄
|
||||
leadIdentity: void 0, // 领衔人身份
|
||||
memberNum: 3, // 成员人数
|
||||
type: void 0, // 工作室类型
|
||||
track: void 0, // 工作室赛道
|
||||
address: void 0, // 工作室具体位置
|
||||
introduction: void 0, // 工作室基本情况介绍
|
||||
brandStudioMembers: [
|
||||
{ name: void 0, birthdate: void 0, grade: void 0, professional: void 0, deptName: void 0 },
|
||||
{ name: void 0, birthdate: void 0, grade: void 0, professional: void 0, deptName: void 0 },
|
||||
{ name: void 0, birthdate: void 0, grade: void 0, professional: void 0, deptName: void 0 }
|
||||
]
|
||||
});
|
||||
|
||||
// 成员信息校验
|
||||
const rulesMember = reactive({
|
||||
birthdate: [
|
||||
{ required: true, message: '请选择出生年月', trigger: ['change', 'blur'] },
|
||||
{
|
||||
validator: (_, v, cb) => {
|
||||
if (StrUtil.isBlank(v)) return cb(new Error('请选择出生年月'));
|
||||
const s = String(v).trim();
|
||||
if (!/^\d{4}-(0[1-9]|1[0-2])$/.test(s)) {
|
||||
return cb(new Error('出生年月格式应为 YYYY-MM'));
|
||||
}
|
||||
// 不能大于当前月份(可按业务改)
|
||||
const d = dayjs(s, 'YYYY-MM', true);
|
||||
if (!d.isValid()) return cb(new Error('出生年月不合法'));
|
||||
if (d.isAfter(dayjs(), 'month')) return cb(new Error('出生年月不能晚于当前月份'));
|
||||
cb();
|
||||
},
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
grade: [
|
||||
{ required: true, message: '请选择学历', trigger: ['change', 'blur'] }
|
||||
],
|
||||
professional: [
|
||||
{ required: true, message: '请输入职称', trigger: ['blur', 'change'] },
|
||||
{
|
||||
validator: (_, v, cb) => {
|
||||
if (StrUtil.isBlank(v)) return cb(new Error('请输入职称'));
|
||||
const s = String(v).trim();
|
||||
if (s.length > 30) return cb(new Error('职称长度不能超过 30'));
|
||||
// 常见职称字符集(中英数/空格/.-/括号)
|
||||
const ok = /^[\u4e00-\u9fa5A-Za-z0-9\s.\-()()]+$/.test(s);
|
||||
if (!ok) return cb(new Error('职称包含非法字符'));
|
||||
cb();
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
});
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => [
|
||||
{ prop: 'name', label: '姓名', align: 'center', minWidth: 80, slot: 'name' },
|
||||
{ prop: 'birthdate', label: '出生年月', align: 'center', minWidth: 120, slot: 'birthdate', required: true },
|
||||
{ prop: 'grade', label: '学历', align: 'center', minWidth: 80, slot: 'grade', required: true },
|
||||
{ prop: 'professional', label: '职称', align: 'center', minWidth: 100, slot: 'professional', required: true },
|
||||
{ prop: 'deptName', label: '所在部门', align: 'center', minWidth: 100, slot: 'deptName' },
|
||||
{ columnKey: 'action', label: '操作', width: 80, align: 'center', slot: 'action', notRequired: true }
|
||||
]);
|
||||
const fieldLabelMap = {};
|
||||
columns.value.forEach((col) => {
|
||||
fieldLabelMap[col.prop] = col.label;
|
||||
});
|
||||
/** 表单验证规则(同步改 prop key) */
|
||||
const rules = reactive({
|
||||
unionId: [
|
||||
{ required: true, message: '所属单位工会', trigger: 'change' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入工作室名称', trigger: 'blur' }
|
||||
],
|
||||
leadPeople: [
|
||||
{ required: true, message: '请选择领衔人', trigger: 'change' }
|
||||
],
|
||||
leadAge: [
|
||||
{ required: true, message: '请输入年龄', trigger: 'change' }
|
||||
],
|
||||
leadIdentity: [
|
||||
{ required: true, message: '请选择领衔人身份', trigger: 'change', type: 'array' }
|
||||
],
|
||||
memberNum: [
|
||||
{ required: true, message: '请输入成员人数', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择工作室类型', trigger: 'change' }
|
||||
],
|
||||
track: [
|
||||
{ required: true, message: '请选择所属赛道', trigger: 'change' }
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: '请输入工作室具体位置', trigger: 'blur' }
|
||||
],
|
||||
introduction: [
|
||||
{ required: true, message: '请输入工作室基本情况介绍', trigger: 'blur' }
|
||||
],
|
||||
brandStudioMembers: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
const members = value.filter(item => StrUtil.isNotBlank(item.name))
|
||||
console.log(value)
|
||||
// 1. 必须是数组且长度 >= 1
|
||||
if (!Array.isArray(members) || members.length < 1) {
|
||||
ElMessageBox.alert(
|
||||
`请至少选择1位工作室成员!`,
|
||||
`系统提示`, {
|
||||
confirmButtonText: '确定',
|
||||
type: 'warning',
|
||||
});
|
||||
return callback(new Error('请至少选择1位工作室成员'));
|
||||
}
|
||||
// 2. 检查每个成员的必填字段
|
||||
const requiredFields = columns.value
|
||||
.filter((col) => col.notRequired !== true)
|
||||
.map((col) => col.prop); // ['name', 'birthdate', ...]
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const item = value[i];
|
||||
for (const field of requiredFields) {
|
||||
const val = item?.[field];
|
||||
if (StrUtil.isEmpty(val)) {
|
||||
const label = fieldLabelMap[field] || field; // fallback to field name
|
||||
ElMessageBox.alert(
|
||||
`【${item.name}】成员的【${label}】不能为空!`,
|
||||
`系统提示`, {
|
||||
confirmButtonText: '确定',
|
||||
type: 'warning',
|
||||
});
|
||||
return callback(
|
||||
new Error(`第 ${i + 1} 位成员的“${label}”不能为空`)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/** 领衔人荣誉 */
|
||||
const leaderHonors = ref([]);
|
||||
const leaderChange = (emplid) => {
|
||||
console.log('emplid: ' + emplid);
|
||||
const matchedItem = leaderHonors.value.find(
|
||||
(item) => item.emplid === emplid
|
||||
);
|
||||
console.log(matchedItem)
|
||||
if (matchedItem) {
|
||||
form.leadHonor = matchedItem.honorNames?.join(',') || '';
|
||||
form.leadAge = matchedItem.age || 0;
|
||||
form.leadPeople = matchedItem.userName || '';
|
||||
} else {
|
||||
form.leadHonor = '';
|
||||
form.leadAge = 0;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveMember = (idx) => {
|
||||
form.brandStudioMembers.splice(idx, 1);
|
||||
form.memberNum = form.brandStudioMembers.length;
|
||||
// 可选:删完后清一下校验(避免残留错误)
|
||||
nextTick(() => formRef.value?.clearValidate?.());
|
||||
};
|
||||
|
||||
const unionAssign = (item) => {
|
||||
if (!item) {
|
||||
form.unionName = '';
|
||||
return;
|
||||
}
|
||||
form.unionName = item.name;
|
||||
}
|
||||
|
||||
const userUnionId = ref('')
|
||||
// 获取成员当前所在工会和所有工会
|
||||
const assignUserUnion = (userUnionInfo) => {
|
||||
form.unionId = userUnionInfo.unionId;
|
||||
form.unionName = userUnionInfo.unionName;
|
||||
form.deptId = userUnionInfo.deptId;
|
||||
form.deptName = userUnionInfo.deptName;
|
||||
form.createYear = new Date().getFullYear().toString();
|
||||
}
|
||||
|
||||
watch(() => props.userUnionInfo,
|
||||
(newVal, oldVal) => {
|
||||
if (StrUtil.isBlank(newVal?.unionId)) {
|
||||
return;
|
||||
}
|
||||
assignUserUnion(props.userUnionInfo);
|
||||
}, {immediate: true})
|
||||
|
||||
watch(
|
||||
() => form.brandStudioMembers.length,
|
||||
(len) => {
|
||||
form.memberNum = len
|
||||
}, { immediate: true }
|
||||
)
|
||||
watch(
|
||||
() => props.brandForm,
|
||||
(newVal, oldVal) => {
|
||||
console.log('newVal---', newVal)
|
||||
if (StrUtil.isBlank(newVal?.id)) {
|
||||
return
|
||||
}
|
||||
const data = {
|
||||
...newVal,
|
||||
leadIdentity: JSON.parse(newVal?.leadIdentity)
|
||||
}
|
||||
assignFields(data)
|
||||
}, {immediate: true}
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('mounted');
|
||||
// 调用接口获取所有工会列表并转为tree
|
||||
get2union().then((res) => {
|
||||
userUnionId.value = res.data
|
||||
})
|
||||
const res = await getLeaderHonorApi();
|
||||
leaderHonors.value = res.data.map((item, index) => {
|
||||
return {
|
||||
id: index,
|
||||
emplid: item.emplid,
|
||||
userName: item.userName,
|
||||
age: item.age,
|
||||
honorNames: item.honorNames
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// 提交数据/保存草稿
|
||||
const submit = (item) => {
|
||||
form.status = item.saveType;
|
||||
const params = { ...form };
|
||||
params.leadIdentity = JSON.stringify(form.leadIdentity) || {};
|
||||
params.domain = params.track;
|
||||
formRef.value?.validate?.((valid) => {
|
||||
if (!valid) {
|
||||
emit('update:loading', false)
|
||||
return;
|
||||
}
|
||||
const saveOrUpdate = item.isUpdate
|
||||
? updateBrandStudioApplicationApi
|
||||
: addBrandStudioApplicationApi;
|
||||
saveOrUpdate(params)
|
||||
.then(() => {
|
||||
EleMessage.success({ message: '保存成功', plain: true });
|
||||
emit('editFinish')
|
||||
})
|
||||
.catch((err) => {
|
||||
EleMessage.error({ message: '服务错误', plain: true });
|
||||
console.warn(err);
|
||||
})
|
||||
.finally(() => {
|
||||
emit('update:loading', false)
|
||||
});
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
submit
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.label-center, .union-member {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 基础尺寸:和 el-checkbox 完全一致 */
|
||||
.radio-as-checkbox :deep(.el-radio__inner) {
|
||||
box-sizing: border-box;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 干掉 radio 原点 */
|
||||
.radio-as-checkbox :deep(.el-radio__inner::after) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* hover 边框 */
|
||||
.radio-as-checkbox :deep(.el-radio__input:not(.is-disabled):hover .el-radio__inner) {
|
||||
border-color: var(--el-color-primary);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 选中态:背景 + 边框 */
|
||||
.radio-as-checkbox :deep(.el-radio__input.is-checked .el-radio__inner) {
|
||||
background-color: var(--el-color-primary);
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
/* el-checkbox 同款对勾 */
|
||||
.radio-as-checkbox :deep(.el-radio__input.is-checked .el-radio__inner::before) {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
bottom: 3px;
|
||||
width: 4px;
|
||||
height: 8px;
|
||||
border: 2px solid #fff;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
/* disabled 状态(和 el-checkbox 对齐) */
|
||||
.radio-as-checkbox :deep(.el-radio__input.is-disabled .el-radio__inner) {
|
||||
background-color: var(--el-fill-color-light);
|
||||
border-color: var(--el-border-color-light);
|
||||
}
|
||||
|
||||
.radio-as-checkbox :deep(.el-radio__input.is-disabled.is-checked .el-radio__inner) {
|
||||
background-color: var(--el-color-primary-light-5);
|
||||
border-color: var(--el-color-primary-light-5);
|
||||
}
|
||||
|
||||
/* 只放开人员表格里的 td */
|
||||
.union-member {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.union-member :deep(.el-select__selected-item),
|
||||
.union-member :deep(.el-input__inner),
|
||||
.union-member :deep(.el-input__wrapper .el-input__inner) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.label-required::before {
|
||||
content: '*';
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,27 @@
|
||||
import {h} from "vue";
|
||||
|
||||
export const withRequiredHeader = (col) => ({
|
||||
...col,
|
||||
renderHeader: () => {
|
||||
if (!col.required) return col.label;
|
||||
return h(
|
||||
'span',
|
||||
{ style: { display: 'inline-flex', alignItems: 'center' } },
|
||||
[
|
||||
h('span', null, col.label),
|
||||
h(
|
||||
'span',
|
||||
{
|
||||
style: {
|
||||
color: '#f56c6c', // 红色
|
||||
fontWeight: '700',
|
||||
fontSize: '16px',
|
||||
marginLeft: '4px' // 放右侧留间距
|
||||
}
|
||||
},
|
||||
'*'
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<el-form :inline="true" :model="pageForm">
|
||||
<el-form-item label="工作室名称">
|
||||
<el-input v-model="pageForm.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建年份">
|
||||
<el-date-picker v-model="pageForm.createYear" type="year" value-format="yyyy"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="pageData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="tableData" border>
|
||||
<el-table-column type="index" label="序号" width="60"></el-table-column>
|
||||
<el-table-column prop="name" label="工作室名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="createYear" label="创立年度" width="100"></el-table-column>
|
||||
<el-table-column prop="leadPeople" label="领衔人" width="120"></el-table-column>
|
||||
<el-table-column prop="deptName" label="所属机构" min-width="140"></el-table-column>
|
||||
<el-table-column prop="type" label="工作室类型" width="120"></el-table-column>
|
||||
<el-table-column prop="track" label="工作室赛道" width="120"></el-table-column>
|
||||
<el-table-column prop="memberNum" label="成员人数" width="90"></el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<template slot-scope="{row}">
|
||||
<el-button type="text" @click="openApply(row.id)">编辑工作室</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
status: 5,
|
||||
createYear: String(new Date().getFullYear())
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData(res) {
|
||||
return res.data && res.data.data !== undefined ? res.data.data : res.data
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.get('/platform/zhgh/brand/application/page', {params: this.pageForm}).then((res) => {
|
||||
const data = this.getData(res) || {}
|
||||
this.tableData = data.list || data.data || []
|
||||
})
|
||||
},
|
||||
openApply(id) {
|
||||
window.location.href = '/platform/zhgh/brand/apply/index?id=' + id
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<ele-page>
|
||||
<!-- 搜索表单 -->
|
||||
<param-search @search="reload" />
|
||||
<ele-card :body-style="{ paddingTop: '8px' }">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:show-overflow-tooltip="true"
|
||||
v-model:selections="selections"
|
||||
highlight-current-row
|
||||
:export-config="{ fileName: '参数设置' }"
|
||||
cache-key="systemConfigTable"
|
||||
:tools="false"
|
||||
>
|
||||
<template #createTime="{ row }">
|
||||
{{ dayjs(row.createTime).format('YYYY-MM-DD') }}
|
||||
</template>
|
||||
|
||||
<template #leadIdentity="{ row }">
|
||||
<div
|
||||
style="display: flex"
|
||||
v-for="(item, index) in JSON.parse(row.leadIdentity)"
|
||||
:key="index"
|
||||
>
|
||||
<el-tag type="primary">
|
||||
{{ item.dictLabel }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #memberNum="{ row }">
|
||||
{{ row.memberNum + '人' }}
|
||||
</template>
|
||||
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="openEdit(row)"
|
||||
:icon="EditOutlined"
|
||||
>
|
||||
编辑工作室
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import ParamSearch from '../components/param-search.vue';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
getBrandStudioApplicationPageApi,
|
||||
getUserBelongUnionApi
|
||||
} from '@/api/office/brand/index.js';
|
||||
import { EditOutlined } from '@/components/icons/index.js';
|
||||
import { BRAND_EDIT_PATH } from '@/config/setting.js';
|
||||
import { useRouter } from 'vue-router';
|
||||
const { push } = useRouter();
|
||||
import { usePageTab } from '@/utils/use-page-tab';
|
||||
const { addPageTab } = usePageTab();
|
||||
defineOptions({ name: 'Application' });
|
||||
|
||||
/** 表格实例 */
|
||||
const tableRef = ref(null);
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
// {
|
||||
// type: 'selection',
|
||||
// columnKey: 'selection',
|
||||
// width: 50,
|
||||
// align: 'center'
|
||||
// },
|
||||
{
|
||||
type: 'index',
|
||||
columnKey: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
label: '序号'
|
||||
},
|
||||
{
|
||||
prop: 'name',
|
||||
label: '工作室名称',
|
||||
align: 'center',
|
||||
minWidth: 180
|
||||
},
|
||||
{
|
||||
prop: 'createYear',
|
||||
label: '创立年度',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'createYear'
|
||||
},
|
||||
{
|
||||
prop: 'leadPeople',
|
||||
label: '领衔人',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'leadPeople'
|
||||
},
|
||||
{
|
||||
prop: 'deptName',
|
||||
label: '所属单位机构',
|
||||
minWidth: 140,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'type',
|
||||
label: '工作室类型',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'type'
|
||||
},
|
||||
{
|
||||
prop: 'track',
|
||||
label: '工作室赛道',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'track'
|
||||
},
|
||||
{
|
||||
prop: 'memberNum',
|
||||
label: '成员人数',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'memberNum'
|
||||
},
|
||||
{
|
||||
prop: 'address',
|
||||
label: '工作室地址',
|
||||
minWidth: 140,
|
||||
align: 'center',
|
||||
slot: 'address'
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '申请时间',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'createTime'
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
hideInPrint: true,
|
||||
hideInExport: true,
|
||||
fixed: 'right'
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
/** 表格选中数据 */
|
||||
const selections = ref([]);
|
||||
|
||||
/** 表格数据源 */
|
||||
const datasource = async ({ pages, where, filters }) => {
|
||||
where = {
|
||||
...where,
|
||||
status: 5,
|
||||
createYear: new Date().getFullYear().toString(),
|
||||
};
|
||||
const { data } = await getBrandStudioApplicationPageApi({
|
||||
...where,
|
||||
...filters,
|
||||
...pages
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
const unionName = ref('');
|
||||
onMounted(async () => {
|
||||
console.log('mounted');
|
||||
const { data } = await getUserBelongUnionApi();
|
||||
unionName.value = data.name;
|
||||
});
|
||||
|
||||
/** 搜索 */
|
||||
const reload = (where) => {
|
||||
tableRef.value?.reload?.({ page: 1, where });
|
||||
};
|
||||
|
||||
/** 打开编辑弹窗 */
|
||||
const openEdit = (row) => {
|
||||
const path = BRAND_EDIT_PATH + '/' + row.id + '/edit';
|
||||
addPageTab({
|
||||
title: '工作室管理',
|
||||
key: path,
|
||||
closable: true,
|
||||
meta: { icon: 'LinkOutlined' }
|
||||
});
|
||||
push(path);
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,145 @@
|
||||
<!-- 项目进度 -->
|
||||
<template>
|
||||
<ele-card :header="title" :body-style="{ padding: '10px', height: '370px' }">
|
||||
<ele-pro-table
|
||||
:height="352"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="applyWarning"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
:pagination="false"
|
||||
:toolbar="false"
|
||||
:bottom-line="false"
|
||||
size="large"
|
||||
class="project-table"
|
||||
>
|
||||
<template #pendingDays="{ row }">
|
||||
<span v-if="Math.floor(row.pendingDays) === 0">
|
||||
{{ Math.round(row.pendingDays * 24) + '小时' }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ Math.round(row.pendingDays * 100) / 100 + '天' }}
|
||||
</span>
|
||||
</template>
|
||||
<template #warnStatus="{ row }">
|
||||
<ele-text v-if="row.warnStatus === 1" type="default">待处理</ele-text>
|
||||
<ele-text v-else-if="row.warnStatus === 2" type="primary"
|
||||
>关注</ele-text
|
||||
>
|
||||
<ele-text v-else-if="row.warnStatus === 3" type="warning"
|
||||
>预警</ele-text
|
||||
>
|
||||
<ele-text v-else-if="row.warnStatus === 4" type="info">严重</ele-text>
|
||||
<ele-text v-else type="danger">紧急</ele-text>
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-if="row.status !== 0"
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
:icon="FileOutlined"
|
||||
>
|
||||
<span @click="handleCommand(row)"> 审批 </span>
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { getApplyWarningStatsApi } from '@/api/office/statistics/index.js';
|
||||
import { FileOutlined } from '@/components/icons/index.js';
|
||||
|
||||
defineProps({
|
||||
title: String
|
||||
});
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = ref([
|
||||
{
|
||||
prop: 'name',
|
||||
label: '品牌工作室名称',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'unionName',
|
||||
label: '直属工会',
|
||||
align: 'center',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'leadPeople',
|
||||
label: '领衔人',
|
||||
align: 'center',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'receiveTime',
|
||||
label: '接收时间',
|
||||
align: 'center',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'pendingDays',
|
||||
label: '已提交时间',
|
||||
width: 110,
|
||||
align: 'center',
|
||||
slot: 'pendingDays'
|
||||
},
|
||||
{
|
||||
prop: 'warnStatus',
|
||||
label: '审核预警',
|
||||
width: 110,
|
||||
align: 'center',
|
||||
slot: 'warnStatus'
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
hideInPrint: true,
|
||||
hideInExport: true,
|
||||
fixed: 'right'
|
||||
}
|
||||
]);
|
||||
|
||||
/** 申请预警数据表 */
|
||||
const applyWarning = ref([]);
|
||||
|
||||
const emit = defineEmits(['command']);
|
||||
|
||||
const handleCommand = (command) => {
|
||||
emit('command', {
|
||||
...command,
|
||||
id: command.applicationId,
|
||||
op: 'applyWarning'
|
||||
});
|
||||
};
|
||||
|
||||
/** 查询申请进度数据 */
|
||||
const queryApplyWarningList = () => {
|
||||
getApplyWarningStatsApi()
|
||||
.then((res) => {
|
||||
// console.log(res);
|
||||
applyWarning.value = res.data;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
queryApplyWarningList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.project-table :deep(.el-progress__text) {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,144 @@
|
||||
<!-- 项目进度 -->
|
||||
<template>
|
||||
<ele-card :header="title" :body-style="{ padding: '10px', height: '370px' }">
|
||||
<ele-pro-table
|
||||
:height="352"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="applyProgress"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
:pagination="false"
|
||||
:toolbar="false"
|
||||
:bottom-line="false"
|
||||
size="large"
|
||||
class="project-table"
|
||||
>
|
||||
<template #projectName="{ row }">
|
||||
<el-link type="primary" underline="never">
|
||||
{{ row.projectName }}
|
||||
</el-link>
|
||||
</template>
|
||||
<template #status="{ row }">
|
||||
<ele-text v-if="row.status === 0" type="danger">待申请</ele-text>
|
||||
<ele-text v-else-if="row.status === 1" type="primary">
|
||||
审核中
|
||||
</ele-text>
|
||||
<ele-text v-else-if="[2, 4].includes(row.status)" type="warning">
|
||||
待修改
|
||||
</ele-text>
|
||||
<ele-text v-else type="success">已完成</ele-text>
|
||||
</template>
|
||||
<template #progressPct="{ row }">
|
||||
<el-progress :percentage="row.progressPct" />
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="handleCommand(row)"
|
||||
:icon="FileOutlined"
|
||||
>
|
||||
查看
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { getApplyProgressStatsApi } from '@/api/office/statistics/index.js';
|
||||
import { FileOutlined } from '@/components/icons/index.js';
|
||||
|
||||
defineProps({
|
||||
title: String
|
||||
});
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = ref([
|
||||
{
|
||||
prop: 'applicationName',
|
||||
label: '品牌工作室名称',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'unionName',
|
||||
label: '直属工会',
|
||||
align: 'center',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'leadPeople',
|
||||
label: '领衔人',
|
||||
align: 'center',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
align: 'center',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
slot: 'status',
|
||||
align: 'center',
|
||||
width: 90
|
||||
},
|
||||
{
|
||||
prop: 'progressPct',
|
||||
label: '进度',
|
||||
width: 180,
|
||||
align: 'center',
|
||||
slot: 'progressPct',
|
||||
showOverflowTooltip: false
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
hideInPrint: true,
|
||||
hideInExport: true,
|
||||
fixed: 'right'
|
||||
}
|
||||
]);
|
||||
|
||||
/** 申请进度数据表 */
|
||||
const applyProgress = ref([]);
|
||||
|
||||
const emit = defineEmits(['command']);
|
||||
|
||||
const handleCommand = (command) => {
|
||||
emit('command', {
|
||||
...command,
|
||||
id: command.applicationId,
|
||||
op: 'applyProgress'
|
||||
});
|
||||
};
|
||||
|
||||
/** 查询申请进度数据 */
|
||||
const queryApplyProgressList = () => {
|
||||
getApplyProgressStatsApi()
|
||||
.then((res) => {
|
||||
applyProgress.value = res.data;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
queryApplyProgressList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.project-table :deep(.el-progress__text) {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<ele-card :header="title" :body-style="{ height: '370px' }">
|
||||
<div class="workplace-goal">
|
||||
<v-chart
|
||||
ref="saleChartRef"
|
||||
:style="{ height: height }"
|
||||
:option="saleChartOption"
|
||||
/>
|
||||
</div>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, provide, computed } from 'vue';
|
||||
import VChart, { THEME_KEY } from 'vue-echarts';
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { BarChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import { useEcharts } from '@/utils/use-echarts';
|
||||
import { useBodyResize } from '@/utils/use-body-resize.js';
|
||||
import { ChartTheme } from 'ele-admin-plus';
|
||||
|
||||
use([CanvasRenderer, BarChart, GridComponent, TooltipComponent]);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
data: Object,
|
||||
height: {
|
||||
type: String,
|
||||
default: () => '320px'
|
||||
},
|
||||
grid: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {left: 50, right: 20, top: 20, bottom: 70}
|
||||
}
|
||||
},
|
||||
xAxisLabel: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
interval: 0,
|
||||
rotate: 25,
|
||||
formatter: (val) => {
|
||||
const text = String(val ?? '');
|
||||
return text.length > 10 ? `${text.slice(0, 10)}…` : text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 图表ref
|
||||
const saleChartRef = ref(null);
|
||||
|
||||
// 传递图表的ref, 数组形式, 可传多个
|
||||
useEcharts([saleChartRef]);
|
||||
// EleAdminPlus提供的主题, 对颜色间距等都做了默认设置
|
||||
provide(THEME_KEY, ChartTheme);
|
||||
// 在侧栏折叠展开以及浏览器窗口大小改变后重置尺寸
|
||||
useBodyResize(() => {
|
||||
saleChartRef.value?.resize?.();
|
||||
});
|
||||
// 柱状图配置
|
||||
const saleChartOption = computed(() => {
|
||||
return {
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: props.grid,
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: props.data.x || [],
|
||||
axisLabel: props.xAxisLabel
|
||||
}
|
||||
],
|
||||
yAxis: [{ type: 'value' }],
|
||||
series: [{ type: 'bar', data: props.data.y || [] }]
|
||||
};
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,61 @@
|
||||
<!-- 本月目标 -->
|
||||
<template>
|
||||
<ele-card :header="title" :body-style="{ height: '370px' }">
|
||||
<div class="workplace-goal">
|
||||
<el-progress
|
||||
:width="180"
|
||||
:percentage="80"
|
||||
color="var(--el-color-primary)"
|
||||
type="dashboard"
|
||||
:format="() => ''"
|
||||
/>
|
||||
<div class="workplace-goal-body">
|
||||
<el-tag
|
||||
size="large"
|
||||
:disable-transitions="true"
|
||||
style="width: 36px; height: 36px; border-radius: 50%; line-height: 0"
|
||||
>
|
||||
<el-icon style="cursor: default; border-radius: 0">
|
||||
<TrophyBase />
|
||||
</el-icon>
|
||||
</el-tag>
|
||||
<div style="font-size: 40px">285</div>
|
||||
</div>
|
||||
<div>恭喜, 本月目标已达标!</div>
|
||||
</div>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { TrophyBase } from '@element-plus/icons-vue';
|
||||
|
||||
defineProps({
|
||||
title: String
|
||||
});
|
||||
|
||||
const emit = defineEmits(['command']);
|
||||
|
||||
const handleCommand = (command) => {
|
||||
emit('command', command);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workplace-goal {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.workplace-goal-body {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 180px;
|
||||
margin: -48px 0 0 -90px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<ele-card :header="title" :body-style="{ height: '370px' }">
|
||||
<div class="workplace-goal">
|
||||
<v-chart
|
||||
ref="saleChartRef"
|
||||
style="height: 320px"
|
||||
:option="saleChartOption"
|
||||
/>
|
||||
</div>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, provide, computed } from 'vue';
|
||||
import VChart, { THEME_KEY } from 'vue-echarts';
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import { useEcharts } from '@/utils/use-echarts';
|
||||
import { useBodyResize } from '@/utils/use-body-resize.js';
|
||||
import { ChartTheme } from 'ele-admin-plus';
|
||||
|
||||
use([CanvasRenderer, LineChart, GridComponent, TooltipComponent]);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
data: Object
|
||||
});
|
||||
|
||||
// 图表ref
|
||||
const saleChartRef = ref(null);
|
||||
|
||||
// 传递图表的ref, 数组形式, 可传多个
|
||||
useEcharts([saleChartRef]);
|
||||
// EleAdminPlus提供的主题, 对颜色间距等都做了默认设置
|
||||
provide(THEME_KEY, ChartTheme);
|
||||
// 在侧栏折叠展开以及浏览器窗口大小改变后重置尺寸
|
||||
useBodyResize(() => {
|
||||
saleChartRef.value?.resize?.();
|
||||
});
|
||||
// 柱状图配置
|
||||
const saleChartOption = computed(() => {
|
||||
return {
|
||||
tooltip: { trigger: 'axis' },
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: props.data.x
|
||||
}
|
||||
],
|
||||
yAxis: [{ type: 'value' }],
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
data: props.data.y
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<ele-card :header="title" :body-style="{ height: '370px' }">
|
||||
<div class="workplace-goal">
|
||||
<v-chart
|
||||
ref="saleChartRef"
|
||||
:style="{ height: height }"
|
||||
:option="saleChartOption"
|
||||
/>
|
||||
</div>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, provide, onMounted } from 'vue';
|
||||
import VChart, { THEME_KEY } from 'vue-echarts';
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { PieChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import { useEcharts } from '@/utils/use-echarts';
|
||||
import { useBodyResize } from '@/utils/use-body-resize.js';
|
||||
import { ChartTheme } from 'ele-admin-plus';
|
||||
|
||||
use([CanvasRenderer, PieChart, GridComponent, TooltipComponent]);
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: () => '320px'
|
||||
},
|
||||
});
|
||||
|
||||
// 图表ref
|
||||
const saleChartRef = ref(null);
|
||||
|
||||
// 传递图表的ref, 数组形式, 可传多个
|
||||
useEcharts([saleChartRef]);
|
||||
// EleAdminPlus提供的主题, 对颜色间距等都做了默认设置
|
||||
provide(THEME_KEY, ChartTheme);
|
||||
// 在侧栏折叠展开以及浏览器窗口大小改变后重置尺寸
|
||||
useBodyResize(() => {
|
||||
saleChartRef.value?.resize?.();
|
||||
});
|
||||
// 柱状图配置
|
||||
const saleChartOption = computed(() => ({
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: props.title,
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b}: {d}%'
|
||||
},
|
||||
data: props.data || []
|
||||
}
|
||||
]
|
||||
}));
|
||||
</script>
|
||||
@@ -0,0 +1,114 @@
|
||||
<!-- 项目进度 -->
|
||||
<template>
|
||||
<ele-card
|
||||
:header="title"
|
||||
:body-style="{ padding: '10px', minHeight: '150px' }"
|
||||
>
|
||||
<ele-pro-table
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="unionApplies"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
:pagination="false"
|
||||
:toolbar="false"
|
||||
:bottom-line="false"
|
||||
size="large"
|
||||
class="project-table"
|
||||
>
|
||||
<template #passRate="{ row }">
|
||||
<el-link type="primary" underline="never">
|
||||
{{ row.passRate + '%' }}
|
||||
</el-link>
|
||||
</template>
|
||||
<template #repealRate="{ row }">
|
||||
<el-link type="danger" underline="never">
|
||||
{{ row.repealRate + '%' }}
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { getUnionApplyStatsApi } from '@/api/office/statistics/index.js';
|
||||
|
||||
defineProps({
|
||||
title: String
|
||||
});
|
||||
|
||||
const emit = defineEmits(['command']);
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = ref([
|
||||
{
|
||||
type: 'index',
|
||||
columnKey: 'index',
|
||||
width: 50,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'unionName',
|
||||
label: '工会名称',
|
||||
slot: 'unionName',
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'applyCnt',
|
||||
label: '申请总数',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'passedCnt',
|
||||
label: '通过总数',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'reviewCnt',
|
||||
label: '待审批数',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'rejectCnt',
|
||||
label: '驳回数',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'repealCnt',
|
||||
label: '撤销数',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'passRate',
|
||||
label: '通过率',
|
||||
align: 'center',
|
||||
slot: 'passRate'
|
||||
},
|
||||
{
|
||||
prop: 'repealRate',
|
||||
label: '撤销率',
|
||||
align: 'center',
|
||||
slot: 'repealRate'
|
||||
}
|
||||
]);
|
||||
|
||||
/** 工会审核指标数据 */
|
||||
const unionApplies = ref([]);
|
||||
|
||||
/** 查询工会审核指标数据 */
|
||||
const unionApplyStats = () => {
|
||||
getUnionApplyStatsApi()
|
||||
.then((res) => {
|
||||
const { data } = res;
|
||||
unionApplies.value = data;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
unionApplyStats();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,236 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
||||
import GoalCard from './components/goal-card.vue';
|
||||
import PieChart from './components/pie-chart.vue';
|
||||
import UnionTable from './components/union-table.vue';
|
||||
import ApplyProgress from './components/apply-progress.vue';
|
||||
import ApplyPending from './components/apply-pending.vue';
|
||||
import BarChart from './components/bar-chart.vue';
|
||||
import LineChart from './components/line-chart.vue';
|
||||
import SortableJs from 'sortablejs';
|
||||
import FlowAudit from '@/views/brand/components/flow-audit.vue';
|
||||
import { getApplyCountStatsApi } from '@/api/office/statistics/index.js';
|
||||
|
||||
defineOptions({
|
||||
name: 'Overview',
|
||||
components: {
|
||||
GoalCard,
|
||||
PieChart,
|
||||
UnionTable,
|
||||
ApplyProgress,
|
||||
ApplyPending,
|
||||
LineChart,
|
||||
BarChart
|
||||
}
|
||||
});
|
||||
|
||||
/** 卡片数据 */
|
||||
const data = ref([
|
||||
{
|
||||
name: 'pie-chart',
|
||||
title: '申请情况(个人)',
|
||||
data: [
|
||||
{ value: 1048, name: '通过' },
|
||||
{ value: 735, name: '待审批' },
|
||||
{ value: 580, name: '待提交' },
|
||||
{ value: 484, name: '驳回' },
|
||||
{ value: 300, name: '失败' }
|
||||
],
|
||||
md: 8,
|
||||
sm: 24,
|
||||
xs: 24
|
||||
},
|
||||
{
|
||||
name: 'apply-progress',
|
||||
title: '申请进度记录(个人)',
|
||||
md: 16,
|
||||
sm: 24,
|
||||
xs: 24
|
||||
},
|
||||
{
|
||||
name: 'pie-chart',
|
||||
title: '年龄分布(组织)',
|
||||
data: [
|
||||
{ value: 1048, name: '<20' },
|
||||
{ value: 735, name: '20-40' },
|
||||
{ value: 580, name: '40-60' },
|
||||
{ value: 256, name: '60+' }
|
||||
],
|
||||
md: 8,
|
||||
sm: 24,
|
||||
xs: 24
|
||||
},
|
||||
{
|
||||
name: 'apply-pending',
|
||||
title: '工会平均审核时长和预警(组织)',
|
||||
md: 16,
|
||||
sm: 24,
|
||||
xs: 24
|
||||
},
|
||||
{
|
||||
name: 'bar-chart',
|
||||
title: '工作室类型统计(个人/组织)',
|
||||
label: 'type',
|
||||
data: [],
|
||||
md: 8,
|
||||
sm: 24,
|
||||
xs: 24
|
||||
},
|
||||
{
|
||||
name: 'line-chart',
|
||||
title: '年度申请数统计(个人/组织)',
|
||||
label: 'createYear',
|
||||
data: [],
|
||||
md: 8,
|
||||
sm: 24,
|
||||
xs: 24
|
||||
},
|
||||
{
|
||||
name: 'union-table',
|
||||
title: '工会审核情况统计(组织)',
|
||||
md: 24,
|
||||
sm: 24,
|
||||
xs: 24
|
||||
}
|
||||
]);
|
||||
/** 拖拽排序实例 */
|
||||
let sortableIns = null;
|
||||
/** 容器 */
|
||||
const wrapRef = ref(null);
|
||||
|
||||
/** 当前审核流数据 */
|
||||
const current = ref(null);
|
||||
|
||||
/** 显示审核流界面 */
|
||||
const showFlowCurrent = ref(false);
|
||||
/** 审核流界面是否可以编辑 */
|
||||
const isAudit = ref(false);
|
||||
|
||||
/** 编辑卡片 */
|
||||
const handleCommand = (command, index) => {
|
||||
switch (command.op) {
|
||||
case 'applyProgress': // 刷新
|
||||
current.value = command;
|
||||
isAudit.value = false;
|
||||
showFlowCurrent.value = true;
|
||||
break;
|
||||
case 'applyWarning':
|
||||
current.value = command;
|
||||
isAudit.value = true;
|
||||
showFlowCurrent.value = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const applyCountObject = ref({});
|
||||
|
||||
/** 统计用户申请的各字段分组 */
|
||||
const queryApplyCountStats = () => {
|
||||
getApplyCountStatsApi().then((res) => {
|
||||
console.log(res.data);
|
||||
applyCountObject.value = res.data;
|
||||
for (const element of data.value) {
|
||||
if (element.label) {
|
||||
const label = element.label;
|
||||
const item = res.data[label];
|
||||
element.data = {
|
||||
x: Object.keys(item), // ['公益活动', '社会实践', '社会实践报告', '科学科研', '绿色环保']
|
||||
y: Object.values(item) // [1, 1, 1, 1, 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
console.log(data.value);
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
queryApplyCountStats();
|
||||
// 卡片支持拖动排序
|
||||
sortableIns = new SortableJs(wrapRef.value?.$el, {
|
||||
handle: '.ele-card-header',
|
||||
filter: '.demo-more-icon',
|
||||
animation: 300,
|
||||
delay: 150,
|
||||
delayOnTouchOnly: true,
|
||||
onUpdate: ({ oldIndex, newIndex }) => {
|
||||
if (typeof oldIndex === 'number' && typeof newIndex === 'number') {
|
||||
const temp = [...data.value];
|
||||
temp.splice(newIndex, 0, temp.splice(oldIndex, 1)[0]);
|
||||
data.value = temp;
|
||||
}
|
||||
},
|
||||
setData: () => {},
|
||||
forceFallback: true
|
||||
});
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
sortableIns && sortableIns.destroy();
|
||||
sortableIns = null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ele-page>
|
||||
<el-row :gutter="16" ref="wrapRef">
|
||||
<el-col
|
||||
v-for="(item, index) in data"
|
||||
:key="item.name"
|
||||
:md="item.md"
|
||||
:sm="item.sm"
|
||||
:xs="item.xs"
|
||||
>
|
||||
<component
|
||||
:is="item.name"
|
||||
:title="item.title"
|
||||
:data="item.data"
|
||||
@command="(command) => handleCommand(command, index)"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<flow-audit v-model="showFlowCurrent" :data="current" :is-audit="isAudit" />
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workplace-page {
|
||||
:deep(.ele-card-header) {
|
||||
user-select: none;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
:deep(.el-col) {
|
||||
&.sortable-chosen > .ele-card {
|
||||
box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
&.sortable-ghost {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&.sortable-fallback {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 底部按钮 */
|
||||
.workplace-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.workplace-button {
|
||||
flex: 1;
|
||||
padding: 10px 0;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: hsla(0, 0%, 60%, 0.05);
|
||||
}
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 15px;
|
||||
margin: -1px 6px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,92 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<el-form :inline="true" :model="pageForm">
|
||||
<el-form-item label="工作室名称">
|
||||
<el-input v-model="pageForm.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建年份">
|
||||
<el-date-picker v-model="pageForm.createYear" type="year" value-format="yyyy"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态">
|
||||
<el-select v-model="pageForm.processStatus" clearable>
|
||||
<el-option label="待审核" :value="1"></el-option>
|
||||
<el-option label="已审核" :value="5"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="pageData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="tableData" border>
|
||||
<el-table-column type="index" label="序号" width="60"></el-table-column>
|
||||
<el-table-column prop="name" label="工作室名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="createYear" label="创立年度" width="100"></el-table-column>
|
||||
<el-table-column prop="leadPeople" label="领衔人" width="120"></el-table-column>
|
||||
<el-table-column prop="deptName" label="所属机构" min-width="140"></el-table-column>
|
||||
<el-table-column prop="processTaskNode" label="审核节点" width="140"></el-table-column>
|
||||
<el-table-column prop="processTaskReason" label="任务状态" width="100"></el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<template slot-scope="{row}">
|
||||
<el-button type="text" @click="audit(row, 'PASS')" v-if="row.processTaskReason==='ACTIVE'">通过</el-button>
|
||||
<el-button type="text" @click="audit(row, 'REJECT')" v-if="row.processTaskReason==='ACTIVE'">驳回</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
processStatus: 1,
|
||||
createYear: String(new Date().getFullYear())
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData(res) {
|
||||
return res.data && res.data.data !== undefined ? res.data.data : res.data
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.get('/platform/zhgh/brand/application/auditPage', {params: this.pageForm}).then((res) => {
|
||||
const data = this.getData(res) || {}
|
||||
this.tableData = data.list || data.data || []
|
||||
})
|
||||
},
|
||||
audit(row, type) {
|
||||
this.$prompt('请输入审批意见', '审批', {
|
||||
inputType: 'textarea',
|
||||
inputValue: type === 'PASS' ? '同意' : ''
|
||||
}).then(({value}) => {
|
||||
this.$axios.post('/platform/zhgh/brand/flow/audit', {
|
||||
applicationId: row.id,
|
||||
processInstanceId: row.processInstanceId,
|
||||
processInstanceTaskId: row.processInstanceTaskId || row.flowId,
|
||||
bpmTaskApprovalType: type,
|
||||
remark: value
|
||||
}).then(() => {
|
||||
this.$message.success('操作成功')
|
||||
this.pageData()
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<ele-page>
|
||||
<!-- 搜索表单 -->
|
||||
<param-search @search="reload" />
|
||||
<ele-card :body-style="{ paddingTop: '8px' }">
|
||||
<div class="radio-right">
|
||||
<el-radio-group
|
||||
v-model="auditStatus"
|
||||
size="default"
|
||||
@change="handleChange"
|
||||
>
|
||||
<el-radio-button
|
||||
v-for="item in auditStatusOptions"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
>
|
||||
{{ item.label }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:show-overflow-tooltip="true"
|
||||
v-model:selections="selections"
|
||||
highlight-current-row
|
||||
:export-config="{ fileName: '参数设置' }"
|
||||
cache-key="systemConfigTable"
|
||||
:tools="false"
|
||||
>
|
||||
<template #createTime="{ row }">
|
||||
{{ dayjs(row.createTime).format('YYYY-MM-DD') }}
|
||||
</template>
|
||||
|
||||
<template #leadIdentity="{ row }">
|
||||
<div
|
||||
style="display: flex"
|
||||
v-for="(item, index) in JSON.parse(row.leadIdentity)"
|
||||
:key="index"
|
||||
>
|
||||
<el-tag type="primary">
|
||||
{{ item.dictLabel }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #memberNum="{ row }">
|
||||
{{ row.memberNum + '人' }}
|
||||
</template>
|
||||
|
||||
<template #status="{ row }">
|
||||
<el-tag
|
||||
style="cursor: pointer"
|
||||
v-if="row.processUserTaskStatus === 1"
|
||||
type="warning"
|
||||
>
|
||||
待审核
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.processUserTaskStatus === 3" type="danger">
|
||||
拒绝
|
||||
</el-tag>
|
||||
<el-tag style="cursor: pointer" v-if="row.processUserTaskStatus === 4" type="info">
|
||||
取消
|
||||
</el-tag>
|
||||
<el-tag
|
||||
style="cursor: pointer"
|
||||
v-if="row.processUserTaskStatus === 2"
|
||||
type="success"
|
||||
>
|
||||
通过
|
||||
</el-tag>
|
||||
<el-tag
|
||||
style="cursor: pointer"
|
||||
v-if="row.processUserTaskStatus === 5"
|
||||
type="danger"
|
||||
>
|
||||
已退回
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click.stop="handleProcessDetail(row)"
|
||||
:icon="row.processUserTaskStatus === 1 ? FileOutlined : View"
|
||||
>
|
||||
{{ row.processUserTaskStatus === 1 ? '审批' : '查看' }}
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import ParamSearch from '../components/param-search.vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { getBrandApplicationAuditPageApi } from '@/api/office/brand/index.js';
|
||||
import { FileOutlined } from '@/components/icons/index.js';
|
||||
import {View} from "@element-plus/icons-vue";
|
||||
import $enums from "@/utils/enums.js";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
defineOptions({ name: 'Review' });
|
||||
const { push } = useRouter();
|
||||
/** 表格实例 */
|
||||
const tableRef = ref(null);
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
{
|
||||
type: 'index',
|
||||
columnKey: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
label: '序号'
|
||||
},
|
||||
{
|
||||
prop: 'name',
|
||||
label: '工作室名称',
|
||||
align: 'center',
|
||||
minWidth: 180
|
||||
},
|
||||
{
|
||||
prop: 'createYear',
|
||||
label: '创立年度',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'createYear'
|
||||
},
|
||||
{
|
||||
prop: 'leadPeople',
|
||||
label: '领衔人',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'leadPeople'
|
||||
},
|
||||
{
|
||||
prop: 'deptName',
|
||||
label: '所属单位机构',
|
||||
minWidth: 140,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'type',
|
||||
label: '工作室类型',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'type'
|
||||
},
|
||||
{
|
||||
prop: 'track',
|
||||
label: '工作室赛道',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'track'
|
||||
},
|
||||
{
|
||||
prop: 'memberNum',
|
||||
label: '成员人数',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'memberNum'
|
||||
},
|
||||
{
|
||||
prop: 'address',
|
||||
label: '工作室地址',
|
||||
minWidth: 140,
|
||||
align: 'center',
|
||||
slot: 'address'
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '申请时间',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'createTime'
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
minWidth: 90,
|
||||
align: 'center',
|
||||
slot: 'status'
|
||||
},
|
||||
{
|
||||
prop: 'processTaskNode',
|
||||
label: '审核节点',
|
||||
minWidth: 150,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
hideInPrint: true,
|
||||
hideInExport: true,
|
||||
fixed: 'right'
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
/** 表格选中数据 */
|
||||
const selections = ref([]);
|
||||
|
||||
const auditStatus = ref(1);
|
||||
|
||||
const auditStatusOptions = [
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '未审核', value: 1 },
|
||||
{ label: '已审核', value: 2 },
|
||||
];
|
||||
|
||||
const handleChange = (val) => {
|
||||
console.log('当前选中值:', val);
|
||||
auditStatus.value = val;
|
||||
if (val === 0) {
|
||||
reload({});
|
||||
} else {
|
||||
reload({ processStatus: val });
|
||||
}
|
||||
};
|
||||
|
||||
/** 表格数据源 */
|
||||
const datasource = async ({ pages, where, filters }) => {
|
||||
const finalWhere = { ...where, processStatus: auditStatus.value, createYear: new Date().getFullYear().toString() };
|
||||
const { data } = await getBrandApplicationAuditPageApi({
|
||||
...finalWhere,
|
||||
...filters,
|
||||
...pages
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/** 搜索 */
|
||||
const reload = (where) => {
|
||||
tableRef.value?.reload?.({ page: 1, where });
|
||||
};
|
||||
|
||||
/** 审批进度 */
|
||||
const handleProcessDetail = (row) => {
|
||||
push({
|
||||
name: 'WorkflowProcessInstanceDetail',
|
||||
query: {
|
||||
businessId: row.id,
|
||||
businessType: $enums.BUSINESS_PROCESS_KEY_NUMBER.BRAND_OFFICE_USER_APPLY,
|
||||
processInstanceId: row.processInstanceId,
|
||||
processFormPath: encodeURI(
|
||||
'/brand/components/flow-view.vue'
|
||||
)
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.radio-right {
|
||||
display: flex;
|
||||
justify-content: flex-end; /* 关键:右对齐 */
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<ele-card :body-style="{ paddingBottom: '2px' }">
|
||||
<el-form label-width="72px" @keyup.enter="search" @submit.prevent="">
|
||||
<el-row :gutter="8">
|
||||
<el-col :lg="4" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label="工作室名称" label-width="100px">
|
||||
<el-input
|
||||
clearable
|
||||
v-model.trim="form.name"
|
||||
placeholder="请输入工作室名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="4" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label="创立年度">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.createYear"
|
||||
type="year"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择工作室创立年度"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="4" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label="工作室领衔人" label-width="100px">
|
||||
<el-input
|
||||
clearable
|
||||
v-model.trim="form.leadPeople"
|
||||
placeholder="请输入工作室领衔人"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="12" :xs="24">
|
||||
<el-form-item label-width="20px">
|
||||
<el-button type="primary" @click="search">查询</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</ele-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useFormData } from '@/utils/use-form-data.js';
|
||||
const emit = defineEmits(['search']);
|
||||
|
||||
/** 表单数据 */
|
||||
const [form, resetFields] = useFormData({
|
||||
name: '',
|
||||
leadPeople: '',
|
||||
createYear: new Date().getFullYear().toString()
|
||||
});
|
||||
|
||||
/** 搜索 */
|
||||
const search = () => {
|
||||
emit('search', { ...form, params: {} });
|
||||
};
|
||||
|
||||
/** 重置 */
|
||||
const reset = () => {
|
||||
resetFields();
|
||||
search();
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,65 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<el-form :inline="true" :model="pageForm">
|
||||
<el-form-item label="工作室名称">
|
||||
<el-input v-model="pageForm.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建年份">
|
||||
<el-date-picker v-model="pageForm.createYear" type="year" value-format="yyyy"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="pageData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="tableData" border>
|
||||
<el-table-column type="index" label="序号" width="60"></el-table-column>
|
||||
<el-table-column prop="deptName" label="一级机构" min-width="120"></el-table-column>
|
||||
<el-table-column prop="name" label="工作室名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="leadPeople" label="领衔人" width="120"></el-table-column>
|
||||
<el-table-column prop="honorName" label="外部荣誉称号" min-width="150"></el-table-column>
|
||||
<el-table-column prop="createYear" label="创立年度" width="100"></el-table-column>
|
||||
<el-table-column prop="track" label="所属领域" width="120"></el-table-column>
|
||||
<el-table-column prop="leadHonor" label="领衔人荣誉称号" min-width="160"></el-table-column>
|
||||
<el-table-column prop="memberNum" label="成员人数" width="90"></el-table-column>
|
||||
<el-table-column prop="address" label="工作室地址" min-width="160"></el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
status: 5
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData(res) {
|
||||
return res.data && res.data.data !== undefined ? res.data.data : res.data
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.get('/platform/zhgh/brand/application/summaryPage', {params: this.pageForm}).then((res) => {
|
||||
const data = this.getData(res) || {}
|
||||
this.tableData = data.list || data.data || []
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,338 @@
|
||||
<template>
|
||||
<ele-page>
|
||||
<!-- 搜索表单 -->
|
||||
<param-search @search="reload" />
|
||||
<ele-card :body-style="{ paddingTop: '8px' }">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:show-overflow-tooltip="true"
|
||||
v-model:selections="selections"
|
||||
highlight-current-row
|
||||
:export-config="exportConfig"
|
||||
cache-key="systemConfigTable"
|
||||
:tools="['export', 'print', 'columns']"
|
||||
>
|
||||
<template #createTime="{ row }">
|
||||
{{ dayjs(row.createTime).format('YYYY-MM-DD') }}
|
||||
</template>
|
||||
|
||||
<template #leadIdentity="{ row }">
|
||||
<div
|
||||
style="display: flex"
|
||||
v-for="(item, index) in JSON.parse(row.leadIdentity)"
|
||||
:key="index"
|
||||
>
|
||||
<el-tag type="primary">
|
||||
{{ item.dictLabel }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #memberNum="{ row }">
|
||||
{{ row.memberNum + '人' }}
|
||||
</template>
|
||||
|
||||
<template #createYear="{ row }">
|
||||
{{ row.createYear }}
|
||||
</template>
|
||||
|
||||
<template #honorName="{ row }">
|
||||
{{ row.honorName || '暂无' }}
|
||||
</template>
|
||||
|
||||
<!-- <template #honorGrade="{ row }">-->
|
||||
<!-- {{ row.honorGrade || '暂无' }}-->
|
||||
<!-- </template>-->
|
||||
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-permission="'system:config:edit'"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="openLook(row)"
|
||||
:icon="FileOutlined"
|
||||
>
|
||||
查看
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</ele-card>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import {EleMessage} from 'ele-admin-plus';
|
||||
import ParamSearch from './components/param-search.vue';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
getBrandStudioApplicationHonorPageApi,
|
||||
getUserBelongUnionApi
|
||||
} from '@/api/office/brand/index.js';
|
||||
import { FileOutlined } from '@/components/icons/index.js';
|
||||
import { BRAND_EDIT_PATH } from '@/config/setting.js';
|
||||
|
||||
import { useRouter } from 'vue-router';
|
||||
const { push } = useRouter();
|
||||
import { usePageTab } from '@/utils/use-page-tab';
|
||||
import request from '@/utils/request.js';
|
||||
import { download } from '@/utils/common.js';
|
||||
const { addPageTab } = usePageTab();
|
||||
|
||||
defineOptions({ name: 'BrandSummary' });
|
||||
|
||||
/** 表格实例 */
|
||||
const tableRef = ref(null);
|
||||
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => {
|
||||
return [
|
||||
// {
|
||||
// type: 'selection',
|
||||
// columnKey: 'selection',
|
||||
// width: 50,
|
||||
// align: 'center'
|
||||
// },
|
||||
{
|
||||
type: 'index',
|
||||
columnKey: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
label: '序号'
|
||||
},
|
||||
{
|
||||
prop: 'name',
|
||||
label: '工作室名称',
|
||||
align: 'center',
|
||||
minWidth: 180
|
||||
},
|
||||
{
|
||||
prop: 'createYear',
|
||||
label: '创立年度',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'createYear'
|
||||
},
|
||||
{
|
||||
prop: 'leadPeople',
|
||||
label: '领衔人',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
slot: 'leadPeople'
|
||||
},
|
||||
{
|
||||
prop: 'deptName',
|
||||
label: '一级机构',
|
||||
minWidth: 120,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'honorName',
|
||||
label: '外部荣誉称号',
|
||||
minWidth: 150,
|
||||
align: 'center',
|
||||
slot: 'honorName'
|
||||
},
|
||||
// {
|
||||
// prop: 'honorGrade',
|
||||
// label: '级别',
|
||||
// minWidth: 80,
|
||||
// align: 'center',
|
||||
// slot: 'honorGrade'
|
||||
// },
|
||||
{
|
||||
prop: 'track',
|
||||
label: '所属领域',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'track'
|
||||
},
|
||||
{
|
||||
prop: 'leadHonor',
|
||||
label: '领衔人荣誉称号',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
slot: 'leadHonor'
|
||||
},
|
||||
{
|
||||
prop: 'memberNum',
|
||||
label: '成员人数',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'memberNum'
|
||||
},
|
||||
{
|
||||
prop: 'address',
|
||||
label: '工作室地址',
|
||||
minWidth: 140,
|
||||
align: 'center',
|
||||
slot: 'address'
|
||||
},
|
||||
// {
|
||||
// prop: 'remark',
|
||||
// label: '备注',
|
||||
// minWidth: 140,
|
||||
// align: 'center'
|
||||
// }
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
hideInPrint: true,
|
||||
hideInExport: true,
|
||||
fixed: 'right'
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
/** 表格选中数据 */
|
||||
const selections = ref([]);
|
||||
|
||||
/** 表格数据源 */
|
||||
const datasource = async ({ pages, where, filters }) => {
|
||||
where = {
|
||||
...where,
|
||||
status: 5
|
||||
};
|
||||
const { data } = await getBrandStudioApplicationHonorPageApi({
|
||||
...where,
|
||||
...filters,
|
||||
...pages
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
const unionName = ref('');
|
||||
onMounted(async () => {
|
||||
console.log('mounted');
|
||||
const { data } = await getUserBelongUnionApi();
|
||||
unionName.value = data.name;
|
||||
});
|
||||
|
||||
/** 搜索 */
|
||||
const reload = (where) => {
|
||||
tableRef.value?.reload?.({ page: 1, where });
|
||||
};
|
||||
|
||||
/** 打开编辑弹窗 */
|
||||
const openLook = (row) => {
|
||||
const path = BRAND_EDIT_PATH + '/' + row.id + '/look';
|
||||
addPageTab({
|
||||
title: '工作室管理',
|
||||
key: path,
|
||||
closable: true,
|
||||
meta: { icon: 'LinkOutlined' }
|
||||
});
|
||||
push(path);
|
||||
};
|
||||
|
||||
const exportUsers = async (data) => {
|
||||
const res = await request({
|
||||
url: '/act/brand/application/export',
|
||||
method: 'POST',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
});
|
||||
console.log('OK res=', res);
|
||||
download(
|
||||
res.data,
|
||||
'全行品牌工作室清单.xlsx',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
);
|
||||
};
|
||||
import {excelExport} from "@/utils/export-config.js";
|
||||
const exportConfig = reactive({
|
||||
beforeExport: (params) => {
|
||||
console.log("beforeExport")
|
||||
// 导出为excel格式
|
||||
excelExport(params, 'Sheet1');
|
||||
// 禁用掉原始默认导出
|
||||
return false;
|
||||
},
|
||||
// 数据源方法加 async 然后 return null
|
||||
datasource: async ({ where, filters, pages, orders }) => {
|
||||
console.log(columns.value);
|
||||
// 这里就可以调用后端接口下载文件, 还可以传递表格当前的搜索、排序参数等
|
||||
const loading = EleMessage.loading({
|
||||
message: '正在下载文件..',
|
||||
plain: true
|
||||
});
|
||||
exportUsers({ ...where, ...orders })
|
||||
.then(() => {
|
||||
loading.close();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
EleMessage.error(e.message);
|
||||
});
|
||||
},
|
||||
// 例如设置导出默认的文件名
|
||||
fileName: '全行品牌工作室清单'
|
||||
});
|
||||
|
||||
// 模板导出
|
||||
// import { utils, writeFile } from 'xlsx';
|
||||
/* 导出excel */
|
||||
const onExport = async () => {
|
||||
const { data } = await getBrandStudioApplicationHonorPageApi({
|
||||
page: 1,
|
||||
limit: 1000
|
||||
});
|
||||
console.log(data);
|
||||
const array = [
|
||||
[
|
||||
'序号',
|
||||
'一级机构',
|
||||
'工作室名称',
|
||||
'领衔人',
|
||||
'外部荣誉称号',
|
||||
'级别',
|
||||
'创立/获评年度',
|
||||
'所属领域',
|
||||
'是否有总行先进领衔(领衔人荣誉称号)',
|
||||
'是否有创新团队(工作室成员人数)',
|
||||
'备注'
|
||||
]
|
||||
];
|
||||
data.forEach((d, i) => {
|
||||
array.push([
|
||||
i + 1,
|
||||
d.deptName,
|
||||
d.name,
|
||||
d.leadPeople,
|
||||
d.honorName,
|
||||
d.honorGrade,
|
||||
d.createYear + '/' + d.requireYear,
|
||||
d.track,
|
||||
d.leadHonor,
|
||||
d.memberNum,
|
||||
d.remark
|
||||
]);
|
||||
});
|
||||
console.log(data);
|
||||
// const sheet = utils.aoa_to_sheet(array);
|
||||
// // 如果需要设置列宽可以这样写
|
||||
// sheet['!cols'] = [
|
||||
// { wch: 10 },
|
||||
// { wch: 60 },
|
||||
// { wch: 20 },
|
||||
// { wch: 20 },
|
||||
// { wch: 20 },
|
||||
// { wch: 20 },
|
||||
// { wch: 20 }
|
||||
// ];
|
||||
// writeFile(
|
||||
// {
|
||||
// SheetNames: ['Sheet1'],
|
||||
// Sheets: { Sheet1: sheet }
|
||||
// },
|
||||
// '用户数据.xlsx'
|
||||
// );
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,998 @@
|
||||
<script setup>
|
||||
import { EleMessage } from 'ele-admin-plus';
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
||||
import {
|
||||
ClusterOutlined,
|
||||
DeleteOutlined,
|
||||
UserOutlined,
|
||||
AppstoreOutlined
|
||||
} from '@/components/icons/index.js';
|
||||
import { useFormData } from '@/utils/use-form-data.js';
|
||||
import { useDictData } from '@/utils/use-dict-data.js';
|
||||
import {
|
||||
getBrandStudioApplicationApi,
|
||||
getLeaderHonorApi,
|
||||
getUserBelongUnionApi,
|
||||
updateBrandStudioBaseInfoApi,
|
||||
updateBrandStudioMemberOrHonorApi
|
||||
} from '@/api/office/brand/index.js';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { QuestionFilled } from '@element-plus/icons-vue';
|
||||
import UnionUserSelect from "@/components/UnionUserSelect/index.vue";
|
||||
import {withRequiredHeader} from "@/views/brand/js/common-brand.js";
|
||||
import {ElMessageBox} from "element-plus";
|
||||
import {StrUtil} from "@/utils/toolkit.js";
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const activeTab = ref('basic'); // 默认选中
|
||||
|
||||
const tabsOptions = ref([
|
||||
{ name: 'basic', label: '基本信息', value: 'basic', index: 1 },
|
||||
{ name: 'member', label: '成员信息', value: 'member', index: 2 },
|
||||
{ name: 'honor', label: '荣誉信息', value: 'honor', index: 3 }
|
||||
]);
|
||||
|
||||
/** 二级弹窗是否打开:选择用户 */
|
||||
const selectUserVisible = ref(false);
|
||||
|
||||
/** 是否是修改:针对整体 */
|
||||
const isUpdate = ref(false);
|
||||
|
||||
/** 是否可以编辑:针对申请表部分,主要是为了区分成员部分 */
|
||||
const editMember = ref(true);
|
||||
|
||||
/** 提交状态 */
|
||||
const loading = ref(false);
|
||||
|
||||
/** 领衔人荣誉 */
|
||||
const leaderHonors = ref([]);
|
||||
|
||||
/** 表单实例 */
|
||||
const formRef = ref();
|
||||
|
||||
/** 字典数据 */
|
||||
const [
|
||||
leadPeopleDict,
|
||||
brandOfficeTypeDict,
|
||||
userEducationDict,
|
||||
brandOfficeDomainDict
|
||||
] = useDictData([
|
||||
'lead_people',
|
||||
'brand_office_type',
|
||||
'user_education',
|
||||
'brand_office_domain'
|
||||
]);
|
||||
|
||||
/** 表单数据 */
|
||||
const [form, resetFields, assignFields] = useFormData({
|
||||
id: '',
|
||||
unionName: '', // 所属单位工会
|
||||
deptName: '',
|
||||
name: '', // 工作室名称
|
||||
createYear: '', // 创建年度
|
||||
leadPeople: '', // 工作室领衔人
|
||||
leadAge: 25, // 领衔人年龄
|
||||
leadIdentity: [], // 领衔人身份
|
||||
memberNum: 0, // 成员人数
|
||||
type: '', // 工作室类型
|
||||
track: '', // 工作室赛道
|
||||
address: '', // 工作室具体位置
|
||||
introduction: '' // 工作室基本情况介绍
|
||||
});
|
||||
|
||||
/** 表单验证规则 */
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入工作室名称',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
unionName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入所属单位工会',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
deptName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入所属单位机构',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
createYear: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择创建年度',
|
||||
type: 'string',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
leadPeople: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择工作室领衔人',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{ type: 'string', max: 20, message: '领衔人最多 20 个字符', trigger: ['blur', 'change'] }
|
||||
],
|
||||
leadAge: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入领衔人年龄',
|
||||
type: 'number',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
min: 0,
|
||||
max: 150,
|
||||
message: '年龄必须在0-150岁之间',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
leadIdentity: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择领衔人身份',
|
||||
type: 'array',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
leadHonor: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入领衔人荣誉称号',
|
||||
type: 'string',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
memberNum: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入成员人数',
|
||||
type: 'number',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择工作室类型',
|
||||
type: 'string',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
track: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入工作室赛道',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
address: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入工作室具体位置',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
introduction: [
|
||||
{
|
||||
required: true,
|
||||
message: '请填写工作室基本情况介绍',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
});
|
||||
const validateMembers = () => {
|
||||
const members = editableData.value;
|
||||
// 1. 至少 1 人
|
||||
if (!Array.isArray(members) || members.length < 1) {
|
||||
ElMessageBox.alert(
|
||||
'请至少选择 1 位工作室成员',
|
||||
'系统提示',
|
||||
{ type: 'warning' }
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// 2. 必填字段校验
|
||||
const requiredFields = columns.value
|
||||
.filter(col => col.notRequired !== true)
|
||||
.map(col => col.prop);
|
||||
for (let i = 0; i < members.length; i++) {
|
||||
const member = members[i];
|
||||
for (const field of requiredFields) {
|
||||
if (StrUtil.isEmpty(member[field])) {
|
||||
const label = fieldLabelMap[field] || field;
|
||||
ElMessageBox.alert(
|
||||
`【${member.name || '未命名'}】的【${label}】不能为空`,
|
||||
'系统提示',
|
||||
{ type: 'warning' }
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const validateHonors = () => {
|
||||
const honors = editableHonorData.value;
|
||||
// 1. 至少一条
|
||||
if (!Array.isArray(honors) || honors.length < 1) {
|
||||
ElMessageBox.alert(
|
||||
'请至少填写一条工作室荣誉',
|
||||
'系统提示',
|
||||
{ type: 'warning' }
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// 2. 必填字段校验
|
||||
const requiredFields = [
|
||||
{ field: 'honorName', label: '荣誉称号' },
|
||||
{ field: 'requireYear', label: '获取年度' },
|
||||
{ field: 'honorCategory', label: '荣誉类别' }
|
||||
];
|
||||
for (let i = 0; i < honors.length; i++) {
|
||||
const item = honors[i];
|
||||
for (const { field, label } of requiredFields) {
|
||||
if (StrUtil.isEmpty(item[field])) {
|
||||
ElMessageBox.alert(
|
||||
`第 ${i + 1} 条荣誉的【${label}】不能为空`,
|
||||
'系统提示',
|
||||
{ type: 'warning' }
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/** 返回 */
|
||||
const goBack = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
const showSelectUser = () => {
|
||||
selectUserVisible.value = true;
|
||||
};
|
||||
// 可选择的成员
|
||||
const userIds = ref([]);
|
||||
const topUnionId = ref('');
|
||||
const unionId = ref('');
|
||||
/** 选择成员 */
|
||||
// user-select 组件回调
|
||||
const handleSelect = (data) => {
|
||||
// orgEditableData 原来数据
|
||||
const orgEditableData = editableData.value;
|
||||
// 查找已经存在的用户
|
||||
const existingIds = new Set(
|
||||
orgEditableData.map((item) => item.userId || item.id)
|
||||
);
|
||||
// 过滤掉已经选择的用户,之前有的就不做处理
|
||||
const selectData = data
|
||||
.filter((item) => !existingIds.has(item.id))
|
||||
.map((item) => ({
|
||||
...item,
|
||||
userId: item.id,
|
||||
oldName: item.name,
|
||||
oldBirthdate: item.birthdate
|
||||
}));
|
||||
|
||||
editableData.value = [...orgEditableData, ...selectData];
|
||||
form.memberNum = editableData.value.length;
|
||||
// 选完情况组件中的用户
|
||||
userIds.value = [];
|
||||
};
|
||||
|
||||
/** beforeConfirm 为确定按钮点击钩子, 可以 return false 阻止确定 */
|
||||
const beforeConfirm = (data) => {
|
||||
if (!data?.length) {
|
||||
EleMessage.error('请至少选择一个用户');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 可编辑的副本(用于 v-model)
|
||||
const editableData = ref([]);
|
||||
const removeMember = (row) => {
|
||||
if (!editMember.value) {
|
||||
EleMessage.warning({ message: '查看界面,无法删除', plain: true });
|
||||
return false;
|
||||
}
|
||||
const index = editableData.value.findIndex(
|
||||
(item) => item.userId === row.userId
|
||||
);
|
||||
if (index !== -1) {
|
||||
userIds.value.splice(index, 1);
|
||||
editableData.value.splice(index, 1);
|
||||
form.memberNum--;
|
||||
}
|
||||
};
|
||||
|
||||
/** 表格实例 */
|
||||
const tableRef = ref(null);
|
||||
/** 表格列配置 */
|
||||
const columns = computed(() => [
|
||||
withRequiredHeader({ prop: 'name', label: '姓名', align: 'center', minWidth: 80, slot: 'name' }),
|
||||
withRequiredHeader({ prop: 'birthdate', label: '出生年月', align: 'center', minWidth: 120, slot: 'birthdate', required: true }),
|
||||
withRequiredHeader({ prop: 'grade', label: '学历', align: 'center', minWidth: 80, slot: 'grade', required: true }),
|
||||
withRequiredHeader({ prop: 'professional', label: '职称', align: 'center', minWidth: 100, slot: 'professional', required: true }),
|
||||
withRequiredHeader({ prop: 'deptName', label: '所在部门', align: 'center', minWidth: 100, slot: 'deptName' }),
|
||||
withRequiredHeader({ columnKey: 'action', label: '操作', width: 80, align: 'center', slot: 'action', notRequired: true })
|
||||
]);
|
||||
// 自动生成映射:{ name: '姓名', birthdate: '出生年月', ... }
|
||||
const fieldLabelMap = {};
|
||||
columns.value.forEach((col) => {
|
||||
fieldLabelMap[col.prop] = col.label;
|
||||
});
|
||||
|
||||
/** 表格实例 */
|
||||
const honorTableRef = ref(null);
|
||||
/** 表格列配置 */
|
||||
const honorColumns = computed(() => {
|
||||
return [
|
||||
{
|
||||
prop: 'honorName',
|
||||
label: '荣誉称号',
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
slot: 'honorName'
|
||||
},
|
||||
{
|
||||
prop: 'requireYear',
|
||||
label: '获取年度',
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
slot: 'requireYear'
|
||||
},
|
||||
{
|
||||
prop: 'honorCategory',
|
||||
label: '荣誉类别',
|
||||
align: 'center',
|
||||
minWidth: 100,
|
||||
slot: 'honorCategory'
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
slot: 'action',
|
||||
notRequired: true
|
||||
}
|
||||
];
|
||||
});
|
||||
// 可编辑的副本(用于 v-model)
|
||||
const editableHonorData = ref([]);
|
||||
const addHonor = () => {
|
||||
editableHonorData.value.push({
|
||||
id: editableHonorData.value.length + 1,
|
||||
honorName: '',
|
||||
honorGrade: '',
|
||||
requireYear: '',
|
||||
honorCategory: 1
|
||||
});
|
||||
};
|
||||
const removeHonor = (row) => {
|
||||
console.log(row);
|
||||
if (!editMember.value) {
|
||||
EleMessage.warning({ message: '查看界面,无法删除', plain: true });
|
||||
return false;
|
||||
}
|
||||
const index = editableHonorData.value.findIndex(
|
||||
(item) => item.id === row.id
|
||||
);
|
||||
if (index !== -1) {
|
||||
editableHonorData.value.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
const save = (isBase) => {
|
||||
loading.value = true;
|
||||
console.log('save', isBase);
|
||||
// 1 = 基本信息,2 = 成员,3 = 荣誉
|
||||
if (isBase === 2) {
|
||||
if (!validateMembers()) {
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBase === 3) {
|
||||
if (!validateHonors()) {
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
formRef.value?.validate?.((valid) => {
|
||||
if (!valid && isBase === 1) {
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
const updateApi = isBase === 1
|
||||
? updateBrandStudioBaseInfoApi
|
||||
: updateBrandStudioMemberOrHonorApi;
|
||||
const params = { ...form };
|
||||
params.leadIdentity = JSON.stringify(form.leadIdentity) || {};
|
||||
params.brandStudioMembers = form.unionUsers || [];
|
||||
params.domain = params.track;
|
||||
params.id = form.id;
|
||||
params.memberNum = form.memberNum;
|
||||
params.brandStudioMembers = editableData.value || [];
|
||||
params.brandStudioHonors = editableHonorData.value || [];
|
||||
updateApi(params)
|
||||
.then(() => {
|
||||
EleMessage.success({ message: '保存成功', plain: true });
|
||||
queryInfoById(form.id);
|
||||
})
|
||||
.catch((err) => {
|
||||
EleMessage.error({ message: '服务错误', plain: true });
|
||||
console.warn(err);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const queryInfoById = (id) => {
|
||||
userIds.value = [];
|
||||
getBrandStudioApplicationApi(id)
|
||||
.then(({ data }) => {
|
||||
const formData = {
|
||||
...data,
|
||||
leadIdentity: JSON.parse(data.leadIdentity)
|
||||
};
|
||||
form.leadHonor = formData.leadHonor;
|
||||
assignFields(formData);
|
||||
editableData.value =
|
||||
data.brandStudioMembers?.map((item) => {
|
||||
// userIds.value.push(item.userId);
|
||||
return {
|
||||
...item,
|
||||
oldName: item.name,
|
||||
oldBirthdate: item.birthdate
|
||||
};
|
||||
}) || [];
|
||||
console.log(data.brandStudioHonors);
|
||||
editableHonorData.value = data.brandStudioHonors || [];
|
||||
loadUserUnion()
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const leaderChange = (emplid) => {
|
||||
console.log('emplid: ' + emplid);
|
||||
const matchedItem = leaderHonors.value.find(
|
||||
(item) => item.emplid === emplid
|
||||
);
|
||||
|
||||
if (matchedItem) {
|
||||
form.leadHonor = matchedItem.honorNames?.join(',') || '';
|
||||
form.leadAge = matchedItem.age || 0;
|
||||
form.leadPeople = matchedItem.userName || '';
|
||||
} else {
|
||||
form.leadHonor = '';
|
||||
form.leadAge = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// 获取成员当前所在工会
|
||||
const loadUserUnion = async () => {
|
||||
const { data } = await getUserBelongUnionApi();
|
||||
unionId.value = data.unionId;
|
||||
topUnionId.value = data.topUnionId;
|
||||
// form.unionName = data.unionName;
|
||||
// form.deptName = data.deptName;
|
||||
// form.createYear = new Date().getFullYear().toString();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('mounted');
|
||||
await loadUserUnion()
|
||||
// 获取领衔人
|
||||
const res = await getLeaderHonorApi();
|
||||
leaderHonors.value = res.data.map((item, index) => {
|
||||
return {
|
||||
id: index,
|
||||
emplid: item.emplid,
|
||||
userName: item.userName,
|
||||
age: item.age,
|
||||
honorNames: item.honorNames
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => {
|
||||
editMember.value = route.params.edit === 'edit';
|
||||
const id = route.params.id;
|
||||
if (id) {
|
||||
queryInfoById(id);
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
resetFields();
|
||||
editableData.value = [];
|
||||
isUpdate.value = false;
|
||||
// form.unionName = route.query.unionName;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ele-page>
|
||||
<ele-card style="height: 800px">
|
||||
<ele-tabs
|
||||
v-model="activeTab"
|
||||
:items="tabsOptions"
|
||||
type="indicator"
|
||||
style="margin-bottom: 8px"
|
||||
>
|
||||
<template #label="{ item }">
|
||||
<div
|
||||
class="tab-item-container"
|
||||
style="display: flex; align-items: center; gap: 8px"
|
||||
>
|
||||
<ClusterOutlined
|
||||
v-if="item.index === 1"
|
||||
style="width: 14px; height: 14px"
|
||||
/>
|
||||
<UserOutlined
|
||||
v-else-if="item.index === 2"
|
||||
style="width: 14px; height: 14px"
|
||||
/>
|
||||
<AppstoreOutlined
|
||||
v-else-if="item.index === 3"
|
||||
style="width: 14px; height: 14px"
|
||||
/>
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #basic>
|
||||
<el-form
|
||||
style="padding: 20px 20px"
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="110px"
|
||||
@submit.prevent=""
|
||||
:disabled="true"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属单位工会" prop="unionName" required>
|
||||
<el-input
|
||||
v-model="form.unionName"
|
||||
:disabled="true"
|
||||
placeholder="请输入所属单位工会"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属单位机构" prop="deptName" required>
|
||||
<el-input
|
||||
v-model="form.deptName"
|
||||
:disabled="true"
|
||||
placeholder="请输入所属单位机构"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室名称" prop="name" required>
|
||||
<el-input
|
||||
v-model="form.name"
|
||||
placeholder="请输入工作室名称"
|
||||
maxlength="30"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建年度" required prop="createYear">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.createYear"
|
||||
type="year"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年度"
|
||||
:disabled="true"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室领衔人" prop="leadPeople" required>
|
||||
<el-select
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请选择工作室领衔人"
|
||||
v-model="form.leadPeople"
|
||||
@change="leaderChange"
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in leaderHonors"
|
||||
:key="item.emplid"
|
||||
:value="item.emplid"
|
||||
:label="`${item.emplid} - ${item.userName}`"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人年龄" required prop="leadAge">
|
||||
<el-input-number
|
||||
placeholder="请输入领衔人年龄"
|
||||
v-model="form.leadAge"
|
||||
min="0"
|
||||
max="150"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领衔人身份" prop="leadIdentity">
|
||||
<el-select
|
||||
placeholder="请选择领衔人身份"
|
||||
v-model="form.leadIdentity"
|
||||
multiple
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in leadPeopleDict"
|
||||
:key="item.id"
|
||||
:value="{
|
||||
id: item.id,
|
||||
dictLabel: item.dictLabel,
|
||||
dictTypeId: item.dictTypeId
|
||||
}"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="荣誉称号" required prop="leadHonor">
|
||||
<el-input
|
||||
placeholder="请输入领衔人荣誉称号"
|
||||
v-model="form.leadHonor"
|
||||
maxlength="40"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作室类型" prop="type">
|
||||
<el-select
|
||||
placeholder="请选择工作室类型"
|
||||
v-model="form.type"
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandOfficeTypeDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属赛道" prop="track" required>
|
||||
<el-select
|
||||
placeholder="请选择工作室赛道"
|
||||
v-model="form.track"
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandOfficeDomainDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="具体位置" prop="address" required>
|
||||
<el-input
|
||||
v-model="form.address"
|
||||
placeholder="请输入工作室具体位置"
|
||||
maxlength="80"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="基本情况介绍" required prop="introduction">
|
||||
<el-input
|
||||
:rows="8"
|
||||
type="textarea"
|
||||
v-model="form.introduction"
|
||||
placeholder="请输入基本情况介绍"
|
||||
clearable
|
||||
maxlength="1500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<div
|
||||
style="flex: 1; display: flex; justify-content: flex-end"
|
||||
v-if="editMember"
|
||||
>
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
<el-button type="primary" @click="save(1)">
|
||||
保存信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
<template #member>
|
||||
<div style="padding: 20px 20px">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<el-form-item
|
||||
label="工作室成员"
|
||||
required
|
||||
prop="unionUsers"
|
||||
:disabled="!editMember"
|
||||
>
|
||||
<span>{{ form.memberNum }}人</span>
|
||||
<el-tooltip
|
||||
content="团队成员数量,根据选择成员人数自动变化"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon
|
||||
style="cursor: help; margin-left: 4px; color: #909399"
|
||||
>
|
||||
<QuestionFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<div v-if="editMember">
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
<el-button type="primary" @click="showSelectUser">
|
||||
选择工作室成员
|
||||
</el-button>
|
||||
<el-button type="primary" @click="save(2)">
|
||||
保存人员
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:height="500"
|
||||
:columns="columns"
|
||||
:datasource="editableData"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
:export-config="{ fileName: '用户数据' }"
|
||||
:style="{ paddingBottom: '16px' }"
|
||||
cache-key="systemUserTable"
|
||||
:tools="false"
|
||||
>
|
||||
<template #name="{ row }">
|
||||
<span v-if="editMember && false">
|
||||
<el-input class="ipt-text" v-model="row.name" maxlength="20" show-word-limit />
|
||||
</span>
|
||||
<span v-else>{{ row.name }}</span>
|
||||
</template>
|
||||
<template #birthdate="{ row }">
|
||||
<span v-if="editMember">
|
||||
<el-date-picker
|
||||
style="width: 160px; padding: 0 20px"
|
||||
v-model="row.birthdate"
|
||||
type="month"
|
||||
placeholder="选择年月"
|
||||
format="YYYY-MM"
|
||||
value-format="YYYY-MM"
|
||||
size="large"
|
||||
/>
|
||||
</span>
|
||||
<span v-else>{{ row.birthdate }}</span>
|
||||
</template>
|
||||
<template #grade="{ row }">
|
||||
<span class="ipt-text">
|
||||
<el-select
|
||||
:disabled="!editMember"
|
||||
placeholder="请选择学历类型"
|
||||
v-model="row.grade"
|
||||
value-key="id"
|
||||
clearable
|
||||
maxlength="30"
|
||||
show-word-limit
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userEducationDict"
|
||||
:key="item.id"
|
||||
:value="item.dictLabel"
|
||||
:label="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</span>
|
||||
</template>
|
||||
<template #professional="{ row }">
|
||||
<span v-if="editMember" class="ipt-text">
|
||||
<el-input v-model="row.professional" maxlength="30" show-word-limit />
|
||||
</span>
|
||||
<span v-else>{{ row.professional }}</span>
|
||||
</template>
|
||||
<template #deptName="{ row }">
|
||||
<span class="ipt-text" v-if="editMember && false">
|
||||
<el-input v-model="row.deptName" />
|
||||
</span>
|
||||
<span v-else>{{ row.deptName }}</span>
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-permission="'system:config:remove'"
|
||||
type="danger"
|
||||
underline="never"
|
||||
@click="removeMember(row)"
|
||||
:icon="DeleteOutlined"
|
||||
:disabled="!editMember"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</div>
|
||||
</template>
|
||||
<template #honor>
|
||||
<div style="padding: 20px 20px">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<el-form-item label="工作室荣誉" required prop="honors" />
|
||||
<div v-if="editMember">
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
<el-button type="primary" @click="addHonor">
|
||||
添加荣誉
|
||||
</el-button>
|
||||
<el-button type="primary" @click="save(3)">
|
||||
保存荣誉
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="honorTableRef"
|
||||
row-key="id"
|
||||
:height="500"
|
||||
:columns="honorColumns"
|
||||
:datasource="editableHonorData"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
:style="{ paddingBottom: '16px' }"
|
||||
cache-key="systemUserTable"
|
||||
:tools="false"
|
||||
>
|
||||
<template #honorName="{ row }">
|
||||
<span class="ipt-text">
|
||||
<el-input
|
||||
v-if="editMember"
|
||||
v-model="row.honorName"
|
||||
maxlength="30" show-word-limit
|
||||
/>
|
||||
<span v-else>{{ row.honorName }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template #requireYear="{ row }">
|
||||
<span v-if="editMember" class="ipt-text">
|
||||
<el-date-picker
|
||||
style="padding: 0 20px"
|
||||
v-model="row.requireYear"
|
||||
type="year"
|
||||
placeholder="选择年度"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
size="large"
|
||||
/>
|
||||
</span>
|
||||
<span v-else>{{ row.requireYear }}</span>
|
||||
</template>
|
||||
<template #honorCategory="{ row }">
|
||||
<span class="ipt-text">
|
||||
<el-select
|
||||
:disabled="!editMember"
|
||||
style="padding: 0 20px"
|
||||
placeholder="请选择荣誉类别"
|
||||
v-model="row.honorCategory"
|
||||
value-key="id"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in [
|
||||
{
|
||||
id: 1,
|
||||
label: '外部荣誉'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: '行内荣誉'
|
||||
}
|
||||
]"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.label"
|
||||
/>
|
||||
</el-select>
|
||||
</span>
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-link
|
||||
v-permission="'system:config:remove'"
|
||||
type="danger"
|
||||
underline="never"
|
||||
@click="removeHonor(row)"
|
||||
:icon="DeleteOutlined"
|
||||
:disabled="!editMember"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</div>
|
||||
</template>
|
||||
</ele-tabs>
|
||||
</ele-card>
|
||||
<union-user-select
|
||||
clearable
|
||||
multiple
|
||||
view-type="picker"
|
||||
v-model:visible="selectUserVisible"
|
||||
v-model="userIds"
|
||||
placeholder="请选择用户"
|
||||
queryType="union"
|
||||
:union-id="topUnionId"
|
||||
@select="handleSelect"
|
||||
:before-confirm="beforeConfirm"
|
||||
/>
|
||||
</ele-page>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ipt-text {
|
||||
:deep(.el-input__inner) {
|
||||
text-align: center;
|
||||
}
|
||||
:deep(.el-select__selected-item) {
|
||||
text-align: center;
|
||||
}
|
||||
:deep(.el-date-picker__input) {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.foot-btn {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user