Browse Source

Merge remote-tracking branch 'origin/dev' into dev

qrs 1 month ago
parent
commit
0846717f3a
37 changed files with 1325 additions and 73 deletions
  1. 1 1
      alien-entity/src/main/java/shop/alien/entity/store/LawyerExpertiseArea.java
  2. 5 1
      alien-entity/src/main/java/shop/alien/entity/store/LifeSys.java
  3. 136 0
      alien-entity/src/main/java/shop/alien/entity/store/dto/LawyerUserDto.java
  4. 31 0
      alien-entity/src/main/java/shop/alien/entity/store/dto/SystemRegisterDto.java
  5. 3 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/LawyerUserVo.java
  6. 46 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/OrderRevenueVO.java
  7. 1 0
      alien-entity/src/main/java/shop/alien/mapper/LawFirmMapper.java
  8. 70 0
      alien-entity/src/main/java/shop/alien/mapper/LawyerUserMapper.java
  9. 81 20
      alien-entity/src/main/java/shop/alien/mapper/LifeFansMapper.java
  10. 1 0
      alien-entity/src/main/java/shop/alien/mapper/LifeGroupBuyMainMapper.java
  11. 1 1
      alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java
  12. 1 0
      alien-entity/src/main/resources/mapper/LawFirmMapper.xml
  13. 47 0
      alien-gateway/src/main/java/shop/alien/gateway/controller/LawyerUserLogInController.java
  14. 16 1
      alien-gateway/src/main/java/shop/alien/gateway/controller/SystemController.java
  15. 19 0
      alien-gateway/src/main/java/shop/alien/gateway/mapper/LawFirmMapper.java
  16. 30 0
      alien-gateway/src/main/java/shop/alien/gateway/mapper/LawyerServiceAreaMapper.java
  17. 89 0
      alien-gateway/src/main/java/shop/alien/gateway/mapper/LawyerUserMapper.java
  18. 26 0
      alien-gateway/src/main/java/shop/alien/gateway/service/LawyerUserService.java
  19. 12 0
      alien-gateway/src/main/java/shop/alien/gateway/service/SystemService.java
  20. 136 0
      alien-gateway/src/main/java/shop/alien/gateway/service/impl/LawyerUserServiceImpl.java
  21. 40 2
      alien-gateway/src/main/java/shop/alien/gateway/service/impl/SystemServiceImpl.java
  22. 41 0
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/AliController.java
  23. 9 0
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawFirmController.java
  24. 18 0
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerConsultationOrderController.java
  25. 2 1
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerLegalProblemScenarioController.java
  26. 6 9
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerUserController.java
  27. 9 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/LawFirmService.java
  28. 9 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerConsultationOrderService.java
  29. 7 3
      alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerUserService.java
  30. 84 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawFirmServiceImpl.java
  31. 142 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerConsultationOrderServiceImpl.java
  32. 7 2
      alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerExpertiseAreaServiceImpl.java
  33. 33 29
      alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerUserServiceImpl.java
  34. 98 0
      alien-lawyer/src/main/java/shop/alien/lawyer/util/AliSms.java
  35. 16 1
      alien-store/src/main/java/shop/alien/store/controller/SystemController.java
  36. 12 0
      alien-store/src/main/java/shop/alien/store/service/SystemService.java
  37. 40 2
      alien-store/src/main/java/shop/alien/store/service/impl/SystemServiceImpl.java

+ 1 - 1
alien-entity/src/main/java/shop/alien/entity/store/LawyerExpertiseArea.java

@@ -25,7 +25,7 @@ public class LawyerExpertiseArea extends Model<LawyerExpertiseArea> {
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
 
-    @ApiModelProperty(value = "图片描述")
+    @ApiModelProperty(value = "领域名称")
     @TableField("expertise_area_info")
     private String expertiseAreaInfo;
 

+ 5 - 1
alien-entity/src/main/java/shop/alien/entity/store/LifeSys.java

@@ -16,13 +16,17 @@ import java.util.Date;
 @TableName("life_sys")
 public class LifeSys {
 
+    @ApiModelProperty(value = "主键")
     @TableId(value = "id", type = IdType.AUTO)
-    private String id;
+    private Integer id;
 
+    @ApiModelProperty(value = "用户名")
     private String userName;
 
+    @ApiModelProperty(value = "密码")
     private String userPassword;
 
+    @ApiModelProperty(value = "角色id")
     private String roleId;
 
     @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")

+ 136 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/LawyerUserDto.java

@@ -0,0 +1,136 @@
+package shop.alien.entity.store.dto;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import shop.alien.entity.store.LawyerLegalProblemScenario;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 律师用户视图对象
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@ApiModel(value = "LawyerUserVo对象", description = "律师用户视图对象")
+public class LawyerUserDto implements Serializable {
+
+
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "律所id")
+    @TableField("firm_id")
+    private Integer firmId;
+
+    @ApiModelProperty(value = "手机号")
+    @TableField("phone")
+    private String phone;
+
+    @ApiModelProperty(value = "姓名")
+    @TableField("name")
+    private String name;
+
+    @ApiModelProperty(value = "身份证")
+    @TableField("id_card")
+    private String idCard;
+
+    @ApiModelProperty(value = "用户状态, 0:禁用, 1:启用")
+    @TableField("status")
+    private Integer status;
+
+    @ApiModelProperty(value = "昵称")
+    @TableField("nick_name")
+    private String nickName;
+
+    @ApiModelProperty(value = "头像")
+    @TableField("head_img")
+    private String headImg;
+
+    @ApiModelProperty(value = "律师执业证号")
+    @TableField("lawyer_certificate_no")
+    private String lawyerCertificateNo;
+
+    @ApiModelProperty(value = "所属律师事务所")
+    @TableField("law_firm")
+    private String lawFirm;
+
+    @ApiModelProperty(value = "执业年限")
+    @TableField("practice_years")
+    private Integer practiceYears;
+
+    @ApiModelProperty(value = "执业开始日期")
+    @TableField("practice_start_date")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date practiceStartDate;
+
+    @ApiModelProperty(value = "专业领域,多个用逗号分隔")
+    @TableField("specialty_fields")
+    private String specialtyFields;
+
+    @ApiModelProperty(value = "执业证照片")
+    @TableField("certificate_image")
+    private String certificateImage;
+
+    @ApiModelProperty(value = "所属省份")
+    @TableField("province")
+    private String province;
+
+    @ApiModelProperty(value = "所属城市")
+    @TableField("city")
+    private String city;
+
+    @ApiModelProperty(value = "所属区县")
+    @TableField("district")
+    private String district;
+
+    @ApiModelProperty(value = "详细地址")
+    @TableField("address")
+    private String address;
+
+    @ApiModelProperty(value = "邮箱")
+    @TableField("email")
+    private String email;
+
+    @ApiModelProperty(value = "性别, 0:未知, 1:男, 2:女")
+    @TableField("gender")
+    private Integer gender;
+
+    @ApiModelProperty(value = "生日")
+    @TableField("birthday")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date birthday;
+
+    @ApiModelProperty(value = "个人简介(详细)")
+    @TableField("personal_introduction")
+    private String personalIntroduction;
+
+    @ApiModelProperty(value = "领域ID")
+    @TableField("lawyer_expertise_area_id")
+    private Integer lawyerExpertiseAreaId;
+
+    @ApiModelProperty(value = "法律问题场景")
+    @TableField(exist = false)
+    private List<Integer> problemScenarioIds;
+
+    @ApiModelProperty(value = "律师事务所收款账号")
+    @TableField("payment_num")
+    private String paymentNum;
+
+    @ApiModelProperty(value = "登录Token")
+    private String token;
+
+    @ApiModelProperty(value = "登录Token")
+    private String msgCode;
+}
+

+ 31 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/SystemRegisterDto.java

@@ -0,0 +1,31 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 系统用户注册DTO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "SystemRegisterDto对象", description = "系统用户注册信息")
+public class SystemRegisterDto {
+
+    @ApiModelProperty(value = "用户名", required = true)
+    private String userName;
+
+    @ApiModelProperty(value = "密码", required = true)
+    private String password;
+
+    @ApiModelProperty(value = "角色id")
+    private String roleId;
+
+}
+

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LawyerUserVo.java

@@ -297,5 +297,8 @@ public class LawyerUserVo implements Serializable {
 
     @TableField(exist = false)
     private String firmName;
+
+    @ApiModelProperty(value = "登录Token")
+    private String token;
 }
 

+ 46 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/OrderRevenueVO.java

@@ -0,0 +1,46 @@
+package shop.alien.entity.store.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 订单收益统计VO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "OrderRevenueVO对象", description = "订单收益统计")
+public class OrderRevenueVO implements Serializable {
+
+    @ApiModelProperty(value = "全部收益-订单总数")
+    private Long allOrderCount;
+
+    @ApiModelProperty(value = "全部收益-收益合计(单位:分)")
+    private Long allRevenue;
+
+    @ApiModelProperty(value = "全部收益-收益合计(单位:分,格式化显示)")
+    private Long allRevenueStr;
+
+    @ApiModelProperty(value = "进行中-订单总数")
+    private Long inProgressOrderCount;
+
+    @ApiModelProperty(value = "进行中-收益合计(单位:分)")
+    private Long inProgressRevenue;
+
+    @ApiModelProperty(value = "进行中-收益合计(单位:分,格式化显示)")
+    private Long inProgressRevenueStr;
+
+    @ApiModelProperty(value = "已完成-订单总数")
+    private Long completedOrderCount;
+
+    @ApiModelProperty(value = "已完成-收益合计(单位:分)")
+    private Long completedRevenue;
+
+    @ApiModelProperty(value = "已完成-收益合计(单位:分,格式化显示)")
+    private Long completedRevenueStr;
+}
+

+ 1 - 0
alien-entity/src/main/java/shop/alien/mapper/LawFirmMapper.java

@@ -17,3 +17,4 @@ public interface LawFirmMapper extends BaseMapper<LawFirm> {
 
 }
 
+

+ 70 - 0
alien-entity/src/main/java/shop/alien/mapper/LawyerUserMapper.java

