style: 使用eslint、prettier

This commit is contained in:
zy7y 2022-09-14 18:03:28 +08:00
parent d06ac9e983
commit 0ea5217a9f
28 changed files with 2610 additions and 332 deletions

15
frontend/.editorconfig Normal file
View File

@ -0,0 +1,15 @@
# http://editorconfig.org
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格tab | space
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false

21
frontend/.eslintrc.js Normal file
View File

@ -0,0 +1,21 @@
module.exports = {
root: true,
env: {
node: true
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/prettier',
'plugin:prettier/recommended'
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'vue/multi-word-component-names': 'off', // 组件名称校验
'vue/valid-v-pre': 'off' // 自定指令校验
}
}

9
frontend/.prettierignore Normal file
View File

@ -0,0 +1,9 @@
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*

9
frontend/.prettierrc Normal file
View File

@ -0,0 +1,9 @@
{
"useTabs": false,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": true,
"semi": false
}

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,9 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"preview": "vite preview --port 4173" "preview": "vite preview --port 4173",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
"prettier": "prettier --write ."
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^3.2.12", "ant-design-vue": "^3.2.12",
@ -17,7 +19,12 @@
"vue-router": "^4.1.5" "vue-router": "^4.1.5"
}, },
"devDependencies": { "devDependencies": {
"@rushstack/eslint-patch": "^1.1.4",
"@vitejs/plugin-vue": "^3.0.3", "@vitejs/plugin-vue": "^3.0.3",
"@vue/eslint-config-prettier": "^7.0.0",
"eslint": "^8.22.0",
"eslint-plugin-vue": "^9.3.0",
"prettier": "^2.7.1",
"unplugin-vue-components": "^0.22.7", "unplugin-vue-components": "^0.22.7",
"vite": "^3.0.9" "vite": "^3.0.9"
} }

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import { RouterView } from "vue-router"; import { RouterView } from 'vue-router'
import { Spin } from "ant-design-vue"; import { Spin } from 'ant-design-vue'
import { userStore } from "./stores/user"; import { userStore } from './stores/user'
</script> </script>
<template> <template>

View File

@ -1,19 +1,19 @@
<script setup> <script setup>
import { useRoute } from "vue-router"; import { useRoute } from 'vue-router'
import { computed } from "vue"; import { computed } from 'vue'
const route = useRoute(); const route = useRoute()
const cruPath = computed(() => { const cruPath = computed(() => {
return route.path.substring(1, route.path.length).split("/"); return route.path.substring(1, route.path.length).split('/')
}); })
console.log(route.path, route.fullPath); console.log(route.path, route.fullPath)
</script> </script>
<template> <template>
<div class="crumb"> <div class="crumb">
<a-breadcrumb> <a-breadcrumb>
<a-breadcrumb-item href="">Home</a-breadcrumb-item> <a-breadcrumb-item href="">Home</a-breadcrumb-item>
<template v-for="path in cruPath"> <template v-for="path in cruPath" :key="path">
<a-breadcrumb-item> <a-breadcrumb-item>
{{ path }} {{ path }}
</a-breadcrumb-item> </a-breadcrumb-item>

View File

@ -1,20 +1,20 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from 'vue'
import UserInfo from "@/components/layout/layout-info/layout-info.vue"; import UserInfo from '@/components/layout/layout-info/layout-info.vue'
import HeaderCrumb from "./header-crumb.vue"; import HeaderCrumb from './header-crumb.vue'
import { loadIconCpn } from "@/utils/loadCpn"; import { loadIconCpn } from '@/utils/loadCpn'
// //
const collapsed = ref(false); const collapsed = ref(false)
const emits = defineEmits(["changeFold"]); const emits = defineEmits(['changeFold'])
// //
const clickMenuFold = () => { const clickMenuFold = () => {
collapsed.value = !collapsed.value; collapsed.value = !collapsed.value
// //
emits("changeFold", collapsed.value); emits('changeFold', collapsed.value)
}; }
</script> </script>
<template> <template>

View File

