浏览代码

数据趋势添加周月筛选

guojing_wu 1 年之前
父节点
当前提交
66065af443

+ 0 - 24
src/views/adManage/portfolios/PortfoliosSelector.vue

@@ -1,24 +0,0 @@
-<template>
-  <el-select v-model="portfolios" placeholder="广告组合">
-    <el-options v-for="info in portfolios" :label="info.name" :value="info.portfolioId"></el-options>
-  </el-select>
-</template>
-
-<script lang="ts" setup>
-import { ref, onBeforeMount, Ref } from 'vue'
-import { GetList } from './api'
-
-defineOptions({
-  name: 'PortfoliosSelector'
-})
-const portfolios:Ref<portfolios[]> = ref([])
-onBeforeMount(async () => {
-  const resp:APIResponseData = await GetList({ limit: 999 })
-  portfolios.value = resp.data
-})
-
-</script>
-
-<style scoped>
-
-</style>

+ 32 - 0
src/views/adManage/portfolios/api.ts

@@ -39,3 +39,35 @@ export function DelObj(id: DelReq) {
         data: { id },
     });
 }
+
+export function getCardData(query: UserPageQuery) {
+    return request({
+        url: apiPrefix + "report/amount",
+        method: 'GET',
+        params: query
+    })
+}
+
+export function getLineData(query: UserPageQuery) {
+    return request({
+        url: apiPrefix + "report/trend/daily",
+        method: 'GET',
+        params: query
+    })
+}
+
+export function getLineWeekData(query: UserPageQuery) {
+    return request({
+        url: apiPrefix + "report/trend/weekly",
+        method: 'GET',
+        params: query
+    })
+}
+
+export function getLineMonthData(query: UserPageQuery) {
+    return request({
+        url: apiPrefix + "report/trend/monthly",
+        method: 'GET',
+        params: query
+    })
+}

+ 81 - 72
src/views/adManage/portfolios/crud.tsx

@@ -1,26 +1,25 @@
-import * as api from './api';
-import { dict, UserPageQuery, AddReq, DelReq, EditReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud';
-import { inject, nextTick, ref } from 'vue';
-import { successMessage } from '/@/utils/message';
-import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js';
+import * as api from './api'
+import { dict, UserPageQuery, AddReq, DelReq, EditReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
+import { inject, nextTick, ref } from 'vue'
+import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
 
 export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
 	const pageRequest = async (query: UserPageQuery) => {
-		return await api.GetList(query);
-	};
+		return await api.GetList(query)
+	}
 	const editRequest = async ({ form, row }: EditReq) => {
-		form.id = row.id;
-		return await api.UpdateObj(form);
-	};
+		form.id = row.id
+		return await api.UpdateObj(form)
+	}
 	const delRequest = async ({ row }: DelReq) => {
-		return await api.DelObj(row.id);
-	};
+		return await api.DelObj(row.id)
+	}
 	const addRequest = async ({ form }: AddReq) => {
-		return await api.AddObj(form);
-	};
+		return await api.AddObj(form)
+	}
 
 	//权限判定
-	const hasPermissions = inject('$hasPermissions');
+	const hasPermissions = inject('$hasPermissions')
 
 	return {
 		crudOptions: {
@@ -28,8 +27,8 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 				height: 800,
 			},
 			container: {
-        fixedHeight: false
-      },
+				fixedHeight: false,
+			},
 			request: {
 				pageRequest,
 				addRequest,
@@ -46,13 +45,13 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 					edit: {
 						iconRight: 'Edit',
 						type: 'text',
-            text: null
+						text: null,
 						// show: hasPermissions('dictionary:Update'),
 					},
 					remove: {
 						iconRight: 'Delete',
 						type: 'text',
-            text: null
+						text: null,
 						// show: hasPermissions('dictionary:Delete'),
 					},
 					// custom: {
@@ -75,6 +74,16 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 					// },
 				},
 			},