@@ -2,6 +2,7 @@ package shop.alien.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Update;
 import shop.alien.entity.store.LawyerUser;
 
 /**
@@ -15,5 +16,74 @@ import shop.alien.entity.store.LawyerUser;
 @Mapper
 public interface LawyerUserMapper extends BaseMapper<LawyerUser> {
 
+
+@Update("<script>" +
+        "UPDATE lawyer_user " +
+        "<set>" +
+        "<if test='firmId != null'>firm_id = #{firmId},</if>" +
+        "<if test='phone != null'>phone = #{phone},</if>" +
+        "<if test='name != null'>name = #{name},</if>" +
+        "<if test='idCard != null'>id_card = #{idCard},</if>" +
+        "<if test='password != null'>password = #{password},</if>" +
+        "<if test='payPassword != null'>pay_password = #{payPassword},</if>" +
+        "<if test='money != null'>money = #{money},</if>" +
+        "<if test='status != null'>status = #{status},</if>" +
+        "<if test='passType != null'>pass_type = #{passType},</if>" +
+        "<if test='deleteFlag != null'>delete_flag = #{deleteFlag},</if>" +
+        "<if test='createdTime != null'>created_time = #{createdTime},</if>" +
+        "<if test='createdUserId != null'>created_user_id = #{createdUserId},</if>" +
+        "<if test='updatedTime != null'>updated_time = #{updatedTime},</if>" +
+        "<if test='updatedUserId != null'>updated_user_id = #{updatedUserId},</if>" +
+        "<if test='logoutFlag != null'>logout_flag = #{logoutFlag},</if>" +
+        "<if test='logoutReason != null'>logout_reason = #{logoutReason},</if>" +
+        "<if test='logoutTime != null'>logout_time = #{logoutTime},</if>" +
+        "<if test='logoutCode != null'>logout_code = #{logoutCode},</if>" +
+        "<if test='nickName != null'>nick_name = #{nickName},</if>" +
+        "<if test='accountBlurb != null'>account_blurb = #{accountBlurb},</if>" +
+        "<if test='headImg != null'>head_img = #{headImg},</if>" +
+        "<if test='alipayAccount != null'>alipay_account = #{alipayAccount},</if>" +
+        "<if test='lawyerCertificateNo != null'>lawyer_certificate_no = #{lawyerCertificateNo},</if>" +
+        "<if test='lawFirm != null'>law_firm = #{lawFirm},</if>" +
+        "<if test='practiceYears != null'>practice_years = #{practiceYears},</if>" +
+        "<if test='practiceStartDate != null'>practice_start_date = #{practiceStartDate},</if>" +
+        "<if test='specialtyFields != null'>specialty_fields = #{specialtyFields},</if>" +
+        "<if test='certificationStatus != null'>certification_status = #{certificationStatus},</if>" +
+        "<if test='certificationFailReason != null'>certification_fail_reason = #{certificationFailReason},</if>" +
+        "<if test='certificationTime != null'>certification_time = #{certificationTime},</if>" +
+        "<if test='certificationReviewerId != null'>certification_reviewer_id = #{certificationReviewerId},</if>" +
+        "<if test='certificateImage != null'>certificate_image = #{certificateImage},</if>" +
+        "<if test='idCardFrontImage != null'>id_card_front_image = #{idCardFrontImage},</if>" +
+        "<if test='idCardBackImage != null'>id_card_back_image = #{idCardBackImage},</if>" +
+        "<if test='serviceScore != null'>service_score = #{serviceScore},</if>" +
+        "<if test='serviceCount != null'>service_count = #{serviceCount},</if>" +
+        "<if test='goodReviewCount != null'>good_review_count = #{goodReviewCount},</if>" +
+        "<if test='mediumReviewCount != null'>medium_review_count = #{mediumReviewCount},</if>" +
+        "<if test='badReviewCount != null'>bad_review_count = #{badReviewCount},</if>" +
+        "<if test='consultationFee != null'>consultation_fee = #{consultationFee},</if>" +
+        "<if test='agencyFee != null'>agency_fee = #{agencyFee},</if>" +
+        "<if test='province != null'>province = #{province},</if>" +
+        "<if test='city != null'>city = #{city},</if>" +
+        "<if test='district != null'>district = #{district},</if>" +
+        "<if test='address != null'>address = #{address},</if>" +
+        "<if test='email != null'>email = #{email},</if>" +
+        "<if test='gender != null'>gender = #{gender},</if>" +
+        "<if test='birthday != null'>birthday = #{birthday},</if>" +
+        "<if test='personalIntroduction != null'>personal_introduction = #{personalIntroduction},</if>" +
+        "<if test='educationBackground != null'>education_background = #{educationBackground},</if>" +
+        "<if test='workExperience != null'>work_experience = #{workExperience},</if>" +
+        "<if test='expertiseCases != null'>expertise_cases = #{expertiseCases},</if>" +
+        "<if test='isOnline != null'>is_online = #{isOnline},</if>" +
+        "<if test='lastOnlineTime != null'>last_online_time = #{lastOnlineTime},</if>" +
+        "<if test='isRecommended != null'>is_recommended = #{isRecommended},</if>" +
+        "<if test='recommendSort != null'>recommend_sort = #{recommendSort},</if>" +
+        "<if test='orderReceivingStatus != null'>order_receiving_status = #{orderReceivingStatus},</if>" +
+        "<if test='lawyerExpertiseAreaId != null'>lawyer_expertise_area_id = #{lawyerExpertiseAreaId},</if>" +
+        "<if test='commissionRate != null'>commission_rate = #{commissionRate},</if>" +
+        "<if test='paymentNum != null'>payment_num = #{paymentNum},</if>" +
+        "</set>" +
+        "WHERE id = #{id}" +
+        "</script>")
+Integer updateLawyerUser(LawyerUser user);
+
 }
 

+ 81 - 20
alien-entity/src/main/java/shop/alien/mapper/LifeFansMapper.java

@@ -24,14 +24,14 @@ public interface LifeFansMapper extends BaseMapper<LifeFans> {
             "        where delete_flag = 0 and fans_id = #{fansId} " +
             "    )   " +
             "    select info.id, IF(info.store_application_status = 0, user.nick_name, info.store_name) AS NAME," +
-            "    user.head_img image, concat('store_', user.phone) phoneId, IF(info.store_application_status = 0, user.account_blurb, info.store_blurb) AS blurb, 1 blockedType,user.id blockedId" +
+            "    user.head_img image, concat('store_', user.phone) phoneId, IF(info.store_application_status = 0, user.account_blurb, info.store_blurb) AS blurb, 1 blockedType,user.id blockedId ,IFNULL(user.nick_name, user.name) username, user.account_blurb accountBlurb " +
             "    from follow foll " +
             "    join store_user user on foll.phone = user.phone " +
             "    join store_info info on info.id = user.store_id " +
             "    left join store_img img on img.store_id = user.store_id and img.img_type = '10' and img.delete_flag = 0 " +
             "    where foll.flag = 'store' and user.delete_flag = 0 and info.delete_flag = 0 " +
             "    union " +
-            "    select user.id, user.user_name name, user.user_image image, concat('user_', user.user_phone) phoneId, user.jianjie blurb, 2 blockedType,user.id blockedId" +
+            "    select user.id, user.user_name name, user.user_image image, concat('user_', user.user_phone) phoneId, user.jianjie blurb, 2 blockedType,user.id blockedId,'' username, '' accountBlurb " +
             "    from follow foll " +
             "    join life_user user on foll.phone = user.user_phone   " +
             "    where foll.flag = 'user' and user.delete_flag = 0   " +
@@ -89,23 +89,84 @@ public interface LifeFansMapper extends BaseMapper<LifeFans> {
             "${ew.customSqlSegment} ")
     IPage<LifeFansVo> getMyFans(IPage<LifeFansVo> iPage, @Param("fansId") String fansId, @Param("blockerType") String blockerType, @Param("blockerId") String blockerId, @Param(Constants.WRAPPER) QueryWrapper<LifeFansVo> wrapper);
 
-    @Select("select foll.*, if(isnull(fans.id), 0, 1) isFollowThis, 1 as isFollowMe, count(fans2.id) fansNum, count(fans3.id) followNum from ( " +
-            "    with follow as ( " +
-            "    select substring_index(fans_id, '_', 1) as flag, substring_index(fans_id, '_', -1) as phone " +
-            "    from life_fans " +
-            "    where delete_flag = 0 and followed_id = #{fansId} " +
-            "    ) " +
-            "    select info.id, info.store_name name, user.head_img image, concat('store_', user.phone) phoneId, info.store_blurb blurb " +
-            "    from follow foll " +
-            "    join store_user user on foll.phone = user.phone " +
-            "    join store_info info on info.id = user.store_id " +
-            "    left join store_img img on img.store_id = user.store_id and img.img_type = '10' and img.delete_flag = 0 " +
-            "    where foll.flag = 'store' and user.delete_flag = 0 and info.delete_flag = 0 " +
+//    @Select("select foll.*, if(isnull(fans.id), 0, 1) isFollowThis, 1 as isFollowMe, count(fans2.id) fansNum, count(fans3.id) followNum from ( " +
+//            "    with follow as ( " +
+//            "    select substring_index(fans_id, '_', 1) as flag, substring_index(fans_id, '_', -1) as phone " +
+//            "    from life_fans " +
+//            "    where delete_flag = 0 and followed_id = #{fansId} " +
+//            "    ) " +
+//            "    select info.id," +
+//            "    \"CASE \" +\n" +
+//            "        \"WHEN user.store_id IS NULL OR info.store_application_status = 0 THEN user.nick_name \" +\n" +
+//            "        \"ELSE info.store_name \" +\n" +
+//            "        \"END AS name, \" +\n" +
+//            "        \"CASE \" +\n" +
+//            "        \"WHEN user.store_id IS NULL OR info.store_application_status IN (0, 2) THEN user.account_blurb \" +\n" +
+//            "        \"ELSE info.store_blurb \" +\n" +
+//            "        \"END AS store_blurb, \" + " +
+//            "    user.head_img image, concat('store_', user.phone) phoneId" +
+//            "    from follow foll " +
+//            "    join store_user user on foll.phone = user.phone " +
+//            "    LEFT JOIN store_info info ON user.store_id IS NOT NULL AND info.id = user.store_id " +
+//            "    and info.delete_flag = 0" +
+//            "    left join store_img img on img.store_id = user.store_id and img.img_type = '10' and img.delete_flag = 0 " +
+//            "    where foll.flag = 'store' and user.delete_flag = 0 " +
+//            ") foll " +
+//            "left join life_fans fans on fans.followed_id = foll.phoneId and fans.fans_id = #{fansId} and fans.delete_flag = 0 " +
+//            "left join life_fans fans2 on fans2.followed_id = foll.phoneId and fans2.delete_flag = 0 " +
+//            "left join life_fans fans3 on fans3.fans_id = foll.phoneId and fans3.delete_flag = 0 " +
+//            "${ew.customSqlSegment} ")
+    @Select("SELECT " +
+            "foll.*, " +
+            "IF(isnull(fans.id), 0, 1) isFollowThis, " +
+            "1 AS isFollowMe, " +
+            "count(fans2.id) fansNum, " +
+            "count(fans3.id) followNum " +
+            "FROM " +
+            "( " +
+            "WITH follow AS ( " +
+            "SELECT " +
+            "substring_index(fans_id, '_', 1) AS flag, " +
+            "substring_index(fans_id, '_', -1) AS phone " +
+            "FROM " +
+            "life_fans " +
+            "WHERE " +
+            "delete_flag = 0 " +
+            "AND followed_id = #{fansId} " +
+            ") " +
+            "SELECT " +
+            "info.id, " +
+            "CASE " +
+            "WHEN user.store_id IS NULL OR info.store_application_status = 0 THEN user.nick_name " +
+            "ELSE info.store_name " +
+            "END AS name, " +
+            "CASE " +
+            "WHEN user.store_id IS NULL OR info.store_application_status IN (0, 2) THEN user.account_blurb " +
+            "ELSE info.store_blurb " +
+            "END AS blurb, " +
+            "user.head_img AS image, " +
+            "concat('store_', user.phone) AS phoneId " +
+            "FROM " +
+            "follow foll " +
+            "JOIN store_user user ON foll.phone = user.phone " +
+            "LEFT JOIN store_info info ON user.store_id IS NOT NULL " +
+            "AND info.id = user.store_id " +
+            "AND info.delete_flag = 0 " +
+            "LEFT JOIN store_img img ON img.store_id = user.store_id " +
+            "AND img.img_type = '10' " +
+            "AND img.delete_flag = 0 " +
+            "WHERE " +
+            "foll.flag = 'store' " +
+            "AND user.delete_flag = 0 " +
             ") foll " +
-            "left join life_fans fans on fans.followed_id = foll.phoneId and fans.fans_id = #{fansId} and fans.delete_flag = 0 " +
-            "left join life_fans fans2 on fans2.followed_id = foll.phoneId and fans2.delete_flag = 0 " +
-            "left join life_fans fans3 on fans3.fans_id = foll.phoneId and fans3.delete_flag = 0 " +
-            "${ew.customSqlSegment} ")
+            "LEFT JOIN life_fans fans ON fans.followed_id = foll.phoneId " +
+            "AND fans.fans_id = #{fansId} " +
+            "AND fans.delete_flag = 0 " +
+            "LEFT JOIN life_fans fans2 ON fans2.followed_id = foll.phoneId " +
+            "AND fans2.delete_flag = 0 " +
+            "LEFT JOIN life_fans fans3 ON fans3.fans_id = foll.phoneId " +
+            "AND fans3.delete_flag = 0 " +
+            "${ew.customSqlSegment}")
     IPage<LifeFansVo> getMyStoreFans(IPage<LifeFansVo> iPage, @Param("fansId") String fansId, @Param(Constants.WRAPPER) QueryWrapper<LifeFansVo> wrapper);
 
     @Select("select foll.*, if(isnull(fans.id), 0, 1) isFollowThis, 1 as isFollowMe, " +
@@ -136,14 +197,14 @@ public interface LifeFansMapper extends BaseMapper<LifeFans> {
             "        join life_fans fans2 on fans1.followed_id = fans2.fans_id and fans1.fans_id = fans2.followed_id " +
             "        where fans1.delete_flag = 0 and fans2.delete_flag = 0 and fans1.fans_id = #{fansId} " +
             "    ) " +
-            "    select info.id, info.store_name name, user.head_img image, concat('store_', user.phone) phoneId, info.store_blurb blurb, 1 blockedType,user.id blockedId " +
+            "    select info.id, info.store_name name, user.head_img image, concat('store_', user.phone) phoneId, info.store_blurb blurb, 1 blockedType,user.id blockedId ,IFNULL(user.nick_name, user.name) username, user.account_blurb accountBlurb " +
             "    from follow foll " +
             "    join store_user user on foll.phone = user.phone " +
             "    join store_info info on info.id = user.store_id " +
             "    left join store_img img on img.store_id = user.store_id and img.img_type = '10' and img.delete_flag = 0 " +
             "    where foll.flag = 'store' and user.delete_flag = 0 and info.delete_flag = 0 " +
             "    union " +
-            "    select user.id, user.user_name name, user.user_image image, concat('user_', user.user_phone) phoneId, user.jianjie blurb, 2 blockedType,user.id blockedId " +
+            "    select user.id, user.user_name name, user.user_image image, concat('user_', user.user_phone) phoneId, user.jianjie blurb, 2 blockedType,user.id blockedId,'' username, '' accountBlurb " +
             "    from follow foll " +
             "    join life_user user on foll.phone = user.user_phone " +
             "    where foll.flag = 'user' and user.delete_flag = 0 " +

+ 1 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeGroupBuyMainMapper.java

@@ -102,6 +102,7 @@ public interface LifeGroupBuyMainMapper extends BaseMapper<LifeGroupBuyMain> {
             "LEFT JOIN store_info s \n" +
             "    ON g.store_id = s.id \n" +
             "    AND s.delete_flag = 0 \n" +
+            "    AND g.status = 5 \n" +
             "LEFT JOIN store_img img \n" +
             "    ON FIND_IN_SET(img.id, g.image_id) > 0 \n" +
             "    AND img.delete_flag = 0\t\t \n" +

+ 1 - 1
alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java

@@ -126,7 +126,7 @@ public interface StoreInfoMapper extends BaseMapper<StoreInfo> {
 
     @Select(
             "select " +
-            "            ROUND(ST_Distance_Sphere(ST_GeomFromText(CONCAT('POINT(', REPLACE(#{position}, ',', ' '), ')' )), ST_GeomFromText(CONCAT('POINT(', REPLACE(store_position, ',', ' '), ')' ))) / 1000, 2) dist " +
+            "            ROUND(ST_Distance_Sphere(ST_GeomFromText(CONCAT('POINT(', REPLACE(#{position}, ',', ' '), ')' )), ST_GeomFromText(CONCAT('POINT(', REPLACE(store_position, ',', ' '), ')' ))) / 1000, 1) dist " +
             "from store_info where id = #{storeId}"
             )
     Double getStoreDistance(@Param("position") String position,@Param("storeId") Integer storeId);

+ 1 - 0
alien-entity/src/main/resources/mapper/LawFirmMapper.xml

@@ -58,3 +58,4 @@
 
 </mapper>
 
+

+ 47 - 0
alien-gateway/src/main/java/shop/alien/gateway/controller/LawyerUserLogInController.java

@@ -0,0 +1,47 @@
+package shop.alien.gateway.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiOperationSupport;
+import io.swagger.annotations.ApiSort;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.dto.LawyerUserDto;
+import shop.alien.entity.store.vo.LawyerUserVo;
+import shop.alien.gateway.service.LawyerUserService;
+
+/**
+ * 门店用户 前端控制器
+ *
+ * @author ssk
+ * @since 2024-12-11
+ */
+@Slf4j
+@Api(tags = {"律师用户"})
+@ApiSort(8)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/user")
+@RequiredArgsConstructor
+public class LawyerUserLogInController {
+
+    private final LawyerUserService lawyerUserService;
+
+    @ApiOperation("律师用户登录")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/login")
+    public R<LawyerUserVo> login(@RequestBody LawyerUserDto lawyerUserDto) {
+        log.info("StoreUserController.login?lawyerUserDto={}", lawyerUserDto);
+        return lawyerUserService.logIn(lawyerUserDto);
+    }
+
+    @ApiOperation("律师用户验证码校验")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/checkMsgCode")
+    public R<LawyerUserVo> checkMsgCode(@RequestBody LawyerUserDto lawyerUserDto) {
+        log.info("StoreUserController.login?lawyerUserDto={}", lawyerUserDto);
+        return lawyerUserService.logIn(lawyerUserDto);
+    }
+}

