diff --git a/mhd-auth/src/main/resources/bootstrap.yml b/mhd-auth/src/main/resources/bootstrap.yml index eede5c5a3..c529aac6a 100644 --- a/mhd-auth/src/main/resources/bootstrap.yml +++ b/mhd-auth/src/main/resources/bootstrap.yml @@ -14,7 +14,7 @@ spring: discovery: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 + #server-addr: 10.33.0.129:6010 #线上正式环境 server-addr: 10.102.192.5:6848 username: nacos @@ -22,7 +22,7 @@ spring: config: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 + #server-addr: 10.33.0.129:6010 #线上正式环境 server-addr: 10.102.192.5:6848 username: nacos diff --git a/mhd-gateway/src/main/resources/bootstrap.yml b/mhd-gateway/src/main/resources/bootstrap.yml index 2d80c4c78..44ad69314 100644 --- a/mhd-gateway/src/main/resources/bootstrap.yml +++ b/mhd-gateway/src/main/resources/bootstrap.yml @@ -15,23 +15,24 @@ spring: discovery: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.102.192.5:6848 + server-addr: 10.102.192.5:6848 # server-addr: 10.33.0.129:6010 #线上正式环境 - server-addr: 10.102.192.5:6848 +# server-addr: mhd-nacos:8848 username: nacos password: manhuoda@2023 config: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.102.192.5:6848 -# server-addr: 10.33.0.129:6010 - #线上正式环境 +# server-addr: mhd-nacos:8848 server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 +# server-addr: 10.33.0.129:6010 + #线上正式环境 +# server-addr: 10.102.192.105:6848 group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置 file-extension: yml #默认properties # 共享配置 shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} \ No newline at end of file + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/mhd-modules/mhd-system/src/main/resources/bootstrap.yml b/mhd-modules/mhd-system/src/main/resources/bootstrap.yml index dc7b508d7..b89dfcf75 100644 --- a/mhd-modules/mhd-system/src/main/resources/bootstrap.yml +++ b/mhd-modules/mhd-system/src/main/resources/bootstrap.yml @@ -15,19 +15,19 @@ spring: discovery: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 - #线上正式环境 server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 + #线上正式环境 +# server-addr: 10.102.192.105:6848 config: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 - #线上正式环境 server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 + #线上正式环境 +# server-addr: 10.102.192.105:6848 group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置 file-extension: yml #默认properties # 共享配置 diff --git a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java index 35709b37e..0fad3e4fb 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java @@ -679,9 +679,9 @@ public class UserShipperApplicationService { AccountCashWalletDto accountCashWalletDto = new AccountCashWalletDto(); accountCashWalletDto.setUserId(userShipperPo.getUserId()); AjaxResult ajaxResult = financeServiceFeign.accountCashWalletSave(accountCashWalletDto); - if (null == ajaxResult || !"200".equals(String.valueOf(ajaxResult.get("code")))) { + /*if (null == ajaxResult || !"200".equals(String.valueOf(ajaxResult.get("code")))) { throw new ServiceException("开通钱包失败"); - } + }*/ //审核通过,此时重新更新网货中的角色code,需要重新查询 List roleCodeList = userRoleDomainService.selectRolesByUserId(userShipperDO.getUserId()); diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserShipperEntity.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserShipperEntity.java index eeacaaadd..3db787715 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserShipperEntity.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserShipperEntity.java @@ -194,4 +194,7 @@ public class UserShipperEntity extends BaseVOEntity { @ApiModelProperty(name = "客户nc编码") private String customerNcCode; + + @ApiModelProperty("结算币种") + private String settlementCurrency; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/po/UserShipperPo.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/po/UserShipperPo.java index d25de5e24..d8163e9b5 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/po/UserShipperPo.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/po/UserShipperPo.java @@ -257,4 +257,7 @@ public class UserShipperPo implements Serializable { @ApiModelProperty(name = "客户nc编码") private String customerNcCode; + + @ApiModelProperty("结算币种") + private String settlementCurrency; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserShipperDO.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserShipperDO.java index 5557c5a95..4d9ff808c 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserShipperDO.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserShipperDO.java @@ -228,4 +228,7 @@ public class UserShipperDO extends UserDO { @ApiModelProperty(name = "客户nc编码") private String customerNcCode; + + @ApiModelProperty("结算币种") + private String settlementCurrency; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserShipperDTO.java b/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserShipperDTO.java index 2a62458b4..ca8c70633 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserShipperDTO.java +++ b/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserShipperDTO.java @@ -194,4 +194,7 @@ public class UserShipperDTO extends UserDTO { @ApiModelProperty("客户nc编码") private String customerNcCode; + @ApiModelProperty("结算币种") + private String settlementCurrency; + } diff --git a/mhd-user-center/src/main/resources/bootstrap.yml b/mhd-user-center/src/main/resources/bootstrap.yml index 73d8acd49..092834b37 100644 --- a/mhd-user-center/src/main/resources/bootstrap.yml +++ b/mhd-user-center/src/main/resources/bootstrap.yml @@ -20,19 +20,19 @@ spring: discovery: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 - #线上正式环境 server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 + #线上正式环境 +# server-addr: 10.102.192.105:6848 config: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 - #线上正式环境 server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 + #线上正式环境 +# server-addr: 10.102.192.105:6848 group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置 file-extension: yml #默认properties # 共享配置 diff --git a/mhd-user-center/src/main/resources/mapper/UserMapper.xml b/mhd-user-center/src/main/resources/mapper/UserMapper.xml index b5f65eb23..8354d2d3d 100644 --- a/mhd-user-center/src/main/resources/mapper/UserMapper.xml +++ b/mhd-user-center/src/main/resources/mapper/UserMapper.xml @@ -96,7 +96,7 @@ FROM user_shipper s LEFT JOIN - "user" u + "USER" u ON u.user_id = s.user_id and u.top_organization_id = #{topOrganizationId} @@ -117,7 +117,7 @@ FROM user_shipper s LEFT JOIN - "user" u + "USER" u ON u.user_id = s.user_id and u.del_flag = 1 s.del_flag = 1 and s.shipper_fill = 3 @@ -411,7 +411,7 @@ a.user_account, a.avatar FROM - "user" a + "USER" a WHERE a.del_flag = 1 @@ -658,7 +658,7 @@ us.shipper_enterprise_name, us.shipper_type FROM - "user" u + "USER" u LEFT JOIN user_shipper us ON u.user_id = us.user_id WHERE u.del_flag = 1 @@ -676,7 +676,7 @@ ude.driver_enterprise_name, ude.driver_type FROM - "user" u + "USER" u LEFT JOIN user_driver_enterprise ude ON u.user_id = ude.user_id WHERE u.del_flag = 1 @@ -700,7 +700,7 @@ a.user_account, a.avatar FROM - "user" a + "USER" a WHERE a.del_flag = 1 and a.top_organization_id = #{topOrganizationId} diff --git a/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml b/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml index c89277bb2..4866e3a3a 100644 --- a/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml +++ b/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml @@ -139,7 +139,7 @@ b.monthly_settlement_flag, a.user_auth_status, b.original_receipt_flag, - b.freight_node,b.customer_nc_code + b.freight_node,b.customer_nc_code,b.settlement_currency FROM "USER" a LEFT JOIN user_shipper b ON a.user_id = b.user_id left join (select user_id, LISTAGG(DISTINCT r.role_name, '&') WITHIN GROUP(ORDER BY r.role_name) AS roleName @@ -191,7 +191,7 @@ b.shipper_enterprise_fill, a.business_type FROM - "user" a + "USER" a LEFT JOIN user_shipper b ON b.user_id = a.user_id LEFT JOIN user_role ur ON b.user_id = ur.user_id LEFT JOIN role r ON ur.role_id = r.role_id diff --git a/mhd_finance/src/main/java/com/linke/finance/application/server/reconciliation/ReconciliationApplicationService.java b/mhd_finance/src/main/java/com/linke/finance/application/server/reconciliation/ReconciliationApplicationService.java index 3ef7020f6..d4592bd6c 100644 --- a/mhd_finance/src/main/java/com/linke/finance/application/server/reconciliation/ReconciliationApplicationService.java +++ b/mhd_finance/src/main/java/com/linke/finance/application/server/reconciliation/ReconciliationApplicationService.java @@ -1,5 +1,6 @@ package com.linke.finance.application.server.reconciliation; +import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; import com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceResponse; import com.linke.finance.domain.businessDocument.entity.BusinessDocument; @@ -14,10 +15,13 @@ import com.linke.finance.domain.reconciliation.repository.todo.ReconciliationDO; import com.linke.finance.domain.reconciliation.service.ReconciliationDomainService; import com.linke.finance.domain.revenueExpensesRecord.entity.RevenueExpensesRecord; import com.linke.finance.domain.revenueExpensesRecord.service.RevenueExpensesRecordDomainService; +import com.linke.finance.domain.tmsReceipt.entity.TmsReceipt; +import com.linke.finance.domain.tmsReceipt.repository.mapper.TmsReceiptMapper; import com.linke.finance.domain.tmsReceipt.repository.po.TmsReceiptPO; import com.linke.finance.domain.tmsReceipt.service.TmsReceiptDomainService; import com.linke.finance.domain.verification.service.VerificationDomainService; import com.linke.finance.infrastructure.feign.ProductServiceFeign; +import com.linke.finance.infrastructure.feign.WlhyServiceFeign; import com.mhd.common.core.constant.SubjectConstants; import com.mhd.common.core.domain.dto.ReconciliationDTO; import com.mhd.common.core.domain.entity.Verification; @@ -37,11 +41,13 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestParam; +import javax.annotation.Resource; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -65,6 +71,10 @@ public class ReconciliationApplicationService { private TmsReceiptDomainService tmsReceiptDomainService; @Autowired private RevenueExpensesRecordDomainService revenueExpensesRecordDomainService; + @Autowired + private WlhyServiceFeign wlhyServiceFeign; + @Resource + private TmsReceiptMapper tmsReceiptMapper; @@ -86,7 +96,21 @@ public class ReconciliationApplicationService { reconciliationDO.setOrganizationId(userPo.getOrganizationId()); } } - return reconciliationDomainService.queryList(reconciliationDO); + List reconciliationPOS = reconciliationDomainService.queryList(reconciliationDO); + for (ReconciliationPO reconciliationPO : reconciliationPOS) { + Long reconciliationId = reconciliationPO.getReconciliationId(); + AjaxResult tmsOrderSettlementDetails = wlhyServiceFeign.getById(reconciliationId); + Map result = (Map)tmsOrderSettlementDetails.get("result"); + if (ObjectUtil.isNotEmpty( result)){ + Integer receiptIdstr = (Integer)result.get("receiptId"); + Long receiptId = receiptIdstr.longValue(); + TmsReceipt tmsReceipt = tmsReceiptMapper.selectById(receiptId); + if (tmsReceipt != null) { + reconciliationPO.setSettlementCurrency(tmsReceipt.getSettlementCurrency()); + } + } + } + return reconciliationPOS; } /** diff --git a/mhd_finance/src/main/java/com/linke/finance/domain/reconciliation/repository/po/ReconciliationPO.java b/mhd_finance/src/main/java/com/linke/finance/domain/reconciliation/repository/po/ReconciliationPO.java index 04c776ae0..54f0efb49 100644 --- a/mhd_finance/src/main/java/com/linke/finance/domain/reconciliation/repository/po/ReconciliationPO.java +++ b/mhd_finance/src/main/java/com/linke/finance/domain/reconciliation/repository/po/ReconciliationPO.java @@ -238,4 +238,8 @@ public class ReconciliationPO extends BaseVOEntity{ @ApiModelProperty(value = "nc唯一标识") private String skNcId; + + @ApiModelProperty("结算币种") + private String settlementCurrency; + } diff --git a/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/entity/TmsReceipt.java b/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/entity/TmsReceipt.java index bea4a0078..51d7de86f 100644 --- a/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/entity/TmsReceipt.java +++ b/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/entity/TmsReceipt.java @@ -115,4 +115,7 @@ public class TmsReceipt extends BaseVOEntity{ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private java.util.Date synchronousTime; + @ApiModelProperty("结算币种") + private String settlementCurrency; + } diff --git a/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/po/TmsReceiptPO.java b/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/po/TmsReceiptPO.java index 1046767cc..8e40b75f5 100644 --- a/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/po/TmsReceiptPO.java +++ b/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/po/TmsReceiptPO.java @@ -107,4 +107,6 @@ public class TmsReceiptPO extends BaseVOEntity{ @ApiModelProperty("组织名称") @Excel(name = "组织名称") private String organizationName; + @ApiModelProperty("结算币种") + private String settlementCurrency; } diff --git a/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/todo/TmsReceiptDO.java b/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/todo/TmsReceiptDO.java index ac58c2c05..1586c1321 100644 --- a/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/todo/TmsReceiptDO.java +++ b/mhd_finance/src/main/java/com/linke/finance/domain/tmsReceipt/repository/todo/TmsReceiptDO.java @@ -132,4 +132,6 @@ public class TmsReceiptDO extends BaseVOEntity{ @ApiModelProperty("收款单号") @Excel(name = "收款单号") private String receivePaymentNumber; + @ApiModelProperty("结算币种") + private String settlementCurrency; } diff --git a/mhd_finance/src/main/java/com/linke/finance/infrastructure/feign/WlhyServiceFeign.java b/mhd_finance/src/main/java/com/linke/finance/infrastructure/feign/WlhyServiceFeign.java new file mode 100644 index 000000000..864ea2e89 --- /dev/null +++ b/mhd_finance/src/main/java/com/linke/finance/infrastructure/feign/WlhyServiceFeign.java @@ -0,0 +1,19 @@ +package com.linke.finance.infrastructure.feign; + +import com.mhd.common.core.domain.dto.UserDriverDTO; +import com.mhd.common.core.web.domain.AjaxResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient("mhd-wlhy-service") +public interface WlhyServiceFeign { + + /** + * @Description 绑定车辆 + * @Author Alex + * @Date 2023/1/5 21:24 + */ + @GetMapping("/ntocc/tmsOrder/getById") + public AjaxResult getById(@RequestParam(name="id",required=true) Long id); +} diff --git a/mhd_finance/src/main/java/com/linke/finance/interfaces/dto/TmsReceiptDTO.java b/mhd_finance/src/main/java/com/linke/finance/interfaces/dto/TmsReceiptDTO.java index 1289619b9..114129a43 100644 --- a/mhd_finance/src/main/java/com/linke/finance/interfaces/dto/TmsReceiptDTO.java +++ b/mhd_finance/src/main/java/com/linke/finance/interfaces/dto/TmsReceiptDTO.java @@ -127,4 +127,6 @@ public class TmsReceiptDTO extends BaseVOEntity{ @ApiModelProperty("挂账原因") @Excel(name = "挂账原因") private String creditReason; + @ApiModelProperty("结算币种") + private String settlementCurrency; } diff --git a/mhd_finance/src/main/java/com/linke/finance/interfaces/facade/reconciliation/ReconciliationApi.java b/mhd_finance/src/main/java/com/linke/finance/interfaces/facade/reconciliation/ReconciliationApi.java index 143ed1ad2..4e3099400 100644 --- a/mhd_finance/src/main/java/com/linke/finance/interfaces/facade/reconciliation/ReconciliationApi.java +++ b/mhd_finance/src/main/java/com/linke/finance/interfaces/facade/reconciliation/ReconciliationApi.java @@ -272,7 +272,12 @@ public class ReconciliationApi extends BaseController{ @GetMapping(value = "/synchronousNc") public AjaxResult synchronousNc(@RequestParam(name="reconciliationId") String reconciliationId) { - return AjaxResult.success(reconciliationApplicationService.synchronousNc(reconciliationId)); + try{ + return AjaxResult.success(reconciliationApplicationService.synchronousNc(reconciliationId));} + catch (Exception e){ + e.printStackTrace(); + return AjaxResult.error(e.getMessage()); + } } /** @@ -283,7 +288,13 @@ public class ReconciliationApi extends BaseController{ @GetMapping(value = "/synchronousNcSK") public AjaxResult synchronousNcSK(@RequestParam(name="reconciliationId") String reconciliationId) { - return AjaxResult.success(reconciliationApplicationService.synchronousNcSK(reconciliationId)); + try{ + return AjaxResult.success(reconciliationApplicationService.synchronousNcSK(reconciliationId)); + } catch (Exception e){ + e.printStackTrace(); + return AjaxResult.error(e.getMessage()); + } + } } diff --git a/mhd_finance/src/main/resources/mapper/tmsReceipt/TmsReceiptMapper.xml b/mhd_finance/src/main/resources/mapper/tmsReceipt/TmsReceiptMapper.xml index 02e08049e..bdbb3c5b8 100644 --- a/mhd_finance/src/main/resources/mapper/tmsReceipt/TmsReceiptMapper.xml +++ b/mhd_finance/src/main/resources/mapper/tmsReceipt/TmsReceiptMapper.xml @@ -37,7 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select id, top_organization_id,organization_id,organization_name,department_name,settlement_party_name,receive_payment_number, receive_payment_amount, assignable_amount,assignment_status,credit_amount,credit_reason, receive_payment_time, serial_number,receive_voucher_url, - remark, account_name, account_information, create_by,create_by_name, create_time, update_by,update_by_name, update_time, del_flag from tms_receipt + remark, account_name, account_information, create_by,create_by_name, create_time, update_by,update_by_name, update_time, del_flag,SETTLEMENT_CURRENCY from tms_receipt diff --git a/mhd_product/pom.xml b/mhd_product/pom.xml index 317ea4ab5..ca2e80a4b 100644 --- a/mhd_product/pom.xml +++ b/mhd_product/pom.xml @@ -134,6 +134,11 @@ minio 8.4.3 + + com.huaweicloud + esdk-obs-java + 3.25.10 + com.squareup.okhttp3 okhttp diff --git a/mhd_product/src/main/java/com/linke/product/infrastructure/obs/FileController.java b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/FileController.java new file mode 100644 index 000000000..8b0b8b763 --- /dev/null +++ b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/FileController.java @@ -0,0 +1,31 @@ +package com.linke.product.infrastructure.obs; +import com.mhd.common.core.web.domain.AjaxResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +@RestController +@RequestMapping("/api/file") +public class FileController { + + @Autowired + private FileStorageService fileStorageService; + + @PostMapping("/upload") + public AjaxResult uploadFile(@RequestParam("file") MultipartFile file) { + String fileKey = fileStorageService.uploadFile(file); + return AjaxResult.success(fileKey); + } + + @GetMapping("/url") + public AjaxResult getFileUrl(@RequestParam String fileKey) { + String fileUrl = fileStorageService.getFileUrl(fileKey); + return AjaxResult.success(fileUrl); + } + + @DeleteMapping + public AjaxResult deleteFile(@RequestParam String fileKey) { + boolean result = fileStorageService.deleteFile(fileKey); + return AjaxResult.success(result); + } +} \ No newline at end of file diff --git a/mhd_product/src/main/java/com/linke/product/infrastructure/obs/FileStorageService.java b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/FileStorageService.java new file mode 100644 index 000000000..26ccc99a0 --- /dev/null +++ b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/FileStorageService.java @@ -0,0 +1,37 @@ +package com.linke.product.infrastructure.obs; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; + +public interface FileStorageService { + /** + * 文件上传 + */ + String uploadFile(MultipartFile file); + + /** + * 文件上传(指定路径) + */ + String uploadFile(String filePath, MultipartFile file); + + /** + * 获取文件访问URL + */ + String getFileUrl(String fileKey); + + /** + * 下载文件 + */ + InputStream downloadFile(String fileKey); + + /** + * 删除文件 + */ + boolean deleteFile(String fileKey); + + /** + * 判断文件是否存在 + */ + boolean fileExists(String fileKey); +} \ No newline at end of file diff --git a/mhd_product/src/main/java/com/linke/product/infrastructure/obs/HuaweiObsService.java b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/HuaweiObsService.java new file mode 100644 index 000000000..a3b52c81d --- /dev/null +++ b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/HuaweiObsService.java @@ -0,0 +1,198 @@ +package com.linke.product.infrastructure.obs; +import com.mhd.common.core.utils.StringUtils; +import com.obs.services.ObsClient; +import com.obs.services.model.HttpMethodEnum; +import com.obs.services.model.ObsObject; +import com.obs.services.model.TemporarySignatureRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.io.InputStream; +import java.util.UUID; + +@Slf4j +@Service +public class HuaweiObsService implements FileStorageService { + + /*@Autowired + private ObsClient obsClient;*/ + + @Autowired + private ObsProperties obsProperties; + + private String bucketName; + + private String folder = "mhd"; + + @PostConstruct + public void init() { + this.bucketName = obsProperties.getBucketName(); + } + + @Override + public String uploadFile(MultipartFile file) { + String originalFilename = file.getOriginalFilename(); + String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); + String fileKey = folder + "/" + UUID.randomUUID().toString() + fileExtension; + return uploadFile(fileKey, file); + } + + @Override + public String uploadFile(String fileKey, MultipartFile file) { + ObsClient obsClient = null; + try { + obsClient = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretKey(), obsProperties.getEndpoint()); + // 上传文件到OBS + obsClient.putObject(bucketName, fileKey, file.getInputStream()); + + log.info("文件上传成功: {}", fileKey); + return fileKey; + } catch (Exception e) { + log.error("文件上传失败: {}", fileKey, e); + throw new RuntimeException("文件上传失败", e); + } finally { + if (obsClient != null) { + try { + obsClient.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + @Override + public String getFileUrl(String fileKey) { + return generateTemporaryUrl(fileKey,60*60); + } + + /** + * 生成指定有效期的临时URL + */ + public String generateTemporaryUrl(String objectKey, long expireSeconds) { + ObsClient obsClient = null; + try { + obsClient = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretKey(), obsProperties.getEndpoint()); + TemporarySignatureRequest request = new TemporarySignatureRequest( + HttpMethodEnum.GET, + expireSeconds + ); + request.setBucketName(bucketName); + request.setObjectKey(objectKey); + + return obsClient.createTemporarySignature(request).getSignedUrl(); + } finally { + if (obsClient != null) { + try { + obsClient.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + @Override + public InputStream downloadFile(String fileKey) { + ObsClient obsClient = null; + try { + obsClient = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretKey(), obsProperties.getEndpoint()); + ObsObject obsObject = obsClient.getObject(bucketName, fileKey); + return obsObject.getObjectContent(); + } catch (Exception e) { + log.error("文件下载失败: {}", fileKey, e); + throw new RuntimeException("文件下载失败", e); + } finally { + if (obsClient != null) { + try { + obsClient.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + @Override + public boolean deleteFile(String fileKey) { + ObsClient obsClient = null; + try { + obsClient = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretKey(), obsProperties.getEndpoint()); + obsClient.deleteObject(bucketName, fileKey); + log.info("文件删除成功: {}", fileKey); + return true; + } catch (Exception e) { + log.error("文件删除失败: {}", fileKey, e); + return false; + } finally { + if (obsClient != null) { + try { + obsClient.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + @Override + public boolean fileExists(String fileKey) { + ObsClient obsClient = null; + try { + obsClient = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretKey(), obsProperties.getEndpoint()); + return obsClient.doesObjectExist(bucketName, fileKey); + } catch (Exception e) { + log.error("检查文件存在失败: {}", fileKey, e); + return false; + } finally { + if (obsClient != null) { + try { + obsClient.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + /** + * 分片上传(大文件) + */ + /*public String multipartUpload(String fileKey, MultipartFile file) { + try { + // 初始化分片上传 + String uploadId = obsClient.initiateMultipartUpload(bucketName, fileKey).getUploadId(); + + // 计算分片数量(每片5MB) + long partSize = 5 * 1024 * 1024L; + long fileSize = file.getSize(); + int partCount = (int) (fileSize / partSize); + if (fileSize % partSize != 0) { + partCount++; + } + + // 上传分片 + for (int i = 0; i < partCount; i++) { + long startPos = i * partSize; + long curPartSize = (i + 1 == partCount) ? (fileSize - startPos) : partSize; + + InputStream inputStream = file.getInputStream(); + inputStream.skip(startPos); + + obsClient.uploadPart(bucketName, fileKey, uploadId, i + 1, inputStream, curPartSize); + } + + // 完成分片上传 + obsClient.completeMultipartUpload(bucketName, fileKey, uploadId); + + log.info("分片上传成功: {}", fileKey); + return fileKey; + } catch (Exception e) { + log.error("分片上传失败: {}", fileKey, e); + throw new RuntimeException("文件上传失败", e); + } + }*/ +} \ No newline at end of file diff --git a/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsBucketInitializer.java b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsBucketInitializer.java new file mode 100644 index 000000000..c575ac57e --- /dev/null +++ b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsBucketInitializer.java @@ -0,0 +1,128 @@ +package com.linke.product.infrastructure.obs; +import com.obs.services.ObsClient; +import com.obs.services.exception.ObsException; +import com.obs.services.model.BucketCors; +import com.obs.services.model.BucketCorsRule; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Component +public class ObsBucketInitializer { + + @Autowired + private ObsClient obsClient; + + @Autowired + private ObsProperties obsProperties; + + private static final String BUCKET_PREFIX = "diglog"; + + /** + * 应用启动时自动创建并配置桶 + */ + //@PostConstruct + public void initBucket() { + // 根据环境生成桶名称,如:diglog-dev, diglog-test, diglog-prod + //String env = getEnvironment(); + String bucketName = BUCKET_PREFIX; + + try { + // 检查桶是否存在 + boolean exists = obsClient.headBucket(bucketName); + + if (!exists) { + // 创建桶 + obsClient.createBucket(bucketName); + log.info("创建OBS桶成功: {}", bucketName); + + // 配置桶的CORS(跨域资源共享) + configureBucketCors(bucketName); + + // 配置生命周期规则(可选) + //configureLifecycle(bucketName); + + // 配置访问日志(可选) + //configureAccessLog(bucketName); + } else { + log.info("OBS桶已存在: {}", bucketName); + } + + // 更新配置中的桶名称 + obsProperties.setBucketName(bucketName); + + } catch (ObsException e) { + log.error("OBS桶操作失败: {}", e.getErrorMessage(), e); + throw new RuntimeException("OBS桶初始化失败", e); + } + } + + /** + * 配置CORS规则 + */ + private void configureBucketCors(String bucketName) { + BucketCors cors = new BucketCors(); + List rules = new ArrayList<>(); + + BucketCorsRule rule = new BucketCorsRule(); + rule.getAllowedHeader().add("*"); + rule.getAllowedMethod().add("GET"); + rule.getAllowedMethod().add("PUT"); + rule.getAllowedMethod().add("POST"); + rule.getAllowedMethod().add("DELETE"); + rule.getAllowedMethod().add("HEAD"); + rule.getAllowedOrigin().add("*"); + rule.getExposeHeader().add("*"); + rule.setMaxAgeSecond(3600); + + rules.add(rule); + cors.setRules(rules); + + obsClient.setBucketCors(bucketName, cors); + log.info("配置桶CORS规则: {}", bucketName); + } + + /** + * 配置生命周期规则 + */ + /*private void configureLifecycle(String bucketName) { + // 示例:30天后转为低频访问,365天后删除 + String lifecycleConfig = + "" + + " " + + " transition-and-expiration-rule" + + " " + + " Enabled" + + " " + + " 30" + + " WARM" + + " " + + " " + + " 365" + + " " + + " " + + ""; + + obsClient.setBucketLifecycle(bucketName, lifecycleConfig); + log.info("配置桶生命周期规则: {}", bucketName); + }*/ + + /** + * 获取当前环境 + */ + /*private String getEnvironment() { + // 从配置文件或系统变量获取环境 + String env = System.getProperty("spring.profiles.active", + System.getenv("SPRING_PROFILES_ACTIVE")); + + if (env == null || env.isEmpty()) { + env = "dev"; // 默认开发环境 + } + + return env.toLowerCase(); + }*/ +} \ No newline at end of file diff --git a/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsConfig.java b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsConfig.java new file mode 100644 index 000000000..028fbd8dc --- /dev/null +++ b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsConfig.java @@ -0,0 +1,37 @@ +package com.linke.product.infrastructure.obs; +import com.mhd.common.core.utils.StringUtils; +import com.obs.services.ObsClient; +import com.obs.services.ObsConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ObsConfig { + + @Bean + public ObsClient obsClient(ObsProperties obsProperties) { + // 创建配置实例 + ObsConfiguration config = new ObsConfiguration(); + config.setSocketTimeout(obsProperties.getSocketTimeout()); + config.setConnectionTimeout(obsProperties.getConnectionTimeout()); + config.setEndPoint(obsProperties.getEndpoint()); + + // 创建ObsClient实例 + if (StringUtils.isNotBlank(obsProperties.getSecurityToken())) { + // 使用临时安全令牌 + return new ObsClient( + obsProperties.getAccessKey(), + obsProperties.getSecretKey(), + obsProperties.getSecurityToken(), + config + ); + } else { + // 使用永久AK/SK + return new ObsClient( + obsProperties.getAccessKey(), + obsProperties.getSecretKey(), + config + ); + } + } +} \ No newline at end of file diff --git a/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsProperties.java b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsProperties.java new file mode 100644 index 000000000..f22636404 --- /dev/null +++ b/mhd_product/src/main/java/com/linke/product/infrastructure/obs/ObsProperties.java @@ -0,0 +1,23 @@ +package com.linke.product.infrastructure.obs; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "huawei.obs") +@Data +public class ObsProperties { + private String accessKey; + private String secretKey; + private String endpoint; + private String bucketName; + private String securityToken; + private String region; + private String cdnDomain; + private int maxConnections = 100; + private int socketTimeout = 30000; + private int connectionTimeout = 10000; + private int idleConnectionTime = 30000; + + // getters and setters +} \ No newline at end of file diff --git a/mhd_product/src/main/java/com/linke/product/interfaces/facade/menu/MenuApi.java b/mhd_product/src/main/java/com/linke/product/interfaces/facade/menu/MenuApi.java index 26b266a6d..3da528ec9 100644 --- a/mhd_product/src/main/java/com/linke/product/interfaces/facade/menu/MenuApi.java +++ b/mhd_product/src/main/java/com/linke/product/interfaces/facade/menu/MenuApi.java @@ -1,10 +1,13 @@ package com.linke.product.interfaces.facade.menu; +import cn.hutool.core.io.resource.InputStreamResource; import cn.hutool.core.util.StrUtil; import com.linke.product.application.service.menu.MenuApplicationService; import com.linke.product.domain.menu.entity.Menu; import com.linke.product.domain.menu.repository.po.MenuPo; import com.linke.product.domain.util.Base64Util; +import com.linke.product.infrastructure.obs.FileStorageService; +import com.linke.product.infrastructure.obs.ObsProperties; import com.linke.product.interfaces.assemble.menu.MenuAssembler; import com.linke.product.interfaces.dto.menu.MenuDto; import com.mhd.common.core.domain.po.MenuVo; @@ -19,11 +22,20 @@ import com.mhd.common.log.annotation.Log; import com.mhd.common.log.enums.BusinessType; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.model.LoginUser; +import com.obs.services.ObsClient; +import com.obs.services.model.GetObjectRequest; +import com.obs.services.model.ObsObject; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import javax.annotation.PostConstruct; import java.io.File; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -41,6 +53,23 @@ public class MenuApi extends BaseController { @Autowired private MenuApplicationService menuApplicationService; + @Autowired + private FileStorageService fileStorageService; + + @Autowired + private ObsClient obsClient; + + @Autowired + private ObsProperties obsProperties; + + private String bucketName; + + private String folder = "mhd"; + + @PostConstruct + public void init() { + this.bucketName = obsProperties.getBucketName(); + } /** * 查询菜单集合 @@ -144,7 +173,7 @@ public class MenuApi extends BaseController { * 文件上传到oss * */ - @PostMapping("/upload") + /*@PostMapping("/upload") public AjaxResult upload(@RequestParam("file") MultipartFile file) { File fileUpload = null; if (!file.isEmpty()) @@ -164,6 +193,18 @@ public class MenuApi extends BaseController { } //return AjaxResult.success(menuApplicationService.uploadOss(fileUpload)); return AjaxResult.success(menuApplicationService.uploadMinio(file)); + }*/ + + @PostMapping("/upload") + public AjaxResult uploadFile(@RequestParam("file") MultipartFile file) { + String fileKey = fileStorageService.uploadFile(file); + return AjaxResult.success(fileKey); + } + + @GetMapping("/url") + public AjaxResult getFileUrl(@RequestParam String fileKey) { + String fileUrl = fileStorageService.getFileUrl(fileKey); + return AjaxResult.success(fileUrl); } @PostMapping("/uploadFeign") @@ -191,7 +232,7 @@ public class MenuApi extends BaseController { * 文件批量上传到oss * */ - @PostMapping("/batchUpload") + /*@PostMapping("/batchUpload") public AjaxResult batchUpload(@RequestParam("files") List files) { if (files == null || files.size() == 0) { return AjaxResult.error("上传文件不能为空"); @@ -221,6 +262,106 @@ public class MenuApi extends BaseController { } return AjaxResult.success(fileUrls); + }*/ + + + @PostMapping("/batchUpload") + public AjaxResult batchUpload(@RequestParam("files") List files) { + if (files == null || files.size() == 0) { + return AjaxResult.error("上传文件不能为空"); + } + List fileUrls = new ArrayList<>(); + for (MultipartFile multipartFile : files) { + String fileKey = fileStorageService.uploadFile(multipartFile); + fileUrls.add(fileKey); + } + + return AjaxResult.success(fileUrls); + } + + @GetMapping("/download") + public ResponseEntity downloadFromOBS( + @RequestParam String obsUrl, + @RequestParam String filename) { + + try { + // 1. 连接到OBS临时URL + URL url = new URL(obsUrl); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + // 2. 获取输入流 + InputStream inputStream = connection.getInputStream(); + + // 3. 设置响应头 + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=\"" + filename + "\""); + headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate"); + headers.add(HttpHeaders.PRAGMA, "no-cache"); + headers.add(HttpHeaders.EXPIRES, "0"); + + // 4. 根据文件类型设置Content-Type + String contentType = connection.getContentType(); + MediaType mediaType = contentType != null ? + MediaType.valueOf(contentType) : + MediaType.APPLICATION_OCTET_STREAM; + + // 5. 返回流式响应 + return ResponseEntity.ok() + .headers(headers) + .contentType(mediaType) + .body(new InputStreamResource(inputStream)); + + } catch (Exception e) { + throw new RuntimeException("下载文件失败", e); + } + } + + /** + * 方法2:使用StreamingResponseBody(更灵活) + */ + @GetMapping("/download-streaming") + public ResponseEntity downloadStreaming( + @RequestParam String bucketName, + @RequestParam String objectKey, + @RequestParam String filename) { + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=\"" + filename + "\"") + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(outputStream -> { + ObsClient obsClient1 = null; + try { + System.out.println( + "AccessKey:" + obsProperties.getAccessKey() + + "SecretKey:" + obsProperties.getSecretKey() + + "Endpoint:" + obsProperties.getEndpoint() + ); + logger.error( + "AccessKey:" + obsProperties.getAccessKey() + + "SecretKey:" + obsProperties.getSecretKey() + + "Endpoint:" + obsProperties.getEndpoint() + ); + obsClient1 = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretKey(), obsProperties.getEndpoint()); + GetObjectRequest request = new GetObjectRequest(bucketName, objectKey); + ObsObject obsObject = obsClient1.getObject(request); + + try (InputStream inputStream = obsObject.getObjectContent()) { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + outputStream.flush(); + } + } finally { + if (obsClient1 != null) { + obsClient1.close(); + } + } + }); } diff --git a/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/CreateMaterialCommand.java b/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/CreateMaterialCommand.java index a907e2d2a..97a54b2fd 100644 --- a/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/CreateMaterialCommand.java +++ b/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/CreateMaterialCommand.java @@ -3,18 +3,19 @@ package com.linke.transport.application.service.warehouse.material.command; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; -import java.math.BigDecimal; +import lombok.Data; + import javax.validation.constraints.DecimalMin; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import lombok.Data; +import java.math.BigDecimal; @Data @ApiModel(description = "创建物料") public class CreateMaterialCommand { @ApiModelProperty("货主Id") - @NotNull(message = "货主Id不可以为空") + //@NotNull(message = "货主Id不可以为空") private Long ownerId; @ApiModelProperty("分类") @@ -58,4 +59,4 @@ public class CreateMaterialCommand { private String topOrganizationId; /**组织相关*/ private String organizationId; -} +} \ No newline at end of file diff --git a/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/MaterialCommandService.java b/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/MaterialCommandService.java index 92c05251d..834f0e0fb 100644 --- a/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/MaterialCommandService.java +++ b/mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/MaterialCommandService.java @@ -26,7 +26,10 @@ public class MaterialCommandService { * 创建物料 */ public Long handle(CreateMaterialCommand command) { - String shipper = userServiceFeignService.findUserNameByUserId(command.getOwnerId(),"物料模块-调用RPC错误"); + String shipper = null; + if (command.getOwnerId() != null) { + shipper = userServiceFeignService.findUserNameByUserId(command.getOwnerId(),"物料模块-调用RPC错误"); + } Material material = Material.create( command.getOwnerId(), shipper, command.getCategory(), @@ -50,7 +53,10 @@ public class MaterialCommandService { public void handle(UpdateMaterialCommand command) { Material material = materialRepository.findById(command.getId()) .orElseThrow(() -> new MaterialDomainException("物料不存在")); - String shipper = userServiceFeignService.findUserNameByUserId(command.getOwnerId(),"物料模块-调用RPC错误"); + String shipper = ""; + if (command.getOwnerId() != null) { + shipper = userServiceFeignService.findUserNameByUserId(command.getOwnerId(),"物料模块-调用RPC错误"); + } material.update(command.getOwnerId(),shipper, command.getCategory(), command.getName(), @@ -84,4 +90,4 @@ public class MaterialCommandService { public int updateOwnerNameByOwnerId(Long ownerId, String ownerName) { return materialRepository.updateOwnerNameByOwnerId(ownerId, ownerName); } -} +} \ No newline at end of file