Explorar o código

关注和评论功能

30262728@qq.com hai 6 días
pai
achega
695a78efda
Modificáronse 44 ficheiros con 1044 adicións e 30 borrados
  1. 155 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/RatingsReviewsController.java
  2. 116 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/UserFollowsController.java
  3. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/RatingsReviewsDao.java
  4. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/UserFollowsDao.java
  5. 44 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/RatingsReviewsDTO.java
  6. 32 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/RatingsReviewsListDTO.java
  7. 38 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/UserFollowsDTO.java
  8. 29 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/UserFollowsListDTO.java
  9. 14 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/ReviewSetting.java
  10. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cUserReceiptEntity.java
  11. 12 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cUserStatEntity.java
  12. 74 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/RatingsReviewsEntity.java
  13. 49 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/UserFollowsEntity.java
  14. 29 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/ReviewsAnonymousEnum.java
  15. 39 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/RatingsReviewsService.java
  16. 43 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/UserFollowsService.java
  17. 62 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/RatingsReviewsServiceImpl.java
  18. 71 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/UserFollowsServiceImpl.java
  19. 2 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/SettingEnum.java
  20. 9 0
      qnfhq-api/src/main/resources/i18n/messages.properties
  21. 8 0
      qnfhq-api/src/main/resources/i18n/messages_de.properties
  22. 9 1
      qnfhq-api/src/main/resources/i18n/messages_en.properties
  23. 8 0
      qnfhq-api/src/main/resources/i18n/messages_es.properties
  24. 8 0
      qnfhq-api/src/main/resources/i18n/messages_fr.properties
  25. 8 0
      qnfhq-api/src/main/resources/i18n/messages_ja.properties
  26. 8 0
      qnfhq-api/src/main/resources/i18n/messages_ko.properties
  27. 8 0
      qnfhq-api/src/main/resources/i18n/messages_th.properties
  28. 8 0
      qnfhq-api/src/main/resources/i18n/messages_tw.properties
  29. 8 0
      qnfhq-api/src/main/resources/i18n/messages_vi.properties
  30. 10 1
      qnfhq-api/src/main/resources/i18n/messages_zh.properties
  31. 7 3
      qnfhq-api/src/main/resources/i18n/validation.properties
  32. 7 3
      qnfhq-api/src/main/resources/i18n/validation_de.properties
  33. 5 2
      qnfhq-api/src/main/resources/i18n/validation_en.properties
  34. 7 3
      qnfhq-api/src/main/resources/i18n/validation_es.properties
  35. 7 3
      qnfhq-api/src/main/resources/i18n/validation_fr.properties
  36. 6 2
      qnfhq-api/src/main/resources/i18n/validation_ja.properties
  37. 6 2
      qnfhq-api/src/main/resources/i18n/validation_ko.properties
  38. 5 1
      qnfhq-api/src/main/resources/i18n/validation_th.properties
  39. 8 4
      qnfhq-api/src/main/resources/i18n/validation_tw.properties
  40. 6 2
      qnfhq-api/src/main/resources/i18n/validation_vi.properties
  41. 6 1
      qnfhq-api/src/main/resources/i18n/validation_zh.properties
  42. 2 0
      qnfhq-api/src/main/resources/mapper/c2c/C2cUserStatDao.xml
  43. 24 0
      qnfhq-api/src/main/resources/mapper/c2c/RatingsReviewsDao.xml
  44. 14 0
      qnfhq-api/src/main/resources/mapper/c2c/UserFollowsDao.xml

+ 155 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/RatingsReviewsController.java

@@ -0,0 +1,155 @@
+package com.qnfhq.modules.c2c.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.json.JSONUtil;
+import com.qnfhq.annotation.RepeatSubmit;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.common.validator.ValidatorUtils;
+import com.qnfhq.modules.c2c.dto.RatingsReviewsDTO;
+import com.qnfhq.modules.c2c.dto.RatingsReviewsListDTO;
+import com.qnfhq.modules.c2c.dto.setting.ReviewSetting;
+import com.qnfhq.modules.c2c.entity.C2cOrderEntity;
+import com.qnfhq.modules.c2c.entity.RatingsReviewsEntity;
+import com.qnfhq.modules.c2c.enums.C2cOrderStatusEnum;
+import com.qnfhq.modules.c2c.enums.ReviewsAnonymousEnum;
+import com.qnfhq.modules.c2c.service.C2cOrderService;
+import com.qnfhq.modules.c2c.service.RatingsReviewsService;
+import com.qnfhq.modules.user.entity.SettingEntity;
+import com.qnfhq.modules.user.enums.SettingEnum;
+import com.qnfhq.modules.user.service.SettingService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * c2c交易对象评价
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@RestController
+@RequestMapping("/reviews")
+@Tag(name="c2c交易对象评价")
+@Slf4j
+public class RatingsReviewsController {
+    @Resource
+    private RatingsReviewsService ratingsReviewsService;
+
+    @Resource
+    private SettingService settingService;
+
+    @Resource
+    private C2cOrderService c2cOrderService;
+
+
+    @PostMapping("/list")
+    @Operation(summary = "收到的评价")
+    public Result<PageData<RatingsReviewsEntity>> list(@RequestBody RatingsReviewsListDTO dto){
+        ValidatorUtils.validateEntity(dto);
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put(Constant.PAGE, dto.getPageNum());
+        params.put(Constant.LIMIT, dto.getPageSize());
+        params.put(Constant.ORDER_FIELD, "id");
+        params.put(Constant.ORDER, "desc");
+        params.put("userId", StpUtil.getLoginIdAsLong());
+        params.put("rating", dto.getRating());
+        PageData<RatingsReviewsEntity> page = ratingsReviewsService.selectPageByUserId(params);
+        return new Result<PageData<RatingsReviewsEntity>>().ok(page);
+    }
+
+
+    /**
+     *  对c2c订单交易评价,交易双方都能评价一次
+     * @param dto
+     * @return
+     */
+    @PostMapping("/create")
+    @Operation(summary = "发表评价")
+    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
+    public Result create(@RequestBody RatingsReviewsDTO dto){
+        //效验数据
+        ValidatorUtils.validateEntity(dto);
+
+        Long orderId = dto.getOrderId();
+        C2cOrderEntity order = c2cOrderService.selectById(orderId);
+        if (order == null) {
+            return new Result().error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
+        }
+
+        //确认是交易方
+        if (StpUtil.getLoginIdAsLong()!=order.getUserId().longValue()
+                && StpUtil.getLoginIdAsLong()!=order.getTranUserId().longValue()) {
+            return new Result().error(MessageUtils.message("c2c.order.reviews.not.tran.user"));//订单的交易方才能发表评论
+        }
+
+        if(order.getStatus() != C2cOrderStatusEnum.COMPLETE.getCode()) {
+            return new Result().error(MessageUtils.message("c2c.order.reviews.not.complete"));//订单状态"已完成"才能发表评论
+        }
+
+        Long inputUserId = StpUtil.getLoginIdAsLong();//提交人编号
+        String inputNickname = null;//提交人昵称
+        Long ratingUserId = null;//被评价人编号
+        String ratingNickname = null;//被评价人昵称
+        if(order.getUserId().longValue() == inputUserId.longValue()) {
+            ratingUserId = order.getTranUserId();
+            ratingNickname = order.getTranUserName();
+            inputNickname = order.getUserName();
+        } else {
+            ratingUserId = order.getUserId();
+            ratingNickname = order.getUserName();
+            inputNickname = order.getTranUserName();
+        }
+
+        RatingsReviewsEntity reviews = ratingsReviewsService.selectByOrderIdInputUserId(orderId, StpUtil.getLoginIdAsLong());
+        if(reviews!=null) {
+            return new Result().error(MessageUtils.message("c2c.order.you.reviewed"));//该订单您已发表评价
+        }
+
+        reviews = new RatingsReviewsEntity();
+        reviews.setOrderId(orderId);
+        reviews.setUserId(ratingUserId);
+        reviews.setNickname(ratingNickname);
+        reviews.setRating(dto.getRating());
+        reviews.setLables(dto.getLables());
+        reviews.setContent(dto.getContent());
+        reviews.setIsAnonymous(dto.getIsAnonymous());
+        if(dto.getIsAnonymous().equals(ReviewsAnonymousEnum.YES.getCode())) {
+            reviews.setInputNickname("匿名");
+        } else {
+            reviews.setInputNickname(inputNickname);
+        }
+        reviews.setStatus(0);//待审核
+        reviews.setInputUserId(inputUserId);
+        reviews.setCreateTime(new Date());
+        reviews.setUpdateTime(new Date());
+        try {
+            return ratingsReviewsService.create(reviews);
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return new Result().error(MessageUtils.message("c2c.order.reviews.create.fail"));//发表评价
+        }
+    }
+
+    @PostMapping("/lables")
+    @Operation(summary = "评价标签")
+    public Result lables(){
+        SettingEntity setting = settingService.getSetting(SettingEnum.REVIEW_SETTING.name());
+        List<ReviewSetting> settingsList = JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), ReviewSetting.class);
+        if (CollectionUtils.isEmpty(settingsList)) {
+            return new Result().error(MessageUtils.message("c2c.reviews.lables.notset"));//"未配置评价标签"
+        }
+        return new Result().ok(settingsList);
+    }
+
+}

