master
parent
3bccecd710
commit
9a4f8bcc5f
@ -0,0 +1,30 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none"
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"Vue.volar",
|
||||
"Vue.vscode-typescript-vue-plugin",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
# bingwu-admin
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
pnpm build
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
pnpm lint
|
||||
```
|
||||
|
||||
# 参考项目
|
||||
|
||||
vben:[GitHub地址](https://github.com/vbenjs/vue-vben-admin)
|
||||
|
||||
vue-element-admin:[GitHub地址](https://github.com/PanJiaChen/vue-element-admin)
|
||||
|
||||
ruo-yi:[GitHub地址](https://github.com/yangzongzhuan/RuoYi-Vue3)
|
@ -0,0 +1,61 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AvatarCom: typeof import('./src/components/AvatarCom.vue')['default']
|
||||
BaseTableCom: typeof import('./src/components/table/BaseTableCom.vue')['default']
|
||||
CollapseAsideCom: typeof import('./src/components/utils/CollapseAsideCom.vue')['default']
|
||||
DarkSwitchCom: typeof import('./src/components/utils/DarkSwitchCom.vue')['default']
|
||||
ElAside: typeof import('element-plus/es')['ElAside']
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
|
||||
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
||||
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElImage: typeof import('element-plus/es')['ElImage']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElMain: typeof import('element-plus/es')['ElMain']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElProgress: typeof import('element-plus/es')['ElProgress']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
ExportExcelCom: typeof import('./src/components/excel/ExportExcelCom.vue')['default']
|
||||
ImportExcelCom: typeof import('./src/components/excel/ImportExcelCom.vue')['default']
|
||||
MyEcharts: typeof import('./src/components/echarts/MyEcharts.vue')['default']
|
||||
PreviewPictureCom: typeof import('./src/components/PreviewPictureCom.vue')['default']
|
||||
ProgressCom: typeof import('./src/components/progress/ProgressCom.vue')['default']
|
||||
ProgressLiteCom: typeof import('./src/components/progress/ProgressLiteCom.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SettingCom: typeof import('./src/components/SettingCom.vue')['default']
|
||||
SwitchLanguageCom: typeof import('./src/components/utils/SwitchLanguageCom.vue')['default']
|
||||
UploadFileCom: typeof import('./src/components/file/UploadFileCom.vue')['default']
|
||||
}
|
||||
export interface ComponentCustomProperties {
|
||||
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-04-10 16:15:37
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-04-11 17:08:12
|
||||
* @FilePath: \app\index.html
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_4503951_gwy78199vxn.css">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>bingwu-admin</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "bingwu-admin",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@vueuse/core": "^10.7.2",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"axios": "^1.6.7",
|
||||
"cos-js-sdk-v5": "^1.6.0",
|
||||
"echarts": "^5.4.3",
|
||||
"element-plus": "^2.5.3",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"vue": "^3.3.11",
|
||||
"vue-i18n": "^9.9.0",
|
||||
"vue-router": "^4.2.5",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.3.3",
|
||||
"@vitejs/plugin-vue": "^4.5.2",
|
||||
"@vue/eslint-config-prettier": "^8.0.0",
|
||||
"eslint": "^8.49.0",
|
||||
"eslint-plugin-vue": "^9.17.0",
|
||||
"prettier": "^3.0.3",
|
||||
"sass": "^1.70.0",
|
||||
"unplugin-auto-import": "^0.17.3",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.0.10"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,45 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-20 23:24:08
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-23 23:18:53
|
||||
* @FilePath: \bingwu-admin\src\App.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
import en from 'element-plus/dist/locale/en.mjs'
|
||||
import { RouterView } from 'vue-router'
|
||||
import { getStateStore } from './stores'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const myLocale = useI18n().locale
|
||||
const stateStore = getStateStore()
|
||||
myLocale.value = stateStore.currentLang
|
||||
// 控制element组件的语言
|
||||
const langArr = ref([
|
||||
{
|
||||
lang: 'zh-cn',
|
||||
locale: zhCn
|
||||
},
|
||||
{
|
||||
lang: 'en-us',
|
||||
locale: en
|
||||
}
|
||||
])
|
||||
const locale = computed(() => {
|
||||
const item = langArr.value.find(
|
||||
(item) => item.lang === stateStore.currentLang
|
||||
)
|
||||
return item.locale
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-config-provider :locale="locale">
|
||||
<RouterView />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -0,0 +1,10 @@
|
||||
import http from '@/utils/http'
|
||||
|
||||
const getUser = () => {
|
||||
return http.get('/user/get', {
|
||||
params: {
|
||||
_id: '66136094633f0524859aa797'
|
||||
}
|
||||
})
|
||||
}
|
||||
export { getUser }
|
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 202 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 276 B |
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="avatar">
|
||||
<div class="left">
|
||||
<el-avatar
|
||||
:size="28"
|
||||
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
|
||||
/>
|
||||
<el-dropdown trigger="click">
|
||||
<span class="el-dropdown-link">
|
||||
<el-icon class="el-icon--right"><CaretBottom /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item icon="Plus">Action 1</el-dropdown-item>
|
||||
<el-dropdown-item icon="CirclePlusFilled">
|
||||
Action 2
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="CirclePlus">Action 3</el-dropdown-item>
|
||||
<el-dropdown-item icon="Check">Action 4</el-dropdown-item>
|
||||
<el-dropdown-item icon="CircleCheck">Action 5</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.avatar {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 14px 0 12px;
|
||||
}
|
||||
:deep(.el-dropdown) {
|
||||
transform: translateY(15px);
|
||||
}
|
||||
</style>
|
@ -0,0 +1,113 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-17 16:40:17
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-25 16:52:35
|
||||
* @FilePath: \vue-movie\bingwu-admin\src\components\PreviewPictureCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="preview-picture">
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
:show-file-list="false"
|
||||
:auto-upload="false"
|
||||
:on-change="uploaderFile"
|
||||
>
|
||||
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
// 图片的base64编码
|
||||
const imageUrl = ref('')
|
||||
// 图片文件
|
||||
const file = ref(null)
|
||||
const uploaderFile = async (imagefile) => {
|
||||
file.value = imagefile
|
||||
await fileToBase64(imagefile)
|
||||
.then((base64Url) => {
|
||||
imageUrl.value = base64Url
|
||||
})
|
||||
.catch((error) => {
|
||||
ElMessage.error(error)
|
||||
})
|
||||
}
|
||||
|
||||
const fileToBase64 = (imagefile) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
reader.readAsDataURL(imagefile.raw)
|
||||
reader.onload = () => {
|
||||
const base64Url = reader.result
|
||||
|
||||
resolve(base64Url)
|
||||
}
|
||||
// 加载失败时
|
||||
reader.onerror = function () {
|
||||
reject(new Error('Failed to load file'))
|
||||
}
|
||||
})
|
||||
}
|
||||
// 获取和设置图片的url
|
||||
const imageUrlFn = () => {
|
||||
return {
|
||||
getImageUrl() {
|
||||
return imageUrl
|
||||
},
|
||||
setImageUrl(newImageUrl) {
|
||||
imageUrl.value = newImageUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取和设置文件
|
||||
const fileFn = () => {
|
||||
return {
|
||||
getFile() {
|
||||
return file
|
||||
},
|
||||
setFile(newFile) {
|
||||
file.value = newFile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
imageUrlFn,
|
||||
fileFn
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.avatar-uploader .avatar) {
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
:deep(.avatar-uploader .el-upload) {
|
||||
border: 1px dashed var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
}
|
||||
|
||||
:deep(.avatar-uploader .el-upload:hover) {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
:deep(.el-icon.avatar-uploader-icon) {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,30 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-24 18:02:40
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-29 18:51:38
|
||||
* @FilePath: \bingwu-admin\src\components\SettingCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="setting">
|
||||
<el-dropdown trigger="click">
|
||||
<el-icon :size="20"><Setting /></el-icon>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>
|
||||
<span style="margin-right: 8px">黑暗模式</span>
|
||||
<DarkSwitchCom></DarkSwitchCom>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import DarkSwitchCom from '@/components/utils/DarkSwitchCom.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,121 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-30 22:31:39
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-31 23:06:46
|
||||
* @FilePath: \bingwu-admin\src\components\excel\ExportExcelCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="export-excel">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="Download"
|
||||
@click="
|
||||
() => {
|
||||
formData.fileName = ''
|
||||
formData.fileExtension = ''
|
||||
dialogVisible = true
|
||||
}
|
||||
"
|
||||
>导出文件</el-button
|
||||
>
|
||||
|
||||
<el-dialog v-model="dialogVisible" title="导出" width="30%">
|
||||
<el-form :model="formData" :rules="rules" ref="formRef">
|
||||
<el-form-item label="文件名称">
|
||||
<el-input
|
||||
v-model="formData.fileName"
|
||||
placeholder="默认为excelFile"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件后缀" prop="fileExtension">
|
||||
<el-select
|
||||
v-model="formData.fileExtension"
|
||||
placeholder="请选择文件后缀"
|
||||
clearable
|
||||
>
|
||||
<el-option label="xlsx" value="xlsx" />
|
||||
<el-option label="xls" value="xls" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm"> 确认 </el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 把数组对象数据转化为xlsx文件的时候用
|
||||
import { utils, writeFileXLSX } from 'xlsx'
|
||||
import { ref, reactive } from 'vue'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
|
||||
const emits = defineEmits(['handleExportData'])
|
||||
|
||||
const formData = reactive({
|
||||
fileName: '',
|
||||
fileExtension: ''
|
||||
})
|
||||
|
||||
const formRef = ref(null)
|
||||
|
||||
const rules = ref({
|
||||
fileExtension: [
|
||||
{ required: true, message: '请选择文件后缀', trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
|
||||
const handleConfirm = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
emits(
|
||||
'handleExportData',
|
||||
exportFile,
|
||||
formData.fileName,
|
||||
formData.fileExtension
|
||||
)
|
||||
// exportFile(props.exportData, formData.fileName, formData.fileExtension)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 自定义excel导出函数
|
||||
const exportFile = (exportData, fileName, fileExtension) => {
|
||||
if (exportData.length === 0) {
|
||||
ElMessage({
|
||||
showClose: true,
|
||||
message: '没有要导出的数据',
|
||||
type: 'error'
|
||||
})
|
||||
} else {
|
||||
if (!fileName) {
|
||||
fileName = 'excelFile'
|
||||
}
|
||||
// utils.json_to_sheet(参数) 参数为数组对象
|
||||
const ws = utils.json_to_sheet(exportData)
|
||||
const wb = utils.book_new()
|
||||
// utils.book_append_sheet(参数1, 参数2, 参数3)
|
||||
// 参数1 为 utils.json_to_sheet(arr) 返回的对象
|
||||
// 参数2 为 utils.book_new() 返回的对象
|
||||
// 参数3 为 工作表的名称
|
||||
utils.book_append_sheet(wb, ws, 'Data')
|
||||
// writeFileXLSX(参数1, 参数2)
|
||||
// 参数1 为 utils.book_new() 返回的对象
|
||||
// 参数2 为 导出的excel的文件名 后缀为xlsx 例如: 'abc.xlsx' '好看的.xlsx'
|
||||
writeFileXLSX(wb, `${fileName}.${fileExtension}`)
|
||||
dialogVisible.value = !dialogVisible.value
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,115 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-30 22:31:26
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-31 21:31:30
|
||||
* @FilePath: \bingwu-admin\src\components\excel\ImportExcelCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="import-excel">
|
||||
<UploadFileCom
|
||||
ref="uploadFileComRef"
|
||||
accept=".xls,.xlsx"
|
||||
@handleConfirm="handleImport"
|
||||
>
|
||||
<template #tip>文件格式要求为xls,xlsx</template>
|
||||
</UploadFileCom>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 把数组对象数据转化为xlsx文件的时候用
|
||||
// import { utils, writeFileXLSX } from 'xlsx'
|
||||
// 把xslx文件转化为json数据的时候用
|
||||
import XLSX from 'xlsx'
|
||||
import UploadFileCom from '@/components/file/UploadFileCom.vue'
|
||||
import { ref } from 'vue'
|
||||
const uploadFileComRef = ref(null)
|
||||
const emits = defineEmits(['importData'])
|
||||
const handleImport = async (selectFiles) => {
|
||||
if (selectFiles.length === 0) {
|
||||
ElMessage.error('导入失败,当前没有要导入的文件')
|
||||
} else {
|
||||
let existErrorFileType = false
|
||||
selectFiles.forEach((item) => {
|
||||
let fileExtension = item.raw.name.substring(
|
||||
item.raw.name.lastIndexOf('.') + 1
|
||||
)
|
||||
if (!(fileExtension === 'xlsx' || fileExtension === 'xls')) {
|
||||
existErrorFileType = true
|
||||
}
|
||||
})
|
||||
if (existErrorFileType) {
|
||||
ElMessage.error('导入失败,存在格式不为xls/xlsx的文件类型')
|
||||
} else {
|
||||
// 此处转换文件里的数据
|
||||
const excelFilesData = await getFilesDataSync(selectFiles)
|
||||
emits('importData', excelFilesData)
|
||||
uploadFileComRef.value.offDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const readFileSync = (file) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
reader.readAsBinaryString(file.raw)
|
||||
reader.onload = (event) => {
|
||||
resolve(event.target.result)
|
||||
}
|
||||
|
||||
reader.onerror = (event) => {
|
||||
reject(event.target.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getFilesDataSync = async (selectFiles) => {
|
||||
let excelFilesData = []
|
||||
|
||||
for (const file of selectFiles) {
|
||||
try {
|
||||
const data = await readFileSync(file)
|
||||
const excelData = XLSX.read(data, { type: 'binary' })
|
||||
const wsname = excelData.SheetNames[0]
|
||||
const content = XLSX.utils.sheet_to_json(excelData.Sheets[wsname])
|
||||
excelFilesData = excelFilesData.concat(content)
|
||||
} catch (error) {
|
||||
console.error('Error reading file:', error)
|
||||
}
|
||||
}
|
||||
|
||||
return excelFilesData
|
||||
}
|
||||
|
||||
// const getFilesData = (selectFiles) => {
|
||||
// let excelFilesData = []
|
||||
// selectFiles.forEach(async (file) => {
|
||||
// // 创建fileReader对象
|
||||
// const reader = new FileReader()
|
||||
// // 读取文件属性
|
||||
// reader.readAsBinaryString(file.raw)
|
||||
// reader.onload = (re) => {
|
||||
// // 获取到二进制的文件
|
||||
// const data = re.target.result
|
||||
// // 解析二进制的xlsx文件
|
||||
// const excelData = XLSX.read(data, {
|
||||
// type: 'binary'
|
||||
// })
|
||||
// // 下标0 表示 拿到excel文件里的第一张表
|
||||
// // wsname 为表名
|
||||
// const wsname = excelData.SheetNames[0]
|
||||
// console.log('wsname', wsname)
|
||||
// const content = XLSX.utils.sheet_to_json(excelData.Sheets[wsname])
|
||||
// excelFilesData = excelFilesData.concat(content)
|
||||
// console.log('11111', excelFilesData)
|
||||
// }
|
||||
// })
|
||||
|
||||
// return excelFilesData
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,90 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-30 22:31:39
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-26 17:42:24
|
||||
* @FilePath: \bingwu-admin\src\components\file\UploadFileCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="export-file">
|
||||
<el-button type="primary" icon="Upload" @click="dialogVisible = true">
|
||||
上传文件
|
||||
</el-button>
|
||||
|
||||
<el-dialog v-model="dialogVisible" title="上传文件" width="30%">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:on-change="
|
||||
(_, files) => {
|
||||
selectFiles = files
|
||||
}
|
||||
"
|
||||
drag
|
||||
:accept="props.accept"
|
||||
>
|
||||
<el-icon size="30"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处或 <em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="tip"><slot name="tip"></slot></div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
emits('handleConfirm', selectFiles)
|
||||
}
|
||||
"
|
||||
>
|
||||
确认
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
const selectFiles = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const uploadRef = ref(null)
|
||||
const emits = defineEmits(['handleConfirm'])
|
||||
const getSelectFiles = () => {
|
||||
return selectFiles.value
|
||||
}
|
||||
const props = defineProps({
|
||||
// 文件上传类型 默认为所有类型
|
||||
accept: {
|
||||
type: String
|
||||
}
|
||||
})
|
||||
// 清空文件
|
||||
const clearFiles = () => {
|
||||
selectFiles.value = []
|
||||
uploadRef.value.clearFiles()
|
||||
}
|
||||
const offDialog = () => {
|
||||
dialogVisible.value = !dialogVisible.value
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getSelectFiles,
|
||||
offDialog,
|
||||
clearFiles
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.export-file {
|
||||
width: 20%;
|
||||
.tip {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="progress-lite">
|
||||
<!-- 假性进度条组件 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="上传中"
|
||||
width="500"
|
||||
:show-close="false"
|
||||
>
|
||||
<div class="demo-progress">
|
||||
<template v-if="props.progressType.type1">
|
||||
<el-progress
|
||||
:percentage="percentage"
|
||||
:stroke-width="22"
|
||||
striped
|
||||
:status="status"
|
||||
:duration="80"
|
||||
striped-flow
|
||||
:text-inside="true"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="props.progressType.type2">
|
||||
<el-progress
|
||||
:percentage="percentage"
|
||||
:indeterminate="true"
|
||||
:status="status"
|
||||
:stroke-width="16"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="props.progressType.type3"
|
||||
><el-progress
|
||||
type="dashboard"
|
||||
:percentage="percentage"
|
||||
:status="status"
|
||||
>
|
||||
<template #default="{ percentage }">
|
||||
<span class="percentage-value">{{ percentage }}%</span>
|
||||
</template>
|
||||
</el-progress></template
|
||||
>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useProgress } from '@/hooks/progress'
|
||||
const props = defineProps({
|
||||
// 进度条类型
|
||||
progressType: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
type1: true,
|
||||
type2: false,
|
||||
type3: false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const {
|
||||
percentage,
|
||||
status,
|
||||
dialogVisible,
|
||||
changePercentage,
|
||||
offProgress,
|
||||
openProgress
|
||||
} = useProgress()
|
||||
|
||||
defineExpose({
|
||||
changePercentage,
|
||||
offProgress,
|
||||
openProgress
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div class="progress-lite">
|
||||
<!-- 假性进度条组件 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="上传中"
|
||||
width="500"
|
||||
:show-close="false"
|
||||
>
|
||||
<div class="demo-progress">
|
||||
<template v-if="props.progressType.type1">
|
||||
<el-progress
|
||||
:percentage="percentage"
|
||||
:stroke-width="22"
|
||||
striped
|
||||
:status="status"
|
||||
:duration="80"
|
||||
striped-flow
|
||||
:text-inside="true"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="props.progressType.type2">
|
||||
<el-progress
|
||||
:percentage="percentage"
|
||||
:indeterminate="true"
|
||||
:status="status"
|
||||
:stroke-width="16"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="props.progressType.type3"
|
||||
><el-progress
|
||||
type="dashboard"
|
||||
:percentage="percentage"
|
||||
:status="status"
|
||||
>
|
||||
<template #default="{ percentage }">
|
||||
<span class="percentage-value">{{ percentage }}%</span>
|
||||
</template>
|
||||
</el-progress></template
|
||||
>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 假性进度条组件
|
||||
import { ref } from 'vue'
|
||||
const percentage = ref(0)
|
||||
const status = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const props = defineProps({
|
||||
// 最开始的累加时间间隔
|
||||
time: {
|
||||
type: Number,
|
||||
default: 1000
|
||||
},
|
||||
// 每次累加量(最好是能被100整除)
|
||||
increment: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
// 进度条类型
|
||||
progressType: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
type1: true,
|
||||
type2: false,
|
||||
type3: false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const start = () => {
|
||||
percentage.value = 0
|
||||
status.value = ''
|
||||
dialogVisible.value = true
|
||||
const startWork = setInterval(() => {
|
||||
// 做累加之前判断一下percentage的值 大于等于100直接赋值为99
|
||||
percentage.value =
|
||||
percentage.value + props.increment >= 100
|
||||
? 100
|
||||
: percentage.value + props.increment
|
||||
}, props.time)
|
||||
return startWork
|
||||
}
|
||||
|
||||
const end = async (startWork, newState = 'success', message = '上传成功') => {
|
||||
clearInterval(startWork)
|
||||
if (newState == 'success') {
|
||||
// 做累加
|
||||
const endWork = setInterval(() => {
|
||||
if (percentage.value >= 100) {
|
||||
percentage.value = 100
|
||||
clearInterval(endWork)
|
||||
status.value = 'success'
|
||||
ElMessage({
|
||||
message,
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
// 做累加之前判断一下percentage的值 大于等于100直接赋值为100
|
||||
percentage.value =
|
||||
percentage.value + props.increment >= 100
|
||||
? 100
|
||||
: percentage.value + props.increment
|
||||
}, 80)
|
||||
} else {
|
||||
// 上传失败
|
||||
ElMessage.error(`${message}`)
|
||||
status.value = 'exception'
|
||||
}
|
||||
// 隐藏进度条
|
||||
setTimeout(() => {
|
||||
dialogVisible.value = false
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
start,
|
||||
end
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<div class="base-table">
|
||||
<el-table
|
||||
:data="props.tableData"
|
||||
v-loading="tableLoading"
|
||||
@selection-change="handleSelectionChange"
|
||||
ref="tableRef"
|
||||
>
|
||||
<el-table-column type="selection" width="55" v-if="props.showSelect" />
|
||||
<el-table-column
|
||||
v-for="(item, index) in props.columnData"
|
||||
:prop="item.prop"
|
||||
:label="item.label"
|
||||
:key="index"
|
||||
:width="item.width"
|
||||
:sortable="item.sortable"
|
||||
>
|
||||
<!-- tag列 -->
|
||||
<template #default="{ row }" v-if="item?.tagColumn">
|
||||
<el-tag :type="row[item.prop].tagType">{{
|
||||
row[item.prop].tagName
|
||||
}}</el-tag>
|
||||
</template>
|
||||
<!-- 图片列 -->
|
||||
<template #default="{ row }" v-else-if="item?.pictureColumn">
|
||||
<el-image
|
||||
style="
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
:src="row[item.prop]"
|
||||
fit
|
||||
lazy
|
||||
>
|
||||
<template #error>
|
||||
<el-icon size="30"><Picture /></el-icon>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
<!-- 开关列 -->
|
||||
<template #default="{ row }" v-else-if="item?.switchColumn">
|
||||
<el-switch
|
||||
v-model="row[item.prop]"
|
||||
size="large"
|
||||
:loading="switchLoading"
|
||||
:before-change="beforeSwitchChange"
|
||||
@change="
|
||||
(switchState) => {
|
||||
emits('updateSwitchState', switchState)
|
||||
}
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 操作列 -->
|
||||
<el-table-column label="操作" v-if="props?.dropdownData">
|
||||
<template #default="{ row }">
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
@command="
|
||||
(command) => {
|
||||
handleCommand(command, row)
|
||||
}
|
||||
"
|
||||
>
|
||||
<el-button type="primary" icon="Operation">操作 </el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<template
|
||||
v-for="(item, index) in props.dropdownData"
|
||||
:key="index"
|
||||
>
|
||||
<!-- 权限控制 item.auth-->
|
||||
<div v-permission="item.auth">
|
||||
<el-dropdown-item
|
||||
:command="item.command"
|
||||
:icon="item.icon"
|
||||
>{{ item.actionName }}</el-dropdown-item
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #empty>
|
||||
<el-empty description="没有数据" />
|
||||
</template>
|
||||
</el-table>
|
||||
<div class="pagination" v-if="props.showPagination">
|
||||
<el-pagination
|
||||
v-model:current-page="paginationData.currentPage"
|
||||
v-model:page-size="paginationData.pageSize"
|
||||
:page-sizes="props.pageSizes"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="props.total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useTable } from '@/hooks/table'
|
||||
const props = defineProps({
|
||||
columnData: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [
|
||||
{
|
||||
prop: 'columnProp1',
|
||||
label: '列1',
|
||||
width: '100'
|
||||
},
|
||||
{
|
||||
prop: 'columnProp2',
|
||||
label: '列2',
|
||||
width: '100'
|
||||
},
|
||||
{
|
||||
prop: 'columnProp3',
|
||||
label: '列3',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
prop: 'columnProp4',
|
||||
label: '列4'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
tableData: {
|
||||
type: Array
|
||||
},
|
||||
dropdownData: {
|
||||
type: Array
|
||||
},
|
||||
// 开关状态改变时的弹窗内容
|
||||
messageBoxContent: {
|
||||
type: String,
|
||||
default: '默认内容'
|
||||
},
|
||||
// 开关状态改变时的弹窗标题
|
||||
messageBoxTitle: {
|
||||
type: String,
|
||||
default: '默认标题'
|
||||
},
|
||||
// 显示多选行
|
||||
showSelect: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 当前页的数据容量
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [5, 10, 15]
|
||||
}
|
||||
},
|
||||
// 表格的数据总数
|
||||
total: {
|
||||
type: Number
|
||||
},
|
||||
// 是否显示分页
|
||||
showPagination: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const tableRef = ref(null)
|
||||
const emits = defineEmits(['updateSwitchState'], ['updateTableData'])
|
||||
const {
|
||||
tableLoading,
|
||||
switchLoading,
|
||||
changeTableLoading,
|
||||
changeSwitchLoading,
|
||||
beforeSwitchChange,
|
||||
handleCommand,
|
||||
paginationData,
|
||||
handleCurrentChange,
|
||||
handleSizeChange
|
||||
} = useTable(props, emits)
|
||||
const getSelectRows = () => {
|
||||
return tableRef.value.getSelectionRows()
|
||||
}
|
||||
const getPaginationData = () => {
|
||||
return paginationData.value
|
||||
}
|
||||
defineExpose({
|
||||
changeTableLoading,
|
||||
changeSwitchLoading,
|
||||
getSelectRows,
|
||||
getPaginationData
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.base-table {
|
||||
.pagination {
|
||||
margin-top: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 18:29:12
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-10 21:46:46
|
||||
* @FilePath: \bingwu-admin\src\components\utils\CollapseAsideCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="collapse-aside" @click="stateStore.updateCollapse">
|
||||
<el-icon :size="20" v-if="stateStore.isCollapse"><Expand /></el-icon>
|
||||
<el-icon :size="20" v-else><Fold /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getStateStore } from '@/stores/index'
|
||||
const stateStore = getStateStore()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,38 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 17:57:13
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-23 18:24:27
|
||||
* @FilePath: \bingwu-admin\src\components\utils\DarkSwitchCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="dark-switch">
|
||||
<el-switch
|
||||
v-model="switchState"
|
||||
style="--el-switch-on-color: #2c2c2c"
|
||||
@change="toggleDark"
|
||||
size="large"
|
||||
>
|
||||
<template #active-action>
|
||||
<el-icon><Moon /></el-icon>
|
||||
</template>
|
||||
<template #inactive-action>
|
||||
<el-icon><Sunny /></el-icon>
|
||||
</template>
|
||||
</el-switch>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Moon, Sunny } from '@element-plus/icons-vue'
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
import { ref } from 'vue'
|
||||
const toggleDark = useToggle(useDark())
|
||||
const switchState = ref(false)
|
||||
const colorName = localStorage.getItem('vueuse-color-scheme')
|
||||
switchState.value = colorName === 'light' ? false : true
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,38 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 21:13:17
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-10 23:52:44
|
||||
* @FilePath: \bingwu-admin\src\components\utils\SwitchLanguageCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="switch-language">
|
||||
<el-dropdown trigger="click" @command="changeLang">
|
||||
<el-icon> <i class="icon iconfont icon-yuyan1"></i></el-icon>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="zh-cn">中文</el-dropdown-item>
|
||||
<el-dropdown-item command="en-us">English</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getStateStore } from '@/stores'
|
||||
const stateStore = getStateStore()
|
||||
const changeLang = (lang) => {
|
||||
stateStore.updateCurrentLang(lang)
|
||||
// 刷新页面更换语言
|
||||
location.reload()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.switch-language {
|
||||
margin-right: 12px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-03-27 00:33:27
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-03-27 00:37:44
|
||||
* @FilePath: \bingwu-admin\src\hooks\progress.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
import { ref } from 'vue'
|
||||
export const useProgress = () => {
|
||||
const percentage = ref(0)
|
||||
const status = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const changePercentage = (newPercentage) => {
|
||||
percentage.value = newPercentage
|
||||
}
|
||||
const offProgress = (newState = 'success', message = '上传成功') => {
|
||||
setTimeout(() => {
|
||||
dialogVisible.value = false
|
||||
}, 1200)
|
||||
if (newState === 'success') {
|
||||
status.value = 'success'
|
||||
ElMessage({
|
||||
message,
|
||||
type: 'success'
|
||||
})
|
||||
} else {
|
||||
ElMessage.error(`${message}`)
|
||||
status.value = 'exception'
|
||||
}
|
||||
}
|
||||
const openProgress = () => {
|
||||
status.value = ''
|
||||
percentage.value = 0
|
||||
dialogVisible.value = true
|
||||
}
|
||||
return {
|
||||
percentage,
|
||||
status,
|
||||
dialogVisible,
|
||||
changePercentage,
|
||||
offProgress,
|
||||
openProgress
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 22:17:57
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-23 22:45:53
|
||||
* @FilePath: \bingwu-admin\src\language\index.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import zhCN from './locales/zh-CN'
|
||||
import enUS from './locales/en-US'
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh-cn', // 默认显示语言
|
||||
messages: {
|
||||
'zh-cn': zhCN,
|
||||
'en-us': enUS
|
||||
}
|
||||
})
|
||||
|
||||
export default i18n
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 22:17:32
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-23 22:17:40
|
||||
* @FilePath: \bingwu-admin\src\language\locales\en_US.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
export default {
|
||||
common: {
|
||||
more: 'Look More'
|
||||
},
|
||||
leftMenus: {
|
||||
'/': 'Home',
|
||||
Home: 'Home',
|
||||
home: 'Home'
|
||||
},
|
||||
headMenus: {
|
||||
subTitle: 'Organization service platform',
|
||||
userName: 'ZhangSan',
|
||||
name: 'name',
|
||||
menu1: 'international'
|
||||
},
|
||||
login: {
|
||||
personal_center: 'personal center',
|
||||
sign_out: 'sign out'
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 22:16:55
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-23 22:17:09
|
||||
* @FilePath: \bingwu-admin\src\language\locales\zh.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
export default {
|
||||
common: {
|
||||
more: '查看更多'
|
||||
},
|
||||
leftMenus: {
|
||||
'/': '首页',
|
||||
Home: '首页',
|
||||
home: '首页'
|
||||
},
|
||||
headMenus: {
|
||||
subTitle: '机构服务平台',
|
||||
userName: '张三',
|
||||
name: '姓名',
|
||||
menu1: '国际化'
|
||||
},
|
||||
login: {
|
||||
personal_center: '个人中心',
|
||||
sign_out: '退出'
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 03:50:29
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-03-28 17:44:22
|
||||
* @FilePath: \bingwu-admin\src\layout\IndexCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="index">
|
||||
<el-container>
|
||||
<el-aside style="width: auto">
|
||||
<AsideCom></AsideCom>
|
||||
</el-aside>
|
||||
<el-container style="height: 100vh">
|
||||
<el-header style="height: 6%">
|
||||
<HeaderCom></HeaderCom>
|
||||
</el-header>
|
||||
<el-divider style="margin: 0" />
|
||||
<el-main style="height: 94%">
|
||||
<main class="content">
|
||||
<RouterView />
|
||||
</main>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { RouterView } from 'vue-router'
|
||||
import HeaderCom from './components/HeaderCom.vue'
|
||||
import AsideCom from './components/AsideCom.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.index {
|
||||
.content {
|
||||
height: 100%;
|
||||
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
|
||||
padding: 30px;
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,238 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 03:46:33
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-16 20:57:57
|
||||
* @FilePath: \bingwu-admin\src\layout\components\AsideCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="aside">
|
||||
<el-menu
|
||||
style="height: 100%"
|
||||
:collapse="stateStore.isCollapse"
|
||||
active-text-color="#ffd04b"
|
||||
:default-active="$route.path"
|
||||
router
|
||||
>
|
||||
<!-- 静态侧边栏 -->
|
||||
<!-- <el-menu-item index="/home">
|
||||
<el-icon> <i class="icon iconfont icon-home"></i></el-icon>
|
||||
<template #title>首页</template>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="/rich-text">
|
||||
<el-icon> <i class="icon iconfont icon-fuwenben2"></i></el-icon>
|
||||
<template #title>富文本编辑器</template>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="/excel">
|
||||
<el-icon> <i class="icon iconfont icon-excel"></i></el-icon>
|
||||
<template #title>excel(导出/导入)</template>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="/file">
|
||||
<el-icon> <i class="icon iconfont icon-wenjian"></i></el-icon>
|
||||
<template #title>文件上传</template>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="/permission">
|
||||
<el-icon> <i class="icon iconfont icon-quanxian"></i></el-icon>
|
||||
<template #title>按钮权限管理</template>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="/international">
|
||||
<el-icon> <i class="icon iconfont icon-yuyan1"></i></el-icon>
|
||||
<template #title>国际化</template>
|
||||
</el-menu-item>
|
||||
|
||||
<el-sub-menu index="/error">
|
||||
<template #title>
|
||||
<el-icon> <i class="icon iconfont icon-cuowu"></i></el-icon>
|
||||
<span>错误页面</span>
|
||||
</template>
|
||||
<el-menu-item index="/error/not-find1">错误页面1</el-menu-item>
|
||||
<el-menu-item index="/error/not-find2">错误页面2</el-menu-item>
|
||||
<el-menu-item index="/error/not-find3">错误页面3</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-sub-menu index="/table">
|
||||
<template #title>
|
||||
<el-icon> <i class="icon iconfont icon-biaoge"></i></el-icon>
|
||||
<span>表格</span>
|
||||
</template>
|
||||
<el-menu-item index="/table/main-table1">表格1</el-menu-item>
|
||||
<el-menu-item index="/table/main-table2">表格2</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-sub-menu index="/menu">
|
||||
<template #title>
|
||||
<el-icon> <i class="icon iconfont icon-cuowu"></i></el-icon>
|
||||
<span>多级菜单</span>
|
||||
</template>
|
||||
<el-sub-menu>
|
||||
<template #title>菜单1</template>
|
||||
<el-menu-item index="/menu/menu-1-1">菜单1-1</el-menu-item>
|
||||
<el-menu-item index="menu-1-2">菜单1-2</el-menu-item>
|
||||
<el-sub-menu index="menu-1-3">
|
||||
<template #title>菜单1-3</template>
|
||||
<el-menu-item index="/menu/menu-1-1/menu-1-3-1"
|
||||
>菜单1-3-1</el-menu-item
|
||||
>
|
||||
<el-menu-item index="menu-1-3-2">菜单1-3-2</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</el-sub-menu>
|
||||
</el-sub-menu> -->
|
||||
<!-- 动态侧边栏 -->
|
||||
<template v-for="item in userStore.asideData" :key="item">
|
||||
<!-- 多级菜单 -->
|
||||
<el-sub-menu
|
||||
v-if="item.children && item.children.length > 0"
|
||||
:index="item.index"
|
||||
>
|
||||
<template #title>
|
||||
<el-icon><i :class="item.icon"></i></el-icon>
|
||||
<span>{{ item.name }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 开始循环遍历children -->
|
||||
<template v-for="child in item.children" :key="child">
|
||||
<!-- 如果是三级菜单 -->
|
||||
<template v-if="child.sons && child.sons.length > 0">
|
||||
<el-sub-menu :index="child.index">
|
||||
<template #title>{{ child.name }}</template>
|
||||
<!-- 三级菜单的item -->
|
||||
<el-menu-item
|
||||
v-for="son in child.sons"
|
||||
:key="son"
|
||||
:index="son.index"
|
||||
>{{ son.name }}</el-menu-item
|
||||
>
|
||||
</el-sub-menu></template
|
||||
>
|
||||
<!-- 二级菜单的item -->
|
||||
<template v-else>
|
||||
<el-menu-item :index="child.index">{{ child.name }}</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
</el-sub-menu>
|
||||
<!-- 单级 -->
|
||||
<el-menu-item v-else :index="item.index">
|
||||
<el-icon> <i :class="item.icon"></i></el-icon>
|
||||
<template #title>{{ item.name }}</template>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getStateStore, getUserStore } from '@/stores/index'
|
||||
const stateStore = getStateStore()
|
||||
const userStore = getUserStore()
|
||||
// const data = [
|
||||
// {
|
||||
// index: '/home',
|
||||
// icon: 'icon iconfont icon-home',
|
||||
// name: '首页'
|
||||
// },
|
||||
// {
|
||||
// index: '/rich-text',
|
||||
// icon: 'icon iconfont icon-fuwenben2',
|
||||
// name: '富文本编辑器'
|
||||
// },
|
||||
// {
|
||||
// index: '/excel',
|
||||
// icon: 'icon iconfont icon-excel',
|
||||
// name: 'excel(导出/导入)'
|
||||
// },
|
||||
// {
|
||||
// index: '/file',
|
||||
// icon: 'icon iconfont icon-wenjian',
|
||||
// name: '文件上传'
|
||||
// },
|
||||
// {
|
||||
// index: '/permission',
|
||||
// icon: 'icon iconfont icon-quanxian',
|
||||
// name: '按钮权限管理'
|
||||
// },
|
||||
// {
|
||||
// index: '/international',
|
||||
// icon: 'icon iconfont icon-yuyan1',
|
||||
// name: '国际化'
|
||||
// },
|
||||
// // 二级
|
||||
// {
|
||||
// index: '/table',
|
||||
// icon: 'icon iconfont icon-biaoge',
|
||||
// name: '表格',
|
||||
// children: [
|
||||
// {
|
||||
// index: '/table/main-table1',
|
||||
// name: '表格1'
|
||||
// },
|
||||
// {
|
||||
// index: '/table/main-table2',
|
||||
// name: '表格2'
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// // 二级
|
||||
// {
|
||||
// index: '/error',
|
||||
// icon: 'icon iconfont icon-cuowu',
|
||||
// name: '错误页面',
|
||||
// children: [
|
||||
// {
|
||||
// index: '/error/not-find1',
|
||||
// name: '错误页面1'
|
||||
// },
|
||||
// {
|
||||
// index: '/error/not-find2',
|
||||
// name: '错误页面2'
|
||||
// },
|
||||
// {
|
||||
// index: '/error/not-find3',
|
||||
// name: '错误页面3'
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// // 三级
|
||||
// {
|
||||
// index: '/menu',
|
||||
// icon: 'icon iconfont icon-caidan',
|
||||
// name: '多级菜单',
|
||||
// children: [
|
||||
// {
|
||||
// index: '/menu/menu-1-1',
|
||||
// name: '菜单1-1'
|
||||
// },
|
||||
// {
|
||||
// index: '/menu/menu-1-2',
|
||||
// name: '菜单1-2'
|
||||
// },
|
||||
// {
|
||||
// index: '/menu/menu-1-3',
|
||||
// name: '菜单1-3',
|
||||
// sons: [
|
||||
// {
|
||||
// index: '/menu/menu-1-1/menu-1-3-1',
|
||||
// name: '菜单1-3-1'
|
||||
// },
|
||||
// {
|
||||
// index: '/menu/menu-1-1/menu-1-3-2',
|
||||
// name: '菜单1-3-2'
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.aside {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,58 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 03:46:53
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-11 00:01:53
|
||||
* @FilePath: \bingwu-admin\src\layout\components\HeaderCom.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="left">
|
||||
<CollapseAsideCom></CollapseAsideCom>
|
||||
<el-breadcrumb
|
||||
separator-icon="ArrowRight"
|
||||
style="margin-left: 24px; transform: translateY(-1px)"
|
||||
>
|
||||
<el-breadcrumb-item
|
||||
v-for="item in $route.matched"
|
||||
:key="item"
|
||||
:to="item.path"
|
||||
>{{ item.meta.name }}</el-breadcrumb-item
|
||||
>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="right">
|
||||
<SwitchLanguageCom></SwitchLanguageCom>
|
||||
<AvatarCom></AvatarCom>
|
||||
<SettingCom></SettingCom>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import CollapseAsideCom from '@/components/utils/CollapseAsideCom.vue'
|
||||
import SwitchLanguageCom from '@/components/utils/SwitchLanguageCom.vue'
|
||||
import SettingCom from '@/components/SettingCom.vue'
|
||||
import AvatarCom from '@/components/AvatarCom.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.header {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.left {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.right {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-20 23:24:08
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-15 14:29:07
|
||||
* @FilePath: \bingwu-admin\src\main.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
|
||||
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||
import 'normalize.css'
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
import i18n from './language'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
// 导入插件
|
||||
import permission from './plugins/permission'
|
||||
const app = createApp(App)
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
const pinia = createPinia()
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
app.use(pinia).use(router).use(i18n).use(permission).mount('#app')
|
@ -0,0 +1,24 @@
|
||||
import { getUserStore } from '@/stores'
|
||||
// 判断权限的插件
|
||||
export default {
|
||||
install: (app, options) => {
|
||||
// 权限内容存在user中
|
||||
const userStroe = getUserStore()
|
||||
console.log('我的permission插件')
|
||||
// 使用自定义指令
|
||||
app.directive('permission', {
|
||||
mounted(el, binding) {
|
||||
console.log('options', options)
|
||||
console.log('binding', binding)
|
||||
let permission = binding.value // 获取到传入 v-permission的值
|
||||
if (permission) {
|
||||
let hasPermission = userStroe.hasPermission(permission)
|
||||
if (!hasPermission) {
|
||||
// 没有权限 移除Dom元素
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* ..Author: BINGWU
|
||||
* ..Date: 2024-01-20 23:24:08
|
||||
* ..LastEditors: BINGWU HuJiaCheng2003..163.com
|
||||
* ..LastEditTime: 2024-02-15 19:48:22
|
||||
* ..FilePath: \bingwu-admin\src\router\index.js
|
||||
* ..Describe:
|
||||
* ..Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
// 页面组件的文件路径
|
||||
const modules = import.meta.glob('../views/**/**.vue')
|
||||
import { getUserStore } from '@/stores'
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('../layout/IndexCom.vue'),
|
||||
meta: {
|
||||
name: '首页'
|
||||
},
|
||||
name: 'main',
|
||||
children: [
|
||||
// {
|
||||
// path: 'home',
|
||||
// name: 'home',
|
||||
// component: () => import('../views/HomeView.vue')
|
||||
// },
|
||||
// {
|
||||
// path: 'international',
|
||||
// name: 'international',
|
||||
// component: () => import('../views/InternationalView.vue'),
|
||||
// meta: {
|
||||
// name: '国际化'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: 'table/main-table1',
|
||||
// name: 'main-table',
|
||||
// component: () => import('../views/table/MainTableView.vue'),
|
||||
// meta: {
|
||||
// name: '表格1'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: 'excel',
|
||||
// name: 'excel',
|
||||
// component: () => import('../views/ExcelView.vue'),
|
||||
// meta: {
|
||||
// name: 'excel'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: 'file',
|
||||
// name: 'file',
|
||||
// component: () => import('../views/FileView.vue'),
|
||||
// meta: {
|
||||
// name: 'file'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: 'rich-text',
|
||||
// name: 'rich-text',
|
||||
// component: () => import('../views/RichTextView.vue'),
|
||||
// meta: {
|
||||
// name: 'rich-text'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: 'permission',
|
||||
// name: 'permission',
|
||||
// component: () => import('../views/PermissionView.vue'),
|
||||
// meta: {
|
||||
// name: 'permission'
|
||||
// }
|
||||
// },
|
||||
// // 三级路由
|
||||
// {
|
||||
// path: 'menu/menu-1-1',
|
||||
// name: 'child-menu',
|
||||
// component: () => import('../views/FatherMenu/FatherMenuView.vue'),
|
||||
// meta: {
|
||||
// name: '菜单1'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: '/menu/menu-1-1/menu-1-3-1',
|
||||
// name: 'father-menu',
|
||||
// component: () =>
|
||||
// import('../views/FatherMenu/ChildMenu/ChildMenuView.vue'),
|
||||
// meta: {
|
||||
// name: '菜单1'
|
||||
// }
|
||||
// }
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/error/not-find1',
|
||||
name: 'not-find1',
|
||||
component: () => import('../views/Error/NotFindView1.vue'),
|
||||
meta: {
|
||||
name: 'not-find1'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/error/not-find2',
|
||||
name: 'not-find2',
|
||||
component: () => import('../views/Error/NotFindView2.vue'),
|
||||
meta: {
|
||||
name: 'not-find2'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/error/not-find3',
|
||||
name: 'not-find3',
|
||||
component: () => import('../views/Error/NotFindView3.vue'),
|
||||
meta: {
|
||||
name: 'not-find3'
|
||||
}
|
||||
},
|
||||
// 访问不存在的路由所跳转的页面
|
||||
// {
|
||||
// path: '/:catchAll(.*)',
|
||||
// redirect: '/error/not-find2'
|
||||
// },
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('../views/LoginView.vue'),
|
||||
meta: {
|
||||
name: 'login'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/test',
|
||||
name: 'test',
|
||||
component: () => import('../views/test/TestView.vue'),
|
||||
meta: {
|
||||
name: 'test'
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
router.beforeEach((to, from) => {
|
||||
if (to.name !== 'login') {
|
||||
if (!getUserStore().token) {
|
||||
return { name: 'login' }
|
||||
}
|
||||
}
|
||||
// 处理动态路由刷新白屏
|
||||
if (!to.redirectedFrom) {
|
||||
getUserStore().addUserRoute(router, modules)
|
||||
return { ...to, replace: true }
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
@ -0,0 +1,9 @@
|
||||
import useStateStore from './modules/state'
|
||||
import useUserStore from './modules/user'
|
||||
const getStateStore = () => {
|
||||
return useStateStore()
|
||||
}
|
||||
const getUserStore = () => {
|
||||
return useUserStore()
|
||||
}
|
||||
export { getStateStore, getUserStore }
|
@ -0,0 +1,21 @@
|
||||
import { ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
const useStateStore = defineStore(
|
||||
'state',
|
||||
() => {
|
||||
const isCollapse = ref(false)
|
||||
const updateCollapse = () => {
|
||||
isCollapse.value = !isCollapse.value
|
||||
}
|
||||
const currentLang = ref('zh-cn')
|
||||
const updateCurrentLang = (lang) => {
|
||||
currentLang.value = lang
|
||||
}
|
||||
return { isCollapse, updateCollapse, currentLang, updateCurrentLang }
|
||||
},
|
||||
{
|
||||
persist: true
|
||||
}
|
||||
)
|
||||
|
||||
export default useStateStore
|
@ -0,0 +1,519 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-15 14:18:43
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-04-11 17:38:14
|
||||
* @FilePath: \app\src\stores\modules\user.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
import { ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
const useUserStore = defineStore(
|
||||
'user',
|
||||
() => {
|
||||
// 模拟后台返回的token
|
||||
const token = ref('')
|
||||
const setToken = (newToken) => {
|
||||
token.value = newToken
|
||||
}
|
||||
// 模拟后台返回的侧边栏数据
|
||||
const asideData = ref([
|
||||
{
|
||||
index: '/home',
|
||||
icon: 'icon iconfont icon-shouye',
|
||||
name: '首页'
|
||||
},
|
||||
//
|
||||
{
|
||||
index: '/user-manage',
|
||||
icon: 'icon iconfont icon-guanliyuan_jiaoseguanli',
|
||||
name: '用户管理'
|
||||
},
|
||||
{
|
||||
index: '/employee-manage',
|
||||
icon: 'icon iconfont icon-yuangongguanli',
|
||||
name: '职工管理'
|
||||
},
|
||||
{
|
||||
index: '/reward-manage',
|
||||
icon: 'icon iconfont icon-wodejixiao',
|
||||
name: '绩效管理'
|
||||
},
|
||||
// 二级
|
||||
{
|
||||
index: '/feedback',
|
||||
icon: 'icon iconfont icon-xinxifankui',
|
||||
name: '员工反馈与投诉管理',
|
||||
children: [
|
||||
{
|
||||
index: '/feedback/manage',
|
||||
name: '投诉管理'
|
||||
},
|
||||
{
|
||||
index: '/feedback/view',
|
||||
name: '员工反馈'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
index: '/request',
|
||||
icon: 'icon iconfont icon-qingjiatiao',
|
||||
name: '请假管理',
|
||||
children: [
|
||||
{
|
||||
index: '/request/manage',
|
||||
name: '请假信息管理'
|
||||
},
|
||||
{
|
||||
index: '/request/view',
|
||||
name: '个人请假信息'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
index: '/person',
|
||||
icon: 'icon iconfont icon-geren',
|
||||
name: '个人信息管理',
|
||||
children: [
|
||||
{
|
||||
index: '/person/password',
|
||||
name: '修改密码'
|
||||
},
|
||||
{
|
||||
index: '/person/avatar',
|
||||
name: '修改个人信息'
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
// 模拟后台返回的路由数据
|
||||
const routerData = ref([
|
||||
{
|
||||
path: 'home',
|
||||
name: 'home',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/HomeView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'international',
|
||||
name: 'international',
|
||||
|
||||
meta: {
|
||||
name: '国际化',
|
||||
url: '../views/InternationalView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'table/main-table1',
|
||||
name: 'main-table',
|
||||
meta: {
|
||||
name: '表格1',
|
||||
url: '../views/table/MainTableView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'excel',
|
||||
name: 'excel',
|
||||
|
||||
meta: {
|
||||
name: 'excel',
|
||||
url: '../views/ExcelView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'file',
|
||||
name: 'file',
|
||||
|
||||
meta: {
|
||||
name: 'file',
|
||||
url: '../views/FileView.vue'
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: 'rich-text',
|
||||
name: 'rich-text',
|
||||
|
||||
meta: {
|
||||
name: 'rich-text',
|
||||
url: '../views/RichTextView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'permission',
|
||||
name: 'permission',
|
||||
|
||||
meta: {
|
||||
name: 'permission',
|
||||
url: '../views/PermissionView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'tx-yun',
|
||||
name: 'tx-yun',
|
||||
|
||||
meta: {
|
||||
name: 'tx-yun',
|
||||
url: '../views/TxView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'progress',
|
||||
name: 'progress',
|
||||
meta: {
|
||||
name: 'progress',
|
||||
url: '../views/ProgressView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'preview-picture',
|
||||
name: 'preview-picture',
|
||||
|
||||
meta: {
|
||||
name: 'preview-picture',
|
||||
url: '../views/PreviewPictureView.vue'
|
||||
}
|
||||
},
|
||||
// 三级路由
|
||||
{
|
||||
path: 'menu/menu-1-1',
|
||||
name: 'child-menu',
|
||||
|
||||
meta: {
|
||||
name: '菜单1-1',
|
||||
url: '../views/FatherMenu/FatherMenuView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/menu/menu-1-1/menu-1-3-1',
|
||||
name: 'father-menu',
|
||||
|
||||
meta: {
|
||||
name: '菜单1-3-1',
|
||||
url: '../views/FatherMenu/ChildMenu/ChildMenuView.vue'
|
||||
}
|
||||
},
|
||||
//
|
||||
{
|
||||
path: 'user-manage',
|
||||
name: 'user-manage',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/UserManageView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'employee-manage',
|
||||
name: 'employee-manage',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/EmployeeManageView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'reward-manage',
|
||||
name: 'reward-manage',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/RewardManageView.vue'
|
||||
}
|
||||
},
|
||||
// 二级
|
||||
{
|
||||
path: 'feedback/manage',
|
||||
name: 'feedback-manage',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/feedback/FeedbackManageView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'feedback/view',
|
||||
name: 'feedback-view',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/feedback/FeedbackView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'request/manage',
|
||||
name: 'request-manage',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/request/RequestManageView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'request/view',
|
||||
name: 'request-view',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/request/RequestView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'person/password',
|
||||
name: 'person-password',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/PersonInfo/ChangePasswordView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'person/avatar',
|
||||
name: 'person-avatar',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/PersonInfo/ChangeAvatarView.vue'
|
||||
}
|
||||
}
|
||||
])
|
||||
// 动态添加路由
|
||||
const addUserRoute = (router, modules) => {
|
||||
routerData.value.forEach((item) => {
|
||||
router.addRoute('main', {
|
||||
...item,
|
||||
// item.url 匹配对应路由文件
|
||||
component: modules[item.meta.url]
|
||||
})
|
||||
})
|
||||
}
|
||||
// 模拟后台返回的权限数组
|
||||
const authArr = ref(['a', 'b', 'c', 'd', 'view', 'delete', 'edit'])
|
||||
// 判断权限
|
||||
const hasPermission = (auth) => {
|
||||
return authArr.value.indexOf(auth) !== -1
|
||||
}
|
||||
// 切换用户
|
||||
const switchUser = (username) => {
|
||||
if (username === 'cxk') {
|
||||
asideData.value = [
|
||||
{
|
||||
index: '/home',
|
||||
icon: 'icon iconfont icon-home',
|
||||
name: '首页'
|
||||
},
|
||||
{
|
||||
index: '/rich-text',
|
||||
icon: 'icon iconfont icon-fuwenben2',
|
||||
name: '富文本编辑器'
|
||||
},
|
||||
{
|
||||
index: '/excel',
|
||||
icon: 'icon iconfont icon-excel',
|
||||
name: 'excel(导出/导入)'
|
||||
},
|
||||
{
|
||||
index: '/file',
|
||||
icon: 'icon iconfont icon-wenjian',
|
||||
name: '文件上传'
|
||||
},
|
||||
{
|
||||
index: '/permission',
|
||||
icon: 'icon iconfont icon-quanxian',
|
||||
name: '按钮权限管理'
|
||||
},
|
||||
{
|
||||
index: '/international',
|
||||
icon: 'icon iconfont icon-yuyan1',
|
||||
name: '国际化'
|
||||
}
|
||||
]
|
||||
routerData.value = [
|
||||
{
|
||||
path: 'home',
|
||||
name: 'home',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/HomeView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'international',
|
||||
name: 'international',
|
||||
|
||||
meta: {
|
||||
name: '国际化',
|
||||
url: '../views/InternationalView.vue'
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: 'excel',
|
||||
name: 'excel',
|
||||
|
||||
meta: {
|
||||
name: 'excel',
|
||||
url: '../views/ExcelView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'file',
|
||||
name: 'file',
|
||||
|
||||
meta: {
|
||||
name: 'file',
|
||||
url: '../views/FileView.vue'
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: 'rich-text',
|
||||
name: 'rich-text',
|
||||
|
||||
meta: {
|
||||
name: 'rich-text',
|
||||
url: '../views/RichTextView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'permission',
|
||||
name: 'permission',
|
||||
|
||||
meta: {
|
||||
name: 'permission',
|
||||
url: '../views/PermissionView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'home',
|
||||
name: 'home',
|
||||
meta: {
|
||||
// 路由组件的路径
|
||||
url: '../views/HomeView.vue'
|
||||
}
|
||||
}
|
||||
]
|
||||
authArr.value = ['a', 'b']
|
||||
} else {
|
||||
asideData.value = [
|
||||
{
|
||||
index: '/permission',
|
||||
icon: 'icon iconfont icon-quanxian',
|
||||
name: '按钮权限管理'
|
||||
},
|
||||
// 二级
|
||||
{
|
||||
index: '/table',
|
||||
icon: 'icon iconfont icon-biaoge',
|
||||
name: '表格',
|
||||
children: [
|
||||
{
|
||||
index: '/table/main-table1',
|
||||
name: '表格1'
|
||||
},
|
||||
{
|
||||
index: '/table/main-table2',
|
||||
name: '表格2'
|
||||
}
|
||||
]
|
||||
},
|
||||
// 二级
|
||||
{
|
||||
index: '/error',
|
||||
icon: 'icon iconfont icon-cuowu',
|
||||
name: '错误页面',
|
||||
children: [
|
||||
{
|
||||
index: '/error/not-find1',
|
||||
name: '错误页面1'
|
||||
},
|
||||
{
|
||||
index: '/error/not-find2',
|
||||
name: '错误页面2'
|
||||
},
|
||||
{
|
||||
index: '/error/not-find3',
|
||||
name: '错误页面3'
|
||||
}
|
||||
]
|
||||
},
|
||||
// 三级
|
||||
{
|
||||
index: '/menu',
|
||||
icon: 'icon iconfont icon-caidan',
|
||||
name: '多级菜单',
|
||||
children: [
|
||||
{
|
||||
index: '/menu/menu-1-1',
|
||||
name: '菜单1-1'
|
||||
},
|
||||
{
|
||||
index: '/menu/menu-1-2',
|
||||
name: '菜单1-2'
|
||||
},
|
||||
{
|
||||
index: '/menu/menu-1-3',
|
||||
name: '菜单1-3',
|
||||
sons: [
|
||||
{
|
||||
index: '/menu/menu-1-1/menu-1-3-1',
|
||||
name: '菜单1-3-1'
|
||||
},
|
||||
{
|
||||
index: '/menu/menu-1-1/menu-1-3-2',
|
||||
name: '菜单1-3-2'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
routerData.value = [
|
||||
{
|
||||
path: 'permission',
|
||||
name: 'permission',
|
||||
meta: {
|
||||
name: 'permission',
|
||||
url: '../views/PermissionView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'table/main-table1',
|
||||
name: 'main-table',
|
||||
meta: {
|
||||
name: '表格1',
|
||||
url: '../views/table/MainTableView.vue'
|
||||
}
|
||||
},
|
||||
// 三级路由
|
||||
{
|
||||
path: 'menu/menu-1-1',
|
||||
name: 'child-menu',
|
||||
meta: {
|
||||
name: '菜单1-1',
|
||||
url: '../views/FatherMenu/FatherMenuView.vue'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/menu/menu-1-1/menu-1-3-1',
|
||||
name: 'father-menu',
|
||||
meta: {
|
||||
name: '菜单1-3-1',
|
||||
url: '../views/FatherMenu/ChildMenu/ChildMenuView.vue'
|
||||
}
|
||||
}
|
||||
]
|
||||
authArr.value = ['c', 'd']
|
||||
}
|
||||
}
|
||||
return {
|
||||
authArr,
|
||||
hasPermission,
|
||||
addUserRoute,
|
||||
routerData,
|
||||
setToken,
|
||||
token,
|
||||
asideData,
|
||||
switchUser
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true
|
||||
}
|
||||
)
|
||||
|
||||
export default useUserStore
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-23 21:37:43
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-04-11 16:27:14
|
||||
* @FilePath: \app\src\utils\http.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
import axios from 'axios'
|
||||
const instance = axios.create({
|
||||
baseURL: '/api'
|
||||
})
|
||||
|
||||
// 添加请求拦截器
|
||||
instance.interceptors.request.use(
|
||||
(config) => {
|
||||
// 在发送请求之前做些什么
|
||||
config.headers.Authorization =
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjI3MTI3Mjk3MTIsImlhdCI6MTcxMjcyOTcxMywiZGF0YSI6eyJ1c2VybmFtZSI6IkFsZ2ZkZ2RmZ2RpY2UiLCJwYXNzd29yZCI6IjEyZ2RmZ2QzIiwicm9sZV9kYXRhIjoiZGVmYXVsdCJ9fQ.cLo2NZ01z2umdbmnDBBuyekFrT8yTyvzBv8gHifzhKU'
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
// 对请求错误做些什么
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 添加响应拦截器
|
||||
instance.interceptors.response.use(
|
||||
(response) => {
|
||||
// 2xx 范围内的状态码都会触发该函数。
|
||||
// 对响应数据做点什么
|
||||
return response
|
||||
},
|
||||
(error) => {
|
||||
// 超出 2xx 范围的状态码都会触发该函数。
|
||||
// 对响应错误做点什么
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default instance
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>职工信息管理</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div class="main-container">
|
||||
<div class="img-container container-item">
|
||||
<img src="../../assets/error/notfind1/static/404.svg" />
|
||||
</div>
|
||||
<div class="text-container container-item">
|
||||
<div class="code">404</div>
|
||||
<div class="msg">你查看的页面貌似丢失了呢...</div>
|
||||
<div class="action">返回首页,查看更多内容.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: rgba(223, 223, 255, 0.39);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
width: 80%;
|
||||
max-width: 1000px;
|
||||
max-height: 500px;
|
||||
min-width: 600px;
|
||||
background-color: white;
|
||||
font-size: 0;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 0 50px 0 rgba(146, 146, 146, 0.63);
|
||||
}
|
||||
|
||||
.main-container .container-item {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.main-container .img-container {
|
||||
background-color: rgba(253, 216, 168, 0.692);
|
||||
border-top-left-radius: 20px;
|
||||
border-bottom-left-radius: 20px;
|
||||
}
|
||||
|
||||
.main-container .text-container .code {
|
||||
font-size: clamp(150px, 20vw, 200px);
|
||||
font-family: 'Arial Narrow';
|
||||
color: rgb(86, 86, 253);
|
||||
font-weight: bolder;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.main-container .text-container .msg {
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
font-weight: 200;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.main-container .text-container .action {
|
||||
font-size: 15px;
|
||||
font-weight: 200;
|
||||
text-align: center;
|
||||
text-decoration-line: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,157 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-10 22:19:03
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-10 22:57:10
|
||||
* @FilePath: \bingwu-admin\src\views\Error\NotFindView2.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="content">
|
||||
<div class="page-404">
|
||||
<h1>404</h1>
|
||||
<p>You are lost this page</p>
|
||||
<p class="info">
|
||||
you've reached the edge of universe.The Page you've requested , can't
|
||||
befound. Don't Worry , you can return to previous page.
|
||||
</p>
|
||||
<button class="go-home btn">GO HOME</button>
|
||||
<button class="back btn">BACK</button>
|
||||
</div>
|
||||
<div class="astronaut">
|
||||
<img
|
||||
src="../../assets/error/notfind2/astronaut.png"
|
||||
class="astronaut-img"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@font-face {
|
||||
font-family: dogica;
|
||||
src: url(../../assets/error/notfind2/font/dogica.ttf);
|
||||
}
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: url(../../assets/error/notfind2/bg.png);
|
||||
background-attachment: fixed;
|
||||
background-size: cover;
|
||||
.astronaut {
|
||||
transform: rotate(0deg) translate(0, -18%);
|
||||
animation-name: PAnimation;
|
||||
animation-direction: alternate;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
animation-duration: 3s;
|
||||
}
|
||||
.page-404 {
|
||||
width: 40vw;
|
||||
font-family: dogica;
|
||||
z-index: 1;
|
||||
h1 {
|
||||
font-size: 5vw;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
p {
|
||||
font-size: 1vw;
|
||||
margin: 10px 0;
|
||||
line-height: 2vw;
|
||||
}
|
||||
.btn {
|
||||
width: 10vw;
|
||||
height: 50px;
|
||||
border-radius: 30px;
|
||||
margin-top: 10px;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
border: 2px solid #000;
|
||||
font-size: 1vw;
|
||||
&:hover {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
.astronaut {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
}
|
||||
.page-404 {
|
||||
width: 40vw;
|
||||
position: absolute;
|
||||
left: 10%;
|
||||
top: 40%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: 1024px) {
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.page-404 {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10vh;
|
||||
h1 {
|
||||
font-size: 10vw;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
p {
|
||||
font-size: 3vw;
|
||||
line-height: 6vw;
|
||||
}
|
||||
.info {
|
||||
display: none;
|
||||
}
|
||||
.btn {
|
||||
width: 30vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
.astronaut {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.astronaut-img {
|
||||
width: 70%;
|
||||
height: 80%;
|
||||
transform: translateY(40%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes PAnimation {
|
||||
0% {
|
||||
transform: rotate(0deg) translate(0, -15%);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(10deg) translate(0, -18%);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,97 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-10 23:16:48
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-10 23:16:53
|
||||
* @FilePath: \bingwu-admin\src\views\Error\NotFindView3.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div class="number">404</div>
|
||||
|
||||
<div class="text"><span>页面找不到了</span><br />可能已经被删除</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
flex-flow: row wrap;
|
||||
align-content: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.number {
|
||||
margin: 100px 0 0 0;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
font: 900 30vmin 'Consolas';
|
||||
letter-spacing: 5vmin;
|
||||
text-shadow:
|
||||
2px -1px 0 #000,
|
||||
4px -2px 0 #0a0a0a,
|
||||
6px -3px 0 #0f0f0f,
|
||||
8px -4px 0 #141414,
|
||||
10px -5px 0 #1a1a1a,
|
||||
12px -6px 0 #1f1f1f,
|
||||
14px -7px 0 #242424,
|
||||
16px -8px 0 #292929;
|
||||
}
|
||||
.number::before {
|
||||
background-color: #673ab7;
|
||||
background-image: radial-gradient(
|
||||
closest-side at 50% 50%,
|
||||
#ffc107 100%,
|
||||
rgba(0, 0, 0, 0)
|
||||
),
|
||||
radial-gradient(closest-side at 50% 50%, #e91e63 100%, rgba(0, 0, 0, 0));
|
||||
background-repeat: repeat-x;
|
||||
background-size: 40vmin 40vmin;
|
||||
background-position:
|
||||
-100vmin 20vmin,
|
||||
100vmin -25vmin;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
mix-blend-mode: screen;
|
||||
-webkit-animation: moving 10s linear infinite both;
|
||||
animation: moving 10s linear infinite both;
|
||||
display: block;
|
||||
position: absolute;
|
||||
content: '';
|
||||
}
|
||||
@-webkit-keyframes moving {
|
||||
to {
|
||||
background-position:
|
||||
100vmin 20vmin,
|
||||
-100vmin -25vmin;
|
||||
}
|
||||
}
|
||||
@keyframes moving {
|
||||
to {
|
||||
background-position:
|
||||
100vmin 20vmin,
|
||||
-100vmin -25vmin;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
font: 400 5vmin 'Courgette';
|
||||
}
|
||||
.text span {
|
||||
font-size: 10vmin;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="excel">
|
||||
<h3>导出</h3>
|
||||
<ExportExcelCom @handleExportData="handleExportData"></ExportExcelCom>
|
||||
<h3>导入</h3>
|
||||
<ImportExcelCom @importData="importData"></ImportExcelCom>
|
||||
<h3>表格</h3>
|
||||
<BaseTableCom
|
||||
:columnData="columnData"
|
||||
:showSelect="true"
|
||||
:tableData="tableData"
|
||||
ref="baseTableComRef"
|
||||
></BaseTableCom>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ExportExcelCom from '@/components/excel/ExportExcelCom.vue'
|
||||
import ImportExcelCom from '@/components/excel/ImportExcelCom.vue'
|
||||
import BaseTableCom from '@/components/table/BaseTableCom.vue'
|
||||
import { ref } from 'vue'
|
||||
const baseTableComRef = ref(null)
|
||||
// 点击确认后获取到已被导入的文件的数据
|
||||
const importData = (excelFilesData) => {
|
||||
console.log('已被导入的文件的数据', excelFilesData)
|
||||
ElMessage({
|
||||
showClose: true,
|
||||
message: '处理导入的数据',
|
||||
type: 'success'
|
||||
})
|
||||
tableData.value = tableData.value.concat(excelFilesData)
|
||||
}
|
||||
// 要导出的数据
|
||||
let exportData = []
|
||||
// 表格属性
|
||||
const columnData = [
|
||||
{
|
||||
prop: 'age',
|
||||
label: '年龄'
|
||||
},
|
||||
{
|
||||
prop: 'name',
|
||||
label: '性别'
|
||||
},
|
||||
{
|
||||
prop: 'hobby',
|
||||
label: '爱好'
|
||||
},
|
||||
{
|
||||
prop: 'project',
|
||||
label: '专业'
|
||||
}
|
||||
]
|
||||
const tableData = ref([
|
||||
{
|
||||
age: 18,
|
||||
name: '永远18岁',
|
||||
hobby: '夹声音',
|
||||
project: '唱歌'
|
||||
},
|
||||
{
|
||||
age: 19,
|
||||
name: '永远18岁',
|
||||
hobby: '夹声音',
|
||||
project: '唱歌'
|
||||
},
|
||||
{
|
||||
age: 20,
|
||||
name: '永远18岁',
|
||||
hobby: '夹声音',
|
||||
project: '唱歌'
|
||||
},
|
||||
{
|
||||
age: 21,
|
||||
name: '永远18岁',
|
||||
hobby: '夹声音',
|
||||
project: '唱歌'
|
||||
}
|
||||
])
|
||||
// 导出的处理函数
|
||||
const handleExportData = (exportFile, fileName, fileExtension) => {
|
||||
// exportData 为要导出的数据
|
||||
exportData = baseTableComRef.value.getSelectRows()
|
||||
exportFile(exportData, fileName, fileExtension)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,20 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-01 00:31:58
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-10 21:21:20
|
||||
* @FilePath: \bingwu-admin\src\views\FatherMenu\ChiladMenu\ChildMenuView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
ChildMenu
|
||||
<!-- <RouterView /> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,16 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-01 00:31:24
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-01 00:32:18
|
||||
* @FilePath: \bingwu-admin\src\views\FatherMenu\FatherMenu.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div>FatherMenu</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div class="file">
|
||||
<UploadFileCom
|
||||
ref="uploadFileComRef"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
@handleConfirm="handleConfirm"
|
||||
>
|
||||
<template #tip>选择文件的提示</template>
|
||||
</UploadFileCom>
|
||||
<div style="margin: 50px 0">
|
||||
<el-button
|
||||
@click="
|
||||
() => {
|
||||
const files = uploadFileComRef.getSelectFiles()
|
||||
console.log('files:', files)
|
||||
}
|
||||
"
|
||||
>获取已被选择的文件</el-button
|
||||
>
|
||||
</div>
|
||||
<ProgressLiteCom ref="progressLiteComRef"></ProgressLiteCom>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import UploadFileCom from '@/components/file/UploadFileCom.vue'
|
||||
import ProgressLiteCom from '@/components/progress/ProgressLiteCom.vue'
|
||||
import { ref, toRaw } from 'vue'
|
||||
const uploadFileComRef = ref([])
|
||||
const progressLiteComRef = ref(null)
|
||||
// 点击确认按钮后的处理逻辑
|
||||
const handleConfirm = (selectFiles) => {
|
||||
// toRaw转换proxy代理的数据
|
||||
console.log('confirm', toRaw(selectFiles))
|
||||
uploadFileComRef.value.offDialog()
|
||||
ElMessage({
|
||||
showClose: true,
|
||||
message: '点击了确认按钮',
|
||||
type: 'success'
|
||||
})
|
||||
|
||||
// 模拟异步请求
|
||||
const startWork = progressLiteComRef.value.start()
|
||||
setTimeout(() => {
|
||||
progressLiteComRef.value.end(startWork)
|
||||
}, 3000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.file {
|
||||
width: 30%;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,19 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-20 23:24:08
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-16 23:44:10
|
||||
* @FilePath: \bingwu-admin\src\views\HomeView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="home">
|
||||
<MyEcharts></MyEcharts>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import MyEcharts from '@/components/echarts/MyEcharts.vue'
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,29 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-24 17:35:53
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-10 23:50:21
|
||||
* @FilePath: \bingwu-admin\src\views\InternationalView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="international">
|
||||
<h1>国际化展示(局部国际化)</h1>
|
||||
<h4>自定义内容国际化</h4>
|
||||
<div>
|
||||
<span>{{ $t('headMenus.name') }}:</span>
|
||||
<span>{{ $t('headMenus.userName') }}</span>
|
||||
</div>
|
||||
<h4>element-plus组件的国际化</h4>
|
||||
<div style="width: 30%">
|
||||
<el-table mb-1 :data="[]" />
|
||||
<el-pagination :total="100" />
|
||||
</div>
|
||||
<i class="icon iconfont icon-yuyan"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div class="login">
|
||||
<div class="content">
|
||||
<el-button type="primary" @click="login">登陆</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getUserStore } from '@/stores'
|
||||
const modules = import.meta.glob('../views/**/**.vue')
|
||||
const router = useRouter()
|
||||
const userStore = getUserStore()
|
||||
const login = () => {
|
||||
userStore.addUserRoute(router, modules)
|
||||
userStore.setToken('my-token')
|
||||
router.push('/home')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.content {
|
||||
margin-top: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,55 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-15 14:28:56
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-16 21:12:52
|
||||
* @FilePath: \bingwu-admin\src\views\PermissionView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="permission">
|
||||
<h1>按钮的权限管理</h1>
|
||||
<!-- 四个按钮有a,b,c,d权限 -->
|
||||
<el-button v-permission="'a'">a按钮</el-button>
|
||||
<el-button v-permission="'b'">b按钮</el-button>
|
||||
<el-button v-permission="'c'">c按钮</el-button>
|
||||
<el-button v-permission="'d'">d按钮</el-button>
|
||||
<hr />
|
||||
<h4>用户切换</h4>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
swictUser('cxk')
|
||||
}
|
||||
"
|
||||
>切换为用户cxk</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
swictUser('admin')
|
||||
}
|
||||
"
|
||||
>切换为用户admin</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getUserStore } from '@/stores'
|
||||
const userStore = getUserStore()
|
||||
const swictUser = (usename) => {
|
||||
userStore.switchUser(usename)
|
||||
// 刷新页面
|
||||
location.reload()
|
||||
ElMessage({
|
||||
message: `切换为用户${usename}`,
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>avatar管理</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>密码管理</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,36 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-17 16:32:46
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-17 18:01:52
|
||||
* @FilePath: \bingwu-admin\src\views\PreviewPictureView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="preview-picture">
|
||||
<PreviewPictureCom ref="previewPictureComRef"> </PreviewPictureCom>
|
||||
<div style="margin-top: 60px">
|
||||
<el-button @click="getFileData" type="primary">获取图片文件</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PreviewPictureCom from '@/components/PreviewPictureCom.vue'
|
||||
import { ref } from 'vue'
|
||||
const previewPictureComRef = ref(null)
|
||||
const getFileData = () => {
|
||||
const fileData = previewPictureComRef.value.fileFn().getFile()
|
||||
const url = previewPictureComRef.value.imageUrlFn().getImageUrl()
|
||||
console.log('file-data: ', fileData)
|
||||
console.log('url: ', url.value)
|
||||
previewPictureComRef.value
|
||||
.imageUrlFn()
|
||||
.setImageUrl(
|
||||
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,54 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-17 19:59:25
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-22 21:25:38
|
||||
* @FilePath: \bingwu-admin\src\views\ProgressView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="progress">
|
||||
<h5>进度条</h5>
|
||||
<ProgressLiteCom
|
||||
ref="progressLiteComRef"
|
||||
:time="data.time"
|
||||
:increment="data.increment"
|
||||
:progress-type="data.progressType"
|
||||
></ProgressLiteCom>
|
||||
<div style="margin-top: 60px">
|
||||
<el-button @click="test" type="primary">测试</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ProgressLiteCom from '@/components/progress/ProgressLiteCom.vue'
|
||||
import { ref } from 'vue'
|
||||
const progressLiteComRef = ref(null)
|
||||
const data = {
|
||||
// 最开始的累加时间间隔
|
||||
time: 500,
|
||||
// 每次累加量(最好是能被100整除)
|
||||
increment: 8,
|
||||
// 进度条类型
|
||||
progressType: {
|
||||
type1: true,
|
||||
type2: true,
|
||||
type3: true
|
||||
}
|
||||
}
|
||||
const test = () => {
|
||||
// 模拟异步请求
|
||||
const startWork = progressLiteComRef.value.start()
|
||||
setTimeout(() => {
|
||||
progressLiteComRef.value.end(startWork, 'error', '上传失败')
|
||||
}, 4000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.progress {
|
||||
width: 20%;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>REWARD</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>腾讯储存桶测试</h1>
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
:show-file-list="false"
|
||||
:auto-upload="false"
|
||||
:on-change="uploaderFile"
|
||||
>
|
||||
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<div style="margin-top: 60px">
|
||||
<el-button @click="submit" type="primary">提交</el-button>
|
||||
</div>
|
||||
<h5>进度条</h5>
|
||||
<ProgressCom ref="progressComRef"></ProgressCom>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ProgressCom from '@/components/progress/ProgressCom.vue'
|
||||
import { smallFileUpload, largeFileUpload } from '@/utils/tencentCloud'
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 进度条
|
||||
const progressComRef = ref(null)
|
||||
const uploadFile = ref(null)
|
||||
const imageUrl = ref('')
|
||||
|
||||
const uploaderFile = (file) => {
|
||||
console.log('file', file)
|
||||
uploadFile.value = file
|
||||
}
|
||||
const update = (data) => {
|
||||
progressComRef.value.changePercentage(data)
|
||||
}
|
||||
const submit = () => {
|
||||
// 打开进度条
|
||||
progressComRef.value.openProgress()
|
||||
smallFileUpload(uploadFile.value, '', update).then((res) => {
|
||||
progressComRef.value.offProgress()
|
||||
imageUrl.value = res
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.avatar-uploader .avatar) {
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
:deep(.avatar-uploader .el-upload) {
|
||||
border: 1px dashed var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
}
|
||||
|
||||
:deep(.avatar-uploader .el-upload:hover) {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
:deep(.el-icon.avatar-uploader-icon) {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,16 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-04-11 16:53:10
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-04-11 16:53:18
|
||||
* @FilePath: \app\src\views\UserManageView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div>用户管理</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>feedback管理</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>员工反馈</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>请假信息管理</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,16 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-04-11 17:27:48
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-04-11 17:28:00
|
||||
* @FilePath: \app\src\views\request\RequestView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div>请假请假</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div class="main-table">
|
||||
<BaseTableCom
|
||||
:tableData="tableData"
|
||||
:columnData="columnData"
|
||||
:dropdownData="dropdownData"
|
||||
:showSelect="true"
|
||||
:pageSizes="[10, 15, 20]"
|
||||
:total="100"
|
||||
:showPagination="true"
|
||||
messageBoxContent="确认要切换状态吗?"
|
||||
messageBoxTitle="警告"
|
||||
@updateSwitchState="updateSwitchState"
|
||||
@updateTableData="updateTableData"
|
||||
ref="baseTableComRef"
|
||||
></BaseTableCom>
|
||||
<div style="margin-top: 40px">
|
||||
<el-button
|
||||
@click="
|
||||
() => {
|
||||
// 打开/关闭表格加载动画
|
||||
baseTableComRef.changeTableLoading()
|
||||
}
|
||||
"
|
||||
>表格加载动画</el-button
|
||||
>
|
||||
<el-button
|
||||
@click="
|
||||
() => {
|
||||
// 获取被勾选的行
|
||||
const rows = baseTableComRef.getSelectRows()
|
||||
console.log('被勾选的行', rows)
|
||||
}
|
||||
"
|
||||
>获取被勾选的行</el-button
|
||||
>
|
||||
<el-button
|
||||
@click="
|
||||
() => {
|
||||
// 获取分页数据
|
||||
const paginationData = baseTableComRef.getPaginationData()
|
||||
console.log('分页数据', paginationData)
|
||||
}
|
||||
"
|
||||
>获取分页数据</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import BaseTableCom from '@/components/table/BaseTableCom.vue'
|
||||
import { ref } from 'vue'
|
||||
const baseTableComRef = ref(null)
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
// tag列的数据
|
||||
// tag 对应 列的prop
|
||||
tag: {
|
||||
// tagName和tagType不能变
|
||||
tagName: '成功',
|
||||
tagType: 'success'
|
||||
},
|
||||
// 图片列的数据
|
||||
// picture 对应 列的prop
|
||||
picture:
|
||||
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
|
||||
name: 'Tom1',
|
||||
// 开关列对应的数据
|
||||
switch: false
|
||||
},
|
||||
{
|
||||
tag: {
|
||||
tagName: '信息',
|
||||
tagType: 'info'
|
||||
},
|
||||
name: 'Tom2',
|
||||
picture: 'https://placekitten.com/800/600',
|
||||
switch: true
|
||||
},
|
||||
{
|
||||
tag: {
|
||||
tagName: '警告',
|
||||
tagType: 'warning'
|
||||
},
|
||||
name: 'Tom3',
|
||||
picture: 'https://placebear.com/800/600',
|
||||
switch: true
|
||||
},
|
||||
{
|
||||
tag: {
|
||||
tagName: '默认',
|
||||
tagType: 'default'
|
||||
},
|
||||
name: 'Tom4',
|
||||
picture:
|
||||
'https://loremflickr.com/cache/resized/65535_53040484749_6fd5663cd5_c_800_600_nofilter.jpg',
|
||||
switch: false
|
||||
},
|
||||
{
|
||||
tag: {
|
||||
tagName: '危险',
|
||||
tagType: 'danger'
|
||||
},
|
||||
name: 'Tom5',
|
||||
picture:
|
||||
'https://fastly.picsum.photos/id/875/800/600.jpg?hmac=NXX-SwYycWXsbCWcJJnivoEGENe8Mp4fvuHqATxgOSY',
|
||||
switch: false
|
||||
}
|
||||
]
|
||||
// 操作列
|
||||
const dropdownData = [
|
||||
{
|
||||
command: 'command1',
|
||||
handleAction: (row) => {
|
||||
console.log('command1', row)
|
||||
},
|
||||
actionName: '删除',
|
||||
// 图标类型 对应element图标库
|
||||
icon: 'Delete',
|
||||
// 权限名称
|
||||
auth: 'delete'
|
||||
},
|
||||
{
|
||||
command: 'command2',
|
||||
handleAction: (row) => {
|
||||
console.log('command2', row)
|
||||
},
|
||||
actionName: '查看',
|
||||
icon: 'View',
|
||||
auth: 'view'
|
||||
},
|
||||
{
|
||||
command: 'conmmand3',
|
||||
handleAction: (row) => {
|
||||
console.log('command3', row)
|
||||
},
|
||||
actionName: '修改',
|
||||
icon: 'Edit',
|
||||
auth: 'edit'
|
||||
}
|
||||
]
|
||||
|
||||
// 列属性
|
||||
const columnData = [
|
||||
// 图片列
|
||||
{
|
||||
prop: 'picture',
|
||||
label: '图片列',
|
||||
// 使用图片
|
||||
pictureColumn: true
|
||||
},
|
||||
{
|
||||
prop: 'name',
|
||||
label: '普通数据列',
|
||||
// 列宽 单位为px
|
||||
width: '200',
|
||||
// 该列使用排序
|
||||
sortable: true
|
||||
},
|
||||
// tag列
|
||||
{
|
||||
prop: 'tag',
|
||||
label: 'tag列',
|
||||
// 使用tag
|
||||
tagColumn: true
|
||||
},
|
||||
// 开关列
|
||||
{
|
||||
prop: 'switch',
|
||||
label: '开关列',
|
||||
// 使用开关
|
||||
switchColumn: true
|
||||
}
|
||||
]
|
||||
// 开关状态变更时调用的函数
|
||||
const updateSwitchState = (switchState) => {
|
||||
console.log('改变后的switch状态', switchState)
|
||||
// 开关切换时的动画
|
||||
baseTableComRef.value.changeSwitchLoading()
|
||||
// 模拟异步请求
|
||||
setTimeout(() => {
|
||||
baseTableComRef.value.changeSwitchLoading()
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 页面变化和页面数据容量被修改时触发的函数
|
||||
const updateTableData = (pageSize, currentPage) => {
|
||||
console.log('页码', currentPage)
|
||||
console.log('页面数据容量', pageSize)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-02-16 18:42:11
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-02-17 19:50:10
|
||||
* @FilePath: \bingwu-admin\src\views\test\TestView.vue
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
-->
|
||||
<template>
|
||||
<div class="test">
|
||||
<ProgressLiteCom ref="progressLiteComRef"></ProgressLiteCom>
|
||||
<el-button type="primary" @click="test">测试</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ProgressLiteCom from '@/components/progress/ProgressLiteCom.vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getUser } from '@/api/user'
|
||||
const progressLiteComRef = ref(null)
|
||||
const test = () => {
|
||||
const startWork = progressLiteComRef.value.start()
|
||||
setTimeout(() => {
|
||||
progressLiteComRef.value.end(startWork)
|
||||
}, 5000)
|
||||
}
|
||||
onMounted(async () => {
|
||||
await getUser().then((res) => {
|
||||
console.log(res)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.test {
|
||||
padding-top: 40px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Author: BINGWU
|
||||
* @Date: 2024-01-20 23:24:08
|
||||
* @LastEditors: BINGWU HuJiaCheng2003@163.com
|
||||
* @LastEditTime: 2024-01-29 18:09:25
|
||||
* @FilePath: \bingwu-admin\vite.config.js
|
||||
* @Describe:
|
||||
* @Mark: ૮(˶ᵔ ᵕ ᵔ˶)ა
|
||||
*/
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
import { defineConfig } from 'vite'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()]
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()]
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
server: {
|
||||
open: true, // 是否主动唤醒浏览器,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: ' http://localhost:6699',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '') // 不可以省略rewrite
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
Binary file not shown.
Loading…
Reference in new issue