+ 16 - 1
alien-gateway/src/main/java/shop/alien/gateway/controller/SystemController.java

@@ -5,8 +5,10 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeSys;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.dto.SystemLoginDto;
+import shop.alien.entity.store.dto.SystemRegisterDto;
 import shop.alien.entity.store.vo.SystemLoginVo;
 import shop.alien.gateway.service.SystemService;
 import shop.alien.util.common.TokenInfo;
@@ -41,7 +43,7 @@ public class SystemController {
     }
 
     @ApiOperation("web中台退出登录")
-    @ApiOperationSupport(order = 1)
+    @ApiOperationSupport(order = 2)
     @ApiImplicitParams({
             @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query"),
@@ -51,4 +53,17 @@ public class SystemController {
         return R.success("退出成功");
     }
 
+    @ApiOperation("web中台系统用户注册")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", paramType = "body", required = true),
+            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "body", required = true),
+            @ApiImplicitParam(name = "roleId", value = "角色id", dataType = "String", paramType = "body", required = false),
+    })
+    @PostMapping(value = "/register")
+    public R<LifeSys> register(@RequestBody SystemRegisterDto registerDto) {
+        log.info("SystemController.register?userName={},roleId={}", registerDto.getUserName(), registerDto.getRoleId());
+        return systemService.register(registerDto.getUserName(), registerDto.getPassword(), registerDto.getRoleId());
+    }
+
 }

