feat:新增账号设置模块和引入表格组件
This commit is contained in:
13
Yi.Bbs.Vue3/package-lock.json
generated
13
Yi.Bbs.Vue3/package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"@microsoft/signalr": "^8.0.0",
|
||||
"axios": "^1.3.4",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.4.2",
|
||||
"element-plus": "^2.2.32",
|
||||
"highlight": "^0.2.4",
|
||||
@@ -1846,9 +1847,9 @@
|
||||
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.7",
|
||||
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz",
|
||||
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
|
||||
"version": "1.11.10",
|
||||
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz",
|
||||
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
@@ -5456,9 +5457,9 @@
|
||||
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
|
||||
},
|
||||
"dayjs": {
|
||||
"version": "1.11.7",
|
||||
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz",
|
||||
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
|
||||
"version": "1.11.10",
|
||||
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz",
|
||||
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"@microsoft/signalr": "^8.0.0",
|
||||
"axios": "^1.3.4",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.4.2",
|
||||
"element-plus": "^2.2.32",
|
||||
"highlight": "^0.2.4",
|
||||
|
||||
@@ -73,3 +73,45 @@ export function getLoginCode() {
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方账号登录
|
||||
* @param {*} params 参数
|
||||
* @param {*} scheme 类型
|
||||
* @returns
|
||||
*/
|
||||
export function authOtherLogin(params, scheme) {
|
||||
return request({
|
||||
url: `/auth/oauth/login/${scheme}`,
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方账号绑定
|
||||
* @param {*} params 参数
|
||||
* @param {*} scheme 类型
|
||||
* @returns
|
||||
*/
|
||||
export function authOtherBind(params, scheme) {
|
||||
return request({
|
||||
url: `/auth/oauth/bind/${scheme}`,
|
||||
method: "post",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方账号绑定
|
||||
* @param {*} params 参数
|
||||
* @param {*} scheme 类型
|
||||
* @returns
|
||||
*/
|
||||
export function getOtherAuthInfo(params) {
|
||||
return request({
|
||||
url: `auth/account`,
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
BIN
Yi.Bbs.Vue3/src/assets/login_images/gitee-setting.png
Normal file
BIN
Yi.Bbs.Vue3/src/assets/login_images/gitee-setting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
BIN
Yi.Bbs.Vue3/src/assets/login_images/qq-setting.png
Normal file
BIN
Yi.Bbs.Vue3/src/assets/login_images/qq-setting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
128
Yi.Bbs.Vue3/src/components/yi-table/TableColumn.vue
Normal file
128
Yi.Bbs.Vue3/src/components/yi-table/TableColumn.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
defineProps({
|
||||
col: {
|
||||
// Column
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(["command"]);
|
||||
// 按钮组事件
|
||||
const handleAction = (command, scope) => {
|
||||
emit("command", command, scope.row);
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<!-- 如果有配置多级表头的数据,则递归该组件 -->
|
||||
<template v-if="col.children?.length">
|
||||
<el-table-column
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
:align="col.align"
|
||||
v-bind="col"
|
||||
>
|
||||
<TableColumn
|
||||
v-for="(item, index) in col.children"
|
||||
:col="item"
|
||||
:key="index"
|
||||
/>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!-- 其他正常列 -->
|
||||
<el-table-column
|
||||
v-else
|
||||
:show-overflow-tooltip="col.showOverflowTooltip"
|
||||
:sortable="col.sortable"
|
||||
:prop="col.prop"
|
||||
:align="col.align"
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
v-bind="col"
|
||||
>
|
||||
<template #default="{ row, $index }">
|
||||
<!---图片 (START)-->
|
||||
<!-- 如需更改图片size,可自行配置参数 -->
|
||||
<el-image
|
||||
v-if="col.type === 'image'"
|
||||
preview-teleported
|
||||
:hide-on-click-modal="true"
|
||||
:preview-src-list="[row[col.prop]]"
|
||||
:src="row[col.prop]"
|
||||
fit="cover"
|
||||
class="w-9 h-9 rounded-lg"
|
||||
/>
|
||||
<!---图片 (END)-->
|
||||
<!--- 格式化日期 (本项目日期是时间戳,这里日期格式化可根据你的项目来更改) (START)-->
|
||||
<template v-else-if="col.type === 'date'">
|
||||
<!---十位数时间戳-->
|
||||
<span v-if="String(row[col.prop])?.length <= 10">
|
||||
{{
|
||||
row[col.prop]
|
||||
? dayjs.unix(row[col.prop]).format(col.dateFormat ?? "YYYY-MM-DD")
|
||||
: ""
|
||||
}}
|
||||
</span>
|
||||
<!---十三位数时间戳-->
|
||||
<span v-else>{{
|
||||
dayjs(row[col.prop]).format(col.dateFormat ?? "YYYY-MM-DD")
|
||||
}}</span>
|
||||
</template>
|
||||
<!--- 格式化日期 (本项目日期是时间戳,这里日期格式化可根据你的项目来更改) (END)-->
|
||||
<!-- 如果传递按钮数组,就展示按钮组 START-->
|
||||
<!-- v-permission 给按钮添加权限 传[]则不设置权限-->
|
||||
<el-button-group v-else-if="col.buttons?.length">
|
||||
<el-button
|
||||
v-for="(btn, index) in col.buttons"
|
||||
:key="index"
|
||||
:size="btn.size || 'small'"
|
||||
:type="btn.type"
|
||||
@click="handleAction(btn.command, { row, $index })"
|
||||
:disabled="btn.disabled || false"
|
||||
v-permission="btn.permission || []"
|
||||
>{{ btn.name }}</el-button
|
||||
>
|
||||
</el-button-group>
|
||||
<!-- 如果传递按钮数组,就展示按钮组 END-->
|
||||
<!-- render函数 (START) -->
|
||||
<!-- 使用内置的component组件可以支持h函数渲染和txs语法 -->
|
||||
<component
|
||||
v-else-if="col.render"
|
||||
:is="col.render"
|
||||
:row="row"
|
||||
:index="$index"
|
||||
/>
|
||||
<!-- render函数 (END) -->
|
||||
<!-- 自定义slot (START) -->
|
||||
<slot
|
||||
v-else-if="col.slot"
|
||||
:slotName="col.slot"
|
||||
:row="row"
|
||||
:index="$index"
|
||||
></slot>
|
||||
<!-- 自定义slot (END) -->
|
||||
<!-- 默认渲染 (START) -->
|
||||
<span v-else>{{ row[col.prop] }}</span>
|
||||
<!-- 默认渲染 (END) -->
|
||||
</template>
|
||||
<!-- 自定义表头 -->
|
||||
<template #header="{ column, $index }">
|
||||
<component
|
||||
v-if="col.headerRender"
|
||||
:is="col.headerRender"
|
||||
:column="column"
|
||||
:index="$index"
|
||||
/>
|
||||
<slot
|
||||
v-else-if="col.headerSlot"
|
||||
name="customHeader"
|
||||
:slotName="col.headerSlot"
|
||||
:column="column"
|
||||
:index="$index"
|
||||
></slot>
|
||||
<span v-else>{{ column.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
206
Yi.Bbs.Vue3/src/components/yi-table/index.vue
Normal file
206
Yi.Bbs.Vue3/src/components/yi-table/index.vue
Normal file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div class="yi-table">
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
v-bind="_options"
|
||||
header-row-class-name="header-row-class-name"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick"
|
||||
@cell-click="handleCellClick"
|
||||
@sort-change="handleSortChange"
|
||||
>
|
||||
<template v-for="(col, index) in columns">
|
||||
<!---复选框, 序号 (START)-->
|
||||
<el-table-column
|
||||
:key="index"
|
||||
v-if="
|
||||
col.type === 'index' ||
|
||||
col.type === 'selection' ||
|
||||
col.type === 'expand'
|
||||
"
|
||||
:sortable="col.sortable"
|
||||
:prop="col.prop"
|
||||
:align="col.align"
|
||||
:label="col.label"
|
||||
:type="col.type"
|
||||
:index="indexMethod"
|
||||
:width="col.width"
|
||||
v-bind="col"
|
||||
/>
|
||||
|
||||
<!---复选框, 序号 (END)-->
|
||||
<TableColumn
|
||||
:key="index + '_key'"
|
||||
:col="col"
|
||||
v-else
|
||||
@command="handleAction"
|
||||
>
|
||||
<template #default="{ slotName, row, index }">
|
||||
<slot :name="slotName" :row="row" :index="index" />
|
||||
</template>
|
||||
<!-- 自定义表头插槽 -->
|
||||
<template #customHeader="{ slotName, column, index }">
|
||||
<slot :name="slotName" :column="column" :index="index" />
|
||||
</template>
|
||||
</TableColumn>
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 分页器 -->
|
||||
<div
|
||||
v-if="_options.showPagination"
|
||||
class="table-pagination"
|
||||
:class="[`pagination_${_options.paginationPosition}`]"
|
||||
>
|
||||
<el-pagination
|
||||
v-bind="_paginationConfig"
|
||||
@size-change="pageSizeChange"
|
||||
@current-change="currentPageChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="YiTable">
|
||||
import { computed, ref } from "vue";
|
||||
import TableColumn from "./TableColumn.vue";
|
||||
|
||||
const props = defineProps({
|
||||
tableData: {
|
||||
// table的数据
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
});
|
||||
const tableRef = ref();
|
||||
// 设置option默认值,如果传入自定义的配置则合并option配置项
|
||||
const _options = computed(() => {
|
||||
const option = {
|
||||
stripe: false,
|
||||
tooltipEffect: "dark",
|
||||
showHeader: true,
|
||||
showPagination: false,
|
||||
paginationPosition: "right",
|
||||
rowStyle: () => "cursor:pointer", // 行样式
|
||||
// headerRowClassName: 'table-header-row',
|
||||
};
|
||||
return Object.assign(option, props?.options);
|
||||
});
|
||||
// 合并分页配置
|
||||
const _paginationConfig = computed(() => {
|
||||
const config = {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
pageSizes: [10, 20, 50],
|
||||
background: true,
|
||||
layout: "total, sizes, prev, pager, next, jumper",
|
||||
};
|
||||
return Object.assign(config, _options.value.paginationConfig);
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
"selection-change", // 当选择项发生变化时会触发该事件
|
||||
"row-click", // 当某一行被点击时会触发该事件
|
||||
"cell-click", // 当某个单元格被点击时会触发该事件
|
||||
"command", // 按钮组事件
|
||||
"size-change", // pageSize事件
|
||||
"current-change", // currentPage按钮组事件
|
||||
"pagination-change", // currentPage或者pageSize改变触发
|
||||
"sort-change", // 列排序发生改变触发
|
||||
]);
|
||||
// 自定义索引
|
||||
const indexMethod = (index) => {
|
||||
const tabIndex =
|
||||
index +
|
||||
(_paginationConfig.value.currentPage - 1) *
|
||||
_paginationConfig.value.pageSize +
|
||||
1;
|
||||
return tabIndex;
|
||||
};
|
||||
// 切换pageSize
|
||||
const pageSizeChange = (pageSize) => {
|
||||
emit("size-change", pageSize);
|
||||
emit("pagination-change", 1, pageSize);
|
||||
};
|
||||
// 切换currentPage
|
||||
const currentPageChange = (currentPage) => {
|
||||
emit("current-change", currentPage);
|
||||
emit("pagination-change", currentPage, _paginationConfig.value.pageSize);
|
||||
};
|
||||
// 按钮组事件
|
||||
const handleAction = (command, row) => {
|
||||
emit("command", command, row);
|
||||
};
|
||||
// 多选事件
|
||||
const handleSelectionChange = (val) => {
|
||||
emit("selection-change", val);
|
||||
};
|
||||
// 当某一行被点击时会触发该事件
|
||||
const handleRowClick = (row, column, event) => {
|
||||
emit("row-click", row, column, event);
|
||||
};
|
||||
// 当某个单元格被点击时会触发该事件
|
||||
const handleCellClick = (row, column, cell, event) => {
|
||||
emit("cell-click", row, column, cell, event);
|
||||
};
|
||||
/**
|
||||
* 当表格的排序条件发生变化的时候会触发该事件
|
||||
* 在列中设置 sortable 属性即可实现以该列为基准的排序, 接受一个 Boolean,默认为 false。
|
||||
* 可以通过 Table 的 default-sort 属性设置默认的排序列和排序顺序。
|
||||
* 如果需要后端排序,需将 sortable 设置为 custom,同时在 Table 上监听 sort-change 事件,
|
||||
* 在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。
|
||||
*/
|
||||
const handleSortChange = ({ column, prop, order }) => {
|
||||
emit("sort-change", { column, prop, order });
|
||||
};
|
||||
// 暴露给父组件参数和方法,如果外部需要更多的参数或者方法,都可以从这里暴露出去。
|
||||
defineExpose({ element: tableRef });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-image__inner) {
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.yi-table {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
.el-table {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.table-pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.table-pagination.pagination_left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.table-pagination.pagination_center {
|
||||
justify-content: center;
|
||||
}
|
||||
.table-pagination.pagination_right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
@@ -3,8 +3,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ref, watch, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { authOtherLogin, authOtherBind } from "@/apis/auth.js";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
@@ -13,8 +14,14 @@ const code = ref(route.query.code);
|
||||
const message = ref("");
|
||||
watch(
|
||||
() => code.value,
|
||||
(val) => {
|
||||
async (val) => {
|
||||
if (val) {
|
||||
// 使用正则表达式提取路由参数
|
||||
const regex = /\/auth\/([\w-]+)[?]?/;
|
||||
const result = regex.exec(route.fullPath);
|
||||
const authParam = result != null ? result[1].toUpperCase() : null;
|
||||
const res = await authOtherBind({ code: val }, authParam);
|
||||
console.log(res, "res");
|
||||
message.value = "授权成功";
|
||||
// window.close();
|
||||
}
|
||||
|
||||
143
Yi.Bbs.Vue3/src/views/profile/AccountSetting.vue
Normal file
143
Yi.Bbs.Vue3/src/views/profile/AccountSetting.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<div class="account-box">
|
||||
<div class="title">您可以绑定以下第三方账号</div>
|
||||
<div class="image-list">
|
||||
<div class="item" @click="handleQQLogin">
|
||||
<div class="image">
|
||||
<img src="@/assets/login_images/qq-setting.png" alt="" />
|
||||
</div>
|
||||
<div class="text">QQ</div>
|
||||
</div>
|
||||
<div class="item" @click="handleGiteeLogin">
|
||||
<div class="image">
|
||||
<img src="@/assets/login_images/gitee-setting.png" alt="" />
|
||||
</div>
|
||||
<div class="text">Gitee</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">使用以下任意方式都可以登录到您的意社区账号</div>
|
||||
<div class="table">
|
||||
<yi-table
|
||||
:table-data="tableData"
|
||||
:options="tableOptions"
|
||||
:columns="tableColumn"
|
||||
></yi-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted } from "vue";
|
||||
import { getOtherAuthInfo } from "@/apis/auth.js";
|
||||
import YiTable from "@/components/yi-table/index.vue";
|
||||
import useUserStore from "@/stores/user";
|
||||
|
||||
const userInfo = useUserStore();
|
||||
const tableOptions = computed(() => {
|
||||
return {
|
||||
showPagination: false,
|
||||
border: true,
|
||||
};
|
||||
});
|
||||
|
||||
const tableColumn = [
|
||||
{
|
||||
type: "index",
|
||||
minWidth: "50",
|
||||
label: "序号",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
prop: "timeInterval",
|
||||
label: "绑定账号信息",
|
||||
minWidth: "110",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
prop: "timeInterval",
|
||||
label: "详情",
|
||||
minWidth: "110",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
prop: "timeInterval",
|
||||
label: "绑定时间",
|
||||
minWidth: "110",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
prop: "timeInterval",
|
||||
label: "状态",
|
||||
minWidth: "110",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
label: "操作",
|
||||
align: "center",
|
||||
minWidth: "200",
|
||||
fixed: "right",
|
||||
buttons: [
|
||||
{
|
||||
name: "绑定",
|
||||
type: "text",
|
||||
command: "edit",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(async () => {
|
||||
const { data } = await getOtherAuthInfo({ userId: userInfo.id });
|
||||
});
|
||||
|
||||
const handleQQLogin = () => {
|
||||
window.open(
|
||||
"https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=102087446&redirect_uri=https://ccnetcore.com/auth/qq&state=true&scope=get_user_info",
|
||||
undefined,
|
||||
"width=500,height=500,left=50,top=50"
|
||||
);
|
||||
};
|
||||
|
||||
const handleGiteeLogin = () => {
|
||||
window.open(
|
||||
"https://gitee.com/oauth/authorize?client_id=949f3519969adc5cfe82c209b71300e8e0868e8536f3d7f59195c8f1e5b72502&redirect_uri=https%3A%2F%2Fccnetcore.com%2Fauth%2Fgitee&response_type=code",
|
||||
undefined,
|
||||
"width=500,height=500,left=50,top=50"
|
||||
);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.account-box {
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.image-list {
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
.item {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-right: 20px;
|
||||
.image {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.table {
|
||||
margin-top: 10px;
|
||||
:deep(.yi-table) {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -61,6 +61,9 @@
|
||||
<el-tab-pane label="修改密码" name="resetPwd">
|
||||
<resetPwd />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="账号设置" name="accountSetting">
|
||||
<accountSet />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -72,6 +75,7 @@
|
||||
import userAvatar from "./UserAvatar.vue";
|
||||
import userInfo from "./UserInfo.vue";
|
||||
import resetPwd from "./ResetPwd.vue";
|
||||
import accountSet from "./AccountSetting.vue";
|
||||
import { getUserProfile } from "@/apis/userApi.js";
|
||||
import { onMounted, ref, reactive } from "vue";
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user