Sfoglia il codice sorgente

2022年6月6日16:38:00

master
wq 3 anni fa
parent
commit
386f946de3

+ 15
- 0
.vscode/launch.json Vedi File

@@ -0,0 +1,15 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}

+ 4
- 0
config.js Vedi File

@@ -0,0 +1,4 @@
/* 一般用作项目的全局配置 */
export const config = {
onLineState: true
};

+ 1
- 1
package-lock.json Vedi File

@@ -1,5 +1,5 @@
{
"name": "etc-project",
"name": "etcProject",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,

BIN
src/assets/image/three.jpg Vedi File


+ 2
- 3
src/components/SlidingBlockVerifyTwo/SlidingBlockVerifyTwo.vue Vedi File

@@ -1,8 +1,7 @@
<template>
<div class="as-gravity-center as-radius-5px" @mouseup="onmouseup" style="background-color:#FFFFFF;
padding: 15px 10px 15px 10px;width:340px;box-shadow: 0px 0px 5px #999999;">
<!-- <img src="http://localhost:2222/slide_img_four.jpg" style="height: 200px;width: 300px;">
<img src="http://localhost:2222/slide_img_three.jpg" style="height: 200px;width: 300px;"> -->
<!-- <img src="http://localhost:2222/slide_img_four.jpg" style="height: 200px;width: 300px;"> -->
<div :style="`width: ${totalWidth}px;`">
<!-- 文字提示 -->
<div class="as-gravity-center-start" style="display:flex;margin-bottom: 10px;">
@@ -64,7 +63,7 @@
</template>

<script>
import SlideImgThreePng from '@/assets/image/slide_img_three.png';
import SlideImgThreePng from '@/assets/image/three.jpg';
//md开撸第二版
export default {
props: {

+ 5
- 0
src/config.ts Vedi File

@@ -0,0 +1,5 @@
/* 全局配置项 */
export const system = {
//在线模式
onLineState: true,
}

+ 4
- 1
src/crud/index.vue Vedi File

@@ -40,7 +40,7 @@
<!-- 分页组件 -->
<el-pagination v-if="false" :page-size="20" :pager-count="11" layout="prev, pager, next" :total="1000" />
<!-- 对话框 -->
<el-dialog v-model="dialogFormVisible" width="40%"
<el-dialog v-model="dialogFormVisible" width="40%" @close="cancel"
:title="tableFrom.titleDialog ? tableFrom.titleDialog : `${title}`">
<!-- 是否自定义Dialog -->
<div v-if="tableFrom.dialogCustom">
@@ -104,6 +104,7 @@ const emit = defineEmits([
'submit',
'handleEdit',
'handleDelete',
'cancel'
])
// 声明props
const props = defineProps({
@@ -257,6 +258,8 @@ function reset() {

//取消
const cancel = () => {
emit('cancel') //弹窗关闭
reset()
dialogFormVisible.value = false
}


+ 49
- 3
src/data/menuData.ts Vedi File

@@ -1,3 +1,6 @@



/*
title:string; 页面标题,通常必选。
icon?:string; 图标,一般配合菜单使用。
@@ -9,32 +12,53 @@ hideMenu?:boolean; 有些路由我们并不想在菜单中显示,比如某些
order?:number; 菜单排序。
frameUrl?:string; 嵌套外链。
*/
import { getCurrentInstance } from 'vue'

export function getMenuData(proxy: any, callback: any, lose: any) {
// const {
// proxy
// }: any = getCurrentInstance();
proxy.$request.get('menu/findAll', {},
{ baseURL: 'http://localhost:8081/' }).then((res: any) => {
callback(res.data)
}).catch((error: any) => {
lose(error)
})
}


export const list = [
{
id: 1,
title: '基础信息查询服务',
path: 'home',
icon: 'Notification',
children: [{
id: 2,
title: '用户信息查询及变更服务',
path: 'userQueryChange',
icon: 'User',
children: []
}, {
id: 3,
title: '车辆信息查询及变更服务',
path: 'vehicleEnquirChange',
icon: 'Van',
children: []
}, {
id: 4,
title: '签约信息查询服务',
path: 'signingQuery',
icon: 'Tickets',
children: []
}, {
id: 5,
title: '卡片信息查询服务',
path: 'cardQueries',
icon: 'Postcard',
children: []
}, {
id: 6,
title: 'OBU信息查询服务',
path: 'OBUQuery',
icon: 'Link',
@@ -42,84 +66,101 @@ export const list = [
}]
},
{
id: 7,
title: '通行流水查询服务',
path: 'trafficFlow',
icon: 'Promotion',
children: []
}, {
id: 8,
title: '黑名单查询服务',
path: 'blacklistQuery',
icon: 'Opportunity',
children: []
}, {
id: 9,
title: '卡签售后服务',
path: 'home',
icon: 'Postcard',
children: [{
id: 10,
title: '卡签补办服务',
path: 'cardFillDo',
icon: 'Postcard',
children: []
}, {
id: 11,
title: '卡签续期服务',
icon: 'Postcard',
path: 'cardRenewal',
children: []
}, {
id: 12,
icon: 'Postcard',
title: '主动挂起(解除)服务',
path: 'initiativeHangUp',
children: []
}, {
id: 13,
icon: 'Postcard',
title: '被动挂起(解除)服务',
path: 'passivityHangUp',
children: []
}, {
id: 14,
icon: 'Postcard',
title: '卡签注销',
path: 'TABActivate',
children: []
}]
}, {
id: 15,
title: '储值卡资金服务',
path: 'home',
icon: 'CreditCard',
children: [{
id: 16,
title: '对公账户注册审核服务',
path: 'corporateaccountManage',
icon: 'Collection',
children: []
}, {
id: 17,
title: '充值及圈存服务',
path: 'home',
icon: 'CopyDocument',
children: [{
id: 18,
title: '储值卡充值服务(修复)[圈存]',
path: 'cardrechargefix',
icon: 'Notebook',
children: []
}, {
id: 19,
title: '对公账户打款充值服务',
icon: 'Plus',
path: 'advancepaymentaccount',
children: []
}]
}, {
id: 20,
title: '注销退费服务',
icon: 'Scissor',
path: 'cardrefundcostManage',
children: []
}, {
id: 21,
title: '补卡额及补交服务',
path: 'home',
icon: 'Connection',
children: [{
id: 22,
title: '储值卡-补卡额服务',
icon: 'Tickets',
path: 'supplyCardBalance',
children: []
}, {
id: 23,
title: '储值卡-补交服务',
icon: 'Box',
path: 'addsupplyCardBalance',
@@ -127,24 +168,29 @@ export const list = [
}]
}]
}, {
id: 24,
title: '系统管理',
icon: 'Notification',
children: [{
id: 25,
title: '菜单管理',
path: 'menu',
icon: 'Expand',
children: []
},{
}, {
id: 26,
title: '用户管理',
path: 'user',
icon: 'User',
children: []
},{
}, {
id: 27,
title: '角色管理',
path: 'role',
icon: 'UserFilled',
children: []
},{
}, {
id: 28,
title: '部门管理',
path: 'department',
icon: 'HomeFilled',

+ 1
- 1
src/layout/components/SidebarItem.vue Vedi File

@@ -1,5 +1,5 @@
<template>
<template v-for="item in list" :key="item.path">
<template v-for="item in list" :key="item.id">
<!-- 父级菜单 -->
<el-sub-menu
v-if="item.children && item.children.length > 0"

+ 36
- 13
src/layout/index.vue Vedi File

@@ -15,10 +15,10 @@

<!-- 菜单主体部分 height="100%" -->
<div class="as-border-width" style="height: 100%; background-color: #ffffff">
<el-scrollbar max-height="90%">
<el-scrollbar max-height="90%" wrap-class="scrollbar-wrapper">
<el-menu :default-active="menuIndex.menuIndex" mode="vertical" :router="false" @select="select"
:collapse="!menuStart.menuIsExpansion" class="el-menu-vertical-demo">
<sidebar-item :list="list" />
<sidebar-item :list="itemMenuData" />
</el-menu>
</el-scrollbar>
</div>
@@ -36,17 +36,19 @@
<!-- 头部 height: 8%;-->
<div style="background-color: #ffffff; padding: 10px 0px 10px 0px">
<!-- 选项卡 -->
<tab-container> </tab-container>
<tab-container></tab-container>

<!-- 主体内容页面 -->
<router-view name="key"></router-view>
<!-- <router-view name="key"></router-view> -->

<!-- 路由缓存 https://blog.csdn.net/kDevelop/article/details/122036896 -->
<!-- <router-view name="key" v-slot="{ Component }">
<keep-alive style="height:100vh">
<component :is="Component" />
</keep-alive>
</router-view> -->
<router-view name="key" v-slot="{ Component }">
<!-- style="height:100vh" -->
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>

</div>
</div>
</el-scrollbar>
@@ -66,8 +68,8 @@ import VideoBg from '@/components/VideoBackround/VideoBackground.vue' //视频
import BgTwo from '@/assets/video/homeBg.mp4' //视频资源
import $store from '@/store/index' // 引入vuex
import $storeTab from '@/store/tabValue' //引入tab vuex
import { list } from '@/data/menuData'
import { ref, reactive, onMounted } from 'vue'
import { list, getMenuData } from '@/data/menuData'
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { useRouter } from 'vue-router'

const bgVideo = BgTwo
@@ -75,6 +77,15 @@ const router = useRouter()
//默认菜单为打开状态
let menuStart = ref($store.state.data)
let menuIndex = ref($storeTab.state.editableTabsValue)
let itemMenuData = ref(list)
const {
proxy
}: any = getCurrentInstance();
//获取菜单数据
getMenuData(proxy, (res: any) => {
itemMenuData.value = res
}, (err: any) => { })

//处理刷新页面重置问题
onMounted(() => {
const newTab = sessionStorage.getItem('newTab')
@@ -85,8 +96,7 @@ onMounted(() => {
type: 1,
data: dataTabs,
}
console.log(dataTabs);

$storeTab.dispatch('addTab', value)
$storeTab.dispatch('updateETV', 1 + '')
$storeTab.dispatch('updateMI', `${dataTabs.title},${dataTabs.path}`)
@@ -96,6 +106,10 @@ onMounted(() => {
})
}
sessionStorage.removeItem('newTab')

//监听页面卸载(关闭)或刷新
// window.addEventListener('beforeunload', () => beforeunloadHandler())
// window.addEventListener('unload', () => unloadHandler())
})

//返回首页
@@ -130,4 +144,13 @@ function select(data: unknown) {
.bg-theme {
background-color: $test-color;
}

/* 去除进度条圆角 */
::v-deep .el-progress-bar__outer {
border-radius: 0;
}

::v-deep .el-progress-bar__inner {
border-radius: 0;
}
</style>

+ 3
- 0
src/main.ts Vedi File

@@ -15,6 +15,8 @@ import './style/main.css'
import { isValidKey } from '@/utils/utils'
//请求
import * as request from '@/api/index'
//全局配置
import { system } from '@/config'
//导出表格
//import JsonExcel from 'vue-json-excel'

@@ -27,6 +29,7 @@ const app = createApp(App)
//app.component('downloadExcel', JsonExcel)
//全局注册请求
app.config.globalProperties.$request = request;
app.config.globalProperties.$system = system;
app.use(router)
.use(Fragment.Plugin)
.use(ElementPlus, { // 使用element-plus

+ 38
- 7
src/router/index.ts Vedi File

@@ -1,18 +1,46 @@
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Cookies from 'js-cookie'
import { nextTick, getCurrentInstance } from 'vue';



//菜单数据处理
function backMenu() {
const {
proxy
}: any = getCurrentInstance();
proxy.$request.post('/menu/list', {}, {
baseURL: 'http://localhost:8081/'
}).then((res: any) => {
console.log(res.data);
res.data.forEach((item: any) => {
const menu = {
path: '/views/home',
name: 'home',
meta: { title: '主页', isAuth: true }, //用户自定内容
components: {
key: () => import('@/views/system/home/Home.vue'),
},
}
});
}).catch((err: any) => {
console.log(err, '====456');
})
}

// component: () => import('') 异步加载
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'Login',
component: () => import('@/views/system/login/Login.vue'),
path: '/', //路由地址
name: 'Login', //路由名称
component: () => import('@/views/system/login/Login.vue'),//路由页面
},
{
path: '/404',
name: '404',
component: () => import('@/views/features/404.vue'),
},
{
path: '/layout/index',
name: 'Layout',
@@ -216,21 +244,24 @@ const router = createRouter({

//新增前置路由首位
router.beforeEach((to, from, next) => {
console.log(to.path, to, from);
if (to.name) {
if (to.meta.isAuth) { //是否需要验证权限
if (Cookies.get('token')) {
next() //继续往下
nextTick(() => {
next() //继续往下

})
} else {
next({ name: 'Login' }); //没登录,跳转到login页
}
} else {
next() //继续往下
nextTick(() => {
next() //继续往下
})
}
} else { //页面不存在
next({ name: '404' });
}

})

export default router

+ 0
- 2
src/store/tabValue.ts Vedi File

@@ -102,8 +102,6 @@ export default createStore<any>({
},
//更新ETV
UpdateETV(state, value) {
console.log(value);
state.editableTabsValue.index = value;
},
//更新MI

+ 2
- 2
src/views/system/department/department.vue Vedi File

@@ -175,11 +175,11 @@ const submit = () => {
</script>
<style scoped>
/*数字文本框文本对齐方式 */
/deep/ .el-input-number .el-input__inner {
::v-deep .el-input-number .el-input__inner {
text-align: left;
}

/deep/.el-range-editor.el-input__inner {
::v-deep .el-range-editor.el-input__inner {
display: inline-flex;
align-items: center;
padding: 3px 10px;

+ 2
- 2
src/views/system/home/Home.vue Vedi File

@@ -175,11 +175,11 @@ const submit = () => {
</script>
<style scoped>
/*数字文本框文本对齐方式 */
/deep/ .el-input-number .el-input__inner {
::v-deep .el-input-number .el-input__inner {
text-align: left;
}

/deep/.el-range-editor.el-input__inner {
::v-deep .el-range-editor.el-input__inner {
display: inline-flex;
align-items: center;
padding: 3px 10px;

+ 2
- 5
src/views/system/login/Login.vue Vedi File

@@ -52,7 +52,7 @@ import {
Lock
} from '@element-plus/icons-vue'
import Cookies from 'js-cookie'
import SlideImgThreePng from '@/assets/image/slide_img_three.png';
import SlideImgThreePng from '@/assets/image/three.jpg';
//@ts-ignore 引入滑块组件
import SlidingBlockVerifyTwo from '@/components/SlidingBlockVerifyTwo/SlidingBlockVerifyTwo.vue'

@@ -66,16 +66,13 @@ const {
const slidingBlock = reactive({
marginTop: 100, //10-150
marginLeft: 100, //80-220
bgImg: "http://localhost:2222/滑块/one.jpg"
// bgImg: "http://localhost:2222/slide_img_three.jpg"
// bgImg: "http://localhost:2222/slide_img_four.jpg"
bgImg: SlideImgThreePng
})

const refresh = () => {
proxy.$request.post('initialValue', {}, {
baseURL: 'http://localhost:8081/'
}).then((res: any) => {
console.log(res.data);
slidingBlock.marginTop = res.data.coordinateX
slidingBlock.marginLeft = res.data.coordinateY
slidingBlock.bgImg = res.data.background

+ 192
- 4
src/views/system/menu/index.vue Vedi File

@@ -1,5 +1,6 @@
<template>
<crud-template :home-data="field" :tableData="list">
<crud-template v-if="itemStart" ref="crud" :home-data="field" :tableData="initMenuData" @cancel="cancel"
@submit="submit" @handleEdit="handleEdit">
<template #search="{ searchCondition }">
<el-input v-model="searchCondition.fileTwo" clearable placeholder="输入名称或邮箱名称" style="width: 200px;" />
<div>
@@ -7,19 +8,193 @@
start-placeholder="开始日期" end-placeholder="结束日期" style="margin: 0 10px 0 10px;" />
</div>
</template>

<template #dialog>
<el-form :model="item" ref="ruleFormRef" :rules="rules">
<el-form-item class="as-bold" :label-width="labelWidth" label="菜单类型">
<el-radio-group v-model="item.menuType" @change="change">
<el-radio-button :label="0">
目录
</el-radio-button>
<el-radio-button :label="1">
菜单
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item class="as-bold" :label-width="labelWidth" :label="`${menuTitle}图标`">
<div style="width: 100%">
<el-input v-model="item.menuIoc" placeholder="请输入图标名称"></el-input>
</div>
</el-form-item>
<el-form-item class="as-bold" :label-width="labelWidth" :label="`${menuTitle}标题`" prop="menuTitle">
<div style="width: 100%">
<el-input v-model="item.menuTitle" :placeholder="`请输入${menuTitle}标题`"></el-input>
</div>
</el-form-item>
<el-form-item v-if="item.menuType === 1" class="as-bold" :label-width="labelWidth" label="路由地址" prop="menuUrl">
<div style="width: 100%">
<el-input v-model="item.menuUrl" placeholder="请输入路由地址"></el-input>
</div>
</el-form-item>
<div class="as-layout-horizontal">
<el-form-item class="as-bold" :label-width="labelWidth" label="页面名称" prop="menuName">
<div style="width: 100%">
<el-input v-model="item.menuName" placeholder="请输入页面名称"></el-input>
</div>
</el-form-item>
<el-form-item class="as-bold" :label-width="labelWidth" :label="`${menuTitle}排序`">
<div v-show="false">
{{ item.menuSort = Number(item.menuSort) }}
</div>
<el-input-number :min="0" class="el-input-number" v-model="item.menuSort" style="width: 100%;"
controls-position="right">
</el-input-number>
</el-form-item>
</div>
<el-form-item class="as-bold" :label-width="labelWidth" label="上级类目" prop="menuFatherId">
<el-tree-select v-if="item.menuType === 0" check-strictly :props="props" :data="itemMenuData"
v-model="item.menuFatherId" style="width: 100%;" />
<el-tree-select v-else check-strictly :props="props" :data="initMenuData" v-model="item.menuFatherId"
style="width: 100%;" />
</el-form-item>
</el-form>
</template>

</crud-template>
</template>
<script lang="ts" setup>
// @ts-ignore crudFrom模板
import CrudTemplate from "@/crud/index.vue"
import {
list
list,
getMenuData
} from '@/data/menuData'
import {
ElNotification
} from 'element-plus'
import { nextTick, ref, reactive, getCurrentInstance, toRaw } from 'vue'

const {
proxy
}: any = getCurrentInstance();
const labelWidth = '80px'
let initMenuData = ref(list)
let itemMenuData = ref([
{
title: '顶级类目',
id: 0,
children: []
}
])
let itemStart = ref(true)
const props = {
label: 'title',
value: 'id',
children: 'children'
}
const menuTitle = ref('目录')
const initItem = {
menuType: 0,
menuName: '',
menuTitle: '',
menuPath: '',
menuIoc: '',
menuSort: 0,
menuFatherId: '',
menuUrl: '',
}
//表单校验
const crud: any = ref()
const ruleFormRef: any = ref()
const rules = reactive({
menuTitle: [{ required: true, message: '请输入菜单标题', trigger: 'blur' }],
menuName: [{ required: true, message: '请输入菜单路径', trigger: 'blur' }],
menuUrl: [{ required: true, message: '请输入路由地址', trigger: 'blur' }],
menuFatherId: [{ required: true, message: '请选择上级类目', trigger: 'blur' }],
})

let item: any = ref(initItem)

function initData() {
//获取菜单数据
getMenuData(proxy,(res: any) => {
itemMenuData.value[0].children = res
initMenuData.value = res
itemStart.value = false
nextTick(() => {
itemStart.value = true
})
}, (err: any) => { })
}
//初始化数据
initData()

//数据变化监听
const change = (value: any) => {
item.value.menuFatherId = ''
menuTitle.value = value === 0 ? '目录' : '菜单'
}

//关闭弹窗
const cancel = () => {
ruleFormRef.value.resetFields(); //重置提示
item.value = JSON.parse(JSON.stringify(initItem)) //清空数据
crud.value.reset()
}

//表单编辑按钮
const handleEdit = (idx: any, row: any) => {
const data = toRaw(row);
//数据适配器
item.value = {
id: data.id,
menuType: data.type,
menuName: data.path,
menuTitle: data.title,
menuPath: data.name, //页面路径
menuIoc: data.icon,
menuSort: data.menuSort ? data.menuSort : 0,
menuFatherId: data.fatherId,
menuUrl: data.url, //路由路径
}
}

const submit = () => {
console.log(crud.value.title);
ruleFormRef.value.validate((valid: any, fields: any) => {
if (valid) {
const url = crud.value.title === '添加' ? '/menu/add' : '/menu/update'
proxy.$request.post(url, item.value, {
baseURL: 'http://localhost:8081/'
}).then((res: any) => {
item.value = JSON.parse(JSON.stringify(initItem))
crud.value.reset()
ElNotification({
title: '提示',
message: `${crud.value.title}成功!`,
type: 'success',
})
nextTick(() => {
initData()
})
}).catch((err: any) => {
ElNotification({
title: '提示',
message: `${crud.value.title}失败!`,
type: 'error',
})
})
} else {
return false
}
})
}

const field = {
rowKey: 'title',
rowKey: 'id', //展开数据的主键(关键)
searchShow: true,
crudShow: true,
dialogCustom: true,
field: [{
prop: 'title',
label: '菜单标题',
@@ -33,7 +208,20 @@ const field = {
}
</script>
<style scoped>
/deep/.el-range-editor.el-input__inner {
::v-deep .el-range-editor.el-input__inner {
display: inline-flex;
align-items: center;
padding: 3px 10px;
height: 33px;
width: 300px;
}

/*数字文本框文本对齐方式 */
::v-deep .el-input-number .el-input__inner {
text-align: left;
}

::v-deep .el-range-editor.el-input__inner {
display: inline-flex;
align-items: center;
padding: 3px 10px;

+ 1
- 1
src/views/system/role/role.vue Vedi File

@@ -141,7 +141,7 @@ const submit = () => {

</script>
<style scoped>
/deep/.el-range-editor.el-input__inner {
::v-deep .el-range-editor.el-input__inner {
display: inline-flex;
align-items: center;
padding: 3px 10px;

+ 1
- 1
src/views/system/user/user.vue Vedi File

@@ -176,7 +176,7 @@ const submit = () => {

</script>
<style scoped>
/deep/.el-range-editor.el-input__inner {
::v-deep .el-range-editor.el-input__inner {
display: inline-flex;
align-items: center;
padding: 3px 10px;

Loading…
Annulla
Salva