+ 19 - 0
alien-gateway/src/main/java/shop/alien/gateway/mapper/LawFirmMapper.java

@@ -0,0 +1,19 @@
+package shop.alien.gateway.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.store.LawFirm;
+
+/**
+ * <p>
+ * 律所表 Mapper 接口
+ * </p>
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Mapper
+public interface LawFirmMapper extends BaseMapper<LawFirm> {
+
+}
+

+ 30 - 0
alien-gateway/src/main/java/shop/alien/gateway/mapper/LawyerServiceAreaMapper.java

@@ -0,0 +1,30 @@
+package shop.alien.gateway.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import shop.alien.entity.store.LawyerServiceArea;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 律师服务领域关联 Mapper 接口
+ * </p>
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Mapper
+public interface LawyerServiceAreaMapper extends BaseMapper<LawyerServiceArea> {
+
+    @Select("select lsa.lawyer_user_id, llps.name from lawyer_service_area lsa \n" +
+            "left join lawyer_legal_problem_scenario llps on llps.id = lsa.problem_scenario_id \n" +
+            " ${ew.customSqlSegment}")
+    List<Map<String, Object>> getLawyerLegalProblemScenarioList(@Param(Constants.WRAPPER) QueryWrapper<LawyerServiceArea> queryWrapper);
+}
+

+ 89 - 0
alien-gateway/src/main/java/shop/alien/gateway/mapper/LawyerUserMapper.java

@@ -0,0 +1,89 @@
+package shop.alien.gateway.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Update;
+import shop.alien.entity.store.LawyerUser;
+
+/**
+ * <p>
+ * 律师用户 Mapper 接口
+ * </p>
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Mapper
+public interface LawyerUserMapper extends BaseMapper<LawyerUser> {
+
+
+@Update("<script>" +
+        "UPDATE lawyer_user " +
+        "<set>" +
+        "<if test='firmId != null'>firm_id = #{firmId},</if>" +
+        "<if test='phone != null'>phone = #{phone},</if>" +
+        "<if test='name != null'>name = #{name},</if>" +
+        "<if test='idCard != null'>id_card = #{idCard},</if>" +
+        "<if test='password != null'>password = #{password},</if>" +
+        "<if test='payPassword != null'>pay_password = #{payPassword},</if>" +
+        "<if test='money != null'>money = #{money},</if>" +
+        "<if test='status != null'>status = #{status},</if>" +
+        "<if test='passType != null'>pass_type = #{passType},</if>" +
+        "<if test='deleteFlag != null'>delete_flag = #{deleteFlag},</if>" +
+        "<if test='createdTime != null'>created_time = #{createdTime},</if>" +
+        "<if test='createdUserId != null'>created_user_id = #{createdUserId},</if>" +
+        "<if test='updatedTime != null'>updated_time = #{updatedTime},</if>" +
+        "<if test='updatedUserId != null'>updated_user_id = #{updatedUserId},</if>" +
+        "<if test='logoutFlag != null'>logout_flag = #{logoutFlag},</if>" +
+        "<if test='logoutReason != null'>logout_reason = #{logoutReason},</if>" +
+        "<if test='logoutTime != null'>logout_time = #{logoutTime},</if>" +
+        "<if test='logoutCode != null'>logout_code = #{logoutCode},</if>" +
+        "<if test='nickName != null'>nick_name = #{nickName},</if>" +
+        "<if test='accountBlurb != null'>account_blurb = #{accountBlurb},</if>" +
+        "<if test='headImg != null'>head_img = #{headImg},</if>" +
+        "<if test='alipayAccount != null'>alipay_account = #{alipayAccount},</if>" +
+        "<if test='lawyerCertificateNo != null'>lawyer_certificate_no = #{lawyerCertificateNo},</if>" +
+        "<if test='lawFirm != null'>law_firm = #{lawFirm},</if>" +
+        "<if test='practiceYears != null'>practice_years = #{practiceYears},</if>" +
+        "<if test='practiceStartDate != null'>practice_start_date = #{practiceStartDate},</if>" +
+        "<if test='specialtyFields != null'>specialty_fields = #{specialtyFields},</if>" +
+        "<if test='certificationStatus != null'>certification_status = #{certificationStatus},</if>" +
+        "<if test='certificationFailReason != null'>certification_fail_reason = #{certificationFailReason},</if>" +
+        "<if test='certificationTime != null'>certification_time = #{certificationTime},</if>" +
+        "<if test='certificationReviewerId != null'>certification_reviewer_id = #{certificationReviewerId},</if>" +
+        "<if test='certificateImage != null'>certificate_image = #{certificateImage},</if>" +
+        "<if test='idCardFrontImage != null'>id_card_front_image = #{idCardFrontImage},</if>" +
+        "<if test='idCardBackImage != null'>id_card_back_image = #{idCardBackImage},</if>" +
+        "<if test='serviceScore != null'>service_score = #{serviceScore},</if>" +
+        "<if test='serviceCount != null'>service_count = #{serviceCount},</if>" +
+        "<if test='goodReviewCount != null'>good_review_count = #{goodReviewCount},</if>" +
+        "<if test='mediumReviewCount != null'>medium_review_count = #{mediumReviewCount},</if>" +
+        "<if test='badReviewCount != null'>bad_review_count = #{badReviewCount},</if>" +
+        "<if test='consultationFee != null'>consultation_fee = #{consultationFee},</if>" +
+        "<if test='agencyFee != null'>agency_fee = #{agencyFee},</if>" +
+        "<if test='province != null'>province = #{province},</if>" +
+        "<if test='city != null'>city = #{city},</if>" +
+        "<if test='district != null'>district = #{district},</if>" +
+        "<if test='address != null'>address = #{address},</if>" +
+        "<if test='email != null'>email = #{email},</if>" +
+        "<if test='gender != null'>gender = #{gender},</if>" +
+        "<if test='birthday != null'>birthday = #{birthday},</if>" +
+        "<if test='personalIntroduction != null'>personal_introduction = #{personalIntroduction},</if>" +
+        "<if test='educationBackground != null'>education_background = #{educationBackground},</if>" +
+        "<if test='workExperience != null'>work_experience = #{workExperience},</if>" +
+        "<if test='expertiseCases != null'>expertise_cases = #{expertiseCases},</if>" +
+        "<if test='isOnline != null'>is_online = #{isOnline},</if>" +
+        "<if test='lastOnlineTime != null'>last_online_time = #{lastOnlineTime},</if>" +
+        "<if test='isRecommended != null'>is_recommended = #{isRecommended},</if>" +
+        "<if test='recommendSort != null'>recommend_sort = #{recommendSort},</if>" +
+        "<if test='orderReceivingStatus != null'>order_receiving_status = #{orderReceivingStatus},</if>" +
+        "<if test='lawyerExpertiseAreaId != null'>lawyer_expertise_area_id = #{lawyerExpertiseAreaId},</if>" +
+        "<if test='commissionRate != null'>commission_rate = #{commissionRate},</if>" +
+        "<if test='paymentNum != null'>payment_num = #{paymentNum},</if>" +
+        "</set>" +
+        "WHERE id = #{id}" +
+        "</script>")
+Integer updateLawyerUser(LawyerUser user);
+
+}
+

+ 26 - 0
alien-gateway/src/main/java/shop/alien/gateway/service/LawyerUserService.java

@@ -0,0 +1,26 @@
+package shop.alien.gateway.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerUser;
+import shop.alien.entity.store.StoreUser;
+import shop.alien.entity.store.dto.LawyerUserDto;
+import shop.alien.entity.store.vo.LawyerUserVo;
+import shop.alien.entity.store.vo.StoreUserVo;
+
+/**
+ * 二期-门店用户 服务类
+ *
+ * @author ssk
+ * @since 2024-12-11
+ */
+public interface LawyerUserService extends IService<LawyerUser> {
+
+    /**
+     * 创建token
+     * @return
+     */
+    R<LawyerUserVo> createToKen(LawyerUser lawyerUser);
+    R<LawyerUserVo> logIn(LawyerUserDto lawyerUserDto);
+
+}

+ 12 - 0
alien-gateway/src/main/java/shop/alien/gateway/service/SystemService.java

@@ -1,5 +1,7 @@
 package shop.alien.gateway.service;
 
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeSys;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.vo.SystemLoginVo;
 
@@ -15,4 +17,14 @@ public interface SystemService {
 
     public SystemLoginVo logout(UserLoginInfo userLoginInfo);
 
+    /**
+     * 系统用户注册
+     *
+     * @param userName 用户名
+     * @param password 密码
+     * @param roleId   角色id
+     * @return R<LifeSys>
+     */
+    R<LifeSys> register(String userName, String password, String roleId);
+
 }

+ 136 - 0
alien-gateway/src/main/java/shop/alien/gateway/service/impl/LawyerUserServiceImpl.java

