Translate user account info page

pull/436/head
Lorenzo 2025-06-26 00:36:22 +02:00
parent dfddfc3e06
commit b50121ad0b
8 changed files with 303 additions and 258 deletions

View File

@ -77,4 +77,8 @@ export default {
newPasswordNotSameOld: "The new password cannot be the same as the old password",
enterPasswordAgain: "Please enter the password again",
passwordsNotMatch: "The two passwords do not match!",
avatar: "Avatar",
nickName: "Nickname",
phoneNumber: "Phone Number",
changePassword: "Change Password",
}

View File

@ -289,4 +289,15 @@ export default {
step3: "3. Enter the verification code",
inputVerifyCode: "Please enter the verification code",
cancel: "Cancel",
authorizationManagement: "Authorization Management",
manageThirdPartyAuth: "Manage third-party system authorization information",
name: "Name",
pleaseEnterName: "Please enter the name",
nameHelper: "Fill in as you like, useful to distinguish when multiple authorizations of the same type exist",
level: "Level",
system: "System",
usera: "User",
nickName: "Nickname",
max50Chars: "Maximum 50 characters",
myInfo: "My Information",
};

View File

@ -78,4 +78,8 @@ export default {
newPasswordNotSameOld: "新密码不能和旧密码相同",
enterPasswordAgain: "请再次输入密码",
passwordsNotMatch: "两次输入密码不一致!",
avatar: "头像",
nickName: "昵称",
phoneNumber: "手机号",
changePassword: "修改密码",
}

View File

@ -295,4 +295,15 @@ export default {
step3: "3. 输入验证码",
inputVerifyCode: "请输入验证码",
cancel: "取消",
authorizationManagement: "授权管理",
manageThirdPartyAuth: "管理第三方系统授权信息",
name: "名称",
pleaseEnterName: "请填写名称",
nameHelper: "随便填,当多个相同类型的授权时,便于区分",
level: "级别",
system: "系统",
usera: "用户",
nickName: "昵称",
max50Chars: "最大50个字符",
myInfo: "我的信息",
};

View File

