Browse Source

coding:问诊处方相关接口

zhangqin 2 weeks ago
parent
commit
2d9bfaa4bc

+ 4 - 2
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java

@@ -73,8 +73,9 @@ public interface FsStoreProductScrmMapper
      */
     public int deleteFsStoreProductByIds(Long[] productIds);
     @Select({"<script> " +
-            "select p.*,pc.cate_name, fs_store.store_name from fs_store_product_scrm p left join fs_store_product_category_scrm pc on p.cate_id=pc.cate_id  " +
+            "select p.*,pc.cate_name, fs_store.store_name,hs.push_status from fs_store_product_scrm p left join fs_store_product_category_scrm pc on p.cate_id=pc.cate_id  " +
             "left join fs_store on fs_store.store_id = p.store_id " +
+            "left join (select product_id, push_status from fs_store_hospital580_product_push_scrm h1 where h1.id = (select max(h2.id) from fs_store_hospital580_product_push_scrm h2 where h2.product_id = h1.product_id)) hs on hs.product_id = p.product_id " +
             "where 1=1 " +
             "<if test = 'maps.productName != null and  maps.productName !=\"\"    '> " +
             "and p.product_name like CONCAT('%',#{maps.productName},'%') " +
@@ -151,9 +152,10 @@ public interface FsStoreProductScrmMapper
     @Select({"<script> " +
             "  select p.*,pc.cate_name from (SELECT ave.bar_code as bar_code,p.product_id, p.image, p.slider_image,p.product_name, p.product_info,p.keyword, p.cate_id, p.price, p.vip_price, " +
             " p.ot_price,p.agent_price, p.postage,p.unit_name,p.sort,p.sales,p.stock,p.is_show,p.is_hot,p.is_benefit,p.is_best,p.is_new,p.description,p.create_time,p.update_time,p.is_postage,p.is_del,p.give_integral," +
-            " p.cost,p.is_good,p.browse,p.code_path,p.temp_id,p.spec_type,p.is_integral,p.integral,p.product_type,p.prescribe_code, p.prescribe_spec,p.prescribe_factory,p.prescribe_name,p.is_display,p.tui_cate_id " +
+            " p.cost,p.is_good,p.browse,p.code_path,p.temp_id,p.spec_type,p.is_integral,p.integral,p.product_type,p.prescribe_code, p.prescribe_spec,p.prescribe_factory,p.prescribe_name,p.is_display,p.tui_cate_id ,hs.push_status" +
             " FROM fs_store_product_scrm p LEFT JOIN fs_store_product_attr_value_scrm ave on p.product_id=ave.product_id  WHERE ave.bar_code != '' and p.product_id is not null" +
             ") p left join fs_store_product_category_scrm pc on p.cate_id=pc.cate_id   " +
+            "left join (select product_id, push_status from fs_store_hospital580_product_push_scrm h1 where h1.id = (select max(h2.id) from fs_store_hospital580_product_push_scrm h2 where h2.product_id = h1.product_id)) hs on hs.product_id = p.product_id " +
             " where 1=1 " +
             "<if test = 'maps.productName != null and  maps.productName !=\"\"  '> " +
             "and p.product_name like CONCAT('%',#{maps.productName},'%') " +

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreProductListVO.java

@@ -116,5 +116,7 @@ public class FsStoreProductListVO  implements Serializable
 
     private String storeId;
     private String storeName;
+    // 同步药品状态 推送状态 0推送中1成功2失
+    private Byte pushStatus;
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hospital580/service/impl/Hospital580ScrmServiceImpl.java

@@ -67,6 +67,8 @@ public class Hospital580ScrmServiceImpl extends ServiceImpl<Hospital580ScrmMappe
                 return productPushScrmEntity;
             }).collect(Collectors.toList());
             pushScrmService.saveBatch(collect);
+        }else {
+            throw new RuntimeException("同步药品失败"+result580.getErrmsg());
         }
     }
 

+ 2 - 1
fs-service/src/main/java/com/fs/hospital580/service/impl/Hospital580ServiceImpl.java

