Commit 7cab68d9 by chehuidong

Merge branch 'taskManage' into 'dev'

Task manage

See merge request !2
parents 80cc2748 c8e002c5
......@@ -17,5 +17,8 @@ module.exports = {
'space-before-function-paren': 'off',
indent: 'off',
'multiline-ternary': 'off',
"vue/multi-word-component-names":"off",
'eol-last': 0,
'vue/no-mutating-props':"off"
},
}
......@@ -2,7 +2,7 @@
node_modules
/dist
package-lock.json
# local env files
.env.local
.env.*.local
......
{
"tabWidth": 2,
"singleQuote": true,
"printWidth": 80,
"semi": false,
"trailingComma": "none",
"bracketSpacing": true,
"bracketSameLine": true,
"arrowParens": "always",
"htmlWhitespaceSensitivity": "ignore"
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -8,6 +8,8 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^1.0.2",
"axios": "^1.1.3",
"core-js": "^3.8.3",
"element-ui": "^2.15.10",
......
window.apiHostSetting = {
VUE_APP_BASE_URL: '',
VUE_APP_BASE_URL: 'https://dbh.joshine.cn',
}
import axios from './axios'
export function getLoginState({ userName, password }) {
return axios.post('sys/saasUserLogin/login', null, {
params: { userName, password },
})
export function getLoginState({ account, password }) {
return axios.post('platform/user/login', { account, password })
}
export function logout() {
return axios.get('sys/saasUserLogin/logout')
return axios.get('platform/user/logout')
}
import axios from './axios'
export function uploadImg(file, params = {}) {
const from = new FormData()
from.append('file', file)
const { url, ...otherParams } = params
for (const key in otherParams) {
from.append(key, otherParams[key])
}
return axios.post(url || 'upload/fileUpload/images', from, {
headers: { 'content-type': 'multipart/form-data' },
})
}
\ No newline at end of file
......@@ -61,3 +61,15 @@
.el-dialog__body {
padding: 10px;
}
.pagination {
text-align: center;
padding-top: 10px;
}
.icon-view{
font-size: 18px;
cursor: pointer;
}
.icon-view + .icon-view{
margin-left: 10px;
}
\ No newline at end of file
<script>
function getStartTime() {
const date = new Date()
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
return `${year}-${month}-${day} 00:00:00`
}
const pickerOptions = {
shortcuts: [
{
text: '今日',
onClick(picker) {
const start = new Date(
new Date(getStartTime()).getTime(),
)
const end = new Date()
picker.$emit('pick', [start, end])
},
},
{
text: '昨天',
onClick(picker) {
const start = new Date()
const end = new Date(
new Date(getStartTime()).getTime() - 1,
)
start.setTime(
end.getTime() - 3600 * 1000 * 24 * 1 + 1,
)
console.log(start, end)
picker.$emit('pick', [start, end])
},
},
{
text: '最近7天',
onClick(picker) {
const end = new Date()
const start = new Date(getStartTime())
start.setTime(
start.getTime() - 3600 * 1000 * 24 * 6,
)
picker.$emit('pick', [start, end])
},
},
{
text: '最近14天',
onClick(picker) {
const end = new Date()
const start = new Date(getStartTime())
start.setTime(
start.getTime() - 3600 * 1000 * 24 * 13,
)
picker.$emit('pick', [start, end])
},
},
{
text: '最近30天',
onClick(picker) {
const end = new Date()
const start = new Date(getStartTime())
start.setTime(
start.getTime() - 3600 * 1000 * 24 * 29,
)
picker.$emit('pick', [start, end])
},
},
{
text: '本星期',
onClick(picker) {
const end = new Date()
const start = new Date()
const nowDay = new Date().getDay() - 1
start.setTime(
new Date(getStartTime()).getTime() -
3600 * 1000 * 24 * nowDay,
)
picker.$emit('pick', [start, end])
},
},
{
text: '上星期',
onClick(picker) {
const end = new Date()
const start = new Date()
const nowDay = new Date().getDay() - 1
end.setTime(
new Date(getStartTime()).getTime() -
3600 * 1000 * 24 * nowDay -
1,
)
start.setTime(
end.getTime() - 3600 * 1000 * 24 * 7 + 1,
)
picker.$emit('pick', [start, end])
},
},
{
text: '这个月',
onClick(picker) {
const end = new Date()
const start = new Date()
const nowDate = new Date().getDate() - 1
start.setTime(
new Date(getStartTime()).getTime() -
3600 * 1000 * 24 * nowDate,
)
picker.$emit('pick', [start, end])
},
},
{
text: '上个月',
onClick(picker) {
const date = new Date()
let year = date.getFullYear()
let month = date.getMonth()
const end = new Date(
new Date(
`${year}-${month + 1}-1 00:00:00`,
).getTime() - 1,
)
if (month === 0) {
month = 12
year = year - 1
}
const start = new Date(
new Date(`${year}-${month}-1 00:00:00`).getTime(),
)
picker.$emit('pick', [start, end])
},
},
{
text: '历史',
onClick(picker) {
picker.$emit('pick', ['', ''])
},
},
],
}
export default {
name: 'choose-time-period',
props: {
periodTime: {
type: Array,
default: () => {},
},
clearable: {
type: Boolean,
default: true,
},
placeholder: {
type: String,
default: '时间',
},
format: {
type: String,
default: 'yyyy-MM-dd HH:mm:ss',
},
type: {
type: String,
default: 'datetimerange',
},
align: {
type: String,
default: 'left',
},
},
model: {
prop: 'periodTime',
event: 'setVal',
},
render() {
return (
<el-date-picker
type={this.type}
value={this.periodTime}
clearable={this.clearable}
onInput={(v) => this.$emit('setVal', v)}
range-separator="-"
value-format={this.format}
start-placeholder={`开始${this.placeholder}`}
end-placeholder={`结束${this.placeholder}`}
style="width:200px"
default-time={['00:00:00', '23:59:59']}
picker-options={pickerOptions}
align={this.align}
></el-date-picker>
)
},
}
</script>
<!--
* @Description: 描述
* @Author: chd
* @Date: 2021-02-01 10:24:15
* @LastEditors: chd
* @LastEditTime: 2021-07-02 14:42:27
-->
<script>
export default {
name: 'status-list',
data() {
return {
statusCode: '',
}
},
mounted() {
if (!this.statusCode && this.statuslist.length > 0) {
this.statusCode = this.statuslist[this.defauntIndex].statusCode
}
},
props: {
statuslist: {
type: Array,
defaunt: () => {},
},
defauntIndex: {
type: Number,
defaunt: 0,
},
isHide: {
type: Boolean,
defaunt: false,
},
},
watch: {
statuslist(list) {
if (
!this.statusCode &&
this.defauntIndex !== null &&
this.defauntIndex !== undefined
) {
this.statusCode = list[this.defauntIndex].statusCode
}
if (
this.isHide &&
this.defauntIndex !== null &&
this.defauntIndex !== undefined
) {
this.statusCode = list[this.defauntIndex].statusCode
}
},
},
methods: {
setTabIndex(item, index) {
this.statusCode = item.statusCode
this.$emit('statusChange', { item, index })
},
changeStatusCode(code) {
this.statusCode = code
},
},
render() {
const elItem = (item, index) => (
<li
key={item.statusCode}
style={
this.isHide
? {
display: index !== 0 && item.quantity === 0 ? 'none' : 'block',
}
: { display: item.show === false ? 'none' : 'block' }
}
onClick={() => this.setTabIndex(item, index)}
class={`tabs-item ${
this.statusCode === item.statusCode ? 'active' : ''
}`}>
{item.statusName}({item.quantity})
<span class="right_btn">
{this.$scopedSlots.operate && this.$scopedSlots.operate(item)}
</span>
</li>
)
return (
<ul>
{this.statuslist.map((item, index) => {
if (item.children) {
return (
<div key={index}>
{elItem(item, index)}
<ul style="margin-left:1em">
{item.children.map((item1, index1) => {
if (item1.children) {
return (
<div key={item1.statusCode}>
{elItem(item1, index1)}
<ul style="margin-left:1em">
{item1.children.map((item2, index2) => {
return elItem(item2, index2)
})}
</ul>
</div>
)
} else {
return elItem(item1, index1)
}
})}
</ul>
</div>
)
} else {
return elItem(item, index)
}
})}
</ul>
)
},
}
</script>
<style scoped>
.tabs-item {
font-size: 14px;
padding: 5px 10px 5px 20px;
cursor: pointer;
position: relative;
}
.tabs-item:hover,
.tabs-item.active {
color: #4168FF;
background: #ddd;
}
.subtitle {
margin-left: 1em;
}
.right_btn {
display: none;
position: absolute;
top: 0;
right: 0;
}
.tabs-item:hover .right_btn {
display: block;
}
</style>
class EditSourceCode {
constructor() {
this.title = '代码' // 自定义菜单标题
this.iconSvg = `<svg
t="1644825421859"
class="active"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="9348" width="18" height="18">
<path
d="M875.52 89.6H148.48c-33.792 0-61.44 27.648-61.44 61.44v721.92c0 33.792 27.648 61.44 61.44 61.44h727.04c33.792 0 61.44-27.648 61.44-61.44v-721.92c0-33.792-27.648-61.44-61.44-61.44z m20.48 783.36c0 11.1104-9.3696 20.48-20.48 20.48H148.48c-11.1104 0-20.48-9.3696-20.48-20.48v-568.32h768v568.32z m0-609.28H128v-112.64c0-11.1104 9.3696-20.48 20.48-20.48h727.04c11.1104 0 20.48 9.3696 20.48 20.48v112.64z"
fill="#1e88e5" p-id="9349"></path>
<path
d="M215.04 204.8m-20.48 0a20.48 20.48 0 1 0 40.96 0 20.48 20.48 0 1 0-40.96 0Z"
fill="#1e88e5" p-id="9350"></path>
<path d="M291.84 204.8m-20.48 0a20.48 20.48 0 1 0 40.96 0 20.48 20.48 0 1 0-40.96 0Z"
fill="#1e88e5" p-id="9351">
</path><path
d="M368.64 204.8m-20.48 0a20.48 20.48 0 1 0 40.96 0 20.48 20.48 0 1 0-40.96 0Z"
fill="#1e88e5" p-id="9352"></path>
<path d="M196.7616 621.6192l129.8432 129.8432c6.912 6.912 17.8688 8.5504 26.0608 3.2256 11.2128-7.3728 12.3904-22.7328 3.3792-31.6928L243.8656 610.816c-2.816-2.816-2.816-7.3216 0-10.0864L355.584 488.96c6.912-6.912 8.5504-17.8688 3.2256-26.0608-7.3728-11.2128-22.7328-12.3904-31.6928-3.3792L196.7616 589.824c-4.352 4.352-11.3664 10.1888-10.9568 15.872-0.3584 5.7344 6.656 11.5712 10.9568 15.9232zM780.1344 600.6784c2.816 2.816 2.816 7.3216 0 10.0864l-112.1792 112.1792c-8.96 8.96-7.8336 24.3712 3.3792 31.6928 8.192 5.3248 19.1488 3.6864 26.0608-3.2256l129.8432-129.8432c4.352-4.352 11.3664-10.1888 10.9568-15.872 0.4096-5.6832-6.6048-11.52-10.9568-15.872l-130.304-130.304c-8.96-8.96-24.3712-7.8336-31.6928 3.3792-5.3248 8.192-3.6864 19.1488 3.2256 26.0608l111.6672 111.7184zM430.2336 786.432c10.1888 4.8128 22.4768 0.4096 27.2896-9.7792l146.0224-308.8896c4.8128-10.1888 0.4096-22.4768-9.7792-27.2896a20.56704 20.56704 0 0 0-27.2896 9.7792l-146.0224 308.8896a20.56704 20.56704 0 0 0 9.7792 27.2896z"
fill="#1e88e5"
p-id="9353"></path>
</svg>` // 可选
this.tag = 'button'
this.active = false
}
// 获取菜单执行时的 value ,用不到则返回空 字符串或 false
getValue(editor) {
return this.active ? editor.getText() : editor.getHtml()
}
// 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
isActive() {
return this.active
}
// 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
isDisabled() {
return false
}
// 点击菜单时触发的函数
exec(editor, value) {
if (this.isDisabled(editor)) return
console.log(value)
this.active = !this.active
if (this.active) {
value = value
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/ /g, '&nbsp;')
} else {
value = value
.replace(/&lt;/gi, '<')
.replace(/&gt;/gi, '>')
.replace(/&nbsp;/gi, ' ')
}
console.log(value)
editor.setHtml(value) // value 即 this.value(editor) 的返回值
}
}
const editCode = {
key: 'editCode', // 定义 menu key :要保证唯一、不重复(重要)
factory() {
return new EditSourceCode() // 把 `YourMenuClass` 替换为你菜单的 class
},
}
export default editCode
import { Boot } from '@wangeditor/editor'
import editCode from './code'
import insetSelect from './inset'
const module = {
menus: [editCode, insetSelect],
}
Boot.registerModule(module)
function insertKeys(isInsert) {
if (isInsert) {
return {
index: -2,
keys: ['editCode', 'insertSelect'],
}
}
return {
index: -1,
keys: ['editCode'],
}
}
export default insertKeys
\ No newline at end of file
<template>
<div style="border: 1px solid #ccc; z-index: 9999">
<Toolbar
class="editor_toolbar"
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 300px; overflow-y: hidden"
v-model="html"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="onCreated"
/>
</div>
</template>
<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'
import insertKeys from './index'
import { uploadImg } from '../../common/api/upload'
export default {
components: { Editor, Toolbar },
data() {
return {
editor: null,
mode: 'default',
}
},
model: {
prop: 'content',
event: 'change',
},
props: {
content: {
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
isInsert: {
type: Boolean,
default: false,
},
insertData: {
type: Array,
default: () => [
{
label: '客户名称',
value: '{payerName} {payerSurname}',
},
{ label: '订单编号', value: '{id}' },
{ label: '店铺单号', value: '{shopNumber}' },
{ label: '物流单号', value: '{trackingNumber}' },
{ label: '发货数量', value: '{purchaseNumber}' },
{ label: '发货时间', value: '{shipmentTime}' },
{ label: '妥投时间', value: '{properTime}' },
{ label: '商品', value: '{products}' },
{ label: '收货地址', value: '{address}' },
],
},
},
computed: {
html: {
get() {
return this.content
},
set(value) {
this.$emit('change', value)
},
},
toolbarConfig() {
return {
excludeKeys: ['group-video'],
insertKeys: insertKeys(this.isInsert),
}
},
editorConfig() {
const _this = this
return {
placeholder: this.placeholder || '请输入内容...',
MENU_CONF: {
uploadImage: {
allowedFileTypes: [
'jpg',
'jpeg',
'png',
'gif',
'bmp',
],
async customUpload(files, insertFn) {
// JS 语法
// res 即服务端的返回结果
const res = await uploadImg(files)
console.log(res)
const { imagePath } = res
const url = _this.setimgUrl(imagePath, {
w: 640,
})
// 从 res 中找到 url alt href ,然后插入图片
insertFn(url)
},
},
insertSelect: { options: this.insertData },
},
}
},
},
watch: {},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
console.log(editor.getConfig())
this.editor.getAllMenuKeys()
},
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
},
}
</script>
<style scoped>
.editor_toolbar >>> .panel_menu li:hover {
background: #efefef;
}
</style>
class MyDropPanelMenu {
constructor() {
this.title = '插入参数'
// this.iconSvg = '<svg >...</svg>'
this.tag = 'button'
this.showDropPanel = true
}
// 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
isActive() {
return false
}
// 获取菜单执行时的 value ,用不到则返回空 字符串或 false
getValue() {
return ''
}
// 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
isDisabled() {
return false
}
// 点击菜单时触发的函数
exec() {
// DropPanel menu ,这个函数不用写,空着即可
}
// 定义 DropPanel 内部的 DOM Element
getPanelContentElem(editor) {
const list = document.createElement('ul')
list.classList.add('panel_menu')
const { options } = editor.getMenuConfig('insertSelect')
let html = ''
for (const iterator of options) {
html += `<li style="line-height:28px;cursor: pointer;" data-value="${iterator.value}">${iterator.label}</li>`
}
list.innerHTML = html
list.addEventListener('click', (e) => {
if (e.target.nodeName === 'LI') {
const value = e.target.dataset.value
if (value) {
editor.insertText(value)
editor.insertText(' ')
}
}
})
return list // 返回 DOM Element 类型
// PS:也可以把 $list 缓存下来,这样不用每次重复创建、重复绑定事件,优化性能
}
}
const insetSelect = {
key: 'insertSelect', // 定义 menu key :要保证唯一、不重复(重要)
factory() {
return new MyDropPanelMenu() // 把 `YourMenuClass` 替换为你菜单的 class
},
config: {
options: [],
},
}
export default insetSelect
\ No newline at end of file
......@@ -5,7 +5,7 @@ import store from './store'
import element from '@/common/components/element-ui.js'
import vxeTable from '@/common/components/vxeTable.js'
import './common/style/index.scss'
import { getToken } from '@/utils/auth'
// import { getToken } from '@/utils/auth'
Vue.config.productionTip = false
......@@ -23,12 +23,13 @@ router.afterEach((to, from) => {
})
router.beforeEach((to, form, next) => {
const auth = getToken()
if (!auth && to.path !== '/login') {
next({ path: '/login' })
} else {
next()
}
// const auth = getToken()
// if (!auth && to.path !== '/login') {
// next({ path: '/login' })
// } else {
// next()
// }
next()
})
new Vue({
......
......@@ -4,8 +4,9 @@ import HomeView from '../views/home/HomeView.vue'
import SaasManage from '@/views/saasManage/indexPage.vue'
import LoginPage from '@/views/LoginPage.vue'
import menuPage from '@/views/menu.vue'
export const DEFAULT_DASHBOARD = 'saasManage'
import TaskManage from '@/views/taskManage/index.vue'
import HomePage from '@/views/homePage/index.vue'
export const DEFAULT_DASHBOARD = 'home'
Vue.use(VueRouter)
......@@ -15,16 +16,23 @@ const routes = [
name: 'login',
component: LoginPage,
},
{
path: '/',
name: 'home',
component: HomeView,
redirect: '/saas/manage',
redirect: '/saas/home',
children: [
{
path: '/saas/home',
name: 'home',
component: HomePage,
meta: { title: '首页' },
},
{
path: '/saas/manage',
name: 'saasManage',
meta: { title: 'SaaS管理页面' },
meta: { title: 'ERP管理' },
component: SaasManage,
},
{
......@@ -33,6 +41,18 @@ const routes = [
name: 'saasMenu',
meta: { title: '菜单管理' },
},
{
path: '/saas/taskManage',
component: TaskManage,
name: 'taskManage',
meta: { title: '工单管理' },
},
{
path: '/saas/user',
component: () => import('@/views/system/users.vue'),
name: 'system_user',
meta: { title: '用户管理' },
},
],
},
]
......
......@@ -5,14 +5,14 @@
<h2>登录</h2>
<el-form ref="loginForm" :model="loginForm" class="login-form">
<el-form-item
prop="userName"
prop="account"
:rules="[
{ required: true, message: '请输入用户名' },
]"
>
<el-input
prefix-icon="el-icon-user"
v-model="loginForm.userName"
v-model="loginForm.account"
placeholder="User Name"
clearable
></el-input>
......@@ -61,7 +61,7 @@ export default {
data() {
return {
loginForm: {
userName: '',
account: '',
password: '',
},
showPwd: false,
......@@ -87,7 +87,7 @@ export default {
setToken(res.data.token)
setUser(res.data.saasUser)
this.setUserInfo(res.data.saasUser)
this.$router.push('/saas/manage')
this.$router.push('/saas/home')
}
} catch (e) {
console.error(e)
......
<template>
<div class="home-header">
<page-tags />
<div class="user-area">
<span class="user-name">{{ userInfo && userInfo.userName }}</span>
<el-button type="text" @click="logout"
>退出登录</el-button
>
</div>
</div>
</template>
<script>
import pageTags from './pageTags.vue'
import { logout } from '@/common/api/login'
import { setToken, setUser } from '@/utils/auth'
import { mapState } from 'vuex'
export default {
components: { pageTags },
name: 'HomeHeader',
computed: {
...mapState(['userInfo']),
},
methods: {
async logout() {
try {
await logout()
} catch (e) {
console.error(e)
}
setUser(null)
setToken('')
localStorage.setItem('tags', null)
this.$store.commit('tags/removeAllTags')
this.$router.push('/login')
},
},
computed: {},
methods: {},
}
</script>
<style lang="scss" scoped>
......@@ -48,15 +23,4 @@ export default {
flex: 1;
overflow: auto hidden;
}
.user-area {
display: flex;
align-items: center;
flex-shrink: 0;
padding-right: 16px;
.user-name {
margin-right: 10px;
}
}
</style>
......@@ -39,22 +39,11 @@ export default {
<style lang="scss" scoped>
.home {
height: 100%;
display: flex;
overflow: hidden;
&::v-deep {
.el-menu {
height: 100%;
}
}
}
.nav-menu {
height: 100%;
width: 240px;
}
.right {
height: calc(100% - 60px);
flex: 1;
display: flex;
flex-direction: column;
......@@ -70,7 +59,7 @@ export default {
.content {
flex: 1;
padding: 10px 10px 0px 10px;
padding: 10px;
background-color: #f1f1f1;
}
</style>
......@@ -6,19 +6,17 @@
<el-menu
ref="menu"
router
mode="horizontal"
:default-active="this.$route.path"
class="el-menu-vertical-demo"
text-color="#fff"
style="flex: 1"
background-color="#1565C0"
@click.native="onClickMenus"
active-text-color="#ffd04b"
>
<div
class="menu-list"
v-for="nav in menuList"
:key="nav.id"
>
<template v-for="(nav,index) in menuList">
<el-menu-item
:key="index"
v-if="nav.children.length === 0"
:index="nav.index"
>
......@@ -27,15 +25,15 @@
<span class="label">{{ nav.label }}</span>
</template>
</el-menu-item>
<el-submenu v-else :index="nav.index">
<el-submenu :key="index" v-else :index="nav.index">
<template slot="title">
<i :class="nav.icon"></i>
<span class="label">{{ nav.label }}</span>
</template>
<el-menu-item
:index="subs.index"
v-for="subs in nav.children"
:key="subs.id"
v-for="(subs, index) in nav.children"
:key="index"
>
<template slot="title">
<i :class="subs.icon"></i>
......@@ -45,12 +43,25 @@
>
</el-menu-item>
</el-submenu>
</div>
</template>
</el-menu>
<div class="user-area">
<span class="user-name">{{
userInfo && userInfo.userName
}}</span>
<el-button
type="text"
style="color: #fff"
@click="logout"
>退出登录</el-button
>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { mapGetters, mapState } from 'vuex'
import { logout } from '@/common/api/login'
import { setToken, setUser } from '@/utils/auth'
export default {
name: 'navMenu',
data() {
......@@ -59,12 +70,28 @@ export default {
{
id: 1,
path: '',
label: 'SaaS管理页面',
label: 'ERP管理',
icon: 'el-icon-menu',
index: '/saas/manage',
children: [],
},
{
id: 3,
path: '',
label: 'ERP菜单管理',
icon: 'el-icon-menu',
index: '/saas/menu',
children: [],
},
{
id: 4,
path: '',
label: '工单管理',
icon: 'el-icon-s-order',
index: '/saas/taskManage',
children: [],
},
{
id: 2,
path: '',
label: '系统管理',
......@@ -72,11 +99,19 @@ export default {
index: '/system',
children: [
{
id: 3,
id: 4,
path: '',
label: '菜单管理',
icon: '',
index: '/saas/menu',
label: '用户管理',
icon: 'el-icon-s-order',
index: 'user',
children: [],
},
{
id: 4,
path: '',
label: '角色管理',
icon: 'el-icon-s-order',
index: 'user',
children: [],
},
],
......@@ -86,6 +121,7 @@ export default {
},
computed: {
...mapGetters('tags', ['currentTag']),
...mapState(['userInfo']),
},
watch: {
currentTag(v) {
......@@ -103,13 +139,34 @@ export default {
},
},
methods: {
async logout() {
try {
await logout()
} catch (e) {
console.error(e)
}
setUser(null)
setToken('')
localStorage.setItem('tags', null)
this.$store.commit('tags/removeAllTags')
this.$router.push('/login')
},
onClickMenus() {},
},
}
</script>
<style lang="scss" scoped>
.nav-menu {
display: flex;
height: 60px;
overflow: hidden;
background-color: #1565c0;
&::v-deep {
.el-menu {
border-bottom: none;
}
.el-submenu__title i {
color: #fff;
}
......@@ -120,16 +177,25 @@ export default {
}
.header-logo {
font-size: 20px;
font-size: 22px;
color: #fff;
font-weight: bold;
padding: 12px 20px;
font-style: italic;
border-right: 1px solid #e6e6e6;
background-color: #1565C0;
padding: 14px 20px;
background-color: #1565c0;
}
.label {
font-size: 16px;
}
.user-area {
float: right;
display: flex;
align-items: center;
flex-shrink: 0;
padding-right: 16px;
color: #fff;
.user-name {
margin-right: 10px;
}
}
</style>
<template>
<div>首页</div>
</template>
<script>
export default {
data() {
return {}
},
}
</script>
<style>
</style>
\ No newline at end of file
......@@ -416,8 +416,8 @@ export default {
height: 100%;
display: flex;
flex-direction: column;
padding: 0 20px;
padding-top: 10px;
padding: 10px 20px 0;
overflow: hidden;
}
.table-wrap {
......
......@@ -125,7 +125,7 @@
<el-table-column
label="域名"
prop="domain"
min-width="180"
min-width="160"
header-align="center"
:show-overflow-tooltip="true"
></el-table-column>
......@@ -134,7 +134,7 @@
prop="companyName"
header-align="center"
align="center"
width="160"
width="180"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
......@@ -142,7 +142,7 @@
prop="headName"
header-align="center"
align="center"
width="140"
width="80"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
......@@ -150,7 +150,7 @@
prop="contactPhone"
header-align="center"
align="center"
width="140"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
......@@ -158,7 +158,7 @@
prop="packages"
header-align="center"
align="center"
width="140"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
......@@ -166,7 +166,7 @@
prop="charges"
header-align="center"
align="center"
width="140"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
......@@ -174,21 +174,21 @@
prop="dataHost"
header-align="center"
align="left"
width="160"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
label="数据库名称"
prop="databaseName"
header-align="center"
width="160"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
label="状态"
header-align="center"
align="center"
width="120"
width="80"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
......@@ -377,9 +377,7 @@
clearable
/>
</el-form-item>
<el-form-item
label="数据库名称"
>
<el-form-item label="数据库名称">
<el-input
style="width: 200px"
:value="`saas_${editForm.databaseName || ''}`"
......@@ -471,7 +469,11 @@
prop="contactPhone"
:rules="[
{ required: true, message: '请输入联系电话' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的电话号码格式', trigger: 'blur' },
{
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的电话号码格式',
trigger: 'blur',
},
]"
>
<el-input
......@@ -679,7 +681,10 @@ export default {
this.getList()
},
rowClick(row) {
if (this.selection.length === 1 && this.selection[0] === row) {
if (
this.selection.length === 1 &&
this.selection[0] === row
) {
this.selection = []
this.$refs.table.clearSelection()
} else {
......@@ -750,9 +755,4 @@ export default {
flex: 1;
overflow: hidden;
}
.pagination {
text-align: center;
padding-top: 10px;
}
</style>
......@@ -3,6 +3,6 @@ module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port: 8082,
host: 'wjz.local.cn',
host: '',
},
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment