TRX před 1 rokem
rodič
revize
fdf2a9c75a
31 změnil soubory, kde provedl 740 přidání a 188 odebrání
  1. 18 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/base/CodeParam.java
  2. 3 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/org/RegisterUserAccountParam.java
  3. 1 3
      FullCardClient/src/main/java/com/zhongshu/card/client/model/org/UserCountAddParam.java
  4. 1 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoModel.java
  5. 26 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoPoolBind2OrgUserParam.java
  6. 1 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoPoolBind2UserParam.java
  7. 0 3
      FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoSearch.java
  8. 19 1
      FullCardClient/src/main/java/com/zhongshu/card/client/service/school/CardInfoService.java
  9. 8 6
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/org/OrganizationUserController.java
  10. 40 6
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/orgManager/CardController.java
  11. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/orgManager/CardInfoPoolController.java
  12. 2 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java
  13. 2 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/CardInfoDao.java
  14. 4 4
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/CardInfoPoolDao.java
  15. 2 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/extend/CardInfoDaoExtend.java
  16. 1 6
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/impl/CardInfoDaoImpl.java
  17. 2 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/org/OrganizationUser.java
  18. 5 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/school/CardInfo.java
  19. 7 11
      FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/ApiRequestService.java
  20. 0 85
      FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/apiConf/APIResponseModel.java
  21. 0 26
      FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/apiConf/ApiConfParam.java
  22. 5 5
      FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/conf/IotCenterAPIConfig.java
  23. 1 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissIotService.java
  24. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/openAPI/OpenAPIRegisterService.java
  25. 217 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/openAPI/OpenApiRequestService.java
  26. 21 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/OrganizationUserServiceImpl.java
  27. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/ExpenseFlowServiceImpl.java
  28. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/RequestInfoService.java
  29. 4 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/CardInfoPoolService.java
  30. 247 26
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/CardInfoServiceImpl.java
  31. 99 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/util/AesUtils.java

+ 18 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/base/CodeParam.java

@@ -0,0 +1,18 @@
+package com.zhongshu.card.client.model.base;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author TRX
+ * @date 2024/10/14
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CodeParam extends ProjectOidParam {
+
+    private String code;
+
+}

+ 3 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/org/RegisterUserAccountParam.java

@@ -38,6 +38,9 @@ public class RegisterUserAccountParam {
         return password;
     }
 
+    @Schema(description = "头像")
+    private String profilePic;
+
     @Schema(description = "用户手机号")
     @NotEmpty(message = "phone不能为空")
     private String phone;

+ 1 - 3
FullCardClient/src/main/java/com/zhongshu/card/client/model/org/UserCountAddParam.java