+			toolbar: {
+				buttons: {
+					search: {
+						show: true,
+					},
+					compact: {
+						show: false,
+					},
+				},
+			},
 			columns: {
 				// _index: {
 				// 	title: '序号',
@@ -93,36 +102,36 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 				// 		},
 				// 	},
 				// },
-        name: {
-          title: '广告组合',
-          column: {
-            width: '150px'
-          },
+				name: {
+					title: '广告组合',
+					column: {
+						width: '150px',
+					},
 					search: {
 						show: true,
 						component: {
 							props: {
-								clearable: true
-							}
-						}
+								clearable: true,
+							},
+						},
 					},
 					form: {
-						rules: [{required: true, message:'必填项'}]
-					}
-        },
-        state: {
-          title: '状态',
-          type: 'dict-select',
-          dict: dict({
-            data:[
-              {value:'enabled', label:'投放中'},
-              {value:'disable', label:'禁用'},
-            ] 
-          }),
+						rules: [{ required: true, message: '必填项' }],
+					},
+				},
+				state: {
+					title: '状态',
+					type: 'dict-select',
+					dict: dict({
+						data: [
+							{ value: 'enabled', label: '投放中' },
+							{ value: 'disable', label: '禁用' },
+						],
+					}),
 					form: {
-						show: false
-					}
-        },
+						show: false,
+					},
+				},
 				budget_policy: {
 					title: '预算类型',
 					type: 'dict-select',
@@ -131,49 +140,49 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 							{ value: '', label: '无预算上限' },
 							{ value: 'dateRange', label: '日期范围' },
 							{ value: 'monthlyRecurring', label: '按月' },
-						]
+						],
 					}),
 					form: {
-						value: ''
-					}
+						value: '',
+					},
 				},
-        budget_startDate: {
-          title: '开始日期',
+				budget_startDate: {
+					title: '开始日期',
 					type: 'date',
 					form: {
-						show: compute(context => context.form.budget_policy === "dateRange"),
-						rules: [{required: true, message:'必填项'}]
-					}
-        },
-        budget_endDate: {
-          title: '结束日期',
+						show: compute((context) => context.form.budget_policy === 'dateRange'),
+						rules: [{ required: true, message: '必填项' }],
+					},
+				},
+				budget_endDate: {
+					title: '结束日期',
 					type: 'date',
 					form: {
-						show: compute(context => context.form.budget_policy !== '')
-					}
-        },
-        budget_amount: {
-          title: '预算',
+						show: compute((context) => context.form.budget_policy !== ''),
+					},
+				},
+				budget_amount: {
+					title: '预算',
 					type: 'number',
 					form: {
 						value: 0,
-						show: compute(context => context.form.budget_policy !== ''),
-						rules: [{required: true, message:'必填项'}],
+						show: compute((context) => context.form.budget_policy !== ''),
+						rules: [{ required: true, message: '必填项' }],
 						component: {
 							min: 0,
 							precision: 2,
-							controlsPosition: "right"
-						}
-					}
-        },
-        inBudget: {
-          title: '是否预算内',
+							controlsPosition: 'right',
+						},
+					},
+				},
+				inBudget: {
+					title: '是否预算内',
 					form: {
-						show: false
-					}
-        },
-        ...BaseColumn
+						show: false,
+					},
+				},
+				...BaseColumn,
 			},
 		},
-	};
-};
+	}
+}

+ 30 - 5
src/views/adManage/portfolios/index.vue

@@ -1,12 +1,28 @@
 <template>
 	<div class="asj-container">
-		<div class="public-search">
-			<DateRangePicker v-model="dateRange" timezone="America/Los_Angeles" ></DateRangePicker>
-		</div>
 		<fs-page class="fs-page-custom">
 			<fs-crud ref="crudRef" v-bind="crudBinding">
+				<template #search-left>
+					<DateRangePicker v-model="dateRange" timezone="America/Los_Angeles"></DateRangePicker>
+				</template>
 				<template #header-middle>
