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": {
"dev": "vite",
"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": {
"ant-design-vue": "^3.2.12",
@ -17,7 +19,12 @@
"vue-router": "^4.1.5"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.4",
"@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",
"vite": "^3.0.9"
}

View File

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

View File

@ -1,19 +1,19 @@
<script setup>
import { useRoute } from "vue-router";
import { computed } from "vue";
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute();
const route = useRoute()
const cruPath = computed(() => {
return route.path.substring(1, route.path.length).split("/");
});
console.log(route.path, route.fullPath);
return route.path.substring(1, route.path.length).split('/')
})
console.log(route.path, route.fullPath)
</script>
<template>
<div class="crumb">
<a-breadcrumb>
<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>
{{ path }}
</a-breadcrumb-item>

View File

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

View File

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

View File

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

View File

@ -1,15 +1,15 @@
<script setup>
import { useRouter } from "vue-router";
import { userStore } from "@/stores/user";
import { loadIconCpn } from "@/utils/loadCpn";
import { useRouter } from 'vue-router'
import { userStore } from '@/stores/user'
import { loadIconCpn } from '@/utils/loadCpn'
const store = userStore();
const router = useRouter();
const store = userStore()
const router = useRouter()
//
const menuClick = (menu) => {
router.push(menu.path);
};
router.push(menu.path)
}
</script>
<template>
@ -44,7 +44,7 @@ const menuClick = (menu) => {
.logo {
display: flex;
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;
background-size: 100% 100%;
}

View File

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

View File

@ -1,48 +1,48 @@
import { createRouter, createWebHistory } from "vue-router";
import { message } from "ant-design-vue";
import { userStore } from "@/stores/user";
import { createRouter, createWebHistory } from 'vue-router'
import { message } from 'ant-design-vue'
import { userStore } from '@/stores/user'
const routes = [
{
path: "/",
redirect: "/main",
path: '/',
redirect: '/main'
},
{
path: "/login",
meta: { title: "登录页" },
component: () => import("@/views/login/login.vue"),
path: '/login',
meta: { title: '登录页' },
component: () => import('@/views/login/login.vue')
},
{
name: "main",
path: "/main",
meta: { title: "主页" },
component: () => import("@/views/main/main.vue"),
name: 'main',
path: '/main',
meta: { title: '主页' },
component: () => import('@/views/main/main.vue')
},
{
path: "/:pathMatch(.*)*",
component: () => import("@/views/error/404.vue"),
},
];
path: '/:pathMatch(.*)*',
component: () => import('@/views/error/404.vue')
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: routes,
});
routes: routes
})
// 导航守卫
router.beforeEach((to) => {
// 修改页面标题
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) {
return;
return
}
message.warning("请登录");
return "/login";
message.warning('请登录')
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) {
return request({
url: "/login",
method: "post",
data,
});
url: '/login',
method: 'post',
data
})
}
// 获取用户信息
export function getUserInfo(uid) {
return request({
url: `/user/${uid}`,
});
url: `/user/${uid}`
})
}
// 获取权限信息
export function getMenus(rid) {
return request({
url: `/role/${rid}/menu`,
});
url: `/role/${rid}/menu`
})
}
// 修改用户信息
export function selectRole(rid) {
return request({
url: `/user/role/${rid}`,
method: "put",
});
method: 'put'
})
}
// 获取用户列表
export function getUsers() {
return request({
url: "/user",
});
url: '/user'
})
}

View File

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

View File