@ -1,24 +1,24 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from 'vue'
import { useRouter } from "vue-router"; import { useRouter } from 'vue-router'
import { userStore } from "@/stores/user"; import { userStore } from '@/stores/user'
import SelectRole from "./select-role.vue"; import SelectRole from './select-role.vue'
const store = userStore(); const store = userStore()
const router = useRouter(); const router = useRouter()
const roleChangeRef = ref(); const roleChangeRef = ref()
const onClick = ({ key }) => { const onClick = ({ key }) => {
if (key === "1") { if (key === '1') {
// //
roleChangeRef.value?.showModal(); roleChangeRef.value?.showModal()
} else { } else {
store.$reset(); store.$reset()
router.push("/login"); router.push('/login')
} }
}; }
</script> </script>
<template> <template>

View File

@ -1,42 +1,42 @@
<script setup> <script setup>
import { ref, computed } from "vue"; import { ref, computed } from 'vue'
import { userStore } from "@/stores/user"; import { userStore } from '@/stores/user'
const store = userStore(); const store = userStore()
const loading = ref(false); const loading = ref(false)
const visible = ref(false); const visible = ref(false)
const currentRoleId = ref(store.userInfo.roles[0].id); const currentRoleId = ref(store.userInfo.roles[0].id)
// //
const options = computed(() => { const options = computed(() => {
return store.userInfo.roles.map((role) => ({ return store.userInfo.roles.map((role) => ({
label: role.name, label: role.name,
value: role.id, value: role.id
})); }))
}); })
const showModal = () => { const showModal = () => {
visible.value = true; visible.value = true
}; }
const handleOk = () => { const handleOk = () => {
loading.value = true; loading.value = true
store.userSelectRole(currentRoleId.value); store.userSelectRole(currentRoleId.value)
setTimeout(() => { setTimeout(() => {
loading.value = false; loading.value = false
visible.value = false; visible.value = false
}, 1000); }, 1000)
}; }
const handleCancel = () => { const handleCancel = () => {
visible.value = false; visible.value = false
}; }
defineExpose({ defineExpose({
showModal, showModal
}); })
</script> </script>
<template> <template>
@ -44,13 +44,7 @@ defineExpose({
<a-modal v-model:visible="visible" title="切换角色" @ok="handleOk"> <a-modal v-model:visible="visible" title="切换角色" @ok="handleOk">
<template #footer> <template #footer>
<a-button key="back" @click="handleCancel">取消</a-button> <a-button key="back" @click="handleCancel">取消</a-button>
<a-button <a-button key="submit" type="primary" :loading="loading" @click="handleOk">确定</a-button>
key="submit"
type="primary"
:loading="loading"
@click="handleOk"
>确定</a-button
>
</template> </template>
<span>选择角色</span> <span>选择角色</span>

View File

@ -1,15 +1,15 @@
<script setup> <script setup>
import { useRouter } from "vue-router"; import { useRouter } from 'vue-router'
import { userStore } from "@/stores/user"; import { userStore } from '@/stores/user'
import { loadIconCpn } from "@/utils/loadCpn"; import { loadIconCpn } from '@/utils/loadCpn'
const store = userStore(); const store = userStore()
const router = useRouter(); const router = useRouter()
// //
const menuClick = (menu) => { const menuClick = (menu) => {
router.push(menu.path); router.push(menu.path)
}; }
</script> </script>
<template> <template>
@ -44,7 +44,7 @@ const menuClick = (menu) => {
.logo { .logo {
display: flex; display: flex;
height: 32px; height: 32px;
background: rgba(255, 255, 255, 0.3) url("@/assets/img/fastapi.svg"); background: rgba(255, 255, 255, 0.3) url('@/assets/img/fastapi.svg');
margin: 16px; margin: 16px;
background-size: 100% 100%; background-size: 100% 100%;
} }

View File

@ -1,22 +1,22 @@
import { createApp } from "vue"; import { createApp } from 'vue'
import App from "./App.vue"; import App from './App.vue'
import router from "./router"; import router from './router'
import store from "./stores"; import store from './stores'
import { userStore } from "./stores/user"; import { userStore } from './stores/user'
import "normalize.css"; import 'normalize.css'
import "@/assets/css/base.css"; import '@/assets/css/base.css'
import "ant-design-vue/dist/antd.css"; import 'ant-design-vue/dist/antd.css'
import hasPermisson from "@/utils/directive"; import hasPermisson from '@/utils/directive'
const app = createApp(App); const app = createApp(App)
hasPermisson(app); hasPermisson(app)
app.use(store); app.use(store)
userStore().loadRoleRouter(); userStore().loadRoleRouter()
app.use(router); app.use(router)
app.mount("#app"); app.mount('#app')

View File

@ -1,48 +1,48 @@
import { createRouter, createWebHistory } from "vue-router"; import { createRouter, createWebHistory } from 'vue-router'
import { message } from "ant-design-vue"; import { message } from 'ant-design-vue'
import { userStore } from "@/stores/user"; import { userStore } from '@/stores/user'
const routes = [ const routes = [
{ {
path: "/", path: '/',
redirect: "/main", redirect: '/main'
}, },
{ {
path: "/login", path: '/login',
meta: { title: "登录页" }, meta: { title: '登录页' },
component: () => import("@/views/login/login.vue"), component: () => import('@/views/login/login.vue')
}, },
{ {
name: "main", name: 'main',
path: "/main", path: '/main',
meta: { title: "主页" }, meta: { title: '主页' },
component: () => import("@/views/main/main.vue"), component: () => import('@/views/main/main.vue')
}, },
{ {
path: "/:pathMatch(.*)*", path: '/:pathMatch(.*)*',
component: () => import("@/views/error/404.vue"), component: () => import('@/views/error/404.vue')
}, }
]; ]
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(import.meta.env.BASE_URL),
routes: routes, routes: routes
}); })
// 导航守卫 // 导航守卫
router.beforeEach((to) => { router.beforeEach((to) => {
// 修改页面标题 // 修改页面标题
if (to.meta.title) { if (to.meta.title) {
document.title = to.meta.title; document.title = to.meta.title
} }
if (to.path !== "/login") { if (to.path !== '/login') {
if (userStore().token) { if (userStore().token) {
return; return
} }
message.warning("请登录"); message.warning('请登录')
return "/login"; return '/login'
} }
}); })
export default router; export default router

