up
This commit is contained in:
@@ -185,6 +185,11 @@ func ApiUser(r *gin.RouterGroup) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//修改用户头像
|
||||||
|
r.POST("/updateAvatar", func(ctx *gin.Context) {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
//更新用户info
|
//更新用户info
|
||||||
r.POST("/updateInfo", func(ctx *gin.Context) {
|
r.POST("/updateInfo", func(ctx *gin.Context) {
|
||||||
isAuth, user, data := AuthenticationAuthority(ctx)
|
isAuth, user, data := AuthenticationAuthority(ctx)
|
||||||
|
|||||||
@@ -206,18 +206,18 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
|
<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")
|
t("message.user_home")
|
||||||
}}</router-link>
|
}}</router-link> -->
|
||||||
<router-link to="/settings/account" class="dropdown-item">{{
|
<router-link to="/settings/account" class="dropdown-item">{{
|
||||||
t("message.user_settings")
|
t("message.user_settings")
|
||||||
}}</router-link>
|
}}</router-link>
|
||||||
<router-link to="" class="dropdown-item">{{
|
<!-- <router-link to="" class="dropdown-item">{{
|
||||||
t("message.preferences")
|
t("message.preferences")
|
||||||
}}</router-link>
|
}}</router-link> -->
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<!-- 如何用户是系统管理员这里显示跳转管理的url -->
|
<!-- 如何用户是系统管理员这里显示跳转管理的url -->
|
||||||
<router-link to="/admin" class="dropdown-item">
|
<!-- <router-link to="/admin" class="dropdown-item">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="24"
|
width="24"
|
||||||
@@ -237,7 +237,7 @@ onMounted(() => {
|
|||||||
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
|
||||||
</svg>
|
</svg>
|
||||||
{{ t("message.administrator") }}</router-link
|
{{ t("message.administrator") }}</router-link
|
||||||
>
|
> -->
|
||||||
<div @click="logOut" class="dropdown-item">
|
<div @click="logOut" class="dropdown-item">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@@ -11,14 +11,31 @@ const { t } = useI18n();
|
|||||||
<div class="list-group list-group-transparent">
|
<div class="list-group list-group-transparent">
|
||||||
<router-link
|
<router-link
|
||||||
to="/settings/account"
|
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>
|
</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">
|
<div class="list-group list-group-transparent">
|
||||||
<router-link
|
<router-link
|
||||||
to="/settings/account"
|
to="/settings/account"
|
||||||
@@ -26,7 +43,7 @@ const { t } = useI18n();
|
|||||||
>
|
>
|
||||||
{{t('settings.website_settings')}}</router-link
|
{{t('settings.website_settings')}}</router-link
|
||||||
>
|
>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -105,6 +105,10 @@
|
|||||||
"confirm_password_incorrect": "Confirm password is incorrect"
|
"confirm_password_incorrect": "Confirm password is incorrect"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"basic_information":"Basic Information",
|
||||||
|
"contact_information":"Contact Information",
|
||||||
|
"security_settings":"Security Settings",
|
||||||
"account_settings": "Account Settings",
|
"account_settings": "Account Settings",
|
||||||
"my_account": "My Account",
|
"my_account": "My Account",
|
||||||
"profile_information": "Profile Information",
|
"profile_information": "Profile Information",
|
||||||
|
|||||||
@@ -105,6 +105,10 @@
|
|||||||
"confirm_password_incorrect":"确认密码不正确"
|
"confirm_password_incorrect":"确认密码不正确"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
"cancel": "取消",
|
||||||
|
"basic_information":"基本信息",
|
||||||
|
"contact_information":"联系信息",
|
||||||
|
"security_settings":"安全设置",
|
||||||
"account_settings": "个人设置",
|
"account_settings": "个人设置",
|
||||||
"my_account": "我的账户",
|
"my_account": "我的账户",
|
||||||
"profile_information": "个人信息",
|
"profile_information": "个人信息",
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ export const my_network_func = {
|
|||||||
re_data["error"] = error;
|
re_data["error"] = error;
|
||||||
callback(re_data);
|
callback(re_data);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
postflise(path,flise,json,callback){
|
||||||
|
|
||||||
},
|
},
|
||||||
postJson(path, json, callback) {
|
postJson(path, json, callback) {
|
||||||
//把cookie插入json
|
//把cookie插入json
|
||||||
|
|||||||
@@ -13,6 +13,21 @@ const router = createRouter({
|
|||||||
name: "home",
|
name: "home",
|
||||||
component: HomeView,
|
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",
|
path: "/about",
|
||||||
name: "about",
|
name: "about",
|
||||||
@@ -46,11 +61,7 @@ const router = createRouter({
|
|||||||
name: "admin",
|
name: "admin",
|
||||||
component: () => import("../views/adminView.vue"),
|
component: () => import("../views/adminView.vue"),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/settings/account",
|
|
||||||
name: "settings account",
|
|
||||||
component: () => import("../views/settings/account.vue"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/schedule",
|
path: "/schedule",
|
||||||
name: "schedule",
|
name: "schedule",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import imageCropper from "@/components/imageCropper.vue";
|
|||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
import { my_network_func } from "@/my_network_func";
|
import { my_network_func } from "@/my_network_func";
|
||||||
import MyOffcanvas from "@/components/MyOffcanvas.vue";
|
import MyOffcanvas from "@/components/MyOffcanvas.vue";
|
||||||
import { myfuncs } from "@/myfunc";
|
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
const mos = ref();
|
const mos = ref();
|
||||||
|
|
||||||
@@ -19,24 +19,13 @@ const birthday = ref();
|
|||||||
const username = ref();
|
const username = ref();
|
||||||
const userremark = ref();
|
const userremark = ref();
|
||||||
|
|
||||||
const emailInput = ref();
|
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const oldPassInput = ref();
|
|
||||||
const newPassInput = ref();
|
|
||||||
const cnfPassInput = ref();
|
|
||||||
|
|
||||||
const isShowPassword = ref(false);
|
|
||||||
|
|
||||||
const is_avatar_change = ref(false);
|
const is_avatar_change = ref(false);
|
||||||
const avatar_temp_url = ref("");
|
const avatar_temp_url = ref("");
|
||||||
|
|
||||||
function togglePasswordVisibility() {
|
|
||||||
isShowPassword.value = !isShowPassword.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updataInfo() {
|
function updataInfo() {
|
||||||
|
|
||||||
let isDataErr = false;
|
let isDataErr = false;
|
||||||
|
|
||||||
let birthdayValue = birthday.value.datepicker.value;
|
let birthdayValue = birthday.value.datepicker.value;
|
||||||
@@ -66,10 +55,13 @@ function updataInfo() {
|
|||||||
//console.log("用户信息有误,无法保存");
|
//console.log("用户信息有误,无法保存");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// console.log("保存用户信息");
|
|
||||||
// console.log("用户名:", usernameValue);
|
//检查头像是否需要更新
|
||||||
// console.log("备注:", userremarkValue);
|
if(is_avatar_change)
|
||||||
// console.log("生日:", birthdayValue);
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
my_network_func.postJson(
|
my_network_func.postJson(
|
||||||
"/users/updateInfo",
|
"/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) {
|
function rev_avatar_url(url) {
|
||||||
is_avatar_change.value=true
|
is_avatar_change.value = true;
|
||||||
avatar_temp_url.value=url
|
avatar_temp_url.value = url;
|
||||||
//console.log(url)
|
//console.log(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cancel_change_avatar(){
|
||||||
|
is_avatar_change.value=false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function functionupdataTitle() {
|
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-wrapper">
|
||||||
<div class="page-header d-print-none">
|
<div class="page-header d-print-none">
|
||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
<h2 class="page-title">{{ t("settings.account_settings") }}</h2>
|
<h2 class="page-title">{{ t("settings.my_account") }}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -285,14 +138,18 @@ onMounted(() => {
|
|||||||
<settingNavigation />
|
<settingNavigation />
|
||||||
<div class="col-12 col-md-9 d-flex flex-column">
|
<div class="col-12 col-md-9 d-flex flex-column">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="mb-4">{{ t("settings.my_account") }}</h2>
|
<!-- <h2 class="mb-4">{{ t("settings.my_account") }}</h2> -->
|
||||||
<h3 class="card-title">
|
<!-- <h3 class="card-title">
|
||||||
{{ t("settings.profile_information") }}
|
{{ t("settings.profile_information") }}
|
||||||
</h3>
|
</h3> -->
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<img
|
<img
|
||||||
:src="is_avatar_change?avatar_temp_url:userStore.getUserAvatarPath()"
|
:src="
|
||||||
|
is_avatar_change
|
||||||
|
? avatar_temp_url
|
||||||
|
: userStore.getUserAvatarPath()
|
||||||
|
"
|
||||||
alt=""
|
alt=""
|
||||||
class="avatar avatar-xl"
|
class="avatar avatar-xl"
|
||||||
/>
|
/>
|
||||||
@@ -300,9 +157,10 @@ onMounted(() => {
|
|||||||
<!-- <imageCropper /> -->
|
<!-- <imageCropper /> -->
|
||||||
<div class="col-auto " >
|
<div class="col-auto " >
|
||||||
<imageCropper @crop="rev_avatar_url"></imageCropper>
|
<imageCropper @crop="rev_avatar_url"></imageCropper>
|
||||||
<!-- <button class="btn" @click="changeAvatar">
|
|
||||||
{{ t("settings.change_avatar") }}
|
<button v-show="is_avatar_change" class="btn btn-outline-secondary " @click="cancel_change_avatar">
|
||||||
</button> -->
|
{{ t("settings.cancel") }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="card-title mt-4">-</h3>
|
<h3 class="card-title mt-4">-</h3>
|
||||||
@@ -342,96 +200,6 @@ onMounted(() => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</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