@ -1,32 +1,32 @@
import { ref, computed } from "vue";
import { defineStore } from "pinia";
import { message } from "ant-design-vue";
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { message } from 'ant-design-vue'
import router from "@/router";
import { loadRouter, loadDefaultMenu } from "@/utils/loadCpn";
import { getMenus, getUserInfo, login, selectRole } from "@/service/user";
import router from '@/router'
import { loadRouter, loadDefaultMenu } from '@/utils/loadCpn'
import { getMenus, getUserInfo, login, selectRole } from '@/service/user'
export const userStore = defineStore(
"user",
'user',
() => {
const token = ref("");
const userInfo = ref({});
const userMenus = ref([]);
const token = ref('')
const userInfo = ref({})
const userMenus = ref([])
const selectKey = ref(null);
const selectKey = ref(null)
const isLoading = ref(false);
const isLoading = ref(false)
// getter
const accessToken = computed(() => "Bearer " + token.value);
const accessToken = computed(() => 'Bearer ' + token.value)
// setup store 不提供$reset 需要自己重置
// https://github.com/vuejs/pinia/issues/1056
const $reset = () => {
token.value = "";
userInfo.value = {};
userMenus.value = [];
};
token.value = ''
userInfo.value = {}
userMenus.value = []
}
/**
* 获取用户信息 & 菜单路由
@ -34,48 +34,48 @@ export const userStore = defineStore(
*/
const getUserData = async (uid) => {
// 2. 获取用户信息
const info = await getUserInfo(uid);
userInfo.value = info.data;
const info = await getUserInfo(uid)
userInfo.value = info.data
// 3. 获取权限信息
const menus = await getMenus(info.data.roles[0].id);
userMenus.value = menus.data;
const menus = await getMenus(info.data.roles[0].id)
userMenus.value = menus.data
// 3.1 加载权限
loadRouter(menus.data);
loadRouter(menus.data)
// 3.2 默认跳转路由
const defaultMenu = loadDefaultMenu(menus.data);
const defaultMenu = loadDefaultMenu(menus.data)
selectKey.value = [defaultMenu.id];
selectKey.value = [defaultMenu.id]
// 4. 跳转
if (defaultMenu.path) {
router.push(defaultMenu.path);
router.push(defaultMenu.path)
} else {
router.push("/main");
router.push('/main')
}
};
}
const loginAction = async (data) => {
// 1. 登录
const res = await login(data);
token.value = res.data.token;
await getUserData(res.data.id);
const res = await login(data)
token.value = res.data.token
await getUserData(res.data.id)
// 弹框提示登录成功
message.success("登录成功.");
};
message.success('登录成功.')
}
// loadRouter 刷新问题
const loadRoleRouter = () => {
loadRouter(userMenus.value);
};
loadRouter(userMenus.value)
}
// 切换角色
const userSelectRole = async (rid) => {
await selectRole(rid);
await selectRole(rid)
// 重新拿用户信息
await getUserData(userInfo.value.id);
};
await getUserData(userInfo.value.id)
}
return {
token,
@ -87,10 +87,10 @@ export const userStore = defineStore(
$reset,
loginAction,
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) => {
// 按钮权限
app.directive("per", {
app.directive('per', {
mounted(el, binding) {
console.log(el, binding.value);
console.log(el, binding.value)
if (
// 是否存在
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) => {
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 router from "@/router";
import * as icons from '@ant-design/icons-vue'
import router from '@/router'
/**
* 动态加载antd icon
@ -10,27 +10,27 @@ import router from "@/router";
* template: 使用 <component :is="loadIconCpn("UserField")">
*/
function loadIconCpn(iconName) {
return icons[iconName];
return icons[iconName]
}
// 拿到views下所有.vue文件
const modules = import.meta.glob("../views/**/**.vue");
const modules = import.meta.glob('../views/**/**.vue')
function loadRouter(menus) {
for (const menu of menus) {
// type 为1 菜单组件
if (menu.type === 1 && menu.path !== "") {
const cnpPath = `../views/main${menu.component}`;
if (menu.type === 1 && menu.path !== '') {
const cnpPath = `../views/main${menu.component}`
router.addRoute("main", {
router.addRoute('main', {
path: menu.path,
name: menu.name,
// 映射取值
component: modules[/* @vite-ignore */ cnpPath],
meta: menu.meta,
});
meta: menu.meta
})
} else if (menu.children) {
loadRouter(menu.children);
loadRouter(menu.children)
}
}
}
@ -38,8 +38,8 @@ function loadRouter(menus) {
// 默认打开第一个
function loadDefaultMenu(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 { message } from "ant-design-vue";
import { userStore } from "@/stores/user";
import axios from 'axios'
import { message } from 'ant-design-vue'
import { userStore } from '@/stores/user'
export default (config) => {
const instance = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
timeout: 10000,
});
timeout: 10000
})
instance.interceptors.request.use((config) => {
userStore().isLoading = !userStore().isLoading;
config.headers.Authorization = userStore().accessToken;
return config;
});
userStore().isLoading = !userStore().isLoading
config.headers.Authorization = userStore().accessToken
return config
})
instance.interceptors.response.use(
(res) => {
userStore().isLoading = !userStore().isLoading;
userStore().isLoading = !userStore().isLoading
if (res.data.code !== 200) {
message.error(res.data.msg);
message.error(res.data.msg)
}
console.log(res.data);
return res.data;
console.log(res.data)
return res.data
},
(err) => {
userStore().isLoading = !userStore().isLoading;
userStore().isLoading = !userStore().isLoading
if (err.response.data?.msg) {
message.error(err.response.data.msg);
message.error(err.response.data.msg)
} else if (err.response.data?.detail) {
// 请求参数缺失
message.error(err.response.data?.detail[0].msg);
message.error(err.response.data?.detail[0].msg)
} 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>
import { useRouter } from "vue-router";
import { useRouter } from 'vue-router'
const router = useRouter();
const router = useRouter()
const toHome = () => {
router.push("/");
};
router.push('/')
}
</script>
<template>

View File

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

View File

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

View File

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

View File

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

View File

@ -1,24 +1,24 @@
<script setup>
import { getUsers } from "@/service/user";
import { columns } from "./conf";
import { formatTime } from "@/utils/format";
import { getUsers } from '@/service/user'
import { columns } from './conf'
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) => {
console.log(current, size, "展示数量变化");
};
console.log(current, size, '展示数量变化')
}
//
const pageChange = (page, pageSize) => {
console.log(page, pageSize, "页码变化");
};
console.log(page, pageSize, '页码变化')
}
//
const pagination = reactive({
@ -26,22 +26,22 @@ const pagination = reactive({
pageSize: 10, //
showSizeChanger: true,
total: 200,
pageSizeOptions: ["10", "50", "100"],
pageSizeOptions: ['10', '50', '100'],
showTotal: (total) => `${total}条数据`,
onShowSizeChange: pageSizeChange,
onChange: pageChange,
});
onChange: pageChange
})
onMounted(() => {
getPageData();
});
getPageData()
})
const getPageData = () => {
getUsers().then((res) => {
dataSource.value = res.data.items;
pagination.total = res.data.total;
});
};
dataSource.value = res.data.items
pagination.total = res.data.total
})
}
</script>
<template>
@ -74,15 +74,11 @@ const getPageData = () => {
</template>
<!-- 数据 -->
<a-table
:columns="columns"
:data-source="dataSource"
:pagination="pagination"
>
<a-table :columns="columns" :data-source="dataSource" :pagination="pagination">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'">
<a-tag :color="record.status !== 9 ? 'green' : 'red'">
{{ record.status !== 9 ? "正常" : "已删除" }}
{{ record.status !== 9 ? '正常' : '已删除' }}
</a-tag>
</template>
<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 vue from "@vitejs/plugin-vue";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [AntDesignVueResolver()],
}),
resolvers: [AntDesignVueResolver()]
})
],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server: {
proxy: {
// 代理
"/api": {
target: "http://localhost:8000",
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
rewrite: (path) => path.replace(/^\/api/, '')
},
"/socket.io": {
target: "ws://localhost:5000",
ws: true,
},
},
},
});
'/socket.io': {
target: 'ws://localhost:5000',
ws: true
}
}
}
})