Merge remote-tracking branch 'origin/feature/v1.3_营销资产中台' into feature/v1.3_营销资产中台
# Conflicts: # src/api/all/propertyMarketing.ts
This commit is contained in:
@ -285,7 +285,6 @@ export const getPlacementAccountsTrend = (params = {}) => {
|
||||
return Http.get(`/v1/placement-accounts/trend`, params);
|
||||
};
|
||||
|
||||
|
||||
// 投放账号计划数据-趋势
|
||||
export const getPlacementAccountProjectsTrend = (params = {}) => {
|
||||
return Http.get(`/v1/placement-account-projects/trend`, params);
|
||||
@ -293,7 +292,7 @@ export const getPlacementAccountProjectsTrend = (params = {}) => {
|
||||
|
||||
// 投放指南查询
|
||||
export const getPlacementGuide = (params: {}) => {
|
||||
return Http.get(`/v1/placement-account-projects/getGuideList`,params);
|
||||
return Http.get(`/v1/placement-account-projects/getGuideList`, params);
|
||||
};
|
||||
//查询投放指南历史
|
||||
export const getPlacementGuideHistory = (params: {}) => {
|
||||
@ -323,4 +322,9 @@ export const getPlacementAccountsList = (params = {}) => {
|
||||
return Http.get('/v1/placement-accounts/list', params);
|
||||
};
|
||||
|
||||
// 投放账号-同步数据
|
||||
export const postPlacementAccountsSync = (id: string) => {
|
||||
return Http.post(`/v1/placement-accounts/${id}/sync-data`);
|
||||
};
|
||||
|
||||
|
||||
|
||||
3
src/assets/svg/icon-intelligentSolution.svg
Normal file
3
src/assets/svg/icon-intelligentSolution.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M11.4165 8.97559C12.8259 8.97562 13.969 10.118 13.9693 11.5273L13.9556 11.7891C13.9073 12.2634 13.7275 12.6982 13.4556 13.0596L14.0542 13.6582C14.2495 13.8535 14.2495 14.17 14.0542 14.3652C13.8589 14.5603 13.5424 14.5604 13.3472 14.3652L12.7085 13.7256C12.3292 13.949 11.8886 14.0801 11.4165 14.0801L11.1558 14.0664C9.86908 13.9356 8.86497 12.8485 8.86477 11.5273C8.86501 10.1182 10.0073 8.97583 11.4165 8.97559ZM8.74074 3.80469C8.74092 4.35682 9.18857 4.80469 9.74074 4.80469L11.8862 4.80469V7.85937C11.7712 7.84857 11.6545 7.84278 11.5366 7.84277C9.49559 7.84277 7.84035 9.49802 7.84035 11.5391C7.84042 12.5835 8.27458 13.5262 8.97121 14.1982H2.79934C2.24716 14.1981 1.79934 13.7504 1.79934 13.1982L1.79934 2.48828C1.79934 1.93608 2.24716 1.48841 2.79934 1.48828L8.74074 1.48828V3.80469ZM11.4165 9.97559C10.5596 9.97583 9.86501 10.6704 9.86477 11.5273C9.86498 12.3843 10.5596 13.0798 11.4165 13.0801C12.2736 13.08 12.969 12.3844 12.9693 11.5273C12.969 10.6703 12.2736 9.97562 11.4165 9.97559ZM3.48879 6.35156C3.37847 6.35156 3.28882 6.44051 3.28859 6.55078V7.0498C3.28868 7.16018 3.37839 7.25 3.48879 7.25L7.14211 7.25C7.25238 7.24984 7.34221 7.16009 7.3423 7.0498V6.55078C7.34208 6.44061 7.25229 6.35172 7.14211 6.35156L3.48879 6.35156ZM3.48879 4.04395C3.37837 4.04395 3.28866 4.13374 3.28859 4.24414V4.74316C3.28884 4.85341 3.37848 4.94238 3.48879 4.94238H7.14211C7.25228 4.94222 7.34206 4.85332 7.3423 4.74316V4.24414C7.34223 4.13384 7.25239 4.0441 7.14211 4.04395H3.48879ZM11.978 3.91895L10.0474 3.91895C9.77124 3.91895 9.54738 3.69509 9.54738 3.41895V1.48828L11.978 3.91895Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
3
src/assets/svg/icon-mediaAccount.svg
Normal file
3
src/assets/svg/icon-mediaAccount.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M10.0492 9.03058C12.2731 9.03059 14.0867 10.8117 14.1273 13.0352C14.1439 13.9477 13.4092 14.6964 12.4966 14.6966L3.50042 14.6966C2.59261 14.6965 1.86034 13.9541 1.87254 13.0463C1.90255 10.8197 3.71631 9.03058 5.94319 9.03058H10.0492ZM7.87154 1.30322C9.93387 1.30328 11.6061 2.88101 11.6064 4.8269C11.6064 6.773 9.93402 8.35146 7.87154 8.35151C5.809 8.35151 4.1367 6.77303 4.1367 4.8269C4.13695 2.88097 5.80916 1.30322 7.87154 1.30322Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 571 B |
3
src/assets/svg/icon-putAccount.svg
Normal file
3
src/assets/svg/icon-putAccount.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M13.434 6.4018C13.7387 6.4018 13.9863 6.64936 13.9863 6.95409L13.9863 13.4136C13.9863 13.9214 13.5744 14.333 13.0667 14.3332L2.94324 14.3332C2.4355 14.333 2.02367 13.9214 2.02367 13.4136L2.02367 6.95409C2.02367 6.64938 2.27125 6.40182 2.57595 6.4018L13.434 6.4018ZM3.6482 9.82418C3.49585 9.8242 3.3725 9.94752 3.3725 10.0999L3.3725 12.6521C3.37274 12.8042 3.496 12.9277 3.6482 12.9278H5.6948C5.84701 12.9278 5.97025 12.8042 5.97049 12.6521L5.97049 10.0999C5.97049 9.94751 5.84716 9.82418 5.6948 9.82418H3.6482ZM7.55192 5.66362L2.38198 5.66362C2.1291 5.66334 1.95132 5.41309 2.03444 5.1742L3.04113 2.28345C3.16976 1.9142 3.51856 1.66682 3.90952 1.6665L7.55192 1.6665L7.55192 5.66362ZM12.0537 1.6665C12.4421 1.66658 12.7886 1.91054 12.9194 2.27626L13.9549 5.1715C14.0405 5.41104 13.8626 5.66357 13.6082 5.66362L8.44276 5.66362V1.6665L12.0537 1.6665Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 984 B |
3
src/assets/svg/icon-repository.svg
Normal file
3
src/assets/svg/icon-repository.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M2.97785 10.8532C3.06071 10.71 3.24367 10.6612 3.38703 10.7438L6.48859 12.5348C6.63203 12.6176 6.68168 12.8005 6.59894 12.944L5.44757 14.9371C5.34178 15.1204 5.08511 15.1398 4.95343 14.9743L3.88214 13.6256C3.83419 13.5653 3.76511 13.5259 3.68878 13.5153L2.04816 13.2897C1.83724 13.2606 1.72302 13.0269 1.82941 12.8424L2.97785 10.8532ZM12.6126 10.7438C12.7561 10.661 12.9399 10.7097 13.0228 10.8532L14.1712 12.8424C14.2775 13.0269 14.1625 13.2607 13.9515 13.2897L12.3118 13.5153C12.2353 13.5258 12.1655 13.5651 12.1175 13.6256L11.0472 14.9743C10.9155 15.14 10.6579 15.1205 10.5521 14.9371L9.40167 12.944C9.31889 12.8006 9.36778 12.6177 9.51105 12.5348L12.6126 10.7438ZM7.55304 0.954723C7.82985 0.795119 8.17083 0.794962 8.44757 0.954723L12.7542 3.44105C13.0311 3.60091 13.2015 3.89674 13.2015 4.21644L13.2015 9.1891C13.2015 9.50881 13.0311 9.80462 12.7542 9.96449L8.44757 12.4508C8.17085 12.6105 7.82982 12.6104 7.55304 12.4508L3.2464 9.96449C2.96951 9.80462 2.79816 9.50883 2.79816 9.1891L2.79816 4.21644C2.79817 3.89673 2.96952 3.60091 3.2464 3.44105L7.55304 0.954723ZM10.8304 4.61488C10.5246 4.42717 10.1247 4.52313 9.93683 4.82875L8.0921 7.8307L6.04914 4.80433L5.96417 4.70375C5.74823 4.49246 5.406 4.45398 5.14582 4.62953C4.88559 4.80537 4.79393 5.1373 4.90949 5.41664L4.97101 5.53285L7.58039 9.39418C7.70405 9.57726 7.91224 9.6851 8.13312 9.68031C8.35384 9.67538 8.55762 9.5589 8.67316 9.37074L11.0443 5.50843C11.2316 5.20262 11.136 4.80263 10.8304 4.61488Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@ -87,7 +87,30 @@ export default defineComponent({
|
||||
// 跳过没有 name 的菜单项,防止 key 报错
|
||||
if (!element?.name) return;
|
||||
|
||||
const icon = element?.meta?.icon ? () => h(element?.meta?.icon as object) : null;
|
||||
// const icon element?.meta?.icon
|
||||
const icon = element?.meta?.icon
|
||||
? (() => {
|
||||
if (typeof element.meta.icon === 'string') {
|
||||
return h(
|
||||
'svg',
|
||||
{
|
||||
style: {
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
},
|
||||
},
|
||||
[
|
||||
h('use', {
|
||||
'xlink:href': element.meta.icon,
|
||||
}),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
// 如果是对象,按原来的方式渲染
|
||||
return h(element.meta.icon as object);
|
||||
}
|
||||
})()
|
||||
: null;
|
||||
if (element.children && element.children.length > 0) {
|
||||
nodes.push(
|
||||
<a-sub-menu
|
||||
|
||||
@ -2,10 +2,14 @@
|
||||
* 资产营销平台
|
||||
*/
|
||||
|
||||
import { IconBookmark } from '@arco-design/web-vue/es/icon';
|
||||
import type { AppRouteRecordRaw } from '../types';
|
||||
import { MENU_GROUP_IDS } from '@/router/constants';
|
||||
|
||||
import IconRepository from '@/assets/svg/icon-repository.svg';
|
||||
import IconMediaAccount from '@/assets/svg/icon-mediaAccount.svg';
|
||||
import IconPutAccount from '@/assets/svg/icon-putAccount.svg';
|
||||
import IconIntelligentSolution from '@/assets/svg/icon-intelligentSolution.svg';
|
||||
|
||||
const COMPONENTS: AppRouteRecordRaw[] = [
|
||||
{
|
||||
path: '/repository',
|
||||
@ -13,7 +17,7 @@ const COMPONENTS: AppRouteRecordRaw[] = [
|
||||
redirect: 'repository/brandMaterials',
|
||||
meta: {
|
||||
locale: '品牌资产管理',
|
||||
icon: IconBookmark,
|
||||
icon: IconRepository,
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
requiresSidebar: true,
|
||||
@ -39,7 +43,7 @@ const COMPONENTS: AppRouteRecordRaw[] = [
|
||||
redirect: 'media-account/accountManagement',
|
||||
meta: {
|
||||
locale: '账号资源中心',
|
||||
icon: IconBookmark,
|
||||
icon: IconMediaAccount,
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
requiresSidebar: true,
|
||||
@ -87,7 +91,7 @@ const COMPONENTS: AppRouteRecordRaw[] = [
|
||||
redirect: 'put-account/accountManagement',
|
||||
meta: {
|
||||
locale: '投放资源中心',
|
||||
icon: IconBookmark,
|
||||
icon: IconPutAccount,
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
requiresSidebar: true,
|
||||
@ -154,7 +158,7 @@ const COMPONENTS: AppRouteRecordRaw[] = [
|
||||
redirect: 'intelligent-solution/businessAnalysisReport',
|
||||
meta: {
|
||||
locale: '智能方案管理',
|
||||
icon: IconBookmark,
|
||||
icon: IconIntelligentSolution,
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
requiresSidebar: true,
|
||||
|
||||
2
src/router/typeings.d.ts
vendored
2
src/router/typeings.d.ts
vendored
@ -4,7 +4,7 @@ declare module 'vue-router' {
|
||||
interface RouteMeta {
|
||||
roles?: string[]; // Controls roles that have access to the page
|
||||
requiresAuth?: boolean; // Whether login is required to access the current page (every route must declare)
|
||||
icon?: RouteComponent; // The icon show in the side menu
|
||||
icon?: RouteComponent | string; // The icon show in the side menu
|
||||
locale?: string; // The locale name show in side menu and breadcrumb
|
||||
needNavigate?: boolean; // if set true, the breadcrumb will support navigate
|
||||
hideInMenu?: boolean; // If true, it is not displayed in the side menu
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<!-- 关键词热度榜 -->
|
||||
<a-space
|
||||
direction="vertical"
|
||||
class="bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid w-100% py-0 px-20px mb-24px"
|
||||
class="bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid w-100% py-0 px-20px mb-20px"
|
||||
>
|
||||
<div class="title-row">
|
||||
<span class="title mr-4px">关键词热度榜</span>
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
<!-- 头部 -->
|
||||
<a-space
|
||||
direction="vertical"
|
||||
class="bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid"
|
||||
style="background-color: #fff; width: 100%; padding: 24px; margin: 24px 0; color: #737478; font-size: 14px"
|
||||
class="bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid mb-20px"
|
||||
style="background-color: #fff; width: 100%; padding: 24px; color: #737478; font-size: 14px"
|
||||
>
|
||||
<a-space align="start" style="width: 100%; align-items: flex-start" class="mb-12px">
|
||||
<span style="flex-shrink: 0; line-height: 28px" class="mr-32px">行业大类</span>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="flex arco-row-justify-space-between flex-center">
|
||||
<div class="flex arco-row-justify-space-between">
|
||||
<img class="avatar" :src="props.product.image" :alt="props.product.name" />
|
||||
<a-tag v-if="props.product.status === Status.Enable" class="status status-enable">已开通</a-tag>
|
||||
<a-tag v-if="props.product.status === Status.Disable" class="status status-disable">未开通</a-tag>
|
||||
@ -21,7 +21,7 @@
|
||||
{{ props.product.desc }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="footer flex arco-row-justify-start flex-center">
|
||||
<div class="footer flex arco-row-justify-start">
|
||||
<a-button
|
||||
v-if="props.product.status === Status.Enable || props.product.status === Status.ON_TRIAL"
|
||||
class="primary-button"
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
ref="tableRef"
|
||||
:data="dataSource"
|
||||
row-key="id"
|
||||
column-resizable
|
||||
:row-selection="{
|
||||
type: 'checkbox',
|
||||
showCheckedAll: true,
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
:disabled="option.is_require === ENUM_STATUS.NO"
|
||||
@change="(checked) => onCheckChange(checked, option)"
|
||||
>
|
||||
{{ option.label }}
|
||||
{{ localFields.find((item) => item.prop === option.value)?.title }}
|
||||
</a-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
@ -77,7 +77,7 @@ import { ref, defineExpose } from 'vue';
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
|
||||
import { getCustomColumns, updateCustomColumns } from '@/api/all/common';
|
||||
import { getPropPrefix } from '@/views/property-marketing/media-account/account-dashboard/constants';
|
||||
import { getPropPrefix, getDefaultColumns } from '@/views/property-marketing/media-account/account-dashboard/constants';
|
||||
|
||||
import icon1 from './img/icon-lock.png';
|
||||
|
||||
@ -106,9 +106,13 @@ const dataSource = ref([]);
|
||||
const checkColumns = ref([]); // 选中字段
|
||||
const allColumns = ref([]); // 所有字段
|
||||
const requiredGroupNames = ref([]); // 必选分组名称
|
||||
const localFields = ref([]);
|
||||
|
||||
const open = () => {
|
||||
initData();
|
||||
|
||||
localFields.value = getDefaultColumns(props.dateType);
|
||||
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
@ -118,6 +122,7 @@ const close = () => {
|
||||
dataSource.value = [];
|
||||
checkColumns.value = [];
|
||||
allColumns.value = [];
|
||||
localFields.value = [];
|
||||
requiredGroupNames.value = [];
|
||||
};
|
||||
|
||||
@ -150,8 +155,8 @@ 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 column = localFields.value.find((column) => column.prop === value);
|
||||
return column?.title;
|
||||
};
|
||||
const isRequiredColumn = (value) => {
|
||||
const column = allColumns.value.find((column) => column.value === value);
|
||||
|
||||
@ -72,7 +72,7 @@ export const getDefaultColumns = (type = 'week') => {
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: '项目分组',
|
||||
title: '账号分组',
|
||||
dataIndex: 'group.name',
|
||||
prop: 'group',
|
||||
width: 180,
|
||||
@ -111,7 +111,7 @@ export const getDefaultColumns = (type = 'week') => {
|
||||
{
|
||||
title: '总赞藏数',
|
||||
dataIndex: 'like_collect_number',
|
||||
prop: 'like_collect_number',
|
||||
prop: 'like_number',
|
||||
width: 180,
|
||||
tooltip: '账号所有内容获得的点赞数与收藏数总和,用于衡量历史内容的整体吸引力与认可度。',
|
||||
align: 'right',
|
||||
@ -222,6 +222,17 @@ export const getDefaultColumns = (type = 'week') => {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '次新作品收藏数',
|
||||
dataIndex: 'second_new_work_collect_number',
|
||||
prop: 'second_new_work_collect_number',
|
||||
width: 180,
|
||||
tooltip: '次新作品内容的收藏数',
|
||||
align: 'right',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '次新作品评论数',
|
||||
dataIndex: 'second_new_work_comment_number',
|
||||
|
||||
@ -49,7 +49,15 @@
|
||||
<template #default>重置</template>
|
||||
</a-button>
|
||||
</div>
|
||||
<a-table :data="dataSource" row-key="id" :pagination="false" :scroll="{ x: '100%' }" class="w-100%" bordered>
|
||||
<a-table
|
||||
:data="dataSource"
|
||||
row-key="id"
|
||||
:pagination="false"
|
||||
:scroll="{ x: '100%' }"
|
||||
class="w-100%"
|
||||
bordered
|
||||
column-resizable
|
||||
>
|
||||
<template #empty>
|
||||
<NoData />
|
||||
</template>
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
<!-- 分别编辑 -->
|
||||
<template v-if="editType === 'each'">
|
||||
<a-table :data="accountGroupList" :pagination="false" row-key="id" class="w-100%">
|
||||
<a-table :data="accountGroupList" :pagination="false" row-key="id" class="w-100%" column-resizable>
|
||||
<template #columns>
|
||||
<a-table-column title="账号名称" data-index="name" width="200">
|
||||
<template #cell="{ record }">
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
<!-- 分别编辑 -->
|
||||
<template v-if="editType === 'each'">
|
||||
<a-table :data="accountTagList" :pagination="false" row-key="id" class="w-100%">
|
||||
<a-table :data="accountTagList" :pagination="false" row-key="id" class="w-100%" column-resizable>
|
||||
<template #columns>
|
||||
<a-table-column title="账号名称" data-index="name" width="200">
|
||||
<template #cell="{ record }">
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
</div>
|
||||
|
||||
<a-table
|
||||
column-resizable
|
||||
:columns="columns"
|
||||
:data="list"
|
||||
row-key="id"
|
||||
|
||||
@ -20,7 +20,7 @@ export const TABLE_COLUMNS = [
|
||||
{
|
||||
title: '运营人员',
|
||||
dataIndex: 'operator_ame',
|
||||
prop: 'operator_ame',
|
||||
prop: 'operator',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
@ -73,8 +73,8 @@ export const TABLE_COLUMNS = [
|
||||
},
|
||||
// {
|
||||
// title: '账户余额',
|
||||
// dataIndex: 'balance',
|
||||
// prop: 'balance',
|
||||
// dataIndex: 'balance_amount',
|
||||
// prop: 'balance_amount',
|
||||
// width: 180,
|
||||
// tooltip: '当前账户剩余的可用余额,用于后续广告投放。',
|
||||
// prefix: '¥',
|
||||
@ -83,23 +83,23 @@ export const TABLE_COLUMNS = [
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: 'AI评价',
|
||||
// dataIndex: 'ai_evaluate',
|
||||
// prop: 'ai_evaluate',
|
||||
// width: 260,
|
||||
// },
|
||||
// {
|
||||
// title: '投资回报率',
|
||||
// dataIndex: 'roi',
|
||||
// prop: 'roi',
|
||||
// width: 180,
|
||||
// tooltip: '投入产出比(ROI),等于收益 ÷ 投入,反映投放带来的商业价值。',
|
||||
// align: 'right',
|
||||
// sortable: {
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: 'AI评价',
|
||||
dataIndex: 'ai_evaluate',
|
||||
prop: 'ai_evaluate',
|
||||
width: 260,
|
||||
},
|
||||
{
|
||||
title: '投资回报率',
|
||||
dataIndex: 'roi',
|
||||
prop: 'roi',
|
||||
width: 180,
|
||||
tooltip: '投入产出比(ROI),等于收益 ÷ 投入,反映投放带来的商业价值。',
|
||||
align: 'right',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '投资回报率环比',
|
||||
// dataIndex: 'roi_chain',
|
||||
@ -114,7 +114,7 @@ export const TABLE_COLUMNS = [
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '展示量',
|
||||
title: '展示数',
|
||||
dataIndex: 'show_number',
|
||||
prop: 'show_number',
|
||||
width: 180,
|
||||
@ -124,21 +124,21 @@ export const TABLE_COLUMNS = [
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '展示量环比',
|
||||
// dataIndex: 'view_number_chain',
|
||||
// prop: 'view_number_chain',
|
||||
// width: 180,
|
||||
// tooltip: '展示量与上一周期的变化百分比,反映广告曝光趋势。',
|
||||
// align: 'right',
|
||||
// suffix: '%',
|
||||
// isRateField: true,
|
||||
// sortable: {
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '点击量',
|
||||
title: '展示数环比',
|
||||
dataIndex: 'show_number_chain',
|
||||
prop: 'show_number_chain',
|
||||
width: 180,
|
||||
tooltip: '展示数与上一周期的变化百分比,反映广告曝光趋势。',
|
||||
align: 'right',
|
||||
suffix: '%',
|
||||
isRateField: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '点击数',
|
||||
dataIndex: 'click_number',
|
||||
prop: 'click_number',
|
||||
width: 180,
|
||||
@ -148,19 +148,19 @@ export const TABLE_COLUMNS = [
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '点击量环比',
|
||||
// dataIndex: 'click_number_chain',
|
||||
// prop: 'click_number_chain',
|
||||
// width: 180,
|
||||
// tooltip: '当前周期点击量相较上一周期的变化百分比。',
|
||||
// align: 'right',
|
||||
// suffix: '%',
|
||||
// isRateField: true,
|
||||
// sortable: {
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '点击数环比',
|
||||
dataIndex: 'click_number_chain',
|
||||
prop: 'click_number_chain',
|
||||
width: 180,
|
||||
tooltip: '当前周期点击数相较上一周期的变化百分比。',
|
||||
align: 'right',
|
||||
suffix: '%',
|
||||
isRateField: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '点击率',
|
||||
dataIndex: 'click_rate',
|
||||
@ -172,19 +172,19 @@ export const TABLE_COLUMNS = [
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '点击率环比',
|
||||
// dataIndex: 'click_rate_chain',
|
||||
// prop: 'click_rate_chain',
|
||||
// width: 180,
|
||||
// tooltip: '当前 CTR 相较上一周期的变化百分比,评估广告表现是否优化。',
|
||||
// align: 'right',
|
||||
// suffix: '%',
|
||||
// isRateField: true,
|
||||
// sortable: {
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '点击率环比',
|
||||
dataIndex: 'click_rate_chain',
|
||||
prop: 'click_rate_chain',
|
||||
width: 180,
|
||||
tooltip: '当前 CTR 相较上一周期的变化百分比,评估广告表现是否优化。',
|
||||
align: 'right',
|
||||
suffix: '%',
|
||||
isRateField: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '平均点击成本',
|
||||
dataIndex: 'avg_click_cost',
|
||||
@ -197,7 +197,7 @@ export const TABLE_COLUMNS = [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '千次展现费用',
|
||||
title: '千次展示费用',
|
||||
dataIndex: 'thousand_show_cost',
|
||||
prop: 'thousand_show_cost',
|
||||
width: 180,
|
||||
@ -296,14 +296,4 @@ export const TABLE_COLUMNS = [
|
||||
// prop: 'newest_work_title',
|
||||
// width: 260,
|
||||
// },
|
||||
// {
|
||||
// title: '投放回报率',
|
||||
// dataIndex: 'roi_chain1',
|
||||
// prop: 'roi_chain1',
|
||||
// width: 180,
|
||||
// align: 'right',
|
||||
// sortable: {
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
];
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
ref="tableRef"
|
||||
:data="dataSource"
|
||||
row-key="id"
|
||||
column-resizable
|
||||
:row-selection="{
|
||||
type: 'checkbox',
|
||||
showCheckedAll: true,
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
<a-range-picker
|
||||
v-model="query.data_time"
|
||||
size="medium"
|
||||
allow-clear
|
||||
:allow-clear="false"
|
||||
format="YYYY-MM-DD"
|
||||
class="w-100%"
|
||||
@change="handleSearch"
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
</a-button>
|
||||
</div>
|
||||
<a-table
|
||||
column-resizable
|
||||
:columns="columns"
|
||||
:data="list"
|
||||
row-key="id"
|
||||
|
||||
@ -34,7 +34,7 @@ export const TABLE_COLUMNS = [
|
||||
{
|
||||
title: '运营人员',
|
||||
dataIndex: 'operator_name',
|
||||
prop: 'operator_name',
|
||||
prop: 'operator',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
@ -51,8 +51,8 @@ export const TABLE_COLUMNS = [
|
||||
},
|
||||
// {
|
||||
// title: '账户余额',
|
||||
// dataIndex: 'balance',
|
||||
// prop: 'balance',
|
||||
// dataIndex: 'balance_amount',
|
||||
// prop: 'balance_amount',
|
||||
// width: 180,
|
||||
// tooltip: '当前投流计划剩余可用预算,用于后续广告持续投放。',
|
||||
// prefix: '¥',
|
||||
@ -61,25 +61,25 @@ export const TABLE_COLUMNS = [
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: 'AI评价',
|
||||
// dataIndex: 'ai_evaluate',
|
||||
// prop: 'ai_evaluate',
|
||||
// width: 260,
|
||||
// },
|
||||
// {
|
||||
// title: '投资回报率',
|
||||
// dataIndex: 'roi',
|
||||
// prop: 'roi',
|
||||
// width: 180,
|
||||
// tooltip: '投入产出比(ROI),= 收益 ÷ 投入,用于衡量该计划的经济效益。',
|
||||
// align: 'right',
|
||||
// sortable: {
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '展示量',
|
||||
title: 'AI评价',
|
||||
dataIndex: 'ai_evaluate',
|
||||
prop: 'ai_evaluate',
|
||||
width: 260,
|
||||
},
|
||||
{
|
||||
title: '投资回报率',
|
||||
dataIndex: 'roi',
|
||||
prop: 'roi',
|
||||
width: 180,
|
||||
tooltip: '投入产出比(ROI),= 收益 ÷ 投入,用于衡量该计划的经济效益。',
|
||||
align: 'right',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '展示数',
|
||||
dataIndex: 'show_number',
|
||||
prop: 'show_number',
|
||||
width: 180,
|
||||
@ -90,7 +90,7 @@ export const TABLE_COLUMNS = [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '点击量',
|
||||
title: '点击数',
|
||||
dataIndex: 'click_number',
|
||||
prop: 'click_number',
|
||||
width: 180,
|
||||
@ -111,19 +111,19 @@ export const TABLE_COLUMNS = [
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '点击率环比',
|
||||
// dataIndex: 'click_rate_chain',
|
||||
// prop: 'click_rate_chain',
|
||||
// width: 180,
|
||||
// tooltip: '当前 CTR 与上一周期对比的变化百分比,用于追踪广告吸引力趋势。',
|
||||
// align: 'right',
|
||||
// suffix: '%',
|
||||
// isRateField: true,
|
||||
// sortable: {
|
||||
// sortDirections: ['ascend', 'descend'],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '点击率环比',
|
||||
dataIndex: 'click_rate_chain',
|
||||
prop: 'click_rate_chain',
|
||||
width: 180,
|
||||
tooltip: '当前 CTR 与上一周期对比的变化百分比,用于追踪广告吸引力趋势。',
|
||||
align: 'right',
|
||||
suffix: '%',
|
||||
isRateField: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '平均点击成本',
|
||||
dataIndex: 'avg_click_cost',
|
||||
@ -136,7 +136,7 @@ export const TABLE_COLUMNS = [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '千次展现费用',
|
||||
title: '千次展示费用',
|
||||
dataIndex: 'thousand_show_cost',
|
||||
prop: 'thousand_show_cost',
|
||||
width: 180,
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
<a-table
|
||||
ref="tableRef"
|
||||
column-resizable
|
||||
:data="dataSource"
|
||||
row-key="id"
|
||||
:row-selection="{
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
v-model:query="query"
|
||||
:isAccountTab="isAccountTab"
|
||||
@onSearch="getData"
|
||||
@onReset="handleReset"
|
||||
@onReset="init"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@ -84,6 +84,19 @@ const pageInfo = ref(cloneDeep(INITIAL_PAGE_INFO));
|
||||
|
||||
const isAccountTab = computed(() => activeTab.value === '1');
|
||||
|
||||
const init = () => {
|
||||
query.value = cloneDeep(INITIAL_QUERY);
|
||||
dataSource.value = [];
|
||||
pageInfo.value = cloneDeep(INITIAL_PAGE_INFO);
|
||||
selectedRowKeys.value = [];
|
||||
accountTableRef.value?.resetTable();
|
||||
|
||||
const data_time = [dayjs().format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')];
|
||||
query.value.data_time = data_time;
|
||||
|
||||
getData();
|
||||
};
|
||||
|
||||
const getData = async () => {
|
||||
const _fn = isAccountTab.value ? getPlacementAccountData : getPlacementAccountDataList;
|
||||
const { page, page_size } = pageInfo.value;
|
||||
@ -113,14 +126,6 @@ const reload = () => {
|
||||
getData();
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
pageInfo.value = cloneDeep(INITIAL_PAGE_INFO);
|
||||
selectedRowKeys.value = [];
|
||||
accountTableRef.value?.resetTable();
|
||||
query.value = cloneDeep(INITIAL_QUERY);
|
||||
reload();
|
||||
};
|
||||
|
||||
const handleSorterChange = (column, order) => {
|
||||
query.value.column = column;
|
||||
query.value.order = order;
|
||||
@ -132,8 +137,7 @@ const handleSelectionChange = (selectedRows) => {
|
||||
|
||||
const handleTabClick = (key) => {
|
||||
activeTab.value = key;
|
||||
dataSource.value = [];
|
||||
handleReset();
|
||||
init();
|
||||
};
|
||||
|
||||
const handleExport = () => {
|
||||
@ -153,7 +157,7 @@ const handleOpenGroupModal = () => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -119,14 +119,14 @@
|
||||
<a-input v-model="form.balance_amount" placeholder="请输入..." size="large" disabled />
|
||||
</a-form-item>
|
||||
</template>
|
||||
<a-form-item label="同步项目数据" field="is_sync">
|
||||
<a-form-item label="同步项目数据" field="is_sync_project">
|
||||
<template #label>
|
||||
<span class="label">同步项目数据</span>
|
||||
<a-tooltip content="同步项目数据后,账户数据将同步到项目中">
|
||||
<icon-question-circle size="14" class="ml-4px color-#737478" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-switch v-model="form.is_sync" size="medium" :checked-value="1" :un-checked-value="0" />
|
||||
<a-switch v-model="form.is_sync_project" size="medium" :checked-value="1" :un-checked-value="0" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
@ -173,7 +173,7 @@ const INITIAL_FORM = {
|
||||
operator_name: '',
|
||||
holder_name: '',
|
||||
platform: 0,
|
||||
is_sync: 0,
|
||||
is_sync_project: 0,
|
||||
};
|
||||
|
||||
const visible = ref(false);
|
||||
|
||||
@ -16,9 +16,9 @@
|
||||
<div class="flex items-center mb-20px">
|
||||
<img :src="icon1" width="16" height="16" class="mr-16px" />
|
||||
<p class="s2">
|
||||
检测到该账户最后更新日期为{{ exactFormatTime(lastSyncedAt, 'MM-DD', 'YYYY-MM-DD') }},已有{{
|
||||
dayjs().diff(dayjs(lastSyncedAt * 1000), 'day')
|
||||
}}天未同步最新数据。
|
||||
检测到该账户最后更新日期为{{ exactFormatTime(lastSyncedAt, 'MM月DD日HH:mm', 'YYYY年MM月DD日 HH:mm') }},已有{{
|
||||
getDaysDiffText(lastSyncedAt)
|
||||
}}未同步最新数据。
|
||||
</p>
|
||||
</div>
|
||||
<a-radio-group v-model="syncType" class="ml-32px">
|
||||
@ -65,14 +65,18 @@
|
||||
import dayjs from 'dayjs';
|
||||
import { defineExpose, ref, computed, defineEmits } from 'vue';
|
||||
import { exactFormatTime } from '@/utils/tools';
|
||||
import { putPlacementAccountsAuthorized, getPlacementAccountsAuthorizedStatus } from '@/api/all/propertyMarketing';
|
||||
import {
|
||||
putPlacementAccountsAuthorized,
|
||||
getPlacementAccountsAuthorizedStatus,
|
||||
postPlacementAccountsSync,
|
||||
} from '@/api/all/propertyMarketing';
|
||||
|
||||
import icon1 from '@/assets/img/media-account/icon-warn-1.png';
|
||||
import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
|
||||
import icon3 from '@/assets/img/media-account/icon-feedback-fail.png';
|
||||
|
||||
const emits = defineEmits(['update']);
|
||||
|
||||
const INITIAL_SYNC_TYPE = 'sync';
|
||||
const visible = ref(false);
|
||||
const isLoading = ref(false);
|
||||
const isCompleted = ref(false);
|
||||
@ -81,9 +85,10 @@ const formRef = ref(null);
|
||||
const failReason = ref('');
|
||||
const progress = ref(0);
|
||||
const id = ref('');
|
||||
const lastSyncedAt = ref(null);
|
||||
const syncType = ref('sync'); // sync | no_sync
|
||||
|
||||
const lastSyncedAt = ref(null); // 上次同步时间戳
|
||||
const showSyncTip = ref(false);
|
||||
const syncType = ref(INITIAL_SYNC_TYPE); // sync | no_sync
|
||||
|
||||
const INITIAL_FORM = {
|
||||
account: '',
|
||||
@ -111,6 +116,15 @@ const confirmBtnText = computed(() => {
|
||||
return isSuccess.value ? '继续添加' : '重试';
|
||||
});
|
||||
|
||||
const getDaysDiffText = (lastSyncedAt) => {
|
||||
if (!lastSyncedAt) return '0天';
|
||||
|
||||
const daysDiff = dayjs().diff(dayjs(lastSyncedAt * 1000), 'day');
|
||||
|
||||
if (daysDiff === 0) return '不到1天';
|
||||
return `${daysDiff}天`;
|
||||
};
|
||||
|
||||
const open = (accountId, last_synced_at = null) => {
|
||||
id.value = accountId;
|
||||
lastSyncedAt.value = last_synced_at;
|
||||
@ -129,7 +143,7 @@ const close = () => {
|
||||
progress.value = 0;
|
||||
id.value = '';
|
||||
lastSyncedAt.value = null;
|
||||
syncType.value = 'sync';
|
||||
syncType.value = INITIAL_SYNC_TYPE;
|
||||
showSyncTip.value = false;
|
||||
clearFakeProgressTimer();
|
||||
clearStatusPollingTimer();
|
||||
@ -206,8 +220,8 @@ const clearFakeProgressTimer = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
if (lastSyncedAt.value) {
|
||||
const handleSyncData = () => {
|
||||
if (!showSyncTip.value) {
|
||||
formRef.value.validate(async (errors) => {
|
||||
if (!errors) {
|
||||
showSyncTip.value = true;
|
||||
@ -216,6 +230,23 @@ const handleOk = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (syncType.value === INITIAL_SYNC_TYPE) {
|
||||
postPlacementAccountsSync(id.value).then((res) => {
|
||||
if (res.code === 200) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
if (lastSyncedAt.value && lastSyncedAt.value < dayjs().startOf('day').valueOf()) {
|
||||
handleSyncData();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCompleted.value) {
|
||||
if (isSuccess.value) {
|
||||
emits('update');
|
||||
|
||||
Reference in New Issue
Block a user