@@ -44,9 +44,6 @@ public class UserCountAddParam extends SuperParam {
     @Schema(description = "职位")
     private String positionId;
 
-    @Schema(description = "人脸照片")
-    private List<String> faceImages;
-
     @Schema(description = "用户在机构的类型")
     private OrganizationUserType userType = OrganizationUserType.Teacher;
 
@@ -64,4 +61,5 @@ public class UserCountAddParam extends SuperParam {
 
     @Schema(description = "是否是管理员")
     private Boolean isAdmin = Boolean.FALSE;
+
 }

+ 1 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoModel.java

@@ -15,6 +15,7 @@ import lombok.Data;
  */
 @Data
 public class CardInfoModel extends SuperModel {
+
     @Schema(description = "卡片名称")
     private String name;
 

+ 26 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoPoolBind2OrgUserParam.java

@@ -0,0 +1,26 @@
+package com.zhongshu.card.client.model.school;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author TRX
+ * @date 2024/9/10
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CardInfoPoolBind2OrgUserParam {
+
+    @Schema(description = "卡池卡片ID")
+    @NotEmpty(message = "卡池卡片ID不能为空")
+    private String poolId;
+
+    @Schema(description = "机构用户id")
+    @NotEmpty(message = "id不能为空")
+    private String id;
+
+}

+ 1 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoPoolBind2UserParam.java

@@ -22,4 +22,5 @@ public class CardInfoPoolBind2UserParam {
     @Schema(description = "用户userId")
     @NotEmpty(message = "userId不能为空")
     private String userId;
+
 }

+ 0 - 3
FullCardClient/src/main/java/com/zhongshu/card/client/model/school/CardInfoSearch.java

@@ -17,9 +17,6 @@ import org.hibernate.internal.build.AllowPrintStacktrace;
 @NoArgsConstructor
 public class CardInfoSearch extends SuperSearch {
 
-    @Schema(description = "学校oid")
-    private String schoolOid;
-
     @Schema(description = "卡片名称")
     private String name;
 

+ 19 - 1
FullCardClient/src/main/java/com/zhongshu/card/client/service/school/CardInfoService.java

@@ -1,9 +1,13 @@
 package com.zhongshu.card.client.service.school;
 
+import com.zhongshu.card.client.model.base.OidModel;
 import com.zhongshu.card.client.model.school.*;
 import com.github.microservice.net.ResultContent;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
@@ -19,11 +23,16 @@ public interface CardInfoService {
     // 从卡池选择卡片绑定到个人
     ResultContent bindCardFromPool(String poolId, String userId);
 
+    // 绑定
+    ResultContent bindCardFromPoolByOrgId(String poolId, String id);
+
     // 解绑用户卡片
     ResultContent unBindCard(String id);
 
     ResultContent<List<CardInfoModel>> getCurrentUserOrgAll(String oid);
 
+    ResultContent<List<CardInfoModel>> getOrgCardList(String id);
+
     List<CardInfoModel> getUserOrgAllCard(String userId, String oid);
 
     // 删除卡片
@@ -49,7 +58,7 @@ public interface CardInfoService {
 
     //----------------------------园区卡片操作 start ------------------------
 
-    ResultContent<Page<CardInfoPoolModel>> page(CardInfoSearch param, Pageable pageable);
+    ResultContent<Page<CardInfoModel>> page(CardInfoSearch param, Pageable pageable);
 
     // 通过数据ID挂失(园区操作)
     ResultContent lossById(String id);
@@ -63,4 +72,13 @@ public interface CardInfoService {
     // 恢复作废
     ResultContent restoreCardCancel(String id);
 
+    ResultContent<ImportResultModel> importCard(
+            HttpServletRequest request,
+            HttpServletResponse response,
+            MultipartFile file,
+            OidModel param);
+
+    void exportProjectCard(HttpServletRequest request, HttpServletResponse response,
+            CardInfoSearch param);
+
 }

+ 8 - 6
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/org/OrganizationUserController.java

@@ -5,15 +5,14 @@ import com.github.microservice.auth.security.annotations.ResourceAuth;
 import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.card.client.model.base.IDParam;
-import com.zhongshu.card.client.model.base.OidModel;
 import com.zhongshu.card.client.model.base.ProjectOidParam;
-import com.zhongshu.card.client.model.org.*;
+import com.zhongshu.card.client.model.org.OrgUserDetailParam;
+import com.zhongshu.card.client.model.org.OrganizationUserModel;
+import com.zhongshu.card.client.model.org.OrganizationUserSearch;
+import com.zhongshu.card.client.model.org.UserCountAddParam;
 import com.zhongshu.card.client.model.orgModel.OrgBindUserAllParam;
-import com.zhongshu.card.client.model.project.ProjectSaveParam;
 import com.zhongshu.card.client.model.school.ImportResultModel;
-import com.zhongshu.card.client.service.org.OrganizationService;
 import com.zhongshu.card.client.service.org.UserAccountService;
-import com.zhongshu.card.server.core.model.org.OrgBindUserParam;
 import com.zhongshu.card.server.core.service.org.OrganizationUserServiceImpl;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -31,7 +30,6 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.Valid;
 import java.io.IOException;
-import java.util.List;
 
 @RestController
 @RequestMapping("organizationUser")
@@ -54,6 +52,10 @@ public class OrganizationUserController {
     @Operation(summary = "机构保存用户", description = "机构保存用户")
     @RequestMapping(value = {"saveOrgUser"}, method = {RequestMethod.POST})
     public ResultContent saveOrgUser(@RequestBody UserCountAddParam param) {
+        Assert.hasText(param.getCode(), "code不能为空");
+        Assert.hasText(param.getProjectOid(), "projectOid不能为空");
+        Assert.hasText(param.getOid(), "oid不能为空");
+        Assert.hasText(param.getPhone(), "phone不能为空");
         return organizationUserService.saveOrgUser(param);
     }
 

+ 40 - 6
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/orgManager/CardController.java

@@ -13,13 +13,18 @@ import com.zhongshu.card.client.service.school.SchoolUserService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.web.PageableDefault;
+import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.Valid;
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -47,6 +52,13 @@ public class CardController {
         return cardInfoService.getCurrentUserOrgAll(param.getOid());
     }
 
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "查询机构用户卡变列表", description = "查询机构用户卡变列表")
+    @RequestMapping(value = {"getOrgCardList"}, method = {RequestMethod.POST})
+    public ResultContent<List<CardInfoModel>> getOrgCardList(@RequestBody @Valid IDParam param) {
+        return cardInfoService.getOrgCardList(param.getId());
+    }
+
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "得到当前用户所有卡片", description = "得到当前用户所有卡片(不区分机构)")
     @RequestMapping(value = {"getCurrentUserAllCard"}, method = {RequestMethod.GET})
@@ -57,8 +69,7 @@ public class CardController {
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "得到指定用户在机构的所有卡片", description = "得到指定用户在学校的所有卡片")
     @RequestMapping(value = {"getUserOrgAllCard"}, method = {RequestMethod.POST})
-    public ResultContent<List<CardInfoModel>> getUserOrgAllCard(
-            @RequestBody @Valid OrgUserDetailParam param) {
+    public ResultContent<List<CardInfoModel>> getUserOrgAllCard(@RequestBody @Valid OrgUserDetailParam param) {
         List<CardInfoModel> cardInfoModels = cardInfoService.getUserOrgAllCard(param.getUserId(), param.getOid());
         return ResultContent.buildSuccess(cardInfoModels);
     }
@@ -116,9 +127,7 @@ public class CardController {
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "code查询卡片详情", description = "code查询卡片详情")
     @RequestMapping(value = {"getCardDetailByCode"}, method = {RequestMethod.GET})
-    public ResultContent<CardInfoSimpleModel> getCardDetailByCode(
-            @Parameter(name = "code", description = "code", required = true)
-            @RequestParam(name = "code") String code) {
+    public ResultContent<CardInfoSimpleModel> getCardDetailByCode(@Parameter(name = "code", description = "code", required = true) @RequestParam(name = "code") String code) {
         return cardInfoService.getCardDetailByCode(code);
     }
 
@@ -126,7 +135,7 @@ public class CardController {
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "卡片列表-分页查询(园区使用)", description = "卡片列表-分页查询")
     @RequestMapping(value = {"page"}, method = {RequestMethod.POST})
-    public ResultContent<Page<CardInfoPoolModel>> page(
+    public ResultContent<Page<CardInfoModel>> page(
             @Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
             @Parameter(required = false) CardInfoSearch param) {
         return cardInfoService.page(param, pageable);
@@ -169,6 +178,13 @@ public class CardController {
         return cardInfoService.bindCardFromPool(param.getPoolId(), param.getUserId());
     }
 
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "从卡池选择卡片绑定机构用户", description = "从卡池选择卡片绑定机构用户")
+    @RequestMapping(value = {"bindCardFromPoolByOrgId"}, method = {RequestMethod.POST})
+    public ResultContent bindCardFromPoolByOrgId(@RequestBody @Valid CardInfoPoolBind2OrgUserParam param) {
+        return cardInfoService.bindCardFromPoolByOrgId(param.getPoolId(), param.getId());
+    }
+
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "解除绑定", description = "解除绑定")
     @RequestMapping(value = {"unBindCard"}, method = {RequestMethod.POST})
@@ -182,4 +198,22 @@ public class CardController {
         return cardInfoService.bindCardFromPool(param.getPoolId(), param.getUserId());
     }
 
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @RequestMapping(value = "importCard", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, method = RequestMethod.POST)
+    @Operation(summary = "导入用户和卡片的关系", description = "导入用户和卡片的关系")
+    public ResultContent<ImportResultModel> importCard(HttpServletRequest request, HttpServletResponse response, @RequestPart("file") MultipartFile file, OidModel param) throws IOException {
+        if (file == null || file.isEmpty()) {
+            return ResultContent.buildFail("文件不能为空");
+        }
+        return cardInfoService.importCard(request, response, file, param);
+    }
+
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @RequestMapping(value = "exportProjectCard", method = RequestMethod.POST)
+    @Operation(summary = "导出项目卡片", description = "导出项目卡片")
+    public void exportProjectCard(
+            HttpServletRequest request, HttpServletResponse response, CardInfoSearch param) throws IOException {
+        cardInfoService.exportProjectCard(request, response, param);
+    }
+
 }

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/orgManager/CardInfoPoolController.java

@@ -126,7 +126,7 @@ public class CardInfoPoolController {
         cardInfoPoolService.exportProjectCard(request, response, param);
     }
 
-    @Operation(summary = "池卡搜索卡片", description = "池卡搜索卡片")
+    @Operation(summary = "池卡搜索卡片(可用)", description = "池卡搜索卡片")
     @RequestMapping(value = {"queryPoolCard"}, method = {RequestMethod.POST})
     public ResultContent<List<CardInfoPoolSimpleModel>> queryPoolCard(
             @RequestBody @Valid CardInfoPoolQueryParam param) {

+ 2 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java

@@ -44,4 +44,6 @@ public interface OrganizationUserDao extends MongoDao<OrganizationUser>, Organiz
 
     List<OrganizationUser> findByUserAndAuthType(UserAccount userAccount, AuthType authType);
 
+    List<OrganizationUser> findByUserIdAndProjectOidAndIsOrg(String userId, String projectOid, Boolean isOrg);
+
 }

+ 2 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/CardInfoDao.java

@@ -23,5 +23,7 @@ public interface CardInfoDao extends MongoDao<CardInfo>, CardInfoDaoExtend {
 
     List<CardInfo> findByUserId(String userId);
 
+    List<CardInfo> findByUserIdAndProjectOid(String userId, String projectOid);
+
     void deleteByUserIdAndOid(String userId, String oid);
 }

+ 4 - 4
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/CardInfoPoolDao.java

@@ -1,6 +1,7 @@
 package com.zhongshu.card.server.core.dao.school;
 
 import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.card.client.type.CardCancelState;
 import com.zhongshu.card.server.core.dao.school.extend.CardInfoPoolDaoExtend;
 import com.zhongshu.card.server.core.domain.school.Area;
 import com.zhongshu.card.server.core.domain.school.CardInfoPool;
@@ -23,10 +24,9 @@ public interface CardInfoPoolDao extends MongoDao<CardInfoPool>, CardInfoPoolDao
 
     CardInfoPool findTopByCodeAndProjectOid(String code, String projectOid);
 
-    // 模糊搜索10张卡片
-    List<CardInfoPool> findTop10BySchoolOidAndCodeLike(String schoolOid, String code);
-
-    List<CardInfoPool> findTop10ByOidAndCodeLike(String oid, String code);
+    List<CardInfoPool> findTop10ByProjectOidAndCodeLikeAndIsUsedAndCardCancelState(
+            String projectOid, String code,
+            Boolean isUsed, CardCancelState cardCancelState);
 
     boolean existsByCodeAndProjectOid(String code, String projectOid);
 

+ 2 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/extend/CardInfoDaoExtend.java

@@ -13,5 +13,7 @@ import org.springframework.data.domain.Pageable;
  * @Version: 1.0
  */
 public interface CardInfoDaoExtend {
+
     Page<CardInfo> page(Pageable pageable, CardInfoSearch param);
+
 }

+ 1 - 6
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/school/impl/CardInfoDaoImpl.java

@@ -36,16 +36,12 @@ public class CardInfoDaoImpl extends BaseImpl implements CardInfoDaoExtend {
 
     @Override
     public Page<CardInfo> page(Pageable pageable, CardInfoSearch param) {
-        Criteria criteria = new Criteria();
+        Criteria criteria = buildCriteriaNotOid(param);
 
         if (ObjectUtils.isNotEmpty(param.getProjectOid())) {
             criteria.and("projectOid").is(param.getProjectOid());
         }
 
-        if (ObjectUtils.isNotEmpty(param.getSchoolOid())) {
-            criteria.and("schoolOid").is(param.getSchoolOid());
-        }
-
         if (param.getCardType() != null) {
             criteria.and("cardType").is(param.getCardType());
         }
@@ -104,7 +100,6 @@ public class CardInfoDaoImpl extends BaseImpl implements CardInfoDaoExtend {
                     Criteria.where("phone").regex(pattern)
             );
         }
-
         criteria.and("isDelete").is(Boolean.FALSE);
         Sort sort = buildSort(param);
         Query query = Query.query(criteria);

+ 2 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/org/OrganizationUser.java

@@ -92,4 +92,6 @@ public class OrganizationUser extends SuperMain {
     @DBRef(lazy = true)
     private Department department;
 
+    @Schema(description = "是否是结构类型")
+    private Boolean isOrg = Boolean.FALSE;
 }

+ 5 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/school/CardInfo.java

@@ -5,6 +5,7 @@ import com.zhongshu.card.client.type.school.CardState;
 import com.zhongshu.card.client.type.school.CardType;
 import com.zhongshu.card.server.core.domain.base.SuperMain;
 import com.zhongshu.card.server.core.domain.org.Organization;
+import com.zhongshu.card.server.core.domain.org.OrganizationUser;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
@@ -68,4 +69,8 @@ public class CardInfo extends SuperMain {
 
     @Schema(description = "校园名称")
     private String orgName;
+
+    @Schema(description = "企业用户")
+    @DBRef(lazy = true)
+    private OrganizationUser organizationUser;
 }

+ 7 - 11
FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/ApiRequestService.java

@@ -8,10 +8,9 @@ import com.github.microservice.core.util.net.apache.HttpClientUtil;
 import com.github.microservice.core.util.net.apache.HttpModel;
 import com.github.microservice.core.util.net.apache.MethodType;
 import com.github.microservice.core.util.net.apache.ResponseModel;
-import com.github.microservice.models.hxz.TransactionInquiryResult;
+import com.github.microservice.http.APIResponseModel;
+import com.github.microservice.http.ApiConfParam;
 import com.github.microservice.models.hxz.WxPayResult;
-import com.zhongshu.card.server.core.httpRequest.apiConf.APIResponseModel;
-import com.zhongshu.card.server.core.httpRequest.apiConf.ApiConfParam;
 import com.zhongshu.card.server.core.httpRequest.conf.IotCenterAPIConfig;
 import com.zhongshu.card.server.core.httpRequest.conf.IotCenterConf;
 import com.zhongshu.card.server.core.service.base.SuperService;
@@ -19,8 +18,6 @@ import com.zhongshu.card.server.core.service.payment.RequestInfoService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.kafka.common.protocol.types.Field;
-import org.springdoc.webmvc.core.service.RequestService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -61,8 +58,8 @@ public class ApiRequestService extends SuperService {
         stopWatch.start();
         try {
             String url = iotCenterConf.getUrl() + iotCenterConf.getIotserverName() + apiConfParam.getApiName();
-            ResponseModel request = HttpClientUtil.request(HttpModel.builder()
-                    .url(url).method(apiConfParam.getMethodType()).charset("utf-8").body(data).build());
+            ResponseModel request = HttpClientUtil.request(HttpModel.builder().url(url).method(
+                    MethodType.Json).charset("utf-8").body(data).build());
             if (request.getCode() == 200) {
                 responseModel = BeanUtil.copyProperties(request.getBody(), APIResponseModel.class);
             } else {
@@ -96,16 +93,15 @@ public class ApiRequestService extends SuperService {
 
         ApiConfParam apiConfParam = new ApiConfParam();
         apiConfParam.setApiName(url);
-        apiConfParam.setMethodType(MethodType.Json);
+        apiConfParam.setMethodType(MethodType.Json.name());
 
         StopWatch stopWatch = new StopWatch();
         stopWatch.start();
         try {
             JSONObject jsonObject = JSONUtil.parseObj(JSONUtil.toJsonStr(data));
             responseModel.setParam(apiConfParam);
-            ResponseModel request = HttpClientUtil.request(HttpModel.builder()
-                    .url(apiConfParam.getApiName()).method(apiConfParam.getMethodType())
-                    .charset("utf-8").body(jsonObject).build());
+            ResponseModel request = HttpClientUtil.request(HttpModel.builder().url(apiConfParam.getApiName()).method(
+                    MethodType.Json).charset("utf-8").body(jsonObject).build());
             WxPayResult result = null;
             if (request.getCode() == 200) {
                 Object object = request.getBody();

+ 0 - 85
FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/apiConf/APIResponseModel.java

@@ -1,85 +0,0 @@
-package com.zhongshu.card.server.core.httpRequest.apiConf;
-
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.apache.commons.lang3.StringUtils;
-
-/**
- * @author TRX
- * @date 2024/6/25
- */
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-public class APIResponseModel {
-    @Schema(description = "访问是否失败")
-    private boolean failed;
-
-    @Schema(description = "访问是否成功标记")
-    private boolean success;
-
-    @Schema(description = "消息")
-    private String msg;
-
-    @Schema(description = "状态")
-    private String state;
-
-    @Schema(description = "响应内容")
-    private String content;
-
-    //----------------------------请求数据 start -----------------------
-    @Schema(description = "请求API定义")
-    private ApiConfParam param;
-
-    @Schema(description = "请求参数")
-    private Object requestData;
-
-    @Schema(description = "请求耗时:毫秒")
-    private Long millis;
-
-    public <T> T toBean(Class<T> tClass) {
-        if (content != null) {
-            return JSONUtil.toBean(content, tClass);
-        }
-        return null;
-    }
-
-    public JSONObject toJson() {
-        if (content != null) {
-            return JSONUtil.parseObj(content);
-        }
-        return null;
-    }
-
-    public boolean isSuccess() {
-        if (StringUtils.isNotEmpty(this.state) && "Fail".equals(state)) {
-            return false;
-        }
-        return success;
-    }
-
-    public boolean isFailed() {
-        return !this.isSuccess();
-    }
-
-    public void setIsFailed() {
-        this.success = Boolean.FALSE;
-        this.failed = Boolean.TRUE;
-        this.state = "Fail";
-    }
-
-    public void setIsSuccess() {
-        this.success = Boolean.TRUE;
-        this.failed = Boolean.FALSE;
-        this.state = "Success";
-    }
-
-    public void setIsFailed(String msg) {
-        this.setIsFailed();
-        this.msg = msg;
-    }
-}

+ 0 - 26
FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/apiConf/ApiConfParam.java

@@ -1,26 +0,0 @@
-package com.zhongshu.card.server.core.httpRequest.apiConf;
-
-import com.github.microservice.core.util.net.apache.MethodType;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * @author TRX
- * @date 2024/6/25
- */
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-@Builder
-public class ApiConfParam {
-
-    @Schema(description = "API名称")
-    private String apiName;
-
-    @Schema(description = "方式")
-    private MethodType methodType;
-
-}

+ 5 - 5
FullCardServer/src/main/java/com/zhongshu/card/server/core/httpRequest/conf/IotCenterAPIConfig.java

@@ -1,12 +1,12 @@
 package com.zhongshu.card.server.core.httpRequest.conf;
 
 import com.github.microservice.core.util.net.apache.MethodType;
-import com.zhongshu.card.server.core.httpRequest.apiConf.ApiConfParam;
+import com.github.microservice.http.ApiConfParam;
 
 import java.util.HashMap;
 
 /**
- * 物联网平台的 APIP诶这
+ * 物联网平台的 APIP
  *
  * @author TRX
  * @date 2024/6/25
@@ -24,10 +24,10 @@ public class IotCenterAPIConfig {
     public static final HashMap<String, ApiConfParam> map = new HashMap<>();
 
     static {
-        map.put(sendMessage, ApiConfParam.builder().apiName(sendMessage).methodType(MethodType.Json).build());
-        map.put(ping, ApiConfParam.builder().apiName(ping).methodType(MethodType.Get).build());
+        map.put(sendMessage, ApiConfParam.builder().apiName(sendMessage).methodType(MethodType.Json.name()).build());
+        map.put(ping, ApiConfParam.builder().apiName(ping).methodType(MethodType.Get.name()).build());
 
-        map.put(syncFromFullCardProjects, ApiConfParam.builder().apiName(syncFromFullCardProjects).methodType(MethodType.Json).build());
+        map.put(syncFromFullCardProjects, ApiConfParam.builder().apiName(syncFromFullCardProjects).methodType(MethodType.Json.name()).build());
 
 
     }

+ 1 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/devices/DevicePermissIotService.java

@@ -101,6 +101,7 @@ public class DevicePermissIotService {
         log.info("设备权限发生变化...");
         // 通知物联网 设备权限发生变化
 
+
     }
 
     public UserPermiss toModel(DevicePermiss devicePermiss) {

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/openAPI/OpenAPIRegisterService.java

@@ -41,7 +41,7 @@ public class OpenAPIRegisterService {
         param.setOpenApiInfo(openAPIS);
         param.setApiType(ApiType.FullCard.name());
 
-        ResultContent content = restTemplate.postForObject("http://openapiserver-wjf/openapi/manager/api/refresh", param, ResultContent.class);
+        ResultContent content = restTemplate.postForObject("http://openapiserver/openapi/manager/api/refresh", param, ResultContent.class);
         if (content == null) {
             content = ResultContent.buildSuccess();
         }

+ 217 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/openAPI/OpenApiRequestService.java

@@ -0,0 +1,217 @@
+package com.zhongshu.card.server.core.service.openAPI;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.json.JSONUtil;
+import com.github.microservice.core.helper.JsonHelper;
+import com.github.microservice.core.util.net.apache.HttpClientUtil;
+import com.github.microservice.core.util.net.apache.HttpModel;
+import com.github.microservice.core.util.net.apache.MethodType;
+import com.github.microservice.core.util.net.apache.ResponseModel;
+import com.github.microservice.http.APIResponseModel;
+import com.github.microservice.models.iot.IotSendParam;
+import com.github.microservice.models.requestModel.SuperResponseModel;
+import com.github.microservice.net.ResultContent;
+import com.zhongshu.card.client.model.payment.RequestInfoSaveParam;
+import com.zhongshu.card.client.type.payment.RequestType;
+import com.zhongshu.card.client.utils.DateUtils;
+import com.zhongshu.card.server.core.dao.org.OrganizationDao;
+import com.zhongshu.card.server.core.dao.projectAbout.ProjectIotInfoDao;
+import com.zhongshu.card.server.core.domain.org.Organization;
+import com.zhongshu.card.server.core.domain.projectAbout.ProjectIotInfo;
+import com.zhongshu.card.server.core.service.base.SuperService;
+import com.zhongshu.card.server.core.service.payment.RequestInfoService;
+import com.zhongshu.card.server.core.util.AesUtils;
+import com.zhongshu.card.server.core.util.CommonUtil;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.model.ApiConfParam;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StopWatch;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * openAPI 的请求调用
+ *
+ * @author TRX
+ * @date 2024/10/14
+ */
+@Slf4j
+@Service
+public class OpenApiRequestService extends SuperService {
+
+    @Autowired
+    private RequestInfoService requestInfoService;
+
+    @Autowired
+    private JsonHelper jsonHelper;
+
+    @Autowired
+    private OrganizationDao organizationDao;
+
+    @Autowired
+    private ProjectIotInfoDao projectIotInfoDao;
+
+    /**
+     * 请求物联网接口
+     *
+     * @param param
+     * @param projectOid
+     * @return
+     */
+    public ResultContent sendIotRequest(IotSendParam param, String projectOid) {
+        if (StringUtils.isEmpty(projectOid)) {
+            return ResultContent.buildFail("projectOid为空");
+        }
+        ProjectIotInfo projectIotInfo = projectIotInfoDao.findTopByProjectOid(projectOid);
+        if (ObjectUtils.isEmpty(projectIotInfo)) {
+            return ResultContent.buildFail(String.format("", projectOid));
+        }
+
+        return ResultContent.buildSuccess();
+    }
+
+//    /**
+//     * 银联请求
+//     *
+//     * @param url
+//     * @param data
+//     * @param tClass
+//     * @return
+//     */
+//    public SuperResponseModel requestUnionAPI(String url,
+//            Object data,
+//            Class<? extends SuperResponseModel> tClass) {
+//        RequestInfoSaveParam param = new RequestInfoSaveParam();
+//        param.setParam(data);
+//        param.setApiParam(url);
+//        param.setUserId(getCurrentUserId());
+//        SuperResponseModel responseModel = null;
+//        try {
+//            responseModel = tClass.newInstance();
+//            ApiConfParam apiConfParam = new ApiConfParam();
+//            apiConfParam.setApiName(url);
+//            apiConfParam.setMethodType(MethodType.Json);
+//            String dataJsonStr = JSONUtil.toJsonStr(data);
+//            String sign = AesUtils.signData(dataJsonStr);
+//            // 请求时间记时
+//            StopWatch stopWatch = new StopWatch();
+//            stopWatch.start();
+//
+//            String timestamp = DateUtils.paresTime(System.currentTimeMillis(), DateUtils.unionAuth);
+//            String nonce = CommonUtil.UUID();
+//            String c = String.format("%s%s%s%s", payConfig.getAppId(), timestamp, nonce, sign);
+//
+//            String signature = AesUtils.signMacSHA256(c, payConfig.getAppKey());
+//            String authorization = "OPEN-BODY-SIG AppId=" + "\"" + payConfig.getAppId() + "\""
+//                    + ",Timestamp=" + "\"" + timestamp + "\""
+//                    + ",Nonce=" + "\"" + nonce + "\""
+//                    + ",Signature=" + "\"" + signature + "\"";
+//
+//
+//            String response = "";
+//            PrintWriter out = null;
+//            BufferedReader in = null;
+//            int code = 400;
+//            try {
+//                URL realUrl = new URL(url);
+//                URLConnection conn = realUrl.openConnection();
+//                HttpURLConnection httpUrlConnection = (HttpURLConnection) conn;
+//                httpUrlConnection.setRequestProperty("Content-Type", "application/json");
+//                httpUrlConnection.setRequestProperty("authorization", authorization);
+//                httpUrlConnection.setDoOutput(true);
+//                httpUrlConnection.setDoInput(true);
+//                out = new PrintWriter(httpUrlConnection.getOutputStream());
+//                out.write(dataJsonStr);
+//                out.flush();
+//                httpUrlConnection.connect();
+//                code = httpUrlConnection.getResponseCode();
+//                in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
+//                String line;
+//                while ((line = in.readLine()) != null) {
+//                    response += line;
+//                }
+//                log.info("response: {}", response);
+//                responseModel = jsonHelper.toObject(response, tClass);
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//                responseModel.setCode(code);
+//                responseModel.setMsg(e.getMessage());
+//            } finally {
+//                try {
+//                    if (out != null) {
+//                        out.close();
+//                    }
+//                    if (in != null) {
+//                        in.close();
+//                    }
+//                } catch (Exception ex) {
+//                    ex.printStackTrace();
+//                }
+//            }
+//            String errMsg = responseModel.getErrMsg();
+//            if (StringUtils.isNotEmpty(errMsg) && !errMsg.equals("success")) {
+//                code = 400;
+//            }
+//            log.info("response: {} {}", responseModel.getErrCode(), code);
+//            responseModel.setCode(code);
+//            if (code == 504) {
+//                responseModel.setErrMsg("银联服务无法访问");
+//            }
+//            stopWatch.stop();
+//            responseModel.setMillis(stopWatch.getTotalTimeMillis());
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            responseModel.setFailed(String.format("请求出错:%s", e.getMessage()));
+//            return responseModel;
+//        }
+//        param.setMillis(responseModel.getMillis());
+//        param.setIsSuccess(responseModel.isSuccess);
+//        param.setMsg(responseModel.getMsg());
+//        param.setResponse(responseModel);
+//        param.setRequestType(RequestType.UnionFrictionlessPay);
+//        // 请求日志
+//        requestInfoService.saveRequestInfo(param);
+//        return responseModel;
+//    }
+
+
+    public APIResponseModel requestAPI(String url, Object data) {
+        APIResponseModel responseModel = new APIResponseModel();
+        try {
+            ApiConfParam apiConfParam = new ApiConfParam();
+            apiConfParam.setApiName(url);
+
+            StopWatch stopWatch = new StopWatch();
+            stopWatch.start();
+            ResponseModel request = HttpClientUtil.request(HttpModel.builder()
+                    .url(url).method(MethodType.Json).charset("utf-8").body(data).build());
+            int code = request.getCode();
+            if (code == 200) {
+                responseModel = BeanUtil.copyProperties(request.getBody(), APIResponseModel.class);
+            } else if (code == 404) {
+                responseModel.setIsFailed("404 not found");
+            } else {
+                responseModel = BeanUtil.copyProperties(request.getBody(), APIResponseModel.class);
+            }
+            responseModel.setParam(apiConfParam);
+            stopWatch.stop();
+            responseModel.setMillis(stopWatch.getTotalTimeMillis());
+        } catch (Exception e) {
+            e.printStackTrace();
+            responseModel.setIsFailed(String.format("请求出错:%s", e.getMessage()));
+            return responseModel;
+        }
+        // 记录请求日志
+        requestInfoService.addIotRequestInfo(data, responseModel);
+        return responseModel;
+    }
+
+}

+ 21 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/OrganizationUserServiceImpl.java

@@ -141,6 +141,7 @@ public class OrganizationUserServiceImpl extends SuperService {
         userAccountParam.setName(param.getName());
         userAccountParam.setCardNumber(param.getCardNumber());
         userAccountParam.setSex(param.getSex());
+        userAccountParam.setProfilePic(param.getProfilePic());
         if (temp != null && temp.getUser() != null) {
             userAccountParam.setLoginName(temp.getUser().getLoginName());
         }
@@ -197,6 +198,8 @@ public class OrganizationUserServiceImpl extends SuperService {
         }
 
         boolean isUpdate = false;
+
+        // 要绑定的机构 (不是项目)
         Organization organization = organizationDao.findTopByOid(param.getOrgOid());
         if (ObjectUtils.isEmpty(organization)) {
             return ResultContent.buildFail(String.format("机构信息不存在:%s", param.getOrgOid()));
@@ -218,7 +221,6 @@ public class OrganizationUserServiceImpl extends SuperService {
             organizationUser = organizationUserDao.findTopByOrganizationAndUser(organization, userAccount);
         }
 
-
         if (ObjectUtils.isEmpty(organizationUser)) {
             // 添加
             if (ObjectUtils.isNotEmpty(codeTemp)) {
@@ -292,6 +294,12 @@ public class OrganizationUserServiceImpl extends SuperService {
         organizationUser.setPhone(userAccount.getPhone());
         organizationUser.setName(userAccount.getName());
         organizationUser.setCardNumber(userAccount.getCardNumber());
+
+        if (organization.getAuthType() == AuthType.Project) {
+            organizationUser.setIsOrg(Boolean.FALSE);
+        } else {
+            organizationUser.setIsOrg(Boolean.TRUE);
+        }
         organizationUserDao.save(organizationUser);
 
         if (isUpdate) {
@@ -464,6 +472,18 @@ public class OrganizationUserServiceImpl extends SuperService {
         return ResultContent.buildSuccess();
     }
 
+    /**
+     * 查询用户在项目中的 绑定的机构数据列表
+     *
+     * @param userId
+     * @param projectOid
+     * @return
+     */
+    public List<OrganizationUser> getUserOrgList(String userId, String projectOid) {
+        return organizationUserDao.findByUserIdAndProjectOidAndIsOrg(
+                userId, projectOid, Boolean.TRUE);
+    }
+
     /**
      * 导入 学校用户excel
      *

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/ExpenseFlowServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.components.data.base.util.PageEntityUtil;
+import com.github.microservice.http.APIResponseModel;
 import com.github.microservice.models.hxz.ConsumTransactionsModel;
 import com.github.microservice.models.hxz.ConsumTransactionsResult;
 import com.github.microservice.models.hxz.QRCodeTransactionModel;
@@ -44,7 +45,6 @@ import com.zhongshu.card.server.core.domain.projectAbout.ProjectPaySetting;
 import com.zhongshu.card.server.core.domain.school.CardInfo;
 import com.zhongshu.card.server.core.domain.devices.DeviceBind;
 import com.zhongshu.card.server.core.httpRequest.ApiRequestService;
-import com.zhongshu.card.server.core.httpRequest.apiConf.APIResponseModel;
 import com.zhongshu.card.server.core.service.base.SuperService;
 import com.zhongshu.card.server.core.service.org.OrganizationServiceImpl;
 import com.zhongshu.card.server.core.service.user.OperationLogsService;

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/RequestInfoService.java

@@ -1,5 +1,6 @@
 package com.zhongshu.card.server.core.service.payment;
 
+import com.github.microservice.http.APIResponseModel;
 import com.github.microservice.models.hxz.base.IotBaseResult;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.card.client.model.payment.RequestInfoSaveParam;
@@ -8,7 +9,6 @@ import com.zhongshu.card.server.core.dao.org.UserCountDao;
 import com.zhongshu.card.server.core.dao.payment.RequestInfoDao;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
 import com.zhongshu.card.server.core.domain.payment.RequestInfo;
-import com.zhongshu.card.server.core.httpRequest.apiConf.APIResponseModel;
 import com.zhongshu.card.client.utils.DateUtils;
 import com.zhongshu.card.server.core.util.BeanUtils;
 import com.zhongshu.card.server.core.util.CommonUtil;

+ 4 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/CardInfoPoolService.java

@@ -341,6 +341,8 @@ public class CardInfoPoolService extends SuperService {
         ExcelUtils.commonExecuteExcel(request, response, execlParam);
     }
 
+
+
     /**
      * 搜索卡片
      *
@@ -353,7 +355,8 @@ public class CardInfoPoolService extends SuperService {
         }
 
         // 查询前十的卡片数据
-        List<CardInfoPool> list = cardInfoPoolDao.findTop10ByOidAndCodeLike(param.getOid(), param.getCode());
+        List<CardInfoPool> list = cardInfoPoolDao.findTop10ByProjectOidAndCodeLikeAndIsUsedAndCardCancelState(
+                param.getOid(), param.getCode(), Boolean.FALSE, CardCancelState.Common);
         List<CardInfoPoolSimpleModel> models = new ArrayList<>();
         if (ObjectUtils.isNotEmpty(list)) {
             models = list.stream().map(this::toSimpleModel).collect(Collectors.toList());

+ 247 - 26
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/projectAbout/CardInfoServiceImpl.java

@@ -1,8 +1,12 @@
 package com.zhongshu.card.server.core.service.projectAbout;
 
+import cn.afterturn.easypoi.excel.ExcelImportUtil;
+import cn.afterturn.easypoi.excel.entity.ImportParams;
 import com.github.microservice.auth.client.content.ResultState;
 import com.github.microservice.auth.client.service.UserService;
 import com.github.microservice.components.data.base.util.PageEntityUtil;
+import com.github.microservice.core.util.bean.BeanUtil;
+import com.zhongshu.card.client.model.base.OidModel;
 import com.zhongshu.card.client.model.org.OidAboutInfo;
 import com.zhongshu.card.client.model.org.OrganizationUserModel;
 import com.zhongshu.card.client.model.school.*;
@@ -12,33 +16,46 @@ import com.zhongshu.card.client.service.school.CardInfoService;
 import com.zhongshu.card.client.type.CardCancelState;
 import com.zhongshu.card.client.type.CardOperationType;
 import com.zhongshu.card.client.type.school.CardState;
+import com.zhongshu.card.client.type.school.CardType;
+import com.zhongshu.card.server.core.dao.org.OrganizationUserDao;
 import com.zhongshu.card.server.core.dao.school.CardInfoDao;
 import com.zhongshu.card.server.core.dao.org.OrganizationDao;
 import com.zhongshu.card.server.core.dao.org.UserCountDao;
 import com.zhongshu.card.server.core.dao.school.CardInfoPoolDao;
 import com.zhongshu.card.server.core.dao.user.CardInfoLossRecordDao;
 import com.zhongshu.card.server.core.domain.org.Organization;
+import com.zhongshu.card.server.core.domain.org.OrganizationUser;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
 import com.zhongshu.card.server.core.domain.school.CardInfo;
 import com.zhongshu.card.server.core.domain.school.CardInfoLossRecord;
 import com.zhongshu.card.server.core.domain.school.CardInfoPool;
 import com.zhongshu.card.server.core.service.base.SuperService;
 import com.zhongshu.card.server.core.service.org.OrganizationServiceImpl;
+import com.zhongshu.card.server.core.service.org.OrganizationUserServiceImpl;
 import com.zhongshu.card.server.core.service.orgManager.OrganizationManagerServiceImpl;
 import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
 import com.zhongshu.card.server.core.util.BeanUtils;
+import com.zhongshu.card.server.core.util.CommonUtil;
+import com.zhongshu.card.server.core.util.ExcelUtils;
+import com.zhongshu.card.server.core.util.excel.CommonExeclParam;
+import com.zhongshu.card.server.core.util.excel.CommonExeclTd;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -55,28 +72,34 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
     private CardInfoDao cardInfoDao;
 
     @Autowired
-    OrganizationDao organizationDao;
+    private OrganizationDao organizationDao;
 
     @Autowired
-    UserCountDao userCountDao;
+    private UserCountDao userCountDao;
 
     @Autowired
-    UserService userService;
+    private UserService userService;
 
     @Autowired
-    CardInfoLossRecordDao cardInfoLossRecordDao;
+    private CardInfoLossRecordDao cardInfoLossRecordDao;
 
     @Autowired
-    CardInfoPoolDao cardInfoPoolDao;
+    private CardInfoPoolDao cardInfoPoolDao;
 
     @Autowired
-    OrganizationServiceImpl organizationService;
+    private OrganizationServiceImpl organizationService;
 
     @Autowired
-    UserAccountServiceImpl userAccountService;
+    private UserAccountServiceImpl userAccountService;
 
     @Autowired
-    OrganizationManagerServiceImpl organizationManagerService;
+    private OrganizationManagerServiceImpl organizationManagerService;
+
+    @Autowired
+    private OrganizationUserDao organizationUserDao;
+
+    @Autowired
+    private OrganizationUserServiceImpl organizationUserService;
 
     /**
      * 添加或修改卡片信息
@@ -141,8 +164,6 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
      * @param poolId
      * @return
      */
-    @Transactional
-    @Override
     public ResultContent bindCardFromPool(String poolId, String userId) {
         if (StringUtils.isEmpty(userId)) {
             return ResultContent.buildFail("userId不能为空");
@@ -155,18 +176,50 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
         if (ObjectUtils.isEmpty(cardInfoPool)) {
             return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, poolId));
         }
+        List<OrganizationUser> list = organizationUserService.getUserOrgList(cardInfoPool.getProjectOid(), userId);
+        if (ObjectUtils.isEmpty(list)) {
+            return ResultContent.buildFail("用户未加入结构,不能绑定卡片");
+        }
+        return bindCardFromPoolByOrgId(poolId, list.get(0).getId());
+    }
+
+    @Transactional
+    @Override
+    public ResultContent bindCardFromPoolByOrgId(String poolId, String id) {
+        if (StringUtils.isEmpty(id)) {
+            return ResultContent.buildFail("id不能为空");
+        }
+        if (StringUtils.isEmpty(poolId)) {
+            return ResultContent.buildFail("poolId不能为空");
+        }
+        // 卡池数据
+        CardInfoPool cardInfoPool = cardInfoPoolDao.findTopById(poolId);
+        if (ObjectUtils.isEmpty(cardInfoPool)) {
+            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, poolId));
+        }
         if (cardInfoPool.getIsUsed() != null && cardInfoPool.getIsUsed()) {
             return ResultContent.buildFail(String.format("卡片已使用:%s", cardInfoPool.getCode()));
         }
         if (cardInfoPool.getCardCancelState() != null && cardInfoPool.getCardCancelState() != CardCancelState.Common) {
             return ResultContent.buildFail(String.format("卡片:%s", cardInfoPool.getCardCancelState().getRemark()));
         }
+
+        OrganizationUser organizationUser = organizationUserDao.findTopById(id);
+        if (ObjectUtils.isEmpty(organizationUser)) {
+            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
+        }
+
+        if (!cardInfoPool.getProjectOid().equals(organizationUser.getProjectOid())) {
+            return ResultContent.buildFail(String.format("卡片和用户不在同一个项目下,不能绑定"));
+        }
+
         // 用户信息
-        UserAccount account = userCountDao.findTopByUserId(userId);
+        UserAccount account = organizationUser.getUser();
         if (ObjectUtils.isEmpty(account)) {
-            return ResultContent.buildFail(String.format("", userId));
+            return ResultContent.buildFail("机构用户信息为空");
         }
 
+        String userId = account.getUserId();
         String code = cardInfoPool.getCode();
         CardInfo cardInfo = cardInfoDao.findByCode(code);
         if (ObjectUtils.isNotEmpty(cardInfo)) {
@@ -183,21 +236,22 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
         cardInfo.setSchoolOid(cardInfoPool.getSchoolOid());
         cardInfo.setAboutAuthType(cardInfoPool.getAboutAuthType());
         cardInfo.setAboutOid(cardInfoPool.getAboutOid());
+        cardInfo.setOid(cardInfoPool.getOid());
+        cardInfo.setOrganization(organizationUser.getOrganization());
+        cardInfo.setOrganizationUser(organizationUser);
 
         cardInfo.setCardState(CardState.Enable);
         cardInfo.setUserAccount(account);
         cardInfo.setUserId(userId);
         cardInfo.setUserName(account.getName());
         cardInfo.setPhone(account.getPhone());
-        cardInfo.setOid(cardInfoPool.getOid());
         cardInfoDao.save(cardInfo);
 
-        // 标记卡池这张卡使用
+        // 标记卡池这张卡使用
         cardInfoPool.setIsUsed(Boolean.TRUE);
         cardInfoPool.setUseUserId(userId);
         cardInfoPool.setUseTime(System.currentTimeMillis());
         cardInfoPoolDao.save(cardInfoPool);
-
         return ResultContent.buildSuccess();
     }
 
@@ -236,6 +290,25 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
         return ResultContent.buildSuccess(getUserOrgAllCard(userId, oid));
     }
 
+    /**
+     * 查询结构用户的卡片信息
+     *
+     * @param id
+     * @return
+     */
+    public ResultContent<List<CardInfoModel>> getOrgCardList(String id) {
+        List<CardInfoModel> models = new ArrayList<>();
+        OrganizationUser organizationUser = organizationUserDao.findTopById(id);
+        if (ObjectUtils.isEmpty(organizationUser)) {
+            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
+        }
+        List<CardInfo> list = cardInfoDao.findByUserIdAndProjectOid(organizationUser.getUserId(), organizationUser.getProjectOid());
+        if (ObjectUtils.isNotEmpty(list)) {
+            models = list.stream().map(this::toModel).collect(Collectors.toList());
+        }
+        return ResultContent.buildSuccess(models);
+    }
+
     @Override
     public List<CardInfoModel> getUserOrgAllCard(String userId, String oid) {
         List<CardInfoModel> models = new ArrayList<>();
@@ -246,7 +319,7 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
             list = cardInfoDao.findByUserId(userId);
         }
         if (ObjectUtils.isNotEmpty(list)) {
-            models = list.stream().map(this::toModel).collect(Collectors.toList());
+            models = list.parallelStream().map(this::toModel).collect(Collectors.toList());
         }
         return models;
     }
@@ -480,13 +553,10 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
 
     //----------------------------园区卡片操作 start ------------------------
 
-    public ResultContent<Page<CardInfoPoolModel>> page(CardInfoSearch param, Pageable pageable) {
-        checkParamOid(param);
-        initOidSearchParam(param);
-        String oid = param.getOid();
-        OidAboutInfo aboutInfo = organizationService.getOidAboutOrgInfo(oid);
-        param.setProjectOid(aboutInfo.getProjectOid());
-
+    public ResultContent<Page<CardInfoModel>> page(CardInfoSearch param, Pageable pageable) {
+        if (StringUtils.isEmpty(param.getProjectOid())) {
+            return ResultContent.buildFail("projectOid不能为空");
+        }
         Page<CardInfo> page = cardInfoDao.page(pageable, param);
         return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toOrgModel));
     }
@@ -604,9 +674,155 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
         return ResultContent.buildSuccess();
     }
 
-    //----------------------------园区卡片操作 end --------------------------
+    /**
+     * 导入 学校卡片excel
+     *
+     * @param request
+     * @param response
+     * @param file
+     * @return
+     */
+    public ResultContent<ImportResultModel> importCard(HttpServletRequest request, HttpServletResponse response, MultipartFile file, OidModel param) {
+        String oid = param.getOid();
+        Assert.hasText(oid, "oid不能为空");
 
+        OidAboutInfo oidAboutInfo = organizationManagerService.getOidAboutInfo(oid);
+        String projectOid = oidAboutInfo.getProjectOid();
+
+        ImportResultModel model = new ImportResultModel();
+        try {
+            int startRow = 3;
+            ImportParams params = new ImportParams();
+            params.setHeadRows(1);
+            params.setTitleRows(1);
+            List<CardInfoPoolImportParam> list = ExcelImportUtil.importExcel(file.getInputStream(), CardInfoPoolImportParam.class, params);
+            model.setTotal(list.size());
+
+            List<String> failDetails = new ArrayList<>();
+            List<CardInfoPool> cardInfoPools = new ArrayList<>();
+            if (ObjectUtils.isNotEmpty(list)) {
+                for (CardInfoPoolImportParam param1 : list) {
+                    // 验证数据合法性
+                    boolean b = true;
+                    if (b && StringUtils.isEmpty(param1.getCode())) {
+                        b = false;
+                        failDetails.add(String.format("第%d行卡号不能为空", startRow));
+                    }
+                    if (b && StringUtils.isEmpty(param1.getCardType())) {
+                        b = false;
+                        failDetails.add(String.format("第%d行卡片类型不能为空", startRow));
+                    }
+
+                    if (b && StringUtils.isNotEmpty(param1.getCardType())) {
+                        CardType cardType = CommonUtil.getCardTypeByStr(param1.getCardType());
+                        if (cardType == null) {
+                            b = false;
+                            failDetails.add(String.format("第%d行卡片类型不正确", startRow));
+                        }
+                    }
+
+                    if (b) {
+                        // 检查是否已存在 code
+                        boolean exit = cardInfoPoolDao.existsByCode(param1.getCode());
+                        if (exit) {
+                            b = false;
+                        }
+                    }
+
+                    if (b) {
+                        // 验证通过
+                        CardInfoPool pool = new CardInfoPool();
+                        initEntity(pool);
+                        param1.setCode(param1.getCode().trim());
+                        BeanUtils.copyProperties(param1, pool, "cardType");
+                        pool.setSchoolOid("");
+                        pool.setProjectOid(projectOid);
+                        pool.setOid(oid);
+                        pool.setAboutOid(oidAboutInfo.getOid());
+                        pool.setAboutAuthType(oidAboutInfo.getAuthType());
+
+                        // 初始状态为  未使用
+                        pool.setIsUsed(Boolean.FALSE);
+                        // 对比出卡片类型
+                        CardType cardType = CommonUtil.getCardTypeByStr(param1.getCardType());
+                        pool.setCardType(cardType);
+                        cardInfoPools.add(pool);
+                    }
+                    startRow++;
+                }
+                cardInfoPoolDao.saveAll(cardInfoPools);
+                model.setSuccess(cardInfoPools.size());
+                model.setFailDetails(failDetails);
+            }
+        } catch (Exception e) {
+            return ResultContent.buildFail(String.format("导入出错:%s", e.getMessage()));
+        }
+        return ResultContent.buildSuccess(model);
+    }
+
+    /**
+     * 导出项目用户
+     *
+     * @param request
+     * @param response
+     * @param param
+     */
+    public void exportProjectCard(HttpServletRequest request, HttpServletResponse response, CardInfoSearch param) {
+        Assert.hasText(param.getProjectOid(), "projectOid不能为空");
 
+        Organization organization = organizationDao.findTopByOid(param.getProjectOid());
+        Pageable pageable = PageRequest.of(0, Integer.MAX_VALUE);
+        Page<CardInfo> page = cardInfoDao.page(pageable, param);
+
+        List<Map<String, Object>> maps = new ArrayList<>();
+        if (page.getContent() != null) {
+            List<CardInfo> list = page.getContent();
+            maps = list.stream().map(it -> {
+                Map<String, Object> map = BeanUtil.bean2Map(it);
+                String cardStr = it.getCardType().getRemark();
+                map.put("cardStr", cardStr);
+
+                OrganizationUser orgUser = it.getOrganizationUser();
+                if (ObjectUtils.isEmpty(orgUser)) {
+                    // 人员编号
+                    List<OrganizationUser> tempList = organizationUserService.getUserOrgList(it.getUserId(), it.getProjectOid());
+                    if (ObjectUtils.isNotEmpty(tempList)) {
+                        orgUser = tempList.get(0);
+                    }
+                }
+                return map;
+            }).collect(Collectors.toList());
+        }
+
+        CommonExeclParam execlParam = new CommonExeclParam();
+        execlParam.setTitle(String.format("%s卡片数据", organization.getName()));
+        execlParam.setStartRow(2);
+        execlParam.setDatas(maps);
+
+        List<CommonExeclTd> tds = new ArrayList<>();
+        tds.add(CommonExeclTd.build("卡片ID", "code"));
+        tds.add(CommonExeclTd.build("卡片类型", "cardStr"));
+        tds.add(CommonExeclTd.build("人员编号", "useStr"));
+        tds.add(CommonExeclTd.build("姓名", "cancelStr"));
+        tds.add(CommonExeclTd.build("性别", "cancelStr"));
+        tds.add(CommonExeclTd.build("机构", "cancelStr"));
+        tds.add(CommonExeclTd.build("部门", "cancelStr"));
+        tds.add(CommonExeclTd.build("人员类型", "cancelStr"));
+        tds.add(CommonExeclTd.build("手机号", "cancelStr"));
+        tds.add(CommonExeclTd.build("作废状态", "cancelStr"));
+        tds.add(CommonExeclTd.build("挂失状态", "cancelStr"));
+        tds.add(CommonExeclTd.build("创建人员", "cancelStr"));
+        tds.add(CommonExeclTd.build("创建时间", "cancelStr"));
+        tds.add(CommonExeclTd.build("更新人员", "cancelStr"));
+        tds.add(CommonExeclTd.build("更新时间", "cancelStr"));
+
+        execlParam.setTds(tds);
+        ExcelUtils.commonExecuteExcel(request, response, execlParam);
+    }
+
+    //----------------------------园区卡片操作 end --------------------------
+
+    // 简单的信息
     public CardInfoModel toModel(CardInfo entity) {
         CardInfoModel model = null;
         if (ObjectUtils.isNotEmpty(entity)) {
@@ -621,9 +837,14 @@ public class CardInfoServiceImpl extends SuperService implements CardInfoService
         if (ObjectUtils.isNotEmpty(entity)) {
             model = new CardInfoModel();
             BeanUtils.copyProperties(entity, model);
+
             // 机构用户信息
-            OrganizationUserModel organizationUser = userAccountService.getOrgUserDetail(entity.getOid(), entity.getUserId(), true);
-            model.setOrganizationUser(organizationUser);
+            List<OrganizationUser> list = organizationUserService.getUserOrgList(entity.getUserId(), entity.getProjectOid());
+            OrganizationUserModel orgUserInfo = null;
+            if (ObjectUtils.isEmpty(list)) {
+                orgUserInfo = userAccountService.toOrgUserModel(list.get(0));
+            }
+            model.setOrganizationUser(orgUserInfo);
         }
         return model;
     }

+ 99 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/util/AesUtils.java

@@ -0,0 +1,99 @@
+package com.zhongshu.card.server.core.util;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+import static org.apache.tomcat.util.buf.HexUtils.toHexString;
+
+@Slf4j
+public class AesUtils {
+
+    @SneakyThrows
+    public static String signData(String json_data) {
+        MessageDigest md = MessageDigest.getInstance("SHA-256");
+        md.reset();
+        md.update(json_data.getBytes("utf-8"));
+        return toHexString(md.digest());
+    }
+
+    @SneakyThrows
+    public static String signMacSHA256(String str, String key) {
+        Mac mac = Mac.getInstance("HmacSHA256");
+        mac.init(new SecretKeySpec(key.getBytes("utf-8"), "HmacSHA256"));
+        mac.update(str.getBytes("utf-8"));
+        byte[] arr = mac.doFinal();
+        return Base64.getEncoder().encodeToString(arr);
+    }
+
+    public static String getMD5Str(String s) {
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+//            byte[] digest = md.digest(s.getBytes());
+//            StringBuilder sb = new StringBuilder();
+//            for (byte b : digest) {
+//                sb.append(String.format("%02x", b));
+//            }
+//            return sb.toString();
+            byte[] bytes = md.digest(s.getBytes("utf-8"));
+            return toHex(bytes);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String toHex(byte[] bytes) {
+        final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+        StringBuilder ret = new StringBuilder(bytes.length * 2);
+        for (int i = 0; i < bytes.length; i++) {
+            ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
+            ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
+        }
+        return ret.toString();
+    }
+
+    public static String base64Encode(String str) {
+        if (StringUtils.isNotEmpty(str)) {
+            try {
+                byte[] encoded = Base64.getEncoder().encode(str.getBytes("utf-8"));
+                return new String(encoded);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return str;
+    }
+
+    public static String base64Decode(String str) {
+        if (StringUtils.isNotEmpty(str)) {
+            try {
+                byte[] decoded = Base64.getDecoder().decode(str.getBytes("utf-8"));
+                return new String(decoded);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return str;
+    }
+
+    public static PublicKey initializeSM3WithSM2PublicKey(String publicKeyStr) throws Exception {
+        // 将字节转换为PublicKey
+        Security.addProvider(new BouncyCastleProvider());
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(base64Decode(publicKeyStr).getBytes(StandardCharsets.UTF_8));
+        KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
+        PublicKey publicKey = keyFactory.generatePublic(keySpec);
+        return publicKey;
+    }
+
+}