@@ -0,0 +1,136 @@
+package shop.alien.gateway.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawFirm;
+import shop.alien.entity.store.LawyerServiceArea;
+import shop.alien.entity.store.LawyerUser;
+import shop.alien.entity.store.dto.LawyerUserDto;
+import shop.alien.entity.store.vo.LawyerUserVo;
+import shop.alien.gateway.config.BaseRedisService;
+import shop.alien.gateway.mapper.LawFirmMapper;
+import shop.alien.gateway.mapper.LawyerServiceAreaMapper;
+import shop.alien.gateway.mapper.LawyerUserMapper;
+import shop.alien.gateway.service.LawyerUserService;
+import shop.alien.util.common.JwtUtil;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 二期-门店用户 服务实现类
+ *
+ * @author ssk
+ * @since 2024-12-11
+ */
+@Transactional
+@Service
+@RequiredArgsConstructor
+public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerUser> implements LawyerUserService {
+
+    @Value("${jwt.expiration-time}")
+    private String effectiveTime;
+
+    /**
+     * 设定初始化默认密码
+     */
+
+    private final BaseRedisService baseRedisService;
+    private final LawyerUserMapper lawyerUserMapper;
+    private final LawyerServiceAreaMapper lawyerServiceAreaMapper;
+    private final LawFirmMapper lawFirmMapper;
+
+    /**
+     * token
+     *
+     * @param lawyerUser
+     * @return
+     */
+    @Override
+    public R<LawyerUserVo> createToKen(LawyerUser lawyerUser) {
+        int effectiveTimeInt = Integer.parseInt(effectiveTime.substring(0, effectiveTime.length() - 1));
+        String effectiveTimeUnit = effectiveTime.substring(effectiveTime.length() - 1);
+        long effectiveTimeIntLong = 0L;
+        switch (effectiveTimeUnit) {
+            case "s": {
+                effectiveTimeIntLong = effectiveTimeInt * 1000L;
+                break;
+            }
+            case "m": {
+                effectiveTimeIntLong = effectiveTimeInt * 60L * 1000L;
+                break;
+            }
+            case "h": {
+                effectiveTimeIntLong = effectiveTimeInt * 60L * 60L * 1000L;
+                break;
+            }
+            case "d": {
+                effectiveTimeIntLong = effectiveTimeInt * 24L * 60L * 60L * 1000L;
+                break;
+            }
+        }
+
+        LawyerUserVo lawyerUserVo = new LawyerUserVo();
+        BeanUtils.copyProperties(lawyerUser, lawyerUserVo);
+        Map<String, String> tokenMap = new HashMap<>();
+        tokenMap.put("phone", lawyerUser.getPhone());
+        tokenMap.put("userName", lawyerUser.getName());
+        tokenMap.put("userId", lawyerUser.getId().toString());
+        tokenMap.put("userType", "lawyer");
+        tokenMap.put("passType", lawyerUser.getPassType().toString());
+        lawyerUserVo.setToken(JwtUtil.createJWT("lawyer_" + lawyerUser.getPhone(), lawyerUser.getName(), JSONObject.toJSONString(tokenMap), effectiveTimeIntLong));
+        baseRedisService.setString("lawyer_" + lawyerUser.getPhone(), lawyerUserVo.getToken());
+        return R.data(lawyerUserVo);
+    }
+
+    @Override
+    public R<LawyerUserVo> logIn(LawyerUserDto lawyerUserDto) {
+        LawyerUser lawyerUser = lawyerUserMapper.selectOne(new LambdaQueryWrapper<LawyerUser>()
+                .eq(LawyerUser::getPhone, lawyerUserDto.getPhone()).last("limit 1"));
+        if (ObjectUtils.isNotEmpty(lawyerUser)) {
+            if (lawyerUser.getStatus() == 0) {
+                return R.fail("账号被禁用");
+            }
+            lawyerUser.setPassType(1);
+            return createToKen(lawyerUser);
+        }else {
+            LawyerUser user = new LawyerUser();
+            BeanUtils.copyProperties(lawyerUserDto, user);
+            user.setLogoutFlag(0);
+            user.setStatus(1);
+            user.setDeleteFlag(0);
+            user.setIsOnline(1);
+            user.setIsRecommended(0);
+            user.setOrderReceivingStatus(0);
+            lawyerUserMapper.insert(user);
+            lawyerUserDto.getProblemScenarioIds().forEach(item -> {
+                LawyerServiceArea lawyerServiceArea = new LawyerServiceArea();
+                lawyerServiceArea.setLawyerUserId(user.getId());
+                lawyerServiceArea.setProblemScenarioId(item);
+                lawyerServiceArea.setCreatedTime(new Date());
+                lawyerServiceAreaMapper.insert(lawyerServiceArea);
+            });
+            LambdaQueryWrapper<LawyerUser> lawFirmLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            lawFirmLambdaQueryWrapper.eq(LawyerUser::getFirmId, lawyerUserDto.getFirmId());
+            List<LawyerUser> lawyerUsers = lawyerUserMapper.selectList(lawFirmLambdaQueryWrapper);
+            if (ObjectUtils.isNotEmpty(lawyerUsers)) {
+                String lawFirmIds = lawyerUsers.stream().map(u -> String.valueOf(u.getFirmId())).filter(Objects::nonNull).distinct().collect(Collectors.joining(","));
+                LawFirm lawFirm = new LawFirm();
+                lawFirm.setId(lawyerUserDto.getFirmId());
+                lawFirm.setPaymentAccount(lawFirmIds);
+                lawFirmMapper.updateById(lawFirm);
+            }
+            user.setPassType(0);
+            return createToKen(user);
+        }
+    }
+
+}

+ 40 - 2
alien-gateway/src/main/java/shop/alien/gateway/service/impl/SystemServiceImpl.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import shop.alien.entity.result.R;
 import shop.alien.entity.store.LifeSys;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.vo.SystemLoginVo;
@@ -66,11 +68,11 @@ public class SystemServiceImpl implements SystemService {
                 new LambdaQueryWrapper<LifeSys>()
                         .eq(LifeSys::getUserName, username)
         );
-        if (lifeSys != null && encryptToMD5(lifeSys.getUserPassword()).equals(password)) {
+        if (lifeSys != null && lifeSys.getUserPassword().equals(encryptToMD5(password))) {
             Map<String, String> tokenMap = new HashMap<>();
             tokenMap.put("phone", "123456");
             tokenMap.put("userName", lifeSys.getUserName());
-            tokenMap.put("userId", lifeSys.getId());
+            tokenMap.put("userId", String.valueOf(lifeSys.getId()));
             tokenMap.put("userType", "web");
             //存入token
             result.setToken(JwtUtil.createJWT("web_" + lifeSys.getId(), lifeSys.getUserName(), JSONObject.toJSONString(tokenMap), effectiveTimeIntLong));
@@ -92,6 +94,42 @@ public class SystemServiceImpl implements SystemService {
         return null;
     }
 
+    @Override
+    public R<LifeSys> register(String userName, String password, String roleId) {
+        // 校验必填字段
+        if (!StringUtils.hasText(userName)) {
+            return R.fail("用户名不能为空");
+        }
+        if (!StringUtils.hasText(password)) {
+            return R.fail("密码不能为空");
+        }
+
+        // 校验用户名是否已存在
+        LambdaQueryWrapper<LifeSys> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LifeSys::getUserName, userName);
+        LifeSys existingUser = lifeSysMapper.selectOne(queryWrapper);
+        if (existingUser != null) {
+            return R.fail("该用户名已存在,请更换其他用户名");
+        }
+
+        // 创建新用户
+        LifeSys lifeSys = new LifeSys();
+        lifeSys.setUserName(userName);
+        // 密码使用MD5加密后存储
+//        lifeSys.setUserPassword(encryptToMD5(password));
+//        if (StringUtils.hasText(roleId)) {
+//            lifeSys.setRoleId(roleId);
+//        }
+        lifeSys.setDeleteFlag(0); // 未删除
+
+        // 保存用户
+        int result = lifeSysMapper.insert(lifeSys);
+        if (result > 0) {
+            return R.data(lifeSys, "注册成功");
+        }
+        return R.fail("注册失败,请稍后重试");
+    }
+
     public static String encryptToMD5(String input) {
         try {
             // 获取 MD5 算法的 MessageDigest 实例

+ 41 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/AliController.java

@@ -0,0 +1,41 @@
+package shop.alien.lawyer.controller;
+
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import shop.alien.entity.result.R;
+import shop.alien.lawyer.util.AliSms;
+
+/**
+ * @author ssk
+ * @version 1.0
+ * @date 2024/12/11 17:34
+ */
+@Slf4j
+@Api(tags = {"二期-阿里接口"})
+@ApiSort(9)
+@CrossOrigin
+@RestController
+@RequestMapping("/ali")
+@RequiredArgsConstructor
+public class AliController {
+
+    private final AliSms aliSmsConfig;
+
+    @ApiOperation("发送短信")
+    @ApiOperationSupport(order = 4)
+    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true)})
+    @GetMapping("/sendSms")
+    public R sendSms(String phone) {
+        Integer code = aliSmsConfig.sendSms(phone);
+        log.info("AliController.sendSms?phone={}&code={}", phone, code);
+        if (code != null) {
+            return R.data(code);
+        }
+        return R.fail("短信发送失败");
+    }
+}

+ 9 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawFirmController.java

@@ -118,5 +118,14 @@ public class LawFirmController {
                 .page(lawFirmService);
         return R.data(pageResult);
     }
+
+    @ApiOperation("律所注册")
+    @ApiOperationSupport(order = 7)
+    @PostMapping("/register")
+    public R<LawFirm> register(@RequestBody LawFirm lawFirm) {
+        log.info("LawFirmController.register?lawFirm={}", lawFirm);
+        return lawFirmService.register(lawFirm);
+    }
 }
 
+

+ 18 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerConsultationOrderController.java

@@ -342,5 +342,23 @@ public class LawyerConsultationOrderController {
         return consultationOrderService.checkOrder(clientUserId, lawyerUserId);
     }
 
+    @ApiOperation("订单收益统计接口")
+    @ApiOperationSupport(order = 16)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "Integer", paramType = "query", required = true),
+    })
+    @GetMapping("/getOrderIncome")
+    public R<Map<String, Object>> getOrderIncome(@RequestParam Integer lawyerUserId) {
+        log.info("LawyerConsultationOrderController.getOrderIncome?lawyerUserId={}", lawyerUserId);
+        
+        // 参数校验
+        if (lawyerUserId == null) {
+            log.warn("查询订单收益失败:律师用户ID为空");
+            return R.fail("律师用户ID不能为空");
+        }
+        
+        return consultationOrderService.getOrderIncome(lawyerUserId);
+    }
+
 }
 

+ 2 - 1
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerLegalProblemScenarioController.java

