This commit is contained in:
小陌 2023-12-21 19:04:06 +08:00
parent 8fda6dfaa7
commit e41096adbd
6 changed files with 262 additions and 351 deletions

View File

@ -1,12 +1,6 @@
<template>
<div
:class="{
'vux-flex-col': orient === 'vertical',
'vux-flex-row': orient === 'horizontal'
}"
:style="styles"
class="vux-flexbox">
<slot/>
<div :class="{ 'vux-flex-col': orient === 'vertical', 'vux-flex-row': orient === 'horizontal' }" :style="styles" class="vux-flexbox">
<slot />
</div>
</template>
@ -14,10 +8,6 @@
export default {
name: 'Flexbox',
props: {
gutter: {
type: Number,
default: 8
},
orient: {
type: String,
default: 'horizontal'
@ -52,11 +42,13 @@ export default {
display: -webkit-flex;
box-align: center;
align-items: center;
.vux-flexbox-item {
flex: 1;
-webkit-flex: 1;
min-width: 20px;
width: 0%;
&:first-child {
margin-left: 0 !important;
margin-top: 0 !important;
@ -73,7 +65,8 @@ export default {
.vux-flex-col {
box-orient: vertical;
flex-direction: column;
> .vux-flexbox-item {
>.vux-flexbox-item {
width: 100%;
}
}

View File

@ -1,8 +1,10 @@
<template>
<div :class="{'is-select':select}" class="x-menu-item">
<i :style="{backgroundColor: select ? iconColor || '#2362FB' : '#edf2f6'}" :class="['x-menu-item__icon', iconClass]" />
<div :class="{ 'is-select': select }" class="x-menu-item">
<el-icon :style="{ backgroundColor: select ? iconColor || '#2362FB' : '#edf2f6' }" :class="['x-menu-item__icon', iconClass]">
<component :is="icon" />
</el-icon>
<span class="x-menu-item__label">{{ label }}</span>
<el-badge v-if="num > 0" :max="99" :value="num"/>
<el-badge v-if="num > 0" :max="99" :value="num" />
</div>
</template>
@ -12,7 +14,7 @@ export default {
name: 'xMenuItem',
components: {},
props: {
iconClass: String,
icon: String,
iconColor: String,
label: String,
//
@ -25,7 +27,7 @@ export default {
},
computed: {},
watch: {},
mounted() {},
mounted() { },
methods: {}
}
</script>
@ -35,25 +37,30 @@ export default {
padding: 12px 20px;
position: relative;
cursor: pointer;
display: flex;
align-items: center; /* 垂直居中 */
&__icon {
display: inline-block;
font-size: 12px;
padding: 6px;
border-radius: 4px;
background-color: #edf2f6;
color: #8a94a6;;
color: #bac5d8;
height: 1.3em;
text-align: center;
padding: 2px;
width: 1.3em;
line-height: 1.3em;
}
&__label {
color: var(--el-text-color-primary);
font-size: 13px;
margin-left: 10px;
margin-left: 5px;
}
&.is-select {
.x-menu-item__icon {
/* background-color: $x-color-primary;*/
color: white;
}
}
@ -71,7 +78,7 @@ export default {
top: 0;
bottom: 0;
width: 2px;
background-color: #2362fb;
background-color: var(--el-color-primary);
opacity: 0;
}
@ -79,7 +86,7 @@ export default {
opacity: 1;
}
.el-badge .el-badge__content {
.el-badge .el-badge__content {
border: none;
top: 0;
}
@ -87,6 +94,6 @@ export default {
.el-badge {
position: absolute;
right: 10px;
top: 15px;
top: 12px;
}
</style>

View File

@ -1,19 +1,21 @@
<!--
* @Descripttion: 页面头部样式组件
-->
<template>
<div class="x-page-header">
<div v-if="icon" class="x-page-header__icon">
<span>
<el-icon><component :is="icon" /></el-icon>
<el-icon>
<component :is="icon" />
</el-icon>
</span>
</div>
<div class="x-page-header__title">
<h2>{{ title }}</h2>
<h2>{{ title }} </h2>
<p v-if="description || $slots.default">
<slot>
{{ description }}
{{ description }}
</slot>
</p>
</div>
@ -24,24 +26,64 @@
</template>
<script>
export default {
props: {
title: { type: String, required: true, default: "" },
description: { type: String, default: "" },
icon: { type: String, default: "" },
}
export default {
props: {
title: { type: String, required: true, default: "" },
description: { type: String, default: "" },
icon: { type: String, default: "" },
}
}
</script>
<style scoped>
.x-page-header {background: var(--el-bg-color-overlay); border-bottom: 1px solid #e6e6e6; padding:20px 25px;display: flex;}
.x-page-header__icon {width: 50px;}
.x-page-header__icon span {display: inline-block;width: 30px;height: 30px;background: #409EFF;border-radius: 40%;display: flex;align-items: center;justify-content: center;}
.x-page-header__icon span i {color: #fff;font-size: 14px;}
.x-page-header__title {flex: 1;}
.x-page-header__title h2 {font-size: 17px;color: #3c4a54;font-weight: bold;margin-top: 3px;}
.x-page-header__title p {font-size: 13px;color: #999;margin-top: 15px;}
.x-page-header {
background: var(--el-bg-color-overlay);
border-bottom: 1px solid #e6e6e6;
padding: 20px 25px;
display: flex;
}
.dark .x-page-header {;border-color:var(--el-border-color-base);}
.dark .x-page-header__title h2 {color: #d0d0d0;}
</style>
.x-page-header__icon {
width: 40px;
}
.x-page-header__icon span {
display: inline-block;
width: 30px;
height: 30px;
background: var(--el-color-primary);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
}
.x-page-header__icon span i {
color: #fff;
font-size: 14px;
}
.x-page-header__title {
flex: 1;
}
.x-page-header__title h2 {
font-size: 17px;
color: #3c4a54;
font-weight: bold;
margin-top: 3px;
}
.x-page-header__title p {
font-size: 13px;
color: #999;
margin-top: 15px;
}
.dark .x-page-header {
border-color: var(--el-border-color-base);
}
.dark .x-page-header__title h2 {
color: #d0d0d0;
}</style>

View File

@ -3,7 +3,7 @@
<el-main>
<ContentWrap style="margin-bottom: 10px;" v-if="filter && filter.length > 0">
<el-form ref="queryFormRef" :inline="true" :model="search" class="-mb-15px" label-width="68">
<el-form-item style="white-space: nowrap;" :label="i.label" :prop="i.name" v-for="(i, index) in filter" :key="index">
<el-form-item :label="i.label" :style="{ 'white-space': 'nowrap', 'width': getWidth(i) }" :prop="i.name" v-for="(i, index) in filter" :key="index">
<x-item :item="i" v-model="search"></x-item>
</el-form-item>
<el-form-item>
@ -16,9 +16,14 @@
<ContentWrap class="xtable">
<el-tabs v-if="tabs && tabs.length > 0" v-model="search[tabskey]" @tab-change="tabChange">
<el-tab-pane v-for="item in tabs" :key="item.value" :label="item.label + (item.count ? '(' + item.count + ')' : '')" :name="item.value" />
<el-tab-pane v-for="item in tabs" :key="item.value" :label="item.label + (item.num ? '(' + item.num + ')' : '')" :name="item.value" />
</el-tabs>
<xTable :operationInfo="operation" ref="table" :tableColumn="column" :name="tablename" :params="search" :api="api" :row-key="key" :remoteSort="true" :remoteFilter="true" stripe>
<xTable :operationInfo="operation" :defaultExpandAll="tableexpand" ref="table" :tableColumn="column" :name="tablename" :params="search" :api="api" :row-key="key" :remoteSort="true" :remoteFilter="true" stripe>
<el-table-column type="expand" v-if="tableexpand">
<template #default="{ row }">
<el-input :value="row.content" type="textarea" style="cursor: pointer; " class="expandtextarea" readonly></el-input>
</template>
</el-table-column>
<el-table-column v-if="isselection" type="selection" width="50"></el-table-column>
<el-table-column :label="operation.label || '操作'" :width="operation.width || 124" :fixed="operation.fixed || 'right'" :align="operation.align || 'left'" v-if="operation.edit || operation.delete">
<template #default="scope">
@ -57,6 +62,7 @@ export default {
stat: false,
},
isselection: true,
tableexpand: false,
selection: [],
column: [],
aside: {
@ -66,6 +72,7 @@ export default {
api: '',
operation: {},
key: 'id',
title: '',
search: {},
tabs: [
// {label:'', value:0},
@ -94,12 +101,20 @@ export default {
if (res.data.tabsdefaultvalue && res.data.tabskey) {
this.search[res.data.tabskey] = res.data.tabsdefaultvalue
}
//
this.$emit('child-loaded', Object.assign({}, this.$data.aside, {search: this.$data.search}));
}
});
}
},
computed: {
getWidth() {
return function(item) {
return item.width ? item.width+'px' : 'auto';
}
},
filterObj() {
const obj = []
this.filter.forEach((item) => {
@ -201,6 +216,7 @@ export default {
</script>
<style>
.expandtextarea .el-textarea__inner{ box-shadow: none}
.xtable {
margin-top: 0px;
margin-bottom: 0px !important;

155
src/views/table/3/index.vue Normal file
View File

@ -0,0 +1,155 @@
<template>
<div class="message-body">
<div v-loading="loading" class="message-content">
<div class="message-body-side">
<div class="message-body-flexbox">
<x-page-header :title="title" :icon="icon"></x-page-header>
</div>
<div class="message-body-item">
<x-menu-item v-for="(item, index) in items" :key="index" :label="item.label" :num="item.num" :icon="item.icon" :icon-color="item.color" :select="search[searchkey] == item.value" @click="sideClick(item)" />
</div>
</div>
<div class="message-body-content">
<table2 ref="table" @childLoaded="getChildData"></table2>
</div>
</div>
</div>
</template>
<script>
import xMenuItem from '@/components/xMenu/item'
import table2 from './../2'
export default {
name: 'table_3',
components: {
table2,
xMenuItem,
},
data() {
return {
loading: true,
icon: '',
title: '',
items: [],
searchkey: '',
search: {},
}
},
computed: {
},
watch: {
},
mounted() {
},
methods: {
/**
* 侧边点击
*/
sideClick(item) {
this.info = item
this.search[this.searchkey || 'type'] = item.value;
this.$refs.table.filterChange(this.search);
},
getChildData(o) {
Object.assign(this.$data, o);
this.loading = false;
},
}
}
</script>
<style lang="scss" scoped>
.x-page-header {
border-bottom: 1px solid #ebebebc2;
padding: 10px 20px;
.x-page-header__icon {
width: 40px;
}
}
.message-header {
margin-left: 28px;
height: 60px;
.title-icon {
width: 30px;
height: 30px;
margin-right: 10px;
border-radius: 4px;
}
.title {
font-size: 16px;
font-weight: 600;
}
}
.message-body {
position: relative;
height: 100%;
}
.message-content {
position: relative;
height: 100%;
}
.message-body-side {
padding: 0px 0;
width: 180px;
font-size: 14px;
background-color: white;
position: absolute;
top: 0;
left: 0;
bottom: 0;
z-index: 100;
border-right: 1px solid #e6e6e6;
// border-radius: 4px;
overflow-y: auto;
.side-item {
position: relative;
height: 50px;
line-height: 50px;
padding: 0 20px;
font-size: 13px;
cursor: pointer;
i {
color: #999;
}
}
}
.message-body-content {
margin-left: 180px;
height: 100%;
overflow: hidden;
}
@media (max-width: 767px) {
.message-body-side {
width: 0px;
transition: all 0.1s;
overflow-y: hidden;
}
.message-body-content {
margin-left: 0px;
transition: all 0.1s;
}
}
</style>

View File

@ -1,302 +0,0 @@
<template>
<div class="message-body">
<div v-loading="loading" class="message-content">
<div class="message-body-side">
<div class="message-body-flexbox">
<flexbox class="message-header">
<img src="@/assets/img/crm/todo.png" class="title-icon">
<span class="title">待办事项</span>
</flexbox>
</div>
<div class="message-body-item">
<x-menu-item v-for="(item, index) in showLeftSides" :key="index" :label="item.name" :num="item.num" :icon-class="item.iconClass" :icon-color="item.color" :select="leftType == item.infoType" @click="sideClick(item)" />
</div>
</div>
<div class="message-body-content">
<table2></table2>
</div>
</div>
</div>
</template>
<script>
import xMenuItem from '@/components/xMenu/item'
import table2 from './../../table/2'
export default {
/** 客户管理 的 消息列表 */
name: 'trajectory',
components: {
table2,
xMenuItem,
},
data() {
return {
loading: false,
leftType: '',
contentHeight: document.documentElement.clientHeight - 84,
info: {},
leftSides: [
{
name: '今日需联系线索',
color: '#2362FB',
iconClass: 'wk wk-leads',
infoType: 'todayLeads',
num: 10,
hidden: false
},
{
name: '今日需联系客户',
color: '#2362FB',
iconClass: 'wk wk-customer',
infoType: 'todayCustomer',
num: 0,
hidden: false
},
{
name: '今日需联系商机',
color: '#2362FB',
iconClass: 'wk wk-business',
infoType: 'todayBusiness',
num: 0,
hidden: false
},
{
name: '分配给我的线索',
color: '#704AFD',
iconClass: 'wk wk-leads',
infoType: 'followLeads',
num: 0,
hidden: false
},
{
name: '分配给我的客户',
color: '#19B5F6',
iconClass: 'wk wk-s-seas',
infoType: 'followCustomer',
num: 0,
hidden: false
},
{
name: '待进入公海的客户',
color: '#26D4DA',
iconClass: 'wk wk-seas',
infoType: 'putInPoolRemind',
num: 0,
hidden: false
},
{
name: '待审核合同',
color: '#FD5B4A',
iconClass: 'wk wk-contract',
infoType: 'checkContract',
num: 0,
hidden: false
},
{
name: '待审核回款',
color: '#FFB940',
iconClass: 'wk wk-receivables',
infoType: 'checkReceivables',
num: 0,
hidden: false
},
{
name: '待回款提醒',
color: '#27BA4A',
iconClass: 'wk wk-bell',
infoType: 'remindReceivablesPlan',
num: 0,
hidden: false
},
{
name: '即将到期的合同',
color: '#FF7A38',
iconClass: 'wk wk-contract',
infoType: 'endContract',
num: 0,
hidden: false
},
{
name: '待回访合同',
color: '#ff9232',
iconClass: 'wk wk-house',
infoType: 'returnVisitRemind',
num: 0,
hidden: false
},
{
name: '待审核发票',
color: '#ff9232',
iconClass: 'wk wk-invoice',
infoType: 'checkInvoice',
num: 0,
hidden: false
}
]
}
},
computed: {
showLeftSides() {
return this.leftSides.filter(item => {
return !item.hidden
})
}
},
watch: {
/** 变化就刷新数据 */
// messageNum() {
// this.refreshNum()
// }
},
mounted() {
// this.loading = true
// this.requestNumCount()
/** 控制table的高度 */
// window.onresize = () => {
// var offsetHei = document.documentElement.clientHeight
// this.$bus.emit('message-scroll', offsetHei - 300)
// }
},
methods: {
/**
* 获取数据
*/
requestNumCount() {
// this.$store
// .dispatch('GetMessageNum')
// .then(res => {
// this.loading = false
// this.refreshNum()
// })
// .catch(() => {
// this.loading = false
// })
// this.refreshNum()
},
/**
* 刷新消息数据
*/
refreshNum() {
for (let index = 0; index < this.leftSides.length; index++) {
const element = this.leftSides[index]
// if (this.messageNum.hasOwnProperty(element.infoType)) {
// element.num = this.messageNum[element.infoType] || 0
element.hidden = false
// } else {
// element.hidden = true
// }
}
if (!this.leftType && this.showLeftSides.length > 0) {
this.leftType = this.showLeftSides[0].infoType
}
},
/**
* 消息页面点击操作
*/
messageHandle(data) {
if (data.type == 'follow') {
const copyNum = {}
const num = parseInt(copyNum[data.infoType]) - data.value
copyNum[data.infoType] = num > 0 ? num : 0
this.$store.commit('SET_MESSAGENUM', copyNum)
}
},
/**
* 侧边点击
*/
sideClick(item) {
this.info = item
this.leftType = item.infoType
}
}
}
</script>
<style lang="scss" scoped>
.message-header {
margin-left: 28px;
height: 60px;
.title-icon {
width: 30px;
height: 30px;
margin-right: 10px;
}
.title {
font-size: 16px;
font-weight: 600;
}
}
.message-body {
position: relative;
height: 100%;
}
.message-content {
position: relative;
height: 100%;
}
.message-body-side {
padding: 0px 0;
width: 180px;
font-size: 14px;
background-color: white;
position: absolute;
top: 0;
left: 0;
bottom: 0;
z-index: 1;
border-right: 1px solid #e6e6e6;
// border-radius: 4px;
overflow-y: auto;
.side-item {
position: relative;
height: 50px;
line-height: 50px;
padding: 0 20px;
font-size: 13px;
cursor: pointer;
i {
color: #999;
}
}
}
.message-body-content {
margin-left: 180px;
height: 100%;
overflow: hidden;
}
@media (max-width: 767px) {
.message-body-side {
width: 0px;
transition: all 0.1s;
overflow-y: hidden;
}
.message-body-content {
margin-left: 10px;
transition: all 0.1s;
}
}
</style>