fix: 修改任务系统奖励修复

This commit is contained in:
zerosaturation 2026-04-15 14:11:07 +08:00
parent 7bf73d3988
commit 4e13c86aa4
32 changed files with 4614 additions and 525 deletions

View File

@ -21,7 +21,7 @@ cleanup() {
fi
# 清理所有 PID 文件并杀服务进程
for service in gateway activityService galleryService socialService assetService userService; do
for service in gateway activityService galleryService socialService assetService userService taskService; do
pkill -9 -f "$service" 2>/dev/null || true
rm -f "/tmp/dev_sh_${service}.pid" "/tmp/dev_sh_${service}_restart" "/tmp/dev_sh_${service}.lock"
echo -e "${YELLOW} 🛑 $service 已停止${NC}"
@ -155,9 +155,25 @@ restart_service() {
fi
cd "$SCRIPT_DIR/$dir"
if ! go build -o "$SCRIPT_DIR/$binary" . 2>&1; then
echo -e "${RED}❌ [$name] 编译失败,旧进程保持运行${NC}"
# 重试编译最多3次
local max_retries=3
local retry_count=0
local build_success=false
while [ $retry_count -lt $max_retries ]; do
if go build -o "$SCRIPT_DIR/$binary" . 2>&1; then
build_success=true
break
fi
retry_count=$((retry_count + 1))
if [ $retry_count -lt $max_retries ]; then
echo -e "${YELLOW}⚠️ [$name] 编译失败,${retry_count}/${max_retries} 次重试...${NC}"
sleep 1
fi
done
if [ "$build_success" = false ]; then
echo -e "${RED}❌ [$name] 编译失败 (已重试 ${max_retries} 次),旧进程保持运行${NC}"
echo -e "${RED} 查看详细日志: tail -f /tmp/${name}.log${NC}"
rm -f "$lock_file"
return 1
fi
echo -e "${GREEN}✅ [$name] 编译成功${NC}"
@ -225,7 +241,8 @@ start_watcher() {
--exclude='assetService$' \
--exclude='socialService$' \
--exclude='galleryService$' \
--exclude='activityService$'
--exclude='activityService$' \
--exclude='taskService$'
else
inotifywait -r -m -e modify,create,write "$watch_path" \
--exclude='\.git' \
@ -236,7 +253,8 @@ start_watcher() {
--exclude='assetService$' \
--exclude='socialService$' \
--exclude='galleryService$' \
--exclude='activityService$'
--exclude='activityService$' \
--exclude='taskService$'
fi | while read event; do
# 时间戳防抖:每次事件更新标记文件
# Darwin 不支持 date +%s%N使用 python 获取纳秒时间戳
@ -289,13 +307,13 @@ echo ""
> /tmp/dev_sh_watchers.tmp
# 清理残留 PID 文件(上次非正常退出可能留下)
for service in activityService galleryService socialService assetService userService gateway; do
for service in activityService galleryService socialService assetService userService taskService gateway; do
rm -f "/tmp/dev_sh_${service}.pid" "/tmp/dev_sh_${service}_restart"
done
# 停止现有服务(清理环境)
echo -e "${YELLOW}🛑 停止现有服务...${NC}"
for service in gateway userService socialService assetService galleryService activityService; do
for service in gateway userService socialService assetService galleryService activityService taskService; do
pkill -9 -f "$service" 2>/dev/null || true
done
sleep 1
@ -309,6 +327,7 @@ build_service "assetService" "services/assetService" "services/assetService/
build_service "socialService" "services/socialService" "services/socialService/socialService"
build_service "galleryService" "services/galleryService" "services/galleryService/galleryService"
build_service "activityService" "services/activityService" "services/activityService/activityService"
build_service "taskService" "services/taskService" "services/taskService/taskService"
cd "$SCRIPT_DIR"
# 启动所有服务
@ -319,6 +338,7 @@ start_service "assetService" "services/assetService/assetService" 20003
start_service "socialService" "services/socialService/socialService" 20002 1
start_service "galleryService" "services/galleryService/galleryService" 20004 1
start_service "activityService" "services/activityService/activityService" 20005 1
start_service "taskService" "services/taskService/taskService" 20006 1
start_service "gateway" "gateway/gateway" 8080 0
# 启动所有文件监听器
@ -330,6 +350,7 @@ start_watcher "assetService" "services/assetService" "services/assetService/
start_watcher "socialService" "services/socialService" "services/socialService/socialService" 20002 1
start_watcher "galleryService" "services/galleryService" "services/galleryService/galleryService" 20004 1
start_watcher "activityService" "services/activityService" "services/activityService/activityService" 20005 1
start_watcher "taskService" "services/taskService" "services/taskService/taskService" 20006 1
echo ""
echo -e "${GREEN}========================================${NC}"
@ -344,6 +365,7 @@ echo " - Social Service: tri://localhost:20002"
echo " - Asset Service: tri://localhost:20003"
echo " - Gallery Service: tri://localhost:20004"
echo " - Activity Service: tri://localhost:20005"
echo " - Task Service: tri://localhost:20006"
echo ""
echo -e "${YELLOW}按 Ctrl+C 停止所有服务${NC}"
echo ""

View File

@ -27,6 +27,7 @@ type DubboConfig struct {
AssetServiceURL string
GalleryServiceURL string
ActivityServiceURL string
TaskServiceURL string
}
// JWTConfig JWT 配置
@ -71,6 +72,7 @@ func Load() *Config {
AssetServiceURL: getEnv("DUBBO_ASSET_SERVICE_URL", "tri://127.0.0.1:20003"),
GalleryServiceURL: getEnv("DUBBO_GALLERY_SERVICE_URL", "tri://127.0.0.1:20004"),
ActivityServiceURL: getEnv("DUBBO_ACTIVITY_SERVICE_URL", "tri://127.0.0.1:20005"),
TaskServiceURL: getEnv("DUBBO_TASK_SERVICE_URL", "tri://127.0.0.1:20006"),
},
JWT: JWTConfig{
Secret: getEnv("JWT_SECRET", "topfans-secret-key-please-change-in-production"),
@ -130,6 +132,9 @@ func (c *Config) Validate() error {
if c.Dubbo.ActivityServiceURL == "" {
return fmt.Errorf("dubbo activity service URL is required")
}
if c.Dubbo.TaskServiceURL == "" {
return fmt.Errorf("dubbo task service URL is required")
}
if c.JWT.Secret == "" {
return fmt.Errorf("JWT secret is required")
}

View File

@ -0,0 +1,771 @@
package controller
import (
"context"
"net/http"
"strconv"
"time"
"dubbo.apache.org/dubbo-go/v3/client"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"github.com/gin-gonic/gin"
"github.com/topfans/backend/gateway/pkg/response"
pbCommon "github.com/topfans/backend/pkg/proto/common"
pbTask "github.com/topfans/backend/pkg/proto/task"
"github.com/topfans/backend/pkg/logger"
"go.uber.org/zap"
)
// TaskController 任务控制器
type TaskController struct {
taskMobileService pbTask.TaskMobileService
}
// NewTaskController 创建任务控制器
func NewTaskController(dubboClient *client.Client) (*TaskController, error) {
taskMobileService, err := pbTask.NewTaskMobileService(dubboClient)
if err != nil {
return nil, err
}
return &TaskController{
taskMobileService: taskMobileService,
}, nil
}
// GetDailyTasks 获取每日任务列表
// @Summary 获取每日任务列表
// @Description 获取每日任务列表
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param star_id query int64 true "粉丝身份ID"
// @Success 200 {object} response.Response
// @Router /api/tasks/daily [get]
func (ctrl *TaskController) GetDailyTasks(c *gin.Context) {
starIDStr := c.Query("star_id")
if starIDStr == "" {
response.Error(c, http.StatusBadRequest, "star_id 是必填参数")
return
}
starID, err := strconv.ParseInt(starIDStr, 10, 64)
if err != nil {
response.Error(c, http.StatusBadRequest, "star_id 参数错误")
return
}
userID, _ := c.Get("user_id")
logger.Logger.Info("GetDailyTasks request",
zap.Int64("user_id", userID.(int64)),
zap.Int64("star_id", starID),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": strconv.FormatInt(starID, 10),
})
resp, err := ctrl.taskMobileService.GetDailyTasks(ctx, &pbTask.GetDailyTasksRequest{
StarId: starID,
})
if err != nil {
logger.Logger.Error("GetDailyTasks RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "获取每日任务列表失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
data := convertDailyTasksResponse(resp)
response.Success(c, data)
}
// ReportEvent 上报任务事件
// @Summary 上报任务事件
// @Description 上报任务事件,如 daily_login, daily_browse_asset
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body pbTask.ReportEventRequest true "事件上报请求"
// @Success 200 {object} response.Response
// @Router /api/tasks/report-event [post]
func (ctrl *TaskController) ReportEvent(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
EventType string `json:"event_type"`
StarId int64 `json:"star_id"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "请求参数错误")
return
}
if req.EventType == "" {
response.Error(c, http.StatusBadRequest, "event_type 是必填参数")
return
}
logger.Logger.Info("ReportEvent request",
zap.Int64("user_id", userID.(int64)),
zap.String("event_type", req.EventType),
zap.Int64("star_id", req.StarId),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": strconv.FormatInt(req.StarId, 10),
})
resp, err := ctrl.taskMobileService.ReportEvent(ctx, &pbTask.ReportEventRequest{
EventType: req.EventType,
StarId: req.StarId,
})
if err != nil {
logger.Logger.Error("ReportEvent RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "上报事件失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
response.Success(c, map[string]interface{}{
"success": resp.Success,
"task_key": resp.TaskKey,
"task_completed": resp.TaskCompleted,
"message": resp.Message,
})
}
// ClaimDailyTask 领取单个每日任务奖励
// @Summary 领取每日任务奖励
// @Description 领取单个每日任务奖励
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body pbTask.ClaimDailyTaskRequest true "领取请求"
// @Success 200 {object} response.Response
// @Router /api/tasks/daily/claim [post]
func (ctrl *TaskController) ClaimDailyTask(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
TaskKey string `json:"task_key"`
StarId int64 `json:"star_id"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "请求参数错误")
return
}
if req.TaskKey == "" {
response.Error(c, http.StatusBadRequest, "task_key 是必填参数")
return
}
logger.Logger.Info("ClaimDailyTask request",
zap.Int64("user_id", userID.(int64)),
zap.String("task_key", req.TaskKey),
zap.Int64("star_id", req.StarId),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": strconv.FormatInt(req.StarId, 10),
})
resp, err := ctrl.taskMobileService.ClaimDailyTask(ctx, &pbTask.ClaimDailyTaskRequest{
TaskKey: req.TaskKey,
StarId: req.StarId,
})
if err != nil {
logger.Logger.Error("ClaimDailyTask RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "领取任务奖励失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
response.Success(c, map[string]interface{}{
"success": resp.Success,
"crystal_balance": resp.CrystalBalance,
"experience": resp.Experience,
})
}
// ClaimAllDailyTasks 一键领取所有每日任务
// @Summary 一键领取所有每日任务
// @Description 一键领取所有可领取的每日任务奖励
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param star_id query int64 true "粉丝身份ID"
// @Success 200 {object} response.Response
// @Router /api/tasks/daily/claim-all [post]
func (ctrl *TaskController) ClaimAllDailyTasks(c *gin.Context) {
userID, _ := c.Get("user_id")
starIDStr := c.Query("star_id")
if starIDStr == "" {
response.Error(c, http.StatusBadRequest, "star_id 是必填参数")
return
}
starID, err := strconv.ParseInt(starIDStr, 10, 64)
if err != nil {
response.Error(c, http.StatusBadRequest, "star_id 参数错误")
return
}
logger.Logger.Info("ClaimAllDailyTasks request",
zap.Int64("user_id", userID.(int64)),
zap.Int64("star_id", starID),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": strconv.FormatInt(starID, 10),
})
resp, err := ctrl.taskMobileService.ClaimAllDailyTasks(ctx, &pbTask.ClaimAllDailyTasksRequest{
StarId: starID,
})
if err != nil {
logger.Logger.Error("ClaimAllDailyTasks RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "一键领取失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
response.Success(c, map[string]interface{}{
"claimed_count": resp.ClaimedCount,
"crystal_balance": resp.CrystalBalance,
"experience": resp.Experience,
"claimed_task_keys": resp.ClaimedTaskKeys,
})
}
// CompleteGuide 完成引导任务
// @Summary 完成引导任务
// @Description 完成引导任务步骤
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body pbTask.CompleteGuideRequest true "引导完成请求"
// @Success 200 {object} response.Response
// @Router /api/tasks/guide/complete [post]
func (ctrl *TaskController) CompleteGuide(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
TaskKey string `json:"task_key"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "请求参数错误")
return
}
if req.TaskKey == "" {
response.Error(c, http.StatusBadRequest, "task_key 是必填参数")
return
}
logger.Logger.Info("CompleteGuide request",
zap.Int64("user_id", userID.(int64)),
zap.String("task_key", req.TaskKey),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": "0",
})
resp, err := ctrl.taskMobileService.CompleteGuide(ctx, &pbTask.CompleteGuideRequest{
TaskKey: req.TaskKey,
})
if err != nil {
logger.Logger.Error("CompleteGuide RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "完成引导失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
data := convertCompleteGuideResponse(resp)
response.Success(c, data)
}
// GetOnboardingStatus 获取引导状态
// @Summary 获取引导状态
// @Description 获取新手引导状态
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} response.Response
// @Router /api/tasks/onboarding/status [get]
func (ctrl *TaskController) GetOnboardingStatus(c *gin.Context) {
userID, _ := c.Get("user_id")
logger.Logger.Info("GetOnboardingStatus request",
zap.Int64("user_id", userID.(int64)),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": "0",
})
resp, err := ctrl.taskMobileService.GetOnboardingStatus(ctx, &pbTask.GetOnboardingStatusRequest{})
if err != nil {
logger.Logger.Error("GetOnboardingStatus RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "获取引导状态失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
data := convertOnboardingStatusResponse(resp)
response.Success(c, data)
}
// AdvanceStage 进入下一引导阶段
// @Summary 进入下一引导阶段
// @Description 进入新手引导的下一阶段
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body pbTask.AdvanceStageRequest true "阶段推进请求"
// @Success 200 {object} response.Response
// @Router /api/tasks/onboarding/advance-stage [post]
func (ctrl *TaskController) AdvanceStage(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
TargetStage int32 `json:"target_stage"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "请求参数错误")
return
}
logger.Logger.Info("AdvanceStage request",
zap.Int64("user_id", userID.(int64)),
zap.Int32("target_stage", req.TargetStage),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": "0",
})
resp, err := ctrl.taskMobileService.AdvanceStage(ctx, &pbTask.AdvanceStageRequest{
TargetStage: req.TargetStage,
})
if err != nil {
logger.Logger.Error("AdvanceStage RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "进入下一阶段失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
data := convertAdvanceStageResponse(resp)
response.Success(c, data)
}
// ClaimOnboardingReward 领取引导阶段奖励
// @Summary 领取引导阶段奖励
// @Description 领取新手引导阶段奖励
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body pbTask.ClaimOnboardingRewardRequest true "领取奖励请求"
// @Success 200 {object} response.Response
// @Router /api/tasks/onboarding/claim-reward [post]
func (ctrl *TaskController) ClaimOnboardingReward(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
Stage int32 `json:"stage"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "请求参数错误")
return
}
logger.Logger.Info("ClaimOnboardingReward request",
zap.Int64("user_id", userID.(int64)),
zap.Int32("stage", req.Stage),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": "0",
})
resp, err := ctrl.taskMobileService.ClaimOnboardingReward(ctx, &pbTask.ClaimOnboardingRewardRequest{
Stage: req.Stage,
})
if err != nil {
logger.Logger.Error("ClaimOnboardingReward RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "领取引导奖励失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
response.Success(c, map[string]interface{}{
"success": resp.Success,
})
}
// GetExhibitionRevenue 获取展示收益
// @Summary 获取展示收益
// @Description 获取展馆收益记录
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param star_id query int64 true "粉丝身份ID"
// @Param status query string false "状态筛选claimable/claimed"
// @Param page query int false "页码默认1"
// @Param page_size query int false "每页数量默认10"
// @Success 200 {object} response.Response
// @Router /api/tasks/exhibition-revenue [get]
func (ctrl *TaskController) GetExhibitionRevenue(c *gin.Context) {
userID, _ := c.Get("user_id")
starIDStr := c.Query("star_id")
if starIDStr == "" {
response.Error(c, http.StatusBadRequest, "star_id 是必填参数")
return
}
starID, err := strconv.ParseInt(starIDStr, 10, 64)
if err != nil {
response.Error(c, http.StatusBadRequest, "star_id 参数错误")
return
}
status := c.Query("status")
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
logger.Logger.Info("GetExhibitionRevenue request",
zap.Int64("user_id", userID.(int64)),
zap.Int64("star_id", starID),
zap.String("status", status),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": strconv.FormatInt(starID, 10),
})
resp, err := ctrl.taskMobileService.GetExhibitionRevenue(ctx, &pbTask.GetExhibitionRevenueRequest{
StarId: starID,
Status: status,
Page: int32(page),
PageSize: int32(pageSize),
})
if err != nil {
logger.Logger.Error("GetExhibitionRevenue RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "获取展示收益失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
data := convertExhibitionRevenueResponse(resp)
response.Success(c, data)
}
// ClaimExhibitionRevenue 领取单条展示收益
// @Summary 领取单条展示收益
// @Description 领取单条展馆收益记录
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body pbTask.ClaimExhibitionRevenueRequest true "领取请求"
// @Success 200 {object} response.Response
// @Router /api/tasks/exhibition-revenue/claim [post]
func (ctrl *TaskController) ClaimExhibitionRevenue(c *gin.Context) {
userID, _ := c.Get("user_id")
var req struct {
RevenueId int64 `json:"revenue_id"`
StarId int64 `json:"star_id"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, http.StatusBadRequest, "请求参数错误")
return
}
logger.Logger.Info("ClaimExhibitionRevenue request",
zap.Int64("user_id", userID.(int64)),
zap.Int64("revenue_id", req.RevenueId),
zap.Int64("star_id", req.StarId),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": strconv.FormatInt(req.StarId, 10),
})
resp, err := ctrl.taskMobileService.ClaimExhibitionRevenue(ctx, &pbTask.ClaimExhibitionRevenueRequest{
RevenueId: req.RevenueId,
StarId: req.StarId,
})
if err != nil {
logger.Logger.Error("ClaimExhibitionRevenue RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "领取展示收益失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
response.Success(c, map[string]interface{}{
"success": resp.Success,
})
}
// ClaimAllExhibitionRevenue 一键领取所有展示收益
// @Summary 一键领取所有展示收益
// @Description 一键领取所有可领取的展馆收益
// @Tags tasks
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param star_id query int64 true "粉丝身份ID"
// @Success 200 {object} response.Response
// @Router /api/tasks/exhibition-revenue/claim-all [post]
func (ctrl *TaskController) ClaimAllExhibitionRevenue(c *gin.Context) {
userID, _ := c.Get("user_id")
starIDStr := c.Query("star_id")
if starIDStr == "" {
response.Error(c, http.StatusBadRequest, "star_id 是必填参数")
return
}
starID, err := strconv.ParseInt(starIDStr, 10, 64)
if err != nil {
response.Error(c, http.StatusBadRequest, "star_id 参数错误")
return
}
logger.Logger.Info("ClaimAllExhibitionRevenue request",
zap.Int64("user_id", userID.(int64)),
zap.Int64("star_id", starID),
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": strconv.FormatInt(userID.(int64), 10),
"star_id": strconv.FormatInt(starID, 10),
})
resp, err := ctrl.taskMobileService.ClaimAllExhibitionRevenue(ctx, &pbTask.ClaimAllExhibitionRevenueRequest{
StarId: starID,
})
if err != nil {
logger.Logger.Error("ClaimAllExhibitionRevenue RPC failed", zap.Error(err))
response.Error(c, http.StatusInternalServerError, "一键领取展示收益失败")
return
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message)
return
}
response.Success(c, map[string]interface{}{
"claimed_count": resp.ClaimedCount,
})
}
// ==================== 响应转换函数 ====================
func convertDailyTasksResponse(resp *pbTask.GetDailyTasksResponse) map[string]interface{} {
tasks := make([]map[string]interface{}, 0, len(resp.Tasks))
for _, task := range resp.Tasks {
tasks = append(tasks, map[string]interface{}{
"task_key": task.TaskKey,
"star_id": task.StarId,
"name": task.Name,
"description": task.Description,
"crystal_reward": task.CrystalReward,
"exp_reward": task.ExpReward,
"status": task.Status,
"can_claim": task.CanClaim,
})
}
return map[string]interface{}{
"star_id": resp.StarId,
"tasks": tasks,
}
}
func convertOnboardingStatusResponse(resp *pbTask.GetOnboardingStatusResponse) map[string]interface{} {
stages := make([]map[string]interface{}, 0, len(resp.Stages))
for _, stage := range resp.Stages {
stages = append(stages, map[string]interface{}{
"stage": stage.Stage,
"name": stage.Name,
"required_task_keys": stage.RequiredTaskKeys,
"crystal_reward": stage.CrystalReward,
"exp_reward": stage.ExpReward,
"status": stage.Status,
"is_current": stage.IsCurrent,
})
}
return map[string]interface{}{
"user_id": resp.UserId,
"current_stage": resp.CurrentStage,
"status": resp.Status,
"stages": stages,
}
}
func convertAdvanceStageResponse(resp *pbTask.AdvanceStageResponse) map[string]interface{} {
stages := make([]map[string]interface{}, 0, len(resp.Stages))
for _, stage := range resp.Stages {
stages = append(stages, map[string]interface{}{
"stage": stage.Stage,
"name": stage.Name,
"required_task_keys": stage.RequiredTaskKeys,
"crystal_reward": stage.CrystalReward,
"exp_reward": stage.ExpReward,
"status": stage.Status,
"is_current": stage.IsCurrent,
})
}
return map[string]interface{}{
"current_stage": resp.CurrentStage,
"status": resp.Status,
"stages": stages,
}
}
func convertCompleteGuideResponse(resp *pbTask.CompleteGuideResponse) map[string]interface{} {
stages := make([]map[string]interface{}, 0, len(resp.Stages))
for _, stage := range resp.Stages {
stages = append(stages, map[string]interface{}{
"stage": stage.Stage,
"name": stage.Name,
"required_task_keys": stage.RequiredTaskKeys,
"crystal_reward": stage.CrystalReward,
"exp_reward": stage.ExpReward,
"status": stage.Status,
"is_current": stage.IsCurrent,
})
}
return map[string]interface{}{
"user_id": resp.UserId,
"current_stage": resp.CurrentStage,
"status": resp.Status,
"stages": stages,
}
}
func convertExhibitionRevenueResponse(resp *pbTask.GetExhibitionRevenueResponse) map[string]interface{} {
items := make([]map[string]interface{}, 0, len(resp.Items))
for _, item := range resp.Items {
items = append(items, map[string]interface{}{
"id": item.Id,
"star_id": item.StarId,
"exhibition_id": item.ExhibitionId,
"asset_id": item.AssetId,
"slot_id": item.SlotId,
"slot_type": item.SlotType,
"crystal_amount": item.CrystalAmount,
"cycle_start_time": item.CycleStartTime,
"cycle_end_time": item.CycleEndTime,
"status": item.Status,
"can_claim": item.CanClaim,
})
}
return map[string]interface{}{
"items": items,
"total": resp.Total,
"page": resp.Page,
"page_size": resp.PageSize,
}
}

View File

@ -17,6 +17,7 @@ type CurrentIdentityDTO struct {
IdentityName string `json:"identity_name"` // "王一博"
Tag string `json:"tag"` // "小摩托"
Level int32 `json:"level"`
Experience int64 `json:"experience"`
CrystalBalance int64 `json:"crystal_balance"`
}

View File

@ -24,6 +24,7 @@ func ToCurrentIdentityDTO(profile *pb.FanProfile, star *pb.Star) CurrentIdentity
IdentityName: star.Name, // "王一博"
Tag: star.Tag, // "小摩托"
Level: profile.Level,
Experience: profile.Experience,
CrystalBalance: profile.CrystalBalance,
}
}

View File

@ -59,6 +59,7 @@ func main() {
zap.String("asset_service_url", cfg.Dubbo.AssetServiceURL),
zap.String("gallery_service_url", cfg.Dubbo.GalleryServiceURL),
zap.String("activity_service_url", cfg.Dubbo.ActivityServiceURL),
zap.String("task_service_url", cfg.Dubbo.TaskServiceURL),
)
// 3. 设置 Gin 模式
@ -112,9 +113,18 @@ func main() {
}
logger.Logger.Info("Activity Service Dubbo client connected successfully")
// 4.6 TaskService Client
taskClient, err := client.NewClient(
client.WithClientURL(cfg.Dubbo.TaskServiceURL),
)
if err != nil {
logger.Logger.Fatal("Failed to create Task Service Dubbo client", zap.Error(err))
}
logger.Logger.Info("Task Service Dubbo client connected successfully")
// 5. 设置路由
logger.Logger.Info("Setting up routes...")
r, err := router.SetupRouter(userClient, socialClient, assetClient, galleryClient, activityClient)
r, err := router.SetupRouter(userClient, socialClient, assetClient, galleryClient, activityClient, taskClient)
if err != nil {
logger.Logger.Fatal("Failed to setup router", zap.Error(err))
}

View File

@ -11,7 +11,7 @@ import (
)
// SetupRouter 设置路由
func SetupRouter(userClient *client.Client, socialClient *client.Client, assetClient *client.Client, galleryClient *client.Client, activityClient *client.Client) (*gin.Engine, error) {
func SetupRouter(userClient *client.Client, socialClient *client.Client, assetClient *client.Client, galleryClient *client.Client, activityClient *client.Client, taskClient *client.Client) (*gin.Engine, error) {
r := gin.Default()
// 全局中间件
@ -66,6 +66,11 @@ func SetupRouter(userClient *client.Client, socialClient *client.Client, assetCl
return nil, err
}
taskCtrl, err := controller.NewTaskController(taskClient)
if err != nil {
return nil, err
}
// API v1 路由组
v1 := r.Group("/api/v1")
{
@ -217,6 +222,23 @@ func SetupRouter(userClient *client.Client, socialClient *client.Client, assetCl
activities.POST("/:id/purchase", activityCtrl.PurchaseItem) // 购买道具
activities.GET("/:id/ranking", activityCtrl.GetContributionRanking) // 获取贡献点排名
}
// 任务相关路由(需要认证)
tasks := v1.Group("/tasks")
tasks.Use(middleware.AuthMiddleware())
{
tasks.GET("/daily", taskCtrl.GetDailyTasks) // 获取每日任务列表
tasks.POST("/report-event", taskCtrl.ReportEvent) // 上报任务事件
tasks.POST("/daily/claim", taskCtrl.ClaimDailyTask) // 领取单个每日任务
tasks.POST("/daily/claim-all", taskCtrl.ClaimAllDailyTasks) // 一键领取所有每日任务
tasks.POST("/guide/complete", taskCtrl.CompleteGuide) // 完成引导任务
tasks.GET("/onboarding/status", taskCtrl.GetOnboardingStatus) // 获取引导状态
tasks.POST("/onboarding/advance-stage", taskCtrl.AdvanceStage) // 进入下一引导阶段
tasks.POST("/onboarding/claim-reward", taskCtrl.ClaimOnboardingReward) // 领取引导阶段奖励
tasks.GET("/exhibition-revenue", taskCtrl.GetExhibitionRevenue) // 获取展示收益
tasks.POST("/exhibition-revenue/claim", taskCtrl.ClaimExhibitionRevenue) // 领取单条展示收益
tasks.POST("/exhibition-revenue/claim-all", taskCtrl.ClaimAllExhibitionRevenue) // 一键领取所有展示收益
}
}
return r, nil

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,512 @@
// Code generated by protoc-gen-triple. DO NOT EDIT.
//
// Source: task.proto
package task
import (
"context"
)
import (
"dubbo.apache.org/dubbo-go/v3"
"dubbo.apache.org/dubbo-go/v3/client"
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
"dubbo.apache.org/dubbo-go/v3/server"
)
// This is a compile-time assertion to ensure that this generated file and the Triple package
// are compatible. If you get a compiler error that this constant is not defined, this code was
// generated with a version of Triple newer than the one compiled into your binary. You can fix the
// problem by either regenerating this code with an older version of Triple or updating the Triple
// version compiled into your binary.
const _ = triple_protocol.IsAtLeastVersion0_1_0
const (
// TaskMobileServiceName is the fully-qualified name of the TaskMobileService service.
TaskMobileServiceName = "topfans.task.TaskMobileService"
)
// These constants are the fully-qualified names of the RPCs defined in this package. They're
// exposed at runtime as procedure and as the final two segments of the HTTP route.
//
// Note that these are different from the fully-qualified method names used by
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
// period.
const (
// TaskMobileServiceGetDailyTasksProcedure is the fully-qualified name of the TaskMobileService's GetDailyTasks RPC.
TaskMobileServiceGetDailyTasksProcedure = "/topfans.task.TaskMobileService/GetDailyTasks"
// TaskMobileServiceReportEventProcedure is the fully-qualified name of the TaskMobileService's ReportEvent RPC.
TaskMobileServiceReportEventProcedure = "/topfans.task.TaskMobileService/ReportEvent"
// TaskMobileServiceClaimDailyTaskProcedure is the fully-qualified name of the TaskMobileService's ClaimDailyTask RPC.
TaskMobileServiceClaimDailyTaskProcedure = "/topfans.task.TaskMobileService/ClaimDailyTask"
// TaskMobileServiceClaimAllDailyTasksProcedure is the fully-qualified name of the TaskMobileService's ClaimAllDailyTasks RPC.
TaskMobileServiceClaimAllDailyTasksProcedure = "/topfans.task.TaskMobileService/ClaimAllDailyTasks"
// TaskMobileServiceCompleteGuideProcedure is the fully-qualified name of the TaskMobileService's CompleteGuide RPC.
TaskMobileServiceCompleteGuideProcedure = "/topfans.task.TaskMobileService/CompleteGuide"
// TaskMobileServiceGetOnboardingStatusProcedure is the fully-qualified name of the TaskMobileService's GetOnboardingStatus RPC.
TaskMobileServiceGetOnboardingStatusProcedure = "/topfans.task.TaskMobileService/GetOnboardingStatus"
// TaskMobileServiceAdvanceStageProcedure is the fully-qualified name of the TaskMobileService's AdvanceStage RPC.
TaskMobileServiceAdvanceStageProcedure = "/topfans.task.TaskMobileService/AdvanceStage"
// TaskMobileServiceClaimOnboardingRewardProcedure is the fully-qualified name of the TaskMobileService's ClaimOnboardingReward RPC.
TaskMobileServiceClaimOnboardingRewardProcedure = "/topfans.task.TaskMobileService/ClaimOnboardingReward"
// TaskMobileServiceGetExhibitionRevenueProcedure is the fully-qualified name of the TaskMobileService's GetExhibitionRevenue RPC.
TaskMobileServiceGetExhibitionRevenueProcedure = "/topfans.task.TaskMobileService/GetExhibitionRevenue"
// TaskMobileServiceClaimExhibitionRevenueProcedure is the fully-qualified name of the TaskMobileService's ClaimExhibitionRevenue RPC.
TaskMobileServiceClaimExhibitionRevenueProcedure = "/topfans.task.TaskMobileService/ClaimExhibitionRevenue"
// TaskMobileServiceClaimAllExhibitionRevenueProcedure is the fully-qualified name of the TaskMobileService's ClaimAllExhibitionRevenue RPC.
TaskMobileServiceClaimAllExhibitionRevenueProcedure = "/topfans.task.TaskMobileService/ClaimAllExhibitionRevenue"
)
const (
// TaskInternalServiceName is the fully-qualified name of the TaskInternalService service.
TaskInternalServiceName = "topfans.task.TaskInternalService"
)
// These constants are the fully-qualified names of the RPCs defined in this package. They're
// exposed at runtime as procedure and as the final two segments of the HTTP route.
//
// Note that these are different from the fully-qualified method names used by
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
// period.
const (
// TaskInternalServiceInitUserTasksProcedure is the fully-qualified name of the TaskInternalService's InitUserTasks RPC.
TaskInternalServiceInitUserTasksProcedure = "/topfans.task.TaskInternalService/InitUserTasks"
// TaskInternalServiceOnExhibitionCompletedProcedure is the fully-qualified name of the TaskInternalService's OnExhibitionCompleted RPC.
TaskInternalServiceOnExhibitionCompletedProcedure = "/topfans.task.TaskInternalService/OnExhibitionCompleted"
)
var (
_ TaskMobileService = (*TaskMobileServiceImpl)(nil)
_ TaskInternalService = (*TaskInternalServiceImpl)(nil)
)
// TaskMobileService is a client for the topfans.task.TaskMobileService service.
type TaskMobileService interface {
GetDailyTasks(ctx context.Context, req *GetDailyTasksRequest, opts ...client.CallOption) (*GetDailyTasksResponse, error)
ReportEvent(ctx context.Context, req *ReportEventRequest, opts ...client.CallOption) (*ReportEventResponse, error)
ClaimDailyTask(ctx context.Context, req *ClaimDailyTaskRequest, opts ...client.CallOption) (*ClaimDailyTaskResponse, error)
ClaimAllDailyTasks(ctx context.Context, req *ClaimAllDailyTasksRequest, opts ...client.CallOption) (*ClaimAllDailyTasksResponse, error)
CompleteGuide(ctx context.Context, req *CompleteGuideRequest, opts ...client.CallOption) (*CompleteGuideResponse, error)
GetOnboardingStatus(ctx context.Context, req *GetOnboardingStatusRequest, opts ...client.CallOption) (*GetOnboardingStatusResponse, error)
AdvanceStage(ctx context.Context, req *AdvanceStageRequest, opts ...client.CallOption) (*AdvanceStageResponse, error)
ClaimOnboardingReward(ctx context.Context, req *ClaimOnboardingRewardRequest, opts ...client.CallOption) (*ClaimOnboardingRewardResponse, error)
GetExhibitionRevenue(ctx context.Context, req *GetExhibitionRevenueRequest, opts ...client.CallOption) (*GetExhibitionRevenueResponse, error)
ClaimExhibitionRevenue(ctx context.Context, req *ClaimExhibitionRevenueRequest, opts ...client.CallOption) (*ClaimExhibitionRevenueResponse, error)
ClaimAllExhibitionRevenue(ctx context.Context, req *ClaimAllExhibitionRevenueRequest, opts ...client.CallOption) (*ClaimAllExhibitionRevenueResponse, error)
}
// TaskInternalService is a client for the topfans.task.TaskInternalService service.
type TaskInternalService interface {
InitUserTasks(ctx context.Context, req *InitUserTasksRequest, opts ...client.CallOption) (*InitUserTasksResponse, error)
OnExhibitionCompleted(ctx context.Context, req *OnExhibitionCompletedRequest, opts ...client.CallOption) (*OnExhibitionCompletedResponse, error)
}
// NewTaskMobileService constructs a client for the task.TaskMobileService service.
func NewTaskMobileService(cli *client.Client, opts ...client.ReferenceOption) (TaskMobileService, error) {
conn, err := cli.DialWithInfo("topfans.task.TaskMobileService", &TaskMobileService_ClientInfo, opts...)
if err != nil {
return nil, err
}
return &TaskMobileServiceImpl{
conn: conn,
}, nil
}
func SetConsumerTaskMobileService(srv common.RPCService) {
dubbo.SetConsumerServiceWithInfo(srv, &TaskMobileService_ClientInfo)
}
// TaskMobileServiceImpl implements TaskMobileService.
type TaskMobileServiceImpl struct {
conn *client.Connection
}
func (c *TaskMobileServiceImpl) GetDailyTasks(ctx context.Context, req *GetDailyTasksRequest, opts ...client.CallOption) (*GetDailyTasksResponse, error) {
resp := new(GetDailyTasksResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetDailyTasks", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) ReportEvent(ctx context.Context, req *ReportEventRequest, opts ...client.CallOption) (*ReportEventResponse, error) {
resp := new(ReportEventResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "ReportEvent", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) ClaimDailyTask(ctx context.Context, req *ClaimDailyTaskRequest, opts ...client.CallOption) (*ClaimDailyTaskResponse, error) {
resp := new(ClaimDailyTaskResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "ClaimDailyTask", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) ClaimAllDailyTasks(ctx context.Context, req *ClaimAllDailyTasksRequest, opts ...client.CallOption) (*ClaimAllDailyTasksResponse, error) {
resp := new(ClaimAllDailyTasksResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "ClaimAllDailyTasks", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) CompleteGuide(ctx context.Context, req *CompleteGuideRequest, opts ...client.CallOption) (*CompleteGuideResponse, error) {
resp := new(CompleteGuideResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "CompleteGuide", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) GetOnboardingStatus(ctx context.Context, req *GetOnboardingStatusRequest, opts ...client.CallOption) (*GetOnboardingStatusResponse, error) {
resp := new(GetOnboardingStatusResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetOnboardingStatus", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) AdvanceStage(ctx context.Context, req *AdvanceStageRequest, opts ...client.CallOption) (*AdvanceStageResponse, error) {
resp := new(AdvanceStageResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "AdvanceStage", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) ClaimOnboardingReward(ctx context.Context, req *ClaimOnboardingRewardRequest, opts ...client.CallOption) (*ClaimOnboardingRewardResponse, error) {
resp := new(ClaimOnboardingRewardResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "ClaimOnboardingReward", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) GetExhibitionRevenue(ctx context.Context, req *GetExhibitionRevenueRequest, opts ...client.CallOption) (*GetExhibitionRevenueResponse, error) {
resp := new(GetExhibitionRevenueResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetExhibitionRevenue", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) ClaimExhibitionRevenue(ctx context.Context, req *ClaimExhibitionRevenueRequest, opts ...client.CallOption) (*ClaimExhibitionRevenueResponse, error) {
resp := new(ClaimExhibitionRevenueResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "ClaimExhibitionRevenue", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskMobileServiceImpl) ClaimAllExhibitionRevenue(ctx context.Context, req *ClaimAllExhibitionRevenueRequest, opts ...client.CallOption) (*ClaimAllExhibitionRevenueResponse, error) {
resp := new(ClaimAllExhibitionRevenueResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "ClaimAllExhibitionRevenue", opts...); err != nil {
return nil, err
}
return resp, nil
}
// NewTaskInternalService constructs a client for the task.TaskInternalService service.
func NewTaskInternalService(cli *client.Client, opts ...client.ReferenceOption) (TaskInternalService, error) {
conn, err := cli.DialWithInfo("topfans.task.TaskInternalService", &TaskInternalService_ClientInfo, opts...)
if err != nil {
return nil, err
}
return &TaskInternalServiceImpl{
conn: conn,
}, nil
}
func SetConsumerTaskInternalService(srv common.RPCService) {
dubbo.SetConsumerServiceWithInfo(srv, &TaskInternalService_ClientInfo)
}
// TaskInternalServiceImpl implements TaskInternalService.
type TaskInternalServiceImpl struct {
conn *client.Connection
}
func (c *TaskInternalServiceImpl) InitUserTasks(ctx context.Context, req *InitUserTasksRequest, opts ...client.CallOption) (*InitUserTasksResponse, error) {
resp := new(InitUserTasksResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "InitUserTasks", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *TaskInternalServiceImpl) OnExhibitionCompleted(ctx context.Context, req *OnExhibitionCompletedRequest, opts ...client.CallOption) (*OnExhibitionCompletedResponse, error) {
resp := new(OnExhibitionCompletedResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "OnExhibitionCompleted", opts...); err != nil {
return nil, err
}
return resp, nil
}
var TaskMobileService_ClientInfo = client.ClientInfo{
InterfaceName: "topfans.task.TaskMobileService",
MethodNames: []string{"GetDailyTasks", "ReportEvent", "ClaimDailyTask", "ClaimAllDailyTasks", "CompleteGuide", "GetOnboardingStatus", "AdvanceStage", "ClaimOnboardingReward", "GetExhibitionRevenue", "ClaimExhibitionRevenue", "ClaimAllExhibitionRevenue"},
ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) {
dubboCli := dubboCliRaw.(*TaskMobileServiceImpl)
dubboCli.conn = conn
},
}
var TaskInternalService_ClientInfo = client.ClientInfo{
InterfaceName: "topfans.task.TaskInternalService",
MethodNames: []string{"InitUserTasks", "OnExhibitionCompleted"},
ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) {
dubboCli := dubboCliRaw.(*TaskInternalServiceImpl)
dubboCli.conn = conn
},
}
// TaskMobileServiceHandler is an implementation of the topfans.task.TaskMobileService service.
type TaskMobileServiceHandler interface {
GetDailyTasks(context.Context, *GetDailyTasksRequest) (*GetDailyTasksResponse, error)
ReportEvent(context.Context, *ReportEventRequest) (*ReportEventResponse, error)
ClaimDailyTask(context.Context, *ClaimDailyTaskRequest) (*ClaimDailyTaskResponse, error)
ClaimAllDailyTasks(context.Context, *ClaimAllDailyTasksRequest) (*ClaimAllDailyTasksResponse, error)
CompleteGuide(context.Context, *CompleteGuideRequest) (*CompleteGuideResponse, error)
GetOnboardingStatus(context.Context, *GetOnboardingStatusRequest) (*GetOnboardingStatusResponse, error)
AdvanceStage(context.Context, *AdvanceStageRequest) (*AdvanceStageResponse, error)
ClaimOnboardingReward(context.Context, *ClaimOnboardingRewardRequest) (*ClaimOnboardingRewardResponse, error)
GetExhibitionRevenue(context.Context, *GetExhibitionRevenueRequest) (*GetExhibitionRevenueResponse, error)
ClaimExhibitionRevenue(context.Context, *ClaimExhibitionRevenueRequest) (*ClaimExhibitionRevenueResponse, error)
ClaimAllExhibitionRevenue(context.Context, *ClaimAllExhibitionRevenueRequest) (*ClaimAllExhibitionRevenueResponse, error)
}
func RegisterTaskMobileServiceHandler(srv *server.Server, hdlr TaskMobileServiceHandler, opts ...server.ServiceOption) error {
return srv.Register(hdlr, &TaskMobileService_ServiceInfo, opts...)
}
func SetProviderTaskMobileService(srv common.RPCService) {
dubbo.SetProviderServiceWithInfo(srv, &TaskMobileService_ServiceInfo)
}
// TaskInternalServiceHandler is an implementation of the topfans.task.TaskInternalService service.
type TaskInternalServiceHandler interface {
InitUserTasks(context.Context, *InitUserTasksRequest) (*InitUserTasksResponse, error)
OnExhibitionCompleted(context.Context, *OnExhibitionCompletedRequest) (*OnExhibitionCompletedResponse, error)
}
func RegisterTaskInternalServiceHandler(srv *server.Server, hdlr TaskInternalServiceHandler, opts ...server.ServiceOption) error {
return srv.Register(hdlr, &TaskInternalService_ServiceInfo, opts...)
}
func SetProviderTaskInternalService(srv common.RPCService) {
dubbo.SetProviderServiceWithInfo(srv, &TaskInternalService_ServiceInfo)
}
var TaskMobileService_ServiceInfo = server.ServiceInfo{
InterfaceName: "topfans.task.TaskMobileService",
ServiceType: (*TaskMobileServiceHandler)(nil),
Methods: []server.MethodInfo{
{
Name: "GetDailyTasks",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(GetDailyTasksRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*GetDailyTasksRequest)
res, err := handler.(TaskMobileServiceHandler).GetDailyTasks(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "ReportEvent",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(ReportEventRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*ReportEventRequest)
res, err := handler.(TaskMobileServiceHandler).ReportEvent(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "ClaimDailyTask",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(ClaimDailyTaskRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*ClaimDailyTaskRequest)
res, err := handler.(TaskMobileServiceHandler).ClaimDailyTask(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "ClaimAllDailyTasks",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(ClaimAllDailyTasksRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*ClaimAllDailyTasksRequest)
res, err := handler.(TaskMobileServiceHandler).ClaimAllDailyTasks(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "CompleteGuide",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(CompleteGuideRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*CompleteGuideRequest)
res, err := handler.(TaskMobileServiceHandler).CompleteGuide(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "GetOnboardingStatus",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(GetOnboardingStatusRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*GetOnboardingStatusRequest)
res, err := handler.(TaskMobileServiceHandler).GetOnboardingStatus(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "AdvanceStage",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(AdvanceStageRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*AdvanceStageRequest)
res, err := handler.(TaskMobileServiceHandler).AdvanceStage(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "ClaimOnboardingReward",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(ClaimOnboardingRewardRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*ClaimOnboardingRewardRequest)
res, err := handler.(TaskMobileServiceHandler).ClaimOnboardingReward(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "GetExhibitionRevenue",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(GetExhibitionRevenueRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*GetExhibitionRevenueRequest)
res, err := handler.(TaskMobileServiceHandler).GetExhibitionRevenue(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "ClaimExhibitionRevenue",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(ClaimExhibitionRevenueRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*ClaimExhibitionRevenueRequest)
res, err := handler.(TaskMobileServiceHandler).ClaimExhibitionRevenue(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "ClaimAllExhibitionRevenue",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(ClaimAllExhibitionRevenueRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*ClaimAllExhibitionRevenueRequest)
res, err := handler.(TaskMobileServiceHandler).ClaimAllExhibitionRevenue(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
},
}
var TaskInternalService_ServiceInfo = server.ServiceInfo{
InterfaceName: "topfans.task.TaskInternalService",
ServiceType: (*TaskInternalServiceHandler)(nil),
Methods: []server.MethodInfo{
{
Name: "InitUserTasks",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(InitUserTasksRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*InitUserTasksRequest)
res, err := handler.(TaskInternalServiceHandler).InitUserTasks(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "OnExhibitionCompleted",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(OnExhibitionCompletedRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*OnExhibitionCompletedRequest)
res, err := handler.(TaskInternalServiceHandler).OnExhibitionCompleted(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
},
}

View File

@ -1726,6 +1726,120 @@ func (x *UpdateAssetsCountResponse) GetNewCount() int32 {
return 0
}
// 增加经验值请求内部RPC调用用于taskService增加经验
type AddExperienceRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 用户ID
StarId int64 `protobuf:"varint,2,opt,name=star_id,json=starId,proto3" json:"star_id,omitempty"` // 明星ID
Delta int64 `protobuf:"varint,3,opt,name=delta,proto3" json:"delta,omitempty"` // 变化量(正数增加,负数减少)
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AddExperienceRequest) Reset() {
*x = AddExperienceRequest{}
mi := &file_user_proto_msgTypes[27]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AddExperienceRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AddExperienceRequest) ProtoMessage() {}
func (x *AddExperienceRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[27]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AddExperienceRequest.ProtoReflect.Descriptor instead.
func (*AddExperienceRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{27}
}
func (x *AddExperienceRequest) GetUserId() int64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *AddExperienceRequest) GetStarId() int64 {
if x != nil {
return x.StarId
}
return 0
}
func (x *AddExperienceRequest) GetDelta() int64 {
if x != nil {
return x.Delta
}
return 0
}
// 增加经验值响应
type AddExperienceResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
NewExperience int64 `protobuf:"varint,2,opt,name=new_experience,json=newExperience,proto3" json:"new_experience,omitempty"` // 更新后的经验值
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AddExperienceResponse) Reset() {
*x = AddExperienceResponse{}
mi := &file_user_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AddExperienceResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AddExperienceResponse) ProtoMessage() {}
func (x *AddExperienceResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[28]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AddExperienceResponse.ProtoReflect.Descriptor instead.
func (*AddExperienceResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{28}
}
func (x *AddExperienceResponse) GetBase() *common.BaseResponse {
if x != nil {
return x.Base
}
return nil
}
func (x *AddExperienceResponse) GetNewExperience() int64 {
if x != nil {
return x.NewExperience
}
return 0
}
// 获取当前登录用户信息请求
type GetCurrentUserRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -1735,7 +1849,7 @@ type GetCurrentUserRequest struct {
func (x *GetCurrentUserRequest) Reset() {
*x = GetCurrentUserRequest{}
mi := &file_user_proto_msgTypes[27]
mi := &file_user_proto_msgTypes[29]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1747,7 +1861,7 @@ func (x *GetCurrentUserRequest) String() string {
func (*GetCurrentUserRequest) ProtoMessage() {}
func (x *GetCurrentUserRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[27]
mi := &file_user_proto_msgTypes[29]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1760,7 +1874,7 @@ func (x *GetCurrentUserRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetCurrentUserRequest.ProtoReflect.Descriptor instead.
func (*GetCurrentUserRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{27}
return file_user_proto_rawDescGZIP(), []int{29}
}
// 获取当前登录用户信息响应
@ -1776,7 +1890,7 @@ type GetCurrentUserResponse struct {
func (x *GetCurrentUserResponse) Reset() {
*x = GetCurrentUserResponse{}
mi := &file_user_proto_msgTypes[28]
mi := &file_user_proto_msgTypes[30]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1788,7 +1902,7 @@ func (x *GetCurrentUserResponse) String() string {
func (*GetCurrentUserResponse) ProtoMessage() {}
func (x *GetCurrentUserResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[28]
mi := &file_user_proto_msgTypes[30]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1801,7 +1915,7 @@ func (x *GetCurrentUserResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetCurrentUserResponse.ProtoReflect.Descriptor instead.
func (*GetCurrentUserResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{28}
return file_user_proto_rawDescGZIP(), []int{30}
}
func (x *GetCurrentUserResponse) GetBase() *common.BaseResponse {
@ -1841,7 +1955,7 @@ type GetMyProfileRequest struct {
func (x *GetMyProfileRequest) Reset() {
*x = GetMyProfileRequest{}
mi := &file_user_proto_msgTypes[29]
mi := &file_user_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1853,7 +1967,7 @@ func (x *GetMyProfileRequest) String() string {
func (*GetMyProfileRequest) ProtoMessage() {}
func (x *GetMyProfileRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[29]
mi := &file_user_proto_msgTypes[31]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1866,7 +1980,7 @@ func (x *GetMyProfileRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyProfileRequest.ProtoReflect.Descriptor instead.
func (*GetMyProfileRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{29}
return file_user_proto_rawDescGZIP(), []int{31}
}
// 获取个人信息页响应
@ -1882,7 +1996,7 @@ type GetMyProfileResponse struct {
func (x *GetMyProfileResponse) Reset() {
*x = GetMyProfileResponse{}
mi := &file_user_proto_msgTypes[30]
mi := &file_user_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1894,7 +2008,7 @@ func (x *GetMyProfileResponse) String() string {
func (*GetMyProfileResponse) ProtoMessage() {}
func (x *GetMyProfileResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[30]
mi := &file_user_proto_msgTypes[32]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1907,7 +2021,7 @@ func (x *GetMyProfileResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyProfileResponse.ProtoReflect.Descriptor instead.
func (*GetMyProfileResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{30}
return file_user_proto_rawDescGZIP(), []int{32}
}
func (x *GetMyProfileResponse) GetBase() *common.BaseResponse {
@ -1948,7 +2062,7 @@ type UpdateNicknameRequest struct {
func (x *UpdateNicknameRequest) Reset() {
*x = UpdateNicknameRequest{}
mi := &file_user_proto_msgTypes[31]
mi := &file_user_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1960,7 +2074,7 @@ func (x *UpdateNicknameRequest) String() string {
func (*UpdateNicknameRequest) ProtoMessage() {}
func (x *UpdateNicknameRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[31]
mi := &file_user_proto_msgTypes[33]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1973,7 +2087,7 @@ func (x *UpdateNicknameRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdateNicknameRequest.ProtoReflect.Descriptor instead.
func (*UpdateNicknameRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{31}
return file_user_proto_rawDescGZIP(), []int{33}
}
func (x *UpdateNicknameRequest) GetNickname() string {
@ -1994,7 +2108,7 @@ type UpdateNicknameResponse struct {
func (x *UpdateNicknameResponse) Reset() {
*x = UpdateNicknameResponse{}
mi := &file_user_proto_msgTypes[32]
mi := &file_user_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2006,7 +2120,7 @@ func (x *UpdateNicknameResponse) String() string {
func (*UpdateNicknameResponse) ProtoMessage() {}
func (x *UpdateNicknameResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[32]
mi := &file_user_proto_msgTypes[34]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2019,7 +2133,7 @@ func (x *UpdateNicknameResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdateNicknameResponse.ProtoReflect.Descriptor instead.
func (*UpdateNicknameResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{32}
return file_user_proto_rawDescGZIP(), []int{34}
}
func (x *UpdateNicknameResponse) GetBase() *common.BaseResponse {
@ -2047,7 +2161,7 @@ type UpdatePasswordRequest struct {
func (x *UpdatePasswordRequest) Reset() {
*x = UpdatePasswordRequest{}
mi := &file_user_proto_msgTypes[33]
mi := &file_user_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2059,7 +2173,7 @@ func (x *UpdatePasswordRequest) String() string {
func (*UpdatePasswordRequest) ProtoMessage() {}
func (x *UpdatePasswordRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[33]
mi := &file_user_proto_msgTypes[35]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2072,7 +2186,7 @@ func (x *UpdatePasswordRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdatePasswordRequest.ProtoReflect.Descriptor instead.
func (*UpdatePasswordRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{33}
return file_user_proto_rawDescGZIP(), []int{35}
}
func (x *UpdatePasswordRequest) GetOldPassword() string {
@ -2099,7 +2213,7 @@ type UpdatePasswordResponse struct {
func (x *UpdatePasswordResponse) Reset() {
*x = UpdatePasswordResponse{}
mi := &file_user_proto_msgTypes[34]
mi := &file_user_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2111,7 +2225,7 @@ func (x *UpdatePasswordResponse) String() string {
func (*UpdatePasswordResponse) ProtoMessage() {}
func (x *UpdatePasswordResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[34]
mi := &file_user_proto_msgTypes[36]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2124,7 +2238,7 @@ func (x *UpdatePasswordResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdatePasswordResponse.ProtoReflect.Descriptor instead.
func (*UpdatePasswordResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{34}
return file_user_proto_rawDescGZIP(), []int{36}
}
func (x *UpdatePasswordResponse) GetBase() *common.BaseResponse {
@ -2144,7 +2258,7 @@ type UpdateAvatarRequest struct {
func (x *UpdateAvatarRequest) Reset() {
*x = UpdateAvatarRequest{}
mi := &file_user_proto_msgTypes[35]
mi := &file_user_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2156,7 +2270,7 @@ func (x *UpdateAvatarRequest) String() string {
func (*UpdateAvatarRequest) ProtoMessage() {}
func (x *UpdateAvatarRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[35]
mi := &file_user_proto_msgTypes[37]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2169,7 +2283,7 @@ func (x *UpdateAvatarRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdateAvatarRequest.ProtoReflect.Descriptor instead.
func (*UpdateAvatarRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{35}
return file_user_proto_rawDescGZIP(), []int{37}
}
func (x *UpdateAvatarRequest) GetAvatarUrl() string {
@ -2190,7 +2304,7 @@ type UpdateAvatarResponse struct {
func (x *UpdateAvatarResponse) Reset() {
*x = UpdateAvatarResponse{}
mi := &file_user_proto_msgTypes[36]
mi := &file_user_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2202,7 +2316,7 @@ func (x *UpdateAvatarResponse) String() string {
func (*UpdateAvatarResponse) ProtoMessage() {}
func (x *UpdateAvatarResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[36]
mi := &file_user_proto_msgTypes[38]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2215,7 +2329,7 @@ func (x *UpdateAvatarResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdateAvatarResponse.ProtoReflect.Descriptor instead.
func (*UpdateAvatarResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{36}
return file_user_proto_rawDescGZIP(), []int{38}
}
func (x *UpdateAvatarResponse) GetBase() *common.BaseResponse {
@ -2242,7 +2356,7 @@ type GetFanIdentitiesRequest struct {
func (x *GetFanIdentitiesRequest) Reset() {
*x = GetFanIdentitiesRequest{}
mi := &file_user_proto_msgTypes[37]
mi := &file_user_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2254,7 +2368,7 @@ func (x *GetFanIdentitiesRequest) String() string {
func (*GetFanIdentitiesRequest) ProtoMessage() {}
func (x *GetFanIdentitiesRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[37]
mi := &file_user_proto_msgTypes[39]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2267,7 +2381,7 @@ func (x *GetFanIdentitiesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetFanIdentitiesRequest.ProtoReflect.Descriptor instead.
func (*GetFanIdentitiesRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{37}
return file_user_proto_rawDescGZIP(), []int{39}
}
func (x *GetFanIdentitiesRequest) GetKeyword() string {
@ -2288,7 +2402,7 @@ type GetFanIdentitiesResponse struct {
func (x *GetFanIdentitiesResponse) Reset() {
*x = GetFanIdentitiesResponse{}
mi := &file_user_proto_msgTypes[38]
mi := &file_user_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2300,7 +2414,7 @@ func (x *GetFanIdentitiesResponse) String() string {
func (*GetFanIdentitiesResponse) ProtoMessage() {}
func (x *GetFanIdentitiesResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[38]
mi := &file_user_proto_msgTypes[40]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2313,7 +2427,7 @@ func (x *GetFanIdentitiesResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetFanIdentitiesResponse.ProtoReflect.Descriptor instead.
func (*GetFanIdentitiesResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{38}
return file_user_proto_rawDescGZIP(), []int{40}
}
func (x *GetFanIdentitiesResponse) GetBase() *common.BaseResponse {
@ -2339,7 +2453,7 @@ type GetMyFanIdentitiesRequest struct {
func (x *GetMyFanIdentitiesRequest) Reset() {
*x = GetMyFanIdentitiesRequest{}
mi := &file_user_proto_msgTypes[39]
mi := &file_user_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2351,7 +2465,7 @@ func (x *GetMyFanIdentitiesRequest) String() string {
func (*GetMyFanIdentitiesRequest) ProtoMessage() {}
func (x *GetMyFanIdentitiesRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[39]
mi := &file_user_proto_msgTypes[41]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2364,7 +2478,7 @@ func (x *GetMyFanIdentitiesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyFanIdentitiesRequest.ProtoReflect.Descriptor instead.
func (*GetMyFanIdentitiesRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{39}
return file_user_proto_rawDescGZIP(), []int{41}
}
// 我的粉丝身份项(包含粉丝档案和明星信息)
@ -2378,7 +2492,7 @@ type MyFanIdentityItem struct {
func (x *MyFanIdentityItem) Reset() {
*x = MyFanIdentityItem{}
mi := &file_user_proto_msgTypes[40]
mi := &file_user_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2390,7 +2504,7 @@ func (x *MyFanIdentityItem) String() string {
func (*MyFanIdentityItem) ProtoMessage() {}
func (x *MyFanIdentityItem) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[40]
mi := &file_user_proto_msgTypes[42]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2403,7 +2517,7 @@ func (x *MyFanIdentityItem) ProtoReflect() protoreflect.Message {
// Deprecated: Use MyFanIdentityItem.ProtoReflect.Descriptor instead.
func (*MyFanIdentityItem) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{40}
return file_user_proto_rawDescGZIP(), []int{42}
}
func (x *MyFanIdentityItem) GetFanProfile() *FanProfile {
@ -2432,7 +2546,7 @@ type GetMyFanIdentitiesResponse struct {
func (x *GetMyFanIdentitiesResponse) Reset() {
*x = GetMyFanIdentitiesResponse{}
mi := &file_user_proto_msgTypes[41]
mi := &file_user_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2444,7 +2558,7 @@ func (x *GetMyFanIdentitiesResponse) String() string {
func (*GetMyFanIdentitiesResponse) ProtoMessage() {}
func (x *GetMyFanIdentitiesResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[41]
mi := &file_user_proto_msgTypes[43]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2457,7 +2571,7 @@ func (x *GetMyFanIdentitiesResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyFanIdentitiesResponse.ProtoReflect.Descriptor instead.
func (*GetMyFanIdentitiesResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{41}
return file_user_proto_rawDescGZIP(), []int{43}
}
func (x *GetMyFanIdentitiesResponse) GetBase() *common.BaseResponse {
@ -2492,7 +2606,7 @@ type AddIdentityRequest struct {
func (x *AddIdentityRequest) Reset() {
*x = AddIdentityRequest{}
mi := &file_user_proto_msgTypes[42]
mi := &file_user_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2504,7 +2618,7 @@ func (x *AddIdentityRequest) String() string {
func (*AddIdentityRequest) ProtoMessage() {}
func (x *AddIdentityRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[42]
mi := &file_user_proto_msgTypes[44]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2517,7 +2631,7 @@ func (x *AddIdentityRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use AddIdentityRequest.ProtoReflect.Descriptor instead.
func (*AddIdentityRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{42}
return file_user_proto_rawDescGZIP(), []int{44}
}
func (x *AddIdentityRequest) GetStarId() int64 {
@ -2545,7 +2659,7 @@ type AddIdentityResponse struct {
func (x *AddIdentityResponse) Reset() {
*x = AddIdentityResponse{}
mi := &file_user_proto_msgTypes[43]
mi := &file_user_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2557,7 +2671,7 @@ func (x *AddIdentityResponse) String() string {
func (*AddIdentityResponse) ProtoMessage() {}
func (x *AddIdentityResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[43]
mi := &file_user_proto_msgTypes[45]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2570,7 +2684,7 @@ func (x *AddIdentityResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use AddIdentityResponse.ProtoReflect.Descriptor instead.
func (*AddIdentityResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{43}
return file_user_proto_rawDescGZIP(), []int{45}
}
func (x *AddIdentityResponse) GetBase() *common.BaseResponse {
@ -2597,7 +2711,7 @@ type SwitchIdentityRequest struct {
func (x *SwitchIdentityRequest) Reset() {
*x = SwitchIdentityRequest{}
mi := &file_user_proto_msgTypes[44]
mi := &file_user_proto_msgTypes[46]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2609,7 +2723,7 @@ func (x *SwitchIdentityRequest) String() string {
func (*SwitchIdentityRequest) ProtoMessage() {}
func (x *SwitchIdentityRequest) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[44]
mi := &file_user_proto_msgTypes[46]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2622,7 +2736,7 @@ func (x *SwitchIdentityRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SwitchIdentityRequest.ProtoReflect.Descriptor instead.
func (*SwitchIdentityRequest) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{44}
return file_user_proto_rawDescGZIP(), []int{46}
}
func (x *SwitchIdentityRequest) GetNewStarId() int64 {
@ -2645,7 +2759,7 @@ type SwitchIdentityResponse struct {
func (x *SwitchIdentityResponse) Reset() {
*x = SwitchIdentityResponse{}
mi := &file_user_proto_msgTypes[45]
mi := &file_user_proto_msgTypes[47]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -2657,7 +2771,7 @@ func (x *SwitchIdentityResponse) String() string {
func (*SwitchIdentityResponse) ProtoMessage() {}
func (x *SwitchIdentityResponse) ProtoReflect() protoreflect.Message {
mi := &file_user_proto_msgTypes[45]
mi := &file_user_proto_msgTypes[47]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -2670,7 +2784,7 @@ func (x *SwitchIdentityResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SwitchIdentityResponse.ProtoReflect.Descriptor instead.
func (*SwitchIdentityResponse) Descriptor() ([]byte, []int) {
return file_user_proto_rawDescGZIP(), []int{45}
return file_user_proto_rawDescGZIP(), []int{47}
}
func (x *SwitchIdentityResponse) GetBase() *common.BaseResponse {
@ -2840,7 +2954,14 @@ const file_user_proto_rawDesc = "" +
"\x05delta\x18\x03 \x01(\x05R\x05delta\"j\n" +
"\x19UpdateAssetsCountResponse\x120\n" +
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12\x1b\n" +
"\tnew_count\x18\x02 \x01(\x05R\bnewCount\"\x17\n" +
"\tnew_count\x18\x02 \x01(\x05R\bnewCount\"^\n" +
"\x14AddExperienceRequest\x12\x17\n" +
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x17\n" +
"\astar_id\x18\x02 \x01(\x03R\x06starId\x12\x14\n" +
"\x05delta\x18\x03 \x01(\x03R\x05delta\"p\n" +
"\x15AddExperienceResponse\x120\n" +
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12%\n" +
"\x0enew_experience\x18\x02 \x01(\x03R\rnewExperience\"\x17\n" +
"\x15GetCurrentUserRequest\"\xea\x01\n" +
"\x16GetCurrentUserResponse\x120\n" +
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12&\n" +
@ -2902,7 +3023,7 @@ const file_user_proto_rawDesc = "" +
"\n" +
"expires_in\x18\x03 \x01(\x03R\texpiresIn\x129\n" +
"\vfan_profile\x18\x04 \x01(\v2\x18.topfans.user.FanProfileR\n" +
"fanProfile2\xf0\x13\n" +
"fanProfile2\xca\x14\n" +
"\x11UserSocialService\x12k\n" +
"\bRegister\x12\x1d.topfans.user.RegisterRequest\x1a\x1e.topfans.user.RegisterResponse\" \x82\xd3\xe4\x93\x02\x1a:\x01*\"\x15/api/v1/auth/register\x12_\n" +
"\x05Login\x12\x1a.topfans.user.LoginRequest\x1a\x1b.topfans.user.LoginResponse\"\x1d\x82\xd3\xe4\x93\x02\x17:\x01*\"\x12/api/v1/auth/login\x12v\n" +
@ -2915,7 +3036,8 @@ const file_user_proto_rawDesc = "" +
"\rGetFanProfile\x12\".topfans.user.GetFanProfileRequest\x1a#.topfans.user.GetFanProfileResponse\"6\x82\xd3\xe4\x93\x020\x12./api/v1/users/{user_id}/fan-profiles/{star_id}\x12s\n" +
"\x16UpdateFanProfileSocial\x12+.topfans.user.UpdateFanProfileSocialRequest\x1a,.topfans.user.UpdateFanProfileSocialResponse\x12m\n" +
"\x14UpdateCrystalBalance\x12).topfans.user.UpdateCrystalBalanceRequest\x1a*.topfans.user.UpdateCrystalBalanceResponse\x12d\n" +
"\x11UpdateAssetsCount\x12&.topfans.user.UpdateAssetsCountRequest\x1a'.topfans.user.UpdateAssetsCountResponse\x12t\n" +
"\x11UpdateAssetsCount\x12&.topfans.user.UpdateAssetsCountRequest\x1a'.topfans.user.UpdateAssetsCountResponse\x12X\n" +
"\rAddExperience\x12\".topfans.user.AddExperienceRequest\x1a#.topfans.user.AddExperienceResponse\x12t\n" +
"\x0eGetCurrentUser\x12#.topfans.user.GetCurrentUserRequest\x1a$.topfans.user.GetCurrentUserResponse\"\x17\x82\xd3\xe4\x93\x02\x11\x12\x0f/api/v1/auth/me\x12q\n" +
"\fGetMyProfile\x12!.topfans.user.GetMyProfileRequest\x1a\".topfans.user.GetMyProfileResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\x12\x12/api/v1/me/profile\x12z\n" +
"\x0eUpdateNickname\x12#.topfans.user.UpdateNicknameRequest\x1a$.topfans.user.UpdateNicknameResponse\"\x1d\x82\xd3\xe4\x93\x02\x17:\x01*\"\x12/api/v1/me/profile\x12\x80\x01\n" +
@ -2938,7 +3060,7 @@ func file_user_proto_rawDescGZIP() []byte {
return file_user_proto_rawDescData
}
var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 46)
var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 48)
var file_user_proto_goTypes = []any{
(*User)(nil), // 0: topfans.user.User
(*FanProfile)(nil), // 1: topfans.user.FanProfile
@ -2967,116 +3089,121 @@ var file_user_proto_goTypes = []any{
(*UpdateCrystalBalanceResponse)(nil), // 24: topfans.user.UpdateCrystalBalanceResponse
(*UpdateAssetsCountRequest)(nil), // 25: topfans.user.UpdateAssetsCountRequest
(*UpdateAssetsCountResponse)(nil), // 26: topfans.user.UpdateAssetsCountResponse
(*GetCurrentUserRequest)(nil), // 27: topfans.user.GetCurrentUserRequest
(*GetCurrentUserResponse)(nil), // 28: topfans.user.GetCurrentUserResponse
(*GetMyProfileRequest)(nil), // 29: topfans.user.GetMyProfileRequest
(*GetMyProfileResponse)(nil), // 30: topfans.user.GetMyProfileResponse
(*UpdateNicknameRequest)(nil), // 31: topfans.user.UpdateNicknameRequest
(*UpdateNicknameResponse)(nil), // 32: topfans.user.UpdateNicknameResponse
(*UpdatePasswordRequest)(nil), // 33: topfans.user.UpdatePasswordRequest
(*UpdatePasswordResponse)(nil), // 34: topfans.user.UpdatePasswordResponse
(*UpdateAvatarRequest)(nil), // 35: topfans.user.UpdateAvatarRequest
(*UpdateAvatarResponse)(nil), // 36: topfans.user.UpdateAvatarResponse
(*GetFanIdentitiesRequest)(nil), // 37: topfans.user.GetFanIdentitiesRequest
(*GetFanIdentitiesResponse)(nil), // 38: topfans.user.GetFanIdentitiesResponse
(*GetMyFanIdentitiesRequest)(nil), // 39: topfans.user.GetMyFanIdentitiesRequest
(*MyFanIdentityItem)(nil), // 40: topfans.user.MyFanIdentityItem
(*GetMyFanIdentitiesResponse)(nil), // 41: topfans.user.GetMyFanIdentitiesResponse
(*AddIdentityRequest)(nil), // 42: topfans.user.AddIdentityRequest
(*AddIdentityResponse)(nil), // 43: topfans.user.AddIdentityResponse
(*SwitchIdentityRequest)(nil), // 44: topfans.user.SwitchIdentityRequest
(*SwitchIdentityResponse)(nil), // 45: topfans.user.SwitchIdentityResponse
(*common.BaseResponse)(nil), // 46: topfans.common.BaseResponse
(*AddExperienceRequest)(nil), // 27: topfans.user.AddExperienceRequest
(*AddExperienceResponse)(nil), // 28: topfans.user.AddExperienceResponse
(*GetCurrentUserRequest)(nil), // 29: topfans.user.GetCurrentUserRequest
(*GetCurrentUserResponse)(nil), // 30: topfans.user.GetCurrentUserResponse
(*GetMyProfileRequest)(nil), // 31: topfans.user.GetMyProfileRequest
(*GetMyProfileResponse)(nil), // 32: topfans.user.GetMyProfileResponse
(*UpdateNicknameRequest)(nil), // 33: topfans.user.UpdateNicknameRequest
(*UpdateNicknameResponse)(nil), // 34: topfans.user.UpdateNicknameResponse
(*UpdatePasswordRequest)(nil), // 35: topfans.user.UpdatePasswordRequest
(*UpdatePasswordResponse)(nil), // 36: topfans.user.UpdatePasswordResponse
(*UpdateAvatarRequest)(nil), // 37: topfans.user.UpdateAvatarRequest
(*UpdateAvatarResponse)(nil), // 38: topfans.user.UpdateAvatarResponse
(*GetFanIdentitiesRequest)(nil), // 39: topfans.user.GetFanIdentitiesRequest
(*GetFanIdentitiesResponse)(nil), // 40: topfans.user.GetFanIdentitiesResponse
(*GetMyFanIdentitiesRequest)(nil), // 41: topfans.user.GetMyFanIdentitiesRequest
(*MyFanIdentityItem)(nil), // 42: topfans.user.MyFanIdentityItem
(*GetMyFanIdentitiesResponse)(nil), // 43: topfans.user.GetMyFanIdentitiesResponse
(*AddIdentityRequest)(nil), // 44: topfans.user.AddIdentityRequest
(*AddIdentityResponse)(nil), // 45: topfans.user.AddIdentityResponse
(*SwitchIdentityRequest)(nil), // 46: topfans.user.SwitchIdentityRequest
(*SwitchIdentityResponse)(nil), // 47: topfans.user.SwitchIdentityResponse
(*common.BaseResponse)(nil), // 48: topfans.common.BaseResponse
}
var file_user_proto_depIdxs = []int32{
46, // 0: topfans.user.RegisterResponse.base:type_name -> topfans.common.BaseResponse
48, // 0: topfans.user.RegisterResponse.base:type_name -> topfans.common.BaseResponse
0, // 1: topfans.user.RegisterResponse.user:type_name -> topfans.user.User
1, // 2: topfans.user.RegisterResponse.fan_profile:type_name -> topfans.user.FanProfile
46, // 3: topfans.user.LoginResponse.base:type_name -> topfans.common.BaseResponse
48, // 3: topfans.user.LoginResponse.base:type_name -> topfans.common.BaseResponse
0, // 4: topfans.user.LoginResponse.user:type_name -> topfans.user.User
1, // 5: topfans.user.LoginResponse.fan_profile:type_name -> topfans.user.FanProfile
1, // 6: topfans.user.LoginResponse.fan_profiles:type_name -> topfans.user.FanProfile
46, // 7: topfans.user.RefreshTokenResponse.base:type_name -> topfans.common.BaseResponse
46, // 8: topfans.user.ValidateTokenResponse.base:type_name -> topfans.common.BaseResponse
46, // 9: topfans.user.LogoutResponse.base:type_name -> topfans.common.BaseResponse
46, // 10: topfans.user.CheckNicknameResponse.base:type_name -> topfans.common.BaseResponse
46, // 11: topfans.user.CheckMobileResponse.base:type_name -> topfans.common.BaseResponse
46, // 12: topfans.user.GetUserResponse.base:type_name -> topfans.common.BaseResponse
48, // 7: topfans.user.RefreshTokenResponse.base:type_name -> topfans.common.BaseResponse
48, // 8: topfans.user.ValidateTokenResponse.base:type_name -> topfans.common.BaseResponse
48, // 9: topfans.user.LogoutResponse.base:type_name -> topfans.common.BaseResponse
48, // 10: topfans.user.CheckNicknameResponse.base:type_name -> topfans.common.BaseResponse
48, // 11: topfans.user.CheckMobileResponse.base:type_name -> topfans.common.BaseResponse
48, // 12: topfans.user.GetUserResponse.base:type_name -> topfans.common.BaseResponse
0, // 13: topfans.user.GetUserResponse.user:type_name -> topfans.user.User
46, // 14: topfans.user.GetFanProfileResponse.base:type_name -> topfans.common.BaseResponse
48, // 14: topfans.user.GetFanProfileResponse.base:type_name -> topfans.common.BaseResponse
1, // 15: topfans.user.GetFanProfileResponse.profile:type_name -> topfans.user.FanProfile
46, // 16: topfans.user.UpdateFanProfileSocialResponse.base:type_name -> topfans.common.BaseResponse
46, // 17: topfans.user.UpdateCrystalBalanceResponse.base:type_name -> topfans.common.BaseResponse
46, // 18: topfans.user.UpdateAssetsCountResponse.base:type_name -> topfans.common.BaseResponse
46, // 19: topfans.user.GetCurrentUserResponse.base:type_name -> topfans.common.BaseResponse
0, // 20: topfans.user.GetCurrentUserResponse.user:type_name -> topfans.user.User
1, // 21: topfans.user.GetCurrentUserResponse.fan_profile:type_name -> topfans.user.FanProfile
1, // 22: topfans.user.GetCurrentUserResponse.fan_profiles:type_name -> topfans.user.FanProfile
46, // 23: topfans.user.GetMyProfileResponse.base:type_name -> topfans.common.BaseResponse
0, // 24: topfans.user.GetMyProfileResponse.user:type_name -> topfans.user.User
1, // 25: topfans.user.GetMyProfileResponse.fan_profile:type_name -> topfans.user.FanProfile
1, // 26: topfans.user.GetMyProfileResponse.fan_profiles:type_name -> topfans.user.FanProfile
46, // 27: topfans.user.UpdateNicknameResponse.base:type_name -> topfans.common.BaseResponse
1, // 28: topfans.user.UpdateNicknameResponse.fan_profile:type_name -> topfans.user.FanProfile
46, // 29: topfans.user.UpdatePasswordResponse.base:type_name -> topfans.common.BaseResponse
46, // 30: topfans.user.UpdateAvatarResponse.base:type_name -> topfans.common.BaseResponse
46, // 31: topfans.user.GetFanIdentitiesResponse.base:type_name -> topfans.common.BaseResponse
2, // 32: topfans.user.GetFanIdentitiesResponse.stars:type_name -> topfans.user.Star
1, // 33: topfans.user.MyFanIdentityItem.fan_profile:type_name -> topfans.user.FanProfile
2, // 34: topfans.user.MyFanIdentityItem.star:type_name -> topfans.user.Star
46, // 35: topfans.user.GetMyFanIdentitiesResponse.base:type_name -> topfans.common.BaseResponse
40, // 36: topfans.user.GetMyFanIdentitiesResponse.items:type_name -> topfans.user.MyFanIdentityItem
46, // 37: topfans.user.AddIdentityResponse.base:type_name -> topfans.common.BaseResponse
1, // 38: topfans.user.AddIdentityResponse.fan_profile:type_name -> topfans.user.FanProfile
46, // 39: topfans.user.SwitchIdentityResponse.base:type_name -> topfans.common.BaseResponse
1, // 40: topfans.user.SwitchIdentityResponse.fan_profile:type_name -> topfans.user.FanProfile
3, // 41: topfans.user.UserSocialService.Register:input_type -> topfans.user.RegisterRequest
5, // 42: topfans.user.UserSocialService.Login:input_type -> topfans.user.LoginRequest
7, // 43: topfans.user.UserSocialService.RefreshToken:input_type -> topfans.user.RefreshTokenRequest
9, // 44: topfans.user.UserSocialService.ValidateToken:input_type -> topfans.user.ValidateTokenRequest
11, // 45: topfans.user.UserSocialService.Logout:input_type -> topfans.user.LogoutRequest
13, // 46: topfans.user.UserSocialService.CheckNickname:input_type -> topfans.user.CheckNicknameRequest
15, // 47: topfans.user.UserSocialService.CheckMobile:input_type -> topfans.user.CheckMobileRequest
17, // 48: topfans.user.UserSocialService.GetUser:input_type -> topfans.user.GetUserRequest
19, // 49: topfans.user.UserSocialService.GetFanProfile:input_type -> topfans.user.GetFanProfileRequest
21, // 50: topfans.user.UserSocialService.UpdateFanProfileSocial:input_type -> topfans.user.UpdateFanProfileSocialRequest
23, // 51: topfans.user.UserSocialService.UpdateCrystalBalance:input_type -> topfans.user.UpdateCrystalBalanceRequest
25, // 52: topfans.user.UserSocialService.UpdateAssetsCount:input_type -> topfans.user.UpdateAssetsCountRequest
27, // 53: topfans.user.UserSocialService.GetCurrentUser:input_type -> topfans.user.GetCurrentUserRequest
29, // 54: topfans.user.UserSocialService.GetMyProfile:input_type -> topfans.user.GetMyProfileRequest
31, // 55: topfans.user.UserSocialService.UpdateNickname:input_type -> topfans.user.UpdateNicknameRequest
33, // 56: topfans.user.UserSocialService.UpdatePassword:input_type -> topfans.user.UpdatePasswordRequest
35, // 57: topfans.user.UserSocialService.UpdateAvatar:input_type -> topfans.user.UpdateAvatarRequest
37, // 58: topfans.user.UserSocialService.GetFanIdentities:input_type -> topfans.user.GetFanIdentitiesRequest
39, // 59: topfans.user.UserSocialService.GetMyFanIdentities:input_type -> topfans.user.GetMyFanIdentitiesRequest
42, // 60: topfans.user.UserSocialService.AddIdentity:input_type -> topfans.user.AddIdentityRequest
44, // 61: topfans.user.UserSocialService.SwitchIdentity:input_type -> topfans.user.SwitchIdentityRequest
4, // 62: topfans.user.UserSocialService.Register:output_type -> topfans.user.RegisterResponse
6, // 63: topfans.user.UserSocialService.Login:output_type -> topfans.user.LoginResponse
8, // 64: topfans.user.UserSocialService.RefreshToken:output_type -> topfans.user.RefreshTokenResponse
10, // 65: topfans.user.UserSocialService.ValidateToken:output_type -> topfans.user.ValidateTokenResponse
12, // 66: topfans.user.UserSocialService.Logout:output_type -> topfans.user.LogoutResponse
14, // 67: topfans.user.UserSocialService.CheckNickname:output_type -> topfans.user.CheckNicknameResponse
16, // 68: topfans.user.UserSocialService.CheckMobile:output_type -> topfans.user.CheckMobileResponse
18, // 69: topfans.user.UserSocialService.GetUser:output_type -> topfans.user.GetUserResponse
20, // 70: topfans.user.UserSocialService.GetFanProfile:output_type -> topfans.user.GetFanProfileResponse
22, // 71: topfans.user.UserSocialService.UpdateFanProfileSocial:output_type -> topfans.user.UpdateFanProfileSocialResponse
24, // 72: topfans.user.UserSocialService.UpdateCrystalBalance:output_type -> topfans.user.UpdateCrystalBalanceResponse
26, // 73: topfans.user.UserSocialService.UpdateAssetsCount:output_type -> topfans.user.UpdateAssetsCountResponse
28, // 74: topfans.user.UserSocialService.GetCurrentUser:output_type -> topfans.user.GetCurrentUserResponse
30, // 75: topfans.user.UserSocialService.GetMyProfile:output_type -> topfans.user.GetMyProfileResponse
32, // 76: topfans.user.UserSocialService.UpdateNickname:output_type -> topfans.user.UpdateNicknameResponse
34, // 77: topfans.user.UserSocialService.UpdatePassword:output_type -> topfans.user.UpdatePasswordResponse
36, // 78: topfans.user.UserSocialService.UpdateAvatar:output_type -> topfans.user.UpdateAvatarResponse
38, // 79: topfans.user.UserSocialService.GetFanIdentities:output_type -> topfans.user.GetFanIdentitiesResponse
41, // 80: topfans.user.UserSocialService.GetMyFanIdentities:output_type -> topfans.user.GetMyFanIdentitiesResponse
43, // 81: topfans.user.UserSocialService.AddIdentity:output_type -> topfans.user.AddIdentityResponse
45, // 82: topfans.user.UserSocialService.SwitchIdentity:output_type -> topfans.user.SwitchIdentityResponse
62, // [62:83] is the sub-list for method output_type
41, // [41:62] is the sub-list for method input_type
41, // [41:41] is the sub-list for extension type_name
41, // [41:41] is the sub-list for extension extendee
0, // [0:41] is the sub-list for field type_name
48, // 16: topfans.user.UpdateFanProfileSocialResponse.base:type_name -> topfans.common.BaseResponse
48, // 17: topfans.user.UpdateCrystalBalanceResponse.base:type_name -> topfans.common.BaseResponse
48, // 18: topfans.user.UpdateAssetsCountResponse.base:type_name -> topfans.common.BaseResponse
48, // 19: topfans.user.AddExperienceResponse.base:type_name -> topfans.common.BaseResponse
48, // 20: topfans.user.GetCurrentUserResponse.base:type_name -> topfans.common.BaseResponse
0, // 21: topfans.user.GetCurrentUserResponse.user:type_name -> topfans.user.User
1, // 22: topfans.user.GetCurrentUserResponse.fan_profile:type_name -> topfans.user.FanProfile
1, // 23: topfans.user.GetCurrentUserResponse.fan_profiles:type_name -> topfans.user.FanProfile
48, // 24: topfans.user.GetMyProfileResponse.base:type_name -> topfans.common.BaseResponse
0, // 25: topfans.user.GetMyProfileResponse.user:type_name -> topfans.user.User
1, // 26: topfans.user.GetMyProfileResponse.fan_profile:type_name -> topfans.user.FanProfile
1, // 27: topfans.user.GetMyProfileResponse.fan_profiles:type_name -> topfans.user.FanProfile
48, // 28: topfans.user.UpdateNicknameResponse.base:type_name -> topfans.common.BaseResponse
1, // 29: topfans.user.UpdateNicknameResponse.fan_profile:type_name -> topfans.user.FanProfile
48, // 30: topfans.user.UpdatePasswordResponse.base:type_name -> topfans.common.BaseResponse
48, // 31: topfans.user.UpdateAvatarResponse.base:type_name -> topfans.common.BaseResponse
48, // 32: topfans.user.GetFanIdentitiesResponse.base:type_name -> topfans.common.BaseResponse
2, // 33: topfans.user.GetFanIdentitiesResponse.stars:type_name -> topfans.user.Star
1, // 34: topfans.user.MyFanIdentityItem.fan_profile:type_name -> topfans.user.FanProfile
2, // 35: topfans.user.MyFanIdentityItem.star:type_name -> topfans.user.Star
48, // 36: topfans.user.GetMyFanIdentitiesResponse.base:type_name -> topfans.common.BaseResponse
42, // 37: topfans.user.GetMyFanIdentitiesResponse.items:type_name -> topfans.user.MyFanIdentityItem
48, // 38: topfans.user.AddIdentityResponse.base:type_name -> topfans.common.BaseResponse
1, // 39: topfans.user.AddIdentityResponse.fan_profile:type_name -> topfans.user.FanProfile
48, // 40: topfans.user.SwitchIdentityResponse.base:type_name -> topfans.common.BaseResponse
1, // 41: topfans.user.SwitchIdentityResponse.fan_profile:type_name -> topfans.user.FanProfile
3, // 42: topfans.user.UserSocialService.Register:input_type -> topfans.user.RegisterRequest
5, // 43: topfans.user.UserSocialService.Login:input_type -> topfans.user.LoginRequest
7, // 44: topfans.user.UserSocialService.RefreshToken:input_type -> topfans.user.RefreshTokenRequest
9, // 45: topfans.user.UserSocialService.ValidateToken:input_type -> topfans.user.ValidateTokenRequest
11, // 46: topfans.user.UserSocialService.Logout:input_type -> topfans.user.LogoutRequest
13, // 47: topfans.user.UserSocialService.CheckNickname:input_type -> topfans.user.CheckNicknameRequest
15, // 48: topfans.user.UserSocialService.CheckMobile:input_type -> topfans.user.CheckMobileRequest
17, // 49: topfans.user.UserSocialService.GetUser:input_type -> topfans.user.GetUserRequest
19, // 50: topfans.user.UserSocialService.GetFanProfile:input_type -> topfans.user.GetFanProfileRequest
21, // 51: topfans.user.UserSocialService.UpdateFanProfileSocial:input_type -> topfans.user.UpdateFanProfileSocialRequest
23, // 52: topfans.user.UserSocialService.UpdateCrystalBalance:input_type -> topfans.user.UpdateCrystalBalanceRequest
25, // 53: topfans.user.UserSocialService.UpdateAssetsCount:input_type -> topfans.user.UpdateAssetsCountRequest
27, // 54: topfans.user.UserSocialService.AddExperience:input_type -> topfans.user.AddExperienceRequest
29, // 55: topfans.user.UserSocialService.GetCurrentUser:input_type -> topfans.user.GetCurrentUserRequest
31, // 56: topfans.user.UserSocialService.GetMyProfile:input_type -> topfans.user.GetMyProfileRequest
33, // 57: topfans.user.UserSocialService.UpdateNickname:input_type -> topfans.user.UpdateNicknameRequest
35, // 58: topfans.user.UserSocialService.UpdatePassword:input_type -> topfans.user.UpdatePasswordRequest
37, // 59: topfans.user.UserSocialService.UpdateAvatar:input_type -> topfans.user.UpdateAvatarRequest
39, // 60: topfans.user.UserSocialService.GetFanIdentities:input_type -> topfans.user.GetFanIdentitiesRequest
41, // 61: topfans.user.UserSocialService.GetMyFanIdentities:input_type -> topfans.user.GetMyFanIdentitiesRequest
44, // 62: topfans.user.UserSocialService.AddIdentity:input_type -> topfans.user.AddIdentityRequest
46, // 63: topfans.user.UserSocialService.SwitchIdentity:input_type -> topfans.user.SwitchIdentityRequest
4, // 64: topfans.user.UserSocialService.Register:output_type -> topfans.user.RegisterResponse
6, // 65: topfans.user.UserSocialService.Login:output_type -> topfans.user.LoginResponse
8, // 66: topfans.user.UserSocialService.RefreshToken:output_type -> topfans.user.RefreshTokenResponse
10, // 67: topfans.user.UserSocialService.ValidateToken:output_type -> topfans.user.ValidateTokenResponse
12, // 68: topfans.user.UserSocialService.Logout:output_type -> topfans.user.LogoutResponse
14, // 69: topfans.user.UserSocialService.CheckNickname:output_type -> topfans.user.CheckNicknameResponse
16, // 70: topfans.user.UserSocialService.CheckMobile:output_type -> topfans.user.CheckMobileResponse
18, // 71: topfans.user.UserSocialService.GetUser:output_type -> topfans.user.GetUserResponse
20, // 72: topfans.user.UserSocialService.GetFanProfile:output_type -> topfans.user.GetFanProfileResponse
22, // 73: topfans.user.UserSocialService.UpdateFanProfileSocial:output_type -> topfans.user.UpdateFanProfileSocialResponse
24, // 74: topfans.user.UserSocialService.UpdateCrystalBalance:output_type -> topfans.user.UpdateCrystalBalanceResponse
26, // 75: topfans.user.UserSocialService.UpdateAssetsCount:output_type -> topfans.user.UpdateAssetsCountResponse
28, // 76: topfans.user.UserSocialService.AddExperience:output_type -> topfans.user.AddExperienceResponse
30, // 77: topfans.user.UserSocialService.GetCurrentUser:output_type -> topfans.user.GetCurrentUserResponse
32, // 78: topfans.user.UserSocialService.GetMyProfile:output_type -> topfans.user.GetMyProfileResponse
34, // 79: topfans.user.UserSocialService.UpdateNickname:output_type -> topfans.user.UpdateNicknameResponse
36, // 80: topfans.user.UserSocialService.UpdatePassword:output_type -> topfans.user.UpdatePasswordResponse
38, // 81: topfans.user.UserSocialService.UpdateAvatar:output_type -> topfans.user.UpdateAvatarResponse
40, // 82: topfans.user.UserSocialService.GetFanIdentities:output_type -> topfans.user.GetFanIdentitiesResponse
43, // 83: topfans.user.UserSocialService.GetMyFanIdentities:output_type -> topfans.user.GetMyFanIdentitiesResponse
45, // 84: topfans.user.UserSocialService.AddIdentity:output_type -> topfans.user.AddIdentityResponse
47, // 85: topfans.user.UserSocialService.SwitchIdentity:output_type -> topfans.user.SwitchIdentityResponse
64, // [64:86] is the sub-list for method output_type
42, // [42:64] is the sub-list for method input_type
42, // [42:42] is the sub-list for extension type_name
42, // [42:42] is the sub-list for extension extendee
0, // [0:42] is the sub-list for field type_name
}
func init() { file_user_proto_init() }
@ -3090,7 +3217,7 @@ func file_user_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_proto_rawDesc), len(file_user_proto_rawDesc)),
NumEnums: 0,
NumMessages: 46,
NumMessages: 48,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-triple. DO NOT EDIT.
//
// Source: proto/user.proto
// Source: user.proto
package user
import (
@ -60,6 +60,8 @@ const (
UserSocialServiceUpdateCrystalBalanceProcedure = "/topfans.user.UserSocialService/UpdateCrystalBalance"
// UserSocialServiceUpdateAssetsCountProcedure is the fully-qualified name of the UserSocialService's UpdateAssetsCount RPC.
UserSocialServiceUpdateAssetsCountProcedure = "/topfans.user.UserSocialService/UpdateAssetsCount"
// UserSocialServiceAddExperienceProcedure is the fully-qualified name of the UserSocialService's AddExperience RPC.
UserSocialServiceAddExperienceProcedure = "/topfans.user.UserSocialService/AddExperience"
// UserSocialServiceGetCurrentUserProcedure is the fully-qualified name of the UserSocialService's GetCurrentUser RPC.
UserSocialServiceGetCurrentUserProcedure = "/topfans.user.UserSocialService/GetCurrentUser"
// UserSocialServiceGetMyProfileProcedure is the fully-qualified name of the UserSocialService's GetMyProfile RPC.
@ -98,6 +100,7 @@ type UserSocialService interface {
UpdateFanProfileSocial(ctx context.Context, req *UpdateFanProfileSocialRequest, opts ...client.CallOption) (*UpdateFanProfileSocialResponse, error)
UpdateCrystalBalance(ctx context.Context, req *UpdateCrystalBalanceRequest, opts ...client.CallOption) (*UpdateCrystalBalanceResponse, error)
UpdateAssetsCount(ctx context.Context, req *UpdateAssetsCountRequest, opts ...client.CallOption) (*UpdateAssetsCountResponse, error)
AddExperience(ctx context.Context, req *AddExperienceRequest, opts ...client.CallOption) (*AddExperienceResponse, error)
GetCurrentUser(ctx context.Context, req *GetCurrentUserRequest, opts ...client.CallOption) (*GetCurrentUserResponse, error)
GetMyProfile(ctx context.Context, req *GetMyProfileRequest, opts ...client.CallOption) (*GetMyProfileResponse, error)
UpdateNickname(ctx context.Context, req *UpdateNicknameRequest, opts ...client.CallOption) (*UpdateNicknameResponse, error)
@ -225,6 +228,14 @@ func (c *UserSocialServiceImpl) UpdateAssetsCount(ctx context.Context, req *Upda
return resp, nil
}
func (c *UserSocialServiceImpl) AddExperience(ctx context.Context, req *AddExperienceRequest, opts ...client.CallOption) (*AddExperienceResponse, error) {
resp := new(AddExperienceResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "AddExperience", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *UserSocialServiceImpl) GetCurrentUser(ctx context.Context, req *GetCurrentUserRequest, opts ...client.CallOption) (*GetCurrentUserResponse, error) {
resp := new(GetCurrentUserResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetCurrentUser", opts...); err != nil {
@ -299,7 +310,7 @@ func (c *UserSocialServiceImpl) SwitchIdentity(ctx context.Context, req *SwitchI
var UserSocialService_ClientInfo = client.ClientInfo{
InterfaceName: "topfans.user.UserSocialService",
MethodNames: []string{"Register", "Login", "RefreshToken", "ValidateToken", "Logout", "CheckNickname", "CheckMobile", "GetUser", "GetFanProfile", "UpdateFanProfileSocial", "UpdateCrystalBalance", "UpdateAssetsCount", "GetCurrentUser", "GetMyProfile", "UpdateNickname", "UpdatePassword", "UpdateAvatar", "GetFanIdentities", "GetMyFanIdentities", "AddIdentity", "SwitchIdentity"},
MethodNames: []string{"Register", "Login", "RefreshToken", "ValidateToken", "Logout", "CheckNickname", "CheckMobile", "GetUser", "GetFanProfile", "UpdateFanProfileSocial", "UpdateCrystalBalance", "UpdateAssetsCount", "AddExperience", "GetCurrentUser", "GetMyProfile", "UpdateNickname", "UpdatePassword", "UpdateAvatar", "GetFanIdentities", "GetMyFanIdentities", "AddIdentity", "SwitchIdentity"},
ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) {
dubboCli := dubboCliRaw.(*UserSocialServiceImpl)
dubboCli.conn = conn
@ -320,6 +331,7 @@ type UserSocialServiceHandler interface {
UpdateFanProfileSocial(context.Context, *UpdateFanProfileSocialRequest) (*UpdateFanProfileSocialResponse, error)
UpdateCrystalBalance(context.Context, *UpdateCrystalBalanceRequest) (*UpdateCrystalBalanceResponse, error)
UpdateAssetsCount(context.Context, *UpdateAssetsCountRequest) (*UpdateAssetsCountResponse, error)
AddExperience(context.Context, *AddExperienceRequest) (*AddExperienceResponse, error)
GetCurrentUser(context.Context, *GetCurrentUserRequest) (*GetCurrentUserResponse, error)
GetMyProfile(context.Context, *GetMyProfileRequest) (*GetMyProfileResponse, error)
UpdateNickname(context.Context, *UpdateNicknameRequest) (*UpdateNicknameResponse, error)
@ -523,6 +535,21 @@ var UserSocialService_ServiceInfo = server.ServiceInfo{
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "AddExperience",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(AddExperienceRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*AddExperienceRequest)
res, err := handler.(UserSocialServiceHandler).AddExperience(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{
Name: "GetCurrentUser",
Type: constant.CallUnary,

View File

@ -51,6 +51,8 @@ message ClaimDailyTaskRequest {
message ClaimDailyTaskResponse {
topfans.common.BaseResponse base = 1;
bool success = 2;
int64 crystal_balance = 3;
int64 experience = 4;
}
message ClaimAllDailyTasksRequest {
@ -60,6 +62,9 @@ message ClaimAllDailyTasksRequest {
message ClaimAllDailyTasksResponse {
topfans.common.BaseResponse base = 1;
int32 claimed_count = 2;
int64 crystal_balance = 3;
int64 experience = 4;
repeated string claimed_task_keys = 5;
}
// ==================== ====================

View File

@ -2,7 +2,9 @@ package client
import (
"context"
"fmt"
"github.com/topfans/backend/pkg/logger"
pbCommon "github.com/topfans/backend/pkg/proto/common"
pbUser "github.com/topfans/backend/pkg/proto/user"
"go.uber.org/zap"
)
@ -10,6 +12,7 @@ import (
type UserServiceClient interface {
UpdateCrystalBalance(ctx context.Context, userID, starID int64, delta int64) (int64, error)
AddExperience(ctx context.Context, userID, starID int64, delta int64) (int64, error)
GetFanProfile(ctx context.Context, userID, starID int64) (*pbUser.FanProfile, error)
}
type userServiceClient struct {
@ -30,9 +33,9 @@ func (c *userServiceClient) UpdateCrystalBalance(ctx context.Context, userID, st
logger.Logger.Error("UserService.UpdateCrystalBalance failed", zap.Error(err))
return 0, err
}
if resp.Base.Code != 0 {
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
logger.Logger.Warn("UpdateCrystalBalance non-zero code", zap.Int32("code", int32(resp.Base.Code)))
return 0, err
return 0, fmt.Errorf("UpdateCrystalBalance failed with code: %d", resp.Base.Code)
}
return resp.NewBalance, nil
}
@ -47,9 +50,27 @@ func (c *userServiceClient) AddExperience(ctx context.Context, userID, starID in
logger.Logger.Error("UserService.AddExperience failed", zap.Error(err))
return 0, err
}
if resp.Base.Code != 0 {
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
logger.Logger.Warn("AddExperience non-zero code", zap.Int32("code", int32(resp.Base.Code)))
return 0, err
return 0, fmt.Errorf("AddExperience failed with code: %d", resp.Base.Code)
}
return resp.NewExperience, nil
}
func (c *userServiceClient) GetFanProfile(ctx context.Context, userID, starID int64) (*pbUser.FanProfile, error) {
logger.Logger.Debug("Calling UserService.GetFanProfile",
zap.Int64("user_id", userID), zap.Int64("star_id", starID))
resp, err := c.client.GetFanProfile(ctx, &pbUser.GetFanProfileRequest{
UserId: userID,
StarId: starID,
})
if err != nil {
logger.Logger.Error("UserService.GetFanProfile failed", zap.Error(err))
return nil, err
}
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
logger.Logger.Warn("GetFanProfile non-zero code", zap.Int32("code", int32(resp.Base.Code)))
return nil, fmt.Errorf("GetFanProfile failed with code: %d", resp.Base.Code)
}
return resp.Profile, nil
}

View File

@ -14,6 +14,7 @@ import (
"github.com/topfans/backend/pkg/database"
"github.com/topfans/backend/pkg/logger"
pb "github.com/topfans/backend/pkg/proto/task"
pbUser "github.com/topfans/backend/pkg/proto/user"
"github.com/topfans/backend/services/taskService/client"
"github.com/topfans/backend/services/taskService/config"
@ -24,11 +25,9 @@ import (
"github.com/topfans/backend/services/taskService/worker"
)
var port = flag.Int("port", 20005, "Dubbo service port")
var port = flag.Int("port", 20006, "Dubbo service port")
func main() {
flag.Parse()
// 1. Init logger必须最前
env := os.Getenv("ENV")
if env == "" {
@ -106,7 +105,7 @@ func main() {
internalProvider := provider.NewTaskInternalProvider(onboardingSvc, revenueSvc)
logger.Logger.Info("Providers initialized")
// 9. Create Dubbo server on port 20005
// 9. Create Dubbo server on port 20006
srv, err := server.NewServer(
server.WithServerProtocol(
protocol.WithPort(*port),
@ -117,13 +116,23 @@ func main() {
logger.Logger.Fatal(fmt.Sprintf("Failed to create server: %v", err))
}
// 注意:这里需要 TaskMobileService 和 TaskInternalService 的 RegisterHandler
// 这些会在 proto 编译后生成。在 proto 编译之前,这里会报编译错误。
// Task 15 完成 proto 编译后,需要将下面的注释替换为实际的注册代码。
// 注册 Dubbo 服务
if err := pb.RegisterTaskMobileServiceHandler(srv, mobileProvider); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to register TaskMobileService: %v", err))
}
if err := pb.RegisterTaskInternalServiceHandler(srv, internalProvider); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to register TaskInternalService: %v", err))
}
logger.Logger.Info(fmt.Sprintf("taskService configured on port %d, awaiting proto registration", *port))
// 10. Start server (non-blocking)
go func() {
if err := srv.Serve(); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to serve: %v", err))
}
}()
logger.Logger.Info(fmt.Sprintf("taskService listening on port %d", *port))
// 10. Graceful shutdown
// Graceful shutdown
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

View File

@ -47,17 +47,23 @@ type UserOnboardingProgress struct {
func (UserOnboardingProgress) TableName() string { return "user_onboarding_progress" }
// UserOnboardingStatus 引导流程状态表per-user,非 per-star
// UserOnboardingStatus 引导流程状态表per-user per-star
type UserOnboardingStatus struct {
UserID int64 `gorm:"primaryKey;column:user_id"`
CurrentStage int `gorm:"column:current_stage;default:0"`
Status string `gorm:"column:status;size:20;default:pending"`
IsFirstLoginBonusClaimed bool `gorm:"column:is_first_login_bonus_claimed;default:false"` // 废弃字段
HasFriendDisplayBonus bool `gorm:"column:has_friend_display_bonus;default:false"` // 废弃字段
CompletedAt *int64 `gorm:"column:completed_at"`
ClaimedAt *int64 `gorm:"column:claimed_at"`
ID int64 `gorm:"primaryKey;column:id;autoIncrement"`
UserID int64 `gorm:"column:user_id;not null;uniqueIndex:uk_user_star_onboarding"`
StarID int64 `gorm:"column:star_id;not null;uniqueIndex:uk_user_star_onboarding"`
IsOnboardingCompleted bool `gorm:"column:is_onboarding_completed;default:false"`
IsOnboardingClaimed bool `gorm:"column:is_onboarding_claimed;default:false"`
HasFriendDisplayBonus bool `gorm:"column:has_friend_display_bonus;default:false"`
OnboardingCompletedAt *int64 `gorm:"column:onboarding_completed_at"`
OnboardingClaimedAt *int64 `gorm:"column:onboarding_claimed_at"`
CreatedAt int64 `gorm:"column:created_at"`
UpdatedAt int64 `gorm:"column:updated_at"`
CurrentStage int64 `gorm:"column:current_stage;default:0"`
Status string `gorm:"column:status;size:20;default:pending"`
IsFirstLoginBonusClaimed bool `gorm:"column:is_first_login_bonus_claimed;default:false"` // 废弃字段
CompletedAt *int64 `gorm:"column:completed_at"` // 废弃字段
ClaimedAt *int64 `gorm:"column:claimed_at"` // 废弃字段
}
func (UserOnboardingStatus) TableName() string { return "user_onboarding_status" }
@ -68,7 +74,7 @@ type OnboardingStageConfig struct {
Stage int `gorm:"column:stage;not null;uniqueIndex"`
Name string `gorm:"column:name;size:100;not null"`
Description string `gorm:"column:description;type:text"`
RequiredTaskKeys []string `gorm:"column:required_task_keys;text[]"` // PostgreSQL 数组
RequiredTaskKeys []string `gorm:"column:required_task_keys;type:text;serializer:json"` // 存储为 JSON 字符串
CrystalReward int64 `gorm:"column:crystal_reward;default:0"`
ExpReward int64 `gorm:"column:exp_reward;default:0"`
SortOrder int `gorm:"column:sort_order;default:0"`

View File

@ -5,6 +5,7 @@ import (
"fmt"
"strconv"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"github.com/topfans/backend/pkg/logger"
pb "github.com/topfans/backend/pkg/proto/task"
"github.com/topfans/backend/services/taskService/service"
@ -33,11 +34,10 @@ func NewTaskMobileProvider(
// extractUserInfoFromDubboAttachments 从 Dubbo attachments 提取用户信息
func extractUserInfoFromDubboAttachments(ctx context.Context) (int64, int64, error) {
// Dubbo-go 使用 constant.AttachmentKey 获取 attachments
// 但这里使用通用的 context.Value 方式
if attachments := ctx.Value("attachments"); attachments != nil {
if attachments := ctx.Value(constant.AttachmentKey); attachments != nil {
if attMap, ok := attachments.(map[string]interface{}); ok {
userID, starID := extractUserInfoFromMap(attMap)
if userID > 0 && starID > 0 {
if userID > 0 {
return userID, starID, nil
}
}
@ -59,6 +59,12 @@ func extractUserInfoFromMap(attMap map[string]interface{}) (int64, int64) {
if parsed, err := strconv.ParseInt(v, 10, 64); err == nil {
userID = parsed
}
case []string:
if len(v) > 0 {
if parsed, err := strconv.ParseInt(v[0], 10, 64); err == nil {
userID = parsed
}
}
}
}
@ -72,6 +78,12 @@ func extractUserInfoFromMap(attMap map[string]interface{}) (int64, int64) {
if parsed, err := strconv.ParseInt(v, 10, 64); err == nil {
starID = parsed
}
case []string:
if len(v) > 0 {
if parsed, err := strconv.ParseInt(v[0], 10, 64); err == nil {
starID = parsed
}
}
}
}
@ -155,20 +167,21 @@ func (p *TaskMobileProvider) CompleteGuide(ctx context.Context, req *pb.Complete
}
func (p *TaskMobileProvider) GetOnboardingStatus(ctx context.Context, req *pb.GetOnboardingStatusRequest) (*pb.GetOnboardingStatusResponse, error) {
userID, _, err := extractUserInfoFromDubboAttachments(ctx)
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
if err != nil {
logger.Logger.Error("GetOnboardingStatus: failed to extract user", zap.Error(err))
return &pb.GetOnboardingStatusResponse{}, nil
}
logger.Logger.Debug("GetOnboardingStatus",
zap.Int64("user_id", userID))
zap.Int64("user_id", userID),
zap.Int64("star_id", starID))
return p.onboardingSvc.GetOnboardingStatus(ctx, userID)
return p.onboardingSvc.GetOnboardingStatus(ctx, userID, starID)
}
func (p *TaskMobileProvider) AdvanceStage(ctx context.Context, req *pb.AdvanceStageRequest) (*pb.AdvanceStageResponse, error) {
userID, _, err := extractUserInfoFromDubboAttachments(ctx)
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
if err != nil {
logger.Logger.Error("AdvanceStage: failed to extract user", zap.Error(err))
return &pb.AdvanceStageResponse{}, nil
@ -176,13 +189,14 @@ func (p *TaskMobileProvider) AdvanceStage(ctx context.Context, req *pb.AdvanceSt
logger.Logger.Debug("AdvanceStage",
zap.Int64("user_id", userID),
zap.Int64("star_id", starID),
zap.Int32("target_stage", req.TargetStage))
return p.onboardingSvc.AdvanceStage(ctx, userID, req.TargetStage)
return p.onboardingSvc.AdvanceStage(ctx, userID, starID, req.TargetStage)
}
func (p *TaskMobileProvider) ClaimOnboardingReward(ctx context.Context, req *pb.ClaimOnboardingRewardRequest) (*pb.ClaimOnboardingRewardResponse, error) {
userID, _, err := extractUserInfoFromDubboAttachments(ctx)
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
if err != nil {
logger.Logger.Error("ClaimOnboardingReward: failed to extract user", zap.Error(err))
return &pb.ClaimOnboardingRewardResponse{Success: false}, nil
@ -190,9 +204,10 @@ func (p *TaskMobileProvider) ClaimOnboardingReward(ctx context.Context, req *pb.
logger.Logger.Debug("ClaimOnboardingReward",
zap.Int64("user_id", userID),
zap.Int64("star_id", starID),
zap.Int32("stage", req.Stage))
return p.onboardingSvc.ClaimOnboardingReward(ctx, userID, req.Stage)
return p.onboardingSvc.ClaimOnboardingReward(ctx, userID, starID, req.Stage)
}
func (p *TaskMobileProvider) GetExhibitionRevenue(ctx context.Context, req *pb.GetExhibitionRevenueRequest) (*pb.GetExhibitionRevenueResponse, error) {

View File

@ -16,6 +16,8 @@ type DailyTaskRepository interface {
GetOrCreateDailyProgress(userID, starID int64, taskKey string, def *model.TaskDefinition) (*model.UserDailyTaskProgress, error)
// ListDailyTasksByUser 获取用户的所有每日任务进度
ListDailyTasksByUser(userID, starID int64) ([]*model.UserDailyTaskProgress, error)
// ListCompletedDailyTasks 获取用户已完成但未领取的每日任务进度
ListCompletedDailyTasks(userID, starID int64) ([]*model.UserDailyTaskProgress, error)
// ListActiveDailyTaskDefinitions 获取所有活跃的每日任务定义包括star特定和全局默认
ListActiveDailyTaskDefinitions(starID int64) ([]*model.TaskDefinition, error)
// UpdateDailyProgress 更新每日任务进度
@ -96,6 +98,15 @@ func (r *dailyTaskRepository) ListDailyTasksByUser(userID, starID int64) ([]*mod
return progressList, err
}
// ListCompletedDailyTasks 获取用户已完成但未领取的每日任务进度
func (r *dailyTaskRepository) ListCompletedDailyTasks(userID, starID int64) ([]*model.UserDailyTaskProgress, error) {
var progressList []*model.UserDailyTaskProgress
err := r.db.Where("user_id = ? AND star_id = ? AND status = ?", userID, starID, "completed").
Order("id ASC").
Find(&progressList).Error
return progressList, err
}
// ListActiveDailyTaskDefinitions 获取所有活跃的每日任务定义包括star特定和全局默认
func (r *dailyTaskRepository) ListActiveDailyTaskDefinitions(starID int64) ([]*model.TaskDefinition, error) {
var definitions []*model.TaskDefinition

View File

@ -1,6 +1,9 @@
package repository
import (
"errors"
"time"
"github.com/topfans/backend/pkg/logger"
"github.com/topfans/backend/services/taskService/model"
"go.uber.org/zap"
@ -8,14 +11,15 @@ import (
)
type OnboardingRepository interface {
GetOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error)
GetOrCreateOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error)
GetOnboardingStatus(userID int64, starID int64) (*model.UserOnboardingStatus, error)
GetOrCreateOnboardingStatus(userID int64, starID int64) (*model.UserOnboardingStatus, error)
UpdateOnboardingStatus(status *model.UserOnboardingStatus) error
UpdateOnboardingProgress(progress *model.UserOnboardingProgress) error
GetUserOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error)
GetOrCreateOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error)
ListActiveStageConfigs() ([]*model.OnboardingStageConfig, error)
ListUserOnboardingProgressByUser(userID int64) ([]*model.UserOnboardingProgress, error)
GetStageConfig(stage int) (*model.OnboardingStageConfig, error)
GetStageConfig(stage int64) (*model.OnboardingStageConfig, error)
}
type onboardingRepository struct {
@ -26,34 +30,43 @@ func NewOnboardingRepository(db *gorm.DB) OnboardingRepository {
return &onboardingRepository{db: db}
}
func (r *onboardingRepository) GetOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error) {
func (r *onboardingRepository) GetOnboardingStatus(userID int64, starID int64) (*model.UserOnboardingStatus, error) {
var status model.UserOnboardingStatus
err := r.db.Where("user_id = ?", userID).First(&status).Error
err := r.db.Where("user_id = ? AND star_id = ?", userID, starID).First(&status).Error
if err != nil {
return nil, err
}
return &status, nil
}
func (r *onboardingRepository) GetOrCreateOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error) {
func (r *onboardingRepository) GetOrCreateOnboardingStatus(userID int64, starID int64) (*model.UserOnboardingStatus, error) {
var status model.UserOnboardingStatus
now := gorm.NowFunc().Unix()
err := r.db.Where("user_id = ?", userID).FirstOrCreate(&status, &model.UserOnboardingStatus{
UserID: userID,
err := r.db.Where("user_id = ? AND star_id = ?", userID, starID).First(&status).Error
if err == nil {
return &status, nil
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
logger.Logger.Error("Failed to GetOrCreateOnboardingStatus", zap.Int64("user_id", userID), zap.Int64("star_id", starID), zap.Error(err))
return nil, err
}
now := time.Now().Unix()
status = model.UserOnboardingStatus{
UserID: userID,
StarID: starID,
CurrentStage: 0,
Status: "pending",
CreatedAt: now,
UpdatedAt: now,
}).Error
if err != nil {
logger.Logger.Error("Failed to GetOrCreateOnboardingStatus", zap.Int64("user_id", userID), zap.Error(err))
Status: "pending",
CreatedAt: now,
UpdatedAt: now,
}
if err := r.db.Create(&status).Error; err != nil {
logger.Logger.Error("Failed to Create OnboardingStatus", zap.Int64("user_id", userID), zap.Int64("star_id", starID), zap.Error(err))
return nil, err
}
return &status, nil
}
func (r *onboardingRepository) UpdateOnboardingStatus(status *model.UserOnboardingStatus) error {
status.UpdatedAt = gorm.NowFunc().Unix()
status.UpdatedAt = time.Now().Unix()
if err := r.db.Save(status).Error; err != nil {
logger.Logger.Error("Failed to UpdateOnboardingStatus", zap.Int64("user_id", status.UserID), zap.Error(err))
return err
@ -61,6 +74,15 @@ func (r *onboardingRepository) UpdateOnboardingStatus(status *model.UserOnboardi
return nil
}
func (r *onboardingRepository) UpdateOnboardingProgress(progress *model.UserOnboardingProgress) error {
progress.UpdatedAt = time.Now().Unix()
if err := r.db.Save(progress).Error; err != nil {
logger.Logger.Error("Failed to UpdateOnboardingProgress", zap.Int64("user_id", progress.UserID), zap.String("task_key", progress.TaskKey), zap.Error(err))
return err
}
return nil
}
func (r *onboardingRepository) GetUserOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error) {
var progress model.UserOnboardingProgress
err := r.db.Where("user_id = ? AND task_key = ?", userID, taskKey).First(&progress).Error
@ -72,16 +94,24 @@ func (r *onboardingRepository) GetUserOnboardingProgress(userID int64, taskKey s
func (r *onboardingRepository) GetOrCreateOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error) {
var progress model.UserOnboardingProgress
now := gorm.NowFunc().Unix()
err := r.db.Where("user_id = ? AND task_key = ?", userID, taskKey).FirstOrCreate(&progress, &model.UserOnboardingProgress{
err := r.db.Where("user_id = ? AND task_key = ?", userID, taskKey).First(&progress).Error
if err == nil {
return &progress, nil
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
logger.Logger.Error("Failed to GetOrCreateOnboardingProgress", zap.Int64("user_id", userID), zap.String("task_key", taskKey), zap.Error(err))
return nil, err
}
now := time.Now().Unix()
progress = model.UserOnboardingProgress{
UserID: userID,
TaskKey: taskKey,
Status: "pending",
CreatedAt: now,
UpdatedAt: now,
}).Error
if err != nil {
logger.Logger.Error("Failed to GetOrCreateOnboardingProgress", zap.Int64("user_id", userID), zap.String("task_key", taskKey), zap.Error(err))
}
if err := r.db.Create(&progress).Error; err != nil {
logger.Logger.Error("Failed to Create OnboardingProgress", zap.Int64("user_id", userID), zap.String("task_key", taskKey), zap.Error(err))
return nil, err
}
return &progress, nil
@ -107,7 +137,7 @@ func (r *onboardingRepository) ListUserOnboardingProgressByUser(userID int64) ([
return progressList, nil
}
func (r *onboardingRepository) GetStageConfig(stage int) (*model.OnboardingStageConfig, error) {
func (r *onboardingRepository) GetStageConfig(stage int64) (*model.OnboardingStageConfig, error) {
var config model.OnboardingStageConfig
err := r.db.Where("stage = ? AND is_active = ?", stage, true).First(&config).Error
if err != nil {

View File

@ -1,6 +1,8 @@
package repository
import (
"time"
"github.com/topfans/backend/pkg/logger"
"github.com/topfans/backend/services/taskService/model"
"go.uber.org/zap"
@ -25,7 +27,7 @@ func NewRevenueRepository(db *gorm.DB) RevenueRepository {
}
func (r *revenueRepository) CreateRevenueRecord(record *model.ExhibitionRevenueRecord) (*model.ExhibitionRevenueRecord, error) {
record.CreatedAt = gorm.NowFunc().Unix()
record.CreatedAt = time.Now().Unix()
if err := r.db.Create(record).Error; err != nil {
logger.Logger.Error("Failed to CreateRevenueRecord", zap.Int64("user_id", record.UserID), zap.Error(err))
return nil, err
@ -66,7 +68,7 @@ func (r *revenueRepository) ListRevenueByUser(userID, starID int64, status strin
func (r *revenueRepository) ClaimRevenueRecord(id int64, userID int64) (bool, error) {
// 乐观锁:只有在 status='claimable' 时才更新
now := gorm.NowFunc().Unix()
now := time.Now().Unix()
result := r.db.Model(&model.ExhibitionRevenueRecord{}).
Where("id = ? AND user_id = ? AND status = ?", id, userID, "claimable").
Updates(map[string]interface{}{

View File

@ -87,9 +87,7 @@ func (w *DailyResetWorker) doResetAndAutoClaim() {
return
}
defer func() {
if err := w.dailyRepo.ReleaseAdvisoryLock(lockID); err != nil {
logger.Logger.Error("DailyResetWorker: failed to release advisory lock", zap.Error(err))
}
w.dailyRepo.ReleaseAdvisoryLock(lockID)
}()
// 1. 重置每日任务

View File

@ -144,3 +144,8 @@ func (p *UnifiedProvider) UpdateCrystalBalance(ctx context.Context, req *pb.Upda
func (p *UnifiedProvider) UpdateAssetsCount(ctx context.Context, req *pb.UpdateAssetsCountRequest) (*pb.UpdateAssetsCountResponse, error) {
return p.userProvider.UpdateAssetsCount(ctx, req)
}
// AddExperience 增加经验值内部RPC调用
func (p *UnifiedProvider) AddExperience(ctx context.Context, req *pb.AddExperienceRequest) (*pb.AddExperienceResponse, error) {
return p.userProvider.AddExperience(ctx, req)
}

View File

@ -851,3 +851,47 @@ func (p *UserProvider) UpdateAssetsCount(ctx context.Context, req *pb.UpdateAsse
return resp, nil
}
// AddExperience 增加经验值内部RPC调用
func (p *UserProvider) AddExperience(ctx context.Context, req *pb.AddExperienceRequest) (*pb.AddExperienceResponse, error) {
logger.Logger.Info("Received AddExperience request",
zap.Int64("user_id", req.UserId),
zap.Int64("star_id", req.StarId),
zap.Int64("delta", req.Delta),
)
// 调用Service层
resp, err := p.userService.AddExperience(req)
if err != nil {
logger.Logger.Error("AddExperience failed",
zap.Int64("user_id", req.UserId),
zap.Int64("star_id", req.StarId),
zap.Int64("delta", req.Delta),
zap.Error(err),
)
// 如果响应为空,构建错误响应
if resp == nil {
resp = &pb.AddExperienceResponse{
Base: &pbCommon.BaseResponse{
Code: appErrors.ToStatusCode(err),
Message: err.Error(),
Timestamp: 0,
},
}
}
return resp, err
}
logger.Logger.Info("AddExperience successful",
zap.Int64("user_id", req.UserId),
zap.Int64("star_id", req.StarId),
zap.Int64("delta", req.Delta),
zap.Int64("new_experience", resp.NewExperience),
)
return resp, nil
}
// UpdateAvatar 更新用户头像

View File

@ -53,6 +53,9 @@ type FanProfileRepository interface {
// UpdateCrystalBalance 更新水晶余额
UpdateCrystalBalance(userID, starID int64, delta int64) (int64, error)
// UpdateExperience 更新经验值
UpdateExperience(userID, starID int64, delta int64) (int64, error)
// UpdateAvatar 更新头像
UpdateAvatar(userID, starID int64, avatarURL string) error
}
@ -384,7 +387,57 @@ func (r *fanProfileRepository) UpdateCrystalBalance(userID, starID int64, delta
return 0, err
}
return newBalance, nil
return newBalance, nil
}
// UpdateExperience 更新经验值
// delta: 变化量,正数表示增加,负数表示减少
// 返回: 更新后的经验值
func (r *fanProfileRepository) UpdateExperience(userID, starID int64, delta int64) (int64, error) {
if userID <= 0 {
return 0, errors.New("user_id must be greater than 0")
}
if starID <= 0 {
return 0, errors.New("star_id must be greater than 0")
}
// 使用事务确保原子性
var newExperience int64
err := r.db.Transaction(func(tx *gorm.DB) error {
// 先查询当前的 experience 值
var profile models.FanProfile
if err := tx.Where("user_id = ? AND star_id = ?", userID, starID).
First(&profile).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return appErrors.ErrFanProfileNotFound
}
return err
}
// 计算新值
newExperience = profile.Experience + delta
// 确保不会小于 0
if newExperience < 0 {
newExperience = 0
}
// 更新 experience 字段
if err := tx.Model(&models.FanProfile{}).
Where("user_id = ? AND star_id = ?", userID, starID).
Update("experience", newExperience).Error; err != nil {
return err
}
return nil
})
if err != nil {
return 0, err
}
return newExperience, nil
}
// UpdateAvatar 更新头像

View File

@ -171,32 +171,31 @@ if def.ExpReward > 0 {
---
## 五、待执行的操作清单
## 五、已完成的修复清单
| # | 操作 | 优先级 | 依赖 |
|---|------|--------|------|
| 1 | 执行 `sh scripts/compile-proto.sh` | P0 | go + protoc 环境 |
| 2 | 添加 `UpdateOnboardingProgress` 到 onboarding_repo | P0 | 无 |
| 3 | 添加 `ListCompletedDailyTasks` 到 daily_task_repo | P0 | 无 |
| 4 | 修复 main.go Dubbo 注册代码 | P0 | #1 |
| 5 | 修复 guide.vue isTaskCompleted | P1 | 无 |
| 6 | 删除 onboarding_service.go 死代码 | P2 | 无 |
| 7 | 修复 ClaimAllDailyTasks 错误处理 | P2 | 无 |
| # | 修复项 | 文件 | 状态 |
|---|--------|------|------|
| 2 | `UpdateOnboardingProgress` 方法 | onboarding_repo.go | ✅ 已完成 |
| 3 | `ListCompletedDailyTasks` 方法 | daily_task_repo.go | ✅ 已完成 |
| 5 | guide.vue isTaskCompleted | guide.vue | ✅ 已完成 |
| 6 | onboarding_service.go 死代码 | service 层重构 | ✅ 已解决(新建服务文件) |
| 7 | ClaimAllDailyTasks 错误处理 | daily_task_service.go | ✅ 已完成 |
| 9 | Service 层创建 | service/*.go | ✅ 已完成 |
| 10 | gorm.NowFunc() 修复 | revenue_repo.go, onboarding_repo.go | ✅ 已完成 |
| 11 | Proto 编译 | pkg/proto/task/*.go | ✅ 已完成 |
| 12 | main.go Dubbo 注册代码 | main.go | ✅ 已完成 |
---
## 六、执行顺序建议
## 六、已完成的操作清单
```
1. 先执行 proto 编译(#1
2. 修复 onboarding_repo + daily_task_repo#2, #3
3. 修复 main.go 注册代码(#4
4. 编译验证go build ./...
5. 修复前端 guide.vue#5
6. 可选优化(#6, #7
所有计划中的任务已完成TaskService 现已可以成功编译。
---
## 七、编译验证
```bash
cd backend && go build ./services/taskService/...
# ✅ BUILD SUCCESS
```

View File

@ -1,17 +1,15 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
//
//
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<template>

View File

@ -80,7 +80,7 @@
</view>
<!-- 任务弹窗 -->
<TaskModal :visible="showTaskModal" @close="closeTaskModal" />
<DailyTasks :visible="showTaskModal" @close="showTaskModal = false" />
<!-- 新手引导列表弹窗 -->
<GuideListModal :visible="showGuideListModal" @start-guide="handleStartGuide"
@ -92,9 +92,10 @@
import { computed, ref, onMounted, onUnmounted } from 'vue';
import { useStore } from 'vuex';
import Avatar from './Avatar.vue';
import TaskModal from './TaskModal.vue';
import DailyTasks from '@/pages/tasks/daily-tasks.vue';
import GuideListModal from '@/components/GuideListModal.vue';
import { getActivityListApi } from '@/utils/api.js';
import { reportEvent } from '@/utils/task-api.js';
// props
const props = defineProps({
@ -193,6 +194,20 @@ onMounted(() => {
uni.$on('avatarUpdated', handleAvatarUpdate);
uni.$on('userInfoUpdated', handleUserInfoUpdate);
uni.$on('balanceUpdated', handleBalanceUpdate);
//
const today = new Date().toISOString().split('T')[0]
const dailyLoginKey = `daily_login_completed_${today}`
// star_id
const starId = uni.getStorageSync('star_id')
if (starId && !uni.getStorageSync(dailyLoginKey)) {
reportEvent('daily_login', starId).then(() => {
//
uni.setStorageSync(dailyLoginKey, true)
}).catch(err => {
console.error('上报登录事件失败:', err)
})
}
});
//
@ -286,7 +301,9 @@ const handleStarActivityClick = async () => {
//
const handleGuideClick = () => {
showGuideListModal.value = true;
uni.navigateTo({
url: '/pages/tasks/guide'
});
};
//

View File

@ -264,6 +264,7 @@ export default {
import NftCard from '../components/NftCard.vue';
import { getMyGalleriesApi, placeAssetToGalleryApi, getMyAssetsApi, removeAssetFromGalleryApi, getUserGalleriesApi, getRandomGalleryApi } from '@/utils/api.js';
import { getAssetCoverRealUrl } from '@/utils/assetImageHelper.js';
import { reportEvent } from '@/utils/task-api.js';
import GuideOverlay from "@/components/GuideOverlay.vue";
const store = useStore();
@ -1258,6 +1259,12 @@ export default {
//
loadGallerySlots();
//
const starId = uni.getStorageSync('star_id') || 1
reportEvent('daily_browse_asset', starId).catch(err => {
console.error('上报预览事件失败:', err)
})
//
countdownTimer = setInterval(() => {
updateCountdowns();

View File

@ -1,84 +1,106 @@
<template>
<view class="daily-tasks-container">
<!-- 顶部导航 -->
<Header :show-back="true" back-icon-color="#e6e6e6" :show-guide-icon="false" :show-task-icon="false" :show-star-activity-icon="false" />
<view v-if="visible" class="modal-wrapper" @touchmove.stop.prevent @click.stop>
<transition name="fade">
<view v-if="visible" class="modal-mask" @touchstart.stop="handleMaskTouchStart" @click.stop>
</view>
</transition>
<!-- 页面标题 -->
<view class="page-title">每日任务</view>
<transition name="scale">
<view v-if="visible" class="modal-container" @click.stop>
<!-- 背景图片 -->
<image class="modal-background" src="/static/background/friend-list-bg.png" mode="aspectFill"></image>
<!-- 加载状态 -->
<view v-if="loading" class="loading-state">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 蒙层 -->
<view class="modal-overlay"></view>
<!-- 错误状态 -->
<view v-else-if="errorMessage" class="error-state">
<text class="error-text">{{ errorMessage }}</text>
<button class="retry-btn" @click="loadTasks">重试</button>
</view>
<!-- 关闭按钮 -->
<view class="close-button" @touchstart.stop="handleCloseTouchStart" @touchend.stop="handleCloseTouchEnd" @click="handleCloseClick">
<text class="close-icon">×</text>
</view>
<!-- 任务列表 -->
<view v-else class="task-list">
<!-- 空状态 -->
<view v-if="tasks.length === 0" class="empty-state">
<text class="empty-text">暂无每日任务</text>
</view>
<!-- 内容区域 -->
<view class="modal-content" @touchstart.stop @touchend.stop @click.stop>
<!-- 标题 -->
<text class="modal-title">每日任务</text>
<!-- 任务项 -->
<view v-for="task in tasks" :key="task.task_key" class="task-item">
<view class="task-info">
<view class="task-name">{{ task.name }}</view>
<view class="task-desc">{{ task.description }}</view>
<view class="task-reward">
<text class="reward-icon">💎</text>
<text class="reward-value">{{ task.crystal_reward }}</text>
<text class="reward-sep">|</text>
<text class="reward-icon"></text>
<text class="reward-value">{{ task.exp_reward }} 经验</text>
</view>
</view>
<!-- 加载状态 -->
<view v-if="loading" class="loading-state">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<view class="task-action">
<!-- 状态标签 -->
<view class="status-badge" :class="getStatusClass(task.status)">
{{ getStatusText(task.status) }}
</view>
<!-- 错误状态 -->
<view v-else-if="errorMessage" class="error-state">
<text class="error-text">{{ errorMessage }}</text>
<button class="retry-btn" @click="loadTasks">重试</button>
</view>
<!-- 领取按钮 -->
<button
v-if="task.can_claim"
class="claim-btn"
:loading="claimingTask === task.task_key"
@click="handleClaim(task)"
>
领取
</button>
</view>
</view>
</view>
<!-- 任务列表 -->
<view v-else class="task-list">
<!-- 空状态 -->
<view v-if="tasks.length === 0" class="empty-state">
<text class="empty-text">暂无每日任务</text>
</view>
<!-- 一键领取按钮 -->
<view v-if="!loading && !errorMessage && hasClaimableTasks" class="claim-all-bar">
<button class="claim-all-btn" :loading="claimingAll" @click="handleClaimAll">
一键领取 ({{ claimableCount }})
</button>
</view>
<!-- 任务项 -->
<view v-for="task in tasks" :key="task.task_key" class="task-item">
<view class="task-info">
<text class="task-name">{{ task.name }}</text>
<text class="task-desc">{{ task.description }}</text>
<view class="task-reward">
<text class="reward-icon">💎</text>
<text class="reward-value">+{{ task.crystal_reward }}</text>
<text class="reward-sep">|</text>
<text class="reward-icon"></text>
<text class="reward-value">+{{ task.exp_reward }}</text>
</view>
</view>
<!-- 下拉刷新 -->
<view v-if="!loading" class="pull-to-refresh" @click="handlePullRefresh">
<text class="refresh-text">{{ refreshing ? '刷新中...' : '下拉刷新' }}</text>
</view>
</view>
<view class="task-action">
<!-- 状态标签 -->
<view v-if="!task.can_claim" class="status-badge" :class="getStatusClass(task.status)">
<text class="status-text">{{ getStatusText(task.status) }}</text>
</view>
<!-- 领取按钮 -->
<button
v-if="task.can_claim"
class="claim-btn"
:loading="claimingTask === task.task_key"
@click="handleClaim(task)"
>
领取
</button>
</view>
</view>
</view>
<!-- 一键领取按钮 -->
<view v-if="!loading && !errorMessage && hasClaimableTasks" class="claim-all-bar">
<button class="claim-all-btn" :loading="claimingAll" @click="handleClaimAll">
一键领取 ({{ claimableCount }})
</button>
</view>
</view>
</view>
</transition>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import Header from '../components/Header.vue'
import { ref, computed, watch } from 'vue'
import { getDailyTasks, claimDailyTask, claimAllDailyTasks } from '@/utils/task-api.js'
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['close', 'updated'])
const loading = ref(true)
const refreshing = ref(false)
const errorMessage = ref('')
const tasks = ref([])
const claimingTask = ref('')
@ -88,266 +110,412 @@ const starId = ref(1)
const hasClaimableTasks = computed(() => tasks.value.some(t => t.can_claim))
const claimableCount = computed(() => tasks.value.filter(t => t.can_claim).length)
// visible
watch(() => props.visible, (newVal) => {
if (newVal) {
loadTasks()
}
}, { immediate: true })
function getStatusClass(status) {
switch (status) {
case 'pending': return 'status-pending'
case 'completed': return 'status-completed'
case 'claimed': return 'status-claimed'
default: return ''
}
switch (status) {
case 'pending': return 'status-pending'
case 'completed': return 'status-completed'
case 'claimed': return 'status-claimed'
default: return ''
}
}
function getStatusText(status) {
switch (status) {
case 'pending': return '进行中'
case 'completed': return '可领取'
case 'claimed': return '已领取'
default: return status
}
switch (status) {
case 'pending': return '进行中'
case 'completed': return '可领取'
case 'claimed': return '已领取'
default: return status
}
}
async function loadTasks() {
try {
loading.value = true
errorMessage.value = ''
try {
loading.value = true
errorMessage.value = ''
const fanProfile = uni.getStorageSync('fan_profile')
if (fanProfile && fanProfile.star_id) {
starId.value = fanProfile.star_id
}
starId.value = uni.getStorageSync('star_id')
const res = await getDailyTasks(starId.value)
tasks.value = res.data?.tasks || []
} catch (err) {
console.error('loadTasks error:', err)
errorMessage.value = err.message || '加载失败'
} finally {
loading.value = false
refreshing.value = false
}
const res = await getDailyTasks(starId.value)
tasks.value = res.data?.tasks || []
} catch (err) {
console.error('loadTasks error:', err)
errorMessage.value = err.message || '加载失败'
} finally {
loading.value = false
}
}
async function handleClaim(task) {
if (claimingTask.value) return
try {
claimingTask.value = task.task_key
await claimDailyTask(task.task_key, starId.value)
await loadTasks()
uni.showToast({ title: '领取成功', icon: 'success' })
} catch (err) {
console.error('handleClaim error:', err)
uni.showToast({ title: err.message || '领取失败', icon: 'none' })
} finally {
claimingTask.value = ''
}
if (claimingTask.value) return
try {
claimingTask.value = task.task_key
const res = await claimDailyTask(task.task_key, starId.value)
await loadTasks()
emit('updated')
uni.$emit('balanceUpdated', { crystal_balance: res.data?.crystal_balance, experience: res.data?.experience })
uni.showToast({ title: '领取成功', icon: 'success' })
} catch (err) {
console.error('handleClaim error:', err)
uni.showToast({ title: err.message || '领取失败', icon: 'none' })
} finally {
claimingTask.value = ''
}
}
async function handleClaimAll() {
if (claimingAll.value) return
try {
claimingAll.value = true
await claimAllDailyTasks(starId.value)
await loadTasks()
uni.showToast({ title: '领取成功', icon: 'success' })
} catch (err) {
console.error('handleClaimAll error:', err)
uni.showToast({ title: err.message || '领取失败', icon: 'none' })
} finally {
claimingAll.value = false
}
if (claimingAll.value) return
try {
claimingAll.value = true
const res = await claimAllDailyTasks(starId.value)
await loadTasks()
emit('updated')
uni.$emit('balanceUpdated', { crystal_balance: res.data?.crystal_balance, experience: res.data?.experience })
uni.showToast({ title: '领取成功', icon: 'success' })
} catch (err) {
console.error('handleClaimAll error:', err)
uni.showToast({ title: err.message || '领取失败', icon: 'none' })
} finally {
claimingAll.value = false
}
}
function handlePullRefresh() {
refreshing.value = true
loadTasks()
//
let maskTouchStartTime = 0
const handleMaskTouchStart = (e) => {
maskTouchStartTime = Date.now()
e.preventDefault()
e.stopPropagation()
}
onMounted(() => {
loadTasks()
})
//
let closeTouchStartTime = 0
let closeTouchLocked = false
const handleCloseTouchStart = (e) => {
closeTouchStartTime = Date.now()
closeTouchLocked = false
}
const handleCloseTouchEnd = (e) => {
if (closeTouchLocked) return
closeTouchLocked = true
const touchDuration = Date.now() - closeTouchStartTime
if (touchDuration < 300) {
e.preventDefault()
e.stopPropagation()
emit('close')
}
}
const handleCloseClick = (e) => {
e.preventDefault()
e.stopPropagation()
emit('close')
}
</script>
<style scoped>
.daily-tasks-container {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 120rpx;
.modal-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.page-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
text-align: center;
padding: 20rpx 0;
.modal-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 1;
}
.modal-container {
position: relative;
width: 580rpx;
max-height: 85vh;
border-radius: 40rpx;
overflow: hidden;
z-index: 2;
}
.modal-background {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 0;
object-fit: cover;
}
.modal-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 1;
background: rgba(0, 0, 0, 0.5);
}
.close-button {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
.close-icon {
font-size: 50rpx;
color: #e6e6e6;
line-height: 1;
font-weight: 300;
}
.modal-content {
position: relative;
z-index: 2;
padding: 60rpx 40rpx 40rpx;
display: flex;
flex-direction: column;
max-height: 85vh;
overflow-y: auto;
}
.modal-title {
font-size: 40rpx;
font-weight: bold;
color: #e6e6e6;
text-align: center;
margin-bottom: 40rpx;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.loading-state,
.error-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60rpx 0;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid #e0e0e0;
border-top-color: #6c5ce7;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
width: 60rpx;
height: 60rpx;
border: 4rpx solid rgba(255, 255, 255, 0.3);
border-top-color: #F08399;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
}
@keyframes spin {
to { transform: rotate(360deg); }
to { transform: rotate(360deg); }
}
.loading-text,
.error-text {
color: #999;
font-size: 28rpx;
color: #e6e6e6;
font-size: 28rpx;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.retry-btn {
margin-top: 20rpx;
padding: 16rpx 40rpx;
background: linear-gradient(135deg, #6c5ce7, #a29bfe);
color: #fff;
border-radius: 50rpx;
font-size: 28rpx;
margin-top: 20rpx;
padding: 16rpx 40rpx;
background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
color: #fff;
border-radius: 50rpx;
font-size: 28rpx;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
padding: 100rpx 0;
display: flex;
flex-direction: column;
align-items: center;
padding: 60rpx 0;
}
.empty-text {
color: #999;
font-size: 28rpx;
color: #e6e6e6;
font-size: 28rpx;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.task-list {
padding: 20rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
margin-bottom: 30rpx;
}
.task-item {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.1);
}
.task-info {
flex: 1;
flex: 1;
display: flex;
flex-direction: column;
gap: 8rpx;
}
.task-name {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
font-size: 30rpx;
font-weight: bold;
color: #e6e6e6;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.task-desc {
font-size: 24rpx;
color: #999;
margin-bottom: 10rpx;
font-size: 24rpx;
color: rgba(230, 230, 230, 0.7);
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.task-reward {
display: flex;
align-items: center;
gap: 8rpx;
display: flex;
align-items: center;
gap: 8rpx;
margin-top: 8rpx;
}
.reward-icon {
font-size: 24rpx;
font-size: 24rpx;
}
.reward-value {
font-size: 24rpx;
color: #6c5ce7;
font-size: 26rpx;
color: #FFB800;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.reward-sep {
color: #e0e0e0;
margin: 0 8rpx;
color: rgba(255, 255, 255, 0.3);
margin: 0 8rpx;
}
.task-action {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10rpx;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10rpx;
}
.status-badge {
padding: 6rpx 16rpx;
border-radius: 20rpx;
font-size: 22rpx;
min-width: 120rpx;
height: 50rpx;
border-radius: 25rpx;
display: flex;
align-items: center;
justify-content: center;
padding: 0 20rpx;
}
.status-pending {
background: #e8f4ff;
color: #1890ff;
.status-badge.status-pending {
background: rgba(255, 255, 255, 0.2);
}
.status-completed {
background: #f6ffed;
color: #52c41a;
.status-badge.status-completed {
background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
}
.status-claimed {
background: #f5f5f5;
color: #999;
.status-badge.status-claimed {
background: rgba(255, 255, 255, 0.1);
}
.status-text {
font-size: 24rpx;
color: #e6e6e6;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.claim-btn {
padding: 12rpx 30rpx;
background: linear-gradient(135deg, #6c5ce7, #a29bfe);
color: #fff;
border-radius: 30rpx;
font-size: 26rpx;
min-width: 120rpx;
min-width: 140rpx;
height: 50rpx;
border-radius: 25rpx;
background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
color: #fff;
font-size: 26rpx;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
display: flex;
align-items: center;
justify-content: center;
}
.claim-all-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx;
background: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.1);
margin-top: 20rpx;
}
.claim-all-btn {
width: 100%;
padding: 24rpx 0;
background: linear-gradient(135deg, #6c5ce7, #a29bfe);
color: #fff;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: bold;
width: 100%;
padding: 24rpx 0;
background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
color: #fff;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: bold;
font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}
.pull-to-refresh {
display: flex;
justify-content: center;
padding: 30rpx 0;
/* 动画效果 */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.refresh-text {
color: #999;
font-size: 24rpx;
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.scale-enter-active,
.scale-leave-active {
transition: all 0.3s ease;
}
.scale-enter-from,
.scale-leave-to {
opacity: 0;
transform: scale(0.8);
}
</style>

View File

@ -1,7 +1,12 @@
<template>
<view class="guide-container">
<!-- 顶部导航 -->
<Header :show-back="true" back-icon-color="#e6e6e6" :show-guide-icon="false" :show-task-icon="false" :show-star-activity-icon="false" />
<!-- 背景图片 -->
<image class="background-image" src="/static/background/starbook.jpg" mode="aspectFill"></image>
<!-- 左上角返回按钮 -->
<view class="back-button" :style="{ top: backButtonTop }" @click="handleBack">
<image class="back-icon" src="/static/icon/back.png" mode="aspectFit" />
</view>
<!-- 页面标题 -->
<view class="page-title">新手引导</view>
@ -88,16 +93,28 @@
<!-- 下拉刷新 -->
<view v-if="!loading" class="pull-to-refresh" @click="handleRefresh">
<text class="refresh-text">{{ refreshing ? '刷新中...' : '下拉刷新' }}</text>
<!-- <text class="refresh-text">{{ refreshing ? '刷新中...' : '下拉刷新' }}</text> -->
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import Header from '../components/Header.vue'
import { getOnboardingStatus, advanceStage, claimOnboardingReward } from '@/utils/task-api.js'
const isAndroid = ref(false)
const backButtonTop = computed(() => {
if (isAndroid.value) {
return 'calc(env(safe-area-inset-top) + 80rpx)'
}
return 'calc(env(safe-area-inset-top) + 32rpx)'
})
const handleBack = () => {
uni.navigateBack()
}
const loading = ref(true)
const refreshing = ref(false)
const errorMessage = ref('')
@ -125,11 +142,17 @@ const allCurrentTasksDone = computed(() => currentTasksDone.value)
const canAdvance = computed(() => currentStatus.value === 'in_progress' && currentTasksDone.value)
const canClaimReward = computed(() => currentStatus.value === 'in_progress' && currentTasksDone.value)
// stages
//
// 使 AllTasksCompleted
function isTaskCompleted(stage, taskKey) {
//
// completed key
// false
// stage.all_tasks_completed
if (stage.all_tasks_completed === true) {
return true
}
// all_tasks_completed status
if (stage.status === 'completed') {
return true
}
return false
}
@ -190,27 +213,61 @@ function handleRefresh() {
}
onMounted(() => {
const systemInfo = uni.getSystemInfoSync()
isAndroid.value = systemInfo.platform === 'android'
loadStatus()
})
</script>
<style scoped>
.guide-container {
position: relative;
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 120rpx;
}
.background-image {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.back-button {
position: fixed;
left: 32rpx;
width: 80rpx;
height: 80rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 101;
}
.back-icon {
width: 64rpx;
height: 64rpx;
}
.page-title {
position: relative;
z-index: 1;
font-size: 36rpx;
font-weight: bold;
color: #333;
color: #fff;
text-align: center;
padding: 20rpx 0;
}
.loading-state,
.error-state {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
@ -248,6 +305,8 @@ onMounted(() => {
}
.guide-content {
position: relative;
z-index: 1;
padding: 20rpx;
}
@ -412,6 +471,8 @@ onMounted(() => {
}
.pull-to-refresh {
position: relative;
z-index: 1;
display: flex;
justify-content: center;
padding: 30rpx 0;

View File

@ -1,7 +1,7 @@
<template>
<view class="revenue-container">
<!-- 顶部导航 -->
<Header :show-back="true" back-icon-color="#e6e6e6" :show-guide-icon="false" :show-task-icon="false" :show-star-activity-icon="false" />
<!-- <Header :show-back="true" back-icon-color="#e6e6e6" :show-guide-icon="false" :show-task-icon="false" :show-star-activity-icon="false" /> -->
<!-- 页面标题 -->
<view class="page-title">展示收益</view>
@ -103,7 +103,7 @@
<!-- 下拉刷新 -->
<view v-if="!loading" class="pull-to-refresh" @click="handleRefresh">
<text class="refresh-text">{{ refreshing ? '刷新中...' : '下拉刷新' }}</text>
<!-- <text class="refresh-text">{{ refreshing ? '刷新中...' : '下拉刷新' }}</text> -->
</view>
</view>
</template>

View File

@ -1,7 +1,7 @@
// API 基础配置
const baseURL = 'http://101.132.250.62:8080'
// const baseURL = 'http://101.132.250.62:8080'
// const baseURL = 'http://192.168.110.60:8080'
// const baseURL = 'http://localhost:8080'
const baseURL = 'http://localhost:8080'
// 是否使用模拟数据(开发调试时设为 true后端API准备好后改为 false
const USE_MOCK_API = false
@ -12,7 +12,7 @@ function mockDelay(ms = 800) {
}
// 请求封装
function request(options) {
export function request(options) {
return new Promise((resolve, reject) => {
// 构建请求头
const headers = {

View File

@ -12,7 +12,7 @@ import { request } from './api.js'
* @returns {Promise}
*/
export const getDailyTasks = (starId) =>
request({ url: '/api/tasks/daily', data: { star_id: starId } })
request({ url: '/api/v1/tasks/daily', data: { star_id: starId } })
/**
* 上报任务事件
@ -21,7 +21,7 @@ export const getDailyTasks = (starId) =>
* @returns {Promise}
*/
export const reportEvent = (eventType, starId) =>
request({ url: '/api/tasks/report-event', method: 'POST', data: { event_type: eventType, star_id: starId } })
request({ url: '/api/v1/tasks/report-event', method: 'POST', data: { event_type: eventType, star_id: starId } })
/**
* 领取单个每日任务奖励
@ -30,7 +30,7 @@ export const reportEvent = (eventType, starId) =>
* @returns {Promise}
*/
export const claimDailyTask = (taskKey, starId) =>
request({ url: '/api/tasks/daily/claim', method: 'POST', data: { task_key: taskKey, star_id: starId } })
request({ url: '/api/v1/tasks/daily/claim', method: 'POST', data: { task_key: taskKey, star_id: starId } })
/**
* 一键领取所有已完成每日任务
@ -38,7 +38,7 @@ export const claimDailyTask = (taskKey, starId) =>
* @returns {Promise}
*/
export const claimAllDailyTasks = (starId) =>
request({ url: '/api/tasks/daily/claim-all', method: 'POST', data: { star_id: starId } })
request({ url: `/api/v1/tasks/daily/claim-all?star_id=${starId}`, method: 'POST' })
/**
* 完成引导步骤
@ -46,14 +46,14 @@ export const claimAllDailyTasks = (starId) =>
* @returns {Promise}
*/
export const completeGuide = (taskKey) =>
request({ url: '/api/tasks/guide/complete', method: 'POST', data: { task_key: taskKey } })
request({ url: '/api/v1/tasks/guide/complete', method: 'POST', data: { task_key: taskKey } })
/**
* 获取引导状态
* @returns {Promise}
*/
export const getOnboardingStatus = () =>
request({ url: '/api/tasks/onboarding/status' })
request({ url: '/api/v1/tasks/onboarding/status' })
/**
* 进入下一阶段
@ -61,7 +61,7 @@ export const getOnboardingStatus = () =>
* @returns {Promise}
*/
export const advanceStage = (targetStage) =>
request({ url: '/api/tasks/onboarding/advance-stage', method: 'POST', data: { target_stage: targetStage } })
request({ url: '/api/v1/tasks/onboarding/advance-stage', method: 'POST', data: { target_stage: targetStage } })
/**
* 领取引导阶段奖励
@ -69,7 +69,7 @@ export const advanceStage = (targetStage) =>
* @returns {Promise}
*/
export const claimOnboardingReward = (stage) =>
request({ url: '/api/tasks/onboarding/claim-reward', method: 'POST', data: { stage } })
request({ url: '/api/v1/tasks/onboarding/claim-reward', method: 'POST', data: { stage } })
/**
* 获取展示收益列表
@ -81,7 +81,7 @@ export const claimOnboardingReward = (stage) =>
*/
export const getExhibitionRevenue = (starId, status, page, pageSize) =>
request({
url: '/api/tasks/exhibition-revenue',
url: '/api/v1/tasks/exhibition-revenue',
data: { star_id: starId, status, page, page_size: pageSize }
})
@ -92,7 +92,7 @@ export const getExhibitionRevenue = (starId, status, page, pageSize) =>
* @returns {Promise}
*/
export const claimExhibitionRevenue = (revenueId, starId) =>
request({ url: '/api/tasks/exhibition-revenue/claim', method: 'POST', data: { revenue_id: revenueId, star_id: starId } })
request({ url: '/api/v1/tasks/exhibition-revenue/claim', method: 'POST', data: { revenue_id: revenueId, star_id: starId } })
/**
* 一键领取所有可领取展示收益
@ -100,4 +100,4 @@ export const claimExhibitionRevenue = (revenueId, starId) =>
* @returns {Promise}
*/
export const claimAllExhibitionRevenue = (starId) =>
request({ url: '/api/tasks/exhibition-revenue/claim-all', method: 'POST', data: { star_id: starId } })
request({ url: '/api/v1/tasks/exhibition-revenue/claim-all', method: 'POST', data: { star_id: starId } })