@@ -1,6 +1,7 @@
 package shop.alien.lawyer.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -94,7 +95,7 @@ public class LawyerLegalProblemScenarioController {
         for (LawyerLegalProblemScenario item : list) {
             Integer id = item.getId();
             LawyerImg a = lawyerImgMapper.getLawyerImgById(id);
-            item.setImgUrl(a.getImgUrl());
+            item.setImgUrl(ObjectUtils.isNotEmpty(a) ? a.getImgUrl() : "");
         }
 
         return R.data(list);

+ 6 - 9
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerUserController.java

@@ -229,11 +229,8 @@ public class LawyerUserController {
         return lawyerUserService.getLawyerInfo(lawyerId);
     }
 
-
-
-
-    @ApiOperation("编辑新律师用户")
-    @ApiOperationSupport(order = 2)
+    @ApiOperation("更新律师用户信息")
+    @ApiOperationSupport(order = 15)
     @ApiImplicitParams({
             @ApiImplicitParam(name = "lawyerId", value = "律师ID", dataType = "Integer", paramType = "query", required = true),
             @ApiImplicitParam(name = "name", value = "律师姓名", dataType = "String", paramType = "query"),
@@ -243,10 +240,10 @@ public class LawyerUserController {
             @ApiImplicitParam(name = "headImg", value = "律师头像", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "certificationTime", value = "认证时间(从业时间??待确认)", dataType = "Data", paramType = "query"),
     })
-    @PostMapping("/upDateLawyerUser")
-    public R<LawyerUser> editLawyerUser(@RequestBody LawyerUserVo lawyerUserVo) {
-        log.info("LawyerUserController.upDateLawyerUser?lawyerUserVo={}",lawyerUserVo);
-        return lawyerUserService.upDateLawyerUser(lawyerUserVo);
+    @PostMapping("/updateLawyerUser")
+    public R<LawyerUser> updateLawyerUser(@RequestBody LawyerUserVo lawyerUserVo) {
+        log.info("LawyerUserController.updateLawyerUser?lawyerUserVo={}", lawyerUserVo);
+        return lawyerUserService.updateLawyerUser(lawyerUserVo);
     }
 
 }

+ 9 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawFirmService.java

@@ -47,5 +47,14 @@ public interface LawFirmService extends IService<LawFirm> {
      * @return R<Boolean>
      */
     R<Boolean> deleteLawFirm(Integer id);
+
+    /**
+     * 律所注册
+     *
+     * @param lawFirm 律所信息
+     * @return R<LawFirm>
+     */
+    R<LawFirm> register(LawFirm lawFirm);
 }
 
+

+ 9 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerConsultationOrderService.java

@@ -123,5 +123,14 @@ public interface LawyerConsultationOrderService extends IService<LawyerConsultat
      * @return
      */
    R<Map<String, String>> checkOrder(Integer clientUserId,Integer lawyerUserId);
+
+
+   /**
+   * 获取律师订单收益统计
+   *
+   * @param lawyerUserId 律师用户ID
+   * @return 订单收益统计信息
+   */
+   R<Map<String, Object>> getOrderIncome(Integer lawyerUserId);
 }
 

+ 7 - 3
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerUserService.java

@@ -2,7 +2,6 @@ package shop.alien.lawyer.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
-import org.springframework.web.bind.annotation.RequestParam;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawyerUser;
 import shop.alien.entity.store.vo.LawyerUserVo;
@@ -132,7 +131,12 @@ public interface LawyerUserService extends IService<LawyerUser> {
      */
     R<LawyerUser> getLawyerInfo(Integer lawyerId);
 
-
-    R<LawyerUser> upDateLawyerUser(LawyerUserVo lawyerUserVo);
+    /**
+     * 更新律师用户信息
+     *
+     * @param lawyerUserVo 律师用户信息VO
+     * @return R<LawyerUser> 更新后的律师信息
+     */
+    R<LawyerUser> updateLawyerUser(LawyerUserVo lawyerUserVo);
 }
 

+ 84 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawFirmServiceImpl.java

@@ -74,5 +74,89 @@ public class LawFirmServiceImpl extends ServiceImpl<LawFirmMapper, LawFirm> impl
         }
         return R.fail("删除失败");
     }
+
+    @Override
+    public R<LawFirm> register(LawFirm lawFirm) {
+        log.info("LawFirmServiceImpl.register?lawFirm={}", lawFirm);
+        
+        // 校验必填字段
+        if (!StringUtils.hasText(lawFirm.getFirmName())) {
+            return R.fail("律所名称不能为空");
+        }
+        if (!StringUtils.hasText(lawFirm.getCreditCode())) {
+            return R.fail("统一社会信用代码不能为空");
+        }
+        if (!StringUtils.hasText(lawFirm.getPhone())) {
+            return R.fail("联系电话不能为空");
+        }
+        if (!StringUtils.hasText(lawFirm.getDirectorName())) {
+            return R.fail("负责人姓名不能为空");
+        }
+        if (!StringUtils.hasText(lawFirm.getDirectorPhone())) {
+            return R.fail("负责人电话不能为空");
+        }
+        
+        // 校验统一社会信用代码是否已存在
+        LambdaQueryWrapper<LawFirm> creditCodeWrapper = new LambdaQueryWrapper<>();
+        creditCodeWrapper.eq(LawFirm::getCreditCode, lawFirm.getCreditCode());
+        creditCodeWrapper.eq(LawFirm::getDeleteFlag, 0);
+        long creditCodeCount = this.count(creditCodeWrapper);
+        if (creditCodeCount > 0) {
+            return R.fail("该统一社会信用代码已注册,请勿重复注册");
+        }
+        
+        // 校验联系电话是否已存在
+        if (StringUtils.hasText(lawFirm.getPhone())) {
+            LambdaQueryWrapper<LawFirm> phoneWrapper = new LambdaQueryWrapper<>();
+            phoneWrapper.eq(LawFirm::getPhone, lawFirm.getPhone());
+            phoneWrapper.eq(LawFirm::getDeleteFlag, 0);
+            long phoneCount = this.count(phoneWrapper);
+            if (phoneCount > 0) {
+                return R.fail("该联系电话已被使用,请更换其他号码");
+            }
+        }
+        
+        // 校验负责人电话是否已存在
+        if (StringUtils.hasText(lawFirm.getDirectorPhone())) {
+            LambdaQueryWrapper<LawFirm> directorPhoneWrapper = new LambdaQueryWrapper<>();
+            directorPhoneWrapper.eq(LawFirm::getDirectorPhone, lawFirm.getDirectorPhone());
+            directorPhoneWrapper.eq(LawFirm::getDeleteFlag, 0);
+            long directorPhoneCount = this.count(directorPhoneWrapper);
+            if (directorPhoneCount > 0) {
+                return R.fail("该负责人电话已被使用,请更换其他号码");
+            }
+        }
+        
+        // 校验邮箱是否已存在
+        if (StringUtils.hasText(lawFirm.getEmail())) {
+            LambdaQueryWrapper<LawFirm> emailWrapper = new LambdaQueryWrapper<>();
+            emailWrapper.eq(LawFirm::getEmail, lawFirm.getEmail());
+            emailWrapper.eq(LawFirm::getDeleteFlag, 0);
+            long emailCount = this.count(emailWrapper);
+            if (emailCount > 0) {
+                return R.fail("该邮箱已被使用,请更换其他邮箱");
+            }
+        }
+        
+        // 设置注册时的初始状态
+        lawFirm.setStatus(1); // 启用状态
+        lawFirm.setCertificationStatus(0); // 未认证状态
+        lawFirm.setDeleteFlag(0); // 未删除
+        lawFirm.setIsRecommended(0); // 默认不推荐
+        if (lawFirm.getLawyerCount() == null) {
+            lawFirm.setLawyerCount(0);
+        }
+        if (lawFirm.getPartnerCount() == null) {
+            lawFirm.setPartnerCount(0);
+        }
+        
+        // 保存律所信息
+        boolean result = this.save(lawFirm);
+        if (result) {
+            return R.data(lawFirm, "注册成功,请等待审核");
+        }
+        return R.fail("注册失败,请稍后重试");
+    }
 }
 
+

+ 142 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerConsultationOrderServiceImpl.java

@@ -21,6 +21,7 @@ import shop.alien.entity.store.LawyerUser;
 import shop.alien.entity.store.dto.LawyerConsultationOrderDto;
 import shop.alien.entity.store.dto.PayStatusRequest;
 import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
+import shop.alien.entity.store.vo.OrderRevenueVO;
 import shop.alien.lawyer.service.LawyerConsultationOrderService;
 import shop.alien.lawyer.service.LawyerUserService;
 import shop.alien.lawyer.service.OrderExpirationService;
@@ -30,6 +31,9 @@ import shop.alien.mapper.LawyerServiceAreaMapper;
 import shop.alien.mapper.LawyerUserMapper;
 import shop.alien.util.common.constant.LawyerStatusEnum;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -910,6 +914,144 @@ public class LawyerConsultationOrderServiceImpl extends ServiceImpl<LawyerConsul
         return R.success("可以咨询该律师");
     }
 