@@ -68,7 +68,7 @@ public class Hospital580ServiceImpl implements Hospital580Service {
         t.initCommonDto(CLIENTID, SECRETKEY);
         String url = HOSPITAL_580_URL + path;
         String body = JSONUtil.toJsonStr(t);
-        String result = "";
+        String result;
         Result580 result580;
         boolean requestStatus;
         try {
@@ -84,6 +84,7 @@ public class Hospital580ServiceImpl implements Hospital580Service {
             log.info("请求580接口异常:", e);
             result580 = new Result580(e.getMessage());
             requestStatus = false;
+            result="";
         }
         /*
           保存调用记录

+ 17 - 9
fs-user-app/src/main/java/com/fs/app/facade/impl/Hospital580FacadeServiceImpl.java

@@ -13,6 +13,7 @@ import com.fs.app.facade.Hospital580FacadeService;
 import com.fs.common.core.domain.PageResponse;
 import com.fs.common.core.domain.Result;
 import com.fs.common.core.page.PageRequest;
+import com.fs.framework.aspectj.lock.DistributeLock;
 import com.fs.hospital580.dto.DiseaseDto;
 import com.fs.hospital580.dto.PreDemandDto;
 import com.fs.hospital580.dto.Result580;
@@ -54,27 +55,33 @@ public class Hospital580FacadeServiceImpl implements Hospital580FacadeService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
+    @DistributeLock(keyExpression = "#vo.userId", scene = "savePreDemand", waitTime = 5000, errorMsg = "红包领取失败")
     public Result<String> savePreDemand(SaveOrderScrmReq vo) {
         // 保存问诊信息
         Hospital580PrescriptionScrmEntity order = new Hospital580PrescriptionScrmEntity();
         BeanUtil.copyProperties(vo, order);
         order.insert();
-        List<Hospital580PrescriptionAnswerScrmEntity> answerScrmEntities = vo.getBeforeAiDataList().stream().map(item -> {
-            Hospital580PrescriptionAnswerScrmEntity answerScrmEntity = new Hospital580PrescriptionAnswerScrmEntity();
-            BeanUtil.copyProperties(item, answerScrmEntity);
-            answerScrmEntity.setPreId(order.getPreId());
-            return answerScrmEntity;
-        }).collect(Collectors.toList());
-        answerScrmService.saveBatch(answerScrmEntities);
-
-        // 获取问诊链接
+
+        // 保存问诊答案
+        answerScrmService.saveBatch(vo.getBeforeAiDataList().stream()
+                .map(item -> {
+                    Hospital580PrescriptionAnswerScrmEntity entity = new Hospital580PrescriptionAnswerScrmEntity();
+                    BeanUtil.copyProperties(item, entity);
+                    entity.setPreId(order.getPreId());
+                    return entity;
+                })
+                .collect(Collectors.toList()));
+
+        // 获取问诊链接并更新
         PreDemandDto dto = new PreDemandDto();
         BeanUtil.copyProperties(vo, dto);
         dto.setBizOrderId(order.getPreId().toString());
         dto.setMemberId(vo.getUserFamilyPhone());
+
         Result580 result580 = hospital580Service.initPreDemand(dto);
         order.setJumpUrl(result580.getData());
         order.updateById();
+
         return processResult(result580);
     }
 
@@ -158,6 +165,7 @@ public class Hospital580FacadeServiceImpl implements Hospital580FacadeService {
                 .collect(Collectors.toList());
         productPushScrm.update(new LambdaUpdateWrapper<Hospital580ProductPushScrmEntity>()
                 .in(Hospital580ProductPushScrmEntity::getProductId, medicineIds)
+                .eq(Hospital580ProductPushScrmEntity::getPushStatus, 0)
                 .set(Hospital580ProductPushScrmEntity::getPushStatus, vo.getErrCode().equals("0") ? 1 : 2)
                 .set(Hospital580ProductPushScrmEntity::getErrMsg, vo.getErrMsg())
                 .set(Hospital580ProductPushScrmEntity::getUpdateTime, LocalDateTime.now()));

+ 58 - 0
fs-user-app/src/main/java/com/fs/framework/aspectj/lock/DistributeLock.java

@@ -0,0 +1,58 @@
+package com.fs.framework.aspectj.lock;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 分布式锁注解
+ *
+ * @author Hollis
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DistributeLock {
+
+    /**
+     * 锁的场景
+     *
+     * @return
+     */
+    public String scene() default "lock";
+
+    /**
+     * 加锁的key,优先取key(),如果没有,则取keyExpression()
+     *
+     * @return
+     */
+    public String key() default DistributeLockConstant.NONE_KEY;
+
+    /**
+     * SPEL表达式:
+     * <pre>
+     *     #id
+     *     #insertResult.id
+     * </pre>
+     *
+     * @return
+     */
+    public String keyExpression() default DistributeLockConstant.NONE_KEY;
+
+    /**
+     * 超时时间,毫秒
+     * 默认情况下不设置超时时间,会自动续期
+     *
+     * @return
+     */
+    public int expireTime() default DistributeLockConstant.DEFAULT_EXPIRE_TIME;
+
+    public String errorMsg() default DistributeLockConstant.ERROR_MSG;
+
+    /**
+     * 加锁等待时长,毫秒
+     * 默认情况下不设置等待时长,会一直等待直到获取到锁
+     * @return
+     */
+    public int waitTime() default DistributeLockConstant.DEFAULT_WAIT_TIME;
+}

+ 113 - 0
fs-user-app/src/main/java/com/fs/framework/aspectj/lock/DistributeLockAspect.java

@@ -0,0 +1,113 @@
+package com.fs.framework.aspectj.lock;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.StandardReflectionParameterNameDiscoverer;
+import org.springframework.core.annotation.Order;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+@Aspect
+@Component
+@Order(Integer.MIN_VALUE + 1)
+public class DistributeLockAspect {
+
+    private RedissonClient redissonClient;
+
+    public DistributeLockAspect(RedissonClient redissonClient) {
+        this.redissonClient = redissonClient;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(DistributeLockAspect.class);
+
+    @Around("@annotation(com.fs.framework.aspectj.lock.DistributeLock)")
+    public Object process(ProceedingJoinPoint pjp) throws Throwable {
+        Object response = null;
+        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
+        DistributeLock distributeLock = method.getAnnotation(DistributeLock.class);
+
+        String key = distributeLock.key();
+        if (DistributeLockConstant.NONE_KEY.equals(key)) {
+            if (DistributeLockConstant.NONE_KEY.equals(distributeLock.keyExpression())) {
+                throw new DistributeLockException("no lock key found...");
+            }
+            SpelExpressionParser parser = new SpelExpressionParser();
+            Expression expression = parser.parseExpression(distributeLock.keyExpression());
+
+            EvaluationContext context = new StandardEvaluationContext();
+            // 获取参数值
+            Object[] args = pjp.getArgs();
+
+            // 获取运行时参数的名称
+            StandardReflectionParameterNameDiscoverer discoverer
+                    = new StandardReflectionParameterNameDiscoverer();
+            String[] parameterNames = discoverer.getParameterNames(method);
+
+            // 将参数绑定到context中
+            if (parameterNames != null) {
+                for (int i = 0; i < parameterNames.length; i++) {
+                    context.setVariable(parameterNames[i], args[i]);
+                }
+            }
+
+            // 解析表达式,获取结果
+            key = String.valueOf(expression.getValue(context));
+        }
+
+        String scene = distributeLock.scene();
+
+        String lockKey = scene + "#" + key;
+
+        int expireTime = distributeLock.expireTime();
+        int waitTime = distributeLock.waitTime();
+        RLock rLock= redissonClient.getLock(lockKey);
+        try {
+            boolean lockResult = false;
+            if (waitTime == DistributeLockConstant.DEFAULT_WAIT_TIME) {
+                if (expireTime == DistributeLockConstant.DEFAULT_EXPIRE_TIME) {
+                    LOG.info(String.format("lock for key : %s", lockKey));
+                    rLock.lock();
+                } else {
+                    LOG.info(String.format("lock for key : %s , expire : %s", lockKey, expireTime));
+                    rLock.lock(expireTime, TimeUnit.MILLISECONDS);
+                }
+                lockResult = true;
+            } else {
+                if (expireTime == DistributeLockConstant.DEFAULT_EXPIRE_TIME) {
+                    LOG.info(String.format("try lock for key : %s , wait : %s", lockKey, waitTime));
+                    lockResult = rLock.tryLock(waitTime, TimeUnit.MILLISECONDS);
+                } else {
+                    LOG.info(String.format("try lock for key : %s , expire : %s , wait : %s", lockKey, expireTime, waitTime));
+                    lockResult = rLock.tryLock(waitTime, expireTime, TimeUnit.MILLISECONDS);
+                }
+            }
+
+            if (!lockResult) {
+                LOG.warn(String.format("lock failed for key : %s , expire : %s", lockKey, expireTime));
+                throw new DistributeLockException(distributeLock.errorMsg());
+            }
+
+
+            LOG.info(String.format("lock success for key : %s , expire : %s", lockKey, expireTime));
+            response = pjp.proceed();
+        }  finally {
+            if (rLock.isHeldByCurrentThread()) {
+                rLock.unlock();
+                LOG.info(String.format("unlock for key : %s , expire : %s", lockKey, expireTime));
+            }
+        }
+        return response;
+    }
+}

+ 13 - 0
fs-user-app/src/main/java/com/fs/framework/aspectj/lock/DistributeLockConstant.java

@@ -0,0 +1,13 @@
+package com.fs.framework.aspectj.lock;
+
+public class DistributeLockConstant {
+
+    public static final String NONE_KEY = "NONE";
+
+    public static final String DEFAULT_OWNER = "DEFAULT";
+
+    public static final int DEFAULT_EXPIRE_TIME = -1;
+
+    public static final int DEFAULT_WAIT_TIME = Integer.MAX_VALUE;
+    public static final String ERROR_MSG  = "请勿重复操作";
+}

+ 24 - 0
fs-user-app/src/main/java/com/fs/framework/aspectj/lock/DistributeLockException.java

@@ -0,0 +1,24 @@
+package com.fs.framework.aspectj.lock;
+
+
+public class DistributeLockException extends RuntimeException {
+
+    public DistributeLockException() {
+    }
+
+    public DistributeLockException(String message) {
+        super(message);
+    }
+
+    public DistributeLockException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public DistributeLockException(Throwable cause) {
+        super(cause);
+    }
+
+    public DistributeLockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}