View File

@ -1,38 +1,38 @@
import request from "@/utils/request"; import request from '@/utils/request'
export function login(data) { export function login(data) {
return request({ return request({
url: "/login", url: '/login',
method: "post", method: 'post',
data, data
}); })
} }
// 获取用户信息 // 获取用户信息
export function getUserInfo(uid) { export function getUserInfo(uid) {
return request({ return request({
url: `/user/${uid}`, url: `/user/${uid}`
}); })
} }
// 获取权限信息 // 获取权限信息
export function getMenus(rid) { export function getMenus(rid) {
return request({ return request({
url: `/role/${rid}/menu`, url: `/role/${rid}/menu`
}); })
} }
// 修改用户信息 // 修改用户信息
export function selectRole(rid) { export function selectRole(rid) {
return request({ return request({
url: `/user/role/${rid}`, url: `/user/role/${rid}`,
method: "put", method: 'put'
}); })
} }
// 获取用户列表 // 获取用户列表
export function getUsers() { export function getUsers() {
return request({ return request({
url: "/user", url: '/user'
}); })
} }

View File

@ -4,5 +4,4 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia() const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) pinia.use(piniaPluginPersistedstate)
export default pinia export default pinia

View File

@ -1,32 +1,32 @@
import { ref, computed } from "vue"; import { ref, computed } from 'vue'
import { defineStore } from "pinia"; import { defineStore } from 'pinia'
import { message } from "ant-design-vue"; import { message } from 'ant-design-vue'
import router from "@/router"; import router from '@/router'
import { loadRouter, loadDefaultMenu } from "@/utils/loadCpn"; import { loadRouter, loadDefaultMenu } from '@/utils/loadCpn'
import { getMenus, getUserInfo, login, selectRole } from "@/service/user"; import { getMenus, getUserInfo, login, selectRole } from '@/service/user'
export const userStore = defineStore( export const userStore = defineStore(
"user", 'user',
() => { () => {
const token = ref(""); const token = ref('')
const userInfo = ref({}); const userInfo = ref({})
const userMenus = ref([]); const userMenus = ref([])
const selectKey = ref(null); const selectKey = ref(null)
const isLoading = ref(false); const isLoading = ref(false)
// getter // getter
const accessToken = computed(() => "Bearer " + token.value); const accessToken = computed(() => 'Bearer ' + token.value)
// setup store 不提供$reset 需要自己重置 // setup store 不提供$reset 需要自己重置
// https://github.com/vuejs/pinia/issues/1056 // https://github.com/vuejs/pinia/issues/1056
const $reset = () => { const $reset = () => {
token.value = ""; token.value = ''
userInfo.value = {}; userInfo.value = {}
userMenus.value = []; userMenus.value = []
}; }
/** /**
* 获取用户信息 & 菜单路由 * 获取用户信息 & 菜单路由
@ -34,48 +34,48 @@ export const userStore = defineStore(
*/ */
const getUserData = async (uid) => { const getUserData = async (uid) => {
// 2. 获取用户信息 // 2. 获取用户信息
const info = await getUserInfo(uid); const info = await getUserInfo(uid)
userInfo.value = info.data; userInfo.value = info.data
// 3. 获取权限信息 // 3. 获取权限信息
const menus = await getMenus(info.data.roles[0].id); const menus = await getMenus(info.data.roles[0].id)
userMenus.value = menus.data; userMenus.value = menus.data
// 3.1 加载权限 // 3.1 加载权限
loadRouter(menus.data); loadRouter(menus.data)
// 3.2 默认跳转路由 // 3.2 默认跳转路由
const defaultMenu = loadDefaultMenu(menus.data); const defaultMenu = loadDefaultMenu(menus.data)
selectKey.value = [defaultMenu.id]; selectKey.value = [defaultMenu.id]
// 4. 跳转 // 4. 跳转
if (defaultMenu.path) { if (defaultMenu.path) {
router.push(defaultMenu.path); router.push(defaultMenu.path)
} else { } else {
router.push("/main"); router.push('/main')
} }
}; }
const loginAction = async (data) => { const loginAction = async (data) => {
// 1. 登录 // 1. 登录
const res = await login(data); const res = await login(data)
token.value = res.data.token; token.value = res.data.token
await getUserData(res.data.id); await getUserData(res.data.id)
// 弹框提示登录成功 // 弹框提示登录成功
message.success("登录成功."); message.success('登录成功.')
}; }
// loadRouter 刷新问题 // loadRouter 刷新问题
const loadRoleRouter = () => { const loadRoleRouter = () => {
loadRouter(userMenus.value); loadRouter(userMenus.value)
}; }
// 切换角色 // 切换角色
const userSelectRole = async (rid) => { const userSelectRole = async (rid) => {
await selectRole(rid); await selectRole(rid)
// 重新拿用户信息 // 重新拿用户信息
await getUserData(userInfo.value.id); await getUserData(userInfo.value.id)
}; }
return { return {
token, token,
@ -87,10 +87,10 @@ export const userStore = defineStore(
$reset, $reset,
loginAction, loginAction,
loadRoleRouter, loadRoleRouter,
userSelectRole, userSelectRole
}; }
}, },
{ {
persist: true, persist: true
} }
); )

View File

@ -1,17 +1,17 @@
import { userStore } from "@/stores/user"; import { userStore } from '@/stores/user'
export default (app) => { export default (app) => {
// 按钮权限 // 按钮权限
app.directive("per", { app.directive('per', {
mounted(el, binding) { mounted(el, binding) {
console.log(el, binding.value); console.log(el, binding.value)
if ( if (
// 是否存在 // 是否存在
userStore().userInfo.permissions.indexOf(binding.value) === -1 userStore().userInfo.permissions.indexOf(binding.value) === -1
) { ) {
// 删除元素 // 删除元素
el.parentNode && el.parentNode.removeChild(el); el.parentNode && el.parentNode.removeChild(el)
} }
}, }
}); })
}; }

View File

@ -1,5 +1,5 @@
import moment from "moment"; import moment from 'moment'
export const formatTime = (value) => { export const formatTime = (value) => {
return moment(value).format("YYYY-MM-DD HH:mm:ss"); return moment(value).format('YYYY-MM-DD HH:mm:ss')
}; }

View File

@ -1,6 +1,6 @@
// 动态加载组件 // 动态加载组件
import * as icons from "@ant-design/icons-vue"; import * as icons from '@ant-design/icons-vue'
import router from "@/router"; import router from '@/router'
/** /**
* 动态加载antd icon * 动态加载antd icon
@ -10,27 +10,27 @@ import router from "@/router";
* template: 使用 <component :is="loadIconCpn("UserField")"> * template: 使用 <component :is="loadIconCpn("UserField")">
*/ */
function loadIconCpn(iconName) { function loadIconCpn(iconName) {
return icons[iconName]; return icons[iconName]
} }
// 拿到views下所有.vue文件 // 拿到views下所有.vue文件
const modules = import.meta.glob("../views/**/**.vue"); const modules = import.meta.glob('../views/**/**.vue')
function loadRouter(menus) { function loadRouter(menus) {
for (const menu of menus) { for (const menu of menus) {
// type 为1 菜单组件 // type 为1 菜单组件
if (menu.type === 1 && menu.path !== "") { if (menu.type === 1 && menu.path !== '') {
const cnpPath = `../views/main${menu.component}`; const cnpPath = `../views/main${menu.component}`
router.addRoute("main", { router.addRoute('main', {
path: menu.path, path: menu.path,
name: menu.name, name: menu.name,
// 映射取值 // 映射取值
component: modules[/* @vite-ignore */ cnpPath], component: modules[/* @vite-ignore */ cnpPath],
meta: menu.meta, meta: menu.meta
}); })
} else if (menu.children) { } else if (menu.children) {
loadRouter(menu.children); loadRouter(menu.children)
} }
} }
} }
@ -38,8 +38,8 @@ function loadRouter(menus) {
// 默认打开第一个 // 默认打开第一个
function loadDefaultMenu(menus) { function loadDefaultMenu(menus) {
for (const menu of menus) { for (const menu of menus) {
return menu.children.find((e) => e.type === 1); return menu.children.find((e) => e.type === 1)
} }
} }
export { loadIconCpn, loadRouter, loadDefaultMenu }; export { loadIconCpn, loadRouter, loadDefaultMenu }

View File

@ -1,42 +1,42 @@
import axios from "axios"; import axios from 'axios'
import { message } from "ant-design-vue"; import { message } from 'ant-design-vue'
import { userStore } from "@/stores/user"; import { userStore } from '@/stores/user'
export default (config) => { export default (config) => {
const instance = axios.create({ const instance = axios.create({
baseURL: import.meta.env.VITE_BASE_URL, baseURL: import.meta.env.VITE_BASE_URL,
timeout: 10000, timeout: 10000
}); })
instance.interceptors.request.use((config) => { instance.interceptors.request.use((config) => {
userStore().isLoading = !userStore().isLoading; userStore().isLoading = !userStore().isLoading
config.headers.Authorization = userStore().accessToken; config.headers.Authorization = userStore().accessToken
return config; return config
}); })
instance.interceptors.response.use( instance.interceptors.response.use(
(res) => { (res) => {
userStore().isLoading = !userStore().isLoading; userStore().isLoading = !userStore().isLoading
if (res.data.code !== 200) { if (res.data.code !== 200) {
message.error(res.data.msg); message.error(res.data.msg)
} }
console.log(res.data); console.log(res.data)
return res.data; return res.data
}, },
(err) => { (err) => {
userStore().isLoading = !userStore().isLoading; userStore().isLoading = !userStore().isLoading
if (err.response.data?.msg) { if (err.response.data?.msg) {
message.error(err.response.data.msg); message.error(err.response.data.msg)
} else if (err.response.data?.detail) { } else if (err.response.data?.detail) {
// 请求参数缺失 // 请求参数缺失
message.error(err.response.data?.detail[0].msg); message.error(err.response.data?.detail[0].msg)
} else { } else {
message.error(err.message); message.error(err.message)
} }
return Promise.reject(err); return Promise.reject(err)
} }
); )
return instance(config); return instance(config)
}; }

View File

@ -1,11 +1,11 @@
<script setup> <script setup>
import { useRouter } from "vue-router"; import { useRouter } from 'vue-router'
const router = useRouter(); const router = useRouter()
const toHome = () => { const toHome = () => {
router.push("/"); router.push('/')
}; }
</script> </script>
<template> <template>

View File

@ -1,43 +1,38 @@
<script setup> <script setup>
import { UserOutlined, LockOutlined } from "@ant-design/icons-vue"; import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
import { ref, reactive, computed } from "vue"; import { ref, reactive, computed } from 'vue'
import { userStore } from "@/stores/user"; import { userStore } from '@/stores/user'
const store = userStore(); const store = userStore()
// //
const rules = { const rules = {
username: [ username: [
{ required: true, message: "请输入用户名", trigger: "blur" }, { required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 20, message: "5~20", trigger: "blur" }, { min: 5, max: 20, message: '5~20', trigger: 'blur' }
], ],
password: [ password: [
{ required: true, message: "请输入密码", trigger: "blur" }, { required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 12, message: "6~12", trigger: "blur" }, { min: 6, max: 12, message: '6~12', trigger: 'blur' }
], ]
}; }
// //
const formRef = ref(); const formRef = ref()
const formData = reactive({ const formData = reactive({
username: "admin", username: 'admin',
password: "123456", password: '123456'
}); })
// //
const disabled = computed(() => { const disabled = computed(() => {
return !(formData.username && formData.password); return !(formData.username && formData.password)
}); })
// //
const submitForm = (formEl) => { const submitForm = (formEl) => {
if (!formEl) return; if (!formEl) return
formEl.validate().then( formEl.validate().then(() => store.loginAction(formData))
(res) => { }
store.loginAction(formData);
},
(err) => err
);
};
</script> </script>
<template> <template>
@ -47,10 +42,7 @@ const submitForm = (formEl) => {
<a-form ref="formRef" :model="formData" :rules="rules"> <a-form ref="formRef" :model="formData" :rules="rules">
<a-form-item has-feedback name="username"> <a-form-item has-feedback name="username">
<a-input <a-input v-model:value.trim="formData.username" placeholder="Username">
v-model:value.trim="formData.username"
placeholder="Username"
>
<template #prefix> <template #prefix>
<UserOutlined style="color: rgba(0, 0, 0, 0.25)" /> <UserOutlined style="color: rgba(0, 0, 0, 0.25)" />
</template> </template>
@ -90,7 +82,7 @@ const submitForm = (formEl) => {
text-align: center; text-align: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-image: url("@/assets/img/background.svg"); background-image: url('@/assets/img/background.svg');
} }
.continer { .continer {
width: 300px; width: 300px;

View File

@ -1,16 +1,16 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from 'vue'
import SiderMenu from "@/components/layout/sider-menu.vue"; import SiderMenu from '@/components/layout/sider-menu.vue'
import LayoutHeader from "@/components/layout/layout-header.vue"; import LayoutHeader from '@/components/layout/layout-header.vue'
// a-ayout-sider // a-ayout-sider
const collapsed = ref(false); const collapsed = ref(false)
// header a-layout-sider // header a-layout-sider
const changeSiderFold = (subValue) => { const changeSiderFold = (subValue) => {
collapsed.value = subValue; collapsed.value = subValue
}; }
</script> </script>
<template> <template>
@ -30,7 +30,7 @@ const changeSiderFold = (subValue) => {
:style="{ :style="{
margin: '24px 16px', margin: '24px 16px',
background: '#F0F2F5', background: '#F0F2F5',
minHeight: '280px', minHeight: '280px'
}" }"
> >
<router-view /> <router-view />

View File

@ -1,11 +1,7 @@
<script setup> <script setup></script>
</script>
<template> <template>
<div>role</div> <div>role</div>
</template> </template>
<style scoped> <style scoped></style>
</style>

View File

@ -1,39 +1,39 @@
// 表格数据列 表头配置 // 表格数据列 表头配置
export const columns = [ export const columns = [
{ {
title: "序号", title: '序号',
dataIndex: "index", dataIndex: 'index',
key: "index", key: 'index',
align: "center", align: 'center',
customRender: ({ text, record, index }) => `${index + 1}`, customRender: ({ index }) => `${index + 1}`
}, },
{ {
title: "用户名", title: '用户名',
dataIndex: "username", dataIndex: 'username',
key: "username", key: 'username'
}, },
{ {
title: "昵称", title: '昵称',
dataIndex: "nickname", dataIndex: 'nickname',
key: "nickname", key: 'nickname'
}, },
{ {
title: "状态", title: '状态',
dataIndex: "status", dataIndex: 'status',
key: "status", key: 'status'
}, },
{ {
title: "创建时间", title: '创建时间',
dataIndex: "created", dataIndex: 'created',
key: "created", key: 'created'
}, },
{ {
title: "更新时间", title: '更新时间',
dataIndex: "modified", dataIndex: 'modified',
key: "modified", key: 'modified'
}, },
{ {
title: "操作", title: '操作',
key: "action", key: 'action'
}, }
]; ]

View File

@ -1,24 +1,24 @@
<script setup> <script setup>
import { getUsers } from "@/service/user"; import { getUsers } from '@/service/user'
import { columns } from "./conf"; import { columns } from './conf'
import { formatTime } from "@/utils/format"; import { formatTime } from '@/utils/format'
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from 'vue'
import { PlusOutlined, SearchOutlined } from "@ant-design/icons-vue"; import { PlusOutlined, SearchOutlined } from '@ant-design/icons-vue'
// //
const dataSource = ref([]); const dataSource = ref([])
// //
const pageSizeChange = (current, size) => { const pageSizeChange = (current, size) => {
console.log(current, size, "展示数量变化"); console.log(current, size, '展示数量变化')
}; }
// //
const pageChange = (page, pageSize) => { const pageChange = (page, pageSize) => {
console.log(page, pageSize, "页码变化"); console.log(page, pageSize, '页码变化')
}; }
// //
const pagination = reactive({ const pagination = reactive({
@ -26,22 +26,22 @@ const pagination = reactive({
pageSize: 10, // pageSize: 10, //
showSizeChanger: true, showSizeChanger: true,
total: 200, total: 200,
pageSizeOptions: ["10", "50", "100"], pageSizeOptions: ['10', '50', '100'],
showTotal: (total) => `${total}条数据`, showTotal: (total) => `${total}条数据`,
onShowSizeChange: pageSizeChange, onShowSizeChange: pageSizeChange,
onChange: pageChange, onChange: pageChange
}); })
onMounted(() => { onMounted(() => {
getPageData(); getPageData()
}); })
const getPageData = () => { const getPageData = () => {
getUsers().then((res) => { getUsers().then((res) => {
dataSource.value = res.data.items; dataSource.value = res.data.items
pagination.total = res.data.total; pagination.total = res.data.total
}); })
}; }
</script> </script>
<template> <template>
@ -74,15 +74,11 @@ const getPageData = () => {
</template> </template>
<!-- 数据 --> <!-- 数据 -->
<a-table <a-table :columns="columns" :data-source="dataSource" :pagination="pagination">
:columns="columns"
:data-source="dataSource"
:pagination="pagination"
>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'"> <template v-if="column.key === 'status'">
<a-tag :color="record.status !== 9 ? 'green' : 'red'"> <a-tag :color="record.status !== 9 ? 'green' : 'red'">
{{ record.status !== 9 ? "正常" : "已删除" }} {{ record.status !== 9 ? '正常' : '已删除' }}
</a-tag> </a-tag>
</template> </template>
<template v-else-if="column.key === 'created'"> <template v-else-if="column.key === 'created'">

View File

@ -1,35 +1,35 @@
import { fileURLToPath, URL } from "node:url"; import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from "vite"; import { defineConfig } from 'vite'
import vue from "@vitejs/plugin-vue"; import vue from '@vitejs/plugin-vue'
import Components from "unplugin-vue-components/vite"; import Components from 'unplugin-vue-components/vite'
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers"; import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
vue(), vue(),
Components({ Components({
resolvers: [AntDesignVueResolver()], resolvers: [AntDesignVueResolver()]
}), })
], ],
resolve: { resolve: {
alias: { alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)), '@': fileURLToPath(new URL('./src', import.meta.url))
}, }
}, },
server: { server: {
proxy: { proxy: {
// 代理 // 代理
"/api": { '/api': {
target: "http://localhost:8000", target: 'http://localhost:8000',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""), rewrite: (path) => path.replace(/^\/api/, '')
}, },
"/socket.io": { '/socket.io': {
target: "ws://localhost:5000", target: 'ws://localhost:5000',
ws: true, ws: true
}, }
}, }
}, }
}); })