+    /**
+     * 获取律师订单收益统计
+     * <p>
+     * 统计三个维度的收益数据:
+     * 1. 全部收益:所有已支付订单的订单总数和收益合计
+     * 2. 进行中:订单状态=2(进行中)且已支付的订单总数和收益合计
+     * 3. 已完成:订单状态=3(已完成)且已支付的订单总数和收益合计
+     * </p>
+     *
+     * @param lawyerUserId 律师用户ID
+     * @return 订单收益统计信息
+     */
+    @Override
+    public R<Map<String, Object>> getOrderIncome(Integer lawyerUserId) {
+        log.info("LawyerConsultationOrderServiceImpl.getOrderIncome?lawyerUserId={}", lawyerUserId);
+
+        // 参数校验
+        if (lawyerUserId == null) {
+            log.warn("查询订单收益失败:律师用户ID为空");
+            return R.fail("律师用户ID不能为空");
+        }
+
+        Map<String, Object> resultMap = new HashMap<>();
+        OrderRevenueVO revenueVO = new OrderRevenueVO();
+
+        try {
+            // 构建查询条件:查询已支付的订单(paymentStatus = 1)
+            LambdaQueryWrapper<LawyerConsultationOrder> allRevenueWrapper = new LambdaQueryWrapper<>();
+            allRevenueWrapper.eq(LawyerConsultationOrder::getLawyerUserId, lawyerUserId)
+                    .eq(LawyerConsultationOrder::getPaymentStatus, 1) // 已支付
+                    .eq(LawyerConsultationOrder::getDeleteFlag, 0);
+
+            // 查询全部已支付订单的统计
+            List<LawyerConsultationOrder> allPaidOrders = consultationOrderMapper.selectList(allRevenueWrapper);
+            long allOrderCount = allPaidOrders.size();
+            long allRevenue = allPaidOrders.stream()
+                    .filter(order -> order.getOrderAmount() != null)
+                    .mapToLong(LawyerConsultationOrder::getOrderAmount)
+                    .sum();
+
+            long consultationFee = allPaidOrders.stream()
+                    .filter(order -> order.getConsultationFee() != null)
+                    .mapToLong(LawyerConsultationOrder::getConsultationFee)
+                    .sum();
+
+            revenueVO.setAllOrderCount(allOrderCount);
+            revenueVO.setAllRevenue(allRevenue-consultationFee);
+
+
+            // 查询进行中订单的统计(orderStatus = 2 且已支付)
+            LambdaQueryWrapper<LawyerConsultationOrder> inProgressWrapper = new LambdaQueryWrapper<>();
+            inProgressWrapper.eq(LawyerConsultationOrder::getLawyerUserId, lawyerUserId)
+                    .eq(LawyerConsultationOrder::getOrderStatus, LawyerStatusEnum.INPROGRESS.getStatus()) // 2:进行中
+                    .eq(LawyerConsultationOrder::getPaymentStatus, 1) // 已支付
+                    .eq(LawyerConsultationOrder::getDeleteFlag, 0);
+
+            List<LawyerConsultationOrder> inProgressOrders = consultationOrderMapper.selectList(inProgressWrapper);
+            long inProgressOrderCount = inProgressOrders.size();
+
+            long inProgressRevenue = inProgressOrders.stream()
+                    .filter(order -> order.getOrderAmount() != null)
+                    .mapToLong(LawyerConsultationOrder::getOrderAmount)
+                    .sum();
+
+            long inProgressFee = inProgressOrders.stream()
+                    .filter(order -> order.getConsultationFee() != null)
+                    .mapToLong(LawyerConsultationOrder::getConsultationFee)
+                    .sum();
+
+            revenueVO.setInProgressOrderCount(inProgressOrderCount);
+            revenueVO.setInProgressRevenue(inProgressRevenue-inProgressFee);
+
+
+            // 查询已完成订单的统计(orderStatus = 3 且已支付)
+            LambdaQueryWrapper<LawyerConsultationOrder> completedWrapper = new LambdaQueryWrapper<>();
+            completedWrapper.eq(LawyerConsultationOrder::getLawyerUserId, lawyerUserId)
+                    .eq(LawyerConsultationOrder::getOrderStatus, LawyerStatusEnum.COMPLETE.getStatus()) // 3:已完成
+                    .eq(LawyerConsultationOrder::getPaymentStatus, 1) // 已支付
+                    .eq(LawyerConsultationOrder::getDeleteFlag, 0);
+
+            List<LawyerConsultationOrder> completedOrders = consultationOrderMapper.selectList(completedWrapper);
+            long completedOrderCount = completedOrders.size();
+            long completedRevenue = completedOrders.stream()
+                    .filter(order -> order.getOrderAmount() != null)
+                    .mapToLong(LawyerConsultationOrder::getOrderAmount)
+                    .sum();
+
+            long completedFee = completedOrders.stream()
+                    .filter(order -> order.getConsultationFee() != null)
+                    .mapToLong(LawyerConsultationOrder::getConsultationFee)
+                    .sum();
+
+            revenueVO.setCompletedOrderCount(completedOrderCount);
+            revenueVO.setCompletedRevenue(completedRevenue-completedFee);
+
+            // 构建返回结果
+            Map<String, Object> allRevenueMap = new HashMap<>();
+            allRevenueMap.put("orderCount", revenueVO.getAllOrderCount());
+            allRevenueMap.put("totalRevenue", revenueVO.getAllRevenue());
+            resultMap.put("allRevenue", allRevenueMap);
+
+            Map<String, Object> inProgressMap = new HashMap<>();
+            inProgressMap.put("orderCount", revenueVO.getInProgressOrderCount());
+            inProgressMap.put("totalRevenue", revenueVO.getInProgressRevenue());
+            resultMap.put("inProgress", inProgressMap);
+
+            Map<String, Object> completedMap = new HashMap<>();
+            completedMap.put("orderCount", revenueVO.getCompletedOrderCount());
+            completedMap.put("totalRevenue", revenueVO.getCompletedRevenue());
+            resultMap.put("completed", completedMap);
+
+            log.info("查询订单收益成功,律师ID={}, 全部订单数={}, 全部收益={}, 进行中订单数={}, 进行中收益={}, 已完成订单数={}, 已完成收益={}",
+                    lawyerUserId, allOrderCount, allRevenue, inProgressOrderCount, inProgressRevenue,
+                    completedOrderCount, completedRevenue);
+
+            return R.data(resultMap);
+
+        } catch (Exception e) {
+            log.error("查询订单收益失败,律师ID={}", lawyerUserId, e);
+            return R.fail("查询订单收益失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 格式化收益金额(分转元)
+     *
+     * @param revenueInCents 收益金额(单位:分)
+     * @return 格式化后的金额字符串(单位:元)
+     */
+    private String formatRevenue(long revenueInCents) {
+        if (revenueInCents == 0) {
+            return "0";
+        }
+        BigDecimal revenue = new BigDecimal(revenueInCents);
+        BigDecimal revenueInYuan = revenue.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
+        return revenueInYuan.toString();
+    }
+
 
 }
 

+ 7 - 2
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerExpertiseAreaServiceImpl.java

@@ -6,9 +6,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.StringUtils;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawyerExpertiseArea;
 import shop.alien.lawyer.service.LawyerExpertiseAreaService;
@@ -39,7 +39,7 @@ public class LawyerExpertiseAreaServiceImpl extends ServiceImpl<LawyerExpertiseA
         Page<LawyerExpertiseArea> page = new Page<>(pageNum, pageSize);
         LambdaQueryWrapper<LawyerExpertiseArea> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(LawyerExpertiseArea::getDeleteFlag, 0);
-        if (StringUtils.hasText(expertiseAreaInfo)) {
+        if (StringUtils.isNotBlank(expertiseAreaInfo)) {
             queryWrapper.like(LawyerExpertiseArea::getExpertiseAreaInfo, expertiseAreaInfo);
         }
         queryWrapper.orderByDesc(LawyerExpertiseArea::getCreatedTime);
@@ -56,6 +56,11 @@ public class LawyerExpertiseAreaServiceImpl extends ServiceImpl<LawyerExpertiseA
             log.warn("新增领域信息失败:参数为空");
             return R.fail("参数不能为空");
         }
+        // 参数校验
+        if (StringUtils.isBlank(expertiseArea.getExpertiseAreaInfo())) {
+            log.warn("新增领域信息失败:领域名称为空");
+            return R.fail("领域名称不能为空");
+        }
 
         // 设置默认值
         if (expertiseArea.getDeleteFlag() == null) {

+ 33 - 29
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerUserServiceImpl.java

@@ -356,16 +356,16 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
     /**
      * 获取AI推荐律师列表
      *
-     * @param page 页码
-     *             pageSize 页大小
-     *             categoryId 分类ID
+     * @param page       页码
+     * @param size       页大小
+     * @param categoryId 分类ID
+     * @return R<IPage<LawyerUser>> 推荐律师列表
      */
     @Override
     public R<IPage<LawyerUser>> getAiRecommendList(int page, int size, Integer categoryId) {
-        log.info("LawyerUserController.aiRecommendList?page={},size={},categoryId={}",
+        log.info("LawyerUserServiceImpl.getAiRecommendList?page={},size={},categoryId={}",
                 page, size, categoryId);
 
-
         // 构建查询条件
         QueryWrapper<LawyerUser> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("delete_flag", 0)
@@ -444,20 +444,20 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
             return R.fail("该律师账号已删除");
         }
 
-        List<LawyerConsultationOrder> list=lawyerConsultationOrderMapper.selectOrder(null, id);
-
+        List<LawyerConsultationOrder> orderList = lawyerConsultationOrderMapper.selectOrder(null, id);
 
-        if (!CollectionUtils.isEmpty( list)){
+        if (!CollectionUtils.isEmpty(orderList)) {
             // 提示前端有未完成订单 1:有未完成订单  0:无未完成订单
             resultMap.put("unfinishedOrder", 1);
         }
 
-        if (lawyerUser.getOrderReceivingStatus() != null && lawyerUser.getOrderReceivingStatus() == 1){
+        if (lawyerUser.getOrderReceivingStatus() != null && lawyerUser.getOrderReceivingStatus() == 1) {
             // 提示前端接单状态为接单中 1:接单中  0:未接单
             resultMap.put("orderReceivingStatus", 1);
         }
 
-        if (CollectionUtils.isEmpty( list) || lawyerUser.getStatus() == 0){
+        // 只有无未完成订单且状态为禁用时,才执行注销操作
+        if (CollectionUtils.isEmpty(orderList) && lawyerUser.getStatus() == 0) {
             // 设置注销相关字段
             lawyerUser.setLogoutFlag(1); // 注销标记:1-已注销
             lawyerUser.setLogoutTime(new Date()); // 注销时间
@@ -467,10 +467,6 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
             lawyerUser.setIsRecommended(0); // 推荐状态设置为不推荐
             lawyerUser.setLastOnlineTime(new Date());
 
-            // 如果传入了注销原因,可以在这里设置
-//         lawyerUser.setLogoutReason(logoutReason);
-//         lawyerUser.setLogoutCode(logoutCode);
-
             // 执行更新操作
             boolean result = this.updateById(lawyerUser);
             if (!result) {
@@ -517,30 +513,38 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
             return R.fail("律师信息已删除");
         }
 
-        LawyerUserVo lawyerUserVo = new LawyerUserVo();
-        BeanUtils.copyProperties(lawyer, lawyerUserVo);
-
-        LawFirm lawFirm=lawFirmMapper.selectById(lawyer.getFirmId());
-        lawyerUserVo.setFirmName(lawFirm.getFirmName());
-        lawyerUserVo.setAddress(lawFirm.getAddress());
-
-        // 为律师设置关联的法律问题场景列表
-//        List<LawyerUser> lawyerList = Collections.singletonList(lawyer);
-//        setLawyerScenarios(lawyerList);
+        LawFirm lawFirm = lawFirmMapper.selectById(lawyer.getFirmId());
+        if (lawFirm != null) {
+            // 如果需要在返回对象中设置律所信息,可以在这里处理
+            // 目前直接返回 LawyerUser 对象
+        }
 
         return R.data(lawyer);
     }
 
     @Override
-    public R<LawyerUser> upDateLawyerUser(LawyerUserVo lawyerUserVo) {
-        log.info("LawyerUserController.upDateLawyerUser?lawyerUserVo={}", lawyerUserVo);
+    public R<LawyerUser> updateLawyerUser(LawyerUserVo lawyerUserVo) {
+        log.info("LawyerUserServiceImpl.updateLawyerUser?lawyerUserVo={}", lawyerUserVo);
+        
+        // 参数校验
+        if (lawyerUserVo == null || lawyerUserVo.getId() == null) {
+            log.warn("更新律师用户信息失败:参数为空或律师ID为空");
+            return R.fail("律师ID不能为空");
+        }
+        
         LawyerUser lawyerUser = new LawyerUser();
         BeanUtils.copyProperties(lawyerUserVo, lawyerUser);
-        boolean result=this.updateById(lawyerUser);
-        if (!result){
+        
+        Integer result = lawyerUserMapper.updateLawyerUser(lawyerUser);
+        if (result <= 0) {
+            log.warn("更新律师用户信息失败:更新数据库失败,律师ID={}", lawyerUserVo.getId());
             return R.fail("修改律师信息失败");
         }
-        return R.success("修改律师信息失败");
+        
+        // 查询更新后的律师信息
+        LawyerUser updatedLawyer = this.getById(lawyerUserVo.getId());
+        log.info("更新律师用户信息成功,律师ID={}", lawyerUserVo.getId());
+        return R.data(updatedLawyer);
     }
 }
 

+ 98 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/util/AliSms.java

@@ -0,0 +1,98 @@
+package shop.alien.lawyer.util;
+
+import com.aliyun.dysmsapi20170525.Client;
+import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
+import com.aliyun.teaopenapi.models.Config;
+import com.aliyun.teautil.models.RuntimeOptions;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import shop.alien.util.common.RandomCreateUtil;
+import shop.alien.lawyer.config.BaseRedisService;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 阿里云验证码配置
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/12/12 10:17
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class AliSms {
+    private final BaseRedisService baseRedisService;
+
+    @Value("${ali.sms.accessKeyId}")
+    private String accessKeyId;
+
+    @Value("${ali.sms.accessKeySecret}")
+    private String accessKeySecret;
+
+    @Value("${ali.sms.endPoint}")
+    private String endPoint;
+
+    @Value("${ali.sms.signName}")
+    private String signName;
+
+    @Value("${ali.sms.templateCode}")
+    private String templateCode;
+
+    /**
+     * 发送验证码
+     *
+     * @param phone 手机号
+     * @return 验证码
+     */
+    public Integer sendSms(String phone) {
+        log.info("AliSmsConfig.sendSms?phone={}", phone);
+        try {
+            // -----------------测试用手机号--------------------------------------------------------------------------------------------
+            List<String> phoneList = Arrays.asList("19999990001", "19999990002", "19999990003", "19999990004", "19999990005", "19999990006", "19999990007", "19999990008", "19999990009", "19999990010",
+                    "16666660001", "16666660002", "16666660003", "16666660004", "16666660005", "16666660006", "16666660007", "16666660008", "16666660009", "16666660010");
+            if (phoneList.contains(phone)) {
+                // 验证码发送成功,将验证码保存到redis中 设置60秒过期
+                baseRedisService.setString("verification_lawyer_"+phone,"123456",Long.valueOf(300));
+                return 123456;
+            }
+            // -----------------测试用手机号--------------------------------------------------------------------------------------------
+
+            Config config = new Config()
+                    .setEndpoint(endPoint)
+                    .setAccessKeyId(accessKeyId)
+                    .setAccessKeySecret(accessKeySecret);
+            Integer code = RandomCreateUtil.getRandomNum(100000, 999999);
+
+            // 构建发送请求
+            SendSmsRequest sendSmsRequest = new SendSmsRequest()
+                    // 设置签名
+                    .setSignName(signName)
+                    // 设置模板
+                    .setTemplateCode(templateCode)
+                    // 设置手机号为参数传入的值
+                    .setPhoneNumbers(phone)
+                    // 设置模板参数为传入的验证码
+                    .setTemplateParam("{\"code\":\"" + code + "\"}");
+            // 运行时选择,可以设置不同的属性来配置运行时环境的参数。
+            RuntimeOptions runtime = new RuntimeOptions();
+            Client client = new Client(config);
+            // 复制代码运行请自行打印 API 的返回值
+            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
+            if (!"OK".equals(sendSmsResponse.getBody().getCode())) {
+                return null;
+            }
+            // 验证码发送成功,将验证码保存到redis中 设置60秒过期
+            baseRedisService.setString("verification_lawyer_"+phone,code.toString(),Long.valueOf(60));
+            return code;
+        } catch (Exception e) {
+            log.error("AliSmsConfig.sendSms ERROR Msg={}", e.getMessage());
+            return null;
+        }
+    }
+
+}

+ 16 - 1
alien-store/src/main/java/shop/alien/store/controller/SystemController.java

@@ -5,8 +5,10 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeSys;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.dto.SystemLoginDto;
+import shop.alien.entity.store.dto.SystemRegisterDto;
 import shop.alien.entity.store.vo.SystemLoginVo;
 import shop.alien.store.service.SystemService;
 import shop.alien.util.common.TokenInfo;
@@ -41,7 +43,7 @@ public class SystemController {
     }
 
     @ApiOperation("web中台退出登录")
-    @ApiOperationSupport(order = 1)
+    @ApiOperationSupport(order = 2)
     @ApiImplicitParams({
             @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query"),
@@ -51,4 +53,17 @@ public class SystemController {
         return R.success("退出成功");
     }
 
+    @ApiOperation("系统用户注册")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", paramType = "body", required = true),
+            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "body", required = true),
+            @ApiImplicitParam(name = "roleId", value = "角色id", dataType = "String", paramType = "body", required = false),
+    })
+    @PostMapping(value = "/register")
+    public R<LifeSys> register(@RequestBody SystemRegisterDto registerDto) {
+        log.info("SystemController.register?userName={},roleId={}", registerDto.getUserName(), registerDto.getRoleId());
+        return systemService.register(registerDto.getUserName(), registerDto.getPassword(), registerDto.getRoleId());
+    }
+
 }

+ 12 - 0
alien-store/src/main/java/shop/alien/store/service/SystemService.java

@@ -1,5 +1,7 @@
 package shop.alien.store.service;
 
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeSys;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.vo.SystemLoginVo;
 
@@ -15,4 +17,14 @@ public interface SystemService {
 
     public SystemLoginVo logout(UserLoginInfo userLoginInfo);
 
+    /**
+     * 系统用户注册
+     *
+     * @param userName 用户名
+     * @param password 密码
+     * @param roleId   角色id
+     * @return R<LifeSys>
+     */
+    R<LifeSys> register(String userName, String password, String roleId);
+
 }

+ 40 - 2
alien-store/src/main/java/shop/alien/store/service/impl/SystemServiceImpl.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import shop.alien.entity.result.R;
 import shop.alien.entity.store.LifeSys;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.vo.SystemLoginVo;
@@ -66,11 +68,11 @@ public class SystemServiceImpl implements SystemService {
                 new LambdaQueryWrapper<LifeSys>()
                         .eq(LifeSys::getUserName, username)
         );
-        if (lifeSys != null && encryptToMD5(lifeSys.getUserPassword()).equals(password)) {
+        if (lifeSys != null && lifeSys.getUserPassword().equals(encryptToMD5(password))) {
             Map<String, String> tokenMap = new HashMap<>();
             tokenMap.put("phone", "123456");
             tokenMap.put("userName", lifeSys.getUserName());
-            tokenMap.put("userId", lifeSys.getId());
+            tokenMap.put("userId", String.valueOf(lifeSys.getId()));
             tokenMap.put("userType", "web");
             //存入token
             result.setToken(JwtUtil.createJWT("web_" + lifeSys.getId(), lifeSys.getUserName(), JSONObject.toJSONString(tokenMap), effectiveTimeIntLong));
@@ -92,6 +94,42 @@ public class SystemServiceImpl implements SystemService {
         return null;
     }
 
+    @Override
+    public R<LifeSys> register(String userName, String password, String roleId) {
+        // 校验必填字段
+        if (!StringUtils.hasText(userName)) {
+            return R.fail("用户名不能为空");
+        }
+        if (!StringUtils.hasText(password)) {
+            return R.fail("密码不能为空");
+        }
+
+        // 校验用户名是否已存在
+        LambdaQueryWrapper<LifeSys> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LifeSys::getUserName, userName);
+        LifeSys existingUser = lifeSysMapper.selectOne(queryWrapper);
+        if (existingUser != null) {
+            return R.fail("该用户名已存在,请更换其他用户名");
+        }
+
+        // 创建新用户
+        LifeSys lifeSys = new LifeSys();
+        lifeSys.setUserName(userName);
+        // 密码使用MD5加密后存储
+        lifeSys.setUserPassword(encryptToMD5(password));
+        if (StringUtils.hasText(roleId)) {
+            lifeSys.setRoleId(roleId);
+        }
+        lifeSys.setDeleteFlag(0); // 未删除
+
+        // 保存用户
+        int result = lifeSysMapper.insert(lifeSys);
+        if (result > 0) {
+            return R.data(lifeSys, "注册成功");
+        }
+        return R.fail("注册失败,请稍后重试");
+    }
+
     public static String encryptToMD5(String input) {
         try {
             // 获取 MD5 算法的 MessageDigest 实例