Pārlūkot izejas kodu

OM合同列表获取

fyz 2 nedēļas atpakaļ
vecāks
revīzija
0f3a302969

+ 16 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/controller/DLController.java

@@ -6,6 +6,8 @@ package com.malk.sdzl.controller;
 
 import com.malk.sdzl.entity.AMS.master.*;
 import com.malk.sdzl.entity.OM.ContractPageListResponse;
+import com.malk.sdzl.entity.dto.AmsOmApprovalCallbackRequest;
+import com.malk.sdzl.entity.dto.AmsOmApprovalCallbackResponse;
 import com.malk.sdzl.service.PayService;
 import com.malk.server.common.McException;
 import com.malk.server.common.McR;
@@ -171,4 +173,18 @@ public class DLController {
         String result = payService.approvalCallbackFile(bodyMap);
         return McR.success(result);
     }
+
+    /**
+     * 将宜搭/钉钉 OM 表单审核结果回写到 AMS。
+     * POST /api/sdzl/ams/om/approval/callback
+     */
+    @PostMapping("/callback")
+    public McR callback(@RequestBody AmsOmApprovalCallbackRequest request) {
+        log.info("开始 AMS OM 审核结果回写,colId={}, oaCode={}, processInstanceId={}",
+                request == null ? null : request.getColId(),
+                request == null ? null : request.getOaCode(),
+                request == null ? null : request.getProcessInstanceId());
+        AmsOmApprovalCallbackResponse response = payService.callback(request);
+        return McR.success(response);
+    }
 }

+ 50 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/controller/YqbOptionPushController.java

@@ -0,0 +1,50 @@
+package com.malk.sdzl.controller;
+
+import com.malk.sdzl.entity.dto.YqbApiResponse;
+import com.malk.sdzl.entity.dto.YqbOptionPushRequest;
+import com.malk.sdzl.entity.dto.YqbOptionPushResult;
+import com.malk.sdzl.service.YqbOptionPushService;
+import com.malk.server.common.McR;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+/** 易企报辅助选项推送接口。 */
+@Slf4j
+@RestController
+@RequestMapping("yqb/option")
+public class YqbOptionPushController {
+
+    @Autowired
+    private YqbOptionPushService yqbOptionPushService;
+
+    /**
+     * 单条推送。
+     * POST /api/sdzl/yqb/option/push
+     */
+    @PostMapping("/push")
+    public McR push(@RequestBody YqbOptionPushRequest request) {
+        log.info("开始单条推送易企报辅助选项,categoryCode={}, itemCode={}",
+                request == null ? null : request.getCategoryCode(),
+                request == null ? null : request.getItemCode());
+        YqbApiResponse<Object> result = yqbOptionPushService.pushOne(request);
+        return McR.success(result);
+    }
+
+    /**
+     * Excel 批量推送。
+     * POST /api/sdzl/yqb/option/upload,Content-Type: multipart/form-data,文件字段名:file。
+     */
+    @PostMapping("/upload")
+    public McR upload(@RequestParam("file") MultipartFile file) {
+        log.info("开始上传 Excel 批量推送易企报辅助选项,fileName={}",
+                file == null ? null : file.getOriginalFilename());
+        YqbOptionPushResult result = yqbOptionPushService.pushByExcel(file);
+        return McR.success(result);
+    }
+}

+ 89 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/OM/OmCollectionForm.java