-					<el-card style="height: 500px;">此处用于显示可视化图形</el-card>
+					<el-tabs v-model="tabActiveName" class="chart-tabs" type="border-card">
+						<el-tab-pane label="数据趋势" name="dataTendency">
+							<DataTendencyChart 
+								v-if="tabActiveName === 'dataTendency'" 
+								:fetch-card="getCardData" 
+								:fetch-line="getLineData"
+								:fetch-line-month="getLineMonthData"
+								:fetch-line-week="getLineWeekData">
+							</DataTendencyChart>
+						</el-tab-pane>
+						<el-tab-pane label="广告结构" name="adStruct" >
+							<!-- <AdStructChart v-if="tabActiveName === 'adStruct'"/> -->
+						</el-tab-pane>
+						<el-tab-pane label="散点视图" name="scatterView">
+							<div v-if="tabActiveName === 'scatterView'">散点视图</div>
+						</el-tab-pane>
+					</el-tabs>
 				</template>
 			</fs-crud>
 		</fs-page>
@@ -18,7 +34,16 @@ import { ref, onMounted } from 'vue';
 import { useFs } from '@fast-crud/fast-crud';
 import { createCrudOptions } from './crud';
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
+import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
+import { useShopInfo } from '/@/stores/shopInfo'
+import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
 
+const shopInfo = useShopInfo()
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+const tabActiveName = ref("dataTendency")
 const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
 
 // 页面打开后获取列表数据
@@ -26,7 +51,7 @@ onMounted(() => {
 	crudExpose.doRefresh();
 });
 
-const dateRange = ref([])
+
 
 </script>
 

+ 3 - 3
src/views/adManage/sp/campaigns/crud.tsx

