Commit e2d28a02 authored by 何小勇's avatar 何小勇

merge

parents 83d44134 133893b6
......@@ -274,8 +274,8 @@ div {
}
.el-dialog__body {
font-size: 18px;
color: #242c43;
font-size: 16px;
color: #404a62;
text-align: center;
padding: 0 16px;
}
......@@ -285,12 +285,6 @@ div {
.dialog_box .el-dialog__footer {
padding: 16px;
}
.result_box .el-dialog__body {
padding: 0px;
}
.sold_up_dialog .el-dialog__body {
padding: 24px 24px 4px;
}
/* 设置tab切换的样式 */
.el-tabs__item.is-disabled {
color: #8890a7 !important;
......@@ -332,9 +326,17 @@ div {
}
/* 设置tree的样式 */
.el-tree {
position: static!important;
}
.el-tree-node__content{
height: 36px;
}
.el-tree-node__content:hover {
background-image: linear-gradient(90deg,
rgba(255, 255, 255, 0.05) 83%,
rgba(0, 0, 0, 0.05) 86%);
}
/* .usrrole .el-tree-node:focus>.el-tree-node__content{
background: rgb(248, 249, 253) !important;
}
......@@ -994,39 +996,32 @@ border-radius:8px;
display: flex;
}
.top_fliter .filter_list {
.filter_list {
flex-grow: 1;
min-width: 550px;
font-size: 0;
padding-left: 16px;
}
.filter_list>.filter_item {
display: inline-block;
vertical-align: middle;
margin-top: 16px;
}
.filter_list>.filter_item {
margin-right:34px;
display: flex;
align-items: center;
margin: 0 34px 16px 0;
}
.filter_list>.filter_item>* {
/* .filter_list>.filter_item>* {
display: inline-block;
vertical-align: middle;
}
} */
.filter_list>.filter_item>.filter_title {
min-width: 56px;
text-align: right;
font-size: 14px;
font-weight: 700;
color: #242c43;
margin-right: 10px;
white-space: nowrap;
width: 84px;
white-space: pre-wrap;
font-weight: normal;
}
.filter_list>.filter_item>.filter_title+* {
/* .filter_list>.filter_item>.filter_title+* {
width: 300px;
}
......@@ -1038,7 +1033,7 @@ border-radius:8px;
position: absolute;
right: 5px;
top: 1px;
}
} */
.top_fliter .filter_action {
flex-shrink: 0;
......@@ -1478,14 +1473,24 @@ border-radius:8px;
}
.flex_left {
<<<<<<< HEAD
height: calc(100% - 20px);
=======
background-color: #fff;
height: calc(100% - 16px);
>>>>>>> 133893b61e0b75788c7111d07959c747c7a0fa2d
width: 320px;
margin-right: 10px;
overflow: hidden;
}
.flex_right {
<<<<<<< HEAD
height: calc(100% - 20px);
=======
background-color: #fff;
height: calc(100% - 16px);
>>>>>>> 133893b61e0b75788c7111d07959c747c7a0fa2d
flex: 1;
overflow: hidden;
......@@ -1500,13 +1505,13 @@ border-radius:8px;
}
.tree::-webkit-scrollbar {
width: 5px;
height: 5px;
width: 6px;
height: 6px;
}
.tree::-webkit-scrollbar-thumb {
background: #bcc1d0;
border-radius: 10px;
height: 5px;
height: 6px;
}
.tree::-webkit-scrollbar-track {
background: transparent;
......@@ -1528,3 +1533,7 @@ border-radius:8px;
.pl-1 {
padding-left: 1rem;
}
.label-text {
font-size: 14px;
color: #404a62;
}
:root {
--font-color: #404a62;
/* --el-color-primary-light-9: #f7f7f9; */
--font-color: #404a62;
/* --el-color-primary-light-9: #f7f7f9; */
--el-color-white: #ffffff;
--el-color-black: #1a1a1a;
--el-color-primary: #2b4695;
--el-color-primary-light-3: #6b7eb5;
--el-color-primary-light-5: #95a3ca;
--el-color-primary-light-7: #c0c8df;
--el-color-primary-light-8: #d5daea;
--el-color-primary-light-9: #eaedf5;
--el-color-primary-dark-2: #223877;
--el-color-success: #429e8a;
--el-color-success-light-3: #7bbbad;
--el-color-success-light-5: #a1cfc5;
--el-color-success-light-7: #c7e2dc;
--el-color-success-light-8: #d9ece8;
--el-color-success-light-9: #ecf5f4;
--el-color-success-dark-2: #357e6e;
--el-color-warning: #e56600;
--el-color-warning-light-3: #ed944d;
--el-color-warning-light-5: #f2b380;
--el-color-warning-light-7: #f7d1b3;
--el-color-warning-light-8: #fae0cc;
--el-color-warning-light-9: #fcf0e6;
--el-color-warning-dark-2: #b75200;
--el-color-danger: #d75138;
--el-color-danger-light-3: #e38674;
--el-color-danger-light-5: #eba89c;
--el-color-danger-light-7: #f3cbc4;
--el-color-danger-light-8: #f7dcd7;
--el-color-danger-light-9: #fbeeeb;
--el-color-danger-dark-2: #ac412d;
--el-color-error: #d75138;
--el-color-error-light-3: #e38674;
--el-color-error-light-5: #eba89c;
--el-color-error-light-7: #f3cbc4;
--el-color-error-light-8: #f7dcd7;
--el-color-error-light-9: #fbeeeb;
--el-color-error-dark-2: #ac412d;
--el-color-info: #404a62;
--el-color-info-light-3: #7a8191;
--el-color-info-light-5: #a0a5b1;
--el-color-info-light-7: #c6c9d0;
--el-color-info-light-8: #d9dbe0;
--el-color-info-light-9: #ecedf0;
--el-color-info-dark-2: #333b4e;
--el-bg-color: #ffffff;
--el-bg-color-page: #f2f3f5;
--el-bg-color-overlay: #ffffff;
--el-text-color-primary: #202531;
--el-text-color-regular: #404a62;
--el-text-color-secondary: #909bb6;
--el-text-color-placeholder: #a9b1c7;
--el-text-color-disabled: #a9b1c7;
--el-border-color: #dadee7;
--el-border-color-light: #e3e5eb;
--el-border-color-lighter: #e6e9ef;
--el-border-color-extra-light: #edf0f5;
--el-border-color-dark: #d1d5de;
--el-border-color-darker: #cbced7;
--el-fill-color: #f0f2f5;
--el-fill-color-light: #f2f3f7;
--el-fill-color-lighter: #f7f7f9;
--el-fill-color-extra-light: #fafcff;
--el-fill-color-dark: #ebedf0;
--el-fill-color-darker: #e6e8eb;
--el-fill-color-blank: #ffffff;
--el-component-size: 36px;
}
--el-color-white: #ffffff;
--el-color-black: #1a1a1a;
--el-color-primary: #2b4695;
--el-color-primary-light-3: #6b7eb5;
--el-color-primary-light-5: #95a3ca;
--el-color-primary-light-7: #c0c8df;
--el-color-primary-light-8: #d5daea;
--el-color-primary-light-9: #eaedf5;
--el-color-primary-dark-2: #223877;
--el-color-success: #429e8a;
--el-color-success-light-3: #7bbbad;
--el-color-success-light-5: #a1cfc5;
--el-color-success-light-7: #c7e2dc;
--el-color-success-light-8: #d9ece8;
--el-color-success-light-9: #ecf5f4;
--el-color-success-dark-2: #357e6e;
--el-color-warning: #e56600;
--el-color-warning-light-3: #ed944d;
--el-color-warning-light-5: #f2b380;
--el-color-warning-light-7: #f7d1b3;
--el-color-warning-light-8: #fae0cc;
--el-color-warning-light-9: #fcf0e6;
--el-color-warning-dark-2: #b75200;
--el-color-danger: #d75138;
--el-color-danger-light-3: #e38674;
--el-color-danger-light-5: #eba89c;
--el-color-danger-light-7: #f3cbc4;
--el-color-danger-light-8: #f7dcd7;
--el-color-danger-light-9: #fbeeeb;
--el-color-danger-dark-2: #ac412d;
--el-color-error: #d75138;
--el-color-error-light-3: #e38674;
--el-color-error-light-5: #eba89c;
--el-color-error-light-7: #f3cbc4;
--el-color-error-light-8: #f7dcd7;
--el-color-error-light-9: #fbeeeb;
--el-color-error-dark-2: #ac412d;
--el-color-info: #404a62;
--el-color-info-light-3: #7a8191;
--el-color-info-light-5: #a0a5b1;
--el-color-info-light-7: #c6c9d0;
--el-color-info-light-8: #d9dbe0;
--el-color-info-light-9: #ecedf0;
--el-color-info-dark-2: #333b4e;
--el-bg-color: #ffffff;
--el-bg-color-page: #f2f3f5;
--el-bg-color-overlay: #ffffff;
--el-text-color-primary: #202531;
--el-text-color-regular: #404a62;
--el-text-color-secondary: #909bb6;
--el-text-color-placeholder: #a9b1c7;
--el-text-color-disabled: #a9b1c7;
--el-border-color: #dadee7;
--el-border-color-light: #e3e5eb;
--el-border-color-lighter: #e6e9ef;
--el-border-color-extra-light: #edf0f5;
--el-border-color-dark: #d1d5de;
--el-border-color-darker: #cbced7;
--el-fill-color: #f0f2f5;
--el-fill-color-light: #f2f3f7;
--el-fill-color-lighter: #f7f7f9;
--el-fill-color-extra-light: #fafcff;
--el-fill-color-dark: #ebedf0;
--el-fill-color-darker: #e6e8eb;
--el-fill-color-blank: #ffffff;
}
.text-hide1{
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.log_content_nor::-webkit-scrollbar {
width: 0px; /*对垂直流动条有效*/
height: 0px; /*对水平流动条有效*/
}
\ No newline at end of file
.text-hide1{
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.log_content_nor::-webkit-scrollbar {
width: 0px; /*对垂直流动条有效*/
height: 0px; /*对水平流动条有效*/
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
<slot name="left_action"></slot>
</div>
<div class="right-filter">
<el-input :placeholder="placeholder" v-model="modelValue">
<el-input :placeholder="placeholder" v-model="value">
<template #append>
<div class="append-btn" @click="search">
<bg-icon style="font-size: 12px; color: #404a62; " icon="#bg-ic-search"></bg-icon>
......@@ -28,17 +28,17 @@
</template>
<script setup>
import { computed, onMounted, reactive, toRefs, watch,ref } from "vue-demi"
import { computed, onMounted, reactive, toRefs, watch,ref } from "vue"
const state = reactive({
showFlag: false,
modelValue: ""
value: ""
})
const props = defineProps({
keyword: {
modelValue: {
type: String,
default: ""
default: '',
},
placeholder: {
type: String,
......@@ -47,17 +47,20 @@ const props = defineProps({
})
watch(props,(n,o) => {
state.modelValue = n.keyword
state.value = n.modelValue
})
const emit = defineEmits(['search'])
watch(() => state.value,(n,o) => {
emit('update:modelValue',n)
})
const emit = defineEmits(['search','update:modelValue'])
const search = () => {
emit('search',state.modelValue)
emit('search',state.value)
}
const moreFilter = () => {
state.showFlag = !state.showFlag
}
onMounted(() => {
state.modelValue = props.keyword
state.value = props.modelValue
})
const { modelValue,showFlag } = toRefs(state)
const { value,showFlag } = toRefs(state)
</script>
\ No newline at end of file
<template>
<el-switch
class="bg-switch-ele"
v-model="value"
:active-value="1"
:inactive-value="0"
inline-prompt
:active-text="activeText"
:inactive-text="inactiveText"
@change="changeState"
/>
</template>
<script setup>
import { onMounted, reactive, toRefs, watch } from "vue"
const props = defineProps({
modelValue: {
type: Number,
default: 0
},
activeText: {
type: String,
default: "",
},
inactiveText: {
type: String,
default: ""
},
rowId: {
type: Number,
default: null
}
})
const state = reactive({
value: 1
})
const emit = defineEmits(['changeState'])
const changeState = () => {
if (props.rowId) {
let params = {
state: state.value,
id: props.rowId
}
emit('changeState',params)
}else {
emit('changeState',state.value)
}
}
onMounted(()=> {
state.value = props.modelValue
})
const { value } = toRefs(state)
</script>
......@@ -58,24 +58,22 @@ export default {
},
now_style() {
return {
color: this.colors[this.now_index],
borderColor: this.colors[this.now_index],
backgroundColor: this.colors[this.now_index],
};
},
now_label_style() {
return this.now_index == 0
? { left: this.circle_height + this.gap + 5 + "px" }
: { left: "10px" };
: { left: "6px" };
},
now_circle_style() {
return this.now_index == 0
? {
left: this.gap + "px",
backgroundColor: this.colors[this.now_index],
}
: {
right: this.gap + "px",
backgroundColor: this.colors[this.now_index],
};
},
},
......
<template>
<div class="bg-table-btns-more" :style="style" @click.stop>
<bg-table-btn
v-for="(item, index) in operations"
:key="index"
:disabled="isDisabled(item)"
@click="clickAction(item)"
>
{{ getName(item) }}
</bg-table-btn>
</div>
</template>
<script>
export default {
name: "BgTableBtnsMore",
props: {
operations: {
type: Array,
default: () => [],
},
},
data() {
return {
style: {},
};
},
methods: {
isDisabled({ disabled }) {
if (typeof disabled === "function") {
return disabled();
} else if (typeof disabled === "boolean") {
return disabled;
} else if (typeof disabled === "undefined") {
return false;
} else {
return !!disabled;
}
},
clickAction({ callback }) {
typeof callback === "function" && callback();
},
getName({ name }) {
if (typeof name === "function") {
return name();
} else {
return name;
}
},
upStyle() {
let { top, right } = this.$parent.$el.getBoundingClientRect();
let { width } = window.document.body.getBoundingClientRect();
this.style = {
position: "fixed",
top: `${top + 16}px`,
right: `${width - right - 16}px`,
};
},
},
mounted() {
document.body.append(this.$el);
this.upStyle();
},
beforeDestroy() {
this.$el && this.$el.remove();
},
};
</script>
<template>
<div class="bg-table-btns">
<bg-table-btn
v-for="(item, index) in curOperations"
:key="index"
:disabled="isDisabled(item)"
@click="clickAction(item)"
>
{{ getName(item) }}
</bg-table-btn>
<a
class="bg-table-btn"
@mouseenter="showMOreBtns"
@mouseleave="hideMoreBtns"
v-if="otherOperations.length > 0"
>
<!-- <i class="el-icon-more" /> -->
<bg-icon style="font-size: 12px; color: #2b4695;" icon="#bg-ic-s-more" />
<bg-table-btns-more
:operations="otherOperations"
@mouseenter="showMOreBtns"
@mouseleave="hideMoreBtns"
v-if="showMore"
/>
</a>
</div>
</template>
<script>
import BgTableBtnsMore from "./bg-table-btns-more.vue";
export default {
name: "BgTableBtns",
components: { BgTableBtnsMore },
props: {
operations: {
type: Array,
default: () => [],
},
},
data() {
return {
showMore: false,
timer: null,
};
},
computed: {
curOperations() {
return this.operations.slice(0, this.operations.length > 3 ? 2 : 3);
},
otherOperations() {
return this.operations.slice(2, this.operations.length);
},
},
methods: {
isDisabled({ disabled }) {
if (typeof disabled === "function") {
return disabled();
} else if (typeof disabled === "boolean") {
return disabled;
} else if (typeof disabled === "undefined") {
return false;
} else {
return !!disabled;
}
},
clickAction({ callback }) {
typeof callback === "function" && callback();
},
getName({ name }) {
if (typeof name === "function") {
return name();
} else {
return name;
}
},
showMOreBtns() {
if (this.timer) clearTimeout(this.timer);
this.showMore = true;
},
hideMoreBtns() {
if (this.timer) clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.showMore = false;
}, 50);
},
},
};
</script>
......@@ -7,6 +7,8 @@
@select="selectActionRow"
@select-all="selectActionAll"
:stripe="stripe"
:row-class-name="stripe ? tableRowClassName : ''"
tooltip-effect="light"
>
<template v-slot:empty>
<div class="empty_container">
......@@ -16,6 +18,10 @@
</div>
</div>
</template>
<el-table-column
v-if="paddingLeft > 10"
:width="paddingLeft - 10"
></el-table-column>
<el-table-column
type="selection"
:selectable="selectable"
......@@ -30,7 +36,7 @@
type="index"
:label="indexLabel"
width="80"
align="center"
align="left"
>
<!-- 序号 -->
</el-table-column>
......@@ -111,7 +117,11 @@ export default {
stripe: {
type: Boolean,
default: false
}
},
paddingLeft: {
type: [Number, String],
default: () => 33,
},
},
/* filters: {
ellipsis(value, max) {
......@@ -172,7 +182,14 @@ export default {
this.allSelectData={}
this.nowSelectData=[]
this.clearSelection();
}
},
tableRowClassName({ row, rowIndex }) {
if (rowIndex % 2 == 0) {
return "white-row";
} else {
return "stripe-row";
}
},
},
};
</script>
......@@ -32,6 +32,9 @@
import debounce from './debounce'
import BgPagination from './bg-pagination.vue'
import BgInnerTabs from './bg-inner-tabs.vue'
import BgFilterGroup from './bg-filter-group.vue'
import BgSwitchEle from './bg-switch-ele.vue'
import BgTableBtns from './bg-table-btns.vue'
const components = {
BgIcon,//字体图标
......@@ -65,6 +68,9 @@ const components = {
debounce,//防抖组件
BgPagination,// 分页组件
BgInnerTabs,//内部tab
BgFilterGroup,//高级搜索
BgSwitchEle,
BgTableBtns,
};
const install = (Vue) => {
......
......@@ -659,17 +659,16 @@ a {
}
th,
td {
padding: 12px 0!important;
padding: 11px 0!important;
> .cell {
padding: 0 10px !important;
color: #404a62;
line-height: 18px;
line-height: 14px;
}
}
&.el-table--border {
border-top-color: #b0bee8;
border-bottom: 1px solid #ebeef5;
.el-table__header-wrapper {
position: relative;
......@@ -687,7 +686,7 @@ a {
&::after {
content: "";
width: 1px;
width: 0px;
height: 100%;
background-color: #b0bee8;
position: absolute;
......@@ -705,7 +704,12 @@ a {
}
}
}
.stripe-row td {
background-color: #fff!important;
}
.white-row td {
background-color: #f7f7f9!important;
}
.el-table--striped .el-table__body tr.el-table__row--striped td {
background-color: #f7f7f9;
}
......@@ -738,6 +742,15 @@ a {
margin: 0 !important;
}
}
.el-popper {
max-width: 388px;
padding: 15px 12px;
color: #202531;
box-shadow: 0px 4px 12px 0px
rgba(18, 30, 63, 0.1);
border: solid 1px #e6e9ef;
font-size: 14px;
}
}
.bg-table-pro{
......@@ -2023,29 +2036,31 @@ a {
.bg-switch {
display: inline-block;
vertical-align: middle;
width: 64px;
height: 28px;
border-radius: 14px;
border: solid 2px #275a9d;
width: 44px;
height: 20px;
border-radius: 10px;
border: solid 2px #2b4695;
position: relative;
color: #275a9d;
color: #fff;
background-color: #2b4695;
cursor: pointer;
user-select: none;
> .label {
font-size: 12px;
font-weight: 600;
line-height: 24px;
font-weight: 400;
line-height: 15px;
position: absolute;
color: #fff;
}
> .circle {
width: 18px;
height: 18px;
width: 16px;
height: 16px;
border-radius: 50%;
position: absolute;
top: 3px;
background-color: #275a9d;
// top: 2px;
background-color: #fff;
}
&.disabled {
......@@ -2312,9 +2327,8 @@ a {
.bg-pagination {
height: 32px;
position: absolute;
right: 24px;
bottom: 16px;
margin-top: 16px;
float: right;
.el-pagination {
text-align: center;
margin: 0 auto;
......@@ -2459,4 +2473,64 @@ a {
border: 1px solid #e6e9ef;
padding: 24px 16px 8px;
}
}
// 表格操作按钮组
.bg-table-btns {
position: relative;
display: inline-block;
vertical-align: middle;
}
.bg-table-btns-more {
position: absolute;
top: 28px;
right: -16px;
z-index: 19;
padding: 4px 0;
background-color: #ffffff;
box-shadow: 0px 4px 12px 0px rgba(18, 30, 63, 0.1);
border-radius: 4px;
border: solid 1px #e6e9ef;
width: 88px;
.bg-table-btn {
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
white-space: nowrap;
display: block;
padding: 0 16px;
margin: 0;
color: #202531;
line-height: 34px;
padding-left: 16px;
&:hover {
background-color: #f2f3f7;
color: #202531;
}
&.disabled {
color: #a9b1c7;
}
&::before {
display: none;
}
}
&::before {
content: "";
position: absolute;
top: -10px;
left: 0;
height: 10px;
width: 100%;
}
}
.bg-switch-ele {
width: 44px;
height: 20px;
.el-switch__core {
width: 100%;
}
}
\ No newline at end of file
......@@ -6,91 +6,180 @@
<el-breadcrumb-item> 字典配置 </el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="main_container">
<div class="left_type">
<el-input class="type-input" v-model="search" @input="searchType" placeholder="请输入内容"></el-input>
<div class="flex_row">
<div class="flex_left">
<div class="box">
<el-input class="type-input" v-model="typeKeyword" @input="searchType" placeholder="请输入内容"></el-input>
<div class="type_station bg-scroll">
<div class="type-box" :class="{'current-type':nodeId==item.id}" @click="nodeClick(item)" v-for="(item,index) in typeList" :key="'type'+index+200">
{{item.name}}
<div class="type_station bg-scroll">
<div class="type-box" :class="{'current-type':nodeClassifyId==item.classify_id}" @click="nodeClick(item)" v-for="(item,index) in typeList" :key="'type'+index+200">
{{item.classify_name}}
</div>
</div>
</div>
</div>
<div class="right_container">
<div class="apaas_button">
<el-button class="register_btn" type="primary" @click="register">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
新建
</el-button>
</div>
<div class="table_container">
<bg-table ref="bgTable" :headers="headers" :rows="tableRows" :isIndex="true" :stripe="true">
<template v-slot:state="{ row }">
{{ ["-","启用","禁用"][row.state] }}
</template>
<template v-slot:updated_time="{ row }">
{{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
<div class="flex_right">
<div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入关键字">
<template v-slot:left_action>
<div class="apaas_button">
<el-button class="register_btn" type="primary" @click="register">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
新建
</el-button>
</div>
</template>
<template v-slot:action="{ row }">
<bg-table-btn class="btn" :click="()=>{edit_row(row)}" :disabled="row.state == 1">
编辑
</bg-table-btn>
<bg-table-btn class="btn" :click="()=>{delete_row(row)}" :disabled="row.state == 1">
删除
</bg-table-btn>
<template v-slot:filter_group>
<div class="left-filter filter_list">
<div class="filter_item">
<span class="filter_title">状态</span>
<el-select
v-model="filter.state"
placeholder="请选择"
style="width: 300px"
>
<el-option
v-for="(item, index) in stateOptions"
:key="'pushOptions' + index"
:label="item.name"
:value="item.value"
>
</el-option>
</el-select>
</div>
</div>
<div class="right-action apaas_button">
<el-button type="primary" @click="filterAction"> 查询 </el-button>
<el-button type="default" @click="filterClear"> 重置 </el-button>
</div>
</template>
</bg-table>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize"
>
</bg-pagination>
</bg-filter-group>
<div class="table_container">
<bg-table ref="bgTable" :headers="headers" :rows="tableRows" :isIndex="true" :stripe="true">
<template v-slot:updated_time="{ row }">
{{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
</template>
<template v-slot:state="{ row }">
<bg-switch-ele
v-model="row.state"
:rowId="row.id"
inline-prompt
activeText="是"
inactiveText="否"
@changeState="changeUseRow"
/>
</template>
<template v-slot:action="{ row }">
<bg-table-btns :operations="getOperations(row)" />
</template>
</bg-table>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize"
>
</bg-pagination>
</div>
</div>
</div>
</div>
<!-- 新建/编辑弹窗 -->
<el-dialog
custom-class="dialog_box"
:title=" addType == 1 ? '新建' : '编辑'"
v-model="addDialog"
width="758px"
:before-close="
() => {
addDialog = false;
}
"
>
<el-form
ref="bgForm"
:model="formData"
:rules="rules"
label-width="80px"
class="bg_form"
>
<el-form-item label="名称" prop="name">
<el-input
v-model="formData.name"
placeholder="请输入名称"
></el-input>
</el-form-item>
<el-form-item label="描述" prop="describe">
<el-input
v-model="formData.describe"
type="textarea"
:autosize="{ minRows: 5 }"
show-word-limit
maxlength="200"
resize="vertical"
placeholder="请输入描述"
></el-input>
</el-form-item>
<el-form-item label="是否启用" prop="state" style="margin-bottom: 0px">
<el-switch
class="bg-switch-ele"
v-model="formData.state"
:active-value="1"
:inactive-value="0"
inline-prompt
active-text="是"
inactive-text="否"
/>
</el-form-item>
</el-form>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="addDialog = false">取 消</el-button>
<el-button type="primary" @click="addConfirm">确 定</el-button>
</div>
</template>
</el-dialog>
<!-- 删除弹窗 -->
<el-dialog
custom-class="dialog_box"
title="提示"
v-model="dialogDelete"
width="400px"
:before-close="
() => {
dialogDelete = false;
}
"
>
<div>确定要删除此字典值吗?</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="dialogDelete = false">取 消</el-button>
<el-button type="primary" @click="deleteData">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { reactive, ref,onBeforeMount,toRefs,computed,watch } from 'vue'
import { reactive, ref,onBeforeMount,toRefs,computed, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router';
import bgTable from '@/bg-ui/bg-table.vue'
import { ElMessage } from 'element-plus'
import axios from '../../../../request/http.js'
const bgForm = ref(null)
const state = reactive({
typeList: [
{
name: "业务分类",
id: 1,
},
{
name: "业务领域",
id: 2,
},
{
name: "开放程度",
id: 3,
},
{
name: "开发厂商",
id: 4,
},
{
name: "菜单分组",
id: 5,
},
],
search: "",
nodeId: null,
timer: null,
bgForm,
typeList: [], // 分类数据
typeKeyword: "", // 分类删选关键词
nodeClassifyId: null, // 当前选中分类的uuid 用于新建字典
nodeId: null, // 当前选中分类的id 用于请求列表
timer: null, // 定时器
headers: [
{
label: "业务分类名称",
label: "名称",
prop: "name",
},
{
......@@ -98,34 +187,80 @@ const state = reactive({
prop: "describe",
minWidth: 360
},
{
label: "状态",
prop: "state",
},
{
label: "更新时间",
prop: "updated_time",
width: 220,
},
{
label: "状态",
prop: "state",
},
{
label: "操作",
prop: "action",
width: 260,
width: 176,
fixed: "right",
},
],
tableRows: [],
tableTotal: 0,
], // 表格数据表头
tableRows: [], // 表格数据
tableTotal: 0, // 表格数据条数
filter: {
state: "",
search: "",
page: 1,
limit: 10,
kind: "business_type",
}, // 表格筛选项
stateOptions: [
{
name: "全部",
value: ""
},
{
name: "启用",
value: "1"
},
{
name: "禁用",
value: "2"
},
], // 启用禁用
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
addType: 0, //
addDialog: false,
formData: {
name: "",
describe: "",
state: 1,
},
rules: {
name: [
{ required: true, message: "请输入名称", trigger: "blur" },
{ max: 20, message: "名称最大为20字", trigger: "blur"}
],
describe: [
{ required: true, message: "请输入描述", trigger: "blur" },
{ max: 200, message: "描述最大为200字", trigger: "blur"}
],
state: [
{ required: true, message: "请选择是否启用", trigger: "change" }
]
},
})
const nodeClick = (item) => {
state.nodeId = item.id
}
state.nodeClassifyId = item.classify_id
state.filter = {
state: "",
search: "",
page: 1,
limit: 10,
}
getTableRows()
} // 切换字典分类
const searchType = () => {
if (state.timer) {
clearTimeout(state.timer);
......@@ -133,12 +268,74 @@ const searchType = () => {
state.timer = setTimeout(() => {
getTypeList()
}, 500);
}
} // 字典分类筛选
const getTypeList = () => {
console.log(state.search)
}
axios
.get(`/apaas/system/v5/dictionary/classify/list?name=${state.typeKeyword}`)
.then( (res) => {
if (res.data.code == 200) {
state.typeList = res.data.data || []
state.nodeClassifyId = state.typeList[0].classify_id || null
state.nodeId = state.typeList[0].id || null
if (state.nodeId) {
getTableRows()
}
}else {
ElMessage.error(res.data.data)
}
}).catch((err) => {
console.log(err)
})
} // 获取字典分类
const changeSearch = (val) => {
state.filter.search = val
changePage(1)
} // 表格关键字筛选
const filterAction = () => {
changePage(1)
} // 查询按钮
const filterClear = () => {
state.filter = {
state: "",
search: "",
limit: 10,
page: 1,
}
changePage(1)
} // 重置筛选项
const getOperations = (row) => {
return [
{
name: "编辑",
callback: () => edit_row(row),
disabled: row.state == 1,
},
{
name: "删除",
callback: () => delete_row(row),
disabled: row.state == 1,
},
{
name: "上移",
callback: () => moveRow(row,1),
disabled: !row.canMoveUp,
},
{
name: "下移",
callback: () => moveRow(row,2),
disabled: !row.canMoveDown,
},
];
} // 表格操作按钮
const getTableRows = () => {
let params = {...state.filter}
params.id = state.nodeId
axios
.get(
`/apaas/system/v5/dictionary/list`,
......@@ -150,38 +347,213 @@ const getTableRows = () => {
if (res.data.code == 200) {
state.tableRows = res.data.data || []
state.tableTotal = res.data.total
if (state.tableRows.length > 0) {
state.tableRows.forEach(e => {
e.canMoveUp = true
e.canMoveDown = true
})
state.tableRows[0].canMoveUp = false
state.tableRows[state.tableRows.length - 1].canMoveDown = false
}
}else {
ElMessage.error(res.data.msg)
ElMessage.error(res.data.data)
}
})
} // 获取数据
const changePage = () => {
} // 获取表格数据
}
const changeSize = () => {
const changeUseRow = (row) => {
axios
.put(`/apaas/system/v5/dictionary/state?id=${row.id}&state=${row.state}`)
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.data)
changePage(1)
}else {
ElMessage.error(res.data.data)
}
})
} // 启用禁用
const changePage = (page) => {
state.filter.page = page
getTableRows()
} // 改变页码
const changeSize = (size) => {
state.filter.limit = size
changePage(1)
} // 改变每页条数
}
const register = () => {
state.formData = {
name: "",
describe: "",
state: 1,
}
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate(valid => {
if (!valid) {
state.bgForm.clearValidate()
}
})
})
}
state.addType = 1
state.addDialog = true
} // 新建字典按钮
}
const edit_row = (row) => {
axios
.get(`/apaas/system/v5/dictionary/${row.id}`)
.then((res) => {
if (res.data.code == 200) {
state.actionRow = res.data.data
state.formData = {
name: state.actionRow.name,
describe: state.actionRow.describe,
state: state.actionRow.state
}
}else {
ElMessage.error(res.data.data)
}
}).catch((err) => {
console.log(err)
})
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate(valid => {
if (!valid) {
state.bgForm.clearValidate()
}
})
})
}
state.addType = 2
state.addDialog = true
} // 编辑按钮
const addConfirm = () => {
state.bgForm.validate(valid => {
if (valid) {
if (state.addType == 1) { // 新增
let params = {
classify_id: state.nodeClassifyId,
...state.formData
}
axios
.post(`/apaas/system/v5/dictionary/add`,params)
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.data)
state.tableRows = []
state.addDialog = false
changePage(1)
}else {
ElMessage.error(res.data.data)
}
})
}else { // 编辑
let params = {
id: state.actionRow.id,
...state.formData
}
axios
.put(`/apaas/system/v5/dictionary/update`,params)
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.data)
state.tableRows = []
state.addDialog = false
changePage(1)
}else {
ElMessage.error(res.data.data)
}
})
}
}
})
} // 确定新增/编辑
}
const delete_row = (row) => {
state.dialogDelete = true
state.actionRow = row
} // 删除按钮
const deleteData = () => {
axios
.delete(
`/apaas/system/v5/dictionary/${state.actionRow.id}`
)
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.data)
state.dialogDelete = false
state.tableRows = []
changePage(1)
}else {
ElMessage.error(res.data.data)
}
})
} // 确定删除
const moveRow = (row,type) => {
let index
state.tableRows.forEach((e,i) => {
if (e.id == row.id) {
index = i
}
})
let nextRow
if (type == 1) { // 上移
nextRow = state.tableRows[index - 1]
}else { // 下移
nextRow = state.tableRows[index + 1]
}
let params = [
{
id: row.id,
sort: nextRow.sort
},
{
id: nextRow.id,
sort: row.sort
}
]
// axios
// .put(``,[...params])
// .then((res) => {
// if (res.data.code == 200) {
// ElMessage.success(res.data.data)
// state.tableRows = []
// changePage(1)
// }else {
// ElMessage.error(res.data.data)
// }
// })
// .catch((err) => {
// console.log(err)
// })
}
onBeforeMount(() => {
state.nodeId = 1
onBeforeMount(() => {
getTypeList()
})
const {
typeList,
search,
nodeId,
typeKeyword,
nodeClassifyId,
headers,
tableRows,
tableTotal,
filter,
stateOptions,
dialogDelete,
addType,
addDialog,
formData,
rules,
} = toRefs(state)
......@@ -190,56 +562,123 @@ const {
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.main_container {
flex-grow: 1;
.flex_row {
// flex-grow: 1;
width: 100%;
display: flex;
// box-shadow: 0px 1px 4px 0px rgba(0,7,101,0.15);
margin-bottom: 16px;
position: relative;
.left_type {
height: calc(100vh - 118px);
width: 280px;
height: calc(100% - 62px);
.flex_left {
width: 240px;
background-color: #fff;
margin-right: 16px;
border-radius: 6px;
overflow: hidden;
padding: 16px;
.type_station {
margin-top: 16px;
height: calc(100% - 50px);
.type-box {
height: 32px;
line-height: 32px;
padding-left: 38px;
font-size: 14px;
color: #404a62;
cursor: pointer;
&:hover {
color: #3759be;
background-color: #dfe5f6;
height: 100%;
box-shadow: 0px 1px 4px 0px
rgba(0, 7, 101, 0.15);
overflow: hidden;
.box {
width: 208px;
height: 100%;
overflow: hidden;
.type_station {
width: 100%;
margin-top: 16px;
height: calc(100% - 50px);
.type-box {
height: 32px;
line-height: 32px;
text-align: center;
font-size: 14px;
color: #404a62;
cursor: pointer;
&:hover {
background-color: #f2f3f7;
}
}
.current-type{
background-color: #f2f3f7;
border-radius: 4px;
}
}
.current-type{
color: #3759be;
background-color: #dfe5f6;
}
}
}
.right_container {
.flex_right {
flex: 1;
background-color: #fff;
border-radius: 6px;
box-shadow: 0px 1px 4px 0px rgba(0,7,101,0.15);
height: 100%;
.filter-group {
.left-filter {
flex: 1;
display: flex;
justify-content: start;
flex-wrap: wrap;
}
.right-action {
width: 144px;
padding-bottom: 16px;
.el-button {
width: 64px;
}
}
}
.table_container {
width: 100%;
padding: 0 16px;
}
}
}
.bg_form {
width: 100%;
box-sizing: border-box;
.el-form-item {
margin-bottom: 24px;
:deep().el-form-item__label {
line-height: 36px;
height: 36px;
}
.el-form-item__content {
width: 100%;
.el-textarea {
:deep().el-input__count {
bottom: -16px;
right: 4px;
font-family: Roboto-Regular;
color: #a9b1c7;
}
}
.bg-switch-ele {
width: 52px;
height: 24px;
:deep().el-switch__core {
width: 100%;
height: 24px;
.el-switch__inner,
.el-switch__action {
top: 3px;
}
}
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="detail_container">
菜单管理
<div class="page_container">
<div class="bg-breadcrumb">
<el-breadcrumb separator="/">
<el-breadcrumb-item> 开发管理 </el-breadcrumb-item>
<el-breadcrumb-item > 菜单管理 </el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="flex_row">
<div class="flex_left">
<div class="tree_content">
<div class="search">
<el-input
v-model="search"
placeholder="请输入内容"
:prefix-icon="Search"
/>
</div>
<div class="tree">
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
:default-expand-all="true"
:highlight-current="true"
node-key="menu_id"
ref="menuTree"
>
<template #default="{ node, data }">
<div class="custom-tree-node" pointer-events="none">
<span
class="label-text text_clip"
:title="data.menu_name"
>{{ data.menu_name }}</span
>
</div>
<span class="tree-action-box">
<bg-icon
@click.stop="showAction($event, data,node)"
class="tree-more"
icon="#bg-ic-s-more"
></bg-icon>
</span>
</template>
</el-tree >
<Teleport to="body">
<div
class="tree-action"
ref="treeAction"
v-show="actionFlag"
:style="{ top: acTop, left: acLeft,bottom:acBottom }"
>
<div class="action" @click="fileAction(1,selectData,selectParentData)">
新建本级
</div>
<div class="action" @click="fileAction(2,selectData,selectParentData)">
新建下级
</div>
<div class="action" @click="fileAction(3,selectData,selectParentData)">
删除
</div>
<div class="action" :class="{'disable':moveIndex==0}" @click="fileAction(4,selectData,selectParentData,moveIndex==0)">
上移
</div>
<div class="action" :class="{'disable': !selectParentData ? moveIndex == data.length - 1 : moveIndex==selectParentData.Child.length-1}" @click="fileAction(5,selectData,selectParentData,!selectParentData ? moveIndex == data.length - 1 : moveIndex==selectParentData.Child.length-1)" >
下移
</div>
</div>
</Teleport>
</div>
</div>
</div>
<div class="flex_right">
<div class="main_container">
</div>
</div>
</div>
</div>
</template>
<script >
import { reactive, toRefs, ref, } from '@vue/reactivity'
import { getCurrentInstance } from 'vue'
import { computed, onBeforeMount } from '@vue/runtime-core'
<script setup>
import { Search } from '@element-plus/icons-vue'
import { reactive, toRefs, ref, nextTick, computed, onBeforeMount, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router';
export default {
components: {
import { ElMessage } from 'element-plus'
import axios from '../../../../request/http.js'
const router = useRouter();
const menuTree = ref(null)
const treeAction = ref(null)
const acTop = ref('');
const acLeft = ref('');
const acBottom = ref('');
const actionFlag = ref(false)
const state = reactive({
data: [],
search: "",
selectData:null,
selectParentData:null,
treeAction,
menuTree,
bottomGap:30,//弹窗吸底高度
defaultProps: {
children: 'Child',
label: 'menu_name',
},
setup() {
actionDataIndex: 0,
})
const moveIndex = computed({
get: () => {
let index = 0
if(state.selectData) {
console.log(state.selectData)
findIndex(state.selectData.menu_id,state.data)
index = state.actionDataIndex
}
return index
}
})
const getMenuTree = () => {
axios
.get(`/apaas/system/v5/menu/tree`)
.then((res) => {
if (res.data.code == 200) {
state.data = res.data.data || []
nextTick().then(() => {
state.menuTree && state.menuTree.setCurrentKey(state.data[0].menu_id);
handleNodeClick(state.data[0]);
})
}else {
ElMessage.error(res.data.data)
}
})
}
const findIndex= (code,arr) => {
arr.forEach((e,i) => {
if (e.menu_id == code) {
state.actionDataIndex = i
console.log(e,i)
}else {
if (e.Child && e.Child.length > 0) {
findIndex(code,e.Child)
}
}
})
}
const showAction = (e, data,node) => {
acTop.value = ''
acLeft.value = ''
acBottom.value = ''
const rect = e.target.getBoundingClientRect(); //获取点击的dom的位置
var allHeight = document.body.scrollHeight
console.log(rect, data,node);
onBeforeMount(() => {
actionFlag.value = true;
state.selectData = data
if(node.parent.data.Child){
state.selectParentData = node.parent.data
}else{
//没有children则是最上层元素
state.selectParentData = null
}
nextTick().then(()=>{
setTimeout(()=>{
var height = window.getComputedStyle(state.treeAction).height
height = parseInt(height)
//判断弹窗位置是否超过屏幕,超过则吸底展示
if(height+rect.y - 17>allHeight-state.bottomGap){
acBottom.value = state.bottomGap+ "px";
acLeft.value = rect.x + 35 + "px";
}else{
acTop.value = rect.y - 17 + "px";
acLeft.value = rect.x + 35 + "px";
}
})
return {
...toRefs(),
})
};
const handleNodeClick = (data) => {
if (state.selectData && state.selectData.menu_id == data.menu_id) {
return
}
state.selectData = data
console.log(data)
closeAction()
}
const fileAction = (val,data,parent,disabled=false) => {
if (val == 1) {
console.log("新建本级", data ,parent,disabled)
test()
}else if (val == 2) {
console.log("新建下级",data,parent,disabled)
test()
}else if (val == 3) {
console.log("删除",data,parent,disabled)
test()
}else if (val == 4) {
console.log("上移",data,parent,disabled)
test()
if (disabled) {
return
}
},
test()
}else {
console.log("下移",data,parent,disabled)
if (disabled) {
return
}
test()
}
}
const test = () => {
console.log("执行了")
}
const closeAction = () => {
actionFlag.value = false;
}
onBeforeMount(()=>{
window.addEventListener("click", closeAction)
window.addEventListener("scroll", closeAction,true)
getMenuTree()
})
onBeforeUnmount(()=>{
window.removeEventListener('click', closeAction);
window.removeEventListener('scroll', closeAction);
})
const {
data,
search,
defaultProps,
selectParentData,
selectData,
} = toRefs(state)
</script>
<style lang="scss" scoped>
<style scoped>
.tree_content {
overflow: hidden;
height: calc(100% - 4px);
position: relative;
}
.search {
padding: 16px 16px 10px;
}
.tree {
overflow: auto;
height: calc(100% - 65px);
}
.tree :deep().el-tree-node .el-tree-node__content {
padding: 0 16px!important;
}
.tree :deep() .el-tree-node>.el-tree-node__children {
overflow: unset;
padding-left: 16px;
}
.tree-action-box {
display: none;
position: absolute;
right: 0px;
background-color: #f2f3f7;
width: 44px;
text-align: center;
height: 36px;
line-height: 36px;
}
.tree .el-tree-node__content:hover .tree-action-box {
display: inline-block;
}
.tree-more {
font-size: 12px;
color: #3759be;
}
.tree-action {
width: 144px;
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
padding: 4px 0;
border-radius: 4px;
position: fixed;
z-index: 9;
}
.tree-action .action {
width: 100%;
height: 34px;
line-height: 34px;
padding-left: 16px;
font-size: 14px;
color: #202531;
cursor: pointer;
}
.tree-action .action:hover {
background-color: #f2f3f7;
color: #3759be;
}
.tree-action .disable{
cursor: not-allowed;
color: #616f94;
}
.tree-action .disable:hover{
background-color: #fff;
color: #616f94;
}
.main_container {
padding: 15px;
height: 100%;
}
.table_container {
height: calc(100% - 30px);
overflow: auto;
}
.pagination_box {
position: sticky;
margin-top: 16px;
bottom: 0px;
background-color: #fff;
z-index: 1024;
height: 40px;
line-height: 40px;
padding-top: 8px;
}
.bg-pagination {
bottom: unset
}
</style>
\ No newline at end of file
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