xy 2 years ago
parent f7bc528572
commit ecc813dc89

@ -3,5 +3,5 @@ ENV = 'development'
# base api
VUE_APP_BASE_API='https://cz-hjjc.115.langye.net'
VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/admin/upload-file'
VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/upload-file'
VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview

@ -3,6 +3,6 @@ ENV = 'production'
# base api
VUE_APP_BASE_API='https://cz-hjjc.115.langye.net'
VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/admin/upload-file'
VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/upload-file'
VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview

@ -0,0 +1,35 @@
import request from '@/utils/request'
export function index(params) {
return request({
method: 'get',
url: '/api/oa/vehicle/index',
params
})
}
export function show(params) {
return request({
method: 'get',
url: '/api/oa/vehicle/show',
params
})
}
export function save(data, isLoading = true) {
return request({
method: 'post',
url: '/api/oa/vehicle/save',
data,
isLoading
})
}
export function destroy(params, isLoading = true) {
return request({
method: 'get',
url: '/api/oa/vehicle/destroy',
params,
isLoading
})
}

@ -0,0 +1,35 @@
import request from '@/utils/request'
export function index(params) {
return request({
method: 'get',
url: '/api/oa/vehicle-certificate/index',
params
})
}
export function show(params) {
return request({
method: 'get',
url: '/api/oa/vehicle-certificate/show',
params
})
}
export function save(data, isLoading = true) {
return request({
method: 'post',
url: '/api/oa/vehicle-certificate/save',
data,
isLoading
})
}
export function destroy(params, isLoading = true) {
return request({
method: 'get',
url: '/api/oa/vehicle-certificate/destroy',
params,
isLoading
})
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -8,10 +8,11 @@
</template>
<script>
import Cookies from "js-cookie"
import Cookies from 'js-cookie'
import chalkCss from '@/assets/chalk.js'
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
let index = 0;
let index = 0
export default {
data() {
return {
@ -19,14 +20,6 @@ export default {
theme: ''
}
},
created() {
},
mounted() {
this.$nextTick(() => {
this.theme = Cookies.get("defaultTheme") || ORIGINAL_THEME
document.body.style.setProperty('--theme-color', Cookies.get("defaultTheme"));
})
},
computed: {
},
@ -64,8 +57,9 @@ export default {
}
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
// const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
// await this.getCSSString(url, 'chalk')
this.chalk = chalkCss.replace(/@font-face{[^}]+}/, '')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
@ -84,12 +78,20 @@ export default {
})
this.$emit('change', val)
Cookies.set("defaultTheme", val)
document.body.style.setProperty('--theme-color', val);
index++;
Cookies.set('defaultTheme', val)
document.body.style.setProperty('--theme-color', val)
index++
$message?.close()
}
},
created() {
},
mounted() {
this.$nextTick(() => {
this.theme = Cookies.get('defaultTheme') || ORIGINAL_THEME
document.body.style.setProperty('--theme-color', Cookies.get('defaultTheme'))
})
},
methods: {
updateStyle(style, oldCluster, newCluster) {

@ -0,0 +1 @@
<svg t="1728372298341" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8336" width="200" height="200"><path d="M256.26 440.16a32 32 0 0 0 32 32H737a18 18 0 0 0 2.43-0.11 24.33 24.33 0 0 0 3-0.58l0.47-0.12a32 32 0 0 0 26.1-33.62c-0.11-1.27-9.15-104.63 46.35-325.81a1.42 1.42 0 0 1 0.12-0.7 28.9 28.9 0 0 0 0.46-3.25 28.87 28.87 0 0 0 0.35-3.36V104c0-0.69-0.23-1.39-0.23-2.08-0.12-1.16-0.12-2.44-0.35-3.6a21.73 21.73 0 0 0-0.81-2.89 22.51 22.51 0 0 0-0.93-3 28.18 28.18 0 0 0-1.28-2.9c-0.45-0.93-0.92-1.85-1.38-2.66s-1.16-1.63-1.86-2.44-1.27-1.62-2-2.43-1.5-1.39-2.2-2.09-1.62-1.39-2.43-2-1.74-1-2.66-1.62a21 21 0 0 0-2.67-1.51 28.21 28.21 0 0 0-3.36-1.15c-0.7-0.24-1.27-0.58-2.09-0.81a1.4 1.4 0 0 1-0.69-0.12 26.49 26.49 0 0 0-3.25-0.46l-3.24-0.35H336.2c-0.81 0-1.5 0.23-2.32 0.23a31.77 31.77 0 0 0-3.36 0.35 29.84 29.84 0 0 0-3.12 0.81 23.7 23.7 0 0 0-2.78 0.81c-1.05 0.46-2.09 0.93-3.13 1.51-0.81 0.46-1.63 0.81-2.44 1.27a23.14 23.14 0 0 0-2.66 2 16.28 16.28 0 0 0-2.2 1.86 19.12 19.12 0 0 0-2.09 2.31c-0.69 0.81-1.27 1.51-1.85 2.32s-1.16 1.85-1.74 2.78a19.64 19.64 0 0 0-1.39 2.66 30.13 30.13 0 0 0-1.12 3.38c-0.23 0.7-0.58 1.28-0.81 2.09-51.25 204.39-49.87 312.61-48.47 339.73a22.33 22.33 0 0 0-0.47 4.17z m135-292.33h290a30.59 30.59 0 1 1 0 61.18h-290a30.59 30.59 0 0 1 0-61.18z m-20.74 161h290a30.59 30.59 0 1 1 0 61.18h-290a30.59 30.59 0 1 1 0-61.18z" p-id="8337"></path><path d="M896.16 440.16v64H128.08v-64C92.62 441 64 469.6 64 504.93v382.25c0 35.8 29.32 64.88 65.47 64.88h765.07c36.15 0 65.46-29.08 65.46-64.88V505.05c0.12-35.45-28.39-64.05-63.84-64.89z m-64.07 368A64.1 64.1 0 0 1 768 872.23H256.11A64.08 64.08 0 0 1 192 808.16v-64.08h640.09z m16.1-192a31.72 31.72 0 0 1-27.69-16 32.16 32.16 0 0 1 0-32 31.73 31.73 0 0 1 27.69-16 32 32 0 0 1 0 64z" p-id="8338"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -0,0 +1 @@
<svg t="1728357749350" class="icon" viewBox="0 0 1027 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4289" width="200" height="200"><path d="M908.41987514 559.81019253A58.52549952 58.52549952 0 0 0 840.79919685 511.96164193c-5.53619554 0-15.42226015-10.28150677-18.1903583-17.79491538q-26.494652-66.82979322-50.61664798-134.84591444a83.04293845 83.04293845 0 0 0-58.52549953-54.96651629c-39.54425615-10.28150677-79.08851305-16.60858738-116.26011398-24.51743892A567.85552279 567.85552279 0 0 0 509.02288524 274.69610352a195.34862703 195.34862703 0 0 0-53.38474616-100.44241168A191.7896438 191.7896438 0 0 0 315.25602836 116.51907739a201.67570765 201.67570765 0 0 0-140.38211074 57.73461446A200.88482257 200.88482257 0 0 0 117.53474609 314.24035966a197.72128226 197.72128226 0 0 0 57.33917153 139.98666781 185.85800534 185.85800534 0 0 0 33.61261846 26.89009493l-5.93163847 15.81770229c-2.76809815 6.72252353-11.86327693 17.0040303-16.60858815 16.60858738C145.21572531 508.40265869 129.39802302 532.92009761 117.53474609 564.55550299a45.47589461 45.47589461 0 0 0 0 19.37668553l42.31235429 11.07239185c0 57.73461445 0 115.07378597-2.37265522 172.41295826v92.53356013a70.78421937 70.78421937 0 0 0 14.23593216 41.91691215 375.67043607 375.67043607 0 0 0 129.70516104 0c9.09517877-3.55898323 13.44504707-48.24399276 20.56301353-75.13408768h384.76561561c9.4906217 25.308324-8.69973662 56.54828645 20.56301276 75.13408768a370.13424053 370.13424053 0 0 0 126.54162074-2.372656 62.47992491 62.47992491 0 0 0 13.44504707-36.38071584v-219.0751801a398.60610484 398.60610484 0 0 0-5.53619553-47.8485506l46.6622226-12.25871985a51.01209091 51.01209091 0 0 0 0-24.12199599zM157.07900224 314.24035966a160.9451235 160.9451235 0 0 1 45.87133752-111.91024566A161.73600858 161.73600858 0 0 1 315.25602836 156.06333431a151.84994474 151.84994474 0 0 1 112.30568859 46.26677969A154.22259997 154.22259997 0 0 1 468.68774323 274.69610352c0 4.3498683 0 8.69973662 2.37265524 13.44504706A161.34056642 161.34056642 0 0 1 473.43305448 314.24035966a158.17702612 158.17702612 0 0 1-2.76809816 29.65819229 162.13145151 162.13145151 0 0 1-43.10323937 82.25205338A161.73600858 161.73600858 0 0 1 315.25602836 472.41738578a166.48131981 166.48131981 0 0 1-39.54425614-5.53619631 158.17702612 158.17702612 0 0 1-26.494652-9.09517877 140.77755289 140.77755289 0 0 1-23.72655384-13.44504707 152.64082981 152.64082981 0 0 1-20.56301353-17.39947322A158.17702612 158.17702612 0 0 1 157.07900224 314.24035966z m172.01751611 395.44256452a192.97597181 192.97597181 0 0 1-42.3123543 3.55898323c-20.56301353-1.97721308-39.54425615-2.76809815-61.6890406-6.72252354-26.09920907-5.53619554-33.61261768-24.51743892-25.70376615-58.92094245 5.53619554-23.33111168 24.12199676-24.51743892 39.54425615-18.9812426a923.75383041 923.75383041 0 0 1 98.86064074 39.54425614c7.90885154 3.55898323 17.0040303 18.58580047 15.02681801 24.12199677a39.54425615 39.54425615 0 0 1-23.72655385 17.39947245z m-75.92497275-184.27623519l7.90885153-21.35389783A204.04836365 204.04836365 0 0 0 315.25602836 511.96164193a201.67570765 201.67570765 0 0 0 140.38211073-57.73461446 202.07115057 202.07115057 0 0 0 54.17563123-108.74670535c51.80297599 0 103.21050905 2.76809815 155.01348503 4.74531122a65.64346598 65.64346598 0 0 1 65.64346598 52.59386106c11.07239183 39.54425615 25.70376692 79.08851305 39.54425615 122.58719459a1249.20306141 1249.20306141 0 0 1-516.84343188 0z m553.61959065 178.74003966a564.69198172 564.69198172 0 0 1-62.08448276 7.90885076 445.26832743 445.26832743 0 0 1-53.38474614-4.74531047c-19.77212846-4.3498683-26.09920907-27.28553707-8.69973662-35.58983075a856.92403718 856.92403718 0 0 1 118.63276921-45.08045244c16.21314523-5.14075339 27.28553707 8.30429369 28.07642215 26.09920907s5.14075339 44.68500952-24.51743893 51.40753383z" p-id="4290"></path><path d="M394.34454142 353.78461657V314.24035966H315.25602836V235.1518466H275.71177221v118.63276997h118.6327692z" p-id="4291"></path></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

@ -1,10 +1,12 @@
<template>
<div class="sidebar-item" v-if="!item.hidden">
<div v-if="!item.hidden" class="sidebar-item">
<template
v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"
>
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)">
<icon :icon="onlyOneChild.meta.icon"></icon>{{ onlyOneChild.meta.title }}
<icon :icon="onlyOneChild.meta.icon" />
<span>{{ onlyOneChild.meta.title }}</span>
</el-menu-item>
</app-link>
</template>
@ -12,13 +14,16 @@
<template v-else>
<el-submenu ref="subMenu" :index="/^\/+/.test(resolvePath(item.path)) ? Math.random().toString() : resolvePath(item.path)" popper-append-to-body>
<template slot="title">
<icon :icon="item.meta.icon"></icon>{{ item.meta.title }}
<icon :icon="item.meta.icon" />
<span>{{ item.meta.title }}</span>
</template>
<navbar-item v-for="child in item.children"
:key="child.path"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu" />
<navbar-item
v-for="child in item.children"
:key="child.key"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-submenu>
</template>
</div>
@ -28,7 +33,7 @@
import path from 'path'
import AppLink from '../Sidebar/Link.vue'
import { isExternal } from '@/utils/validate'
import Icon from "./Icon.vue"
import Icon from './Icon.vue'
export default {
name: 'NavbarItem',
@ -39,17 +44,19 @@ export default {
props: {
item: {
type: Object,
required: true,
required: true
},
basePath: {
type: String,
default: "",
},
default: ''
}
},
data() {
return {
onlyOneChild: null,
};
onlyOneChild: null
}
},
computed: {
},
methods: {
resolvePath(routePath) {
@ -89,11 +96,9 @@ export default {
}
return false
},
},
computed: {
},
};
}
}
}
</script>
<style scoped lang="scss"></style>

@ -1,45 +1,54 @@
<template>
<div>
<header class="navbar navbar-expand-md d-print-none">
<div class="container-xl">
<button v-show="$store.state.app.device === 'mobile'" :aria-expanded="isShowMenuMobile" class="navbar-toggler" @click="isShowMenuMobile = !isShowMenuMobile">
<span class="navbar-toggler-icon" />
</button>
<div class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
<header class="navbar">
<div class="container">
<!-- <button v-show="$store.state.app.device === 'mobile'" :aria-expanded="isShowMenuMobile" class="navbar-toggler" @click="isShowMenuMobile = !isShowMenuMobile">-->
<!-- <span class="navbar-toggler-icon" />-->
<!-- </button>-->
<div class="navbar-brand">
<router-link to="/">
<img :src="require('@/assets/title.png')" style="height: 20px;filter: drop-shadow(0 2px 4px #00000088)" alt="">
<img class="navbar-brand__logo" :src="require('@/assets/logo-mini.png')" alt="">
<img class="navbar-brand__img" :src="require('@/assets/title.png')" alt="">
</router-link>
</div>
<div class="navbar-module" @click="isShowMenuMobile = !isShowMenuMobile">
<svg-icon icon-class="modules" class-name="modules__toggler" />
<el-menu
id="navbar-menu"
:text-color="variables.menuText"
:background-color="variables.menuBg"
:active-text-color="variables.menuActiveText"
:default-active="activeMenu"
mode="horizontal"
>
<Item v-for="(item) in permission_routes" :key="item.key" :item="item" :base-path="item.path" />
</el-menu>
</div>
<div class="navbar-nav flex-row order-md-last">
<div class="d-none d-md-flex">
<div class="tool">
<template v-if="isFullscreen">
<a class="nav-link px-0 fullscreen" @click="fullscreen">
<div class="tool-item fullscreen" @click="fullscreen">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path stroke-width="2" d="M 4 8 l 4 0 l 0 -4 M 16 4 l 0 4 l 4 0 M 20 16 l -4 0 l 0 4 M 8 20 l 0 -4 l -4 0" />
</svg>
</a>
</div>
</template>
<template v-else>
<a class="nav-link px-0 fullscreen" @click="fullscreen">
<div class="tool-item fullscreen" @click="fullscreen">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path stroke-width="2" d="M 4 8 l 0 -4 l 4 0 M 16 4 l 4 0 l 0 4 M 20 16 l 0 4 l -4 0 M 8 20 l -4 0 l 0 -4" />
</svg>
</a>
</div>
</template>
<div class="nav-item d-md-flex">
<theme-picker class="nav-link" />
</div>
<div class="nav-item d-none d-md-flex me-3">
<a class="nav-link px-0" data-bs-toggle="dropdown" tabindex="-1" aria-label="Show notifications">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6" /><path d="M9 17v1a3 3 0 0 0 6 0v-1" /></svg>
<span class="badge bg-red" />
</a>
</div>
<theme-picker class="tool-item" />
<el-badge :is-dot="device === 'mobile'" :max="99" :value="12" class="tool-item">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6" /><path d="M9 17v1a3 3 0 0 0 6 0v-1" /></svg>
</el-badge>
</div>
<div class="nav-item">
<el-dropdown @command="userCommandHandle">
<a class="nav-link d-flex lh-1 text-reset p-0" aria-label="Open user menu">
<el-dropdown @command="userCommandHandle">
<a class="nav-link d-flex lh-1 text-reset p-0 nav-info">
<img class="avatar avatar-sm" style="" src="@/assets/face.jpg" alt="">
<div class="d-none d-xl-block ps-2">
<div>{{ name }}</div>
@ -53,7 +62,7 @@
<span style="padding-left: 8px;">用户信息</span>
</el-dropdown-item>
<el-dropdown-item command="password">
<SvgIcon icon-class="password"/>
<SvgIcon icon-class="password" />
<span style="padding-left: 8px;">修改密码</span>
</el-dropdown-item>
<el-dropdown-item divided command="logout">
@ -68,36 +77,33 @@
</header>
<header class="navbar-expand-md">
<div id="navbar-menu" class="navbar-collapse" v-if="$store.state.app.device === 'desktop'">
<el-menu
style="width: 100%;padding: 0 10px;"
:text-color="variables.menuText"
:background-color="variables.menuBg"
:active-text-color="variables.menuActiveText"
:default-active="activeMenu"
mode="horizontal"
>
<Item v-for="(item, index) in permission_routes" :key="item.key" :item="item" :base-path="item.path" />
</el-menu>
</div>
<!-- <div v-if="$store.state.app.device === 'desktop'" id="navbar-menu" class="navbar-collapse">-->
<!-- <el-menu-->
<!-- style="width: 100%;padding: 0 10px;"-->
<!-- :text-color="variables.menuText"-->
<!-- :background-color="variables.menuBg"-->
<!-- :active-text-color="variables.menuActiveText"-->
<!-- :default-active="activeMenu"-->
<!-- mode="horizontal"-->
<!-- >-->
<!-- <Item v-for="(item) in permission_routes" :key="item.key" :item="item" :base-path="item.path" />-->
<!-- </el-menu>-->
<!-- </div>-->
<div id="navbar-menu-mobile" class="navbar-collapse collapse" v-else>
<div id="navbar-menu-mobile" class="navbar-collapse collapse" :style="{ zIndex: zIndex }">
<transition name="fade-transform-y">
<div class="navbar" v-show="isShowMenuMobile">
<div class="container-xl">
<div class="row flex-fill align-items-center">
<el-menu
unique-opened
style="width: 100%;padding: 0 10px;"
:text-color="variables.menuText"
:background-color="variables.menuBg"
:active-text-color="variables.menuActiveText"
:default-active="activeMenu"
>
<Item v-for="(item, index) in permission_routes" :key="item.key" :item="item" :base-path="item.path" />
</el-menu>
</div>
</div>
<div v-show="isShowMenuMobile" class="navbar">
<el-menu
unique-opened
style="width: 100%;padding: 0 6px;"
:text-color="variables.menuText"
:background-color="variables.menuBg"
:active-text-color="variables.menuActiveText"
:default-active="activeMenu"
@select="isShowMenuMobile = false"
>
<Item v-for="(item) in permission_routes" :key="item.key" :item="item" :base-path="item.path" />
</el-menu>
</div>
</transition>
</div>
@ -111,6 +117,7 @@ import { mapGetters } from 'vuex'
import Item from './Item.vue'
import SvgIcon from '@/components/SvgIcon/index.vue'
import ThemePicker from '@/components/ThemePicker/index.vue'
import { PopupManager } from 'element-ui/lib/utils/popup'
export default {
components: {
ThemePicker,
@ -119,8 +126,9 @@ export default {
},
data() {
return {
zIndex: PopupManager.nextZIndex(),
isFullscreen: false,
isShowMenuMobile: true,
isShowMenuMobile: false,
}
},
computed: {
@ -132,7 +140,8 @@ export default {
'avatar',
'name',
'permission_routes',
'department'
'department',
'device'
]),
activeMenu() {
const route = this.$route
@ -147,6 +156,13 @@ export default {
return path
}
},
watch: {
isShowMenuMobile(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
},
created() {
},
mounted() {
@ -169,16 +185,16 @@ export default {
}
},
async userCommandHandle (command) {
switch (command){
case "logout":
await this.logout();
break;
async userCommandHandle(command) {
switch (command) {
case 'logout':
await this.logout()
break
}
},
async logout() {
await this.$store.dispatch('user/logout')
await this.$store.commit('permission/SET_ROUTES',[])
await this.$store.commit('permission/SET_ROUTES', [])
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
}
}
@ -187,4 +203,5 @@ export default {
<style lang="scss" scoped>
@import url('~@/styles/navbar.scss');
</style>

@ -1,19 +1,16 @@
<template>
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<!-- <sidebar class="sidebar-container" />-->
<navbar></navbar>
<navbar />
<div class="main-container">
<div :class="{'fixed-header':fixedHeader}">
<!-- <navbar />-->
</div>
<div :class="{'fixed-header':fixedHeader}" />
<app-main />
</div>
</div>
</template>
<script>
import Navbar from "./components/Navbar"
import Navbar from './components/Navbar'
import { AppMain } from './components'
import ResizeMixin from './mixin/ResizeHandler'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,35 +1,64 @@
@import "variables";
#navbar-menu {
.sidebar-item {
display: inline-block;
.el-menu-item:hover ,.el-submenu__title:hover {
color: $menuActiveText !important;
background-color: transparent !important;
}
}
.el-menu-item, .el-submenu__title {
height: 50px;
line-height: 50px;
height: 54px;
line-height: 54px;
}
.el-submenu__icon-arrow {
position: initial;
margin-top: 0;
display: none;
}
}
.navbar {
.el-menu--horizontal {
border-bottom: none !important;
overflow: hidden;
white-space: nowrap;
}
}
.el-menu--collapse .el-menu .el-submenu, .el-menu--popup {
text-align: center;
min-width: 120px !important;
min-width: 124px !important;
background-color: $subMenuBg !important;
}
.el-menu--horizontal .el-menu .el-menu-item, .el-menu--horizontal .el-menu .el-submenu__title {
color: $subMenuText !important;
}
#navbar-menu-mobile {
position: absolute;
left: 0;
right: 0;
box-shadow: 0 1px 6px rgba(0,0,0,.2);
.el-menu {
border-right: none;
.el-menu-item, .el-submenu__title{
font-size: var(--tblr-nav-link-font-size);
height: auto;
line-height: inherit;
min-height: 2rem;
padding: .5rem calc(calc(var(--tblr-page-padding)* 2) / 2);
display: flex;
align-items: center;
}
.el-submenu.is-active .el-submenu__title {
border-bottom: 0;
color: var(--theme-color);
}
}
.el-menu {
background-color: #fff !important;
}
.sidebar-item {
.el-menu-item ,.el-submenu__title {
color: #333 !important;
background-color: #fff !important;
}
}
}

@ -2,15 +2,16 @@
:root {
--theme-color: #5898f2;
}
$menuText:#333;
$menuActiveText: var(--theme-color);
$menuText: hsla(0,0%,100%,.7);
$subMenuText: #333;
$menuActiveText: #fff;
$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
$menuBg:#fff;
$menuHover:#263445;
$menuBg: transparent;
$menuHover: transparent;
$subMenuBg:#1f2d3d;
$subMenuHover:#001528;
$subMenuBg: #fff;
$subMenuHover: #001528;
$sideBarWidth: 210px;
$navBarHeight: 200px;

@ -1,46 +1,50 @@
<template>
<div>
<vxe-modal :value="isShow"
show-footer
:z-index="zIndex"
title="权限菜单"
show-confirm-button
:width="600"
:height="600"
esc-closable
@input="e => $emit('update:isShow',e)">
<vxe-modal
:value="isShow"
show-footer
:z-index="zIndex"
title="权限菜单"
show-confirm-button
:width="600"
:height="600"
esc-closable
@input="e => $emit('update:isShow',e)"
>
<el-form ref="elForm" :model="form" :rules="rules" label-position="top" label-width="100">
<el-form-item label="父级菜单" prop="pid" required>
<Treeselect v-model="form.pid"
:options="list"
noChildrenText="无子菜单"
:normalizer="node => ({
id: node.id,
label: node.name,
children: node.children,
isDefaultExpanded: true
})"></Treeselect>
<Treeselect
v-model="form.pid"
:options="list"
no-children-text="无子菜单"
:normalizer="node => ({
id: node.id,
label: node.name,
children: node.children,
isDefaultExpanded: true
})"
/>
</el-form-item>
<el-form-item label="名称" prop="name" required>
<el-input v-model="form.name" clearable></el-input>
<el-input v-model="form.name" clearable />
</el-form-item>
<el-form-item label="图标" prop="icon">
<el-input v-model="form.icon" clearable></el-input>
<el-input v-model="form.icon" clearable />
</el-form-item>
<el-form-item label="路由路径" prop="path" required>
<el-input v-model="form.path" clearable></el-input>
<el-input v-model="form.path" clearable />
</el-form-item>
<el-form-item label="页面模块路径" prop="url">
<el-input v-model="form.url" clearable></el-input>
<el-input v-model="form.url" clearable />
</el-form-item>
<el-form-item label="api前缀" prop="api_profix" required>
<el-input v-model="form.api_profix" clearable></el-input>
<el-input v-model="form.api_profix" clearable />
</el-form-item>
<el-form-item label="是否可见" prop="visible">
<el-switch v-model="form.visible" :active-value="1" :inactive-value="0" active-text="显示" inactive-text="隐藏"></el-switch>
<el-switch v-model="form.visible" :active-value="1" :inactive-value="0" active-text="" inactive-text="" />
</el-form-item>
<el-form-item label="排序" prop="sortnumber">
<el-input-number controls-position="right" :precision="0" v-model="form.sortnumber"></el-input-number>
<el-input-number v-model="form.sortnumber" controls-position="right" :precision="0" />
</el-form-item>
</el-form>
@ -53,10 +57,10 @@
<script>
import { PopupManager } from 'element-ui/lib/utils/popup'
import { menuSave } from "@/api/module"
import { menuSave } from '@/api/module'
export default {
props: {
moduleId: [String,Number],
moduleId: [String, Number],
list: {
type: Array,
default: () => []
@ -71,62 +75,62 @@ export default {
return {
loading: false,
form: {
name: "",
name: '',
pid: 0,
icon: "",
icon: '',
visible: 1,
path: "",
url: "",
api_profix: "",
path: '',
url: '',
api_profix: '',
sortnumber: 0
},
rules: {
name: [
{ required: true, message: "请输入名称" }
{ required: true, message: '请输入名称' }
],
path: [
{ required: true, message: "请输入路由路径" },
{ required: true, message: '请输入路由路径' }
],
api_profix: [
{ required: true, message: "请输入api前缀" }
{ required: true, message: '请输入api前缀' }
]
},
zIndex: PopupManager.nextZIndex(),
zIndex: PopupManager.nextZIndex()
}
},
computed: {
},
watch: {
isShow(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
},
methods: {
setPid (pid) {
this.form.pid = pid;
setPid(pid) {
this.form.pid = pid
},
submit () {
this.$refs["elForm"].validate(async valid => {
submit() {
this.$refs['elForm'].validate(async valid => {
if (valid) {
this.loading = true
try {
this.form.module_id = this.moduleId
await menuSave(this.form)
this.$message.success("新增成功")
this.$message.success('新增成功')
this.$emit('refresh')
this.$emit('update:isShow',false)
this.$emit('update:isShow', false)
this.loading = false
this.$refs["elForm"].resetFields()
this.$refs['elForm'].resetFields()
} catch (err) {
this.loading = false
}
}
})
}
},
computed: {
},
watch: {
isShow(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
}
}
</script>

@ -0,0 +1,189 @@
<template>
<div>
<vxe-modal
:value="isShow"
show-footer
title="车船管理"
show-confirm-button
:width="840"
:height="620"
esc-closable
@input="e => $emit('update:isShow',e)"
>
<el-form ref="elForm" :model="form" :rules="rules" label-position="top" label-width="100">
<el-form-item label="型号" prop="name" required>
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="号码" prop="license" required>
<el-input v-model="form.license" />
</el-form-item>
<el-form-item label="驾驶员" prop="driver" required>
<el-input v-model="form.driver" />
</el-form-item>
<el-form-item label="照片" prop="photo_file_id" required>
<el-upload
:action="action"
:headers="{
Authorization: `Bearer ${getToken()}`
}"
:file-list="fileList"
:before-upload="beforePhotoUpload"
list-type="picture"
:limit="1"
:on-success="photoSuccess"
:on-remove="photoRemove"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过10Mb</div>
</el-upload>
</el-form-item>
<el-form-item label="上牌日期" prop="start_date">
<el-date-picker v-model="form.start_date" style="width: 100%;" value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item label="保险到期日期" prop="insurance_expire">
<el-date-picker v-model="form.insurance_expire" style="width: 100%;" value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item label="年检日期" prop="inspect_date">
<el-date-picker v-model="form.inspect_date" style="width: 100%;" value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item label="保养日期" prop="maintain_expire">
<el-date-picker v-model="form.maintain_expire" style="width: 100%;" value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item label="报废日期" prop="discard_date">
<el-date-picker v-model="form.discard_date" style="width: 100%;" value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item label="所在部门" prop="department_id">
<el-select v-model="form.department_id" style="width: 100%;">
<el-option v-for="item in departments" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="归属结束日期" prop="end_date">
<el-date-picker v-model="form.end_date" style="width: 100%;" value-format="yyyy-MM-dd" />
</el-form-item>
<el-form-item label="车辆状态" prop="status">
<el-select v-model="form.status" style="width: 100%;">
<el-option :value="1" label="正常可用" />
<el-option :value="-1" label="维修中" />
</el-select>
</el-form-item>
<el-form-item label="是否开放精准预约" prop="is_open_detail">
<el-select v-model="form.is_open_detail" style="width: 100%;">
<el-option :value="1" label="开放" />
<el-option :value="0" label="不开放" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" :loading="loading" @click="submit"></el-button>
</template>
</vxe-modal>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
import { save } from '@/api/vehicle'
export default {
props: {
departments: {
type: Array,
default: () => []
},
isShow: {
type: Boolean,
default: false,
required: true
}
},
data() {
return {
action: process.env.VUE_APP_UPLOAD_API,
fileList: [],
loading: false,
form: {
name: '',
license: '',
driver: '',
photo_file_id: '',
start_date: '',
insurance_expire: '',
maintain_expire: '',
status: 1,
department_id: '',
discard_date: '',
inspect_date: '',
is_open_detail: 1,
type: '',
end_date: ''
},
rules: {
name: [
{ required: true, message: '请填写型号' }
],
license: [
{ required: true, message: '请填写号码' }
],
driver: [
{ required: true, message: '请填写驾驶员' }
],
photo_file_id: [
{ required: true, message: '请上传照片' }
]
}
}
},
computed: {},
methods: {
getToken,
setType(type) {
this.form.type = type
},
photoRemove() {
this.form.photo_file_id = ''
},
photoSuccess(response, file, fileList) {
this.fileList = fileList
this.form.photo_file_id = this.fileList[0]?.response?.data?.id
},
beforePhotoUpload(file) {
const isJPG = file.type === 'image/jpeg'
const isLt10M = file.size / 1024 / 1024 < 10
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!')
}
if (!isLt10M) {
this.$message.error('上传头像图片大小不能超过 10MB!')
}
return isJPG && isLt10M
},
submit() {
this.$refs['elForm'].validate(async valid => {
if (valid) {
this.loading = true
try {
await save(this.form)
this.$message.success('新增成功')
this.$emit('refresh')
this.$emit('update:isShow', false)
this.loading = false
this.$refs['elForm'].resetFields()
} catch (err) {
this.loading = false
}
}
})
}
}
}
</script>
<style scoped lang="scss">
::v-deep .el-form {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 10px 20px;
}
</style>

@ -0,0 +1,229 @@
<template>
<div>
<card-container>
<vxe-toolbar>
<template #buttons>
<el-button icon="el-icon-plus" type="primary" size="small" @click="$refs['AddVehicle'].setType('vehicle'),isShowAdd = true">新增车辆</el-button>
<el-button icon="el-icon-plus" type="primary" size="small" @click="$refs['AddVehicle'].setType('boat'),isShowAdd = true">新增艇</el-button>
<el-button icon="el-icon-search" type="primary" plain size="small" @click="getList"></el-button>
</template>
</vxe-toolbar>
<vxe-table
ref="table"
stripe
style="margin-top: 10px;"
:loading="loading"
keep-source
show-overflow
:column-config="{ resizable: true }"
:edit-rules="validRules"
:edit-config="{ trigger: 'manual', mode: 'row', showStatus: true, isHover: true, autoClear: false }"
:align="allAlign"
:data="tableData"
>
<vxe-column type="seq" width="58" align="center" />
<vxe-column field="date" width="170" title="日期" :edit-render="{}">
<template #edit="{ row }">
<el-date-picker style="width: 100%;" v-model="row.date" value-format="yyyy-MM-dd" />
</template>
</vxe-column>
<vxe-column field="type" title="类型" width="120" :edit-render="{}">
<template #edit="{ row }">
<el-select v-model="row.type">
<el-option value="workday" label="工作日" />
<el-option value="holiday" label="节假日" />
</el-select>
</template>
</vxe-column>
<vxe-column field="reason" min-width="180" title="说明" align="center" :edit-render="{ name: 'input', attrs: { type: 'text' } }" />
<vxe-column field="operate" title="操作" min-width="220">
<template #default="{ row }">
<template v-if="isActiveStatus(row)">
<el-button size="small" type="primary" @click="saveRowEvent(row)"></el-button>
<el-button size="small" type="primary" plain @click="cancelRowEvent(row)"></el-button>
</template>
<template v-else>
<el-button size="small" type="warning" @click="editRowEvent(row)"></el-button>
<el-button size="small" type="danger" @click="destroyRowEvent(row)"></el-button>
</template>
</template>
</vxe-column>
</vxe-table>
<el-pagination
style="margin-top: 10px;"
:current-page="select.page"
:page-sizes="[20, 30, 40, 50]"
:page-size="select.page_size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="e => {
select.page_size = e;
select.page = 1;
getList();
}"
@current-change="e => {
select.page = e;
getList();
}"
/>
</card-container>
<add-vehicle ref="AddVehicle" :departments="departments" :is-show.sync="isShowAdd" @refresh="getList" />
</div>
</template>
<script>
import { index as departmentIndex } from '@/api/department'
import { deepCopy } from '@/utils'
import { index, save, destroy } from '@/api/vehicle'
import AddVehicle from './components/AddVehicle.vue'
export default {
components: {
AddVehicle
},
data() {
return {
departments: [],
isShowAdd: false,
loading: false,
select: {
page: 1,
page_size: 20
},
total: 0,
allAlign: null,
tableData: [],
validRules: {
name: [
{ required: true, message: '请输入角色' }
]
},
form: {
id: '',
name: '',
license: '',
driver: '',
photo_file_id: '',
start_date: '',
insurance_expire: '',
maintain_expire: '',
status: 1,
department_id: '',
discard_date: '',
inspect_date: '',
is_open_detail: '',
type: '',
end_date: ''
}
}
},
computed: {
isActiveStatus() {
return function(row) {
if (this.$refs['table']) {
return this.$refs['table'].isEditByRow(row)
}
}
}
},
created() {
this.getDepartments()
this.getList()
},
methods: {
editRowEvent(row) {
if (this.$refs['table']) {
this.$refs['table'].setEditRow(row)
}
},
cancelRowEvent(row) {
if (this.$refs['table']) {
this.$refs['table'].clearEdit().then(() => {
//
this.$refs['table'].revertData(row)
})
}
},
async getDepartments() {
try {
this.departments = await departmentIndex({
page: 1,
page_size: 9999
})
} catch (err) {
console.error(err)
}
},
async getList() {
this.loading = true
try {
const res = await index(this.select)
this.tableData = res.data
this.total = res.total
this.loading = false
} catch (err) {
console.error(err)
this.loading = false
}
},
async saveRowEvent(row) {
try {
await this.$confirm('确认保存?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消'
})
await this.$refs['table'].clearEdit()
const form = deepCopy(this.form)
for (const key in form) {
form[key] = row[key]
}
if (!form.password) {
delete form.password
}
this.loading = true
await save(form)
await this.getList()
this.loading = false
} catch (err) {
this.loading = false
}
},
async destroyRowEvent(row) {
try {
await this.$confirm('确认删除?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消'
})
this.loading = true
if (row.id) {
await destroy({
id: row.id
})
await this.getList()
} else {
console.log(row)
this.tableData.splice(this.tableData.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY), 1)
}
this.loading = false
} catch (err) {
this.loading = false
}
}
}
}
</script>
<style scoped lang="scss">
.total {
color: #666;
text-align: right;
line-height: 3;
}
::v-deep .el-tag + .el-tag {
margin-left: 4px;
}
</style>
Loading…
Cancel
Save