+ 116 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/UserFollowsController.java

@@ -0,0 +1,116 @@
+package com.qnfhq.modules.c2c.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.qnfhq.annotation.RepeatSubmit;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.common.validator.ValidatorUtils;
+import com.qnfhq.modules.c2c.dto.UserFollowsDTO;
+import com.qnfhq.modules.c2c.dto.UserFollowsListDTO;
+import com.qnfhq.modules.c2c.entity.C2cMerchantEntity;
+import com.qnfhq.modules.c2c.entity.UserFollowsEntity;
+import com.qnfhq.modules.c2c.service.C2cMerchantService;
+import com.qnfhq.modules.c2c.service.UserFollowsService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * c2c用户和商家关注关系
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@RestController
+@RequestMapping("/follows")
+@Tag(name="c2c用户和商家关注关系")
+public class UserFollowsController {
+    @Resource
+    private UserFollowsService userFollowsService;
+    @Resource
+    private C2cMerchantService c2cMerchantService;
+
+
+    @PostMapping("/followList")
+    @Operation(summary = "已关注列表")
+    public Result<PageData<UserFollowsEntity>> followList(@RequestBody UserFollowsListDTO dto){
+        ValidatorUtils.validateEntity(dto);
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put(Constant.PAGE, dto.getPageNum());
+        params.put(Constant.LIMIT, dto.getPageSize());
+        params.put(Constant.ORDER_FIELD, "id");
+        params.put(Constant.ORDER, "desc");
+        params.put("followerId", StpUtil.getLoginIdAsLong());
+        PageData<UserFollowsEntity> page = userFollowsService.selectPageByFollowerId(params);
+        page.getList().forEach(item -> item.setFollowingInfo(c2cMerchantService.getById(item.getFollowingId())));
+
+        return new Result<PageData<UserFollowsEntity>>().ok(page);
+    }
+
+    @PostMapping("/followMeList")
+    @Operation(summary = "关注我列表")
+    public Result<PageData<UserFollowsEntity>> followMeList(@RequestBody UserFollowsListDTO dto){
+        ValidatorUtils.validateEntity(dto);
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put(Constant.PAGE, dto.getPageNum());
+        params.put(Constant.LIMIT, dto.getPageSize());
+        params.put(Constant.ORDER_FIELD, "id");
+        params.put(Constant.ORDER, "desc");
+        params.put("followingId", StpUtil.getLoginIdAsLong());
+        PageData<UserFollowsEntity> page = userFollowsService.selectPageByFollowingId(params);
+        page.getList().forEach(item -> item.setFollowerInfo(c2cMerchantService.getById(item.getFollowerId())));
+
+        return new Result<PageData<UserFollowsEntity>>().ok(page);
+    }
+
+    @PostMapping("/follow")
+    @Operation(summary = "关注")
+    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
+    public Result follow(@RequestBody UserFollowsDTO dto){
+        //效验数据
+        ValidatorUtils.validateEntity(dto);
+
+        Long followingId = dto.getFollowingId();
+        C2cMerchantEntity merchant = c2cMerchantService.getById(followingId);
+        if (merchant==null) {
+            return new Result().error(MessageUtils.message("c2c.follow.merchant.notexists"));//"商家不存在"
+        }
+        if(merchant.getUserId().longValue() == StpUtil.getLoginIdAsLong()) {
+            return new Result().error(MessageUtils.message("c2c.follow.self"));//"不能关注自己"
+        }
+
+        UserFollowsEntity userFollowsExist = userFollowsService.selectByFollowerIdFollowingId(StpUtil.getLoginIdAsLong(),dto.getFollowingId());
+        if(userFollowsExist!=null) {
+            return new Result();
+        } else {
+            UserFollowsEntity userFollows = new UserFollowsEntity();
+            userFollows.setFollowerId(StpUtil.getLoginIdAsLong());
+            userFollows.setFollowingId(dto.getFollowingId());
+            userFollows.setCreateTime(new Date());
+            userFollowsService.insert(userFollows);
+            return new Result();
+        }
+    }
+
+    @PostMapping("/unfollow")
+    @Operation(summary = "取消关注")
+    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
+    public Result unfollow(@RequestBody UserFollowsDTO dto){
+        //效验数据
+        ValidatorUtils.validateEntity(dto);
+
+        userFollowsService.deleteByFollowerIdFollowingId(StpUtil.getLoginIdAsLong(),dto.getFollowingId());
+
+        return new Result();
+    }
+
+
+
+}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/RatingsReviewsDao.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.c2c.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.c2c.entity.RatingsReviewsEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * c2c交易对象评价
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Mapper
+public interface RatingsReviewsDao extends BaseDao<RatingsReviewsEntity> {
+	
+}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/UserFollowsDao.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.c2c.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.c2c.entity.UserFollowsEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * c2c用户和商家关注关系
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Mapper
+public interface UserFollowsDao extends BaseDao<UserFollowsEntity> {
+	
+}

+ 44 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/RatingsReviewsDTO.java

@@ -0,0 +1,44 @@
+package com.qnfhq.modules.c2c.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * c2c交易对象评价
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Data
+@Schema(name = "c2c交易对象评价")
+public class RatingsReviewsDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "订单编号")
+    @NotNull(message="{NotNull.orderId}")//广告编号不能为空
+	private Long orderId;
+
+	@SchemaProperty(name = "评分:1好评 2差评")
+    @NotNull(message="{NotNull.rating}")//评分不能为空
+	private Integer rating;
+
+	@SchemaProperty(name = "标签:多个,分割")
+    @NotBlank(message="{NotBlank.lables}")//标签不能为空
+	private String lables;
+
+	@SchemaProperty(name = "评价内容")
+    @NotBlank(message="{NotBlank.content}")//评价内容不能为空
+	private String content;
+
+	@SchemaProperty(name = "是否匿名(0: 否, 1: 是)")
+    @NotNull(message="{NotNull.isAnonymous}")//是否匿名不能为空
+	private Integer isAnonymous;
+
+}

+ 32 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/RatingsReviewsListDTO.java

@@ -0,0 +1,32 @@
+package com.qnfhq.modules.c2c.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+ * c2c交易对象评价
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Data
+@Schema(name = "c2c交易对象评价")
+public class RatingsReviewsListDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @SchemaProperty(name = "评分:1好评 2差评")
+    private Integer rating;
+
+    @SchemaProperty(name = "页码")
+    private String pageNum;
+
+    @SchemaProperty(name = "每页条数")
+    private String pageSize;
+
+}

+ 38 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/UserFollowsDTO.java

@@ -0,0 +1,38 @@
+package com.qnfhq.modules.c2c.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * c2c用户和商家关注关系
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Data
+@Schema(name = "c2c用户和商家关注关系")
+public class UserFollowsDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "")
+	private Long id;
+
+	@SchemaProperty(name = "关注者ID (粉丝)")
+	private Long followerId;
+
+	@SchemaProperty(name = "被关注者 ID (博主)")
+    @NotNull(message="{NotNull.followingId}")//被关注者ID不能空
+	private Long followingId;
+
+	@SchemaProperty(name = "")
+	private Date createTime;
+
+
+}

