Explorar o código

oa审批数据同步到mec,并处理退课,退团业务逻辑

zouxuan %!s(int64=3) %!d(string=hai) anos
pai
achega
c2c3392b39

+ 37 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/FinancialExpenditureDao.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.dal.dao;
 
 import com.ym.mec.biz.dal.dto.FinancialExpenditureDto;
+import com.ym.mec.biz.dal.dto.PWorkOrderInfo;
 import com.ym.mec.biz.dal.entity.FinancialExpenditure;
 import com.ym.mec.common.dal.BaseDAO;
 import org.apache.ibatis.annotations.Param;
@@ -36,4 +37,40 @@ public interface FinancialExpenditureDao extends BaseDAO<Long, FinancialExpendit
      * @time 11:38
      */
     List<String> countBydingTalk(@Param("collect") List<Object> collect);
+
+    /**
+    * @description: 同步oa审批到支出记录
+     * @param workOrderId
+    * @return java.lang.Boolean
+    * @author zx
+    * @date 2021/11/25 16:09
+    */
+    PWorkOrderInfo getWorkOrderInfo(Integer workOrderId);
+
+    /**
+    * @description: 获取oa表单模板
+     * @param workOrderId
+    * @return java.lang.String
+    * @author zx
+    * @date 2021/11/25 16:55
+    */
+    String getFormStructure(Integer workOrderId);
+
+    /**
+    * @description: 获取oa表单
+     * @param workOrderId
+    * @return java.lang.String
+    * @author zx
+    * @date 2021/11/26 10:09
+    */
+    String getFormData(Integer workOrderId);
+
+    /**
+    * @description: 获取模板
+     * @param tplInfoId
+    * @return java.lang.String
+    * @author zx
+    * @date 2021/11/29 15:16
+    */
+    String getTplInfo(String tplInfoId);
 }

+ 26 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/OaColumnDto.java

@@ -0,0 +1,26 @@
+package com.ym.mec.biz.dal.dto;
+
+import java.util.List;
+
+public class OaColumnDto {
+
+    private Integer span;
+
+    private List<OaInputDto> list;
+
+    public Integer getSpan() {
+        return span;
+    }
+
+    public void setSpan(Integer span) {
+        this.span = span;
+    }
+
+    public List<OaInputDto> getList() {
+        return list;
+    }
+
+    public void setList(List<OaInputDto> list) {
+        this.list = list;
+    }
+}

+ 25 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/OaFormStructureDto.java

@@ -0,0 +1,25 @@
+package com.ym.mec.biz.dal.dto;
+
+import java.util.List;
+
+public class OaFormStructureDto {
+    private Integer id;
+
+    private List<OaInputDto> list;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public List<OaInputDto> getList() {
+        return list;
+    }
+
+    public void setList(List<OaInputDto> list) {
+        this.list = list;
+    }
+}

+ 56 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/OaInputDto.java

