Unverified Commit 7717387f authored by chengchuen's avatar chengchuen Committed by GitHub

International Development (#1079)

Co-authored-by: 's avatarPeter <peter.zheng.external@tkelevator.com>
parent 3ddc5df2
......@@ -75,16 +75,16 @@ public class UserServiceImpl extends SuperServiceImpl<UserMapper, User> implemen
public Result modifyPassword(String username, String password, String newPassword) {
User user = getUserByUsername(username);
if (Asserts.isNull(user)) {
return Result.failed("该账号不存在");
return Result.failed("The account does not exist");
}
if (!Asserts.isEquals(SaSecureUtil.md5(password), user.getPassword())) {
return Result.failed("原密码错误");
return Result.failed("The old password is incorrect");
}
user.setPassword(SaSecureUtil.md5(newPassword));
if (updateById(user)) {
return Result.succeed("密码修改成功");
return Result.succeed("Password changed successfully");
}
return Result.failed("密码修改失败");
return Result.failed("Failed to change password");
}
@Override
......
......@@ -21,6 +21,8 @@
import {Settings as LayoutSettings} from '@ant-design/pro-layout';
const Settings: LayoutSettings & {
pwa?: boolean;
logo?: string;
} = {
......@@ -32,7 +34,7 @@ const Settings: LayoutSettings & {
fixedHeader: false,
fixSiderbar: true,
colorWeak: false,
title: 'Dinky 实时计算平台',
title: 'Dinky Real-time Platform ',
pwa: false,
logo: 'dinky.svg',
iconfontUrl: '',
......
......@@ -28,10 +28,11 @@ import Footer from '@/components/Footer';
import type {ResponseError} from 'umi-request';
import {currentUser as queryCurrentUser} from './services/ant-design-pro/api';
import {BookOutlined, LinkOutlined} from '@ant-design/icons';
import {useIntl} from "@@/plugin-locale/localeExports";
const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/user/login';
/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
loading: <PageLoading />,
......@@ -46,6 +47,8 @@ export async function getInitialState(): Promise<{
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
const fetchUserInfo = async () => {
try {
const result = await queryCurrentUser();
const currentUser: API.CurrentUser = {
......@@ -135,6 +138,8 @@ export const request: RequestConfig = {
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
return {
rightContentRender: () => <RightContent />,
disableContentMargin: false,
......@@ -153,11 +158,11 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
? [
<Link to="/umi/plugin/openapi" target="_blank">
<LinkOutlined />
<span>openAPI 文档</span>
<span>openAPI Document</span>
</Link>,
<Link to="/~docs">
<BookOutlined />
<span>业务组件文档</span>
<span>Business Component Document</span>
</Link>,
]
: [],
......
......@@ -49,4 +49,21 @@ export default {
'menu.editor.flow': 'Flow Editor',
'menu.editor.mind': 'Mind Editor',
'menu.editor.koni': 'Koni Editor',
'menu.datacenter': 'Mate Data Center',
'menu.datacenter.metadata': 'Mate Data',
'menu.registration': 'Regist Center',
'menu.registration.cluster': 'Cluster Management',
'menu.registration.cluster.clusterInstance': 'Cluster Instance',
'menu.registration.cluster.clusterConfiguration': 'Cluster Config',
'menu.registration.database': 'Data Source Management',
'menu.registration.alert': 'Alarm Management',
'menu.registration.alert.alertInstance': 'Alarm Instance Management',
'menu.registration.alert.alertGroup': 'Alarm Group Management',
'menu.registration.jar': 'Jar Management',
'menu.registration.document': 'Document Management',
'menu.registration.fragment': 'Global Variable Management',
'menu.datastudio': 'Data Studio',
'menu.settings': 'System Setting',
'menu.devops': 'Devops',
'menu.about': 'About',
};
This diff is collapsed.
......@@ -58,12 +58,12 @@ export default {
'menu.registration.alert': '报警管理',
'menu.registration.alert.alertInstance': '报警实例管理',
'menu.registration.alert.alertGroup': '报警组管理',
'menu.datastudio': '数据开发',
'menu.devops': '运维中心',
'menu.job': '作业实例',
'menu.registration.jar': 'Jar 管理',
'menu.registration.document': '文档管理',
'menu.registration.fragment': '全局变量管理',
'menu.datastudio': '数据开发',
'menu.devops': '运维中心',
'menu.job': '作业实例',
'menu.settings': '系统设置',
'menu.dev.flink': 'Flink 计算框架',
'menu.dev.flink.docs': '官方文档',
......
......@@ -18,7 +18,8 @@
*/
import {history} from 'umi';
import { useIntl, Link, history, FormattedMessage, SelectLang, useModel } from 'umi';
import {queryData} from "@/components/Common/crud";
import {useState, useRef, useEffect} from "react";
import type {ProColumns, ActionType} from '@ant-design/pro-table';
......@@ -37,14 +38,19 @@ import {
queryAllCatalogue
} from "@/pages/DevOps/service";
const OPS_STATUS_COLOR = {
success: 'lime',
padding: 'yellow',
}
const url = '/api/jobInstance';
const JobInstanceTable = (props: any) => {
const intl = useIntl();
const {status, activeKey, isHistory, taskStatus} = props;
const [time, setTime] = useState(() => Date.now());
const [opsStatusVisible, setOpsStatusVisible] = useState<boolean>(false);
......@@ -265,7 +271,8 @@ const JobInstanceTable = (props: any) => {
search={{
filterType: 'light',
}}
headerTitle={`上次更新时间:${moment(time).format('HH:mm:ss')}`}
headerTitle={intl.formatMessage({id: 'pages.devops.JobInstanceTable.LastUpdateTime', defaultMessage: '上次更新时间',})+`:${moment(time).format('HH:mm:ss')}`}
polling={status == activeKey ? 3000 : undefined}
pagination={{
pageSize: 10,
......
......@@ -26,11 +26,14 @@ import {useEffect, useState} from "react";
import {StatusCount} from "@/pages/DevOps/data";
import {JOB_STATUS} from "@/components/Common/JobStatus";
import {Switch} from "antd";
import { useIntl, Link, history, FormattedMessage, SelectLang, useModel } from 'umi';
const { Statistic } = StatisticCard;
const DevOps = () => {
const intl = useIntl();
const [isHistory, setIsHistory] = useState<boolean>(false);
const handleHistorySwicthChange = (checked: boolean) => {
......@@ -41,6 +44,8 @@ const DevOps = () => {
return (<Switch checkedChildren="历史" unCheckedChildren="实例" onChange={handleHistorySwicthChange}/>);
};
const statusCountDefault = [
{ key: '', title: renderSwitch(), value: 0, total: true },
{ key: JOB_STATUS.CREATED, status: 'default', title: '已创建', value: 0 },
......@@ -70,33 +75,33 @@ const DevOps = () => {
const statusHistoryCountData: StatusCount = result.datas.history;
const historyItems: any = [
{ key: '', title: renderSwitch(), value: statusHistoryCountData.all, total: true },
{ key: JOB_STATUS.CREATED, status: 'default', title: '已创建', value: statusHistoryCountData.created },
{ key: JOB_STATUS.INITIALIZING, status: 'default', title: '初始化', value: statusHistoryCountData.initializing },
{ key: JOB_STATUS.RUNNING, status: 'success', title: '运行中', value: statusHistoryCountData.running },
{ key: JOB_STATUS.FINISHED, status: 'processing', title: '已完成', value: statusHistoryCountData.finished },
{ key: JOB_STATUS.FAILING, status: 'error', title: '异常中', value: statusHistoryCountData.failing },
{ key: JOB_STATUS.FAILED, status: 'error', title: '已异常', value: statusHistoryCountData.failed },
{ key: JOB_STATUS.SUSPENDED, status: 'warning', title: '已暂停', value: statusHistoryCountData.suspended },
{ key: JOB_STATUS.CANCELLING, status: 'warning', title: '停止中', value: statusHistoryCountData.cancelling },
{ key: JOB_STATUS.CANCELED, status: 'warning', title: '停止', value: statusHistoryCountData.canceled },
{ key: JOB_STATUS.RESTARTING, status: 'default', title: '重启中', value: statusHistoryCountData.restarting },
{ key: JOB_STATUS.UNKNOWN, status: 'default', title: '未知', value: statusHistoryCountData.unknown },
{ key: JOB_STATUS.CREATED, status: 'default', title: intl.formatMessage({id: 'pages.devops.jobstatus.CREATED', defaultMessage: '已创建',}), value: statusHistoryCountData.created },
{ key: JOB_STATUS.INITIALIZING, status: 'default', title: intl.formatMessage({id: 'pages.devops.jobstatus.INITIALIZING', defaultMessage: '初始化',}), value: statusHistoryCountData.initializing },
{ key: JOB_STATUS.RUNNING, status: 'success', title: intl.formatMessage({id: 'pages.devops.jobstatus.RUNNING', defaultMessage: '运行中',}), value: statusHistoryCountData.running },
{ key: JOB_STATUS.FINISHED, status: 'processing', title: intl.formatMessage({id: 'pages.devops.jobstatus.FINISHED', defaultMessage: '已完成',}), value: statusHistoryCountData.finished },
{ key: JOB_STATUS.FAILING, status: 'error', title: intl.formatMessage({id: 'pages.devops.jobstatus.FAILING', defaultMessage: '异常中',}), value: statusHistoryCountData.failing },
{ key: JOB_STATUS.FAILED, status: 'error', title: intl.formatMessage({id: 'pages.devops.jobstatus.FAILED', defaultMessage: '已异常',}), value: statusHistoryCountData.failed },
{ key: JOB_STATUS.SUSPENDED, status: 'warning', title: intl.formatMessage({id: 'pages.devops.jobstatus.SUSPENDED', defaultMessage: '已暂停',}), value: statusHistoryCountData.suspended },
{ key: JOB_STATUS.CANCELLING, status: 'warning', title: intl.formatMessage({id: 'pages.devops.jobstatus.CANCELLING', defaultMessage: '停止中',}), value: statusHistoryCountData.cancelling },
{ key: JOB_STATUS.CANCELED, status: 'warning', title: intl.formatMessage({id: 'pages.devops.jobstatus.CANCELED', defaultMessage: '停止',}), value: statusHistoryCountData.canceled },
{ key: JOB_STATUS.RESTARTING, status: 'default', title: intl.formatMessage({id: 'pages.devops.jobstatus.RESTARTING', defaultMessage: '重启中',}), value: statusHistoryCountData.restarting },
{ key: JOB_STATUS.UNKNOWN, status: 'default', title: intl.formatMessage({id: 'pages.devops.jobstatus.UNKNOWN', defaultMessage: '未知',}), value: statusHistoryCountData.unknown },
];
setStatusHistoryCount(historyItems);
const statusCountData: StatusCount = result.datas.instance;
const items: any = [
{ key: '', title: renderSwitch(), value: statusCountData.all, total: true },
{ key: JOB_STATUS.CREATED, status: 'default', title: '已创建', value: statusCountData.created },
{ key: JOB_STATUS.INITIALIZING, status: 'default', title: '初始化', value: statusCountData.initializing },
{ key: JOB_STATUS.RUNNING, status: 'success', title: '运行中', value: statusCountData.running },
{ key: JOB_STATUS.FINISHED, status: 'processing', title: '已完成', value: statusCountData.finished },
{ key: JOB_STATUS.FAILING, status: 'error', title: '异常中', value: statusCountData.failing },
{ key: JOB_STATUS.FAILED, status: 'error', title: '已异常', value: statusCountData.failed },
{ key: JOB_STATUS.SUSPENDED, status: 'warning', title: '已暂停', value: statusCountData.suspended },
{ key: JOB_STATUS.CANCELLING, status: 'warning', title: '停止中', value: statusCountData.cancelling },
{ key: JOB_STATUS.CANCELED, status: 'warning', title: '停止', value: statusCountData.canceled },
{ key: JOB_STATUS.RESTARTING, status: 'default', title: '重启中', value: statusCountData.restarting },
{ key: JOB_STATUS.UNKNOWN, status: 'default', title: '未知', value: statusCountData.unknown },
{ key: JOB_STATUS.CREATED, status: 'default', title: intl.formatMessage({id: 'pages.devops.jobstatus.CREATED', defaultMessage: '已创建',}), value: statusCountData.created },
{ key: JOB_STATUS.INITIALIZING, status: 'default', title:intl.formatMessage({id: 'pages.devops.jobstatus.INITIALIZING', defaultMessage: '初始化',}), value: statusCountData.initializing },
{ key: JOB_STATUS.RUNNING, status: 'success', title: intl.formatMessage({id: 'pages.devops.jobstatus.RUNNING', defaultMessage: '运行中',}), value: statusCountData.running },
{ key: JOB_STATUS.FINISHED, status: 'processing', title: intl.formatMessage({id: 'pages.devops.jobstatus.FINISHED', defaultMessage: '已完成',}), value: statusCountData.finished },
{ key: JOB_STATUS.FAILING, status: 'error', title: intl.formatMessage({id: 'pages.devops.jobstatus.FAILING', defaultMessage: '异常中',}), value: statusCountData.failing },
{ key: JOB_STATUS.FAILED, status: 'error', title: intl.formatMessage({id: 'pages.devops.jobstatus.FAILED', defaultMessage: '已异常',}), value: statusCountData.failed },
{ key: JOB_STATUS.SUSPENDED, status: 'warning', title: intl.formatMessage({id: 'pages.devops.jobstatus.SUSPENDED', defaultMessage: '已暂停',}), value: statusCountData.suspended },
{ key: JOB_STATUS.CANCELLING, status: 'warning', title: intl.formatMessage({id: 'pages.devops.jobstatus.CANCELLING', defaultMessage: '停止中',}), value: statusCountData.cancelling },
{ key: JOB_STATUS.CANCELED, status: 'warning', title: intl.formatMessage({id: 'pages.devops.jobstatus.CANCELED', defaultMessage: '停止',}), value: statusCountData.canceled },
{ key: JOB_STATUS.RESTARTING, status: 'default', title: intl.formatMessage({id: 'pages.devops.jobstatus.RESTARTING', defaultMessage: '重启中',}), value: statusCountData.restarting },
{ key: JOB_STATUS.UNKNOWN, status: 'default', title: intl.formatMessage({id: 'pages.devops.jobstatus.UNKNOWN', defaultMessage: '未知',}), value: statusCountData.unknown },
];
setStatusCount(items);
});
......
......@@ -22,6 +22,7 @@ import {Form, Input, List, Switch} from 'antd';
import {connect} from "umi";
import {SettingsStateType} from "@/pages/Settings/model";
import {saveSettings} from "@/pages/Settings/function";
import { useIntl, Link, history, FormattedMessage, SelectLang} from 'umi';
type FlinkConfigProps = {
sqlSubmitJarPath: SettingsStateType['sqlSubmitJarPath'];
......@@ -34,8 +35,11 @@ type FlinkConfigProps = {
dispatch: any;
};
const FlinkConfigView: React.FC<FlinkConfigProps> = (props) => {
const intl = useIntl();
const {
sqlSubmitJarPath,
sqlSubmitJarParas,
......@@ -56,81 +60,81 @@ const FlinkConfigView: React.FC<FlinkConfigProps> = (props) => {
const getData = () => [
{
title: '提交FlinkSQL的Jar文件路径',
title: intl.formatMessage({id: 'pages.settings.FlinkURL', defaultMessage: '提交FlinkSQL的Jar文件路径',}),
description: (
editName != 'sqlSubmitJarPath' ?
(sqlSubmitJarPath ? sqlSubmitJarPath : '未设置') : (
(sqlSubmitJarPath ? sqlSubmitJarPath : intl.formatMessage({id: 'pages.settings.FlinkNoSetting', defaultMessage: intl.formatMessage({id: 'pages.settings.FlinkNoSetting', defaultMessage: '未设置',}),})) : (
<Input
id='sqlSubmitJarPath'
defaultValue={sqlSubmitJarPath}
onChange={onChange}
placeholder="hdfs:///dlink/jar/dlink-app.jar"/>)),
actions: editName != 'sqlSubmitJarPath' ? [<a onClick={({}) => handleEditClick('sqlSubmitJarPath')}>修改</a>] :
[<a onClick={({}) => handleSaveClick('sqlSubmitJarPath')}>保存</a>,
<a onClick={({}) => handleCancelClick()}>取消</a>],
actions: editName != 'sqlSubmitJarPath' ? [<a onClick={({}) => handleEditClick('sqlSubmitJarPath')}>{intl.formatMessage({id: 'pages.settings.FlinkUpdate', defaultMessage: '修改',})}</a>] :
[<a onClick={({}) => handleSaveClick('sqlSubmitJarPath')}>{intl.formatMessage({id: 'pages.settings.FlinkSave', defaultMessage: '保存',})}</a>,
<a onClick={({}) => handleCancelClick()}>{intl.formatMessage({id: 'pages.settings.FlinkCancel', defaultMessage: '取消',})}</a>],
},
{
title: '提交FlinkSQL的Jar的主类入参',
title: intl.formatMessage({id: 'pages.settings.FlinkSQLJarMainParameter', defaultMessage: '提交FlinkSQL的Jar的主类入参',}),
description: (
editName != 'sqlSubmitJarParas' ?
(sqlSubmitJarParas ? sqlSubmitJarParas : '未设置') : (<Input
(sqlSubmitJarParas ? sqlSubmitJarParas : intl.formatMessage({id: 'pages.settings.FlinkNoSetting', defaultMessage: '未设置',})) : (<Input
id='sqlSubmitJarParas'
defaultValue={sqlSubmitJarParas}
onChange={onChange}
placeholder=""/>)),
actions: editName != 'sqlSubmitJarParas' ? [<a onClick={({}) => handleEditClick('sqlSubmitJarParas')}>修改</a>] :
[<a onClick={({}) => handleSaveClick('sqlSubmitJarParas')}>保存</a>,
<a onClick={({}) => handleCancelClick()}>取消</a>],
actions: editName != 'sqlSubmitJarParas' ? [<a onClick={({}) => handleEditClick('sqlSubmitJarParas')}>{intl.formatMessage({id: 'pages.settings.FlinkUpdate', defaultMessage: '修改',})}</a>] :
[<a onClick={({}) => handleSaveClick('sqlSubmitJarParas')}>{intl.formatMessage({id: 'pages.settings.FlinkSave', defaultMessage: '保存',})}</a>,
<a onClick={({}) => handleCancelClick()}>{intl.formatMessage({id: 'pages.settings.FlinkCancel', defaultMessage: '取消',})}</a>],
},
{
title: '提交FlinkSQL的Jar的主类',
title: intl.formatMessage({id: 'pages.settings.FlinkSQLJarMainClass', defaultMessage: '提交FlinkSQL的Jar的主类',}),
description: (
editName != 'sqlSubmitJarMainAppClass' ?
(sqlSubmitJarMainAppClass ? sqlSubmitJarMainAppClass : '未设置') : (<Input
(sqlSubmitJarMainAppClass ? sqlSubmitJarMainAppClass : intl.formatMessage({id: 'pages.settings.FlinkNoSetting', defaultMessage: '未设置',})) : (<Input
id='sqlSubmitJarMainAppClass'
defaultValue={sqlSubmitJarMainAppClass}
onChange={onChange}
placeholder="com.dlink.app.MainApp"/>)),
actions: editName != 'sqlSubmitJarMainAppClass' ? [<a
onClick={({}) => handleEditClick('sqlSubmitJarMainAppClass')}>修改</a>] :
[<a onClick={({}) => handleSaveClick('sqlSubmitJarMainAppClass')}>保存</a>,
<a onClick={({}) => handleCancelClick()}>取消</a>],
onClick={({}) => handleEditClick('sqlSubmitJarMainAppClass')}>{intl.formatMessage({id: 'pages.settings.FlinkUpdate', defaultMessage: '修改',})}</a>] :
[<a onClick={({}) => handleSaveClick('sqlSubmitJarMainAppClass')}>{intl.formatMessage({id: 'pages.settings.FlinkSave', defaultMessage: '保存',})}</a>,
<a onClick={({}) => handleCancelClick()}>{intl.formatMessage({id: 'pages.settings.FlinkCancel', defaultMessage: '取消',})}</a>],
}, {
title: '使用 RestAPI',
description: '启用后,Flink 任务的 savepoint、停止等操作将通过 JobManager 的 RestAPI 进行',
title: intl.formatMessage({id: 'pages.settings.FlinkRestAPI', defaultMessage: '使用 RestAPI',}),
description: intl.formatMessage({id: 'pages.settings.FlinkNoUseSetting', defaultMessage: '启用后,Flink 任务的 savepoint、停止等操作将通过 JobManager 的 RestAPI 进行',}),
actions: [
<Form.Item
name="useRestAPI" valuePropName="checked"
>
<Switch checkedChildren="启用" unCheckedChildren="禁用"
<Switch checkedChildren={intl.formatMessage({id: 'pages.settings.FlinkUse', defaultMessage: '启用',})} unCheckedChildren={intl.formatMessage({id: 'pages.settings.FlinkNotUse', defaultMessage: '禁用',})}
checked={useRestAPI}
/></Form.Item>],
}, {
title: 'FlinkSQL语句分割符',
title: intl.formatMessage({id: 'pages.settings.FlinkURLSplit', defaultMessage: 'FlinkSQL语句分割符',}),
description: (
editName != 'sqlSeparator' ?
(sqlSeparator ? sqlSeparator : '未设置') : (<Input
(sqlSeparator ? sqlSeparator : intl.formatMessage({id: 'pages.settings.FlinkNoSetting', defaultMessage: '未设置',})) : (<Input
id='sqlSeparator'
defaultValue={sqlSeparator}
onChange={onChange}
placeholder=";"/>)),
actions: editName != 'sqlSeparator' ? [<a onClick={({}) => handleEditClick('sqlSeparator')}>修改</a>] :
[<a onClick={({}) => handleSaveClick('sqlSeparator')}>保存</a>,
<a onClick={({}) => handleCancelClick()}>取消</a>],
actions: editName != 'sqlSeparator' ? [<a onClick={({}) => handleEditClick('sqlSeparator')}>{intl.formatMessage({id: 'pages.settings.FlinkUpdate', defaultMessage: '修改',})}</a>] :
[<a onClick={({}) => handleSaveClick('sqlSeparator')}>{intl.formatMessage({id: 'pages.settings.FlinkSave', defaultMessage: '保存',})}</a>,
<a onClick={({}) => handleCancelClick()}>{intl.formatMessage({id: 'pages.settings.FlinkCancel', defaultMessage: '取消',})}</a>],
},
{
title: '使用逻辑计划计算血缘',
description: '在计算 Flink 任务的字段血缘分析时是否基于逻辑计划进行,只支持 1.14 版本',
title: intl.formatMessage({id: 'pages.settings.FlinkSQLLogic', defaultMessage: '使用逻辑计划计算血缘',}),
description: intl.formatMessage({id: 'pages.settings.FlinkNoUseSetting', defaultMessage: '在计算 Flink 任务的字段血缘分析时是否基于逻辑计划进行,只支持 1.14 版本',}),
actions: [
<Form.Item
name="useLogicalPlan" valuePropName="checked"
>
<Switch checkedChildren="启用" unCheckedChildren="禁用"
<Switch checkedChildren={intl.formatMessage({id: 'pages.settings.FlinkUse', defaultMessage: '启用',})} unCheckedChildren={intl.formatMessage({id: 'pages.settings.FlinkNotUse', defaultMessage: '禁用',})}
checked={useLogicalPlan}
/></Form.Item>],
},
{
title: '获取 Job ID 的最大等待时间(秒)',
title: intl.formatMessage({id: 'pages.settings.FlinkJobID', defaultMessage: '获取 Job ID 的最大等待时间(秒)',}),
description: (
editName != 'jobIdWait' ?
(jobIdWait ? jobIdWait : '30') : (
......@@ -139,9 +143,9 @@ const FlinkConfigView: React.FC<FlinkConfigProps> = (props) => {
defaultValue={jobIdWait}
onChange={onChange}
placeholder="30"/>)),
actions: editName != 'jobIdWait' ? [<a onClick={({}) => handleEditClick('jobIdWait')}>修改</a>] :
[<a onClick={({}) => handleSaveClick('jobIdWait')}>保存</a>,
<a onClick={({}) => handleCancelClick()}>取消</a>],
actions: editName != 'jobIdWait' ? [<a onClick={({}) => handleEditClick('jobIdWait')}>{intl.formatMessage({id: 'pages.settings.FlinkUpdate', defaultMessage: '修改',})}</a>] :
[<a onClick={({}) => handleSaveClick('jobIdWait')}>{intl.formatMessage({id: 'pages.settings.FlinkSave', defaultMessage: '保存',})}</a>,
<a onClick={({}) => handleCancelClick()}>{intl.formatMessage({id: 'pages.settings.FlinkCancel', defaultMessage: '取消',})}</a>],
},
];
......
......@@ -27,6 +27,7 @@ import {loadSettings} from "@/pages/Settings/function";
import {SettingsStateType} from "@/pages/Settings/model";
import {connect,useModel} from "umi";
import UserTableList from '../user';
import { useIntl, Link, history, FormattedMessage, SelectLang} from 'umi';
const { Item } = Menu;
......@@ -41,14 +42,17 @@ type SettingsProps = {
};
const Settings: React.FC<SettingsProps> = (props) => {
const intl = useIntl();
const { initialState, setInitialState } = useModel('@@initialState');
const menuMapAdmin: Record<string, React.ReactNode> = {
userManager: '用户管理',
flinkConfig: 'Flink 设置',
userManager: intl.formatMessage({id: 'pages.settings.UserManagement', defaultMessage: '用户管理',}),
flinkConfig: intl.formatMessage({id: 'pages.settings.Flink', defaultMessage: 'Flink 设置',}),
};
const menuMapUser: Record<string, React.ReactNode> = {
flinkConfig: 'Flink 设置',
flinkConfig: intl.formatMessage({id: 'pages.settings.Flink', defaultMessage: 'Flink 设置',}),
};
const menuMap: Record<string, React.ReactNode> = (initialState?.currentUser?.isAdmin)?menuMapAdmin:menuMapUser;
......
......@@ -21,6 +21,7 @@
import React, {useState} from 'react';
import {Form, Button, Input, Modal} from 'antd';
import {PasswordItem} from "@/pages/user/data";
import { useIntl, Link, history, FormattedMessage, SelectLang} from 'umi';
export type PasswordFormProps = {
onCancel: (flag?: boolean) => void;
......@@ -36,6 +37,8 @@ const formLayout = {
const PasswordForm: React.FC<PasswordFormProps> = (props) => {
const intl = useIntl();
const [form] = Form.useForm();
const [formVals, setFormVals] = useState<Partial<PasswordItem>>({
username: props.values.username,
......@@ -59,38 +62,38 @@ const PasswordForm: React.FC<PasswordFormProps> = (props) => {
<>
<Form.Item
name="password"
label="旧密码"
label= {intl.formatMessage({id: 'pages.user.UserOldPassword', defaultMessage: '旧密码',})}
hasFeedback
rules={[{required: true, message: '请输入旧密码!'}]}>
<Input.Password placeholder="请输入旧密码"/>
rules={[{required: true, message: intl.formatMessage({id: 'pages.user.UserEnterOldPassword', defaultMessage: '请输入旧密码!',})}]}>
<Input.Password placeholder={intl.formatMessage({id: 'pages.user.UserEnterOldPassword', defaultMessage: '请输入旧密码!',})}/>
</Form.Item>
<Form.Item
name="newPassword"
label="新密码"
label={intl.formatMessage({id: 'pages.user.UserNewPassword', defaultMessage: '新密码',})}
hasFeedback
rules={[{required: true, message: '请输入新密码!'}]}>
<Input.Password placeholder="请输入新密码"/>
rules={[{required: true, message: intl.formatMessage({id: 'pages.user.UserEnterNewPassword', defaultMessage: '请输入新密码',})}]}>
<Input.Password placeholder={intl.formatMessage({id: 'pages.user.UserEnterNewPassword', defaultMessage: '请输入新密码',})}/>
</Form.Item>
<Form.Item
name="newPasswordCheck"
label="重复新密码"
label={intl.formatMessage({id: 'pages.user.UserRepeatNewPassword', defaultMessage: '重复新密码',})}
hasFeedback
dependencies={['newPassword']}
rules={[
{
required: true,
message: '请重复输入一致的新密码',
message: intl.formatMessage({id: 'pages.user.UserNewPasswordNotMatch', defaultMessage: '重复密码不一致',}),
},
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('newPassword') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('重复新密码不一致!'));
return Promise.reject(new Error(intl.formatMessage({id: 'pages.user.UserNewPasswordNotMatch', defaultMessage: '重复密码不一致',})));
},
}),
]}>
<Input.Password placeholder="请重复输入新密码"/>
<Input.Password placeholder={intl.formatMessage({id: 'pages.user.UserEnterRepeatNewPassword', defaultMessage: '请重复输入新密码',})}/>
</Form.Item>
</>
);
......@@ -99,9 +102,9 @@ const PasswordForm: React.FC<PasswordFormProps> = (props) => {
const renderFooter = () => {
return (
<>
<Button onClick={() => handleModalVisible(false)}>取消</Button>
<Button onClick={() => handleModalVisible(false)}>{intl.formatMessage({id: 'pages.user.UserCancel', defaultMessage: '取消',})}</Button>
<Button type="primary" onClick={() => submitForm()}>
完成
{intl.formatMessage({id: 'pages.user.UserComplete', defaultMessage: '完成',})}
</Button>
</>
);
......@@ -112,7 +115,7 @@ const PasswordForm: React.FC<PasswordFormProps> = (props) => {
width={1200}
bodyStyle={{padding: '32px 40px 48px'}}
destroyOnClose
title="修改密码"
title={intl.formatMessage({id: 'pages.user.UserUpdatePassword', defaultMessage: '修改密码',})}
visible={modalVisible}
footer={renderFooter()}
onCancel={() => handleModalVisible()}
......
......@@ -21,6 +21,7 @@
import React, {useState} from 'react';
import {Form, Button, Input, Modal, Switch} from 'antd';
import {UserTableListItem} from "@/pages/user/data";
import { useIntl, Link, history, FormattedMessage, SelectLang} from 'umi';
export type UserFormProps = {
onCancel: (flag?: boolean) => void;
......@@ -36,6 +37,8 @@ const formLayout = {
const UserForm: React.FC<UserFormProps> = (props) => {
const intl = useIntl();
const [form] = Form.useForm();
const [formVals, setFormVals] = useState<Partial<UserTableListItem>>({
id: props.values.id,
......@@ -66,32 +69,32 @@ const UserForm: React.FC<UserFormProps> = (props) => {
<>
<Form.Item
name="username"
label="用户名"
rules={[{required: true, message: '请输入用户名!'}]}>
<Input placeholder="请输入唯一用户名"/>
label={intl.formatMessage({id: 'pages.user.UserName', defaultMessage: '用户名',})}
rules={[{required: true, message: intl.formatMessage({id: 'pages.user.UserEnterUserName', defaultMessage: '请输入用户名',})}]}>
<Input placeholder={intl.formatMessage({id: 'pages.user.UserEnterUniqueUserName', defaultMessage: "请输入唯一用户名",})}/>
</Form.Item>
<Form.Item
name="nickname"
label="昵称"
label={intl.formatMessage({id: 'pages.user.UserNickName', defaultMessage: '昵称',})}
>
<Input placeholder="请输入昵称"/>
<Input placeholder={intl.formatMessage({id: 'pages.user.UserEnterNickName', defaultMessage: "请输入昵称",})}/>
</Form.Item>
<Form.Item
name="worknum"
label="工号"
label={intl.formatMessage({id: 'pages.user.UserJobNumber', defaultMessage: '工号',})}
>
<Input placeholder="请输入工号"/>
<Input placeholder={intl.formatMessage({id: 'pages.user.UserEnterJobNumber', defaultMessage: "请输入工号",})}/>
</Form.Item>
<Form.Item
name="mobile"
label="手机号"
label={intl.formatMessage({id: 'pages.user.UserPhoneNumber', defaultMessage: '手机号',})}
>
<Input placeholder="请输入手机号"/>
<Input placeholder={intl.formatMessage({id: 'pages.user.UserEnterPhoneNumber', defaultMessage: "请输入手机号",})}/>
</Form.Item>
<Form.Item
name="enabled"
label="是否启用">
<Switch checkedChildren="启用" unCheckedChildren="禁用"
label={intl.formatMessage({id: 'pages.user.UserIsUse', defaultMessage: '是否启用',})}>
<Switch checkedChildren={intl.formatMessage({id: 'pages.user.UserInUse', defaultMessage: '启用',})} unCheckedChildren={intl.formatMessage({id: 'pages.user.UserNotUse', defaultMessage: '禁用',})}
defaultChecked={formVals.enabled}/>
</Form.Item>
</>
......@@ -101,9 +104,9 @@ const UserForm: React.FC<UserFormProps> = (props) => {
const renderFooter = () => {
return (
<>
<Button onClick={() => handleModalVisible(false)}>取消</Button>
<Button onClick={() => handleModalVisible(false)}>{intl.formatMessage({id: 'pages.user.UserCancel', defaultMessage: '取消',})}</Button>
<Button type="primary" onClick={() => submitForm()}>
完成
{intl.formatMessage({id: 'pages.user.UserComplete', defaultMessage: '完成',})}
</Button>
</>
);
......@@ -114,7 +117,7 @@ const UserForm: React.FC<UserFormProps> = (props) => {
width={1200}
bodyStyle={{padding: '32px 40px 48px'}}
destroyOnClose
title={formVals.id?"维护用户":"创建用户"}
title={formVals.id?intl.formatMessage({id: 'pages.user.UserUpdateUser', defaultMessage: '维护用户',}):intl.formatMessage({id: 'pages.user.UserCreateUser', defaultMessage: '创建用户',})}
visible={modalVisible}
footer={renderFooter()}
onCancel={() => handleModalVisible()}
......
......@@ -29,9 +29,13 @@ import {UserTableListItem} from "@/pages/user/data";
import {handleAddOrUpdate, handleOption, handleRemove, queryData, updateEnabled} from "@/components/Common/crud";
import UserForm from "@/pages/user/components/UserForm";
import PasswordForm from "@/pages/user/components/PasswordForm";
import { useIntl, Link, history, FormattedMessage, SelectLang} from 'umi';
const url = '/api/user';
const UserTableList: React.FC<{}> = (props: any) => {
const intl = useIntl();
const {dispatch} = props;
const [row, setRow] = useState<UserTableListItem>();
const [modalVisible, handleModalVisible] = useState<boolean>(false);
......@@ -50,10 +54,10 @@ const UserTableList: React.FC<{}> = (props: any) => {
handlePasswordModalVisible(true);
} else if (key === 'delete') {
Modal.confirm({
title: '删除用户',
content: '确定删除该用户吗?',
okText: '确认',
cancelText: '取消',
title: intl.formatMessage({id: 'pages.user.UserDelete', defaultMessage: '删除用户',}),
content: intl.formatMessage({id: 'pages.user.UserDeleteUser', defaultMessage: '确定删除该用户吗?',}),
okText: intl.formatMessage({id: 'pages.user.UserConfirm', defaultMessage: '确认',}),
cancelText: intl.formatMessage({id: 'pages.user.UserCancel', defaultMessage: '取消',}),
onOk: async () => {
await handleRemove(url, [currentItem]);
actionRef.current?.reloadAndRest?.();
......@@ -68,21 +72,21 @@ const UserTableList: React.FC<{}> = (props: any) => {
<Dropdown
overlay={
<Menu onClick={({key}) => editAndDelete(key, item)}>
<Menu.Item key="edit">编辑</Menu.Item>
<Menu.Item key="password">修改密码</Menu.Item>
{item.username=='admin'?'':(<Menu.Item key="delete">删除</Menu.Item>)}
<Menu.Item key="edit">{intl.formatMessage({id: 'pages.user.UserEdit', defaultMessage: '编辑',})}</Menu.Item>
<Menu.Item key="password">{intl.formatMessage({id: 'pages.user.UserChangePassword', defaultMessage: '修改密码',})}</Menu.Item>
{item.username=='admin'?'':(<Menu.Item key="delete">{intl.formatMessage({id: 'pages.user.UserDelete', defaultMessage: '删除',})}</Menu.Item>)}
</Menu>
}
>
<a>
更多 <DownOutlined/>
{intl.formatMessage({id: 'pages.user.UserMore', defaultMessage: '更多',})} <DownOutlined/>
</a>
</Dropdown>
);
const columns: ProColumns<UserTableListItem>[] = [
{
title: '用户名',
title: intl.formatMessage({id: 'pages.user.UserName', defaultMessage: '用户名',}),
dataIndex: 'username',
sorter: true,
render: (dom, entity) => {
......@@ -97,60 +101,60 @@ const UserTableList: React.FC<{}> = (props: any) => {
hideInSearch: true,
},
{
title: '昵称',
title: intl.formatMessage({id: 'pages.user.UserNickName', defaultMessage: '昵称',}),
sorter: true,
dataIndex: 'nickname',
hideInTable: false,
},
{
title: '工号',
title: intl.formatMessage({id: 'pages.user.UserJobNumber', defaultMessage: '工号',}),
sorter: true,
dataIndex: 'worknum',
hideInTable: false,
},
{
title: '手机号',
title: intl.formatMessage({id: 'pages.user.UserPhoneNumber', defaultMessage: '手机号',}),
sorter: true,
dataIndex: 'mobile',
hideInTable: false,
},
{
title: '是否启用',
title: intl.formatMessage({id: 'pages.user.UserIsUse', defaultMessage: '是否启用',}),
dataIndex: 'enabled',
hideInForm: true,
hideInSearch: true,
hideInTable: false,
filters: [
{
text: '已启用',
text: intl.formatMessage({id: 'pages.user.UserInUse', defaultMessage: '已启用',}),
value: 1,
},
{
text: '已禁用',
text: intl.formatMessage({id: 'pages.user.UserNotUse', defaultMessage: '已禁用',}),
value: 0,
},
],
filterMultiple: false,
valueEnum: {
true: {text: '已启用', status: 'Success'},
false: {text: '已禁用', status: 'Error'},
true: {text: intl.formatMessage({id: 'pages.user.UserInUse', defaultMessage: '已启用',}), status: 'Success'},
false: {text: intl.formatMessage({id: 'pages.user.UserNotUse', defaultMessage: '已禁用',}), status: 'Error'},
},
},
{
title: '创建时间',
title: intl.formatMessage({id: 'pages.user.UserCreateTime', defaultMessage: '创建时间',}),
dataIndex: 'createTime',
sorter: true,
valueType: 'dateTime',
hideInTable: true,
},
{
title: '最近更新时间',
title: intl.formatMessage({id: 'pages.user.UserUpdateTime', defaultMessage: '最近更新时间',}),
dataIndex: 'updateTime',
sorter: true,
valueType: 'dateTime',
},
{
title: '操作',
title: intl.formatMessage({id: 'pages.user.UserOperate', defaultMessage: '操作',}),
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
......@@ -160,7 +164,7 @@ const UserTableList: React.FC<{}> = (props: any) => {
setFormValues(record);
}}
>
配置
{intl.formatMessage({id: 'pages.user.UserConfig', defaultMessage: intl.formatMessage({id: 'pages.user.UserConfig', defaultMessage: '配置',}),})}
</a>,
<MoreBtn key="more" item={record}/>,
],
......@@ -170,7 +174,7 @@ const UserTableList: React.FC<{}> = (props: any) => {
return (
<>
<ProTable<UserTableListItem>
headerTitle="用户管理"
headerTitle={intl.formatMessage({id: 'pages.user.UserManger', defaultMessage: '用户管理',})}
actionRef={actionRef}
rowKey="id"
search={{
......@@ -178,7 +182,7 @@ const UserTableList: React.FC<{}> = (props: any) => {
}}
toolBarRender={() => [
<Button type="primary" onClick={() => handleModalVisible(true)}>
<PlusOutlined/> 新建
<PlusOutlined/> {intl.formatMessage({id: 'pages.user.UserCreate', defaultMessage: '新建',})}
</Button>,
]}
request={(params, sorter, filter) => queryData(url, {...params, sorter, filter})}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment