4 Commits 22127a9e19 ... 2cb8a1b21d

Author SHA1 Message Date
  liyuan 2cb8a1b21d 更改超期箱使费的计算顺序 2 months ago
  liyuan 46bd2d87ac Merge remote-tracking branch 'origin/dev' into dev 2 months ago
  liyuan cc7fddaa2c 迁移客户拜访相关、客户详情接口增加拜访相关数据 2 months ago
  liyuan eefca10ab7 vgm调用相关 2 months ago
24 changed files with 1015 additions and 43 deletions
  1. 19 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/KeyValueVo.java
  2. 98 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/VgmDeclaration.java
  3. 17 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/VgmDeclarationSend.java
  4. 35 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/VgmParamVo.java
  5. 18 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/dto/CorpsVisitDTO.java
  6. 116 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/entity/CorpsVisit.java
  7. 7 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/entity/PjCorpsDesc.java
  8. 20 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/vo/CorpsVisitVO.java
  9. 18 0
      blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/vo/CustomerTypeKeyValueVo.java
  10. 6 6
      blade-service/blade-los/src/main/java/org/springblade/los/Util/OwBoxUsageFeeUtils.java
  11. 79 0
      blade-service/blade-los/src/main/java/org/springblade/los/Util/VgmUtils.java
  12. 1 0
      blade-service/blade-los/src/main/java/org/springblade/los/box/mapper/PutBoxMapper.xml
  13. 80 0
      blade-service/blade-los/src/main/java/org/springblade/los/enums/VgmOperationType.java
  14. 34 0
      blade-service/blade-los/src/main/java/org/springblade/los/vgm/controller/VgmController.java
  15. 20 0
      blade-service/blade-los/src/main/java/org/springblade/los/vgm/service/IVgmService.java
  16. 81 0
      blade-service/blade-los/src/main/java/org/springblade/los/vgm/service/impl/VgmServiceImpl.java
  17. 138 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/controller/CorpsVisitController.java
  18. 8 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsTypeDescMapper.java
  19. 13 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsTypeDescMapper.xml
  20. 43 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsVisitMapper.java
  21. 30 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsVisitMapper.xml
  22. 43 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/service/ICorpsVisitService.java
  23. 23 37
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/service/impl/CorpsDescServiceImpl.java
  24. 68 0
      blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/service/impl/CorpsVisitServiceImpl.java

+ 19 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/KeyValueVo.java

@@ -0,0 +1,19 @@
+package org.springblade.los.vgm;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Rain
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class KeyValueVo {
+
+	private String key;
+
+	private Object value;
+
+}

+ 98 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/VgmDeclaration.java

@@ -0,0 +1,98 @@
+package org.springblade.los.vgm;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * VGM申报
+ * @author Rain
+ */
+@Data
+public class VgmDeclaration implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 港区代码 (QWG003/QDDG008)
+	 */
+	private String port;
+
+	/**
+	 * 箱号
+	 */
+	private String xh;
+
+	/**
+	 * 尺寸
+	 */
+	private String cc;
+
+	/**
+	 * 箱型
+	 */
+	private String xx;
+
+	/**
+	 * 订舱公司代码
+	 */
+	private String xsgsm;
+
+	/**
+	 * 码头代码
+	 */
+	private String mtdm;
+
+	/**
+	 * 场站代码
+	 */
+	private String czdm;
+
+	/**
+	 * 申报人
+	 */
+	private String applyPerson;
+
+	/**
+	 * 申报人手机号码
+	 */
+	private String applyPhone;
+
+	/**
+	 * VGM重量
+	 */
+	private String weight;
+
+	/**
+	 * 重量单位 (默认kgs)
+	 */
+	private String weightUnit;
+
+	/**
+	 * 用户名
+	 */
+	private String userName;
+
+	/**
+	 * 联系人
+	 */
+	private String linkMan;
+
+	/**
+	 * 联系电话
+	 */
+	private String linkPhone;
+
+	/**
+	 * 联系邮箱
+	 */
+	private String linkMail;
+
+	/**
+	 * 称重方式 (SM1/SM2)
+	 */
+	private String weightMethod;
+
+	/**
+	 * 船公司订舱号
+	 */
+	private String bookingNo;
+}

+ 17 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/VgmDeclarationSend.java

@@ -0,0 +1,17 @@
+package org.springblade.los.vgm;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Rain
+ */
+@Data
+public class VgmDeclarationSend {
+
+	private String tdh;
+
+	private List<VgmDeclaration> data;
+
+}

+ 35 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/vgm/VgmParamVo.java

@@ -0,0 +1,35 @@
+package org.springblade.los.vgm;
+
+import lombok.Data;
+
+/**
+ * @author Rain
+ */
+@Data
+public class VgmParamVo {
+
+	/**
+	 * 签名
+	 */
+	private String sign;
+
+	/**
+	 * 客户代码
+	 */
+	private String customerCode;
+
+	/**
+	 * 接口类型
+	 */
+	private String type;
+
+	/**
+	 * 数据
+	 */
+	private String data;
+
+
+
+
+
+}

+ 18 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/dto/CorpsVisitDTO.java

@@ -0,0 +1,18 @@
+package org.springblade.salesPart.dto;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.salesPart.entity.CorpsVisit;
+
+/**
+ * 客户拜访表数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2025-02-24
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CorpsVisitDTO extends CorpsVisit {
+	private static final long serialVersionUID = 1L;
+
+}

+ 116 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/entity/CorpsVisit.java

@@ -0,0 +1,116 @@
+package org.springblade.salesPart.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.core.secure.utils.AuthUtil;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 客户拜访表实体类
+ *
+ * @author BladeX
+ * @since 2025-02-24
+ */
+@Data
+@TableName("pjpf_corps_visit")
+@ApiModel(value = "CorpsVisit对象", description = "客户拜访表")
+public class CorpsVisit implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private Long id;
+	/**
+	 * 创建人
+	 */
+	@ApiModelProperty(value = "创建人")
+	private Long createUser;
+	/**
+	 * 创建时间
+	 */
+	@ApiModelProperty(value = "创建时间")
+	private Date createTime;
+	/**
+	 * 修改人
+	 */
+	@ApiModelProperty(value = "修改人")
+	private Long updateUser;
+	/**
+	 * 修改时间
+	 */
+	@ApiModelProperty(value = "修改时间")
+	private Date updateTime;
+	/**
+	 * 是否已删除(0 否 1是)
+	 */
+	@ApiModelProperty(value = "是否已删除(0 否 1是)")
+	private Integer isDeleted;
+	/**
+	 * 租户id
+	 */
+	@ApiModelProperty(value = "租户id")
+	private String tenantId = AuthUtil.getTenantId();
+	/**
+	 * 备注
+	 */
+	@ApiModelProperty(value = "备注")
+	private String remarks;
+	/**
+	 * 内容
+	 */
+	@ApiModelProperty(value = "内容")
+	private String content;
+	/**
+	 * 拜访日期
+	 */
+	@ApiModelProperty(value = "拜访日期")
+	private Date visitDate;
+	/**
+	 * 拜访人
+	 */
+	@ApiModelProperty(value = "拜访人")
+	private Long visitPeopleId;
+	/**
+	 * 拜访人
+	 */
+	@ApiModelProperty(value = "拜访人")
+	private String visitPeopleName;
+	/**
+	 * 拜访客户
+	 */
+	@ApiModelProperty(value = "拜访客户")
+	private Long customerId;
+	/**
+	 * 拜访客户
+	 */
+	@ApiModelProperty(value = "拜访客户")
+	private String customerName;
+	/**
+	 * 经度
+	 */
+	@ApiModelProperty(value = "经度")
+	private String longitude;
+	/**
+	 * 维度
+	 */
+	@ApiModelProperty(value = "维度")
+	private String dimension;
+	/**
+	 * 地址
+	 */
+	@ApiModelProperty(value = "地址")
+	private String address;
+
+	/**
+	 * 拜访日期
+	 */
+	@TableField(exist = false)
+	private List<String> visitDateList;
+
+
+}

+ 7 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/entity/PjCorpsDesc.java

@@ -339,4 +339,11 @@ public class PjCorpsDesc implements Serializable {
 	@TableField(exist = false)
 	private List<String> createTimeList;
 
+
+	/**
+	 * 客户拜访记录
+	 */
+	@TableField(exist = false)
+	List<CorpsVisit> corpsVisitList;
+
 }

+ 20 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/vo/CorpsVisitVO.java

@@ -0,0 +1,20 @@
+package org.springblade.salesPart.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.salesPart.entity.CorpsVisit;
+
+/**
+ * 客户拜访表视图实体类
+ *
+ * @author BladeX
+ * @since 2025-02-24
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "CorpsVisitVO对象", description = "客户拜访表")
+public class CorpsVisitVO extends CorpsVisit {
+	private static final long serialVersionUID = 1L;
+
+}

+ 18 - 0
blade-service-api/blade-sales-part-api/src/main/java/org/springblade/salesPart/vo/CustomerTypeKeyValueVo.java

@@ -0,0 +1,18 @@
+package org.springblade.salesPart.vo;
+
+import lombok.Data;
+
+/**
+ * @author Rain
+ */
+@Data
+public class CustomerTypeKeyValueVo {
+
+
+	private Long id;
+
+
+	private String cname;
+
+
+}

+ 6 - 6
blade-service/blade-los/src/main/java/org/springblade/los/Util/OwBoxUsageFeeUtils.java

@@ -406,9 +406,9 @@ public class OwBoxUsageFeeUtils {
 						failureHandling("3", boxDynamicsRecord, "请先维护基础资料-超期标准");
 						return false;
 					}
