Procházet zdrojové kódy

feat: 推广佣金体系后端实体 + 删除废弃 RelationshipPicker 组件

- Commission/CommissionMapper/PromotionCommissionService/PromotionCommissionController: 推广佣金属系列新增
- 删除 RelationshipPicker.vue: 已被 GenerationPicker.vue 替代
Xiaogang Liao před 3 měsíci
rodič
revize
0361063141

+ 56 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/PromotionCommissionController.java

@@ -0,0 +1,56 @@
+package com.etotem.cfc.controller;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.Commission;
+import com.etotem.cfc.service.PromotionCommissionService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@RestController
+@RequestMapping("/api/promotion/commission")
+public class PromotionCommissionController {
+
+    @Resource
+    private PromotionCommissionService promotionCommissionService;
+
+    /**
+     * 记录佣金
+     * @param commission 佣金对象
+     * @return 是否成功
+     */
+    @PostMapping("/record")
+    public Result<Boolean> recordCommission(@RequestBody Commission commission) {
+        boolean success = promotionCommissionService.recordCommission(commission);
+        return Result.success(success);
+    }
+
+    /**
+     * 获取家庭总佣金
+     * @param request 包含familyId的请求对象
+     * @return 总佣金金额
+     */
+    @PostMapping("/family-total")
+    public Result<Integer> getFamilyTotal(@RequestBody FamilyIdRequest request) {
+        Integer total = promotionCommissionService.getFamilyTotal(request.getFamilyId());
+        return Result.success(total);
+    }
+
+    /**
+     * 简单请求对象,仅包含familyId
+     */
+    public static class FamilyIdRequest {
+        private Long familyId;
+
+        public Long getFamilyId() {
+            return familyId;
+        }
+
+        public void setFamilyId(Long familyId) {
+            this.familyId = familyId;
+        }
+    }
+}

+ 37 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/Commission.java

@@ -0,0 +1,37 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("promotion_commission")
+public class Commission implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    private Long familyId; // 家庭ID
+    
+    private Long guideId; // 成长规划师ID
+    
+    private Long memberId; // 家庭成员ID(推广人)
+    
+    private Integer amount; // 金额(分)
+    
+    private String type; // 佣金类型:register, purchase, invite
+    
+    private String source; // 来源:family_promotion, guide_referral
+    
+    private String status; // 状态:pending, paid, cancelled
+    
+    private String remark; // 备注
+    
+    private Date createdAt;
+    
+    private Date updatedAt;
+}

+ 9 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/CommissionMapper.java

@@ -0,0 +1,9 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.Commission;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CommissionMapper extends BaseMapper<Commission> {
+}

+ 45 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/PromotionCommissionService.java

@@ -0,0 +1,45 @@
+package com.etotem.cfc.service;
+
+import com.etotem.cfc.entity.Commission;
+import com.etotem.cfc.mapper.CommissionMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class PromotionCommissionService {
+
+    @Resource
+    private CommissionMapper commissionMapper;
+
+    /**
+     * 记录佣金
+     * @param commission 佣金对象
+     * @return 是否成功
+     */
+    public boolean recordCommission(Commission commission) {
+        if (commission.getCreatedAt() == null) {
+            commission.setCreatedAt(new Date());
+        }
+        commission.setUpdatedAt(new Date());
+        return commissionMapper.insert(commission) > 0;
+    }
+
+    /**
+     * 获取家庭总佣金(分)
+     * @param familyId 家庭ID
+     * @return 总佣金金额
+     */
+    public Integer getFamilyTotal(Long familyId) {
+        Map<String, Object> columnMap = new HashMap<>();
+        columnMap.put("family_id", familyId);
+        
+        return commissionMapper.selectByMap(columnMap)
+                .stream()
+                .mapToInt(Commission::getAmount)
+                .sum();
+    }
+}

+ 0 - 116
cfc-frontend/components/RelationshipPicker.vue

@@ -1,116 +0,0 @@
-<template>
-  <view class="relationship-picker-wrap">
-    <view class="form-item required" v-if="showLabel">
-      <text class="label"><text class="required-mark">*</text>关系类型</text>
-    </view>
-    <picker :range="typeNames" @change="onChange" :disabled="disabled || loadError">
-      <view class="picker" :class="{ 'picker-disabled': disabled || loadError, 'picker-error': loadError }">
-        <text v-if="loading" class="status-text">加载中...</text>
-        <text v-else-if="loadError" class="status-text error-text" @tap.stop="loadTypes">加载失败,点击重试</text>
-        <text v-else>{{ selectedName || '请选择关系类型' }}</text>
-      </view>
-    </picker>
-  </view>
-</template>
-
-<script>
-import { getRelationshipTypes } from '../utils/api.js'
-
-export default {
-  name: 'RelationshipPicker',
-  props: {
-    value: { type: String, default: '' },
-    disabled: { type: Boolean, default: false },
-    showLabel: { type: Boolean, default: true }
-  },
-  data() {
-    return {
-      relationshipTypes: [],
-      loading: false,
-      loadError: false
-    }
-  },
-  computed: {
-    typeNames() {
-      var names = []
-      for (var i = 0; i < this.relationshipTypes.length; i++) {
-        names.push(this.relationshipTypes[i].typeName)
-      }
-      return names
-    },
-    selectedName() {
-      if (!this.value) return ''
-      for (var i = 0; i < this.relationshipTypes.length; i++) {
-        if (this.relationshipTypes[i].typeKey === this.value) {
-          return this.relationshipTypes[i].typeName
-        }
-      }
-      return ''
-    }
-  },
-  mounted() {
-    this.loadTypes()
-  },
-  methods: {
-    async loadTypes() {
-      this.loading = true
-      this.loadError = false
-      try {
-        var res = await getRelationshipTypes()
-        if (res.code === 200 && res.data) {
-          this.relationshipTypes = res.data
-        }
-      } catch (e) {
-        console.error('加载关系类型失败', e)
-        this.loadError = true
-      } finally {
-        this.loading = false
-      }
-    },
-    onChange(e) {
-      var idx = e.detail.value
-      if (idx >= 0 && idx < this.relationshipTypes.length) {
-        this.$emit('input', this.relationshipTypes[idx].typeKey)
-      }
-    }
-  }
-}
-</script>
-
-<style scoped>
-.picker {
-  border: 1rpx solid #ddd;
-  border-radius: 10rpx;
-  padding: 20rpx;
-  font-size: 28rpx;
-  color: #666;
-}
-.picker-disabled {
-  background: #f5f5f5;
-  color: #999;
-}
-.form-item {
-  margin-bottom: 10rpx;
-}
-.form-item .label {
-  display: block;
-  font-size: 28rpx;
-  color: #333;
-  margin-bottom: 10rpx;
-  font-weight: bold;
-}
-.required-mark {
-  color: #F97316;
-  margin-right: 4rpx;
-}
-.status-text {
-  font-size: 28rpx;
-  color: #999;
-}
-.error-text {
-  color: #F97316;
-}
-.picker-error {
-  border-color: #F97316;
-}
-</style>