feat: platform 接入天梯登陆的 依赖

This commit is contained in:
wangxuefeng 2025-03-05 17:55:51 +08:00
parent dd69823a00
commit 47c9ec1aba
15 changed files with 112 additions and 642 deletions

View File

@ -54,7 +54,8 @@
"vue-types": "~5.1.3", "vue-types": "~5.1.3",
"vue-virtual-scroller": "2.0.0-beta.8", "vue-virtual-scroller": "2.0.0-beta.8",
"wujie": "^1.0.25", "wujie": "^1.0.25",
"xlsx": "~0.18.5" "xlsx": "~0.18.5",
"@sy/unified-login": "1.0.29"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "~19.5.0", "@commitlint/cli": "~19.5.0",

View File

@ -1,41 +1,30 @@
import axios from 'axios'; import axios from 'axios';
import { useUserStore } from '@/store/modules/user'; // import { useUserStore } from '@/store/modules/user';
import router from '@/router'; // import router from '@/router';
import appClient from '@/io/tianti';
console.log('appClient', appClient);
// axios拦截器
const { reqInterceptor, resInterceptor } = appClient.getInterceptor();
console.log('reqInterceptor', reqInterceptor);
console.log('resInterceptor', resInterceptor);
const baseApiUrl = import.meta.env.VITE_BASE_API_URL; const baseApiUrl = import.meta.env.VITE_BASE_API_URL;
// 创建独立实例 // 创建独立实例
const instance = axios.create({ const instance = axios.create({
baseURL: baseApiUrl, // 基础URL直接放在实例配置中 baseURL: baseApiUrl,
}); });
// 请求拦截器改为使用实例
instance.interceptors.request.use( instance.interceptors.request.use(
(config) => { (config) => config,
// 可在此处添加统一请求头等配置 (error) => Promise.reject(error),
return config;
},
(error) => {
return Promise.reject(error);
},
); );
instance.interceptors.request.use(reqInterceptor.fulfilled, reqInterceptor.rejected);
// 响应拦截器改为使用实例 // 响应拦截器
instance.interceptors.response.use( instance.interceptors.response.use(resInterceptor.fulfilled, resInterceptor.rejected);
(response) => {
// 如果响应数据中 code 为 -1清空登录状态并跳转到登录页
if (response?.data?.code === -1) {
const userStore = useUserStore();
userStore.clearLoginStatus(); // 清空用户信息
router.push('/login'); // 直接使用路由实例
console.error('请求失败:', response.data.msg);
}
return response;
},
(error) => {
return Promise.reject(error);
},
);
// 导出实例 // 导出实例
export default instance; export default instance;

View File

@ -0,0 +1,12 @@
// @ts-ignore
import AxiosAppClient from '@sy/unified-login/es/app-client/axios';
export type Env = 'dev' | 'test' | 'pre' | 'prod';
const appClient = new AxiosAppClient({
appKey: 'y-code', // 应用标识,不同项目不能一样
env: 'prod', // dev本地开发test测试pre预发布prod正式
devBaseUrl: `https://localhost:${import.meta.env.VITE_PORT}`, // 应用开发环境地址
});
export default appClient;

View File