@@ -0,0 +1,89 @@
+package com.malk.sdzl.entity.OM;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.annotation.Nulls;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/** OM收款单表单数据。 */
+@Data
+public class OmCollectionForm implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 所属板块 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String section = "";
+    /** 核算主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountingEntity = "";
+    /** 客户 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String customer = "";
+    /** 入账日期 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String dateOfEntry = "";
+    /** 收款银行 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String collectionBank = "";
+    /** 收款金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String collectionAmount = "";
+    /** 冲销方式 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String eliminationMode = "";
+    /** 经办人 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String operator = "";
+    /** 收入信息 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private List<IncomeInformation> incomeInformation = new ArrayList<>();
+    /** 收入票据合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalRevenueNotes = "";
+    /** 收入类别合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalRevenueCategory = "";
+    /** 转账信息 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private List<TransferInformation> transferInformation = new ArrayList<>();
+    /** 转账票据合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalTransferNotes = "";
+    /** 转账类别合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalTransferCategories = "";
+    /** 应收票据基础信息登记表 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String billsRegistrationForm = "";
+    /** 票据金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String billAmount = "";
+    /** 票据状态 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String billStatus = "";
+    /** 备注 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String remarks = "";
+    /** 收入类会计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String incomeAccounting = "";
+    /** 出纳 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cashier = "";
+    /** 新房OM回款核查 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String omReturnNewHouse = "";
+    /** 与OM差异的原因 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String omDifferenceReasons = "";
+    /** 流程结束日期 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String processEndDate = "";
+    /** 会计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountant = "";
+    /** 二租结算对接人 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String secondRentPerson = "";
+    /** 营销合伙人 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String marketingPartner = "";
+    /** 渠道集团结算 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String channelGroupSettlement = "";
+    /** 科目编码校验 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountCodeVerification = "";
+    /** 核算主体编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountingSubjectCode = "";
+
+    /** 收入信息子表行。 */
+    @Data
+    public static class IncomeInformation implements Serializable {
+        private static final long serialVersionUID = 1L;
+        /** 收入类别 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String revenueCategory = "";
+        /** 科目编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String subjectCode = "";
+        /** 子表科目编码校验 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String subAccountCodeVerification = "";
+        /** 考核主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String incomeSubject = "";
+        /** 考核主体编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String incomeCode = "";
+        /** 项目 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String project = "";
+        /** 项目编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String itemCode = "";
+        /** 成本中心 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String costCenter = "";
+        /** 成本中心编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String costCenterCode = "";
+        /** 金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String amountOfMoney = "";
+        /** 汇票金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String incomeBillAmount = "";
+        /** 说明 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String explain = "";
+        /** 中转科目 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferSubjects = "";
+        /** 中转科目编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferAccountCode = "";
+        /** 收入类型 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String incomeType = "";
+        /** 诉讼进度表 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String proceedingsSchedule = "";
+        /** 诉讼回款 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String litigationRecovery = "";
+        /** CRIC合同编号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricContractNumber = "";
+        /** 原请款单号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String originalRequestNo = "";
+    }
+
+    /** 转账信息子表行。 */
+    @Data
+    public static class TransferInformation implements Serializable {
+        private static final long serialVersionUID = 1L;
+        /** 转账类别 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferCategory = "";
+        /** 转账类别编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferCategoryCode = "";
+        /** 考核主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferAssessment = "";
+        /** 考核主体编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferAssessmentCode = "";
+        /** 项目 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferProject = "";
+        /** 项目编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferProjectCode = "";
+        /** 成本中心 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String projectCostCenter = "";
+        /** 成本中心编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String projectCostCenterCode = "";
+        /** 金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String projectAmount = "";
+        /** 汇票金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String projectBillAmount = "";
+        /** 票据收入类型 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String noteIncomeType = "";
+        /** 说明 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String projectExplain = "";
+    }
+}

+ 39 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/OM/OmContractTerminationApplicationForm.java

@@ -0,0 +1,39 @@
+package com.malk.sdzl.entity.OM;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.annotation.Nulls;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/** OM合同作废终止申请单表单数据。 */
+@Data
+public class OmContractTerminationApplicationForm implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String code = "";
+    /** 所属条线 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String line = "";
+    /** 类型 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String type = "";
+    /** 核算主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountingEntity = "";
+    /** 所属板块 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String section = "";
+    /** 考核主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String assessmentSubject = "";
+    /** 成本中心 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String costCenter = "";
+    /** 日期 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String date = "";
+    /** 原合同编号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String originalContractNo = "";
+    /** 合同名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractName = "";
+    /** 所属部门 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String department = "";
+    /** 经办人 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String operator = "";
+    /** 原盖章日期 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String originalStampDate = "";
+    /** 合同金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String amountOfContract = "";
+    /** 客户名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String customerName = "";
+    /** 合同归类 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractClassification = "";
+    /** 若有项目成本,是否与合同同步作废 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String whetherCanceledContract = "";
+    /** 若有项目成本,已支付金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String amountPaid = "";
+    /** 原因(详细说明) */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String reasondetailedDescription = "";
+    /** 是否重签 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String whetherToResign = "";
+    /** 新合同金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String newContractAmount = "";
+    /** 新合同名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String newContractName = "";
+    /** 附件 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String enclosure = "";
+    /** 备注 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String remarks = "";
+}

+ 47 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/OM/OmIncomeCountersignForm.java

@@ -0,0 +1,47 @@
+package com.malk.sdzl.entity.OM;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.annotation.Nulls;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/** OM收入会签单表单数据。 */
+@Data
+public class OmIncomeCountersignForm implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String code = "";
+    /** 所属条线 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String line = "";
+    /** 申请人 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String applicant = "";
+    /** 日期 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String date = "";
+    /** 所属板块 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String section = "";
+    /** 考核主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String assessmentSubject = "";
+    /** 核算主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountingEntity = "";
+    /** 考核主体编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String assessmentSubjectCode = "";
+    /** 我方签约公司名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String ourContractedCompany = "";
+    /** 申请人所属成本中心 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String costCenterApplicant = "";
+    /** 合同名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractName = "";
+    /** 合同归类 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractClassification = "";
+    /** 标准模板 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String standardTemplate = "";
+    /** 对方单位名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String nameOfTheOppositeUnit = "";
+    /** 客户类型 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String customerType = "";
+    /** 隶属集团 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String affiliationGroup = "";
+    /** 合同类型 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractType = "";
+    /** 是否为续约客户 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String isItARenewalCustomer = "";
+    /** EBS对方单位名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String ebsOppositeUnitName = "";
+    /** EBS对方客户编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String ebsCustomerCode = "";
+    /** 合同所属部门 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractDepartment = "";
+    /** 经办人 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String operator = "";
+    /** 合同总金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalContractAmount = "";
+    /** 协办金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String coassistanceAmount = "";
+    /** 文件附件 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String annexToTheDocument = "";
+    /** 数据成本测算表附件 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String dataCostAnnex = "";
+    /** 克而瑞大客户签约协办确认单 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String customersSignedContract = "";
+    /** 备注 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String remarks = "";
+    /** 我方盖章日期 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String ourStamp = "";
+    /** 盖章状态 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String stampStatus = "";
+    /** 盖章合同扫描 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String sealContractScan = "";
+    /** 合同编号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractNo = "";
+}

+ 98 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/OM/OmInvoiceApplicationForm.java

@@ -0,0 +1,98 @@
+package com.malk.sdzl.entity.OM;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.annotation.Nulls;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/** OM开票申请单表单数据。 */
+@Data
+public class OmInvoiceApplicationForm implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** OA编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String oaCoding = "";
+    /** 所属板块 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String section = "";
+    /** 核算主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountingEntity = "";
+    /** 考核主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String assessmentSubject = "";
+    /** 项目 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String project = "";
+    /** 成本中心 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String costCenter = "";
+    /** 经办人 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String operator = "";
+    /** 客户全称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String fullNameOfCustomer = "";
+    /** 入账日期 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String dateOfEntry = "";
+    /** 税务登记联系电话 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxRegistrationPhone = "";
+    /** 税务登记号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxRegistrationNumber = "";
+    /** 税务登记地址 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxRegistrationAddress = "";
+    /** 税务开户银行名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String nameOfTaxBank = "";
+    /** 税务开户银行账号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxAccountBankAccount = "";
+    /** 开票类型 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String invoicingType = "";
+    /** 税费类型 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxType = "";
+    /** 合同名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractName = "";
+    /** 合同编号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String contractNo = "";
+    /** CRIC合同名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricContractName = "";
+    /** CRIC合同编号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricContractNumber = "";
+    /** CRIC合同客户名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricContractcustomerName = "";
+    /** CRIC合同归属地 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricContracthome = "";
+    /** CRIC合同金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricContractAmount = "";
+    /** CRIC开票内容 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricBillingContent = "";
+    /** CRIC开票内容(旧) */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricInvoicingContentold = "";
+    /** CRIC合同明细 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private List<CricDetail> cric = new ArrayList<>();
+    /** 本次开票金额合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalAmountInvoicing = "";
+    /** 票据信息 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private List<BillInformation> billInformation = new ArrayList<>();
+    /** 含税开票金额合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalAmountIncludTax = "";
+    /** 金额(不含税)合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalAmountExcludingTax = "";
+    /** 税额合计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String totalTaxAmount = "";
+    /** 发票备注 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String invoiceRemarks = "";
+    /** 发票编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String invoiceCode = "";
+    /** 取票人签字 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String signatureOfTicketMan = "";
+    /** 电子发票收件手机 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String eInvoiceReceiptMobile = "";
+    /** 电子发票收件邮箱 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String eInvoiceReceiptMailbox = "";
+    /** 全电发票交付方式 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String allpowerDeliveryMethod = "";
+    /** 全电发票收件邮箱 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String allpowerReceiveMailbox = "";
+    /** 收入类会计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String incomeAccounting = "";
+    /** 出纳 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cashier = "";
+    /** 渠道集团结算 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String channelGroupSettlement = "";
+    /** 会计 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String accountant = "";
+    /** 备注 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String remarks = "";
+
+    /** CRIC 合同明细子表行。 */
+    @Data
+    public static class CricDetail implements Serializable {
+        private static final long serialVersionUID = 1L;
+        /** CRIC合同编号 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricContractNo = "";
+        /** CRIC产品名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricProductName = "";
+        /** CRIC子项目名称 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricSubprojectName = "";
+        /** CRIC执行金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricExecutionAmount = "";
+        /** CRIC已开票金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricInvoicedAmount = "";
+        /** CRIC已到账金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String amountReceivedByCric = "";
+        /** CRIC未开票金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricUninvoicedAmount = "";
+        /** CRIC本次开票金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String cricThisInvoicingAmount = "";
+    }
+
+    /** 票据信息子表行。 */
+    @Data
+    public static class BillInformation implements Serializable {
+        private static final long serialVersionUID = 1L;
+        /** 收入类别 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String revenueCategory = "";
+        /** 收入类别编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String revenueCategoryCode = "";
+        /** 考核主体 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String billAssessmentSubject = "";
+        /** 考核主体编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String billAssessmentSubjectCode = "";
+        /** 项目 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String billProject = "";
+        /** 项目编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String itemCode = "";
+        /** 成本中心 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String billCostCenter = "";
+        /** 成本中心编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String costCenterCode = "";
+        /** 含税开票金额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String invoicingAmountIncludTax = "";
+        /** 税率 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxRate = "";
+        /** 金额(不含税) */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String amountexcludingTax = "";
+        /** 税额 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxAmount = "";
+        /** 税额调整项 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String taxAdjustment = "";
+        /** 内部结算 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String internalSettlement = "";
+        /** 借方科目 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String debitAccount = "";
+        /** 借方科目编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String debitAccountCode = "";
+        /** 中转科目 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferSubjects = "";
+        /** 中转科目编码 */ @JsonSetter(nulls = Nulls.AS_EMPTY) private String transferAccountCode = "";
+    }
+}

+ 21 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/dto/YqbApiResponse.java

@@ -0,0 +1,21 @@
+package com.malk.sdzl.entity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/** 易企报开放接口通用响应实体。1xx 表示调用成功。 */
+@Data
+public class YqbApiResponse<T> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String apiName;
+    private Integer result;
+    private String message;
+    private T data;
+
+    public boolean isSuccess() {
+        return result != null && result >= 100 && result < 200;
+    }
+}

+ 67 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/dto/YqbOptionExcelRow.java

@@ -0,0 +1,67 @@
+package com.malk.sdzl.entity.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Excel 上传模板行。
+ * roles、departments、users 可填写可选的 JSON 数组;其余字段与开放接口一致。
+ */
+@Data
+public class YqbOptionExcelRow implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ExcelProperty("原辅助选项编码")
+    private String oldItemCode;
+    @ExcelProperty("辅助类别编码")
+    private String categoryCode;
+    @ExcelProperty("父选项编码")
+    private String parentCode;
+    @ExcelProperty("选项编码")
+    private String itemCode;
+    @ExcelProperty("选项名称")
+    private String itemName;
+    @ExcelProperty("全部可见")
+    private Boolean fullVisible;
+    @ExcelProperty("角色可见范围JSON")
+    private String roles;
+    @ExcelProperty("部门可见范围JSON")
+    private String departments;
+    @ExcelProperty("员工可见范围JSON")
+    private String users;
+    @ExcelProperty("收款账号ID")
+    private String payAccountIds;
+    @ExcelProperty("发票抬头ID")
+    private String invoiceTitleIds;
+    @ExcelProperty("关联辅助核算编码")
+    private String auxiliaryCodes;
+
+    public YqbOptionPushRequest toRequest() {
+        YqbOptionPushRequest request = new YqbOptionPushRequest();
+        request.setOldItemCode(oldItemCode);
+        request.setCategoryCode(categoryCode);
+        request.setParentCode(parentCode);
+        request.setItemCode(itemCode);
+        request.setItemName(itemName);
+        request.setPayAccountIds(payAccountIds);
+        request.setInvoiceTitleIds(invoiceTitleIds);
+        request.setAuxiliaryCodes(auxiliaryCodes);
+
+        if (fullVisible != null || hasText(roles) || hasText(departments) || hasText(users)) {
+            YqbOptionPushRequest.VisibleScope visibleScope = new YqbOptionPushRequest.VisibleScope();
+            visibleScope.setIsFullVisible(fullVisible);
+            visibleScope.setRoles(YqbOptionPushRequest.parseScopeEntities(roles));
+            visibleScope.setDepartments(YqbOptionPushRequest.parseScopeEntities(departments));
+            visibleScope.setUsers(YqbOptionPushRequest.parseScopeEntities(users));
+            request.setVisibleScope(visibleScope);
+        }
+        return request;
+    }
+
+    private boolean hasText(String value) {
+        return value != null && !value.trim().isEmpty();
+    }
+}

