style: 调整 Vue 组件内 script 标签到 template 标签之前
1.template 和 style 挨在一起,便于样式调整 2.打开文件,可以便于修改 Script 代码
This commit is contained in:
@@ -1,56 +1,3 @@
|
||||
<template>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:label-col-props="{ span: 8 }"
|
||||
:wrapper-col-props="{ span: 16 }"
|
||||
size="large"
|
||||
class="form"
|
||||
>
|
||||
<a-form-item
|
||||
:label="$t('userCenter.basicInfo.form.label.username')"
|
||||
disabled
|
||||
>
|
||||
<a-input
|
||||
v-model="form.username"
|
||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.username')"
|
||||
:max-length="64"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="$t('userCenter.basicInfo.form.label.nickname')"
|
||||
field="nickname"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.nickname"
|
||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.nickname')"
|
||||
:max-length="30"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="$t('userCenter.basicInfo.form.label.gender')"
|
||||
field="gender"
|
||||
>
|
||||
<a-radio-group v-model="form.gender">
|
||||
<a-radio :value="1">男</a-radio>
|
||||
<a-radio :value="2">女</a-radio>
|
||||
<a-radio :value="0" disabled>未知</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button :loading="loading" type="primary" @click="handleSave">
|
||||
{{ $t('userCenter.basicInfo.form.save') }}
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
{{ $t('userCenter.basicInfo.form.reset') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FieldRule } from '@arco-design/web-vue';
|
||||
import { BasicInfoModel, updateBasicInfo } from '@/api/system/user-center';
|
||||
@@ -125,6 +72,59 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:label-col-props="{ span: 8 }"
|
||||
:wrapper-col-props="{ span: 16 }"
|
||||
size="large"
|
||||
class="form"
|
||||
>
|
||||
<a-form-item
|
||||
:label="$t('userCenter.basicInfo.form.label.username')"
|
||||
disabled
|
||||
>
|
||||
<a-input
|
||||
v-model="form.username"
|
||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.username')"
|
||||
:max-length="64"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="$t('userCenter.basicInfo.form.label.nickname')"
|
||||
field="nickname"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.nickname"
|
||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.nickname')"
|
||||
:max-length="30"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="$t('userCenter.basicInfo.form.label.gender')"
|
||||
field="gender"
|
||||
>
|
||||
<a-radio-group v-model="form.gender">
|
||||
<a-radio :value="1">男</a-radio>
|
||||
<a-radio :value="2">女</a-radio>
|
||||
<a-radio :value="0" disabled>未知</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button :loading="loading" type="primary" @click="handleSave">
|
||||
{{ $t('userCenter.basicInfo.form.save') }}
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
{{ $t('userCenter.basicInfo.form.reset') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.form {
|
||||
width: 540px;
|
||||
|
@@ -1,60 +1,3 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<!-- 列表区域 -->
|
||||
<a-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:data="dataList"
|
||||
:loading="loading"
|
||||
:pagination="{
|
||||
showTotal: true,
|
||||
showPageSize: true,
|
||||
total: total,
|
||||
current: queryParams.page,
|
||||
}"
|
||||
:bordered="false"
|
||||
column-resizable
|
||||
stripe
|
||||
size="large"
|
||||
@page-change="handlePageChange"
|
||||
@page-size-change="handlePageSizeChange"
|
||||
>
|
||||
<template #columns>
|
||||
<a-table-column title="序号">
|
||||
<template #cell="{ rowIndex }">
|
||||
{{ rowIndex + 1 + (queryParams.page - 1) * queryParams.size }}
|
||||
</template>
|
||||
</a-table-column>
|
||||
<a-table-column title="操作时间" data-index="createTime" />
|
||||
<a-table-column title="操作内容" data-index="description" />
|
||||
<a-table-column title="所属模块" data-index="module" />
|
||||
<a-table-column title="操作状态" align="center">
|
||||
<template #cell="{ record }">
|
||||
<a-tag v-if="record.status === 1" color="green"
|
||||
><span class="circle pass" />成功</a-tag
|
||||
>
|
||||
<a-tooltip v-else :content="record.errorMsg">
|
||||
<a-tag color="red" style="cursor: pointer">
|
||||
<span class="circle fail" />失败
|
||||
</a-tag>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-table-column>
|
||||
<a-table-column title="操作 IP" data-index="ip" />
|
||||
<a-table-column title="操作地点" data-index="address" />
|
||||
<a-table-column title="浏览器" data-index="browser" />
|
||||
</template>
|
||||
<template #pagination-left>
|
||||
<a-tooltip content="刷新">
|
||||
<div class="action-icon" @click="handleRefresh">
|
||||
<icon-refresh size="18" />
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
OperationLogParam,
|
||||
@@ -126,6 +69,63 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<!-- 列表区域 -->
|
||||
<a-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:data="dataList"
|
||||
:loading="loading"
|
||||
:pagination="{
|
||||
showTotal: true,
|
||||
showPageSize: true,
|
||||
total: total,
|
||||
current: queryParams.page,
|
||||
}"
|
||||
:bordered="false"
|
||||
column-resizable
|
||||
stripe
|
||||
size="large"
|
||||
@page-change="handlePageChange"
|
||||
@page-size-change="handlePageSizeChange"
|
||||
>
|
||||
<template #columns>
|
||||
<a-table-column title="序号">
|
||||
<template #cell="{ rowIndex }">
|
||||
{{ rowIndex + 1 + (queryParams.page - 1) * queryParams.size }}
|
||||
</template>
|
||||
</a-table-column>
|
||||
<a-table-column title="操作时间" data-index="createTime" />
|
||||
<a-table-column title="操作内容" data-index="description" />
|
||||
<a-table-column title="所属模块" data-index="module" />
|
||||
<a-table-column title="操作状态" align="center">
|
||||
<template #cell="{ record }">
|
||||
<a-tag v-if="record.status === 1" color="green"
|
||||
><span class="circle pass" />成功</a-tag
|
||||
>
|
||||
<a-tooltip v-else :content="record.errorMsg">
|
||||
<a-tag color="red" style="cursor: pointer">
|
||||
<span class="circle fail" />失败
|
||||
</a-tag>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-table-column>
|
||||
<a-table-column title="操作 IP" data-index="ip" />
|
||||
<a-table-column title="操作地点" data-index="address" />
|
||||
<a-table-column title="浏览器" data-index="browser" />
|
||||
</template>
|
||||
<template #pagination-left>
|
||||
<a-tooltip content="刷新">
|
||||
<div class="action-icon" @click="handleRefresh">
|
||||
<icon-refresh size="18" />
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container {
|
||||
padding: 0 20px 20px 20px;
|
||||
|
@@ -1,3 +1,10 @@
|
||||
<script lang="ts" setup>
|
||||
import UpdatePwd from './security-settings/update-pwd.vue';
|
||||
import UpdatePhone from './security-settings/update-phone.vue';
|
||||
import UpdateEmail from './security-settings/update-email.vue';
|
||||
import BindSocial from './security-settings/bind-social.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-list :bordered="false">
|
||||
<a-list-item>
|
||||
@@ -15,13 +22,6 @@
|
||||
</a-list>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import UpdatePwd from './security-settings/update-pwd.vue';
|
||||
import UpdatePhone from './security-settings/update-phone.vue';
|
||||
import UpdateEmail from './security-settings/update-email.vue';
|
||||
import BindSocial from './security-settings/bind-social.vue';
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.arco-list-item) {
|
||||
border-bottom: none !important;
|
||||
|
@@ -1,3 +1,69 @@
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
UserSocialBindRecord,
|
||||
listSocial,
|
||||
unbindSocial,
|
||||
} from '@/api/system/user-center';
|
||||
import { socialAuth } from '@/api/auth';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const socialBinds = ref<UserSocialBindRecord[]>([]);
|
||||
const giteeSocial = ref<UserSocialBindRecord>();
|
||||
const githubSocial = ref<UserSocialBindRecord>();
|
||||
|
||||
/**
|
||||
* 查询绑定的第三方账号
|
||||
*/
|
||||
const list = () => {
|
||||
listSocial().then((res) => {
|
||||
socialBinds.value = res.data;
|
||||
giteeSocial.value = socialBinds.value.find(
|
||||
(item) => item.source === 'GITEE'
|
||||
);
|
||||
githubSocial.value = socialBinds.value.find(
|
||||
(item) => item.source === 'GITHUB'
|
||||
);
|
||||
});
|
||||
};
|
||||
list();
|
||||
|
||||
/**
|
||||
* 绑定或解绑
|
||||
*
|
||||
* @param source 来源
|
||||
* @param sourceDescription 来源描述
|
||||
*/
|
||||
const handleBind = (source: string, sourceDescription: string) => {
|
||||
const isBind = socialBinds.value.some((item) => item.source === source);
|
||||
if (isBind) {
|
||||
proxy.$modal.warning({
|
||||
title: `确认解除和${sourceDescription}平台的三方账号绑定吗?`,
|
||||
titleAlign: 'start',
|
||||
content: '解除绑定后,将无法使用该第三方账户登录到此账号',
|
||||
hideCancel: false,
|
||||
onOk: () => {
|
||||
unbindSocial(source).then((res) => {
|
||||
list();
|
||||
proxy.$message.success(res.msg);
|
||||
});
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
proxy.$modal.info({
|
||||
title: '提示',
|
||||
titleAlign: 'start',
|
||||
content: `确认和${sourceDescription}平台的三方账号绑定吗?`,
|
||||
hideCancel: false,
|
||||
onOk: () => {
|
||||
socialAuth(source).then((res) => {
|
||||
window.location.href = res.data;
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
@@ -75,72 +141,6 @@
|
||||
</a-list-item-meta>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
UserSocialBindRecord,
|
||||
listSocial,
|
||||
unbindSocial,
|
||||
} from '@/api/system/user-center';
|
||||
import { socialAuth } from '@/api/auth';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const socialBinds = ref<UserSocialBindRecord[]>([]);
|
||||
const giteeSocial = ref<UserSocialBindRecord>();
|
||||
const githubSocial = ref<UserSocialBindRecord>();
|
||||
|
||||
/**
|
||||
* 查询绑定的第三方账号
|
||||
*/
|
||||
const list = () => {
|
||||
listSocial().then((res) => {
|
||||
socialBinds.value = res.data;
|
||||
giteeSocial.value = socialBinds.value.find(
|
||||
(item) => item.source === 'GITEE'
|
||||
);
|
||||
githubSocial.value = socialBinds.value.find(
|
||||
(item) => item.source === 'GITHUB'
|
||||
);
|
||||
});
|
||||
};
|
||||
list();
|
||||
|
||||
/**
|
||||
* 绑定或解绑
|
||||
*
|
||||
* @param source 来源
|
||||
* @param sourceDescription 来源描述
|
||||
*/
|
||||
const handleBind = (source: string, sourceDescription: string) => {
|
||||
const isBind = socialBinds.value.some((item) => item.source === source);
|
||||
if (isBind) {
|
||||
proxy.$modal.warning({
|
||||
title: `确认解除和${sourceDescription}平台的三方账号绑定吗?`,
|
||||
titleAlign: 'start',
|
||||
content: '解除绑定后,将无法使用该第三方账户登录到此账号',
|
||||
hideCancel: false,
|
||||
onOk: () => {
|
||||
unbindSocial(source).then((res) => {
|
||||
list();
|
||||
proxy.$message.success(res.msg);
|
||||
});
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
proxy.$modal.info({
|
||||
title: '提示',
|
||||
titleAlign: 'start',
|
||||
content: `确认和${sourceDescription}平台的三方账号绑定吗?`,
|
||||
hideCancel: false,
|
||||
onOk: () => {
|
||||
socialAuth(source).then((res) => {
|
||||
window.location.href = res.data;
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.arco-link) {
|
||||
padding: 1px 2px;
|
||||
|
@@ -1,106 +1,3 @@
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.email.label') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="tip">
|
||||
{{ $t('userCenter.securitySettings.email.tip') }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="userStore.email">
|
||||
{{ userStore.email }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.email.content') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link
|
||||
:title="$t('userCenter.securitySettings.button.update')"
|
||||
@click="toUpdate"
|
||||
>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<a-modal
|
||||
:title="$t('userCenter.securitySettings.updateEmail.modal.title')"
|
||||
:visible="visible"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
@ok="handleUpdate"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" size="large">
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updateEmail.form.label.newEmail')
|
||||
"
|
||||
field="newEmail"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.newEmail"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updateEmail.form.placeholder.newEmail'
|
||||
)
|
||||
"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updateEmail.form.label.captcha')
|
||||
"
|
||||
field="captcha"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.captcha"
|
||||
:placeholder="
|
||||
$t('userCenter.securitySettings.form.placeholder.captcha')
|
||||
"
|
||||
:max-length="6"
|
||||
allow-clear
|
||||
style="width: 80%"
|
||||
/>
|
||||
<a-button
|
||||
:loading="captchaLoading"
|
||||
type="primary"
|
||||
:disabled="captchaDisable"
|
||||
class="captcha-btn"
|
||||
@click="handleSendCaptcha"
|
||||
>
|
||||
{{ captchaBtnName }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t(
|
||||
'userCenter.securitySettings.updateEmail.form.label.currentPassword'
|
||||
)
|
||||
"
|
||||
field="currentPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.currentPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updateEmail.form.placeholder.currentPassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FieldRule } from '@arco-design/web-vue';
|
||||
import { getMailCaptcha } from '@/api/common/captcha';
|
||||
@@ -241,6 +138,109 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.email.label') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="tip">
|
||||
{{ $t('userCenter.securitySettings.email.tip') }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="userStore.email">
|
||||
{{ userStore.email }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.email.content') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link
|
||||
:title="$t('userCenter.securitySettings.button.update')"
|
||||
@click="toUpdate"
|
||||
>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<a-modal
|
||||
:title="$t('userCenter.securitySettings.updateEmail.modal.title')"
|
||||
:visible="visible"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
@ok="handleUpdate"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" size="large">
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updateEmail.form.label.newEmail')
|
||||
"
|
||||
field="newEmail"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.newEmail"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updateEmail.form.placeholder.newEmail'
|
||||
)
|
||||
"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updateEmail.form.label.captcha')
|
||||
"
|
||||
field="captcha"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.captcha"
|
||||
:placeholder="
|
||||
$t('userCenter.securitySettings.form.placeholder.captcha')
|
||||
"
|
||||
:max-length="6"
|
||||
allow-clear
|
||||
style="width: 80%"
|
||||
/>
|
||||
<a-button
|
||||
:loading="captchaLoading"
|
||||
type="primary"
|
||||
:disabled="captchaDisable"
|
||||
class="captcha-btn"
|
||||
@click="handleSendCaptcha"
|
||||
>
|
||||
{{ captchaBtnName }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t(
|
||||
'userCenter.securitySettings.updateEmail.form.label.currentPassword'
|
||||
)
|
||||
"
|
||||
field="currentPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.currentPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updateEmail.form.placeholder.currentPassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.captcha-btn {
|
||||
margin-left: 5px;
|
||||
|
@@ -1,113 +1,3 @@
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.phone.label') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="tip">
|
||||
{{ $t('userCenter.securitySettings.phone.tip') }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="userStore.phone">
|
||||
{{ userStore.phone }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.phone.content') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link
|
||||
:title="$t('userCenter.securitySettings.button.update')"
|
||||
@click="toUpdate"
|
||||
>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<a-modal
|
||||
:title="$t('userCenter.securitySettings.updatePhone.modal.title')"
|
||||
:visible="visible"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
@ok="handleUpdate"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" size="large">
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePhone.form.label.newPhone')
|
||||
"
|
||||
field="newPhone"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.newPhone"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePhone.form.placeholder.newPhone',
|
||||
)
|
||||
"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePhone.form.label.captcha')
|
||||
"
|
||||
field="captcha"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.captcha"
|
||||
:placeholder="
|
||||
$t('userCenter.securitySettings.form.placeholder.captcha')
|
||||
"
|
||||
:max-length="4"
|
||||
allow-clear
|
||||
style="width: 80%"
|
||||
/>
|
||||
<a-button
|
||||
:loading="captchaLoading"
|
||||
type="primary"
|
||||
:disabled="captchaDisable"
|
||||
class="captcha-btn"
|
||||
@click="handleOpenBehaviorCaptcha"
|
||||
>
|
||||
{{ captchaBtnName }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePhone.form.label.currentPassword',
|
||||
)
|
||||
"
|
||||
field="currentPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.currentPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePhone.form.placeholder.currentPassword',
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<Verify
|
||||
ref="verifyRef"
|
||||
:mode="captchaMode"
|
||||
:captcha-type="captchaType"
|
||||
:img-size="{ width: '330px', height: '155px' }"
|
||||
@success="handleSendCaptcha"
|
||||
></Verify>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FieldRule } from '@arco-design/web-vue';
|
||||
import { BehaviorCaptchaReq, getSmsCaptcha } from '@/api/common/captcha';
|
||||
@@ -262,6 +152,116 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.phone.label') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="tip">
|
||||
{{ $t('userCenter.securitySettings.phone.tip') }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="userStore.phone">
|
||||
{{ userStore.phone }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.phone.content') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link
|
||||
:title="$t('userCenter.securitySettings.button.update')"
|
||||
@click="toUpdate"
|
||||
>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<a-modal
|
||||
:title="$t('userCenter.securitySettings.updatePhone.modal.title')"
|
||||
:visible="visible"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
@ok="handleUpdate"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" size="large">
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePhone.form.label.newPhone')
|
||||
"
|
||||
field="newPhone"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.newPhone"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePhone.form.placeholder.newPhone',
|
||||
)
|
||||
"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePhone.form.label.captcha')
|
||||
"
|
||||
field="captcha"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.captcha"
|
||||
:placeholder="
|
||||
$t('userCenter.securitySettings.form.placeholder.captcha')
|
||||
"
|
||||
:max-length="4"
|
||||
allow-clear
|
||||
style="width: 80%"
|
||||
/>
|
||||
<a-button
|
||||
:loading="captchaLoading"
|
||||
type="primary"
|
||||
:disabled="captchaDisable"
|
||||
class="captcha-btn"
|
||||
@click="handleOpenBehaviorCaptcha"
|
||||
>
|
||||
{{ captchaBtnName }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePhone.form.label.currentPassword',
|
||||
)
|
||||
"
|
||||
field="currentPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.currentPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePhone.form.placeholder.currentPassword',
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<Verify
|
||||
ref="verifyRef"
|
||||
:mode="captchaMode"
|
||||
:captcha-type="captchaType"
|
||||
:img-size="{ width: '330px', height: '155px' }"
|
||||
@success="handleSendCaptcha"
|
||||
></Verify>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.captcha-btn {
|
||||
margin-left: 5px;
|
||||
|
@@ -1,98 +1,3 @@
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.password.label') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="tip">
|
||||
{{ $t('userCenter.securitySettings.password.tip') }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="userStore.pwdResetTime">
|
||||
{{ $t('userCenter.securitySettings.content.hasBeenSet') }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.password.content') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link
|
||||
:title="$t('userCenter.securitySettings.button.update')"
|
||||
@click="toUpdate"
|
||||
>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<a-modal
|
||||
:title="$t('userCenter.securitySettings.updatePwd.modal.title')"
|
||||
:visible="visible"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
@ok="handleUpdate"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" size="large">
|
||||
<a-form-item
|
||||
v-if="userStore.pwdResetTime"
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePwd.form.label.oldPassword')
|
||||
"
|
||||
field="oldPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.oldPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePwd.form.label.newPassword')
|
||||
"
|
||||
field="newPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.newPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.newPassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePwd.form.label.rePassword')
|
||||
"
|
||||
field="rePassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.rePassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.rePassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FieldRule } from '@arco-design/web-vue';
|
||||
import { updatePassword } from '@/api/system/user-center';
|
||||
@@ -208,4 +113,99 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.password.label') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="tip">
|
||||
{{ $t('userCenter.securitySettings.password.tip') }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="userStore.pwdResetTime">
|
||||
{{ $t('userCenter.securitySettings.content.hasBeenSet') }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.password.content') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link
|
||||
:title="$t('userCenter.securitySettings.button.update')"
|
||||
@click="toUpdate"
|
||||
>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<a-modal
|
||||
:title="$t('userCenter.securitySettings.updatePwd.modal.title')"
|
||||
:visible="visible"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
@ok="handleUpdate"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" :rules="rules" size="large">
|
||||
<a-form-item
|
||||
v-if="userStore.pwdResetTime"
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePwd.form.label.oldPassword')
|
||||
"
|
||||
field="oldPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.oldPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePwd.form.label.newPassword')
|
||||
"
|
||||
field="newPassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.newPassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.newPassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:label="
|
||||
$t('userCenter.securitySettings.updatePwd.form.label.rePassword')
|
||||
"
|
||||
field="rePassword"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="form.rePassword"
|
||||
:placeholder="
|
||||
$t(
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.rePassword'
|
||||
)
|
||||
"
|
||||
:max-length="32"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
|
@@ -1,3 +1,98 @@
|
||||
<script lang="ts" setup>
|
||||
import { FileItem } from '@arco-design/web-vue';
|
||||
import { uploadAvatar, cropperOptions } from '@/api/system/user-center';
|
||||
import { useUserStore } from '@/store';
|
||||
import getAvatar from '@/utils/avatar';
|
||||
import { VueCropper } from 'vue-cropper';
|
||||
import 'vue-cropper/dist/index.css';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const userStore = useUserStore();
|
||||
const cropperRef = ref();
|
||||
const visible = ref(false);
|
||||
const previews: any = ref({});
|
||||
const previewStyle: any = ref({});
|
||||
const fileRef = ref(reactive({ name: 'avatar.png' }));
|
||||
const avatar = {
|
||||
uid: '-2',
|
||||
name: 'avatar.png',
|
||||
url: getAvatar(userStore.avatar, userStore.gender),
|
||||
};
|
||||
const avatarList = ref<FileItem[]>([avatar]);
|
||||
|
||||
const options: cropperOptions = reactive({
|
||||
img: '',
|
||||
autoCrop: true,
|
||||
autoCropWidth: 160,
|
||||
autoCropHeight: 160,
|
||||
fixedBox: true,
|
||||
fixed: true,
|
||||
full: false,
|
||||
centerBox: true,
|
||||
canMove: true,
|
||||
outputSize: 1,
|
||||
outputType: 'png',
|
||||
});
|
||||
|
||||
/**
|
||||
* 上传前弹出裁剪框
|
||||
*
|
||||
* @param file 头像
|
||||
*/
|
||||
const handleBeforeUpload = (file: File): boolean => {
|
||||
fileRef.value = file;
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
options.img = reader.result;
|
||||
};
|
||||
visible.value = true;
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 关闭裁剪框
|
||||
*/
|
||||
const handleCancel = () => {
|
||||
fileRef.value = { name: '' };
|
||||
options.img = '';
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 上传头像
|
||||
*/
|
||||
const handleUpload = () => {
|
||||
cropperRef.value.getCropBlob((data: any) => {
|
||||
const formData = new FormData();
|
||||
formData.append('avatarFile', data, fileRef.value?.name);
|
||||
uploadAvatar(formData).then((res) => {
|
||||
userStore.avatar = res.data.avatar;
|
||||
avatarList.value[0].url = getAvatar(res.data.avatar, undefined);
|
||||
proxy.$message.success(res.msg);
|
||||
handleCancel();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 实时预览
|
||||
*
|
||||
* @param data data 预览图像
|
||||
*/
|
||||
const handleRealTime = (data: any) => {
|
||||
previewStyle.value = {
|
||||
width: `${data.w}px`,
|
||||
height: `${data.h}px`,
|
||||
overflow: 'hidden',
|
||||
margin: '0',
|
||||
zoom: 100 / data.h,
|
||||
borderRadius: '50%',
|
||||
};
|
||||
previews.value = data;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-card :bordered="false">
|
||||
<a-space :size="54">
|
||||
@@ -111,101 +206,6 @@
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FileItem } from '@arco-design/web-vue';
|
||||
import { uploadAvatar, cropperOptions } from '@/api/system/user-center';
|
||||
import { useUserStore } from '@/store';
|
||||
import getAvatar from '@/utils/avatar';
|
||||
import { VueCropper } from 'vue-cropper';
|
||||
import 'vue-cropper/dist/index.css';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const userStore = useUserStore();
|
||||
const cropperRef = ref();
|
||||
const visible = ref(false);
|
||||
const previews: any = ref({});
|
||||
const previewStyle: any = ref({});
|
||||
const fileRef = ref(reactive({ name: 'avatar.png' }));
|
||||
const avatar = {
|
||||
uid: '-2',
|
||||
name: 'avatar.png',
|
||||
url: getAvatar(userStore.avatar, userStore.gender),
|
||||
};
|
||||
const avatarList = ref<FileItem[]>([avatar]);
|
||||
|
||||
const options: cropperOptions = reactive({
|
||||
img: '',
|
||||
autoCrop: true,
|
||||
autoCropWidth: 160,
|
||||
autoCropHeight: 160,
|
||||
fixedBox: true,
|
||||
fixed: true,
|
||||
full: false,
|
||||
centerBox: true,
|
||||
canMove: true,
|
||||
outputSize: 1,
|
||||
outputType: 'png',
|
||||
});
|
||||
|
||||
/**
|
||||
* 上传前弹出裁剪框
|
||||
*
|
||||
* @param file 头像
|
||||
*/
|
||||
const handleBeforeUpload = (file: File): boolean => {
|
||||
fileRef.value = file;
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
options.img = reader.result;
|
||||
};
|
||||
visible.value = true;
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 关闭裁剪框
|
||||
*/
|
||||
const handleCancel = () => {
|
||||
fileRef.value = { name: '' };
|
||||
options.img = '';
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 上传头像
|
||||
*/
|
||||
const handleUpload = () => {
|
||||
cropperRef.value.getCropBlob((data: any) => {
|
||||
const formData = new FormData();
|
||||
formData.append('avatarFile', data, fileRef.value?.name);
|
||||
uploadAvatar(formData).then((res) => {
|
||||
userStore.avatar = res.data.avatar;
|
||||
avatarList.value[0].url = getAvatar(res.data.avatar, undefined);
|
||||
proxy.$message.success(res.msg);
|
||||
handleCancel();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 实时预览
|
||||
*
|
||||
* @param data data 预览图像
|
||||
*/
|
||||
const handleRealTime = (data: any) => {
|
||||
previewStyle.value = {
|
||||
width: `${data.w}px`,
|
||||
height: `${data.h}px`,
|
||||
overflow: 'hidden',
|
||||
margin: '0',
|
||||
zoom: 100 / data.h,
|
||||
borderRadius: '50%',
|
||||
};
|
||||
previews.value = data;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.arco-card {
|
||||
padding: 14px 0 4px 4px;
|
||||
|
@@ -1,3 +1,26 @@
|
||||
<script lang="ts" setup>
|
||||
import UserPanel from './components/user-panel.vue';
|
||||
import BasicInfo from './components/basic-info.vue';
|
||||
import SecuritySettings from './components/security-settings.vue';
|
||||
import OperationLog from './components/operation-log.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const activeKey = ref('1');
|
||||
const tab = route.query.tab as string;
|
||||
|
||||
onMounted(() => {
|
||||
if (tab === 'security-setting') {
|
||||
activeKey.value = '2';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'UserCenter',
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['menu.user.center']" />
|
||||
@@ -28,29 +51,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import UserPanel from './components/user-panel.vue';
|
||||
import BasicInfo from './components/basic-info.vue';
|
||||
import SecuritySettings from './components/security-settings.vue';
|
||||
import OperationLog from './components/operation-log.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const activeKey = ref('1');
|
||||
const tab = route.query.tab as string;
|
||||
|
||||
onMounted(() => {
|
||||
if (tab === 'security-setting') {
|
||||
activeKey.value = '2';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'UserCenter',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container {
|
||||
padding: 0 20px 20px 20px;
|
||||
|
Reference in New Issue
Block a user