mirror of
https://github.com/certd/certd.git
synced 2026-05-18 22:57:31 +08:00
feat: 商业版支持邀请返佣功能
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
ALTER TABLE cd_trade ADD COLUMN rebate_amount bigint NOT NULL DEFAULT 0;
|
||||
ALTER TABLE cd_trade ADD COLUMN third_party_pay_amount bigint NOT NULL DEFAULT 0;
|
||||
|
||||
CREATE TABLE `cd_invite_code`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`code` varchar(50),
|
||||
`disabled` boolean NOT NULL DEFAULT false,
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE UNIQUE INDEX `index_invite_code_user_id` ON `cd_invite_code` (`user_id`);
|
||||
CREATE UNIQUE INDEX `index_invite_code_code` ON `cd_invite_code` (`code`);
|
||||
|
||||
CREATE TABLE `cd_invite_relation`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`inviter_user_id` bigint,
|
||||
`invitee_user_id` bigint,
|
||||
`invite_code` varchar(50),
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_invite_relation_inviter` ON `cd_invite_relation` (`inviter_user_id`);
|
||||
CREATE UNIQUE INDEX `index_invite_relation_invitee` ON `cd_invite_relation` (`invitee_user_id`);
|
||||
|
||||
CREATE TABLE `cd_user_wallet`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`available_amount` bigint NOT NULL DEFAULT 0,
|
||||
`frozen_amount` bigint NOT NULL DEFAULT 0,
|
||||
`total_income_amount` bigint NOT NULL DEFAULT 0,
|
||||
`total_consumed_amount` bigint NOT NULL DEFAULT 0,
|
||||
`total_withdraw_amount` bigint NOT NULL DEFAULT 0,
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE UNIQUE INDEX `index_user_wallet_user_id` ON `cd_user_wallet` (`user_id`);
|
||||
|
||||
CREATE TABLE `cd_invite_commission_log`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`amount` bigint,
|
||||
`trade_id` bigint,
|
||||
`invitee_user_id` bigint,
|
||||
`consume_amount` bigint NOT NULL DEFAULT 0,
|
||||
`remark` varchar(2048),
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_invite_log_user_id` ON `cd_invite_commission_log` (`user_id`);
|
||||
|
||||
CREATE TABLE `cd_user_wallet_log`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`type` varchar(50),
|
||||
`amount` bigint,
|
||||
`balance_after` bigint,
|
||||
`trade_id` bigint,
|
||||
`withdraw_id` bigint,
|
||||
`remark` varchar(2048),
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_user_wallet_log_user_id` ON `cd_user_wallet_log` (`user_id`);
|
||||
|
||||
CREATE TABLE `cd_user_wallet_withdraw`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`amount` bigint,
|
||||
`status` varchar(50),
|
||||
`channel` varchar(50),
|
||||
`real_name` varchar(100),
|
||||
`account` varchar(200),
|
||||
`bank_name` varchar(200),
|
||||
`audit_user_id` bigint,
|
||||
`audit_remark` varchar(2048),
|
||||
`audit_time` bigint,
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_user_wallet_withdraw_user_id` ON `cd_user_wallet_withdraw` (`user_id`);
|
||||
CREATE INDEX `index_user_wallet_withdraw_status` ON `cd_user_wallet_withdraw` (`status`);
|
||||
@@ -0,0 +1,88 @@
|
||||
ALTER TABLE cd_trade ADD COLUMN rebate_amount bigint NOT NULL DEFAULT 0;
|
||||
ALTER TABLE cd_trade ADD COLUMN third_party_pay_amount bigint NOT NULL DEFAULT 0;
|
||||
|
||||
CREATE TABLE "cd_invite_code"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint,
|
||||
"code" varchar(50),
|
||||
"disabled" boolean NOT NULL DEFAULT (false),
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE UNIQUE INDEX "index_invite_code_user_id" ON "cd_invite_code" ("user_id");
|
||||
CREATE UNIQUE INDEX "index_invite_code_code" ON "cd_invite_code" ("code");
|
||||
|
||||
CREATE TABLE "cd_invite_relation"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"inviter_user_id" bigint,
|
||||
"invitee_user_id" bigint,
|
||||
"invite_code" varchar(50),
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_invite_relation_inviter" ON "cd_invite_relation" ("inviter_user_id");
|
||||
CREATE UNIQUE INDEX "index_invite_relation_invitee" ON "cd_invite_relation" ("invitee_user_id");
|
||||
|
||||
CREATE TABLE "cd_user_wallet"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint,
|
||||
"available_amount" bigint NOT NULL DEFAULT 0,
|
||||
"frozen_amount" bigint NOT NULL DEFAULT 0,
|
||||
"total_income_amount" bigint NOT NULL DEFAULT 0,
|
||||
"total_consumed_amount" bigint NOT NULL DEFAULT 0,
|
||||
"total_withdraw_amount" bigint NOT NULL DEFAULT 0,
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE UNIQUE INDEX "index_user_wallet_user_id" ON "cd_user_wallet" ("user_id");
|
||||
|
||||
CREATE TABLE "cd_invite_commission_log"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint,
|
||||
"amount" bigint,
|
||||
"trade_id" bigint,
|
||||
"invitee_user_id" bigint,
|
||||
"consume_amount" bigint NOT NULL DEFAULT 0,
|
||||
"remark" varchar(2048),
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_invite_log_user_id" ON "cd_invite_commission_log" ("user_id");
|
||||
|
||||
CREATE TABLE "cd_user_wallet_log"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint,
|
||||
"type" varchar(50),
|
||||
"amount" bigint,
|
||||
"balance_after" bigint,
|
||||
"trade_id" bigint,
|
||||
"withdraw_id" bigint,
|
||||
"remark" varchar(2048),
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_user_wallet_log_user_id" ON "cd_user_wallet_log" ("user_id");
|
||||
|
||||
CREATE TABLE "cd_user_wallet_withdraw"
|
||||
(
|
||||
"id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
"user_id" bigint,
|
||||
"amount" bigint,
|
||||
"status" varchar(50),
|
||||
"channel" varchar(50),
|
||||
"real_name" varchar(100),
|
||||
"account" varchar(200),
|
||||
"bank_name" varchar(200),
|
||||
"audit_user_id" bigint,
|
||||
"audit_remark" varchar(2048),
|
||||
"audit_time" bigint,
|
||||
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_user_wallet_withdraw_user_id" ON "cd_user_wallet_withdraw" ("user_id");
|
||||
CREATE INDEX "index_user_wallet_withdraw_status" ON "cd_user_wallet_withdraw" ("status");
|
||||
@@ -0,0 +1,88 @@
|
||||
ALTER TABLE cd_trade ADD COLUMN rebate_amount integer NOT NULL DEFAULT 0;
|
||||
ALTER TABLE cd_trade ADD COLUMN third_party_pay_amount integer NOT NULL DEFAULT 0;
|
||||
|
||||
CREATE TABLE "cd_invite_code"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer,
|
||||
"code" varchar(50),
|
||||
"disabled" boolean NOT NULL DEFAULT (false),
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE UNIQUE INDEX "index_invite_code_user_id" ON "cd_invite_code" ("user_id");
|
||||
CREATE UNIQUE INDEX "index_invite_code_code" ON "cd_invite_code" ("code");
|
||||
|
||||
CREATE TABLE "cd_invite_relation"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"inviter_user_id" integer,
|
||||
"invitee_user_id" integer,
|
||||
"invite_code" varchar(50),
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_invite_relation_inviter" ON "cd_invite_relation" ("inviter_user_id");
|
||||
CREATE UNIQUE INDEX "index_invite_relation_invitee" ON "cd_invite_relation" ("invitee_user_id");
|
||||
|
||||
CREATE TABLE "cd_user_wallet"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer,
|
||||
"available_amount" integer NOT NULL DEFAULT 0,
|
||||
"frozen_amount" integer NOT NULL DEFAULT 0,
|
||||
"total_income_amount" integer NOT NULL DEFAULT 0,
|
||||
"total_consumed_amount" integer NOT NULL DEFAULT 0,
|
||||
"total_withdraw_amount" integer NOT NULL DEFAULT 0,
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE UNIQUE INDEX "index_user_wallet_user_id" ON "cd_user_wallet" ("user_id");
|
||||
|
||||
CREATE TABLE "cd_invite_commission_log"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer,
|
||||
"amount" integer,
|
||||
"trade_id" integer,
|
||||
"invitee_user_id" integer,
|
||||
"consume_amount" integer NOT NULL DEFAULT 0,
|
||||
"remark" varchar(2048),
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_invite_log_user_id" ON "cd_invite_commission_log" ("user_id");
|
||||
|
||||
CREATE TABLE "cd_user_wallet_log"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer,
|
||||
"type" varchar(50),
|
||||
"amount" integer,
|
||||
"balance_after" integer,
|
||||
"trade_id" integer,
|
||||
"withdraw_id" integer,
|
||||
"remark" varchar(2048),
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_user_wallet_log_user_id" ON "cd_user_wallet_log" ("user_id");
|
||||
|
||||
CREATE TABLE "cd_user_wallet_withdraw"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer,
|
||||
"amount" integer,
|
||||
"status" varchar(50),
|
||||
"channel" varchar(50),
|
||||
"real_name" varchar(100),
|
||||
"account" varchar(200),
|
||||
"bank_name" varchar(200),
|
||||
"audit_user_id" integer,
|
||||
"audit_remark" varchar(2048),
|
||||
"audit_time" integer,
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
CREATE INDEX "index_user_wallet_withdraw_user_id" ON "cd_user_wallet_withdraw" ("user_id");
|
||||
CREATE INDEX "index_user_wallet_withdraw_status" ON "cd_user_wallet_withdraw" ("status");
|
||||
@@ -64,6 +64,7 @@ export class LoginController extends BaseController {
|
||||
mobile: body.mobile,
|
||||
smsCode: body.smsCode,
|
||||
randomStr: body.randomStr,
|
||||
inviteCode: body.inviteCode,
|
||||
});
|
||||
|
||||
this.writeTokenCookie(token);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { BaseController, Constants, SysSettingsService } from '@certd/lib-server
|
||||
import { RegisterType, UserService } from '../../../modules/sys/authority/service/user-service.js';
|
||||
import { CodeService } from '../../../modules/basic/service/code-service.js';
|
||||
import { checkComm, checkPlus } from '@certd/plus-core';
|
||||
import { InviteService } from '@certd/commercial-core';
|
||||
|
||||
export type RegisterReq = {
|
||||
type: RegisterType;
|
||||
@@ -14,6 +15,7 @@ export type RegisterReq = {
|
||||
|
||||
validateCode: string;
|
||||
captcha:any;
|
||||
inviteCode?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -29,6 +31,9 @@ export class RegisterController extends BaseController {
|
||||
@Inject()
|
||||
sysSettingsService: SysSettingsService;
|
||||
|
||||
@Inject()
|
||||
inviteService: InviteService;
|
||||
|
||||
@Post('/register', { description: Constants.per.guest })
|
||||
public async register(
|
||||
@Body(ALL)
|
||||
@@ -53,10 +58,13 @@ export class RegisterController extends BaseController {
|
||||
}
|
||||
|
||||
await this.codeService.checkCaptcha(body.captcha,{remoteIp});
|
||||
const newUser = await this.userService.register(body.type, {
|
||||
const registerUser = {
|
||||
username: body.username,
|
||||
password: body.password,
|
||||
} as any);
|
||||
} as any;
|
||||
const newUser = await this.userService.register(body.type, registerUser, async txManager => {
|
||||
await this.inviteService.bindInvitee(registerUser.id, body.inviteCode, txManager);
|
||||
});
|
||||
return this.ok(newUser);
|
||||
} else if (body.type === 'mobile') {
|
||||
if (sysPublicSettings.mobileRegisterEnabled === false) {
|
||||
@@ -70,12 +78,15 @@ export class RegisterController extends BaseController {
|
||||
smsCode: body.validateCode,
|
||||
throwError: true,
|
||||
});
|
||||
const newUser = await this.userService.register(body.type, {
|
||||
const registerUser = {
|
||||
username: body.username,
|
||||
phoneCode: body.phoneCode,
|
||||
mobile: body.mobile,
|
||||
password: body.password,
|
||||
} as any);
|
||||
} as any;
|
||||
const newUser = await this.userService.register(body.type, registerUser, async txManager => {
|
||||
await this.inviteService.bindInvitee(registerUser.id, body.inviteCode, txManager);
|
||||
});
|
||||
return this.ok(newUser);
|
||||
} else if (body.type === 'email') {
|
||||
if (sysPublicSettings.emailRegisterEnabled === false) {
|
||||
@@ -87,11 +98,14 @@ export class RegisterController extends BaseController {
|
||||
validateCode: body.validateCode,
|
||||
throwError: true,
|
||||
});
|
||||
const newUser = await this.userService.register(body.type, {
|
||||
const registerUser = {
|
||||
username: body.username,
|
||||
email: body.email,
|
||||
password: body.password,
|
||||
} as any);
|
||||
} as any;
|
||||
const newUser = await this.userService.register(body.type, registerUser, async txManager => {
|
||||
await this.inviteService.bindInvitee(registerUser.id, body.inviteCode, txManager);
|
||||
});
|
||||
return this.ok(newUser);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
SysSuiteSetting
|
||||
} from "@certd/lib-server";
|
||||
import { AppKey, getPlusInfo, isComm } from "@certd/plus-core";
|
||||
import { SysInviteCommissionSetting } from "@certd/commercial-core";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { getVersion } from "../../utils/version.js";
|
||||
import { http } from "@certd/basic";
|
||||
@@ -57,6 +58,16 @@ export class BasicSettingsController extends BaseController {
|
||||
};
|
||||
}
|
||||
|
||||
public async getInviteSetting() {
|
||||
if (!isComm()) {
|
||||
return { enabled: false };
|
||||
}
|
||||
const setting = await this.sysSettingsService.getSetting<SysInviteCommissionSetting>(SysInviteCommissionSetting);
|
||||
return {
|
||||
enabled: setting.enabled,
|
||||
};
|
||||
}
|
||||
|
||||
public async getSiteEnv() {
|
||||
const env: SysSiteEnv = {
|
||||
agent: this.agentConfig
|
||||
@@ -92,6 +103,7 @@ export class BasicSettingsController extends BaseController {
|
||||
const plusInfo = await this.plusInfo();
|
||||
const headerMenus = await this.getHeaderMenus();
|
||||
const suiteSetting = await this.getSuiteSetting();
|
||||
const inviteSetting = await this.getInviteSetting();
|
||||
const version = await getVersion();
|
||||
return this.ok({
|
||||
sysPublic,
|
||||
@@ -101,6 +113,7 @@ export class BasicSettingsController extends BaseController {
|
||||
plusInfo,
|
||||
headerMenus,
|
||||
suiteSetting,
|
||||
inviteSetting,
|
||||
app: {
|
||||
time: new Date().getTime(),
|
||||
version
|
||||
|
||||
@@ -19,6 +19,7 @@ import { isPlus } from "@certd/plus-core";
|
||||
import { AddonService } from "@certd/lib-server";
|
||||
import { OauthBoundService } from "./oauth-bound-service.js";
|
||||
import { PasskeyService } from "./passkey-service.js";
|
||||
import { InviteService } from "@certd/commercial-core";
|
||||
|
||||
/**
|
||||
*/
|
||||
@@ -49,6 +50,9 @@ export class LoginService {
|
||||
@Inject()
|
||||
passkeyService: PasskeyService;
|
||||
|
||||
@Inject()
|
||||
inviteService: InviteService;
|
||||
|
||||
checkIsBlocked(username: string) {
|
||||
const blockDurationKey = `login_block_duration:${username}`;
|
||||
const value = cache.get(blockDurationKey);
|
||||
@@ -111,7 +115,7 @@ export class LoginService {
|
||||
}
|
||||
|
||||
|
||||
async loginBySmsCode(req: { mobile: string; phoneCode: string; smsCode: string; randomStr: string }) {
|
||||
async loginBySmsCode(req: { mobile: string; phoneCode: string; smsCode: string; randomStr: string; inviteCode?: string }) {
|
||||
|
||||
this.checkIsBlocked(req.mobile)
|
||||
|
||||
@@ -129,11 +133,14 @@ export class LoginService {
|
||||
let info = await this.userService.findOne({phoneCode, mobile: mobile});
|
||||
if (info == null) {
|
||||
//用户不存在,注册
|
||||
info = await this.userService.register('mobile', {
|
||||
const registerUser = {
|
||||
phoneCode,
|
||||
mobile,
|
||||
password: '',
|
||||
} as any);
|
||||
} as any;
|
||||
info = await this.userService.register('mobile', registerUser, async txManager => {
|
||||
await this.inviteService.bindInvitee(registerUser.id, req.inviteCode, txManager);
|
||||
});
|
||||
}
|
||||
this.clearCacheOnSuccess(mobile);
|
||||
return this.onLoginSuccess(info);
|
||||
@@ -264,4 +271,3 @@ export class LoginService {
|
||||
const user = await this.passkeyService.loginByPasskey(credential, challenge, ctx);
|
||||
return this.generateToken(user);
|
||||
}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user