+ 95 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/dto/YqbOptionPushRequest.java

@@ -0,0 +1,95 @@
+package com.malk.sdzl.entity.dto;
+
+import com.alibaba.fastjson.JSON;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 易企报“新增选项”接口请求实体。
+ */
+@Data
+public class YqbOptionPushRequest implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 原辅助选项编码,可为空。 */
+    private String oldItemCode;
+    /** 辅助类别编码,必填。 */
+    private String categoryCode;
+    /** 父选项编码,可为空;为空时新增一级选项。 */
+    private String parentCode;
+    /** 选项编码,必填。 */
+    private String itemCode;
+    /** 选项名称,必填。 */
+    private String itemName;
+    /** 可见范围配置,可为空。 */
+    private VisibleScope visibleScope;
+    /** 收款账号 cardId,多个以英文逗号分隔。 */
+    private String payAccountIds;
+    /** 发票抬头 ID,多个以英文逗号分隔。 */
+    private String invoiceTitleIds;
+    /** 关联的辅助核算编码,多个以英文逗号分隔。 */
+    private String auxiliaryCodes;
+
+    public Map<String, Object> toRequestBody() {
+        Map<String, Object> body = new LinkedHashMap<>();
+        putIfNotBlank(body, "oldItemCode", oldItemCode);
+        putIfNotBlank(body, "categoryCode", categoryCode);
+        putIfNotBlank(body, "parentCode", parentCode);
+        putIfNotBlank(body, "itemCode", itemCode);
+        putIfNotBlank(body, "itemName", itemName);
+        if (visibleScope != null && visibleScope.hasValue()) {
+            body.put("visibleScope", visibleScope);
+        }
+        putIfNotBlank(body, "payAccountIds", payAccountIds);
+        putIfNotBlank(body, "invoiceTitleIds", invoiceTitleIds);
+        putIfNotBlank(body, "auxiliaryCodes", auxiliaryCodes);
+        return body;
+    }
+
+    private void putIfNotBlank(Map<String, Object> body, String key, String value) {
+        if (value != null && !value.trim().isEmpty()) {
+            body.put(key, value.trim());
+        }
+    }
+
+    @Data
+    public static class VisibleScope implements Serializable {
+        private static final long serialVersionUID = 1L;
+        private Boolean isFullVisible;
+        private List<ScopeEntity> roles = new ArrayList<>();
+        private List<ScopeEntity> departments = new ArrayList<>();
+        private List<ScopeEntity> users = new ArrayList<>();
+
+        public boolean hasValue() {
+            return isFullVisible != null
+                    || (roles != null && !roles.isEmpty())
+                    || (departments != null && !departments.isEmpty())
+                    || (users != null && !users.isEmpty());
+        }
+    }
+
+    @Data
+    public static class ScopeEntity implements Serializable {
+        private static final long serialVersionUID = 1L;
+        private String id;
+        private String name;
+        private String form;
+    }
+
+    /**
+     * Excel 中 roles、departments、users 列可填写 JSON 数组,例如:
+     * [{"id":"1","name":"财务","form":"dept"}]
+     */
+    public static List<ScopeEntity> parseScopeEntities(String json) {
+        if (json == null || json.trim().isEmpty()) {
+            return new ArrayList<>();
+        }
+        return JSON.parseArray(json, ScopeEntity.class);
+    }
+}

+ 30 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/entity/dto/YqbOptionPushResult.java

@@ -0,0 +1,30 @@
+package com.malk.sdzl.entity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/** 单条/Excel 批量推送结果。 */
+@Data
+public class YqbOptionPushResult implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private int total;
+    private int successCount;
+    private int failCount;
+    private List<ItemResult> details = new ArrayList<>();
+
+    @Data
+    public static class ItemResult implements Serializable {
+        private static final long serialVersionUID = 1L;
+        private Integer rowNumber;
+        private String itemCode;
+        private String itemName;
+        private boolean success;
+        private Integer result;
+        private String message;
+    }
+}

+ 1 - 1
mjava-sdzl/src/main/java/com/malk/sdzl/service/Impl/DingTalkOaServiceImpl.java

@@ -86,7 +86,7 @@ public class DingTalkOaServiceImpl implements DingTalkOaService {
     @Value("${dingtalk.http-timeout:30000}")
     private int httpTimeout;
 
-    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
     private static final Map<String, String> ATTACHMENT_TYPE = new HashMap<>();
 

+ 28 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/service/Impl/PayServiceImpl.java

@@ -18,6 +18,8 @@ import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
 import com.malk.sdzl.entity.Attachment;
 import com.malk.sdzl.entity.OM.ContractPageListResponse;
+import com.malk.sdzl.entity.dto.AmsOmApprovalCallbackRequest;
+import com.malk.sdzl.entity.dto.AmsOmApprovalCallbackResponse;
 import com.malk.sdzl.service.PayService;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
@@ -1365,6 +1367,32 @@ public class PayServiceImpl implements PayService {
         return tempFile;
     }
 
+    private static final String CALLBACK_PATH = "/api/approval/om/save";
+
+    @Override
+    public AmsOmApprovalCallbackResponse callback(AmsOmApprovalCallbackRequest request) {
+
+        String requestUrl = sdzlUrl + CALLBACK_PATH;
+
+        String authorization = getAuthorization();
+
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json;charset=UTF-8");
+        headers.put("Authorization", authorization);
+
+        String responseBody = UtilHttp.doPost(requestUrl, headers, null, request.toRequestBody());
+        AmsOmApprovalCallbackResponse response = JSON.parseObject(responseBody,
+                AmsOmApprovalCallbackResponse.class);
+        if (response == null) {
+            throw new IllegalStateException("AMS OM 审核回写接口返回为空");
+        }
+        if (!response.isSuccess()) {
+            log.warn("AMS OM 审核回写失败,colId={}, status={}, error={}",
+                    request.getColId(), response.getStatus(), response.getError());
+        }
+        return response;
+    }
+
     /**
      * 密钥算法
      */

+ 192 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/service/Impl/YqbOptionPushServiceImpl.java

@@ -0,0 +1,192 @@
+package com.malk.sdzl.service.Impl;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.sdzl.entity.dto.YqbApiResponse;
+import com.malk.sdzl.entity.dto.YqbOptionExcelRow;
+import com.malk.sdzl.entity.dto.YqbOptionPushRequest;
+import com.malk.sdzl.entity.dto.YqbOptionPushResult;
+import com.malk.sdzl.service.YqbOptionPushService;
+import com.malk.utils.UtilHttp;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** 易企报辅助选项推送服务。 */
+@Slf4j
+@Service
+public class YqbOptionPushServiceImpl implements YqbOptionPushService {
+
+    private static final String TOKEN_PATH = "/auth/getAccessToken.rjson";
+    private static final String ADD_OPTION_PATH = "/reimburse/auxiliary/v2/item/add.rjson";
+    private static final int TOKEN_EXPIRE_MINUTES = 120;
+    private static final int TOKEN_REFRESH_AHEAD_MINUTES = 30;
+
+    private final Object tokenLock = new Object();
+    private volatile String accessToken;
+    private volatile LocalDateTime accessTokenExpireAt;
+
+    @Value("${yqb.base-url}")
+    private String baseUrl;
+    @Value("${yqb.app-key}")
+    private String appKey;
+    @Value("${yqb.app-secret}")
+    private String appSecret;
+
+    @Override
+    public YqbApiResponse<Object> pushOne(YqbOptionPushRequest request) {
+        validateRequest(request);
+
+        String token = getAccessToken();
+        String requestUrl = trimRightSlash(baseUrl) + ADD_OPTION_PATH
+                + "?appKey=" + appKey + "&accessToken=" + token;
+
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json;charset=UTF-8");
+
+        String responseBody = UtilHttp.doPost(requestUrl, headers, null, request.toRequestBody());
+        YqbApiResponse<Object> response = JSON.parseObject(responseBody, YqbApiResponse.class);
+        if (response == null) {
+            throw new IllegalStateException("易企报新增选项接口返回为空");
+        }
+        return response;
+    }
+
+    @Override
+    public YqbOptionPushResult pushByExcel(MultipartFile file) {
+        if (file == null || file.isEmpty()) {
+            throw new IllegalArgumentException("上传文件不能为空");
+        }
+        String fileName = file.getOriginalFilename();
+        if (fileName == null || (!fileName.toLowerCase().endsWith(".xlsx")
+                && !fileName.toLowerCase().endsWith(".xls"))) {
+            throw new IllegalArgumentException("仅支持 .xlsx 或 .xls 格式的 Excel 文件");
+        }
+
+        List<YqbOptionExcelRow> rows;
+        try {
+            rows = EasyExcel.read(file.getInputStream())
+                    .head(YqbOptionExcelRow.class)
+                    .sheet()
+                    .doReadSync();
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Excel 文件读取失败:" + e.getMessage(), e);
+        }
+
+        YqbOptionPushResult result = new YqbOptionPushResult();
+        result.setTotal(rows.size());
+
+        for (int i = 0; i < rows.size(); i++) {
+            YqbOptionExcelRow row = rows.get(i);
+            YqbOptionPushResult.ItemResult itemResult = new YqbOptionPushResult.ItemResult();
+            itemResult.setRowNumber(i + 2);
+            itemResult.setItemCode(row.getItemCode());
+            itemResult.setItemName(row.getItemName());
+
+            try {
+                YqbApiResponse<Object> pushResponse = pushOne(row.toRequest());
+                itemResult.setSuccess(pushResponse.isSuccess());
+                itemResult.setResult(pushResponse.getResult());
+                itemResult.setMessage(pushResponse.getMessage());
+                if (pushResponse.isSuccess()) {
+                    result.setSuccessCount(result.getSuccessCount() + 1);
+                } else {
+                    result.setFailCount(result.getFailCount() + 1);
+                }
+            } catch (Exception e) {
+                log.error("第{}行推送辅助选项失败,itemCode={}", i + 2, row.getItemCode(), e);
+                itemResult.setSuccess(false);
+                itemResult.setMessage(e.getMessage());
+                result.setFailCount(result.getFailCount() + 1);
+            }
+            result.getDetails().add(itemResult);
+        }
+        return result;
+    }
+
+    /**
+     * token 有效期 2 小时;剩余不足 30 分钟时重新获取。
+     * 双重检查与同步锁避免并发请求同时刷新 token。
+     */
+    private String getAccessToken() {
+        if (isTokenUsable()) {
+            return accessToken;
+        }
+        synchronized (tokenLock) {
+            if (isTokenUsable()) {
+                return accessToken;
+            }
+            return refreshAccessToken();
+        }
+    }
+
+    private boolean isTokenUsable() {
+        return accessToken != null
+                && accessTokenExpireAt != null
+                && LocalDateTime.now().plusMinutes(TOKEN_REFRESH_AHEAD_MINUTES).isBefore(accessTokenExpireAt);
+    }
+
+    private String refreshAccessToken() {
+        String requestUrl = trimRightSlash(baseUrl) + TOKEN_PATH;
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json;charset=UTF-8");
+
+        Map<String, Object> requestBody = new HashMap<>();
+        requestBody.put("appKey", appKey);
+        requestBody.put("appSecret", appSecret);
+
+        String responseBody = UtilHttp.doPost(requestUrl, headers, null, requestBody);
+        JSONObject jsonObject = JSON.parseObject(responseBody);
+        Integer result = jsonObject == null ? null : jsonObject.getInteger("result");
+        String token = jsonObject == null || jsonObject.getJSONObject("data") == null
+                ? null : jsonObject.getJSONObject("data").getString("accessToken");
+
+        if (result == null || result < 100 || result >= 200 || token == null || token.trim().isEmpty()) {
+            String message = jsonObject == null ? responseBody : jsonObject.getString("message");
+            throw new IllegalStateException("获取易企报 accessToken 失败:" + message);
+        }
+
+        accessToken = token;
+        accessTokenExpireAt = LocalDateTime.now().plusMinutes(TOKEN_EXPIRE_MINUTES);
+        log.info("易企报 accessToken 已刷新,过期时间:{}", accessTokenExpireAt);
+        return accessToken;
+    }
+
+    private void validateRequest(YqbOptionPushRequest request) {
+        if (request == null) {
+            throw new IllegalArgumentException("请求参数不能为空");
+        }
+        if (isBlank(request.getCategoryCode())) {
+            throw new IllegalArgumentException("categoryCode不能为空");
+        }
+        if (isBlank(request.getItemCode())) {
+            throw new IllegalArgumentException("itemCode不能为空");
+        }
+        if (isBlank(request.getItemName())) {
+            throw new IllegalArgumentException("itemName不能为空");
+        }
+    }
+
+    private boolean isBlank(String value) {
+        return value == null || value.trim().isEmpty();
+    }
+
+    private String trimRightSlash(String url) {
+        if (url == null || url.trim().isEmpty()) {
+            throw new IllegalArgumentException("yqb.base-url 未配置");
+        }
+        String result = url.trim();
+        while (result.endsWith("/")) {
+            result = result.substring(0, result.length() - 1);
+        }
+        return result;
+    }
+}

+ 4 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/service/PayService.java

@@ -2,6 +2,8 @@ package com.malk.sdzl.service;
 
 import com.malk.sdzl.entity.AMS.master.*;
 import com.malk.sdzl.entity.OM.ContractPageListResponse;
+import com.malk.sdzl.entity.dto.AmsOmApprovalCallbackRequest;
+import com.malk.sdzl.entity.dto.AmsOmApprovalCallbackResponse;
 
 import java.util.Map;
 
@@ -91,4 +93,6 @@ public interface PayService {
      * @return
      */
     String approvalCallbackFile(Map bodyMap);
+
+    AmsOmApprovalCallbackResponse callback(AmsOmApprovalCallbackRequest request);
 }

+ 15 - 0
mjava-sdzl/src/main/java/com/malk/sdzl/service/YqbOptionPushService.java

@@ -0,0 +1,15 @@
+package com.malk.sdzl.service;
+
+import com.malk.sdzl.entity.dto.YqbApiResponse;
+import com.malk.sdzl.entity.dto.YqbOptionPushRequest;
+import com.malk.sdzl.entity.dto.YqbOptionPushResult;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface YqbOptionPushService {
+
+    /** 推送一条辅助选项。 */
+    YqbApiResponse<Object> pushOne(YqbOptionPushRequest request);
+
+    /** 上传 Excel 后按行循环推送辅助选项。 */
+    YqbOptionPushResult pushByExcel(MultipartFile file);
+}

+ 6 - 0
mjava-sdzl/src/main/resources/application-dev.yml

@@ -55,6 +55,12 @@ dingtalk:
 sdzl:
   url: http://test.inapi.cric.com
 
+# 易企报开放接口(测试环境)。请通过环境变量配置 appKey / appSecret,避免将密钥提交到代码仓库。
+yqb:
+  base-url: https://yiqbdatatest.superboss.cc
+  app-key: api14c94686e41b1a44f5bf40eda33b7ba0
+  app-secret: c92210d2d399c48b26196ede76cc5529
+
 # aliwork
 aliwork:
   appType: "APP_YYYEKIZY2HIWCG1NZZDY"

+ 6 - 0
mjava-sdzl/src/main/resources/application-prod.yml

@@ -57,6 +57,12 @@ sdzl:
 #  url: http://inapi.cric.com
   url: http://test.inapi.cric.com
 
+# 易企报开放接口(生产环境)。请通过环境变量配置 appKey / appSecret,避免将密钥提交到代码仓库。
+yqb:
+  base-url: https://yiqbdata.superboss.cc
+  app-key: ${YQB_APP_KEY:}
+  app-secret: ${YQB_APP_SECRET:}
+
 # aliwork
 aliwork:
   appType: "APP_YYYEKIZY2HIWCG1NZZDY"