feat: 新媒体数据看板字段对接
This commit is contained in:
@ -44,7 +44,7 @@
|
|||||||
.label {
|
.label {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
color: #211f24;
|
color: #211f24;
|
||||||
font-family: 'PuHuiTi-Medium';
|
font-family: 'PuHuiTi-Regular';
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|||||||
@ -2,13 +2,167 @@
|
|||||||
* @Author: RenXiaoDong
|
* @Author: RenXiaoDong
|
||||||
* @Date: 2025-06-28 10:33:06
|
* @Date: 2025-06-28 10:33:06
|
||||||
*/
|
*/
|
||||||
export const getDefaultColumns = (type = 'week') => {
|
|
||||||
const isWeek = type === 'week';
|
|
||||||
const viewChain = isWeek ? 'week_view_chain' : 'month_view_chain';
|
|
||||||
const likeChain = isWeek ? 'week_like_chain' : 'month_like_chain';
|
|
||||||
const viewChainText = isWeek ? '近7天观看量环比' : '近30天观看量环比';
|
|
||||||
const likeChainText = isWeek ? '近7天点赞量环比' : '近30天点赞量环比';
|
|
||||||
|
|
||||||
|
export const CUSTOM_FIELDS = [
|
||||||
|
{
|
||||||
|
dataIndex: 'comment_number',
|
||||||
|
prop: 'comment_number',
|
||||||
|
title: '评论数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的评论总数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'share_number',
|
||||||
|
prop: 'share_number',
|
||||||
|
title: '分享数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的分享总数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'like_number',
|
||||||
|
prop: 'like_number',
|
||||||
|
title: '点赞数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的点赞总数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'rise_fans_number',
|
||||||
|
prop: 'rise_fans_number',
|
||||||
|
title: '粉丝增长数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的粉丝增长总数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'collect_number',
|
||||||
|
prop: 'collect_number',
|
||||||
|
title: '收藏数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的收藏总数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'view_number',
|
||||||
|
prop: 'view_number',
|
||||||
|
title: '浏览数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的浏览总数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'avg_view_time',
|
||||||
|
prop: 'avg_view_time',
|
||||||
|
title: '平均浏览数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的平均浏览数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'home_view_number',
|
||||||
|
prop: 'home_view_number',
|
||||||
|
title: '主页浏览数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的主页浏览数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'barrage_number',
|
||||||
|
prop: 'barrage_number',
|
||||||
|
title: '弹幕数',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的弹幕总数',
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'rise_fans_rate',
|
||||||
|
prop: 'rise_fans_rate',
|
||||||
|
title: '粉丝增长率',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的粉丝增长率',
|
||||||
|
align: 'right',
|
||||||
|
suffix: '%',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'home_view_rate',
|
||||||
|
prop: 'home_view_rate',
|
||||||
|
title: '主页浏览率',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的主页浏览率',
|
||||||
|
align: 'right',
|
||||||
|
suffix: '%',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'share_rate',
|
||||||
|
prop: 'share_rate',
|
||||||
|
title: '分享率',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的分享率',
|
||||||
|
align: 'right',
|
||||||
|
suffix: '%',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'collect_rate',
|
||||||
|
prop: 'collect_rate',
|
||||||
|
title: '收藏率',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的收藏率',
|
||||||
|
align: 'right',
|
||||||
|
suffix: '%',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'comment_rate',
|
||||||
|
prop: 'comment_rate',
|
||||||
|
title: '评论率',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的评论率',
|
||||||
|
align: 'right',
|
||||||
|
suffix: '%',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'avg_view_time_rate',
|
||||||
|
prop: 'avg_view_time_rate',
|
||||||
|
title: '平均访问时长增长比率',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '账号所有内容的平均访问时长增长比率',
|
||||||
|
align: 'right',
|
||||||
|
suffix: '%',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function getPeriodColumns(type = 'week') {
|
||||||
|
const prefix = type === 'week' ? 'seven' : 'thirty';
|
||||||
|
const labelPrefix = type === 'week' ? '近7天' : '近30天';
|
||||||
|
|
||||||
|
return CUSTOM_FIELDS.map((item) => ({
|
||||||
|
...item,
|
||||||
|
dataIndex: `${prefix}_${item.dataIndex}`,
|
||||||
|
title: `${labelPrefix}${item.title}`,
|
||||||
|
prop: `${prefix}_${item.prop}`,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getDefaultColumns = (type = 'week') => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: '账号名称',
|
title: '账号名称',
|
||||||
@ -65,56 +219,12 @@ export const getDefaultColumns = (type = 'week') => {
|
|||||||
sortDirections: ['ascend', 'descend'],
|
sortDirections: ['ascend', 'descend'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
...getPeriodColumns(type),
|
||||||
title: '观看量',
|
|
||||||
dataIndex: 'view_number',
|
|
||||||
prop: 'view_number',
|
|
||||||
width: 180,
|
|
||||||
tooltip: '账号所有内容的总观看次数',
|
|
||||||
align: 'right',
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: viewChainText,
|
|
||||||
dataIndex: viewChain,
|
|
||||||
prop: viewChain,
|
|
||||||
width: 180,
|
|
||||||
tooltip: '相比上一周期的观看量变化百分比',
|
|
||||||
align: 'right',
|
|
||||||
suffix: '%',
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '点赞量',
|
|
||||||
dataIndex: 'like_number',
|
|
||||||
prop: 'like_number',
|
|
||||||
width: 180,
|
|
||||||
tooltip: '账号所有内容的总点赞数',
|
|
||||||
align: 'right',
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: likeChainText,
|
|
||||||
dataIndex: likeChain,
|
|
||||||
prop: likeChain,
|
|
||||||
width: 180,
|
|
||||||
tooltip: '相比上一周期的点赞量变化百分比',
|
|
||||||
align: 'right',
|
|
||||||
suffix: '%',
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '最新内容标题/日期',
|
title: '最新内容标题/日期',
|
||||||
dataIndex: 'newest_work_title_and_publish_time',
|
dataIndex: 'newest_work_title',
|
||||||
prop: 'newest_work_title_and_publish_time',
|
prop: 'newest_work_title',
|
||||||
width: 240,
|
width: 240,
|
||||||
tooltip: '最新发布内容的标题和发布日期',
|
tooltip: '最新发布内容的标题和发布日期',
|
||||||
},
|
},
|
||||||
@ -130,20 +240,64 @@ export const getDefaultColumns = (type = 'week') => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '最新作品日增长',
|
title: '最新作品点赞数',
|
||||||
dataIndex: 'newest_work_view_grow_number',
|
dataIndex: 'newest_work_like_number',
|
||||||
prop: 'newest_work_view_grow_number',
|
prop: 'newest_work_like_number',
|
||||||
width: 180,
|
width: 180,
|
||||||
tooltip: '最新作品每日观看量的增长情况',
|
tooltip: '最新发布内容的点赞数',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
sortable: {
|
sortable: {
|
||||||
sortDirections: ['ascend', 'descend'],
|
sortDirections: ['ascend', 'descend'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '最新作品收藏数',
|
||||||
|
dataIndex: 'newest_work_collect_number',
|
||||||
|
prop: 'newest_work_collect_number',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '最新发布内容的收藏数',
|
||||||
|
align: 'right',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '最新作品评论数',
|
||||||
|
dataIndex: 'newest_work_comment_number',
|
||||||
|
prop: 'newest_work_comment_number',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '最新发布内容的评论数',
|
||||||
|
align: 'right',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '最新作品分享数',
|
||||||
|
dataIndex: 'newest_work_share_number',
|
||||||
|
prop: 'newest_work_share_number',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '最新发布内容的分享数',
|
||||||
|
align: 'right',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: '最新作品日增长',
|
||||||
|
// dataIndex: 'newest_work_view_grow_number',
|
||||||
|
// prop: 'newest_work_view_grow_number',
|
||||||
|
// width: 180,
|
||||||
|
// tooltip: '最新作品每日观看量的增长情况',
|
||||||
|
// align: 'right',
|
||||||
|
// sortable: {
|
||||||
|
// sortDirections: ['ascend', 'descend'],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '次新内容标题/日期',
|
title: '次新内容标题/日期',
|
||||||
dataIndex: 'second_new_work_title_and_publish_time',
|
dataIndex: 'second_new_work_title',
|
||||||
prop: 'second_new_work_title_and_publish_time',
|
prop: 'second_new_work_title',
|
||||||
width: 240,
|
width: 240,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -158,16 +312,49 @@ export const getDefaultColumns = (type = 'week') => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '次新作品日增长',
|
title: '次新作品点赞数',
|
||||||
dataIndex: 'second_new_work_view_grow_number',
|
dataIndex: 'second_new_work_like_number',
|
||||||
prop: 'second_new_work_view_grow_number',
|
prop: 'second_new_work_like_number',
|
||||||
width: 180,
|
width: 180,
|
||||||
tooltip: '倒数第二个作品每日观看量的增长情况',
|
tooltip: '倒数第二个发布内容的点赞数',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
sortable: {
|
sortable: {
|
||||||
sortDirections: ['ascend', 'descend'],
|
sortDirections: ['ascend', 'descend'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '次新作品评论数',
|
||||||
|
dataIndex: 'second_new_work_comment_number',
|
||||||
|
prop: 'second_new_work_comment_number',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '倒数第二个发布内容的评论数',
|
||||||
|
align: 'right',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '次新作品分享数',
|
||||||
|
dataIndex: 'second_new_work_share_number',
|
||||||
|
prop: 'second_new_work_share_number',
|
||||||
|
width: 180,
|
||||||
|
tooltip: '倒数第二个发布内容的分享数',
|
||||||
|
align: 'right',
|
||||||
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: '次新作品日增长',
|
||||||
|
// dataIndex: 'second_new_work_view_grow_number',
|
||||||
|
// prop: 'second_new_work_view_grow_number',
|
||||||
|
// width: 180,
|
||||||
|
// tooltip: '倒数第二个作品每日观看量的增长情况',
|
||||||
|
// align: 'right',
|
||||||
|
// sortable: {
|
||||||
|
// sortDirections: ['ascend', 'descend'],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'operation',
|
dataIndex: 'operation',
|
||||||
|
|||||||
@ -32,7 +32,11 @@
|
|||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:data="dataSource"
|
:data="dataSource"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:row-selection="rowSelection"
|
:row-selection="{
|
||||||
|
type: 'checkbox',
|
||||||
|
showCheckedAll: true,
|
||||||
|
width: 48,
|
||||||
|
}"
|
||||||
:selected-keys="selectedItems"
|
:selected-keys="selectedItems"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:scroll="{ x: '100%' }"
|
:scroll="{ x: '100%' }"
|
||||||
@ -113,14 +117,17 @@
|
|||||||
{{ formatTableField(column, record) }}
|
{{ formatTableField(column, record) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template
|
<template v-else-if="column.dataIndex === 'newest_work_title'" #cell="{ record }">
|
||||||
v-else-if="
|
<p class="cts cursor-pointer hover:!color-#6D4CFE">{{ record.newest_work_title }}</p>
|
||||||
['newest_work_title_and_publish_time', 'second_new_work_title_and_publish_time'].includes(column.dataIndex)
|
<p class="cts text-12px lh-20px !color-#939499">
|
||||||
"
|
{{ exactFormatTime(record.newest_work_published_at) }}
|
||||||
#cell="{ record }"
|
</p>
|
||||||
>
|
</template>
|
||||||
<p class="cts cursor-pointer hover:!color-#6D4CFE">打工人的环游世界旅行计划(国内版)</p>
|
<template v-else-if="column.dataIndex === 'second_new_work_title'" #cell="{ record }">
|
||||||
<p class="cts text-12px lh-20px !color-#939499">2025-06-18</p>
|
<p class="cts cursor-pointer hover:!color-#6D4CFE">{{ record.second_new_work_title }}</p>
|
||||||
|
<p class="cts text-12px lh-20px !color-#939499">
|
||||||
|
{{ exactFormatTime(record.second_new_work_published_at) }}
|
||||||
|
</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else #cell="{ record }">
|
<template v-else #cell="{ record }">
|
||||||
@ -130,7 +137,12 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
|
|
||||||
<CustomTableColumnModal ref="customTableColumnModalRef" :type="CUSTOM_COLUMN_TYPE" @success="onCustomColumnSuccess" />
|
<CustomTableColumnModal
|
||||||
|
ref="customTableColumnModalRef"
|
||||||
|
:type="CUSTOM_COLUMN_TYPE"
|
||||||
|
:dateType="dateType"
|
||||||
|
@success="onCustomColumnSuccess"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -139,9 +151,9 @@ import { useRouter } from 'vue-router';
|
|||||||
|
|
||||||
import { getCustomColumns } from '@/api/all/common';
|
import { getCustomColumns } from '@/api/all/common';
|
||||||
import { STATUS_LIST } from '@/views/property-marketing/media-account/components/status-select/constants';
|
import { STATUS_LIST } from '@/views/property-marketing/media-account/components/status-select/constants';
|
||||||
import { formatTableField, formatNumberShow } from '@/utils/tools';
|
import { formatTableField, formatNumberShow, exactFormatTime } from '@/utils/tools';
|
||||||
import { getDefaultColumns } from './constants';
|
import { getDefaultColumns } from './constants';
|
||||||
import CustomTableColumnModal from '@/components/custom-table-column-modal';
|
import CustomTableColumnModal from '../custom-column-modal';
|
||||||
|
|
||||||
import icon1 from '@/assets/img/media-account/icon-custom.png';
|
import icon1 from '@/assets/img/media-account/icon-custom.png';
|
||||||
import icon2 from '@/assets/img/media-account/icon-warn.png';
|
import icon2 from '@/assets/img/media-account/icon-warn.png';
|
||||||
@ -154,6 +166,10 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
query: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['selectionChange', 'sorterChange', 'export']);
|
const emit = defineEmits(['selectionChange', 'sorterChange', 'export']);
|
||||||
@ -173,15 +189,12 @@ const checkedAll = computed(
|
|||||||
const indeterminate = computed(
|
const indeterminate = computed(
|
||||||
() => selectedItems.value.length > 0 && selectedItems.value.length < props.dataSource.length,
|
() => selectedItems.value.length > 0 && selectedItems.value.length < props.dataSource.length,
|
||||||
);
|
);
|
||||||
|
const dateType = computed(() => (props.query.type === 7 ? 'week' : 'month'));
|
||||||
const rowSelection = computed(() => ({
|
|
||||||
type: 'checkbox',
|
|
||||||
showCheckedAll: true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const tableColumns = computed(() => {
|
const tableColumns = computed(() => {
|
||||||
const _result = [];
|
const _result = [];
|
||||||
const _columns = getDefaultColumns();
|
const _columns = getDefaultColumns(dateType.value);
|
||||||
|
|
||||||
selectedColumns.value.forEach((item) => {
|
selectedColumns.value.forEach((item) => {
|
||||||
const _column = _columns.find((_item) => _item.prop === item);
|
const _column = _columns.find((_item) => _item.prop === item);
|
||||||
if (_column) {
|
if (_column) {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 677 B |
@ -0,0 +1,218 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: RenXiaoDong
|
||||||
|
* @Date: 2025-06-30 10:54:49
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="visible"
|
||||||
|
title="自定义列"
|
||||||
|
width="960px"
|
||||||
|
unmountOnClose
|
||||||
|
titleAlign="start"
|
||||||
|
class="custom-table-column-modal-98"
|
||||||
|
@close="close"
|
||||||
|
>
|
||||||
|
<div class="modal-body">
|
||||||
|
<!-- 左侧分组 -->
|
||||||
|
<div class="left">
|
||||||
|
<div v-for="group in dataSource" :key="group.label" class="group-item">
|
||||||
|
<div class="title-row">
|
||||||
|
<span class="text">{{ group.label }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="fields">
|
||||||
|
<a-checkbox
|
||||||
|
v-for="option in group.columns"
|
||||||
|
:key="option.value"
|
||||||
|
:model-value="isCheck(option)"
|
||||||
|
:value="option.value"
|
||||||
|
:disabled="option.is_require === ENUM_STATUS.NO"
|
||||||
|
@change="(checked) => onCheckChange(checked, option)"
|
||||||
|
>
|
||||||
|
{{ option.label }}
|
||||||
|
</a-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧已选 -->
|
||||||
|
<div class="right">
|
||||||
|
<span class="checked-title mb-16px">
|
||||||
|
已添加<span class="count">({{ checkColumns.length }})</span>
|
||||||
|
</span>
|
||||||
|
<div class="checked-list">
|
||||||
|
<div v-for="(groupName, index) in requiredGroupNames" :key="index" class="checked-item !cursor-default">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img :src="icon1" alt="icon" class="mr-8px" width="16" height="16" />
|
||||||
|
<span>{{ groupName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<VueDraggable v-model="checkColumns">
|
||||||
|
<div
|
||||||
|
v-for="item in checkColumns"
|
||||||
|
:key="item"
|
||||||
|
class="checked-item justify-between"
|
||||||
|
:class="isRequiredColumn(item) ? '!display-none' : ''"
|
||||||
|
>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<icon-menu size="16" class="mr-8px" />
|
||||||
|
<span>{{ getCheckColumnLabel(item) }}</span>
|
||||||
|
</div>
|
||||||
|
<icon-close size="16" class="color-#737478 cursor-pointer" @click="removeCheckedField(item)" />
|
||||||
|
</div>
|
||||||
|
</VueDraggable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<a-button class="mr-8px cancel-btn" size="medium" @click="close">取消</a-button>
|
||||||
|
<a-button type="primary" size="medium" @click="onSubmit">确定</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineExpose } from 'vue';
|
||||||
|
import { VueDraggable } from 'vue-draggable-plus';
|
||||||
|
|
||||||
|
import { getCustomColumns, updateCustomColumns } from '@/api/all/common';
|
||||||
|
import { CUSTOM_FIELDS } from '../account-table/constants';
|
||||||
|
|
||||||
|
import icon1 from './img/icon-lock.png';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
dateType: {
|
||||||
|
type: String,
|
||||||
|
default: 'week',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['success']);
|
||||||
|
|
||||||
|
const ENUM_STATUS = {
|
||||||
|
YES: 0,
|
||||||
|
NO: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const visible = ref(false);
|
||||||
|
|
||||||
|
const dataSource = ref([]);
|
||||||
|
const checkColumns = ref([]); // 选中字段
|
||||||
|
const allColumns = ref([]); // 所有字段
|
||||||
|
const requiredGroupNames = ref([]); // 必选分组名称
|
||||||
|
|
||||||
|
const open = () => {
|
||||||
|
initData();
|
||||||
|
visible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
visible.value = false;
|
||||||
|
|
||||||
|
dataSource.value = [];
|
||||||
|
checkColumns.value = [];
|
||||||
|
allColumns.value = [];
|
||||||
|
requiredGroupNames.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const initData = async () => {
|
||||||
|
const { code, data } = await getCustomColumns({ type: props.type });
|
||||||
|
if (code === 200) {
|
||||||
|
const { selected_columns, groups } = data;
|
||||||
|
dataSource.value = groups;
|
||||||
|
formatDataSource();
|
||||||
|
|
||||||
|
setDefaultCheckColumns(groups, selected_columns);
|
||||||
|
allColumns.value = groups.flatMap((group) => group.columns);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 过滤近7天/近30天字段
|
||||||
|
const formatDataSource = () => {
|
||||||
|
const prefix = props.dateType === 'week' ? 'seven_' : 'thirty_';
|
||||||
|
dataSource.value.forEach((group) => {
|
||||||
|
group.columns = group.columns.filter((item) => {
|
||||||
|
if (item.value.startsWith('seven_') || item.value.startsWith('thirty_')) {
|
||||||
|
return item.value.startsWith(prefix);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const isCheck = (option) => {
|
||||||
|
return checkColumns.value.includes(option.value);
|
||||||
|
};
|
||||||
|
const getCheckColumnLabel = (value) => {
|
||||||
|
const column = allColumns.value.find((column) => column.value === value);
|
||||||
|
return column?.label;
|
||||||
|
};
|
||||||
|
const isRequiredColumn = (value) => {
|
||||||
|
const column = allColumns.value.find((column) => column.value === value);
|
||||||
|
return column?.is_require === 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeCheckedField = (value) => {
|
||||||
|
checkColumns.value = checkColumns.value.filter((column) => column !== value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 勾选/取消
|
||||||
|
const onCheckChange = (checked, option) => {
|
||||||
|
if (checked) {
|
||||||
|
checkColumns.value.push(option.value);
|
||||||
|
} else {
|
||||||
|
checkColumns.value = checkColumns.value.filter((item) => item !== option.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const onSubmit = async () => {
|
||||||
|
const result = checkColumns.value
|
||||||
|
.map((item) => {
|
||||||
|
if (item.startsWith('thirty_')) {
|
||||||
|
return [item, item.replace('thirty_', 'seven_')];
|
||||||
|
} else if (item.startsWith('seven_')) {
|
||||||
|
return [item, item.replace('seven_', 'thirty_')];
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flat();
|
||||||
|
|
||||||
|
const { code } = await updateCustomColumns({ type: props.type, selected_columns: result });
|
||||||
|
if (code === 200) {
|
||||||
|
emit('success', result);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setDefaultCheckColumns = (groups, selected_columns) => {
|
||||||
|
const prefix = props.dateType === 'week' ? 'seven_' : 'thirty_';
|
||||||
|
const requiredGroups = groups.filter((group) => group.is_require === 1);
|
||||||
|
const requiredValues = requiredGroups
|
||||||
|
.flatMap((group) => (group.columns || []).filter((col) => col.is_require === 1))
|
||||||
|
.map((col) => col.value);
|
||||||
|
|
||||||
|
const filteredSelected = selected_columns.filter(
|
||||||
|
(col) => (!col.startsWith('seven_') && !col.startsWith('thirty_')) || col.startsWith(prefix),
|
||||||
|
);
|
||||||
|
|
||||||
|
const merged = union(requiredValues, filteredSelected);
|
||||||
|
|
||||||
|
checkColumns.value = merged;
|
||||||
|
requiredGroupNames.value = requiredGroups.map((group) => group.label);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({ open });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import './style.scss';
|
||||||
|
</style>
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
.custom-table-column-modal-98 {
|
||||||
|
.arco-modal-body {
|
||||||
|
.modal-body {
|
||||||
|
height: 504px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--BG-300, #e6e6e8);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
.left {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
overflow-y: auto;
|
||||||
|
.group-item {
|
||||||
|
.title-row {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--BG-100, #f7f8fa);
|
||||||
|
display: flex;
|
||||||
|
height: 44px;
|
||||||
|
padding: 0px 12px;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
.text {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
font-family: 'PuHuiTi-Medium';
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 24px; /* 150% */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fields {
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
width: 280px;
|
||||||
|
padding: 16px 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.checked-title {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
font-family: 'PuHuiTi-Medium';
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 24px;
|
||||||
|
.count {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.checked-list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
.checked-item {
|
||||||
|
cursor: move;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--BG-100, #f7f8fa);
|
||||||
|
display: flex;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0px 12px;
|
||||||
|
align-items: center;
|
||||||
|
.text {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
font-family: 'PuHuiTi-Medium';
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px; /* 157.143% */
|
||||||
|
}
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.draggable-list {
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.arco-modal-footer {
|
||||||
|
.cancel-btn {
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid var(--BG-500, #b1b2b5);
|
||||||
|
background: var(--BG-white, #fff);
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid var(--BG-500, #b1b2b5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="filter-row flex">
|
<div class="filter-row flex mb-20px">
|
||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
<span class="label">账号名称</span>
|
<span class="label">账号名称</span>
|
||||||
<a-space size="medium" class="w-240px">
|
<a-space size="medium" class="w-240px">
|
||||||
@ -34,7 +34,19 @@
|
|||||||
<OperatorSelect v-model="query.operator_id" :options="operators" @change="handleSearch" />
|
<OperatorSelect v-model="query.operator_id" :options="operators" @change="handleSearch" />
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="filter-row flex">
|
||||||
|
<div class="filter-row-item flex items-center">
|
||||||
|
<span class="label">时间筛选</span>
|
||||||
|
<a-space class="w-240px">
|
||||||
|
<a-select v-model="query.type" size="medium" placeholder="全部" class="w-120px" @change="handleSearch">
|
||||||
|
<template #arrow-icon> <icon-calendar size="16" /> </template>
|
||||||
|
<a-option :value="7" label="近7天">近7天</a-option>
|
||||||
|
<!-- <a-option :value="14" label="近14天">近14天</a-option> -->
|
||||||
|
<a-option :value="30" label="近30天">近30天</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
<a-button class="w-84px search-btn mr-12px" size="medium" @click="handleSearch">
|
<a-button class="w-84px search-btn mr-12px" size="medium" @click="handleSearch">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-search />
|
<icon-search />
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: RenXiaoDong
|
* @Author: RenXiaoDong
|
||||||
* @Date: 2025-06-27 17:23:56
|
* @Date: 2025-07-04 15:50:37
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import icon1 from '@/assets/img/media-account/icon1.png';
|
import icon1 from '@/assets/img/media-account/icon1.png';
|
||||||
import icon2 from '@/assets/img/media-account/icon2.png';
|
import icon2 from '@/assets/img/media-account/icon2.png';
|
||||||
import icon3 from '@/assets/img/media-account/icon3.png';
|
import icon3 from '@/assets/img/media-account/icon3.png';
|
||||||
@ -39,7 +38,7 @@ export const INITIAL_QUERY = {
|
|||||||
status: '',
|
status: '',
|
||||||
operator_id: '',
|
operator_id: '',
|
||||||
group_ids: [],
|
group_ids: [],
|
||||||
// date_range: '',
|
type: 7,
|
||||||
column: '',
|
column: '',
|
||||||
order: '',
|
order: '',
|
||||||
};
|
};
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
<AccountTable
|
<AccountTable
|
||||||
ref="accountTableRef"
|
ref="accountTableRef"
|
||||||
:dataSource="dataSource"
|
:dataSource="dataSource"
|
||||||
|
:query="query"
|
||||||
@selectionChange="handleSelectionChange"
|
@selectionChange="handleSelectionChange"
|
||||||
@export="handleExport"
|
@export="handleExport"
|
||||||
@sorterChange="handleSorterChange"
|
@sorterChange="handleSorterChange"
|
||||||
|
|||||||
@ -33,7 +33,11 @@
|
|||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:data="dataSource"
|
:data="dataSource"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:row-selection="rowSelection"
|
:row-selection="{
|
||||||
|
type: 'checkbox',
|
||||||
|
showCheckedAll: true,
|
||||||
|
width: 48,
|
||||||
|
}"
|
||||||
:selected-keys="selectedItems"
|
:selected-keys="selectedItems"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:scroll="{ x: '100%' }"
|
:scroll="{ x: '100%' }"
|
||||||
@ -173,11 +177,6 @@ const indeterminate = computed(
|
|||||||
() => selectedItems.value.length > 0 && selectedItems.value.length < props.dataSource.length,
|
() => selectedItems.value.length > 0 && selectedItems.value.length < props.dataSource.length,
|
||||||
);
|
);
|
||||||
|
|
||||||
const rowSelection = computed(() => ({
|
|
||||||
type: 'checkbox',
|
|
||||||
showCheckedAll: true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const handleSelectAll = (checked) => {
|
const handleSelectAll = (checked) => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
selectedItems.value = props.dataSource.map((item) => item.id);
|
selectedItems.value = props.dataSource.map((item) => item.id);
|
||||||
|
|||||||
@ -33,7 +33,11 @@
|
|||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:data="dataSource"
|
:data="dataSource"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:row-selection="rowSelection"
|
:row-selection="{
|
||||||
|
type: 'checkbox',
|
||||||
|
showCheckedAll: true,
|
||||||
|
width: 48,
|
||||||
|
}"
|
||||||
:selected-keys="selectedItems"
|
:selected-keys="selectedItems"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:scroll="{ x: '100%' }"
|
:scroll="{ x: '100%' }"
|
||||||
@ -173,11 +177,6 @@ const indeterminate = computed(
|
|||||||
() => selectedItems.value.length > 0 && selectedItems.value.length < props.dataSource.length,
|
() => selectedItems.value.length > 0 && selectedItems.value.length < props.dataSource.length,
|
||||||
);
|
);
|
||||||
|
|
||||||
const rowSelection = computed(() => ({
|
|
||||||
type: 'checkbox',
|
|
||||||
showCheckedAll: true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const handleSelectAll = (checked) => {
|
const handleSelectAll = (checked) => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
selectedItems.value = props.dataSource.map((item) => item.id);
|
selectedItems.value = props.dataSource.map((item) => item.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user