@ -33,10 +33,15 @@
</Menu.Item> --> </Menu.Item> -->
<Menu.Divider /> <Menu.Divider />
<Menu.Item> <Menu.Item>
<div @click.prevent="doLogout"> <div @click.prevent="tianti.logout">
<poweroff-outlined /> {{ $t('layout.header.dropdownItemLoginOut') }} <poweroff-outlined /> {{ $t('layout.header.dropdownItemLoginOut') }}
</div> </div>
</Menu.Item> </Menu.Item>
<Menu.Item v-if="isDevEnv">
<div @click.prevent="tianti.openDev">
{{ $t('layout.header.openDev') }}
</div>
</Menu.Item>
</Menu> </Menu>
</template> </template>
</Dropdown> </Dropdown>
@ -49,6 +54,8 @@
<script lang="tsx" setup> <script lang="tsx" setup>
import { computed, type CSSProperties } from 'vue'; import { computed, type CSSProperties } from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import tianti from '@/io/tianti';
import { import {
QuestionCircleOutlined, QuestionCircleOutlined,
MenuFoldOutlined, MenuFoldOutlined,
@ -71,6 +78,8 @@
import { LOGIN_NAME } from '@/router/constant'; import { LOGIN_NAME } from '@/router/constant';
import { useLayoutSettingStore } from '@/store/modules/layoutSetting'; import { useLayoutSettingStore } from '@/store/modules/layoutSetting';
const isDevEnv = import.meta.env.VITE_NODE_ENV === 'development';
defineProps({ defineProps({
collapsed: { collapsed: {
type: Boolean, type: Boolean,

View File

@ -1,20 +1,20 @@
{ {
"footer": { "onlinePreview": "在线预览", "onlineDocument": "在线文档" }, "footer": {
"onlinePreview": "在线预览",
"onlineDocument": "在线文档"
},
"header": { "header": {
"dropdownItemDoc": "文档", "dropdownItemDoc": "文档",
"dropdownItemLoginOut": "退出系统", "dropdownItemLoginOut": "退出系统",
"openDev": "打开开发环境",
"tooltipErrorLog": "错误日志", "tooltipErrorLog": "错误日志",
"tooltipLock": "锁定屏幕", "tooltipLock": "锁定屏幕",
"tooltipNotify": "消息通知", "tooltipNotify": "消息通知",
"tooltipEntryFull": "全屏", "tooltipEntryFull": "全屏",
"tooltipExitFull": "退出全屏", "tooltipExitFull": "退出全屏",
"lockScreenPassword": "锁屏密码", "lockScreenPassword": "锁屏密码",
"lockScreen": "锁定屏幕", "lockScreen": "锁定屏幕",
"lockScreenBtn": "锁定", "lockScreenBtn": "锁定",
"home": "首页" "home": "首页"
}, },
"multipleTab": { "multipleTab": {
@ -38,20 +38,15 @@
"menuTypeMixSidebar": "左侧菜单混合模式", "menuTypeMixSidebar": "左侧菜单混合模式",
"menuTypeMix": "顶部菜单混合模式", "menuTypeMix": "顶部菜单混合模式",
"menuTypeTopMenu": "顶部菜单模式", "menuTypeTopMenu": "顶部菜单模式",
"on": "开", "on": "开",
"off": "关", "off": "关",
"minute": "分钟", "minute": "分钟",
"operatingTitle": "操作成功", "operatingTitle": "操作成功",
"operatingContent": "复制成功,请到 src/settings/projectSetting.ts 中修改配置!", "operatingContent": "复制成功,请到 src/settings/projectSetting.ts 中修改配置!",
"resetSuccess": "重置成功!", "resetSuccess": "重置成功!",
"copyBtn": "拷贝", "copyBtn": "拷贝",
"clearBtn": "清空缓存并返回登录页", "clearBtn": "清空缓存并返回登录页",
"drawerTitle": "项目配置", "drawerTitle": "项目配置",
"darkMode": "主题", "darkMode": "主题",
"navMode": "导航栏模式", "navMode": "导航栏模式",
"interfaceFunction": "界面功能", "interfaceFunction": "界面功能",
@ -59,11 +54,9 @@
"animation": "动画", "animation": "动画",
"splitMenu": "分割菜单", "splitMenu": "分割菜单",
"closeMixSidebarOnChange": "切换页面关闭菜单", "closeMixSidebarOnChange": "切换页面关闭菜单",
"sysTheme": "系统主题", "sysTheme": "系统主题",
"headerTheme": "顶栏主题", "headerTheme": "顶栏主题",
"sidebarTheme": "菜单主题", "sidebarTheme": "菜单主题",
"menuDrag": "侧边菜单拖拽", "menuDrag": "侧边菜单拖拽",
"menuSearch": "菜单搜索", "menuSearch": "菜单搜索",
"menuAccordion": "侧边菜单手风琴模式", "menuAccordion": "侧边菜单手风琴模式",
@ -73,7 +66,6 @@
"menuCollapseButton": "菜单折叠按钮", "menuCollapseButton": "菜单折叠按钮",
"contentMode": "内容区域宽度", "contentMode": "内容区域宽度",
"expandedMenuWidth": "菜单展开宽度", "expandedMenuWidth": "菜单展开宽度",
"breadcrumb": "面包屑", "breadcrumb": "面包屑",
"breadcrumbIcon": "面包屑图标", "breadcrumbIcon": "面包屑图标",
"tabs": "标签页", "tabs": "标签页",
@ -87,22 +79,17 @@
"fullContent": "全屏内容", "fullContent": "全屏内容",
"grayMode": "灰色模式", "grayMode": "灰色模式",
"colorWeak": "色弱模式", "colorWeak": "色弱模式",
"progress": "顶部进度条", "progress": "顶部进度条",
"switchLoading": "切换loading", "switchLoading": "切换loading",
"switchAnimation": "切换动画", "switchAnimation": "切换动画",
"animationType": "动画类型", "animationType": "动画类型",
"autoScreenLock": "自动锁屏", "autoScreenLock": "自动锁屏",
"notAutoScreenLock": "不自动锁屏", "notAutoScreenLock": "不自动锁屏",
"fixedHeader": "固定header", "fixedHeader": "固定header",
"fixedSideBar": "固定Sidebar", "fixedSideBar": "固定Sidebar",
"mixSidebarTrigger": "混合菜单触发方式", "mixSidebarTrigger": "混合菜单触发方式",
"triggerHover": "悬停", "triggerHover": "悬停",
"triggerClick": "点击", "triggerClick": "点击",
"mixSidebarFixed": "固定展开菜单" "mixSidebarFixed": "固定展开菜单"
} }
} }

View File

@ -13,6 +13,10 @@ import { setupStore } from '@/store';
import { setupI18n } from '@/locales'; import { setupI18n } from '@/locales';
import { setupAntd, setupAssets, setupGlobalMethods } from '@/plugins'; import { setupAntd, setupAssets, setupGlobalMethods } from '@/plugins';
import tianti from '@/io/tianti';
tianti.checkQuery();
dayjs.extend(customParseFormat); dayjs.extend(customParseFormat);
dayjs.extend(utc); dayjs.extend(utc);
dayjs.extend(timezone); dayjs.extend(timezone);

View File

@ -13,60 +13,27 @@ const routes: Array<RouteRecordRaw> = [
}, },
children: [ children: [
{ {
path: 'list', path: 'login',
name: `${moduleName}-list`, name: `${moduleName}-login`,
meta: { meta: {
title: '用户列表', title: '登录',
icon: 'ant-design:unordered-list-outlined', icon: 'ant-design:unordered-list-outlined',
keepAlive: true, keepAlive: true,
hideInMenu: false, hideInMenu: false,
}, },
component: () => import('@/views/user/list.vue'), component: () => import('@/views/login/index.vue'),
},
{
path: 'add',
name: `${moduleName}-add`,
meta: {
title: '新增用户',
icon: 'ant-design:user-add-outlined',
hideInMenu: true,
activeMenu: `${moduleName}-list`,
},
component: () => import('@/views/user/add.vue'),
},
{
path: 'edit/:id',
name: `${moduleName}-edit`,
meta: {
title: '编辑用户',
icon: 'ant-design:edit-outlined',
hideInMenu: true,
activeMenu: `${moduleName}-list`,
},
component: () => import('@/views/user/edit.vue'),
},
{
path: 'detail/:id',
name: `${moduleName}-detail`,
meta: {
title: '用户详情',
icon: 'ant-design:profile-outlined',
hideInMenu: true,
activeMenu: `${moduleName}-list`,
},
component: () => import('@/views/user/detail.vue'),
},
{
path: 'change-password/:id',
name: `${moduleName}-change-password`,
meta: {
title: '修改密码',
icon: 'ant-design:lock-outlined',
hideInMenu: true,
activeMenu: `${moduleName}-list`,
},
component: () => import('@/views/user/change-password.vue'),
}, },
// {
// path: 'list',
// name: `${moduleName}-list`,
// meta: {
// title: '用户列表',
// icon: 'ant-design:unordered-list-outlined',
// keepAlive: true,
// hideInMenu: false,
// },
// component: () => import('@/views/user/list.vue'),
// },
], ],
}, },
]; ];

View File

@ -0,0 +1,28 @@
<script lang="jsx">
import { defineComponent } from 'vue';
import OneClickAuth from '@sy/unified-login/one-click-auth.vue';
export default defineComponent({
name: 'ForbiddenPage',
setup() {
return () => {
return (
<div class="forbidden-page">
<OneClickAuth env="dev" appMark={30} />
</div>
);
};
},
});
</script>
<style lang="less" scoped>
.forbidden-page {
display: flex;
position: relative;
align-items: center;
justify-content: center;
height: 100%;
}
</style>

View File

@ -2,7 +2,13 @@
<div>1</div> <div>1</div>
</template> </template>
<script setup lang="ts"></script> <script setup lang="ts">
import { getProjectList } from '@/io';
getProjectList().then((res) => {
console.log('res', res);
});
</script>
<style lang="less" scoped> <style lang="less" scoped>
.login-box { .login-box {

View File

@ -1,60 +0,0 @@
<template>
<div class="add-user">
<a-card :bordered="false">
<a-form layout="vertical" :model="userForm" @submit="handleAddUser">
<a-form-item label="用户名">
<a-input
v-model:value="userForm.username"
placeholder="请输入用户名"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item label="密码">
<a-input
v-model:value="userForm.password"
placeholder="请输入密码"
type="password"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" html-type="submit">新增用户</a-button>
<a-button @click="goBack">取消</a-button>
</a-space>
</a-form-item>
</a-form>
</a-card>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { message } from 'ant-design-vue';
import { useTabsViewStore } from '@/store/modules/tabsView';
const { closeCurrentTab } = useTabsViewStore();
const router = useRouter();
const route = useRoute();
//
const userForm = reactive({
username: '',
password: '',
});
//
const handleAddUser = async () => {
// TODO:
message.success('用户新增成功');
goBack();
};
const goBack = () => {
router.back();
closeCurrentTab(route);
};
</script>

View File

@ -1,66 +0,0 @@
<template>
<div class="change-password">
<a-card :bordered="false">
<a-form layout="vertical" :model="passwordForm" @submit="handleChangePassword">
<a-form-item label="新密码">
<a-input
v-model:value="passwordForm.newPassword"
placeholder="请输入新密码"
type="password"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item label="确认密码">
<a-input
v-model:value="passwordForm.confirmPassword"
placeholder="请确认新密码"
type="password"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" html-type="submit">修改密码</a-button>
<a-button type="default" @click="goBack">取消</a-button>
</a-space>
</a-form-item>
</a-form>
</a-card>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { message } from 'ant-design-vue';
import { useTabsViewStore } from '@/store/modules/tabsView';
const { closeCurrentTab } = useTabsViewStore();
const router = useRouter();
console.log('router', router);
const route = useRoute();
//
const passwordForm = reactive({
newPassword: '',
confirmPassword: '',
});
//
const handleChangePassword = async () => {
if (passwordForm.newPassword !== passwordForm.confirmPassword) {
message.error('两次输入的密码不一致');
return;
}
// TODO:
message.success('密码修改成功');
goBack();
};
const goBack = () => {
router.back();
closeCurrentTab(route);
};
</script>

View File

@ -1,94 +0,0 @@
<template>
<div class="user-detail">
<a-card title="用户详情" :bordered="false">
<!-- 基本信息 -->
<a-descriptions bordered>
<a-descriptions-item label="用户名">
{{ userInfo.username }}
</a-descriptions-item>
<a-descriptions-item label="昵称">
{{ userInfo.nickname }}
</a-descriptions-item>
<a-descriptions-item label="手机号">
{{ userInfo.phone }}
</a-descriptions-item>
<a-descriptions-item label="邮箱">
{{ userInfo.email }}
</a-descriptions-item>
<a-descriptions-item label="状态">
<a-tag :color="userInfo.status === 1 ? 'green' : 'red'">
{{ userInfo.status === 1 ? '启用' : '禁用' }}
</a-tag>
</a-descriptions-item>
<a-descriptions-item label="创建时间">
{{ userInfo.createTime }}
</a-descriptions-item>
</a-descriptions>
<!-- 操作按钮 -->
<div class="operation-buttons" style="margin-top: 24px">
<a-button type="primary" @click="handleEdit">编辑</a-button>
<a-button style="margin-left: 8px" @click="goBack">返回</a-button>
</div>
</a-card>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useTabsViewStore } from '@/store/modules/tabsView';
const { closeCurrentTab } = useTabsViewStore();
const userInfo = ref({
username: 'mockUser',
nickname: 'mockNickname',
phone: '1234567890',
email: 'mock@example.com',
status: 1,
createTime: '2023-01-01 12:00:00',
});
const route = useRoute();
const router = useRouter();
onMounted(() => {
getUserDetail();
});
//
async function getUserDetail() {
try {
const userId = route.params.id;
// API
const response = await $api.user.getDetail(userId);
userInfo.value = response.data;
} catch (err) {
console.error('err', err);
$message.error('获取用户详情失败');
}
}
//
function handleEdit() {
const userId = route.params.id;
router.push(`/user/edit/${userId}`);
}
//
function goBack() {
router.back();
closeCurrentTab(route);
}
</script>
<style lang="less" scoped>
.user-detail {
padding: 24px;
background: #fff;
.operation-buttons {
text-align: center;
}
}
</style>

View File

@ -1,106 +0,0 @@
<template>
<div class="user-edit">
<a-card :bordered="false">
<a-form layout="vertical" :model="userForm" @submit="handleSave">
<a-form-item label="用户名">
<a-input
v-model:value="userForm.username"
placeholder="请输入用户名"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item label="昵称">
<a-input
v-model:value="userForm.nickname"
placeholder="请输入昵称"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item label="手机号">
<a-input
v-model:value="userForm.phone"
placeholder="请输入手机号"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item label="邮箱">
<a-input
v-model:value="userForm.email"
placeholder="请输入邮箱"
allow-clear
style="max-width: 400px"
/>
</a-form-item>
<a-form-item label="状态">
<a-select v-model:value="userForm.status" style="max-width: 400px">
<a-select-option :value="1">启用</a-select-option>
<a-select-option :value="0">禁用</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" html-type="submit">保存</a-button>
<a-button @click="goBack">取消</a-button>
</a-space>
</a-form-item>
</a-form>
</a-card>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { message } from 'ant-design-vue';
import { useTabsViewStore } from '@/store/modules/tabsView';
const router = useRouter();
const route = useRoute();
const { closeCurrentTab } = useTabsViewStore();
//
const userForm = ref({
username: '',
nickname: '',
phone: '',
email: '',
status: 1,
});
//
const handleSave = async () => {
// TODO:
message.success('保存成功');
goBack();
};
//
const goBack = () => {
router.back(); //
closeCurrentTab(route); //
};
//
const initUserData = async (userId: string) => {
// TODO:
// const res = await getUserInfo(userId);
// mock
userForm.value = {
username: 'mockUser',
nickname: 'mockNickname',
phone: '1234567890',
email: 'mock@example.com',
status: 1,
};
};
// ID
const userId = route.params.id; // ID
if (userId) {
initUserData(userId);
}
</script>

View File

@ -1,219 +0,0 @@
<template>
<div class="user-list">
<a-card :bordered="false">
<!-- 搜索区域 -->
<a-form layout="inline" :model="searchForm" @submit="handleSearch">
<a-form-item label="用户名" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-input v-model:value="searchForm.username" placeholder="请输入用户名" allow-clear />
</a-form-item>
<a-form-item label="手机号" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-input v-model:value="searchForm.phone" placeholder="请输入手机号" allow-clear />
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" html-type="submit">查询</a-button>
<a-button @click="resetSearch">重置</a-button>
</a-space>
</a-form-item>
</a-form>
<!-- 操作按钮区域 -->
<div class="table-operations">
<a-space>
<a-button type="primary" @click="handleAdd">
<template #icon>
<plus-outlined />
</template>
新增用户
</a-button>
</a-space>
</div>
<!-- 表格区域 -->
<a-table
:columns="columns"
:data-source="tableData"
:loading="loading"
:pagination="pagination"
:row-selection="{ selectedRowKeys, onChange: onSelectChange }"
row-key="id"
@change="handleTableChange"
>
<!-- 状态列 -->
<template #status="{ text }">
<a-tag :color="text ? 'success' : 'error'">
{{ text ? '启用' : '禁用' }}
</a-tag>
</template>
<!-- 操作列 -->
<template #action="{ record }">
<a-space>
<a-button type="link" @click="handleEdit(record)">编辑</a-button>
<a-button type="link" @click="handleDetail(record)">详情</a-button>
<a-button type="link" @click="handleChangePassword(record)">修改密码</a-button>
<a-popconfirm title="确定要删除这条记录吗?" @confirm="handleDelete(record)">
<a-button type="link" danger>删除</a-button>
</a-popconfirm>
</a-space>
</template>
</a-table>
</a-card>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { useRouter } from 'vue-router';
import { PlusOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
const router = useRouter();
//
const searchForm = reactive({
username: '',
phone: '',
});
//
const columns = [
{
title: '用户名',
dataIndex: 'username',
width: 120,
},
{
title: '昵称',
dataIndex: 'nickname',
width: 120,
},
{
title: '手机号',
dataIndex: 'phone',
width: 120,
},
{
title: '状态',
dataIndex: 'status',
width: 100,
slots: { customRender: 'status' },
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180,
},
{
title: '操作',
key: 'action',
fixed: 'right',
width: 280,
slots: { customRender: 'action' },
},
];
//
const loading = ref(false);
const tableData = ref<any[]>([]);
const selectedRowKeys = ref<string[]>([]);
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showQuickJumper: true,
});
//
const getTableData = async () => {
loading.value = true;
try {
// TODO:
// const res = await getUserList({
// ...searchForm,
// page: pagination.current,
// pageSize: pagination.pageSize,
// });
// tableData.value = res.data.list;
// pagination.total = res.data.total;
//
tableData.value = Array.from({ length: 10 }).map((_, index) => ({
id: index + 1,
username: `user${index + 1}`,
nickname: `用户${index + 1}`,
phone: '13800138000',
email: `user${index + 1}@example.com`,
status: index % 2,
createTime: '2024-03-20 12:00:00',
}));
pagination.total = 100;
} finally {
loading.value = false;
}
};
//
const onSelectChange = (keys: string[]) => {
selectedRowKeys.value = keys;
};
//
const handleTableChange = (pag: any) => {
pagination.current = pag.current;
pagination.pageSize = pag.pageSize;
getTableData();
};
//
const handleSearch = () => {
pagination.current = 1;
getTableData();
};
//
const resetSearch = () => {
searchForm.username = '';
searchForm.phone = '';
handleSearch();
};
//
const handleAdd = () => {
router.push('/user/add');
};
//
const handleEdit = (record: any) => {
router.push(`/user/edit/${record.id}`);
};
//
const handleDetail = (record: any) => {
router.push(`/user/detail/${record.id}`);
};
//
const handleChangePassword = (record: any) => {
router.push(`/user/change-password/${record.id}`);
};
//
const handleDelete = async (record: any) => {
// TODO:
message.success('删除成功');
getTableData();
};
//
getTableData();
</script>
<style lang="less" scoped>
.user-list {
.table-operations {
margin: 16px 0;
}
}
</style>

12
pnpm-lock.yaml generated
View File

@ -183,6 +183,9 @@ importers:
'@iframe-resizer/parent': '@iframe-resizer/parent':
specifier: ^5.3.3 specifier: ^5.3.3
version: 5.3.3 version: 5.3.3
'@sy/unified-login':
specifier: 1.0.29
version: 1.0.29(vue@3.5.13(typescript@5.6.3))
'@sy/y-code-renderer-adapter': '@sy/y-code-renderer-adapter':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/render-adapter version: link:../../packages/render-adapter
@ -3119,6 +3122,11 @@ packages:
'@sxzz/popperjs-es@2.11.7': '@sxzz/popperjs-es@2.11.7':
resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
'@sy/unified-login@1.0.29':
resolution: {integrity: sha512-ihYgOX8mrrDcXjsxO0C40647F7DbMs3mBMBn0deAV2tIfCEJRMMtryP8Fi4T5UDfEXVpRHoSFNW4zpTIbsL4Vw==}
peerDependencies:
vue: ^2.0.0 || >=3.0.0
'@sy/y-code-chart@1.2.7': '@sy/y-code-chart@1.2.7':
resolution: {integrity: sha512-87/au4OoafTQSqwAAJhB8XpzwTlpu1u42VqYPG28JDarUOva/12eEyAU5i+e7e3t1pV+JSqP+Q/4HIhQw61q9w==} resolution: {integrity: sha512-87/au4OoafTQSqwAAJhB8XpzwTlpu1u42VqYPG28JDarUOva/12eEyAU5i+e7e3t1pV+JSqP+Q/4HIhQw61q9w==}
@ -13090,6 +13098,10 @@ snapshots:
'@sxzz/popperjs-es@2.11.7': {} '@sxzz/popperjs-es@2.11.7': {}
'@sy/unified-login@1.0.29(vue@3.5.13(typescript@5.6.3))':
dependencies:
vue: 3.5.13(typescript@5.6.3)
'@sy/y-code-chart@1.2.7(vue@3.5.13(typescript@5.3.3))': '@sy/y-code-chart@1.2.7(vue@3.5.13(typescript@5.3.3))':
dependencies: dependencies:
'@antv/g2plot': 2.4.32 '@antv/g2plot': 2.4.32