From e0ebc5f827a8f7bfa6392760eab9ce526b0b93ee Mon Sep 17 00:00:00 2001 From: usaveh Date: Tue, 7 May 2024 06:47:10 +0000 Subject: [PATCH 1/8] =?UTF-8?q?feat(mis):=20=E6=96=B0=E5=A2=9E=E8=B4=A6?= =?UTF-8?q?=E6=88=B7=E7=99=BD=E5=90=8D=E5=8D=95=E6=97=B6=E9=97=B4=E5=AD=97?= =?UTF-8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/entities/AccountWhitelist.ts | 5 + .../src/migrations/Migration20240507062612.ts | 13 +++ apps/mis-server/src/services/account.ts | 3 +- apps/mis-web/src/i18n/en.ts | 10 ++ apps/mis-web/src/i18n/zh_cn.ts | 8 ++ .../tenant/AddWhitelistedAccountButton.tsx | 92 ++++++++++++++++++- .../accountWhitelist/whitelistAccount.ts | 4 +- protos/server/account.proto | 1 + 8 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 apps/mis-server/src/migrations/Migration20240507062612.ts diff --git a/apps/mis-server/src/entities/AccountWhitelist.ts b/apps/mis-server/src/entities/AccountWhitelist.ts index bc57ae089a..e9d4fefb57 100644 --- a/apps/mis-server/src/entities/AccountWhitelist.ts +++ b/apps/mis-server/src/entities/AccountWhitelist.ts @@ -31,15 +31,20 @@ export class AccountWhitelist { @Property() operatorId: string; + @Property() + expirationDate: Date; + constructor(init: { account: EntityOrRef, time?: Date, comment: string operatorId: string; + expirationDate?: Date }) { this.account = toRef(init.account); this.time = init.time ?? new Date(); this.comment = init.comment; this.operatorId = init.operatorId; + this.expirationDate = init.expirationDate ?? new Date("2099-12-31 00:00"); } } diff --git a/apps/mis-server/src/migrations/Migration20240507062612.ts b/apps/mis-server/src/migrations/Migration20240507062612.ts new file mode 100644 index 0000000000..714cf9cce5 --- /dev/null +++ b/apps/mis-server/src/migrations/Migration20240507062612.ts @@ -0,0 +1,13 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20240507062612 extends Migration { + + async up(): Promise { + this.addSql('alter table `account_whitelist` add `expiration_date` datetime not null;'); + } + + async down(): Promise { + this.addSql('alter table `account_whitelist` drop column `expiration_date`;'); + } + +} diff --git a/apps/mis-server/src/services/account.ts b/apps/mis-server/src/services/account.ts index e6c9916b45..923bdffde6 100644 --- a/apps/mis-server/src/services/account.ts +++ b/apps/mis-server/src/services/account.ts @@ -318,7 +318,7 @@ export const accountServiceServer = plugin((server) => { }, whitelistAccount: async ({ request, em, logger }) => { - const { accountName, comment, operatorId, tenantName } = request; + const { accountName, comment, operatorId, tenantName, expirationDate } = request; const account = await em.findOne(Account, { accountName, tenant: { name: tenantName } }, { populate: [ "tenant"]}); @@ -338,6 +338,7 @@ export const accountServiceServer = plugin((server) => { time: new Date(), comment, operatorId, + expirationDate:new Date(expirationDate), }); account.whitelist = toRef(whitelist); diff --git a/apps/mis-web/src/i18n/en.ts b/apps/mis-web/src/i18n/en.ts index 277c13af8a..613a99707c 100644 --- a/apps/mis-web/src/i18n/en.ts +++ b/apps/mis-web/src/i18n/en.ts @@ -41,6 +41,8 @@ export default { amount: "Amount", unit: "CNY", comment: "Comment", + indate:"Indate", + submit: "Submit", time: "Time", type: "Type", @@ -236,6 +238,7 @@ export default { blockThresholdAmountTooltip: "The account will be blocked " + "when the balance is less than the block threshold amount.", comment: "Comment", + indate:"Indate", status: "Status", statusTooltip: "Account Status Explanation", statusFrozenTooltip: "Frozen: The account has been frozen by the account administrator " @@ -617,6 +620,13 @@ export default { notExist: "Account does not exist!", addSuccess: "Added successfully!", addWhiteList: "Add Whitelisted Account", + indate:"Indate", + custom:"Custom", + oneWeek:"One Week", + oneMonth:"One Month", + oneYear:"One Year", + permanent:"Permanent", + }, adminJobTable: { batch: "Batch Search", diff --git a/apps/mis-web/src/i18n/zh_cn.ts b/apps/mis-web/src/i18n/zh_cn.ts index fc7706dbde..3f3178bca4 100644 --- a/apps/mis-web/src/i18n/zh_cn.ts +++ b/apps/mis-web/src/i18n/zh_cn.ts @@ -41,6 +41,7 @@ export default { amount:"金额", unit:"元", comment:"备注", + indate:"有效期", submit:"提交", time:"时间", type:"类型", @@ -236,6 +237,7 @@ export default { blockThresholdAmountTooltip: "当账户余额低于此值时,账户将被封锁", comment:"备注", + indate:"有效期", status:"状态", statusTooltip: "账户状态说明", statusFrozenTooltip: "冻结:账户已被账户管理员冻结,无法通过此账户提交作业", @@ -617,6 +619,12 @@ export default { notExist:"账户不存在!", addSuccess:"添加成功!", addWhiteList:"添加白名单账户", + indate:"有效期", + custom:"自定义", + oneWeek:"一周", + oneMonth:"一个月", + oneYear:"一年", + permanent:"永久有效", }, adminJobTable:{ batch:"批量搜索", diff --git a/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx b/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx index 244699c2af..76c4729c88 100644 --- a/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx +++ b/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx @@ -11,7 +11,8 @@ */ import { PlusOutlined } from "@ant-design/icons"; -import { App, Button, Form, Input, Modal } from "antd"; +import { App, Button, DatePicker, Flex, Form, Input, Modal, Select } from "antd"; +import dayjs from "dayjs"; import React, { useState } from "react"; import { api } from "src/apis"; import { prefix, useI18nTranslateToString } from "src/i18n"; @@ -19,6 +20,8 @@ import { prefix, useI18nTranslateToString } from "src/i18n"; interface FormProps { accountName: string; comment: string; + indate: string; + expirationDate: dayjs.Dayjs } interface ModalProps { @@ -39,12 +42,60 @@ const NewAccountModal: React.FC = ({ const { message } = App.useApp(); const [loading, setLoading] = useState(false); const [form] = Form.useForm(); + const [selectedOption, setSelectedOption] = useState("custom"); // 添加状态来跟踪选择的选项 - const onOk = async () => { - const { accountName, comment } = await form.validateFields(); - setLoading(true); - await api.whitelistAccount({ body: { accountName: accountName.trim(), comment } }) + const options = [ // 定义 Select 选项数组,使用国际化函数 t() 翻译每个选项的 label + { value: "custom", label: t(p("custom")) }, + { value: "oneWeek", label: t(p("oneWeek")) }, + { value: "oneMonth", label: t(p("oneMonth")) }, + { value: "oneYear", label: t(p("oneYear")) }, + { value: "permanent", label: t(p("permanent")) }, + ]; + + // 定义规范时间 + const dateFormat = "YYYY-MM-DD"; + // dateRange的时间 + const [expirationDate, setExpirationDate] = useState(dayjs()); + + // 对dateRange时间根据options选项进行处理 + React.useEffect(() => { + let newDate: dayjs.Dayjs; + switch (selectedOption) { + case "oneWeek": + newDate = dayjs().add(1, "week"); + break; + + case "oneMonth": + newDate = dayjs().add(1, "month"); + break; + + case "oneYear": + newDate = dayjs().add(1, "year"); + break; + + case "permanent": + newDate = dayjs("2099-12-31"); + break; + + case "custom": + newDate = expirationDate.isValid() ? expirationDate : dayjs(); + break; + + default: + newDate = dayjs(); + break; + } + setExpirationDate(newDate); // 更新组件状态 + form.setFieldsValue({ expirationDate: newDate }); + }, [selectedOption]); + + + + const onOk = async () => { + const { accountName, indate, expirationDate, comment } = await form.validateFields(); + await api.whitelistAccount({ body: { accountName: accountName.trim(), comment, + expirationDate:expirationDate.toISOString() } }) .httpError(404, () => { message.error(t(p("notExist"))); }) @@ -70,6 +121,33 @@ const NewAccountModal: React.FC = ({ + {/* 日期选择 */} + + + setSelectedOption(value)} // 更新选择 + style={{ width: "35%", marginRight:"5%" }} + /> + {/* 根据选项禁用或启用 DatePicker */} + + { + setExpirationDate(date); + onChange?.(date); + } + } // 更新状态 + /> + + ); +}; + + +const NewAccountModal: React.FC = ({ + open, close, refresh, +}) => { + + const t = useI18nTranslateToString(); + + const { message } = App.useApp(); + const [loading, setLoading] = useState(false); + const [form] = Form.useForm(); const onOk = async () => { - const { accountName, indate, expirationDate, comment } = await form.validateFields(); + const { accountName, expirationDate, comment } = await form.validateFields(); await api.whitelistAccount({ body: { accountName: accountName.trim(), comment, expirationDate:expirationDate.toISOString() } }) .httpError(404, () => { @@ -122,32 +172,13 @@ const NewAccountModal: React.FC = ({ {/* 日期选择 */} - - - {/* 日期选择 */} - + form.setFieldsValue({ expirationDate: date })} + id="expirationTime" + value={form.getFieldValue("expirationTime")} + onChange={(date) => form.setFieldsValue({ expirationTime: date })} /> diff --git a/apps/mis-web/src/pages/api/tenant/accountWhitelist/whitelistAccount.ts b/apps/mis-web/src/pages/api/tenant/accountWhitelist/whitelistAccount.ts index d4fc047efa..c60ae6727d 100644 --- a/apps/mis-web/src/pages/api/tenant/accountWhitelist/whitelistAccount.ts +++ b/apps/mis-web/src/pages/api/tenant/accountWhitelist/whitelistAccount.ts @@ -29,7 +29,7 @@ export const WhitelistAccountSchema = typeboxRouteSchema({ body: Type.Object({ accountName: Type.String(), comment: Type.String(), - expirationDate:Type.String({ format: "date-time" }), + expirationTime:Type.String({ format: "date-time" }), }), responses: { @@ -48,7 +48,7 @@ export default route(WhitelistAccountSchema, return; } - const { accountName, comment, expirationDate } = req.body; + const { accountName, comment, expirationTime } = req.body; const logInfo = { operatorUserId: info.identityId, @@ -66,7 +66,7 @@ export default route(WhitelistAccountSchema, accountName, operatorId: info.identityId, comment, - expirationDate, + expirationTime, }) .then(async () => { await callLog(logInfo, OperationResult.SUCCESS); diff --git a/protos/server/account.proto b/protos/server/account.proto index a907e53169..a7341dd1bc 100644 --- a/protos/server/account.proto +++ b/protos/server/account.proto @@ -54,7 +54,7 @@ message WhitelistedAccount { string operator_id = 5; string comment = 6; common.Money balance = 7; - google.protobuf.Timestamp expiration_date = 8; + optional google.protobuf.Timestamp expiration_time = 8; } message GetWhitelistedAccountsResponse { @@ -66,7 +66,7 @@ message WhitelistAccountRequest { string account_name = 2; string operator_id = 3; string comment = 4; - google.protobuf.Timestamp expiration_date = 5; + optional google.protobuf.Timestamp expiration_time = 5; } // NOT_FOUND: account is not found. From cf9b1df8a289791e0ad113f8cfd2ed950d5b352d Mon Sep 17 00:00:00 2001 From: usaveh Date: Wed, 15 May 2024 08:40:21 +0000 Subject: [PATCH 5/8] =?UTF-8?q?feat(mis):=20PR=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/chatty-sloths-wait.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/chatty-sloths-wait.md b/.changeset/chatty-sloths-wait.md index b01c932b4b..4302767081 100644 --- a/.changeset/chatty-sloths-wait.md +++ b/.changeset/chatty-sloths-wait.md @@ -1,6 +1,6 @@ --- -"@scow/mis-server": minor -"@scow/grpc-api": minor +"@scow/mis-server": patch +"@scow/grpc-api": patch --- getWhitelistedAccounts 新增返回字段 expirationDate,whitelistAccount 新增字段 expirationDate,在 getWhitelistedAccounts 新增每次查询会检测 中是否有账户过期,有的话会自动删除 From e5eae98827ed3bc954825f19142050cc668ccb49 Mon Sep 17 00:00:00 2001 From: usaveh Date: Wed, 15 May 2024 09:01:19 +0000 Subject: [PATCH 6/8] =?UTF-8?q?feat(mis):=20=E6=95=B0=E6=8D=AE=E5=BA=93mig?= =?UTF-8?q?ration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/migrations/Migration20240515090037.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 apps/mis-server/src/migrations/Migration20240515090037.ts diff --git a/apps/mis-server/src/migrations/Migration20240515090037.ts b/apps/mis-server/src/migrations/Migration20240515090037.ts new file mode 100644 index 0000000000..d324fb505f --- /dev/null +++ b/apps/mis-server/src/migrations/Migration20240515090037.ts @@ -0,0 +1,13 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20240515090037 extends Migration { + + async up(): Promise { + this.addSql('alter table `account_whitelist` add `expiration_time` datetime null;'); + } + + async down(): Promise { + this.addSql('alter table `account_whitelist` drop column `expiration_time`;'); + } + +} From 975916b7b5c14a930605dad8391d64910d2972e5 Mon Sep 17 00:00:00 2001 From: usaveh Date: Wed, 15 May 2024 09:15:58 +0000 Subject: [PATCH 7/8] =?UTF-8?q?feat(mis):=20=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/migrations/Migration20240507062612.ts | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 apps/mis-server/src/migrations/Migration20240507062612.ts diff --git a/apps/mis-server/src/migrations/Migration20240507062612.ts b/apps/mis-server/src/migrations/Migration20240507062612.ts deleted file mode 100644 index 714cf9cce5..0000000000 --- a/apps/mis-server/src/migrations/Migration20240507062612.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Migration } from '@mikro-orm/migrations'; - -export class Migration20240507062612 extends Migration { - - async up(): Promise { - this.addSql('alter table `account_whitelist` add `expiration_date` datetime not null;'); - } - - async down(): Promise { - this.addSql('alter table `account_whitelist` drop column `expiration_date`;'); - } - -} From b3aff2bf5e59646af3e46a2d6a5c4c52842a87ad Mon Sep 17 00:00:00 2001 From: usaveh Date: Thu, 16 May 2024 01:40:19 +0000 Subject: [PATCH 8/8] =?UTF-8?q?fix(changeset)=20changeset=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/chatty-sloths-wait.md | 2 +- .changeset/plenty-avocados-tap.md | 5 +++++ .../src/migrations/.snapshot-scow_server.json | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .changeset/plenty-avocados-tap.md diff --git a/.changeset/chatty-sloths-wait.md b/.changeset/chatty-sloths-wait.md index 4302767081..e31a742e2f 100644 --- a/.changeset/chatty-sloths-wait.md +++ b/.changeset/chatty-sloths-wait.md @@ -1,6 +1,6 @@ --- +"@scow/mis-web": patch "@scow/mis-server": patch -"@scow/grpc-api": patch --- getWhitelistedAccounts 新增返回字段 expirationDate,whitelistAccount 新增字段 expirationDate,在 getWhitelistedAccounts 新增每次查询会检测 中是否有账户过期,有的话会自动删除 diff --git a/.changeset/plenty-avocados-tap.md b/.changeset/plenty-avocados-tap.md new file mode 100644 index 0000000000..093eff2911 --- /dev/null +++ b/.changeset/plenty-avocados-tap.md @@ -0,0 +1,5 @@ +--- +"@scow/grpc-api": minor +--- + +getWhitelistedAccounts 新增返回字段 expirationDate,whitelistAccount 新增字段 expirationDate,在 getWhitelistedAccounts 新增每次查询会检测 中是否有账户过期,有的话会自动删除 diff --git a/apps/mis-server/src/migrations/.snapshot-scow_server.json b/apps/mis-server/src/migrations/.snapshot-scow_server.json index 510a6230ee..876ae3736a 100644 --- a/apps/mis-server/src/migrations/.snapshot-scow_server.json +++ b/apps/mis-server/src/migrations/.snapshot-scow_server.json @@ -39,6 +39,16 @@ "primary": false, "nullable": false, "mappedType": "string" + }, + "expiration_time": { + "name": "expiration_time", + "type": "datetime", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 0, + "mappedType": "datetime" } }, "name": "account_whitelist",