@@ -7,9 +7,9 @@ import { dynBidStrategyEnum } from '/@/views/adManage/utils/enum.js'
 
 export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
 	const pageRequest = async (query: UserPageQuery) => {
-		query["profile"] = context.profile.value.profile_id
-		query["start"] = context.dateRange.value[0]
-		query["end"] = context.dateRange.value[1]
+		query["profileId"] = context.profile.value.profile_id
+		query["startDate"] = context.dateRange.value[0]
+		query["endDate"] = context.dateRange.value[1]
 		return await api.GetList(query);
 	};
 	const editRequest = async ({ form, row }: EditReq) => {

+ 49 - 7
src/views/adManage/sp/chartComponents/dataTendency.vue

@@ -1,6 +1,11 @@
 <template>
   <div v-loading="loading">
     <MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
+    <el-radio-group v-model="statDim" class="chart-button-group" @change="changeStatDim">
+      <el-radio-button label="day">日</el-radio-button>
+      <el-radio-button label="week" :disabled="!props.fetchLineWeek">周</el-radio-button>
+      <el-radio-button label="month" :disabled="!props.fetchLineWeek">月</el-radio-button>
+    </el-radio-group>
     <div style="height: 350px;" ref="chartRef"></div>
 </div>
 </template>
@@ -15,6 +20,7 @@ import XEUtils from 'xe-utils'
 import { buildChartOpt } from '/@/views/adManage/utils/tools.js'
 import { usePublicData } from '/@/stores/publicData'
 import { storeToRefs } from 'pinia'
+import { response } from '/@/utils/tools'
 
 defineOptions({
   name: "DataTendencyChart"
@@ -23,6 +29,8 @@ defineOptions({
 interface Props {
   fetchCard: Function,
   fetchLine: Function,
+  fetchLineMonth?: Function,
+  fetchLineWeek?: Function,
   query?: {[key: string]: any},
   initMetric?: ShowMetric[],
   metricEnum?: {[key: string]: string}[]
@@ -42,6 +50,7 @@ const shopInfo = useShopInfo()
 const metricsItems: Ref<MetricData[]> = ref([])
 let chartObj:any
 const chartRef = ref()
+const statDim = ref('day')
 const option: any = {
   dataset: {
     source: []
@@ -59,7 +68,7 @@ const option: any = {
     show: false
   },
   grid: {
-    top: 50, right: 150, bottom: 30, left: 55,
+    top: 50, right: 150, bottom: 30, left: 65,
   },
   xAxis: {
     type: 'category'
@@ -118,7 +127,7 @@ const option: any = {
       name: '',
       type: 'bar',
       encode: {
-        x: 'date',
+        x: 'Name',
         y: ''
       },
       barWidth: '20px',
@@ -133,7 +142,7 @@ const option: any = {
       name: '',
       type: 'line',
       encode: {
-        x: 'date',
+        x: 'Name',
         y: ''
       },
       symbolSize: 6,
@@ -159,7 +168,7 @@ const option: any = {
       name: '',
       type: 'line',
       encode: {
-        x: 'date',
+        x: 'Name',
         y: ''
       },
       symbolSize: 6,
@@ -178,9 +187,9 @@ const { dateRange } = storeToRefs(publicData)
 const loading = ref(true)
 const queryParams = computed(() => {
   return {
-    profile: shopInfo.profile.profile_id,
-    start: dateRange.value[0],
-    end: dateRange.value[1],
+    profileId: shopInfo.profile.profile_id,
+    startDate: dateRange.value[0],
+    endDate: dateRange.value[1],
    ...props.query
   }
 })
@@ -260,6 +269,29 @@ const changeMetric = () => {
   chartObj.setOption(opt)
 }
 
+const changeStatDim = async () => {
+  loading.value = true
+  let source = []
+  if (statDim.value === 'week') {
+    if (props.fetchLineWeek) {
+      const resp = await props.fetchLineWeek(queryParams.value)
+      source = resp.data
+    }
+  } else if (statDim.value === 'month') {
+    if (props.fetchLineMonth) {
+      const resp = await props.fetchLineMonth(queryParams.value)
+      source = resp.data
+    }
+  } else {
+    const resp = await props.fetchLine(queryParams.value)
+    source = resp.data
+  }
+  if (source.length > 0) {
+    chartObj.setOption({dataset: {source: source}})
+  }
+  loading.value = false
+}
+
 watch(
   queryParams, 
   async () => {
@@ -272,6 +304,10 @@ watch(
   }
 )
 
+publicData.$subscribe((mutation, state) => {
+	publicData.setDateRange(state.dateRange)
+})
+
 const resizeChart = () => { chartObj.resize() }
 const addResize = () => { window.addEventListener('resize', resizeChart) }
 const removeResize = () => { window.removeEventListener('resize', resizeChart) }
@@ -287,4 +323,10 @@ const removeResize = () => { window.removeEventListener('resize', resizeChart) }
   gap: 12px;
   width: 100%;
 }
+
+.chart-button-group {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 5px;
+}
 </style>

+ 49 - 50
src/views/adManage/sp/purchasedOtherProducts/crud.tsx

@@ -3,86 +3,85 @@ import { dict, UserPageQuery, compute, CreateCrudOptionsProps, CreateCrudOptions
 import { inject } from 'vue'
 import { SpCampaignPuchasedOtherProductsColumn } from '/@/views/adManage/utils/commonTabColumn.js'
 
-
 export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
 	const pageRequest = async (query: UserPageQuery) => {
-		query["profile"] = context.profile.value.profile_id
-		query["start"] = context.dateRange.value[0]
-		query["end"] = context.dateRange.value[1]
-		return await api.GetList(query);
-	};
+		query['profileId'] = context.profile.value.profile_id
+		query['startDate'] = context.dateRange.value[0]
+		query['endDate'] = context.dateRange.value[1]
+		return await api.GetList(query)
+	}
 
 	//权限判定
-	const hasPermissions = inject('$hasPermissions');
+	const hasPermissions = inject('$hasPermissions')
 
 	return {
 		crudOptions: {
 			table: {
-				height: 800
+				height: 800,
 			},
 			container: {
-        fixedHeight: false
-      },
+				fixedHeight: false,
+			},
 			actionbar: {
-				show: false
+				show: false,
 			},
 			search: {
-				show: false
+				show: false,
 			},
 			toolbar: {
-        buttons: {
+				buttons: {
 					search: {
-						show: true
+						show: true,
 					},
 					compact: {
-						show: false
-					}
-				}
+						show: false,
+					},
+				},
 			},
 			request: {
-				pageRequest
+				pageRequest,
 			},
 			rowHandle: {
-				show: false
+				show: false,
 			},
 			columns: {
-        adProduct: {
-          title: '推广商品',
+				adProduct: {
+					title: '推广商品',
 					column: {
-            width: '250px'
-          }
-        },
-        purchasedProduct: {
-          title: '购买的其它商品'
-        },
-        state: {
-          title: '状态'
-        },
-        campaignName: {
-          title: '广告活动',
-          column: {
-            width: '200px'
-          },
+						width: '250px',
+					},
+				},
+				purchasedProduct: {
+					title: '购买的其它商品',
+				},
+				state: {
+					title: '状态',
+				},
+				campaignName: {
+					title: '广告活动',
+					column: {
+						width: '200px',
+					},
 					search: {
 						show: true,
 						component: {
 							props: {
-								clearable: true
-							}
-						}
+								clearable: true,
+							},
+						},
 					},
 					form: {
-						rules: [{required: true, message:'必填项'}]
-					}
-        },
-        adGroup: {
-          title: '广告组'
-        },
-        matchType: {
-          title: '定向'
-        },
-				...SpCampaignPuchasedOtherProductsColumn
-			}
-		}
+						rules: [{ required: true, message: '必填项' }],
+					},
+				},
+				adGroup: {
+					title: '广告组',
+				},
+				matchType: {
+					title: '定向',
+				},
+				...SpCampaignPuchasedOtherProductsColumn,
+			},
+		},
 	}
 }

+ 26 - 27
src/views/adManage/sp/searchTerm/crud.tsx

@@ -3,64 +3,63 @@ import { dict, UserPageQuery, compute, CreateCrudOptionsProps, CreateCrudOptions
 import { inject } from 'vue'
 import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
 
-
 export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
 	const pageRequest = async (query: UserPageQuery) => {
-		query["profile"] = context.profile.value.profile_id
-		query["start"] = context.dateRange.value[0]
-		query["end"] = context.dateRange.value[1]
-		return await api.GetList(query);
-	};
+		query['profileId'] = context.profile.value.profile_id
+		query['startDate'] = context.dateRange.value[0]
+		query['endDate'] = context.dateRange.value[1]
+		return await api.GetList(query)
+	}
 
 	//权限判定
-	const hasPermissions = inject('$hasPermissions');
+	const hasPermissions = inject('$hasPermissions')
 
 	return {
 		crudOptions: {
 			table: {
 				height: 800,
-				rowKey: (row:any) => row.keywordId + row.searchTerm
+				rowKey: (row: any) => row.keywordId + row.searchTerm,
 			},
 			container: {
-        fixedHeight: false
-      },
+				fixedHeight: false,
+			},
 			actionbar: {
-				show: false
+				show: false,
 			},
 			search: {
-				show: false
+				show: false,
 			},
 			toolbar: {
-        buttons: {
+				buttons: {
 					search: {
-						show: true
+						show: true,
 					},
 					compact: {
-						show: false
-					}
-				}
+						show: false,
+					},
+				},
 			},
 			request: {
-				pageRequest
+				pageRequest,
 			},
 			rowHandle: {
-				show: false
+				show: false,
 			},
 			columns: {
-        searchTerm: {
-					title: '搜索词'
+				searchTerm: {
+					title: '搜索词',
 				},
 				matchType: {
-					title: '定向'
+					title: '定向',
 				},
 				campaignName: {
-					title: '广告活动'
+					title: '广告活动',
 				},
 				adGroupName: {
-					title: '广告组'
+					title: '广告组',
 				},
-				...BaseColumn
-			}
-		}
+				...BaseColumn,
+			},
+		},
 	}
 }

+ 24 - 12
src/views/adManage/utils/commonTabColumn.ts

@@ -5,7 +5,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   Click: {
@@ -14,7 +15,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   CTR: {
@@ -23,7 +25,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   Spend: {
@@ -32,7 +35,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   CPC: {
@@ -41,7 +45,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   TotalPurchases: {
@@ -50,7 +55,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   TotalUnitOrdered: {
@@ -59,7 +65,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   TotalSales: {
@@ -68,7 +75,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   PurchasesRate: {
@@ -77,7 +85,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   ACOS: {
@@ -86,7 +95,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   ROAS: {
@@ -95,7 +105,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   },
   CPA: {
@@ -104,7 +115,8 @@ export const BaseColumn = {
       show: false
     },
     column:{
-      align: 'right'
+      align: 'right',
+      minWidth: '125px'
     }
   }
 }