From e7970ac25feef07ec54fe637f0c3de79c482b5a6 Mon Sep 17 00:00:00 2001 From: wwweww <2646787260@qq.com> Date: Tue, 31 Mar 2026 22:12:06 +0800 Subject: [PATCH] fix: some api bug --- .gitea/workflows/build-push-harbor.yml | 171 +- .gitignore | 2 +- app/authz/adapter/README.md | 31 - app/authz/adapter/authz.go | 5 +- app/email/mq/etc/email.yaml | 2 +- app/game/api/etc/game-api.yaml | 11 +- app/game/api/game.go | 3 + .../handler/game/createGameHandler.go | 32 + app/game/api/internal/handler/routes.go | 6 + .../internal/logic/game/createGameLogic.go | 46 + .../api/internal/logic/game/listGamesLogic.go | 1 + app/game/rpc/etc/pb.yaml | 45 +- app/game/rpc/internal/logic/addGamesLogic.go | 2 +- .../rpc/internal/logic/searchGamesLogic.go | 8 +- app/game/rpc/internal/svc/serviceContext.go | 8 +- app/objectstory/api/etc/file-api.yaml | 14 +- .../api/internal/handler/routes.go | 2 +- app/objectstory/api/internal/types/types.go | 2 +- app/objectstory/api/objectstory.go | 3 + app/objectstory/rpc/etc/file.yaml | 5 +- app/order/api/etc/order-api.yaml | 20 +- app/order/api/order.go | 3 + app/order/rpc/etc/pb.yaml | 42 +- app/order/rpc/internal/svc/serviceContext.go | 16 +- app/order/rpc/pb.go | 2 +- app/player/api/etc/player-api.yaml | 9 +- .../internal/logic/player/listPlayersLogic.go | 6 +- app/player/api/internal/types/types.go | 3 +- app/player/rpc/etc/pb.yaml | 37 +- .../rpc/internal/logic/searchPlayersLogic.go | 16 +- .../rpc/internal/models/migrate/schema.go | 2 +- app/player/rpc/internal/models/mutation.go | 45 +- app/player/rpc/internal/models/players.go | 10 +- .../rpc/internal/models/players/players.go | 2 + .../rpc/internal/models/players/where.go | 36 +- .../rpc/internal/models/players_create.go | 16 +- .../rpc/internal/models/players_update.go | 32 +- app/player/rpc/internal/models/runtime.go | 4 + .../rpc/internal/models/schema/players.go | 7 +- .../internal/models/schema/playerservices.go | 5 +- app/player/rpc/internal/svc/serviceContext.go | 8 +- app/player/rpc/pb/player.pb.go | 130 +- app/shop/api/etc/shop-api.yaml | 10 +- .../handler/shop/acceptInvitationHandler.go | 14 +- .../handler/shop/addAnnouncementHandler.go | 14 +- .../handler/shop/createShopHandler.go | 14 +- .../handler/shop/deleteAnnouncementHandler.go | 14 +- .../internal/handler/shop/getMyShopHandler.go | 14 +- .../internal/handler/shop/getShopHandler.go | 3 +- .../handler/shop/getShopIncomeStatsHandler.go | 14 +- .../handler/shop/getUserShopHandler.go | 3 +- .../handler/shop/invitePlayerHandler.go | 14 +- .../handler/shop/rejectInvitationHandler.go | 14 +- .../handler/shop/removePlayerHandler.go | 14 +- .../handler/shop/updateShopHandler.go | 11 +- .../handler/shop/updateShopTemplateHandler.go | 14 +- .../internal/logic/shop/createShopLogic.go | 3 + .../internal/logic/shop/updateShopLogic.go | 1 + app/shop/api/internal/svc/serviceContext.go | 12 +- app/shop/api/shop.go | 3 + app/shop/rpc/etc/pb.yaml | 50 +- app/shop/rpc/internal/config/config.go | 1 + app/shop/rpc/internal/logic/addShopsLogic.go | 57 +- .../rpc/internal/logic/getShopsByIdLogic.go | 2 +- .../rpc/internal/logic/searchShopsLogic.go | 2 +- .../rpc/internal/logic/updateShopsLogic.go | 3 +- .../rpc/internal/models/migrate/schema.go | 2 +- app/shop/rpc/internal/models/mutation.go | 30 +- app/shop/rpc/internal/models/runtime.go | 4 - app/shop/rpc/internal/models/schema/shops.go | 49 +- app/shop/rpc/internal/models/shops.go | 15 +- app/shop/rpc/internal/models/shops/shops.go | 7 +- app/shop/rpc/internal/models/shops/where.go | 46 + app/shop/rpc/internal/models/shops_create.go | 17 +- app/shop/rpc/internal/models/shops_update.go | 40 +- app/shop/rpc/internal/svc/serviceContext.go | 12 +- app/user_verifications/rpc/etc/pb.yaml | 47 +- .../rpc/internal/config/config.go | 2 +- .../addOrUpdateUserVerificationsLogic.go | 113 ++ .../listUserVerificationsByUserIdLogic.go | 58 + .../logic/searchUserVerificationsLogic.go | 6 +- .../rpc/internal/models/migrate/schema.go | 12 +- .../rpc/internal/models/mutation.go | 107 +- .../rpc/internal/models/runtime.go | 13 +- .../models/schema/userverifications.go | 18 +- .../rpc/internal/models/userverifications.go | 35 +- .../userverifications/userverifications.go | 8 +- .../models/userverifications/where.go | 50 + .../models/userverifications_create.go | 63 +- .../models/userverifications_update.go | 101 + .../server/userVerificationsServer.go | 10 + .../rpc/internal/svc/serviceContext.go | 20 +- .../rpc/pb/user_verifications.pb.go | 275 ++- .../rpc/pb/user_verifications_grpc.pb.go | 88 +- .../userverifications/userVerifications.go | 38 +- app/users/api/etc/user-api.yaml | 18 +- app/users/api/internal/handler/routes.go | 31 +- .../api/internal/logic/auth/registerLogic.go | 6 +- .../internal/logic/user/followUserLogic.go | 18 +- .../api/internal/logic/user/getMeLogic.go | 35 +- .../internal/logic/user/switchRoleLogic.go | 1 - .../internal/logic/user/unfollowUserLogic.go | 17 +- .../user/updateNotificationSettingsLogic.go | 1 - .../rejectVerificationLogic.go | 1 - .../applyVerificationLogic.go | 27 +- .../getMyVerificationsLogic.go | 6 +- app/users/api/internal/types/types.go | 11 +- app/users/api/users.go | 3 + app/users/rpc/etc/pb.yaml | 45 +- .../rpc/internal/logic/addUserFollowsLogic.go | 46 + .../internal/logic/addUserPreferencesLogic.go | 31 + .../rpc/internal/logic/delUserFollowsLogic.go | 39 + .../internal/logic/delUserPreferencesLogic.go | 30 + .../internal/logic/getUserByUsernameLogic.go | 2 +- .../internal/logic/getUserFollowsByIdLogic.go | 30 + .../logic/getUserPreferencesByIdLogic.go | 30 + .../rpc/internal/logic/getUsersByIdLogic.go | 37 +- app/users/rpc/internal/logic/loginLogic.go | 8 +- app/users/rpc/internal/logic/registerLogic.go | 6 +- .../rpc/internal/logic/resetPasswordLogic.go | 2 +- .../internal/logic/searchUserFollowsLogic.go | 30 + .../logic/searchUserPreferencesLogic.go | 30 + .../rpc/internal/logic/searchUsersLogic.go | 5 +- .../rpc/internal/logic/switchRoleLogic.go | 64 + .../internal/logic/updateUserFollowsLogic.go | 30 + .../logic/updateUserPreferencesLogic.go | 30 + .../rpc/internal/logic/updateUsersLogic.go | 11 +- .../rpc/internal/logic/validateTokenLogic.go | 15 +- app/users/rpc/internal/models/client.go | 304 +++- app/users/rpc/internal/models/ent.go | 6 +- app/users/rpc/internal/models/hook/hook.go | 24 + .../rpc/internal/models/migrate/schema.go | 46 +- app/users/rpc/internal/models/mutation.go | 1428 ++++++++++++++- .../internal/models/predicate/predicate.go | 6 + app/users/rpc/internal/models/runtime.go | 51 +- .../rpc/internal/models/schema/userfollows.go | 26 + .../internal/models/schema/userpreferences.go | 31 + app/users/rpc/internal/models/schema/users.go | 18 +- app/users/rpc/internal/models/tx.go | 8 +- app/users/rpc/internal/models/userfollows.go | 126 ++ .../models/userfollows/userfollows.go | 63 + .../rpc/internal/models/userfollows/where.go | 205 +++ .../rpc/internal/models/userfollows_create.go | 222 +++ .../rpc/internal/models/userfollows_delete.go | 88 + .../rpc/internal/models/userfollows_query.go | 527 ++++++ .../rpc/internal/models/userfollows_update.go | 283 +++ .../rpc/internal/models/userpreferences.go | 174 ++ .../models/userpreferences/userpreferences.go | 112 ++ .../internal/models/userpreferences/where.go | 345 ++++ .../internal/models/userpreferences_create.go | 340 ++++ .../internal/models/userpreferences_delete.go | 88 + .../internal/models/userpreferences_query.go | 527 ++++++ .../internal/models/userpreferences_update.go | 434 +++++ app/users/rpc/internal/models/users.go | 35 +- app/users/rpc/internal/models/users/users.go | 21 +- app/users/rpc/internal/models/users/where.go | 76 + app/users/rpc/internal/models/users_create.go | 99 +- app/users/rpc/internal/models/users_update.go | 156 +- .../rpc/internal/server/usercenterServer.go | 67 +- app/users/rpc/internal/svc/serviceContext.go | 29 +- app/users/rpc/pb/users.pb.go | 1621 ++++++++++++++++- app/users/rpc/pb/users_grpc.pb.go | 512 +++++- app/users/rpc/usercenter/usercenter.go | 156 +- app/wallet/api/etc/wallet-api.yaml | 10 +- app/wallet/api/wallet.go | 3 + app/wallet/rpc/etc/pb.yaml | 43 +- .../logic/addWalletTransactionsLogic.go | 1 - .../rpc/internal/logic/addWalletsLogic.go | 2 +- .../rpc/internal/logic/getWalletsByIdLogic.go | 7 +- .../rpc/internal/logic/updateWalletsLogic.go | 5 +- app/wallet/rpc/internal/models/client.go | 8 +- .../rpc/internal/models/migrate/schema.go | 4 +- app/wallet/rpc/internal/models/mutation.go | 129 +- app/wallet/rpc/internal/models/runtime.go | 5 + .../rpc/internal/models/schema/wallet.go | 6 +- .../models/schema/wallettransactions.go | 11 +- app/wallet/rpc/internal/models/wallet.go | 17 +- .../rpc/internal/models/wallet/wallet.go | 14 +- .../rpc/internal/models/wallet/where.go | 63 +- .../rpc/internal/models/wallet_create.go | 45 +- .../rpc/internal/models/wallet_delete.go | 2 +- .../rpc/internal/models/wallet_query.go | 26 +- .../rpc/internal/models/wallet_update.go | 4 +- .../models/wallettransactions/where.go | 10 + .../models/wallettransactions_create.go | 11 +- .../models/wallettransactions_update.go | 36 +- app/wallet/rpc/internal/svc/serviceContext.go | 8 +- .../middlewares/HeaderExtractorMiddleware.go | 47 + common/middlewares/requestIdMiddleware.go | 23 + common/utils/contextj/contextx.go | 8 + deploy/dev/script/pg_docker.sh | 49 + deploy/dev/script/snowflake.sh | 1 + deploy/k8s/service/email/email-mq.yaml | 2 + desc/api/docs/game-api.json | 214 +++ desc/api/docs/order-api.json | 940 ++++++++++ desc/api/docs/os-api.json | 95 + desc/api/docs/player-api.json | 978 ++++++++++ desc/api/docs/shop-api.json | 1113 +++++++++++ desc/api/docs/user-api.json | 1110 +++++++++++ desc/api/docs/wallet-api.json | 232 +++ desc/api/game.api | 4 + desc/api/objectstory.api | 4 +- desc/api/order.api | 19 + desc/api/player.api | 10 +- desc/api/shop.api | 2 +- desc/api/user_verifications.api | 106 +- desc/api/users.api | 16 +- desc/api/wallet.api | 7 + desc/rpc/player.proto | 26 +- desc/rpc/user_verifications.proto | 21 +- desc/rpc/users.proto | 182 +- desc/sql/order/{orders.sql => 00-orders.sql} | 0 desc/sql/player/players.sql | 2 +- desc/sql/shop/shop_players.sql | 2 +- desc/sql/users/user_verifications.sql | 1 + desc/sql/users/users.sql | 3 +- .../wallet/{wallets.sql => 00-wallets.sql} | 4 +- {app/users/api => docs}/INTEGRATION.md | 1202 ++++++------ pkg/types/TextArray.go | 41 + 219 files changed, 16195 insertions(+), 2126 deletions(-) delete mode 100644 app/authz/adapter/README.md create mode 100644 app/game/api/internal/handler/game/createGameHandler.go create mode 100644 app/game/api/internal/logic/game/createGameLogic.go create mode 100644 app/user_verifications/rpc/internal/logic/addOrUpdateUserVerificationsLogic.go create mode 100644 app/user_verifications/rpc/internal/logic/listUserVerificationsByUserIdLogic.go create mode 100644 app/users/rpc/internal/logic/addUserFollowsLogic.go create mode 100644 app/users/rpc/internal/logic/addUserPreferencesLogic.go create mode 100644 app/users/rpc/internal/logic/delUserFollowsLogic.go create mode 100644 app/users/rpc/internal/logic/delUserPreferencesLogic.go create mode 100644 app/users/rpc/internal/logic/getUserFollowsByIdLogic.go create mode 100644 app/users/rpc/internal/logic/getUserPreferencesByIdLogic.go create mode 100644 app/users/rpc/internal/logic/searchUserFollowsLogic.go create mode 100644 app/users/rpc/internal/logic/searchUserPreferencesLogic.go create mode 100644 app/users/rpc/internal/logic/switchRoleLogic.go create mode 100644 app/users/rpc/internal/logic/updateUserFollowsLogic.go create mode 100644 app/users/rpc/internal/logic/updateUserPreferencesLogic.go create mode 100644 app/users/rpc/internal/models/schema/userfollows.go create mode 100644 app/users/rpc/internal/models/schema/userpreferences.go create mode 100644 app/users/rpc/internal/models/userfollows.go create mode 100644 app/users/rpc/internal/models/userfollows/userfollows.go create mode 100644 app/users/rpc/internal/models/userfollows/where.go create mode 100644 app/users/rpc/internal/models/userfollows_create.go create mode 100644 app/users/rpc/internal/models/userfollows_delete.go create mode 100644 app/users/rpc/internal/models/userfollows_query.go create mode 100644 app/users/rpc/internal/models/userfollows_update.go create mode 100644 app/users/rpc/internal/models/userpreferences.go create mode 100644 app/users/rpc/internal/models/userpreferences/userpreferences.go create mode 100644 app/users/rpc/internal/models/userpreferences/where.go create mode 100644 app/users/rpc/internal/models/userpreferences_create.go create mode 100644 app/users/rpc/internal/models/userpreferences_delete.go create mode 100644 app/users/rpc/internal/models/userpreferences_query.go create mode 100644 app/users/rpc/internal/models/userpreferences_update.go create mode 100644 common/middlewares/HeaderExtractorMiddleware.go create mode 100644 common/middlewares/requestIdMiddleware.go create mode 100644 deploy/dev/script/pg_docker.sh create mode 100644 deploy/dev/script/snowflake.sh create mode 100644 desc/api/docs/game-api.json create mode 100644 desc/api/docs/order-api.json create mode 100644 desc/api/docs/os-api.json create mode 100644 desc/api/docs/player-api.json create mode 100644 desc/api/docs/shop-api.json create mode 100644 desc/api/docs/user-api.json create mode 100644 desc/api/docs/wallet-api.json rename desc/sql/order/{orders.sql => 00-orders.sql} (100%) rename desc/sql/wallet/{wallets.sql => 00-wallets.sql} (78%) rename {app/users/api => docs}/INTEGRATION.md (92%) create mode 100644 pkg/types/TextArray.go diff --git a/.gitea/workflows/build-push-harbor.yml b/.gitea/workflows/build-push-harbor.yml index d7cd6be..ea40608 100644 --- a/.gitea/workflows/build-push-harbor.yml +++ b/.gitea/workflows/build-push-harbor.yml @@ -9,10 +9,6 @@ on: - "feature/**" workflow_dispatch: -env: - GO_VERSION: "1.24" - NODE_VERSION: "22" - jobs: docker-build-push: runs-on: ubuntu-latest @@ -20,70 +16,32 @@ jobs: - name: Checkout uses: http://103.236.53.208:3000/actions/checkout@v4 - - name: Setup Node.js - uses: http://103.236.53.208:3000/actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup Go - uses: http://103.236.53.208:3000/actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Install dependencies - run: npm ci - - - name: Install goctl - run: | - go install github.com/zeromicro/go-zero/tools/goctl@latest - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - - name: Set image tags id: vars run: | echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" echo "date_tag=$(date +%Y%m%d%H%M%S)" >> "$GITHUB_OUTPUT" + # 调试步骤:检查 Secret 是否正确读取 (只会输出字符长度,不会泄露密码) + - name: Debug Secrets + run: | + echo "Registry: ${{ secrets.HARBOR_REGISTRY }}" + echo "User length: ${#HARBOR_USERNAME}" + echo "Pass length: ${#HARBOR_PASSWORD}" + env: + HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }} + HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} + - name: Login Harbor env: HARBOR_REGISTRY: ${{ secrets.HARBOR_REGISTRY }} HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }} HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} run: | + # 尝试登录,如果失败会打印详细信息 echo "$HARBOR_PASSWORD" | docker login "$HARBOR_REGISTRY" -u "$HARBOR_USERNAME" --password-stdin - - name: Discover docker targets - id: targets - shell: bash - run: | - set -euo pipefail - : > docker-targets.txt - - while IFS= read -r service_dir; do - service_name="$(basename "$service_dir")" - - while IFS= read -r svc_dir; do - svc_type="$(basename "$svc_dir")" - if [[ "$svc_type" == "rpc" ]]; then - go_entry="$svc_dir/pb.go" - else - go_entry="$svc_dir/$service_name.go" - fi - - if [[ -f "$go_entry" ]]; then - echo "$go_entry" >> docker-targets.txt - fi - done < <(find "$service_dir" -mindepth 1 -maxdepth 1 -type d | sort) - - done < <(find app -mindepth 1 -maxdepth 1 -type d | sort) - - target_count="$(wc -l < docker-targets.txt | tr -d ' ')" - echo "count=$target_count" >> "$GITHUB_OUTPUT" - echo "Found $target_count docker targets" - cat docker-targets.txt - - - name: Generate Dockerfile, build and push images - if: steps.targets.outputs.count != '0' + - name: Build and Push Monorepo Services env: HARBOR_REGISTRY: ${{ secrets.HARBOR_REGISTRY }} HARBOR_PROJECT: ${{ secrets.HARBOR_PROJECT }} @@ -93,27 +51,100 @@ jobs: run: | set -euo pipefail - while IFS= read -r target; do - [[ -z "$target" ]] && continue + # 1. 定义要遍历的微服务根目录 (根据你的项目结构) + # 你的结构是 app// + # 我们只关心 api, rpc, mq 这三种类型 - service_name="$(echo "$target" | cut -d'/' -f2)" - svc_type="$(echo "$target" | cut -d'/' -f3)" - image_name="${service_name}-${svc_type}" + echo "🔍 开始扫描 Go-Zero 微服务..." + + # 找到 app 下所有的 api/rpc/mq 目录 + find app -mindepth 2 -maxdepth 2 -type d \( -name "api" -o -name "rpc" -o -name "mq" \) | sort | while read -r service_dir; do + + # service_dir 举例: app/community/api + service_type=$(basename "$service_dir") # api + parent_dir=$(dirname "$service_dir") # app/community + service_name=$(basename "$parent_dir") # community + + # 2. 智能查找入口文件 (main.go 或 service_name.go) + # 在当前目录下查找含有 "package main" 的 .go 文件 + entry_file=$(grep -l "package main" "$service_dir"/*.go | head -n 1 || true) + + if [[ -z "$entry_file" ]]; then + echo "⚠️ 跳过 $service_dir: 未找到 package main 入口文件" + continue + fi + + # 3. 智能查找配置文件 (etc/*.yaml) + config_file=$(ls "$service_dir/etc/"*.yaml 2>/dev/null | head -n 1 || true) + if [[ -z "$config_file" ]]; then + echo "⚠️ 警告 $service_name-$service_type: 未找到 etc/*.yaml 配置文件,容器启动可能失败" + config_name="config.yaml" # fallback + else + config_name=$(basename "$config_file") + fi + + # 镜像名称: community-api, user-rpc 等 + image_name="${service_name}-${service_type}" image_ref="$HARBOR_REGISTRY/$HARBOR_PROJECT/$image_name" + + echo "----------------------------------------------------" + echo "🚀 构建目标: $image_name" + echo "📂 入口文件: $entry_file" + echo "📄 配置文件: $config_name" + echo "----------------------------------------------------" - echo "==== Building $image_name from $target ====" - npx hereby -t docker -s "$target" + # 4. 动态生成 Dockerfile (针对 Monorepo 优化) + # 关键点:COPY . . 把整个根目录拷进去,因为 Go-Zero 项目通常依赖 ../../common + cat < Dockerfile.tmp + FROM golang:alpine AS builder - docker build \ - -f Dockerfile \ - -t "$image_ref:$SHORT_SHA" \ - -t "$image_ref:$DATE_TAG" \ - -t "$image_ref:latest" \ - . + # 优化:使用阿里云 Alpine 源 + RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \ + apk update --no-cache && apk add --no-cache tzdata + WORKDIR /build + + # 优化:利用层缓存,先下载依赖 + ENV GOPROXY=https://goproxy.cn,direct + COPY go.mod go.sum ./ + RUN go mod download + + # 拷贝所有源码 (解决 common 依赖问题) + COPY . . + + # 编译 + RUN go build -ldflags="-s -w" -o /app/main $entry_file + + # 运行时镜像 + FROM scratch + + COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt + COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai + ENV TZ=Asia/Shanghai + + WORKDIR /app + COPY --from=builder /app/main /app/main + + # 拷贝 etc 配置 + COPY $service_dir/etc /app/etc + + # 启动命令 + CMD ["./main", "-f", "etc/$config_name"] + EOF + + # 5. 执行 Docker Build + docker build -f Dockerfile.tmp -t "$image_ref:$SHORT_SHA" . + + # 打其他 Tag + docker tag "$image_ref:$SHORT_SHA" "$image_ref:$DATE_TAG" + docker tag "$image_ref:$SHORT_SHA" "$image_ref:latest" + + # 6. 推送 + echo "📤 推送镜像..." docker push "$image_ref:$SHORT_SHA" docker push "$image_ref:$DATE_TAG" docker push "$image_ref:latest" - - rm -f Dockerfile - done < docker-targets.txt + + echo "✅ $image_name 完成" + rm -f Dockerfile.tmp + done diff --git a/.gitignore b/.gitignore index 3b63896..af7bba3 100644 --- a/.gitignore +++ b/.gitignore @@ -70,7 +70,7 @@ web_modules/ .yarn-integrity # dotenv environment variables file -.env +dev test .env.test .env.production diff --git a/app/authz/adapter/README.md b/app/authz/adapter/README.md deleted file mode 100644 index a4609fa..0000000 --- a/app/authz/adapter/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# authz-adapter - -Envoy `ext_authz` 适配服务,实现 `envoy.service.auth.v3.Authorization`,并调用 `user-rpc.ValidateToken`。 - -## 环境变量 - -- `LISTEN_ON`:监听地址,默认 `0.0.0.0:9002` -- `USER_RPC_TARGET`:user-rpc 地址,默认 `user-rpc-svc.juwan.svc.cluster.local:9001` - -## 本地运行 - -```powershell -go run ./app/authz/adapter -``` - -## Docker 构建 - -在仓库根目录执行: - -```powershell -docker build -f app/authz/adapter/Dockerfile -t authz-adapter:local . -docker run --rm -p 9002:9002 authz-adapter:local -``` - -## 说明 - -- 放行路径:`/healthz`、`/api/users/login`、`/api/users/register` -- 受保护路径:其余请求要求 - - Cookie 中有 `JToken` - - Header 中有 `x-auth-user-id`(由 Envoy `jwt_authn` 注入) -- 鉴权通过后回传:`x-auth-user-id`、`x-auth-role-type` diff --git a/app/authz/adapter/authz.go b/app/authz/adapter/authz.go index 0957d03..671460d 100644 --- a/app/authz/adapter/authz.go +++ b/app/authz/adapter/authz.go @@ -15,6 +15,7 @@ import ( corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" authv3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" + "github.com/zeromicro/go-zero/core/logx" codepb "google.golang.org/genproto/googleapis/rpc/code" statuspb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" @@ -68,15 +69,17 @@ func (s *authzServer) Check(ctx context.Context, req *authv3.CheckRequest) (*aut UserId: userID, }) if err != nil { + logx.Infof("validate token rpc failed, err: %v", err) return deny(codepb.Code_UNAUTHENTICATED, typev3.StatusCode_Unauthorized, "validate token failed"), nil } if !resp.GetValid() { + logx.Infof("validate token rpc failed, err: %v", err) return deny(codepb.Code_PERMISSION_DENIED, typev3.StatusCode_Forbidden, "token invalid"), nil } outHeaders := []*corev3.HeaderValueOption{ {Header: &corev3.HeaderValue{Key: headerAuthUserID, Value: strconv.FormatInt(resp.GetUserId(), 10)}}, - {Header: &corev3.HeaderValue{Key: headerAuthRoleType, Value: strconv.FormatInt(resp.GetRoleType(), 10)}}, + {Header: &corev3.HeaderValue{Key: headerAuthRoleType, Value: resp.GetRoleType()}}, } if getHeader(httpReq.GetHeaders(), headerAuthIsAdmin) != "" { diff --git a/app/email/mq/etc/email.yaml b/app/email/mq/etc/email.yaml index f9e9c60..7950963 100644 --- a/app/email/mq/etc/email.yaml +++ b/app/email/mq/etc/email.yaml @@ -8,7 +8,7 @@ Prometheus: Kmq: Name: email-mq Brokers: - - my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092 + - "${KAFKA_BROKER}" Topic: email-task Group: email-consumer-group ForceCommit: true diff --git a/app/game/api/etc/game-api.yaml b/app/game/api/etc/game-api.yaml index 107cbf6..664eed9 100644 --- a/app/game/api/etc/game-api.yaml +++ b/app/game/api/etc/game-api.yaml @@ -7,5 +7,14 @@ Prometheus: Port: 4001 Path: /metrics +# ===== PROC CONF ===== +#GameRpcConf: +# Target: k8s://juwan/game-rpc-svc:8080 + +# ===== DEV CONF ===== GameRpcConf: - Target: k8s://juwan/game-rpc-svc:8080 + Endpoints: + - game-rpc:8080 + +Log: + Level: debug \ No newline at end of file diff --git a/app/game/api/game.go b/app/game/api/game.go index 0ea70e5..ef1535a 100644 --- a/app/game/api/game.go +++ b/app/game/api/game.go @@ -6,6 +6,7 @@ package main import ( "flag" "fmt" + "juwan-backend/common/middlewares" "juwan-backend/app/game/api/internal/config" "juwan-backend/app/game/api/internal/handler" @@ -24,6 +25,8 @@ func main() { conf.MustLoad(*configFile, &c) server := rest.MustNewServer(c.RestConf) + server.Use(middlewares.NewRequestMiddleware().Handle) + server.Use(middlewares.NewHeaderExtractorMiddleware().Handle) defer server.Stop() ctx := svc.NewServiceContext(c) diff --git a/app/game/api/internal/handler/game/createGameHandler.go b/app/game/api/internal/handler/game/createGameHandler.go new file mode 100644 index 0000000..d47efdb --- /dev/null +++ b/app/game/api/internal/handler/game/createGameHandler.go @@ -0,0 +1,32 @@ +// Code scaffolded by goctl. Safe to edit. +// goctl 1.9.2 + +package game + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "juwan-backend/app/game/api/internal/logic/game" + "juwan-backend/app/game/api/internal/svc" + "juwan-backend/app/game/api/internal/types" +) + +// 创建游戏 +func CreateGameHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.Game + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := game.NewCreateGameLogic(r.Context(), svcCtx) + resp, err := l.CreateGame(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/app/game/api/internal/handler/routes.go b/app/game/api/internal/handler/routes.go index 912451f..1c6b860 100644 --- a/app/game/api/internal/handler/routes.go +++ b/app/game/api/internal/handler/routes.go @@ -21,6 +21,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/", Handler: game.ListGamesHandler(serverCtx), }, + { + // 创建游戏 + Method: http.MethodPost, + Path: "/", + Handler: game.CreateGameHandler(serverCtx), + }, { // 获取游戏详情 Method: http.MethodGet, diff --git a/app/game/api/internal/logic/game/createGameLogic.go b/app/game/api/internal/logic/game/createGameLogic.go new file mode 100644 index 0000000..1580caa --- /dev/null +++ b/app/game/api/internal/logic/game/createGameLogic.go @@ -0,0 +1,46 @@ +// Code scaffolded by goctl. Safe to edit. +// goctl 1.9.2 + +package game + +import ( + "context" + "errors" + "juwan-backend/app/game/rpc/pb" + + "juwan-backend/app/game/api/internal/svc" + "juwan-backend/app/game/api/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreateGameLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// 创建游戏 +func NewCreateGameLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateGameLogic { + return &CreateGameLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *CreateGameLogic) CreateGame(req *types.Game) (resp *types.Game, err error) { + // todo: add your logic here and delete this line + _, err = l.svcCtx.GameRpc.AddGames(l.ctx, &pb.AddGamesReq{ + Name: req.Name, + Icon: req.Icon, + Category: req.Category, + IsActive: false, + }) + if err != nil { + logx.Errorf("add game err: %v", err) + return nil, errors.New("add game err") + } + + return &types.Game{}, nil +} diff --git a/app/game/api/internal/logic/game/listGamesLogic.go b/app/game/api/internal/logic/game/listGamesLogic.go index 56aff4f..46a3530 100644 --- a/app/game/api/internal/logic/game/listGamesLogic.go +++ b/app/game/api/internal/logic/game/listGamesLogic.go @@ -35,6 +35,7 @@ func (l *ListGamesLogic) ListGames(req *types.PageReq) (resp *types.GameListResp Limit: req.Limit, }) if err != nil { + logx.Errorf("ListGames err:%v", err) return nil, err } diff --git a/app/game/rpc/etc/pb.yaml b/app/game/rpc/etc/pb.yaml index 1b9b37e..9300327 100644 --- a/app/game/rpc/etc/pb.yaml +++ b/app/game/rpc/etc/pb.yaml @@ -6,23 +6,40 @@ Prometheus: Port: 4001 Path: /metrics -DB: - Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - +# ===== PROC CONF ===== +#DB: +# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# +# +#SnowflakeRpcConf: +# Target: k8s://juwan/snowflake-svc:8080 +# +#CacheConf: +# - Host: "${REDIS_M_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# - Host: "${REDIS_S_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# +#Log: +# Level: info +# ===== DEV CONF ===== SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc:8080 - + Endpoints: + - snowflake:8080 + +DB: + Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + CacheConf: - - Host: "${REDIS_M_HOST}" + - Host: "${REDIS_HOST}:${REDIS_PORT}" Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" - - Host: "${REDIS_S_HOST}" - Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" Log: - Level: info + Level: debug diff --git a/app/game/rpc/internal/logic/addGamesLogic.go b/app/game/rpc/internal/logic/addGamesLogic.go index f2bb784..b254272 100644 --- a/app/game/rpc/internal/logic/addGamesLogic.go +++ b/app/game/rpc/internal/logic/addGamesLogic.go @@ -37,7 +37,7 @@ func (l *AddGamesLogic) AddGames(in *pb.AddGamesReq) (*pb.AddGamesResp, error) { SetName(in.Name). SetIcon(in.Icon). SetCategory(in.Category). - SetSortOrder(int(in.SortOrder)). + SetSortOrder(0). Save(l.ctx) if err != nil { logx.Errorf("AddGamesLogic.addGames err:%v", err) diff --git a/app/game/rpc/internal/logic/searchGamesLogic.go b/app/game/rpc/internal/logic/searchGamesLogic.go index 09320c2..766bb27 100644 --- a/app/game/rpc/internal/logic/searchGamesLogic.go +++ b/app/game/rpc/internal/logic/searchGamesLogic.go @@ -6,6 +6,7 @@ import ( "juwan-backend/app/game/rpc/internal/svc" "juwan-backend/app/game/rpc/pb" + "ariga.io/entcache" "github.com/jinzhu/copier" "github.com/zeromicro/go-zero/core/logx" ) @@ -25,14 +26,19 @@ func NewSearchGamesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Searc } func (l *SearchGamesLogic) SearchGames(in *pb.SearchGamesReq) (*pb.SearchGamesResp, error) { + notFoundErr := entcache.ErrNotFound if in.Page <= 0 || in.Limit <= 0 || in.Page > 1000 || in.Limit > 100 { return nil, errors.New("invalid pagination parameters") } all, err := l.svcCtx.GameModelRO.Games.Query().Limit(int(in.Limit)).Offset(int(in.Limit * (in.Page - 1))).All(l.ctx) - if err != nil { + if err != nil && !errors.As(err, ¬FoundErr) { logx.Errorf("failed to query games: %v", err) return nil, errors.New("failed to query games") } + logx.Debugf("games: %v", all) + if err != nil { + return &pb.SearchGamesResp{}, nil + } list := make([]*pb.Games, 0, len(all)) for _, v := range all { temp := &pb.Games{} diff --git a/app/game/rpc/internal/svc/serviceContext.go b/app/game/rpc/internal/svc/serviceContext.go index f8a4499..718cd04 100644 --- a/app/game/rpc/internal/svc/serviceContext.go +++ b/app/game/rpc/internal/svc/serviceContext.go @@ -1,6 +1,7 @@ package svc import ( + stdsql "database/sql" "juwan-backend/app/game/rpc/internal/config" "juwan-backend/app/game/rpc/internal/models" "juwan-backend/app/snowflake/rpc/snowflake" @@ -10,6 +11,7 @@ import ( "time" "ariga.io/entcache" + "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" "github.com/zeromicro/go-zero/core/logx" @@ -24,14 +26,16 @@ type ServiceContext struct { } func NewServiceContext(c config.Config) *ServiceContext { - RWConn, err := sql.Open("pgx", c.DB.Master) + rawRW, err := stdsql.Open("pgx", c.DB.Master) if err != nil { panic(err) } - ROConn, err := sql.Open("pgx", c.DB.Slaves) + rawRO, err := stdsql.Open("pgx", c.DB.Slaves) if err != nil { panic(err) } + RWConn := sql.OpenDB(dialect.Postgres, rawRW) + ROConn := sql.OpenDB(dialect.Postgres, rawRO) redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second) if redisCluster == nil || err != nil { diff --git a/app/objectstory/api/etc/file-api.yaml b/app/objectstory/api/etc/file-api.yaml index 231a795..0697f0f 100644 --- a/app/objectstory/api/etc/file-api.yaml +++ b/app/objectstory/api/etc/file-api.yaml @@ -8,10 +8,20 @@ Prometheus: Path: /metrics -FileRpcConf: - Target: k8s://juwan/objectstory-rpc-svc:8080 +# ===== PROC CONF ===== +#FileRpcConf: +# Target: k8s://juwan/objectstory-rpc-svc:8080 # #Log: # Level: info + +# ===== DEV CONF ===== +FileRpcConf: + Endpoints: + - objectstory-rpc:8080 + +Log: + Level: debug + # k8s://juwan/:8080 diff --git a/app/objectstory/api/internal/handler/routes.go b/app/objectstory/api/internal/handler/routes.go index ebe5e60..d9c2fcf 100644 --- a/app/objectstory/api/internal/handler/routes.go +++ b/app/objectstory/api/internal/handler/routes.go @@ -20,7 +20,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { { // 文件获取接口 (如果是私有文件,通过此接口获取或重定向) Method: http.MethodGet, - Path: "/files/:fileId", + Path: "/files", Handler: file.GetFileHandler(serverCtx), }, { diff --git a/app/objectstory/api/internal/types/types.go b/app/objectstory/api/internal/types/types.go index b0bc84d..14f9215 100644 --- a/app/objectstory/api/internal/types/types.go +++ b/app/objectstory/api/internal/types/types.go @@ -4,7 +4,7 @@ package types type GetFileReq struct { - FileId string `path:"fileId"` + FileId string `form:"key"` } type UploadReq struct { diff --git a/app/objectstory/api/objectstory.go b/app/objectstory/api/objectstory.go index 87302be..23c8e71 100644 --- a/app/objectstory/api/objectstory.go +++ b/app/objectstory/api/objectstory.go @@ -6,6 +6,7 @@ package main import ( "flag" "fmt" + "juwan-backend/common/middlewares" "juwan-backend/app/objectstory/api/internal/config" "juwan-backend/app/objectstory/api/internal/handler" @@ -24,6 +25,8 @@ func main() { conf.MustLoad(*configFile, &c) server := rest.MustNewServer(c.RestConf) + server.Use(middlewares.NewRequestMiddleware().Handle) + server.Use(middlewares.NewHeaderExtractorMiddleware().Handle) defer server.Stop() ctx := svc.NewServiceContext(c) diff --git a/app/objectstory/rpc/etc/file.yaml b/app/objectstory/rpc/etc/file.yaml index 5006916..a09c59e 100644 --- a/app/objectstory/rpc/etc/file.yaml +++ b/app/objectstory/rpc/etc/file.yaml @@ -22,6 +22,9 @@ S3Conf: Region: auto UsePathStyle: true +Log: + Level: debug + #DB: # Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" # Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" @@ -36,5 +39,3 @@ S3Conf: # Pass: "${REDIS_PASSWORD}" # User: "default" # -Log: - Level: info diff --git a/app/order/api/etc/order-api.yaml b/app/order/api/etc/order-api.yaml index 758a998..87f541e 100644 --- a/app/order/api/etc/order-api.yaml +++ b/app/order/api/etc/order-api.yaml @@ -8,11 +8,25 @@ Prometheus: Path: /metrics # k8s://juwan/:8080 +# ===== PROC CONF ===== +#OrderRpcConf: +# Target: k8s://juwan/order-rpc-svc:8080 +# +#PlayerRpcConf: +# Target: k8s://juwan/player-rpc-svc:8080 +# +#ShopRpcConf: +# Target: k8s://juwan/shop-rpc-svc:8080 + +# ===== DEV CONF ==== OrderRpcConf: - Target: k8s://juwan/order-rpc-svc:8080 + Endpoints: + - order-rpc:8080 PlayerRpcConf: - Target: k8s://juwan/player-rpc-svc:8080 + Endpoints: + - player-rpc:8080 ShopRpcConf: - Target: k8s://juwan/shop-rpc-svc:8080 + Endpoints: + - shop-rpc:8080 diff --git a/app/order/api/order.go b/app/order/api/order.go index 80cd304..7588fb8 100644 --- a/app/order/api/order.go +++ b/app/order/api/order.go @@ -6,6 +6,7 @@ package main import ( "flag" "fmt" + "juwan-backend/common/middlewares" "juwan-backend/app/order/api/internal/config" "juwan-backend/app/order/api/internal/handler" @@ -24,6 +25,8 @@ func main() { conf.MustLoad(*configFile, &c) server := rest.MustNewServer(c.RestConf) + server.Use(middlewares.NewRequestMiddleware().Handle) + server.Use(middlewares.NewHeaderExtractorMiddleware().Handle) defer server.Stop() ctx := svc.NewServiceContext(c) diff --git a/app/order/rpc/etc/pb.yaml b/app/order/rpc/etc/pb.yaml index 9e44d04..661205c 100644 --- a/app/order/rpc/etc/pb.yaml +++ b/app/order/rpc/etc/pb.yaml @@ -14,25 +14,41 @@ Prometheus: # Target: k8s://juwan/.:8080 +# ==== PROC CONF ==== +#SnowflakeRpcConf: +# Target: k8s://juwan/snowflake-svc:8080 +# +# +#DB: +# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# +# +#CacheConf: +# - Host: "${REDIS_M_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# - Host: "${REDIS_S_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# +#Log: +# Level: info +# ==== DEV CONF ==== SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc:8080 - + Endpoints: + - snowflake:8080 DB: - Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - + Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" CacheConf: - - Host: "${REDIS_M_HOST}" + - Host: "${REDIS_HOST}:${REDIS_PORT}" Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" - - Host: "${REDIS_S_HOST}" - Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" Log: - Level: info + Level: debug \ No newline at end of file diff --git a/app/order/rpc/internal/svc/serviceContext.go b/app/order/rpc/internal/svc/serviceContext.go index a4f73cc..790453d 100644 --- a/app/order/rpc/internal/svc/serviceContext.go +++ b/app/order/rpc/internal/svc/serviceContext.go @@ -1,20 +1,22 @@ package svc import ( + stdsql "database/sql" "fmt" "strings" "time" + "ariga.io/entcache" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + _ "github.com/jackc/pgx/v5/stdlib" + "github.com/zeromicro/go-zero/core/logx" "juwan-backend/app/order/rpc/internal/config" "juwan-backend/app/order/rpc/internal/models" "juwan-backend/app/snowflake/rpc/snowflake" "juwan-backend/common/redisx" "juwan-backend/common/snowflakex" "juwan-backend/pkg/adapter" - - "ariga.io/entcache" - "entgo.io/ent/dialect/sql" - "github.com/zeromicro/go-zero/core/logx" ) type ServiceContext struct { @@ -25,14 +27,16 @@ type ServiceContext struct { } func NewServiceContext(c config.Config) *ServiceContext { - RWConn, err := sql.Open("pgx", c.DB.Master) + rawRW, err := stdsql.Open("pgx", c.DB.Master) if err != nil { panic(err) } - ROConn, err := sql.Open("pgx", c.DB.Slaves) + rawRO, err := stdsql.Open("pgx", c.DB.Slaves) if err != nil { panic(err) } + RWConn := sql.OpenDB(dialect.Postgres, rawRW) + ROConn := sql.OpenDB(dialect.Postgres, rawRO) redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second) if redisCluster == nil || err != nil { diff --git a/app/order/rpc/pb.go b/app/order/rpc/pb.go index 9f44f99..65bf846 100644 --- a/app/order/rpc/pb.go +++ b/app/order/rpc/pb.go @@ -22,7 +22,7 @@ func main() { flag.Parse() var c config.Config - conf.MustLoad(*configFile, &c) + conf.MustLoad(*configFile, &c, conf.UseEnv()) ctx := svc.NewServiceContext(c) s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) { diff --git a/app/player/api/etc/player-api.yaml b/app/player/api/etc/player-api.yaml index cab123f..f1c6c72 100644 --- a/app/player/api/etc/player-api.yaml +++ b/app/player/api/etc/player-api.yaml @@ -8,6 +8,11 @@ Prometheus: Path: /metrics # k8s://juwan/:8080 -PlayerRpcConf: - Target: k8s://juwan/player-rpc-svc:8080 +# ===== PROC CONF ===== +#PlayerRpcConf: +# Target: k8s://juwan/player-rpc-svc:8080 +# ===== DEV CONF ==== +PlayerRpcConf: + Endpoints: + - player-rpc:8080 diff --git a/app/player/api/internal/logic/player/listPlayersLogic.go b/app/player/api/internal/logic/player/listPlayersLogic.go index eb68e3d..9345f16 100644 --- a/app/player/api/internal/logic/player/listPlayersLogic.go +++ b/app/player/api/internal/logic/player/listPlayersLogic.go @@ -32,9 +32,9 @@ func NewListPlayersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListP func (l *ListPlayersLogic) ListPlayers(req *types.PlayerListReq) (resp *types.PlayerListResp, err error) { // todo: add your logic here and delete this line p, err := l.svcCtx.PlayerRpc.SearchPlayers(l.ctx, &pb.SearchPlayersReq{ - Page: req.Offset, - Limit: req.Limit, - Gender: int64(req.Gender), + Page: &req.Offset, + Limit: &req.Limit, + Gender: &req.Gender, }) if err != nil { return nil, err diff --git a/app/player/api/internal/types/types.go b/app/player/api/internal/types/types.go index eff9148..a86dce9 100644 --- a/app/player/api/internal/types/types.go +++ b/app/player/api/internal/types/types.go @@ -48,7 +48,7 @@ type PageReq struct { type PlayerListReq struct { PageReq GameId int64 `form:"gameId,optional"` - Gender int `form:"gender,optional"` + Gender int64 `form:"gender,optional"` } type PlayerListResp struct { @@ -67,6 +67,7 @@ type PlayerProfile struct { Services []PlayerService `json:"services"` ShopId string `json:"shopId,optional"` ShopName string `json:"shopName,optional"` + Gender bool `json:"gender"` Tags []string `json:"tags"` } diff --git a/app/player/rpc/etc/pb.yaml b/app/player/rpc/etc/pb.yaml index 397aa4b..a73865e 100644 --- a/app/player/rpc/etc/pb.yaml +++ b/app/player/rpc/etc/pb.yaml @@ -8,28 +8,41 @@ Prometheus: Path: /metrics -SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc:8080 +# ===== PROC CONF ===== +#SnowflakeRpcConf: +# Target: k8s://juwan/snowflake-svc:8080 + #DB: # Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" # Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# +#CacheConf: +# - Host: "${REDIS_M_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# - Host: "${REDIS_S_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# +#Log: +# Level: info +# ===== DEV CONF ===== +SnowflakeRpcConf: + Endpoints: + - snowflake:8080 DB: - Master: "postgresql://app:7BGs8CdEE8sLPshMjyXkYmxNMTV88EBrd2GN6tdIX1VhIgBzIcgKXbJjVdYiX4a9@user-db-rw:5432/app" - Slaves: "postgresql://app:7BGs8CdEE8sLPshMjyXkYmxNMTV88EBrd2GN6tdIX1VhIgBzIcgKXbJjVdYiX4a9@user-db-ro:5432/app" + Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" CacheConf: - - Host: "${REDIS_M_HOST}" + - Host: "${REDIS_HOST}:${REDIS_PORT}" Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" - - Host: "${REDIS_S_HOST}" - Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" Log: - Level: info + Level: debug diff --git a/app/player/rpc/internal/logic/searchPlayersLogic.go b/app/player/rpc/internal/logic/searchPlayersLogic.go index 25a1133..13eda50 100644 --- a/app/player/rpc/internal/logic/searchPlayersLogic.go +++ b/app/player/rpc/internal/logic/searchPlayersLogic.go @@ -4,7 +4,6 @@ import ( "context" "errors" "juwan-backend/app/player/rpc/internal/models/players" - "juwan-backend/app/player/rpc/internal/svc" "juwan-backend/app/player/rpc/pb" @@ -27,16 +26,17 @@ func NewSearchPlayersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Sea } func (l *SearchPlayersLogic) SearchPlayers(in *pb.SearchPlayersReq) (*pb.SearchPlayersResp, error) { - gender := 0 - if in.Gender > 0 { - gender = 1 - } searcher := l.svcCtx.PlayerModelRO.Players.Query() - if in.Gender >= 0 { + + if in.Gender != nil && *in.Gender != 0 { + // 1 man 2 woman + gender := true + if *in.Gender == 2 { + gender = false + } searcher.Where(players.GenderEQ(gender)) } - - all, err := searcher.Limit(int(in.Limit)).Offset(int(in.Page * in.Limit)).All(l.ctx) + all, err := searcher.Limit(int(*in.Limit)).Offset(int(*in.Page * *in.Limit)).All(l.ctx) if err != nil { logx.Errorf("SearchPlayers err: %v", err) return nil, errors.New("search players") diff --git a/app/player/rpc/internal/models/migrate/schema.go b/app/player/rpc/internal/models/migrate/schema.go index b1a3ac5..c09a895 100644 --- a/app/player/rpc/internal/models/migrate/schema.go +++ b/app/player/rpc/internal/models/migrate/schema.go @@ -36,7 +36,7 @@ var ( {Name: "id", Type: field.TypeInt64, Increment: true}, {Name: "user_id", Type: field.TypeInt64, Unique: true}, {Name: "status", Type: field.TypeString, Size: 20, Default: "offline"}, - {Name: "gender", Type: field.TypeInt, Unique: true}, + {Name: "gender", Type: field.TypeBool, Default: true}, {Name: "rating", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(3,2)"}}, {Name: "total_orders", Type: field.TypeInt, Nullable: true, Default: 0}, {Name: "completed_orders", Type: field.TypeInt, Nullable: true, Default: 0}, diff --git a/app/player/rpc/internal/models/mutation.go b/app/player/rpc/internal/models/mutation.go index 24ec5e2..7ac8c1f 100644 --- a/app/player/rpc/internal/models/mutation.go +++ b/app/player/rpc/internal/models/mutation.go @@ -1131,8 +1131,7 @@ type PlayersMutation struct { user_id *int64 adduser_id *int64 status *string - gender *int - addgender *int + gender *bool rating *decimal.Decimal total_orders *int addtotal_orders *int @@ -1348,13 +1347,12 @@ func (m *PlayersMutation) ResetStatus() { } // SetGender sets the "gender" field. -func (m *PlayersMutation) SetGender(i int) { - m.gender = &i - m.addgender = nil +func (m *PlayersMutation) SetGender(b bool) { + m.gender = &b } // Gender returns the value of the "gender" field in the mutation. -func (m *PlayersMutation) Gender() (r int, exists bool) { +func (m *PlayersMutation) Gender() (r bool, exists bool) { v := m.gender if v == nil { return @@ -1365,7 +1363,7 @@ func (m *PlayersMutation) Gender() (r int, exists bool) { // OldGender returns the old "gender" field's value of the Players entity. // If the Players object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *PlayersMutation) OldGender(ctx context.Context) (v int, err error) { +func (m *PlayersMutation) OldGender(ctx context.Context) (v bool, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldGender is only allowed on UpdateOne operations") } @@ -1379,28 +1377,9 @@ func (m *PlayersMutation) OldGender(ctx context.Context) (v int, err error) { return oldValue.Gender, nil } -// AddGender adds i to the "gender" field. -func (m *PlayersMutation) AddGender(i int) { - if m.addgender != nil { - *m.addgender += i - } else { - m.addgender = &i - } -} - -// AddedGender returns the value that was added to the "gender" field in this mutation. -func (m *PlayersMutation) AddedGender() (r int, exists bool) { - v := m.addgender - if v == nil { - return - } - return *v, true -} - // ResetGender resets all changes to the "gender" field. func (m *PlayersMutation) ResetGender() { m.gender = nil - m.addgender = nil } // SetRating sets the "rating" field. @@ -2001,7 +1980,7 @@ func (m *PlayersMutation) SetField(name string, value ent.Value) error { m.SetStatus(v) return nil case players.FieldGender: - v, ok := value.(int) + v, ok := value.(bool) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } @@ -2074,9 +2053,6 @@ func (m *PlayersMutation) AddedFields() []string { if m.adduser_id != nil { fields = append(fields, players.FieldUserID) } - if m.addgender != nil { - fields = append(fields, players.FieldGender) - } if m.addtotal_orders != nil { fields = append(fields, players.FieldTotalOrders) } @@ -2096,8 +2072,6 @@ func (m *PlayersMutation) AddedField(name string) (ent.Value, bool) { switch name { case players.FieldUserID: return m.AddedUserID() - case players.FieldGender: - return m.AddedGender() case players.FieldTotalOrders: return m.AddedTotalOrders() case players.FieldCompletedOrders: @@ -2120,13 +2094,6 @@ func (m *PlayersMutation) AddField(name string, value ent.Value) error { } m.AddUserID(v) return nil - case players.FieldGender: - v, ok := value.(int) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.AddGender(v) - return nil case players.FieldTotalOrders: v, ok := value.(int) if !ok { diff --git a/app/player/rpc/internal/models/players.go b/app/player/rpc/internal/models/players.go index 638193e..335a18d 100644 --- a/app/player/rpc/internal/models/players.go +++ b/app/player/rpc/internal/models/players.go @@ -25,7 +25,7 @@ type Players struct { // Status holds the value of the "status" field. Status string `json:"status,omitempty"` // Gender holds the value of the "gender" field. - Gender int `json:"gender,omitempty"` + Gender bool `json:"gender,omitempty"` // Rating holds the value of the "rating" field. Rating decimal.Decimal `json:"rating,omitempty"` // TotalOrders holds the value of the "total_orders" field. @@ -56,7 +56,9 @@ func (*Players) scanValues(columns []string) ([]any, error) { values[i] = new(decimal.Decimal) case players.FieldGames: values[i] = new(pq.Int64Array) - case players.FieldID, players.FieldUserID, players.FieldGender, players.FieldTotalOrders, players.FieldCompletedOrders, players.FieldShopID: + case players.FieldGender: + values[i] = new(sql.NullBool) + case players.FieldID, players.FieldUserID, players.FieldTotalOrders, players.FieldCompletedOrders, players.FieldShopID: values[i] = new(sql.NullInt64) case players.FieldStatus: values[i] = new(sql.NullString) @@ -96,10 +98,10 @@ func (_m *Players) assignValues(columns []string, values []any) error { _m.Status = value.String } case players.FieldGender: - if value, ok := values[i].(*sql.NullInt64); !ok { + if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field gender", values[i]) } else if value.Valid { - _m.Gender = int(value.Int64) + _m.Gender = value.Bool } case players.FieldRating: if value, ok := values[i].(*decimal.Decimal); !ok { diff --git a/app/player/rpc/internal/models/players/players.go b/app/player/rpc/internal/models/players/players.go index 1c3b814..a35fd0b 100644 --- a/app/player/rpc/internal/models/players/players.go +++ b/app/player/rpc/internal/models/players/players.go @@ -72,6 +72,8 @@ var ( DefaultStatus string // StatusValidator is a validator for the "status" field. It is called by the builders before save. StatusValidator func(string) error + // DefaultGender holds the default value on creation for the "gender" field. + DefaultGender bool // DefaultRating holds the default value on creation for the "rating" field. DefaultRating decimal.Decimal // DefaultTotalOrders holds the default value on creation for the "total_orders" field. diff --git a/app/player/rpc/internal/models/players/where.go b/app/player/rpc/internal/models/players/where.go index 20088be..d11d63a 100644 --- a/app/player/rpc/internal/models/players/where.go +++ b/app/player/rpc/internal/models/players/where.go @@ -67,7 +67,7 @@ func Status(v string) predicate.Players { } // Gender applies equality check predicate on the "gender" field. It's identical to GenderEQ. -func Gender(v int) predicate.Players { +func Gender(v bool) predicate.Players { return predicate.Players(sql.FieldEQ(FieldGender, v)) } @@ -212,45 +212,15 @@ func StatusContainsFold(v string) predicate.Players { } // GenderEQ applies the EQ predicate on the "gender" field. -func GenderEQ(v int) predicate.Players { +func GenderEQ(v bool) predicate.Players { return predicate.Players(sql.FieldEQ(FieldGender, v)) } // GenderNEQ applies the NEQ predicate on the "gender" field. -func GenderNEQ(v int) predicate.Players { +func GenderNEQ(v bool) predicate.Players { return predicate.Players(sql.FieldNEQ(FieldGender, v)) } -// GenderIn applies the In predicate on the "gender" field. -func GenderIn(vs ...int) predicate.Players { - return predicate.Players(sql.FieldIn(FieldGender, vs...)) -} - -// GenderNotIn applies the NotIn predicate on the "gender" field. -func GenderNotIn(vs ...int) predicate.Players { - return predicate.Players(sql.FieldNotIn(FieldGender, vs...)) -} - -// GenderGT applies the GT predicate on the "gender" field. -func GenderGT(v int) predicate.Players { - return predicate.Players(sql.FieldGT(FieldGender, v)) -} - -// GenderGTE applies the GTE predicate on the "gender" field. -func GenderGTE(v int) predicate.Players { - return predicate.Players(sql.FieldGTE(FieldGender, v)) -} - -// GenderLT applies the LT predicate on the "gender" field. -func GenderLT(v int) predicate.Players { - return predicate.Players(sql.FieldLT(FieldGender, v)) -} - -// GenderLTE applies the LTE predicate on the "gender" field. -func GenderLTE(v int) predicate.Players { - return predicate.Players(sql.FieldLTE(FieldGender, v)) -} - // RatingEQ applies the EQ predicate on the "rating" field. func RatingEQ(v decimal.Decimal) predicate.Players { return predicate.Players(sql.FieldEQ(FieldRating, v)) diff --git a/app/player/rpc/internal/models/players_create.go b/app/player/rpc/internal/models/players_create.go index ea5e179..9e0935d 100644 --- a/app/player/rpc/internal/models/players_create.go +++ b/app/player/rpc/internal/models/players_create.go @@ -43,11 +43,19 @@ func (_c *PlayersCreate) SetNillableStatus(v *string) *PlayersCreate { } // SetGender sets the "gender" field. -func (_c *PlayersCreate) SetGender(v int) *PlayersCreate { +func (_c *PlayersCreate) SetGender(v bool) *PlayersCreate { _c.mutation.SetGender(v) return _c } +// SetNillableGender sets the "gender" field if the given value is not nil. +func (_c *PlayersCreate) SetNillableGender(v *bool) *PlayersCreate { + if v != nil { + _c.SetGender(*v) + } + return _c +} + // SetRating sets the "rating" field. func (_c *PlayersCreate) SetRating(v decimal.Decimal) *PlayersCreate { _c.mutation.SetRating(v) @@ -189,6 +197,10 @@ func (_c *PlayersCreate) defaults() { v := players.DefaultStatus _c.mutation.SetStatus(v) } + if _, ok := _c.mutation.Gender(); !ok { + v := players.DefaultGender + _c.mutation.SetGender(v) + } if _, ok := _c.mutation.Rating(); !ok { v := players.DefaultRating _c.mutation.SetRating(v) @@ -282,7 +294,7 @@ func (_c *PlayersCreate) createSpec() (*Players, *sqlgraph.CreateSpec) { _node.Status = value } if value, ok := _c.mutation.Gender(); ok { - _spec.SetField(players.FieldGender, field.TypeInt, value) + _spec.SetField(players.FieldGender, field.TypeBool, value) _node.Gender = value } if value, ok := _c.mutation.Rating(); ok { diff --git a/app/player/rpc/internal/models/players_update.go b/app/player/rpc/internal/models/players_update.go index 3a771a0..87453d9 100644 --- a/app/player/rpc/internal/models/players_update.go +++ b/app/player/rpc/internal/models/players_update.go @@ -67,26 +67,19 @@ func (_u *PlayersUpdate) SetNillableStatus(v *string) *PlayersUpdate { } // SetGender sets the "gender" field. -func (_u *PlayersUpdate) SetGender(v int) *PlayersUpdate { - _u.mutation.ResetGender() +func (_u *PlayersUpdate) SetGender(v bool) *PlayersUpdate { _u.mutation.SetGender(v) return _u } // SetNillableGender sets the "gender" field if the given value is not nil. -func (_u *PlayersUpdate) SetNillableGender(v *int) *PlayersUpdate { +func (_u *PlayersUpdate) SetNillableGender(v *bool) *PlayersUpdate { if v != nil { _u.SetGender(*v) } return _u } -// AddGender adds value to the "gender" field. -func (_u *PlayersUpdate) AddGender(v int) *PlayersUpdate { - _u.mutation.AddGender(v) - return _u -} - // SetRating sets the "rating" field. func (_u *PlayersUpdate) SetRating(v decimal.Decimal) *PlayersUpdate { _u.mutation.SetRating(v) @@ -297,10 +290,7 @@ func (_u *PlayersUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(players.FieldStatus, field.TypeString, value) } if value, ok := _u.mutation.Gender(); ok { - _spec.SetField(players.FieldGender, field.TypeInt, value) - } - if value, ok := _u.mutation.AddedGender(); ok { - _spec.AddField(players.FieldGender, field.TypeInt, value) + _spec.SetField(players.FieldGender, field.TypeBool, value) } if value, ok := _u.mutation.Rating(); ok { _spec.SetField(players.FieldRating, field.TypeOther, value) @@ -411,26 +401,19 @@ func (_u *PlayersUpdateOne) SetNillableStatus(v *string) *PlayersUpdateOne { } // SetGender sets the "gender" field. -func (_u *PlayersUpdateOne) SetGender(v int) *PlayersUpdateOne { - _u.mutation.ResetGender() +func (_u *PlayersUpdateOne) SetGender(v bool) *PlayersUpdateOne { _u.mutation.SetGender(v) return _u } // SetNillableGender sets the "gender" field if the given value is not nil. -func (_u *PlayersUpdateOne) SetNillableGender(v *int) *PlayersUpdateOne { +func (_u *PlayersUpdateOne) SetNillableGender(v *bool) *PlayersUpdateOne { if v != nil { _u.SetGender(*v) } return _u } -// AddGender adds value to the "gender" field. -func (_u *PlayersUpdateOne) AddGender(v int) *PlayersUpdateOne { - _u.mutation.AddGender(v) - return _u -} - // SetRating sets the "rating" field. func (_u *PlayersUpdateOne) SetRating(v decimal.Decimal) *PlayersUpdateOne { _u.mutation.SetRating(v) @@ -671,10 +654,7 @@ func (_u *PlayersUpdateOne) sqlSave(ctx context.Context) (_node *Players, err er _spec.SetField(players.FieldStatus, field.TypeString, value) } if value, ok := _u.mutation.Gender(); ok { - _spec.SetField(players.FieldGender, field.TypeInt, value) - } - if value, ok := _u.mutation.AddedGender(); ok { - _spec.AddField(players.FieldGender, field.TypeInt, value) + _spec.SetField(players.FieldGender, field.TypeBool, value) } if value, ok := _u.mutation.Rating(); ok { _spec.SetField(players.FieldRating, field.TypeOther, value) diff --git a/app/player/rpc/internal/models/runtime.go b/app/player/rpc/internal/models/runtime.go index dbc4938..9ef71ac 100644 --- a/app/player/rpc/internal/models/runtime.go +++ b/app/player/rpc/internal/models/runtime.go @@ -60,6 +60,10 @@ func init() { players.DefaultStatus = playersDescStatus.Default.(string) // players.StatusValidator is a validator for the "status" field. It is called by the builders before save. players.StatusValidator = playersDescStatus.Validators[0].(func(string) error) + // playersDescGender is the schema descriptor for gender field. + playersDescGender := playersFields[3].Descriptor() + // players.DefaultGender holds the default value on creation for the gender field. + players.DefaultGender = playersDescGender.Default.(bool) // playersDescRating is the schema descriptor for rating field. playersDescRating := playersFields[4].Descriptor() // players.DefaultRating holds the default value on creation for the rating field. diff --git a/app/player/rpc/internal/models/schema/players.go b/app/player/rpc/internal/models/schema/players.go index d07bddb..019063e 100644 --- a/app/player/rpc/internal/models/schema/players.go +++ b/app/player/rpc/internal/models/schema/players.go @@ -1,6 +1,7 @@ package schema import ( + "juwan-backend/pkg/types" "time" "entgo.io/ent" @@ -23,7 +24,7 @@ func (Players) Fields() []ent.Field { field.Int64("id").Immutable().Unique(), field.Int64("user_id").Unique(), field.String("status").MaxLen(20).Default("offline"), - field.Int("gender").Unique(), + field.Bool("gender").Default(true), field.Other("rating", decimal.Decimal{}). Optional(). Default(playerDefaultRating). @@ -33,7 +34,9 @@ func (Players) Fields() []ent.Field { field.Int("total_orders").Optional().Default(0), field.Int("completed_orders").Optional().Default(0), field.Int64("shop_id").Optional().Nillable(), - field.Strings("tags").Optional().Default([]string{}), + field.Other("tags", types.TextArray{}).SchemaType(map[string]string{ + dialect.Postgres: "text[]", + }).Optional(), field.Other("games", pq.Int64Array{}). Optional(). Default(pq.Int64Array{}). diff --git a/app/player/rpc/internal/models/schema/playerservices.go b/app/player/rpc/internal/models/schema/playerservices.go index 88b8b87..5958f69 100644 --- a/app/player/rpc/internal/models/schema/playerservices.go +++ b/app/player/rpc/internal/models/schema/playerservices.go @@ -1,6 +1,7 @@ package schema import ( + "juwan-backend/pkg/types" "time" "entgo.io/ent" @@ -47,7 +48,9 @@ func (PlayerServices) Fields() []ent.Field { }), field.String("unit").MaxLen(20), field.String("rank_range").MaxLen(100).Optional().Nillable(), - field.Strings("availability").Optional().Default([]string{}), + field.Other("availability", types.TextArray{}).SchemaType(map[string]string{ + dialect.Postgres: "text[]", + }).Optional().Nillable(), field.Other("rating", decimal.Decimal{}). Default(decFive). SchemaType(map[string]string{ diff --git a/app/player/rpc/internal/svc/serviceContext.go b/app/player/rpc/internal/svc/serviceContext.go index d0b2d25..8917f60 100644 --- a/app/player/rpc/internal/svc/serviceContext.go +++ b/app/player/rpc/internal/svc/serviceContext.go @@ -1,6 +1,7 @@ package svc import ( + stdsql "database/sql" "juwan-backend/app/player/rpc/internal/config" "juwan-backend/app/player/rpc/internal/models" "juwan-backend/app/snowflake/rpc/snowflake" @@ -10,6 +11,7 @@ import ( "time" "ariga.io/entcache" + "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" "github.com/zeromicro/go-zero/core/logx" @@ -24,14 +26,16 @@ type ServiceContext struct { } func NewServiceContext(c config.Config) *ServiceContext { - RWConn, err := sql.Open("pgx", c.DB.Master) + rawRW, err := stdsql.Open("pgx", c.DB.Master) if err != nil { panic(err) } - ROConn, err := sql.Open("pgx", c.DB.Slaves) + rawRO, err := stdsql.Open("pgx", c.DB.Slaves) if err != nil { panic(err) } + RWConn := sql.OpenDB(dialect.Postgres, rawRW) + ROConn := sql.OpenDB(dialect.Postgres, rawRO) redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second) if redisCluster == nil || err != nil { diff --git a/app/player/rpc/pb/player.pb.go b/app/player/rpc/pb/player.pb.go index d14dd93..4205fba 100644 --- a/app/player/rpc/pb/player.pb.go +++ b/app/player/rpc/pb/player.pb.go @@ -888,7 +888,7 @@ type Players struct { Games []int64 `protobuf:"varint,9,rep,packed,name=games,proto3" json:"games,omitempty"` //games CreatedAt int64 `protobuf:"varint,10,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt UpdatedAt int64 `protobuf:"varint,11,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt - Gender int64 `protobuf:"varint,12,opt,name=gender,proto3" json:"gender,omitempty"` //gender + Gender bool `protobuf:"varint,12,opt,name=gender,proto3" json:"gender,omitempty"` //gender unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1000,11 +1000,11 @@ func (x *Players) GetUpdatedAt() int64 { return 0 } -func (x *Players) GetGender() int64 { +func (x *Players) GetGender() bool { if x != nil { return x.Gender } - return 0 + return false } type AddPlayersReq struct { @@ -1505,20 +1505,20 @@ func (x *GetPlayersByIdResp) GetPlayers() *Players { type SearchPlayersReq struct { state protoimpl.MessageState `protogen:"open.v1"` - Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` //page - Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` //limit - Id int64 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` //id - UserId int64 `protobuf:"varint,4,opt,name=userId,proto3" json:"userId,omitempty"` //userId - Status string `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"` //status - Rating float64 `protobuf:"fixed64,6,opt,name=rating,proto3" json:"rating,omitempty"` //rating - TotalOrders int64 `protobuf:"varint,7,opt,name=totalOrders,proto3" json:"totalOrders,omitempty"` //totalOrders - CompletedOrders int64 `protobuf:"varint,8,opt,name=completedOrders,proto3" json:"completedOrders,omitempty"` //completedOrders - ShopId int64 `protobuf:"varint,9,opt,name=shopId,proto3" json:"shopId,omitempty"` //shopId - Tags []string `protobuf:"bytes,10,rep,name=tags,proto3" json:"tags,omitempty"` //tags - Games []int64 `protobuf:"varint,11,rep,packed,name=games,proto3" json:"games,omitempty"` //games - CreatedAt int64 `protobuf:"varint,12,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt - UpdatedAt int64 `protobuf:"varint,13,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt - Gender int64 `protobuf:"varint,14,opt,name=gender,proto3" json:"gender,omitempty"` //gender + Page *int64 `protobuf:"varint,1,opt,name=page,proto3,oneof" json:"page,omitempty"` //page + Limit *int64 `protobuf:"varint,2,opt,name=limit,proto3,oneof" json:"limit,omitempty"` //limit + Id *int64 `protobuf:"varint,3,opt,name=id,proto3,oneof" json:"id,omitempty"` //id + UserId *int64 `protobuf:"varint,4,opt,name=userId,proto3,oneof" json:"userId,omitempty"` //userId + Status *string `protobuf:"bytes,5,opt,name=status,proto3,oneof" json:"status,omitempty"` //status + Rating *float64 `protobuf:"fixed64,6,opt,name=rating,proto3,oneof" json:"rating,omitempty"` //rating + TotalOrders *int64 `protobuf:"varint,7,opt,name=totalOrders,proto3,oneof" json:"totalOrders,omitempty"` //totalOrders + CompletedOrders *int64 `protobuf:"varint,8,opt,name=completedOrders,proto3,oneof" json:"completedOrders,omitempty"` //completedOrders + ShopId *int64 `protobuf:"varint,9,opt,name=shopId,proto3,oneof" json:"shopId,omitempty"` //shopId + Tags []string `protobuf:"bytes,10,rep,name=tags,proto3" json:"tags,omitempty"` //tags + Games []int64 `protobuf:"varint,11,rep,packed,name=games,proto3" json:"games,omitempty"` //games + CreatedAt *int64 `protobuf:"varint,12,opt,name=createdAt,proto3,oneof" json:"createdAt,omitempty"` //createdAt + UpdatedAt *int64 `protobuf:"varint,13,opt,name=updatedAt,proto3,oneof" json:"updatedAt,omitempty"` //updatedAt + Gender *int64 `protobuf:"varint,14,opt,name=gender,proto3,oneof" json:"gender,omitempty"` //gender unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1554,64 +1554,64 @@ func (*SearchPlayersReq) Descriptor() ([]byte, []int) { } func (x *SearchPlayersReq) GetPage() int64 { - if x != nil { - return x.Page + if x != nil && x.Page != nil { + return *x.Page } return 0 } func (x *SearchPlayersReq) GetLimit() int64 { - if x != nil { - return x.Limit + if x != nil && x.Limit != nil { + return *x.Limit } return 0 } func (x *SearchPlayersReq) GetId() int64 { - if x != nil { - return x.Id + if x != nil && x.Id != nil { + return *x.Id } return 0 } func (x *SearchPlayersReq) GetUserId() int64 { - if x != nil { - return x.UserId + if x != nil && x.UserId != nil { + return *x.UserId } return 0 } func (x *SearchPlayersReq) GetStatus() string { - if x != nil { - return x.Status + if x != nil && x.Status != nil { + return *x.Status } return "" } func (x *SearchPlayersReq) GetRating() float64 { - if x != nil { - return x.Rating + if x != nil && x.Rating != nil { + return *x.Rating } return 0 } func (x *SearchPlayersReq) GetTotalOrders() int64 { - if x != nil { - return x.TotalOrders + if x != nil && x.TotalOrders != nil { + return *x.TotalOrders } return 0 } func (x *SearchPlayersReq) GetCompletedOrders() int64 { - if x != nil { - return x.CompletedOrders + if x != nil && x.CompletedOrders != nil { + return *x.CompletedOrders } return 0 } func (x *SearchPlayersReq) GetShopId() int64 { - if x != nil { - return x.ShopId + if x != nil && x.ShopId != nil { + return *x.ShopId } return 0 } @@ -1631,22 +1631,22 @@ func (x *SearchPlayersReq) GetGames() []int64 { } func (x *SearchPlayersReq) GetCreatedAt() int64 { - if x != nil { - return x.CreatedAt + if x != nil && x.CreatedAt != nil { + return *x.CreatedAt } return 0 } func (x *SearchPlayersReq) GetUpdatedAt() int64 { - if x != nil { - return x.UpdatedAt + if x != nil && x.UpdatedAt != nil { + return *x.UpdatedAt } return 0 } func (x *SearchPlayersReq) GetGender() int64 { - if x != nil { - return x.Gender + if x != nil && x.Gender != nil { + return *x.Gender } return 0 } @@ -1800,7 +1800,7 @@ const file_player_proto_rawDesc = "" + "\tcreatedAt\x18\n" + " \x01(\x03R\tcreatedAt\x12\x1c\n" + "\tupdatedAt\x18\v \x01(\x03R\tupdatedAt\x12\x16\n" + - "\x06gender\x18\f \x01(\x03R\x06gender\"\xb9\x02\n" + + "\x06gender\x18\f \x01(\bR\x06gender\"\xb9\x02\n" + "\rAddPlayersReq\x12\x16\n" + "\x06userId\x18\x01 \x01(\x03R\x06userId\x12\x16\n" + "\x06status\x18\x02 \x01(\tR\x06status\x12\x16\n" + @@ -1847,23 +1847,38 @@ const file_player_proto_rawDesc = "" + "\x11GetPlayersByIdReq\x12\x0e\n" + "\x02id\x18\x01 \x01(\x03R\x02id\";\n" + "\x12GetPlayersByIdResp\x12%\n" + - "\aplayers\x18\x01 \x01(\v2\v.pb.PlayersR\aplayers\"\xf6\x02\n" + - "\x10SearchPlayersReq\x12\x12\n" + - "\x04page\x18\x01 \x01(\x03R\x04page\x12\x14\n" + - "\x05limit\x18\x02 \x01(\x03R\x05limit\x12\x0e\n" + - "\x02id\x18\x03 \x01(\x03R\x02id\x12\x16\n" + - "\x06userId\x18\x04 \x01(\x03R\x06userId\x12\x16\n" + - "\x06status\x18\x05 \x01(\tR\x06status\x12\x16\n" + - "\x06rating\x18\x06 \x01(\x01R\x06rating\x12 \n" + - "\vtotalOrders\x18\a \x01(\x03R\vtotalOrders\x12(\n" + - "\x0fcompletedOrders\x18\b \x01(\x03R\x0fcompletedOrders\x12\x16\n" + - "\x06shopId\x18\t \x01(\x03R\x06shopId\x12\x12\n" + + "\aplayers\x18\x01 \x01(\v2\v.pb.PlayersR\aplayers\"\xc3\x04\n" + + "\x10SearchPlayersReq\x12\x17\n" + + "\x04page\x18\x01 \x01(\x03H\x00R\x04page\x88\x01\x01\x12\x19\n" + + "\x05limit\x18\x02 \x01(\x03H\x01R\x05limit\x88\x01\x01\x12\x13\n" + + "\x02id\x18\x03 \x01(\x03H\x02R\x02id\x88\x01\x01\x12\x1b\n" + + "\x06userId\x18\x04 \x01(\x03H\x03R\x06userId\x88\x01\x01\x12\x1b\n" + + "\x06status\x18\x05 \x01(\tH\x04R\x06status\x88\x01\x01\x12\x1b\n" + + "\x06rating\x18\x06 \x01(\x01H\x05R\x06rating\x88\x01\x01\x12%\n" + + "\vtotalOrders\x18\a \x01(\x03H\x06R\vtotalOrders\x88\x01\x01\x12-\n" + + "\x0fcompletedOrders\x18\b \x01(\x03H\aR\x0fcompletedOrders\x88\x01\x01\x12\x1b\n" + + "\x06shopId\x18\t \x01(\x03H\bR\x06shopId\x88\x01\x01\x12\x12\n" + "\x04tags\x18\n" + " \x03(\tR\x04tags\x12\x14\n" + - "\x05games\x18\v \x03(\x03R\x05games\x12\x1c\n" + - "\tcreatedAt\x18\f \x01(\x03R\tcreatedAt\x12\x1c\n" + - "\tupdatedAt\x18\r \x01(\x03R\tupdatedAt\x12\x16\n" + - "\x06gender\x18\x0e \x01(\x03R\x06gender\":\n" + + "\x05games\x18\v \x03(\x03R\x05games\x12!\n" + + "\tcreatedAt\x18\f \x01(\x03H\tR\tcreatedAt\x88\x01\x01\x12!\n" + + "\tupdatedAt\x18\r \x01(\x03H\n" + + "R\tupdatedAt\x88\x01\x01\x12\x1b\n" + + "\x06gender\x18\x0e \x01(\x03H\vR\x06gender\x88\x01\x01B\a\n" + + "\x05_pageB\b\n" + + "\x06_limitB\x05\n" + + "\x03_idB\t\n" + + "\a_userIdB\t\n" + + "\a_statusB\t\n" + + "\a_ratingB\x0e\n" + + "\f_totalOrdersB\x12\n" + + "\x10_completedOrdersB\t\n" + + "\a_shopIdB\f\n" + + "\n" + + "_createdAtB\f\n" + + "\n" + + "_updatedAtB\t\n" + + "\a_gender\":\n" + "\x11SearchPlayersResp\x12%\n" + "\aplayers\x18\x01 \x03(\v2\v.pb.PlayersR\aplayers2\xc6\x05\n" + "\rplayerService\x12H\n" + @@ -1956,6 +1971,7 @@ func file_player_proto_init() { } file_player_proto_msgTypes[3].OneofWrappers = []any{} file_player_proto_msgTypes[14].OneofWrappers = []any{} + file_player_proto_msgTypes[20].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/app/shop/api/etc/shop-api.yaml b/app/shop/api/etc/shop-api.yaml index d0e4d9a..6ecd4ff 100644 --- a/app/shop/api/etc/shop-api.yaml +++ b/app/shop/api/etc/shop-api.yaml @@ -9,6 +9,12 @@ Prometheus: # k8s://juwan/:8080 -ShopRpcConf: - Target: k8s://juwan/shop-rpc-svc.juwan:8080 +# ===== PROC CONFIG ===== +#ShopRpcConf: +# Target: k8s://juwan/shop-rpc-svc.juwan:8080 + +# ===== DEV CONFIG ==== +ShopRpcConf: + Endpoints: + - shop-rpc:8080 \ No newline at end of file diff --git a/app/shop/api/internal/handler/shop/acceptInvitationHandler.go b/app/shop/api/internal/handler/shop/acceptInvitationHandler.go index 29966d7..8f96f51 100644 --- a/app/shop/api/internal/handler/shop/acceptInvitationHandler.go +++ b/app/shop/api/internal/handler/shop/acceptInvitationHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 接受邀请 @@ -26,12 +21,7 @@ func AcceptInvitationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewAcceptInvitationLogic(ctx, svcCtx) + l := shop.NewAcceptInvitationLogic(r.Context(), svcCtx) resp, err := l.AcceptInvitation(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/addAnnouncementHandler.go b/app/shop/api/internal/handler/shop/addAnnouncementHandler.go index 7220258..bbea91e 100644 --- a/app/shop/api/internal/handler/shop/addAnnouncementHandler.go +++ b/app/shop/api/internal/handler/shop/addAnnouncementHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 新增店铺公告 @@ -26,12 +21,7 @@ func AddAnnouncementHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewAddAnnouncementLogic(ctx, svcCtx) + l := shop.NewAddAnnouncementLogic(r.Context(), svcCtx) resp, err := l.AddAnnouncement(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/createShopHandler.go b/app/shop/api/internal/handler/shop/createShopHandler.go index bcfba6b..e6635d7 100644 --- a/app/shop/api/internal/handler/shop/createShopHandler.go +++ b/app/shop/api/internal/handler/shop/createShopHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 创建店铺 @@ -26,12 +21,7 @@ func CreateShopHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewCreateShopLogic(ctx, svcCtx) + l := shop.NewCreateShopLogic(r.Context(), svcCtx) resp, err := l.CreateShop(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/deleteAnnouncementHandler.go b/app/shop/api/internal/handler/shop/deleteAnnouncementHandler.go index 9a92900..64874cd 100644 --- a/app/shop/api/internal/handler/shop/deleteAnnouncementHandler.go +++ b/app/shop/api/internal/handler/shop/deleteAnnouncementHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 删除店铺公告 @@ -26,12 +21,7 @@ func DeleteAnnouncementHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewDeleteAnnouncementLogic(ctx, svcCtx) + l := shop.NewDeleteAnnouncementLogic(r.Context(), svcCtx) resp, err := l.DeleteAnnouncement(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/getMyShopHandler.go b/app/shop/api/internal/handler/shop/getMyShopHandler.go index 2500e74..37100e4 100644 --- a/app/shop/api/internal/handler/shop/getMyShopHandler.go +++ b/app/shop/api/internal/handler/shop/getMyShopHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 获取当前用户的店铺 @@ -26,12 +21,7 @@ func GetMyShopHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewGetMyShopLogic(ctx, svcCtx) + l := shop.NewGetMyShopLogic(r.Context(), svcCtx) resp, err := l.GetMyShop(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/getShopHandler.go b/app/shop/api/internal/handler/shop/getShopHandler.go index 926579e..09f55a7 100644 --- a/app/shop/api/internal/handler/shop/getShopHandler.go +++ b/app/shop/api/internal/handler/shop/getShopHandler.go @@ -6,11 +6,10 @@ package shop import ( "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 获取店铺详情 diff --git a/app/shop/api/internal/handler/shop/getShopIncomeStatsHandler.go b/app/shop/api/internal/handler/shop/getShopIncomeStatsHandler.go index 08dda35..6fb867c 100644 --- a/app/shop/api/internal/handler/shop/getShopIncomeStatsHandler.go +++ b/app/shop/api/internal/handler/shop/getShopIncomeStatsHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 获取收入统计 @@ -26,12 +21,7 @@ func GetShopIncomeStatsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewGetShopIncomeStatsLogic(ctx, svcCtx) + l := shop.NewGetShopIncomeStatsLogic(r.Context(), svcCtx) resp, err := l.GetShopIncomeStats(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/getUserShopHandler.go b/app/shop/api/internal/handler/shop/getUserShopHandler.go index 1c2ab18..9701aa7 100644 --- a/app/shop/api/internal/handler/shop/getUserShopHandler.go +++ b/app/shop/api/internal/handler/shop/getUserShopHandler.go @@ -6,11 +6,10 @@ package shop import ( "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 获取店长的店铺 diff --git a/app/shop/api/internal/handler/shop/invitePlayerHandler.go b/app/shop/api/internal/handler/shop/invitePlayerHandler.go index 99f1bff..2d124af 100644 --- a/app/shop/api/internal/handler/shop/invitePlayerHandler.go +++ b/app/shop/api/internal/handler/shop/invitePlayerHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 邀请打手 @@ -26,12 +21,7 @@ func InvitePlayerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewInvitePlayerLogic(ctx, svcCtx) + l := shop.NewInvitePlayerLogic(r.Context(), svcCtx) resp, err := l.InvitePlayer(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/rejectInvitationHandler.go b/app/shop/api/internal/handler/shop/rejectInvitationHandler.go index a80fa22..989f8b1 100644 --- a/app/shop/api/internal/handler/shop/rejectInvitationHandler.go +++ b/app/shop/api/internal/handler/shop/rejectInvitationHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 拒绝邀请 @@ -26,12 +21,7 @@ func RejectInvitationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewRejectInvitationLogic(ctx, svcCtx) + l := shop.NewRejectInvitationLogic(r.Context(), svcCtx) resp, err := l.RejectInvitation(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/removePlayerHandler.go b/app/shop/api/internal/handler/shop/removePlayerHandler.go index 544589c..ba87605 100644 --- a/app/shop/api/internal/handler/shop/removePlayerHandler.go +++ b/app/shop/api/internal/handler/shop/removePlayerHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 移除打手 @@ -26,12 +21,7 @@ func RemovePlayerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewRemovePlayerLogic(ctx, svcCtx) + l := shop.NewRemovePlayerLogic(r.Context(), svcCtx) resp, err := l.RemovePlayer(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/updateShopHandler.go b/app/shop/api/internal/handler/shop/updateShopHandler.go index 2e82873..8a519ed 100644 --- a/app/shop/api/internal/handler/shop/updateShopHandler.go +++ b/app/shop/api/internal/handler/shop/updateShopHandler.go @@ -4,10 +4,6 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" "juwan-backend/app/shop/api/internal/logic/shop" @@ -26,12 +22,7 @@ func UpdateShopHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewUpdateShopLogic(ctx, svcCtx) + l := shop.NewUpdateShopLogic(r.Context(), svcCtx) resp, err := l.UpdateShop(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/handler/shop/updateShopTemplateHandler.go b/app/shop/api/internal/handler/shop/updateShopTemplateHandler.go index 2906f93..08b9e6f 100644 --- a/app/shop/api/internal/handler/shop/updateShopTemplateHandler.go +++ b/app/shop/api/internal/handler/shop/updateShopTemplateHandler.go @@ -4,17 +4,12 @@ package shop import ( - "errors" - "juwan-backend/common/utils/contextj" - "juwan-backend/common/utils/httpj" - "juwan-backend/common/utils/responses" "net/http" + "github.com/zeromicro/go-zero/rest/httpx" "juwan-backend/app/shop/api/internal/logic/shop" "juwan-backend/app/shop/api/internal/svc" "juwan-backend/app/shop/api/internal/types" - - "github.com/zeromicro/go-zero/rest/httpx" ) // 更新店铺模板 @@ -26,12 +21,7 @@ func UpdateShopTemplateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - userId, err := httpj.GetUserIdFromHeader(r.Header) - if err != nil { - httpx.ErrorCtx(r.Context(), w, responses.NewErrorResp(403, errors.New("forbidden: user not authenticated"))) - } - ctx := contextj.WithUserID(r.Context(), userId) - l := shop.NewUpdateShopTemplateLogic(ctx, svcCtx) + l := shop.NewUpdateShopTemplateLogic(r.Context(), svcCtx) resp, err := l.UpdateShopTemplate(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/app/shop/api/internal/logic/shop/createShopLogic.go b/app/shop/api/internal/logic/shop/createShopLogic.go index 143c954..b4a0756 100644 --- a/app/shop/api/internal/logic/shop/createShopLogic.go +++ b/app/shop/api/internal/logic/shop/createShopLogic.go @@ -36,6 +36,9 @@ func (l *CreateShopLogic) CreateShop(req *types.CreateShopReq) (resp *types.Shop if err != nil { return nil, err } + if ownerID == 0 { + return nil, errors.New("user not authenticated") + } if req.Name == "" { return nil, errors.New("name is required") diff --git a/app/shop/api/internal/logic/shop/updateShopLogic.go b/app/shop/api/internal/logic/shop/updateShopLogic.go index 39ab6e7..b4b9915 100644 --- a/app/shop/api/internal/logic/shop/updateShopLogic.go +++ b/app/shop/api/internal/logic/shop/updateShopLogic.go @@ -46,6 +46,7 @@ func (l *UpdateShopLogic) UpdateShop(req *types.UpdateShopReq) (resp *types.Shop if current.Shops.OwnerId != userID { return nil, contextj.ERRILLEGALUSER } + logx.Debugf("update shop %+v", req) name := current.Shops.Name if req.Name != "" { diff --git a/app/shop/api/internal/svc/serviceContext.go b/app/shop/api/internal/svc/serviceContext.go index 73ee5ec..c8a407e 100644 --- a/app/shop/api/internal/svc/serviceContext.go +++ b/app/shop/api/internal/svc/serviceContext.go @@ -6,18 +6,22 @@ package svc import ( "juwan-backend/app/shop/api/internal/config" "juwan-backend/app/shop/rpc/shopservice" + "juwan-backend/common/middlewares" + "github.com/zeromicro/go-zero/rest" "github.com/zeromicro/go-zero/zrpc" ) type ServiceContext struct { - Config config.Config - ShopRpc shopservice.ShopService + Config config.Config + ShopRpc shopservice.ShopService + HeaderExtractorMiddleware rest.Middleware } func NewServiceContext(c config.Config) *ServiceContext { return &ServiceContext{ - Config: c, - ShopRpc: shopservice.NewShopService(zrpc.MustNewClient(c.ShopRpcConf)), + Config: c, + ShopRpc: shopservice.NewShopService(zrpc.MustNewClient(c.ShopRpcConf)), + HeaderExtractorMiddleware: middlewares.NewHeaderExtractorMiddleware().Handle, } } diff --git a/app/shop/api/shop.go b/app/shop/api/shop.go index 889504e..02812c6 100644 --- a/app/shop/api/shop.go +++ b/app/shop/api/shop.go @@ -6,6 +6,7 @@ package main import ( "flag" "fmt" + "juwan-backend/common/middlewares" "juwan-backend/app/shop/api/internal/config" "juwan-backend/app/shop/api/internal/handler" @@ -24,6 +25,8 @@ func main() { conf.MustLoad(*configFile, &c) server := rest.MustNewServer(c.RestConf) + server.Use(middlewares.NewHeaderExtractorMiddleware().Handle) + server.Use(middlewares.NewRequestMiddleware().Handle) defer server.Stop() ctx := svc.NewServiceContext(c) diff --git a/app/shop/rpc/etc/pb.yaml b/app/shop/rpc/etc/pb.yaml index 32ca1f7..706de36 100644 --- a/app/shop/rpc/etc/pb.yaml +++ b/app/shop/rpc/etc/pb.yaml @@ -1,7 +1,6 @@ Name: pb.rpc ListenOn: 0.0.0.0:8080 - Prometheus: Host: 0.0.0.0 Port: 4001 @@ -12,26 +11,49 @@ Prometheus: # - 127.0.0.1:2379 # Key: pb.rpc -# Target: k8s://juwan/.:8080 +# ===== PROC Config ===== +#SnowflakeRpcConf: +# Target: k8s://juwan/snowflake-svc:8080 +#UsersRpcConf: +# Target: k8s://juwan/user-rpc-svc:8080 +#DB: +# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@{DB_HOST_RW}.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@{BD_HOST_RO}.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# +# +#CacheConf: +# - Host: "${REDIS_M_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# - Host: "${REDIS_S_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" + +# ===== DEV Config ===== SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc:8080 - + Endpoints: + - snowflake:8080 + - +UsersRpcConf: + Endpoints: + - user-rpc:8080 DB: - Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - + Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" CacheConf: - - Host: "${REDIS_M_HOST}" + - Host: "${REDIS_HOST}:${REDIS_PORT}" Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" - - Host: "${REDIS_S_HOST}" - Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" Log: Level: info + + +# Target: k8s://juwan/.:8080 +#DB: +# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" diff --git a/app/shop/rpc/internal/config/config.go b/app/shop/rpc/internal/config/config.go index 99ce632..cb32a6a 100644 --- a/app/shop/rpc/internal/config/config.go +++ b/app/shop/rpc/internal/config/config.go @@ -8,6 +8,7 @@ import ( type Config struct { zrpc.RpcServerConf SnowflakeRpcConf zrpc.RpcClientConf + UsersRpcConf zrpc.RpcClientConf DB struct { Master string Slaves string diff --git a/app/shop/rpc/internal/logic/addShopsLogic.go b/app/shop/rpc/internal/logic/addShopsLogic.go index bab435f..6a2cefe 100644 --- a/app/shop/rpc/internal/logic/addShopsLogic.go +++ b/app/shop/rpc/internal/logic/addShopsLogic.go @@ -4,7 +4,11 @@ import ( "context" "encoding/json" "errors" + "juwan-backend/app/shop/rpc/internal/models/schema" "juwan-backend/app/snowflake/rpc/snowflake" + pb2 "juwan-backend/app/users/rpc/pb" + "slices" + "strings" "juwan-backend/app/shop/rpc/internal/svc" "juwan-backend/app/shop/rpc/pb" @@ -27,8 +31,25 @@ func NewAddShopsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddShops } } +var allowedRoles = []string{"owner", "admin"} +var allowedCommissionTypes = []string{"fixed", "percentage"} +var allowedDispatchModes = []string{"manual", "auto"} + // -----------------------shops----------------------- func (l *AddShopsLogic) AddShops(in *pb.AddShopsReq) (*pb.AddShopsResp, error) { + user, err := l.svcCtx.UsersRpc.GetUsersById(l.ctx, &pb2.GetUsersByIdReq{ + Id: in.OwnerId, + }) + if err != nil { + logx.Errorf("add shops err: %v", err) + return nil, errors.New("user not found") + } + + if !slices.Contains(allowedRoles, user.Users.CurrentRole) { + logx.Errorf("add shops err: user %v has no permission to add shop", in.OwnerId) + return nil, errors.New("no permission to add shop") + } + idResp, err := l.svcCtx.Snowflake.NextId(l.ctx, &snowflake.NextIdReq{}) if err != nil { logx.Errorf("addPlayerServices err:%v", err) @@ -44,28 +65,53 @@ func (l *AddShopsLogic) AddShops(in *pb.AddShopsReq) (*pb.AddShopsResp, error) { rating, err := decimal.NewFromString(in.Rating) if err != nil { + logx.Errorf("addPlayerServices new from string err:%v", err) return nil, errors.New("invalid rating") } commissionValue, err := decimal.NewFromString(in.CommissionValue) if err != nil { + logx.Errorf("addPlayerServices new from string err:%v", err) return nil, errors.New("invalid commissionValue") } - _, err = l.svcCtx.ShopModelRO.Shops.Create(). + commissionType := strings.ToLower(strings.TrimSpace(in.CommissionType)) + if commissionType == "" { + commissionType = "percentage" + } + if !slices.Contains(allowedCommissionTypes, commissionType) { + logx.Errorf("addPlayerServices contains err: invalid commissionType %v", in.CommissionType) + return nil, errors.New("invalid commissionType") + } + + dispatchMode := strings.ToLower(strings.TrimSpace(in.DispatchMode)) + if dispatchMode == "" { + dispatchMode = "manual" + } + if !slices.Contains(allowedDispatchModes, dispatchMode) { + logx.Errorf("addPlayerServices contains err: invalid dispatchMode %v", in.DispatchMode) + return nil, errors.New("invalid dispatchMode") + } + + announcements := schema.TextArray{Elements: in.Announcements, Valid: true} + if announcements.Elements == nil { + announcements.Elements = []string{} + } + + _, err = l.svcCtx.ShopModelRW.Shops.Create(). SetID(idResp.Id). - SetOwnerID(in.OwnerId). + SetOwnerID(idResp.Id). SetName(in.Name). SetBanner(in.Banner). SetDescription(in.Description). SetRating(rating). SetTotalOrders(int(in.TotalOrders)). SetPlayerCount(int(in.PlayerCount)). - SetNillableCommissionType(&in.CommissionType). + SetCommissionType(commissionType). SetCommissionValue(commissionValue). SetAllowMultiShop(in.AllowMultiShop). SetAllowIndependentOrders(in.AllowIndependentOrders). - SetDispatchMode(in.DispatchMode). - SetAnnouncements(in.Announcements). + SetDispatchMode(dispatchMode). + SetAnnouncements(announcements). SetTemplateConfig(templateConfig). Save(l.ctx) @@ -73,5 +119,6 @@ func (l *AddShopsLogic) AddShops(in *pb.AddShopsReq) (*pb.AddShopsResp, error) { logx.Errorf("addPlayerServices err:%v", err) return nil, errors.New("add player service failed") } + logx.Debugf("shop created with id: %v", idResp.Id) return &pb.AddShopsResp{}, nil } diff --git a/app/shop/rpc/internal/logic/getShopsByIdLogic.go b/app/shop/rpc/internal/logic/getShopsByIdLogic.go index df61adb..c062efa 100644 --- a/app/shop/rpc/internal/logic/getShopsByIdLogic.go +++ b/app/shop/rpc/internal/logic/getShopsByIdLogic.go @@ -51,7 +51,7 @@ func (l *GetShopsByIdLogic) GetShopsById(in *pb.GetShopsByIdReq) (*pb.GetShopsBy AllowMultiShop: shop.AllowMultiShop, AllowIndependentOrders: shop.AllowIndependentOrders, DispatchMode: shop.DispatchMode, - Announcements: shop.Announcements, + Announcements: shop.Announcements.Elements, TemplateConfig: string(templateConfigBytes), CreatedAt: shop.CreatedAt.Unix(), UpdatedAt: shop.UpdatedAt.Unix(), diff --git a/app/shop/rpc/internal/logic/searchShopsLogic.go b/app/shop/rpc/internal/logic/searchShopsLogic.go index 75bf403..6e23343 100644 --- a/app/shop/rpc/internal/logic/searchShopsLogic.go +++ b/app/shop/rpc/internal/logic/searchShopsLogic.go @@ -124,7 +124,7 @@ func (l *SearchShopsLogic) SearchShops(in *pb.SearchShopsReq) (*pb.SearchShopsRe AllowMultiShop: item.AllowMultiShop, AllowIndependentOrders: item.AllowIndependentOrders, DispatchMode: item.DispatchMode, - Announcements: item.Announcements, + Announcements: item.Announcements.Elements, TemplateConfig: string(templateConfigBytes), CreatedAt: item.CreatedAt.Unix(), UpdatedAt: item.UpdatedAt.Unix(), diff --git a/app/shop/rpc/internal/logic/updateShopsLogic.go b/app/shop/rpc/internal/logic/updateShopsLogic.go index 95f7e01..7e5a2ac 100644 --- a/app/shop/rpc/internal/logic/updateShopsLogic.go +++ b/app/shop/rpc/internal/logic/updateShopsLogic.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "errors" + "juwan-backend/app/shop/rpc/internal/models/schema" "juwan-backend/app/shop/rpc/internal/models/shops" "time" @@ -75,7 +76,7 @@ func (l *UpdateShopsLogic) UpdateShops(in *pb.UpdateShopsReq) (*pb.UpdateShopsRe SetAllowIndependentOrders(in.AllowIndependentOrders) if len(in.Announcements) > 0 { - updater = updater.SetAnnouncements(in.Announcements) + updater = updater.SetAnnouncements(schema.TextArray{Elements: in.Announcements, Valid: true}) } if in.TemplateConfig != "" { diff --git a/app/shop/rpc/internal/models/migrate/schema.go b/app/shop/rpc/internal/models/migrate/schema.go index 687937b..891e368 100644 --- a/app/shop/rpc/internal/models/migrate/schema.go +++ b/app/shop/rpc/internal/models/migrate/schema.go @@ -94,7 +94,7 @@ var ( {Name: "allow_multi_shop", Type: field.TypeBool, Nullable: true, Default: false}, {Name: "allow_independent_orders", Type: field.TypeBool, Nullable: true, Default: true}, {Name: "dispatch_mode", Type: field.TypeString, Size: 20, Default: "manual"}, - {Name: "announcements", Type: field.TypeJSON, Nullable: true}, + {Name: "announcements", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"postgres": "text[]"}}, {Name: "template_config", Type: field.TypeJSON, Nullable: true}, {Name: "created_at", Type: field.TypeTime}, {Name: "updated_at", Type: field.TypeTime}, diff --git a/app/shop/rpc/internal/models/mutation.go b/app/shop/rpc/internal/models/mutation.go index 68ebac4..3683ef2 100644 --- a/app/shop/rpc/internal/models/mutation.go +++ b/app/shop/rpc/internal/models/mutation.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "juwan-backend/app/shop/rpc/internal/models/predicate" + "juwan-backend/app/shop/rpc/internal/models/schema" "juwan-backend/app/shop/rpc/internal/models/shopinvitations" "juwan-backend/app/shop/rpc/internal/models/shopplayers" "juwan-backend/app/shop/rpc/internal/models/shops" @@ -1437,8 +1438,7 @@ type ShopsMutation struct { allow_multi_shop *bool allow_independent_orders *bool dispatch_mode *string - announcements *[]string - appendannouncements []string + announcements *schema.TextArray template_config *map[string]interface{} created_at *time.Time updated_at *time.Time @@ -2138,13 +2138,12 @@ func (m *ShopsMutation) ResetDispatchMode() { } // SetAnnouncements sets the "announcements" field. -func (m *ShopsMutation) SetAnnouncements(s []string) { - m.announcements = &s - m.appendannouncements = nil +func (m *ShopsMutation) SetAnnouncements(sa schema.TextArray) { + m.announcements = &sa } // Announcements returns the value of the "announcements" field in the mutation. -func (m *ShopsMutation) Announcements() (r []string, exists bool) { +func (m *ShopsMutation) Announcements() (r schema.TextArray, exists bool) { v := m.announcements if v == nil { return @@ -2155,7 +2154,7 @@ func (m *ShopsMutation) Announcements() (r []string, exists bool) { // OldAnnouncements returns the old "announcements" field's value of the Shops entity. // If the Shops object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *ShopsMutation) OldAnnouncements(ctx context.Context) (v []string, err error) { +func (m *ShopsMutation) OldAnnouncements(ctx context.Context) (v schema.TextArray, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldAnnouncements is only allowed on UpdateOne operations") } @@ -2169,23 +2168,9 @@ func (m *ShopsMutation) OldAnnouncements(ctx context.Context) (v []string, err e return oldValue.Announcements, nil } -// AppendAnnouncements adds s to the "announcements" field. -func (m *ShopsMutation) AppendAnnouncements(s []string) { - m.appendannouncements = append(m.appendannouncements, s...) -} - -// AppendedAnnouncements returns the list of values that were appended to the "announcements" field in this mutation. -func (m *ShopsMutation) AppendedAnnouncements() ([]string, bool) { - if len(m.appendannouncements) == 0 { - return nil, false - } - return m.appendannouncements, true -} - // ClearAnnouncements clears the value of the "announcements" field. func (m *ShopsMutation) ClearAnnouncements() { m.announcements = nil - m.appendannouncements = nil m.clearedFields[shops.FieldAnnouncements] = struct{}{} } @@ -2198,7 +2183,6 @@ func (m *ShopsMutation) AnnouncementsCleared() bool { // ResetAnnouncements resets all changes to the "announcements" field. func (m *ShopsMutation) ResetAnnouncements() { m.announcements = nil - m.appendannouncements = nil delete(m.clearedFields, shops.FieldAnnouncements) } @@ -2581,7 +2565,7 @@ func (m *ShopsMutation) SetField(name string, value ent.Value) error { m.SetDispatchMode(v) return nil case shops.FieldAnnouncements: - v, ok := value.([]string) + v, ok := value.(schema.TextArray) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } diff --git a/app/shop/rpc/internal/models/runtime.go b/app/shop/rpc/internal/models/runtime.go index c4c9bdb..a067a97 100644 --- a/app/shop/rpc/internal/models/runtime.go +++ b/app/shop/rpc/internal/models/runtime.go @@ -76,10 +76,6 @@ func init() { shops.DefaultDispatchMode = shopsDescDispatchMode.Default.(string) // shops.DispatchModeValidator is a validator for the "dispatch_mode" field. It is called by the builders before save. shops.DispatchModeValidator = shopsDescDispatchMode.Validators[0].(func(string) error) - // shopsDescAnnouncements is the schema descriptor for announcements field. - shopsDescAnnouncements := shopsFields[13].Descriptor() - // shops.DefaultAnnouncements holds the default value on creation for the announcements field. - shops.DefaultAnnouncements = shopsDescAnnouncements.Default.([]string) // shopsDescCreatedAt is the schema descriptor for created_at field. shopsDescCreatedAt := shopsFields[15].Descriptor() // shops.DefaultCreatedAt holds the default value on creation for the created_at field. diff --git a/app/shop/rpc/internal/models/schema/shops.go b/app/shop/rpc/internal/models/schema/shops.go index e4a4c5c..a6190fd 100644 --- a/app/shop/rpc/internal/models/schema/shops.go +++ b/app/shop/rpc/internal/models/schema/shops.go @@ -1,6 +1,9 @@ package schema import ( + "database/sql/driver" + "errors" + "strings" "time" "entgo.io/ent" @@ -8,11 +11,53 @@ import ( "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema" "entgo.io/ent/schema/field" + "github.com/jackc/pgx/v5/pgtype" "github.com/shopspring/decimal" ) var shopDefaultRating = decimal.RequireFromString("5.00") +type TextArray pgtype.Array[string] + +func (s *TextArray) Scan(src any) error { + if src == nil { + s.Elements = []string{} + s.Dims = nil + s.Valid = true + return nil + } + + var strSrc string + switch v := src.(type) { + case string: + strSrc = v + case []byte: + strSrc = string(v) + default: + return errors.New("failed to scan text array") + } + + trimmed := strings.Trim(strSrc, "{}") + if len(trimmed) == 0 { + s.Elements = []string{} + s.Dims = nil + s.Valid = true + return nil + } + + s.Elements = strings.Split(trimmed, ",") + s.Dims = nil + s.Valid = true + return nil +} + +func (s TextArray) Value() (driver.Value, error) { + if s.Elements == nil { + return []string{}, nil + } + return s.Elements, nil +} + // Shops holds the schema definition for the Shops entity. type Shops struct { ent.Schema @@ -56,7 +101,9 @@ func (Shops) Fields() []ent.Field { field.Bool("allow_multi_shop").Optional().Default(false), field.Bool("allow_independent_orders").Optional().Default(true), field.String("dispatch_mode").MaxLen(20).Default("manual"), - field.Strings("announcements").Optional().Default([]string{}), + field.Other("announcements", TextArray{}). + SchemaType(map[string]string{dialect.Postgres: "text[]"}). + Optional(), field.JSON("template_config", map[string]any{}).Optional(), field.Time("created_at").Default(time.Now).Immutable(), field.Time("updated_at").Default(time.Now).UpdateDefault(time.Now), diff --git a/app/shop/rpc/internal/models/shops.go b/app/shop/rpc/internal/models/shops.go index 2c4d101..6ed7e5d 100644 --- a/app/shop/rpc/internal/models/shops.go +++ b/app/shop/rpc/internal/models/shops.go @@ -5,6 +5,7 @@ package models import ( "encoding/json" "fmt" + "juwan-backend/app/shop/rpc/internal/models/schema" "juwan-backend/app/shop/rpc/internal/models/shops" "strings" "time" @@ -44,7 +45,7 @@ type Shops struct { // DispatchMode holds the value of the "dispatch_mode" field. DispatchMode string `json:"dispatch_mode,omitempty"` // Announcements holds the value of the "announcements" field. - Announcements []string `json:"announcements,omitempty"` + Announcements schema.TextArray `json:"announcements,omitempty"` // TemplateConfig holds the value of the "template_config" field. TemplateConfig map[string]interface{} `json:"template_config,omitempty"` // CreatedAt holds the value of the "created_at" field. @@ -59,10 +60,12 @@ func (*Shops) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case shops.FieldAnnouncements, shops.FieldTemplateConfig: + case shops.FieldTemplateConfig: values[i] = new([]byte) case shops.FieldRating, shops.FieldCommissionValue: values[i] = new(decimal.Decimal) + case shops.FieldAnnouncements: + values[i] = new(schema.TextArray) case shops.FieldAllowMultiShop, shops.FieldAllowIndependentOrders: values[i] = new(sql.NullBool) case shops.FieldID, shops.FieldOwnerID, shops.FieldTotalOrders, shops.FieldPlayerCount: @@ -167,12 +170,10 @@ func (_m *Shops) assignValues(columns []string, values []any) error { _m.DispatchMode = value.String } case shops.FieldAnnouncements: - if value, ok := values[i].(*[]byte); !ok { + if value, ok := values[i].(*schema.TextArray); !ok { return fmt.Errorf("unexpected type %T for field announcements", values[i]) - } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &_m.Announcements); err != nil { - return fmt.Errorf("unmarshal field announcements: %w", err) - } + } else if value != nil { + _m.Announcements = *value } case shops.FieldTemplateConfig: if value, ok := values[i].(*[]byte); !ok { diff --git a/app/shop/rpc/internal/models/shops/shops.go b/app/shop/rpc/internal/models/shops/shops.go index cf0fa22..3871465 100644 --- a/app/shop/rpc/internal/models/shops/shops.go +++ b/app/shop/rpc/internal/models/shops/shops.go @@ -102,8 +102,6 @@ var ( DefaultDispatchMode string // DispatchModeValidator is a validator for the "dispatch_mode" field. It is called by the builders before save. DispatchModeValidator func(string) error - // DefaultAnnouncements holds the default value on creation for the "announcements" field. - DefaultAnnouncements []string // DefaultCreatedAt holds the default value on creation for the "created_at" field. DefaultCreatedAt func() time.Time // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. @@ -180,6 +178,11 @@ func ByDispatchMode(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldDispatchMode, opts...).ToFunc() } +// ByAnnouncements orders the results by the announcements field. +func ByAnnouncements(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAnnouncements, opts...).ToFunc() +} + // ByCreatedAt orders the results by the created_at field. func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() diff --git a/app/shop/rpc/internal/models/shops/where.go b/app/shop/rpc/internal/models/shops/where.go index 13072b8..8c67acb 100644 --- a/app/shop/rpc/internal/models/shops/where.go +++ b/app/shop/rpc/internal/models/shops/where.go @@ -4,6 +4,7 @@ package shops import ( "juwan-backend/app/shop/rpc/internal/models/predicate" + "juwan-backend/app/shop/rpc/internal/models/schema" "time" "entgo.io/ent/dialect/sql" @@ -115,6 +116,11 @@ func DispatchMode(v string) predicate.Shops { return predicate.Shops(sql.FieldEQ(FieldDispatchMode, v)) } +// Announcements applies equality check predicate on the "announcements" field. It's identical to AnnouncementsEQ. +func Announcements(v schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldEQ(FieldAnnouncements, v)) +} + // CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. func CreatedAt(v time.Time) predicate.Shops { return predicate.Shops(sql.FieldEQ(FieldCreatedAt, v)) @@ -740,6 +746,46 @@ func DispatchModeContainsFold(v string) predicate.Shops { return predicate.Shops(sql.FieldContainsFold(FieldDispatchMode, v)) } +// AnnouncementsEQ applies the EQ predicate on the "announcements" field. +func AnnouncementsEQ(v schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldEQ(FieldAnnouncements, v)) +} + +// AnnouncementsNEQ applies the NEQ predicate on the "announcements" field. +func AnnouncementsNEQ(v schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldNEQ(FieldAnnouncements, v)) +} + +// AnnouncementsIn applies the In predicate on the "announcements" field. +func AnnouncementsIn(vs ...schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldIn(FieldAnnouncements, vs...)) +} + +// AnnouncementsNotIn applies the NotIn predicate on the "announcements" field. +func AnnouncementsNotIn(vs ...schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldNotIn(FieldAnnouncements, vs...)) +} + +// AnnouncementsGT applies the GT predicate on the "announcements" field. +func AnnouncementsGT(v schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldGT(FieldAnnouncements, v)) +} + +// AnnouncementsGTE applies the GTE predicate on the "announcements" field. +func AnnouncementsGTE(v schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldGTE(FieldAnnouncements, v)) +} + +// AnnouncementsLT applies the LT predicate on the "announcements" field. +func AnnouncementsLT(v schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldLT(FieldAnnouncements, v)) +} + +// AnnouncementsLTE applies the LTE predicate on the "announcements" field. +func AnnouncementsLTE(v schema.TextArray) predicate.Shops { + return predicate.Shops(sql.FieldLTE(FieldAnnouncements, v)) +} + // AnnouncementsIsNil applies the IsNil predicate on the "announcements" field. func AnnouncementsIsNil() predicate.Shops { return predicate.Shops(sql.FieldIsNull(FieldAnnouncements)) diff --git a/app/shop/rpc/internal/models/shops_create.go b/app/shop/rpc/internal/models/shops_create.go index 79da509..76ae60b 100644 --- a/app/shop/rpc/internal/models/shops_create.go +++ b/app/shop/rpc/internal/models/shops_create.go @@ -6,6 +6,7 @@ import ( "context" "errors" "fmt" + "juwan-backend/app/shop/rpc/internal/models/schema" "juwan-backend/app/shop/rpc/internal/models/shops" "time" @@ -166,11 +167,19 @@ func (_c *ShopsCreate) SetNillableDispatchMode(v *string) *ShopsCreate { } // SetAnnouncements sets the "announcements" field. -func (_c *ShopsCreate) SetAnnouncements(v []string) *ShopsCreate { +func (_c *ShopsCreate) SetAnnouncements(v schema.TextArray) *ShopsCreate { _c.mutation.SetAnnouncements(v) return _c } +// SetNillableAnnouncements sets the "announcements" field if the given value is not nil. +func (_c *ShopsCreate) SetNillableAnnouncements(v *schema.TextArray) *ShopsCreate { + if v != nil { + _c.SetAnnouncements(*v) + } + return _c +} + // SetTemplateConfig sets the "template_config" field. func (_c *ShopsCreate) SetTemplateConfig(v map[string]interface{}) *ShopsCreate { _c.mutation.SetTemplateConfig(v) @@ -274,10 +283,6 @@ func (_c *ShopsCreate) defaults() { v := shops.DefaultDispatchMode _c.mutation.SetDispatchMode(v) } - if _, ok := _c.mutation.Announcements(); !ok { - v := shops.DefaultAnnouncements - _c.mutation.SetAnnouncements(v) - } if _, ok := _c.mutation.CreatedAt(); !ok { v := shops.DefaultCreatedAt() _c.mutation.SetCreatedAt(v) @@ -407,7 +412,7 @@ func (_c *ShopsCreate) createSpec() (*Shops, *sqlgraph.CreateSpec) { _node.DispatchMode = value } if value, ok := _c.mutation.Announcements(); ok { - _spec.SetField(shops.FieldAnnouncements, field.TypeJSON, value) + _spec.SetField(shops.FieldAnnouncements, field.TypeOther, value) _node.Announcements = value } if value, ok := _c.mutation.TemplateConfig(); ok { diff --git a/app/shop/rpc/internal/models/shops_update.go b/app/shop/rpc/internal/models/shops_update.go index b0282d9..10dbea6 100644 --- a/app/shop/rpc/internal/models/shops_update.go +++ b/app/shop/rpc/internal/models/shops_update.go @@ -7,12 +7,12 @@ import ( "errors" "fmt" "juwan-backend/app/shop/rpc/internal/models/predicate" + "juwan-backend/app/shop/rpc/internal/models/schema" "juwan-backend/app/shop/rpc/internal/models/shops" "time" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" "github.com/shopspring/decimal" ) @@ -262,14 +262,16 @@ func (_u *ShopsUpdate) SetNillableDispatchMode(v *string) *ShopsUpdate { } // SetAnnouncements sets the "announcements" field. -func (_u *ShopsUpdate) SetAnnouncements(v []string) *ShopsUpdate { +func (_u *ShopsUpdate) SetAnnouncements(v schema.TextArray) *ShopsUpdate { _u.mutation.SetAnnouncements(v) return _u } -// AppendAnnouncements appends value to the "announcements" field. -func (_u *ShopsUpdate) AppendAnnouncements(v []string) *ShopsUpdate { - _u.mutation.AppendAnnouncements(v) +// SetNillableAnnouncements sets the "announcements" field if the given value is not nil. +func (_u *ShopsUpdate) SetNillableAnnouncements(v *schema.TextArray) *ShopsUpdate { + if v != nil { + _u.SetAnnouncements(*v) + } return _u } @@ -437,15 +439,10 @@ func (_u *ShopsUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(shops.FieldDispatchMode, field.TypeString, value) } if value, ok := _u.mutation.Announcements(); ok { - _spec.SetField(shops.FieldAnnouncements, field.TypeJSON, value) - } - if value, ok := _u.mutation.AppendedAnnouncements(); ok { - _spec.AddModifier(func(u *sql.UpdateBuilder) { - sqljson.Append(u, shops.FieldAnnouncements, value) - }) + _spec.SetField(shops.FieldAnnouncements, field.TypeOther, value) } if _u.mutation.AnnouncementsCleared() { - _spec.ClearField(shops.FieldAnnouncements, field.TypeJSON) + _spec.ClearField(shops.FieldAnnouncements, field.TypeOther) } if value, ok := _u.mutation.TemplateConfig(); ok { _spec.SetField(shops.FieldTemplateConfig, field.TypeJSON, value) @@ -708,14 +705,16 @@ func (_u *ShopsUpdateOne) SetNillableDispatchMode(v *string) *ShopsUpdateOne { } // SetAnnouncements sets the "announcements" field. -func (_u *ShopsUpdateOne) SetAnnouncements(v []string) *ShopsUpdateOne { +func (_u *ShopsUpdateOne) SetAnnouncements(v schema.TextArray) *ShopsUpdateOne { _u.mutation.SetAnnouncements(v) return _u } -// AppendAnnouncements appends value to the "announcements" field. -func (_u *ShopsUpdateOne) AppendAnnouncements(v []string) *ShopsUpdateOne { - _u.mutation.AppendAnnouncements(v) +// SetNillableAnnouncements sets the "announcements" field if the given value is not nil. +func (_u *ShopsUpdateOne) SetNillableAnnouncements(v *schema.TextArray) *ShopsUpdateOne { + if v != nil { + _u.SetAnnouncements(*v) + } return _u } @@ -913,15 +912,10 @@ func (_u *ShopsUpdateOne) sqlSave(ctx context.Context) (_node *Shops, err error) _spec.SetField(shops.FieldDispatchMode, field.TypeString, value) } if value, ok := _u.mutation.Announcements(); ok { - _spec.SetField(shops.FieldAnnouncements, field.TypeJSON, value) - } - if value, ok := _u.mutation.AppendedAnnouncements(); ok { - _spec.AddModifier(func(u *sql.UpdateBuilder) { - sqljson.Append(u, shops.FieldAnnouncements, value) - }) + _spec.SetField(shops.FieldAnnouncements, field.TypeOther, value) } if _u.mutation.AnnouncementsCleared() { - _spec.ClearField(shops.FieldAnnouncements, field.TypeJSON) + _spec.ClearField(shops.FieldAnnouncements, field.TypeOther) } if value, ok := _u.mutation.TemplateConfig(); ok { _spec.SetField(shops.FieldTemplateConfig, field.TypeJSON, value) diff --git a/app/shop/rpc/internal/svc/serviceContext.go b/app/shop/rpc/internal/svc/serviceContext.go index 61f2931..e2b6708 100644 --- a/app/shop/rpc/internal/svc/serviceContext.go +++ b/app/shop/rpc/internal/svc/serviceContext.go @@ -1,10 +1,12 @@ package svc import ( + stdsql "database/sql" "fmt" "juwan-backend/app/shop/rpc/internal/config" "juwan-backend/app/shop/rpc/internal/models" "juwan-backend/app/snowflake/rpc/snowflake" + "juwan-backend/app/users/rpc/usercenter" "juwan-backend/common/redisx" "juwan-backend/common/snowflakex" "juwan-backend/pkg/adapter" @@ -12,27 +14,32 @@ import ( "time" "ariga.io/entcache" + "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" _ "github.com/jackc/pgx/v5/stdlib" "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/zrpc" ) type ServiceContext struct { Config config.Config Snowflake snowflake.SnowflakeServiceClient + UsersRpc usercenter.Usercenter ShopModelRW *models.Client ShopModelRO *models.Client } func NewServiceContext(c config.Config) *ServiceContext { - RWConn, err := sql.Open("pgx", c.DB.Master) + rawRW, err := stdsql.Open("pgx", c.DB.Master) if err != nil { panic(err) } - ROConn, err := sql.Open("pgx", c.DB.Slaves) + rawRO, err := stdsql.Open("pgx", c.DB.Slaves) if err != nil { panic(err) } + RWConn := sql.OpenDB(dialect.Postgres, rawRW) + ROConn := sql.OpenDB(dialect.Postgres, rawRO) redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second) if redisCluster == nil || err != nil { @@ -58,6 +65,7 @@ func NewServiceContext(c config.Config) *ServiceContext { return &ServiceContext{ Config: c, Snowflake: snowflakex.NewClient(c.SnowflakeRpcConf), + UsersRpc: usercenter.NewUsercenter(zrpc.MustNewClient(c.UsersRpcConf)), ShopModelRO: models.NewClient(roModelOpts...), ShopModelRW: models.NewClient(rwModelOpts...), } diff --git a/app/user_verifications/rpc/etc/pb.yaml b/app/user_verifications/rpc/etc/pb.yaml index 097bc22..ce65f5e 100644 --- a/app/user_verifications/rpc/etc/pb.yaml +++ b/app/user_verifications/rpc/etc/pb.yaml @@ -1,28 +1,45 @@ Name: pb.rpc ListenOn: 0.0.0.0:8080 -DataSource: "${DB_URI}?sslmode=disable" -UserVeriRpcConf : - Target: k8s://juwan/user_verifications-rpc-svc.juwan:8080 +# ===== PROC Config ===== +#SnowflakeRpcConf: +# Target: k8s://juwan/snowflake-svc.juwan:8080 +#UserRpcConf: +# Target: k8s://juwan/user-rpc-svc.juwan:8080 +# +#DB: +# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# +#CacheConf: +# - Host: "${REDIS_M_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# - Host: "${REDIS_S_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# +#Log: +# Level: info +# ===== DEV Config ===== SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc.juwan:8080 - + Endpoints: + - snowflake:8080 +UserRpcConf: + Endpoints: + - user-rpc:8080 DB: - Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" + Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" CacheConf: - - Host: "${REDIS_M_HOST}" + - Host: "${REDIS_HOST}:${REDIS_PORT}" Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" - - Host: "${REDIS_S_HOST}" - Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" Log: - Level: info + Level: debug diff --git a/app/user_verifications/rpc/internal/config/config.go b/app/user_verifications/rpc/internal/config/config.go index f951f06..419627e 100644 --- a/app/user_verifications/rpc/internal/config/config.go +++ b/app/user_verifications/rpc/internal/config/config.go @@ -12,6 +12,6 @@ type Config struct { Slave string } CacheConf cache.CacheConf - UserVeriRpcConf zrpc.RpcClientConf SnowflakeRpcConf zrpc.RpcClientConf + UserRpcConf zrpc.RpcClientConf } diff --git a/app/user_verifications/rpc/internal/logic/addOrUpdateUserVerificationsLogic.go b/app/user_verifications/rpc/internal/logic/addOrUpdateUserVerificationsLogic.go new file mode 100644 index 0000000..d83877d --- /dev/null +++ b/app/user_verifications/rpc/internal/logic/addOrUpdateUserVerificationsLogic.go @@ -0,0 +1,113 @@ +package logic + +import ( + "context" + "encoding/json" + "errors" + "juwan-backend/app/snowflake/rpc/snowflake" + "juwan-backend/app/user_verifications/rpc/internal/models" + "juwan-backend/app/user_verifications/rpc/internal/models/schema" + "juwan-backend/app/user_verifications/rpc/internal/models/userverifications" + "juwan-backend/app/user_verifications/rpc/internal/svc" + "juwan-backend/app/user_verifications/rpc/pb" + "juwan-backend/app/users/rpc/usercenter" + "slices" + + "github.com/zeromicro/go-zero/core/logx" +) + +type AddOrUpdateUserVerificationsLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewAddOrUpdateUserVerificationsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddOrUpdateUserVerificationsLogic { + return &AddOrUpdateUserVerificationsLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *AddOrUpdateUserVerificationsLogic) AddOrUpdateUserVerifications(in *pb.AddOrUpdateUserVerificationsReq) (*pb.AddOrUpdateUserVerificationsResp, error) { + NotFoundError := &models.NotFoundError{} + var materials schema.MaterialStruct + + uv, vErr := l.svcCtx.UserVeriModelRO.Query(). + Where( + userverifications.UserIDEQ(in.UserId), + userverifications.RoleEQ(in.Role), + userverifications.StatusNEQ("rejected"), + ). + First(l.ctx) + if vErr != nil && !errors.As(vErr, &NotFoundError) { + logx.Errorf("add or update user verifications: get user err:%v", vErr) + return nil, errors.New("") + } + + isRole, err := l.checkIsRole(in.UserId, in.Role) + + if err != nil { + logx.Errorf("add or update user verifications: check user err:%v", err) + return nil, errors.New("check user role failed") + } + if isRole { + return nil, errors.New("user already has the role") + } + + jsonErr := json.Unmarshal([]byte(in.Material), &materials) + if jsonErr != nil { + logx.Errorf("add or update user verifications: marshal materials err:%v", jsonErr) + return nil, errors.New("invalid materials") + } + + idResp, rpcErr := l.svcCtx.SnowflakeRpc.NextId(l.ctx, &snowflake.NextIdReq{}) + if errors.As(vErr, &NotFoundError) { + if rpcErr != nil { + logx.Errorf("add or update user verifications: get next id err:%v", rpcErr) + return nil, errors.New("generate id failed: ") + } + + uv, err = l.svcCtx.UserVeriModelRW.Create(). + SetID(idResp.Id). + SetUserID(in.UserId). + SetRole(in.Role). + SetMaterials(materials). + SetRejectReason(""). + SetReviewedBy(0). + Save(l.ctx) + if err != nil { + logx.Errorf("add or update user verifications: create user verifications err:%v", err) + return nil, errors.New("create user verifications failed") + } + } else { + uv, err = uv.Update(). + SetRole(in.Role). + SetMaterials(materials). + Save(l.ctx) + if err != nil { + logx.Errorf("add or update user verifications: update user verifications err:%v", err) + return nil, errors.New("update user verifications failed") + } + } + + return &pb.AddOrUpdateUserVerificationsResp{ + Success: true, + }, nil +} + +func (l *AddOrUpdateUserVerificationsLogic) checkIsRole(userid int64, role string) (bool, error) { + user, err := l.svcCtx.UserRpc.GetUsersById(l.ctx, &usercenter.GetUsersByIdReq{ + Id: userid, + }) + logx.Debug("checkIsRole user:", user) + if err != nil { + return false, err + } + logx.Debug("checkIsRole user verified roles:", user.Users.VerifiedRoles) + if slices.Contains(user.Users.VerifiedRoles, role) { + return true, nil + } + return false, nil +} diff --git a/app/user_verifications/rpc/internal/logic/listUserVerificationsByUserIdLogic.go b/app/user_verifications/rpc/internal/logic/listUserVerificationsByUserIdLogic.go new file mode 100644 index 0000000..98c8646 --- /dev/null +++ b/app/user_verifications/rpc/internal/logic/listUserVerificationsByUserIdLogic.go @@ -0,0 +1,58 @@ +package logic + +import ( + "context" + "errors" + "juwan-backend/app/user_verifications/rpc/internal/models/userverifications" + + "juwan-backend/app/user_verifications/rpc/internal/svc" + "juwan-backend/app/user_verifications/rpc/pb" + + "github.com/jinzhu/copier" + "github.com/zeromicro/go-zero/core/logx" +) + +type ListUserVerificationsByUserIdLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewListUserVerificationsByUserIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListUserVerificationsByUserIdLogic { + return &ListUserVerificationsByUserIdLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *ListUserVerificationsByUserIdLogic) ListUserVerificationsByUserId(in *pb.ListUserVerificationsByUserIdReq) (*pb.ListUserVerificationsByUserIdResp, error) { + all, err := l.svcCtx.UserVeriModelRO.Query(). + Where(userverifications.UserIDEQ(in.UserId)). + All(l.ctx) + + if err != nil { + logx.Errorf("ListUserVerificationsByUserId err: %v", err) + return nil, errors.New("list user verifications by user id err") + } + + list := make([]*pb.UserVerifications, 0, len(all)) + for _, v := range all { + var temp pb.UserVerifications + err = copier.Copy(&temp, v) + if err != nil { + logx.Errorf("copy user verifications err: %v", err) + continue + } + temp.CreatedAt = v.CreatedAt.Unix() + temp.UpdatedAt = v.UpdatedAt.Unix() + if v.ReviewedAt != nil { + temp.ReviewedAt = v.ReviewedAt.Unix() + } + list = append(list, &temp) + } + + return &pb.ListUserVerificationsByUserIdResp{ + UserVerifications: list, + }, nil +} diff --git a/app/user_verifications/rpc/internal/logic/searchUserVerificationsLogic.go b/app/user_verifications/rpc/internal/logic/searchUserVerificationsLogic.go index a3507c0..97cab17 100644 --- a/app/user_verifications/rpc/internal/logic/searchUserVerificationsLogic.go +++ b/app/user_verifications/rpc/internal/logic/searchUserVerificationsLogic.go @@ -31,11 +31,7 @@ func (l *SearchUserVerificationsLogic) SearchUserVerifications(in *pb.SearchUser logx.Errorf("Limit exceeds max limit: %d", in.Limit) return nil, errors.New("limit exceeds max limit") } - verifications, err := l.svcCtx.UserVeriModelRO.Query().Where(userverifications.Or( - userverifications.UserIDEQ(in.UserId), - userverifications.StatusEQ(in.Status), - userverifications.Role(in.Role), - )). + verifications, err := l.svcCtx.UserVeriModelRO.Query().Where(userverifications.UserIDEQ(in.UserId)). Offset(int(in.Page * in.Limit)). Limit(int(in.Limit)). All(l.ctx) diff --git a/app/user_verifications/rpc/internal/models/migrate/schema.go b/app/user_verifications/rpc/internal/models/migrate/schema.go index a460dbd..f573dd8 100644 --- a/app/user_verifications/rpc/internal/models/migrate/schema.go +++ b/app/user_verifications/rpc/internal/models/migrate/schema.go @@ -12,14 +12,14 @@ var ( UserVerificationsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, {Name: "user_id", Type: field.TypeInt64, Unique: true}, - {Name: "role", Type: field.TypeString, Unique: true}, + {Name: "role", Type: field.TypeString}, {Name: "status", Type: field.TypeString, Default: "pending"}, {Name: "materials", Type: field.TypeJSON}, - {Name: "reject_reason", Type: field.TypeString, Default: ""}, - {Name: "reviewed_by", Type: field.TypeInt64}, - {Name: "reviewed_at", Type: field.TypeTime}, - {Name: "created_at", Type: field.TypeTime}, - {Name: "updated_at", Type: field.TypeTime}, + {Name: "reject_reason", Type: field.TypeString, Nullable: true}, + {Name: "reviewed_by", Type: field.TypeInt64, Nullable: true}, + {Name: "reviewed_at", Type: field.TypeTime, Nullable: true}, + {Name: "created_at", Type: field.TypeTime, Nullable: true}, + {Name: "updated_at", Type: field.TypeTime, Nullable: true}, } // UserVerificationsTable holds the schema information for the "user_verifications" table. UserVerificationsTable = &schema.Table{ diff --git a/app/user_verifications/rpc/internal/models/mutation.go b/app/user_verifications/rpc/internal/models/mutation.go index 0a1d297..c979132 100644 --- a/app/user_verifications/rpc/internal/models/mutation.go +++ b/app/user_verifications/rpc/internal/models/mutation.go @@ -336,7 +336,7 @@ func (m *UserVerificationsMutation) RejectReason() (r string, exists bool) { // OldRejectReason returns the old "reject_reason" field's value of the UserVerifications entity. // If the UserVerifications object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *UserVerificationsMutation) OldRejectReason(ctx context.Context) (v string, err error) { +func (m *UserVerificationsMutation) OldRejectReason(ctx context.Context) (v *string, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldRejectReason is only allowed on UpdateOne operations") } @@ -350,9 +350,22 @@ func (m *UserVerificationsMutation) OldRejectReason(ctx context.Context) (v stri return oldValue.RejectReason, nil } +// ClearRejectReason clears the value of the "reject_reason" field. +func (m *UserVerificationsMutation) ClearRejectReason() { + m.reject_reason = nil + m.clearedFields[userverifications.FieldRejectReason] = struct{}{} +} + +// RejectReasonCleared returns if the "reject_reason" field was cleared in this mutation. +func (m *UserVerificationsMutation) RejectReasonCleared() bool { + _, ok := m.clearedFields[userverifications.FieldRejectReason] + return ok +} + // ResetRejectReason resets all changes to the "reject_reason" field. func (m *UserVerificationsMutation) ResetRejectReason() { m.reject_reason = nil + delete(m.clearedFields, userverifications.FieldRejectReason) } // SetReviewedBy sets the "reviewed_by" field. @@ -373,7 +386,7 @@ func (m *UserVerificationsMutation) ReviewedBy() (r int64, exists bool) { // OldReviewedBy returns the old "reviewed_by" field's value of the UserVerifications entity. // If the UserVerifications object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *UserVerificationsMutation) OldReviewedBy(ctx context.Context) (v int64, err error) { +func (m *UserVerificationsMutation) OldReviewedBy(ctx context.Context) (v *int64, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldReviewedBy is only allowed on UpdateOne operations") } @@ -405,10 +418,24 @@ func (m *UserVerificationsMutation) AddedReviewedBy() (r int64, exists bool) { return *v, true } +// ClearReviewedBy clears the value of the "reviewed_by" field. +func (m *UserVerificationsMutation) ClearReviewedBy() { + m.reviewed_by = nil + m.addreviewed_by = nil + m.clearedFields[userverifications.FieldReviewedBy] = struct{}{} +} + +// ReviewedByCleared returns if the "reviewed_by" field was cleared in this mutation. +func (m *UserVerificationsMutation) ReviewedByCleared() bool { + _, ok := m.clearedFields[userverifications.FieldReviewedBy] + return ok +} + // ResetReviewedBy resets all changes to the "reviewed_by" field. func (m *UserVerificationsMutation) ResetReviewedBy() { m.reviewed_by = nil m.addreviewed_by = nil + delete(m.clearedFields, userverifications.FieldReviewedBy) } // SetReviewedAt sets the "reviewed_at" field. @@ -428,7 +455,7 @@ func (m *UserVerificationsMutation) ReviewedAt() (r time.Time, exists bool) { // OldReviewedAt returns the old "reviewed_at" field's value of the UserVerifications entity. // If the UserVerifications object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *UserVerificationsMutation) OldReviewedAt(ctx context.Context) (v time.Time, err error) { +func (m *UserVerificationsMutation) OldReviewedAt(ctx context.Context) (v *time.Time, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldReviewedAt is only allowed on UpdateOne operations") } @@ -442,9 +469,22 @@ func (m *UserVerificationsMutation) OldReviewedAt(ctx context.Context) (v time.T return oldValue.ReviewedAt, nil } +// ClearReviewedAt clears the value of the "reviewed_at" field. +func (m *UserVerificationsMutation) ClearReviewedAt() { + m.reviewed_at = nil + m.clearedFields[userverifications.FieldReviewedAt] = struct{}{} +} + +// ReviewedAtCleared returns if the "reviewed_at" field was cleared in this mutation. +func (m *UserVerificationsMutation) ReviewedAtCleared() bool { + _, ok := m.clearedFields[userverifications.FieldReviewedAt] + return ok +} + // ResetReviewedAt resets all changes to the "reviewed_at" field. func (m *UserVerificationsMutation) ResetReviewedAt() { m.reviewed_at = nil + delete(m.clearedFields, userverifications.FieldReviewedAt) } // SetCreatedAt sets the "created_at" field. @@ -478,9 +518,22 @@ func (m *UserVerificationsMutation) OldCreatedAt(ctx context.Context) (v time.Ti return oldValue.CreatedAt, nil } +// ClearCreatedAt clears the value of the "created_at" field. +func (m *UserVerificationsMutation) ClearCreatedAt() { + m.created_at = nil + m.clearedFields[userverifications.FieldCreatedAt] = struct{}{} +} + +// CreatedAtCleared returns if the "created_at" field was cleared in this mutation. +func (m *UserVerificationsMutation) CreatedAtCleared() bool { + _, ok := m.clearedFields[userverifications.FieldCreatedAt] + return ok +} + // ResetCreatedAt resets all changes to the "created_at" field. func (m *UserVerificationsMutation) ResetCreatedAt() { m.created_at = nil + delete(m.clearedFields, userverifications.FieldCreatedAt) } // SetUpdatedAt sets the "updated_at" field. @@ -514,9 +567,22 @@ func (m *UserVerificationsMutation) OldUpdatedAt(ctx context.Context) (v time.Ti return oldValue.UpdatedAt, nil } +// ClearUpdatedAt clears the value of the "updated_at" field. +func (m *UserVerificationsMutation) ClearUpdatedAt() { + m.updated_at = nil + m.clearedFields[userverifications.FieldUpdatedAt] = struct{}{} +} + +// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation. +func (m *UserVerificationsMutation) UpdatedAtCleared() bool { + _, ok := m.clearedFields[userverifications.FieldUpdatedAt] + return ok +} + // ResetUpdatedAt resets all changes to the "updated_at" field. func (m *UserVerificationsMutation) ResetUpdatedAt() { m.updated_at = nil + delete(m.clearedFields, userverifications.FieldUpdatedAt) } // Where appends a list predicates to the UserVerificationsMutation builder. @@ -762,7 +828,23 @@ func (m *UserVerificationsMutation) AddField(name string, value ent.Value) error // ClearedFields returns all nullable fields that were cleared during this // mutation. func (m *UserVerificationsMutation) ClearedFields() []string { - return nil + var fields []string + if m.FieldCleared(userverifications.FieldRejectReason) { + fields = append(fields, userverifications.FieldRejectReason) + } + if m.FieldCleared(userverifications.FieldReviewedBy) { + fields = append(fields, userverifications.FieldReviewedBy) + } + if m.FieldCleared(userverifications.FieldReviewedAt) { + fields = append(fields, userverifications.FieldReviewedAt) + } + if m.FieldCleared(userverifications.FieldCreatedAt) { + fields = append(fields, userverifications.FieldCreatedAt) + } + if m.FieldCleared(userverifications.FieldUpdatedAt) { + fields = append(fields, userverifications.FieldUpdatedAt) + } + return fields } // FieldCleared returns a boolean indicating if a field with the given name was @@ -775,6 +857,23 @@ func (m *UserVerificationsMutation) FieldCleared(name string) bool { // ClearField clears the value of the field with the given name. It returns an // error if the field is not defined in the schema. func (m *UserVerificationsMutation) ClearField(name string) error { + switch name { + case userverifications.FieldRejectReason: + m.ClearRejectReason() + return nil + case userverifications.FieldReviewedBy: + m.ClearReviewedBy() + return nil + case userverifications.FieldReviewedAt: + m.ClearReviewedAt() + return nil + case userverifications.FieldCreatedAt: + m.ClearCreatedAt() + return nil + case userverifications.FieldUpdatedAt: + m.ClearUpdatedAt() + return nil + } return fmt.Errorf("unknown UserVerifications nullable field %s", name) } diff --git a/app/user_verifications/rpc/internal/models/runtime.go b/app/user_verifications/rpc/internal/models/runtime.go index cec2fc2..5297730 100644 --- a/app/user_verifications/rpc/internal/models/runtime.go +++ b/app/user_verifications/rpc/internal/models/runtime.go @@ -5,6 +5,7 @@ package models import ( "juwan-backend/app/user_verifications/rpc/internal/models/schema" "juwan-backend/app/user_verifications/rpc/internal/models/userverifications" + "time" ) // The init function reads all schema descriptors with runtime code @@ -17,8 +18,12 @@ func init() { userverificationsDescStatus := userverificationsFields[3].Descriptor() // userverifications.DefaultStatus holds the default value on creation for the status field. userverifications.DefaultStatus = userverificationsDescStatus.Default.(string) - // userverificationsDescRejectReason is the schema descriptor for reject_reason field. - userverificationsDescRejectReason := userverificationsFields[5].Descriptor() - // userverifications.DefaultRejectReason holds the default value on creation for the reject_reason field. - userverifications.DefaultRejectReason = userverificationsDescRejectReason.Default.(string) + // userverificationsDescCreatedAt is the schema descriptor for created_at field. + userverificationsDescCreatedAt := userverificationsFields[8].Descriptor() + // userverifications.DefaultCreatedAt holds the default value on creation for the created_at field. + userverifications.DefaultCreatedAt = userverificationsDescCreatedAt.Default.(func() time.Time) + // userverificationsDescUpdatedAt is the schema descriptor for updated_at field. + userverificationsDescUpdatedAt := userverificationsFields[9].Descriptor() + // userverifications.DefaultUpdatedAt holds the default value on creation for the updated_at field. + userverifications.DefaultUpdatedAt = userverificationsDescUpdatedAt.Default.(func() time.Time) } diff --git a/app/user_verifications/rpc/internal/models/schema/userverifications.go b/app/user_verifications/rpc/internal/models/schema/userverifications.go index a429696..da058e1 100644 --- a/app/user_verifications/rpc/internal/models/schema/userverifications.go +++ b/app/user_verifications/rpc/internal/models/schema/userverifications.go @@ -1,6 +1,8 @@ package schema import ( + "time" + "entgo.io/ent" "entgo.io/ent/schema/field" ) @@ -13,8 +15,8 @@ type UserVerifications struct { type MaterialStruct struct { IdCardFront string `json:"idCardFront"` IdCardBack string `json:"idCardBack"` - GameScreenshots []string `json:"gameScreenshots"` - VoiceDemo string `json:"voiceDemo"` + GameScreenshots []string `json:"gameScreenshots,omitempty"` + VoiceDemo string `json:"voiceDemo,omitempty"` } // Fields of the UserVerifications. @@ -22,14 +24,14 @@ func (UserVerifications) Fields() []ent.Field { return []ent.Field{ field.Int64("id").Immutable().Unique(), field.Int64("user_id").Immutable().Unique(), - field.String("role").Unique(), + field.String("role"), field.String("status").Default("pending"), field.JSON("materials", MaterialStruct{}), - field.String("reject_reason").Default(""), - field.Int64("reviewed_by"), - field.Time("reviewed_at").Immutable(), - field.Time("created_at").Immutable(), - field.Time("updated_at").Immutable(), + field.String("reject_reason").Nillable().Optional(), + field.Int64("reviewed_by").Nillable().Optional(), + field.Time("reviewed_at").Nillable().Optional(), + field.Time("created_at").Immutable().Optional().Default(time.Now), + field.Time("updated_at").Immutable().Optional().Default(time.Now), } } diff --git a/app/user_verifications/rpc/internal/models/userverifications.go b/app/user_verifications/rpc/internal/models/userverifications.go index 4d36b2b..7704918 100644 --- a/app/user_verifications/rpc/internal/models/userverifications.go +++ b/app/user_verifications/rpc/internal/models/userverifications.go @@ -14,7 +14,7 @@ import ( "entgo.io/ent/dialect/sql" ) -// UserVerifications is the models entity for the UserVerifications schema. +// UserVerifications is the model entity for the UserVerifications schema. type UserVerifications struct { config `json:"-"` // ID of the ent. @@ -28,11 +28,11 @@ type UserVerifications struct { // Materials holds the value of the "materials" field. Materials schema.MaterialStruct `json:"materials,omitempty"` // RejectReason holds the value of the "reject_reason" field. - RejectReason string `json:"reject_reason,omitempty"` + RejectReason *string `json:"reject_reason,omitempty"` // ReviewedBy holds the value of the "reviewed_by" field. - ReviewedBy int64 `json:"reviewed_by,omitempty"` + ReviewedBy *int64 `json:"reviewed_by,omitempty"` // ReviewedAt holds the value of the "reviewed_at" field. - ReviewedAt time.Time `json:"reviewed_at,omitempty"` + ReviewedAt *time.Time `json:"reviewed_at,omitempty"` // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at,omitempty"` // UpdatedAt holds the value of the "updated_at" field. @@ -104,19 +104,22 @@ func (_m *UserVerifications) assignValues(columns []string, values []any) error if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field reject_reason", values[i]) } else if value.Valid { - _m.RejectReason = value.String + _m.RejectReason = new(string) + *_m.RejectReason = value.String } case userverifications.FieldReviewedBy: if value, ok := values[i].(*sql.NullInt64); !ok { return fmt.Errorf("unexpected type %T for field reviewed_by", values[i]) } else if value.Valid { - _m.ReviewedBy = value.Int64 + _m.ReviewedBy = new(int64) + *_m.ReviewedBy = value.Int64 } case userverifications.FieldReviewedAt: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field reviewed_at", values[i]) } else if value.Valid { - _m.ReviewedAt = value.Time + _m.ReviewedAt = new(time.Time) + *_m.ReviewedAt = value.Time } case userverifications.FieldCreatedAt: if value, ok := values[i].(*sql.NullTime); !ok { @@ -178,14 +181,20 @@ func (_m *UserVerifications) String() string { builder.WriteString("materials=") builder.WriteString(fmt.Sprintf("%v", _m.Materials)) builder.WriteString(", ") - builder.WriteString("reject_reason=") - builder.WriteString(_m.RejectReason) + if v := _m.RejectReason; v != nil { + builder.WriteString("reject_reason=") + builder.WriteString(*v) + } builder.WriteString(", ") - builder.WriteString("reviewed_by=") - builder.WriteString(fmt.Sprintf("%v", _m.ReviewedBy)) + if v := _m.ReviewedBy; v != nil { + builder.WriteString("reviewed_by=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } builder.WriteString(", ") - builder.WriteString("reviewed_at=") - builder.WriteString(_m.ReviewedAt.Format(time.ANSIC)) + if v := _m.ReviewedAt; v != nil { + builder.WriteString("reviewed_at=") + builder.WriteString(v.Format(time.ANSIC)) + } builder.WriteString(", ") builder.WriteString("created_at=") builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) diff --git a/app/user_verifications/rpc/internal/models/userverifications/userverifications.go b/app/user_verifications/rpc/internal/models/userverifications/userverifications.go index 2a1081b..de0a5e6 100644 --- a/app/user_verifications/rpc/internal/models/userverifications/userverifications.go +++ b/app/user_verifications/rpc/internal/models/userverifications/userverifications.go @@ -3,6 +3,8 @@ package userverifications import ( + "time" + "entgo.io/ent/dialect/sql" ) @@ -60,8 +62,10 @@ func ValidColumn(column string) bool { var ( // DefaultStatus holds the default value on creation for the "status" field. DefaultStatus string - // DefaultRejectReason holds the default value on creation for the "reject_reason" field. - DefaultRejectReason string + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time ) // OrderOption defines the ordering options for the UserVerifications queries. diff --git a/app/user_verifications/rpc/internal/models/userverifications/where.go b/app/user_verifications/rpc/internal/models/userverifications/where.go index d50c71b..ce5be99 100644 --- a/app/user_verifications/rpc/internal/models/userverifications/where.go +++ b/app/user_verifications/rpc/internal/models/userverifications/where.go @@ -319,6 +319,16 @@ func RejectReasonHasSuffix(v string) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldHasSuffix(FieldRejectReason, v)) } +// RejectReasonIsNil applies the IsNil predicate on the "reject_reason" field. +func RejectReasonIsNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldIsNull(FieldRejectReason)) +} + +// RejectReasonNotNil applies the NotNil predicate on the "reject_reason" field. +func RejectReasonNotNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldNotNull(FieldRejectReason)) +} + // RejectReasonEqualFold applies the EqualFold predicate on the "reject_reason" field. func RejectReasonEqualFold(v string) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldEqualFold(FieldRejectReason, v)) @@ -369,6 +379,16 @@ func ReviewedByLTE(v int64) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldLTE(FieldReviewedBy, v)) } +// ReviewedByIsNil applies the IsNil predicate on the "reviewed_by" field. +func ReviewedByIsNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldIsNull(FieldReviewedBy)) +} + +// ReviewedByNotNil applies the NotNil predicate on the "reviewed_by" field. +func ReviewedByNotNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldNotNull(FieldReviewedBy)) +} + // ReviewedAtEQ applies the EQ predicate on the "reviewed_at" field. func ReviewedAtEQ(v time.Time) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldEQ(FieldReviewedAt, v)) @@ -409,6 +429,16 @@ func ReviewedAtLTE(v time.Time) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldLTE(FieldReviewedAt, v)) } +// ReviewedAtIsNil applies the IsNil predicate on the "reviewed_at" field. +func ReviewedAtIsNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldIsNull(FieldReviewedAt)) +} + +// ReviewedAtNotNil applies the NotNil predicate on the "reviewed_at" field. +func ReviewedAtNotNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldNotNull(FieldReviewedAt)) +} + // CreatedAtEQ applies the EQ predicate on the "created_at" field. func CreatedAtEQ(v time.Time) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldEQ(FieldCreatedAt, v)) @@ -449,6 +479,16 @@ func CreatedAtLTE(v time.Time) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldLTE(FieldCreatedAt, v)) } +// CreatedAtIsNil applies the IsNil predicate on the "created_at" field. +func CreatedAtIsNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldIsNull(FieldCreatedAt)) +} + +// CreatedAtNotNil applies the NotNil predicate on the "created_at" field. +func CreatedAtNotNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldNotNull(FieldCreatedAt)) +} + // UpdatedAtEQ applies the EQ predicate on the "updated_at" field. func UpdatedAtEQ(v time.Time) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldEQ(FieldUpdatedAt, v)) @@ -489,6 +529,16 @@ func UpdatedAtLTE(v time.Time) predicate.UserVerifications { return predicate.UserVerifications(sql.FieldLTE(FieldUpdatedAt, v)) } +// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field. +func UpdatedAtIsNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldIsNull(FieldUpdatedAt)) +} + +// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field. +func UpdatedAtNotNil() predicate.UserVerifications { + return predicate.UserVerifications(sql.FieldNotNull(FieldUpdatedAt)) +} + // And groups predicates with the AND operator between them. func And(predicates ...predicate.UserVerifications) predicate.UserVerifications { return predicate.UserVerifications(sql.AndPredicates(predicates...)) diff --git a/app/user_verifications/rpc/internal/models/userverifications_create.go b/app/user_verifications/rpc/internal/models/userverifications_create.go index 752207d..b558941 100644 --- a/app/user_verifications/rpc/internal/models/userverifications_create.go +++ b/app/user_verifications/rpc/internal/models/userverifications_create.go @@ -73,24 +73,56 @@ func (_c *UserVerificationsCreate) SetReviewedBy(v int64) *UserVerificationsCrea return _c } +// SetNillableReviewedBy sets the "reviewed_by" field if the given value is not nil. +func (_c *UserVerificationsCreate) SetNillableReviewedBy(v *int64) *UserVerificationsCreate { + if v != nil { + _c.SetReviewedBy(*v) + } + return _c +} + // SetReviewedAt sets the "reviewed_at" field. func (_c *UserVerificationsCreate) SetReviewedAt(v time.Time) *UserVerificationsCreate { _c.mutation.SetReviewedAt(v) return _c } +// SetNillableReviewedAt sets the "reviewed_at" field if the given value is not nil. +func (_c *UserVerificationsCreate) SetNillableReviewedAt(v *time.Time) *UserVerificationsCreate { + if v != nil { + _c.SetReviewedAt(*v) + } + return _c +} + // SetCreatedAt sets the "created_at" field. func (_c *UserVerificationsCreate) SetCreatedAt(v time.Time) *UserVerificationsCreate { _c.mutation.SetCreatedAt(v) return _c } +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *UserVerificationsCreate) SetNillableCreatedAt(v *time.Time) *UserVerificationsCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + // SetUpdatedAt sets the "updated_at" field. func (_c *UserVerificationsCreate) SetUpdatedAt(v time.Time) *UserVerificationsCreate { _c.mutation.SetUpdatedAt(v) return _c } +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *UserVerificationsCreate) SetNillableUpdatedAt(v *time.Time) *UserVerificationsCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + // SetID sets the "id" field. func (_c *UserVerificationsCreate) SetID(v int64) *UserVerificationsCreate { _c.mutation.SetID(v) @@ -136,9 +168,13 @@ func (_c *UserVerificationsCreate) defaults() { v := userverifications.DefaultStatus _c.mutation.SetStatus(v) } - if _, ok := _c.mutation.RejectReason(); !ok { - v := userverifications.DefaultRejectReason - _c.mutation.SetRejectReason(v) + if _, ok := _c.mutation.CreatedAt(); !ok { + v := userverifications.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + v := userverifications.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) } } @@ -156,21 +192,6 @@ func (_c *UserVerificationsCreate) check() error { if _, ok := _c.mutation.Materials(); !ok { return &ValidationError{Name: "materials", err: errors.New(`models: missing required field "UserVerifications.materials"`)} } - if _, ok := _c.mutation.RejectReason(); !ok { - return &ValidationError{Name: "reject_reason", err: errors.New(`models: missing required field "UserVerifications.reject_reason"`)} - } - if _, ok := _c.mutation.ReviewedBy(); !ok { - return &ValidationError{Name: "reviewed_by", err: errors.New(`models: missing required field "UserVerifications.reviewed_by"`)} - } - if _, ok := _c.mutation.ReviewedAt(); !ok { - return &ValidationError{Name: "reviewed_at", err: errors.New(`models: missing required field "UserVerifications.reviewed_at"`)} - } - if _, ok := _c.mutation.CreatedAt(); !ok { - return &ValidationError{Name: "created_at", err: errors.New(`models: missing required field "UserVerifications.created_at"`)} - } - if _, ok := _c.mutation.UpdatedAt(); !ok { - return &ValidationError{Name: "updated_at", err: errors.New(`models: missing required field "UserVerifications.updated_at"`)} - } return nil } @@ -221,15 +242,15 @@ func (_c *UserVerificationsCreate) createSpec() (*UserVerifications, *sqlgraph.C } if value, ok := _c.mutation.RejectReason(); ok { _spec.SetField(userverifications.FieldRejectReason, field.TypeString, value) - _node.RejectReason = value + _node.RejectReason = &value } if value, ok := _c.mutation.ReviewedBy(); ok { _spec.SetField(userverifications.FieldReviewedBy, field.TypeInt64, value) - _node.ReviewedBy = value + _node.ReviewedBy = &value } if value, ok := _c.mutation.ReviewedAt(); ok { _spec.SetField(userverifications.FieldReviewedAt, field.TypeTime, value) - _node.ReviewedAt = value + _node.ReviewedAt = &value } if value, ok := _c.mutation.CreatedAt(); ok { _spec.SetField(userverifications.FieldCreatedAt, field.TypeTime, value) diff --git a/app/user_verifications/rpc/internal/models/userverifications_update.go b/app/user_verifications/rpc/internal/models/userverifications_update.go index ceb0ad9..66beff0 100644 --- a/app/user_verifications/rpc/internal/models/userverifications_update.go +++ b/app/user_verifications/rpc/internal/models/userverifications_update.go @@ -9,6 +9,7 @@ import ( "juwan-backend/app/user_verifications/rpc/internal/models/predicate" "juwan-backend/app/user_verifications/rpc/internal/models/schema" "juwan-backend/app/user_verifications/rpc/internal/models/userverifications" + "time" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -84,6 +85,12 @@ func (_u *UserVerificationsUpdate) SetNillableRejectReason(v *string) *UserVerif return _u } +// ClearRejectReason clears the value of the "reject_reason" field. +func (_u *UserVerificationsUpdate) ClearRejectReason() *UserVerificationsUpdate { + _u.mutation.ClearRejectReason() + return _u +} + // SetReviewedBy sets the "reviewed_by" field. func (_u *UserVerificationsUpdate) SetReviewedBy(v int64) *UserVerificationsUpdate { _u.mutation.ResetReviewedBy() @@ -105,6 +112,32 @@ func (_u *UserVerificationsUpdate) AddReviewedBy(v int64) *UserVerificationsUpda return _u } +// ClearReviewedBy clears the value of the "reviewed_by" field. +func (_u *UserVerificationsUpdate) ClearReviewedBy() *UserVerificationsUpdate { + _u.mutation.ClearReviewedBy() + return _u +} + +// SetReviewedAt sets the "reviewed_at" field. +func (_u *UserVerificationsUpdate) SetReviewedAt(v time.Time) *UserVerificationsUpdate { + _u.mutation.SetReviewedAt(v) + return _u +} + +// SetNillableReviewedAt sets the "reviewed_at" field if the given value is not nil. +func (_u *UserVerificationsUpdate) SetNillableReviewedAt(v *time.Time) *UserVerificationsUpdate { + if v != nil { + _u.SetReviewedAt(*v) + } + return _u +} + +// ClearReviewedAt clears the value of the "reviewed_at" field. +func (_u *UserVerificationsUpdate) ClearReviewedAt() *UserVerificationsUpdate { + _u.mutation.ClearReviewedAt() + return _u +} + // Mutation returns the UserVerificationsMutation object of the builder. func (_u *UserVerificationsUpdate) Mutation() *UserVerificationsMutation { return _u.mutation @@ -158,12 +191,30 @@ func (_u *UserVerificationsUpdate) sqlSave(ctx context.Context) (_node int, err if value, ok := _u.mutation.RejectReason(); ok { _spec.SetField(userverifications.FieldRejectReason, field.TypeString, value) } + if _u.mutation.RejectReasonCleared() { + _spec.ClearField(userverifications.FieldRejectReason, field.TypeString) + } if value, ok := _u.mutation.ReviewedBy(); ok { _spec.SetField(userverifications.FieldReviewedBy, field.TypeInt64, value) } if value, ok := _u.mutation.AddedReviewedBy(); ok { _spec.AddField(userverifications.FieldReviewedBy, field.TypeInt64, value) } + if _u.mutation.ReviewedByCleared() { + _spec.ClearField(userverifications.FieldReviewedBy, field.TypeInt64) + } + if value, ok := _u.mutation.ReviewedAt(); ok { + _spec.SetField(userverifications.FieldReviewedAt, field.TypeTime, value) + } + if _u.mutation.ReviewedAtCleared() { + _spec.ClearField(userverifications.FieldReviewedAt, field.TypeTime) + } + if _u.mutation.CreatedAtCleared() { + _spec.ClearField(userverifications.FieldCreatedAt, field.TypeTime) + } + if _u.mutation.UpdatedAtCleared() { + _spec.ClearField(userverifications.FieldUpdatedAt, field.TypeTime) + } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{userverifications.Label} @@ -240,6 +291,12 @@ func (_u *UserVerificationsUpdateOne) SetNillableRejectReason(v *string) *UserVe return _u } +// ClearRejectReason clears the value of the "reject_reason" field. +func (_u *UserVerificationsUpdateOne) ClearRejectReason() *UserVerificationsUpdateOne { + _u.mutation.ClearRejectReason() + return _u +} + // SetReviewedBy sets the "reviewed_by" field. func (_u *UserVerificationsUpdateOne) SetReviewedBy(v int64) *UserVerificationsUpdateOne { _u.mutation.ResetReviewedBy() @@ -261,6 +318,32 @@ func (_u *UserVerificationsUpdateOne) AddReviewedBy(v int64) *UserVerificationsU return _u } +// ClearReviewedBy clears the value of the "reviewed_by" field. +func (_u *UserVerificationsUpdateOne) ClearReviewedBy() *UserVerificationsUpdateOne { + _u.mutation.ClearReviewedBy() + return _u +} + +// SetReviewedAt sets the "reviewed_at" field. +func (_u *UserVerificationsUpdateOne) SetReviewedAt(v time.Time) *UserVerificationsUpdateOne { + _u.mutation.SetReviewedAt(v) + return _u +} + +// SetNillableReviewedAt sets the "reviewed_at" field if the given value is not nil. +func (_u *UserVerificationsUpdateOne) SetNillableReviewedAt(v *time.Time) *UserVerificationsUpdateOne { + if v != nil { + _u.SetReviewedAt(*v) + } + return _u +} + +// ClearReviewedAt clears the value of the "reviewed_at" field. +func (_u *UserVerificationsUpdateOne) ClearReviewedAt() *UserVerificationsUpdateOne { + _u.mutation.ClearReviewedAt() + return _u +} + // Mutation returns the UserVerificationsMutation object of the builder. func (_u *UserVerificationsUpdateOne) Mutation() *UserVerificationsMutation { return _u.mutation @@ -344,12 +427,30 @@ func (_u *UserVerificationsUpdateOne) sqlSave(ctx context.Context) (_node *UserV if value, ok := _u.mutation.RejectReason(); ok { _spec.SetField(userverifications.FieldRejectReason, field.TypeString, value) } + if _u.mutation.RejectReasonCleared() { + _spec.ClearField(userverifications.FieldRejectReason, field.TypeString) + } if value, ok := _u.mutation.ReviewedBy(); ok { _spec.SetField(userverifications.FieldReviewedBy, field.TypeInt64, value) } if value, ok := _u.mutation.AddedReviewedBy(); ok { _spec.AddField(userverifications.FieldReviewedBy, field.TypeInt64, value) } + if _u.mutation.ReviewedByCleared() { + _spec.ClearField(userverifications.FieldReviewedBy, field.TypeInt64) + } + if value, ok := _u.mutation.ReviewedAt(); ok { + _spec.SetField(userverifications.FieldReviewedAt, field.TypeTime, value) + } + if _u.mutation.ReviewedAtCleared() { + _spec.ClearField(userverifications.FieldReviewedAt, field.TypeTime) + } + if _u.mutation.CreatedAtCleared() { + _spec.ClearField(userverifications.FieldCreatedAt, field.TypeTime) + } + if _u.mutation.UpdatedAtCleared() { + _spec.ClearField(userverifications.FieldUpdatedAt, field.TypeTime) + } _node = &UserVerifications{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/app/user_verifications/rpc/internal/server/userVerificationsServer.go b/app/user_verifications/rpc/internal/server/userVerificationsServer.go index 6945d34..a5e493d 100644 --- a/app/user_verifications/rpc/internal/server/userVerificationsServer.go +++ b/app/user_verifications/rpc/internal/server/userVerificationsServer.go @@ -48,3 +48,13 @@ func (s *UserVerificationsServer) SearchUserVerifications(ctx context.Context, i l := logic.NewSearchUserVerificationsLogic(ctx, s.svcCtx) return l.SearchUserVerifications(in) } + +func (s *UserVerificationsServer) AddOrUpdateUserVerifications(ctx context.Context, in *pb.AddOrUpdateUserVerificationsReq) (*pb.AddOrUpdateUserVerificationsResp, error) { + l := logic.NewAddOrUpdateUserVerificationsLogic(ctx, s.svcCtx) + return l.AddOrUpdateUserVerifications(in) +} + +func (s *UserVerificationsServer) ListUserVerificationsByUserId(ctx context.Context, in *pb.ListUserVerificationsByUserIdReq) (*pb.ListUserVerificationsByUserIdResp, error) { + l := logic.NewListUserVerificationsByUserIdLogic(ctx, s.svcCtx) + return l.ListUserVerificationsByUserId(in) +} diff --git a/app/user_verifications/rpc/internal/svc/serviceContext.go b/app/user_verifications/rpc/internal/svc/serviceContext.go index abfe8bd..06d363e 100644 --- a/app/user_verifications/rpc/internal/svc/serviceContext.go +++ b/app/user_verifications/rpc/internal/svc/serviceContext.go @@ -1,20 +1,24 @@ package svc import ( + stdsql "database/sql" "juwan-backend/app/snowflake/rpc/snowflake" "juwan-backend/app/user_verifications/rpc/internal/config" "juwan-backend/app/user_verifications/rpc/internal/models" - "juwan-backend/app/user_verifications/rpc/userverifications" + "juwan-backend/app/users/rpc/usercenter" "juwan-backend/common/redisx" "juwan-backend/common/snowflakex" "juwan-backend/pkg/adapter" "time" + "entgo.io/ent/dialect" + _ "github.com/jackc/pgx/v5/stdlib" + "github.com/zeromicro/go-zero/zrpc" + "ariga.io/entcache" "entgo.io/ent/dialect/sql" "github.com/redis/go-redis/v9" "github.com/zeromicro/go-zero/core/logx" - "github.com/zeromicro/go-zero/zrpc" ) type ServiceContext struct { @@ -22,19 +26,23 @@ type ServiceContext struct { UserVeriModelRW *models.UserVerificationsClient UserVeriModelRO *models.UserVerificationsClient RedisClient *redis.ClusterClient - UserVeriRpc userverifications.UserVerificationsZrpcClient SnowflakeRpc snowflake.SnowflakeServiceClient + UserRpc usercenter.Usercenter } func NewServiceContext(c config.Config) *ServiceContext { - RWConn, err := sql.Open("pgx", c.DB.Master) + rawRW, err := stdsql.Open("pgx", c.DB.Master) if err != nil { panic(err) } - ROConn, err := sql.Open("pgx", c.DB.Slave) + rawRO, err := stdsql.Open("pgx", c.DB.Slave) if err != nil { panic(err) } + RWConn := sql.OpenDB(dialect.Postgres, rawRW) + ROConn := sql.OpenDB(dialect.Postgres, rawRO) + + logx.Infof("success to connect to postgres~") redisConn, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second) if err != nil || redisConn == nil { @@ -49,7 +57,7 @@ func NewServiceContext(c config.Config) *ServiceContext { UserVeriModelRW: models.NewClient(models.Driver(RWDrv)).UserVerifications, UserVeriModelRO: models.NewClient(models.Driver(RODrv)).UserVerifications, RedisClient: redisConn.Client, - UserVeriRpc: userverifications.NewUserVerificationsZrpcClient(zrpc.MustNewClient(c.UserVeriRpcConf)), SnowflakeRpc: snowflakex.NewClient(c.SnowflakeRpcConf), + UserRpc: usercenter.NewUsercenter(zrpc.MustNewClient(c.UserRpcConf)), } } diff --git a/app/user_verifications/rpc/pb/user_verifications.pb.go b/app/user_verifications/rpc/pb/user_verifications.pb.go index fcdd59c..c1a7300 100644 --- a/app/user_verifications/rpc/pb/user_verifications.pb.go +++ b/app/user_verifications/rpc/pb/user_verifications.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v3.19.4 +// protoc v5.29.6 // source: user_verifications.proto package pb @@ -778,6 +778,198 @@ func (x *SearchUserVerificationsResp) GetUserVerifications() []*UserVerification return nil } +type AddOrUpdateUserVerificationsReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` // userId + Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"` + Material string `protobuf:"bytes,3,opt,name=material,proto3" json:"material,omitempty"` // material + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddOrUpdateUserVerificationsReq) Reset() { + *x = AddOrUpdateUserVerificationsReq{} + mi := &file_user_verifications_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddOrUpdateUserVerificationsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddOrUpdateUserVerificationsReq) ProtoMessage() {} + +func (x *AddOrUpdateUserVerificationsReq) ProtoReflect() protoreflect.Message { + mi := &file_user_verifications_proto_msgTypes[11] + 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 AddOrUpdateUserVerificationsReq.ProtoReflect.Descriptor instead. +func (*AddOrUpdateUserVerificationsReq) Descriptor() ([]byte, []int) { + return file_user_verifications_proto_rawDescGZIP(), []int{11} +} + +func (x *AddOrUpdateUserVerificationsReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *AddOrUpdateUserVerificationsReq) GetRole() string { + if x != nil { + return x.Role + } + return "" +} + +func (x *AddOrUpdateUserVerificationsReq) GetMaterial() string { + if x != nil { + return x.Material + } + return "" +} + +type AddOrUpdateUserVerificationsResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` // success + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddOrUpdateUserVerificationsResp) Reset() { + *x = AddOrUpdateUserVerificationsResp{} + mi := &file_user_verifications_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddOrUpdateUserVerificationsResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddOrUpdateUserVerificationsResp) ProtoMessage() {} + +func (x *AddOrUpdateUserVerificationsResp) ProtoReflect() protoreflect.Message { + mi := &file_user_verifications_proto_msgTypes[12] + 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 AddOrUpdateUserVerificationsResp.ProtoReflect.Descriptor instead. +func (*AddOrUpdateUserVerificationsResp) Descriptor() ([]byte, []int) { + return file_user_verifications_proto_rawDescGZIP(), []int{12} +} + +func (x *AddOrUpdateUserVerificationsResp) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type ListUserVerificationsByUserIdReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` // userId + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListUserVerificationsByUserIdReq) Reset() { + *x = ListUserVerificationsByUserIdReq{} + mi := &file_user_verifications_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListUserVerificationsByUserIdReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUserVerificationsByUserIdReq) ProtoMessage() {} + +func (x *ListUserVerificationsByUserIdReq) ProtoReflect() protoreflect.Message { + mi := &file_user_verifications_proto_msgTypes[13] + 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 ListUserVerificationsByUserIdReq.ProtoReflect.Descriptor instead. +func (*ListUserVerificationsByUserIdReq) Descriptor() ([]byte, []int) { + return file_user_verifications_proto_rawDescGZIP(), []int{13} +} + +func (x *ListUserVerificationsByUserIdReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +type ListUserVerificationsByUserIdResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserVerifications []*UserVerifications `protobuf:"bytes,1,rep,name=userVerifications,proto3" json:"userVerifications,omitempty"` // userVerifications + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListUserVerificationsByUserIdResp) Reset() { + *x = ListUserVerificationsByUserIdResp{} + mi := &file_user_verifications_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListUserVerificationsByUserIdResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUserVerificationsByUserIdResp) ProtoMessage() {} + +func (x *ListUserVerificationsByUserIdResp) ProtoReflect() protoreflect.Message { + mi := &file_user_verifications_proto_msgTypes[14] + 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 ListUserVerificationsByUserIdResp.ProtoReflect.Descriptor instead. +func (*ListUserVerificationsByUserIdResp) Descriptor() ([]byte, []int) { + return file_user_verifications_proto_rawDescGZIP(), []int{14} +} + +func (x *ListUserVerificationsByUserIdResp) GetUserVerifications() []*UserVerifications { + if x != nil { + return x.UserVerifications + } + return nil +} + var File_user_verifications_proto protoreflect.FileDescriptor const file_user_verifications_proto_rawDesc = "" + @@ -863,13 +1055,25 @@ const file_user_verifications_proto_rawDesc = "" + "\tcreatedAt\x18\v \x01(\x03R\tcreatedAt\x12\x1c\n" + "\tupdatedAt\x18\f \x01(\x03R\tupdatedAt\"b\n" + "\x1bSearchUserVerificationsResp\x12C\n" + - "\x11userVerifications\x18\x01 \x03(\v2\x15.pb.UserVerificationsR\x11userVerifications2\xd1\x03\n" + + "\x11userVerifications\x18\x01 \x03(\v2\x15.pb.UserVerificationsR\x11userVerifications\"i\n" + + "\x1fAddOrUpdateUserVerificationsReq\x12\x16\n" + + "\x06userId\x18\x01 \x01(\x03R\x06userId\x12\x12\n" + + "\x04role\x18\x02 \x01(\tR\x04role\x12\x1a\n" + + "\bmaterial\x18\x03 \x01(\tR\bmaterial\"<\n" + + " AddOrUpdateUserVerificationsResp\x12\x18\n" + + "\asuccess\x18\x01 \x01(\bR\asuccess\":\n" + + " ListUserVerificationsByUserIdReq\x12\x16\n" + + "\x06userId\x18\x01 \x01(\x03R\x06userId\"h\n" + + "!ListUserVerificationsByUserIdResp\x12C\n" + + "\x11userVerifications\x18\x01 \x03(\v2\x15.pb.UserVerificationsR\x11userVerifications2\xaa\x05\n" + "\x12user_verifications\x12Q\n" + "\x14AddUserVerifications\x12\x1b.pb.AddUserVerificationsReq\x1a\x1c.pb.AddUserVerificationsResp\x12Z\n" + "\x17UpdateUserVerifications\x12\x1e.pb.UpdateUserVerificationsReq\x1a\x1f.pb.UpdateUserVerificationsResp\x12Q\n" + "\x14DelUserVerifications\x12\x1b.pb.DelUserVerificationsReq\x1a\x1c.pb.DelUserVerificationsResp\x12]\n" + "\x18GetUserVerificationsById\x12\x1f.pb.GetUserVerificationsByIdReq\x1a .pb.GetUserVerificationsByIdResp\x12Z\n" + - "\x17SearchUserVerifications\x12\x1e.pb.SearchUserVerificationsReq\x1a\x1f.pb.SearchUserVerificationsRespB\x06Z\x04./pbb\x06proto3" + "\x17SearchUserVerifications\x12\x1e.pb.SearchUserVerificationsReq\x1a\x1f.pb.SearchUserVerificationsResp\x12i\n" + + "\x1cAddOrUpdateUserVerifications\x12#.pb.AddOrUpdateUserVerificationsReq\x1a$.pb.AddOrUpdateUserVerificationsResp\x12l\n" + + "\x1dListUserVerificationsByUserId\x12$.pb.ListUserVerificationsByUserIdReq\x1a%.pb.ListUserVerificationsByUserIdRespB\x06Z\x04./pbb\x06proto3" var ( file_user_verifications_proto_rawDescOnce sync.Once @@ -883,38 +1087,47 @@ func file_user_verifications_proto_rawDescGZIP() []byte { return file_user_verifications_proto_rawDescData } -var file_user_verifications_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_user_verifications_proto_msgTypes = make([]protoimpl.MessageInfo, 15) var file_user_verifications_proto_goTypes = []any{ - (*UserVerifications)(nil), // 0: pb.UserVerifications - (*AddUserVerificationsReq)(nil), // 1: pb.AddUserVerificationsReq - (*AddUserVerificationsResp)(nil), // 2: pb.AddUserVerificationsResp - (*UpdateUserVerificationsReq)(nil), // 3: pb.UpdateUserVerificationsReq - (*UpdateUserVerificationsResp)(nil), // 4: pb.UpdateUserVerificationsResp - (*DelUserVerificationsReq)(nil), // 5: pb.DelUserVerificationsReq - (*DelUserVerificationsResp)(nil), // 6: pb.DelUserVerificationsResp - (*GetUserVerificationsByIdReq)(nil), // 7: pb.GetUserVerificationsByIdReq - (*GetUserVerificationsByIdResp)(nil), // 8: pb.GetUserVerificationsByIdResp - (*SearchUserVerificationsReq)(nil), // 9: pb.SearchUserVerificationsReq - (*SearchUserVerificationsResp)(nil), // 10: pb.SearchUserVerificationsResp + (*UserVerifications)(nil), // 0: pb.UserVerifications + (*AddUserVerificationsReq)(nil), // 1: pb.AddUserVerificationsReq + (*AddUserVerificationsResp)(nil), // 2: pb.AddUserVerificationsResp + (*UpdateUserVerificationsReq)(nil), // 3: pb.UpdateUserVerificationsReq + (*UpdateUserVerificationsResp)(nil), // 4: pb.UpdateUserVerificationsResp + (*DelUserVerificationsReq)(nil), // 5: pb.DelUserVerificationsReq + (*DelUserVerificationsResp)(nil), // 6: pb.DelUserVerificationsResp + (*GetUserVerificationsByIdReq)(nil), // 7: pb.GetUserVerificationsByIdReq + (*GetUserVerificationsByIdResp)(nil), // 8: pb.GetUserVerificationsByIdResp + (*SearchUserVerificationsReq)(nil), // 9: pb.SearchUserVerificationsReq + (*SearchUserVerificationsResp)(nil), // 10: pb.SearchUserVerificationsResp + (*AddOrUpdateUserVerificationsReq)(nil), // 11: pb.AddOrUpdateUserVerificationsReq + (*AddOrUpdateUserVerificationsResp)(nil), // 12: pb.AddOrUpdateUserVerificationsResp + (*ListUserVerificationsByUserIdReq)(nil), // 13: pb.ListUserVerificationsByUserIdReq + (*ListUserVerificationsByUserIdResp)(nil), // 14: pb.ListUserVerificationsByUserIdResp } var file_user_verifications_proto_depIdxs = []int32{ 0, // 0: pb.GetUserVerificationsByIdResp.userVerifications:type_name -> pb.UserVerifications 0, // 1: pb.SearchUserVerificationsResp.userVerifications:type_name -> pb.UserVerifications - 1, // 2: pb.user_verifications.AddUserVerifications:input_type -> pb.AddUserVerificationsReq - 3, // 3: pb.user_verifications.UpdateUserVerifications:input_type -> pb.UpdateUserVerificationsReq - 5, // 4: pb.user_verifications.DelUserVerifications:input_type -> pb.DelUserVerificationsReq - 7, // 5: pb.user_verifications.GetUserVerificationsById:input_type -> pb.GetUserVerificationsByIdReq - 9, // 6: pb.user_verifications.SearchUserVerifications:input_type -> pb.SearchUserVerificationsReq - 2, // 7: pb.user_verifications.AddUserVerifications:output_type -> pb.AddUserVerificationsResp - 4, // 8: pb.user_verifications.UpdateUserVerifications:output_type -> pb.UpdateUserVerificationsResp - 6, // 9: pb.user_verifications.DelUserVerifications:output_type -> pb.DelUserVerificationsResp - 8, // 10: pb.user_verifications.GetUserVerificationsById:output_type -> pb.GetUserVerificationsByIdResp - 10, // 11: pb.user_verifications.SearchUserVerifications:output_type -> pb.SearchUserVerificationsResp - 7, // [7:12] is the sub-list for method output_type - 2, // [2:7] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 0, // 2: pb.ListUserVerificationsByUserIdResp.userVerifications:type_name -> pb.UserVerifications + 1, // 3: pb.user_verifications.AddUserVerifications:input_type -> pb.AddUserVerificationsReq + 3, // 4: pb.user_verifications.UpdateUserVerifications:input_type -> pb.UpdateUserVerificationsReq + 5, // 5: pb.user_verifications.DelUserVerifications:input_type -> pb.DelUserVerificationsReq + 7, // 6: pb.user_verifications.GetUserVerificationsById:input_type -> pb.GetUserVerificationsByIdReq + 9, // 7: pb.user_verifications.SearchUserVerifications:input_type -> pb.SearchUserVerificationsReq + 11, // 8: pb.user_verifications.AddOrUpdateUserVerifications:input_type -> pb.AddOrUpdateUserVerificationsReq + 13, // 9: pb.user_verifications.ListUserVerificationsByUserId:input_type -> pb.ListUserVerificationsByUserIdReq + 2, // 10: pb.user_verifications.AddUserVerifications:output_type -> pb.AddUserVerificationsResp + 4, // 11: pb.user_verifications.UpdateUserVerifications:output_type -> pb.UpdateUserVerificationsResp + 6, // 12: pb.user_verifications.DelUserVerifications:output_type -> pb.DelUserVerificationsResp + 8, // 13: pb.user_verifications.GetUserVerificationsById:output_type -> pb.GetUserVerificationsByIdResp + 10, // 14: pb.user_verifications.SearchUserVerifications:output_type -> pb.SearchUserVerificationsResp + 12, // 15: pb.user_verifications.AddOrUpdateUserVerifications:output_type -> pb.AddOrUpdateUserVerificationsResp + 14, // 16: pb.user_verifications.ListUserVerificationsByUserId:output_type -> pb.ListUserVerificationsByUserIdResp + 10, // [10:17] is the sub-list for method output_type + 3, // [3:10] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_user_verifications_proto_init() } @@ -929,7 +1142,7 @@ func file_user_verifications_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_verifications_proto_rawDesc), len(file_user_verifications_proto_rawDesc)), NumEnums: 0, - NumMessages: 11, + NumMessages: 15, NumExtensions: 0, NumServices: 1, }, diff --git a/app/user_verifications/rpc/pb/user_verifications_grpc.pb.go b/app/user_verifications/rpc/pb/user_verifications_grpc.pb.go index 6d3b409..eba2d43 100644 --- a/app/user_verifications/rpc/pb/user_verifications_grpc.pb.go +++ b/app/user_verifications/rpc/pb/user_verifications_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.6.1 -// - protoc v3.19.4 +// - protoc v5.29.6 // source: user_verifications.proto package pb @@ -19,11 +19,13 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - UserVerifications_AddUserVerifications_FullMethodName = "/pb.user_verifications/AddUserVerifications" - UserVerifications_UpdateUserVerifications_FullMethodName = "/pb.user_verifications/UpdateUserVerifications" - UserVerifications_DelUserVerifications_FullMethodName = "/pb.user_verifications/DelUserVerifications" - UserVerifications_GetUserVerificationsById_FullMethodName = "/pb.user_verifications/GetUserVerificationsById" - UserVerifications_SearchUserVerifications_FullMethodName = "/pb.user_verifications/SearchUserVerifications" + UserVerifications_AddUserVerifications_FullMethodName = "/pb.user_verifications/AddUserVerifications" + UserVerifications_UpdateUserVerifications_FullMethodName = "/pb.user_verifications/UpdateUserVerifications" + UserVerifications_DelUserVerifications_FullMethodName = "/pb.user_verifications/DelUserVerifications" + UserVerifications_GetUserVerificationsById_FullMethodName = "/pb.user_verifications/GetUserVerificationsById" + UserVerifications_SearchUserVerifications_FullMethodName = "/pb.user_verifications/SearchUserVerifications" + UserVerifications_AddOrUpdateUserVerifications_FullMethodName = "/pb.user_verifications/AddOrUpdateUserVerifications" + UserVerifications_ListUserVerificationsByUserId_FullMethodName = "/pb.user_verifications/ListUserVerificationsByUserId" ) // UserVerificationsClient is the client API for UserVerifications service. @@ -36,6 +38,8 @@ type UserVerificationsClient interface { DelUserVerifications(ctx context.Context, in *DelUserVerificationsReq, opts ...grpc.CallOption) (*DelUserVerificationsResp, error) GetUserVerificationsById(ctx context.Context, in *GetUserVerificationsByIdReq, opts ...grpc.CallOption) (*GetUserVerificationsByIdResp, error) SearchUserVerifications(ctx context.Context, in *SearchUserVerificationsReq, opts ...grpc.CallOption) (*SearchUserVerificationsResp, error) + AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error) + ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error) } type userVerificationsClient struct { @@ -96,6 +100,26 @@ func (c *userVerificationsClient) SearchUserVerifications(ctx context.Context, i return out, nil } +func (c *userVerificationsClient) AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AddOrUpdateUserVerificationsResp) + err := c.cc.Invoke(ctx, UserVerifications_AddOrUpdateUserVerifications_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userVerificationsClient) ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListUserVerificationsByUserIdResp) + err := c.cc.Invoke(ctx, UserVerifications_ListUserVerificationsByUserId_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // UserVerificationsServer is the server API for UserVerifications service. // All implementations must embed UnimplementedUserVerificationsServer // for forward compatibility. @@ -106,6 +130,8 @@ type UserVerificationsServer interface { DelUserVerifications(context.Context, *DelUserVerificationsReq) (*DelUserVerificationsResp, error) GetUserVerificationsById(context.Context, *GetUserVerificationsByIdReq) (*GetUserVerificationsByIdResp, error) SearchUserVerifications(context.Context, *SearchUserVerificationsReq) (*SearchUserVerificationsResp, error) + AddOrUpdateUserVerifications(context.Context, *AddOrUpdateUserVerificationsReq) (*AddOrUpdateUserVerificationsResp, error) + ListUserVerificationsByUserId(context.Context, *ListUserVerificationsByUserIdReq) (*ListUserVerificationsByUserIdResp, error) mustEmbedUnimplementedUserVerificationsServer() } @@ -131,6 +157,12 @@ func (UnimplementedUserVerificationsServer) GetUserVerificationsById(context.Con func (UnimplementedUserVerificationsServer) SearchUserVerifications(context.Context, *SearchUserVerificationsReq) (*SearchUserVerificationsResp, error) { return nil, status.Error(codes.Unimplemented, "method SearchUserVerifications not implemented") } +func (UnimplementedUserVerificationsServer) AddOrUpdateUserVerifications(context.Context, *AddOrUpdateUserVerificationsReq) (*AddOrUpdateUserVerificationsResp, error) { + return nil, status.Error(codes.Unimplemented, "method AddOrUpdateUserVerifications not implemented") +} +func (UnimplementedUserVerificationsServer) ListUserVerificationsByUserId(context.Context, *ListUserVerificationsByUserIdReq) (*ListUserVerificationsByUserIdResp, error) { + return nil, status.Error(codes.Unimplemented, "method ListUserVerificationsByUserId not implemented") +} func (UnimplementedUserVerificationsServer) mustEmbedUnimplementedUserVerificationsServer() {} func (UnimplementedUserVerificationsServer) testEmbeddedByValue() {} @@ -242,6 +274,42 @@ func _UserVerifications_SearchUserVerifications_Handler(srv interface{}, ctx con return interceptor(ctx, in, info, handler) } +func _UserVerifications_AddOrUpdateUserVerifications_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddOrUpdateUserVerificationsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserVerificationsServer).AddOrUpdateUserVerifications(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserVerifications_AddOrUpdateUserVerifications_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserVerificationsServer).AddOrUpdateUserVerifications(ctx, req.(*AddOrUpdateUserVerificationsReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserVerifications_ListUserVerificationsByUserId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListUserVerificationsByUserIdReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserVerificationsServer).ListUserVerificationsByUserId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserVerifications_ListUserVerificationsByUserId_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserVerificationsServer).ListUserVerificationsByUserId(ctx, req.(*ListUserVerificationsByUserIdReq)) + } + return interceptor(ctx, in, info, handler) +} + // UserVerifications_ServiceDesc is the grpc.ServiceDesc for UserVerifications service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -269,6 +337,14 @@ var UserVerifications_ServiceDesc = grpc.ServiceDesc{ MethodName: "SearchUserVerifications", Handler: _UserVerifications_SearchUserVerifications_Handler, }, + { + MethodName: "AddOrUpdateUserVerifications", + Handler: _UserVerifications_AddOrUpdateUserVerifications_Handler, + }, + { + MethodName: "ListUserVerificationsByUserId", + Handler: _UserVerifications_ListUserVerificationsByUserId_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "user_verifications.proto", diff --git a/app/user_verifications/rpc/userverifications/userVerifications.go b/app/user_verifications/rpc/userverifications/userVerifications.go index ed4eff4..b5ca7ae 100644 --- a/app/user_verifications/rpc/userverifications/userVerifications.go +++ b/app/user_verifications/rpc/userverifications/userVerifications.go @@ -14,17 +14,21 @@ import ( ) type ( - AddUserVerificationsReq = pb.AddUserVerificationsReq - AddUserVerificationsResp = pb.AddUserVerificationsResp - DelUserVerificationsReq = pb.DelUserVerificationsReq - DelUserVerificationsResp = pb.DelUserVerificationsResp - GetUserVerificationsByIdReq = pb.GetUserVerificationsByIdReq - GetUserVerificationsByIdResp = pb.GetUserVerificationsByIdResp - SearchUserVerificationsReq = pb.SearchUserVerificationsReq - SearchUserVerificationsResp = pb.SearchUserVerificationsResp - UpdateUserVerificationsReq = pb.UpdateUserVerificationsReq - UpdateUserVerificationsResp = pb.UpdateUserVerificationsResp - UserVerifications = pb.UserVerifications + AddOrUpdateUserVerificationsReq = pb.AddOrUpdateUserVerificationsReq + AddOrUpdateUserVerificationsResp = pb.AddOrUpdateUserVerificationsResp + AddUserVerificationsReq = pb.AddUserVerificationsReq + AddUserVerificationsResp = pb.AddUserVerificationsResp + DelUserVerificationsReq = pb.DelUserVerificationsReq + DelUserVerificationsResp = pb.DelUserVerificationsResp + GetUserVerificationsByIdReq = pb.GetUserVerificationsByIdReq + GetUserVerificationsByIdResp = pb.GetUserVerificationsByIdResp + ListUserVerificationsByUserIdReq = pb.ListUserVerificationsByUserIdReq + ListUserVerificationsByUserIdResp = pb.ListUserVerificationsByUserIdResp + SearchUserVerificationsReq = pb.SearchUserVerificationsReq + SearchUserVerificationsResp = pb.SearchUserVerificationsResp + UpdateUserVerificationsReq = pb.UpdateUserVerificationsReq + UpdateUserVerificationsResp = pb.UpdateUserVerificationsResp + UserVerifications = pb.UserVerifications UserVerificationsZrpcClient interface { // -----------------------userVerifications----------------------- @@ -33,6 +37,8 @@ type ( DelUserVerifications(ctx context.Context, in *DelUserVerificationsReq, opts ...grpc.CallOption) (*DelUserVerificationsResp, error) GetUserVerificationsById(ctx context.Context, in *GetUserVerificationsByIdReq, opts ...grpc.CallOption) (*GetUserVerificationsByIdResp, error) SearchUserVerifications(ctx context.Context, in *SearchUserVerificationsReq, opts ...grpc.CallOption) (*SearchUserVerificationsResp, error) + AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error) + ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error) } defaultUserVerificationsZrpcClient struct { @@ -71,3 +77,13 @@ func (m *defaultUserVerificationsZrpcClient) SearchUserVerifications(ctx context client := pb.NewUserVerificationsClient(m.cli.Conn()) return client.SearchUserVerifications(ctx, in, opts...) } + +func (m *defaultUserVerificationsZrpcClient) AddOrUpdateUserVerifications(ctx context.Context, in *AddOrUpdateUserVerificationsReq, opts ...grpc.CallOption) (*AddOrUpdateUserVerificationsResp, error) { + client := pb.NewUserVerificationsClient(m.cli.Conn()) + return client.AddOrUpdateUserVerifications(ctx, in, opts...) +} + +func (m *defaultUserVerificationsZrpcClient) ListUserVerificationsByUserId(ctx context.Context, in *ListUserVerificationsByUserIdReq, opts ...grpc.CallOption) (*ListUserVerificationsByUserIdResp, error) { + client := pb.NewUserVerificationsClient(m.cli.Conn()) + return client.ListUserVerificationsByUserId(ctx, in, opts...) +} diff --git a/app/users/api/etc/user-api.yaml b/app/users/api/etc/user-api.yaml index 9ec0dfa..8d01408 100644 --- a/app/users/api/etc/user-api.yaml +++ b/app/users/api/etc/user-api.yaml @@ -7,9 +7,19 @@ Prometheus: Port: 4001 Path: /metrics +# ===== PROC CONFIG ===== +#UsercenterRpcConf: +# Target: k8s://juwan/user-rpc-svc:8080 +#UserVerificationRpc: +# Target: k8s://juwan/user_verifications-svc:8080 -SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc:8080 - +# ===== DEV CONFIG ==== UserVerificationRpc: - Target: k8s://juwan/user_verifications-svc:8080 + Endpoints: + - user-verifications-rpc:8080 +UsercenterRpcConf: + Endpoints: + - user-rpc:8080 + +Log: + Level: debug \ No newline at end of file diff --git a/app/users/api/internal/handler/routes.go b/app/users/api/internal/handler/routes.go index 578bf8d..9999ad1 100644 --- a/app/users/api/internal/handler/routes.go +++ b/app/users/api/internal/handler/routes.go @@ -146,23 +146,20 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { ) server.AddRoutes( - rest.WithMiddlewares( - []rest.Middleware{serverCtx.Logger}, - []rest.Route{ - { - // 提交或修改角色认证申请 (支持幂等更新) - Method: http.MethodPost, - Path: "/me/verification", - Handler: verification_user.ApplyVerificationHandler(serverCtx), - }, - { - // 获取我的所有认证状态 - Method: http.MethodGet, - Path: "/me/verification", - Handler: verification_user.GetMyVerificationsHandler(serverCtx), - }, - }..., - ), + []rest.Route{ + { + // 提交或修改角色认证申请 (支持幂等更新) + Method: http.MethodPost, + Path: "/me/verification", + Handler: verification_user.ApplyVerificationHandler(serverCtx), + }, + { + // 获取我的所有认证状态 + Method: http.MethodGet, + Path: "/me/verification", + Handler: verification_user.GetMyVerificationsHandler(serverCtx), + }, + }, rest.WithPrefix("/api/v1/users"), ) } diff --git a/app/users/api/internal/logic/auth/registerLogic.go b/app/users/api/internal/logic/auth/registerLogic.go index 911fd5f..7217ee1 100644 --- a/app/users/api/internal/logic/auth/registerLogic.go +++ b/app/users/api/internal/logic/auth/registerLogic.go @@ -6,6 +6,7 @@ package auth import ( "context" "errors" + "fmt" "juwan-backend/app/users/rpc/pb" "juwan-backend/app/users/rpc/usercenter" "juwan-backend/common/utils/contextj" @@ -57,7 +58,8 @@ func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.RegisterRe return nil, errors.New("hash password failed") } - requestId, err := contextj.RequestIdFrom(l.ctx) + requestId, err := contextj.RIdFrom(l.ctx) + logx.Infof("requestId: %s", requestId) if err != nil { logx.Errorf("contextj.RequestIdFrom failed: %v", err) return nil, errors.New("contextj.RequestIdFrom failed") @@ -73,7 +75,7 @@ func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.RegisterRe }) if err != nil { logx.Error("failed to register user: ", err) - return nil, errors.New("failed to register user") + return nil, errors.New(fmt.Sprintf("failed to register user: %v", err.Error())) } // 返回响应 diff --git a/app/users/api/internal/logic/user/followUserLogic.go b/app/users/api/internal/logic/user/followUserLogic.go index 49bd0cf..2ab73b6 100644 --- a/app/users/api/internal/logic/user/followUserLogic.go +++ b/app/users/api/internal/logic/user/followUserLogic.go @@ -5,6 +5,9 @@ package user import ( "context" + "errors" + "juwan-backend/app/users/rpc/usercenter" + "juwan-backend/common/utils/contextj" "juwan-backend/app/users/api/internal/svc" "juwan-backend/app/users/api/internal/types" @@ -29,6 +32,19 @@ func NewFollowUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Follow func (l *FollowUserLogic) FollowUser(req *types.FollowUserReq) (resp *types.EmptyResp, err error) { // todo: add your logic here and delete this line + userId, err := contextj.UserIDFrom(l.ctx) + if err != nil { + return nil, errors.New("unauthorized") + } - return + _, err = l.svcCtx.UserRpc.AddUserFollows(l.ctx, &usercenter.AddUserFollowsReq{ + FollowerId: userId, + FolloweeId: req.Id, + CreatedAt: 0, + }) + if err != nil { + logx.Errorf("add user follow err: %v", err) + return nil, errors.New("failed to follow user") + } + return &types.EmptyResp{}, nil } diff --git a/app/users/api/internal/logic/user/getMeLogic.go b/app/users/api/internal/logic/user/getMeLogic.go index 325968b..ff7587e 100644 --- a/app/users/api/internal/logic/user/getMeLogic.go +++ b/app/users/api/internal/logic/user/getMeLogic.go @@ -6,15 +6,15 @@ package user import ( "context" "errors" + "juwan-backend/app/users/api/internal/svc" + "juwan-backend/app/users/api/internal/types" "juwan-backend/app/users/rpc/usercenter" - "juwan-backend/common/converter" "juwan-backend/common/utils/contextj" "time" - "juwan-backend/app/users/api/internal/svc" - "juwan-backend/app/users/api/internal/types" - + "github.com/jinzhu/copier" "github.com/zeromicro/go-zero/core/logx" + "k8s.io/apimachinery/pkg/util/json" ) type GetMeLogic struct { @@ -35,19 +35,34 @@ func NewGetMeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMeLogic func (l *GetMeLogic) GetMe() (resp *types.User, err error) { userId, err := contextj.UserIDFrom(l.ctx) if err != nil { - return nil, errors.New("illegal id") + logx.Errorf("get user id from context: %v", err) + return nil, errors.New("illegal user") } + user, err := l.svcCtx.UserRpc.GetUsersById(l.ctx, &usercenter.GetUsersByIdReq{ Id: userId, }) if err != nil { - return nil, errors.New("get user by id error") + logx.Errorf("GetMeLogic.GetUsersById err: %v", err) + return nil, errors.New("get user failed") } - err = converter.StructToStruct(user, &resp) - createAt := time.Unix(user.Users.CreatedAt, 0) - resp.CreatedAt = createAt.Format(time.DateTime) + logx.Debugf("get user resp: %+v", user) + + resp = &types.User{} + + err = copier.Copy(&resp, user.Users) if err != nil { - return nil, errors.New("to struct error") + logx.Errorf("copier.Copy err: %v", err) + return nil, errors.New("copy user failed") } + + var verificationStatus map[string]string + err = json.Unmarshal([]byte(user.Users.VerificationStatus), &verificationStatus) + if err != nil { + logx.Errorf("json.Unmarshal err: %v", err) + } + resp.VerifiedRoles = user.Users.VerifiedRoles + resp.VerificationStatus = verificationStatus + resp.CreatedAt = time.Unix(user.Users.CreatedAt, 0).Format(time.DateTime) return } diff --git a/app/users/api/internal/logic/user/switchRoleLogic.go b/app/users/api/internal/logic/user/switchRoleLogic.go index e49e7c5..7cd5f9f 100644 --- a/app/users/api/internal/logic/user/switchRoleLogic.go +++ b/app/users/api/internal/logic/user/switchRoleLogic.go @@ -32,7 +32,6 @@ func NewSwitchRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Switch } func (l *SwitchRoleLogic) SwitchRole(req *types.SwitchRoleReq) (resp *types.EmptyResp, err error) { - // todo: add your logic here and delete this line id, err := contextj.UserIDFrom(l.ctx) if err != nil { logx.Errorf("get user id from context: %v", err) diff --git a/app/users/api/internal/logic/user/unfollowUserLogic.go b/app/users/api/internal/logic/user/unfollowUserLogic.go index 3fb1cdd..10c9e88 100644 --- a/app/users/api/internal/logic/user/unfollowUserLogic.go +++ b/app/users/api/internal/logic/user/unfollowUserLogic.go @@ -5,6 +5,9 @@ package user import ( "context" + "errors" + "juwan-backend/app/users/rpc/usercenter" + "juwan-backend/common/utils/contextj" "juwan-backend/app/users/api/internal/svc" "juwan-backend/app/users/api/internal/types" @@ -29,6 +32,18 @@ func NewUnfollowUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Unfo func (l *UnfollowUserLogic) UnfollowUser(req *types.UnfollowUserReq) (resp *types.EmptyResp, err error) { // todo: add your logic here and delete this line + userId, err := contextj.UserIDFrom(l.ctx) + if err != nil { + return nil, errors.New("unauthorized") + } - return + _, err = l.svcCtx.UserRpc.DelUserFollows(l.ctx, &usercenter.DelUserFollowsReq{ + Id: req.Id, + UserId: userId, + }) + if err != nil { + logx.Errorf("del user follow err: %v", err) + return nil, errors.New("unfollow user failed") + } + return &types.EmptyResp{}, nil } diff --git a/app/users/api/internal/logic/user/updateNotificationSettingsLogic.go b/app/users/api/internal/logic/user/updateNotificationSettingsLogic.go index c1c3161..d3d0787 100644 --- a/app/users/api/internal/logic/user/updateNotificationSettingsLogic.go +++ b/app/users/api/internal/logic/user/updateNotificationSettingsLogic.go @@ -29,6 +29,5 @@ func NewUpdateNotificationSettingsLogic(ctx context.Context, svcCtx *svc.Service func (l *UpdateNotificationSettingsLogic) UpdateNotificationSettings(req *types.UpdateNotifySettingsReq) (resp *types.EmptyResp, err error) { // todo: add your logic here and delete this line - return } diff --git a/app/users/api/internal/logic/verification_admin/rejectVerificationLogic.go b/app/users/api/internal/logic/verification_admin/rejectVerificationLogic.go index a449f51..e225d8d 100644 --- a/app/users/api/internal/logic/verification_admin/rejectVerificationLogic.go +++ b/app/users/api/internal/logic/verification_admin/rejectVerificationLogic.go @@ -33,7 +33,6 @@ func NewRejectVerificationLogic(ctx context.Context, svcCtx *svc.ServiceContext) var REJECTED = "rejected" func (l *RejectVerificationLogic) RejectVerification(req *types.RejectVerificationReq) (resp *types.VerificationEmptyResp, err error) { - // todo: add your logic here and delete this line adminId, err := contextj.AdminIdFrom(l.ctx) if err != nil { return nil, err diff --git a/app/users/api/internal/logic/verification_user/applyVerificationLogic.go b/app/users/api/internal/logic/verification_user/applyVerificationLogic.go index ccad0b9..36bdbff 100644 --- a/app/users/api/internal/logic/verification_user/applyVerificationLogic.go +++ b/app/users/api/internal/logic/verification_user/applyVerificationLogic.go @@ -36,13 +36,6 @@ func (l *ApplyVerificationLogic) ApplyVerification(req *types.ApplyVerificationR logx.Errorf("get user id from context: %v", err) return nil, contextj.ERRILLEGALUSER } - verifications, err := l.svcCtx.UserVerificationsRpc.SearchUserVerifications(l.ctx, &pb.SearchUserVerificationsReq{ - UserId: userId, - }) - if err != nil { - logx.Errorf("search user verifications: %v", err) - return nil, errors.New("search user verifications failed") - } materials, err := json.Marshal(req.Materials) if err != nil { @@ -50,18 +43,14 @@ func (l *ApplyVerificationLogic) ApplyVerification(req *types.ApplyVerificationR return nil, err } - if verifications == nil || len(verifications.UserVerifications) == 0 { - // 如果没有则增加 - _, err = l.svcCtx.UserVerificationsRpc.AddUserVerifications(l.ctx, &pb.AddUserVerificationsReq{ - Role: req.Role, - Materials: string(materials), - }) - if err != nil { - logx.Errorf("add user verifications: %v", err) - return nil, errors.New("add user verifications failed") - } - } else { - + _, err = l.svcCtx.UserVerificationsRpc.AddOrUpdateUserVerifications(l.ctx, &pb.AddOrUpdateUserVerificationsReq{ + UserId: userId, + Role: req.Role, + Material: string(materials), + }) + if err != nil { + logx.Errorf("call AddOrUpdateUserVerifications: %v", err) + return nil, errors.New("apply verification failed: " + err.Error()) } return &types.VerificationEmptyResp{}, nil diff --git a/app/users/api/internal/logic/verification_user/getMyVerificationsLogic.go b/app/users/api/internal/logic/verification_user/getMyVerificationsLogic.go index 4f65cf9..30f81b9 100644 --- a/app/users/api/internal/logic/verification_user/getMyVerificationsLogic.go +++ b/app/users/api/internal/logic/verification_user/getMyVerificationsLogic.go @@ -32,23 +32,21 @@ func NewGetMyVerificationsLogic(ctx context.Context, svcCtx *svc.ServiceContext) } func (l *GetMyVerificationsLogic) GetMyVerifications() (resp *types.GetMyVerificationsResp, err error) { - // todo: add your logic here and delete this line userId, err := contextj.UserIDFrom(l.ctx) if err != nil { logx.Errorf("get user id from context: %v", err) return nil, contextj.ERRILLEGALUSER } - verifications, err := l.svcCtx.UserVerificationsRpc.SearchUserVerifications(l.ctx, &pb.SearchUserVerificationsReq{ + verifications, err := l.svcCtx.UserVerificationsRpc.ListUserVerificationsByUserId(l.ctx, &pb.ListUserVerificationsByUserIdReq{ UserId: userId, - Page: 1, - Limit: 100, // assuming a user won't have more than 100 verification records, adjust as needed }) if err != nil { return nil, err } var searchResults []types.VerificationItem + for _, v := range verifications.UserVerifications { temp := types.VerificationItem{} err = copier.Copy(&temp, v) diff --git a/app/users/api/internal/types/types.go b/app/users/api/internal/types/types.go index c5c16b1..02db594 100644 --- a/app/users/api/internal/types/types.go +++ b/app/users/api/internal/types/types.go @@ -4,8 +4,8 @@ package types type ApplyVerificationReq struct { - Role string `json:"role"` // 申请什么角色 - Materials map[string]string `json:"materials"` // 证明材料键值对 {"idCardFront": "http...", "license": "http..."} + Role string `json:"role"` // 申请什么角色 + Materials MaterialJson `json:"materials"` // 证明材料键值对 {"idCardFront": "http...", "license": "http..."} } type EmptyResp struct { @@ -56,6 +56,13 @@ type LoginResp struct { type LogoutReq struct { } +type MaterialJson struct { + IdCardFront string `json:"idCardFront"` // 身份证正面照片URL + IdCardBack string `json:"idCardBack"` // 身份证反面照片URL + GameScreenshots []string `json:"gameScreenshots"` // 游戏截图URL列表 + VoiceDemo string `json:"voiceDemo"` // 语音认证示例URL +} + type RegisterReq struct { Phone string `json:"phone,omitempty,optional"` Email string `json:"email,omitempty,"` diff --git a/app/users/api/users.go b/app/users/api/users.go index b023a60..3df890f 100644 --- a/app/users/api/users.go +++ b/app/users/api/users.go @@ -6,6 +6,7 @@ package main import ( "flag" "fmt" + "juwan-backend/common/middlewares" "juwan-backend/app/users/api/internal/config" "juwan-backend/app/users/api/internal/handler" @@ -24,6 +25,8 @@ func main() { conf.MustLoad(*configFile, &c) server := rest.MustNewServer(c.RestConf) + server.Use(middlewares.NewHeaderExtractorMiddleware().Handle) + server.Use(middlewares.NewRequestMiddleware().Handle) defer server.Stop() ctx := svc.NewServiceContext(c) diff --git a/app/users/rpc/etc/pb.yaml b/app/users/rpc/etc/pb.yaml index f4b2e19..2b074a3 100644 --- a/app/users/rpc/etc/pb.yaml +++ b/app/users/rpc/etc/pb.yaml @@ -1,5 +1,5 @@ Name: pb.rpc -ListenOn: 0.0.0.0:9001 +ListenOn: 0.0.0.0:8080 Prometheus: Host: 0.0.0.0 @@ -8,26 +8,45 @@ Prometheus: DataSource: "${DB_URI}?sslmode=disable" + +# ===== PROC CONFIG ===== +#SnowflakeRpcConf: +# Target: k8s://juwan/snowflake-svc:8080 +# +#DB: +# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# +#CacheConf: +# - Host: "${REDIS_M_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# - Host: "${REDIS_S_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# +#Jwt: +# SecretKey: "${JWT_SECRET_KEY}" +# Issuer: "juwan-user-rpc" + +# ===== DEV CONFIG ===== SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc:8080 + Endpoints: + - snowflake:8080 DB: - Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" + Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" CacheConf: - - Host: "${REDIS_M_HOST}" + - Host: "${REDIS_HOST}:${REDIS_PORT}" Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" - - Host: "${REDIS_S_HOST}" - Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" Jwt: - SecretKey: "${JWT_SECRET_KEY}" + SecretKey: "MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ" Issuer: "juwan-user-rpc" Log: - Level: info \ No newline at end of file + Level: debug diff --git a/app/users/rpc/internal/logic/addUserFollowsLogic.go b/app/users/rpc/internal/logic/addUserFollowsLogic.go new file mode 100644 index 0000000..c7a7aff --- /dev/null +++ b/app/users/rpc/internal/logic/addUserFollowsLogic.go @@ -0,0 +1,46 @@ +package logic + +import ( + "context" + "errors" + "juwan-backend/app/snowflake/rpc/snowflake" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type AddUserFollowsLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewAddUserFollowsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddUserFollowsLogic { + return &AddUserFollowsLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +// -----------------------userFollows----------------------- +func (l *AddUserFollowsLogic) AddUserFollows(in *pb.AddUserFollowsReq) (*pb.AddUserFollowsResp, error) { + idResp, err := l.svcCtx.Snowflake.NextId(l.ctx, &snowflake.NextIdReq{}) + if err != nil { + logx.WithContext(l.ctx).Errorf("AddUserFollows error: %s", err.Error()) + return nil, err + } + + _, err = l.svcCtx.UsersModelRW.UserFollows.Create(). + SetFollowerID(in.FollowerId). + SetFolloweeID(in.FolloweeId). + SetID(idResp.Id). + Save(l.ctx) + if err != nil { + logx.WithContext(l.ctx).Errorf("AddUserFollows error: %s", err.Error()) + return nil, errors.New("failed to add user follow relationship") + } + return &pb.AddUserFollowsResp{}, nil +} diff --git a/app/users/rpc/internal/logic/addUserPreferencesLogic.go b/app/users/rpc/internal/logic/addUserPreferencesLogic.go new file mode 100644 index 0000000..17c9641 --- /dev/null +++ b/app/users/rpc/internal/logic/addUserPreferencesLogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type AddUserPreferencesLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewAddUserPreferencesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddUserPreferencesLogic { + return &AddUserPreferencesLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +// -----------------------userPreferences----------------------- +func (l *AddUserPreferencesLogic) AddUserPreferences(in *pb.AddUserPreferencesReq) (*pb.AddUserPreferencesResp, error) { + // todo: add your logic here and delete this line + + return &pb.AddUserPreferencesResp{}, nil +} diff --git a/app/users/rpc/internal/logic/delUserFollowsLogic.go b/app/users/rpc/internal/logic/delUserFollowsLogic.go new file mode 100644 index 0000000..013537a --- /dev/null +++ b/app/users/rpc/internal/logic/delUserFollowsLogic.go @@ -0,0 +1,39 @@ +package logic + +import ( + "context" + "errors" + "juwan-backend/app/users/rpc/internal/models/userfollows" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type DelUserFollowsLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewDelUserFollowsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DelUserFollowsLogic { + return &DelUserFollowsLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *DelUserFollowsLogic) DelUserFollows(in *pb.DelUserFollowsReq) (*pb.DelUserFollowsResp, error) { + _, err := l.svcCtx.UsersModelRW.UserFollows.Delete().Where( + userfollows.IDEQ(in.Id), + userfollows.FollowerIDEQ(in.UserId), + ).Exec(l.ctx) + + if err != nil { + logx.WithContext(l.ctx).Errorf("Failed to delete user follow: %s", err.Error()) + return nil, errors.New("failed to unfollow") + } + return &pb.DelUserFollowsResp{}, nil +} diff --git a/app/users/rpc/internal/logic/delUserPreferencesLogic.go b/app/users/rpc/internal/logic/delUserPreferencesLogic.go new file mode 100644 index 0000000..7ec056a --- /dev/null +++ b/app/users/rpc/internal/logic/delUserPreferencesLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type DelUserPreferencesLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewDelUserPreferencesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DelUserPreferencesLogic { + return &DelUserPreferencesLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *DelUserPreferencesLogic) DelUserPreferences(in *pb.DelUserPreferencesReq) (*pb.DelUserPreferencesResp, error) { + // todo: add your logic here and delete this line + + return &pb.DelUserPreferencesResp{}, nil +} diff --git a/app/users/rpc/internal/logic/getUserByUsernameLogic.go b/app/users/rpc/internal/logic/getUserByUsernameLogic.go index f090256..cd55ef3 100644 --- a/app/users/rpc/internal/logic/getUserByUsernameLogic.go +++ b/app/users/rpc/internal/logic/getUserByUsernameLogic.go @@ -29,7 +29,7 @@ func (l *GetUserByUsernameLogic) GetUserByUsername(in *pb.GetUserByUsernameReq) pbUsers := &pb.Users{} //user, err := l.svcCtx.UsersModelRO.FindOneByUsername(l.ctx, in.Username) - user, err := l.svcCtx.UsersModelRO.Query().Where(users.UsernameEQ(in.Username)).First(l.ctx) + user, err := l.svcCtx.UsersModelRO.Users.Query().Where(users.UsernameEQ(in.Username)).First(l.ctx) if err == nil || user != nil { return &pb.GetUserByUsernameResp{ Users: pbUsers, diff --git a/app/users/rpc/internal/logic/getUserFollowsByIdLogic.go b/app/users/rpc/internal/logic/getUserFollowsByIdLogic.go new file mode 100644 index 0000000..fd02931 --- /dev/null +++ b/app/users/rpc/internal/logic/getUserFollowsByIdLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetUserFollowsByIdLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetUserFollowsByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserFollowsByIdLogic { + return &GetUserFollowsByIdLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *GetUserFollowsByIdLogic) GetUserFollowsById(in *pb.GetUserFollowsByIdReq) (*pb.GetUserFollowsByIdResp, error) { + // todo: add your logic here and delete this line + + return &pb.GetUserFollowsByIdResp{}, nil +} diff --git a/app/users/rpc/internal/logic/getUserPreferencesByIdLogic.go b/app/users/rpc/internal/logic/getUserPreferencesByIdLogic.go new file mode 100644 index 0000000..a5d413d --- /dev/null +++ b/app/users/rpc/internal/logic/getUserPreferencesByIdLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetUserPreferencesByIdLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewGetUserPreferencesByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserPreferencesByIdLogic { + return &GetUserPreferencesByIdLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *GetUserPreferencesByIdLogic) GetUserPreferencesById(in *pb.GetUserPreferencesByIdReq) (*pb.GetUserPreferencesByIdResp, error) { + // todo: add your logic here and delete this line + + return &pb.GetUserPreferencesByIdResp{}, nil +} diff --git a/app/users/rpc/internal/logic/getUsersByIdLogic.go b/app/users/rpc/internal/logic/getUsersByIdLogic.go index 29b7f32..ab09c09 100644 --- a/app/users/rpc/internal/logic/getUsersByIdLogic.go +++ b/app/users/rpc/internal/logic/getUsersByIdLogic.go @@ -2,11 +2,12 @@ package logic import ( "context" + "encoding/json" + "errors" "juwan-backend/app/users/rpc/internal/models/users" "juwan-backend/app/users/rpc/internal/svc" "juwan-backend/app/users/rpc/pb" - "juwan-backend/common/converter" "github.com/zeromicro/go-zero/core/logx" ) @@ -28,15 +29,37 @@ func NewGetUsersByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetU func (l *GetUsersByIdLogic) GetUsersById(in *pb.GetUsersByIdReq) (*pb.GetUsersByIdResp, error) { // todo: add your logic here and delete this line //user, err := l.svcCtx.UsersModelRO.FindOne(l.ctx, in.Id) - user, err := l.svcCtx.UsersModelRO.Query().Where(users.IDEQ(in.Id)).All(l.ctx) - if err != nil { - return nil, err - } - pbUser := &pb.Users{} - err = converter.StructToStruct(&user, &pbUser) + user, err := l.svcCtx.UsersModelRO.Users.Query().Where(users.IDEQ(in.Id)).First(l.ctx) if err != nil { return nil, err } + verificationStatus, err := json.Marshal(user.VerificationStatus) + if err != nil { + logx.Errorf("json marshal verification status failed: %v", err) + return nil, errors.New("marshal verification status failed") + } + + logx.Debugf("Users data: %+v", user) + logx.Debugf("verified_role: %+v", user.VerifiedRoles) + pbUser := &pb.Users{ + Id: user.ID, + Username: user.Username, + PasswordHash: "", + Phone: "", + Email: "", + Nickname: user.Nickname, + Avatar: user.Avatar, + Bio: user.Bio, + CurrentRole: user.CurrentRole, + VerifiedRoles: user.VerifiedRoles.Elements, + VerificationStatus: string(verificationStatus), + IsAdmin: user.IsAdmin, + CreatedAt: user.CreatedAt.Unix(), + UpdatedAt: user.UpdatedAt.Unix(), + DeletedAt: user.DeletedAt.Unix(), + } + logx.Debugf("pb users data: %+v", pbUser) + return &pb.GetUsersByIdResp{Users: pbUser}, nil } diff --git a/app/users/rpc/internal/logic/loginLogic.go b/app/users/rpc/internal/logic/loginLogic.go index 5f21188..2a158b6 100644 --- a/app/users/rpc/internal/logic/loginLogic.go +++ b/app/users/rpc/internal/logic/loginLogic.go @@ -29,11 +29,13 @@ func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic } func (l *LoginLogic) Login(in *pb.LoginReq) (*pb.LoginResp, error) { - //user, err := l.svcCtx.UsersModelRO.FindOneByUsername(l.ctx, in.Username) - user, err := l.svcCtx.UsersModelRO.Query().Where(users.NicknameEQ(in.Username)).First(l.ctx) + user, err := l.svcCtx.UsersModelRO.Users.Query(). + Where(users.UsernameEQ(in.Username)). + Select(users.FieldID, users.FieldUsername, users.FieldPasswordHash, users.FieldEmail). + First(l.ctx) if err != nil { logx.WithContext(l.ctx).Errorf("LoginLogic.Login error:%v", err) - return nil, err + return nil, errors.New("user not found") } logx.Infof("user:%v", user) if !pwdUtils.VerifyPassword(user.PasswordHash, in.Passwd) { diff --git a/app/users/rpc/internal/logic/registerLogic.go b/app/users/rpc/internal/logic/registerLogic.go index 34b5416..024f69a 100644 --- a/app/users/rpc/internal/logic/registerLogic.go +++ b/app/users/rpc/internal/logic/registerLogic.go @@ -49,6 +49,7 @@ func (l *RegisterLogic) Register(in *pb.RegisterReq) (*pb.RegisterResp, error) { } redisKey := fmt.Sprintf(redisx.VCODE_KEY_PREFIX, in.RequestId, redisx.SCENE_REG, in.Email) + logx.Infof("redisKey: %s", redisKey) vcode, err := l.svcCtx.RedisCluster.Get(l.ctx, redisKey).Result() logx.Infof("vcode:%s, err:%v", vcode, err) if err != nil { @@ -66,12 +67,15 @@ func (l *RegisterLogic) Register(in *pb.RegisterReq) (*pb.RegisterResp, error) { return nil, errors.New("generate user ID failed") } - _, err = l.svcCtx.UsersModelRW.Create(). + _, err = l.svcCtx.UsersModelRW.Users.Create(). SetID(resp.Id). SetUsername(in.Username). SetPasswordHash(in.Passwd). SetPhone(in.Phone). SetEmail(in.Email). + SetBio(in.Email). + SetAvatar(""). + SetCurrentRole("consumer"). SetNickname(mustNewRandomNickname()). Save(l.ctx) if err != nil { diff --git a/app/users/rpc/internal/logic/resetPasswordLogic.go b/app/users/rpc/internal/logic/resetPasswordLogic.go index 591070e..e9d9180 100644 --- a/app/users/rpc/internal/logic/resetPasswordLogic.go +++ b/app/users/rpc/internal/logic/resetPasswordLogic.go @@ -38,7 +38,7 @@ func (l *ResetPasswordLogic) ResetPassword(in *pb.ResetPasswordReq) (*pb.ResetPa if vcode != in.Vcode { return nil, errors.New(fmt.Sprintf("user %v reset password failed, invalid vcode.", in.Email)) } - err = l.svcCtx.UsersModelRW.Update().Where(users.EmailEQ(in.Email)). + err = l.svcCtx.UsersModelRW.Users.Update().Where(users.EmailEQ(in.Email)). SetPasswordHash(in.NewPassword). Exec(l.ctx) if err != nil { diff --git a/app/users/rpc/internal/logic/searchUserFollowsLogic.go b/app/users/rpc/internal/logic/searchUserFollowsLogic.go new file mode 100644 index 0000000..b3159d4 --- /dev/null +++ b/app/users/rpc/internal/logic/searchUserFollowsLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SearchUserFollowsLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewSearchUserFollowsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SearchUserFollowsLogic { + return &SearchUserFollowsLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *SearchUserFollowsLogic) SearchUserFollows(in *pb.SearchUserFollowsReq) (*pb.SearchUserFollowsResp, error) { + // todo: add your logic here and delete this line + + return &pb.SearchUserFollowsResp{}, nil +} diff --git a/app/users/rpc/internal/logic/searchUserPreferencesLogic.go b/app/users/rpc/internal/logic/searchUserPreferencesLogic.go new file mode 100644 index 0000000..2f6e289 --- /dev/null +++ b/app/users/rpc/internal/logic/searchUserPreferencesLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SearchUserPreferencesLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewSearchUserPreferencesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SearchUserPreferencesLogic { + return &SearchUserPreferencesLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *SearchUserPreferencesLogic) SearchUserPreferences(in *pb.SearchUserPreferencesReq) (*pb.SearchUserPreferencesResp, error) { + // todo: add your logic here and delete this line + + return &pb.SearchUserPreferencesResp{}, nil +} diff --git a/app/users/rpc/internal/logic/searchUsersLogic.go b/app/users/rpc/internal/logic/searchUsersLogic.go index 2dd4a1c..0deed8c 100644 --- a/app/users/rpc/internal/logic/searchUsersLogic.go +++ b/app/users/rpc/internal/logic/searchUsersLogic.go @@ -38,7 +38,7 @@ func (l *SearchUsersLogic) SearchUsers(in *pb.SearchUsersReq) (out *pb.SearchUse logx.Errorf("Limit exceeds max limit: %d", in.Limit) return nil, errors.New("limit exceeds max limit") } - user, err := l.svcCtx.UsersModelRO.Query(). + user, err := l.svcCtx.UsersModelRO.Users.Query(). Where(users.Or( users.UsernameContainsFold(*in.Username), users.NicknameContainsFold(*in.Username), @@ -80,7 +80,8 @@ func ConvertEntUserToProto(entUser *models.Users) *pb.Users { } out.VerificationStatus = string(verificationStatus) - out.VerifiedRoles = entUser.VerifiedRoles + //out.VerifiedRoles = entUser.VerifiedRoles + out.VerifiedRoles = entUser.VerifiedRoles.Elements out.PasswordHash = "" // 手动清空敏感字段 return out diff --git a/app/users/rpc/internal/logic/switchRoleLogic.go b/app/users/rpc/internal/logic/switchRoleLogic.go new file mode 100644 index 0000000..a695247 --- /dev/null +++ b/app/users/rpc/internal/logic/switchRoleLogic.go @@ -0,0 +1,64 @@ +package logic + +import ( + "context" + "errors" + "slices" + + "juwan-backend/app/users/rpc/internal/models/users" + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SwitchRoleLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewSwitchRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SwitchRoleLogic { + return &SwitchRoleLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +var userRoles = []string{"consumer", "owner", "player", "admin"} + +func (l *SwitchRoleLogic) SwitchRole(in *pb.SwitchRoleReq) (*pb.SwitchRoleResp, error) { + user, err := l.svcCtx.UsersModelRO.Users.Query(). + Select(users.FieldVerifiedRoles). + Where(users.IDEQ(in.UserId)). + First(l.ctx) + if err != nil { + logx.Errorf("find user error by switch role, err: %v", err.Error()) + return &pb.SwitchRoleResp{ + Success: false, + }, errors.New("failed to find user") + } + + if !slices.Contains(userRoles, in.NewRole) { + logx.Infof("user role not found by userId: %v", in.UserId) + return nil, errors.New("user role not found by userId") + } + + if !slices.Contains(user.VerifiedRoles.Elements, in.NewRole) { + logx.Infof("user verified role not exists, user: %v", in.UserId) + return nil, errors.New("no permission to operate") + } + + user, err = l.svcCtx.UsersModelRW.Users.UpdateOneID(in.UserId). + SetCurrentRole(in.NewRole). + Save(l.ctx) + if err != nil { + logx.Errorf("failed to update user role, userId: %v, err: %v", in.UserId, err.Error()) + return nil, errors.New("failed to update user") + } + + return &pb.SwitchRoleResp{ + Success: true, + }, nil +} diff --git a/app/users/rpc/internal/logic/updateUserFollowsLogic.go b/app/users/rpc/internal/logic/updateUserFollowsLogic.go new file mode 100644 index 0000000..39b2b5a --- /dev/null +++ b/app/users/rpc/internal/logic/updateUserFollowsLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UpdateUserFollowsLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUpdateUserFollowsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateUserFollowsLogic { + return &UpdateUserFollowsLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *UpdateUserFollowsLogic) UpdateUserFollows(in *pb.UpdateUserFollowsReq) (*pb.UpdateUserFollowsResp, error) { + // todo: add your logic here and delete this line + + return &pb.UpdateUserFollowsResp{}, nil +} diff --git a/app/users/rpc/internal/logic/updateUserPreferencesLogic.go b/app/users/rpc/internal/logic/updateUserPreferencesLogic.go new file mode 100644 index 0000000..737e982 --- /dev/null +++ b/app/users/rpc/internal/logic/updateUserPreferencesLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "juwan-backend/app/users/rpc/internal/svc" + "juwan-backend/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UpdateUserPreferencesLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUpdateUserPreferencesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateUserPreferencesLogic { + return &UpdateUserPreferencesLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *UpdateUserPreferencesLogic) UpdateUserPreferences(in *pb.UpdateUserPreferencesReq) (*pb.UpdateUserPreferencesResp, error) { + // todo: add your logic here and delete this line + + return &pb.UpdateUserPreferencesResp{}, nil +} diff --git a/app/users/rpc/internal/logic/updateUsersLogic.go b/app/users/rpc/internal/logic/updateUsersLogic.go index 31a5883..60e58ae 100644 --- a/app/users/rpc/internal/logic/updateUsersLogic.go +++ b/app/users/rpc/internal/logic/updateUsersLogic.go @@ -4,6 +4,7 @@ import ( "context" "juwan-backend/app/users/rpc/internal/svc" "juwan-backend/app/users/rpc/pb" + "juwan-backend/pkg/types" "github.com/zeromicro/go-zero/core/logx" ) @@ -23,14 +24,20 @@ func NewUpdateUsersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Updat } func (l *UpdateUsersLogic) UpdateUsers(in *pb.UpdateUsersReq) (*pb.UpdateUsersResp, error) { - updater := l.svcCtx.UsersModelRW.UpdateOneID(in.Id). + updater := l.svcCtx.UsersModelRW.Users.UpdateOneID(in.Id). SetNillableNickname(in.Nickname). SetNillableAvatar(in.Avatar). SetNillableBio(in.Bio). SetNillableCurrentRole(in.CurrentRole). SetNillablePasswordHash(in.PasswordHash) if len(in.VerifiedRoles) > 0 { - updater.SetVerifiedRoles(in.VerifiedRoles) + var verifiedRoles types.TextArray + err := verifiedRoles.Scan(in.VerifiedRoles) + if err != nil { + logx.Errorf("failed to scan verified roles: %v", err) + return nil, err + } + updater.SetVerifiedRoles(verifiedRoles) } err := updater.Exec(l.ctx) if err != nil { diff --git a/app/users/rpc/internal/logic/validateTokenLogic.go b/app/users/rpc/internal/logic/validateTokenLogic.go index 3921fa0..d4b42fd 100644 --- a/app/users/rpc/internal/logic/validateTokenLogic.go +++ b/app/users/rpc/internal/logic/validateTokenLogic.go @@ -2,6 +2,8 @@ package logic import ( "context" + "encoding/json" + "errors" "juwan-backend/app/users/rpc/internal/models/users" "juwan-backend/app/users/rpc/internal/svc" @@ -33,15 +35,24 @@ func (l *ValidateTokenLogic) ValidateToken(in *pb.ValidateTokenReq) (*pb.Validat return nil, err } //users, err := l.svcCtx.UsersModelRO.FindOne(l.ctx, in.UserId) - user, err := l.svcCtx.UsersModelRO.Query().Where(users.IDEQ(in.UserId)).First(l.ctx) + user, err := l.svcCtx.UsersModelRO.Users.Query(). + Where(users.IDEQ(in.UserId)). + Select(users.FieldCurrentRole). + First(l.ctx) if err != nil { return nil, err } + userJson, err := json.Marshal(user.CurrentRole) + if err != nil { + logx.Errorf("json marshal err: %v", err) + return nil, errors.New("internal error") + } + return &pb.ValidateTokenResp{ Valid: true, Message: "OK", UserId: in.UserId, - RoleType: user.CurrentRole, + RoleType: string(userJson), }, nil } diff --git a/app/users/rpc/internal/models/client.go b/app/users/rpc/internal/models/client.go index 4321483..7e55918 100644 --- a/app/users/rpc/internal/models/client.go +++ b/app/users/rpc/internal/models/client.go @@ -11,6 +11,8 @@ import ( "juwan-backend/app/users/rpc/internal/models/migrate" + "juwan-backend/app/users/rpc/internal/models/userfollows" + "juwan-backend/app/users/rpc/internal/models/userpreferences" "juwan-backend/app/users/rpc/internal/models/users" "entgo.io/ent" @@ -23,6 +25,10 @@ type Client struct { config // Schema is the client for creating, migrating and dropping schema. Schema *migrate.Schema + // UserFollows is the client for interacting with the UserFollows builders. + UserFollows *UserFollowsClient + // UserPreferences is the client for interacting with the UserPreferences builders. + UserPreferences *UserPreferencesClient // Users is the client for interacting with the Users builders. Users *UsersClient } @@ -36,6 +42,8 @@ func NewClient(opts ...Option) *Client { func (c *Client) init() { c.Schema = migrate.NewSchema(c.driver) + c.UserFollows = NewUserFollowsClient(c.config) + c.UserPreferences = NewUserPreferencesClient(c.config) c.Users = NewUsersClient(c.config) } @@ -127,9 +135,11 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { cfg := c.config cfg.driver = tx return &Tx{ - ctx: ctx, - config: cfg, - Users: NewUsersClient(cfg), + ctx: ctx, + config: cfg, + UserFollows: NewUserFollowsClient(cfg), + UserPreferences: NewUserPreferencesClient(cfg), + Users: NewUsersClient(cfg), }, nil } @@ -147,16 +157,18 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) cfg := c.config cfg.driver = &txDriver{tx: tx, drv: c.driver} return &Tx{ - ctx: ctx, - config: cfg, - Users: NewUsersClient(cfg), + ctx: ctx, + config: cfg, + UserFollows: NewUserFollowsClient(cfg), + UserPreferences: NewUserPreferencesClient(cfg), + Users: NewUsersClient(cfg), }, nil } // Debug returns a new debug-client. It's used to get verbose logging on specific operations. // // client.Debug(). -// Users. +// UserFollows. // Query(). // Count(ctx) func (c *Client) Debug() *Client { @@ -178,18 +190,26 @@ func (c *Client) Close() error { // Use adds the mutation hooks to all the entity clients. // In order to add hooks to a specific client, call: `client.Node.Use(...)`. func (c *Client) Use(hooks ...Hook) { + c.UserFollows.Use(hooks...) + c.UserPreferences.Use(hooks...) c.Users.Use(hooks...) } // Intercept adds the query interceptors to all the entity clients. // In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`. func (c *Client) Intercept(interceptors ...Interceptor) { + c.UserFollows.Intercept(interceptors...) + c.UserPreferences.Intercept(interceptors...) c.Users.Intercept(interceptors...) } // Mutate implements the ent.Mutator interface. func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { switch m := m.(type) { + case *UserFollowsMutation: + return c.UserFollows.mutate(ctx, m) + case *UserPreferencesMutation: + return c.UserPreferences.mutate(ctx, m) case *UsersMutation: return c.Users.mutate(ctx, m) default: @@ -197,6 +217,272 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { } } +// UserFollowsClient is a client for the UserFollows schema. +type UserFollowsClient struct { + config +} + +// NewUserFollowsClient returns a client for the UserFollows from the given config. +func NewUserFollowsClient(c config) *UserFollowsClient { + return &UserFollowsClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `userfollows.Hooks(f(g(h())))`. +func (c *UserFollowsClient) Use(hooks ...Hook) { + c.hooks.UserFollows = append(c.hooks.UserFollows, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `userfollows.Intercept(f(g(h())))`. +func (c *UserFollowsClient) Intercept(interceptors ...Interceptor) { + c.inters.UserFollows = append(c.inters.UserFollows, interceptors...) +} + +// Create returns a builder for creating a UserFollows entity. +func (c *UserFollowsClient) Create() *UserFollowsCreate { + mutation := newUserFollowsMutation(c.config, OpCreate) + return &UserFollowsCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of UserFollows entities. +func (c *UserFollowsClient) CreateBulk(builders ...*UserFollowsCreate) *UserFollowsCreateBulk { + return &UserFollowsCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *UserFollowsClient) MapCreateBulk(slice any, setFunc func(*UserFollowsCreate, int)) *UserFollowsCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &UserFollowsCreateBulk{err: fmt.Errorf("calling to UserFollowsClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*UserFollowsCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &UserFollowsCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for UserFollows. +func (c *UserFollowsClient) Update() *UserFollowsUpdate { + mutation := newUserFollowsMutation(c.config, OpUpdate) + return &UserFollowsUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *UserFollowsClient) UpdateOne(_m *UserFollows) *UserFollowsUpdateOne { + mutation := newUserFollowsMutation(c.config, OpUpdateOne, withUserFollows(_m)) + return &UserFollowsUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *UserFollowsClient) UpdateOneID(id int64) *UserFollowsUpdateOne { + mutation := newUserFollowsMutation(c.config, OpUpdateOne, withUserFollowsID(id)) + return &UserFollowsUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for UserFollows. +func (c *UserFollowsClient) Delete() *UserFollowsDelete { + mutation := newUserFollowsMutation(c.config, OpDelete) + return &UserFollowsDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *UserFollowsClient) DeleteOne(_m *UserFollows) *UserFollowsDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *UserFollowsClient) DeleteOneID(id int64) *UserFollowsDeleteOne { + builder := c.Delete().Where(userfollows.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserFollowsDeleteOne{builder} +} + +// Query returns a query builder for UserFollows. +func (c *UserFollowsClient) Query() *UserFollowsQuery { + return &UserFollowsQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeUserFollows}, + inters: c.Interceptors(), + } +} + +// Get returns a UserFollows entity by its id. +func (c *UserFollowsClient) Get(ctx context.Context, id int64) (*UserFollows, error) { + return c.Query().Where(userfollows.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *UserFollowsClient) GetX(ctx context.Context, id int64) *UserFollows { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// Hooks returns the client hooks. +func (c *UserFollowsClient) Hooks() []Hook { + return c.hooks.UserFollows +} + +// Interceptors returns the client interceptors. +func (c *UserFollowsClient) Interceptors() []Interceptor { + return c.inters.UserFollows +} + +func (c *UserFollowsClient) mutate(ctx context.Context, m *UserFollowsMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&UserFollowsCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&UserFollowsUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&UserFollowsUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&UserFollowsDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("models: unknown UserFollows mutation op: %q", m.Op()) + } +} + +// UserPreferencesClient is a client for the UserPreferences schema. +type UserPreferencesClient struct { + config +} + +// NewUserPreferencesClient returns a client for the UserPreferences from the given config. +func NewUserPreferencesClient(c config) *UserPreferencesClient { + return &UserPreferencesClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `userpreferences.Hooks(f(g(h())))`. +func (c *UserPreferencesClient) Use(hooks ...Hook) { + c.hooks.UserPreferences = append(c.hooks.UserPreferences, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `userpreferences.Intercept(f(g(h())))`. +func (c *UserPreferencesClient) Intercept(interceptors ...Interceptor) { + c.inters.UserPreferences = append(c.inters.UserPreferences, interceptors...) +} + +// Create returns a builder for creating a UserPreferences entity. +func (c *UserPreferencesClient) Create() *UserPreferencesCreate { + mutation := newUserPreferencesMutation(c.config, OpCreate) + return &UserPreferencesCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of UserPreferences entities. +func (c *UserPreferencesClient) CreateBulk(builders ...*UserPreferencesCreate) *UserPreferencesCreateBulk { + return &UserPreferencesCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *UserPreferencesClient) MapCreateBulk(slice any, setFunc func(*UserPreferencesCreate, int)) *UserPreferencesCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &UserPreferencesCreateBulk{err: fmt.Errorf("calling to UserPreferencesClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*UserPreferencesCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &UserPreferencesCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for UserPreferences. +func (c *UserPreferencesClient) Update() *UserPreferencesUpdate { + mutation := newUserPreferencesMutation(c.config, OpUpdate) + return &UserPreferencesUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *UserPreferencesClient) UpdateOne(_m *UserPreferences) *UserPreferencesUpdateOne { + mutation := newUserPreferencesMutation(c.config, OpUpdateOne, withUserPreferences(_m)) + return &UserPreferencesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *UserPreferencesClient) UpdateOneID(id int) *UserPreferencesUpdateOne { + mutation := newUserPreferencesMutation(c.config, OpUpdateOne, withUserPreferencesID(id)) + return &UserPreferencesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for UserPreferences. +func (c *UserPreferencesClient) Delete() *UserPreferencesDelete { + mutation := newUserPreferencesMutation(c.config, OpDelete) + return &UserPreferencesDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *UserPreferencesClient) DeleteOne(_m *UserPreferences) *UserPreferencesDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *UserPreferencesClient) DeleteOneID(id int) *UserPreferencesDeleteOne { + builder := c.Delete().Where(userpreferences.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &UserPreferencesDeleteOne{builder} +} + +// Query returns a query builder for UserPreferences. +func (c *UserPreferencesClient) Query() *UserPreferencesQuery { + return &UserPreferencesQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeUserPreferences}, + inters: c.Interceptors(), + } +} + +// Get returns a UserPreferences entity by its id. +func (c *UserPreferencesClient) Get(ctx context.Context, id int) (*UserPreferences, error) { + return c.Query().Where(userpreferences.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *UserPreferencesClient) GetX(ctx context.Context, id int) *UserPreferences { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// Hooks returns the client hooks. +func (c *UserPreferencesClient) Hooks() []Hook { + return c.hooks.UserPreferences +} + +// Interceptors returns the client interceptors. +func (c *UserPreferencesClient) Interceptors() []Interceptor { + return c.inters.UserPreferences +} + +func (c *UserPreferencesClient) mutate(ctx context.Context, m *UserPreferencesMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&UserPreferencesCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&UserPreferencesUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&UserPreferencesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&UserPreferencesDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("models: unknown UserPreferences mutation op: %q", m.Op()) + } +} + // UsersClient is a client for the Users schema. type UsersClient struct { config @@ -333,9 +619,9 @@ func (c *UsersClient) mutate(ctx context.Context, m *UsersMutation) (Value, erro // hooks and interceptors per client, for fast access. type ( hooks struct { - Users []ent.Hook + UserFollows, UserPreferences, Users []ent.Hook } inters struct { - Users []ent.Interceptor + UserFollows, UserPreferences, Users []ent.Interceptor } ) diff --git a/app/users/rpc/internal/models/ent.go b/app/users/rpc/internal/models/ent.go index 19a95a8..d4d7e26 100644 --- a/app/users/rpc/internal/models/ent.go +++ b/app/users/rpc/internal/models/ent.go @@ -6,6 +6,8 @@ import ( "context" "errors" "fmt" + "juwan-backend/app/users/rpc/internal/models/userfollows" + "juwan-backend/app/users/rpc/internal/models/userpreferences" "juwan-backend/app/users/rpc/internal/models/users" "reflect" "sync" @@ -73,7 +75,9 @@ var ( func checkColumn(t, c string) error { initCheck.Do(func() { columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ - users.Table: users.ValidColumn, + userfollows.Table: userfollows.ValidColumn, + userpreferences.Table: userpreferences.ValidColumn, + users.Table: users.ValidColumn, }) }) return columnCheck(t, c) diff --git a/app/users/rpc/internal/models/hook/hook.go b/app/users/rpc/internal/models/hook/hook.go index 3a5d32f..58dd971 100644 --- a/app/users/rpc/internal/models/hook/hook.go +++ b/app/users/rpc/internal/models/hook/hook.go @@ -8,6 +8,30 @@ import ( "juwan-backend/app/users/rpc/internal/models" ) +// The UserFollowsFunc type is an adapter to allow the use of ordinary +// function as UserFollows mutator. +type UserFollowsFunc func(context.Context, *models.UserFollowsMutation) (models.Value, error) + +// Mutate calls f(ctx, m). +func (f UserFollowsFunc) Mutate(ctx context.Context, m models.Mutation) (models.Value, error) { + if mv, ok := m.(*models.UserFollowsMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *models.UserFollowsMutation", m) +} + +// The UserPreferencesFunc type is an adapter to allow the use of ordinary +// function as UserPreferences mutator. +type UserPreferencesFunc func(context.Context, *models.UserPreferencesMutation) (models.Value, error) + +// Mutate calls f(ctx, m). +func (f UserPreferencesFunc) Mutate(ctx context.Context, m models.Mutation) (models.Value, error) { + if mv, ok := m.(*models.UserPreferencesMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *models.UserPreferencesMutation", m) +} + // The UsersFunc type is an adapter to allow the use of ordinary // function as Users mutator. type UsersFunc func(context.Context, *models.UsersMutation) (models.Value, error) diff --git a/app/users/rpc/internal/models/migrate/schema.go b/app/users/rpc/internal/models/migrate/schema.go index 1916473..9e07934 100644 --- a/app/users/rpc/internal/models/migrate/schema.go +++ b/app/users/rpc/internal/models/migrate/schema.go @@ -8,6 +8,36 @@ import ( ) var ( + // UserFollowsColumns holds the columns for the "user_follows" table. + UserFollowsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "follower_id", Type: field.TypeInt64}, + {Name: "followee_id", Type: field.TypeInt64}, + {Name: "created_at", Type: field.TypeTime}, + } + // UserFollowsTable holds the schema information for the "user_follows" table. + UserFollowsTable = &schema.Table{ + Name: "user_follows", + Columns: UserFollowsColumns, + PrimaryKey: []*schema.Column{UserFollowsColumns[0]}, + } + // UserPreferencesColumns holds the columns for the "user_preferences" table. + UserPreferencesColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + {Name: "user_id", Type: field.TypeInt64}, + {Name: "notification_order", Type: field.TypeBool, Default: true}, + {Name: "notification_community", Type: field.TypeBool, Default: true}, + {Name: "notification_system", Type: field.TypeBool, Default: true}, + {Name: "theme", Type: field.TypeString, Default: "light"}, + {Name: "language", Type: field.TypeString, Default: "zh-CN"}, + {Name: "updated_at", Type: field.TypeTime}, + } + // UserPreferencesTable holds the schema information for the "user_preferences" table. + UserPreferencesTable = &schema.Table{ + Name: "user_preferences", + Columns: UserPreferencesColumns, + PrimaryKey: []*schema.Column{UserPreferencesColumns[0]}, + } // UsersColumns holds the columns for the "users" table. UsersColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -15,16 +45,16 @@ var ( {Name: "password_hash", Type: field.TypeString}, {Name: "email", Type: field.TypeString, Unique: true}, {Name: "phone", Type: field.TypeString, Unique: true}, - {Name: "nickname", Type: field.TypeString}, - {Name: "avatar", Type: field.TypeString}, - {Name: "bio", Type: field.TypeString}, - {Name: "current_role", Type: field.TypeString}, - {Name: "verified_roles", Type: field.TypeJSON}, - {Name: "verification_status", Type: field.TypeJSON}, + {Name: "nickname", Type: field.TypeString, Default: ""}, + {Name: "avatar", Type: field.TypeString, Default: ""}, + {Name: "bio", Type: field.TypeString, Default: ""}, + {Name: "current_role", Type: field.TypeString, Default: "consumer"}, + {Name: "verification_status", Type: field.TypeJSON, Nullable: true}, {Name: "is_admin", Type: field.TypeBool, Default: false}, {Name: "created_at", Type: field.TypeTime}, {Name: "updated_at", Type: field.TypeTime}, - {Name: "deleted_at", Type: field.TypeTime}, + {Name: "deleted_at", Type: field.TypeTime, Nullable: true}, + {Name: "verified_roles", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"postgres": "text[]"}}, } // UsersTable holds the schema information for the "users" table. UsersTable = &schema.Table{ @@ -34,6 +64,8 @@ var ( } // Tables holds all the tables in the schema. Tables = []*schema.Table{ + UserFollowsTable, + UserPreferencesTable, UsersTable, } ) diff --git a/app/users/rpc/internal/models/mutation.go b/app/users/rpc/internal/models/mutation.go index ff1a7fc..85126f8 100644 --- a/app/users/rpc/internal/models/mutation.go +++ b/app/users/rpc/internal/models/mutation.go @@ -8,7 +8,10 @@ import ( "fmt" "juwan-backend/app/users/rpc/internal/models/predicate" "juwan-backend/app/users/rpc/internal/models/schema" + "juwan-backend/app/users/rpc/internal/models/userfollows" + "juwan-backend/app/users/rpc/internal/models/userpreferences" "juwan-backend/app/users/rpc/internal/models/users" + "juwan-backend/pkg/types" "sync" "time" @@ -25,34 +28,1230 @@ const ( OpUpdateOne = ent.OpUpdateOne // Node types. - TypeUsers = "Users" + TypeUserFollows = "UserFollows" + TypeUserPreferences = "UserPreferences" + TypeUsers = "Users" ) +// UserFollowsMutation represents an operation that mutates the UserFollows nodes in the graph. +type UserFollowsMutation struct { + config + op Op + typ string + id *int64 + follower_id *int64 + addfollower_id *int64 + followee_id *int64 + addfollowee_id *int64 + created_at *time.Time + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*UserFollows, error) + predicates []predicate.UserFollows +} + +var _ ent.Mutation = (*UserFollowsMutation)(nil) + +// userfollowsOption allows management of the mutation configuration using functional options. +type userfollowsOption func(*UserFollowsMutation) + +// newUserFollowsMutation creates new mutation for the UserFollows entity. +func newUserFollowsMutation(c config, op Op, opts ...userfollowsOption) *UserFollowsMutation { + m := &UserFollowsMutation{ + config: c, + op: op, + typ: TypeUserFollows, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withUserFollowsID sets the ID field of the mutation. +func withUserFollowsID(id int64) userfollowsOption { + return func(m *UserFollowsMutation) { + var ( + err error + once sync.Once + value *UserFollows + ) + m.oldValue = func(ctx context.Context) (*UserFollows, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().UserFollows.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withUserFollows sets the old UserFollows of the mutation. +func withUserFollows(node *UserFollows) userfollowsOption { + return func(m *UserFollowsMutation) { + m.oldValue = func(context.Context) (*UserFollows, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserFollowsMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserFollowsMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("models: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of UserFollows entities. +func (m *UserFollowsMutation) SetID(id int64) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *UserFollowsMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *UserFollowsMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().UserFollows.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetFollowerID sets the "follower_id" field. +func (m *UserFollowsMutation) SetFollowerID(i int64) { + m.follower_id = &i + m.addfollower_id = nil +} + +// FollowerID returns the value of the "follower_id" field in the mutation. +func (m *UserFollowsMutation) FollowerID() (r int64, exists bool) { + v := m.follower_id + if v == nil { + return + } + return *v, true +} + +// OldFollowerID returns the old "follower_id" field's value of the UserFollows entity. +// If the UserFollows object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserFollowsMutation) OldFollowerID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFollowerID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFollowerID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFollowerID: %w", err) + } + return oldValue.FollowerID, nil +} + +// AddFollowerID adds i to the "follower_id" field. +func (m *UserFollowsMutation) AddFollowerID(i int64) { + if m.addfollower_id != nil { + *m.addfollower_id += i + } else { + m.addfollower_id = &i + } +} + +// AddedFollowerID returns the value that was added to the "follower_id" field in this mutation. +func (m *UserFollowsMutation) AddedFollowerID() (r int64, exists bool) { + v := m.addfollower_id + if v == nil { + return + } + return *v, true +} + +// ResetFollowerID resets all changes to the "follower_id" field. +func (m *UserFollowsMutation) ResetFollowerID() { + m.follower_id = nil + m.addfollower_id = nil +} + +// SetFolloweeID sets the "followee_id" field. +func (m *UserFollowsMutation) SetFolloweeID(i int64) { + m.followee_id = &i + m.addfollowee_id = nil +} + +// FolloweeID returns the value of the "followee_id" field in the mutation. +func (m *UserFollowsMutation) FolloweeID() (r int64, exists bool) { + v := m.followee_id + if v == nil { + return + } + return *v, true +} + +// OldFolloweeID returns the old "followee_id" field's value of the UserFollows entity. +// If the UserFollows object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserFollowsMutation) OldFolloweeID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFolloweeID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFolloweeID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFolloweeID: %w", err) + } + return oldValue.FolloweeID, nil +} + +// AddFolloweeID adds i to the "followee_id" field. +func (m *UserFollowsMutation) AddFolloweeID(i int64) { + if m.addfollowee_id != nil { + *m.addfollowee_id += i + } else { + m.addfollowee_id = &i + } +} + +// AddedFolloweeID returns the value that was added to the "followee_id" field in this mutation. +func (m *UserFollowsMutation) AddedFolloweeID() (r int64, exists bool) { + v := m.addfollowee_id + if v == nil { + return + } + return *v, true +} + +// ResetFolloweeID resets all changes to the "followee_id" field. +func (m *UserFollowsMutation) ResetFolloweeID() { + m.followee_id = nil + m.addfollowee_id = nil +} + +// SetCreatedAt sets the "created_at" field. +func (m *UserFollowsMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *UserFollowsMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the UserFollows entity. +// If the UserFollows object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserFollowsMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *UserFollowsMutation) ResetCreatedAt() { + m.created_at = nil +} + +// Where appends a list predicates to the UserFollowsMutation builder. +func (m *UserFollowsMutation) Where(ps ...predicate.UserFollows) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the UserFollowsMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *UserFollowsMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.UserFollows, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *UserFollowsMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *UserFollowsMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (UserFollows). +func (m *UserFollowsMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *UserFollowsMutation) Fields() []string { + fields := make([]string, 0, 3) + if m.follower_id != nil { + fields = append(fields, userfollows.FieldFollowerID) + } + if m.followee_id != nil { + fields = append(fields, userfollows.FieldFolloweeID) + } + if m.created_at != nil { + fields = append(fields, userfollows.FieldCreatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *UserFollowsMutation) Field(name string) (ent.Value, bool) { + switch name { + case userfollows.FieldFollowerID: + return m.FollowerID() + case userfollows.FieldFolloweeID: + return m.FolloweeID() + case userfollows.FieldCreatedAt: + return m.CreatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *UserFollowsMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case userfollows.FieldFollowerID: + return m.OldFollowerID(ctx) + case userfollows.FieldFolloweeID: + return m.OldFolloweeID(ctx) + case userfollows.FieldCreatedAt: + return m.OldCreatedAt(ctx) + } + return nil, fmt.Errorf("unknown UserFollows field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserFollowsMutation) SetField(name string, value ent.Value) error { + switch name { + case userfollows.FieldFollowerID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFollowerID(v) + return nil + case userfollows.FieldFolloweeID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFolloweeID(v) + return nil + case userfollows.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + } + return fmt.Errorf("unknown UserFollows field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *UserFollowsMutation) AddedFields() []string { + var fields []string + if m.addfollower_id != nil { + fields = append(fields, userfollows.FieldFollowerID) + } + if m.addfollowee_id != nil { + fields = append(fields, userfollows.FieldFolloweeID) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *UserFollowsMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case userfollows.FieldFollowerID: + return m.AddedFollowerID() + case userfollows.FieldFolloweeID: + return m.AddedFolloweeID() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserFollowsMutation) AddField(name string, value ent.Value) error { + switch name { + case userfollows.FieldFollowerID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddFollowerID(v) + return nil + case userfollows.FieldFolloweeID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddFolloweeID(v) + return nil + } + return fmt.Errorf("unknown UserFollows numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *UserFollowsMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *UserFollowsMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserFollowsMutation) ClearField(name string) error { + return fmt.Errorf("unknown UserFollows nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *UserFollowsMutation) ResetField(name string) error { + switch name { + case userfollows.FieldFollowerID: + m.ResetFollowerID() + return nil + case userfollows.FieldFolloweeID: + m.ResetFolloweeID() + return nil + case userfollows.FieldCreatedAt: + m.ResetCreatedAt() + return nil + } + return fmt.Errorf("unknown UserFollows field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *UserFollowsMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *UserFollowsMutation) AddedIDs(name string) []ent.Value { + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *UserFollowsMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *UserFollowsMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *UserFollowsMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *UserFollowsMutation) EdgeCleared(name string) bool { + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *UserFollowsMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown UserFollows unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *UserFollowsMutation) ResetEdge(name string) error { + return fmt.Errorf("unknown UserFollows edge %s", name) +} + +// UserPreferencesMutation represents an operation that mutates the UserPreferences nodes in the graph. +type UserPreferencesMutation struct { + config + op Op + typ string + id *int + user_id *int64 + adduser_id *int64 + notification_order *bool + notification_community *bool + notification_system *bool + theme *string + language *string + updated_at *time.Time + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*UserPreferences, error) + predicates []predicate.UserPreferences +} + +var _ ent.Mutation = (*UserPreferencesMutation)(nil) + +// userpreferencesOption allows management of the mutation configuration using functional options. +type userpreferencesOption func(*UserPreferencesMutation) + +// newUserPreferencesMutation creates new mutation for the UserPreferences entity. +func newUserPreferencesMutation(c config, op Op, opts ...userpreferencesOption) *UserPreferencesMutation { + m := &UserPreferencesMutation{ + config: c, + op: op, + typ: TypeUserPreferences, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withUserPreferencesID sets the ID field of the mutation. +func withUserPreferencesID(id int) userpreferencesOption { + return func(m *UserPreferencesMutation) { + var ( + err error + once sync.Once + value *UserPreferences + ) + m.oldValue = func(ctx context.Context) (*UserPreferences, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().UserPreferences.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withUserPreferences sets the old UserPreferences of the mutation. +func withUserPreferences(node *UserPreferences) userpreferencesOption { + return func(m *UserPreferencesMutation) { + m.oldValue = func(context.Context) (*UserPreferences, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m UserPreferencesMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m UserPreferencesMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("models: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *UserPreferencesMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *UserPreferencesMutation) IDs(ctx context.Context) ([]int, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().UserPreferences.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetUserID sets the "user_id" field. +func (m *UserPreferencesMutation) SetUserID(i int64) { + m.user_id = &i + m.adduser_id = nil +} + +// UserID returns the value of the "user_id" field in the mutation. +func (m *UserPreferencesMutation) UserID() (r int64, exists bool) { + v := m.user_id + if v == nil { + return + } + return *v, true +} + +// OldUserID returns the old "user_id" field's value of the UserPreferences entity. +// If the UserPreferences object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPreferencesMutation) OldUserID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserID: %w", err) + } + return oldValue.UserID, nil +} + +// AddUserID adds i to the "user_id" field. +func (m *UserPreferencesMutation) AddUserID(i int64) { + if m.adduser_id != nil { + *m.adduser_id += i + } else { + m.adduser_id = &i + } +} + +// AddedUserID returns the value that was added to the "user_id" field in this mutation. +func (m *UserPreferencesMutation) AddedUserID() (r int64, exists bool) { + v := m.adduser_id + if v == nil { + return + } + return *v, true +} + +// ResetUserID resets all changes to the "user_id" field. +func (m *UserPreferencesMutation) ResetUserID() { + m.user_id = nil + m.adduser_id = nil +} + +// SetNotificationOrder sets the "notification_order" field. +func (m *UserPreferencesMutation) SetNotificationOrder(b bool) { + m.notification_order = &b +} + +// NotificationOrder returns the value of the "notification_order" field in the mutation. +func (m *UserPreferencesMutation) NotificationOrder() (r bool, exists bool) { + v := m.notification_order + if v == nil { + return + } + return *v, true +} + +// OldNotificationOrder returns the old "notification_order" field's value of the UserPreferences entity. +// If the UserPreferences object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPreferencesMutation) OldNotificationOrder(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldNotificationOrder is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldNotificationOrder requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldNotificationOrder: %w", err) + } + return oldValue.NotificationOrder, nil +} + +// ResetNotificationOrder resets all changes to the "notification_order" field. +func (m *UserPreferencesMutation) ResetNotificationOrder() { + m.notification_order = nil +} + +// SetNotificationCommunity sets the "notification_community" field. +func (m *UserPreferencesMutation) SetNotificationCommunity(b bool) { + m.notification_community = &b +} + +// NotificationCommunity returns the value of the "notification_community" field in the mutation. +func (m *UserPreferencesMutation) NotificationCommunity() (r bool, exists bool) { + v := m.notification_community + if v == nil { + return + } + return *v, true +} + +// OldNotificationCommunity returns the old "notification_community" field's value of the UserPreferences entity. +// If the UserPreferences object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPreferencesMutation) OldNotificationCommunity(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldNotificationCommunity is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldNotificationCommunity requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldNotificationCommunity: %w", err) + } + return oldValue.NotificationCommunity, nil +} + +// ResetNotificationCommunity resets all changes to the "notification_community" field. +func (m *UserPreferencesMutation) ResetNotificationCommunity() { + m.notification_community = nil +} + +// SetNotificationSystem sets the "notification_system" field. +func (m *UserPreferencesMutation) SetNotificationSystem(b bool) { + m.notification_system = &b +} + +// NotificationSystem returns the value of the "notification_system" field in the mutation. +func (m *UserPreferencesMutation) NotificationSystem() (r bool, exists bool) { + v := m.notification_system + if v == nil { + return + } + return *v, true +} + +// OldNotificationSystem returns the old "notification_system" field's value of the UserPreferences entity. +// If the UserPreferences object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPreferencesMutation) OldNotificationSystem(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldNotificationSystem is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldNotificationSystem requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldNotificationSystem: %w", err) + } + return oldValue.NotificationSystem, nil +} + +// ResetNotificationSystem resets all changes to the "notification_system" field. +func (m *UserPreferencesMutation) ResetNotificationSystem() { + m.notification_system = nil +} + +// SetTheme sets the "theme" field. +func (m *UserPreferencesMutation) SetTheme(s string) { + m.theme = &s +} + +// Theme returns the value of the "theme" field in the mutation. +func (m *UserPreferencesMutation) Theme() (r string, exists bool) { + v := m.theme + if v == nil { + return + } + return *v, true +} + +// OldTheme returns the old "theme" field's value of the UserPreferences entity. +// If the UserPreferences object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPreferencesMutation) OldTheme(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTheme is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTheme requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTheme: %w", err) + } + return oldValue.Theme, nil +} + +// ResetTheme resets all changes to the "theme" field. +func (m *UserPreferencesMutation) ResetTheme() { + m.theme = nil +} + +// SetLanguage sets the "language" field. +func (m *UserPreferencesMutation) SetLanguage(s string) { + m.language = &s +} + +// Language returns the value of the "language" field in the mutation. +func (m *UserPreferencesMutation) Language() (r string, exists bool) { + v := m.language + if v == nil { + return + } + return *v, true +} + +// OldLanguage returns the old "language" field's value of the UserPreferences entity. +// If the UserPreferences object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPreferencesMutation) OldLanguage(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLanguage is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLanguage requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLanguage: %w", err) + } + return oldValue.Language, nil +} + +// ResetLanguage resets all changes to the "language" field. +func (m *UserPreferencesMutation) ResetLanguage() { + m.language = nil +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *UserPreferencesMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *UserPreferencesMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the UserPreferences entity. +// If the UserPreferences object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserPreferencesMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *UserPreferencesMutation) ResetUpdatedAt() { + m.updated_at = nil +} + +// Where appends a list predicates to the UserPreferencesMutation builder. +func (m *UserPreferencesMutation) Where(ps ...predicate.UserPreferences) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the UserPreferencesMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *UserPreferencesMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.UserPreferences, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *UserPreferencesMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *UserPreferencesMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (UserPreferences). +func (m *UserPreferencesMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *UserPreferencesMutation) Fields() []string { + fields := make([]string, 0, 7) + if m.user_id != nil { + fields = append(fields, userpreferences.FieldUserID) + } + if m.notification_order != nil { + fields = append(fields, userpreferences.FieldNotificationOrder) + } + if m.notification_community != nil { + fields = append(fields, userpreferences.FieldNotificationCommunity) + } + if m.notification_system != nil { + fields = append(fields, userpreferences.FieldNotificationSystem) + } + if m.theme != nil { + fields = append(fields, userpreferences.FieldTheme) + } + if m.language != nil { + fields = append(fields, userpreferences.FieldLanguage) + } + if m.updated_at != nil { + fields = append(fields, userpreferences.FieldUpdatedAt) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *UserPreferencesMutation) Field(name string) (ent.Value, bool) { + switch name { + case userpreferences.FieldUserID: + return m.UserID() + case userpreferences.FieldNotificationOrder: + return m.NotificationOrder() + case userpreferences.FieldNotificationCommunity: + return m.NotificationCommunity() + case userpreferences.FieldNotificationSystem: + return m.NotificationSystem() + case userpreferences.FieldTheme: + return m.Theme() + case userpreferences.FieldLanguage: + return m.Language() + case userpreferences.FieldUpdatedAt: + return m.UpdatedAt() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *UserPreferencesMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case userpreferences.FieldUserID: + return m.OldUserID(ctx) + case userpreferences.FieldNotificationOrder: + return m.OldNotificationOrder(ctx) + case userpreferences.FieldNotificationCommunity: + return m.OldNotificationCommunity(ctx) + case userpreferences.FieldNotificationSystem: + return m.OldNotificationSystem(ctx) + case userpreferences.FieldTheme: + return m.OldTheme(ctx) + case userpreferences.FieldLanguage: + return m.OldLanguage(ctx) + case userpreferences.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + } + return nil, fmt.Errorf("unknown UserPreferences field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserPreferencesMutation) SetField(name string, value ent.Value) error { + switch name { + case userpreferences.FieldUserID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserID(v) + return nil + case userpreferences.FieldNotificationOrder: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNotificationOrder(v) + return nil + case userpreferences.FieldNotificationCommunity: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNotificationCommunity(v) + return nil + case userpreferences.FieldNotificationSystem: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNotificationSystem(v) + return nil + case userpreferences.FieldTheme: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTheme(v) + return nil + case userpreferences.FieldLanguage: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLanguage(v) + return nil + case userpreferences.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + } + return fmt.Errorf("unknown UserPreferences field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *UserPreferencesMutation) AddedFields() []string { + var fields []string + if m.adduser_id != nil { + fields = append(fields, userpreferences.FieldUserID) + } + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *UserPreferencesMutation) AddedField(name string) (ent.Value, bool) { + switch name { + case userpreferences.FieldUserID: + return m.AddedUserID() + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *UserPreferencesMutation) AddField(name string, value ent.Value) error { + switch name { + case userpreferences.FieldUserID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.AddUserID(v) + return nil + } + return fmt.Errorf("unknown UserPreferences numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *UserPreferencesMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *UserPreferencesMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *UserPreferencesMutation) ClearField(name string) error { + return fmt.Errorf("unknown UserPreferences nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *UserPreferencesMutation) ResetField(name string) error { + switch name { + case userpreferences.FieldUserID: + m.ResetUserID() + return nil + case userpreferences.FieldNotificationOrder: + m.ResetNotificationOrder() + return nil + case userpreferences.FieldNotificationCommunity: + m.ResetNotificationCommunity() + return nil + case userpreferences.FieldNotificationSystem: + m.ResetNotificationSystem() + return nil + case userpreferences.FieldTheme: + m.ResetTheme() + return nil + case userpreferences.FieldLanguage: + m.ResetLanguage() + return nil + case userpreferences.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + } + return fmt.Errorf("unknown UserPreferences field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *UserPreferencesMutation) AddedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *UserPreferencesMutation) AddedIDs(name string) []ent.Value { + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *UserPreferencesMutation) RemovedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *UserPreferencesMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *UserPreferencesMutation) ClearedEdges() []string { + edges := make([]string, 0, 0) + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *UserPreferencesMutation) EdgeCleared(name string) bool { + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *UserPreferencesMutation) ClearEdge(name string) error { + return fmt.Errorf("unknown UserPreferences unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *UserPreferencesMutation) ResetEdge(name string) error { + return fmt.Errorf("unknown UserPreferences edge %s", name) +} + // UsersMutation represents an operation that mutates the Users nodes in the graph. type UsersMutation struct { config - op Op - typ string - id *int64 - username *string - password_hash *string - email *string - phone *string - nickname *string - avatar *string - bio *string - current_role *string - verified_roles *[]string - appendverified_roles []string - verificationStatus *schema.VerificationStatusStruct - is_admin *bool - created_at *time.Time - updated_at *time.Time - deleted_at *time.Time - clearedFields map[string]struct{} - done bool - oldValue func(context.Context) (*Users, error) - predicates []predicate.Users + op Op + typ string + id *int64 + username *string + password_hash *string + email *string + phone *string + nickname *string + avatar *string + bio *string + current_role *string + verificationStatus *schema.VerificationStatusStruct + is_admin *bool + created_at *time.Time + updated_at *time.Time + deleted_at *time.Time + verified_roles *types.TextArray + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*Users, error) + predicates []predicate.Users } var _ ent.Mutation = (*UsersMutation)(nil) @@ -447,57 +1646,6 @@ func (m *UsersMutation) ResetCurrentRole() { m.current_role = nil } -// SetVerifiedRoles sets the "verified_roles" field. -func (m *UsersMutation) SetVerifiedRoles(s []string) { - m.verified_roles = &s - m.appendverified_roles = nil -} - -// VerifiedRoles returns the value of the "verified_roles" field in the mutation. -func (m *UsersMutation) VerifiedRoles() (r []string, exists bool) { - v := m.verified_roles - if v == nil { - return - } - return *v, true -} - -// OldVerifiedRoles returns the old "verified_roles" field's value of the Users entity. -// If the Users object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *UsersMutation) OldVerifiedRoles(ctx context.Context) (v []string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldVerifiedRoles is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldVerifiedRoles requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldVerifiedRoles: %w", err) - } - return oldValue.VerifiedRoles, nil -} - -// AppendVerifiedRoles adds s to the "verified_roles" field. -func (m *UsersMutation) AppendVerifiedRoles(s []string) { - m.appendverified_roles = append(m.appendverified_roles, s...) -} - -// AppendedVerifiedRoles returns the list of values that were appended to the "verified_roles" field in this mutation. -func (m *UsersMutation) AppendedVerifiedRoles() ([]string, bool) { - if len(m.appendverified_roles) == 0 { - return nil, false - } - return m.appendverified_roles, true -} - -// ResetVerifiedRoles resets all changes to the "verified_roles" field. -func (m *UsersMutation) ResetVerifiedRoles() { - m.verified_roles = nil - m.appendverified_roles = nil -} - // SetVerificationStatus sets the "verificationStatus" field. func (m *UsersMutation) SetVerificationStatus(sss schema.VerificationStatusStruct) { m.verificationStatus = &sss @@ -529,9 +1677,22 @@ func (m *UsersMutation) OldVerificationStatus(ctx context.Context) (v schema.Ver return oldValue.VerificationStatus, nil } +// ClearVerificationStatus clears the value of the "verificationStatus" field. +func (m *UsersMutation) ClearVerificationStatus() { + m.verificationStatus = nil + m.clearedFields[users.FieldVerificationStatus] = struct{}{} +} + +// VerificationStatusCleared returns if the "verificationStatus" field was cleared in this mutation. +func (m *UsersMutation) VerificationStatusCleared() bool { + _, ok := m.clearedFields[users.FieldVerificationStatus] + return ok +} + // ResetVerificationStatus resets all changes to the "verificationStatus" field. func (m *UsersMutation) ResetVerificationStatus() { m.verificationStatus = nil + delete(m.clearedFields, users.FieldVerificationStatus) } // SetIsAdmin sets the "is_admin" field. @@ -673,9 +1834,71 @@ func (m *UsersMutation) OldDeletedAt(ctx context.Context) (v time.Time, err erro return oldValue.DeletedAt, nil } +// ClearDeletedAt clears the value of the "deleted_at" field. +func (m *UsersMutation) ClearDeletedAt() { + m.deleted_at = nil + m.clearedFields[users.FieldDeletedAt] = struct{}{} +} + +// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation. +func (m *UsersMutation) DeletedAtCleared() bool { + _, ok := m.clearedFields[users.FieldDeletedAt] + return ok +} + // ResetDeletedAt resets all changes to the "deleted_at" field. func (m *UsersMutation) ResetDeletedAt() { m.deleted_at = nil + delete(m.clearedFields, users.FieldDeletedAt) +} + +// SetVerifiedRoles sets the "verified_roles" field. +func (m *UsersMutation) SetVerifiedRoles(ta types.TextArray) { + m.verified_roles = &ta +} + +// VerifiedRoles returns the value of the "verified_roles" field in the mutation. +func (m *UsersMutation) VerifiedRoles() (r types.TextArray, exists bool) { + v := m.verified_roles + if v == nil { + return + } + return *v, true +} + +// OldVerifiedRoles returns the old "verified_roles" field's value of the Users entity. +// If the Users object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UsersMutation) OldVerifiedRoles(ctx context.Context) (v types.TextArray, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldVerifiedRoles is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldVerifiedRoles requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldVerifiedRoles: %w", err) + } + return oldValue.VerifiedRoles, nil +} + +// ClearVerifiedRoles clears the value of the "verified_roles" field. +func (m *UsersMutation) ClearVerifiedRoles() { + m.verified_roles = nil + m.clearedFields[users.FieldVerifiedRoles] = struct{}{} +} + +// VerifiedRolesCleared returns if the "verified_roles" field was cleared in this mutation. +func (m *UsersMutation) VerifiedRolesCleared() bool { + _, ok := m.clearedFields[users.FieldVerifiedRoles] + return ok +} + +// ResetVerifiedRoles resets all changes to the "verified_roles" field. +func (m *UsersMutation) ResetVerifiedRoles() { + m.verified_roles = nil + delete(m.clearedFields, users.FieldVerifiedRoles) } // Where appends a list predicates to the UsersMutation builder. @@ -737,9 +1960,6 @@ func (m *UsersMutation) Fields() []string { if m.current_role != nil { fields = append(fields, users.FieldCurrentRole) } - if m.verified_roles != nil { - fields = append(fields, users.FieldVerifiedRoles) - } if m.verificationStatus != nil { fields = append(fields, users.FieldVerificationStatus) } @@ -755,6 +1975,9 @@ func (m *UsersMutation) Fields() []string { if m.deleted_at != nil { fields = append(fields, users.FieldDeletedAt) } + if m.verified_roles != nil { + fields = append(fields, users.FieldVerifiedRoles) + } return fields } @@ -779,8 +2002,6 @@ func (m *UsersMutation) Field(name string) (ent.Value, bool) { return m.Bio() case users.FieldCurrentRole: return m.CurrentRole() - case users.FieldVerifiedRoles: - return m.VerifiedRoles() case users.FieldVerificationStatus: return m.VerificationStatus() case users.FieldIsAdmin: @@ -791,6 +2012,8 @@ func (m *UsersMutation) Field(name string) (ent.Value, bool) { return m.UpdatedAt() case users.FieldDeletedAt: return m.DeletedAt() + case users.FieldVerifiedRoles: + return m.VerifiedRoles() } return nil, false } @@ -816,8 +2039,6 @@ func (m *UsersMutation) OldField(ctx context.Context, name string) (ent.Value, e return m.OldBio(ctx) case users.FieldCurrentRole: return m.OldCurrentRole(ctx) - case users.FieldVerifiedRoles: - return m.OldVerifiedRoles(ctx) case users.FieldVerificationStatus: return m.OldVerificationStatus(ctx) case users.FieldIsAdmin: @@ -828,6 +2049,8 @@ func (m *UsersMutation) OldField(ctx context.Context, name string) (ent.Value, e return m.OldUpdatedAt(ctx) case users.FieldDeletedAt: return m.OldDeletedAt(ctx) + case users.FieldVerifiedRoles: + return m.OldVerifiedRoles(ctx) } return nil, fmt.Errorf("unknown Users field %s", name) } @@ -893,13 +2116,6 @@ func (m *UsersMutation) SetField(name string, value ent.Value) error { } m.SetCurrentRole(v) return nil - case users.FieldVerifiedRoles: - v, ok := value.([]string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetVerifiedRoles(v) - return nil case users.FieldVerificationStatus: v, ok := value.(schema.VerificationStatusStruct) if !ok { @@ -935,6 +2151,13 @@ func (m *UsersMutation) SetField(name string, value ent.Value) error { } m.SetDeletedAt(v) return nil + case users.FieldVerifiedRoles: + v, ok := value.(types.TextArray) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetVerifiedRoles(v) + return nil } return fmt.Errorf("unknown Users field %s", name) } @@ -964,7 +2187,17 @@ func (m *UsersMutation) AddField(name string, value ent.Value) error { // ClearedFields returns all nullable fields that were cleared during this // mutation. func (m *UsersMutation) ClearedFields() []string { - return nil + var fields []string + if m.FieldCleared(users.FieldVerificationStatus) { + fields = append(fields, users.FieldVerificationStatus) + } + if m.FieldCleared(users.FieldDeletedAt) { + fields = append(fields, users.FieldDeletedAt) + } + if m.FieldCleared(users.FieldVerifiedRoles) { + fields = append(fields, users.FieldVerifiedRoles) + } + return fields } // FieldCleared returns a boolean indicating if a field with the given name was @@ -977,6 +2210,17 @@ func (m *UsersMutation) FieldCleared(name string) bool { // ClearField clears the value of the field with the given name. It returns an // error if the field is not defined in the schema. func (m *UsersMutation) ClearField(name string) error { + switch name { + case users.FieldVerificationStatus: + m.ClearVerificationStatus() + return nil + case users.FieldDeletedAt: + m.ClearDeletedAt() + return nil + case users.FieldVerifiedRoles: + m.ClearVerifiedRoles() + return nil + } return fmt.Errorf("unknown Users nullable field %s", name) } @@ -1008,9 +2252,6 @@ func (m *UsersMutation) ResetField(name string) error { case users.FieldCurrentRole: m.ResetCurrentRole() return nil - case users.FieldVerifiedRoles: - m.ResetVerifiedRoles() - return nil case users.FieldVerificationStatus: m.ResetVerificationStatus() return nil @@ -1026,6 +2267,9 @@ func (m *UsersMutation) ResetField(name string) error { case users.FieldDeletedAt: m.ResetDeletedAt() return nil + case users.FieldVerifiedRoles: + m.ResetVerifiedRoles() + return nil } return fmt.Errorf("unknown Users field %s", name) } diff --git a/app/users/rpc/internal/models/predicate/predicate.go b/app/users/rpc/internal/models/predicate/predicate.go index 7da0420..204618f 100644 --- a/app/users/rpc/internal/models/predicate/predicate.go +++ b/app/users/rpc/internal/models/predicate/predicate.go @@ -6,5 +6,11 @@ import ( "entgo.io/ent/dialect/sql" ) +// UserFollows is the predicate function for userfollows builders. +type UserFollows func(*sql.Selector) + +// UserPreferences is the predicate function for userpreferences builders. +type UserPreferences func(*sql.Selector) + // Users is the predicate function for users builders. type Users func(*sql.Selector) diff --git a/app/users/rpc/internal/models/runtime.go b/app/users/rpc/internal/models/runtime.go index 83eda3c..135f2e2 100644 --- a/app/users/rpc/internal/models/runtime.go +++ b/app/users/rpc/internal/models/runtime.go @@ -4,6 +4,7 @@ package models import ( "juwan-backend/app/users/rpc/internal/models/schema" + "juwan-backend/app/users/rpc/internal/models/userpreferences" "juwan-backend/app/users/rpc/internal/models/users" "time" ) @@ -12,18 +13,62 @@ import ( // (default values, validators, hooks and policies) and stitches it // to their package variables. func init() { + userpreferencesFields := schema.UserPreferences{}.Fields() + _ = userpreferencesFields + // userpreferencesDescNotificationOrder is the schema descriptor for notification_order field. + userpreferencesDescNotificationOrder := userpreferencesFields[1].Descriptor() + // userpreferences.DefaultNotificationOrder holds the default value on creation for the notification_order field. + userpreferences.DefaultNotificationOrder = userpreferencesDescNotificationOrder.Default.(bool) + // userpreferencesDescNotificationCommunity is the schema descriptor for notification_community field. + userpreferencesDescNotificationCommunity := userpreferencesFields[2].Descriptor() + // userpreferences.DefaultNotificationCommunity holds the default value on creation for the notification_community field. + userpreferences.DefaultNotificationCommunity = userpreferencesDescNotificationCommunity.Default.(bool) + // userpreferencesDescNotificationSystem is the schema descriptor for notification_system field. + userpreferencesDescNotificationSystem := userpreferencesFields[3].Descriptor() + // userpreferences.DefaultNotificationSystem holds the default value on creation for the notification_system field. + userpreferences.DefaultNotificationSystem = userpreferencesDescNotificationSystem.Default.(bool) + // userpreferencesDescTheme is the schema descriptor for theme field. + userpreferencesDescTheme := userpreferencesFields[4].Descriptor() + // userpreferences.DefaultTheme holds the default value on creation for the theme field. + userpreferences.DefaultTheme = userpreferencesDescTheme.Default.(string) + // userpreferencesDescLanguage is the schema descriptor for language field. + userpreferencesDescLanguage := userpreferencesFields[5].Descriptor() + // userpreferences.DefaultLanguage holds the default value on creation for the language field. + userpreferences.DefaultLanguage = userpreferencesDescLanguage.Default.(string) + // userpreferencesDescUpdatedAt is the schema descriptor for updated_at field. + userpreferencesDescUpdatedAt := userpreferencesFields[6].Descriptor() + // userpreferences.DefaultUpdatedAt holds the default value on creation for the updated_at field. + userpreferences.DefaultUpdatedAt = userpreferencesDescUpdatedAt.Default.(func() time.Time) usersFields := schema.Users{}.Fields() _ = usersFields + // usersDescNickname is the schema descriptor for nickname field. + usersDescNickname := usersFields[5].Descriptor() + // users.DefaultNickname holds the default value on creation for the nickname field. + users.DefaultNickname = usersDescNickname.Default.(string) + // usersDescAvatar is the schema descriptor for avatar field. + usersDescAvatar := usersFields[6].Descriptor() + // users.DefaultAvatar holds the default value on creation for the avatar field. + users.DefaultAvatar = usersDescAvatar.Default.(string) + // usersDescBio is the schema descriptor for bio field. + usersDescBio := usersFields[7].Descriptor() + // users.DefaultBio holds the default value on creation for the bio field. + users.DefaultBio = usersDescBio.Default.(string) + // usersDescCurrentRole is the schema descriptor for current_role field. + usersDescCurrentRole := usersFields[8].Descriptor() + // users.DefaultCurrentRole holds the default value on creation for the current_role field. + users.DefaultCurrentRole = usersDescCurrentRole.Default.(string) + // users.CurrentRoleValidator is a validator for the "current_role" field. It is called by the builders before save. + users.CurrentRoleValidator = usersDescCurrentRole.Validators[0].(func(string) error) // usersDescIsAdmin is the schema descriptor for is_admin field. - usersDescIsAdmin := usersFields[11].Descriptor() + usersDescIsAdmin := usersFields[10].Descriptor() // users.DefaultIsAdmin holds the default value on creation for the is_admin field. users.DefaultIsAdmin = usersDescIsAdmin.Default.(bool) // usersDescCreatedAt is the schema descriptor for created_at field. - usersDescCreatedAt := usersFields[12].Descriptor() + usersDescCreatedAt := usersFields[11].Descriptor() // users.DefaultCreatedAt holds the default value on creation for the created_at field. users.DefaultCreatedAt = usersDescCreatedAt.Default.(func() time.Time) // usersDescUpdatedAt is the schema descriptor for updated_at field. - usersDescUpdatedAt := usersFields[13].Descriptor() + usersDescUpdatedAt := usersFields[12].Descriptor() // users.DefaultUpdatedAt holds the default value on creation for the updated_at field. users.DefaultUpdatedAt = usersDescUpdatedAt.Default.(func() time.Time) } diff --git a/app/users/rpc/internal/models/schema/userfollows.go b/app/users/rpc/internal/models/schema/userfollows.go new file mode 100644 index 0000000..615c89c --- /dev/null +++ b/app/users/rpc/internal/models/schema/userfollows.go @@ -0,0 +1,26 @@ +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/schema/field" +) + +// UserFollows holds the schema definition for the UserFollows entity. +type UserFollows struct { + ent.Schema +} + +// Fields of the UserFollows. +func (UserFollows) Fields() []ent.Field { + return []ent.Field{ + field.Int64("id").Immutable().Unique(), + field.Int64("follower_id"), + field.Int64("followee_id"), + field.Time("created_at").Immutable(), + } +} + +// Edges of the UserFollows. +func (UserFollows) Edges() []ent.Edge { + return nil +} diff --git a/app/users/rpc/internal/models/schema/userpreferences.go b/app/users/rpc/internal/models/schema/userpreferences.go new file mode 100644 index 0000000..9301df1 --- /dev/null +++ b/app/users/rpc/internal/models/schema/userpreferences.go @@ -0,0 +1,31 @@ +package schema + +import ( + "time" + + "entgo.io/ent" + "entgo.io/ent/schema/field" +) + +// UserPreferences holds the schema definition for the UserPreferences entity. +type UserPreferences struct { + ent.Schema +} + +// Fields of the UserPreferences. +func (UserPreferences) Fields() []ent.Field { + return []ent.Field{ + field.Int64("user_id"), + field.Bool("notification_order").Default(true), + field.Bool("notification_community").Default(true), + field.Bool("notification_system").Default(true), + field.String("theme").Default("light"), + field.String("language").Default("zh-CN"), + field.Time("updated_at").Default(time.Now), + } +} + +// Edges of the UserPreferences. +func (UserPreferences) Edges() []ent.Edge { + return nil +} diff --git a/app/users/rpc/internal/models/schema/users.go b/app/users/rpc/internal/models/schema/users.go index 7a5e3b0..cee5c7c 100644 --- a/app/users/rpc/internal/models/schema/users.go +++ b/app/users/rpc/internal/models/schema/users.go @@ -1,9 +1,11 @@ package schema import ( + "juwan-backend/pkg/types" "time" "entgo.io/ent" + "entgo.io/ent/dialect" "entgo.io/ent/schema/field" ) @@ -26,16 +28,18 @@ func (Users) Fields() []ent.Field { field.String("password_hash"), field.String("email").Unique(), field.String("phone").Unique(), - field.String("nickname"), - field.String("avatar"), - field.String("bio"), - field.String("current_role"), - field.Strings("verified_roles"), - field.JSON("verificationStatus", VerificationStatusStruct{}), + field.String("nickname").Default(""), + field.String("avatar").Default(""), + field.String("bio").Default(""), + field.String("current_role").Default("consumer").NotEmpty(), + //field.Strings("verified_roles").Default([]string{"consumer"}), + field.JSON("verificationStatus", VerificationStatusStruct{}).Optional(), field.Bool("is_admin").Default(false), field.Time("created_at").Default(time.Now), field.Time("updated_at").Default(time.Now), - field.Time("deleted_at"), + field.Time("deleted_at").Optional(), + field.Other("verified_roles", types.TextArray{}). + SchemaType(map[string]string{dialect.Postgres: "text[]"}).Optional(), } } diff --git a/app/users/rpc/internal/models/tx.go b/app/users/rpc/internal/models/tx.go index b10f159..c05cac7 100644 --- a/app/users/rpc/internal/models/tx.go +++ b/app/users/rpc/internal/models/tx.go @@ -12,6 +12,10 @@ import ( // Tx is a transactional client that is created by calling Client.Tx(). type Tx struct { config + // UserFollows is the client for interacting with the UserFollows builders. + UserFollows *UserFollowsClient + // UserPreferences is the client for interacting with the UserPreferences builders. + UserPreferences *UserPreferencesClient // Users is the client for interacting with the Users builders. Users *UsersClient @@ -145,6 +149,8 @@ func (tx *Tx) Client() *Client { } func (tx *Tx) init() { + tx.UserFollows = NewUserFollowsClient(tx.config) + tx.UserPreferences = NewUserPreferencesClient(tx.config) tx.Users = NewUsersClient(tx.config) } @@ -155,7 +161,7 @@ func (tx *Tx) init() { // of them in order to commit or rollback the transaction. // // If a closed transaction is embedded in one of the generated entities, and the entity -// applies a query, for example: Users.QueryXXX(), the query will be executed +// applies a query, for example: UserFollows.QueryXXX(), the query will be executed // through the driver which created this transaction. // // Note that txDriver is not goroutine safe. diff --git a/app/users/rpc/internal/models/userfollows.go b/app/users/rpc/internal/models/userfollows.go new file mode 100644 index 0000000..86e4124 --- /dev/null +++ b/app/users/rpc/internal/models/userfollows.go @@ -0,0 +1,126 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "fmt" + "juwan-backend/app/users/rpc/internal/models/userfollows" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" +) + +// UserFollows is the model entity for the UserFollows schema. +type UserFollows struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // FollowerID holds the value of the "follower_id" field. + FollowerID int64 `json:"follower_id,omitempty"` + // FolloweeID holds the value of the "followee_id" field. + FolloweeID int64 `json:"followee_id,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + selectValues sql.SelectValues +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*UserFollows) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case userfollows.FieldID, userfollows.FieldFollowerID, userfollows.FieldFolloweeID: + values[i] = new(sql.NullInt64) + case userfollows.FieldCreatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the UserFollows fields. +func (_m *UserFollows) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case userfollows.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case userfollows.FieldFollowerID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field follower_id", values[i]) + } else if value.Valid { + _m.FollowerID = value.Int64 + } + case userfollows.FieldFolloweeID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field followee_id", values[i]) + } else if value.Valid { + _m.FolloweeID = value.Int64 + } + case userfollows.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the UserFollows. +// This includes values selected through modifiers, order, etc. +func (_m *UserFollows) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// Update returns a builder for updating this UserFollows. +// Note that you need to call UserFollows.Unwrap() before calling this method if this UserFollows +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *UserFollows) Update() *UserFollowsUpdateOne { + return NewUserFollowsClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the UserFollows entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *UserFollows) Unwrap() *UserFollows { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("models: UserFollows is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *UserFollows) String() string { + var builder strings.Builder + builder.WriteString("UserFollows(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("follower_id=") + builder.WriteString(fmt.Sprintf("%v", _m.FollowerID)) + builder.WriteString(", ") + builder.WriteString("followee_id=") + builder.WriteString(fmt.Sprintf("%v", _m.FolloweeID)) + builder.WriteString(", ") + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// UserFollowsSlice is a parsable slice of UserFollows. +type UserFollowsSlice []*UserFollows diff --git a/app/users/rpc/internal/models/userfollows/userfollows.go b/app/users/rpc/internal/models/userfollows/userfollows.go new file mode 100644 index 0000000..39e8b5b --- /dev/null +++ b/app/users/rpc/internal/models/userfollows/userfollows.go @@ -0,0 +1,63 @@ +// Code generated by ent, DO NOT EDIT. + +package userfollows + +import ( + "entgo.io/ent/dialect/sql" +) + +const ( + // Label holds the string label denoting the userfollows type in the database. + Label = "user_follows" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldFollowerID holds the string denoting the follower_id field in the database. + FieldFollowerID = "follower_id" + // FieldFolloweeID holds the string denoting the followee_id field in the database. + FieldFolloweeID = "followee_id" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // Table holds the table name of the userfollows in the database. + Table = "user_follows" +) + +// Columns holds all SQL columns for userfollows fields. +var Columns = []string{ + FieldID, + FieldFollowerID, + FieldFolloweeID, + FieldCreatedAt, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +// OrderOption defines the ordering options for the UserFollows queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByFollowerID orders the results by the follower_id field. +func ByFollowerID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFollowerID, opts...).ToFunc() +} + +// ByFolloweeID orders the results by the followee_id field. +func ByFolloweeID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFolloweeID, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} diff --git a/app/users/rpc/internal/models/userfollows/where.go b/app/users/rpc/internal/models/userfollows/where.go new file mode 100644 index 0000000..ff2cc5f --- /dev/null +++ b/app/users/rpc/internal/models/userfollows/where.go @@ -0,0 +1,205 @@ +// Code generated by ent, DO NOT EDIT. + +package userfollows + +import ( + "juwan-backend/app/users/rpc/internal/models/predicate" + "time" + + "entgo.io/ent/dialect/sql" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLTE(FieldID, id)) +} + +// FollowerID applies equality check predicate on the "follower_id" field. It's identical to FollowerIDEQ. +func FollowerID(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldFollowerID, v)) +} + +// FolloweeID applies equality check predicate on the "followee_id" field. It's identical to FolloweeIDEQ. +func FolloweeID(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldFolloweeID, v)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldCreatedAt, v)) +} + +// FollowerIDEQ applies the EQ predicate on the "follower_id" field. +func FollowerIDEQ(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldFollowerID, v)) +} + +// FollowerIDNEQ applies the NEQ predicate on the "follower_id" field. +func FollowerIDNEQ(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNEQ(FieldFollowerID, v)) +} + +// FollowerIDIn applies the In predicate on the "follower_id" field. +func FollowerIDIn(vs ...int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldIn(FieldFollowerID, vs...)) +} + +// FollowerIDNotIn applies the NotIn predicate on the "follower_id" field. +func FollowerIDNotIn(vs ...int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNotIn(FieldFollowerID, vs...)) +} + +// FollowerIDGT applies the GT predicate on the "follower_id" field. +func FollowerIDGT(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGT(FieldFollowerID, v)) +} + +// FollowerIDGTE applies the GTE predicate on the "follower_id" field. +func FollowerIDGTE(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGTE(FieldFollowerID, v)) +} + +// FollowerIDLT applies the LT predicate on the "follower_id" field. +func FollowerIDLT(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLT(FieldFollowerID, v)) +} + +// FollowerIDLTE applies the LTE predicate on the "follower_id" field. +func FollowerIDLTE(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLTE(FieldFollowerID, v)) +} + +// FolloweeIDEQ applies the EQ predicate on the "followee_id" field. +func FolloweeIDEQ(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldFolloweeID, v)) +} + +// FolloweeIDNEQ applies the NEQ predicate on the "followee_id" field. +func FolloweeIDNEQ(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNEQ(FieldFolloweeID, v)) +} + +// FolloweeIDIn applies the In predicate on the "followee_id" field. +func FolloweeIDIn(vs ...int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldIn(FieldFolloweeID, vs...)) +} + +// FolloweeIDNotIn applies the NotIn predicate on the "followee_id" field. +func FolloweeIDNotIn(vs ...int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNotIn(FieldFolloweeID, vs...)) +} + +// FolloweeIDGT applies the GT predicate on the "followee_id" field. +func FolloweeIDGT(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGT(FieldFolloweeID, v)) +} + +// FolloweeIDGTE applies the GTE predicate on the "followee_id" field. +func FolloweeIDGTE(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGTE(FieldFolloweeID, v)) +} + +// FolloweeIDLT applies the LT predicate on the "followee_id" field. +func FolloweeIDLT(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLT(FieldFolloweeID, v)) +} + +// FolloweeIDLTE applies the LTE predicate on the "followee_id" field. +func FolloweeIDLTE(v int64) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLTE(FieldFolloweeID, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.UserFollows { + return predicate.UserFollows(sql.FieldLTE(FieldCreatedAt, v)) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.UserFollows) predicate.UserFollows { + return predicate.UserFollows(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.UserFollows) predicate.UserFollows { + return predicate.UserFollows(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.UserFollows) predicate.UserFollows { + return predicate.UserFollows(sql.NotPredicates(p)) +} diff --git a/app/users/rpc/internal/models/userfollows_create.go b/app/users/rpc/internal/models/userfollows_create.go new file mode 100644 index 0000000..dce79e6 --- /dev/null +++ b/app/users/rpc/internal/models/userfollows_create.go @@ -0,0 +1,222 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "errors" + "fmt" + "juwan-backend/app/users/rpc/internal/models/userfollows" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserFollowsCreate is the builder for creating a UserFollows entity. +type UserFollowsCreate struct { + config + mutation *UserFollowsMutation + hooks []Hook +} + +// SetFollowerID sets the "follower_id" field. +func (_c *UserFollowsCreate) SetFollowerID(v int64) *UserFollowsCreate { + _c.mutation.SetFollowerID(v) + return _c +} + +// SetFolloweeID sets the "followee_id" field. +func (_c *UserFollowsCreate) SetFolloweeID(v int64) *UserFollowsCreate { + _c.mutation.SetFolloweeID(v) + return _c +} + +// SetCreatedAt sets the "created_at" field. +func (_c *UserFollowsCreate) SetCreatedAt(v time.Time) *UserFollowsCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetID sets the "id" field. +func (_c *UserFollowsCreate) SetID(v int64) *UserFollowsCreate { + _c.mutation.SetID(v) + return _c +} + +// Mutation returns the UserFollowsMutation object of the builder. +func (_c *UserFollowsCreate) Mutation() *UserFollowsMutation { + return _c.mutation +} + +// Save creates the UserFollows in the database. +func (_c *UserFollowsCreate) Save(ctx context.Context) (*UserFollows, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *UserFollowsCreate) SaveX(ctx context.Context) *UserFollows { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *UserFollowsCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *UserFollowsCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *UserFollowsCreate) check() error { + if _, ok := _c.mutation.FollowerID(); !ok { + return &ValidationError{Name: "follower_id", err: errors.New(`models: missing required field "UserFollows.follower_id"`)} + } + if _, ok := _c.mutation.FolloweeID(); !ok { + return &ValidationError{Name: "followee_id", err: errors.New(`models: missing required field "UserFollows.followee_id"`)} + } + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`models: missing required field "UserFollows.created_at"`)} + } + return nil +} + +func (_c *UserFollowsCreate) sqlSave(ctx context.Context) (*UserFollows, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != _node.ID { + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + } + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *UserFollowsCreate) createSpec() (*UserFollows, *sqlgraph.CreateSpec) { + var ( + _node = &UserFollows{config: _c.config} + _spec = sqlgraph.NewCreateSpec(userfollows.Table, sqlgraph.NewFieldSpec(userfollows.FieldID, field.TypeInt64)) + ) + if id, ok := _c.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = id + } + if value, ok := _c.mutation.FollowerID(); ok { + _spec.SetField(userfollows.FieldFollowerID, field.TypeInt64, value) + _node.FollowerID = value + } + if value, ok := _c.mutation.FolloweeID(); ok { + _spec.SetField(userfollows.FieldFolloweeID, field.TypeInt64, value) + _node.FolloweeID = value + } + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(userfollows.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + return _node, _spec +} + +// UserFollowsCreateBulk is the builder for creating many UserFollows entities in bulk. +type UserFollowsCreateBulk struct { + config + err error + builders []*UserFollowsCreate +} + +// Save creates the UserFollows entities in the database. +func (_c *UserFollowsCreateBulk) Save(ctx context.Context) ([]*UserFollows, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*UserFollows, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserFollowsMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil && nodes[i].ID == 0 { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *UserFollowsCreateBulk) SaveX(ctx context.Context) []*UserFollows { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *UserFollowsCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *UserFollowsCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/app/users/rpc/internal/models/userfollows_delete.go b/app/users/rpc/internal/models/userfollows_delete.go new file mode 100644 index 0000000..e388be8 --- /dev/null +++ b/app/users/rpc/internal/models/userfollows_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "juwan-backend/app/users/rpc/internal/models/predicate" + "juwan-backend/app/users/rpc/internal/models/userfollows" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserFollowsDelete is the builder for deleting a UserFollows entity. +type UserFollowsDelete struct { + config + hooks []Hook + mutation *UserFollowsMutation +} + +// Where appends a list predicates to the UserFollowsDelete builder. +func (_d *UserFollowsDelete) Where(ps ...predicate.UserFollows) *UserFollowsDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *UserFollowsDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *UserFollowsDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *UserFollowsDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(userfollows.Table, sqlgraph.NewFieldSpec(userfollows.FieldID, field.TypeInt64)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// UserFollowsDeleteOne is the builder for deleting a single UserFollows entity. +type UserFollowsDeleteOne struct { + _d *UserFollowsDelete +} + +// Where appends a list predicates to the UserFollowsDelete builder. +func (_d *UserFollowsDeleteOne) Where(ps ...predicate.UserFollows) *UserFollowsDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *UserFollowsDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{userfollows.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *UserFollowsDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/app/users/rpc/internal/models/userfollows_query.go b/app/users/rpc/internal/models/userfollows_query.go new file mode 100644 index 0000000..4c30ca2 --- /dev/null +++ b/app/users/rpc/internal/models/userfollows_query.go @@ -0,0 +1,527 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "fmt" + "juwan-backend/app/users/rpc/internal/models/predicate" + "juwan-backend/app/users/rpc/internal/models/userfollows" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserFollowsQuery is the builder for querying UserFollows entities. +type UserFollowsQuery struct { + config + ctx *QueryContext + order []userfollows.OrderOption + inters []Interceptor + predicates []predicate.UserFollows + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the UserFollowsQuery builder. +func (_q *UserFollowsQuery) Where(ps ...predicate.UserFollows) *UserFollowsQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *UserFollowsQuery) Limit(limit int) *UserFollowsQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *UserFollowsQuery) Offset(offset int) *UserFollowsQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *UserFollowsQuery) Unique(unique bool) *UserFollowsQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *UserFollowsQuery) Order(o ...userfollows.OrderOption) *UserFollowsQuery { + _q.order = append(_q.order, o...) + return _q +} + +// First returns the first UserFollows entity from the query. +// Returns a *NotFoundError when no UserFollows was found. +func (_q *UserFollowsQuery) First(ctx context.Context) (*UserFollows, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{userfollows.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *UserFollowsQuery) FirstX(ctx context.Context) *UserFollows { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first UserFollows ID from the query. +// Returns a *NotFoundError when no UserFollows ID was found. +func (_q *UserFollowsQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{userfollows.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *UserFollowsQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single UserFollows entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one UserFollows entity is found. +// Returns a *NotFoundError when no UserFollows entities are found. +func (_q *UserFollowsQuery) Only(ctx context.Context) (*UserFollows, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{userfollows.Label} + default: + return nil, &NotSingularError{userfollows.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *UserFollowsQuery) OnlyX(ctx context.Context) *UserFollows { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only UserFollows ID in the query. +// Returns a *NotSingularError when more than one UserFollows ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *UserFollowsQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{userfollows.Label} + default: + err = &NotSingularError{userfollows.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *UserFollowsQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of UserFollowsSlice. +func (_q *UserFollowsQuery) All(ctx context.Context) ([]*UserFollows, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*UserFollows, *UserFollowsQuery]() + return withInterceptors[[]*UserFollows](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *UserFollowsQuery) AllX(ctx context.Context) []*UserFollows { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of UserFollows IDs. +func (_q *UserFollowsQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(userfollows.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *UserFollowsQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *UserFollowsQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*UserFollowsQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *UserFollowsQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *UserFollowsQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("models: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *UserFollowsQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the UserFollowsQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *UserFollowsQuery) Clone() *UserFollowsQuery { + if _q == nil { + return nil + } + return &UserFollowsQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]userfollows.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.UserFollows{}, _q.predicates...), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// FollowerID int64 `json:"follower_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.UserFollows.Query(). +// GroupBy(userfollows.FieldFollowerID). +// Aggregate(models.Count()). +// Scan(ctx, &v) +func (_q *UserFollowsQuery) GroupBy(field string, fields ...string) *UserFollowsGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &UserFollowsGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = userfollows.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// FollowerID int64 `json:"follower_id,omitempty"` +// } +// +// client.UserFollows.Query(). +// Select(userfollows.FieldFollowerID). +// Scan(ctx, &v) +func (_q *UserFollowsQuery) Select(fields ...string) *UserFollowsSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &UserFollowsSelect{UserFollowsQuery: _q} + sbuild.label = userfollows.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a UserFollowsSelect configured with the given aggregations. +func (_q *UserFollowsQuery) Aggregate(fns ...AggregateFunc) *UserFollowsSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *UserFollowsQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("models: uninitialized interceptor (forgotten import models/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !userfollows.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("models: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *UserFollowsQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*UserFollows, error) { + var ( + nodes = []*UserFollows{} + _spec = _q.querySpec() + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*UserFollows).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &UserFollows{config: _q.config} + nodes = append(nodes, node) + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + return nodes, nil +} + +func (_q *UserFollowsQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *UserFollowsQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(userfollows.Table, userfollows.Columns, sqlgraph.NewFieldSpec(userfollows.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, userfollows.FieldID) + for i := range fields { + if fields[i] != userfollows.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *UserFollowsQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(userfollows.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = userfollows.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// UserFollowsGroupBy is the group-by builder for UserFollows entities. +type UserFollowsGroupBy struct { + selector + build *UserFollowsQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *UserFollowsGroupBy) Aggregate(fns ...AggregateFunc) *UserFollowsGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *UserFollowsGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserFollowsQuery, *UserFollowsGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *UserFollowsGroupBy) sqlScan(ctx context.Context, root *UserFollowsQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// UserFollowsSelect is the builder for selecting fields of UserFollows entities. +type UserFollowsSelect struct { + *UserFollowsQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *UserFollowsSelect) Aggregate(fns ...AggregateFunc) *UserFollowsSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *UserFollowsSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserFollowsQuery, *UserFollowsSelect](ctx, _s.UserFollowsQuery, _s, _s.inters, v) +} + +func (_s *UserFollowsSelect) sqlScan(ctx context.Context, root *UserFollowsQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/app/users/rpc/internal/models/userfollows_update.go b/app/users/rpc/internal/models/userfollows_update.go new file mode 100644 index 0000000..093b7c3 --- /dev/null +++ b/app/users/rpc/internal/models/userfollows_update.go @@ -0,0 +1,283 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "errors" + "fmt" + "juwan-backend/app/users/rpc/internal/models/predicate" + "juwan-backend/app/users/rpc/internal/models/userfollows" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserFollowsUpdate is the builder for updating UserFollows entities. +type UserFollowsUpdate struct { + config + hooks []Hook + mutation *UserFollowsMutation +} + +// Where appends a list predicates to the UserFollowsUpdate builder. +func (_u *UserFollowsUpdate) Where(ps ...predicate.UserFollows) *UserFollowsUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetFollowerID sets the "follower_id" field. +func (_u *UserFollowsUpdate) SetFollowerID(v int64) *UserFollowsUpdate { + _u.mutation.ResetFollowerID() + _u.mutation.SetFollowerID(v) + return _u +} + +// SetNillableFollowerID sets the "follower_id" field if the given value is not nil. +func (_u *UserFollowsUpdate) SetNillableFollowerID(v *int64) *UserFollowsUpdate { + if v != nil { + _u.SetFollowerID(*v) + } + return _u +} + +// AddFollowerID adds value to the "follower_id" field. +func (_u *UserFollowsUpdate) AddFollowerID(v int64) *UserFollowsUpdate { + _u.mutation.AddFollowerID(v) + return _u +} + +// SetFolloweeID sets the "followee_id" field. +func (_u *UserFollowsUpdate) SetFolloweeID(v int64) *UserFollowsUpdate { + _u.mutation.ResetFolloweeID() + _u.mutation.SetFolloweeID(v) + return _u +} + +// SetNillableFolloweeID sets the "followee_id" field if the given value is not nil. +func (_u *UserFollowsUpdate) SetNillableFolloweeID(v *int64) *UserFollowsUpdate { + if v != nil { + _u.SetFolloweeID(*v) + } + return _u +} + +// AddFolloweeID adds value to the "followee_id" field. +func (_u *UserFollowsUpdate) AddFolloweeID(v int64) *UserFollowsUpdate { + _u.mutation.AddFolloweeID(v) + return _u +} + +// Mutation returns the UserFollowsMutation object of the builder. +func (_u *UserFollowsUpdate) Mutation() *UserFollowsMutation { + return _u.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *UserFollowsUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *UserFollowsUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *UserFollowsUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *UserFollowsUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +func (_u *UserFollowsUpdate) sqlSave(ctx context.Context) (_node int, err error) { + _spec := sqlgraph.NewUpdateSpec(userfollows.Table, userfollows.Columns, sqlgraph.NewFieldSpec(userfollows.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.FollowerID(); ok { + _spec.SetField(userfollows.FieldFollowerID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedFollowerID(); ok { + _spec.AddField(userfollows.FieldFollowerID, field.TypeInt64, value) + } + if value, ok := _u.mutation.FolloweeID(); ok { + _spec.SetField(userfollows.FieldFolloweeID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedFolloweeID(); ok { + _spec.AddField(userfollows.FieldFolloweeID, field.TypeInt64, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{userfollows.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// UserFollowsUpdateOne is the builder for updating a single UserFollows entity. +type UserFollowsUpdateOne struct { + config + fields []string + hooks []Hook + mutation *UserFollowsMutation +} + +// SetFollowerID sets the "follower_id" field. +func (_u *UserFollowsUpdateOne) SetFollowerID(v int64) *UserFollowsUpdateOne { + _u.mutation.ResetFollowerID() + _u.mutation.SetFollowerID(v) + return _u +} + +// SetNillableFollowerID sets the "follower_id" field if the given value is not nil. +func (_u *UserFollowsUpdateOne) SetNillableFollowerID(v *int64) *UserFollowsUpdateOne { + if v != nil { + _u.SetFollowerID(*v) + } + return _u +} + +// AddFollowerID adds value to the "follower_id" field. +func (_u *UserFollowsUpdateOne) AddFollowerID(v int64) *UserFollowsUpdateOne { + _u.mutation.AddFollowerID(v) + return _u +} + +// SetFolloweeID sets the "followee_id" field. +func (_u *UserFollowsUpdateOne) SetFolloweeID(v int64) *UserFollowsUpdateOne { + _u.mutation.ResetFolloweeID() + _u.mutation.SetFolloweeID(v) + return _u +} + +// SetNillableFolloweeID sets the "followee_id" field if the given value is not nil. +func (_u *UserFollowsUpdateOne) SetNillableFolloweeID(v *int64) *UserFollowsUpdateOne { + if v != nil { + _u.SetFolloweeID(*v) + } + return _u +} + +// AddFolloweeID adds value to the "followee_id" field. +func (_u *UserFollowsUpdateOne) AddFolloweeID(v int64) *UserFollowsUpdateOne { + _u.mutation.AddFolloweeID(v) + return _u +} + +// Mutation returns the UserFollowsMutation object of the builder. +func (_u *UserFollowsUpdateOne) Mutation() *UserFollowsMutation { + return _u.mutation +} + +// Where appends a list predicates to the UserFollowsUpdate builder. +func (_u *UserFollowsUpdateOne) Where(ps ...predicate.UserFollows) *UserFollowsUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *UserFollowsUpdateOne) Select(field string, fields ...string) *UserFollowsUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated UserFollows entity. +func (_u *UserFollowsUpdateOne) Save(ctx context.Context) (*UserFollows, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *UserFollowsUpdateOne) SaveX(ctx context.Context) *UserFollows { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *UserFollowsUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *UserFollowsUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +func (_u *UserFollowsUpdateOne) sqlSave(ctx context.Context) (_node *UserFollows, err error) { + _spec := sqlgraph.NewUpdateSpec(userfollows.Table, userfollows.Columns, sqlgraph.NewFieldSpec(userfollows.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`models: missing "UserFollows.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, userfollows.FieldID) + for _, f := range fields { + if !userfollows.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("models: invalid field %q for query", f)} + } + if f != userfollows.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.FollowerID(); ok { + _spec.SetField(userfollows.FieldFollowerID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedFollowerID(); ok { + _spec.AddField(userfollows.FieldFollowerID, field.TypeInt64, value) + } + if value, ok := _u.mutation.FolloweeID(); ok { + _spec.SetField(userfollows.FieldFolloweeID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedFolloweeID(); ok { + _spec.AddField(userfollows.FieldFolloweeID, field.TypeInt64, value) + } + _node = &UserFollows{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{userfollows.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/app/users/rpc/internal/models/userpreferences.go b/app/users/rpc/internal/models/userpreferences.go new file mode 100644 index 0000000..12a3154 --- /dev/null +++ b/app/users/rpc/internal/models/userpreferences.go @@ -0,0 +1,174 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "fmt" + "juwan-backend/app/users/rpc/internal/models/userpreferences" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" +) + +// UserPreferences is the model entity for the UserPreferences schema. +type UserPreferences struct { + config `json:"-"` + // ID of the ent. + ID int `json:"id,omitempty"` + // UserID holds the value of the "user_id" field. + UserID int64 `json:"user_id,omitempty"` + // NotificationOrder holds the value of the "notification_order" field. + NotificationOrder bool `json:"notification_order,omitempty"` + // NotificationCommunity holds the value of the "notification_community" field. + NotificationCommunity bool `json:"notification_community,omitempty"` + // NotificationSystem holds the value of the "notification_system" field. + NotificationSystem bool `json:"notification_system,omitempty"` + // Theme holds the value of the "theme" field. + Theme string `json:"theme,omitempty"` + // Language holds the value of the "language" field. + Language string `json:"language,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + selectValues sql.SelectValues +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*UserPreferences) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case userpreferences.FieldNotificationOrder, userpreferences.FieldNotificationCommunity, userpreferences.FieldNotificationSystem: + values[i] = new(sql.NullBool) + case userpreferences.FieldID, userpreferences.FieldUserID: + values[i] = new(sql.NullInt64) + case userpreferences.FieldTheme, userpreferences.FieldLanguage: + values[i] = new(sql.NullString) + case userpreferences.FieldUpdatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the UserPreferences fields. +func (_m *UserPreferences) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case userpreferences.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int(value.Int64) + case userpreferences.FieldUserID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field user_id", values[i]) + } else if value.Valid { + _m.UserID = value.Int64 + } + case userpreferences.FieldNotificationOrder: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field notification_order", values[i]) + } else if value.Valid { + _m.NotificationOrder = value.Bool + } + case userpreferences.FieldNotificationCommunity: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field notification_community", values[i]) + } else if value.Valid { + _m.NotificationCommunity = value.Bool + } + case userpreferences.FieldNotificationSystem: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field notification_system", values[i]) + } else if value.Valid { + _m.NotificationSystem = value.Bool + } + case userpreferences.FieldTheme: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field theme", values[i]) + } else if value.Valid { + _m.Theme = value.String + } + case userpreferences.FieldLanguage: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field language", values[i]) + } else if value.Valid { + _m.Language = value.String + } + case userpreferences.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + _m.UpdatedAt = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the UserPreferences. +// This includes values selected through modifiers, order, etc. +func (_m *UserPreferences) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// Update returns a builder for updating this UserPreferences. +// Note that you need to call UserPreferences.Unwrap() before calling this method if this UserPreferences +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *UserPreferences) Update() *UserPreferencesUpdateOne { + return NewUserPreferencesClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the UserPreferences entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *UserPreferences) Unwrap() *UserPreferences { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("models: UserPreferences is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *UserPreferences) String() string { + var builder strings.Builder + builder.WriteString("UserPreferences(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("user_id=") + builder.WriteString(fmt.Sprintf("%v", _m.UserID)) + builder.WriteString(", ") + builder.WriteString("notification_order=") + builder.WriteString(fmt.Sprintf("%v", _m.NotificationOrder)) + builder.WriteString(", ") + builder.WriteString("notification_community=") + builder.WriteString(fmt.Sprintf("%v", _m.NotificationCommunity)) + builder.WriteString(", ") + builder.WriteString("notification_system=") + builder.WriteString(fmt.Sprintf("%v", _m.NotificationSystem)) + builder.WriteString(", ") + builder.WriteString("theme=") + builder.WriteString(_m.Theme) + builder.WriteString(", ") + builder.WriteString("language=") + builder.WriteString(_m.Language) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(_m.UpdatedAt.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// UserPreferencesSlice is a parsable slice of UserPreferences. +type UserPreferencesSlice []*UserPreferences diff --git a/app/users/rpc/internal/models/userpreferences/userpreferences.go b/app/users/rpc/internal/models/userpreferences/userpreferences.go new file mode 100644 index 0000000..b1b435f --- /dev/null +++ b/app/users/rpc/internal/models/userpreferences/userpreferences.go @@ -0,0 +1,112 @@ +// Code generated by ent, DO NOT EDIT. + +package userpreferences + +import ( + "time" + + "entgo.io/ent/dialect/sql" +) + +const ( + // Label holds the string label denoting the userpreferences type in the database. + Label = "user_preferences" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldUserID holds the string denoting the user_id field in the database. + FieldUserID = "user_id" + // FieldNotificationOrder holds the string denoting the notification_order field in the database. + FieldNotificationOrder = "notification_order" + // FieldNotificationCommunity holds the string denoting the notification_community field in the database. + FieldNotificationCommunity = "notification_community" + // FieldNotificationSystem holds the string denoting the notification_system field in the database. + FieldNotificationSystem = "notification_system" + // FieldTheme holds the string denoting the theme field in the database. + FieldTheme = "theme" + // FieldLanguage holds the string denoting the language field in the database. + FieldLanguage = "language" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // Table holds the table name of the userpreferences in the database. + Table = "user_preferences" +) + +// Columns holds all SQL columns for userpreferences fields. +var Columns = []string{ + FieldID, + FieldUserID, + FieldNotificationOrder, + FieldNotificationCommunity, + FieldNotificationSystem, + FieldTheme, + FieldLanguage, + FieldUpdatedAt, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // DefaultNotificationOrder holds the default value on creation for the "notification_order" field. + DefaultNotificationOrder bool + // DefaultNotificationCommunity holds the default value on creation for the "notification_community" field. + DefaultNotificationCommunity bool + // DefaultNotificationSystem holds the default value on creation for the "notification_system" field. + DefaultNotificationSystem bool + // DefaultTheme holds the default value on creation for the "theme" field. + DefaultTheme string + // DefaultLanguage holds the default value on creation for the "language" field. + DefaultLanguage string + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time +) + +// OrderOption defines the ordering options for the UserPreferences queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByUserID orders the results by the user_id field. +func ByUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserID, opts...).ToFunc() +} + +// ByNotificationOrder orders the results by the notification_order field. +func ByNotificationOrder(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNotificationOrder, opts...).ToFunc() +} + +// ByNotificationCommunity orders the results by the notification_community field. +func ByNotificationCommunity(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNotificationCommunity, opts...).ToFunc() +} + +// ByNotificationSystem orders the results by the notification_system field. +func ByNotificationSystem(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNotificationSystem, opts...).ToFunc() +} + +// ByTheme orders the results by the theme field. +func ByTheme(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldTheme, opts...).ToFunc() +} + +// ByLanguage orders the results by the language field. +func ByLanguage(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLanguage, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} diff --git a/app/users/rpc/internal/models/userpreferences/where.go b/app/users/rpc/internal/models/userpreferences/where.go new file mode 100644 index 0000000..0874eb7 --- /dev/null +++ b/app/users/rpc/internal/models/userpreferences/where.go @@ -0,0 +1,345 @@ +// Code generated by ent, DO NOT EDIT. + +package userpreferences + +import ( + "juwan-backend/app/users/rpc/internal/models/predicate" + "time" + + "entgo.io/ent/dialect/sql" +) + +// ID filters vertices based on their ID field. +func ID(id int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLTE(FieldID, id)) +} + +// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. +func UserID(v int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldUserID, v)) +} + +// NotificationOrder applies equality check predicate on the "notification_order" field. It's identical to NotificationOrderEQ. +func NotificationOrder(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldNotificationOrder, v)) +} + +// NotificationCommunity applies equality check predicate on the "notification_community" field. It's identical to NotificationCommunityEQ. +func NotificationCommunity(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldNotificationCommunity, v)) +} + +// NotificationSystem applies equality check predicate on the "notification_system" field. It's identical to NotificationSystemEQ. +func NotificationSystem(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldNotificationSystem, v)) +} + +// Theme applies equality check predicate on the "theme" field. It's identical to ThemeEQ. +func Theme(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldTheme, v)) +} + +// Language applies equality check predicate on the "language" field. It's identical to LanguageEQ. +func Language(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldLanguage, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UserIDEQ applies the EQ predicate on the "user_id" field. +func UserIDEQ(v int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldUserID, v)) +} + +// UserIDNEQ applies the NEQ predicate on the "user_id" field. +func UserIDNEQ(v int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldUserID, v)) +} + +// UserIDIn applies the In predicate on the "user_id" field. +func UserIDIn(vs ...int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldIn(FieldUserID, vs...)) +} + +// UserIDNotIn applies the NotIn predicate on the "user_id" field. +func UserIDNotIn(vs ...int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNotIn(FieldUserID, vs...)) +} + +// UserIDGT applies the GT predicate on the "user_id" field. +func UserIDGT(v int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGT(FieldUserID, v)) +} + +// UserIDGTE applies the GTE predicate on the "user_id" field. +func UserIDGTE(v int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGTE(FieldUserID, v)) +} + +// UserIDLT applies the LT predicate on the "user_id" field. +func UserIDLT(v int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLT(FieldUserID, v)) +} + +// UserIDLTE applies the LTE predicate on the "user_id" field. +func UserIDLTE(v int64) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLTE(FieldUserID, v)) +} + +// NotificationOrderEQ applies the EQ predicate on the "notification_order" field. +func NotificationOrderEQ(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldNotificationOrder, v)) +} + +// NotificationOrderNEQ applies the NEQ predicate on the "notification_order" field. +func NotificationOrderNEQ(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldNotificationOrder, v)) +} + +// NotificationCommunityEQ applies the EQ predicate on the "notification_community" field. +func NotificationCommunityEQ(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldNotificationCommunity, v)) +} + +// NotificationCommunityNEQ applies the NEQ predicate on the "notification_community" field. +func NotificationCommunityNEQ(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldNotificationCommunity, v)) +} + +// NotificationSystemEQ applies the EQ predicate on the "notification_system" field. +func NotificationSystemEQ(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldNotificationSystem, v)) +} + +// NotificationSystemNEQ applies the NEQ predicate on the "notification_system" field. +func NotificationSystemNEQ(v bool) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldNotificationSystem, v)) +} + +// ThemeEQ applies the EQ predicate on the "theme" field. +func ThemeEQ(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldTheme, v)) +} + +// ThemeNEQ applies the NEQ predicate on the "theme" field. +func ThemeNEQ(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldTheme, v)) +} + +// ThemeIn applies the In predicate on the "theme" field. +func ThemeIn(vs ...string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldIn(FieldTheme, vs...)) +} + +// ThemeNotIn applies the NotIn predicate on the "theme" field. +func ThemeNotIn(vs ...string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNotIn(FieldTheme, vs...)) +} + +// ThemeGT applies the GT predicate on the "theme" field. +func ThemeGT(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGT(FieldTheme, v)) +} + +// ThemeGTE applies the GTE predicate on the "theme" field. +func ThemeGTE(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGTE(FieldTheme, v)) +} + +// ThemeLT applies the LT predicate on the "theme" field. +func ThemeLT(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLT(FieldTheme, v)) +} + +// ThemeLTE applies the LTE predicate on the "theme" field. +func ThemeLTE(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLTE(FieldTheme, v)) +} + +// ThemeContains applies the Contains predicate on the "theme" field. +func ThemeContains(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldContains(FieldTheme, v)) +} + +// ThemeHasPrefix applies the HasPrefix predicate on the "theme" field. +func ThemeHasPrefix(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldHasPrefix(FieldTheme, v)) +} + +// ThemeHasSuffix applies the HasSuffix predicate on the "theme" field. +func ThemeHasSuffix(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldHasSuffix(FieldTheme, v)) +} + +// ThemeEqualFold applies the EqualFold predicate on the "theme" field. +func ThemeEqualFold(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEqualFold(FieldTheme, v)) +} + +// ThemeContainsFold applies the ContainsFold predicate on the "theme" field. +func ThemeContainsFold(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldContainsFold(FieldTheme, v)) +} + +// LanguageEQ applies the EQ predicate on the "language" field. +func LanguageEQ(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldLanguage, v)) +} + +// LanguageNEQ applies the NEQ predicate on the "language" field. +func LanguageNEQ(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldLanguage, v)) +} + +// LanguageIn applies the In predicate on the "language" field. +func LanguageIn(vs ...string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldIn(FieldLanguage, vs...)) +} + +// LanguageNotIn applies the NotIn predicate on the "language" field. +func LanguageNotIn(vs ...string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNotIn(FieldLanguage, vs...)) +} + +// LanguageGT applies the GT predicate on the "language" field. +func LanguageGT(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGT(FieldLanguage, v)) +} + +// LanguageGTE applies the GTE predicate on the "language" field. +func LanguageGTE(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGTE(FieldLanguage, v)) +} + +// LanguageLT applies the LT predicate on the "language" field. +func LanguageLT(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLT(FieldLanguage, v)) +} + +// LanguageLTE applies the LTE predicate on the "language" field. +func LanguageLTE(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLTE(FieldLanguage, v)) +} + +// LanguageContains applies the Contains predicate on the "language" field. +func LanguageContains(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldContains(FieldLanguage, v)) +} + +// LanguageHasPrefix applies the HasPrefix predicate on the "language" field. +func LanguageHasPrefix(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldHasPrefix(FieldLanguage, v)) +} + +// LanguageHasSuffix applies the HasSuffix predicate on the "language" field. +func LanguageHasSuffix(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldHasSuffix(FieldLanguage, v)) +} + +// LanguageEqualFold applies the EqualFold predicate on the "language" field. +func LanguageEqualFold(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEqualFold(FieldLanguage, v)) +} + +// LanguageContainsFold applies the ContainsFold predicate on the "language" field. +func LanguageContainsFold(v string) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldContainsFold(FieldLanguage, v)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.UserPreferences { + return predicate.UserPreferences(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.UserPreferences) predicate.UserPreferences { + return predicate.UserPreferences(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.UserPreferences) predicate.UserPreferences { + return predicate.UserPreferences(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.UserPreferences) predicate.UserPreferences { + return predicate.UserPreferences(sql.NotPredicates(p)) +} diff --git a/app/users/rpc/internal/models/userpreferences_create.go b/app/users/rpc/internal/models/userpreferences_create.go new file mode 100644 index 0000000..280064a --- /dev/null +++ b/app/users/rpc/internal/models/userpreferences_create.go @@ -0,0 +1,340 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "errors" + "fmt" + "juwan-backend/app/users/rpc/internal/models/userpreferences" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserPreferencesCreate is the builder for creating a UserPreferences entity. +type UserPreferencesCreate struct { + config + mutation *UserPreferencesMutation + hooks []Hook +} + +// SetUserID sets the "user_id" field. +func (_c *UserPreferencesCreate) SetUserID(v int64) *UserPreferencesCreate { + _c.mutation.SetUserID(v) + return _c +} + +// SetNotificationOrder sets the "notification_order" field. +func (_c *UserPreferencesCreate) SetNotificationOrder(v bool) *UserPreferencesCreate { + _c.mutation.SetNotificationOrder(v) + return _c +} + +// SetNillableNotificationOrder sets the "notification_order" field if the given value is not nil. +func (_c *UserPreferencesCreate) SetNillableNotificationOrder(v *bool) *UserPreferencesCreate { + if v != nil { + _c.SetNotificationOrder(*v) + } + return _c +} + +// SetNotificationCommunity sets the "notification_community" field. +func (_c *UserPreferencesCreate) SetNotificationCommunity(v bool) *UserPreferencesCreate { + _c.mutation.SetNotificationCommunity(v) + return _c +} + +// SetNillableNotificationCommunity sets the "notification_community" field if the given value is not nil. +func (_c *UserPreferencesCreate) SetNillableNotificationCommunity(v *bool) *UserPreferencesCreate { + if v != nil { + _c.SetNotificationCommunity(*v) + } + return _c +} + +// SetNotificationSystem sets the "notification_system" field. +func (_c *UserPreferencesCreate) SetNotificationSystem(v bool) *UserPreferencesCreate { + _c.mutation.SetNotificationSystem(v) + return _c +} + +// SetNillableNotificationSystem sets the "notification_system" field if the given value is not nil. +func (_c *UserPreferencesCreate) SetNillableNotificationSystem(v *bool) *UserPreferencesCreate { + if v != nil { + _c.SetNotificationSystem(*v) + } + return _c +} + +// SetTheme sets the "theme" field. +func (_c *UserPreferencesCreate) SetTheme(v string) *UserPreferencesCreate { + _c.mutation.SetTheme(v) + return _c +} + +// SetNillableTheme sets the "theme" field if the given value is not nil. +func (_c *UserPreferencesCreate) SetNillableTheme(v *string) *UserPreferencesCreate { + if v != nil { + _c.SetTheme(*v) + } + return _c +} + +// SetLanguage sets the "language" field. +func (_c *UserPreferencesCreate) SetLanguage(v string) *UserPreferencesCreate { + _c.mutation.SetLanguage(v) + return _c +} + +// SetNillableLanguage sets the "language" field if the given value is not nil. +func (_c *UserPreferencesCreate) SetNillableLanguage(v *string) *UserPreferencesCreate { + if v != nil { + _c.SetLanguage(*v) + } + return _c +} + +// SetUpdatedAt sets the "updated_at" field. +func (_c *UserPreferencesCreate) SetUpdatedAt(v time.Time) *UserPreferencesCreate { + _c.mutation.SetUpdatedAt(v) + return _c +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *UserPreferencesCreate) SetNillableUpdatedAt(v *time.Time) *UserPreferencesCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + +// Mutation returns the UserPreferencesMutation object of the builder. +func (_c *UserPreferencesCreate) Mutation() *UserPreferencesMutation { + return _c.mutation +} + +// Save creates the UserPreferences in the database. +func (_c *UserPreferencesCreate) Save(ctx context.Context) (*UserPreferences, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *UserPreferencesCreate) SaveX(ctx context.Context) *UserPreferences { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *UserPreferencesCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *UserPreferencesCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *UserPreferencesCreate) defaults() { + if _, ok := _c.mutation.NotificationOrder(); !ok { + v := userpreferences.DefaultNotificationOrder + _c.mutation.SetNotificationOrder(v) + } + if _, ok := _c.mutation.NotificationCommunity(); !ok { + v := userpreferences.DefaultNotificationCommunity + _c.mutation.SetNotificationCommunity(v) + } + if _, ok := _c.mutation.NotificationSystem(); !ok { + v := userpreferences.DefaultNotificationSystem + _c.mutation.SetNotificationSystem(v) + } + if _, ok := _c.mutation.Theme(); !ok { + v := userpreferences.DefaultTheme + _c.mutation.SetTheme(v) + } + if _, ok := _c.mutation.Language(); !ok { + v := userpreferences.DefaultLanguage + _c.mutation.SetLanguage(v) + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + v := userpreferences.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *UserPreferencesCreate) check() error { + if _, ok := _c.mutation.UserID(); !ok { + return &ValidationError{Name: "user_id", err: errors.New(`models: missing required field "UserPreferences.user_id"`)} + } + if _, ok := _c.mutation.NotificationOrder(); !ok { + return &ValidationError{Name: "notification_order", err: errors.New(`models: missing required field "UserPreferences.notification_order"`)} + } + if _, ok := _c.mutation.NotificationCommunity(); !ok { + return &ValidationError{Name: "notification_community", err: errors.New(`models: missing required field "UserPreferences.notification_community"`)} + } + if _, ok := _c.mutation.NotificationSystem(); !ok { + return &ValidationError{Name: "notification_system", err: errors.New(`models: missing required field "UserPreferences.notification_system"`)} + } + if _, ok := _c.mutation.Theme(); !ok { + return &ValidationError{Name: "theme", err: errors.New(`models: missing required field "UserPreferences.theme"`)} + } + if _, ok := _c.mutation.Language(); !ok { + return &ValidationError{Name: "language", err: errors.New(`models: missing required field "UserPreferences.language"`)} + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`models: missing required field "UserPreferences.updated_at"`)} + } + return nil +} + +func (_c *UserPreferencesCreate) sqlSave(ctx context.Context) (*UserPreferences, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *UserPreferencesCreate) createSpec() (*UserPreferences, *sqlgraph.CreateSpec) { + var ( + _node = &UserPreferences{config: _c.config} + _spec = sqlgraph.NewCreateSpec(userpreferences.Table, sqlgraph.NewFieldSpec(userpreferences.FieldID, field.TypeInt)) + ) + if value, ok := _c.mutation.UserID(); ok { + _spec.SetField(userpreferences.FieldUserID, field.TypeInt64, value) + _node.UserID = value + } + if value, ok := _c.mutation.NotificationOrder(); ok { + _spec.SetField(userpreferences.FieldNotificationOrder, field.TypeBool, value) + _node.NotificationOrder = value + } + if value, ok := _c.mutation.NotificationCommunity(); ok { + _spec.SetField(userpreferences.FieldNotificationCommunity, field.TypeBool, value) + _node.NotificationCommunity = value + } + if value, ok := _c.mutation.NotificationSystem(); ok { + _spec.SetField(userpreferences.FieldNotificationSystem, field.TypeBool, value) + _node.NotificationSystem = value + } + if value, ok := _c.mutation.Theme(); ok { + _spec.SetField(userpreferences.FieldTheme, field.TypeString, value) + _node.Theme = value + } + if value, ok := _c.mutation.Language(); ok { + _spec.SetField(userpreferences.FieldLanguage, field.TypeString, value) + _node.Language = value + } + if value, ok := _c.mutation.UpdatedAt(); ok { + _spec.SetField(userpreferences.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + return _node, _spec +} + +// UserPreferencesCreateBulk is the builder for creating many UserPreferences entities in bulk. +type UserPreferencesCreateBulk struct { + config + err error + builders []*UserPreferencesCreate +} + +// Save creates the UserPreferences entities in the database. +func (_c *UserPreferencesCreateBulk) Save(ctx context.Context) ([]*UserPreferences, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*UserPreferences, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*UserPreferencesMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *UserPreferencesCreateBulk) SaveX(ctx context.Context) []*UserPreferences { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *UserPreferencesCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *UserPreferencesCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/app/users/rpc/internal/models/userpreferences_delete.go b/app/users/rpc/internal/models/userpreferences_delete.go new file mode 100644 index 0000000..8f00e13 --- /dev/null +++ b/app/users/rpc/internal/models/userpreferences_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "juwan-backend/app/users/rpc/internal/models/predicate" + "juwan-backend/app/users/rpc/internal/models/userpreferences" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserPreferencesDelete is the builder for deleting a UserPreferences entity. +type UserPreferencesDelete struct { + config + hooks []Hook + mutation *UserPreferencesMutation +} + +// Where appends a list predicates to the UserPreferencesDelete builder. +func (_d *UserPreferencesDelete) Where(ps ...predicate.UserPreferences) *UserPreferencesDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *UserPreferencesDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *UserPreferencesDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *UserPreferencesDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(userpreferences.Table, sqlgraph.NewFieldSpec(userpreferences.FieldID, field.TypeInt)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// UserPreferencesDeleteOne is the builder for deleting a single UserPreferences entity. +type UserPreferencesDeleteOne struct { + _d *UserPreferencesDelete +} + +// Where appends a list predicates to the UserPreferencesDelete builder. +func (_d *UserPreferencesDeleteOne) Where(ps ...predicate.UserPreferences) *UserPreferencesDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *UserPreferencesDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{userpreferences.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *UserPreferencesDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/app/users/rpc/internal/models/userpreferences_query.go b/app/users/rpc/internal/models/userpreferences_query.go new file mode 100644 index 0000000..2b704d6 --- /dev/null +++ b/app/users/rpc/internal/models/userpreferences_query.go @@ -0,0 +1,527 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "fmt" + "juwan-backend/app/users/rpc/internal/models/predicate" + "juwan-backend/app/users/rpc/internal/models/userpreferences" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserPreferencesQuery is the builder for querying UserPreferences entities. +type UserPreferencesQuery struct { + config + ctx *QueryContext + order []userpreferences.OrderOption + inters []Interceptor + predicates []predicate.UserPreferences + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the UserPreferencesQuery builder. +func (_q *UserPreferencesQuery) Where(ps ...predicate.UserPreferences) *UserPreferencesQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *UserPreferencesQuery) Limit(limit int) *UserPreferencesQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *UserPreferencesQuery) Offset(offset int) *UserPreferencesQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *UserPreferencesQuery) Unique(unique bool) *UserPreferencesQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *UserPreferencesQuery) Order(o ...userpreferences.OrderOption) *UserPreferencesQuery { + _q.order = append(_q.order, o...) + return _q +} + +// First returns the first UserPreferences entity from the query. +// Returns a *NotFoundError when no UserPreferences was found. +func (_q *UserPreferencesQuery) First(ctx context.Context) (*UserPreferences, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{userpreferences.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *UserPreferencesQuery) FirstX(ctx context.Context) *UserPreferences { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first UserPreferences ID from the query. +// Returns a *NotFoundError when no UserPreferences ID was found. +func (_q *UserPreferencesQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{userpreferences.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *UserPreferencesQuery) FirstIDX(ctx context.Context) int { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single UserPreferences entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one UserPreferences entity is found. +// Returns a *NotFoundError when no UserPreferences entities are found. +func (_q *UserPreferencesQuery) Only(ctx context.Context) (*UserPreferences, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{userpreferences.Label} + default: + return nil, &NotSingularError{userpreferences.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *UserPreferencesQuery) OnlyX(ctx context.Context) *UserPreferences { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only UserPreferences ID in the query. +// Returns a *NotSingularError when more than one UserPreferences ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *UserPreferencesQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{userpreferences.Label} + default: + err = &NotSingularError{userpreferences.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *UserPreferencesQuery) OnlyIDX(ctx context.Context) int { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of UserPreferencesSlice. +func (_q *UserPreferencesQuery) All(ctx context.Context) ([]*UserPreferences, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*UserPreferences, *UserPreferencesQuery]() + return withInterceptors[[]*UserPreferences](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *UserPreferencesQuery) AllX(ctx context.Context) []*UserPreferences { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of UserPreferences IDs. +func (_q *UserPreferencesQuery) IDs(ctx context.Context) (ids []int, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(userpreferences.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *UserPreferencesQuery) IDsX(ctx context.Context) []int { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *UserPreferencesQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*UserPreferencesQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *UserPreferencesQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *UserPreferencesQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("models: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *UserPreferencesQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the UserPreferencesQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *UserPreferencesQuery) Clone() *UserPreferencesQuery { + if _q == nil { + return nil + } + return &UserPreferencesQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]userpreferences.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.UserPreferences{}, _q.predicates...), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// UserID int64 `json:"user_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.UserPreferences.Query(). +// GroupBy(userpreferences.FieldUserID). +// Aggregate(models.Count()). +// Scan(ctx, &v) +func (_q *UserPreferencesQuery) GroupBy(field string, fields ...string) *UserPreferencesGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &UserPreferencesGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = userpreferences.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// UserID int64 `json:"user_id,omitempty"` +// } +// +// client.UserPreferences.Query(). +// Select(userpreferences.FieldUserID). +// Scan(ctx, &v) +func (_q *UserPreferencesQuery) Select(fields ...string) *UserPreferencesSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &UserPreferencesSelect{UserPreferencesQuery: _q} + sbuild.label = userpreferences.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a UserPreferencesSelect configured with the given aggregations. +func (_q *UserPreferencesQuery) Aggregate(fns ...AggregateFunc) *UserPreferencesSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *UserPreferencesQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("models: uninitialized interceptor (forgotten import models/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !userpreferences.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("models: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *UserPreferencesQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*UserPreferences, error) { + var ( + nodes = []*UserPreferences{} + _spec = _q.querySpec() + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*UserPreferences).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &UserPreferences{config: _q.config} + nodes = append(nodes, node) + return node.assignValues(columns, values) + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + return nodes, nil +} + +func (_q *UserPreferencesQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *UserPreferencesQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(userpreferences.Table, userpreferences.Columns, sqlgraph.NewFieldSpec(userpreferences.FieldID, field.TypeInt)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, userpreferences.FieldID) + for i := range fields { + if fields[i] != userpreferences.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *UserPreferencesQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(userpreferences.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = userpreferences.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// UserPreferencesGroupBy is the group-by builder for UserPreferences entities. +type UserPreferencesGroupBy struct { + selector + build *UserPreferencesQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *UserPreferencesGroupBy) Aggregate(fns ...AggregateFunc) *UserPreferencesGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *UserPreferencesGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserPreferencesQuery, *UserPreferencesGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *UserPreferencesGroupBy) sqlScan(ctx context.Context, root *UserPreferencesQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// UserPreferencesSelect is the builder for selecting fields of UserPreferences entities. +type UserPreferencesSelect struct { + *UserPreferencesQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *UserPreferencesSelect) Aggregate(fns ...AggregateFunc) *UserPreferencesSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *UserPreferencesSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*UserPreferencesQuery, *UserPreferencesSelect](ctx, _s.UserPreferencesQuery, _s, _s.inters, v) +} + +func (_s *UserPreferencesSelect) sqlScan(ctx context.Context, root *UserPreferencesQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/app/users/rpc/internal/models/userpreferences_update.go b/app/users/rpc/internal/models/userpreferences_update.go new file mode 100644 index 0000000..7938e76 --- /dev/null +++ b/app/users/rpc/internal/models/userpreferences_update.go @@ -0,0 +1,434 @@ +// Code generated by ent, DO NOT EDIT. + +package models + +import ( + "context" + "errors" + "fmt" + "juwan-backend/app/users/rpc/internal/models/predicate" + "juwan-backend/app/users/rpc/internal/models/userpreferences" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" +) + +// UserPreferencesUpdate is the builder for updating UserPreferences entities. +type UserPreferencesUpdate struct { + config + hooks []Hook + mutation *UserPreferencesMutation +} + +// Where appends a list predicates to the UserPreferencesUpdate builder. +func (_u *UserPreferencesUpdate) Where(ps ...predicate.UserPreferences) *UserPreferencesUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetUserID sets the "user_id" field. +func (_u *UserPreferencesUpdate) SetUserID(v int64) *UserPreferencesUpdate { + _u.mutation.ResetUserID() + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *UserPreferencesUpdate) SetNillableUserID(v *int64) *UserPreferencesUpdate { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// AddUserID adds value to the "user_id" field. +func (_u *UserPreferencesUpdate) AddUserID(v int64) *UserPreferencesUpdate { + _u.mutation.AddUserID(v) + return _u +} + +// SetNotificationOrder sets the "notification_order" field. +func (_u *UserPreferencesUpdate) SetNotificationOrder(v bool) *UserPreferencesUpdate { + _u.mutation.SetNotificationOrder(v) + return _u +} + +// SetNillableNotificationOrder sets the "notification_order" field if the given value is not nil. +func (_u *UserPreferencesUpdate) SetNillableNotificationOrder(v *bool) *UserPreferencesUpdate { + if v != nil { + _u.SetNotificationOrder(*v) + } + return _u +} + +// SetNotificationCommunity sets the "notification_community" field. +func (_u *UserPreferencesUpdate) SetNotificationCommunity(v bool) *UserPreferencesUpdate { + _u.mutation.SetNotificationCommunity(v) + return _u +} + +// SetNillableNotificationCommunity sets the "notification_community" field if the given value is not nil. +func (_u *UserPreferencesUpdate) SetNillableNotificationCommunity(v *bool) *UserPreferencesUpdate { + if v != nil { + _u.SetNotificationCommunity(*v) + } + return _u +} + +// SetNotificationSystem sets the "notification_system" field. +func (_u *UserPreferencesUpdate) SetNotificationSystem(v bool) *UserPreferencesUpdate { + _u.mutation.SetNotificationSystem(v) + return _u +} + +// SetNillableNotificationSystem sets the "notification_system" field if the given value is not nil. +func (_u *UserPreferencesUpdate) SetNillableNotificationSystem(v *bool) *UserPreferencesUpdate { + if v != nil { + _u.SetNotificationSystem(*v) + } + return _u +} + +// SetTheme sets the "theme" field. +func (_u *UserPreferencesUpdate) SetTheme(v string) *UserPreferencesUpdate { + _u.mutation.SetTheme(v) + return _u +} + +// SetNillableTheme sets the "theme" field if the given value is not nil. +func (_u *UserPreferencesUpdate) SetNillableTheme(v *string) *UserPreferencesUpdate { + if v != nil { + _u.SetTheme(*v) + } + return _u +} + +// SetLanguage sets the "language" field. +func (_u *UserPreferencesUpdate) SetLanguage(v string) *UserPreferencesUpdate { + _u.mutation.SetLanguage(v) + return _u +} + +// SetNillableLanguage sets the "language" field if the given value is not nil. +func (_u *UserPreferencesUpdate) SetNillableLanguage(v *string) *UserPreferencesUpdate { + if v != nil { + _u.SetLanguage(*v) + } + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *UserPreferencesUpdate) SetUpdatedAt(v time.Time) *UserPreferencesUpdate { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_u *UserPreferencesUpdate) SetNillableUpdatedAt(v *time.Time) *UserPreferencesUpdate { + if v != nil { + _u.SetUpdatedAt(*v) + } + return _u +} + +// Mutation returns the UserPreferencesMutation object of the builder. +func (_u *UserPreferencesUpdate) Mutation() *UserPreferencesMutation { + return _u.mutation +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *UserPreferencesUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *UserPreferencesUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *UserPreferencesUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *UserPreferencesUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +func (_u *UserPreferencesUpdate) sqlSave(ctx context.Context) (_node int, err error) { + _spec := sqlgraph.NewUpdateSpec(userpreferences.Table, userpreferences.Columns, sqlgraph.NewFieldSpec(userpreferences.FieldID, field.TypeInt)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(userpreferences.FieldUserID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedUserID(); ok { + _spec.AddField(userpreferences.FieldUserID, field.TypeInt64, value) + } + if value, ok := _u.mutation.NotificationOrder(); ok { + _spec.SetField(userpreferences.FieldNotificationOrder, field.TypeBool, value) + } + if value, ok := _u.mutation.NotificationCommunity(); ok { + _spec.SetField(userpreferences.FieldNotificationCommunity, field.TypeBool, value) + } + if value, ok := _u.mutation.NotificationSystem(); ok { + _spec.SetField(userpreferences.FieldNotificationSystem, field.TypeBool, value) + } + if value, ok := _u.mutation.Theme(); ok { + _spec.SetField(userpreferences.FieldTheme, field.TypeString, value) + } + if value, ok := _u.mutation.Language(); ok { + _spec.SetField(userpreferences.FieldLanguage, field.TypeString, value) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(userpreferences.FieldUpdatedAt, field.TypeTime, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{userpreferences.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// UserPreferencesUpdateOne is the builder for updating a single UserPreferences entity. +type UserPreferencesUpdateOne struct { + config + fields []string + hooks []Hook + mutation *UserPreferencesMutation +} + +// SetUserID sets the "user_id" field. +func (_u *UserPreferencesUpdateOne) SetUserID(v int64) *UserPreferencesUpdateOne { + _u.mutation.ResetUserID() + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *UserPreferencesUpdateOne) SetNillableUserID(v *int64) *UserPreferencesUpdateOne { + if v != nil { + _u.SetUserID(*v) + } + return _u +} + +// AddUserID adds value to the "user_id" field. +func (_u *UserPreferencesUpdateOne) AddUserID(v int64) *UserPreferencesUpdateOne { + _u.mutation.AddUserID(v) + return _u +} + +// SetNotificationOrder sets the "notification_order" field. +func (_u *UserPreferencesUpdateOne) SetNotificationOrder(v bool) *UserPreferencesUpdateOne { + _u.mutation.SetNotificationOrder(v) + return _u +} + +// SetNillableNotificationOrder sets the "notification_order" field if the given value is not nil. +func (_u *UserPreferencesUpdateOne) SetNillableNotificationOrder(v *bool) *UserPreferencesUpdateOne { + if v != nil { + _u.SetNotificationOrder(*v) + } + return _u +} + +// SetNotificationCommunity sets the "notification_community" field. +func (_u *UserPreferencesUpdateOne) SetNotificationCommunity(v bool) *UserPreferencesUpdateOne { + _u.mutation.SetNotificationCommunity(v) + return _u +} + +// SetNillableNotificationCommunity sets the "notification_community" field if the given value is not nil. +func (_u *UserPreferencesUpdateOne) SetNillableNotificationCommunity(v *bool) *UserPreferencesUpdateOne { + if v != nil { + _u.SetNotificationCommunity(*v) + } + return _u +} + +// SetNotificationSystem sets the "notification_system" field. +func (_u *UserPreferencesUpdateOne) SetNotificationSystem(v bool) *UserPreferencesUpdateOne { + _u.mutation.SetNotificationSystem(v) + return _u +} + +// SetNillableNotificationSystem sets the "notification_system" field if the given value is not nil. +func (_u *UserPreferencesUpdateOne) SetNillableNotificationSystem(v *bool) *UserPreferencesUpdateOne { + if v != nil { + _u.SetNotificationSystem(*v) + } + return _u +} + +// SetTheme sets the "theme" field. +func (_u *UserPreferencesUpdateOne) SetTheme(v string) *UserPreferencesUpdateOne { + _u.mutation.SetTheme(v) + return _u +} + +// SetNillableTheme sets the "theme" field if the given value is not nil. +func (_u *UserPreferencesUpdateOne) SetNillableTheme(v *string) *UserPreferencesUpdateOne { + if v != nil { + _u.SetTheme(*v) + } + return _u +} + +// SetLanguage sets the "language" field. +func (_u *UserPreferencesUpdateOne) SetLanguage(v string) *UserPreferencesUpdateOne { + _u.mutation.SetLanguage(v) + return _u +} + +// SetNillableLanguage sets the "language" field if the given value is not nil. +func (_u *UserPreferencesUpdateOne) SetNillableLanguage(v *string) *UserPreferencesUpdateOne { + if v != nil { + _u.SetLanguage(*v) + } + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *UserPreferencesUpdateOne) SetUpdatedAt(v time.Time) *UserPreferencesUpdateOne { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_u *UserPreferencesUpdateOne) SetNillableUpdatedAt(v *time.Time) *UserPreferencesUpdateOne { + if v != nil { + _u.SetUpdatedAt(*v) + } + return _u +} + +// Mutation returns the UserPreferencesMutation object of the builder. +func (_u *UserPreferencesUpdateOne) Mutation() *UserPreferencesMutation { + return _u.mutation +} + +// Where appends a list predicates to the UserPreferencesUpdate builder. +func (_u *UserPreferencesUpdateOne) Where(ps ...predicate.UserPreferences) *UserPreferencesUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *UserPreferencesUpdateOne) Select(field string, fields ...string) *UserPreferencesUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated UserPreferences entity. +func (_u *UserPreferencesUpdateOne) Save(ctx context.Context) (*UserPreferences, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *UserPreferencesUpdateOne) SaveX(ctx context.Context) *UserPreferences { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *UserPreferencesUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *UserPreferencesUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +func (_u *UserPreferencesUpdateOne) sqlSave(ctx context.Context) (_node *UserPreferences, err error) { + _spec := sqlgraph.NewUpdateSpec(userpreferences.Table, userpreferences.Columns, sqlgraph.NewFieldSpec(userpreferences.FieldID, field.TypeInt)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`models: missing "UserPreferences.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, userpreferences.FieldID) + for _, f := range fields { + if !userpreferences.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("models: invalid field %q for query", f)} + } + if f != userpreferences.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(userpreferences.FieldUserID, field.TypeInt64, value) + } + if value, ok := _u.mutation.AddedUserID(); ok { + _spec.AddField(userpreferences.FieldUserID, field.TypeInt64, value) + } + if value, ok := _u.mutation.NotificationOrder(); ok { + _spec.SetField(userpreferences.FieldNotificationOrder, field.TypeBool, value) + } + if value, ok := _u.mutation.NotificationCommunity(); ok { + _spec.SetField(userpreferences.FieldNotificationCommunity, field.TypeBool, value) + } + if value, ok := _u.mutation.NotificationSystem(); ok { + _spec.SetField(userpreferences.FieldNotificationSystem, field.TypeBool, value) + } + if value, ok := _u.mutation.Theme(); ok { + _spec.SetField(userpreferences.FieldTheme, field.TypeString, value) + } + if value, ok := _u.mutation.Language(); ok { + _spec.SetField(userpreferences.FieldLanguage, field.TypeString, value) + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(userpreferences.FieldUpdatedAt, field.TypeTime, value) + } + _node = &UserPreferences{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{userpreferences.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/app/users/rpc/internal/models/users.go b/app/users/rpc/internal/models/users.go index 5b7a5ab..127472c 100644 --- a/app/users/rpc/internal/models/users.go +++ b/app/users/rpc/internal/models/users.go @@ -7,6 +7,7 @@ import ( "fmt" "juwan-backend/app/users/rpc/internal/models/schema" "juwan-backend/app/users/rpc/internal/models/users" + "juwan-backend/pkg/types" "strings" "time" @@ -14,7 +15,7 @@ import ( "entgo.io/ent/dialect/sql" ) -// Users is the models entity for the Users schema. +// Users is the model entity for the Users schema. type Users struct { config `json:"-"` // ID of the ent. @@ -35,8 +36,6 @@ type Users struct { Bio string `json:"bio,omitempty"` // CurrentRole holds the value of the "current_role" field. CurrentRole string `json:"current_role,omitempty"` - // VerifiedRoles holds the value of the "verified_roles" field. - VerifiedRoles []string `json:"verified_roles,omitempty"` // VerificationStatus holds the value of the "verificationStatus" field. VerificationStatus schema.VerificationStatusStruct `json:"verificationStatus,omitempty"` // IsAdmin holds the value of the "is_admin" field. @@ -46,8 +45,10 @@ type Users struct { // UpdatedAt holds the value of the "updated_at" field. UpdatedAt time.Time `json:"updated_at,omitempty"` // DeletedAt holds the value of the "deleted_at" field. - DeletedAt time.Time `json:"deleted_at,omitempty"` - selectValues sql.SelectValues + DeletedAt time.Time `json:"deleted_at,omitempty"` + // VerifiedRoles holds the value of the "verified_roles" field. + VerifiedRoles types.TextArray `json:"verified_roles,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. @@ -55,7 +56,7 @@ func (*Users) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case users.FieldVerifiedRoles, users.FieldVerificationStatus: + case users.FieldVerificationStatus: values[i] = new([]byte) case users.FieldIsAdmin: values[i] = new(sql.NullBool) @@ -65,6 +66,8 @@ func (*Users) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullString) case users.FieldCreatedAt, users.FieldUpdatedAt, users.FieldDeletedAt: values[i] = new(sql.NullTime) + case users.FieldVerifiedRoles: + values[i] = new(types.TextArray) default: values[i] = new(sql.UnknownType) } @@ -134,14 +137,6 @@ func (_m *Users) assignValues(columns []string, values []any) error { } else if value.Valid { _m.CurrentRole = value.String } - case users.FieldVerifiedRoles: - if value, ok := values[i].(*[]byte); !ok { - return fmt.Errorf("unexpected type %T for field verified_roles", values[i]) - } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &_m.VerifiedRoles); err != nil { - return fmt.Errorf("unmarshal field verified_roles: %w", err) - } - } case users.FieldVerificationStatus: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field verificationStatus", values[i]) @@ -174,6 +169,12 @@ func (_m *Users) assignValues(columns []string, values []any) error { } else if value.Valid { _m.DeletedAt = value.Time } + case users.FieldVerifiedRoles: + if value, ok := values[i].(*types.TextArray); !ok { + return fmt.Errorf("unexpected type %T for field verified_roles", values[i]) + } else if value != nil { + _m.VerifiedRoles = *value + } default: _m.selectValues.Set(columns[i], values[i]) } @@ -234,9 +235,6 @@ func (_m *Users) String() string { builder.WriteString("current_role=") builder.WriteString(_m.CurrentRole) builder.WriteString(", ") - builder.WriteString("verified_roles=") - builder.WriteString(fmt.Sprintf("%v", _m.VerifiedRoles)) - builder.WriteString(", ") builder.WriteString("verificationStatus=") builder.WriteString(fmt.Sprintf("%v", _m.VerificationStatus)) builder.WriteString(", ") @@ -251,6 +249,9 @@ func (_m *Users) String() string { builder.WriteString(", ") builder.WriteString("deleted_at=") builder.WriteString(_m.DeletedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("verified_roles=") + builder.WriteString(fmt.Sprintf("%v", _m.VerifiedRoles)) builder.WriteByte(')') return builder.String() } diff --git a/app/users/rpc/internal/models/users/users.go b/app/users/rpc/internal/models/users/users.go index c50559c..83ee310 100644 --- a/app/users/rpc/internal/models/users/users.go +++ b/app/users/rpc/internal/models/users/users.go @@ -29,8 +29,6 @@ const ( FieldBio = "bio" // FieldCurrentRole holds the string denoting the current_role field in the database. FieldCurrentRole = "current_role" - // FieldVerifiedRoles holds the string denoting the verified_roles field in the database. - FieldVerifiedRoles = "verified_roles" // FieldVerificationStatus holds the string denoting the verificationstatus field in the database. FieldVerificationStatus = "verification_status" // FieldIsAdmin holds the string denoting the is_admin field in the database. @@ -41,6 +39,8 @@ const ( FieldUpdatedAt = "updated_at" // FieldDeletedAt holds the string denoting the deleted_at field in the database. FieldDeletedAt = "deleted_at" + // FieldVerifiedRoles holds the string denoting the verified_roles field in the database. + FieldVerifiedRoles = "verified_roles" // Table holds the table name of the users in the database. Table = "users" ) @@ -56,12 +56,12 @@ var Columns = []string{ FieldAvatar, FieldBio, FieldCurrentRole, - FieldVerifiedRoles, FieldVerificationStatus, FieldIsAdmin, FieldCreatedAt, FieldUpdatedAt, FieldDeletedAt, + FieldVerifiedRoles, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -75,6 +75,16 @@ func ValidColumn(column string) bool { } var ( + // DefaultNickname holds the default value on creation for the "nickname" field. + DefaultNickname string + // DefaultAvatar holds the default value on creation for the "avatar" field. + DefaultAvatar string + // DefaultBio holds the default value on creation for the "bio" field. + DefaultBio string + // DefaultCurrentRole holds the default value on creation for the "current_role" field. + DefaultCurrentRole string + // CurrentRoleValidator is a validator for the "current_role" field. It is called by the builders before save. + CurrentRoleValidator func(string) error // DefaultIsAdmin holds the default value on creation for the "is_admin" field. DefaultIsAdmin bool // DefaultCreatedAt holds the default value on creation for the "created_at" field. @@ -150,3 +160,8 @@ func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldDeletedAt, opts...).ToFunc() } + +// ByVerifiedRoles orders the results by the verified_roles field. +func ByVerifiedRoles(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldVerifiedRoles, opts...).ToFunc() +} diff --git a/app/users/rpc/internal/models/users/where.go b/app/users/rpc/internal/models/users/where.go index 99325dc..5475729 100644 --- a/app/users/rpc/internal/models/users/where.go +++ b/app/users/rpc/internal/models/users/where.go @@ -4,6 +4,7 @@ package users import ( "juwan-backend/app/users/rpc/internal/models/predicate" + "juwan-backend/pkg/types" "time" "entgo.io/ent/dialect/sql" @@ -114,6 +115,11 @@ func DeletedAt(v time.Time) predicate.Users { return predicate.Users(sql.FieldEQ(FieldDeletedAt, v)) } +// VerifiedRoles applies equality check predicate on the "verified_roles" field. It's identical to VerifiedRolesEQ. +func VerifiedRoles(v types.TextArray) predicate.Users { + return predicate.Users(sql.FieldEQ(FieldVerifiedRoles, v)) +} + // UsernameEQ applies the EQ predicate on the "username" field. func UsernameEQ(v string) predicate.Users { return predicate.Users(sql.FieldEQ(FieldUsername, v)) @@ -634,6 +640,16 @@ func CurrentRoleContainsFold(v string) predicate.Users { return predicate.Users(sql.FieldContainsFold(FieldCurrentRole, v)) } +// VerificationStatusIsNil applies the IsNil predicate on the "verificationStatus" field. +func VerificationStatusIsNil() predicate.Users { + return predicate.Users(sql.FieldIsNull(FieldVerificationStatus)) +} + +// VerificationStatusNotNil applies the NotNil predicate on the "verificationStatus" field. +func VerificationStatusNotNil() predicate.Users { + return predicate.Users(sql.FieldNotNull(FieldVerificationStatus)) +} + // IsAdminEQ applies the EQ predicate on the "is_admin" field. func IsAdminEQ(v bool) predicate.Users { return predicate.Users(sql.FieldEQ(FieldIsAdmin, v)) @@ -764,6 +780,66 @@ func DeletedAtLTE(v time.Time) predicate.Users { return predicate.Users(sql.FieldLTE(FieldDeletedAt, v)) } +// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field. +func DeletedAtIsNil() predicate.Users { + return predicate.Users(sql.FieldIsNull(FieldDeletedAt)) +} + +// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field. +func DeletedAtNotNil() predicate.Users { + return predicate.Users(sql.FieldNotNull(FieldDeletedAt)) +} + +// VerifiedRolesEQ applies the EQ predicate on the "verified_roles" field. +func VerifiedRolesEQ(v types.TextArray) predicate.Users { + return predicate.Users(sql.FieldEQ(FieldVerifiedRoles, v)) +} + +// VerifiedRolesNEQ applies the NEQ predicate on the "verified_roles" field. +func VerifiedRolesNEQ(v types.TextArray) predicate.Users { + return predicate.Users(sql.FieldNEQ(FieldVerifiedRoles, v)) +} + +// VerifiedRolesIn applies the In predicate on the "verified_roles" field. +func VerifiedRolesIn(vs ...types.TextArray) predicate.Users { + return predicate.Users(sql.FieldIn(FieldVerifiedRoles, vs...)) +} + +// VerifiedRolesNotIn applies the NotIn predicate on the "verified_roles" field. +func VerifiedRolesNotIn(vs ...types.TextArray) predicate.Users { + return predicate.Users(sql.FieldNotIn(FieldVerifiedRoles, vs...)) +} + +// VerifiedRolesGT applies the GT predicate on the "verified_roles" field. +func VerifiedRolesGT(v types.TextArray) predicate.Users { + return predicate.Users(sql.FieldGT(FieldVerifiedRoles, v)) +} + +// VerifiedRolesGTE applies the GTE predicate on the "verified_roles" field. +func VerifiedRolesGTE(v types.TextArray) predicate.Users { + return predicate.Users(sql.FieldGTE(FieldVerifiedRoles, v)) +} + +// VerifiedRolesLT applies the LT predicate on the "verified_roles" field. +func VerifiedRolesLT(v types.TextArray) predicate.Users { + return predicate.Users(sql.FieldLT(FieldVerifiedRoles, v)) +} + +// VerifiedRolesLTE applies the LTE predicate on the "verified_roles" field. +func VerifiedRolesLTE(v types.TextArray) predicate.Users { + return predicate.Users(sql.FieldLTE(FieldVerifiedRoles, v)) +} + +// VerifiedRolesIsNil applies the IsNil predicate on the "verified_roles" field. +func VerifiedRolesIsNil() predicate.Users { + return predicate.Users(sql.FieldIsNull(FieldVerifiedRoles)) +} + +// VerifiedRolesNotNil applies the NotNil predicate on the "verified_roles" field. +func VerifiedRolesNotNil() predicate.Users { + return predicate.Users(sql.FieldNotNull(FieldVerifiedRoles)) +} + // And groups predicates with the AND operator between them. func And(predicates ...predicate.Users) predicate.Users { return predicate.Users(sql.AndPredicates(predicates...)) diff --git a/app/users/rpc/internal/models/users_create.go b/app/users/rpc/internal/models/users_create.go index 2d7b608..ecd0ccf 100644 --- a/app/users/rpc/internal/models/users_create.go +++ b/app/users/rpc/internal/models/users_create.go @@ -8,6 +8,7 @@ import ( "fmt" "juwan-backend/app/users/rpc/internal/models/schema" "juwan-backend/app/users/rpc/internal/models/users" + "juwan-backend/pkg/types" "time" "entgo.io/ent/dialect/sql/sqlgraph" @@ -51,27 +52,53 @@ func (_c *UsersCreate) SetNickname(v string) *UsersCreate { return _c } +// SetNillableNickname sets the "nickname" field if the given value is not nil. +func (_c *UsersCreate) SetNillableNickname(v *string) *UsersCreate { + if v != nil { + _c.SetNickname(*v) + } + return _c +} + // SetAvatar sets the "avatar" field. func (_c *UsersCreate) SetAvatar(v string) *UsersCreate { _c.mutation.SetAvatar(v) return _c } +// SetNillableAvatar sets the "avatar" field if the given value is not nil. +func (_c *UsersCreate) SetNillableAvatar(v *string) *UsersCreate { + if v != nil { + _c.SetAvatar(*v) + } + return _c +} + // SetBio sets the "bio" field. func (_c *UsersCreate) SetBio(v string) *UsersCreate { _c.mutation.SetBio(v) return _c } +// SetNillableBio sets the "bio" field if the given value is not nil. +func (_c *UsersCreate) SetNillableBio(v *string) *UsersCreate { + if v != nil { + _c.SetBio(*v) + } + return _c +} + // SetCurrentRole sets the "current_role" field. func (_c *UsersCreate) SetCurrentRole(v string) *UsersCreate { _c.mutation.SetCurrentRole(v) return _c } -// SetVerifiedRoles sets the "verified_roles" field. -func (_c *UsersCreate) SetVerifiedRoles(v []string) *UsersCreate { - _c.mutation.SetVerifiedRoles(v) +// SetNillableCurrentRole sets the "current_role" field if the given value is not nil. +func (_c *UsersCreate) SetNillableCurrentRole(v *string) *UsersCreate { + if v != nil { + _c.SetCurrentRole(*v) + } return _c } @@ -81,6 +108,14 @@ func (_c *UsersCreate) SetVerificationStatus(v schema.VerificationStatusStruct) return _c } +// SetNillableVerificationStatus sets the "verificationStatus" field if the given value is not nil. +func (_c *UsersCreate) SetNillableVerificationStatus(v *schema.VerificationStatusStruct) *UsersCreate { + if v != nil { + _c.SetVerificationStatus(*v) + } + return _c +} + // SetIsAdmin sets the "is_admin" field. func (_c *UsersCreate) SetIsAdmin(v bool) *UsersCreate { _c.mutation.SetIsAdmin(v) @@ -129,6 +164,28 @@ func (_c *UsersCreate) SetDeletedAt(v time.Time) *UsersCreate { return _c } +// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil. +func (_c *UsersCreate) SetNillableDeletedAt(v *time.Time) *UsersCreate { + if v != nil { + _c.SetDeletedAt(*v) + } + return _c +} + +// SetVerifiedRoles sets the "verified_roles" field. +func (_c *UsersCreate) SetVerifiedRoles(v types.TextArray) *UsersCreate { + _c.mutation.SetVerifiedRoles(v) + return _c +} + +// SetNillableVerifiedRoles sets the "verified_roles" field if the given value is not nil. +func (_c *UsersCreate) SetNillableVerifiedRoles(v *types.TextArray) *UsersCreate { + if v != nil { + _c.SetVerifiedRoles(*v) + } + return _c +} + // SetID sets the "id" field. func (_c *UsersCreate) SetID(v int64) *UsersCreate { _c.mutation.SetID(v) @@ -170,6 +227,22 @@ func (_c *UsersCreate) ExecX(ctx context.Context) { // defaults sets the default values of the builder before save. func (_c *UsersCreate) defaults() { + if _, ok := _c.mutation.Nickname(); !ok { + v := users.DefaultNickname + _c.mutation.SetNickname(v) + } + if _, ok := _c.mutation.Avatar(); !ok { + v := users.DefaultAvatar + _c.mutation.SetAvatar(v) + } + if _, ok := _c.mutation.Bio(); !ok { + v := users.DefaultBio + _c.mutation.SetBio(v) + } + if _, ok := _c.mutation.CurrentRole(); !ok { + v := users.DefaultCurrentRole + _c.mutation.SetCurrentRole(v) + } if _, ok := _c.mutation.IsAdmin(); !ok { v := users.DefaultIsAdmin _c.mutation.SetIsAdmin(v) @@ -210,11 +283,10 @@ func (_c *UsersCreate) check() error { if _, ok := _c.mutation.CurrentRole(); !ok { return &ValidationError{Name: "current_role", err: errors.New(`models: missing required field "Users.current_role"`)} } - if _, ok := _c.mutation.VerifiedRoles(); !ok { - return &ValidationError{Name: "verified_roles", err: errors.New(`models: missing required field "Users.verified_roles"`)} - } - if _, ok := _c.mutation.VerificationStatus(); !ok { - return &ValidationError{Name: "verificationStatus", err: errors.New(`models: missing required field "Users.verificationStatus"`)} + if v, ok := _c.mutation.CurrentRole(); ok { + if err := users.CurrentRoleValidator(v); err != nil { + return &ValidationError{Name: "current_role", err: fmt.Errorf(`models: validator failed for field "Users.current_role": %w`, err)} + } } if _, ok := _c.mutation.IsAdmin(); !ok { return &ValidationError{Name: "is_admin", err: errors.New(`models: missing required field "Users.is_admin"`)} @@ -225,9 +297,6 @@ func (_c *UsersCreate) check() error { if _, ok := _c.mutation.UpdatedAt(); !ok { return &ValidationError{Name: "updated_at", err: errors.New(`models: missing required field "Users.updated_at"`)} } - if _, ok := _c.mutation.DeletedAt(); !ok { - return &ValidationError{Name: "deleted_at", err: errors.New(`models: missing required field "Users.deleted_at"`)} - } return nil } @@ -292,10 +361,6 @@ func (_c *UsersCreate) createSpec() (*Users, *sqlgraph.CreateSpec) { _spec.SetField(users.FieldCurrentRole, field.TypeString, value) _node.CurrentRole = value } - if value, ok := _c.mutation.VerifiedRoles(); ok { - _spec.SetField(users.FieldVerifiedRoles, field.TypeJSON, value) - _node.VerifiedRoles = value - } if value, ok := _c.mutation.VerificationStatus(); ok { _spec.SetField(users.FieldVerificationStatus, field.TypeJSON, value) _node.VerificationStatus = value @@ -316,6 +381,10 @@ func (_c *UsersCreate) createSpec() (*Users, *sqlgraph.CreateSpec) { _spec.SetField(users.FieldDeletedAt, field.TypeTime, value) _node.DeletedAt = value } + if value, ok := _c.mutation.VerifiedRoles(); ok { + _spec.SetField(users.FieldVerifiedRoles, field.TypeOther, value) + _node.VerifiedRoles = value + } return _node, _spec } diff --git a/app/users/rpc/internal/models/users_update.go b/app/users/rpc/internal/models/users_update.go index 646118c..a529986 100644 --- a/app/users/rpc/internal/models/users_update.go +++ b/app/users/rpc/internal/models/users_update.go @@ -9,11 +9,11 @@ import ( "juwan-backend/app/users/rpc/internal/models/predicate" "juwan-backend/app/users/rpc/internal/models/schema" "juwan-backend/app/users/rpc/internal/models/users" + "juwan-backend/pkg/types" "time" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" ) @@ -142,18 +142,6 @@ func (_u *UsersUpdate) SetNillableCurrentRole(v *string) *UsersUpdate { return _u } -// SetVerifiedRoles sets the "verified_roles" field. -func (_u *UsersUpdate) SetVerifiedRoles(v []string) *UsersUpdate { - _u.mutation.SetVerifiedRoles(v) - return _u -} - -// AppendVerifiedRoles appends value to the "verified_roles" field. -func (_u *UsersUpdate) AppendVerifiedRoles(v []string) *UsersUpdate { - _u.mutation.AppendVerifiedRoles(v) - return _u -} - // SetVerificationStatus sets the "verificationStatus" field. func (_u *UsersUpdate) SetVerificationStatus(v schema.VerificationStatusStruct) *UsersUpdate { _u.mutation.SetVerificationStatus(v) @@ -168,6 +156,12 @@ func (_u *UsersUpdate) SetNillableVerificationStatus(v *schema.VerificationStatu return _u } +// ClearVerificationStatus clears the value of the "verificationStatus" field. +func (_u *UsersUpdate) ClearVerificationStatus() *UsersUpdate { + _u.mutation.ClearVerificationStatus() + return _u +} + // SetIsAdmin sets the "is_admin" field. func (_u *UsersUpdate) SetIsAdmin(v bool) *UsersUpdate { _u.mutation.SetIsAdmin(v) @@ -224,6 +218,32 @@ func (_u *UsersUpdate) SetNillableDeletedAt(v *time.Time) *UsersUpdate { return _u } +// ClearDeletedAt clears the value of the "deleted_at" field. +func (_u *UsersUpdate) ClearDeletedAt() *UsersUpdate { + _u.mutation.ClearDeletedAt() + return _u +} + +// SetVerifiedRoles sets the "verified_roles" field. +func (_u *UsersUpdate) SetVerifiedRoles(v types.TextArray) *UsersUpdate { + _u.mutation.SetVerifiedRoles(v) + return _u +} + +// SetNillableVerifiedRoles sets the "verified_roles" field if the given value is not nil. +func (_u *UsersUpdate) SetNillableVerifiedRoles(v *types.TextArray) *UsersUpdate { + if v != nil { + _u.SetVerifiedRoles(*v) + } + return _u +} + +// ClearVerifiedRoles clears the value of the "verified_roles" field. +func (_u *UsersUpdate) ClearVerifiedRoles() *UsersUpdate { + _u.mutation.ClearVerifiedRoles() + return _u +} + // Mutation returns the UsersMutation object of the builder. func (_u *UsersUpdate) Mutation() *UsersMutation { return _u.mutation @@ -256,7 +276,20 @@ func (_u *UsersUpdate) ExecX(ctx context.Context) { } } +// check runs all checks and user-defined validators on the builder. +func (_u *UsersUpdate) check() error { + if v, ok := _u.mutation.CurrentRole(); ok { + if err := users.CurrentRoleValidator(v); err != nil { + return &ValidationError{Name: "current_role", err: fmt.Errorf(`models: validator failed for field "Users.current_role": %w`, err)} + } + } + return nil +} + func (_u *UsersUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } _spec := sqlgraph.NewUpdateSpec(users.Table, users.Columns, sqlgraph.NewFieldSpec(users.FieldID, field.TypeInt64)) if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { @@ -289,17 +322,12 @@ func (_u *UsersUpdate) sqlSave(ctx context.Context) (_node int, err error) { if value, ok := _u.mutation.CurrentRole(); ok { _spec.SetField(users.FieldCurrentRole, field.TypeString, value) } - if value, ok := _u.mutation.VerifiedRoles(); ok { - _spec.SetField(users.FieldVerifiedRoles, field.TypeJSON, value) - } - if value, ok := _u.mutation.AppendedVerifiedRoles(); ok { - _spec.AddModifier(func(u *sql.UpdateBuilder) { - sqljson.Append(u, users.FieldVerifiedRoles, value) - }) - } if value, ok := _u.mutation.VerificationStatus(); ok { _spec.SetField(users.FieldVerificationStatus, field.TypeJSON, value) } + if _u.mutation.VerificationStatusCleared() { + _spec.ClearField(users.FieldVerificationStatus, field.TypeJSON) + } if value, ok := _u.mutation.IsAdmin(); ok { _spec.SetField(users.FieldIsAdmin, field.TypeBool, value) } @@ -312,6 +340,15 @@ func (_u *UsersUpdate) sqlSave(ctx context.Context) (_node int, err error) { if value, ok := _u.mutation.DeletedAt(); ok { _spec.SetField(users.FieldDeletedAt, field.TypeTime, value) } + if _u.mutation.DeletedAtCleared() { + _spec.ClearField(users.FieldDeletedAt, field.TypeTime) + } + if value, ok := _u.mutation.VerifiedRoles(); ok { + _spec.SetField(users.FieldVerifiedRoles, field.TypeOther, value) + } + if _u.mutation.VerifiedRolesCleared() { + _spec.ClearField(users.FieldVerifiedRoles, field.TypeOther) + } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{users.Label} @@ -444,18 +481,6 @@ func (_u *UsersUpdateOne) SetNillableCurrentRole(v *string) *UsersUpdateOne { return _u } -// SetVerifiedRoles sets the "verified_roles" field. -func (_u *UsersUpdateOne) SetVerifiedRoles(v []string) *UsersUpdateOne { - _u.mutation.SetVerifiedRoles(v) - return _u -} - -// AppendVerifiedRoles appends value to the "verified_roles" field. -func (_u *UsersUpdateOne) AppendVerifiedRoles(v []string) *UsersUpdateOne { - _u.mutation.AppendVerifiedRoles(v) - return _u -} - // SetVerificationStatus sets the "verificationStatus" field. func (_u *UsersUpdateOne) SetVerificationStatus(v schema.VerificationStatusStruct) *UsersUpdateOne { _u.mutation.SetVerificationStatus(v) @@ -470,6 +495,12 @@ func (_u *UsersUpdateOne) SetNillableVerificationStatus(v *schema.VerificationSt return _u } +// ClearVerificationStatus clears the value of the "verificationStatus" field. +func (_u *UsersUpdateOne) ClearVerificationStatus() *UsersUpdateOne { + _u.mutation.ClearVerificationStatus() + return _u +} + // SetIsAdmin sets the "is_admin" field. func (_u *UsersUpdateOne) SetIsAdmin(v bool) *UsersUpdateOne { _u.mutation.SetIsAdmin(v) @@ -526,6 +557,32 @@ func (_u *UsersUpdateOne) SetNillableDeletedAt(v *time.Time) *UsersUpdateOne { return _u } +// ClearDeletedAt clears the value of the "deleted_at" field. +func (_u *UsersUpdateOne) ClearDeletedAt() *UsersUpdateOne { + _u.mutation.ClearDeletedAt() + return _u +} + +// SetVerifiedRoles sets the "verified_roles" field. +func (_u *UsersUpdateOne) SetVerifiedRoles(v types.TextArray) *UsersUpdateOne { + _u.mutation.SetVerifiedRoles(v) + return _u +} + +// SetNillableVerifiedRoles sets the "verified_roles" field if the given value is not nil. +func (_u *UsersUpdateOne) SetNillableVerifiedRoles(v *types.TextArray) *UsersUpdateOne { + if v != nil { + _u.SetVerifiedRoles(*v) + } + return _u +} + +// ClearVerifiedRoles clears the value of the "verified_roles" field. +func (_u *UsersUpdateOne) ClearVerifiedRoles() *UsersUpdateOne { + _u.mutation.ClearVerifiedRoles() + return _u +} + // Mutation returns the UsersMutation object of the builder. func (_u *UsersUpdateOne) Mutation() *UsersMutation { return _u.mutation @@ -571,7 +628,20 @@ func (_u *UsersUpdateOne) ExecX(ctx context.Context) { } } +// check runs all checks and user-defined validators on the builder. +func (_u *UsersUpdateOne) check() error { + if v, ok := _u.mutation.CurrentRole(); ok { + if err := users.CurrentRoleValidator(v); err != nil { + return &ValidationError{Name: "current_role", err: fmt.Errorf(`models: validator failed for field "Users.current_role": %w`, err)} + } + } + return nil +} + func (_u *UsersUpdateOne) sqlSave(ctx context.Context) (_node *Users, err error) { + if err := _u.check(); err != nil { + return _node, err + } _spec := sqlgraph.NewUpdateSpec(users.Table, users.Columns, sqlgraph.NewFieldSpec(users.FieldID, field.TypeInt64)) id, ok := _u.mutation.ID() if !ok { @@ -621,17 +691,12 @@ func (_u *UsersUpdateOne) sqlSave(ctx context.Context) (_node *Users, err error) if value, ok := _u.mutation.CurrentRole(); ok { _spec.SetField(users.FieldCurrentRole, field.TypeString, value) } - if value, ok := _u.mutation.VerifiedRoles(); ok { - _spec.SetField(users.FieldVerifiedRoles, field.TypeJSON, value) - } - if value, ok := _u.mutation.AppendedVerifiedRoles(); ok { - _spec.AddModifier(func(u *sql.UpdateBuilder) { - sqljson.Append(u, users.FieldVerifiedRoles, value) - }) - } if value, ok := _u.mutation.VerificationStatus(); ok { _spec.SetField(users.FieldVerificationStatus, field.TypeJSON, value) } + if _u.mutation.VerificationStatusCleared() { + _spec.ClearField(users.FieldVerificationStatus, field.TypeJSON) + } if value, ok := _u.mutation.IsAdmin(); ok { _spec.SetField(users.FieldIsAdmin, field.TypeBool, value) } @@ -644,6 +709,15 @@ func (_u *UsersUpdateOne) sqlSave(ctx context.Context) (_node *Users, err error) if value, ok := _u.mutation.DeletedAt(); ok { _spec.SetField(users.FieldDeletedAt, field.TypeTime, value) } + if _u.mutation.DeletedAtCleared() { + _spec.ClearField(users.FieldDeletedAt, field.TypeTime) + } + if value, ok := _u.mutation.VerifiedRoles(); ok { + _spec.SetField(users.FieldVerifiedRoles, field.TypeOther, value) + } + if _u.mutation.VerifiedRolesCleared() { + _spec.ClearField(users.FieldVerifiedRoles, field.TypeOther) + } _node = &Users{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/app/users/rpc/internal/server/usercenterServer.go b/app/users/rpc/internal/server/usercenterServer.go index 1eafc35..6472954 100644 --- a/app/users/rpc/internal/server/usercenterServer.go +++ b/app/users/rpc/internal/server/usercenterServer.go @@ -44,16 +44,16 @@ func (s *UsercenterServer) GetUsersById(ctx context.Context, in *pb.GetUsersById return l.GetUsersById(in) } -func (s *UsercenterServer) GetUserByUsername(ctx context.Context, in *pb.GetUserByUsernameReq) (*pb.GetUserByUsernameResp, error) { - l := logic.NewGetUserByUsernameLogic(ctx, s.svcCtx) - return l.GetUserByUsername(in) -} - func (s *UsercenterServer) SearchUsers(ctx context.Context, in *pb.SearchUsersReq) (*pb.SearchUsersResp, error) { l := logic.NewSearchUsersLogic(ctx, s.svcCtx) return l.SearchUsers(in) } +func (s *UsercenterServer) GetUserByUsername(ctx context.Context, in *pb.GetUserByUsernameReq) (*pb.GetUserByUsernameResp, error) { + l := logic.NewGetUserByUsernameLogic(ctx, s.svcCtx) + return l.GetUserByUsername(in) +} + func (s *UsercenterServer) Login(ctx context.Context, in *pb.LoginReq) (*pb.LoginResp, error) { l := logic.NewLoginLogic(ctx, s.svcCtx) return l.Login(in) @@ -83,3 +83,60 @@ func (s *UsercenterServer) ResetPassword(ctx context.Context, in *pb.ResetPasswo l := logic.NewResetPasswordLogic(ctx, s.svcCtx) return l.ResetPassword(in) } + +func (s *UsercenterServer) SwitchRole(ctx context.Context, in *pb.SwitchRoleReq) (*pb.SwitchRoleResp, error) { + l := logic.NewSwitchRoleLogic(ctx, s.svcCtx) + return l.SwitchRole(in) +} + +// -----------------------userFollows----------------------- +func (s *UsercenterServer) AddUserFollows(ctx context.Context, in *pb.AddUserFollowsReq) (*pb.AddUserFollowsResp, error) { + l := logic.NewAddUserFollowsLogic(ctx, s.svcCtx) + return l.AddUserFollows(in) +} + +func (s *UsercenterServer) UpdateUserFollows(ctx context.Context, in *pb.UpdateUserFollowsReq) (*pb.UpdateUserFollowsResp, error) { + l := logic.NewUpdateUserFollowsLogic(ctx, s.svcCtx) + return l.UpdateUserFollows(in) +} + +func (s *UsercenterServer) DelUserFollows(ctx context.Context, in *pb.DelUserFollowsReq) (*pb.DelUserFollowsResp, error) { + l := logic.NewDelUserFollowsLogic(ctx, s.svcCtx) + return l.DelUserFollows(in) +} + +func (s *UsercenterServer) GetUserFollowsById(ctx context.Context, in *pb.GetUserFollowsByIdReq) (*pb.GetUserFollowsByIdResp, error) { + l := logic.NewGetUserFollowsByIdLogic(ctx, s.svcCtx) + return l.GetUserFollowsById(in) +} + +func (s *UsercenterServer) SearchUserFollows(ctx context.Context, in *pb.SearchUserFollowsReq) (*pb.SearchUserFollowsResp, error) { + l := logic.NewSearchUserFollowsLogic(ctx, s.svcCtx) + return l.SearchUserFollows(in) +} + +// -----------------------userPreferences----------------------- +func (s *UsercenterServer) AddUserPreferences(ctx context.Context, in *pb.AddUserPreferencesReq) (*pb.AddUserPreferencesResp, error) { + l := logic.NewAddUserPreferencesLogic(ctx, s.svcCtx) + return l.AddUserPreferences(in) +} + +func (s *UsercenterServer) UpdateUserPreferences(ctx context.Context, in *pb.UpdateUserPreferencesReq) (*pb.UpdateUserPreferencesResp, error) { + l := logic.NewUpdateUserPreferencesLogic(ctx, s.svcCtx) + return l.UpdateUserPreferences(in) +} + +func (s *UsercenterServer) DelUserPreferences(ctx context.Context, in *pb.DelUserPreferencesReq) (*pb.DelUserPreferencesResp, error) { + l := logic.NewDelUserPreferencesLogic(ctx, s.svcCtx) + return l.DelUserPreferences(in) +} + +func (s *UsercenterServer) GetUserPreferencesById(ctx context.Context, in *pb.GetUserPreferencesByIdReq) (*pb.GetUserPreferencesByIdResp, error) { + l := logic.NewGetUserPreferencesByIdLogic(ctx, s.svcCtx) + return l.GetUserPreferencesById(in) +} + +func (s *UsercenterServer) SearchUserPreferences(ctx context.Context, in *pb.SearchUserPreferencesReq) (*pb.SearchUserPreferencesResp, error) { + l := logic.NewSearchUserPreferencesLogic(ctx, s.svcCtx) + return l.SearchUserPreferences(in) +} diff --git a/app/users/rpc/internal/svc/serviceContext.go b/app/users/rpc/internal/svc/serviceContext.go index ea6e8ca..72a5107 100644 --- a/app/users/rpc/internal/svc/serviceContext.go +++ b/app/users/rpc/internal/svc/serviceContext.go @@ -1,6 +1,7 @@ package svc import ( + stdsql "database/sql" "juwan-backend/app/snowflake/rpc/snowflake" "juwan-backend/app/users/rpc/internal/config" "juwan-backend/app/users/rpc/internal/models" @@ -11,30 +12,34 @@ import ( "time" "ariga.io/entcache" + "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" + _ "github.com/jackc/pgx/v5/stdlib" "github.com/redis/go-redis/v9" "github.com/zeromicro/go-zero/core/logx" ) type ServiceContext struct { Config config.Config - UsersModelRW *models.UsersClient - UsersModelRO *models.UsersClient + UsersModelRW *models.Client + UsersModelRO *models.Client RedisCluster *redis.ClusterClient Snowflake snowflake.SnowflakeServiceClient JwtManager *utils.JwtManager } func NewServiceContext(c config.Config) *ServiceContext { + rawRW, err := stdsql.Open("pgx", c.DB.Master) + if err != nil { + panic(err) + } + rawRO, err := stdsql.Open("pgx", c.DB.Slave) + if err != nil { + panic(err) + } + RWConn := sql.OpenDB(dialect.Postgres, rawRW) + ROConn := sql.OpenDB(dialect.Postgres, rawRO) - RWConn, err := sql.Open("pgx", c.DB.Master) - if err != nil { - panic(err) - } - ROConn, err := sql.Open("pgx", c.DB.Slave) - if err != nil { - panic(err) - } logx.Infof("success to connect to postgres~") // Initialize Redis Cluster client from CacheConf @@ -59,8 +64,8 @@ func NewServiceContext(c config.Config) *ServiceContext { RWDrv := entcache.NewDriver(RWConn, entcache.TTL(time.Second*30), entcache.Levels(adapter.NewRedisCache(redisCluster))) return &ServiceContext{ Config: c, - UsersModelRW: models.NewClient(models.Driver(RWDrv)).Users, - UsersModelRO: models.NewClient(models.Driver(RODrv)).Users, + UsersModelRW: models.NewClient(models.Driver(RWDrv)), + UsersModelRO: models.NewClient(models.Driver(RODrv)), RedisCluster: redisCluster, JwtManager: jwtManager, Snowflake: snowflakex.NewClient(c.SnowflakeRpcConf), diff --git a/app/users/rpc/pb/users.pb.go b/app/users/rpc/pb/users.pb.go index eb133db..e951dbe 100644 --- a/app/users/rpc/pb/users.pb.go +++ b/app/users/rpc/pb/users.pb.go @@ -1691,6 +1691,1344 @@ func (*ResetPasswordResp) Descriptor() ([]byte, []int) { return file_users_proto_rawDescGZIP(), []int{24} } +type SwitchRoleReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` + NewRole string `protobuf:"bytes,2,opt,name=newRole,proto3" json:"newRole,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchRoleReq) Reset() { + *x = SwitchRoleReq{} + mi := &file_users_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchRoleReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchRoleReq) ProtoMessage() {} + +func (x *SwitchRoleReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[25] + 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 SwitchRoleReq.ProtoReflect.Descriptor instead. +func (*SwitchRoleReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{25} +} + +func (x *SwitchRoleReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *SwitchRoleReq) GetNewRole() string { + if x != nil { + return x.NewRole + } + return "" +} + +type SwitchRoleResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchRoleResp) Reset() { + *x = SwitchRoleResp{} + mi := &file_users_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchRoleResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchRoleResp) ProtoMessage() {} + +func (x *SwitchRoleResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[26] + 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 SwitchRoleResp.ProtoReflect.Descriptor instead. +func (*SwitchRoleResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{26} +} + +func (x *SwitchRoleResp) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +// --------------------------------userFollows-------------------------------- +type UserFollows struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //id + FollowerId int64 `protobuf:"varint,2,opt,name=followerId,proto3" json:"followerId,omitempty"` //followerId + FolloweeId int64 `protobuf:"varint,3,opt,name=followeeId,proto3" json:"followeeId,omitempty"` //followeeId + CreatedAt int64 `protobuf:"varint,4,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserFollows) Reset() { + *x = UserFollows{} + mi := &file_users_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserFollows) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserFollows) ProtoMessage() {} + +func (x *UserFollows) ProtoReflect() protoreflect.Message { + mi := &file_users_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 UserFollows.ProtoReflect.Descriptor instead. +func (*UserFollows) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{27} +} + +func (x *UserFollows) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UserFollows) GetFollowerId() int64 { + if x != nil { + return x.FollowerId + } + return 0 +} + +func (x *UserFollows) GetFolloweeId() int64 { + if x != nil { + return x.FolloweeId + } + return 0 +} + +func (x *UserFollows) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +type AddUserFollowsReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + FollowerId int64 `protobuf:"varint,1,opt,name=followerId,proto3" json:"followerId,omitempty"` //followerId + FolloweeId int64 `protobuf:"varint,2,opt,name=followeeId,proto3" json:"followeeId,omitempty"` //followeeId + CreatedAt int64 `protobuf:"varint,3,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddUserFollowsReq) Reset() { + *x = AddUserFollowsReq{} + mi := &file_users_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddUserFollowsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddUserFollowsReq) ProtoMessage() {} + +func (x *AddUserFollowsReq) ProtoReflect() protoreflect.Message { + mi := &file_users_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 AddUserFollowsReq.ProtoReflect.Descriptor instead. +func (*AddUserFollowsReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{28} +} + +func (x *AddUserFollowsReq) GetFollowerId() int64 { + if x != nil { + return x.FollowerId + } + return 0 +} + +func (x *AddUserFollowsReq) GetFolloweeId() int64 { + if x != nil { + return x.FolloweeId + } + return 0 +} + +func (x *AddUserFollowsReq) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +type AddUserFollowsResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddUserFollowsResp) Reset() { + *x = AddUserFollowsResp{} + mi := &file_users_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddUserFollowsResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddUserFollowsResp) ProtoMessage() {} + +func (x *AddUserFollowsResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[29] + 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 AddUserFollowsResp.ProtoReflect.Descriptor instead. +func (*AddUserFollowsResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{29} +} + +type UpdateUserFollowsReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //id + FollowerId int64 `protobuf:"varint,2,opt,name=followerId,proto3" json:"followerId,omitempty"` //followerId + FolloweeId int64 `protobuf:"varint,3,opt,name=followeeId,proto3" json:"followeeId,omitempty"` //followeeId + CreatedAt int64 `protobuf:"varint,4,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateUserFollowsReq) Reset() { + *x = UpdateUserFollowsReq{} + mi := &file_users_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateUserFollowsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserFollowsReq) ProtoMessage() {} + +func (x *UpdateUserFollowsReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[30] + 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 UpdateUserFollowsReq.ProtoReflect.Descriptor instead. +func (*UpdateUserFollowsReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{30} +} + +func (x *UpdateUserFollowsReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UpdateUserFollowsReq) GetFollowerId() int64 { + if x != nil { + return x.FollowerId + } + return 0 +} + +func (x *UpdateUserFollowsReq) GetFolloweeId() int64 { + if x != nil { + return x.FolloweeId + } + return 0 +} + +func (x *UpdateUserFollowsReq) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +type UpdateUserFollowsResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateUserFollowsResp) Reset() { + *x = UpdateUserFollowsResp{} + mi := &file_users_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateUserFollowsResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserFollowsResp) ProtoMessage() {} + +func (x *UpdateUserFollowsResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[31] + 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 UpdateUserFollowsResp.ProtoReflect.Descriptor instead. +func (*UpdateUserFollowsResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{31} +} + +type DelUserFollowsReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //id + UserId int64 `protobuf:"varint,2,opt,name=userId,proto3" json:"userId,omitempty"` // userId + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DelUserFollowsReq) Reset() { + *x = DelUserFollowsReq{} + mi := &file_users_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DelUserFollowsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DelUserFollowsReq) ProtoMessage() {} + +func (x *DelUserFollowsReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[32] + 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 DelUserFollowsReq.ProtoReflect.Descriptor instead. +func (*DelUserFollowsReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{32} +} + +func (x *DelUserFollowsReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *DelUserFollowsReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +type DelUserFollowsResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DelUserFollowsResp) Reset() { + *x = DelUserFollowsResp{} + mi := &file_users_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DelUserFollowsResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DelUserFollowsResp) ProtoMessage() {} + +func (x *DelUserFollowsResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[33] + 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 DelUserFollowsResp.ProtoReflect.Descriptor instead. +func (*DelUserFollowsResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{33} +} + +type GetUserFollowsByIdReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //id + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserFollowsByIdReq) Reset() { + *x = GetUserFollowsByIdReq{} + mi := &file_users_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserFollowsByIdReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserFollowsByIdReq) ProtoMessage() {} + +func (x *GetUserFollowsByIdReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[34] + 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 GetUserFollowsByIdReq.ProtoReflect.Descriptor instead. +func (*GetUserFollowsByIdReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{34} +} + +func (x *GetUserFollowsByIdReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type GetUserFollowsByIdResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserFollows *UserFollows `protobuf:"bytes,1,opt,name=userFollows,proto3" json:"userFollows,omitempty"` //userFollows + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserFollowsByIdResp) Reset() { + *x = GetUserFollowsByIdResp{} + mi := &file_users_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserFollowsByIdResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserFollowsByIdResp) ProtoMessage() {} + +func (x *GetUserFollowsByIdResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[35] + 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 GetUserFollowsByIdResp.ProtoReflect.Descriptor instead. +func (*GetUserFollowsByIdResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{35} +} + +func (x *GetUserFollowsByIdResp) GetUserFollows() *UserFollows { + if x != nil { + return x.UserFollows + } + return nil +} + +type SearchUserFollowsReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` //page + Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` //limit + Id int64 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` //id + FollowerId int64 `protobuf:"varint,4,opt,name=followerId,proto3" json:"followerId,omitempty"` //followerId + FolloweeId int64 `protobuf:"varint,5,opt,name=followeeId,proto3" json:"followeeId,omitempty"` //followeeId + CreatedAt int64 `protobuf:"varint,6,opt,name=createdAt,proto3" json:"createdAt,omitempty"` //createdAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchUserFollowsReq) Reset() { + *x = SearchUserFollowsReq{} + mi := &file_users_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchUserFollowsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchUserFollowsReq) ProtoMessage() {} + +func (x *SearchUserFollowsReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[36] + 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 SearchUserFollowsReq.ProtoReflect.Descriptor instead. +func (*SearchUserFollowsReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{36} +} + +func (x *SearchUserFollowsReq) GetPage() int64 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *SearchUserFollowsReq) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *SearchUserFollowsReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *SearchUserFollowsReq) GetFollowerId() int64 { + if x != nil { + return x.FollowerId + } + return 0 +} + +func (x *SearchUserFollowsReq) GetFolloweeId() int64 { + if x != nil { + return x.FolloweeId + } + return 0 +} + +func (x *SearchUserFollowsReq) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +type SearchUserFollowsResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserFollows []*UserFollows `protobuf:"bytes,1,rep,name=userFollows,proto3" json:"userFollows,omitempty"` //userFollows + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchUserFollowsResp) Reset() { + *x = SearchUserFollowsResp{} + mi := &file_users_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchUserFollowsResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchUserFollowsResp) ProtoMessage() {} + +func (x *SearchUserFollowsResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[37] + 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 SearchUserFollowsResp.ProtoReflect.Descriptor instead. +func (*SearchUserFollowsResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{37} +} + +func (x *SearchUserFollowsResp) GetUserFollows() []*UserFollows { + if x != nil { + return x.UserFollows + } + return nil +} + +// --------------------------------userPreferences-------------------------------- +type UserPreferences struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` //userId + NotificationOrder bool `protobuf:"varint,2,opt,name=notificationOrder,proto3" json:"notificationOrder,omitempty"` //notificationOrder + NotificationCommunity bool `protobuf:"varint,3,opt,name=notificationCommunity,proto3" json:"notificationCommunity,omitempty"` //notificationCommunity + NotificationSystem bool `protobuf:"varint,4,opt,name=notificationSystem,proto3" json:"notificationSystem,omitempty"` //notificationSystem + Theme string `protobuf:"bytes,5,opt,name=theme,proto3" json:"theme,omitempty"` //theme + Language string `protobuf:"bytes,6,opt,name=language,proto3" json:"language,omitempty"` //language + UpdatedAt int64 `protobuf:"varint,7,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserPreferences) Reset() { + *x = UserPreferences{} + mi := &file_users_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserPreferences) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserPreferences) ProtoMessage() {} + +func (x *UserPreferences) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[38] + 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 UserPreferences.ProtoReflect.Descriptor instead. +func (*UserPreferences) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{38} +} + +func (x *UserPreferences) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *UserPreferences) GetNotificationOrder() bool { + if x != nil { + return x.NotificationOrder + } + return false +} + +func (x *UserPreferences) GetNotificationCommunity() bool { + if x != nil { + return x.NotificationCommunity + } + return false +} + +func (x *UserPreferences) GetNotificationSystem() bool { + if x != nil { + return x.NotificationSystem + } + return false +} + +func (x *UserPreferences) GetTheme() string { + if x != nil { + return x.Theme + } + return "" +} + +func (x *UserPreferences) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +func (x *UserPreferences) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +type AddUserPreferencesReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` //userId + NotificationOrder bool `protobuf:"varint,2,opt,name=notificationOrder,proto3" json:"notificationOrder,omitempty"` //notificationOrder + NotificationCommunity bool `protobuf:"varint,3,opt,name=notificationCommunity,proto3" json:"notificationCommunity,omitempty"` //notificationCommunity + NotificationSystem bool `protobuf:"varint,4,opt,name=notificationSystem,proto3" json:"notificationSystem,omitempty"` //notificationSystem + Theme string `protobuf:"bytes,5,opt,name=theme,proto3" json:"theme,omitempty"` //theme + Language string `protobuf:"bytes,6,opt,name=language,proto3" json:"language,omitempty"` //language + UpdatedAt int64 `protobuf:"varint,7,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddUserPreferencesReq) Reset() { + *x = AddUserPreferencesReq{} + mi := &file_users_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddUserPreferencesReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddUserPreferencesReq) ProtoMessage() {} + +func (x *AddUserPreferencesReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[39] + 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 AddUserPreferencesReq.ProtoReflect.Descriptor instead. +func (*AddUserPreferencesReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{39} +} + +func (x *AddUserPreferencesReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *AddUserPreferencesReq) GetNotificationOrder() bool { + if x != nil { + return x.NotificationOrder + } + return false +} + +func (x *AddUserPreferencesReq) GetNotificationCommunity() bool { + if x != nil { + return x.NotificationCommunity + } + return false +} + +func (x *AddUserPreferencesReq) GetNotificationSystem() bool { + if x != nil { + return x.NotificationSystem + } + return false +} + +func (x *AddUserPreferencesReq) GetTheme() string { + if x != nil { + return x.Theme + } + return "" +} + +func (x *AddUserPreferencesReq) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +func (x *AddUserPreferencesReq) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +type AddUserPreferencesResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddUserPreferencesResp) Reset() { + *x = AddUserPreferencesResp{} + mi := &file_users_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddUserPreferencesResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddUserPreferencesResp) ProtoMessage() {} + +func (x *AddUserPreferencesResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[40] + 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 AddUserPreferencesResp.ProtoReflect.Descriptor instead. +func (*AddUserPreferencesResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{40} +} + +type UpdateUserPreferencesReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"` //userId + NotificationOrder bool `protobuf:"varint,2,opt,name=notificationOrder,proto3" json:"notificationOrder,omitempty"` //notificationOrder + NotificationCommunity bool `protobuf:"varint,3,opt,name=notificationCommunity,proto3" json:"notificationCommunity,omitempty"` //notificationCommunity + NotificationSystem bool `protobuf:"varint,4,opt,name=notificationSystem,proto3" json:"notificationSystem,omitempty"` //notificationSystem + Theme string `protobuf:"bytes,5,opt,name=theme,proto3" json:"theme,omitempty"` //theme + Language string `protobuf:"bytes,6,opt,name=language,proto3" json:"language,omitempty"` //language + UpdatedAt int64 `protobuf:"varint,7,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateUserPreferencesReq) Reset() { + *x = UpdateUserPreferencesReq{} + mi := &file_users_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateUserPreferencesReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserPreferencesReq) ProtoMessage() {} + +func (x *UpdateUserPreferencesReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[41] + 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 UpdateUserPreferencesReq.ProtoReflect.Descriptor instead. +func (*UpdateUserPreferencesReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{41} +} + +func (x *UpdateUserPreferencesReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *UpdateUserPreferencesReq) GetNotificationOrder() bool { + if x != nil { + return x.NotificationOrder + } + return false +} + +func (x *UpdateUserPreferencesReq) GetNotificationCommunity() bool { + if x != nil { + return x.NotificationCommunity + } + return false +} + +func (x *UpdateUserPreferencesReq) GetNotificationSystem() bool { + if x != nil { + return x.NotificationSystem + } + return false +} + +func (x *UpdateUserPreferencesReq) GetTheme() string { + if x != nil { + return x.Theme + } + return "" +} + +func (x *UpdateUserPreferencesReq) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +func (x *UpdateUserPreferencesReq) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +type UpdateUserPreferencesResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateUserPreferencesResp) Reset() { + *x = UpdateUserPreferencesResp{} + mi := &file_users_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateUserPreferencesResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserPreferencesResp) ProtoMessage() {} + +func (x *UpdateUserPreferencesResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[42] + 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 UpdateUserPreferencesResp.ProtoReflect.Descriptor instead. +func (*UpdateUserPreferencesResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{42} +} + +type DelUserPreferencesReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //id + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DelUserPreferencesReq) Reset() { + *x = DelUserPreferencesReq{} + mi := &file_users_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DelUserPreferencesReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DelUserPreferencesReq) ProtoMessage() {} + +func (x *DelUserPreferencesReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[43] + 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 DelUserPreferencesReq.ProtoReflect.Descriptor instead. +func (*DelUserPreferencesReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{43} +} + +func (x *DelUserPreferencesReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type DelUserPreferencesResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DelUserPreferencesResp) Reset() { + *x = DelUserPreferencesResp{} + mi := &file_users_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DelUserPreferencesResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DelUserPreferencesResp) ProtoMessage() {} + +func (x *DelUserPreferencesResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[44] + 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 DelUserPreferencesResp.ProtoReflect.Descriptor instead. +func (*DelUserPreferencesResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{44} +} + +type GetUserPreferencesByIdReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` //id + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserPreferencesByIdReq) Reset() { + *x = GetUserPreferencesByIdReq{} + mi := &file_users_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserPreferencesByIdReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserPreferencesByIdReq) ProtoMessage() {} + +func (x *GetUserPreferencesByIdReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[45] + 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 GetUserPreferencesByIdReq.ProtoReflect.Descriptor instead. +func (*GetUserPreferencesByIdReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{45} +} + +func (x *GetUserPreferencesByIdReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type GetUserPreferencesByIdResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserPreferences *UserPreferences `protobuf:"bytes,1,opt,name=userPreferences,proto3" json:"userPreferences,omitempty"` //userPreferences + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserPreferencesByIdResp) Reset() { + *x = GetUserPreferencesByIdResp{} + mi := &file_users_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserPreferencesByIdResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserPreferencesByIdResp) ProtoMessage() {} + +func (x *GetUserPreferencesByIdResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[46] + 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 GetUserPreferencesByIdResp.ProtoReflect.Descriptor instead. +func (*GetUserPreferencesByIdResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{46} +} + +func (x *GetUserPreferencesByIdResp) GetUserPreferences() *UserPreferences { + if x != nil { + return x.UserPreferences + } + return nil +} + +type SearchUserPreferencesReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` //page + Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` //limit + UserId int64 `protobuf:"varint,3,opt,name=userId,proto3" json:"userId,omitempty"` //userId + NotificationOrder bool `protobuf:"varint,4,opt,name=notificationOrder,proto3" json:"notificationOrder,omitempty"` //notificationOrder + NotificationCommunity bool `protobuf:"varint,5,opt,name=notificationCommunity,proto3" json:"notificationCommunity,omitempty"` //notificationCommunity + NotificationSystem bool `protobuf:"varint,6,opt,name=notificationSystem,proto3" json:"notificationSystem,omitempty"` //notificationSystem + Theme string `protobuf:"bytes,7,opt,name=theme,proto3" json:"theme,omitempty"` //theme + Language string `protobuf:"bytes,8,opt,name=language,proto3" json:"language,omitempty"` //language + UpdatedAt int64 `protobuf:"varint,9,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` //updatedAt + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchUserPreferencesReq) Reset() { + *x = SearchUserPreferencesReq{} + mi := &file_users_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchUserPreferencesReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchUserPreferencesReq) ProtoMessage() {} + +func (x *SearchUserPreferencesReq) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[47] + 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 SearchUserPreferencesReq.ProtoReflect.Descriptor instead. +func (*SearchUserPreferencesReq) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{47} +} + +func (x *SearchUserPreferencesReq) GetPage() int64 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *SearchUserPreferencesReq) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *SearchUserPreferencesReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *SearchUserPreferencesReq) GetNotificationOrder() bool { + if x != nil { + return x.NotificationOrder + } + return false +} + +func (x *SearchUserPreferencesReq) GetNotificationCommunity() bool { + if x != nil { + return x.NotificationCommunity + } + return false +} + +func (x *SearchUserPreferencesReq) GetNotificationSystem() bool { + if x != nil { + return x.NotificationSystem + } + return false +} + +func (x *SearchUserPreferencesReq) GetTheme() string { + if x != nil { + return x.Theme + } + return "" +} + +func (x *SearchUserPreferencesReq) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +func (x *SearchUserPreferencesReq) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +type SearchUserPreferencesResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserPreferences []*UserPreferences `protobuf:"bytes,1,rep,name=userPreferences,proto3" json:"userPreferences,omitempty"` //userPreferences + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchUserPreferencesResp) Reset() { + *x = SearchUserPreferencesResp{} + mi := &file_users_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchUserPreferencesResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchUserPreferencesResp) ProtoMessage() {} + +func (x *SearchUserPreferencesResp) ProtoReflect() protoreflect.Message { + mi := &file_users_proto_msgTypes[48] + 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 SearchUserPreferencesResp.ProtoReflect.Descriptor instead. +func (*SearchUserPreferencesResp) Descriptor() ([]byte, []int) { + return file_users_proto_rawDescGZIP(), []int{48} +} + +func (x *SearchUserPreferencesResp) GetUserPreferences() []*UserPreferences { + if x != nil { + return x.UserPreferences + } + return nil +} + var File_users_proto protoreflect.FileDescriptor const file_users_proto_rawDesc = "" + @@ -1860,21 +3198,132 @@ const file_users_proto_rawDesc = "" + "\x05email\x18\x02 \x01(\tR\x05email\x12\x1c\n" + "\trequestId\x18\x03 \x01(\tR\trequestId\x12\x14\n" + "\x05vcode\x18\x04 \x01(\tR\x05vcode\"\x13\n" + - "\x11ResetPasswordResp2\x9d\x05\n" + + "\x11ResetPasswordResp\"A\n" + + "\rSwitchRoleReq\x12\x16\n" + + "\x06userId\x18\x01 \x01(\x03R\x06userId\x12\x18\n" + + "\anewRole\x18\x02 \x01(\tR\anewRole\"*\n" + + "\x0eSwitchRoleResp\x12\x18\n" + + "\asuccess\x18\x01 \x01(\bR\asuccess\"{\n" + + "\vUserFollows\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1e\n" + + "\n" + + "followerId\x18\x02 \x01(\x03R\n" + + "followerId\x12\x1e\n" + + "\n" + + "followeeId\x18\x03 \x01(\x03R\n" + + "followeeId\x12\x1c\n" + + "\tcreatedAt\x18\x04 \x01(\x03R\tcreatedAt\"q\n" + + "\x11AddUserFollowsReq\x12\x1e\n" + + "\n" + + "followerId\x18\x01 \x01(\x03R\n" + + "followerId\x12\x1e\n" + + "\n" + + "followeeId\x18\x02 \x01(\x03R\n" + + "followeeId\x12\x1c\n" + + "\tcreatedAt\x18\x03 \x01(\x03R\tcreatedAt\"\x14\n" + + "\x12AddUserFollowsResp\"\x84\x01\n" + + "\x14UpdateUserFollowsReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1e\n" + + "\n" + + "followerId\x18\x02 \x01(\x03R\n" + + "followerId\x12\x1e\n" + + "\n" + + "followeeId\x18\x03 \x01(\x03R\n" + + "followeeId\x12\x1c\n" + + "\tcreatedAt\x18\x04 \x01(\x03R\tcreatedAt\"\x17\n" + + "\x15UpdateUserFollowsResp\";\n" + + "\x11DelUserFollowsReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x16\n" + + "\x06userId\x18\x02 \x01(\x03R\x06userId\"\x14\n" + + "\x12DelUserFollowsResp\"'\n" + + "\x15GetUserFollowsByIdReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"K\n" + + "\x16GetUserFollowsByIdResp\x121\n" + + "\vuserFollows\x18\x01 \x01(\v2\x0f.pb.UserFollowsR\vuserFollows\"\xae\x01\n" + + "\x14SearchUserFollowsReq\x12\x12\n" + + "\x04page\x18\x01 \x01(\x03R\x04page\x12\x14\n" + + "\x05limit\x18\x02 \x01(\x03R\x05limit\x12\x0e\n" + + "\x02id\x18\x03 \x01(\x03R\x02id\x12\x1e\n" + + "\n" + + "followerId\x18\x04 \x01(\x03R\n" + + "followerId\x12\x1e\n" + + "\n" + + "followeeId\x18\x05 \x01(\x03R\n" + + "followeeId\x12\x1c\n" + + "\tcreatedAt\x18\x06 \x01(\x03R\tcreatedAt\"J\n" + + "\x15SearchUserFollowsResp\x121\n" + + "\vuserFollows\x18\x01 \x03(\v2\x0f.pb.UserFollowsR\vuserFollows\"\x8d\x02\n" + + "\x0fUserPreferences\x12\x16\n" + + "\x06userId\x18\x01 \x01(\x03R\x06userId\x12,\n" + + "\x11notificationOrder\x18\x02 \x01(\bR\x11notificationOrder\x124\n" + + "\x15notificationCommunity\x18\x03 \x01(\bR\x15notificationCommunity\x12.\n" + + "\x12notificationSystem\x18\x04 \x01(\bR\x12notificationSystem\x12\x14\n" + + "\x05theme\x18\x05 \x01(\tR\x05theme\x12\x1a\n" + + "\blanguage\x18\x06 \x01(\tR\blanguage\x12\x1c\n" + + "\tupdatedAt\x18\a \x01(\x03R\tupdatedAt\"\x93\x02\n" + + "\x15AddUserPreferencesReq\x12\x16\n" + + "\x06userId\x18\x01 \x01(\x03R\x06userId\x12,\n" + + "\x11notificationOrder\x18\x02 \x01(\bR\x11notificationOrder\x124\n" + + "\x15notificationCommunity\x18\x03 \x01(\bR\x15notificationCommunity\x12.\n" + + "\x12notificationSystem\x18\x04 \x01(\bR\x12notificationSystem\x12\x14\n" + + "\x05theme\x18\x05 \x01(\tR\x05theme\x12\x1a\n" + + "\blanguage\x18\x06 \x01(\tR\blanguage\x12\x1c\n" + + "\tupdatedAt\x18\a \x01(\x03R\tupdatedAt\"\x18\n" + + "\x16AddUserPreferencesResp\"\x96\x02\n" + + "\x18UpdateUserPreferencesReq\x12\x16\n" + + "\x06userId\x18\x01 \x01(\x03R\x06userId\x12,\n" + + "\x11notificationOrder\x18\x02 \x01(\bR\x11notificationOrder\x124\n" + + "\x15notificationCommunity\x18\x03 \x01(\bR\x15notificationCommunity\x12.\n" + + "\x12notificationSystem\x18\x04 \x01(\bR\x12notificationSystem\x12\x14\n" + + "\x05theme\x18\x05 \x01(\tR\x05theme\x12\x1a\n" + + "\blanguage\x18\x06 \x01(\tR\blanguage\x12\x1c\n" + + "\tupdatedAt\x18\a \x01(\x03R\tupdatedAt\"\x1b\n" + + "\x19UpdateUserPreferencesResp\"'\n" + + "\x15DelUserPreferencesReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"\x18\n" + + "\x16DelUserPreferencesResp\"+\n" + + "\x19GetUserPreferencesByIdReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"[\n" + + "\x1aGetUserPreferencesByIdResp\x12=\n" + + "\x0fuserPreferences\x18\x01 \x01(\v2\x13.pb.UserPreferencesR\x0fuserPreferences\"\xc0\x02\n" + + "\x18SearchUserPreferencesReq\x12\x12\n" + + "\x04page\x18\x01 \x01(\x03R\x04page\x12\x14\n" + + "\x05limit\x18\x02 \x01(\x03R\x05limit\x12\x16\n" + + "\x06userId\x18\x03 \x01(\x03R\x06userId\x12,\n" + + "\x11notificationOrder\x18\x04 \x01(\bR\x11notificationOrder\x124\n" + + "\x15notificationCommunity\x18\x05 \x01(\bR\x15notificationCommunity\x12.\n" + + "\x12notificationSystem\x18\x06 \x01(\bR\x12notificationSystem\x12\x14\n" + + "\x05theme\x18\a \x01(\tR\x05theme\x12\x1a\n" + + "\blanguage\x18\b \x01(\tR\blanguage\x12\x1c\n" + + "\tupdatedAt\x18\t \x01(\x03R\tupdatedAt\"Z\n" + + "\x19SearchUserPreferencesResp\x12=\n" + + "\x0fuserPreferences\x18\x01 \x03(\v2\x13.pb.UserPreferencesR\x0fuserPreferences2\xd4\v\n" + "\n" + "usercenter\x12-\n" + "\bAddUsers\x12\x0f.pb.AddUsersReq\x1a\x10.pb.AddUsersResp\x126\n" + "\vUpdateUsers\x12\x12.pb.UpdateUsersReq\x1a\x13.pb.UpdateUsersResp\x12-\n" + "\bDelUsers\x12\x0f.pb.DelUsersReq\x1a\x10.pb.DelUsersResp\x129\n" + - "\fGetUsersById\x12\x13.pb.GetUsersByIdReq\x1a\x14.pb.GetUsersByIdResp\x12H\n" + - "\x11GetUserByUsername\x12\x18.pb.GetUserByUsernameReq\x1a\x19.pb.GetUserByUsernameResp\x126\n" + - "\vSearchUsers\x12\x12.pb.SearchUsersReq\x1a\x13.pb.SearchUsersResp\x12$\n" + + "\fGetUsersById\x12\x13.pb.GetUsersByIdReq\x1a\x14.pb.GetUsersByIdResp\x126\n" + + "\vSearchUsers\x12\x12.pb.SearchUsersReq\x1a\x13.pb.SearchUsersResp\x12H\n" + + "\x11GetUserByUsername\x12\x18.pb.GetUserByUsernameReq\x1a\x19.pb.GetUserByUsernameResp\x12$\n" + "\x05Login\x12\f.pb.LoginReq\x1a\r.pb.LoginResp\x12-\n" + "\bRegister\x12\x0f.pb.RegisterReq\x1a\x10.pb.RegisterResp\x12<\n" + "\rValidateToken\x12\x14.pb.ValidateTokenReq\x1a\x15.pb.ValidateTokenResp\x12B\n" + "\x0fCheckPermission\x12\x16.pb.CheckPermissionReq\x1a\x17.pb.CheckPermissionResp\x12'\n" + "\x06Logout\x12\r.pb.LogoutReq\x1a\x0e.pb.LogoutResp\x12<\n" + - "\rResetPassword\x12\x14.pb.ResetPasswordReq\x1a\x15.pb.ResetPasswordRespB\x06Z\x04./pbb\x06proto3" + "\rResetPassword\x12\x14.pb.ResetPasswordReq\x1a\x15.pb.ResetPasswordResp\x123\n" + + "\n" + + "SwitchRole\x12\x11.pb.SwitchRoleReq\x1a\x12.pb.SwitchRoleResp\x12?\n" + + "\x0eAddUserFollows\x12\x15.pb.AddUserFollowsReq\x1a\x16.pb.AddUserFollowsResp\x12H\n" + + "\x11UpdateUserFollows\x12\x18.pb.UpdateUserFollowsReq\x1a\x19.pb.UpdateUserFollowsResp\x12?\n" + + "\x0eDelUserFollows\x12\x15.pb.DelUserFollowsReq\x1a\x16.pb.DelUserFollowsResp\x12K\n" + + "\x12GetUserFollowsById\x12\x19.pb.GetUserFollowsByIdReq\x1a\x1a.pb.GetUserFollowsByIdResp\x12H\n" + + "\x11SearchUserFollows\x12\x18.pb.SearchUserFollowsReq\x1a\x19.pb.SearchUserFollowsResp\x12K\n" + + "\x12AddUserPreferences\x12\x19.pb.AddUserPreferencesReq\x1a\x1a.pb.AddUserPreferencesResp\x12T\n" + + "\x15UpdateUserPreferences\x12\x1c.pb.UpdateUserPreferencesReq\x1a\x1d.pb.UpdateUserPreferencesResp\x12K\n" + + "\x12DelUserPreferences\x12\x19.pb.DelUserPreferencesReq\x1a\x1a.pb.DelUserPreferencesResp\x12W\n" + + "\x16GetUserPreferencesById\x12\x1d.pb.GetUserPreferencesByIdReq\x1a\x1e.pb.GetUserPreferencesByIdResp\x12T\n" + + "\x15SearchUserPreferences\x12\x1c.pb.SearchUserPreferencesReq\x1a\x1d.pb.SearchUserPreferencesRespB\x06Z\x04./pbb\x06proto3" var ( file_users_proto_rawDescOnce sync.Once @@ -1888,67 +3337,117 @@ func file_users_proto_rawDescGZIP() []byte { return file_users_proto_rawDescData } -var file_users_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_users_proto_msgTypes = make([]protoimpl.MessageInfo, 49) var file_users_proto_goTypes = []any{ - (*Users)(nil), // 0: pb.Users - (*AddUsersReq)(nil), // 1: pb.AddUsersReq - (*AddUsersResp)(nil), // 2: pb.AddUsersResp - (*UpdateUsersReq)(nil), // 3: pb.UpdateUsersReq - (*UpdateUsersResp)(nil), // 4: pb.UpdateUsersResp - (*DelUsersReq)(nil), // 5: pb.DelUsersReq - (*DelUsersResp)(nil), // 6: pb.DelUsersResp - (*GetUsersByIdReq)(nil), // 7: pb.GetUsersByIdReq - (*GetUsersByIdResp)(nil), // 8: pb.GetUsersByIdResp - (*SearchUsersReq)(nil), // 9: pb.SearchUsersReq - (*SearchUsersResp)(nil), // 10: pb.SearchUsersResp - (*GetUserByUsernameReq)(nil), // 11: pb.GetUserByUsernameReq - (*GetUserByUsernameResp)(nil), // 12: pb.GetUserByUsernameResp - (*LoginReq)(nil), // 13: pb.LoginReq - (*LoginResp)(nil), // 14: pb.LoginResp - (*ValidateTokenReq)(nil), // 15: pb.ValidateTokenReq - (*ValidateTokenResp)(nil), // 16: pb.ValidateTokenResp - (*CheckPermissionReq)(nil), // 17: pb.CheckPermissionReq - (*CheckPermissionResp)(nil), // 18: pb.CheckPermissionResp - (*RegisterReq)(nil), // 19: pb.RegisterReq - (*RegisterResp)(nil), // 20: pb.RegisterResp - (*LogoutReq)(nil), // 21: pb.LogoutReq - (*LogoutResp)(nil), // 22: pb.LogoutResp - (*ResetPasswordReq)(nil), // 23: pb.ResetPasswordReq - (*ResetPasswordResp)(nil), // 24: pb.ResetPasswordResp + (*Users)(nil), // 0: pb.Users + (*AddUsersReq)(nil), // 1: pb.AddUsersReq + (*AddUsersResp)(nil), // 2: pb.AddUsersResp + (*UpdateUsersReq)(nil), // 3: pb.UpdateUsersReq + (*UpdateUsersResp)(nil), // 4: pb.UpdateUsersResp + (*DelUsersReq)(nil), // 5: pb.DelUsersReq + (*DelUsersResp)(nil), // 6: pb.DelUsersResp + (*GetUsersByIdReq)(nil), // 7: pb.GetUsersByIdReq + (*GetUsersByIdResp)(nil), // 8: pb.GetUsersByIdResp + (*SearchUsersReq)(nil), // 9: pb.SearchUsersReq + (*SearchUsersResp)(nil), // 10: pb.SearchUsersResp + (*GetUserByUsernameReq)(nil), // 11: pb.GetUserByUsernameReq + (*GetUserByUsernameResp)(nil), // 12: pb.GetUserByUsernameResp + (*LoginReq)(nil), // 13: pb.LoginReq + (*LoginResp)(nil), // 14: pb.LoginResp + (*ValidateTokenReq)(nil), // 15: pb.ValidateTokenReq + (*ValidateTokenResp)(nil), // 16: pb.ValidateTokenResp + (*CheckPermissionReq)(nil), // 17: pb.CheckPermissionReq + (*CheckPermissionResp)(nil), // 18: pb.CheckPermissionResp + (*RegisterReq)(nil), // 19: pb.RegisterReq + (*RegisterResp)(nil), // 20: pb.RegisterResp + (*LogoutReq)(nil), // 21: pb.LogoutReq + (*LogoutResp)(nil), // 22: pb.LogoutResp + (*ResetPasswordReq)(nil), // 23: pb.ResetPasswordReq + (*ResetPasswordResp)(nil), // 24: pb.ResetPasswordResp + (*SwitchRoleReq)(nil), // 25: pb.SwitchRoleReq + (*SwitchRoleResp)(nil), // 26: pb.SwitchRoleResp + (*UserFollows)(nil), // 27: pb.UserFollows + (*AddUserFollowsReq)(nil), // 28: pb.AddUserFollowsReq + (*AddUserFollowsResp)(nil), // 29: pb.AddUserFollowsResp + (*UpdateUserFollowsReq)(nil), // 30: pb.UpdateUserFollowsReq + (*UpdateUserFollowsResp)(nil), // 31: pb.UpdateUserFollowsResp + (*DelUserFollowsReq)(nil), // 32: pb.DelUserFollowsReq + (*DelUserFollowsResp)(nil), // 33: pb.DelUserFollowsResp + (*GetUserFollowsByIdReq)(nil), // 34: pb.GetUserFollowsByIdReq + (*GetUserFollowsByIdResp)(nil), // 35: pb.GetUserFollowsByIdResp + (*SearchUserFollowsReq)(nil), // 36: pb.SearchUserFollowsReq + (*SearchUserFollowsResp)(nil), // 37: pb.SearchUserFollowsResp + (*UserPreferences)(nil), // 38: pb.UserPreferences + (*AddUserPreferencesReq)(nil), // 39: pb.AddUserPreferencesReq + (*AddUserPreferencesResp)(nil), // 40: pb.AddUserPreferencesResp + (*UpdateUserPreferencesReq)(nil), // 41: pb.UpdateUserPreferencesReq + (*UpdateUserPreferencesResp)(nil), // 42: pb.UpdateUserPreferencesResp + (*DelUserPreferencesReq)(nil), // 43: pb.DelUserPreferencesReq + (*DelUserPreferencesResp)(nil), // 44: pb.DelUserPreferencesResp + (*GetUserPreferencesByIdReq)(nil), // 45: pb.GetUserPreferencesByIdReq + (*GetUserPreferencesByIdResp)(nil), // 46: pb.GetUserPreferencesByIdResp + (*SearchUserPreferencesReq)(nil), // 47: pb.SearchUserPreferencesReq + (*SearchUserPreferencesResp)(nil), // 48: pb.SearchUserPreferencesResp } var file_users_proto_depIdxs = []int32{ 0, // 0: pb.GetUsersByIdResp.users:type_name -> pb.Users 0, // 1: pb.SearchUsersResp.users:type_name -> pb.Users 0, // 2: pb.GetUserByUsernameResp.users:type_name -> pb.Users - 1, // 3: pb.usercenter.AddUsers:input_type -> pb.AddUsersReq - 3, // 4: pb.usercenter.UpdateUsers:input_type -> pb.UpdateUsersReq - 5, // 5: pb.usercenter.DelUsers:input_type -> pb.DelUsersReq - 7, // 6: pb.usercenter.GetUsersById:input_type -> pb.GetUsersByIdReq - 11, // 7: pb.usercenter.GetUserByUsername:input_type -> pb.GetUserByUsernameReq - 9, // 8: pb.usercenter.SearchUsers:input_type -> pb.SearchUsersReq - 13, // 9: pb.usercenter.Login:input_type -> pb.LoginReq - 19, // 10: pb.usercenter.Register:input_type -> pb.RegisterReq - 15, // 11: pb.usercenter.ValidateToken:input_type -> pb.ValidateTokenReq - 17, // 12: pb.usercenter.CheckPermission:input_type -> pb.CheckPermissionReq - 21, // 13: pb.usercenter.Logout:input_type -> pb.LogoutReq - 23, // 14: pb.usercenter.ResetPassword:input_type -> pb.ResetPasswordReq - 2, // 15: pb.usercenter.AddUsers:output_type -> pb.AddUsersResp - 4, // 16: pb.usercenter.UpdateUsers:output_type -> pb.UpdateUsersResp - 6, // 17: pb.usercenter.DelUsers:output_type -> pb.DelUsersResp - 8, // 18: pb.usercenter.GetUsersById:output_type -> pb.GetUsersByIdResp - 12, // 19: pb.usercenter.GetUserByUsername:output_type -> pb.GetUserByUsernameResp - 10, // 20: pb.usercenter.SearchUsers:output_type -> pb.SearchUsersResp - 14, // 21: pb.usercenter.Login:output_type -> pb.LoginResp - 20, // 22: pb.usercenter.Register:output_type -> pb.RegisterResp - 16, // 23: pb.usercenter.ValidateToken:output_type -> pb.ValidateTokenResp - 18, // 24: pb.usercenter.CheckPermission:output_type -> pb.CheckPermissionResp - 22, // 25: pb.usercenter.Logout:output_type -> pb.LogoutResp - 24, // 26: pb.usercenter.ResetPassword:output_type -> pb.ResetPasswordResp - 15, // [15:27] is the sub-list for method output_type - 3, // [3:15] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 27, // 3: pb.GetUserFollowsByIdResp.userFollows:type_name -> pb.UserFollows + 27, // 4: pb.SearchUserFollowsResp.userFollows:type_name -> pb.UserFollows + 38, // 5: pb.GetUserPreferencesByIdResp.userPreferences:type_name -> pb.UserPreferences + 38, // 6: pb.SearchUserPreferencesResp.userPreferences:type_name -> pb.UserPreferences + 1, // 7: pb.usercenter.AddUsers:input_type -> pb.AddUsersReq + 3, // 8: pb.usercenter.UpdateUsers:input_type -> pb.UpdateUsersReq + 5, // 9: pb.usercenter.DelUsers:input_type -> pb.DelUsersReq + 7, // 10: pb.usercenter.GetUsersById:input_type -> pb.GetUsersByIdReq + 9, // 11: pb.usercenter.SearchUsers:input_type -> pb.SearchUsersReq + 11, // 12: pb.usercenter.GetUserByUsername:input_type -> pb.GetUserByUsernameReq + 13, // 13: pb.usercenter.Login:input_type -> pb.LoginReq + 19, // 14: pb.usercenter.Register:input_type -> pb.RegisterReq + 15, // 15: pb.usercenter.ValidateToken:input_type -> pb.ValidateTokenReq + 17, // 16: pb.usercenter.CheckPermission:input_type -> pb.CheckPermissionReq + 21, // 17: pb.usercenter.Logout:input_type -> pb.LogoutReq + 23, // 18: pb.usercenter.ResetPassword:input_type -> pb.ResetPasswordReq + 25, // 19: pb.usercenter.SwitchRole:input_type -> pb.SwitchRoleReq + 28, // 20: pb.usercenter.AddUserFollows:input_type -> pb.AddUserFollowsReq + 30, // 21: pb.usercenter.UpdateUserFollows:input_type -> pb.UpdateUserFollowsReq + 32, // 22: pb.usercenter.DelUserFollows:input_type -> pb.DelUserFollowsReq + 34, // 23: pb.usercenter.GetUserFollowsById:input_type -> pb.GetUserFollowsByIdReq + 36, // 24: pb.usercenter.SearchUserFollows:input_type -> pb.SearchUserFollowsReq + 39, // 25: pb.usercenter.AddUserPreferences:input_type -> pb.AddUserPreferencesReq + 41, // 26: pb.usercenter.UpdateUserPreferences:input_type -> pb.UpdateUserPreferencesReq + 43, // 27: pb.usercenter.DelUserPreferences:input_type -> pb.DelUserPreferencesReq + 45, // 28: pb.usercenter.GetUserPreferencesById:input_type -> pb.GetUserPreferencesByIdReq + 47, // 29: pb.usercenter.SearchUserPreferences:input_type -> pb.SearchUserPreferencesReq + 2, // 30: pb.usercenter.AddUsers:output_type -> pb.AddUsersResp + 4, // 31: pb.usercenter.UpdateUsers:output_type -> pb.UpdateUsersResp + 6, // 32: pb.usercenter.DelUsers:output_type -> pb.DelUsersResp + 8, // 33: pb.usercenter.GetUsersById:output_type -> pb.GetUsersByIdResp + 10, // 34: pb.usercenter.SearchUsers:output_type -> pb.SearchUsersResp + 12, // 35: pb.usercenter.GetUserByUsername:output_type -> pb.GetUserByUsernameResp + 14, // 36: pb.usercenter.Login:output_type -> pb.LoginResp + 20, // 37: pb.usercenter.Register:output_type -> pb.RegisterResp + 16, // 38: pb.usercenter.ValidateToken:output_type -> pb.ValidateTokenResp + 18, // 39: pb.usercenter.CheckPermission:output_type -> pb.CheckPermissionResp + 22, // 40: pb.usercenter.Logout:output_type -> pb.LogoutResp + 24, // 41: pb.usercenter.ResetPassword:output_type -> pb.ResetPasswordResp + 26, // 42: pb.usercenter.SwitchRole:output_type -> pb.SwitchRoleResp + 29, // 43: pb.usercenter.AddUserFollows:output_type -> pb.AddUserFollowsResp + 31, // 44: pb.usercenter.UpdateUserFollows:output_type -> pb.UpdateUserFollowsResp + 33, // 45: pb.usercenter.DelUserFollows:output_type -> pb.DelUserFollowsResp + 35, // 46: pb.usercenter.GetUserFollowsById:output_type -> pb.GetUserFollowsByIdResp + 37, // 47: pb.usercenter.SearchUserFollows:output_type -> pb.SearchUserFollowsResp + 40, // 48: pb.usercenter.AddUserPreferences:output_type -> pb.AddUserPreferencesResp + 42, // 49: pb.usercenter.UpdateUserPreferences:output_type -> pb.UpdateUserPreferencesResp + 44, // 50: pb.usercenter.DelUserPreferences:output_type -> pb.DelUserPreferencesResp + 46, // 51: pb.usercenter.GetUserPreferencesById:output_type -> pb.GetUserPreferencesByIdResp + 48, // 52: pb.usercenter.SearchUserPreferences:output_type -> pb.SearchUserPreferencesResp + 30, // [30:53] is the sub-list for method output_type + 7, // [7:30] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_users_proto_init() } @@ -1964,7 +3463,7 @@ func file_users_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_users_proto_rawDesc), len(file_users_proto_rawDesc)), NumEnums: 0, - NumMessages: 25, + NumMessages: 49, NumExtensions: 0, NumServices: 1, }, diff --git a/app/users/rpc/pb/users_grpc.pb.go b/app/users/rpc/pb/users_grpc.pb.go index 4f7a28e..f09e093 100644 --- a/app/users/rpc/pb/users_grpc.pb.go +++ b/app/users/rpc/pb/users_grpc.pb.go @@ -19,18 +19,29 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Usercenter_AddUsers_FullMethodName = "/pb.usercenter/AddUsers" - Usercenter_UpdateUsers_FullMethodName = "/pb.usercenter/UpdateUsers" - Usercenter_DelUsers_FullMethodName = "/pb.usercenter/DelUsers" - Usercenter_GetUsersById_FullMethodName = "/pb.usercenter/GetUsersById" - Usercenter_GetUserByUsername_FullMethodName = "/pb.usercenter/GetUserByUsername" - Usercenter_SearchUsers_FullMethodName = "/pb.usercenter/SearchUsers" - Usercenter_Login_FullMethodName = "/pb.usercenter/Login" - Usercenter_Register_FullMethodName = "/pb.usercenter/Register" - Usercenter_ValidateToken_FullMethodName = "/pb.usercenter/ValidateToken" - Usercenter_CheckPermission_FullMethodName = "/pb.usercenter/CheckPermission" - Usercenter_Logout_FullMethodName = "/pb.usercenter/Logout" - Usercenter_ResetPassword_FullMethodName = "/pb.usercenter/ResetPassword" + Usercenter_AddUsers_FullMethodName = "/pb.usercenter/AddUsers" + Usercenter_UpdateUsers_FullMethodName = "/pb.usercenter/UpdateUsers" + Usercenter_DelUsers_FullMethodName = "/pb.usercenter/DelUsers" + Usercenter_GetUsersById_FullMethodName = "/pb.usercenter/GetUsersById" + Usercenter_SearchUsers_FullMethodName = "/pb.usercenter/SearchUsers" + Usercenter_GetUserByUsername_FullMethodName = "/pb.usercenter/GetUserByUsername" + Usercenter_Login_FullMethodName = "/pb.usercenter/Login" + Usercenter_Register_FullMethodName = "/pb.usercenter/Register" + Usercenter_ValidateToken_FullMethodName = "/pb.usercenter/ValidateToken" + Usercenter_CheckPermission_FullMethodName = "/pb.usercenter/CheckPermission" + Usercenter_Logout_FullMethodName = "/pb.usercenter/Logout" + Usercenter_ResetPassword_FullMethodName = "/pb.usercenter/ResetPassword" + Usercenter_SwitchRole_FullMethodName = "/pb.usercenter/SwitchRole" + Usercenter_AddUserFollows_FullMethodName = "/pb.usercenter/AddUserFollows" + Usercenter_UpdateUserFollows_FullMethodName = "/pb.usercenter/UpdateUserFollows" + Usercenter_DelUserFollows_FullMethodName = "/pb.usercenter/DelUserFollows" + Usercenter_GetUserFollowsById_FullMethodName = "/pb.usercenter/GetUserFollowsById" + Usercenter_SearchUserFollows_FullMethodName = "/pb.usercenter/SearchUserFollows" + Usercenter_AddUserPreferences_FullMethodName = "/pb.usercenter/AddUserPreferences" + Usercenter_UpdateUserPreferences_FullMethodName = "/pb.usercenter/UpdateUserPreferences" + Usercenter_DelUserPreferences_FullMethodName = "/pb.usercenter/DelUserPreferences" + Usercenter_GetUserPreferencesById_FullMethodName = "/pb.usercenter/GetUserPreferencesById" + Usercenter_SearchUserPreferences_FullMethodName = "/pb.usercenter/SearchUserPreferences" ) // UsercenterClient is the client API for Usercenter service. @@ -42,14 +53,27 @@ type UsercenterClient interface { UpdateUsers(ctx context.Context, in *UpdateUsersReq, opts ...grpc.CallOption) (*UpdateUsersResp, error) DelUsers(ctx context.Context, in *DelUsersReq, opts ...grpc.CallOption) (*DelUsersResp, error) GetUsersById(ctx context.Context, in *GetUsersByIdReq, opts ...grpc.CallOption) (*GetUsersByIdResp, error) - GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) SearchUsers(ctx context.Context, in *SearchUsersReq, opts ...grpc.CallOption) (*SearchUsersResp, error) + GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*RegisterResp, error) ValidateToken(ctx context.Context, in *ValidateTokenReq, opts ...grpc.CallOption) (*ValidateTokenResp, error) CheckPermission(ctx context.Context, in *CheckPermissionReq, opts ...grpc.CallOption) (*CheckPermissionResp, error) Logout(ctx context.Context, in *LogoutReq, opts ...grpc.CallOption) (*LogoutResp, error) ResetPassword(ctx context.Context, in *ResetPasswordReq, opts ...grpc.CallOption) (*ResetPasswordResp, error) + SwitchRole(ctx context.Context, in *SwitchRoleReq, opts ...grpc.CallOption) (*SwitchRoleResp, error) + // -----------------------userFollows----------------------- + AddUserFollows(ctx context.Context, in *AddUserFollowsReq, opts ...grpc.CallOption) (*AddUserFollowsResp, error) + UpdateUserFollows(ctx context.Context, in *UpdateUserFollowsReq, opts ...grpc.CallOption) (*UpdateUserFollowsResp, error) + DelUserFollows(ctx context.Context, in *DelUserFollowsReq, opts ...grpc.CallOption) (*DelUserFollowsResp, error) + GetUserFollowsById(ctx context.Context, in *GetUserFollowsByIdReq, opts ...grpc.CallOption) (*GetUserFollowsByIdResp, error) + SearchUserFollows(ctx context.Context, in *SearchUserFollowsReq, opts ...grpc.CallOption) (*SearchUserFollowsResp, error) + // -----------------------userPreferences----------------------- + AddUserPreferences(ctx context.Context, in *AddUserPreferencesReq, opts ...grpc.CallOption) (*AddUserPreferencesResp, error) + UpdateUserPreferences(ctx context.Context, in *UpdateUserPreferencesReq, opts ...grpc.CallOption) (*UpdateUserPreferencesResp, error) + DelUserPreferences(ctx context.Context, in *DelUserPreferencesReq, opts ...grpc.CallOption) (*DelUserPreferencesResp, error) + GetUserPreferencesById(ctx context.Context, in *GetUserPreferencesByIdReq, opts ...grpc.CallOption) (*GetUserPreferencesByIdResp, error) + SearchUserPreferences(ctx context.Context, in *SearchUserPreferencesReq, opts ...grpc.CallOption) (*SearchUserPreferencesResp, error) } type usercenterClient struct { @@ -100,20 +124,20 @@ func (c *usercenterClient) GetUsersById(ctx context.Context, in *GetUsersByIdReq return out, nil } -func (c *usercenterClient) GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) { +func (c *usercenterClient) SearchUsers(ctx context.Context, in *SearchUsersReq, opts ...grpc.CallOption) (*SearchUsersResp, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(GetUserByUsernameResp) - err := c.cc.Invoke(ctx, Usercenter_GetUserByUsername_FullMethodName, in, out, cOpts...) + out := new(SearchUsersResp) + err := c.cc.Invoke(ctx, Usercenter_SearchUsers_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *usercenterClient) SearchUsers(ctx context.Context, in *SearchUsersReq, opts ...grpc.CallOption) (*SearchUsersResp, error) { +func (c *usercenterClient) GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(SearchUsersResp) - err := c.cc.Invoke(ctx, Usercenter_SearchUsers_FullMethodName, in, out, cOpts...) + out := new(GetUserByUsernameResp) + err := c.cc.Invoke(ctx, Usercenter_GetUserByUsername_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -180,6 +204,116 @@ func (c *usercenterClient) ResetPassword(ctx context.Context, in *ResetPasswordR return out, nil } +func (c *usercenterClient) SwitchRole(ctx context.Context, in *SwitchRoleReq, opts ...grpc.CallOption) (*SwitchRoleResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SwitchRoleResp) + err := c.cc.Invoke(ctx, Usercenter_SwitchRole_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) AddUserFollows(ctx context.Context, in *AddUserFollowsReq, opts ...grpc.CallOption) (*AddUserFollowsResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AddUserFollowsResp) + err := c.cc.Invoke(ctx, Usercenter_AddUserFollows_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) UpdateUserFollows(ctx context.Context, in *UpdateUserFollowsReq, opts ...grpc.CallOption) (*UpdateUserFollowsResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateUserFollowsResp) + err := c.cc.Invoke(ctx, Usercenter_UpdateUserFollows_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) DelUserFollows(ctx context.Context, in *DelUserFollowsReq, opts ...grpc.CallOption) (*DelUserFollowsResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DelUserFollowsResp) + err := c.cc.Invoke(ctx, Usercenter_DelUserFollows_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) GetUserFollowsById(ctx context.Context, in *GetUserFollowsByIdReq, opts ...grpc.CallOption) (*GetUserFollowsByIdResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetUserFollowsByIdResp) + err := c.cc.Invoke(ctx, Usercenter_GetUserFollowsById_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) SearchUserFollows(ctx context.Context, in *SearchUserFollowsReq, opts ...grpc.CallOption) (*SearchUserFollowsResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SearchUserFollowsResp) + err := c.cc.Invoke(ctx, Usercenter_SearchUserFollows_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) AddUserPreferences(ctx context.Context, in *AddUserPreferencesReq, opts ...grpc.CallOption) (*AddUserPreferencesResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AddUserPreferencesResp) + err := c.cc.Invoke(ctx, Usercenter_AddUserPreferences_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) UpdateUserPreferences(ctx context.Context, in *UpdateUserPreferencesReq, opts ...grpc.CallOption) (*UpdateUserPreferencesResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateUserPreferencesResp) + err := c.cc.Invoke(ctx, Usercenter_UpdateUserPreferences_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) DelUserPreferences(ctx context.Context, in *DelUserPreferencesReq, opts ...grpc.CallOption) (*DelUserPreferencesResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DelUserPreferencesResp) + err := c.cc.Invoke(ctx, Usercenter_DelUserPreferences_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) GetUserPreferencesById(ctx context.Context, in *GetUserPreferencesByIdReq, opts ...grpc.CallOption) (*GetUserPreferencesByIdResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetUserPreferencesByIdResp) + err := c.cc.Invoke(ctx, Usercenter_GetUserPreferencesById_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *usercenterClient) SearchUserPreferences(ctx context.Context, in *SearchUserPreferencesReq, opts ...grpc.CallOption) (*SearchUserPreferencesResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SearchUserPreferencesResp) + err := c.cc.Invoke(ctx, Usercenter_SearchUserPreferences_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // UsercenterServer is the server API for Usercenter service. // All implementations must embed UnimplementedUsercenterServer // for forward compatibility. @@ -189,14 +323,27 @@ type UsercenterServer interface { UpdateUsers(context.Context, *UpdateUsersReq) (*UpdateUsersResp, error) DelUsers(context.Context, *DelUsersReq) (*DelUsersResp, error) GetUsersById(context.Context, *GetUsersByIdReq) (*GetUsersByIdResp, error) - GetUserByUsername(context.Context, *GetUserByUsernameReq) (*GetUserByUsernameResp, error) SearchUsers(context.Context, *SearchUsersReq) (*SearchUsersResp, error) + GetUserByUsername(context.Context, *GetUserByUsernameReq) (*GetUserByUsernameResp, error) Login(context.Context, *LoginReq) (*LoginResp, error) Register(context.Context, *RegisterReq) (*RegisterResp, error) ValidateToken(context.Context, *ValidateTokenReq) (*ValidateTokenResp, error) CheckPermission(context.Context, *CheckPermissionReq) (*CheckPermissionResp, error) Logout(context.Context, *LogoutReq) (*LogoutResp, error) ResetPassword(context.Context, *ResetPasswordReq) (*ResetPasswordResp, error) + SwitchRole(context.Context, *SwitchRoleReq) (*SwitchRoleResp, error) + // -----------------------userFollows----------------------- + AddUserFollows(context.Context, *AddUserFollowsReq) (*AddUserFollowsResp, error) + UpdateUserFollows(context.Context, *UpdateUserFollowsReq) (*UpdateUserFollowsResp, error) + DelUserFollows(context.Context, *DelUserFollowsReq) (*DelUserFollowsResp, error) + GetUserFollowsById(context.Context, *GetUserFollowsByIdReq) (*GetUserFollowsByIdResp, error) + SearchUserFollows(context.Context, *SearchUserFollowsReq) (*SearchUserFollowsResp, error) + // -----------------------userPreferences----------------------- + AddUserPreferences(context.Context, *AddUserPreferencesReq) (*AddUserPreferencesResp, error) + UpdateUserPreferences(context.Context, *UpdateUserPreferencesReq) (*UpdateUserPreferencesResp, error) + DelUserPreferences(context.Context, *DelUserPreferencesReq) (*DelUserPreferencesResp, error) + GetUserPreferencesById(context.Context, *GetUserPreferencesByIdReq) (*GetUserPreferencesByIdResp, error) + SearchUserPreferences(context.Context, *SearchUserPreferencesReq) (*SearchUserPreferencesResp, error) mustEmbedUnimplementedUsercenterServer() } @@ -219,12 +366,12 @@ func (UnimplementedUsercenterServer) DelUsers(context.Context, *DelUsersReq) (*D func (UnimplementedUsercenterServer) GetUsersById(context.Context, *GetUsersByIdReq) (*GetUsersByIdResp, error) { return nil, status.Error(codes.Unimplemented, "method GetUsersById not implemented") } -func (UnimplementedUsercenterServer) GetUserByUsername(context.Context, *GetUserByUsernameReq) (*GetUserByUsernameResp, error) { - return nil, status.Error(codes.Unimplemented, "method GetUserByUsername not implemented") -} func (UnimplementedUsercenterServer) SearchUsers(context.Context, *SearchUsersReq) (*SearchUsersResp, error) { return nil, status.Error(codes.Unimplemented, "method SearchUsers not implemented") } +func (UnimplementedUsercenterServer) GetUserByUsername(context.Context, *GetUserByUsernameReq) (*GetUserByUsernameResp, error) { + return nil, status.Error(codes.Unimplemented, "method GetUserByUsername not implemented") +} func (UnimplementedUsercenterServer) Login(context.Context, *LoginReq) (*LoginResp, error) { return nil, status.Error(codes.Unimplemented, "method Login not implemented") } @@ -243,6 +390,39 @@ func (UnimplementedUsercenterServer) Logout(context.Context, *LogoutReq) (*Logou func (UnimplementedUsercenterServer) ResetPassword(context.Context, *ResetPasswordReq) (*ResetPasswordResp, error) { return nil, status.Error(codes.Unimplemented, "method ResetPassword not implemented") } +func (UnimplementedUsercenterServer) SwitchRole(context.Context, *SwitchRoleReq) (*SwitchRoleResp, error) { + return nil, status.Error(codes.Unimplemented, "method SwitchRole not implemented") +} +func (UnimplementedUsercenterServer) AddUserFollows(context.Context, *AddUserFollowsReq) (*AddUserFollowsResp, error) { + return nil, status.Error(codes.Unimplemented, "method AddUserFollows not implemented") +} +func (UnimplementedUsercenterServer) UpdateUserFollows(context.Context, *UpdateUserFollowsReq) (*UpdateUserFollowsResp, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateUserFollows not implemented") +} +func (UnimplementedUsercenterServer) DelUserFollows(context.Context, *DelUserFollowsReq) (*DelUserFollowsResp, error) { + return nil, status.Error(codes.Unimplemented, "method DelUserFollows not implemented") +} +func (UnimplementedUsercenterServer) GetUserFollowsById(context.Context, *GetUserFollowsByIdReq) (*GetUserFollowsByIdResp, error) { + return nil, status.Error(codes.Unimplemented, "method GetUserFollowsById not implemented") +} +func (UnimplementedUsercenterServer) SearchUserFollows(context.Context, *SearchUserFollowsReq) (*SearchUserFollowsResp, error) { + return nil, status.Error(codes.Unimplemented, "method SearchUserFollows not implemented") +} +func (UnimplementedUsercenterServer) AddUserPreferences(context.Context, *AddUserPreferencesReq) (*AddUserPreferencesResp, error) { + return nil, status.Error(codes.Unimplemented, "method AddUserPreferences not implemented") +} +func (UnimplementedUsercenterServer) UpdateUserPreferences(context.Context, *UpdateUserPreferencesReq) (*UpdateUserPreferencesResp, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateUserPreferences not implemented") +} +func (UnimplementedUsercenterServer) DelUserPreferences(context.Context, *DelUserPreferencesReq) (*DelUserPreferencesResp, error) { + return nil, status.Error(codes.Unimplemented, "method DelUserPreferences not implemented") +} +func (UnimplementedUsercenterServer) GetUserPreferencesById(context.Context, *GetUserPreferencesByIdReq) (*GetUserPreferencesByIdResp, error) { + return nil, status.Error(codes.Unimplemented, "method GetUserPreferencesById not implemented") +} +func (UnimplementedUsercenterServer) SearchUserPreferences(context.Context, *SearchUserPreferencesReq) (*SearchUserPreferencesResp, error) { + return nil, status.Error(codes.Unimplemented, "method SearchUserPreferences not implemented") +} func (UnimplementedUsercenterServer) mustEmbedUnimplementedUsercenterServer() {} func (UnimplementedUsercenterServer) testEmbeddedByValue() {} @@ -336,24 +516,6 @@ func _Usercenter_GetUsersById_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } -func _Usercenter_GetUserByUsername_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetUserByUsernameReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(UsercenterServer).GetUserByUsername(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Usercenter_GetUserByUsername_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UsercenterServer).GetUserByUsername(ctx, req.(*GetUserByUsernameReq)) - } - return interceptor(ctx, in, info, handler) -} - func _Usercenter_SearchUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SearchUsersReq) if err := dec(in); err != nil { @@ -372,6 +534,24 @@ func _Usercenter_SearchUsers_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _Usercenter_GetUserByUsername_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserByUsernameReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).GetUserByUsername(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_GetUserByUsername_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).GetUserByUsername(ctx, req.(*GetUserByUsernameReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Usercenter_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(LoginReq) if err := dec(in); err != nil { @@ -480,6 +660,204 @@ func _Usercenter_ResetPassword_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Usercenter_SwitchRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SwitchRoleReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).SwitchRole(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_SwitchRole_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).SwitchRole(ctx, req.(*SwitchRoleReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_AddUserFollows_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddUserFollowsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).AddUserFollows(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_AddUserFollows_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).AddUserFollows(ctx, req.(*AddUserFollowsReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_UpdateUserFollows_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserFollowsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).UpdateUserFollows(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_UpdateUserFollows_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).UpdateUserFollows(ctx, req.(*UpdateUserFollowsReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_DelUserFollows_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DelUserFollowsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).DelUserFollows(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_DelUserFollows_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).DelUserFollows(ctx, req.(*DelUserFollowsReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_GetUserFollowsById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserFollowsByIdReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).GetUserFollowsById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_GetUserFollowsById_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).GetUserFollowsById(ctx, req.(*GetUserFollowsByIdReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_SearchUserFollows_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SearchUserFollowsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).SearchUserFollows(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_SearchUserFollows_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).SearchUserFollows(ctx, req.(*SearchUserFollowsReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_AddUserPreferences_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddUserPreferencesReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).AddUserPreferences(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_AddUserPreferences_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).AddUserPreferences(ctx, req.(*AddUserPreferencesReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_UpdateUserPreferences_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserPreferencesReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).UpdateUserPreferences(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_UpdateUserPreferences_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).UpdateUserPreferences(ctx, req.(*UpdateUserPreferencesReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_DelUserPreferences_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DelUserPreferencesReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).DelUserPreferences(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_DelUserPreferences_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).DelUserPreferences(ctx, req.(*DelUserPreferencesReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_GetUserPreferencesById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserPreferencesByIdReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).GetUserPreferencesById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_GetUserPreferencesById_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).GetUserPreferencesById(ctx, req.(*GetUserPreferencesByIdReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Usercenter_SearchUserPreferences_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SearchUserPreferencesReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UsercenterServer).SearchUserPreferences(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Usercenter_SearchUserPreferences_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UsercenterServer).SearchUserPreferences(ctx, req.(*SearchUserPreferencesReq)) + } + return interceptor(ctx, in, info, handler) +} + // Usercenter_ServiceDesc is the grpc.ServiceDesc for Usercenter service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -503,14 +881,14 @@ var Usercenter_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetUsersById", Handler: _Usercenter_GetUsersById_Handler, }, - { - MethodName: "GetUserByUsername", - Handler: _Usercenter_GetUserByUsername_Handler, - }, { MethodName: "SearchUsers", Handler: _Usercenter_SearchUsers_Handler, }, + { + MethodName: "GetUserByUsername", + Handler: _Usercenter_GetUserByUsername_Handler, + }, { MethodName: "Login", Handler: _Usercenter_Login_Handler, @@ -535,6 +913,50 @@ var Usercenter_ServiceDesc = grpc.ServiceDesc{ MethodName: "ResetPassword", Handler: _Usercenter_ResetPassword_Handler, }, + { + MethodName: "SwitchRole", + Handler: _Usercenter_SwitchRole_Handler, + }, + { + MethodName: "AddUserFollows", + Handler: _Usercenter_AddUserFollows_Handler, + }, + { + MethodName: "UpdateUserFollows", + Handler: _Usercenter_UpdateUserFollows_Handler, + }, + { + MethodName: "DelUserFollows", + Handler: _Usercenter_DelUserFollows_Handler, + }, + { + MethodName: "GetUserFollowsById", + Handler: _Usercenter_GetUserFollowsById_Handler, + }, + { + MethodName: "SearchUserFollows", + Handler: _Usercenter_SearchUserFollows_Handler, + }, + { + MethodName: "AddUserPreferences", + Handler: _Usercenter_AddUserPreferences_Handler, + }, + { + MethodName: "UpdateUserPreferences", + Handler: _Usercenter_UpdateUserPreferences_Handler, + }, + { + MethodName: "DelUserPreferences", + Handler: _Usercenter_DelUserPreferences_Handler, + }, + { + MethodName: "GetUserPreferencesById", + Handler: _Usercenter_GetUserPreferencesById_Handler, + }, + { + MethodName: "SearchUserPreferences", + Handler: _Usercenter_SearchUserPreferences_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "users.proto", diff --git a/app/users/rpc/usercenter/usercenter.go b/app/users/rpc/usercenter/usercenter.go index 3849234..925127a 100644 --- a/app/users/rpc/usercenter/usercenter.go +++ b/app/users/rpc/usercenter/usercenter.go @@ -14,31 +14,55 @@ import ( ) type ( - AddUsersReq = pb.AddUsersReq - AddUsersResp = pb.AddUsersResp - CheckPermissionReq = pb.CheckPermissionReq - CheckPermissionResp = pb.CheckPermissionResp - DelUsersReq = pb.DelUsersReq - DelUsersResp = pb.DelUsersResp - GetUserByUsernameReq = pb.GetUserByUsernameReq - GetUserByUsernameResp = pb.GetUserByUsernameResp - GetUsersByIdReq = pb.GetUsersByIdReq - GetUsersByIdResp = pb.GetUsersByIdResp - LoginReq = pb.LoginReq - LoginResp = pb.LoginResp - LogoutReq = pb.LogoutReq - LogoutResp = pb.LogoutResp - RegisterReq = pb.RegisterReq - RegisterResp = pb.RegisterResp - ResetPasswordReq = pb.ResetPasswordReq - ResetPasswordResp = pb.ResetPasswordResp - SearchUsersReq = pb.SearchUsersReq - SearchUsersResp = pb.SearchUsersResp - UpdateUsersReq = pb.UpdateUsersReq - UpdateUsersResp = pb.UpdateUsersResp - Users = pb.Users - ValidateTokenReq = pb.ValidateTokenReq - ValidateTokenResp = pb.ValidateTokenResp + AddUserFollowsReq = pb.AddUserFollowsReq + AddUserFollowsResp = pb.AddUserFollowsResp + AddUserPreferencesReq = pb.AddUserPreferencesReq + AddUserPreferencesResp = pb.AddUserPreferencesResp + AddUsersReq = pb.AddUsersReq + AddUsersResp = pb.AddUsersResp + CheckPermissionReq = pb.CheckPermissionReq + CheckPermissionResp = pb.CheckPermissionResp + DelUserFollowsReq = pb.DelUserFollowsReq + DelUserFollowsResp = pb.DelUserFollowsResp + DelUserPreferencesReq = pb.DelUserPreferencesReq + DelUserPreferencesResp = pb.DelUserPreferencesResp + DelUsersReq = pb.DelUsersReq + DelUsersResp = pb.DelUsersResp + GetUserByUsernameReq = pb.GetUserByUsernameReq + GetUserByUsernameResp = pb.GetUserByUsernameResp + GetUserFollowsByIdReq = pb.GetUserFollowsByIdReq + GetUserFollowsByIdResp = pb.GetUserFollowsByIdResp + GetUserPreferencesByIdReq = pb.GetUserPreferencesByIdReq + GetUserPreferencesByIdResp = pb.GetUserPreferencesByIdResp + GetUsersByIdReq = pb.GetUsersByIdReq + GetUsersByIdResp = pb.GetUsersByIdResp + LoginReq = pb.LoginReq + LoginResp = pb.LoginResp + LogoutReq = pb.LogoutReq + LogoutResp = pb.LogoutResp + RegisterReq = pb.RegisterReq + RegisterResp = pb.RegisterResp + ResetPasswordReq = pb.ResetPasswordReq + ResetPasswordResp = pb.ResetPasswordResp + SearchUserFollowsReq = pb.SearchUserFollowsReq + SearchUserFollowsResp = pb.SearchUserFollowsResp + SearchUserPreferencesReq = pb.SearchUserPreferencesReq + SearchUserPreferencesResp = pb.SearchUserPreferencesResp + SearchUsersReq = pb.SearchUsersReq + SearchUsersResp = pb.SearchUsersResp + SwitchRoleReq = pb.SwitchRoleReq + SwitchRoleResp = pb.SwitchRoleResp + UpdateUserFollowsReq = pb.UpdateUserFollowsReq + UpdateUserFollowsResp = pb.UpdateUserFollowsResp + UpdateUserPreferencesReq = pb.UpdateUserPreferencesReq + UpdateUserPreferencesResp = pb.UpdateUserPreferencesResp + UpdateUsersReq = pb.UpdateUsersReq + UpdateUsersResp = pb.UpdateUsersResp + UserFollows = pb.UserFollows + UserPreferences = pb.UserPreferences + Users = pb.Users + ValidateTokenReq = pb.ValidateTokenReq + ValidateTokenResp = pb.ValidateTokenResp Usercenter interface { // -----------------------users----------------------- @@ -46,14 +70,27 @@ type ( UpdateUsers(ctx context.Context, in *UpdateUsersReq, opts ...grpc.CallOption) (*UpdateUsersResp, error) DelUsers(ctx context.Context, in *DelUsersReq, opts ...grpc.CallOption) (*DelUsersResp, error) GetUsersById(ctx context.Context, in *GetUsersByIdReq, opts ...grpc.CallOption) (*GetUsersByIdResp, error) - GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) SearchUsers(ctx context.Context, in *SearchUsersReq, opts ...grpc.CallOption) (*SearchUsersResp, error) + GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*RegisterResp, error) ValidateToken(ctx context.Context, in *ValidateTokenReq, opts ...grpc.CallOption) (*ValidateTokenResp, error) CheckPermission(ctx context.Context, in *CheckPermissionReq, opts ...grpc.CallOption) (*CheckPermissionResp, error) Logout(ctx context.Context, in *LogoutReq, opts ...grpc.CallOption) (*LogoutResp, error) ResetPassword(ctx context.Context, in *ResetPasswordReq, opts ...grpc.CallOption) (*ResetPasswordResp, error) + SwitchRole(ctx context.Context, in *SwitchRoleReq, opts ...grpc.CallOption) (*SwitchRoleResp, error) + // -----------------------userFollows----------------------- + AddUserFollows(ctx context.Context, in *AddUserFollowsReq, opts ...grpc.CallOption) (*AddUserFollowsResp, error) + UpdateUserFollows(ctx context.Context, in *UpdateUserFollowsReq, opts ...grpc.CallOption) (*UpdateUserFollowsResp, error) + DelUserFollows(ctx context.Context, in *DelUserFollowsReq, opts ...grpc.CallOption) (*DelUserFollowsResp, error) + GetUserFollowsById(ctx context.Context, in *GetUserFollowsByIdReq, opts ...grpc.CallOption) (*GetUserFollowsByIdResp, error) + SearchUserFollows(ctx context.Context, in *SearchUserFollowsReq, opts ...grpc.CallOption) (*SearchUserFollowsResp, error) + // -----------------------userPreferences----------------------- + AddUserPreferences(ctx context.Context, in *AddUserPreferencesReq, opts ...grpc.CallOption) (*AddUserPreferencesResp, error) + UpdateUserPreferences(ctx context.Context, in *UpdateUserPreferencesReq, opts ...grpc.CallOption) (*UpdateUserPreferencesResp, error) + DelUserPreferences(ctx context.Context, in *DelUserPreferencesReq, opts ...grpc.CallOption) (*DelUserPreferencesResp, error) + GetUserPreferencesById(ctx context.Context, in *GetUserPreferencesByIdReq, opts ...grpc.CallOption) (*GetUserPreferencesByIdResp, error) + SearchUserPreferences(ctx context.Context, in *SearchUserPreferencesReq, opts ...grpc.CallOption) (*SearchUserPreferencesResp, error) } defaultUsercenter struct { @@ -88,16 +125,16 @@ func (m *defaultUsercenter) GetUsersById(ctx context.Context, in *GetUsersByIdRe return client.GetUsersById(ctx, in, opts...) } -func (m *defaultUsercenter) GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) { - client := pb.NewUsercenterClient(m.cli.Conn()) - return client.GetUserByUsername(ctx, in, opts...) -} - func (m *defaultUsercenter) SearchUsers(ctx context.Context, in *SearchUsersReq, opts ...grpc.CallOption) (*SearchUsersResp, error) { client := pb.NewUsercenterClient(m.cli.Conn()) return client.SearchUsers(ctx, in, opts...) } +func (m *defaultUsercenter) GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.GetUserByUsername(ctx, in, opts...) +} + func (m *defaultUsercenter) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error) { client := pb.NewUsercenterClient(m.cli.Conn()) return client.Login(ctx, in, opts...) @@ -127,3 +164,60 @@ func (m *defaultUsercenter) ResetPassword(ctx context.Context, in *ResetPassword client := pb.NewUsercenterClient(m.cli.Conn()) return client.ResetPassword(ctx, in, opts...) } + +func (m *defaultUsercenter) SwitchRole(ctx context.Context, in *SwitchRoleReq, opts ...grpc.CallOption) (*SwitchRoleResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.SwitchRole(ctx, in, opts...) +} + +// -----------------------userFollows----------------------- +func (m *defaultUsercenter) AddUserFollows(ctx context.Context, in *AddUserFollowsReq, opts ...grpc.CallOption) (*AddUserFollowsResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.AddUserFollows(ctx, in, opts...) +} + +func (m *defaultUsercenter) UpdateUserFollows(ctx context.Context, in *UpdateUserFollowsReq, opts ...grpc.CallOption) (*UpdateUserFollowsResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.UpdateUserFollows(ctx, in, opts...) +} + +func (m *defaultUsercenter) DelUserFollows(ctx context.Context, in *DelUserFollowsReq, opts ...grpc.CallOption) (*DelUserFollowsResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.DelUserFollows(ctx, in, opts...) +} + +func (m *defaultUsercenter) GetUserFollowsById(ctx context.Context, in *GetUserFollowsByIdReq, opts ...grpc.CallOption) (*GetUserFollowsByIdResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.GetUserFollowsById(ctx, in, opts...) +} + +func (m *defaultUsercenter) SearchUserFollows(ctx context.Context, in *SearchUserFollowsReq, opts ...grpc.CallOption) (*SearchUserFollowsResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.SearchUserFollows(ctx, in, opts...) +} + +// -----------------------userPreferences----------------------- +func (m *defaultUsercenter) AddUserPreferences(ctx context.Context, in *AddUserPreferencesReq, opts ...grpc.CallOption) (*AddUserPreferencesResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.AddUserPreferences(ctx, in, opts...) +} + +func (m *defaultUsercenter) UpdateUserPreferences(ctx context.Context, in *UpdateUserPreferencesReq, opts ...grpc.CallOption) (*UpdateUserPreferencesResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.UpdateUserPreferences(ctx, in, opts...) +} + +func (m *defaultUsercenter) DelUserPreferences(ctx context.Context, in *DelUserPreferencesReq, opts ...grpc.CallOption) (*DelUserPreferencesResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.DelUserPreferences(ctx, in, opts...) +} + +func (m *defaultUsercenter) GetUserPreferencesById(ctx context.Context, in *GetUserPreferencesByIdReq, opts ...grpc.CallOption) (*GetUserPreferencesByIdResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.GetUserPreferencesById(ctx, in, opts...) +} + +func (m *defaultUsercenter) SearchUserPreferences(ctx context.Context, in *SearchUserPreferencesReq, opts ...grpc.CallOption) (*SearchUserPreferencesResp, error) { + client := pb.NewUsercenterClient(m.cli.Conn()) + return client.SearchUserPreferences(ctx, in, opts...) +} diff --git a/app/wallet/api/etc/wallet-api.yaml b/app/wallet/api/etc/wallet-api.yaml index ca8a0e6..fb9fb3b 100644 --- a/app/wallet/api/etc/wallet-api.yaml +++ b/app/wallet/api/etc/wallet-api.yaml @@ -7,8 +7,16 @@ Prometheus: Port: 4001 Path: /metrics +# ===== PROC CONF ===== +#WalletRpcConf: +# Target: k8s://juwan/wallet-rpc:8080 + + + +# ===== DEV CONF ===== WalletRpcConf: - Target: k8s://juwan/wallet-rpc:8080 + Endpoints: + - wallet-rpc:8080 # k8s://juwan/:8080 diff --git a/app/wallet/api/wallet.go b/app/wallet/api/wallet.go index 2e32313..d23f4b9 100644 --- a/app/wallet/api/wallet.go +++ b/app/wallet/api/wallet.go @@ -6,6 +6,7 @@ package main import ( "flag" "fmt" + "juwan-backend/common/middlewares" "juwan-backend/app/wallet/api/internal/config" "juwan-backend/app/wallet/api/internal/handler" @@ -24,6 +25,8 @@ func main() { conf.MustLoad(*configFile, &c) server := rest.MustNewServer(c.RestConf) + server.Use(middlewares.NewRequestMiddleware().Handle) + server.Use(middlewares.NewHeaderExtractorMiddleware().Handle) defer server.Stop() ctx := svc.NewServiceContext(c) diff --git a/app/wallet/rpc/etc/pb.yaml b/app/wallet/rpc/etc/pb.yaml index 9e44d04..3d6bf89 100644 --- a/app/wallet/rpc/etc/pb.yaml +++ b/app/wallet/rpc/etc/pb.yaml @@ -15,24 +15,41 @@ Prometheus: # Target: k8s://juwan/.:8080 -SnowflakeRpcConf: - Target: k8s://juwan/snowflake-svc:8080 +# ===== PROC CONF ===== +#SnowflakeRpcConf: +# Target: k8s://juwan/snowflake-svc:8080 +# +# +#DB: +# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" +# +# +#CacheConf: +# - Host: "${REDIS_M_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# - Host: "${REDIS_S_HOST}" +# Type: node +# Pass: "${REDIS_PASSWORD}" +# User: "default" +# +#Log: +# Level: info +# ===== DEV CONFIG ===== +SnowflakeRpcConf: + Endpoints: + - snowflake:8080 DB: - Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable" - + Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" + Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable" CacheConf: - - Host: "${REDIS_M_HOST}" + - Host: "${REDIS_HOST}:${REDIS_PORT}" Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" - - Host: "${REDIS_S_HOST}" - Type: node - Pass: "${REDIS_PASSWORD}" - User: "default" Log: - Level: info + Level: debug \ No newline at end of file diff --git a/app/wallet/rpc/internal/logic/addWalletTransactionsLogic.go b/app/wallet/rpc/internal/logic/addWalletTransactionsLogic.go index 1bf5a5e..6437e9e 100644 --- a/app/wallet/rpc/internal/logic/addWalletTransactionsLogic.go +++ b/app/wallet/rpc/internal/logic/addWalletTransactionsLogic.go @@ -70,7 +70,6 @@ func (l *AddWalletTransactionsLogic) AddWalletTransactions(in *pb.AddWalletTrans SetDescription([]string{in.Description}). SetOrderID(in.OrderId). SetCreatedAt(createdAt). - SetSearchText(searchText). Save(l.ctx) if err != nil { _ = tx.Rollback() diff --git a/app/wallet/rpc/internal/logic/addWalletsLogic.go b/app/wallet/rpc/internal/logic/addWalletsLogic.go index 9870449..1bcd901 100644 --- a/app/wallet/rpc/internal/logic/addWalletsLogic.go +++ b/app/wallet/rpc/internal/logic/addWalletsLogic.go @@ -50,7 +50,7 @@ func (l *AddWalletsLogic) AddWallets(in *pb.AddWalletsReq) (*pb.AddWalletsResp, } _, err = tx.Wallet.Create(). - SetUserID(in.UserId). + SetID(in.UserId). SetBalance(balance). SetFrozenBalance(frozenBalance). SetVersion(1). diff --git a/app/wallet/rpc/internal/logic/getWalletsByIdLogic.go b/app/wallet/rpc/internal/logic/getWalletsByIdLogic.go index d8b238d..c539a78 100644 --- a/app/wallet/rpc/internal/logic/getWalletsByIdLogic.go +++ b/app/wallet/rpc/internal/logic/getWalletsByIdLogic.go @@ -26,10 +26,13 @@ func NewGetWalletsByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge func (l *GetWalletsByIdLogic) GetWalletsById(in *pb.GetWalletsByIdReq) (*pb.GetWalletsByIdResp, error) { item, err := l.svcCtx.WalletModelsRO.Wallet.Query(). - Where(wallet.UserIDEQ(in.Id)). + Where(wallet.IDEQ(in.Id)). First(l.ctx) if err != nil { if models.IsNotFound(err) { + if _, e := l.svcCtx.WalletModelsRO.Wallet.Create().SetID(in.Id).Save(l.ctx); e != nil { + return nil, e + } return &pb.GetWalletsByIdResp{}, nil } return nil, err @@ -42,7 +45,7 @@ func (l *GetWalletsByIdLogic) GetWalletsById(in *pb.GetWalletsByIdReq) (*pb.GetW return &pb.GetWalletsByIdResp{ Wallets: &pb.Wallets{ - UserId: item.UserID, + UserId: item.ID, Balance: item.Balance.String(), FrozenBalance: item.FrozenBalance.String(), UpdatedAt: updatedAt, diff --git a/app/wallet/rpc/internal/logic/updateWalletsLogic.go b/app/wallet/rpc/internal/logic/updateWalletsLogic.go index dace6b2..4006cda 100644 --- a/app/wallet/rpc/internal/logic/updateWalletsLogic.go +++ b/app/wallet/rpc/internal/logic/updateWalletsLogic.go @@ -39,9 +39,8 @@ func (l *UpdateWalletsLogic) UpdateWallets(in *pb.UpdateWalletsReq) (*pb.UpdateW } updater := tx.Wallet.Update(). - Where(wallet.UserIDEQ(in.UserId), wallet.VersionEQ(int(in.GetVersion()))). + Where(wallet.IDEQ(in.UserId), wallet.VersionEQ(int(in.GetVersion()))). AddVersion(1) - if in.Balance != nil { parsedBalance, perr := decimal.NewFromString(in.GetBalance()) if perr != nil { @@ -70,7 +69,7 @@ func (l *UpdateWalletsLogic) UpdateWallets(in *pb.UpdateWalletsReq) (*pb.UpdateW return nil, err } if affected == 0 { - exist, qerr := tx.Wallet.Query().Where(wallet.UserIDEQ(in.UserId)).Exist(l.ctx) + exist, qerr := tx.Wallet.Query().Where(wallet.IDEQ(in.UserId)).Exist(l.ctx) _ = tx.Rollback() if qerr != nil { return nil, qerr diff --git a/app/wallet/rpc/internal/models/client.go b/app/wallet/rpc/internal/models/client.go index 45dcfc3..1edefda 100644 --- a/app/wallet/rpc/internal/models/client.go +++ b/app/wallet/rpc/internal/models/client.go @@ -268,7 +268,7 @@ func (c *WalletClient) UpdateOne(_m *Wallet) *WalletUpdateOne { } // UpdateOneID returns an update builder for the given id. -func (c *WalletClient) UpdateOneID(id int) *WalletUpdateOne { +func (c *WalletClient) UpdateOneID(id int64) *WalletUpdateOne { mutation := newWalletMutation(c.config, OpUpdateOne, withWalletID(id)) return &WalletUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -285,7 +285,7 @@ func (c *WalletClient) DeleteOne(_m *Wallet) *WalletDeleteOne { } // DeleteOneID returns a builder for deleting the given entity by its id. -func (c *WalletClient) DeleteOneID(id int) *WalletDeleteOne { +func (c *WalletClient) DeleteOneID(id int64) *WalletDeleteOne { builder := c.Delete().Where(wallet.ID(id)) builder.mutation.id = &id builder.mutation.op = OpDeleteOne @@ -302,12 +302,12 @@ func (c *WalletClient) Query() *WalletQuery { } // Get returns a Wallet entity by its id. -func (c *WalletClient) Get(ctx context.Context, id int) (*Wallet, error) { +func (c *WalletClient) Get(ctx context.Context, id int64) (*Wallet, error) { return c.Query().Where(wallet.ID(id)).Only(ctx) } // GetX is like Get, but panics if an error occurs. -func (c *WalletClient) GetX(ctx context.Context, id int) *Wallet { +func (c *WalletClient) GetX(ctx context.Context, id int64) *Wallet { obj, err := c.Get(ctx, id) if err != nil { panic(err) diff --git a/app/wallet/rpc/internal/models/migrate/schema.go b/app/wallet/rpc/internal/models/migrate/schema.go index f781cac..75a5f9b 100644 --- a/app/wallet/rpc/internal/models/migrate/schema.go +++ b/app/wallet/rpc/internal/models/migrate/schema.go @@ -10,8 +10,7 @@ import ( var ( // WalletsColumns holds the columns for the "wallets" table. WalletsColumns = []*schema.Column{ - {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "user_id", Type: field.TypeInt64, Unique: true}, + {Name: "user_id", Type: field.TypeInt64, Increment: true}, {Name: "balance", Type: field.TypeOther, SchemaType: map[string]string{"postgres": "decimal(12,2)"}}, {Name: "frozen_balance", Type: field.TypeOther, SchemaType: map[string]string{"postgres": "decimal(12,2)"}}, {Name: "version", Type: field.TypeInt, Default: 1}, @@ -33,7 +32,6 @@ var ( {Name: "description", Type: field.TypeJSON}, {Name: "order_id", Type: field.TypeInt64, Unique: true}, {Name: "created_at", Type: field.TypeTime}, - {Name: "search_text", Type: field.TypeString}, } // WalletTransactionsTable holds the schema information for the "wallet_transactions" table. WalletTransactionsTable = &schema.Table{ diff --git a/app/wallet/rpc/internal/models/mutation.go b/app/wallet/rpc/internal/models/mutation.go index c271463..29778f6 100644 --- a/app/wallet/rpc/internal/models/mutation.go +++ b/app/wallet/rpc/internal/models/mutation.go @@ -35,9 +35,7 @@ type WalletMutation struct { config op Op typ string - id *int - user_id *int64 - adduser_id *int64 + id *int64 balance *decimal.Decimal frozen_balance *decimal.Decimal version *int @@ -69,7 +67,7 @@ func newWalletMutation(c config, op Op, opts ...walletOption) *WalletMutation { } // withWalletID sets the ID field of the mutation. -func withWalletID(id int) walletOption { +func withWalletID(id int64) walletOption { return func(m *WalletMutation) { var ( err error @@ -119,9 +117,15 @@ func (m WalletMutation) Tx() (*Tx, error) { return tx, nil } +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of Wallet entities. +func (m *WalletMutation) SetID(id int64) { + m.id = &id +} + // ID returns the ID value in the mutation. Note that the ID is only available // if it was provided to the builder or after it was returned from the database. -func (m *WalletMutation) ID() (id int, exists bool) { +func (m *WalletMutation) ID() (id int64, exists bool) { if m.id == nil { return } @@ -132,12 +136,12 @@ func (m *WalletMutation) ID() (id int, exists bool) { // That means, if the mutation is applied within a transaction with an isolation level such // as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated // or updated by the mutation. -func (m *WalletMutation) IDs(ctx context.Context) ([]int, error) { +func (m *WalletMutation) IDs(ctx context.Context) ([]int64, error) { switch { case m.op.Is(OpUpdateOne | OpDeleteOne): id, exists := m.ID() if exists { - return []int{id}, nil + return []int64{id}, nil } fallthrough case m.op.Is(OpUpdate | OpDelete): @@ -147,62 +151,6 @@ func (m *WalletMutation) IDs(ctx context.Context) ([]int, error) { } } -// SetUserID sets the "user_id" field. -func (m *WalletMutation) SetUserID(i int64) { - m.user_id = &i - m.adduser_id = nil -} - -// UserID returns the value of the "user_id" field in the mutation. -func (m *WalletMutation) UserID() (r int64, exists bool) { - v := m.user_id - if v == nil { - return - } - return *v, true -} - -// OldUserID returns the old "user_id" field's value of the Wallet entity. -// If the Wallet object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *WalletMutation) OldUserID(ctx context.Context) (v int64, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldUserID is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldUserID requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldUserID: %w", err) - } - return oldValue.UserID, nil -} - -// AddUserID adds i to the "user_id" field. -func (m *WalletMutation) AddUserID(i int64) { - if m.adduser_id != nil { - *m.adduser_id += i - } else { - m.adduser_id = &i - } -} - -// AddedUserID returns the value that was added to the "user_id" field in this mutation. -func (m *WalletMutation) AddedUserID() (r int64, exists bool) { - v := m.adduser_id - if v == nil { - return - } - return *v, true -} - -// ResetUserID resets all changes to the "user_id" field. -func (m *WalletMutation) ResetUserID() { - m.user_id = nil - m.adduser_id = nil -} - // SetBalance sets the "balance" field. func (m *WalletMutation) SetBalance(d decimal.Decimal) { m.balance = &d @@ -401,10 +349,7 @@ func (m *WalletMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *WalletMutation) Fields() []string { - fields := make([]string, 0, 5) - if m.user_id != nil { - fields = append(fields, wallet.FieldUserID) - } + fields := make([]string, 0, 4) if m.balance != nil { fields = append(fields, wallet.FieldBalance) } @@ -425,8 +370,6 @@ func (m *WalletMutation) Fields() []string { // schema. func (m *WalletMutation) Field(name string) (ent.Value, bool) { switch name { - case wallet.FieldUserID: - return m.UserID() case wallet.FieldBalance: return m.Balance() case wallet.FieldFrozenBalance: @@ -444,8 +387,6 @@ func (m *WalletMutation) Field(name string) (ent.Value, bool) { // database failed. func (m *WalletMutation) OldField(ctx context.Context, name string) (ent.Value, error) { switch name { - case wallet.FieldUserID: - return m.OldUserID(ctx) case wallet.FieldBalance: return m.OldBalance(ctx) case wallet.FieldFrozenBalance: @@ -463,13 +404,6 @@ func (m *WalletMutation) OldField(ctx context.Context, name string) (ent.Value, // type. func (m *WalletMutation) SetField(name string, value ent.Value) error { switch name { - case wallet.FieldUserID: - v, ok := value.(int64) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetUserID(v) - return nil case wallet.FieldBalance: v, ok := value.(decimal.Decimal) if !ok { @@ -506,9 +440,6 @@ func (m *WalletMutation) SetField(name string, value ent.Value) error { // this mutation. func (m *WalletMutation) AddedFields() []string { var fields []string - if m.adduser_id != nil { - fields = append(fields, wallet.FieldUserID) - } if m.addversion != nil { fields = append(fields, wallet.FieldVersion) } @@ -520,8 +451,6 @@ func (m *WalletMutation) AddedFields() []string { // was not set, or was not defined in the schema. func (m *WalletMutation) AddedField(name string) (ent.Value, bool) { switch name { - case wallet.FieldUserID: - return m.AddedUserID() case wallet.FieldVersion: return m.AddedVersion() } @@ -533,13 +462,6 @@ func (m *WalletMutation) AddedField(name string) (ent.Value, bool) { // type. func (m *WalletMutation) AddField(name string, value ent.Value) error { switch name { - case wallet.FieldUserID: - v, ok := value.(int64) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.AddUserID(v) - return nil case wallet.FieldVersion: v, ok := value.(int) if !ok { @@ -574,9 +496,6 @@ func (m *WalletMutation) ClearField(name string) error { // It returns an error if the field is not defined in the schema. func (m *WalletMutation) ResetField(name string) error { switch name { - case wallet.FieldUserID: - m.ResetUserID() - return nil case wallet.FieldBalance: m.ResetBalance() return nil @@ -1106,9 +1025,22 @@ func (m *WalletTransactionsMutation) OldSearchText(ctx context.Context) (v strin return oldValue.SearchText, nil } +// ClearSearchText clears the value of the "search_text" field. +func (m *WalletTransactionsMutation) ClearSearchText() { + m.search_text = nil + m.clearedFields[wallettransactions.FieldSearchText] = struct{}{} +} + +// SearchTextCleared returns if the "search_text" field was cleared in this mutation. +func (m *WalletTransactionsMutation) SearchTextCleared() bool { + _, ok := m.clearedFields[wallettransactions.FieldSearchText] + return ok +} + // ResetSearchText resets all changes to the "search_text" field. func (m *WalletTransactionsMutation) ResetSearchText() { m.search_text = nil + delete(m.clearedFields, wallettransactions.FieldSearchText) } // Where appends a list predicates to the WalletTransactionsMutation builder. @@ -1340,7 +1272,11 @@ func (m *WalletTransactionsMutation) AddField(name string, value ent.Value) erro // ClearedFields returns all nullable fields that were cleared during this // mutation. func (m *WalletTransactionsMutation) ClearedFields() []string { - return nil + var fields []string + if m.FieldCleared(wallettransactions.FieldSearchText) { + fields = append(fields, wallettransactions.FieldSearchText) + } + return fields } // FieldCleared returns a boolean indicating if a field with the given name was @@ -1353,6 +1289,11 @@ func (m *WalletTransactionsMutation) FieldCleared(name string) bool { // ClearField clears the value of the field with the given name. It returns an // error if the field is not defined in the schema. func (m *WalletTransactionsMutation) ClearField(name string) error { + switch name { + case wallettransactions.FieldSearchText: + m.ClearSearchText() + return nil + } return fmt.Errorf("unknown WalletTransactions nullable field %s", name) } diff --git a/app/wallet/rpc/internal/models/runtime.go b/app/wallet/rpc/internal/models/runtime.go index dc85cdf..51245ad 100644 --- a/app/wallet/rpc/internal/models/runtime.go +++ b/app/wallet/rpc/internal/models/runtime.go @@ -5,6 +5,7 @@ package models import ( "juwan-backend/app/wallet/rpc/internal/models/schema" "juwan-backend/app/wallet/rpc/internal/models/wallet" + "time" "github.com/shopspring/decimal" ) @@ -27,4 +28,8 @@ func init() { walletDescVersion := walletFields[3].Descriptor() // wallet.DefaultVersion holds the default value on creation for the version field. wallet.DefaultVersion = walletDescVersion.Default.(int) + // walletDescUpdatedAt is the schema descriptor for updated_at field. + walletDescUpdatedAt := walletFields[4].Descriptor() + // wallet.DefaultUpdatedAt holds the default value on creation for the updated_at field. + wallet.DefaultUpdatedAt = walletDescUpdatedAt.Default.(func() time.Time) } diff --git a/app/wallet/rpc/internal/models/schema/wallet.go b/app/wallet/rpc/internal/models/schema/wallet.go index 7f770b6..f9b4f89 100644 --- a/app/wallet/rpc/internal/models/schema/wallet.go +++ b/app/wallet/rpc/internal/models/schema/wallet.go @@ -1,6 +1,8 @@ package schema import ( + "time" + "entgo.io/ent" "entgo.io/ent/dialect" "entgo.io/ent/schema/field" @@ -17,7 +19,7 @@ type Wallet struct { // Fields of the Wallet. func (Wallet) Fields() []ent.Field { return []ent.Field{ - field.Int64("user_id").Immutable().Unique(), + field.Int64("id").StorageKey("user_id").Immutable().Unique(), field.Other("balance", decimal.Decimal{}). Default(defalutBalance). SchemaType(map[string]string{ @@ -29,7 +31,7 @@ func (Wallet) Fields() []ent.Field { dialect.Postgres: "decimal(12,2)", }), field.Int("version").Default(1), - field.Time("updated_at"), + field.Time("updated_at").Default(time.Now), } } diff --git a/app/wallet/rpc/internal/models/schema/wallettransactions.go b/app/wallet/rpc/internal/models/schema/wallettransactions.go index f8b5872..9f75b34 100644 --- a/app/wallet/rpc/internal/models/schema/wallettransactions.go +++ b/app/wallet/rpc/internal/models/schema/wallettransactions.go @@ -1,8 +1,11 @@ package schema import ( + "juwan-backend/pkg/types" + "entgo.io/ent" "entgo.io/ent/dialect" + "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema/field" "github.com/shopspring/decimal" ) @@ -26,10 +29,14 @@ func (WalletTransactions) Fields() []ent.Field { SchemaType(map[string]string{ dialect.Postgres: "decimal(12,2)", }).Unique().Immutable(), - field.Strings("description"), + field.Other("description", types.TextArray{}).SchemaType(map[string]string{ + dialect.Postgres: "text[]", + }).Optional(), field.Int64("order_id").Immutable().Unique(), field.Time("created_at"), - field.String("search_text"), + field.String("search_text").Optional().Immutable().Annotations(entsql.Annotation{ + Skip: true, + }), } } diff --git a/app/wallet/rpc/internal/models/wallet.go b/app/wallet/rpc/internal/models/wallet.go index 6f633be..1a2da72 100644 --- a/app/wallet/rpc/internal/models/wallet.go +++ b/app/wallet/rpc/internal/models/wallet.go @@ -17,9 +17,7 @@ import ( type Wallet struct { config `json:"-"` // ID of the ent. - ID int `json:"id,omitempty"` - // UserID holds the value of the "user_id" field. - UserID int64 `json:"user_id,omitempty"` + ID int64 `json:"id,omitempty"` // Balance holds the value of the "balance" field. Balance decimal.Decimal `json:"balance,omitempty"` // FrozenBalance holds the value of the "frozen_balance" field. @@ -38,7 +36,7 @@ func (*Wallet) scanValues(columns []string) ([]any, error) { switch columns[i] { case wallet.FieldBalance, wallet.FieldFrozenBalance: values[i] = new(decimal.Decimal) - case wallet.FieldID, wallet.FieldUserID, wallet.FieldVersion: + case wallet.FieldID, wallet.FieldVersion: values[i] = new(sql.NullInt64) case wallet.FieldUpdatedAt: values[i] = new(sql.NullTime) @@ -62,13 +60,7 @@ func (_m *Wallet) assignValues(columns []string, values []any) error { if !ok { return fmt.Errorf("unexpected type %T for field id", value) } - _m.ID = int(value.Int64) - case wallet.FieldUserID: - if value, ok := values[i].(*sql.NullInt64); !ok { - return fmt.Errorf("unexpected type %T for field user_id", values[i]) - } else if value.Valid { - _m.UserID = value.Int64 - } + _m.ID = int64(value.Int64) case wallet.FieldBalance: if value, ok := values[i].(*decimal.Decimal); !ok { return fmt.Errorf("unexpected type %T for field balance", values[i]) @@ -129,9 +121,6 @@ func (_m *Wallet) String() string { var builder strings.Builder builder.WriteString("Wallet(") builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) - builder.WriteString("user_id=") - builder.WriteString(fmt.Sprintf("%v", _m.UserID)) - builder.WriteString(", ") builder.WriteString("balance=") builder.WriteString(fmt.Sprintf("%v", _m.Balance)) builder.WriteString(", ") diff --git a/app/wallet/rpc/internal/models/wallet/wallet.go b/app/wallet/rpc/internal/models/wallet/wallet.go index d79f0f0..820aa1b 100644 --- a/app/wallet/rpc/internal/models/wallet/wallet.go +++ b/app/wallet/rpc/internal/models/wallet/wallet.go @@ -3,6 +3,8 @@ package wallet import ( + "time" + "entgo.io/ent/dialect/sql" "github.com/shopspring/decimal" ) @@ -11,9 +13,7 @@ const ( // Label holds the string label denoting the wallet type in the database. Label = "wallet" // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldUserID holds the string denoting the user_id field in the database. - FieldUserID = "user_id" + FieldID = "user_id" // FieldBalance holds the string denoting the balance field in the database. FieldBalance = "balance" // FieldFrozenBalance holds the string denoting the frozen_balance field in the database. @@ -29,7 +29,6 @@ const ( // Columns holds all SQL columns for wallet fields. var Columns = []string{ FieldID, - FieldUserID, FieldBalance, FieldFrozenBalance, FieldVersion, @@ -53,6 +52,8 @@ var ( DefaultFrozenBalance decimal.Decimal // DefaultVersion holds the default value on creation for the "version" field. DefaultVersion int + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time ) // OrderOption defines the ordering options for the Wallet queries. @@ -63,11 +64,6 @@ func ByID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldID, opts...).ToFunc() } -// ByUserID orders the results by the user_id field. -func ByUserID(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldUserID, opts...).ToFunc() -} - // ByBalance orders the results by the balance field. func ByBalance(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldBalance, opts...).ToFunc() diff --git a/app/wallet/rpc/internal/models/wallet/where.go b/app/wallet/rpc/internal/models/wallet/where.go index 83b527e..309ac73 100644 --- a/app/wallet/rpc/internal/models/wallet/where.go +++ b/app/wallet/rpc/internal/models/wallet/where.go @@ -11,55 +11,50 @@ import ( ) // ID filters vertices based on their ID field. -func ID(id int) predicate.Wallet { +func ID(id int64) predicate.Wallet { return predicate.Wallet(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. -func IDEQ(id int) predicate.Wallet { +func IDEQ(id int64) predicate.Wallet { return predicate.Wallet(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. -func IDNEQ(id int) predicate.Wallet { +func IDNEQ(id int64) predicate.Wallet { return predicate.Wallet(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. -func IDIn(ids ...int) predicate.Wallet { +func IDIn(ids ...int64) predicate.Wallet { return predicate.Wallet(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. -func IDNotIn(ids ...int) predicate.Wallet { +func IDNotIn(ids ...int64) predicate.Wallet { return predicate.Wallet(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. -func IDGT(id int) predicate.Wallet { +func IDGT(id int64) predicate.Wallet { return predicate.Wallet(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. -func IDGTE(id int) predicate.Wallet { +func IDGTE(id int64) predicate.Wallet { return predicate.Wallet(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. -func IDLT(id int) predicate.Wallet { +func IDLT(id int64) predicate.Wallet { return predicate.Wallet(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. -func IDLTE(id int) predicate.Wallet { +func IDLTE(id int64) predicate.Wallet { return predicate.Wallet(sql.FieldLTE(FieldID, id)) } -// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. -func UserID(v int64) predicate.Wallet { - return predicate.Wallet(sql.FieldEQ(FieldUserID, v)) -} - // Balance applies equality check predicate on the "balance" field. It's identical to BalanceEQ. func Balance(v decimal.Decimal) predicate.Wallet { return predicate.Wallet(sql.FieldEQ(FieldBalance, v)) @@ -80,46 +75,6 @@ func UpdatedAt(v time.Time) predicate.Wallet { return predicate.Wallet(sql.FieldEQ(FieldUpdatedAt, v)) } -// UserIDEQ applies the EQ predicate on the "user_id" field. -func UserIDEQ(v int64) predicate.Wallet { - return predicate.Wallet(sql.FieldEQ(FieldUserID, v)) -} - -// UserIDNEQ applies the NEQ predicate on the "user_id" field. -func UserIDNEQ(v int64) predicate.Wallet { - return predicate.Wallet(sql.FieldNEQ(FieldUserID, v)) -} - -// UserIDIn applies the In predicate on the "user_id" field. -func UserIDIn(vs ...int64) predicate.Wallet { - return predicate.Wallet(sql.FieldIn(FieldUserID, vs...)) -} - -// UserIDNotIn applies the NotIn predicate on the "user_id" field. -func UserIDNotIn(vs ...int64) predicate.Wallet { - return predicate.Wallet(sql.FieldNotIn(FieldUserID, vs...)) -} - -// UserIDGT applies the GT predicate on the "user_id" field. -func UserIDGT(v int64) predicate.Wallet { - return predicate.Wallet(sql.FieldGT(FieldUserID, v)) -} - -// UserIDGTE applies the GTE predicate on the "user_id" field. -func UserIDGTE(v int64) predicate.Wallet { - return predicate.Wallet(sql.FieldGTE(FieldUserID, v)) -} - -// UserIDLT applies the LT predicate on the "user_id" field. -func UserIDLT(v int64) predicate.Wallet { - return predicate.Wallet(sql.FieldLT(FieldUserID, v)) -} - -// UserIDLTE applies the LTE predicate on the "user_id" field. -func UserIDLTE(v int64) predicate.Wallet { - return predicate.Wallet(sql.FieldLTE(FieldUserID, v)) -} - // BalanceEQ applies the EQ predicate on the "balance" field. func BalanceEQ(v decimal.Decimal) predicate.Wallet { return predicate.Wallet(sql.FieldEQ(FieldBalance, v)) diff --git a/app/wallet/rpc/internal/models/wallet_create.go b/app/wallet/rpc/internal/models/wallet_create.go index 943bdb6..ae618f3 100644 --- a/app/wallet/rpc/internal/models/wallet_create.go +++ b/app/wallet/rpc/internal/models/wallet_create.go @@ -21,12 +21,6 @@ type WalletCreate struct { hooks []Hook } -// SetUserID sets the "user_id" field. -func (_c *WalletCreate) SetUserID(v int64) *WalletCreate { - _c.mutation.SetUserID(v) - return _c -} - // SetBalance sets the "balance" field. func (_c *WalletCreate) SetBalance(v decimal.Decimal) *WalletCreate { _c.mutation.SetBalance(v) @@ -75,6 +69,20 @@ func (_c *WalletCreate) SetUpdatedAt(v time.Time) *WalletCreate { return _c } +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *WalletCreate) SetNillableUpdatedAt(v *time.Time) *WalletCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + +// SetID sets the "id" field. +func (_c *WalletCreate) SetID(v int64) *WalletCreate { + _c.mutation.SetID(v) + return _c +} + // Mutation returns the WalletMutation object of the builder. func (_c *WalletCreate) Mutation() *WalletMutation { return _c.mutation @@ -122,13 +130,14 @@ func (_c *WalletCreate) defaults() { v := wallet.DefaultVersion _c.mutation.SetVersion(v) } + if _, ok := _c.mutation.UpdatedAt(); !ok { + v := wallet.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) + } } // check runs all checks and user-defined validators on the builder. func (_c *WalletCreate) check() error { - if _, ok := _c.mutation.UserID(); !ok { - return &ValidationError{Name: "user_id", err: errors.New(`models: missing required field "Wallet.user_id"`)} - } if _, ok := _c.mutation.Balance(); !ok { return &ValidationError{Name: "balance", err: errors.New(`models: missing required field "Wallet.balance"`)} } @@ -155,8 +164,10 @@ func (_c *WalletCreate) sqlSave(ctx context.Context) (*Wallet, error) { } return nil, err } - id := _spec.ID.Value.(int64) - _node.ID = int(id) + if _spec.ID.Value != _node.ID { + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + } _c.mutation.id = &_node.ID _c.mutation.done = true return _node, nil @@ -165,11 +176,11 @@ func (_c *WalletCreate) sqlSave(ctx context.Context) (*Wallet, error) { func (_c *WalletCreate) createSpec() (*Wallet, *sqlgraph.CreateSpec) { var ( _node = &Wallet{config: _c.config} - _spec = sqlgraph.NewCreateSpec(wallet.Table, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt)) + _spec = sqlgraph.NewCreateSpec(wallet.Table, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt64)) ) - if value, ok := _c.mutation.UserID(); ok { - _spec.SetField(wallet.FieldUserID, field.TypeInt64, value) - _node.UserID = value + if id, ok := _c.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = id } if value, ok := _c.mutation.Balance(); ok { _spec.SetField(wallet.FieldBalance, field.TypeOther, value) @@ -235,9 +246,9 @@ func (_c *WalletCreateBulk) Save(ctx context.Context) ([]*Wallet, error) { return nil, err } mutation.id = &nodes[i].ID - if specs[i].ID.Value != nil { + if specs[i].ID.Value != nil && nodes[i].ID == 0 { id := specs[i].ID.Value.(int64) - nodes[i].ID = int(id) + nodes[i].ID = int64(id) } mutation.done = true return nodes[i], nil diff --git a/app/wallet/rpc/internal/models/wallet_delete.go b/app/wallet/rpc/internal/models/wallet_delete.go index 07dc1c1..e273041 100644 --- a/app/wallet/rpc/internal/models/wallet_delete.go +++ b/app/wallet/rpc/internal/models/wallet_delete.go @@ -40,7 +40,7 @@ func (_d *WalletDelete) ExecX(ctx context.Context) int { } func (_d *WalletDelete) sqlExec(ctx context.Context) (int, error) { - _spec := sqlgraph.NewDeleteSpec(wallet.Table, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt)) + _spec := sqlgraph.NewDeleteSpec(wallet.Table, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt64)) if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { diff --git a/app/wallet/rpc/internal/models/wallet_query.go b/app/wallet/rpc/internal/models/wallet_query.go index 3902f0d..f8a471c 100644 --- a/app/wallet/rpc/internal/models/wallet_query.go +++ b/app/wallet/rpc/internal/models/wallet_query.go @@ -82,8 +82,8 @@ func (_q *WalletQuery) FirstX(ctx context.Context) *Wallet { // FirstID returns the first Wallet ID from the query. // Returns a *NotFoundError when no Wallet ID was found. -func (_q *WalletQuery) FirstID(ctx context.Context) (id int, err error) { - var ids []int +func (_q *WalletQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } @@ -95,7 +95,7 @@ func (_q *WalletQuery) FirstID(ctx context.Context) (id int, err error) { } // FirstIDX is like FirstID, but panics if an error occurs. -func (_q *WalletQuery) FirstIDX(ctx context.Context) int { +func (_q *WalletQuery) FirstIDX(ctx context.Context) int64 { id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) @@ -133,8 +133,8 @@ func (_q *WalletQuery) OnlyX(ctx context.Context) *Wallet { // OnlyID is like Only, but returns the only Wallet ID in the query. // Returns a *NotSingularError when more than one Wallet ID is found. // Returns a *NotFoundError when no entities are found. -func (_q *WalletQuery) OnlyID(ctx context.Context) (id int, err error) { - var ids []int +func (_q *WalletQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } @@ -150,7 +150,7 @@ func (_q *WalletQuery) OnlyID(ctx context.Context) (id int, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (_q *WalletQuery) OnlyIDX(ctx context.Context) int { +func (_q *WalletQuery) OnlyIDX(ctx context.Context) int64 { id, err := _q.OnlyID(ctx) if err != nil { panic(err) @@ -178,7 +178,7 @@ func (_q *WalletQuery) AllX(ctx context.Context) []*Wallet { } // IDs executes the query and returns a list of Wallet IDs. -func (_q *WalletQuery) IDs(ctx context.Context) (ids []int, err error) { +func (_q *WalletQuery) IDs(ctx context.Context) (ids []int64, err error) { if _q.ctx.Unique == nil && _q.path != nil { _q.Unique(true) } @@ -190,7 +190,7 @@ func (_q *WalletQuery) IDs(ctx context.Context) (ids []int, err error) { } // IDsX is like IDs, but panics if an error occurs. -func (_q *WalletQuery) IDsX(ctx context.Context) []int { +func (_q *WalletQuery) IDsX(ctx context.Context) []int64 { ids, err := _q.IDs(ctx) if err != nil { panic(err) @@ -262,12 +262,12 @@ func (_q *WalletQuery) Clone() *WalletQuery { // Example: // // var v []struct { -// UserID int64 `json:"user_id,omitempty"` +// Balance decimal.Decimal `json:"balance,omitempty"` // Count int `json:"count,omitempty"` // } // // client.Wallet.Query(). -// GroupBy(wallet.FieldUserID). +// GroupBy(wallet.FieldBalance). // Aggregate(models.Count()). // Scan(ctx, &v) func (_q *WalletQuery) GroupBy(field string, fields ...string) *WalletGroupBy { @@ -285,11 +285,11 @@ func (_q *WalletQuery) GroupBy(field string, fields ...string) *WalletGroupBy { // Example: // // var v []struct { -// UserID int64 `json:"user_id,omitempty"` +// Balance decimal.Decimal `json:"balance,omitempty"` // } // // client.Wallet.Query(). -// Select(wallet.FieldUserID). +// Select(wallet.FieldBalance). // Scan(ctx, &v) func (_q *WalletQuery) Select(fields ...string) *WalletSelect { _q.ctx.Fields = append(_q.ctx.Fields, fields...) @@ -365,7 +365,7 @@ func (_q *WalletQuery) sqlCount(ctx context.Context) (int, error) { } func (_q *WalletQuery) querySpec() *sqlgraph.QuerySpec { - _spec := sqlgraph.NewQuerySpec(wallet.Table, wallet.Columns, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt)) + _spec := sqlgraph.NewQuerySpec(wallet.Table, wallet.Columns, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt64)) _spec.From = _q.sql if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique diff --git a/app/wallet/rpc/internal/models/wallet_update.go b/app/wallet/rpc/internal/models/wallet_update.go index 8a0a8a1..5898b08 100644 --- a/app/wallet/rpc/internal/models/wallet_update.go +++ b/app/wallet/rpc/internal/models/wallet_update.go @@ -125,7 +125,7 @@ func (_u *WalletUpdate) ExecX(ctx context.Context) { } func (_u *WalletUpdate) sqlSave(ctx context.Context) (_node int, err error) { - _spec := sqlgraph.NewUpdateSpec(wallet.Table, wallet.Columns, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt)) + _spec := sqlgraph.NewUpdateSpec(wallet.Table, wallet.Columns, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt64)) if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -277,7 +277,7 @@ func (_u *WalletUpdateOne) ExecX(ctx context.Context) { } func (_u *WalletUpdateOne) sqlSave(ctx context.Context) (_node *Wallet, err error) { - _spec := sqlgraph.NewUpdateSpec(wallet.Table, wallet.Columns, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt)) + _spec := sqlgraph.NewUpdateSpec(wallet.Table, wallet.Columns, sqlgraph.NewFieldSpec(wallet.FieldID, field.TypeInt64)) id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`models: missing "Wallet.id" for update`)} diff --git a/app/wallet/rpc/internal/models/wallettransactions/where.go b/app/wallet/rpc/internal/models/wallettransactions/where.go index 2fab64b..c534046 100644 --- a/app/wallet/rpc/internal/models/wallettransactions/where.go +++ b/app/wallet/rpc/internal/models/wallettransactions/where.go @@ -420,6 +420,16 @@ func SearchTextHasSuffix(v string) predicate.WalletTransactions { return predicate.WalletTransactions(sql.FieldHasSuffix(FieldSearchText, v)) } +// SearchTextIsNil applies the IsNil predicate on the "search_text" field. +func SearchTextIsNil() predicate.WalletTransactions { + return predicate.WalletTransactions(sql.FieldIsNull(FieldSearchText)) +} + +// SearchTextNotNil applies the NotNil predicate on the "search_text" field. +func SearchTextNotNil() predicate.WalletTransactions { + return predicate.WalletTransactions(sql.FieldNotNull(FieldSearchText)) +} + // SearchTextEqualFold applies the EqualFold predicate on the "search_text" field. func SearchTextEqualFold(v string) predicate.WalletTransactions { return predicate.WalletTransactions(sql.FieldEqualFold(FieldSearchText, v)) diff --git a/app/wallet/rpc/internal/models/wallettransactions_create.go b/app/wallet/rpc/internal/models/wallettransactions_create.go index 6391e6b..dfe3226 100644 --- a/app/wallet/rpc/internal/models/wallettransactions_create.go +++ b/app/wallet/rpc/internal/models/wallettransactions_create.go @@ -69,6 +69,14 @@ func (_c *WalletTransactionsCreate) SetSearchText(v string) *WalletTransactionsC return _c } +// SetNillableSearchText sets the "search_text" field if the given value is not nil. +func (_c *WalletTransactionsCreate) SetNillableSearchText(v *string) *WalletTransactionsCreate { + if v != nil { + _c.SetSearchText(*v) + } + return _c +} + // SetID sets the "id" field. func (_c *WalletTransactionsCreate) SetID(v string) *WalletTransactionsCreate { _c.mutation.SetID(v) @@ -130,9 +138,6 @@ func (_c *WalletTransactionsCreate) check() error { if _, ok := _c.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`models: missing required field "WalletTransactions.created_at"`)} } - if _, ok := _c.mutation.SearchText(); !ok { - return &ValidationError{Name: "search_text", err: errors.New(`models: missing required field "WalletTransactions.search_text"`)} - } return nil } diff --git a/app/wallet/rpc/internal/models/wallettransactions_update.go b/app/wallet/rpc/internal/models/wallettransactions_update.go index 96fed77..c396ad6 100644 --- a/app/wallet/rpc/internal/models/wallettransactions_update.go +++ b/app/wallet/rpc/internal/models/wallettransactions_update.go @@ -69,20 +69,6 @@ func (_u *WalletTransactionsUpdate) SetNillableCreatedAt(v *time.Time) *WalletTr return _u } -// SetSearchText sets the "search_text" field. -func (_u *WalletTransactionsUpdate) SetSearchText(v string) *WalletTransactionsUpdate { - _u.mutation.SetSearchText(v) - return _u -} - -// SetNillableSearchText sets the "search_text" field if the given value is not nil. -func (_u *WalletTransactionsUpdate) SetNillableSearchText(v *string) *WalletTransactionsUpdate { - if v != nil { - _u.SetSearchText(*v) - } - return _u -} - // Mutation returns the WalletTransactionsMutation object of the builder. func (_u *WalletTransactionsUpdate) Mutation() *WalletTransactionsMutation { return _u.mutation @@ -138,8 +124,8 @@ func (_u *WalletTransactionsUpdate) sqlSave(ctx context.Context) (_node int, err if value, ok := _u.mutation.CreatedAt(); ok { _spec.SetField(wallettransactions.FieldCreatedAt, field.TypeTime, value) } - if value, ok := _u.mutation.SearchText(); ok { - _spec.SetField(wallettransactions.FieldSearchText, field.TypeString, value) + if _u.mutation.SearchTextCleared() { + _spec.ClearField(wallettransactions.FieldSearchText, field.TypeString) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { @@ -201,20 +187,6 @@ func (_u *WalletTransactionsUpdateOne) SetNillableCreatedAt(v *time.Time) *Walle return _u } -// SetSearchText sets the "search_text" field. -func (_u *WalletTransactionsUpdateOne) SetSearchText(v string) *WalletTransactionsUpdateOne { - _u.mutation.SetSearchText(v) - return _u -} - -// SetNillableSearchText sets the "search_text" field if the given value is not nil. -func (_u *WalletTransactionsUpdateOne) SetNillableSearchText(v *string) *WalletTransactionsUpdateOne { - if v != nil { - _u.SetSearchText(*v) - } - return _u -} - // Mutation returns the WalletTransactionsMutation object of the builder. func (_u *WalletTransactionsUpdateOne) Mutation() *WalletTransactionsMutation { return _u.mutation @@ -300,8 +272,8 @@ func (_u *WalletTransactionsUpdateOne) sqlSave(ctx context.Context) (_node *Wall if value, ok := _u.mutation.CreatedAt(); ok { _spec.SetField(wallettransactions.FieldCreatedAt, field.TypeTime, value) } - if value, ok := _u.mutation.SearchText(); ok { - _spec.SetField(wallettransactions.FieldSearchText, field.TypeString, value) + if _u.mutation.SearchTextCleared() { + _spec.ClearField(wallettransactions.FieldSearchText, field.TypeString) } _node = &WalletTransactions{config: _u.config} _spec.Assign = _node.assignValues diff --git a/app/wallet/rpc/internal/svc/serviceContext.go b/app/wallet/rpc/internal/svc/serviceContext.go index d43deec..6da7bd1 100644 --- a/app/wallet/rpc/internal/svc/serviceContext.go +++ b/app/wallet/rpc/internal/svc/serviceContext.go @@ -1,6 +1,7 @@ package svc import ( + stdsql "database/sql" "fmt" "juwan-backend/app/snowflake/rpc/snowflake" "juwan-backend/app/wallet/rpc/internal/config" @@ -12,6 +13,7 @@ import ( "time" "ariga.io/entcache" + "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" _ "github.com/jackc/pgx/v5/stdlib" "github.com/zeromicro/go-zero/core/logx" @@ -25,14 +27,16 @@ type ServiceContext struct { } func NewServiceContext(c config.Config) *ServiceContext { - RWConn, err := sql.Open("pgx", c.DB.Master) + rawRW, err := stdsql.Open("pgx", c.DB.Master) if err != nil { panic(err) } - ROConn, err := sql.Open("pgx", c.DB.Slaves) + rawRO, err := stdsql.Open("pgx", c.DB.Slaves) if err != nil { panic(err) } + RWConn := sql.OpenDB(dialect.Postgres, rawRW) + ROConn := sql.OpenDB(dialect.Postgres, rawRO) redisCluster, err := redisx.ConnectMasterSlaveCluster(c.CacheConf, 5*time.Second) if redisCluster == nil || err != nil { diff --git a/common/middlewares/HeaderExtractorMiddleware.go b/common/middlewares/HeaderExtractorMiddleware.go new file mode 100644 index 0000000..90a0418 --- /dev/null +++ b/common/middlewares/HeaderExtractorMiddleware.go @@ -0,0 +1,47 @@ +package middlewares + +import ( + "context" + "net/http" + "strconv" + + "github.com/zeromicro/go-zero/core/logx" +) + +type HeaderExtractorMiddleware struct{} + +func NewHeaderExtractorMiddleware() *HeaderExtractorMiddleware { + return &HeaderExtractorMiddleware{} +} + +func (m *HeaderExtractorMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + header := r.Header + logx.Infof("headerExtractorMiddleware header: %v", header) + + ctx := r.Context() + + if userID := r.Header.Get("x-auth-user-id"); userID != "" { + if parsed, err := strconv.ParseInt(userID, 10, 64); err == nil { + ctx = context.WithValue(ctx, "user_id", parsed) + } else { + logx.Errorf("invalid x-auth-user-id header: %v", err) + } + } + + if isAdmin := r.Header.Get("x-auth-is-admin"); isAdmin != "" { + if parsed, err := strconv.ParseBool(isAdmin); err == nil { + ctx = context.WithValue(ctx, "is_admin", parsed) + } else { + logx.Errorf("invalid x-auth-is-admin header: %v", err) + } + } + + if requestID := r.Header.Get("x-request-id"); requestID != "" { + ctx = context.WithValue(ctx, "request_id", requestID) + ctx = context.WithValue(ctx, "rid", requestID) + } + + next(w, r.WithContext(ctx)) + } +} diff --git a/common/middlewares/requestIdMiddleware.go b/common/middlewares/requestIdMiddleware.go new file mode 100644 index 0000000..b9b00c3 --- /dev/null +++ b/common/middlewares/requestIdMiddleware.go @@ -0,0 +1,23 @@ +package middlewares + +import ( + "context" + "net/http" +) + +type RequestIdMiddleware struct{} + +func NewRequestMiddleware() *RequestIdMiddleware { + return &RequestIdMiddleware{} +} + +func (m *RequestIdMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + requestId := r.Header.Get("X-Request-Id") + if requestId != "" { + ctx = context.WithValue(ctx, "request_id", requestId) + } + next(w, r.WithContext(ctx)) + } +} diff --git a/common/utils/contextj/contextx.go b/common/utils/contextj/contextx.go index cdb8c43..1995d12 100644 --- a/common/utils/contextj/contextx.go +++ b/common/utils/contextj/contextx.go @@ -64,6 +64,14 @@ func RequestIDFrom(c context.Context) (string, error) { } } +func RIdFrom(c context.Context) (string, error) { + if rid, ok := c.Value("rid").(string); !ok { + return "", errors.New("rid not found in context") + } else { + return rid, nil + } +} + func WithIsAdmin(c context.Context, isAdmin bool) context.Context { return context.WithValue(c, "is_admin", isAdmin) } diff --git a/deploy/dev/script/pg_docker.sh b/deploy/dev/script/pg_docker.sh new file mode 100644 index 0000000..efaff64 --- /dev/null +++ b/deploy/dev/script/pg_docker.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +PG_CONTAINER_NAME="pg-dev-server" +PG_VERSION="17-bookworm" +DB_USER="postgres" +DB_PASSWORD="123456" +DB_PORT="5432" +VOLUME_NAME="pg_dev_data" + +REDIS_CONTAINER_NAME="redis-dev-server" +REDIS_PORT="6379" +REDIS_VERSION="8" + + +docker pull postgres:$PG_VERSION + +if [ "$(docker ps -aq -f name=$PG_CONTAINER_NAME)" ]; then + docker rm -f $PG_CONTAINER_NAME +fi + +docker run -d \ + --name $PG_CONTAINER_NAME \ + -e POSTGRES_USER=$DB_USER \ + -e POSTGRES_PASSWORD=$DB_PASSWORD \ + -p $DB_PORT:5432 \ + -v $VOLUME_NAME:/var/lib/postgresql/data \ + --restart unless-stopped \ + postgres:$PG_VERSION + +echo "------------------------------------------------" +echo "PostgreSQL 已启动!" +echo "容器名称: $PG_CONTAINER_NAME" +echo "宿主机端口: $DB_PORT" +echo "用户名: $DB_USER" +echo "密码: $DB_PASSWORD" +echo "数据卷: $VOLUME_NAME (数据已持久化)" +echo "------------------------------------------------" + +docker run -d \ + --name $REDIS_CONTAINER_NAME\ + -p $REDIS_PORT:6379 \ + --restart unless-stopped \ + redis:$REDIS_VERSION + +echo "------------------------------------------------" +echo "Redis已启动!" +echo "容器名称: $PG_CONTAINER_NAME" +echo "宿主机端口: $PG_PORT" +echo "------------------------------------------------" diff --git a/deploy/dev/script/snowflake.sh b/deploy/dev/script/snowflake.sh new file mode 100644 index 0000000..a406598 --- /dev/null +++ b/deploy/dev/script/snowflake.sh @@ -0,0 +1 @@ +docker run --rm --name snowflake-svc -d snowflake \ No newline at end of file diff --git a/deploy/k8s/service/email/email-mq.yaml b/deploy/k8s/service/email/email-mq.yaml index e4718e5..85da50f 100644 --- a/deploy/k8s/service/email/email-mq.yaml +++ b/deploy/k8s/service/email/email-mq.yaml @@ -28,6 +28,8 @@ spec: image: email-mq:latest imagePullPolicy: Always env: + - name: KAFKA_BROKER + value: "my-cluster-kafka-bootstrap.kafka:9092" - name: EMAIL_SMTP_HOST valueFrom: secretKeyRef: diff --git a/desc/api/docs/game-api.json b/desc/api/docs/game-api.json new file mode 100644 index 0000000..08d2d7b --- /dev/null +++ b/desc/api/docs/game-api.json @@ -0,0 +1,214 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "swagger": "2.0", + "info": { + "title": "game-api", + "version": "1.0" + }, + "basePath": "/", + "paths": { + "/api/v1/games": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取游戏列表", + "operationId": "gameListGames", + "parameters": [ + { + "type": "integer", + "default": 0, + "name": "offset", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "limit", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "name", + "icon", + "category" + ], + "properties": { + "category": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "required": [ + "total", + "offset", + "limit" + ], + "properties": { + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "创建游戏", + "operationId": "gameCreateGame", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "id", + "name", + "icon", + "category" + ], + "properties": { + "category": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "category": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + } + } + } + } + }, + "/api/v1/games/{id}": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取游戏详情", + "operationId": "gameGetGame", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "category": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + } + } + } + } + } + }, + "x-date": "2026-03-23 01:44:01", + "x-description": "This is a goctl generated swagger file.", + "x-github": "https://github.com/zeromicro/go-zero", + "x-go-zero-doc": "https://go-zero.dev/", + "x-goctl-version": "1.9.2" +} \ No newline at end of file diff --git a/desc/api/docs/order-api.json b/desc/api/docs/order-api.json new file mode 100644 index 0000000..04b6aef --- /dev/null +++ b/desc/api/docs/order-api.json @@ -0,0 +1,940 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "swagger": "2.0", + "info": { + "title": "聚玩订单服务", + "version": "1.0" + }, + "basePath": "/", + "paths": { + "/api/v1/orders": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取订单列表", + "operationId": "orderListOrders", + "parameters": [ + { + "type": "integer", + "default": 0, + "name": "offset", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "limit", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "consumer, player, owner", + "name": "role", + "in": "query", + "required": true + }, + { + "type": "string", + "name": "status", + "in": "query", + "allowEmptyValue": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "consumerId", + "consumerName", + "playerId", + "playerName", + "service", + "status", + "totalPrice", + "createdAt" + ], + "properties": { + "acceptedAt": { + "type": "string" + }, + "completedAt": { + "type": "string" + }, + "consumerId": { + "type": "integer" + }, + "consumerName": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "playerId": { + "type": "string" + }, + "playerName": { + "type": "string" + }, + "service": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + }, + "shopId": { + "type": "integer" + }, + "shopName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "totalPrice": { + "type": "number" + } + } + } + }, + "meta": { + "type": "object", + "required": [ + "total", + "offset", + "limit" + ], + "properties": { + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "创建订单", + "operationId": "orderCreateOrder", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "playerId", + "serviceId", + "quantity" + ], + "properties": { + "note": { + "type": "string" + }, + "playerId": { + "type": "integer" + }, + "quantity": { + "type": "integer" + }, + "serviceId": { + "type": "integer" + }, + "shopId": { + "type": "integer" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "ok": { + "type": "boolean" + }, + "order": { + "type": "object", + "required": [ + "id", + "consumerId", + "consumerName", + "playerId", + "playerName", + "service", + "status", + "totalPrice", + "createdAt" + ], + "properties": { + "acceptedAt": { + "type": "string" + }, + "completedAt": { + "type": "string" + }, + "consumerId": { + "type": "integer" + }, + "consumerName": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "playerId": { + "type": "string" + }, + "playerName": { + "type": "string" + }, + "service": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + }, + "shopId": { + "type": "integer" + }, + "shopName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "totalPrice": { + "type": "number" + } + } + } + } + } + } + } + } + }, + "/api/v1/orders/paid": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "创建并支付订单", + "operationId": "orderCreateAndPayOrder", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "playerId", + "serviceId", + "quantity" + ], + "properties": { + "note": { + "type": "string" + }, + "playerId": { + "type": "integer" + }, + "quantity": { + "type": "integer" + }, + "serviceId": { + "type": "integer" + }, + "shopId": { + "type": "integer" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "ok": { + "type": "boolean" + }, + "order": { + "type": "object", + "required": [ + "id", + "consumerId", + "consumerName", + "playerId", + "playerName", + "service", + "status", + "totalPrice", + "createdAt" + ], + "properties": { + "acceptedAt": { + "type": "string" + }, + "completedAt": { + "type": "string" + }, + "consumerId": { + "type": "integer" + }, + "consumerName": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "playerId": { + "type": "string" + }, + "playerName": { + "type": "string" + }, + "service": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + }, + "shopId": { + "type": "integer" + }, + "shopName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "totalPrice": { + "type": "number" + } + } + } + } + } + } + } + } + }, + "/api/v1/orders/{id}": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取订单详情", + "operationId": "orderGetOrder", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "acceptedAt": { + "type": "string" + }, + "completedAt": { + "type": "string" + }, + "consumerId": { + "type": "integer" + }, + "consumerName": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "playerId": { + "type": "string" + }, + "playerName": { + "type": "string" + }, + "service": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + }, + "shopId": { + "type": "integer" + }, + "shopName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "totalPrice": { + "type": "number" + } + } + } + } + } + } + }, + "/api/v1/orders/{id}/accept": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "接单", + "operationId": "orderAcceptOrder", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/orders/{id}/cancel": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "取消订单", + "operationId": "orderCancelOrder", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/orders/{id}/confirm-close": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "确认结算", + "operationId": "orderConfirmCloseOrder", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/orders/{id}/pay": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "支付订单", + "operationId": "orderPayOrder", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/orders/{id}/reorder": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "再来一单", + "operationId": "orderReorder", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "ok": { + "type": "boolean" + }, + "order": { + "type": "object", + "required": [ + "id", + "consumerId", + "consumerName", + "playerId", + "playerName", + "service", + "status", + "totalPrice", + "createdAt" + ], + "properties": { + "acceptedAt": { + "type": "string" + }, + "completedAt": { + "type": "string" + }, + "consumerId": { + "type": "integer" + }, + "consumerName": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "note": { + "type": "string" + }, + "playerId": { + "type": "string" + }, + "playerName": { + "type": "string" + }, + "service": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + }, + "shopId": { + "type": "integer" + }, + "shopName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "totalPrice": { + "type": "number" + } + } + } + } + } + } + } + } + }, + "/api/v1/orders/{id}/request-close": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "申请结算", + "operationId": "orderRequestCloseOrder", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + } + }, + "x-date": "2026-03-27 17:39:38", + "x-description": "This is a goctl generated swagger file.", + "x-github": "https://github.com/zeromicro/go-zero", + "x-go-zero-doc": "https://go-zero.dev/", + "x-goctl-version": "1.9.2" +} \ No newline at end of file diff --git a/desc/api/docs/os-api.json b/desc/api/docs/os-api.json new file mode 100644 index 0000000..fa90b88 --- /dev/null +++ b/desc/api/docs/os-api.json @@ -0,0 +1,95 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "swagger": "2.0", + "info": { + "title": "文件服务", + "version": "v1" + }, + "basePath": "/", + "paths": { + "/api/v1/files/{fileId}": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "文件获取接口 (如果是私有文件,通过此接口获取或重定向)", + "operationId": "fileGetFile", + "parameters": [ + { + "type": "string", + "name": "fileId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": {} + } + } + } + }, + "/api/v1/upload": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "文件上传接口", + "operationId": "fileUpload", + "parameters": [ + { + "enum": [ + "avatar", + "chat", + "post", + "verification", + "dispute" + ], + "type": "string", + "description": "文件类型限制", + "name": "type", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "url": { + "description": "返回 CDN 地址或访问地址", + "type": "string" + } + } + } + } + } + } + } + }, + "x-date": "2026-03-26 17:05:36", + "x-description": "This is a goctl generated swagger file.", + "x-github": "https://github.com/zeromicro/go-zero", + "x-go-zero-doc": "https://go-zero.dev/", + "x-goctl-version": "1.9.2" +} \ No newline at end of file diff --git a/desc/api/docs/player-api.json b/desc/api/docs/player-api.json new file mode 100644 index 0000000..3db5ec2 --- /dev/null +++ b/desc/api/docs/player-api.json @@ -0,0 +1,978 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "swagger": "2.0", + "info": { + "title": "聚玩打手服务", + "version": "1.0" + }, + "basePath": "/", + "paths": { + "/api/v1/players": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取打手列表", + "operationId": "playerListPlayers", + "parameters": [ + { + "type": "integer", + "default": 0, + "name": "offset", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "limit", + "in": "query", + "required": true + }, + { + "type": "integer", + "name": "gameId", + "in": "query", + "allowEmptyValue": true + }, + { + "type": "integer", + "name": "gender", + "in": "query", + "allowEmptyValue": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "user", + "rating", + "totalOrders", + "completionRate", + "status", + "games", + "services", + "tags" + ], + "properties": { + "completionRate": { + "type": "number" + }, + "games": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "rating": { + "type": "number" + }, + "services": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + }, + "shopId": { + "type": "string" + }, + "shopName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "totalOrders": { + "type": "integer" + }, + "user": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "meta": { + "type": "object", + "required": [ + "total", + "offset", + "limit" + ], + "properties": { + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } + } + } + } + } + }, + "/api/v1/players/me/status": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "更新接单状态", + "operationId": "playerUpdatePlayerStatus", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/players/{id}": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取打手详情", + "operationId": "playerGetPlayer", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "completionRate": { + "type": "number" + }, + "games": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "rating": { + "type": "number" + }, + "services": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + }, + "shopId": { + "type": "string" + }, + "shopName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "totalOrders": { + "type": "integer" + }, + "user": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "/api/v1/players/{id}/services": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取指定打手的服务列表", + "operationId": "playerListPlayerServices", + "parameters": [ + { + "type": "integer", + "default": 0, + "name": "offset", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "limit", + "in": "query", + "required": true + }, + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "required": [ + "total", + "offset", + "limit" + ], + "properties": { + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } + } + } + } + } + }, + "/api/v1/services": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取所有服务列表", + "operationId": "playerListServices", + "parameters": [ + { + "type": "integer", + "default": 0, + "name": "offset", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "limit", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "playerId", + "gameId", + "gameName", + "title", + "description", + "price", + "unit", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "required": [ + "total", + "offset", + "limit" + ], + "properties": { + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "创建服务", + "operationId": "playerCreateService", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "gameId", + "price", + "unit" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + } + } + } + }, + "/api/v1/services/{id}": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取服务详情", + "operationId": "playerGetService", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + } + } + }, + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "更新服务", + "operationId": "playerUpdateService", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "gameId", + "availability" + ], + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "availability": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "gameId": { + "type": "integer" + }, + "gameName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "playerId": { + "type": "integer" + }, + "price": { + "type": "number" + }, + "rankRange": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + } + } + } + } + }, + "delete": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "删除服务", + "operationId": "playerDeleteService", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + } + }, + "x-date": "2026-03-29 23:48:43", + "x-description": "This is a goctl generated swagger file.", + "x-github": "https://github.com/zeromicro/go-zero", + "x-go-zero-doc": "https://go-zero.dev/", + "x-goctl-version": "1.9.2" +} \ No newline at end of file diff --git a/desc/api/docs/shop-api.json b/desc/api/docs/shop-api.json new file mode 100644 index 0000000..c31a911 --- /dev/null +++ b/desc/api/docs/shop-api.json @@ -0,0 +1,1113 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "swagger": "2.0", + "info": { + "version": "1.0" + }, + "basePath": "/", + "paths": { + "/api/v1/shops": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取店铺列表", + "operationId": "shopListShops", + "parameters": [ + { + "type": "integer", + "default": 0, + "name": "offset", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "limit", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "owner", + "name", + "description", + "rating", + "totalOrders", + "playerCount", + "commissionType", + "commissionValue", + "announcements", + "templateConfig" + ], + "properties": { + "announcements": { + "type": "array", + "items": { + "type": "string" + } + }, + "banner": { + "type": "string" + }, + "commissionType": { + "type": "string" + }, + "commissionValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "playerCount": { + "type": "integer" + }, + "rating": { + "type": "string" + }, + "templateConfig": {}, + "totalOrders": { + "type": "integer" + } + } + } + }, + "meta": { + "type": "object", + "required": [ + "total", + "offset", + "limit" + ], + "properties": { + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "创建店铺", + "operationId": "shopCreateShop", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "name", + "description", + "commissionType", + "commissionValue" + ], + "properties": { + "commissionType": { + "type": "string" + }, + "commissionValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "announcements": { + "type": "array", + "items": { + "type": "string" + } + }, + "banner": { + "type": "string" + }, + "commissionType": { + "type": "string" + }, + "commissionValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "playerCount": { + "type": "integer" + }, + "rating": { + "type": "string" + }, + "templateConfig": {}, + "totalOrders": { + "type": "integer" + } + } + } + } + } + } + }, + "/api/v1/shops/invitations/{id}": { + "delete": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "拒绝邀请", + "operationId": "shopRejectInvitation", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/shops/invitations/{id}/accept": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "接受邀请", + "operationId": "shopAcceptInvitation", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/shops/mine": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取当前用户的店铺", + "operationId": "shopGetMyShop", + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "announcements": { + "type": "array", + "items": { + "type": "string" + } + }, + "banner": { + "type": "string" + }, + "commissionType": { + "type": "string" + }, + "commissionValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "playerCount": { + "type": "integer" + }, + "rating": { + "type": "string" + }, + "templateConfig": {}, + "totalOrders": { + "type": "integer" + } + } + } + } + } + } + }, + "/api/v1/shops/{id}": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取店铺详情", + "operationId": "shopGetShop", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "announcements": { + "type": "array", + "items": { + "type": "string" + } + }, + "banner": { + "type": "string" + }, + "commissionType": { + "type": "string" + }, + "commissionValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "playerCount": { + "type": "integer" + }, + "rating": { + "type": "string" + }, + "templateConfig": {}, + "totalOrders": { + "type": "integer" + } + } + } + } + } + }, + "put": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "更新店铺信息", + "operationId": "shopUpdateShop", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "announcements": { + "type": "array", + "items": { + "type": "string" + } + }, + "banner": { + "type": "string" + }, + "commissionType": { + "type": "string" + }, + "commissionValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "playerCount": { + "type": "integer" + }, + "rating": { + "type": "string" + }, + "templateConfig": {}, + "totalOrders": { + "type": "integer" + } + } + } + } + } + } + }, + "/api/v1/shops/{id}/announcements": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "新增店铺公告", + "operationId": "shopAddAnnouncement", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "content" + ], + "properties": { + "content": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/shops/{id}/announcements/{index}": { + "delete": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "删除店铺公告", + "operationId": "shopDeleteAnnouncement", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/shops/{id}/income-stats": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取收入统计", + "operationId": "shopGetShopIncomeStats", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "completedOrders": { + "type": "integer" + }, + "monthlyIncome": { + "type": "string" + }, + "pendingSettlement": { + "type": "string" + }, + "totalOrders": { + "type": "integer" + }, + "totalWithdrawn": { + "type": "string" + } + } + } + } + } + } + }, + "/api/v1/shops/{id}/invitations": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "邀请打手", + "operationId": "shopInvitePlayer", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "playerId" + ], + "properties": { + "playerId": { + "type": "integer" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/shops/{id}/players/{playerId}": { + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "移除打手", + "operationId": "shopRemovePlayer", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "playerId" + ], + "properties": { + "playerId": { + "type": "integer" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/shops/{id}/template": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "更新店铺模板", + "operationId": "shopUpdateShopTemplate", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "sections" + ], + "properties": { + "sections": {} + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/users/{id}/shop": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取店长的店铺", + "operationId": "shopGetUserShop", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "announcements": { + "type": "array", + "items": { + "type": "string" + } + }, + "banner": { + "type": "string" + }, + "commissionType": { + "type": "string" + }, + "commissionValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "playerCount": { + "type": "integer" + }, + "rating": { + "type": "string" + }, + "templateConfig": {}, + "totalOrders": { + "type": "integer" + } + } + } + } + } + } + } + }, + "x-date": "2026-03-18 18:48:06", + "x-description": "This is a goctl generated swagger file.", + "x-github": "https://github.com/zeromicro/go-zero", + "x-go-zero-doc": "https://go-zero.dev/", + "x-goctl-version": "1.9.2" +} \ No newline at end of file diff --git a/desc/api/docs/user-api.json b/desc/api/docs/user-api.json new file mode 100644 index 0000000..9ecc396 --- /dev/null +++ b/desc/api/docs/user-api.json @@ -0,0 +1,1110 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "swagger": "2.0", + "info": { + "title": "聚玩用户服务", + "version": "1.0" + }, + "basePath": "/", + "paths": { + "/api/v1/admin/verifications": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "管理员获取认证申请列表 (分页)", + "operationId": "verificationAdminGetVerifications", + "parameters": [ + { + "type": "integer", + "default": 1, + "name": "page", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "size", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "筛选角色", + "name": "role", + "in": "query", + "allowEmptyValue": true + }, + { + "type": "string", + "description": "筛选状态,默认 pending", + "name": "status", + "in": "query", + "allowEmptyValue": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "userId", + "userNickname", + "role", + "status", + "materials", + "rejectReason", + "createdAt", + "reviewedAt" + ], + "properties": { + "createdAt": { + "description": "申请时间", + "type": "string" + }, + "id": { + "description": "认证记录ID (主键,用于管理员操作)", + "type": "integer" + }, + "materials": { + "description": "核心字段:对应 DB 的 JSONB", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "rejectReason": { + "description": "驳回原因", + "type": "string" + }, + "reviewedAt": { + "description": "审核时间", + "type": "string" + }, + "role": { + "description": "申请角色: player, owner", + "type": "string" + }, + "status": { + "description": "pending, approved, rejected", + "type": "string" + }, + "userId": { + "description": "申请人ID (外键)", + "type": "integer" + }, + "userNickname": { + "description": "冗余显示,方便前端展示", + "type": "string" + } + } + } + }, + "total": { + "type": "integer" + } + } + } + } + } + } + }, + "/api/v1/admin/verifications/{id}/approve": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "管理员通过申请", + "operationId": "verificationAdminApproveVerification", + "parameters": [ + { + "type": "integer", + "description": "注意:这是 user_verifications.id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/admin/verifications/{id}/reject": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "管理员驳回申请", + "operationId": "verificationAdminRejectVerification", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "reason" + ], + "properties": { + "reason": { + "description": "必填:驳回原因", + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/auth/forgot-password": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "忘记密码-发送验证码", + "operationId": "authForgotPassword", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "phone", + "email" + ], + "properties": { + "email": { + "type": "string" + }, + "phone": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/auth/login": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "用户登录", + "operationId": "authLogin", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "username", + "password" + ], + "properties": { + "password": { + "type": "string" + }, + "phone": { + "description": "手机号登录", + "type": "string" + }, + "remember": { + "type": "boolean" + }, + "username": { + "description": "或用户名登录", + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "user": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "phone", + "bio", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "description": "ISO 8601", + "type": "string" + }, + "id": { + "type": "integer" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "description": "e.g. {\"player\": \"approved\"}", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "description": "e.g. [\"consumer\", \"player\"]", + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "/api/v1/auth/logout": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "退出登录", + "operationId": "authLogout", + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/auth/register": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "用户注册", + "operationId": "authRegister", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "email", + "username", + "password", + "vcode" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "username": { + "type": "string" + }, + "vcode": { + "description": "验证码", + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "user": { + "type": "object", + "required": [ + "id", + "username", + "nickname", + "avatar", + "role", + "verifiedRoles", + "verificationStatus", + "phone", + "bio", + "createdAt" + ], + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "description": "ISO 8601", + "type": "string" + }, + "id": { + "type": "integer" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "description": "e.g. {\"player\": \"approved\"}", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "description": "e.g. [\"consumer\", \"player\"]", + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "/api/v1/auth/reset-password": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "重置密码", + "operationId": "authResetPassword", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "phone", + "email", + "vcode", + "newPassword" + ], + "properties": { + "email": { + "type": "string" + }, + "newPassword": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "vcode": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/users/me": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取当前登录用户信息", + "operationId": "userGetMe", + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "description": "ISO 8601", + "type": "string" + }, + "id": { + "type": "integer" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "description": "e.g. {\"player\": \"approved\"}", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "description": "e.g. [\"consumer\", \"player\"]", + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "更新个人资料", + "operationId": "userUpdateMe", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "nickname": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "description": "ISO 8601", + "type": "string" + }, + "id": { + "type": "integer" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "description": "e.g. {\"player\": \"approved\"}", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "description": "e.g. [\"consumer\", \"player\"]", + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + }, + "/api/v1/users/me/preferences/notifications": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "更新通知偏好", + "operationId": "userUpdateNotificationSettings", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "community": { + "type": "boolean" + }, + "order": { + "type": "boolean" + }, + "system": { + "type": "boolean" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/users/me/preferences/theme": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "更新主题偏好", + "operationId": "userUpdateThemeSettings", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "theme" + ], + "properties": { + "theme": { + "description": "dark, light", + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/users/me/switch-role": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "切换当前激活角色", + "operationId": "userSwitchRole", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "role" + ], + "properties": { + "role": { + "description": "目标角色", + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/users/me/verification": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取我的所有认证状态", + "operationId": "verificationUserGetMyVerifications", + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "userId", + "userNickname", + "role", + "status", + "materials", + "rejectReason", + "createdAt", + "reviewedAt" + ], + "properties": { + "createdAt": { + "description": "申请时间", + "type": "string" + }, + "id": { + "description": "认证记录ID (主键,用于管理员操作)", + "type": "integer" + }, + "materials": { + "description": "核心字段:对应 DB 的 JSONB", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "rejectReason": { + "description": "驳回原因", + "type": "string" + }, + "reviewedAt": { + "description": "审核时间", + "type": "string" + }, + "role": { + "description": "申请角色: player, owner", + "type": "string" + }, + "status": { + "description": "pending, approved, rejected", + "type": "string" + }, + "userId": { + "description": "申请人ID (外键)", + "type": "integer" + }, + "userNickname": { + "description": "冗余显示,方便前端展示", + "type": "string" + } + } + } + } + } + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "提交或修改角色认证申请 (支持幂等更新)", + "operationId": "verificationUserApplyVerification", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "role", + "materials" + ], + "properties": { + "materials": { + "description": "证明材料键值对 {\"idCardFront\": \"http...\", \"license\": \"http...\"}", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "role": { + "description": "申请什么角色", + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/users/{id}": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取指定用户信息", + "operationId": "userGetUserInfo", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "createdAt": { + "description": "ISO 8601", + "type": "string" + }, + "id": { + "type": "integer" + }, + "nickname": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "role": { + "description": "consumer, player, owner, admin", + "type": "string" + }, + "username": { + "type": "string" + }, + "verificationStatus": { + "description": "e.g. {\"player\": \"approved\"}", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "verifiedRoles": { + "description": "e.g. [\"consumer\", \"player\"]", + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + }, + "/api/v1/users/{id}/follow": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "关注用户", + "operationId": "userFollowUser", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + }, + "delete": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "取消关注用户", + "operationId": "userUnfollowUser", + "parameters": [ + { + "type": "integer", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + } + }, + "x-date": "2026-03-18 18:48:12", + "x-description": "This is a goctl generated swagger file.", + "x-github": "https://github.com/zeromicro/go-zero", + "x-go-zero-doc": "https://go-zero.dev/", + "x-goctl-version": "1.9.2" +} \ No newline at end of file diff --git a/desc/api/docs/wallet-api.json b/desc/api/docs/wallet-api.json new file mode 100644 index 0000000..656a754 --- /dev/null +++ b/desc/api/docs/wallet-api.json @@ -0,0 +1,232 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "swagger": "2.0", + "info": { + "title": "钱包服务", + "version": "1.0" + }, + "basePath": "/", + "paths": { + "/api/v1/wallet/balance": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取余额", + "operationId": "walletGetBalance", + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "balance": { + "type": "string" + }, + "frozenBalance": { + "type": "string" + } + } + } + } + } + } + }, + "/api/v1/wallet/topup": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "充值", + "operationId": "walletTopup", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "amount", + "method" + ], + "properties": { + "amount": { + "type": "string" + }, + "method": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + }, + "/api/v1/wallet/transactions": { + "get": { + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "获取流水", + "operationId": "walletListTransactions", + "parameters": [ + { + "type": "integer", + "default": 0, + "name": "offset", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "name": "limit", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "type", + "amount", + "description", + "createdAt" + ], + "properties": { + "amount": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "orderId": { + "type": "string" + }, + "type": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "required": [ + "total", + "offset", + "limit" + ], + "properties": { + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } + } + } + } + } + }, + "/api/v1/wallet/withdraw": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https" + ], + "summary": "提现", + "operationId": "walletWithdraw", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "amount", + "method" + ], + "properties": { + "amount": { + "type": "string" + }, + "method": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "", + "schema": { + "type": "object" + } + } + } + } + } + }, + "x-date": "2026-03-26 17:02:28", + "x-description": "This is a goctl generated swagger file.", + "x-github": "https://github.com/zeromicro/go-zero", + "x-go-zero-doc": "https://go-zero.dev/", + "x-goctl-version": "1.9.2" +} \ No newline at end of file diff --git a/desc/api/game.api b/desc/api/game.api index 15aa996..544ba5d 100644 --- a/desc/api/game.api +++ b/desc/api/game.api @@ -30,5 +30,9 @@ service game-api { @doc "获取游戏详情" @handler GetGame get /:id (GetGameReq) returns (Game) + + @doc "创建游戏" + @handler CreateGame + post / (Game) returns (Game) } diff --git a/desc/api/objectstory.api b/desc/api/objectstory.api index 7992a43..ef268e6 100644 --- a/desc/api/objectstory.api +++ b/desc/api/objectstory.api @@ -18,7 +18,7 @@ type ( } // 获取文件请求(用于私有文件或代理访问) GetFileReq { - FileId string `path:"fileId"` + FileId string `form:"key"` } ) @@ -34,6 +34,6 @@ service file-api { @doc "文件获取接口 (如果是私有文件,通过此接口获取或重定向)" @handler GetFile - get /files/:fileId (GetFileReq) + get /files (GetFileReq) } diff --git a/desc/api/order.api b/desc/api/order.api index 7ec7929..5f74bcd 100644 --- a/desc/api/order.api +++ b/desc/api/order.api @@ -1,10 +1,29 @@ syntax = "v1" import "common.api" +info ( + title: "聚玩订单服务" + desc: "处理订单业务" + author: "Asadz" + version: "1.0" +) + type ( PathId { Id int64 `path:"id"` } + PlayerService { + Id int64 `json:"id"` + PlayerId int64 `json:"playerId"` + GameId int64 `json:"gameId"` + GameName string `json:"gameName"` + Title string `json:"title"` + Description string `json:"description"` + Price float64 `json:"price"` + Unit string `json:"unit"` + RankRange string `json:"rankRange,optional"` + Availability []string `json:"availability"` + } Order { Id int64 `json:"id"` ConsumerId int64 `json:"consumerId"` diff --git a/desc/api/player.api b/desc/api/player.api index 0685f33..47e6341 100644 --- a/desc/api/player.api +++ b/desc/api/player.api @@ -1,5 +1,12 @@ syntax = "v1" +info ( + title: "聚玩打手服务" + desc: "聚玩用户服务处理打手信息管理、服务发布及订单相关接口" + author: "Asadz" + version: "1.0" +) + import "common.api" type ( @@ -50,12 +57,13 @@ type ( Services []PlayerService `json:"services"` ShopId string `json:"shopId,optional"` ShopName string `json:"shopName,optional"` + Gender bool `json:"gender"` Tags []string `json:"tags"` } PlayerListReq { PageReq GameId int64 `form:"gameId,optional"` - Gender int `form:"gender,optional"` + Gender int64 `form:"gender,optional"` } PlayerListResp { Items []PlayerProfile `json:"items"` diff --git a/desc/api/shop.api b/desc/api/shop.api index f381e14..fdd0a3a 100644 --- a/desc/api/shop.api +++ b/desc/api/shop.api @@ -110,7 +110,7 @@ service shop-api { @doc "更新店铺信息" @handler UpdateShop - put /shops/:id (ShopIdReq) returns (ShopProfile) + put /shops/:id (UpdateShopReq) returns (ShopProfile) @doc "更新店铺模板" @handler UpdateShopTemplate diff --git a/desc/api/user_verifications.api b/desc/api/user_verifications.api index d991f7d..c2144cf 100644 --- a/desc/api/user_verifications.api +++ b/desc/api/user_verifications.api @@ -1,53 +1,53 @@ -syntax = "v1" - -info ( - title: "聚玩认证审核服务" - desc: "处理用户角色认证申请(打手/店长)及管理员审核流程" - author: "Asadz" - version: "1.0" -) - -// ================================================================================= -// 数据结构定义 (Data Structures) -// ================================================================================= - -// ================================================================================= -// 用户端接口 (User Side) -// 路径前缀: /api/v1/users -// ================================================================================= -@server ( - group: verification_user - prefix: /api/v1/users -) -service verification-api { - @doc "提交或修改角色认证申请 (支持幂等更新)" - @handler ApplyVerification - post /me/verification (ApplyVerificationReq) returns (VerificationEmptyResp) - - @doc "获取我的所有认证状态" - @handler GetMyVerifications - get /me/verification returns (GetMyVerificationsResp) -} - -// ================================================================================= -// 管理端接口 (Admin Side) -// 路径前缀: /api/v1/admin -// ================================================================================= -@server ( - group: verification_admin - prefix: /api/v1/admin -) -service verification-api { - @doc "管理员获取认证申请列表 (分页)" - @handler GetVerifications - get /verifications (GetPendingListReq) returns (GetPendingListResp) - - @doc "管理员通过申请" - @handler ApproveVerification - post /verifications/:id/approve (VerificationIdReq) returns (VerificationEmptyResp) - - @doc "管理员驳回申请" - @handler RejectVerification - post /verifications/:id/reject (RejectVerificationReq) returns (VerificationEmptyResp) -} - +//syntax = "v1" +// +//info ( +// title: "聚玩认证审核服务" +// desc: "处理用户角色认证申请(打手/店长)及管理员审核流程" +// author: "Asadz" +// version: "1.0" +//) +// +//// ================================================================================= +//// 数据结构定义 (Data Structures) +//// ================================================================================= +// +//// ================================================================================= +//// 用户端接口 (User Side) +//// 路径前缀: /api/v1/users +//// ================================================================================= +//@server ( +// group: verification_user +// prefix: /api/v1/users +//) +//service verification-api { +// @doc "提交或修改角色认证申请 (支持幂等更新)" +// @handler ApplyVerification +// post /me/verification (ApplyVerificationReq) returns (VerificationEmptyResp) +// +// @doc "获取我的所有认证状态" +// @handler GetMyVerifications +// get /me/verification returns (GetMyVerificationsResp) +//} +// +//// ================================================================================= +//// 管理端接口 (Admin Side) +//// 路径前缀: /api/v1/admin +//// ================================================================================= +//@server ( +// group: verification_admin +// prefix: /api/v1/admin +//) +//service verification-api { +// @doc "管理员获取认证申请列表 (分页)" +// @handler GetVerifications +// get /verifications (GetPendingListReq) returns (GetPendingListResp) +// +// @doc "管理员通过申请" +// @handler ApproveVerification +// post /verifications/:id/approve (VerificationIdReq) returns (VerificationEmptyResp) +// +// @doc "管理员驳回申请" +// @handler RejectVerification +// post /verifications/:id/reject (RejectVerificationReq) returns (VerificationEmptyResp) +//} +// diff --git a/desc/api/users.api b/desc/api/users.api index ac77e96..a7dd342 100644 --- a/desc/api/users.api +++ b/desc/api/users.api @@ -8,6 +8,13 @@ info ( ) type ( + // 认证材料结构体(示例,实际根据需求定义) + MaterialJson { + IdCardFront string `json:"idCardFront"` // 身份证正面照片URL + IdCardBack string `json:"idCardBack"` // 身份证反面照片URL + GameScreenshots []*string `json:"gameScreenshots,optional"` // 游戏截图URL列表 + VoiceDemo *string `json:"voiceDemo,optional"` // 语音认证示例URL + } // 认证记录展示对象 // 对应数据库 user_verifications 表 VerificationItem { @@ -23,8 +30,8 @@ type ( } // 提交申请请求 ApplyVerificationReq { - Role string `json:"role"` // 申请什么角色 - Materials map[string]string `json:"materials"` // 证明材料键值对 {"idCardFront": "http...", "license": "http..."} + Role string `json:"role"` // 申请什么角色 + Materials MaterialJson `json:"materials"` // 证明材料键值对 {"idCardFront": "http...", "license": "http..."} } // 获取我的申请记录响应 GetMyVerificationsResp { @@ -235,9 +242,8 @@ service user-api { } @server ( - group: verification_user - prefix: /api/v1/users - middleware: Logger // 必须登录 + group: verification_user + prefix: /api/v1/users ) service user-api { @doc "提交或修改角色认证申请 (支持幂等更新)" diff --git a/desc/api/wallet.api b/desc/api/wallet.api index 6194cab..ff5eef2 100644 --- a/desc/api/wallet.api +++ b/desc/api/wallet.api @@ -1,5 +1,12 @@ syntax = "v1" +info ( + title: "钱包服务" + desc: "处理钱包充值相关" + author: "Asadz" + version: "1.0" +) + import "common.api" type ( diff --git a/desc/rpc/player.proto b/desc/rpc/player.proto index c8a4ee9..305536d 100644 --- a/desc/rpc/player.proto +++ b/desc/rpc/player.proto @@ -112,7 +112,7 @@ message Players { repeated int64 games = 9; //games int64 createdAt = 10; //createdAt int64 updatedAt = 11; //updatedAt - int64 gender = 12; //gender + bool gender = 12; //gender } message AddPlayersReq { @@ -166,20 +166,20 @@ message GetPlayersByIdResp { } message SearchPlayersReq { - int64 page = 1; //page - int64 limit = 2; //limit - int64 id = 3; //id - int64 userId = 4; //userId - string status = 5; //status - double rating = 6; //rating - int64 totalOrders = 7; //totalOrders - int64 completedOrders = 8; //completedOrders - int64 shopId = 9; //shopId + optional int64 page = 1; //page + optional int64 limit = 2; //limit + optional int64 id = 3; //id + optional int64 userId = 4; //userId + optional string status = 5; //status + optional double rating = 6; //rating + optional int64 totalOrders = 7; //totalOrders + optional int64 completedOrders = 8; //completedOrders + optional int64 shopId = 9; //shopId repeated string tags = 10; //tags repeated int64 games = 11; //games - int64 createdAt = 12; //createdAt - int64 updatedAt = 13; //updatedAt - int64 gender = 14; //gender + optional int64 createdAt = 12; //createdAt + optional int64 updatedAt = 13; //updatedAt + optional int64 gender = 14; //gender } message SearchPlayersResp { diff --git a/desc/rpc/user_verifications.proto b/desc/rpc/user_verifications.proto index bfcfa65..81d09cc 100644 --- a/desc/rpc/user_verifications.proto +++ b/desc/rpc/user_verifications.proto @@ -87,6 +87,23 @@ message SearchUserVerificationsResp { repeated UserVerifications userVerifications = 1; //userVerifications } +message AddOrUpdateUserVerificationsReq { + int64 userId = 1; // userId + string role = 2; + string material = 3; // material +} + +message AddOrUpdateUserVerificationsResp { + bool success = 1; // success +} + +message ListUserVerificationsByUserIdReq { + int64 userId = 1; // userId +} + +message ListUserVerificationsByUserIdResp { + repeated UserVerifications userVerifications = 1; // userVerifications +} // ------------------------------------ @@ -100,6 +117,8 @@ service user_verifications{ rpc UpdateUserVerifications(UpdateUserVerificationsReq) returns (UpdateUserVerificationsResp); rpc DelUserVerifications(DelUserVerificationsReq) returns (DelUserVerificationsResp); rpc GetUserVerificationsById(GetUserVerificationsByIdReq) returns (GetUserVerificationsByIdResp); - rpc SearchUserVerifications(SearchUserVerificationsReq) returns (SearchUserVerificationsResp); + rpc SearchUserVerifications(SearchUserVerificationsReq) returns (SearchUserVerificationsResp); + rpc AddOrUpdateUserVerifications(AddOrUpdateUserVerificationsReq) returns (AddOrUpdateUserVerificationsResp); + rpc ListUserVerificationsByUserId(ListUserVerificationsByUserIdReq) returns (ListUserVerificationsByUserIdResp); } diff --git a/desc/rpc/users.proto b/desc/rpc/users.proto index 8c6385e..39c7372 100644 --- a/desc/rpc/users.proto +++ b/desc/rpc/users.proto @@ -4,9 +4,9 @@ option go_package = "./pb"; package pb; -// ------------------------------------ +// ------------------------------------ // Messages -// ------------------------------------ +// ------------------------------------ //--------------------------------users-------------------------------- //--------------------------------users-------------------------------- @@ -125,30 +125,30 @@ message LoginResp { string token = 1; string username = 2; string email = 3; - int64 id = 4; + int64 id = 4; } message ValidateTokenReq { - string token = 1; // JWT token - int64 userId = 2; // 用户ID + string token = 1; // JWT token + int64 userId = 2; // 用户ID } message ValidateTokenResp { - bool valid = 1; // token 是否有效(不在黑名单中) - string message = 2; // 验证失败原因 - int64 userId = 3; // 用户ID - string roleType = 4; // 用户角色 + bool valid = 1; // token 是否有效(不在黑名单中) + string message = 2; // 验证失败原因 + int64 userId = 3; // 用户ID + string roleType = 4; // 用户角色 } message CheckPermissionReq { - int64 userId = 1; // 用户ID - string resource = 2; // 资源 ID - string action = 3; // 操作类型: read/write/delete + int64 userId = 1; // 用户ID + string resource = 2; // 资源 ID + string action = 3; // 操作类型: read/write/delete } message CheckPermissionResp { - bool allowed = 1; // 是否有权限 - string message = 2; // 拒绝原因 + bool allowed = 1; // 是否有权限 + string message = 2; // 拒绝原因 } message RegisterReq { @@ -182,9 +182,143 @@ message ResetPasswordReq { message ResetPasswordResp { } + +message SwitchRoleReq { + int64 userId = 1; + string newRole = 2; +} + +message SwitchRoleResp { + bool success = 1; +} + +//--------------------------------userFollows-------------------------------- +message UserFollows { + int64 id = 1; //id + int64 followerId = 2; //followerId + int64 followeeId = 3; //followeeId + int64 createdAt = 4; //createdAt +} + +message AddUserFollowsReq { + int64 followerId = 1; //followerId + int64 followeeId = 2; //followeeId + int64 createdAt = 3; //createdAt +} + +message AddUserFollowsResp { +} + +message UpdateUserFollowsReq { + int64 id = 1; //id + int64 followerId = 2; //followerId + int64 followeeId = 3; //followeeId + int64 createdAt = 4; //createdAt +} + +message UpdateUserFollowsResp { +} + +message DelUserFollowsReq { + int64 id = 1; //id + int64 userId = 2; // userId +} + +message DelUserFollowsResp { +} + +message GetUserFollowsByIdReq { + int64 id = 1; //id +} + +message GetUserFollowsByIdResp { + UserFollows userFollows = 1; //userFollows +} + +message SearchUserFollowsReq { + int64 page = 1; //page + int64 limit = 2; //limit + int64 id = 3; //id + int64 followerId = 4; //followerId + int64 followeeId = 5; //followeeId + int64 createdAt = 6; //createdAt +} + +message SearchUserFollowsResp { + repeated UserFollows userFollows = 1; //userFollows +} + +//--------------------------------userPreferences-------------------------------- +message UserPreferences { + int64 userId = 1; //userId + bool notificationOrder = 2; //notificationOrder + bool notificationCommunity = 3; //notificationCommunity + bool notificationSystem = 4; //notificationSystem + string theme = 5; //theme + string language = 6; //language + int64 updatedAt = 7; //updatedAt +} + +message AddUserPreferencesReq { + int64 userId = 1; //userId + bool notificationOrder = 2; //notificationOrder + bool notificationCommunity = 3; //notificationCommunity + bool notificationSystem = 4; //notificationSystem + string theme = 5; //theme + string language = 6; //language + int64 updatedAt = 7; //updatedAt +} + +message AddUserPreferencesResp { +} + +message UpdateUserPreferencesReq { + int64 userId = 1; //userId + bool notificationOrder = 2; //notificationOrder + bool notificationCommunity = 3; //notificationCommunity + bool notificationSystem = 4; //notificationSystem + string theme = 5; //theme + string language = 6; //language + int64 updatedAt = 7; //updatedAt +} + +message UpdateUserPreferencesResp { +} + +message DelUserPreferencesReq { + int64 id = 1; //id +} + +message DelUserPreferencesResp { +} + +message GetUserPreferencesByIdReq { + int64 id = 1; //id +} + +message GetUserPreferencesByIdResp { + UserPreferences userPreferences = 1; //userPreferences +} + +message SearchUserPreferencesReq { + int64 page = 1; //page + int64 limit = 2; //limit + int64 userId = 3; //userId + bool notificationOrder = 4; //notificationOrder + bool notificationCommunity = 5; //notificationCommunity + bool notificationSystem = 6; //notificationSystem + string theme = 7; //theme + string language = 8; //language + int64 updatedAt = 9; //updatedAt +} + +message SearchUserPreferencesResp { + repeated UserPreferences userPreferences = 1; //userPreferences +} + // ------------------------------------ // Rpc Func -// ------------------------------------ +// ------------------------------------ service usercenter { @@ -193,12 +327,28 @@ service usercenter { rpc UpdateUsers(UpdateUsersReq) returns (UpdateUsersResp); rpc DelUsers(DelUsersReq) returns (DelUsersResp); rpc GetUsersById(GetUsersByIdReq) returns (GetUsersByIdResp); - rpc GetUserByUsername(GetUserByUsernameReq) returns (GetUserByUsernameResp); rpc SearchUsers(SearchUsersReq) returns (SearchUsersResp); + + rpc GetUserByUsername(GetUserByUsernameReq) returns (GetUserByUsernameResp); rpc Login(LoginReq) returns (LoginResp); rpc Register(RegisterReq) returns (RegisterResp); rpc ValidateToken(ValidateTokenReq) returns (ValidateTokenResp); rpc CheckPermission(CheckPermissionReq) returns (CheckPermissionResp); rpc Logout(LogoutReq) returns (LogoutResp); rpc ResetPassword(ResetPasswordReq) returns (ResetPasswordResp); + rpc SwitchRole(SwitchRoleReq) returns (SwitchRoleResp); + + + //-----------------------userFollows----------------------- + rpc AddUserFollows(AddUserFollowsReq) returns (AddUserFollowsResp); + rpc UpdateUserFollows(UpdateUserFollowsReq) returns (UpdateUserFollowsResp); + rpc DelUserFollows(DelUserFollowsReq) returns (DelUserFollowsResp); + rpc GetUserFollowsById(GetUserFollowsByIdReq) returns (GetUserFollowsByIdResp); + rpc SearchUserFollows(SearchUserFollowsReq) returns (SearchUserFollowsResp); + //-----------------------userPreferences----------------------- + rpc AddUserPreferences(AddUserPreferencesReq) returns (AddUserPreferencesResp); + rpc UpdateUserPreferences(UpdateUserPreferencesReq) returns (UpdateUserPreferencesResp); + rpc DelUserPreferences(DelUserPreferencesReq) returns (DelUserPreferencesResp); + rpc GetUserPreferencesById(GetUserPreferencesByIdReq) returns (GetUserPreferencesByIdResp); + rpc SearchUserPreferences(SearchUserPreferencesReq) returns (SearchUserPreferencesResp); } diff --git a/desc/sql/order/orders.sql b/desc/sql/order/00-orders.sql similarity index 100% rename from desc/sql/order/orders.sql rename to desc/sql/order/00-orders.sql diff --git a/desc/sql/player/players.sql b/desc/sql/player/players.sql index 308ddfa..486eb03 100644 --- a/desc/sql/player/players.sql +++ b/desc/sql/player/players.sql @@ -9,7 +9,7 @@ CREATE TABLE players -- [注意] 此字段为冗余缓存,通过消息队列与 shop_players 表保持一致 shop_id BIGINT, - gender bool default 1 not null , + gender bool default true not null , tags TEXT[] DEFAULT ARRAY[]::TEXT[], games BIGINT[] DEFAULT ARRAY[]::BIGINT[], created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), diff --git a/desc/sql/shop/shop_players.sql b/desc/sql/shop/shop_players.sql index 23c7988..3b6bc81 100644 --- a/desc/sql/shop/shop_players.sql +++ b/desc/sql/shop/shop_players.sql @@ -15,6 +15,6 @@ CREATE TABLE shop_players CREATE INDEX idx_shop_players_player ON shop_players (player_id) WHERE left_at IS NULL; CREATE INDEX idx_shop_players_shop_active ON shop_players (shop_id, joined_at DESC) WHERE left_at IS NULL; --- [新增] 唯一索引:确保一个打手同一时间只能有一个主店铺 +-- 唯一索引:确保一个打手同一时间只能有一个主店铺 CREATE UNIQUE INDEX idx_shop_players_one_primary ON shop_players (player_id) WHERE is_primary = TRUE AND left_at IS NULL; diff --git a/desc/sql/users/user_verifications.sql b/desc/sql/users/user_verifications.sql index 794fb1b..899057a 100644 --- a/desc/sql/users/user_verifications.sql +++ b/desc/sql/users/user_verifications.sql @@ -38,6 +38,7 @@ CREATE TRIGGER trigger_sync_verifications FOR EACH ROW EXECUTE FUNCTION sync_user_verification_status(); + -- | 字段名 | 类型 | 技术含义 | 业务目的与设计思考 | -- | :--- | :--- | :--- | :--- | -- | **`id`** | BIGINT | **主键 (Primary Key)** | **这张认证申请单的唯一编号**。
后端代码在处理“审核通过”这个动作时,操作的是这个 ID(例如:`Approve(verificationId)`)。 | diff --git a/desc/sql/users/users.sql b/desc/sql/users/users.sql index 2b1e288..b38f2c1 100644 --- a/desc/sql/users/users.sql +++ b/desc/sql/users/users.sql @@ -21,9 +21,8 @@ CREATE TABLE users updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), deleted_at TIMESTAMPTZ, - CONSTRAINT chk_current_role CHECK (current_role IN ('consumer', 'player', 'owner', 'admin')) + CONSTRAINT chk_current_role CHECK ("current_role" IN ('consumer', 'player', 'owner', 'admin')) ); --- 索引 CREATE INDEX idx_users_phone ON users (phone) WHERE deleted_at IS NULL; CREATE INDEX idx_users_username_trgm ON users USING gin (username gin_trgm_ops) WHERE deleted_at IS NULL; diff --git a/desc/sql/wallet/wallets.sql b/desc/sql/wallet/00-wallets.sql similarity index 78% rename from desc/sql/wallet/wallets.sql rename to desc/sql/wallet/00-wallets.sql index 0732c05..a29434e 100644 --- a/desc/sql/wallet/wallets.sql +++ b/desc/sql/wallet/00-wallets.sql @@ -1,8 +1,8 @@ CREATE TABLE wallets ( user_id BIGINT PRIMARY KEY, - balance DECIMAL(12, 2) NOT NULL DEFAULT 0.00, - frozen_balance DECIMAL(12, 2) NOT NULL DEFAULT 0.00, + balance DECIMAL(12, 2) NOT NULL DEFAULT 0.00, -- 可用余额 + frozen_balance DECIMAL(12, 2) NOT NULL DEFAULT 0.00, -- 冻结余额 version INT NOT NULL DEFAULT 1, -- 必须使用乐观锁 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), diff --git a/app/users/api/INTEGRATION.md b/docs/INTEGRATION.md similarity index 92% rename from app/users/api/INTEGRATION.md rename to docs/INTEGRATION.md index 5741915..f002f4b 100644 --- a/app/users/api/INTEGRATION.md +++ b/docs/INTEGRATION.md @@ -1,601 +1,601 @@ -# JWT 集成指南 - -指导如何将 JWT Manager 集成到 RPC Handlers 和业务逻辑中。 - -## 1. gRPC Unary Interceptor 实现 - -在 RPC 服务中添加 JWT 验证拦截器。 - -### 创建拦截器 - -创建文件 [app/users/rpc/internal/interceptor/jwt_interceptor.go](../../../app/users/rpc/internal/interceptor/jwt_interceptor.go): - -```go -package interceptor - -import ( - "context" - "log" - - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - - "yourmodule/app/users/rpc/internal/svc" -) - -// JwtUnaryInterceptor 验证 gRPC 请求中的 JWT 令牌 -func JwtUnaryInterceptor(svcCtx *svc.ServiceContext) grpc.UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - // 获取请求元数据 - md, ok := metadata.FromIncomingContext(ctx) - if !ok { - return nil, status.Error(codes.Unauthenticated, "missing metadata") - } - - // 从 Authorization 头提取令牌 - tokens := md.Get("authorization") - if len(tokens) == 0 { - return nil, status.Error(codes.Unauthenticated, "missing authorization header") - } - - token := tokens[0] - - // 验证令牌 - claims, err := svcCtx.JwtManager.Valid(ctx, token) - if err != nil { - log.Printf("Token validation failed: %v", err) - - // 尝试刷新令牌(如果过期但仍在 Redis 中) - newToken, refreshErr := svcCtx.JwtManager.Renew(ctx, token) - if refreshErr == nil && newToken != "" { - // 在响应头中返回新令牌 - grpc.SetHeader(ctx, metadata.Pairs("authorization", newToken)) - // 继续处理请求,使用原令牌的声明 - // 注意:实际应用中需要重新验证新令牌 - newClaims, err := svcCtx.JwtManager.Valid(ctx, newToken) - if err != nil { - return nil, status.Error(codes.Unauthenticated, "token refresh failed") - } - claims = newClaims - } else { - return nil, status.Error(codes.Unauthenticated, "invalid or expired token") - } - } - - // 将声明附加到上下文,供处理器使用 - newCtx := context.WithValue(ctx, "claims", claims) - - return handler(newCtx, req) - } -} - -// JwtStreamInterceptor 验证流式 gRPC 请求中的 JWT 令牌 -func JwtStreamInterceptor(svcCtx *svc.ServiceContext) grpc.StreamServerInterceptor { - return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - md, ok := metadata.FromIncomingContext(ss.Context()) - if !ok { - return status.Error(codes.Unauthenticated, "missing metadata") - } - - tokens := md.Get("authorization") - if len(tokens) == 0 { - return status.Error(codes.Unauthenticated, "missing authorization header") - } - - token := tokens[0] - claims, err := svcCtx.JwtManager.Valid(ss.Context(), token) - if err != nil { - return status.Error(codes.Unauthenticated, "invalid token") - } - - // 创建包装流以注入上下文 - wrappedStream := &WrappedStream{ - ServerStream: ss, - ctx: context.WithValue(ss.Context(), "claims", claims), - } - - return handler(srv, wrappedStream) - } -} - -// WrappedStream 包装 grpc.ServerStream 以注入新的上下文 -type WrappedStream struct { - grpc.ServerStream - ctx context.Context -} - -func (w *WrappedStream) Context() context.Context { - return w.ctx -} -``` - -### 在 Server 中注册拦截器 - -修改 [app/users/rpc/usercenter/usercenter.go](../../../app/users/rpc/usercenter/usercenter.go): - -```go -package main - -import ( - "flag" - "fmt" - "log" - - "yourmodule/app/users/rpc/internal/config" - "yourmodule/app/users/rpc/internal/interceptor" - "yourmodule/app/users/rpc/internal/server" - "yourmodule/app/users/rpc/internal/svc" - "yourmodule/app/users/rpc/pb" - - "github.com/zeromicro/go-zero/core/conf" - "github.com/zeromicro/go-zero/core/logx" - "google.golang.org/grpc" -) - -var configFile = flag.String("f", "etc/pb.yaml", "the config file") - -func main() { - flag.Parse() - - var c config.Config - conf.MustLoad(*configFile, &c) - ctx := svc.NewServiceContext(c) - - logx.DisableStat() - - s := grpc.NewServer( - grpc.UnaryInterceptor(interceptor.JwtUnaryInterceptor(ctx)), - grpc.StreamInterceptor(interceptor.JwtStreamInterceptor(ctx)), - ) - - pb.RegisterUsercenterServer(s, server.NewUsercenterServer(ctx)) - - logx.Infof("Starting gRPC server on %s:%d", c.Host, c.Port) - if err := s.Serve(net.Listen("tcp", "0.0.0.0:"+fmt.Sprintf("%d", c.Port))); err != nil { - logx.Error(err) - } -} -``` - -## 2. 登录 Handler 实现 - -实现 [app/users/api/internal/handler/user/loginHandler.go](../../../app/users/api/internal/handler/user/loginHandler.go): - -```go -package user - -import ( - "context" - "log" - "net/http" - - "yourmodule/app/users/api/internal/logic/user" - "yourmodule/app/users/api/internal/svc" - "yourmodule/app/users/api/internal/types" -) - -// LoginHandler 处理用户登录 -func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req types.LoginRequest - - // 解析请求体... - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "Invalid request", http.StatusBadRequest) - return - } - - // 调用业务逻辑 - resp, err := user.NewLoginLogic(r.Context(), svcCtx).Login(&req) - if err != nil { - log.Printf("Login failed: %v", err) - http.Error(w, "Login failed", http.StatusUnauthorized) - return - } - - // 返回令牌 - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(resp) - } -} -``` - -实现 [app/users/api/internal/logic/user/loginLogic.go](../../../app/users/api/internal/logic/user/loginLogic.go): - -```go -package user - -import ( - "context" - "errors" - - "yourmodule/app/users/api/internal/svc" - "yourmodule/app/users/api/internal/types" -) - -type LoginLogic struct { - ctx context.Context - svcCtx *svc.ServiceContext -} - -func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic { - return &LoginLogic{ - ctx: ctx, - svcCtx: svcCtx, - } -} - -func (l *LoginLogic) Login(req *types.LoginRequest) (*types.LoginResponse, error) { - // 1. 验证用户凭证(密码等) - user, err := l.svcCtx.UserModel.FindByEmail(l.ctx, req.Email) - if err != nil { - return nil, errors.New("user not found") - } - - // 2. 验证密码 - if !user.VerifyPassword(req.Password) { - return nil, errors.New("invalid password") - } - - // 3. 生成 JWT 令牌 - token, err := l.svcCtx.JwtManager.New( - l.ctx, - user.ID, - user.Email, - user.Name, - ) - if err != nil { - return nil, errors.New("failed to generate token") - } - - // 4. 返回令牌 - return &types.LoginResponse{ - Token: token, - User: types.User{ - ID: user.ID, - Email: user.Email, - Name: user.Name, - }, - }, nil -} -``` - -## 3. 在 Handlers 中使用声明 - -在 Protected Handlers 中提取并使用声明: - -```go -package user - -import ( - "context" - "log" - "net/http" - - "yourmodule/app/users/api/internal/svc" - "yourmodule/app/users/api/internal/types" - "github.com/golang-jwt/jwt/v4" -) - -// GetUserInfoHandler 获取当前用户信息 -func GetUserInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // 从上下文提取声明(由拦截器设置) - claims, ok := r.Context().Value("claims").(*jwt.RegisteredClaims) - if !ok { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - // 使用声明中的用户信息 - userID := claims.Subject // 用户 ID 存储在 Subject 中 - log.Printf("User %s requested their info", userID) - - // 查询用户信息 - user, err := svcCtx.UserModel.FindByID(r.Context(), userID) - if err != nil { - http.Error(w, "User not found", http.StatusNotFound) - return - } - - // 返回用户信息 - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(user) - } -} -``` - -## 4. 令牌刷新端点 - -实现令牌刷新端点: - -```go -package user - -import ( - "net/http" - - "yourmodule/app/users/api/internal/svc" - "yourmodule/app/users/api/internal/types" -) - -// RefreshTokenHandler 刷新过期的 JWT 令牌 -func RefreshTokenHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req types.RefreshTokenRequest - - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "Invalid request", http.StatusBadRequest) - return - } - - // 提取旧令牌 - oldToken := req.Token - - // 尝试刷新令牌 - newToken, err := svcCtx.JwtManager.Renew(r.Context(), oldToken) - if err != nil { - http.Error(w, "Token refresh failed", http.StatusUnauthorized) - return - } - - // 返回新令牌 - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(types.RefreshTokenResponse{ - Token: newToken, - }) - } -} -``` - -## 5. 登出处理 - -实现登出端点以撤销令牌: - -```go -package user - -import ( - "net/http" - - "yourmodule/app/users/api/internal/svc" -) - -// LogoutHandler 登出用户(撤销令牌) -func LogoutHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // 从上下文提取声明 - claims, ok := r.Context().Value("claims").(*jwt.RegisteredClaims) - if !ok { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - userID := claims.Subject - - // 获取用户当前令牌 - currentToken := r.Header.Get("Authorization") - - // 撤销令牌 - err := svcCtx.JwtManager.Revoke(r.Context(), userID, currentToken) - if err != nil { - http.Error(w, "Logout failed", http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{"message": "logged out successfully"}) - } -} -``` - -## 6. 特定端点的 JWT 验证 - -对于 REST API,在需要的 handlers 中手动验证令牌: - -### 在 Routes 中配置 - -修改 [app/users/api/internal/handler/routes.go](../../../app/users/api/internal/handler/routes.go): - -```go -package handler - -import ( - "net/http" - - "yourmodule/app/users/api/internal/middleware" - "yourmodule/app/users/api/internal/svc" - "yourmodule/app/users/api/internal/handler/user" -) - -// RegisterRoutes 注册所有路由 -func RegisterRoutes(router *http.ServeMux, svcCtx *svc.ServiceContext) { - // 公开路由 - router.HandleFunc("POST /api/v1/auth/login", user.LoginHandler(svcCtx)) - router.HandleFunc("POST /api/v1/auth/refresh", user.RefreshTokenHandler(svcCtx)) - - // 受保护的路由(需要 JWT 验证) - protected := middleware.JwtMiddleware(svcCtx) - router.HandleFunc("GET /api/v1/users/me", protected(user.GetUserInfoHandler(svcCtx))) - router.HandleFunc("POST /api/v1/users/logout", protected(user.LogoutHandler(svcCtx))) - router.HandleFunc("PUT /api/v1/users/me", protected(user.UpdateUserInfoHandler(svcCtx))) -} -``` - -### 创建 JWT 中间件 - -创建 [app/users/api/internal/middleware/jwt.go](../../../app/users/api/internal/middleware/jwt.go): - -```go -package middleware - -import ( - "context" - "net/http" - "strings" - - "yourmodule/app/users/api/internal/svc" -) - -// JwtMiddleware 为 HTTP 处理器添加 JWT 验证 -func JwtMiddleware(svcCtx *svc.ServiceContext) func(http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // 从 Authorization 头提取令牌 - authHeader := r.Header.Get("Authorization") - if authHeader == "" { - http.Error(w, "Missing authorization header", http.StatusUnauthorized) - return - } - - // 期望格式: "Bearer " - parts := strings.SplitN(authHeader, " ", 2) - if len(parts) != 2 || parts[0] != "Bearer" { - http.Error(w, "Invalid authorization header", http.StatusUnauthorized) - return - } - - token := parts[1] - - // 验证令牌 - claims, err := svcCtx.JwtManager.Valid(r.Context(), token) - if err != nil { - // 尝试刷新 - newToken, refreshErr := svcCtx.JwtManager.Renew(r.Context(), token) - if refreshErr != nil { - http.Error(w, "Invalid or expired token", http.StatusUnauthorized) - return - } - - // 在响应头返回新令牌 - w.Header().Set("X-New-Token", newToken) - - // 重新验证新令牌 - claims, err = svcCtx.JwtManager.Valid(r.Context(), newToken) - if err != nil { - http.Error(w, "Token refresh failed", http.StatusUnauthorized) - return - } - } - - // 将声明附加到上下文 - newCtx := context.WithValue(r.Context(), "claims", claims) - next.ServeHTTP(w, r.WithContext(newCtx)) - }) - } -} -``` - -## 7. 错误处理最佳实践 - -```go -package logic - -import ( - "errors" - "log" - - "yourmodule/app/users/rpc/internal/utils" -) - -// HandleJwtError 处理 JWT 相关错误 -func HandleJwtError(err error) error { - if errors.Is(err, utils.ErrTokenExpired) { - log.Println("Token has expired, user needs to refresh") - return errors.New("token expired - use refresh endpoint") - } - - if errors.Is(err, utils.ErrTokenInvalid) { - log.Println("Token is invalid or malformed") - return errors.New("invalid token") - } - - if errors.Is(err, utils.ErrTokenNotFound) { - log.Println("Token not found in Redis (revoked or expired)") - return errors.New("token revoked or expired") - } - - return err -} -``` - -## 8. 测试 JWT 集成 - -### 单元测试示例 - -```go -package interceptor - -import ( - "context" - "testing" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -func TestJwtUnaryInterceptor_ValidToken(t *testing.T) { - // 1. 创建有效的令牌 - token, err := svcCtx.JwtManager.New(context.Background(), "user123", "user@example.com", "John") - if err != nil { - t.Fatalf("Failed to create token: %v", err) - } - - // 2. 创建包含令牌的上下文 - md := metadata.Pairs("authorization", token) - ctx := metadata.NewIncomingContext(context.Background(), md) - - // 3. 调用拦截器 - _, err = JwtUnaryInterceptor(svcCtx)(ctx, nil, nil, func(ctx context.Context, req interface{}) (interface{}, error) { - return "success", nil - }) - - if err != nil { - t.Errorf("Unexpected error: %v", err) - } -} - -func TestJwtUnaryInterceptor_ExpiredToken(t *testing.T) { - // 1. 创建过期的令牌或使用无效令牌 - token := "invalid.token.here" - - // 2. 创建包含令牌的上下文 - md := metadata.Pairs("authorization", token) - ctx := metadata.NewIncomingContext(context.Background(), md) - - // 3. 调用拦截器 - _, err := JwtUnaryInterceptor(svcCtx)(ctx, nil, nil, func(ctx context.Context, req interface{}) (interface{}, error) { - return "success", nil - }) - - // 4. 验证错误 - st, ok := status.FromError(err) - if !ok || st.Code() != codes.Unauthenticated { - t.Errorf("Expected Unauthenticated error, got: %v", err) - } -} -``` - -## 9. 生产部署清单 - -在将 JWT 集成部署到生产环境前: - -- [ ] 所有令牌端点都进行了压力测试 -- [ ] 令牌刷新逻辑已验证 -- [ ] 错误处理覆盖了所有 JWT 失败情况 -- [ ] 审计日志记录了所有认证尝试 -- [ ] 密钥轮换计划已确定 -- [ ] 监控和告警已配置 -- [ ] 灾难恢复流程已文档化 -- [ ] 所有依赖于 JWT 的服务都已更新 - -## 相关文件 - -- [app/users/rpc/internal/utils/jwt.go](../../../app/users/rpc/internal/utils/jwt.go) - JWT Manager 实现 -- [app/users/rpc/internal/config/config.go](../../../app/users/rpc/internal/config/config.go) - JWT 配置 -- [app/users/rpc/internal/svc/serviceContext.go](../../../app/users/rpc/internal/svc/serviceContext.go) - 依赖注入 -- [deploy/k8s/secrets/jwt-secret.yaml](./jwt-secret.yaml) - Secret 和 RBAC -- [deploy/k8s/secrets/DEPLOYMENT.md](./DEPLOYMENT.md) - 部署指南 +# JWT 集成指南 + +指导如何将 JWT Manager 集成到 RPC Handlers 和业务逻辑中。 + +## 1. gRPC Unary Interceptor 实现 + +在 RPC 服务中添加 JWT 验证拦截器。 + +### 创建拦截器 + +创建文件 [app/users/rpc/internal/interceptor/jwt_interceptor.go](../../../app/users/rpc/internal/interceptor/jwt_interceptor.go): + +```go +package interceptor + +import ( + "context" + "log" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + + "yourmodule/app/users/rpc/internal/svc" +) + +// JwtUnaryInterceptor 验证 gRPC 请求中的 JWT 令牌 +func JwtUnaryInterceptor(svcCtx *svc.ServiceContext) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + // 获取请求元数据 + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return nil, status.Error(codes.Unauthenticated, "missing metadata") + } + + // 从 Authorization 头提取令牌 + tokens := md.Get("authorization") + if len(tokens) == 0 { + return nil, status.Error(codes.Unauthenticated, "missing authorization header") + } + + token := tokens[0] + + // 验证令牌 + claims, err := svcCtx.JwtManager.Valid(ctx, token) + if err != nil { + log.Printf("Token validation failed: %v", err) + + // 尝试刷新令牌(如果过期但仍在 Redis 中) + newToken, refreshErr := svcCtx.JwtManager.Renew(ctx, token) + if refreshErr == nil && newToken != "" { + // 在响应头中返回新令牌 + grpc.SetHeader(ctx, metadata.Pairs("authorization", newToken)) + // 继续处理请求,使用原令牌的声明 + // 注意:实际应用中需要重新验证新令牌 + newClaims, err := svcCtx.JwtManager.Valid(ctx, newToken) + if err != nil { + return nil, status.Error(codes.Unauthenticated, "token refresh failed") + } + claims = newClaims + } else { + return nil, status.Error(codes.Unauthenticated, "invalid or expired token") + } + } + + // 将声明附加到上下文,供处理器使用 + newCtx := context.WithValue(ctx, "claims", claims) + + return handler(newCtx, req) + } +} + +// JwtStreamInterceptor 验证流式 gRPC 请求中的 JWT 令牌 +func JwtStreamInterceptor(svcCtx *svc.ServiceContext) grpc.StreamServerInterceptor { + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + md, ok := metadata.FromIncomingContext(ss.Context()) + if !ok { + return status.Error(codes.Unauthenticated, "missing metadata") + } + + tokens := md.Get("authorization") + if len(tokens) == 0 { + return status.Error(codes.Unauthenticated, "missing authorization header") + } + + token := tokens[0] + claims, err := svcCtx.JwtManager.Valid(ss.Context(), token) + if err != nil { + return status.Error(codes.Unauthenticated, "invalid token") + } + + // 创建包装流以注入上下文 + wrappedStream := &WrappedStream{ + ServerStream: ss, + ctx: context.WithValue(ss.Context(), "claims", claims), + } + + return handler(srv, wrappedStream) + } +} + +// WrappedStream 包装 grpc.ServerStream 以注入新的上下文 +type WrappedStream struct { + grpc.ServerStream + ctx context.Context +} + +func (w *WrappedStream) Context() context.Context { + return w.ctx +} +``` + +### 在 Server 中注册拦截器 + +修改 [app/users/rpc/usercenter/usercenter.go](../app/users/rpc/usercenter/usercenter.go): + +```go +package main + +import ( + "flag" + "fmt" + "log" + + "yourmodule/app/users/rpc/internal/config" + "yourmodule/app/users/rpc/internal/interceptor" + "yourmodule/app/users/rpc/internal/server" + "yourmodule/app/users/rpc/internal/svc" + "yourmodule/app/users/rpc/pb" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/grpc" +) + +var configFile = flag.String("f", "etc/pb.yaml", "the config file") + +func main() { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + ctx := svc.NewServiceContext(c) + + logx.DisableStat() + + s := grpc.NewServer( + grpc.UnaryInterceptor(interceptor.JwtUnaryInterceptor(ctx)), + grpc.StreamInterceptor(interceptor.JwtStreamInterceptor(ctx)), + ) + + pb.RegisterUsercenterServer(s, server.NewUsercenterServer(ctx)) + + logx.Infof("Starting gRPC server on %s:%d", c.Host, c.Port) + if err := s.Serve(net.Listen("tcp", "0.0.0.0:"+fmt.Sprintf("%d", c.Port))); err != nil { + logx.Error(err) + } +} +``` + +## 2. 登录 Handler 实现 + +实现 [app/users/api/internal/handler/user/loginHandler.go](../../../app/users/api/internal/handler/user/loginHandler.go): + +```go +package user + +import ( + "context" + "log" + "net/http" + + "yourmodule/app/users/api/internal/logic/user" + "yourmodule/app/users/api/internal/svc" + "yourmodule/app/users/api/internal/types" +) + +// LoginHandler 处理用户登录 +func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.LoginRequest + + // 解析请求体... + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid request", http.StatusBadRequest) + return + } + + // 调用业务逻辑 + resp, err := user.NewLoginLogic(r.Context(), svcCtx).Login(&req) + if err != nil { + log.Printf("Login failed: %v", err) + http.Error(w, "Login failed", http.StatusUnauthorized) + return + } + + // 返回令牌 + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) + } +} +``` + +实现 [app/users/api/internal/logic/user/loginLogic.go](../../../app/users/api/internal/logic/user/loginLogic.go): + +```go +package user + +import ( + "context" + "errors" + + "yourmodule/app/users/api/internal/svc" + "yourmodule/app/users/api/internal/types" +) + +type LoginLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic { + return &LoginLogic{ + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *LoginLogic) Login(req *types.LoginRequest) (*types.LoginResponse, error) { + // 1. 验证用户凭证(密码等) + user, err := l.svcCtx.UserModel.FindByEmail(l.ctx, req.Email) + if err != nil { + return nil, errors.New("user not found") + } + + // 2. 验证密码 + if !user.VerifyPassword(req.Password) { + return nil, errors.New("invalid password") + } + + // 3. 生成 JWT 令牌 + token, err := l.svcCtx.JwtManager.New( + l.ctx, + user.ID, + user.Email, + user.Name, + ) + if err != nil { + return nil, errors.New("failed to generate token") + } + + // 4. 返回令牌 + return &types.LoginResponse{ + Token: token, + User: types.User{ + ID: user.ID, + Email: user.Email, + Name: user.Name, + }, + }, nil +} +``` + +## 3. 在 Handlers 中使用声明 + +在 Protected Handlers 中提取并使用声明: + +```go +package user + +import ( + "context" + "log" + "net/http" + + "yourmodule/app/users/api/internal/svc" + "yourmodule/app/users/api/internal/types" + "github.com/golang-jwt/jwt/v4" +) + +// GetUserInfoHandler 获取当前用户信息 +func GetUserInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // 从上下文提取声明(由拦截器设置) + claims, ok := r.Context().Value("claims").(*jwt.RegisteredClaims) + if !ok { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + // 使用声明中的用户信息 + userID := claims.Subject // 用户 ID 存储在 Subject 中 + log.Printf("User %s requested their info", userID) + + // 查询用户信息 + user, err := svcCtx.UserModel.FindByID(r.Context(), userID) + if err != nil { + http.Error(w, "User not found", http.StatusNotFound) + return + } + + // 返回用户信息 + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(user) + } +} +``` + +## 4. 令牌刷新端点 + +实现令牌刷新端点: + +```go +package user + +import ( + "net/http" + + "yourmodule/app/users/api/internal/svc" + "yourmodule/app/users/api/internal/types" +) + +// RefreshTokenHandler 刷新过期的 JWT 令牌 +func RefreshTokenHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.RefreshTokenRequest + + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid request", http.StatusBadRequest) + return + } + + // 提取旧令牌 + oldToken := req.Token + + // 尝试刷新令牌 + newToken, err := svcCtx.JwtManager.Renew(r.Context(), oldToken) + if err != nil { + http.Error(w, "Token refresh failed", http.StatusUnauthorized) + return + } + + // 返回新令牌 + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(types.RefreshTokenResponse{ + Token: newToken, + }) + } +} +``` + +## 5. 登出处理 + +实现登出端点以撤销令牌: + +```go +package user + +import ( + "net/http" + + "yourmodule/app/users/api/internal/svc" +) + +// LogoutHandler 登出用户(撤销令牌) +func LogoutHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // 从上下文提取声明 + claims, ok := r.Context().Value("claims").(*jwt.RegisteredClaims) + if !ok { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + userID := claims.Subject + + // 获取用户当前令牌 + currentToken := r.Header.Get("Authorization") + + // 撤销令牌 + err := svcCtx.JwtManager.Revoke(r.Context(), userID, currentToken) + if err != nil { + http.Error(w, "Logout failed", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]string{"message": "logged out successfully"}) + } +} +``` + +## 6. 特定端点的 JWT 验证 + +对于 REST API,在需要的 handlers 中手动验证令牌: + +### 在 Routes 中配置 + +修改 [app/users/api/internal/handler/routes.go](../app/users/api/internal/handler/routes.go): + +```go +package handler + +import ( + "net/http" + + "yourmodule/app/users/api/internal/middleware" + "yourmodule/app/users/api/internal/svc" + "yourmodule/app/users/api/internal/handler/user" +) + +// RegisterRoutes 注册所有路由 +func RegisterRoutes(router *http.ServeMux, svcCtx *svc.ServiceContext) { + // 公开路由 + router.HandleFunc("POST /api/v1/auth/login", user.LoginHandler(svcCtx)) + router.HandleFunc("POST /api/v1/auth/refresh", user.RefreshTokenHandler(svcCtx)) + + // 受保护的路由(需要 JWT 验证) + protected := middleware.JwtMiddleware(svcCtx) + router.HandleFunc("GET /api/v1/users/me", protected(user.GetUserInfoHandler(svcCtx))) + router.HandleFunc("POST /api/v1/users/logout", protected(user.LogoutHandler(svcCtx))) + router.HandleFunc("PUT /api/v1/users/me", protected(user.UpdateUserInfoHandler(svcCtx))) +} +``` + +### 创建 JWT 中间件 + +创建 [app/users/api/internal/middleware/jwt.go](../../../app/users/api/internal/middleware/jwt.go): + +```go +package middleware + +import ( + "context" + "net/http" + "strings" + + "yourmodule/app/users/api/internal/svc" +) + +// JwtMiddleware 为 HTTP 处理器添加 JWT 验证 +func JwtMiddleware(svcCtx *svc.ServiceContext) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // 从 Authorization 头提取令牌 + authHeader := r.Header.Get("Authorization") + if authHeader == "" { + http.Error(w, "Missing authorization header", http.StatusUnauthorized) + return + } + + // 期望格式: "Bearer " + parts := strings.SplitN(authHeader, " ", 2) + if len(parts) != 2 || parts[0] != "Bearer" { + http.Error(w, "Invalid authorization header", http.StatusUnauthorized) + return + } + + token := parts[1] + + // 验证令牌 + claims, err := svcCtx.JwtManager.Valid(r.Context(), token) + if err != nil { + // 尝试刷新 + newToken, refreshErr := svcCtx.JwtManager.Renew(r.Context(), token) + if refreshErr != nil { + http.Error(w, "Invalid or expired token", http.StatusUnauthorized) + return + } + + // 在响应头返回新令牌 + w.Header().Set("X-New-Token", newToken) + + // 重新验证新令牌 + claims, err = svcCtx.JwtManager.Valid(r.Context(), newToken) + if err != nil { + http.Error(w, "Token refresh failed", http.StatusUnauthorized) + return + } + } + + // 将声明附加到上下文 + newCtx := context.WithValue(r.Context(), "claims", claims) + next.ServeHTTP(w, r.WithContext(newCtx)) + }) + } +} +``` + +## 7. 错误处理最佳实践 + +```go +package logic + +import ( + "errors" + "log" + + "yourmodule/app/users/rpc/internal/utils" +) + +// HandleJwtError 处理 JWT 相关错误 +func HandleJwtError(err error) error { + if errors.Is(err, utils.ErrTokenExpired) { + log.Println("Token has expired, user needs to refresh") + return errors.New("token expired - use refresh endpoint") + } + + if errors.Is(err, utils.ErrTokenInvalid) { + log.Println("Token is invalid or malformed") + return errors.New("invalid token") + } + + if errors.Is(err, utils.ErrTokenNotFound) { + log.Println("Token not found in Redis (revoked or expired)") + return errors.New("token revoked or expired") + } + + return err +} +``` + +## 8. 测试 JWT 集成 + +### 单元测试示例 + +```go +package interceptor + +import ( + "context" + "testing" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +func TestJwtUnaryInterceptor_ValidToken(t *testing.T) { + // 1. 创建有效的令牌 + token, err := svcCtx.JwtManager.New(context.Background(), "user123", "user@example.com", "John") + if err != nil { + t.Fatalf("Failed to create token: %v", err) + } + + // 2. 创建包含令牌的上下文 + md := metadata.Pairs("authorization", token) + ctx := metadata.NewIncomingContext(context.Background(), md) + + // 3. 调用拦截器 + _, err = JwtUnaryInterceptor(svcCtx)(ctx, nil, nil, func(ctx context.Context, req interface{}) (interface{}, error) { + return "success", nil + }) + + if err != nil { + t.Errorf("Unexpected error: %v", err) + } +} + +func TestJwtUnaryInterceptor_ExpiredToken(t *testing.T) { + // 1. 创建过期的令牌或使用无效令牌 + token := "invalid.token.here" + + // 2. 创建包含令牌的上下文 + md := metadata.Pairs("authorization", token) + ctx := metadata.NewIncomingContext(context.Background(), md) + + // 3. 调用拦截器 + _, err := JwtUnaryInterceptor(svcCtx)(ctx, nil, nil, func(ctx context.Context, req interface{}) (interface{}, error) { + return "success", nil + }) + + // 4. 验证错误 + st, ok := status.FromError(err) + if !ok || st.Code() != codes.Unauthenticated { + t.Errorf("Expected Unauthenticated error, got: %v", err) + } +} +``` + +## 9. 生产部署清单 + +在将 JWT 集成部署到生产环境前: + +- [ ] 所有令牌端点都进行了压力测试 +- [ ] 令牌刷新逻辑已验证 +- [ ] 错误处理覆盖了所有 JWT 失败情况 +- [ ] 审计日志记录了所有认证尝试 +- [ ] 密钥轮换计划已确定 +- [ ] 监控和告警已配置 +- [ ] 灾难恢复流程已文档化 +- [ ] 所有依赖于 JWT 的服务都已更新 + +## 相关文件 + +- [app/users/rpc/internal/utils/jwt.go](../app/users/rpc/internal/utils/jwt.go) - JWT Manager 实现 +- [app/users/rpc/internal/config/config.go](../app/users/rpc/internal/config/config.go) - JWT 配置 +- [app/users/rpc/internal/svc/serviceContext.go](../app/users/rpc/internal/svc/serviceContext.go) - 依赖注入 +- [deploy/k8s/secrets/jwt-secret.yaml](./jwt-secret.yaml) - Secret 和 RBAC +- [deploy/k8s/secrets/DEPLOYMENT.md](./DEPLOYMENT.md) - 部署指南 diff --git a/pkg/types/TextArray.go b/pkg/types/TextArray.go new file mode 100644 index 0000000..d34707c --- /dev/null +++ b/pkg/types/TextArray.go @@ -0,0 +1,41 @@ +package types + +import ( + "database/sql/driver" + "errors" + "strings" + + "github.com/jackc/pgx/v5/pgtype" + "github.com/zeromicro/go-zero/core/logx" +) + +type TextArray pgtype.Array[string] + +func (s *TextArray) Scan(src any) error { + logx.Infof("scan src=%+v", src) + var strSrc string + switch v := src.(type) { + case string: + strSrc = v + case []byte: + strSrc = string(v) + default: + logx.Errorf("src=%+v, failed to assert src as string or []byte", src) + return errors.New("failed to scan src") + } + + trimmed := strings.Trim(strSrc, "{}") + result := strings.Split(trimmed, ",") + logx.Debugf("split result=%+v", result) + if len(trimmed) == 0 { + result = []string{} + } + s.Elements = result + s.Dims = nil + s.Valid = true + return nil +} + +func (s TextArray) Value() (driver.Value, error) { + return s.Elements, nil +}