@ -2,8 +2,10 @@
import { ref } from "vue";
import { getCommonColumnDefine } from "/@/views/certd/access/common";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useI18n } from "vue-i18n";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
const { crudBinding } = crudExpose;
const { props, ctx, api } = context;
const lastResRef = ref();
@ -95,26 +97,26 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
},
},
name: {
title: "名称",
title: t("certd.name"),
search: {
show: true,
},
type: ["text"],
form: {
rules: [{ required: true, message: "请填写名称" }],
helper: "随便填,当多个相同类型的授权时,便于区分",
rules: [{ required: true, message: t("certd.pleaseEnterName") }],
helper: t("certd.nameHelper"),
},
column: {
width: 200,
},
},
from: {
title: "级别",
title: t("certd.level"),
type: "dict-select",
dict: dict({
data: [
{ label: "系统", value: "sys" },
{ label: "用户", value: "user" },
{ label: t("certd.system"), value: "sys" },
{ label: t("certd.usera"), value: "user" },
],
}),
search: {

View File

@ -2,8 +2,8 @@
<fs-page>
<template #header>
<div class="title">
授权管理
<span class="sub">管理第三方系统授权信息</span>
{{ t("certd.authorizationManagement") }}
<span class="sub">{{ t("certd.manageThirdPartyAuth") }}</span>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
@ -15,10 +15,13 @@ import { defineComponent, onActivated, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
import { createAccessApi } from "/@/views/certd/access/api";
import { useI18n } from "vue-i18n";
export default defineComponent({
name: "AccessManager",
setup() {
const { t } = useI18n();
const api = createAccessApi("user");
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
@ -33,6 +36,7 @@ export default defineComponent({
return {
crudBinding,
crudRef,
t
};
},
});

View File

@ -1,6 +1,6 @@
<template>
<a-button v-if="showButton" type="primary" @click="open">
{{ $t("passwordForm.changePasswordButton") }}
{{ $t("authentication.changePasswordButton") }}
</a-button>
</template>
@ -22,21 +22,21 @@ let passwordFormRef = ref();
const validatePass1 = async (rule: any, value: any) => {
if (value === "") {
throw new Error(t("passwordForm.enterPassword"));
throw new Error(t("authentication.enterPassword"));
}
const formData = passwordFormRef.value.getFormData();
if (formData.confirmNewPassword !== "") {
passwordFormRef.value.formRef.formRef.validateFields(["confirmNewPassword"]);
}
if (formData.password === formData.newPassword) {
throw new Error(t("passwordForm.newPasswordNotSameOld"));
throw new Error(t("authentication.newPasswordNotSameOld"));
}
};
const validatePass2 = async (rule: any, value: any) => {
if (value === "") {
throw new Error(t("passwordForm.enterPasswordAgain"));
throw new Error(t("authentication.enterPasswordAgain"));
} else if (value !== passwordFormRef.value.getFormData().newPassword) {
throw new Error(t("passwordForm.passwordsNotMatch"));
throw new Error(t("authentication.passwordsNotMatch"));
}
};
@ -49,7 +49,7 @@ const passwordFormOptions: CrudOptions = {
span: 24,
},
wrapper: {
title: t("passwordForm.title"),
title: t("authentication.title"),
width: "500px",
},
async doSubmit({ form }) {
@ -58,36 +58,36 @@ const passwordFormOptions: CrudOptions = {
await userStore.loadUserInfo();
},
async afterSubmit() {
notification.success({ message: t("passwordForm.successMessage") });
notification.success({ message: t("authentication.successMessage") });
},
},
columns: {
password: {
title: t("passwordForm.oldPassword"),
title: t("authentication.oldPassword"),
type: "password",
form: {
rules: [{ required: true, message: t("passwordForm.oldPasswordRequired") }],
rules: [{ required: true, message: t("authentication.oldPasswordRequired") }],
},
},
newPassword: {
title: t("passwordForm.newPassword"),
title: t("authentication.newPassword"),
type: "password",
form: {
rules: [
{ required: true, message: t("passwordForm.newPasswordRequired") },
{ required: true, message: t("authentication.newPasswordRequired") },
//@ts-ignore
{ validator: validatePass1, trigger: "blur" },
],
},
},
confirmNewPassword: {
title: t("passwordForm.confirmNewPassword"),
title: t("authentication.confirmNewPassword"),
type: "password",
form: {
rules: [
{
required: true,
message: t("passwordForm.confirmNewPasswordRequired"),
message: t("authentication.confirmNewPasswordRequired"),
},
//@ts-ignore
{ validator: validatePass2, trigger: "blur" },

View File

@ -1,32 +1,41 @@
<template>
<fs-page class="page-user-profile">
<template #header>
<div class="title">我的信息</div>
<div class="title">{{ t("certd.myInfo") }}</div>
</template>
<div class="p-10">
<a-descriptions title="" bordered>
<a-descriptions-item label="用户名">{{ userInfo.username }}</a-descriptions-item>
<a-descriptions-item label="头像">
<a-avatar v-if="userInfo.avatar" size="large" :src="'api/basic/file/download?&key=' + userInfo.avatar" style="background-color: #eee"> </a-avatar>
<a-descriptions title="" bordered :column="1">
<a-descriptions-item :label="t('authentication.username')">{{ userInfo.username }}</a-descriptions-item>
<a-descriptions-item :label="t('authentication.avatar')">
<a-avatar v-if="userInfo.avatar" size="large"
:src="'api/basic/file/download?&key=' + userInfo.avatar" style="background-color: #eee">
</a-avatar>
<a-avatar v-else size="large" style="background-color: #00b4f5">
{{ userInfo.username }}
</a-avatar>
</a-descriptions-item>
<a-descriptions-item label="昵称">{{ userInfo.nickName }}</a-descriptions-item>
<a-descriptions-item label="邮箱">{{ userInfo.email }}</a-descriptions-item>
<a-descriptions-item label="手机号">{{ userInfo.phoneCode }}{{ userInfo.mobile }}</a-descriptions-item>
<a-descriptions-item label="修改密码">
<a-descriptions-item :label="t('authentication.nickName')">{{ userInfo.nickName }}</a-descriptions-item>
<a-descriptions-item :label="t('authentication.email')">{{ userInfo.email }}</a-descriptions-item>
<a-descriptions-item :label="t('authentication.phoneNumber')">{{ userInfo.phoneCode }}{{ userInfo.mobile
}}</a-descriptions-item>
<a-descriptions-item :label="t('authentication.changePassword')">
<change-password-button :show-button="true"> </change-password-button>
</a-descriptions-item>
</a-descriptions>
</div>
</fs-page>
</template>
<script lang="ts" setup>
import * as api from "./api";
import { Ref, ref } from "vue";
import ChangePasswordButton from "/@/views/certd/mine/change-password-button.vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
defineOptions({
name: "UserProfile"