-					LocalDateTime ldt1 = bills.getActualEtd().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
-					LocalDateTime ldt2 = polPickUpDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
-					int overdueDays = (int) ChronoUnit.DAYS.between(ldt1, ldt2);
+					LocalDateTime atd = bills.getActualEtd().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+					LocalDateTime polPickUpDateDateTime = polPickUpDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+					int overdueDays = (int) ChronoUnit.DAYS.between(polPickUpDateDateTime, atd);
 					//超期天数
 					if (overdueDays > 0) {
 						FeeCenter feeCenter = this.addFeeCenter(item, bills, fees, storageFeesItems, curExrateList, overdueDays, exrateType, "1");
@@ -1040,9 +1040,9 @@ public class OwBoxUsageFeeUtils {
 					failureHandling("3", boxDynamicsRecord, "请先维护基础资料-超期标准");
 					return false;
 				}
-				LocalDateTime ldt1 = item.getPodEmptyContainerReturnDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
-				LocalDateTime ldt2 = billsHYJK.getActualEta().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
-				int overdueDays = (int) ChronoUnit.DAYS.between(ldt2, ldt1);
+				LocalDateTime podEmptyContainerReturnDate = item.getPodEmptyContainerReturnDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+				LocalDateTime actualEta = billsHYJK.getActualEta().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+				int overdueDays = (int) ChronoUnit.DAYS.between(podEmptyContainerReturnDate, actualEta);
 				//超期天数
 				if (overdueDays > 0) {
 					FeeCenter feeCenter = this.addFeeCenter(item, billsHYJK, fees, storageFeesItems, curExrateList, overdueDays, exrateType, "2");

+ 79 - 0
blade-service/blade-los/src/main/java/org/springblade/los/Util/VgmUtils.java

@@ -0,0 +1,79 @@
+package org.springblade.los.Util;
+
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.asymmetric.Sign;
+import cn.hutool.crypto.asymmetric.SignAlgorithm;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.apache.poi.ss.formula.functions.T;
+import org.springblade.common.constant.Constants;
+import org.springblade.los.enums.VgmOperationType;
+import org.springblade.los.vgm.KeyValueVo;
+import org.springblade.los.vgm.VgmParamVo;
+import org.springframework.util.CollectionUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Rain
+ */
+@Slf4j
+public class VgmUtils {
+
+
+	public static <T> String sendVgmToPlatform(T paramData, VgmOperationType operationType) throws IllegalAccessException, UnsupportedEncodingException {
+		if (Objects.isNull(paramData)) {
+			return "参数不能为空";
+		}
+		String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOTLGHGBjmyJp52KpMX783eY+qGZ6ApFek+tsVEUPMIcstzE2mk7gM0l1I5+SV+ramDWfcmHEu1OZnQXNfocxMgoVFhcbvYZksfJFJWwwRg2qPwQ6+txLoBih4d+IpoMj0Rlv8OlEsvCboQcBaZyfrddjoYN5TlTIsZB/062pqt1AgMBAAECgYBV13GjXLWgOYGfFV6/PcnabJZUvZcXC3xZmtS1k/874WKmfGFqLD4mOnRmxjEnaPwvuypUy44pZUoBcpf48IRP0z7UpBnjeNNYdRw7+ihhExP9VccGKoSesf9CfpcKhI+taJBmlXS18lV+O0itWCy6KTJ6tkm3w6rI1dqLA9WAvQJBAPsblMHJn58AuVETKC/+EfAUDi655nVQXY4rXMTZCFviVTucpMc8aET5qeHSoFYxN4DfSRfKD7FafKyioFzgkO8CQQDpQDg7CN94yB5kojTUuV72r5PXApOPHW8Fuu8/E1tpFhurd3MNfHvssfMcwevARHAxrLA3HouzecLgkXziIkHbAkAT29+M3+Q2z/jX95rjCMXkZcGlYmBegMeVWcqRatSlZ6Xz+/RwKU/ZvKD50g2KI4RPNdly/zD0hsJ7aLUkA0KTAkBY6L7GWfJ84qMbLu0+bM5y76hF29iNQ+Xu5DuP6nv8iY3QhT6Y1GuUZJxLyOtpJW0ysiWVTRJpPi93VF2rAO3jAkEAvLwG/lduFGnOZBos5b1mmTEzgPh7fr884hf5drISYn55NN4PVywmVErQL5HLFMaKH2bGVVxIsWMTbDFUolUtgA==";
+		String paramBody = JSONObject.toJSONString(paramData);
+		Sign sign = SecureUtil.sign(SignAlgorithm.SHA1withRSA, privateKey, null);
+		VgmParamVo vgmParamVo = new VgmParamVo();
+		vgmParamVo.setCustomerCode("92120221660325249F");
+		vgmParamVo.setType(operationType.getSignType());
+		vgmParamVo.setData(paramBody);
+		String signParam = "customerCode=" + URLEncoder.encode(vgmParamVo.getCustomerCode(), "utf-8")  + "&data=" + vgmParamVo.getData() + "&type=" + vgmParamVo.getType();
+		byte[] signedBytes = sign.sign(signParam.getBytes(StandardCharsets.UTF_8));
+		String signature = cn.hutool.core.codec.Base64.encode(signedBytes);
+		vgmParamVo.setSign(signature);
+		HttpPost post = new HttpPost(operationType.getUrl());
+		try {
+			String jsonBody = JSONUtil.toJsonStr(vgmParamVo);
+			StringEntity entity = new StringEntity(jsonBody, ContentType.APPLICATION_JSON);
+			post.setEntity(entity);
+			post.setHeader("Content-Type", "application/json;charset=UTF-8");
+			CloseableHttpClient client = HttpClients.createDefault();
+			CloseableHttpResponse response = client.execute(post);
+			HttpEntity httpEntity = response.getEntity();
+			String result = EntityUtils.toString(httpEntity, Constants.UTF8);
+			Thread.sleep(100);
+			return result;
+		} catch (Exception e1) {
+			log.error(e1.getMessage());
+			return e1.getMessage();
+		}
+	}
+
+
+
+
+}

+ 1 - 0
blade-service/blade-los/src/main/java/org/springblade/los/box/mapper/PutBoxMapper.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--suppress ALL -->
 <mapper namespace="org.springblade.los.box.mapper.PutBoxMapper">
 
     <!-- 通用查询映射结果 -->

+ 80 - 0
blade-service/blade-los/src/main/java/org/springblade/los/enums/VgmOperationType.java

@@ -0,0 +1,80 @@
+package org.springblade.los.enums;
+
+import lombok.Getter;
+
+/**
+ * 云港通 VGM 相关操作类型枚举
+ *
+ * @author Rain
+ */
+@Getter
+public enum VgmOperationType {
+
+	/**
+	 * 【平台-云港通】发送VGM申报到云港通
+	 * <p>
+	 * 业务描述:第三方平台将VGM信息发送给云港通,云港通返回该批VGM信息是否保存成功,并返回保存失败的原因。
+	 */
+	RECEIVE_VGM_REPORT(
+		"https://api.qingdao-port.net/gateway/test/third-platform/consumer/receiveVgmReport",
+		"receiveVgmReport"
+	),
+
+	/**
+	 * 【平台-云港通】提交VGM到场站
+	 * <p>
+	 * 业务描述:第三方平台发起VGM提交到场站的请求,云港通返回该批VGM场站是否接收成功,并返回接收失败的原因。
+	 */
+	SUBMIT_VGM_REPORT(
+		"https://api.qingdao-port.net/gateway/test/third-platform/consumer/submitVgmReport",
+		"submitVgmReport"
+	),
+
+	/**
+	 * 【平台-云港通】VGM变更信息保存
+	 * <p>
+	 * 业务描述:第三方平台发起VGM变更请求,首先提交云港通平台,云港通保存VGM变更信息。平台后续再调用提交场站变更接口,发起变更。
+	 */
+	RECEIVE_MODIFY_VGM_REPORT(
+		"https://api.qingdao-port.net/gateway/test/third-platform/consumer/receiveModifyVgmReport",
+		"receiveModifyVgmReport"
+	),
+
+	/**
+	 * 【平台-云港通】平台提交VGM变更到场站
+	 * <p>
+	 * 业务描述:第三方平台发起VGM变更请求,云港通返回该批VGM场站是否接收成功,并返回接收失败的原因。
+	 */
+	SUBMIT_MODIFY_VGM_REPORT(
+		"https://api.qingdao-port.net/gateway/test/third-platform/consumer/submitModifyVgmReport",
+		"submitModifyVgmReport"
+	),
+
+	/**
+	 * 【平台-云港通】平台发起支付请求(云付钱包协议扣款)
+	 * <p>
+	 * 业务描述:第三方平台发起VGM变更请求,云港通返回场站是否接收到此变更信息。返回的信息仅代表场站收到变更信息,云港通会在场站确认该信息后,再次通知第三方平台场站的处理结果。
+	 */
+	REQUEST_PAY_VGM(
+		"https://api.qingdao-port.net/gateway/test/third-platform/consumer/requestPayVgm",
+		"requestPayVgm"
+	);
+
+
+	/**
+	 * 请求地址
+	 */
+	private final String url;
+
+	/**
+	 * 签名类型
+	 */
+	private final String signType;
+
+	VgmOperationType(String url, String signType) {
+		this.url = url;
+		this.signType = signType;
+	}
+
+
+}

+ 34 - 0
blade-service/blade-los/src/main/java/org/springblade/los/vgm/controller/VgmController.java

@@ -0,0 +1,34 @@
+package org.springblade.los.vgm.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springblade.core.tool.api.R;
+import org.springblade.los.vgm.service.IVgmService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * @author Rain
+ */
+@RestController
+@RequestMapping("/vgm")
+@RequiredArgsConstructor
+public class VgmController {
+
+
+	private final IVgmService vgmService;
+
+
+	@PostMapping("/sendVgm")
+	public R sendVgm(@RequestParam("billId") String billId) throws IllegalAccessException, UnsupportedEncodingException {
+		return vgmService.sendVgm(billId);
+	}
+
+
+
+
+
+}

+ 20 - 0
blade-service/blade-los/src/main/java/org/springblade/los/vgm/service/IVgmService.java

@@ -0,0 +1,20 @@
+package org.springblade.los.vgm.service;
+
+import org.springblade.core.tool.api.R;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * @author Rain
+ */
+public interface IVgmService {
+
+
+	/**
+	 * 发送vgm
+	 *
+	 * @param billId 单据id
+	 * @return 结果
+	 */
+	R sendVgm(String billId) throws IllegalAccessException, UnsupportedEncodingException;
+}

+ 81 - 0
blade-service/blade-los/src/main/java/org/springblade/los/vgm/service/impl/VgmServiceImpl.java

@@ -0,0 +1,81 @@
+package org.springblade.los.vgm.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import io.jsonwebtoken.lang.Collections;
+import lombok.RequiredArgsConstructor;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.los.Util.VgmUtils;
+import org.springblade.los.business.sea.entity.Bills;
+import org.springblade.los.business.sea.entity.Containers;
+import org.springblade.los.business.sea.mapper.BillsMapper;
+import org.springblade.los.business.sea.mapper.ContainersMapper;
+import org.springblade.los.enums.VgmOperationType;
+import org.springblade.los.vgm.VgmDeclaration;
+import org.springblade.los.vgm.VgmDeclarationSend;
+import org.springblade.los.vgm.service.IVgmService;
+import org.springframework.stereotype.Service;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author Rain
+ */
+@Service
+@RequiredArgsConstructor
+public class VgmServiceImpl implements IVgmService {
+
+	private final BillsMapper billsMapper;
+
+	private final ContainersMapper containersMapper;
+
+
+	@Override
+	public R sendVgm(String billId) throws IllegalAccessException, UnsupportedEncodingException {
+		BladeUser bladeUser = AuthUtil.getUser();
+		Bills bills = billsMapper.selectOne(new LambdaQueryWrapper<Bills>().eq(Bills::getTenantId, bladeUser.getTenantId())
+			.eq(Bills::getId, billId).eq(Bills::getIsDeleted, 0).last("limit 1"));
+		if (Objects.isNull(bills)) {
+			return R.fail("未找到对应的提单");
+		}
+		List<Containers> containers = containersMapper.selectList(new LambdaQueryWrapper<Containers>()
+			.eq(Containers::getPid, billId).eq(Containers::getIsDeleted, 0).eq(Containers::getTenantId, bladeUser.getTenantId()));
+		if (Collections.isEmpty(containers)) {
+			return R.fail("未找到对应的提单下的箱列表");
+		}
+		List<VgmDeclaration> vgmDeclarationList = new ArrayList<>();
+		VgmDeclarationSend sendData = new VgmDeclarationSend();
+		sendData.setTdh(bills.getBillNo());
+		sendData.setData(vgmDeclarationList);
+		for (Containers container : containers) {
+			String xx = container.getCntrTypeCode().substring(2, 3);
+			String cc = container.getCntrTypeCode().substring(0, 1);
+			VgmDeclaration vgmDeclaration = new VgmDeclaration();
+			vgmDeclarationList.add(vgmDeclaration);
+			vgmDeclaration.setXh(container.getCntrNo());
+			vgmDeclaration.setXx(xx);
+			vgmDeclaration.setCc(cc);
+			vgmDeclaration.setWeight(String.valueOf(container.getVgmWeight()));
+			vgmDeclaration.setCzdm(bills.getPodCyCode());
+			vgmDeclaration.setMtdm(bills.getPortTerminalCyCode());
+			vgmDeclaration.setWeightMethod("SM1");
+			vgmDeclaration.setBookingNo(bills.getBookingNo());
+			vgmDeclaration.setLinkMan(bladeUser.getUserName());
+			vgmDeclaration.setWeightUnit("kgs");
+			vgmDeclaration.setXsgsm("COS");
+
+			vgmDeclaration.setApplyPerson("x");
+			vgmDeclaration.setApplyPhone("x");
+			vgmDeclaration.setUserName("x");
+			vgmDeclaration.setLinkPhone("x");
+			vgmDeclaration.setLinkMail("x");
+
+		}
+		String result = VgmUtils.sendVgmToPlatform(sendData, VgmOperationType.RECEIVE_VGM_REPORT);
+		return R.success(result);
+	}
+}

+ 138 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/controller/CorpsVisitController.java

@@ -0,0 +1,138 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.salesPart.corps.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.salesPart.corps.service.ICorpsVisitService;
+import org.springblade.salesPart.entity.CorpsVisit;
+import org.springblade.salesPart.vo.CorpsVisitVO;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 客户拜访表 控制器
+ *
+ * @author BladeX
+ * @since 2025-02-24
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/corpsvisit")
+@Api(value = "客户拜访表", tags = "客户拜访表接口")
+public class CorpsVisitController extends BladeController {
+
+	private final ICorpsVisitService corpsVisitService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入corpsVisit")
+	public R<CorpsVisit> detail(CorpsVisit corpsVisit) {
+		CorpsVisit detail = corpsVisitService.getOne(Condition.getQueryWrapper(corpsVisit));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页 客户拜访表
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入corpsVisit")
+	public R<IPage<CorpsVisit>> list(CorpsVisit corpsVisit, Query query) {
+		LambdaQueryWrapper<CorpsVisit> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+		lambdaQueryWrapper.eq(CorpsVisit::getTenantId, AuthUtil.getTenantId())
+			.eq(CorpsVisit::getIsDeleted, 0)
+			.eq(CorpsVisit::getCustomerName, corpsVisit.getCustomerName())
+			.eq(CorpsVisit::getVisitPeopleName, corpsVisit.getVisitPeopleName())
+			.orderByDesc(CorpsVisit::getVisitDate);
+		if (corpsVisit.getVisitDateList() != null && corpsVisit.getVisitDateList().size() > 1) {//拜访日期
+			lambdaQueryWrapper.ge(CorpsVisit::getVisitDateList, corpsVisit.getVisitDateList().get(0));
+			lambdaQueryWrapper.le(CorpsVisit::getVisitDateList, corpsVisit.getVisitDateList().get(1));
+		}
+		IPage<CorpsVisit> pages = corpsVisitService.page(Condition.getPage(query), lambdaQueryWrapper);
+		return R.data(pages);
+	}
+
+	/**
+	 * 自定义分页 客户拜访表
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入corpsVisit")
+	public R<IPage<CorpsVisitVO>> page(CorpsVisitVO corpsVisit, Query query) {
+		IPage<CorpsVisitVO> pages = corpsVisitService.selectCorpsVisitPage(Condition.getPage(query), corpsVisit);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增 客户拜访表
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入corpsVisit")
+	public R save(@Valid @RequestBody CorpsVisit corpsVisit) {
+		return R.status(corpsVisitService.save(corpsVisit));
+	}
+
+	/**
+	 * 修改 客户拜访表
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入corpsVisit")
+	public R update(@Valid @RequestBody CorpsVisit corpsVisit) {
+		return R.status(corpsVisitService.updateById(corpsVisit));
+	}
+
+	/**
+	 * 新增或修改 客户拜访表
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入corpsVisit")
+	public R submit(@Valid @RequestBody CorpsVisit corpsVisit) {
+		return corpsVisitService.submit(corpsVisit);
+	}
+
+
+	/**
+	 * 删除 客户拜访表
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(corpsVisitService.removeByIds(Func.toLongList(ids)));
+	}
+
+
+}

+ 8 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsTypeDescMapper.java

@@ -21,6 +21,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.salesPart.entity.PjCorpsTypeDesc;
 import org.springblade.salesPart.vo.CorpsTypeDescVO;
+import org.springblade.salesPart.vo.CustomerTypeKeyValueVo;
 
 import java.util.List;
 
@@ -57,4 +58,11 @@ public interface CorpsTypeDescMapper extends BaseMapper<PjCorpsTypeDesc> {
 	 */
 	String selectTypeName(@Param("corpId") Long corpId);
 
+
+	/**
+	 * 查询客户类别
+	 * @param customerId 客户id
+	 * @return 结果
+	 */
+	List<CustomerTypeKeyValueVo> getCustomerTypeKeyValueVoList(@Param("customerId") Long customerId);
 }

+ 13 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsTypeDescMapper.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--suppress ALL -->
 <mapper namespace="org.springblade.salesPart.corps.mapper.CorpsTypeDescMapper">
 
     <!-- 通用查询映射结果 -->
@@ -33,5 +34,17 @@
             left join pjpf_corps_type_desc t2 on t1.id = t2.corp_type_id
         where t2.corp_id = #{corpId}
     </select>
+    <select id="getCustomerTypeKeyValueVoList" resultType="org.springblade.salesPart.vo.CustomerTypeKeyValueVo"
+            parameterType="java.lang.Long">
+        SELECT
+            DISTINCT
+            ct.id,
+            ct.cname
+        FROM
+            pjpf_corps_type_desc ctd
+                INNER JOIN pjpf_corps_type ct ON ctd.corp_type_id = ct.id
+        where ctd.status = 0 and ctd.corp_id = #{customerId}
+          and ct.is_deleted = 0
+    </select>
 
 </mapper>

+ 43 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsVisitMapper.java

@@ -0,0 +1,43 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.salesPart.corps.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.salesPart.entity.CorpsVisit;
+import org.springblade.salesPart.vo.CorpsVisitVO;
+
+import java.util.List;
+
+/**
+ * 客户拜访表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2025-02-24
+ */
+public interface CorpsVisitMapper extends BaseMapper<CorpsVisit> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param corpsVisit
+	 * @return
+	 */
+	List<CorpsVisitVO> selectCorpsVisitPage(IPage page, CorpsVisitVO corpsVisit);
+
+}

+ 30 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/mapper/CorpsVisitMapper.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.salesPart.corps.mapper.CorpsVisitMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="corpsVisitResultMap" type="org.springblade.salesPart.entity.CorpsVisit">
+        <id column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="remarks" property="remarks"/>
+        <result column="content" property="content"/>
+        <result column="visit_date" property="visitDate"/>
+        <result column="visit_people_id" property="visitPeopleId"/>
+        <result column="visit_people_name" property="visitPeopleName"/>
+        <result column="customer_id" property="customerId"/>
+        <result column="customer_name" property="customerName"/>
+        <result column="longitude" property="longitude"/>
+        <result column="dimension" property="dimension"/>
+        <result column="address" property="address"/>
+    </resultMap>
+
+
+    <select id="selectCorpsVisitPage" resultMap="corpsVisitResultMap">
+        select * from pjpf_corps_visit where is_deleted = 0
+    </select>
+
+</mapper>

+ 43 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/service/ICorpsVisitService.java

@@ -0,0 +1,43 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.salesPart.corps.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.core.tool.api.R;
+import org.springblade.salesPart.entity.CorpsVisit;
+import org.springblade.salesPart.vo.CorpsVisitVO;
+
+/**
+ * 客户拜访表 服务类
+ *
+ * @author BladeX
+ * @since 2025-02-24
+ */
+public interface ICorpsVisitService extends IService<CorpsVisit> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param corpsVisit
+	 * @return
+	 */
+	IPage<CorpsVisitVO> selectCorpsVisitPage(IPage<CorpsVisitVO> page, CorpsVisitVO corpsVisit);
+
+	R submit(CorpsVisit corpsVisit);
+}

+ 23 - 37
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/service/impl/CorpsDescServiceImpl.java

@@ -1,19 +1,3 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
 package org.springblade.salesPart.corps.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -28,11 +12,13 @@ import org.springblade.client.entity.CorpsDesc;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.salesPart.brand.service.IBrandDescService;
 import org.springblade.salesPart.corps.mapper.CorpsDescMapper;
 import org.springblade.salesPart.corps.mapper.CorpsTypeDescMapper;
 import org.springblade.salesPart.corps.mapper.CorpsTypeMapper;
+import org.springblade.salesPart.corps.mapper.CorpsVisitMapper;
 import org.springblade.salesPart.corps.service.ICorpsDescService;
 import org.springblade.salesPart.entity.*;
 import org.springblade.salesPart.excel.CorpsDescImportExcel;
@@ -43,6 +29,7 @@ import org.springblade.salesPart.settlement.mapper.SettlementMapper;
 import org.springblade.salesPart.ship.mapper.ShipMapper;
 import org.springblade.salesPart.storage.service.IStorageDescService;
 import org.springblade.salesPart.vo.CorpsDescVO;
+import org.springblade.salesPart.vo.CustomerTypeKeyValueVo;
 import org.springblade.system.entity.Dept;
 import org.springblade.system.feign.ISysClient;
 import org.springblade.system.user.entity.User;
@@ -81,6 +68,8 @@ public class CorpsDescServiceImpl extends ServiceImpl<CorpsDescMapper, PjCorpsDe
 
 	private final IBrandDescService brandDescService;
 
+	private final CorpsVisitMapper corpsVisitMapper;
+
 
 	static final int GB_SP_DIFF = 160;
 	// 存放国标一级汉字不同读音的起始区位码
@@ -99,28 +88,25 @@ public class CorpsDescServiceImpl extends ServiceImpl<CorpsDescMapper, PjCorpsDe
 	@Override
 	public PjCorpsDesc getMessageByID(PjCorpsDesc corpsDesc) {
 		PjCorpsDesc desc = baseMapper.selectById(corpsDesc.getId());
-		if (desc != null) {
-			//获取客户联系人
-			desc.setCorpsAttnList(corpsAttnService.list(new QueryWrapper<PjCorpsAttn>().eq("pid", corpsDesc.getId()).eq("is_deleted", 0)));
-			//获取客户地址
-			desc.setCorpsAddrList(corpsAddrService.list(new QueryWrapper<PjCorpsAddr>().eq("pid", corpsDesc.getId()).eq("is_deleted", 0)));
-			//获取客户附件
-			desc.setCorpsFilesList(corpsFilesService.list(new QueryWrapper<PjCorpsFiles>().eq("pid", corpsDesc.getId()).eq("is_deleted", 0)));
-			//获取客户类别
-			List<String> longs = corpsTypeDescMapper.selectTypeId(corpsDesc.getId());
-			desc.setCorpsTypeId(String.join(",", longs));
-			StringBuilder corpsTypeName = new StringBuilder();
-			if (ObjectUtils.isNotNull(longs)) {
-				for (String id : longs) {
-					String name = corpsTypeMapper.selectById(Long.parseLong(id)) == null ? "" : corpsTypeMapper.selectById(Long.parseLong(id)).getCname();
-					corpsTypeName.append(name).append(",");
-				}
-				String corpsName = corpsTypeName.substring(0, corpsTypeName.length() - 1);
-				desc.setCorpsTypeName(corpsName);
-			} else {
-				desc.setCorpsTypeName("");
-			}
+		if (Objects.isNull(desc)){
+			return null;
+		}
+		//获取客户联系人
+		desc.setCorpsAttnList(corpsAttnService.list(new QueryWrapper<PjCorpsAttn>().eq("pid", corpsDesc.getId()).eq("is_deleted", 0)));
+		//获取客户地址
+		desc.setCorpsAddrList(corpsAddrService.list(new QueryWrapper<PjCorpsAddr>().eq("pid", corpsDesc.getId()).eq("is_deleted", 0)));
+		//获取客户附件
+		desc.setCorpsFilesList(corpsFilesService.list(new QueryWrapper<PjCorpsFiles>().eq("pid", corpsDesc.getId()).eq("is_deleted", 0)));
+		//获取客户类别
+		List<String> customerTypeIdList = corpsTypeDescMapper.selectTypeId(corpsDesc.getId());
+		List<CustomerTypeKeyValueVo> customerTypeKeyValueVoList = corpsTypeDescMapper.getCustomerTypeKeyValueVoList(corpsDesc.getId());
+		if (CollectionUtil.isNotEmpty(customerTypeKeyValueVoList)) {
+			desc.setCorpsTypeId(String.join(",", customerTypeIdList));
+			desc.setCorpsTypeId(customerTypeKeyValueVoList.stream().filter(ck -> Objects.nonNull(ck.getId())).map(ctk -> String.valueOf(ctk.getId())).collect(Collectors.joining(",")));
+			desc.setCorpsTypeName(customerTypeKeyValueVoList.stream().map(CustomerTypeKeyValueVo::getCname).filter(Objects::nonNull).collect(Collectors.joining(",")));
 		}
+		List<CorpsVisit> corpsVisitList = corpsVisitMapper.selectList(new LambdaQueryWrapper<CorpsVisit>().eq(CorpsVisit::getCustomerId, corpsDesc.getId()).eq(CorpsVisit::getIsDeleted, 0));
+		desc.setCorpsVisitList(corpsVisitList);
 		return desc;
 	}
 

+ 68 - 0
blade-service/blade-sales-part/src/main/java/org/springblade/salesPart/corps/service/impl/CorpsVisitServiceImpl.java

@@ -0,0 +1,68 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.salesPart.corps.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.secure.utils.SecureUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.salesPart.corps.mapper.CorpsVisitMapper;
+import org.springblade.salesPart.corps.service.ICorpsVisitService;
+import org.springblade.salesPart.entity.CorpsVisit;
+import org.springblade.salesPart.vo.CorpsVisitVO;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+/**
+ * 客户拜访表 服务实现类
+ *
+ * @author BladeX
+ * @since 2025-02-24
+ */
+@Service
+public class CorpsVisitServiceImpl extends ServiceImpl<CorpsVisitMapper, CorpsVisit> implements ICorpsVisitService {
+
+	@Override
+	public IPage<CorpsVisitVO> selectCorpsVisitPage(IPage<CorpsVisitVO> page, CorpsVisitVO corpsVisit) {
+		return page.setRecords(baseMapper.selectCorpsVisitPage(page, corpsVisit));
+	}
+
+	@Override
+	public R submit(CorpsVisit corpsVisit) {
+		Long userId = SecureUtil.getUserId();
+		if (corpsVisit.getId() == null) {
+			corpsVisit.setTenantId(SecureUtil.getTenantId());
+			corpsVisit.setCreateTime(new Date());
+			corpsVisit.setCreateUser(userId);
+			corpsVisit.setVisitDate(new Date());
+			corpsVisit.setVisitPeopleId(AuthUtil.getUserId());
+			corpsVisit.setVisitPeopleName(AuthUtil.getUserName());
+			baseMapper.insert(corpsVisit);
+		} else {
+			corpsVisit.setTenantId(SecureUtil.getTenantId());
+			corpsVisit.setUpdateTime(new Date());
+			corpsVisit.setUpdateUser(AuthUtil.getUserId());
+			corpsVisit.setVisitPeopleId(AuthUtil.getUserId());
+			corpsVisit.setVisitPeopleName(AuthUtil.getUserName());
+			baseMapper.updateById(corpsVisit);
+		}
+		return R.data(corpsVisit);
+	}
+
+}