up
This commit is contained in:
@@ -185,6 +185,11 @@ func ApiUser(r *gin.RouterGroup) {
|
||||
}
|
||||
})
|
||||
|
||||
//修改用户头像
|
||||
r.POST("/updateAvatar", func(ctx *gin.Context) {
|
||||
|
||||
})
|
||||
|
||||
//更新用户info
|
||||
r.POST("/updateInfo", func(ctx *gin.Context) {
|
||||
isAuth, user, data := AuthenticationAuthority(ctx)
|
||||
|
||||
@@ -206,18 +206,18 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
|
||||
<router-link to="" class="dropdown-item">{{
|
||||
<!-- <router-link to="" class="dropdown-item">{{
|
||||
t("message.user_home")
|
||||
}}</router-link>
|
||||
}}</router-link> -->
|
||||
<router-link to="/settings/account" class="dropdown-item">{{
|
||||
t("message.user_settings")
|
||||
}}</router-link>
|
||||
<router-link to="" class="dropdown-item">{{
|
||||
<!-- <router-link to="" class="dropdown-item">{{
|
||||
t("message.preferences")
|
||||
}}</router-link>
|
||||
}}</router-link> -->
|
||||
<div class="dropdown-divider"></div>
|
||||
<!-- 如何用户是系统管理员这里显示跳转管理的url -->
|
||||
<router-link to="/admin" class="dropdown-item">
|
||||
<!-- <router-link to="/admin" class="dropdown-item">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
@@ -237,7 +237,7 @@ onMounted(() => {
|
||||
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||
</svg>
|
||||
{{ t("message.administrator") }}</router-link
|
||||
>
|
||||
> -->
|
||||
<div @click="logOut" class="dropdown-item">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -11,14 +11,31 @@ const { t } = useI18n();
|
||||
<div class="list-group list-group-transparent">
|
||||
<router-link
|
||||
to="/settings/account"
|
||||
class="list-group-item list-group-item-action d-flex align-items-center active"
|
||||
active-class="active"
|
||||
class="list-group-item list-group-item-action d-flex align-items-center"
|
||||
>
|
||||
{{t('settings.account_settings')}}</router-link
|
||||
{{t('settings.basic_information')}}</router-link
|
||||
>
|
||||
|
||||
|
||||
</div>
|
||||
<h4 class="subheader mt-4">{{t('settings.admin')}}</h4>
|
||||
<div class="list-group list-group-transparent">
|
||||
<router-link
|
||||
to="/settings/contact"
|
||||
active-class="active"
|
||||
class="list-group-item list-group-item-action d-flex align-items-center"
|
||||
>
|
||||
{{t('settings.contact_information')}}</router-link
|
||||
>
|
||||
</div>
|
||||
<div class="list-group list-group-transparent">
|
||||
<router-link
|
||||
to="/settings/security"
|
||||
active-class="active"
|
||||
class="list-group-item list-group-item-action d-flex align-items-center"
|
||||
>
|
||||
{{t('settings.security_settings')}}</router-link
|
||||
>
|
||||
</div>
|
||||
<!-- <h4 class="subheader mt-4">{{t('settings.admin')}}</h4>
|
||||
<div class="list-group list-group-transparent">
|
||||
<router-link
|
||||
to="/settings/account"
|
||||
@@ -26,7 +43,7 @@ const { t } = useI18n();
|
||||
>
|
||||
{{t('settings.website_settings')}}</router-link
|
||||
>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -105,6 +105,10 @@
|
||||
"confirm_password_incorrect": "Confirm password is incorrect"
|
||||
},
|
||||
"settings": {
|
||||
"cancel": "Cancel",
|
||||
"basic_information":"Basic Information",
|
||||
"contact_information":"Contact Information",
|
||||
"security_settings":"Security Settings",
|
||||
"account_settings": "Account Settings",
|
||||
"my_account": "My Account",
|
||||
"profile_information": "Profile Information",
|
||||
|
||||
@@ -105,6 +105,10 @@
|
||||
"confirm_password_incorrect":"确认密码不正确"
|
||||
},
|
||||
"settings": {
|
||||
"cancel": "取消",
|
||||
"basic_information":"基本信息",
|
||||
"contact_information":"联系信息",
|
||||
"security_settings":"安全设置",
|
||||
"account_settings": "个人设置",
|
||||
"my_account": "我的账户",
|
||||
"profile_information": "个人信息",
|
||||
|
||||
@@ -21,6 +21,9 @@ export const my_network_func = {
|
||||
re_data["error"] = error;
|
||||
callback(re_data);
|
||||
});
|
||||
},
|
||||
postflise(path,flise,json,callback){
|
||||
|
||||
},
|
||||
postJson(path, json, callback) {
|
||||
//把cookie插入json
|
||||
|
||||
@@ -13,6 +13,21 @@ const router = createRouter({
|
||||
name: "home",
|
||||
component: HomeView,
|
||||
},
|
||||
{
|
||||
path: "/settings/account",
|
||||
name: "settings account",
|
||||
component: () => import("../views/settings/account.vue"),
|
||||
},
|
||||
{
|
||||
path: "/settings/contact",
|
||||
name: "settings contact",
|
||||
component: () => import("../views/settings/contact.vue"),
|
||||
},
|
||||
{
|
||||
path: "/settings/security",
|
||||
name: "settings security",
|
||||
component: () => import("../views/settings/security.vue"),
|
||||
},
|
||||
{
|
||||
path: "/about",
|
||||
name: "about",
|
||||
@@ -46,11 +61,7 @@ const router = createRouter({
|
||||
name: "admin",
|
||||
component: () => import("../views/adminView.vue"),
|
||||
},
|
||||
{
|
||||
path: "/settings/account",
|
||||
name: "settings account",
|
||||
component: () => import("../views/settings/account.vue"),
|
||||
},
|
||||
|
||||
{
|
||||
path: "/schedule",
|
||||
name: "schedule",
|
||||
|
||||
@@ -7,7 +7,7 @@ import imageCropper from "@/components/imageCropper.vue";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { my_network_func } from "@/my_network_func";
|
||||
import MyOffcanvas from "@/components/MyOffcanvas.vue";
|
||||
import { myfuncs } from "@/myfunc";
|
||||
|
||||
import { useRouter } from "vue-router";
|
||||
const mos = ref();
|
||||
|
||||
@@ -19,24 +19,13 @@ const birthday = ref();
|
||||
const username = ref();
|
||||
const userremark = ref();
|
||||
|
||||
const emailInput = ref();
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const oldPassInput = ref();
|
||||
const newPassInput = ref();
|
||||
const cnfPassInput = ref();
|
||||
|
||||
const isShowPassword = ref(false);
|
||||
|
||||
const is_avatar_change = ref(false);
|
||||
const avatar_temp_url = ref("");
|
||||
|
||||
function togglePasswordVisibility() {
|
||||
isShowPassword.value = !isShowPassword.value;
|
||||
}
|
||||
|
||||
function updataInfo() {
|
||||
|
||||
let isDataErr = false;
|
||||
|
||||
let birthdayValue = birthday.value.datepicker.value;
|
||||
@@ -66,10 +55,13 @@ function updataInfo() {
|
||||
//console.log("用户信息有误,无法保存");
|
||||
return;
|
||||
}
|
||||
// console.log("保存用户信息");
|
||||
// console.log("用户名:", usernameValue);
|
||||
// console.log("备注:", userremarkValue);
|
||||
// console.log("生日:", birthdayValue);
|
||||
|
||||
//检查头像是否需要更新
|
||||
if(is_avatar_change)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
my_network_func.postJson(
|
||||
"/users/updateInfo",
|
||||
{
|
||||
@@ -100,158 +92,19 @@ function updataInfo() {
|
||||
);
|
||||
}
|
||||
|
||||
function changeEmail() {
|
||||
if (emailInput.value.value == "") {
|
||||
emailInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert("warning", t("message.please_enter_your_email"), 3000);
|
||||
return;
|
||||
} else {
|
||||
emailInput.value.classList.remove("is-invalid");
|
||||
}
|
||||
//判断是否是合法邮箱
|
||||
if (myfuncs.isValidEmail(emailInput.value.value) == false) {
|
||||
emailInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert("danger", t("message.this_not_email"), 3000);
|
||||
return;
|
||||
} else {
|
||||
emailInput.value.classList.remove("is-invalid");
|
||||
}
|
||||
|
||||
my_network_func.postJson(
|
||||
"/users/changeEmail",
|
||||
{
|
||||
newemail: emailInput.value.value,
|
||||
},
|
||||
(r) => {
|
||||
switch (r.statusCode) {
|
||||
case 200:
|
||||
switch (r.data.err_code) {
|
||||
case 0:
|
||||
mos.value?.showAlert("success", t("message.change_ok"), 5000);
|
||||
// 更新用户信息到store
|
||||
userStore.getUserInfoFromCookie();
|
||||
break;
|
||||
case -43:
|
||||
emailInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert("danger", t("message.this_not_email"), 3000);
|
||||
break;
|
||||
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.server_error"), 5000);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.network_err"), 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function changePassword() {
|
||||
let isDataErr = false;
|
||||
|
||||
let oldPass = oldPassInput.value.value;
|
||||
let newPass = newPassInput.value.value;
|
||||
let cnfPass = cnfPassInput.value.value;
|
||||
|
||||
oldPassInput.value.classList.remove("is-invalid");
|
||||
newPassInput.value.classList.remove("is-invalid");
|
||||
cnfPassInput.value.classList.remove("is-invalid");
|
||||
|
||||
if (!oldPass) {
|
||||
isDataErr = true;
|
||||
oldPassInput.value.classList.add("is-invalid");
|
||||
}
|
||||
if (!newPass) {
|
||||
isDataErr = true;
|
||||
newPassInput.value.classList.add("is-invalid");
|
||||
}
|
||||
|
||||
if (!cnfPass) {
|
||||
isDataErr = true;
|
||||
cnfPassInput.value.classList.add("is-invalid");
|
||||
}
|
||||
|
||||
if (newPass !== cnfPass) {
|
||||
isDataErr = true;
|
||||
newPassInput.value.classList.add("is-invalid");
|
||||
cnfPassInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert(
|
||||
"warning",
|
||||
t("message.confirm_password_incorrect"),
|
||||
3000
|
||||
);
|
||||
}
|
||||
if (isDataErr) {
|
||||
return;
|
||||
}
|
||||
|
||||
my_network_func.postJson(
|
||||
"/users/changePassword",
|
||||
{
|
||||
oldpass: oldPass,
|
||||
newpass: newPass,
|
||||
},
|
||||
(r) => {
|
||||
switch (r.statusCode) {
|
||||
case 200:
|
||||
switch (r.data.err_code) {
|
||||
case 0:
|
||||
// 清空输入框
|
||||
oldPassInput.value.value = "";
|
||||
newPassInput.value.value = "";
|
||||
cnfPassInput.value.value = "";
|
||||
mos.value?.showAlert(
|
||||
"success",
|
||||
t("message.change_ok"),
|
||||
2000,
|
||||
() => {
|
||||
userStore.logout();
|
||||
router.push("/");
|
||||
}
|
||||
);
|
||||
|
||||
break;
|
||||
case -42:
|
||||
oldPassInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert(
|
||||
"danger",
|
||||
t("message.old_pass_incorrect"),
|
||||
3000
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.server_error"), 5000);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.network_err"), 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function changeAvatar() {
|
||||
mos.value?.showAlert(
|
||||
"info",
|
||||
t("message.functionality_not_yet_developed"),
|
||||
5000
|
||||
);
|
||||
}
|
||||
|
||||
function rev_avatar_url(url) {
|
||||
is_avatar_change.value=true
|
||||
avatar_temp_url.value=url
|
||||
is_avatar_change.value = true;
|
||||
avatar_temp_url.value = url;
|
||||
//console.log(url)
|
||||
}
|
||||
|
||||
function cancel_change_avatar(){
|
||||
is_avatar_change.value=false
|
||||
|
||||
}
|
||||
|
||||
function functionupdataTitle() {
|
||||
document.title = "Operations." + t("settings.account_settings");
|
||||
document.title = "Operations." + t("settings.basic_information");
|
||||
}
|
||||
|
||||
// 监听语言变化,更新标题
|
||||
@@ -274,7 +127,7 @@ onMounted(() => {
|
||||
<div class="page-wrapper">
|
||||
<div class="page-header d-print-none">
|
||||
<div class="container-xl">
|
||||
<h2 class="page-title">{{ t("settings.account_settings") }}</h2>
|
||||
<h2 class="page-title">{{ t("settings.my_account") }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -285,14 +138,18 @@ onMounted(() => {
|
||||
<settingNavigation />
|
||||
<div class="col-12 col-md-9 d-flex flex-column">
|
||||
<div class="card-body">
|
||||
<h2 class="mb-4">{{ t("settings.my_account") }}</h2>
|
||||
<h3 class="card-title">
|
||||
<!-- <h2 class="mb-4">{{ t("settings.my_account") }}</h2> -->
|
||||
<!-- <h3 class="card-title">
|
||||
{{ t("settings.profile_information") }}
|
||||
</h3>
|
||||
</h3> -->
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto">
|
||||
<img
|
||||
:src="is_avatar_change?avatar_temp_url:userStore.getUserAvatarPath()"
|
||||
:src="
|
||||
is_avatar_change
|
||||
? avatar_temp_url
|
||||
: userStore.getUserAvatarPath()
|
||||
"
|
||||
alt=""
|
||||
class="avatar avatar-xl"
|
||||
/>
|
||||
@@ -300,9 +157,10 @@ onMounted(() => {
|
||||
<!-- <imageCropper /> -->
|
||||
<div class="col-auto " >
|
||||
<imageCropper @crop="rev_avatar_url"></imageCropper>
|
||||
<!-- <button class="btn" @click="changeAvatar">
|
||||
{{ t("settings.change_avatar") }}
|
||||
</button> -->
|
||||
|
||||
<button v-show="is_avatar_change" class="btn btn-outline-secondary " @click="cancel_change_avatar">
|
||||
{{ t("settings.cancel") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="card-title mt-4">-</h3>
|
||||
@@ -342,96 +200,6 @@ onMounted(() => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="card-title mt-4">{{ t("settings.email") }}</h3>
|
||||
<div>
|
||||
<div class="row g-2">
|
||||
<div class="col-auto">
|
||||
<input
|
||||
ref="emailInput"
|
||||
type="text"
|
||||
class="form-control w-auto"
|
||||
:value="userStore.user.Email"
|
||||
:placeholder="t('message.your_email_address')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="btn" @click="changeEmail">
|
||||
{{ t("settings.change_email") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="card-title mt-4">
|
||||
{{ t("settings.password") }}
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg
|
||||
v-if="!isShowPassword"
|
||||
@click="togglePasswordVisibility"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="icon"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path
|
||||
d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
v-if="isShowPassword"
|
||||
@click="togglePasswordVisibility"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="icon"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" />
|
||||
<path
|
||||
d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87"
|
||||
/>
|
||||
<path d="M3 3l18 18" />
|
||||
</svg>
|
||||
</h3>
|
||||
|
||||
<input
|
||||
ref="oldPassInput"
|
||||
:type="isShowPassword ? 'text' : 'password'"
|
||||
class="form-control w-auto mb-1"
|
||||
:placeholder="t('message.type_old_pass')"
|
||||
/>
|
||||
|
||||
<input
|
||||
ref="newPassInput"
|
||||
:type="isShowPassword ? 'text' : 'password'"
|
||||
class="form-control w-auto mb-1"
|
||||
:placeholder="t('message.type_new_pass')"
|
||||
/>
|
||||
<input
|
||||
ref="cnfPassInput"
|
||||
:type="isShowPassword ? 'text' : 'password'"
|
||||
class="form-control w-auto mb-1"
|
||||
:placeholder="t('message.type_cof_pass')"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<button class="btn" @click="changePassword">
|
||||
{{ t("settings.set_new_password") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
<script setup>
|
||||
import { onMounted, watch, ref } from "vue";
|
||||
import settingNavigation from "@/components/settingNavigation.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { my_network_func } from "@/my_network_func";
|
||||
import MyOffcanvas from "@/components/MyOffcanvas.vue";
|
||||
import { myfuncs } from "@/myfunc";
|
||||
import { useRouter } from "vue-router";
|
||||
const mos = ref();
|
||||
|
||||
const { t, locale } = useI18n();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const emailInput = ref();
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
|
||||
function changeEmail() {
|
||||
if (emailInput.value.value == "") {
|
||||
emailInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert("warning", t("message.please_enter_your_email"), 3000);
|
||||
return;
|
||||
} else {
|
||||
emailInput.value.classList.remove("is-invalid");
|
||||
}
|
||||
//判断是否是合法邮箱
|
||||
if (myfuncs.isValidEmail(emailInput.value.value) == false) {
|
||||
emailInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert("danger", t("message.this_not_email"), 3000);
|
||||
return;
|
||||
} else {
|
||||
emailInput.value.classList.remove("is-invalid");
|
||||
}
|
||||
|
||||
my_network_func.postJson(
|
||||
"/users/changeEmail",
|
||||
{
|
||||
newemail: emailInput.value.value,
|
||||
},
|
||||
(r) => {
|
||||
switch (r.statusCode) {
|
||||
case 200:
|
||||
switch (r.data.err_code) {
|
||||
case 0:
|
||||
mos.value?.showAlert("success", t("message.change_ok"), 5000);
|
||||
// 更新用户信息到store
|
||||
userStore.getUserInfoFromCookie();
|
||||
break;
|
||||
case -43:
|
||||
emailInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert("danger", t("message.this_not_email"), 3000);
|
||||
break;
|
||||
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.server_error"), 5000);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.network_err"), 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function functionupdataTitle() {
|
||||
document.title = "Operations." + t("settings.contact_information");
|
||||
}
|
||||
|
||||
// 监听语言变化,更新标题
|
||||
watch(locale, () => {
|
||||
functionupdataTitle();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
//console.log("account mounted");
|
||||
//username.value.value="Kevin";
|
||||
functionupdataTitle();
|
||||
|
||||
if (!userStore.isLoggedIn) {
|
||||
router.push("/login");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page-wrapper">
|
||||
<div class="page-header d-print-none">
|
||||
<div class="container-xl">
|
||||
<h2 class="page-title">{{ t("settings.my_account") }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<div class="card">
|
||||
<div class="row g-0">
|
||||
<settingNavigation />
|
||||
<div class="col-12 col-md-9 d-flex flex-column">
|
||||
<div class="card-body">
|
||||
|
||||
<h3 class="card-title mt-4">{{ t("settings.email") }}</h3>
|
||||
<div>
|
||||
<div class="row g-2">
|
||||
<div class="col-auto">
|
||||
<input
|
||||
ref="emailInput"
|
||||
type="text"
|
||||
class="form-control w-auto"
|
||||
:value="userStore.user.Email"
|
||||
:placeholder="t('message.your_email_address')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="btn" @click="changeEmail">
|
||||
{{ t("settings.change_email") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MyOffcanvas ref="mos" />
|
||||
</template>
|
||||
@@ -0,0 +1,230 @@
|
||||
<script setup>
|
||||
import { onMounted, watch, ref } from "vue";
|
||||
import settingNavigation from "@/components/settingNavigation.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { my_network_func } from "@/my_network_func";
|
||||
import MyOffcanvas from "@/components/MyOffcanvas.vue";
|
||||
|
||||
import { useRouter } from "vue-router";
|
||||
const mos = ref();
|
||||
|
||||
const { t, locale } = useI18n();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const oldPassInput = ref();
|
||||
const newPassInput = ref();
|
||||
const cnfPassInput = ref();
|
||||
|
||||
const isShowPassword = ref(false);
|
||||
|
||||
function togglePasswordVisibility() {
|
||||
isShowPassword.value = !isShowPassword.value;
|
||||
}
|
||||
|
||||
function changePassword() {
|
||||
let isDataErr = false;
|
||||
|
||||
let oldPass = oldPassInput.value.value;
|
||||
let newPass = newPassInput.value.value;
|
||||
let cnfPass = cnfPassInput.value.value;
|
||||
|
||||
oldPassInput.value.classList.remove("is-invalid");
|
||||
newPassInput.value.classList.remove("is-invalid");
|
||||
cnfPassInput.value.classList.remove("is-invalid");
|
||||
|
||||
if (!oldPass) {
|
||||
isDataErr = true;
|
||||
oldPassInput.value.classList.add("is-invalid");
|
||||
}
|
||||
if (!newPass) {
|
||||
isDataErr = true;
|
||||
newPassInput.value.classList.add("is-invalid");
|
||||
}
|
||||
|
||||
if (!cnfPass) {
|
||||
isDataErr = true;
|
||||
cnfPassInput.value.classList.add("is-invalid");
|
||||
}
|
||||
|
||||
if (newPass !== cnfPass) {
|
||||
isDataErr = true;
|
||||
newPassInput.value.classList.add("is-invalid");
|
||||
cnfPassInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert(
|
||||
"warning",
|
||||
t("message.confirm_password_incorrect"),
|
||||
3000
|
||||
);
|
||||
}
|
||||
if (isDataErr) {
|
||||
return;
|
||||
}
|
||||
|
||||
my_network_func.postJson(
|
||||
"/users/changePassword",
|
||||
{
|
||||
oldpass: oldPass,
|
||||
newpass: newPass,
|
||||
},
|
||||
(r) => {
|
||||
switch (r.statusCode) {
|
||||
case 200:
|
||||
switch (r.data.err_code) {
|
||||
case 0:
|
||||
// 清空输入框
|
||||
oldPassInput.value.value = "";
|
||||
newPassInput.value.value = "";
|
||||
cnfPassInput.value.value = "";
|
||||
mos.value?.showAlert(
|
||||
"success",
|
||||
t("message.change_ok"),
|
||||
2000,
|
||||
() => {
|
||||
userStore.logout();
|
||||
router.push("/");
|
||||
}
|
||||
);
|
||||
|
||||
break;
|
||||
case -42:
|
||||
oldPassInput.value.classList.add("is-invalid");
|
||||
mos.value?.showAlert(
|
||||
"danger",
|
||||
t("message.old_pass_incorrect"),
|
||||
3000
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.server_error"), 5000);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mos.value?.showAlert("danger", t("message.network_err"), 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function functionupdataTitle() {
|
||||
document.title = "Operations." + t("settings.security_settings");
|
||||
}
|
||||
|
||||
// 监听语言变化,更新标题
|
||||
watch(locale, () => {
|
||||
functionupdataTitle();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
//console.log("account mounted");
|
||||
//username.value.value="Kevin";
|
||||
functionupdataTitle();
|
||||
|
||||
if (!userStore.isLoggedIn) {
|
||||
router.push("/login");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page-wrapper">
|
||||
<div class="page-header d-print-none">
|
||||
<div class="container-xl">
|
||||
<h2 class="page-title">{{ t("settings.my_account") }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<div class="card">
|
||||
<div class="row g-0">
|
||||
<settingNavigation />
|
||||
<div class="col-12 col-md-9 d-flex flex-column">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title mt-4">
|
||||
{{ t("settings.password") }}
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/eye -->
|
||||
<svg
|
||||
v-if="!isShowPassword"
|
||||
@click="togglePasswordVisibility"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="icon"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
|
||||
<path
|
||||
d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
v-if="isShowPassword"
|
||||
@click="togglePasswordVisibility"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="icon"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" />
|
||||
<path
|
||||
d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87"
|
||||
/>
|
||||
<path d="M3 3l18 18" />
|
||||
</svg>
|
||||
</h3>
|
||||
|
||||
<input
|
||||
ref="oldPassInput"
|
||||
:type="isShowPassword ? 'text' : 'password'"
|
||||
class="form-control w-auto mb-1"
|
||||
:placeholder="t('message.type_old_pass')"
|
||||
/>
|
||||
|
||||
<input
|
||||
ref="newPassInput"
|
||||
:type="isShowPassword ? 'text' : 'password'"
|
||||
class="form-control w-auto mb-1"
|
||||
:placeholder="t('message.type_new_pass')"
|
||||
/>
|
||||
<input
|
||||
ref="cnfPassInput"
|
||||
:type="isShowPassword ? 'text' : 'password'"
|
||||
class="form-control w-auto mb-1"
|
||||
:placeholder="t('message.type_cof_pass')"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<button class="btn" @click="changePassword">
|
||||
{{ t("settings.set_new_password") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MyOffcanvas ref="mos" />
|
||||
</template>
|
||||
Reference in New Issue
Block a user