@@ -0,0 +1,56 @@
+package com.ym.mec.biz.dal.dto;
+
+import java.util.List;
+
+public class OaInputDto {
+
+    private String key;
+
+    private String type;
+
+    private String model;
+
+    private String name;
+
+    private List<OaColumnDto> columns;
+
+    public List<OaColumnDto> getColumns() {
+        return columns;
+    }
+
+    public void setColumns(List<OaColumnDto> columns) {
+        this.columns = columns;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

+ 83 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/PWorkOrderInfo.java

@@ -0,0 +1,83 @@
+package com.ym.mec.biz.dal.dto;
+
+public class PWorkOrderInfo {
+    private Integer id;
+
+    private Integer process;
+
+    private Integer classify;
+
+    private Boolean isEnd;
+
+    private Boolean isDenied;
+
+    private Boolean isCancel;
+
+    private Integer creator;
+
+    private String title;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getProcess() {
+        return process;
+    }
+
+    public void setProcess(Integer process) {
+        this.process = process;
+    }
+
+    public Integer getClassify() {
+        return classify;
+    }
+
+    public void setClassify(Integer classify) {
+        this.classify = classify;
+    }
+
+    public Boolean getEnd() {
+        return isEnd;
+    }
+
+    public void setEnd(Boolean end) {
+        isEnd = end;
+    }
+
+    public Boolean getDenied() {
+        return isDenied;
+    }
+
+    public void setDenied(Boolean denied) {
+        isDenied = denied;
+    }
+
+    public Boolean getCancel() {
+        return isCancel;
+    }
+
+    public void setCancel(Boolean cancel) {
+        isCancel = cancel;
+    }
+
+    public Integer getCreator() {
+        return creator;
+    }
+
+    public void setCreator(Integer creator) {
+        this.creator = creator;
+    }
+}

+ 44 - 2
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/FinancialExpenditure.java

@@ -7,6 +7,8 @@ import io.swagger.annotations.ApiModelProperty;
 import java.math.BigDecimal;
 import java.util.Date;
 
+import static com.ym.mec.biz.dal.enums.ExpenditureTypeEnum.REFUND;
+
 /**
  * 对应数据库表(financial_expenditure):
  */
@@ -33,10 +35,10 @@ public class FinancialExpenditure {
 	private String applyUser;
 
 	@ApiModelProperty(value = "支出类型(1:固定费用、2:变动费用:3:业务退费)",required = false)
-	private ExpenditureTypeEnum type;
+	private ExpenditureTypeEnum type = REFUND;
 
 	@ApiModelProperty(value = "费用项目",required = false)
-	private FeeProjectEnum feeProject;
+	private FeeProjectEnum feeProject = FeeProjectEnum.REFUND;
 	/**  */
 	@ApiModelProperty(value = "费用",required = false)
 	private BigDecimal amount;
@@ -68,6 +70,46 @@ public class FinancialExpenditure {
 	/**  */
 	private Integer delFlag;
 
+	private Long vipGroupId;
+
+	private String musicGroupId;
+
+	private String returnFeeType;
+
+	private Integer studentId;
+
+	public String getMusicGroupId() {
+		return musicGroupId;
+	}
+
+	public void setMusicGroupId(String musicGroupId) {
+		this.musicGroupId = musicGroupId;
+	}
+
+	public String getReturnFeeType() {
+		return returnFeeType;
+	}
+
+	public void setReturnFeeType(String returnFeeType) {
+		this.returnFeeType = returnFeeType;
+	}
+
+	public Long getVipGroupId() {
+		return vipGroupId;
+	}
+
+	public void setVipGroupId(Long vipGroupId) {
+		this.vipGroupId = vipGroupId;
+	}
+
+	public Integer getStudentId() {
+		return studentId;
+	}
+
+	public void setStudentId(Integer studentId) {
+		this.studentId = studentId;
+	}
+
 	public String getApplyUser() {
 		return applyUser;
 	}

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExpenditureTypeEnum.java

@@ -15,6 +15,16 @@ public enum ExpenditureTypeEnum implements BaseEnum<Integer, ExpenditureTypeEnum
         this.desc = desc;
     }
 
+    public static ExpenditureTypeEnum valueOfDesc(String desc) {
+        ExpenditureTypeEnum[] values = ExpenditureTypeEnum.values();
+        for (ExpenditureTypeEnum value : values) {
+            if(value.getDesc().equals(desc)){
+                return value;
+            }
+        }
+        return null;
+    }
+
     @Override
     public Integer getCode() {
         return code;

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/FeeProjectEnum.java

@@ -32,6 +32,16 @@ public enum FeeProjectEnum implements BaseEnum<Integer, FeeProjectEnum> {
         this.desc = desc;
     }
 
+    public static FeeProjectEnum valueOfDesc(String desc) {
+        FeeProjectEnum[] values = FeeProjectEnum.values();
+        for (FeeProjectEnum value : values) {
+            if(value.getDesc().equals(desc)){
+                return value;
+            }
+        }
+        return null;
+    }
+
     @Override
     public Integer getCode() {
         return code;

+ 21 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/FinancialExpenditureService.java

@@ -1,8 +1,10 @@
 package com.ym.mec.biz.service;
 
 import com.ym.mec.biz.dal.dto.FinancialExpenditureDto;
+import com.ym.mec.biz.dal.dto.ReturnFeeDto;
 import com.ym.mec.biz.dal.entity.FinancialExpenditure;
 import com.ym.mec.biz.dal.page.FinancialExpenditureQueryInfo;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.BaseService;
@@ -10,6 +12,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 
 public interface FinancialExpenditureService extends BaseService<Long, FinancialExpenditure> {
     /**
@@ -44,4 +47,22 @@ public interface FinancialExpenditureService extends BaseService<Long, Financial
      * @return
      */
     List<FinancialExpenditure> batchAdd(List<FinancialExpenditure> financialExpenditures);
+
+    /**
+    * @description: 同步oa审批到支出记录
+     * @param workOrderId
+    * @return void
+    * @author zx
+    * @date 2021/11/25 16:07
+    */
+    void syncOaPayLog(Integer workOrderId);
+
+    /**
+    * @description: 校验课程、乐团退费参数
+     * @param paramMap
+    * @return com.ym.mec.common.entity.HttpResponseResult
+    * @author zx
+    * @date 2021/11/29 14:40
+    */
+    void checkCourseReturnFee(Map<String,String> paramMap);
 }

+ 20 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupService.java

@@ -178,6 +178,26 @@ public interface MusicGroupService extends BaseService<String, MusicGroup> {
 	 */
 	boolean directQuitMusicGroup(String musicGroupId, Integer userId, String reason, boolean isRefundCourseFee, boolean isRefundInstrumentFee,
 								 boolean isRefundTeachingAssistantsFee,boolean isRefundMemberFee, BigDecimal maintenanceFee, BigDecimal cloudTeacherAmount);
+	/**
+	 * 处理oa审批退团逻辑
+	 * @param musicGroupId
+	 * @param userId
+	 * @param reason
+	 * @param isRefundInstrumentFee 是否退还乐器费用
+	 * @param isRefundTeachingAssistantsFee 是否退还教辅费用
+	 * @param maintenanceFee
+	 * @return
+	 */
+	void directQuitMusicGroupOa(String musicGroupId, Integer userId, String reason, boolean isRefundInstrumentFee,
+								   boolean isRefundTeachingAssistantsFee, boolean maintenanceFee,BigDecimal amount);
+
+	/**
+	 * 检测oa退团参数
+	 * @param musicGroupId
+	 * @param userId
+	 * @return
+	 */
+	void checkDirectQuitMusicGroupOa(String musicGroupId, Integer userId);
 
 	/**
 	 *  续费

+ 20 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/VipGroupService.java

@@ -306,6 +306,26 @@ public interface VipGroupService extends BaseService<Long, VipGroup> {
     HttpResponseResult applyRefundForStudent(ReturnFeeDto returnFeeDto);
 
     /**
+     * @describe 校验Oa审批,vip退课参数
+     * @author Joburgess
+     * @date 2019/11/15
+     * @param vipGroupId: vip课程
+     * @param studentId: 学生编号
+     * @return void
+     */
+    void checkApplyRefundForStudentOa(ReturnFeeDto returnFeeDto);
+
+    /**
+     * @describe 处理oa审批的vip退费逻辑
+     * @author Joburgess
+     * @date 2019/11/15
+     * @param vipGroupId: vip课程
+     * @param studentId: 学生编号
+     * @return void
+     */
+    void applyRefundForStudentOa(ReturnFeeDto returnFeeDto);
+
+    /**
      * @describe 对某个学生进行休学
      * @author Joburgess
      * @date 2019/12/18

+ 294 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/FinancialExpenditureServiceImpl.java

@@ -1,17 +1,24 @@
 package com.ym.mec.biz.service.impl;
 
 
+import com.alibaba.druid.sql.visitor.functions.If;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.auth.api.entity.SysUserDevice;
+import com.ym.mec.biz.dal.dao.EmployeeDao;
 import com.ym.mec.biz.dal.dao.FinancialExpenditureDao;
-import com.ym.mec.biz.dal.dto.FinancialExpenditureDto;
+import com.ym.mec.biz.dal.dao.OrganizationDao;
+import com.ym.mec.biz.dal.dto.*;
+import com.ym.mec.biz.dal.entity.Employee;
 import com.ym.mec.biz.dal.entity.FinancialExpenditure;
-import com.ym.mec.biz.dal.enums.ExpenditureTypeEnum;
-import com.ym.mec.biz.dal.enums.FeeProjectEnum;
-import com.ym.mec.biz.dal.enums.GoodsType;
-import com.ym.mec.biz.dal.enums.TemplateTypeEnum;
+import com.ym.mec.biz.dal.entity.Organization;
+import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.FinancialExpenditureQueryInfo;
 import com.ym.mec.biz.service.FinancialExpenditureService;
+import com.ym.mec.biz.service.MusicGroupService;
+import com.ym.mec.biz.service.VipGroupService;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.page.QueryInfo;
@@ -32,6 +39,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -40,6 +48,14 @@ public class FinancialExpenditureServiceImpl extends BaseServiceImpl<Long, Finan
 
     @Autowired
     private FinancialExpenditureDao financialExpenditureDao;
+    @Autowired
+    private OrganizationDao organizationDao;
+    @Autowired
+    private EmployeeDao employeeDao;
+    @Autowired
+    private VipGroupService vipGroupService;
+    @Autowired
+    private MusicGroupService musicGroupService;
 
     @Override
     public BaseDAO<Long, FinancialExpenditure> getDAO() {
@@ -198,5 +214,278 @@ public class FinancialExpenditureServiceImpl extends BaseServiceImpl<Long, Finan
         return financialExpenditures;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void syncOaPayLog(Integer workOrderId) {
+        PWorkOrderInfo pWorkOrderInfo = financialExpenditureDao.getWorkOrderInfo(workOrderId);
+        if (pWorkOrderInfo != null){
+            String formStructure = financialExpenditureDao.getFormStructure(workOrderId);
+            JSONObject formData = JSONObject.parseObject(financialExpenditureDao.getFormData(workOrderId));
+            OaFormStructureDto oaFormStructureDto = JSONObject.parseObject(formStructure, OaFormStructureDto.class);
+            List<OaInputDto> oaInputDtos = oaFormStructureDto.getList();
+            //课程退费和乐团退费需要单独处理
+            if(pWorkOrderInfo.getProcess().equals(22) || pWorkOrderInfo.getProcess().equals(19)){
+                List<FinancialExpenditure> financialExpenditureList = new ArrayList<>();
+                for (OaInputDto oaInputDto : oaInputDtos) {
+                    String submitForm = oaInputDto.getModel();
+                    List<HashMap> hashMaps = JSONObject.parseArray(formData.get(submitForm).toString(), HashMap.class);
+                    for (HashMap hashMap : hashMaps) {
+                        FinancialExpenditure financialExpenditure = new FinancialExpenditure();
+                        financialExpenditure.setBatchNo(pWorkOrderInfo.getId().toString());
+                        financialExpenditure.setFinancialProcessNo(pWorkOrderInfo.getId().toString());
+                        List<OaColumnDto> columns = oaInputDto.getColumns();
+                        if(columns != null && columns.size() > 0){
+                            for (OaColumnDto column : columns) {
+                                List<OaInputDto> columnList = column.getList();
+                                if(columnList != null && columnList.size() > 0){
+
+                                    Employee employee = employeeDao.get(pWorkOrderInfo.getCreator());
+                                    List<SimpleUserDto> byIds = new ArrayList<>();
+                                    if(employee != null){
+                                        List<Integer> userIds = new ArrayList<>();
+                                        userIds.add(employee.getUserId());
+                                        byIds = employeeDao.findByIds(userIds);
+                                    }
+                                    if(employee != null){
+                                        if(byIds != null && byIds.size() > 0){
+                                            SimpleUserDto simpleUserDto = byIds.get(0);
+                                            financialExpenditure.setApplyUser(simpleUserDto.getUserName());
+                                        }
+                                    }
+                                    for (OaInputDto inputDto : columnList) {
+                                        String name = inputDto.getName();
+                                        if(name.contains("课程组编号")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setVipGroupId(Long.parseLong(o.toString()));
+                                                continue;
+                                            }
+                                        }
+                                        if(name.contains("乐团编号")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setMusicGroupId(o.toString());
+                                                continue;
+                                            }
+                                        }
+                                        if(name.contains("退费项目")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setReturnFeeType(o.toString());
+                                                continue;
+                                            }
+                                        }
+                                        if(name.contains("学员编号")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setStudentId(Integer.parseInt(o.toString()));
+                                                continue;
+                                            }
+                                        }
+                                        if(name.contains("分部")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                int organId = Integer.parseInt(o.toString());
+                                                Organization organization = organizationDao.get(organId);
+                                                if(organization != null){
+                                                    financialExpenditure.setOrganId(organization.getId());
+                                                    financialExpenditure.setOrganName(organization.getName());
+                                                }
+                                                continue;
+                                            }
+                                        }
+                                        if(name.contains("金额")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setAmount(new BigDecimal(Double.parseDouble(o.toString())));
+                                                continue;
+                                            }
+                                        }else if(name.contains("情况说明")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setCause(o.toString());
+                                                continue;
+                                            }
+                                        }else if(name.contains("支出类型")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setType(ExpenditureTypeEnum.valueOfDesc(o.toString()));
+                                                continue;
+                                            }
+                                        }else if(name.contains("费用类型")){
+                                            Object o = hashMap.get(inputDto.getModel());
+                                            if(o != null){
+                                                financialExpenditure.setFeeProject(FeeProjectEnum.valueOfDesc(o.toString()));
+                                                continue;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        financialExpenditureList.add(financialExpenditure);
+                    }
+                }
+                //课程退费
+                if(pWorkOrderInfo.getProcess().equals(22)){
+                    for (FinancialExpenditure financialExpenditure : financialExpenditureList) {
+                        ReturnFeeDto returnFeeDto = new ReturnFeeDto();
+                        returnFeeDto.setGroupType(GroupType.VIP);
+                        returnFeeDto.setAmount(financialExpenditure.getAmount());
+                        returnFeeDto.setStudentId(financialExpenditure.getStudentId());
+                        returnFeeDto.setConfirmReturnActivityGive(true);
+                        returnFeeDto.setVipGroupId(financialExpenditure.getVipGroupId());
+                        vipGroupService.applyRefundForStudentOa(returnFeeDto);
+                    }
+                }else {
+                    //退团
+                    for (FinancialExpenditure financialExpenditure : financialExpenditureList) {
+                        Boolean isRefundInstrumentFee = false;
+                        Boolean isRefundTeachingAssistantsFee = false;
+                        Boolean maintenanceFee = false;
+                        String returnFeeType = financialExpenditure.getReturnFeeType();
+                        if(StringUtils.isNotEmpty(returnFeeType)){
+                            if(returnFeeType.contains("乐器")){
+                                isRefundInstrumentFee = true;
+                            }
+                            if(returnFeeType.contains("乐保")){
+                                maintenanceFee = true;
+                            }
+                            if(returnFeeType.contains("教辅")){
+                                isRefundTeachingAssistantsFee = true;
+                            }
+                        }
+                        musicGroupService.directQuitMusicGroupOa(financialExpenditure.getMusicGroupId(), financialExpenditure.getStudentId(),
+                                financialExpenditure.getCause(), isRefundInstrumentFee,
+                                isRefundTeachingAssistantsFee, maintenanceFee, financialExpenditure.getAmount());
+                    }
+                }
+                financialExpenditureDao.batchInsert(financialExpenditureList);
+            }else {
+                FinancialExpenditure financialExpenditure = new FinancialExpenditure();
+                financialExpenditure.setBatchNo(workOrderId.toString());
+                financialExpenditure.setFinancialProcessNo(workOrderId.toString());
+                Employee employee = employeeDao.get(pWorkOrderInfo.getCreator());
+                if(employee != null){
+                    Organization organization = organizationDao.get(employee.getDeptId());
+                    if(organization != null){
+                        financialExpenditure.setOrganId(organization.getId());
+                        financialExpenditure.setOrganName(organization.getName());
+                    }
+                    List<Integer> userIds = new ArrayList<>();
+                    userIds.add(employee.getUserId());
+                    List<SimpleUserDto> byIds = employeeDao.findByIds(userIds);
+                    if(byIds != null && byIds.size() > 0){
+                        SimpleUserDto simpleUserDto = byIds.get(0);
+                        financialExpenditure.setApplyUser(simpleUserDto.getUserName());
+                    }
+                }
+                for (OaInputDto oaInputDto : oaInputDtos) {
+                    String name = oaInputDto.getName();
+                    if(name.contains("金额")){
+                        Object o = formData.get(oaInputDto.getModel());
+                        if(o != null){
+                            financialExpenditure.setAmount(new BigDecimal(Double.parseDouble(o.toString())));
+                            continue;
+                        }
+                    }else if(name.contains("情况说明")){
+                        Object o = formData.get(oaInputDto.getModel());
+                        if(o != null){
+                            financialExpenditure.setCause(o.toString());
+                            continue;
+                        }
+                    }else if(name.contains("支出类型")){
+                        Object o = formData.get(oaInputDto.getModel());
+                        if(o != null){
+                            financialExpenditure.setType(ExpenditureTypeEnum.valueOfDesc(o.toString()));
+                            continue;
+                        }
+                    }else if(name.contains("费用类型")){
+                        Object o = formData.get(oaInputDto.getModel());
+                        if(o != null){
+                            financialExpenditure.setFeeProject(FeeProjectEnum.valueOfDesc(o.toString()));
+                            continue;
+                        }
+                    }
+                }
+                financialExpenditureDao.insert(financialExpenditure);
+            }
+        }
+    }
+
+    @Override
+    public void checkCourseReturnFee(Map<String,String> paramMap) {
+        String tplInfoId = paramMap.get("tplInfoId");
+        if(StringUtils.isEmpty(tplInfoId)){
+            throw new BizException("参数校验失败");
+        }
+        if(tplInfoId.equals("11") || tplInfoId.equals("8")){
+            JSONObject formData = JSONObject.parseObject(paramMap.get("formData"));
+            String formStructure = financialExpenditureDao.getTplInfo(tplInfoId);
+            OaFormStructureDto oaFormStructureDto = JSONObject.parseObject(formStructure, OaFormStructureDto.class);
+            List<OaInputDto> oaInputDtos = oaFormStructureDto.getList();
+            List<FinancialExpenditure> financialExpenditureList = new ArrayList<>();
+            for (OaInputDto oaInputDto : oaInputDtos) {
+                String submitForm = oaInputDto.getModel();
+                List<HashMap> hashMaps = JSONObject.parseArray(formData.get(submitForm).toString(), HashMap.class);
+                for (HashMap hashMap : hashMaps) {
+                    FinancialExpenditure financialExpenditure = new FinancialExpenditure();
+                    List<OaColumnDto> columns = oaInputDto.getColumns();
+                    if(columns != null && columns.size() > 0){
+                        for (OaColumnDto column : columns) {
+                            List<OaInputDto> columnList = column.getList();
+                            if(columnList != null && columnList.size() > 0){
+                                for (OaInputDto inputDto : columnList) {
+                                    String name = inputDto.getName();
+                                    if(name.contains("课程组编号")){
+                                        Object o = hashMap.get(inputDto.getModel());
+                                        if(o != null){
+                                            financialExpenditure.setVipGroupId(Long.parseLong(o.toString()));
+                                            continue;
+                                        }
+                                    }else if(name.contains("乐团编号")){
+                                        Object o = hashMap.get(inputDto.getModel());
+                                        if(o != null){
+                                            financialExpenditure.setMusicGroupId(o.toString());
+                                            continue;
+                                        }
+                                    }else if(name.contains("学员编号")){
+                                        Object o = hashMap.get(inputDto.getModel());
+                                        if(o != null){
+                                            financialExpenditure.setStudentId(Integer.parseInt(o.toString()));
+                                            continue;
+                                        }
+                                    }else if(name.contains("金额")){
+                                        Object o = hashMap.get(inputDto.getModel());
+                                        if(o != null){
+                                            financialExpenditure.setAmount(new BigDecimal(Double.parseDouble(o.toString())));
+                                            continue;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    financialExpenditureList.add(financialExpenditure);
+                }
+            }
+            //课程退费
+            if(tplInfoId.equals("11")){
+                for (FinancialExpenditure financialExpenditure : financialExpenditureList) {
+                    ReturnFeeDto returnFeeDto = new ReturnFeeDto();
+                    returnFeeDto.setGroupType(GroupType.VIP);
+                    returnFeeDto.setAmount(financialExpenditure.getAmount());
+                    returnFeeDto.setStudentId(financialExpenditure.getStudentId());
+                    returnFeeDto.setConfirmReturnActivityGive(true);
+                    returnFeeDto.setVipGroupId(financialExpenditure.getVipGroupId());
+                    vipGroupService.checkApplyRefundForStudentOa(returnFeeDto);
+                }
+            }else {
+                for (FinancialExpenditure financialExpenditure : financialExpenditureList) {
+                    musicGroupService.checkDirectQuitMusicGroupOa(financialExpenditure.getMusicGroupId(), financialExpenditure.getStudentId());
+                }
+            }
 
+        }
+    }
 }

+ 249 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java

@@ -2744,6 +2744,255 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
 
     @Override
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+    public void directQuitMusicGroupOa(String musicGroupId, Integer userId, String reason, boolean isRefundInstrumentFee,
+                                        boolean isRefundTeachingAssistantsFee, boolean maintenanceFee,BigDecimal amount) {
+        MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
+        if (musicGroup == null) {
+            return ;
+        }
+        if (musicGroup.getStatus() == MusicGroupStatusEnum.CANCELED || musicGroup.getStatus() == MusicGroupStatusEnum.PAUSE) {
+            return;
+        }
+
+        StudentRegistration studentRegistration = studentRegistrationDao.queryByUserIdAndMusicGroupId(userId, musicGroupId);
+        if (studentRegistration == null) {
+            return;
+        }
+
+        StudentMusicGroupStatusEnum currentStudentMusicGroupStatus = studentRegistration.getMusicGroupStatus();
+        if (currentStudentMusicGroupStatus != StudentMusicGroupStatusEnum.NORMAL && currentStudentMusicGroupStatus != StudentMusicGroupStatusEnum.APPLY) {
+            return;
+        }
+
+        // 有进行中的课程不能退团
+        List<CourseSchedule> courseScheduleList = courseScheduleDao.findMusicGroupCourseSchedulesWithStudent(musicGroupId, GroupType.MUSIC.getCode(),
+                "UNDERWAY", userId);
+        if (courseScheduleList != null && courseScheduleList.size() > 0) {
+            return;
+        }
+
+        boolean hasPaid = studentRegistration.getMusicGroupStatus().equals(StudentMusicGroupStatusEnum.NORMAL);
+
+        //如果是会员团,并且有预排课计划
+        MusicGroupSchoolTermCourseDetail termCourseDetail = musicGroupSchoolTermCourseDetailDao.findByCourseDateAndMusicGroupId(musicGroupId, null, 0);
+        if(termCourseDetail != null){
+            //是否已经预排部分课程
+            List<CourseSchedule> courseSchedules = courseScheduleDao.queryPreCourseListByMusicGroupId(musicGroup.getId());
+            if(courseSchedules.size() > 0){
+                return;
+            }else {
+                musicGroupSchoolTermStudentCourseDetailDao.deleteByDetailId(termCourseDetail.getId(),userId);
+            }
+        }
+
+        courseScheduleStudentPaymentService.updateCourseActualPrice(Arrays.asList(musicGroupId), Arrays.asList(userId), GroupType.MUSIC);
+
+        Date date = new Date();
+
+        MusicGroupQuit musicGroupQuit = new MusicGroupQuit();
+        musicGroupQuit.setCreateTime(date);
+        musicGroupQuit.setJoinDate(studentRegistration.getCreateTime());
+        musicGroupQuit.setMusicGroupId(musicGroupId);
+        musicGroupQuit.setUserId(userId);
+        musicGroupQuit.setStatus(ApprovalStatus.APPROVED);
+        musicGroupQuit.setReason(reason);
+        musicGroupQuit.setQuitDate(date);
+        musicGroupQuitDao.insert(musicGroupQuit);
+
+        List<Integer> classGroupIdList = classGroupStudentMapperDao.queryClassGroupIdList(musicGroupId, userId, GroupType.MUSIC);
+        for (Integer classGroupId : classGroupIdList) {
+            ClassGroup classGroup = classGroupService.get(classGroupId);
+            if (classGroup.getType().equals(ClassGroupTypeEnum.MUSIC_NETWORK)) {
+                classGroupService.delSingle(classGroupId);
+            } else {
+                classGroupStudentMapperService.delClassGroupStudent(userId, classGroupId, true);
+            }
+        }
+
+        //删除续费周期
+        musicGroupStudentFeeDao.deleteByUserIdAndMusicGroupId(userId, musicGroupId);
+
+        // 退团
+        studentRegistration.setMusicGroupStatus(StudentMusicGroupStatusEnum.QUIT);
+        studentRegistration.setSurplusCourseFee(BigDecimal.ZERO);
+        studentRegistration.setHasCloudTeacher(0);
+        studentRegistration.setUpdateTime(date);
+        studentRegistrationDao.update(studentRegistration);
+
+        //删除进行中加学生,且在审批中或拒绝的缴费
+        List<Long> paymentCalenderIdList = musicGroupPaymentCalenderDao.findStudentNoPaymentCalender(userId, musicGroupId);
+        if (paymentCalenderIdList != null && paymentCalenderIdList.size() > 0) {
+            musicGroupPaymentCalenderDao.delByIds(paymentCalenderIdList);
+        }
+
+        //查询未交费的项目
+        List<MusicGroupPaymentCalenderDetail> musicGroupPaymentCalenderDetailList = musicGroupPaymentCalenderDetailDao.queryNotPaymentStudentByUserIdAndMusicGroupId(userId, musicGroupId);
+
+        for (MusicGroupPaymentCalenderDetail mgpcd : musicGroupPaymentCalenderDetailList) {
+            MusicGroupPaymentCalender mgpc = musicGroupPaymentCalenderDao.get(mgpcd.getMusicGroupPaymentCalenderId());
+            if (mgpc != null) {
+                if (mgpc.getPaymentType() == PaymentType.ADD_STUDENT) {
+                    musicGroupPaymentCalenderDao.delete(mgpc.getId());
+                } else {
+                    // 缴费项目预计人数减一
+                    mgpc.setExpectNum(mgpc.getExpectNum() - 1);
+                    mgpc.setUpdateTime(date);
+                    musicGroupPaymentCalenderDao.update(mgpc);
+                }
+            }
+            musicGroupPaymentCalenderDetailDao.delete(mgpcd.getId());
+        }
+        //删除用户购买的课程记录
+        musicGroupPaymentStudentCourseDetailDao.deleteByUserIdAndMusicGroupId(userId, musicGroupId);
+
+        List<StudentPaymentOrder> studentPaymentOrderList = new ArrayList<StudentPaymentOrder>();
+
+		if (studentRegistration.getMusicGroupPaymentCalenderId() == null) {
+			if(currentStudentMusicGroupStatus == StudentMusicGroupStatusEnum.NORMAL || (currentStudentMusicGroupStatus == StudentMusicGroupStatusEnum.APPLY && studentRegistration.getPaymentStatus() == PaymentStatusEnum.YES)){
+				studentPaymentOrderList = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, musicGroupId, SUCCESS);
+			}
+
+		} else {
+			studentPaymentOrderList = studentPaymentOrderService.queryByBatchNo(userId, studentRegistration.getMusicGroupPaymentCalenderId() + "",
+					DealStatusEnum.SUCCESS);
+		}
+
+        // 判断乐器是否是租赁
+        MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanDao.getMusicOneSubjectClassPlan(musicGroupId, studentRegistration.getActualSubjectId());
+        if (hasPaid && musicGroupSubjectPlan != null) {
+            musicGroupSubjectPlan.setUpdateTime(date);
+            //减去缴费人数(器乐收费,0元时不减缴费人数)
+            if (musicGroup.getCourseViewType() == CourseViewTypeEnum.MEMBER_FEE) {
+
+            	for(StudentPaymentOrder studentPaymentOrder : studentPaymentOrderList){
+            		if (studentPaymentOrder != null && studentPaymentOrder.getPaymentAccountNo() != null && studentPaymentOrder.getPaymentAccountNo().equals("200")) {
+                        musicGroupSubjectPlan.setPaidZeroNum(musicGroupSubjectPlan.getPaidZeroNum() - 1);
+                        musicGroupSubjectPlan.setPaidStudentNum(musicGroupSubjectPlan.getPaidStudentNum() - 1);
+                        break;
+                    } else if (studentPaymentOrder != null && studentPaymentOrder.getPaymentAccountNo() == null) {
+                        musicGroupSubjectPlan.setPaidStudentNum(musicGroupSubjectPlan.getPaidStudentNum() - 1);
+                        break;
+                    }
+            	}
+            } else {
+                musicGroupSubjectPlan.setPaidStudentNum(musicGroupSubjectPlan.getPaidStudentNum() - 1);
+            }
+            musicGroupSubjectPlanDao.update(musicGroupSubjectPlan);
+        }
+
+        if (MusicGroupStatusEnum.PROGRESS.equals(musicGroup.getStatus())) {
+            //统计变更学员数
+            groupEventSource.musicGroupStudentChangeEvent(musicGroupId, StudentMusicGroupStatusEnum.QUIT, new ArrayList<>(Arrays.asList(userId)));
+        }
+
+        if (studentPaymentOrderList.size() > 0) {
+
+        	List<Long> paymentOrderIdList = studentPaymentOrderList.stream().map(t -> t.getId()).collect(Collectors.toList());
+
+        	Long minPaymentOrderId = Collections.min(paymentOrderIdList);
+
+            List<StudentPaymentOrderDetail> orderDetailList = studentPaymentOrderDetailDao.getWithIds(paymentOrderIdList);
+
+            SubjectChange studentLastChange = null;
+            if (isRefundInstrumentFee || isRefundTeachingAssistantsFee) {
+                studentLastChange = subjectChangeDao.getStudentLastChange(userId, musicGroupId);
+            }
+
+			if (studentLastChange != null && minPaymentOrderId <= studentLastChange.getOriginalOrderId()) {
+				if (isRefundInstrumentFee) {
+					StudentInstrument studentMaintenance = studentInstrumentDao.getByOrderId(studentLastChange.getOrderId().longValue());
+		            if (studentMaintenance != null) {
+		                studentMaintenance.setDelFlag(1);
+		                studentInstrumentDao.update(studentMaintenance);
+		            }
+				}
+			} else {
+				for (StudentPaymentOrderDetail detail : orderDetailList) {
+					// 退乐器费用
+					if (isRefundInstrumentFee && detail.getType() == MUSICAL) {
+						StudentInstrument studentMaintenance = studentInstrumentDao.getStudentMaintenance(userId, musicGroupId);
+			            if (studentMaintenance != null) {
+			                studentMaintenance.setDelFlag(1);
+			                studentInstrumentDao.update(studentMaintenance);
+			            }
+					}
+				}
+			}
+
+        }
+        //退乐保费用
+        if (maintenanceFee) {
+            StudentInstrument studentMaintenance = studentInstrumentDao.getStudentMaintenance(userId, musicGroupId);
+            if (studentMaintenance != null) {
+                studentMaintenance.setStatus(0);
+                studentMaintenance.setStartTime(null);
+                studentMaintenance.setEndTime(null);
+                studentInstrumentDao.update(studentMaintenance);
+            }
+        }
+
+        if (amount.doubleValue() > 0) {
+            //这个接口没有退费的操作了
+            SysUserCashAccountLog sysUserCashAccountLog = new SysUserCashAccountLog();
+            sysUserCashAccountLog.setGroupType(GroupType.MUSIC);
+            sysUserCashAccountLog.setUserId(userId);
+            sysUserCashAccountLog.setOrganId(musicGroup.getOrganId());
+            sysUserCashAccountLog.setGroupId(musicGroupId);
+            sysUserCashAccountLog.setAmount(amount);
+            sysUserCashAccountLog.setReturnFeeType(ReturnFeeEnum.MUSIC);
+            sysUserCashAccountLog.setComment("OA审批退团");
+            sysUserCashAccountLogDao.insert(sysUserCashAccountLog);
+        }
+    }
+
+    @Override
+    public void checkDirectQuitMusicGroupOa(String musicGroupId, Integer userId) {
+        SysUser user = teacherDao.getUser(userId);
+        if (user == null) {
+            throw new BizException("学员 {} 信息不存在",userId);
+        }
+        Student student = studentDao.get(userId);
+        if(student == null){
+            throw new BizException("学员 {} 信息不存在",userId);
+        }
+        MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
+        if (musicGroup == null) {
+            throw new BizException("乐团 {} {} 不存在",musicGroupId,musicGroup.getName());
+        }
+        if (musicGroup.getStatus() == MusicGroupStatusEnum.CANCELED || musicGroup.getStatus() == MusicGroupStatusEnum.PAUSE) {
+            throw new BizException("退团失败,乐团 {} {} 状态[已取消]或[已暂停]",musicGroupId,musicGroup.getName());
+        }
+
+        StudentRegistration studentRegistration = studentRegistrationDao.queryByUserIdAndMusicGroupId(userId, musicGroupId);
+        if (studentRegistration == null) {
+            throw new BizException("学员 {} {} 注册信息不存在",userId,user.getUsername());
+        }
+
+        StudentMusicGroupStatusEnum currentStudentMusicGroupStatus = studentRegistration.getMusicGroupStatus();
+        if (currentStudentMusicGroupStatus != StudentMusicGroupStatusEnum.NORMAL && currentStudentMusicGroupStatus != StudentMusicGroupStatusEnum.APPLY) {
+            throw new BizException("学员 {} {} 当前在团状态不能退团",userId,user.getUsername());
+        }
+
+        // 有进行中的课程不能退团
+        List<CourseSchedule> courseScheduleList = courseScheduleDao.findMusicGroupCourseSchedulesWithStudent(musicGroupId, GroupType.MUSIC.getCode(),
+                "UNDERWAY", userId);
+        if (courseScheduleList != null && courseScheduleList.size() > 0) {
+            throw new BizException("学员 {} {} 存在[进行中]的课程",userId,user.getUsername());
+        }
+
+        //如果是会员团,并且有预排课计划
+        MusicGroupSchoolTermCourseDetail termCourseDetail = musicGroupSchoolTermCourseDetailDao.findByCourseDateAndMusicGroupId(musicGroupId, null, 0);
+        if(termCourseDetail != null){
+            //是否已经预排部分课程
+            List<CourseSchedule> courseSchedules = courseScheduleDao.queryPreCourseListByMusicGroupId(musicGroup.getId());
+            if(courseSchedules.size() > 0){
+                throw new BizException("乐团 {} {} 存在预排课课程,请优先完成预排课",musicGroupId,musicGroup.getName());
+            }
+        }
+    }
+
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public Map renew(RenewParamDto renewParamDto) throws Exception {
         Long calenderId = renewParamDto.getCalenderId();
         Integer userId = renewParamDto.getUserId();

+ 152 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java

@@ -3143,6 +3143,158 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 	}
 
 	@Override
+	public void checkApplyRefundForStudentOa(ReturnFeeDto returnFeeDto) {
+		Long vipGroupId = returnFeeDto.getVipGroupId();
+		Integer studentId = returnFeeDto.getStudentId();
+		if(Objects.isNull(vipGroupId) || Objects.isNull(studentId)){
+			throw new BizException("请指定小课与学生");
+		}
+		SysUser user = teacherDao.getUser(studentId);
+		if(user == null){
+			throw new BizException("用户 {} 信息不存在",studentId);
+		}
+		Student student = studentDao.get(studentId);
+		if(student == null){
+			throw new BizException("学员 {} 信息不存在",studentId);
+		}
+		VipGroup vipGroup = vipGroupDao.get(vipGroupId);
+		if(Objects.isNull(vipGroup)){
+			throw new BizException("指定的课程不存在");
+		}
+		if(vipGroup.getStatus().equals(VipGroupStatusEnum.CANCEL)){
+			throw new BizException("不能对已停止的课程进行此操作");
+		}
+		if(vipGroup.getName().startsWith("考前辅导课")){
+			throw new BizException("当前课程类型不支持退学");
+		}
+
+		List<StudentApplyRefunds> studentApplyRefunds = studentApplyRefundsDao.findByGroupAndUser(vipGroupId.toString(), GroupType.VIP.getCode(), studentId);
+		if(!CollectionUtils.isEmpty(studentApplyRefunds)){
+			throw new BizException("学生 {} {} 存在退课申请",studentId,user.getUsername());
+		}
+
+		ClassGroup classGroup = classGroupDao.findByVipGroup(vipGroupId, null);
+
+		ClassGroupStudentMapper classStudentMapperByUserIdAndClassGroupId = classGroupStudentMapperDao.query(classGroup.getId(),
+				studentId);
+
+		if(Objects.isNull(classStudentMapperByUserIdAndClassGroupId)){
+			throw new BizException("学生 {} {} 不在此课程中",studentId,user.getUsername());
+		}
+
+		if(classStudentMapperByUserIdAndClassGroupId.getStatus().equals(ClassGroupStudentStatusEnum.QUIT)){
+			throw new BizException("学生 {} {} 已经是退学状态",studentId,user.getUsername());
+		}
+		BigDecimal amount = returnFeeDto.getAmount();
+		if(!classStudentMapperByUserIdAndClassGroupId.getStatus().equals(ClassGroupStudentStatusEnum.QUIT_SCHOOL)){
+			if(Objects.isNull(amount)){
+				throw new BizException("请确定退费金额");
+			}
+			Map<String, BigDecimal> studentSurplusCourseFee = getStudentSurplusCourseFee(vipGroupId, studentId);
+			BigDecimal suplusCourseFee = studentSurplusCourseFee.get("suplusCourseOriginalFee");
+			if(amount.compareTo(suplusCourseFee) > 0){
+				throw new BizException("学员 {} {} 最大可退费金额为{}元", studentId,user.getUsername(),suplusCourseFee.toString());
+			}
+		}
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void applyRefundForStudentOa(ReturnFeeDto returnFeeDto) {
+		Long vipGroupId = returnFeeDto.getVipGroupId();
+		Integer studentId = returnFeeDto.getStudentId();
+		if(Objects.isNull(vipGroupId) || Objects.isNull(studentId)){
+			return;
+		}
+		VipGroup vipGroup = vipGroupDao.get(vipGroupId);
+		if(Objects.isNull(vipGroup)){
+			return;
+		}
+		if(vipGroup.getStatus().equals(VipGroupStatusEnum.CANCEL)){
+			return;
+		}
+		if(vipGroup.getName().startsWith("考前辅导课")){
+			return;
+		}
+
+		VipGroupCategory vipGroupCategory = vipGroupCategoryDao.get(vipGroup.getVipGroupCategoryId());
+
+		List<StudentApplyRefunds> studentApplyRefunds = studentApplyRefundsDao.findByGroupAndUser(vipGroupId.toString(), GroupType.VIP.getCode(), studentId);
+		if(!CollectionUtils.isEmpty(studentApplyRefunds)){
+			return;
+        }
+
+        ClassGroup classGroup = classGroupDao.findByVipGroup(vipGroupId, null);
+
+		ClassGroupStudentMapper classStudentMapperByUserIdAndClassGroupId = classGroupStudentMapperDao.query(classGroup.getId(),
+				studentId);
+
+		if(Objects.isNull(classStudentMapperByUserIdAndClassGroupId)){
+			return;
+		}
+
+		if(classStudentMapperByUserIdAndClassGroupId.getStatus().equals(ClassGroupStudentStatusEnum.QUIT)){
+			return;
+		}
+		BigDecimal amount = returnFeeDto.getAmount();
+		if(!classStudentMapperByUserIdAndClassGroupId.getStatus().equals(ClassGroupStudentStatusEnum.QUIT_SCHOOL)){
+			if(Objects.isNull(amount)){
+				return;
+			}
+//			Map<String, BigDecimal> studentSurplusCourseFee = getStudentSurplusCourseFee(vipGroupId, studentId);
+//			BigDecimal suplusCourseFee = studentSurplusCourseFee.get("suplusCourseOriginalFee");
+//			if(amount.compareTo(suplusCourseFee) > 0){
+//				throw new BizException("学员最大可退费金额为{}元", suplusCourseFee.toString());
+//			}
+		}
+		//退还活动购买
+		ActivityUserMapper activityUserMapper = activityUserMapperService.findByStudentId(vipGroup.getId(),studentId);
+		HttpResponseResult result = groupClassService.quitActivityGive(activityUserMapper, returnFeeDto.getConfirmReturnActivityGive(),vipGroup.getId(),VIP);
+
+        if(classStudentMapperByUserIdAndClassGroupId.getStatus().equals(ClassGroupStudentStatusEnum.QUIT_SCHOOL)){
+			classStudentMapperByUserIdAndClassGroupId.setStatus(ClassGroupStudentStatusEnum.QUIT);
+			classGroupStudentMapperDao.update(classStudentMapperByUserIdAndClassGroupId);
+			studentPauseInfoDao.deleteUserPauseInfoWithGroup(GroupType.VIP, vipGroupId.toString(), studentId);
+
+			classGroup.setStudentNum(classGroup.getStudentNum()-1);
+			classGroupDao.update(classGroup);
+			return ;
+        }
+
+		//记录日志
+		SysUserCashAccountLog sysUserCashAccountLog = new SysUserCashAccountLog();
+		sysUserCashAccountLog.setUserId(studentId);
+		sysUserCashAccountLog.setGroupType(VIP);
+		sysUserCashAccountLog.setOrganId(vipGroup.getOrganId());
+		sysUserCashAccountLog.setGroupId(vipGroupId.toString());
+		sysUserCashAccountLog.setAmount(amount);
+		sysUserCashAccountLog.setReturnFeeType(ReturnFeeEnum.VIP);
+		sysUserCashAccountLog.setComment("OA审批VIP退课");
+		sysUserCashAccountLogDao.insert(sysUserCashAccountLog);
+
+		classStudentMapperByUserIdAndClassGroupId.setStatus(ClassGroupStudentStatusEnum.QUIT);
+		classGroupStudentMapperDao.update(classStudentMapperByUserIdAndClassGroupId);
+
+		courseScheduleService.batchDeleteMusicGroupCourseWithStudent(vipGroupId.toString(),studentId,GroupType.VIP);
+
+        List<Integer> studentPaymentIds = courseScheduleStudentPaymentDao.findNotStartCourseStudentPaymentIdsWithClassGroupAndStudent(classGroup.getId(), studentId);
+        if(!CollectionUtils.isEmpty(studentPaymentIds)){
+            courseScheduleStudentPaymentDao.batchDeleteWithID(studentPaymentIds);
+        }
+
+        if(!vipGroup.getStatus().equals(VipGroupStatusEnum.APPLYING) || (Objects.nonNull(vipGroupCategory) && vipGroupCategory.getMusicTheory())){
+			courseScheduleTeacherSalaryService.updateVipGroupCourseTeacherSalary(vipGroupId.intValue(), vipGroup.getUserId());
+		}
+
+		classGroup.setStudentNum(classGroup.getStudentNum()-1);
+
+        classGroupDao.update(classGroup);
+
+		//学员退出班级群
+		imGroupMemberService.quit(classGroup.getId().longValue(), studentId);
+	}
+
+	@Override
 	@Transactional(rollbackFor = Exception.class)
 	public void pauseForStudent(Long vipGroupId, Integer studentId) {
 		if(Objects.isNull(vipGroupId)||Objects.isNull(studentId)){

+ 27 - 0
mec-biz/src/main/resources/config/mybatis/FinancialExpenditureMapper.xml

@@ -215,4 +215,31 @@
         </foreach>
         GROUP BY dingtalk_process_no_
     </select>
+    <resultMap id="PWorkOrderInfo" type="com.ym.mec.biz.dal.dto.PWorkOrderInfo">
+        <result property="id" column="id"/>
+        <result property="classify" column="classify"/>
+        <result property="isEnd" column="is_end"/>
+        <result property="isDenied" column="is_denied"/>
+        <result property="isCancel" column="is_cancel"/>
+        <result property="creator" column="mec_user_id"/>
+        <result property="process" column="process"/>
+        <result property="title" column="title"/>
+    </resultMap>
+    <select id="getWorkOrderInfo" resultMap="PWorkOrderInfo">
+        SELECT woi.*,su.mec_user_id FROM mec_dev_api.p_work_order_info woi
+        LEFT JOIN mec_dev_api.p_work_order_circulation_history woch ON woi.id = woch.work_order
+        LEFT JOIN mec_dev_api.p_process_info pi ON pi.id = woi.classify
+        LEFT JOIN mec_dev_api.sys_user su ON su.user_id = woi.creator
+        WHERE woi.is_end = 1  AND woi.is_denied = 0  AND woi.is_cancel = 0
+        AND woch.`status` != 0 AND woi.id = #{workOrderId} AND pi.fee_type = 1 LIMIT 1
+    </select>
+    <select id="getFormStructure" resultType="java.lang.String">
+        SELECT form_structure FROM mec_dev_api.p_work_order_tpl_data WHERE work_order = #{workOrderId}
+    </select>
+    <select id="getFormData" resultType="java.lang.String">
+        SELECT form_data FROM mec_dev_api.p_work_order_tpl_data WHERE work_order = #{workOrderId}
+    </select>
+    <select id="getTplInfo" resultType="java.lang.String">
+        SELECT form_structure FROM mec_dev_api.p_tpl_info WHERE id = #{tplInfoId}
+    </select>
 </mapper>

+ 25 - 2
mec-web/src/main/java/com/ym/mec/web/controller/education/OaContractsController.java

@@ -1,25 +1,48 @@
 package com.ym.mec.web.controller.education;
 
 import com.ym.mec.biz.dal.dto.OAFinancialDto;
+import com.ym.mec.biz.dal.dto.ReturnFeeDto;
+import com.ym.mec.biz.dal.entity.FinancialExpenditure;
+import com.ym.mec.biz.dal.entity.MusicGroupQuit;
 import com.ym.mec.biz.service.ContractService;
+import com.ym.mec.biz.service.FinancialExpenditureService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
-@RequestMapping("oaContracts")
+import java.util.List;
+import java.util.Map;
+
+@RequestMapping()
 @Api(tags = "OA签章服务")
 @RestController
 public class OaContractsController extends BaseController {
 
     @Autowired
     private ContractService contractService;
+    @Autowired
+    private FinancialExpenditureService financialExpenditureService;
 
-    @PostMapping("finance")
+    @PostMapping("oaContracts/finance")
     public HttpResponseResult<String> transferProduceContract(@RequestBody OAFinancialDto financialDto) {
         String fileUrl = contractService.transferOaFinancial(financialDto);
         return succeed(fileUrl);
     }
 
+    @PostMapping("oa/syncPayLog")
+    @ApiOperation("同步oa审批到支出记录")
+    public HttpResponseResult syncOaPayLog(Integer workOrderId) {
+        financialExpenditureService.syncOaPayLog(workOrderId);
+        return succeed();
+    }
+
+    @PostMapping("oa/checkCourseReturnFee")
+    @ApiOperation("校验课程退费、乐团退费参数")
+    public HttpResponseResult checkCourseReturnFee(@RequestBody Map<String,String> paramMap) {
+        financialExpenditureService.checkCourseReturnFee(paramMap);
+        return succeed();
+    }
 }