commit
1a1c3bce4a
16 changed files with 564 additions and 0 deletions
@ -0,0 +1,9 @@
|
||||
# 编辑器 |
||||
.vscode |
||||
.idea |
||||
|
||||
.history |
||||
|
||||
node_modules |
||||
|
||||
*.mjs |
||||
@ -0,0 +1,7 @@
|
||||
# 局长信箱 |
||||
## 技术栈 |
||||
- [Vite](https://www.vitejs.net/) + [Vue 3](https://cn.vuejs.org/guide/quick-start.html) + [Element-plus](https://element-plus.org/zh-CN/) |
||||
- sass |
||||
- [pinia](https://pinia.vuejs.org/zh/introduction.html) 状态管理库 |
||||
- |
||||
|
||||
@ -0,0 +1,13 @@
|
||||
<!doctype html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>局长信箱 即接即办</title> |
||||
</head> |
||||
<body> |
||||
<div id="app"></div> |
||||
<script type="module" src="/src/main.js"></script> |
||||
</body> |
||||
</html> |
||||
@ -0,0 +1,25 @@
|
||||
{ |
||||
"name": "mailbox-vue", |
||||
"private": true, |
||||
"version": "0.0.0", |
||||
"type": "module", |
||||
"scripts": { |
||||
"dev": "vite", |
||||
"build": "vite build", |
||||
"preview": "vite preview" |
||||
}, |
||||
"dependencies": { |
||||
"element-plus": "^2.5.1", |
||||
"pinia": "^2.1.7", |
||||
"vue": "^3.3.11", |
||||
"vue-router": "^4.2.5" |
||||
}, |
||||
"devDependencies": { |
||||
"@vitejs/plugin-vue": "^4.5.2", |
||||
"sass": "^1.69.7", |
||||
"unplugin-auto-import": "^0.17.3", |
||||
"unplugin-vue-components": "^0.26.0", |
||||
"vite": "^5.0.8", |
||||
"vite-svg-loader": "^5.1.0" |
||||
} |
||||
} |
||||
|
After Width: | Height: | Size: 362 KiB |
@ -0,0 +1,8 @@
|
||||
// @/styles/element/index.scss |
||||
@forward "element-plus/theme-chalk/src/common/var.scss" with ( |
||||
$colors: ( |
||||
"primary": ( |
||||
"base": #162582, |
||||
) |
||||
) |
||||
); |
||||
@ -0,0 +1,211 @@
|
||||
:root:root { |
||||
--primary-color: #184DCF; |
||||
--van-blue: var(--primary-color); |
||||
--van-tabs-bottom-bar-width: 60px; |
||||
--background-color: #ededed; |
||||
} |
||||
|
||||
body { |
||||
font-size: 14px; |
||||
font-family: PingFang-SC-Heavy; |
||||
margin: 0; |
||||
--header-height: 8.377vh; |
||||
} |
||||
|
||||
#app { |
||||
margin: auto; |
||||
} |
||||
|
||||
p { |
||||
margin: 0.5em 0; |
||||
} |
||||
|
||||
svg { |
||||
width: 1em; |
||||
} |
||||
|
||||
svg+span { |
||||
margin-left: .5em; |
||||
} |
||||
|
||||
.none { |
||||
display: none; |
||||
} |
||||
|
||||
.flex { |
||||
display: flex; |
||||
} |
||||
|
||||
.flex-inline { |
||||
display: inline-flex; |
||||
} |
||||
|
||||
.flex.v-center, |
||||
.flex-inline.v-center { |
||||
align-items: center; |
||||
} |
||||
|
||||
.flex.center, |
||||
.flex-inline.center { |
||||
justify-content: center; |
||||
} |
||||
|
||||
.flex.between, |
||||
.flex-inline.between { |
||||
justify-content: space-between; |
||||
} |
||||
|
||||
.flex.end, |
||||
.flex-inline.end { |
||||
justify-content: flex-end; |
||||
} |
||||
|
||||
.flex.wrap, |
||||
.flex-inline.wrap { |
||||
flex-wrap: wrap; |
||||
} |
||||
|
||||
.flex.max-content, |
||||
.flex-inline.max-content { |
||||
width: max-content; |
||||
} |
||||
|
||||
.flex.gap, |
||||
.flex-inline.gap { |
||||
gap: 0 8px; |
||||
} |
||||
|
||||
.flex.gap-10 { |
||||
gap: 0 10px; |
||||
} |
||||
|
||||
.flex.gap-16 { |
||||
gap: 0 16px; |
||||
} |
||||
|
||||
.text-center { |
||||
text-align: center; |
||||
} |
||||
|
||||
.text-nowrap { |
||||
white-space: nowrap; |
||||
text-overflow: ellipsis; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
.text-wrap { |
||||
white-space: pre-wrap; |
||||
} |
||||
|
||||
.container { |
||||
padding: 18px 36px; |
||||
} |
||||
|
||||
.pointer:hover { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.relative { |
||||
position: relative; |
||||
} |
||||
|
||||
.ml-4 { |
||||
margin-left: 4px; |
||||
} |
||||
|
||||
.ml-8 { |
||||
margin-left: 8px; |
||||
} |
||||
|
||||
.ml-10 { |
||||
margin-left: 10px; |
||||
} |
||||
|
||||
.mr-4 { |
||||
margin-right: 4px; |
||||
} |
||||
|
||||
.mr-8 { |
||||
margin-right: 8px; |
||||
} |
||||
|
||||
.mr-10 { |
||||
margin-right: 10px; |
||||
} |
||||
|
||||
.mr-20 { |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
.mt-8 { |
||||
margin-top: 8px; |
||||
} |
||||
|
||||
.mt-10 { |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
.mt-20 { |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
.mb-8 { |
||||
margin-bottom: 8px; |
||||
} |
||||
|
||||
.mb-10 { |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
.mb-20 { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.mb-40 { |
||||
margin-bottom: 40px; |
||||
} |
||||
|
||||
|
||||
.card { |
||||
background-color: #fff; |
||||
margin-bottom: 10px; |
||||
padding-top: 6px; |
||||
|
||||
h2 { |
||||
color: #666; |
||||
font-size: 12px; |
||||
font-weight: normal; |
||||
margin: var(--van-cell-group-inset-padding); |
||||
padding: var(--van-cell-vertical-padding) 0; |
||||
} |
||||
|
||||
header { |
||||
margin: var(--van-cell-group-inset-padding); |
||||
margin-top: 16px; |
||||
font-size: 17px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.content { |
||||
box-shadow: inset 0px -1px 0px 0px rgba(227, 227, 227, 1); |
||||
color: #666; |
||||
margin-top: 10px; |
||||
padding: var(--van-cell-group-inset-padding); |
||||
padding-bottom: 30px; |
||||
font-size: 12px; |
||||
font-weight: 400; |
||||
} |
||||
|
||||
footer { |
||||
box-shadow: inset 0px -1px 0px 0px rgba(227, 227, 227, 1); |
||||
padding: var(--van-cell-group-inset-padding); |
||||
padding-top: 16px; |
||||
padding-bottom: 16px; |
||||
} |
||||
} |
||||
|
||||
.wrapper { |
||||
height: 100vh; |
||||
background-color: var(--background-color); |
||||
overflow: auto; |
||||
} |
||||
@ -0,0 +1,29 @@
|
||||
<template> |
||||
<div :style="{ fontSize: size ? `${size}px` : '' }"> |
||||
<IconSvg /> |
||||
</div> |
||||
</template> |
||||
<script setup> |
||||
const props = defineProps({ |
||||
name: { |
||||
type: String, |
||||
require: true, |
||||
}, |
||||
size: { |
||||
type: Number, |
||||
}, |
||||
}); |
||||
|
||||
let IconSvg = ref(h("template")); |
||||
|
||||
import(`@/assets/icons/${props.name}.svg`).then((data) => { |
||||
IconSvg.value = data.render(); |
||||
}); |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
:deep() { |
||||
svg { |
||||
display: block; |
||||
} |
||||
} |
||||
</style> |
||||
@ -0,0 +1,90 @@
|
||||
<template> |
||||
<header class="flex v-center between"> |
||||
<div> |
||||
<div class="title"><a href="">局长信箱</a></div> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary">退出</el-button> |
||||
</div> |
||||
</header> |
||||
<div class="flex"> |
||||
<aside> |
||||
<nav> |
||||
<a class="flex v-center center wrap pointer" @click="router.push('/')"> |
||||
<el-icon><HomeFilled /></el-icon> |
||||
<span>首页</span> |
||||
</a> |
||||
<a class="flex v-center center wrap pointer" @click="router.push('/')"> |
||||
<el-icon><Platform /></el-icon> |
||||
<span>我的大屏</span> |
||||
</a> |
||||
<a class="flex v-center center wrap pointer" @click="router.push('/')"> |
||||
<el-icon><Menu /></el-icon> |
||||
<span>我的工作</span> |
||||
</a> |
||||
<a class="flex v-center center wrap pointer" @click="router.push('/')"> |
||||
<el-icon><HomeFilled /></el-icon> |
||||
<span>来信初筛</span> |
||||
</a> |
||||
<a class="flex v-center center wrap pointer" @click="router.push('/')"> |
||||
<el-icon><HomeFilled /></el-icon> |
||||
<span>数据分析</span> |
||||
</a> |
||||
<a class="flex v-center center wrap pointer" @click="router.push('/')"> |
||||
<el-icon><Setting /></el-icon> |
||||
<span>系统管理</span> |
||||
</a> |
||||
</nav> |
||||
</aside> |
||||
<main><router-view /></main> |
||||
</div> |
||||
</template> |
||||
<script setup> |
||||
import { HomeFilled, Platform, Setting, Menu } from '@element-plus/icons-vue' |
||||
|
||||
import { useRouter } from "vue-router"; |
||||
|
||||
const router = useRouter(); |
||||
|
||||
</script> |
||||
<style lang="scss" scoped> |
||||
:root { |
||||
--header-height: 80px; |
||||
} |
||||
header { |
||||
background-color: #162582; |
||||
color: #fff; |
||||
height: var(--header-height); |
||||
padding: 0 20px; |
||||
.title { |
||||
font-size: 28px; |
||||
a { |
||||
text-decoration: none; |
||||
color: inherit; |
||||
} |
||||
} |
||||
} |
||||
aside { |
||||
background-color: #071254; |
||||
color: #fff; |
||||
width: 100px; |
||||
height: calc(100vh - var(--header-height)); |
||||
nav { |
||||
a { |
||||
height: 100px; |
||||
color: #707ab6; |
||||
&:hover { |
||||
color: #fff; |
||||
} |
||||
.el-icon { |
||||
font-size: 50px; |
||||
|
||||
} |
||||
span { |
||||
width: 100%; |
||||
text-align: center; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
||||
@ -0,0 +1,14 @@
|
||||
import { createApp } from 'vue' |
||||
import router from './router/index' |
||||
import { createPinia } from 'pinia' |
||||
|
||||
import App from './App.vue' |
||||
import IconComponent from '@/components/Icon.vue' |
||||
|
||||
import './assets/style/style.scss' |
||||
|
||||
createApp(App) |
||||
.use(router) |
||||
.use(createPinia()) |
||||
.component('Icon', IconComponent) |
||||
.mount('#app') |
||||
@ -0,0 +1,37 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router' |
||||
|
||||
import Home from '@/views/Home.vue' |
||||
|
||||
import Layout from '@/layout/Index.vue' |
||||
|
||||
import NotFound from '@/views/error/404.vue' |
||||
|
||||
const constantRoutes = [ |
||||
{ |
||||
path: '/layout', |
||||
component: Layout, |
||||
redirect: to => { |
||||
return '/' |
||||
}, |
||||
children: [ |
||||
{ |
||||
path: '/', |
||||
component: Home |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
path: '/:catchAll(.*)', |
||||
component: NotFound, |
||||
meta: { |
||||
title: '404' |
||||
} |
||||
} |
||||
]; |
||||
|
||||
const router = createRouter({ |
||||
history: createWebHashHistory(), |
||||
routes: constantRoutes |
||||
}); |
||||
|
||||
export default router; |
||||
@ -0,0 +1,54 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<h1>首页</h1> |
||||
<h2>按钮</h2> |
||||
<el-row class="mb-4"> |
||||
<el-button>Default</el-button> |
||||
<el-button type="primary">Primary</el-button> |
||||
<el-button type="success">Success</el-button> |
||||
<el-button type="info">Info</el-button> |
||||
<el-button type="warning">Warning</el-button> |
||||
<el-button type="danger">Danger</el-button> |
||||
</el-row> |
||||
|
||||
<el-row class="mb-4"> |
||||
<el-button plain>Plain</el-button> |
||||
<el-button type="primary" plain>Primary</el-button> |
||||
<el-button type="success" plain>Success</el-button> |
||||
<el-button type="info" plain>Info</el-button> |
||||
<el-button type="warning" plain>Warning</el-button> |
||||
<el-button type="danger" plain>Danger</el-button> |
||||
</el-row> |
||||
|
||||
<el-row class="mb-4"> |
||||
<el-button round>Round</el-button> |
||||
<el-button type="primary" round>Primary</el-button> |
||||
<el-button type="success" round>Success</el-button> |
||||
<el-button type="info" round>Info</el-button> |
||||
<el-button type="warning" round>Warning</el-button> |
||||
<el-button type="danger" round>Danger</el-button> |
||||
</el-row> |
||||
|
||||
<el-row> |
||||
<el-button :icon="Search" circle /> |
||||
<el-button type="primary" :icon="Edit" circle /> |
||||
<el-button type="success" :icon="Check" circle /> |
||||
<el-button type="info" :icon="Message" circle /> |
||||
<el-button type="warning" :icon="Star" circle /> |
||||
<el-button type="danger" :icon="Delete" circle /> |
||||
</el-row> |
||||
</div> |
||||
</template> |
||||
<script setup> |
||||
import { useRouter } from "vue-router"; |
||||
|
||||
const router = useRouter(); |
||||
</script> |
||||
<style lang="scss" scoped> |
||||
.container { |
||||
padding: 20px; |
||||
} |
||||
.el-row { |
||||
margin-bottom: 20px; |
||||
} |
||||
</style> |
||||
@ -0,0 +1,9 @@
|
||||
<template> |
||||
<h1>404</h1> |
||||
</template> |
||||
<script setup> |
||||
|
||||
</script> |
||||
<style lang="scss" scoped> |
||||
|
||||
</style> |
||||
@ -0,0 +1,54 @@
|
||||
import { defineConfig } from 'vite' |
||||
import vue from '@vitejs/plugin-vue' |
||||
import path from 'path' |
||||
|
||||
import AutoImport from 'unplugin-auto-import/vite' |
||||
import Components from 'unplugin-vue-components/vite' |
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' |
||||
|
||||
import svgLoader from 'vite-svg-loader' |
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({ |
||||
plugins: [ |
||||
vue(), |
||||
svgLoader(), |
||||
AutoImport({ |
||||
imports: [ |
||||
'vue' |
||||
], |
||||
resolvers: [ElementPlusResolver()], |
||||
}), |
||||
Components({ |
||||
resolvers: [ElementPlusResolver({ |
||||
importStyle: "sass" |
||||
})], |
||||
}), |
||||
], |
||||
resolve: { |
||||
// https://cn.vitejs.dev/config/#resolve-alias
|
||||
alias: { |
||||
// 设置别名
|
||||
'~/': `${path.resolve(__dirname, 'src')}/`, |
||||
'@': path.resolve(__dirname, './src/') |
||||
}, |
||||
// https://cn.vitejs.dev/config/#resolve-extensions
|
||||
extensions: ['.js'] |
||||
}, |
||||
css: { |
||||
preprocessorOptions: { |
||||
scss: { |
||||
additionalData: `@use "src/assets/style/element.scss" as *;` |
||||
}, |
||||
}, |
||||
}, |
||||
server: { |
||||
host: '0.0.0.0', |
||||
proxy: { |
||||
'/api': { |
||||
target: 'http://127.0.0.1:8081', |
||||
changeOrigin: true, |
||||
rewrite: (p) => p.replace(/^\/api/, '') |
||||
} |
||||
} |
||||
} |
||||
}) |
||||
Loading…
Reference in new issue