+ 29 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/UserFollowsListDTO.java

@@ -0,0 +1,29 @@
+package com.qnfhq.modules.c2c.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * c2c用户和商家关注关系
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Data
+@Schema(name = "c2c用户和商家关注关系")
+public class UserFollowsListDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @SchemaProperty(name = "页码")
+    private String pageNum;
+
+    @SchemaProperty(name = "每页条数")
+    private String pageSize;
+
+}

+ 14 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/ReviewSetting.java

@@ -0,0 +1,14 @@
+package com.qnfhq.modules.c2c.dto.setting;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 广告配置
+ */
+@Data
+public class ReviewSetting {
+    private Integer lableId;//标签编号
+    private String lableName;//标签名称
+}

+ 1 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cUserReceiptEntity.java

@@ -27,7 +27,7 @@ public class C2cUserReceiptEntity implements Serializable {
      */
 	private Long userId;
     /**
-     * 支付方式t_pay_way.id
+     * 支付方式编号 c2c_pay_way.id
      */
 	private Integer type;
     /**

+ 12 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cUserStatEntity.java

@@ -85,5 +85,16 @@ public class C2cUserStatEntity implements Serializable {
     /**
      * 粉丝数
      */
-	private Integer fanNum;
+    private Integer fanNum;
+    /**
+     * 好评数
+     */
+    private Integer goodNum;
+    /**
+     * 差评数
+     */
+    private Integer badNum;
+
+
+
 }

+ 74 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/RatingsReviewsEntity.java

@@ -0,0 +1,74 @@
+package com.qnfhq.modules.c2c.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * c2c交易对象评价
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Data
+@TableName("c2c_ratings_reviews")
+public class RatingsReviewsEntity {
+
+    /**
+     * 
+     */
+	private Long id;
+    /**
+     * 订单编号
+     */
+	private Long orderId;
+    /**
+     * 商家或用户编号
+     */
+	private Long userId;
+    /**
+     * 昵称
+     */
+	private String nickname;
+    /**
+     * 评分:1好评 2差评
+     */
+	private Integer rating;
+    /**
+     * 标签:多个,分割
+     */
+	private String lables;
+    /**
+     * 评价内容
+     */
+	private String content;
+    /**
+     * 是否匿名(0: 否, 1: 是)
+     */
+	private Integer isAnonymous;
+    /**
+     * 审核状态(0: 待审核, 1: 审核通过, 2: 审核不通过)
+     */
+	private Integer status;
+    /**
+     * 点赞数量
+     */
+	private Integer likeCount;
+    /**
+     * 提交人编号
+     */
+	private Long inputUserId;
+    /**
+     * 提交人昵称
+     */
+	private String inputNickname;
+    /**
+     * 
+     */
+	private Date createTime;
+    /**
+     * 
+     */
+	private Date updateTime;
+}

+ 49 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/UserFollowsEntity.java

@@ -0,0 +1,49 @@
+package com.qnfhq.modules.c2c.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * c2c用户和商家关注关系
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Data
+@TableName("c2c_user_follows")
+public class UserFollowsEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.AUTO)
+	private Long id;
+    /**
+     * 关注者ID (粉丝)
+     */
+	private Long followerId;
+    /**
+     * 被关注者 ID (博主)
+     */
+	private Long followingId;
+    /**
+     * 
+     */
+	private Date createTime;
+
+    /**
+     * 已关注的商家信息
+     */
+    @TableField(exist = false)
+    private C2cMerchantEntity followingInfo;
+
+    /**
+     * 关注我的商家信息
+     */
+    @TableField(exist = false)
+    private C2cMerchantEntity followerInfo;
+}

+ 29 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/ReviewsAnonymousEnum.java

@@ -0,0 +1,29 @@
+package com.qnfhq.modules.c2c.enums;
+
+/**
+ * C2C评价是否匿名
+ */
+public enum ReviewsAnonymousEnum {
+
+    NO(0,"否"),
+    YES(1,"是");
+
+    private Integer code;
+
+    private String desc;
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    ReviewsAnonymousEnum(Integer code, String desc){
+        this.code = code;
+        this.desc = desc;
+    }
+}

+ 39 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/RatingsReviewsService.java

@@ -0,0 +1,39 @@
+package com.qnfhq.modules.c2c.service;
+
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.BaseService;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.modules.c2c.entity.RatingsReviewsEntity;
+import java.util.Map;
+
+/**
+ * c2c交易对象评价
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+public interface RatingsReviewsService extends BaseService<RatingsReviewsEntity> {
+
+    /**
+     * 根据订单编号和评价人编号查询评价
+     * @param orderId
+     * @param inputUserId
+     * @return
+     */
+    RatingsReviewsEntity selectByOrderIdInputUserId(Long orderId, Long inputUserId);
+
+    /**
+     * 创建评价
+     * @param entity
+     * @return
+     */
+    Result create(RatingsReviewsEntity entity) throws Exception;
+
+
+    /**
+     * 收到的评价
+     * @param params
+     * @return
+     */
+    PageData<RatingsReviewsEntity> selectPageByUserId(Map<String, Object> params);
+}

+ 43 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/UserFollowsService.java

@@ -0,0 +1,43 @@
+package com.qnfhq.modules.c2c.service;
+
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.BaseService;
+import com.qnfhq.modules.c2c.entity.UserFollowsEntity;
+
+import java.util.Map;
+
+/**
+ * c2c用户和商家关注关系
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+public interface UserFollowsService extends BaseService<UserFollowsEntity> {
+
+    /**
+     * 查询关注关系
+     * @param followerId
+     * @param followingId
+     * @return
+     */
+    UserFollowsEntity selectByFollowerIdFollowingId(Long followerId,Long followingId);
+    /**
+     * 取消关注
+     * @param followingId
+     */
+    void deleteByFollowerIdFollowingId(Long followerId,Long followingId);
+
+    /**
+     * 查询已关注列表
+     * @param params
+     * @return
+     */
+    PageData<UserFollowsEntity> selectPageByFollowerId(Map<String, Object> params);
+
+    /**
+     * 查询关注我列表
+     * @param params
+     * @return
+     */
+    PageData<UserFollowsEntity> selectPageByFollowingId(Map<String, Object> params);
+}

+ 62 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/RatingsReviewsServiceImpl.java

@@ -0,0 +1,62 @@
+package com.qnfhq.modules.c2c.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.impl.BaseServiceImpl;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.modules.c2c.dao.RatingsReviewsDao;
+import com.qnfhq.modules.c2c.entity.RatingsReviewsEntity;
+import com.qnfhq.modules.c2c.service.RatingsReviewsService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * c2c交易对象评价
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Service
+public class RatingsReviewsServiceImpl extends BaseServiceImpl<RatingsReviewsDao, RatingsReviewsEntity> implements RatingsReviewsService {
+
+    @Override
+    public RatingsReviewsEntity selectByOrderIdInputUserId(Long orderId, Long inputUserId) {
+        return baseDao.selectOne(new LambdaQueryWrapper<RatingsReviewsEntity>()
+                .eq(RatingsReviewsEntity::getOrderId, orderId)
+                .eq(RatingsReviewsEntity::getInputUserId, inputUserId));
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public Result create(RatingsReviewsEntity entity) throws Exception {
+        if(baseDao.insert(entity)<0) {
+            throw new Exception(MessageUtils.message("c2c.reviews.save.fail"));//评价保存失败
+        }
+        return new Result();
+    }
+
+
+    @Override
+    public PageData<RatingsReviewsEntity> selectPageByUserId(Map<String, Object> params) {
+        Long userId = (Long)params.get("userId");
+        Integer rating = null;
+        if(Objects.nonNull(params.get("rating"))) {
+            rating = (Integer) params.get("rating");
+        }
+
+        LambdaQueryWrapper<RatingsReviewsEntity> wrapper = new LambdaQueryWrapper<RatingsReviewsEntity>()
+                .eq(Objects.nonNull(userId),RatingsReviewsEntity::getUserId, userId)
+                .eq(Objects.nonNull(rating),RatingsReviewsEntity::getRating, rating);
+
+        IPage<RatingsReviewsEntity> page = baseDao.selectPage(
+                getPage(params, (String)params.get(Constant.ORDER_FIELD), "asc".equals(params.get(Constant.ORDER)) ? true : false),
+                wrapper
+        );
+        return getPageData(page, RatingsReviewsEntity.class);
+    }
+}

+ 71 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/UserFollowsServiceImpl.java

@@ -0,0 +1,71 @@
+package com.qnfhq.modules.c2c.service.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.impl.BaseServiceImpl;
+import com.qnfhq.modules.c2c.dao.UserFollowsDao;
+import com.qnfhq.modules.c2c.entity.UserFollowsEntity;
+import com.qnfhq.modules.c2c.service.UserFollowsService;
+import cn.hutool.core.util.StrUtil;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * c2c用户和商家关注关系
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-29
+ */
+@Service
+public class UserFollowsServiceImpl extends BaseServiceImpl<UserFollowsDao, UserFollowsEntity> implements UserFollowsService {
+
+    @Override
+    public UserFollowsEntity selectByFollowerIdFollowingId(Long followerId,Long followingId) {
+        return baseDao.selectOne(new LambdaQueryWrapper<UserFollowsEntity>()
+                .eq(UserFollowsEntity::getFollowerId, followerId)
+                .eq(UserFollowsEntity::getFollowingId, followingId));
+    }
+
+    @Override
+    public void deleteByFollowerIdFollowingId(Long followerId,Long followingId) {
+        baseDao.delete(new LambdaQueryWrapper<UserFollowsEntity>()
+                .eq(UserFollowsEntity::getFollowerId, StpUtil.getLoginIdAsLong())
+                .eq(UserFollowsEntity::getFollowingId, followingId));
+    }
+
+    @Override
+    public PageData<UserFollowsEntity> selectPageByFollowerId(Map<String, Object> params) {
+        Long followerId = (Long)params.get("followerId");
+
+        LambdaQueryWrapper<UserFollowsEntity> wrapper = new LambdaQueryWrapper<UserFollowsEntity>()
+                .eq(Objects.nonNull(followerId),UserFollowsEntity::getFollowerId, followerId);
+
+        IPage<UserFollowsEntity> page = baseDao.selectPage(
+                getPage(params, (String)params.get(Constant.ORDER_FIELD), "asc".equals(params.get(Constant.ORDER)) ? true : false),
+                wrapper
+        );
+        return getPageData(page, UserFollowsEntity.class);
+    }
+
+    @Override
+    public PageData<UserFollowsEntity> selectPageByFollowingId(Map<String, Object> params) {
+        Long followingId = (Long)params.get("followingId");
+
+        LambdaQueryWrapper<UserFollowsEntity> wrapper = new LambdaQueryWrapper<UserFollowsEntity>()
+                .eq(Objects.nonNull(followingId),UserFollowsEntity::getFollowingId, followingId);
+
+        IPage<UserFollowsEntity> page = baseDao.selectPage(
+                getPage(params, (String)params.get(Constant.ORDER_FIELD), "asc".equals(params.get(Constant.ORDER)) ? true : false),
+                wrapper
+        );
+        return getPageData(page, UserFollowsEntity.class);
+    }
+
+
+}

+ 2 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/SettingEnum.java

@@ -101,5 +101,7 @@ public enum SettingEnum {
     AD_SETTING,
     //验证码配置
     CAPTCHA_SETTING,
+    //评论标签设置
+    REVIEW_SETTING
     ;
 }

+ 9 - 0
qnfhq-api/src/main/resources/i18n/messages.properties

@@ -137,3 +137,12 @@ c2c.msg.msgType.err=Jenis mesej salah
 c2c.msg.receptId.err=Tidak boleh menghantar mesej kepada diri sendiri  
 user.verifyIntelligentCaptcha.err=Ralat pada antara muka pengesahan captcha pintar  
 609=Pengesahan captcha pintar gagal
+c2c.follow.self=Tidak boleh mengikuti diri sendiri
+c2c.follow.merchant.notexists=Penjual tidak wujud
+c2c.reviews.lables.notset=Label ulasan belum dikonfigurasi
+c2c.order.reviews.not.tran.user=Hanya pihak transaksi dalam pesanan boleh memberikan ulasan
+c2c.order.reviews.not.complete=Status pesanan "Selesai" diperlukan untuk memberikan ulasan
+c2c.order.reviews.create.fail=Gagal membuat ulasan
+c2c.reviews.save.fail=Gagal menyimpan ulasan
+c2c.order.you.reviewed=Anda telah memberikan ulasan untuk pesanan ini
+

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_de.properties

@@ -137,3 +137,11 @@ c2c.msg.msgType.err=Fehler beim Nachrichtentyp
 c2c.msg.receptId.err=Sie k\u00f6nnen sich selbst keine Nachricht senden  
 user.verifyIntelligentCaptcha.err=Fehler bei der \u00dcberpr\u00fcfung des Captcha-Interfaces  
 609=Intelligente Captcha-\u00dcberpr\u00fcfung fehlgeschlagen
+c2c.follow.self=Sie k\u00f6nnen sich nicht selbst folgen  
+c2c.follow.merchant.notexists=H\u00e4ndler existiert nicht  
+c2c.reviews.lables.notset=Bewertungslabels nicht konfiguriert  
+c2c.order.reviews.not.tran.user=Nur die Transaktionspartei der Bestellung kann eine Bewertung abgeben  
+c2c.order.reviews.not.complete=Nur bei Bestellstatus "Abgeschlossen" kann eine Bewertung abgegeben werden  
+c2c.order.reviews.create.fail=Bewertung abgeben fehlgeschlagen  
+c2c.reviews.save.fail=Bewertung konnte nicht gespeichert werden  
+c2c.order.you.reviewed=Sie haben diese Bestellung bereits bewertet

+ 9 - 1
qnfhq-api/src/main/resources/i18n/messages_en.properties

@@ -136,4 +136,12 @@ c2c.msg.receptId.notexists=Recipient does not exist
 c2c.msg.msgType.err=Message type error
 c2c.msg.receptId.err=Cannot send message to yourself
 user.verifyIntelligentCaptcha.err=Verification code validation interface error
-609 = Intelligent CAPTCHA verification failed
+609 = Intelligent CAPTCHA verification failed
+c2c.follow.self=Cannot follow yourself
+c2c.follow.merchant.notexists=Merchant does not exist
+c2c.reviews.lables.notset=Review labels not configured
+c2c.order.reviews.not.tran.user=Only transaction parties of the order can post reviews
+c2c.order.reviews.not.complete=Order status must be "Completed" to post reviews
+c2c.order.reviews.create.fail=Failed to post review
+c2c.reviews.save.fail=Failed to save review
+c2c.order.you.reviewed=You have already reviewed this order

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_es.properties

@@ -137,3 +137,11 @@ c2c.msg.msgType.err=Error en el tipo de mensaje
 c2c.msg.receptId.err=No puedes enviarte mensajes a ti mismo  
 user.verifyIntelligentCaptcha.err=Error en la interfaz de verificaci\u00f3n del captcha  
 609=Fallo en la verificaci\u00f3n del captcha inteligente
+c2c.follow.self=No puedes seguirte a ti mismo
+c2c.follow.merchant.notexists=El comerciante no existe
+c2c.reviews.lables.notset=Etiquetas de evaluaci\u00f3n no configuradas
+c2c.order.reviews.not.tran.user=Solo las partes de la transacci\u00f3n del pedido pueden publicar comentarios
+c2c.order.reviews.not.complete=El estado del pedido debe ser "Completado" para publicar comentarios
+c2c.order.reviews.create.fail=Error al publicar la evaluaci\u00f3n
+c2c.reviews.save.fail=Error al guardar la evaluaci\u00f3n
+c2c.order.you.reviewed=Ya has publicado una evaluaci\u00f3n para este pedido

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_fr.properties

@@ -137,3 +137,11 @@ c2c.msg.msgType.err=Type de message incorrect
 c2c.msg.receptId.err=Vous ne pouvez pas vous envoyer un message \u00e0 vous-m\u00eame
 user.verifyIntelligentCaptcha.err=Erreur lors de la v\u00e9rification du captcha
 609=\u00c9chec de la v\u00e9rification du captcha intelligent
+c2c.follow.self=Vous ne pouvez pas vous suivre vous-m\u00eame
+c2c.follow.merchant.notexists=Le commer\u00e7ant n'existe pas
+c2c.reviews.lables.notset=\u00c9tiquettes d'\u00e9valuation non configur\u00e9es
+c2c.order.reviews.not.tran.user=Seules les parties \u00e0 la transaction peuvent laisser un commentaire
+c2c.order.reviews.not.complete=Le statut de la commande doit \u00eatre "Termin\u00e9" pour laisser un commentaire
+c2c.order.reviews.create.fail=\u00c9chec de la publication de l'\u00e9valuation
+c2c.reviews.save.fail=\u00c9chec de l'enregistrement de l'\u00e9valuation
+c2c.order.you.reviewed=Vous avez d\u00e9j\u00e0 laiss\u00e9 un commentaire pour cette commande

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_ja.properties

@@ -137,4 +137,12 @@ c2c.msg.msgType.err=\u30e1\u30c3\u30bb\u30fc\u30b8\u30bf\u30a4\u30d7\u304c\u9593
 c2c.msg.receptId.err=\u81ea\u5206\u81ea\u8eab\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
 user.verifyIntelligentCaptcha.err=\u8a8d\u8a3c\u30b3\u30fc\u30c9\u691c\u8a3c\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
 609=\u30a4\u30f3\u30c6\u30ea\u30b8\u30a7\u30f3\u30c8\u8a8d\u8a3c\u30b3\u30fc\u30c9\u306e\u691c\u8a3c\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+c2c.follow.self=\u81ea\u5206\u81ea\u8eab\u3092\u30d5\u30a9\u30ed\u30fc\u3067\u304d\u307e\u305b\u3093
+c2c.follow.merchant.notexists=\u5546\u5bb6\u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+c2c.reviews.lables.notset=\u8a55\u4fa1\u30e9\u30d9\u30eb\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+c2c.order.reviews.not.tran.user=\u6ce8\u6587\u306e\u53d6\u5f15\u76f8\u624b\u306e\u307f\u8a55\u4fa1\u3092\u6295\u7a3f\u3067\u304d\u307e\u3059
+c2c.order.reviews.not.complete=\u6ce8\u6587\u306e\u72b6\u614b\u304c\u300c\u5b8c\u4e86\u300d\u306b\u306a\u3063\u3066\u3044\u308b\u5834\u5408\u306e\u307f\u8a55\u4fa1\u3092\u6295\u7a3f\u3067\u304d\u307e\u3059
+c2c.order.reviews.create.fail=\u8a55\u4fa1\u306e\u6295\u7a3f\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+c2c.reviews.save.fail=\u8a55\u4fa1\u306e\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+c2c.order.you.reviewed=\u3053\u306e\u6ce8\u6587\u306b\u306f\u3059\u3067\u306b\u8a55\u4fa1\u3092\u6295\u7a3f\u3057\u3066\u3044\u307e\u3059
 

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_ko.properties

@@ -137,3 +137,11 @@ c2c.msg.msgType.err=\uba54\uc2dc\uc9c0 \uc720\ud615 \uc624\ub958
 c2c.msg.receptId.err=\uc790\uae30 \uc790\uc2e0\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0bc \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 user.verifyIntelligentCaptcha.err=\uc778\uc99d \ucf54\ub4dc \uac80\uc99d \uc778\ud130\ud398\uc774\uc2a4 \uc624\ub958
 609=\uc9c0\ub2a5\ud615 \uc778\uc99d \ucf54\ub4dc \uac80\uc99d \uc2e4\ud328
+c2c.follow.self=\uc790\uae30 \uc790\uc2e0\uc744 \ud314\ub85c\uc6b0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+c2c.follow.merchant.notexists=\uc0c1\uc778\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
+c2c.reviews.lables.notset=\ud3c9\uac00 \ud0dc\uadf8\uac00 \uc124\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4
+c2c.order.reviews.not.tran.user=\uc8fc\ubb38 \uac70\ub798 \ub2f9\uc0ac\uc790\ub9cc \ud3c9\uac00\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4
+c2c.order.reviews.not.complete=\uc8fc\ubb38 \uc0c1\ud0dc\uac00 "\uc644\ub8cc"\uc77c \ub54c\ub9cc \ud3c9\uac00\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4
+c2c.order.reviews.create.fail=\ud3c9\uac00 \uc791\uc131 \uc2e4\ud328
+c2c.reviews.save.fail=\ud3c9\uac00 \uc800\uc7a5 \uc2e4\ud328
+c2c.order.you.reviewed=\ud574\ub2f9 \uc8fc\ubb38\uc5d0 \uc774\ubbf8 \ud3c9\uac00\ub97c \uc791\uc131\ud558\uc168\uc2b5\ub2c8\ub2e4

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_th.properties

@@ -137,3 +137,11 @@ c2c.msg.msgType.err=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e02\u0e49\u0e2d\u0e04
 c2c.msg.receptId.err=\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e16\u0e36\u0e07\u0e15\u0e31\u0e27\u0e40\u0e2d\u0e07\u0e44\u0e14\u0e49
 user.verifyIntelligentCaptcha.err=\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\u0e43\u0e19\u0e01\u0e32\u0e23\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e23\u0e2b\u0e31\u0e2a\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19
 609=\u0e01\u0e32\u0e23\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e23\u0e2b\u0e31\u0e2a\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e2d\u0e31\u0e08\u0e09\u0e23\u0e34\u0e22\u0e30\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
+c2c.follow.self=\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e15\u0e34\u0e14\u0e15\u0e32\u0e21\u0e15\u0e31\u0e27\u0e40\u0e2d\u0e07\u0e44\u0e14\u0e49
+c2c.follow.merchant.notexists=\u0e23\u0e49\u0e32\u0e19\u0e04\u0e49\u0e32\u0e44\u0e21\u0e48\u0e1e\u0e1a
+c2c.reviews.lables.notset=\u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e1b\u0e49\u0e32\u0e22\u0e23\u0e35\u0e27\u0e34\u0e27
+c2c.order.reviews.not.tran.user=\u0e40\u0e09\u0e1e\u0e32\u0e30\u0e1d\u0e48\u0e32\u0e22\u0e17\u0e35\u0e48\u0e17\u0e33\u0e18\u0e38\u0e23\u0e01\u0e23\u0e23\u0e21\u0e43\u0e19\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e40\u0e17\u0e48\u0e32\u0e19\u0e31\u0e49\u0e19\u0e17\u0e35\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e41\u0e2a\u0e14\u0e07\u0e04\u0e27\u0e32\u0e21\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e47\u0e19\u0e44\u0e14\u0e49
+c2c.order.reviews.not.complete=\u0e2a\u0e16\u0e32\u0e19\u0e30\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d "\u0e40\u0e2a\u0e23\u0e47\u0e08\u0e2a\u0e21\u0e1a\u0e39\u0e23\u0e13\u0e4c" \u0e40\u0e17\u0e48\u0e32\u0e19\u0e31\u0e49\u0e19\u0e17\u0e35\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e41\u0e2a\u0e14\u0e07\u0e04\u0e27\u0e32\u0e21\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e47\u0e19\u0e44\u0e14\u0e49
+c2c.order.reviews.create.fail=\u0e01\u0e32\u0e23\u0e42\u0e1e\u0e2a\u0e15\u0e4c\u0e23\u0e35\u0e27\u0e34\u0e27\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
+c2c.reviews.save.fail=\u0e01\u0e32\u0e23\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e23\u0e35\u0e27\u0e34\u0e27\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
+c2c.order.you.reviewed=\u0e04\u0e38\u0e13\u0e44\u0e14\u0e49\u0e41\u0e2a\u0e14\u0e07\u0e04\u0e27\u0e32\u0e21\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e47\u0e19\u0e43\u0e19\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e19\u0e35\u0e49\u0e41\u0e25\u0e49\u0e27

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_tw.properties

@@ -137,3 +137,11 @@ c2c.msg.msgType.err=\u6d88\u606f\u985e\u578b\u932f\u8aa4
 c2c.msg.receptId.err=\u4e0d\u80fd\u7d66\u81ea\u5df1\u767c\u6d88\u606f
 user.verifyIntelligentCaptcha.err=\u9a57\u8b49\u78bc\u6821\u9a57\u63a5\u53e3\u5831\u932f
 609=\u667a\u80fd\u9a57\u8b49\u78bc\u6821\u9a57\u5931\u6557
+c2c.follow.self=\u4e0d\u80fd\u95dc\u6ce8\u81ea\u5df1
+c2c.follow.merchant.notexists=\u5546\u5bb6\u4e0d\u5b58\u5728
+c2c.reviews.lables.notset=\u672a\u914d\u7f6e\u8a55\u50f9\u6a19\u7c64
+c2c.order.reviews.not.tran.user=\u8a02\u55ae\u7684\u4ea4\u6613\u65b9\u624d\u80fd\u767c\u8868\u8a55\u8ad6
+c2c.order.reviews.not.complete=\u8a02\u55ae\u72c0\u614b"\u5df2\u5b8c\u6210"\u624d\u80fd\u767c\u8868\u8a55\u8ad6
+c2c.order.reviews.create.fail=\u767c\u8868\u8a55\u50f9\u5931\u6557
+c2c.reviews.save.fail=\u8a55\u50f9\u4fdd\u5b58\u5931\u6557
+c2c.order.you.reviewed=\u8a72\u8a02\u55ae\u60a8\u5df2\u767c\u8868\u8a55\u50f9

+ 8 - 0
qnfhq-api/src/main/resources/i18n/messages_vi.properties

@@ -136,3 +136,11 @@ c2c.msg.msgType.err=Lo\u1ea1i tin nh\u1eafn sai
 c2c.msg.receptId.err=Kh\u00f4ng th\u1ec3 g\u1eedi tin nh\u1eafn cho ch\u00ednh m\u00ecnh  
 user.verifyIntelligentCaptcha.err=L\u1ed7i giao di\u1ec7n ki\u1ec3m tra m\u00e3 x\u00e1c nh\u1eadn  
 609=Ki\u1ec3m tra m\u00e3 x\u00e1c nh\u1eadn th\u00f4ng minh th\u1ea5t b\u1ea1i
+c2c.follow.self=Kh\u00f4ng th\u1ec3 theo d\u00f5i ch\u00ednh m\u00ecnh
+c2c.follow.merchant.notexists=Ng\u01b0\u1eddi b\u00e1n kh\u00f4ng t\u1ed3n t\u1ea1i
+c2c.reviews.lables.notset=Ch\u01b0a c\u1ea5u h\u00ecnh nh\u00e3n \u0111\u00e1nh gi\u00e1
+c2c.order.reviews.not.tran.user=Ch\u1ec9 c\u00e1c b\u00ean giao d\u1ecbch trong \u0111\u01a1n h\u00e0ng m\u1edbi c\u00f3 th\u1ec3 b\u00ecnh lu\u1eadn
+c2c.order.reviews.not.complete=Tr\u1ea1ng th\u00e1i \u0111\u01a1n h\u00e0ng ph\u1ea3i l\u00e0 "\u0110\u00e3 ho\u00e0n th\u00e0nh" m\u1edbi c\u00f3 th\u1ec3 b\u00ecnh lu\u1eadn
+c2c.order.reviews.create.fail=\u0110\u0103ng \u0111\u00e1nh gi\u00e1 th\u1ea5t b\u1ea1i
+c2c.reviews.save.fail=L\u01b0u \u0111\u00e1nh gi\u00e1 th\u1ea5t b\u1ea1i
+c2c.order.you.reviewed=B\u1ea1n \u0111\u00e3 \u0111\u00e1nh gi\u00e1 \u0111\u01a1n h\u00e0ng n\u00e0y r\u1ed3i

+ 10 - 1
qnfhq-api/src/main/resources/i18n/messages_zh.properties

@@ -138,4 +138,13 @@ c2c.msg.receptId.notexists=\u63a5\u6536\u4eba\u4e0d\u5b58\u5728
 c2c.msg.msgType.err=\u6d88\u606f\u7c7b\u578b\u9519\u8bef
 c2c.msg.receptId.err=\u4e0d\u80fd\u7ed9\u81ea\u5df1\u53d1\u6d88\u606f
 user.verifyIntelligentCaptcha.err=\u9a8c\u8bc1\u7801\u6821\u9a8c\u63a5\u53e3\u62a5\u9519
-609=\u667a\u80fd\u9a8c\u8bc1\u7801\u6821\u9a8c\u5931\u8d25
+609=\u667a\u80fd\u9a8c\u8bc1\u7801\u6821\u9a8c\u5931\u8d25
+
+c2c.follow.self=\u4e0d\u80fd\u5173\u6ce8\u81ea\u5df1
+c2c.follow.merchant.notexists=\u5546\u5bb6\u4e0d\u5b58\u5728
+c2c.reviews.lables.notset=\u672a\u914d\u7f6e\u8bc4\u4ef7\u6807\u7b7e
+c2c.order.reviews.not.tran.user=\u8ba2\u5355\u7684\u4ea4\u6613\u65b9\u624d\u80fd\u53d1\u8868\u8bc4\u8bba
+c2c.order.reviews.not.complete=\u8ba2\u5355\u72b6\u6001"\u5df2\u5b8c\u6210"\u624d\u80fd\u53d1\u8868\u8bc4\u8bba
+c2c.order.reviews.create.fail=\u53d1\u8868\u8bc4\u4ef7
+c2c.reviews.save.fail=\u8bc4\u4ef7\u4fdd\u5b58\u5931\u8d25
+c2c.order.you.reviewed=\u8be5\u8ba2\u5355\u60a8\u5df2\u53d1\u8868\u8bc4\u4ef7

+ 7 - 3
qnfhq-api/src/main/resources/i18n/validation.properties

@@ -39,10 +39,14 @@ NotBlank.country=Negara tidak boleh kosong
 NotNull.tag=Label tidak boleh kosong  
 NotNull.unit=Unit transaksi tidak boleh kosong  
 NotBlank.senderId=Pengirim tidak boleh kosong  
-NotBlank.recipientId=Penerima tidak boleh kosong  
-NotBlank.content=Kandungan mesej tidak boleh kosong  
+NotBlank.recipientId=Penerima tidak boleh kosong   
 NotBlank.msgType=Jenis mesej tidak boleh kosong  
 NotNull.ownerUid=ID pengguna tidak boleh kosong
 NotNull.otherUid=Nombor pihak lain tidak boleh kosong
 Length.content=Kandungan mesej tidak boleh melebihi 1000 aksara
-NotBlank.verifyParam=Parameter kod pengesahan tidak boleh kosong
+NotBlank.verifyParam=Parameter kod pengesahan tidak boleh kosong
+NotNull.followingId=ID yang diikuti tidak boleh kosong
+NotNull.rating=Penilaian tidak boleh kosong
+NotBlank.lables=Label tidak boleh kosong
+NotNull.isAnonymous=Adakah anonim tidak boleh kosong
+NotBlank.content=Kandungan tidak boleh kosong

+ 7 - 3
qnfhq-api/src/main/resources/i18n/validation_de.properties

@@ -39,10 +39,14 @@ NotBlank.country=Land darf nicht leer sein
 NotNull.tag=Das Etikett darf nicht leer sein  
 NotNull.unit=Die Handelseinheit darf nicht leer sein  
 NotBlank.senderId=Absender darf nicht leer sein  
-NotBlank.recipientId=Empf\u00e4nger darf nicht leer sein  
-NotBlank.content=Nachrichteninhalt darf nicht leer sein  
+NotBlank.recipientId=Empf\u00e4nger darf nicht leer sein
 NotBlank.msgType=Nachrichtentyp darf nicht leer sein  
 NotNull.ownerUid=Benutzernummer darf nicht leer sein
 NotNull.otherUid=Die Gegenpartei-ID darf nicht leer sein  
 Length.content=Die Nachrichtenl\u00e4nge darf 1000 Zeichen nicht \u00fcberschreiten  
-NotBlank.verifyParam=Der Verifizierungscode darf nicht leer sein
+NotBlank.verifyParam=Der Verifizierungscode darf nicht leer sein
+NotNull.followingId=Die ID des Gefolgten darf nicht leer sein  
+NotNull.rating=Die Bewertung darf nicht leer sein  
+NotBlank.lables=Die Labels d\u00fcrfen nicht leer sein  
+NotNull.isAnonymous=Die Angabe, ob anonym, darf nicht leer sein  
+NotBlank.content=Der Inhalt darf nicht leer sein

+ 5 - 2
qnfhq-api/src/main/resources/i18n/validation_en.properties

@@ -36,14 +36,17 @@ NotBlank.remark=Voucher description cannot be empty
 NotBlank.img1=Voucher screenshot 1 cannot be empty
 NotNull.complainId=Appeal ID cannot be empty
 NotBlank.country=Country cannot be empty
-
 NotNull.tag=Tag cannot be empty
 NotNull.unit=Transaction unit cannot be empty
 NotBlank.senderId=Sender cannot be empty
 NotBlank.recipientId=Recipient cannot be empty
-NotBlank.content=Message content cannot be empty
 NotBlank.msgType=Message type cannot be empty
 NotNull.ownerUid=User ID cannot be empty
 NotNull.otherUid=Counterparty ID cannot be empty
 Length.content=The length of the message content cannot exceed 1000
 NotBlank.verifyParam=Verification code parameter cannot be empty
+NotNull.followingId=Followed user ID cannot be empty  
+NotNull.rating=Rating cannot be empty  
+NotBlank.lables=Labels cannot be empty  
+NotNull.isAnonymous=Anonymous status cannot be empty  
+NotBlank.content=Content cannot be empty

+ 7 - 3
qnfhq-api/src/main/resources/i18n/validation_es.properties

@@ -39,10 +39,14 @@ NotBlank.country=El pa\u00eds no puede estar vac\u00edo
 NotNull.tag=La etiqueta no puede estar vac\u00eda  
 NotNull.unit=La unidad de transacci\u00f3n no puede estar vac\u00eda  
 NotBlank.senderId=El remitente no puede estar vac\u00edo  
-NotBlank.recipientId=El destinatario no puede estar vac\u00edo  
-NotBlank.content=El contenido del mensaje no puede estar vac\u00edo  
+NotBlank.recipientId=El destinatario no puede estar vac\u00edo
 NotBlank.msgType=El tipo de mensaje no puede estar vac\u00edo  
 NotNull.ownerUid=El n\u00famero de usuario no puede estar vac\u00edo
 NotNull.otherUid=El n\u00famero de la otra parte no puede estar vac\u00edo
 Length.content=La longitud del contenido del mensaje no puede exceder de 1000
-NotBlank.verifyParam=El par\u00e1metro del c\u00f3digo de verificaci\u00f3n no puede estar vac\u00edo
+NotBlank.verifyParam=El par\u00e1metro del c\u00f3digo de verificaci\u00f3n no puede estar vac\u00edo
+NotNull.followingId=El ID del seguido no puede estar vac\u00edo  
+NotNull.rating=La calificaci\u00f3n no puede estar vac\u00eda  
+NotBlank.lables=Las etiquetas no pueden estar vac\u00edas  
+NotNull.isAnonymous=No puede estar vac\u00edo si es an\u00f3nimo  
+NotBlank.content=El contenido no puede estar vac\u00edo

+ 7 - 3
qnfhq-api/src/main/resources/i18n/validation_fr.properties

@@ -39,10 +39,14 @@ NotBlank.country=Le pays ne peut pas \u00eatre vide
 NotNull.tag=Le tag ne peut pas \u00eatre vide  
 NotNull.unit=L'unit\u00e9 de transaction ne peut pas \u00eatre vide  
 NotBlank.senderId=L'exp\u00e9diteur ne peut pas \u00eatre vide  
-NotBlank.recipientId=Le destinataire ne peut pas \u00eatre vide  
-NotBlank.content=Le contenu du message ne peut pas \u00eatre vide  
+NotBlank.recipientId=Le destinataire ne peut pas \u00eatre vide
 NotBlank.msgType=Le type de message ne peut pas \u00eatre vide  
 NotNull.ownerUid=Le num\u00e9ro d'utilisateur ne peut pas \u00eatre vide
 NotNull.otherUid=Le num\u00e9ro de l'autre partie ne peut pas \u00eatre nul  
 Length.content=La longueur du contenu du message ne peut pas d\u00e9passer 1000  
-NotBlank.verifyParam=Le param\u00e8tre du code de v\u00e9rification ne peut pas \u00eatre vide
+NotBlank.verifyParam=Le param\u00e8tre du code de v\u00e9rification ne peut pas \u00eatre vide
+NotNull.followingId=L'ID de la personne suivie ne peut pas \u00eatre vide  
+NotNull.rating=La note ne peut pas \u00eatre vide  
+NotBlank.lables=Les \u00e9tiquettes ne peuvent pas \u00eatre vides  
+NotNull.isAnonymous=Le statut anonyme ne peut pas \u00eatre vide  
+NotBlank.content=Le contenu ne peut pas \u00eatre vide

+ 6 - 2
qnfhq-api/src/main/resources/i18n/validation_ja.properties

@@ -40,9 +40,13 @@ NotNull.tag=\u30bf\u30b0\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.unit=\u53d6\u5f15\u5358\u4f4d\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.senderId=\u9001\u4fe1\u8005\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.recipientId=\u53d7\u4fe1\u8005\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
-NotBlank.content=\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.msgType=\u30e1\u30c3\u30bb\u30fc\u30b8\u30bf\u30a4\u30d7\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.ownerUid=\u30e6\u30fc\u30b6\u30fc\u756a\u53f7\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.otherUid=\u76f8\u624b\u306e\u756a\u53f7\u3092\u7a7a\u306b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
 Length.content=\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u306e\u9577\u3055\u306f1000\u3092\u8d85\u3048\u3066\u306f\u3044\u3051\u307e\u305b\u3093
-NotBlank.verifyParam=\u691c\u8a3c\u30b3\u30fc\u30c9\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u7a7a\u306b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
+NotBlank.verifyParam=\u691c\u8a3c\u30b3\u30fc\u30c9\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u7a7a\u306b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
+NotNull.followingId=\u88ab\u30d5\u30a9\u30ed\u30fc\u8005ID\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.rating=\u8a55\u4fa1\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.lables=\u30e9\u30d9\u30eb\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.isAnonymous=\u533f\u540d\u304b\u3069\u3046\u304b\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.content=\u5185\u5bb9\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093

+ 6 - 2
qnfhq-api/src/main/resources/i18n/validation_ko.properties

@@ -40,9 +40,13 @@ NotNull.tag=\ud0dc\uadf8\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e
 NotNull.unit=\uac70\ub798 \ub2e8\uc704\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotBlank.senderId=\ubcf4\ub0b4\ub294 \uc0ac\ub78c\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotBlank.recipientId=\ubc1b\ub294 \uc0ac\ub78c\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
-NotBlank.content=\uba54\uc2dc\uc9c0 \ub0b4\uc6a9\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotBlank.msgType=\uba54\uc2dc\uc9c0 \uc720\ud615\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotNull.ownerUid=\uc0ac\uc6a9\uc790 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotNull.otherUid=\uc0c1\ub300\ubc29 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 Length.content=\uba54\uc2dc\uc9c0 \ub0b4\uc6a9 \uae38\uc774\ub294 1000\uc790\ub97c \ucd08\uacfc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
-NotBlank.verifyParam=\uc778\uc99d \ucf54\ub4dc \ub9e4\uac1c\ubcc0\uc218\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.verifyParam=\uc778\uc99d \ucf54\ub4dc \ub9e4\uac1c\ubcc0\uc218\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.followingId=\u88ab\u5173\u6ce8\u8005ID\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.rating=\ud3c9\uc810\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.lables=\ub77c\ubca8\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.isAnonymous=\uc775\uba85 \uc5ec\ubd80\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.content=\ub0b4\uc6a9\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4

+ 5 - 1
qnfhq-api/src/main/resources/i18n/validation_th.properties

@@ -40,9 +40,13 @@ NotNull.tag=\u0e41\u0e17\u0e47\u0e01\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u
 NotNull.unit=\u0e2b\u0e19\u0e48\u0e27\u0e22\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e02\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotBlank.senderId=\u0e1c\u0e39\u0e49\u0e2a\u0e48\u0e07\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotBlank.recipientId=\u0e1c\u0e39\u0e49\u0e23\u0e31\u0e1a\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
-NotBlank.content=\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotBlank.msgType=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.ownerUid=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.otherUid=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e1d\u0e48\u0e32\u0e22\u0e15\u0e23\u0e07\u0e02\u0e49\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07\u0e40\u0e1b\u0e25\u0e48\u0e32
 Length.content=\u0e04\u0e27\u0e32\u0e21\u0e22\u0e32\u0e27\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e40\u0e01\u0e34\u0e19 1000
 NotBlank.verifyParam=\u0e1e\u0e32\u0e23\u0e32\u0e21\u0e34\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e23\u0e2b\u0e31\u0e2a\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07\u0e40\u0e1b\u0e25\u0e48\u0e32
+NotNull.followingId=ID \u0e02\u0e2d\u0e07\u0e1c\u0e39\u0e49\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e15\u0e34\u0e14\u0e15\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotNull.rating=\u0e04\u0e30\u0e41\u0e19\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotBlank.lables=\u0e1b\u0e49\u0e32\u0e22\u0e01\u0e33\u0e01\u0e31\u0e1a\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotNull.isAnonymous=\u0e15\u0e49\u0e2d\u0e07\u0e23\u0e30\u0e1a\u0e38\u0e27\u0e48\u0e32\u0e0b\u0e48\u0e2d\u0e19\u0e0a\u0e37\u0e48\u0e2d\u0e2b\u0e23\u0e37\u0e2d\u0e44\u0e21\u0e48
+NotBlank.content=\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07

+ 8 - 4
qnfhq-api/src/main/resources/i18n/validation_tw.properties

@@ -40,9 +40,13 @@ NotNull.tag=\u6a19\u7c64\u4e0d\u80fd\u70ba\u7a7a
 NotNull.unit=\u4ea4\u6613\u55ae\u4f4d\u4e0d\u80fd\u70ba\u7a7a
 NotBlank.senderId=\u767c\u9001\u4eba\u4e0d\u80fd\u7a7a
 NotBlank.recipientId=\u63a5\u6536\u4eba\u4e0d\u80fd\u7a7a
-NotBlank.content=\u6d88\u606f\u5167\u5bb9\u4e0d\u80fd\u7a7a
 NotBlank.msgType=\u6d88\u606f\u985e\u578b\u4e0d\u80fd\u7a7a
 NotNull.ownerUid=\u7528\u6236\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
-NotNull.otherUid=????????
-Length.content=??????????1000
-NotBlank.verifyParam=?????????
+NotNull.otherUid=\u5c0d\u65b9\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
+Length.content=\u6d88\u606f\u5167\u5bb9\u9577\u5ea6\u4e0d\u80fd\u8d85\u904e1000
+NotBlank.verifyParam=\u9a57\u8b49\u78bc\u53c3\u6578\u4e0d\u80fd\u70ba\u7a7a
+NotNull.followingId=\u88ab\u95dc\u6ce8\u8005ID\u4e0d\u80fd\u7a7a
+NotNull.rating=\u8a55\u5206\u4e0d\u80fd\u7a7a
+NotBlank.lables=\u6a19\u7c64\u4e0d\u80fd\u7a7a
+NotNull.isAnonymous=\u662f\u5426\u533f\u540d\u4e0d\u80fd\u7a7a
+NotBlank.content=\u5167\u5bb9\u4e0d\u80fd\u7a7a

+ 6 - 2
qnfhq-api/src/main/resources/i18n/validation_vi.properties

@@ -40,9 +40,13 @@ NotNull.tag=Th\u1ebb kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.unit=\u0110\u01a1n v\u1ecb giao d\u1ecbch kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.senderId=Ng\u01b0\u1eddi g\u1eedi kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.recipientId=Ng\u01b0\u1eddi nh\u1eadn kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
-NotBlank.content=N\u1ed9i dung tin nh\u1eafn kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.msgType=Lo\u1ea1i tin nh\u1eafn kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.ownerUid=M\u00e3 ng\u01b0\u1eddi d\u00f9ng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.otherUid=M\u00e3 s\u1ed1 \u0111\u1ed1i ph\u01b0\u01a1ng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 Length.content=\u0110\u1ed9 d\u00e0i n\u1ed9i dung tin nh\u1eafn kh\u00f4ng \u0111\u01b0\u1ee3c v\u01b0\u1ee3t qu\u00e1 1000
-NotBlank.verifyParam=Tham s\u1ed1 m\u00e3 x\u00e1c minh kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.verifyParam=Tham s\u1ed1 m\u00e3 x\u00e1c minh kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.followingId=ID ng\u01b0\u1eddi \u0111\u01b0\u1ee3c theo d\u00f5i kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.rating=\u0110\u00e1nh gi\u00e1 kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.lables=Nh\u00e3n kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.isAnonymous=Kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng vi\u1ec7c c\u00f3 \u1ea9n danh hay kh\u00f4ng
+NotBlank.content=N\u1ed9i dung kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng

+ 6 - 1
qnfhq-api/src/main/resources/i18n/validation_zh.properties

@@ -41,9 +41,14 @@ NotNull.tag=\u6807\u7b7e\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.unit=\u4ea4\u6613\u5355\u4f4d\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.senderId=\u53d1\u9001\u4eba\u4e0d\u80fd\u7a7a
 NotBlank.recipientId=\u63a5\u6536\u4eba\u4e0d\u80fd\u7a7a
-NotBlank.content=\u6d88\u606f\u5185\u5bb9\u4e0d\u80fd\u7a7a
 NotBlank.msgType=\u6d88\u606f\u7c7b\u578b\u4e0d\u80fd\u7a7a
 NotNull.ownerUid=\u7528\u6237\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.otherUid=\u5bf9\u65b9\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
 Length.content=\u6d88\u606f\u5185\u5bb9\u957f\u5ea6\u4e0d\u80fd\u8d85\u8fc71000
 NotBlank.verifyParam=\u9a8c\u8bc1\u7801\u53c2\u6570\u4e0d\u80fd\u4e3a\u7a7a
+
+NotNull.followingId=\u88ab\u5173\u6ce8\u8005ID\u4e0d\u80fd\u7a7a
+NotNull.rating=\u8bc4\u5206\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.lables=\u6807\u7b7e\u4e0d\u80fd\u4e3a\u7a7a
+NotNull.isAnonymous=\u662f\u5426\u533f\u540d\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.content=\u5185\u5bb9\u4e0d\u80fd\u7a7a

+ 2 - 0
qnfhq-api/src/main/resources/mapper/c2c/C2cUserStatDao.xml

@@ -21,6 +21,8 @@
         <result property="day30SellRate" column="day30_sell_rate"/>
         <result property="day30TranUserNum" column="day30_tran_user_num"/>
         <result property="fanNum" column="fan_num"/>
+        <result property="goodNum" column="good_num"/>
+        <result property="badNum" column="bad_num"/>
     </resultMap>
 
 

+ 24 - 0
qnfhq-api/src/main/resources/mapper/c2c/RatingsReviewsDao.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.qnfhq.modules.c2c.dao.RatingsReviewsDao">
+
+    <resultMap type="com.qnfhq.modules.c2c.entity.RatingsReviewsEntity" id="ratingsReviewsMap">
+        <result property="id" column="id"/>
+        <result property="orderId" column="order_id"/>
+        <result property="userId" column="user_id"/>
+        <result property="nickname" column="nickname"/>
+        <result property="rating" column="rating"/>
+        <result property="lables" column="lables"/>
+        <result property="content" column="content"/>
+        <result property="isAnonymous" column="is_anonymous"/>
+        <result property="status" column="status"/>
+        <result property="likeCount" column="like_count"/>
+        <result property="inputUserId" column="input_user_id"/>
+        <result property="inputNickname" column="input_nickname"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+    </resultMap>
+
+
+</mapper>

+ 14 - 0
qnfhq-api/src/main/resources/mapper/c2c/UserFollowsDao.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.qnfhq.modules.c2c.dao.UserFollowsDao">
+
+    <resultMap type="com.qnfhq.modules.c2c.entity.UserFollowsEntity" id="userFollowsMap">
+        <result property="id" column="id"/>
+        <result property="followerId" column="follower_id"/>
+        <result property="followingId" column="following_id"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+
+
+</mapper>