浏览代码

新增sb/groupdetail/ads,keywords,negativekeywords,searchwords页面

WanGxC 1 年之前
父节点
当前提交
8b74157da8
共有 21 个文件被更改,包括 340 次插入191 次删除
  1. 89 89
      src/router/index.ts
  2. 15 0
      src/theme/app.scss
  3. 10 10
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/ads/api.ts
  4. 29 12
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/ads/crud.tsx
  5. 40 28
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/index.vue
  6. 18 1
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/keyword/api.ts
  7. 29 2
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/keyword/crud.tsx
  8. 5 1
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/keyword/index.vue
  9. 1 1
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/negKeyword/api.ts
  10. 39 15
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/negKeyword/crud.tsx
  11. 1 1
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/searchTerm/api.ts
  12. 16 12
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/searchTerm/crud.tsx
  13. 24 1
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/searchTerm/index.vue
  14. 1 0
      src/views/adManage/sb/campaigns/campaignDetail/adGroups/index.vue
  15. 8 9
      src/views/adManage/sb/campaigns/campaignDetail/index.vue
  16. 2 2
      src/views/adManage/sb/campaigns/index.vue
  17. 3 3
      src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/adProducts/api.ts
  18. 0 0
      src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/adProducts/crud.tsx
  19. 0 0
      src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/adProducts/index.vue
  20. 4 4
      src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/index.vue
  21. 6 0
      src/views/adManage/utils/enum.ts

+ 89 - 89
src/router/index.ts

@@ -1,15 +1,15 @@
-import {createRouter, createWebHashHistory} from 'vue-router';
-import NProgress from 'nprogress';
-import 'nprogress/nprogress.css';
-import pinia from '/@/stores/index';
-import {storeToRefs} from 'pinia';
-import {useKeepALiveNames} from '/@/stores/keepAliveNames';
-import {useRoutesList} from '/@/stores/routesList';
-import {useThemeConfig} from '/@/stores/themeConfig';
-import {Session} from '/@/utils/storage';
-import {staticRoutes} from '/@/router/route';
-import {initFrontEndControlRoutes} from '/@/router/frontEnd';
-import {initBackEndControlRoutes} from '/@/router/backEnd';
+import {createRouter, createWebHashHistory} from 'vue-router'
+import NProgress from 'nprogress'
+import 'nprogress/nprogress.css'
+import pinia from '/@/stores/index'
+import {storeToRefs} from 'pinia'
+import {useKeepALiveNames} from '/@/stores/keepAliveNames'
+import {useRoutesList} from '/@/stores/routesList'
+import {useThemeConfig} from '/@/stores/themeConfig'
+import {Session} from '/@/utils/storage'
+import {staticRoutes} from '/@/router/route'
+import {initFrontEndControlRoutes} from '/@/router/frontEnd'
+import {initBackEndControlRoutes} from '/@/router/backEnd'
 
 /**
  * 1、前端控制路由时:isRequestRoutes 为 false,需要写 roles,需要走 setFilterRoute 方法。
@@ -21,9 +21,9 @@ import {initBackEndControlRoutes} from '/@/router/backEnd';
  */
 
 // 读取 `/src/stores/themeConfig.ts` 是否开启后端控制路由配置
-const storesThemeConfig = useThemeConfig(pinia);
-const {themeConfig} = storeToRefs(storesThemeConfig);
-const {isRequestRoutes} = themeConfig.value;
+const storesThemeConfig = useThemeConfig(pinia)
+const {themeConfig} = storeToRefs(storesThemeConfig)
+const {isRequestRoutes} = themeConfig.value
 
 /**
  * 创建一个可以被 Vue 应用程序使用的路由实例
@@ -31,9 +31,9 @@ const {isRequestRoutes} = themeConfig.value;
  * @link 参考:https://next.router.vuejs.org/zh/api/#createrouter
  */
 export const router = createRouter({
-    history: createWebHashHistory(),
-    routes: staticRoutes,
-});
+  history: createWebHashHistory(),
+  routes: staticRoutes,
+})
 
 /**
  * 路由多级嵌套数组处理成一维数组
@@ -41,13 +41,13 @@ export const router = createRouter({
  * @returns 返回处理后的一维路由菜单数组
  */
 export function formatFlatteningRoutes(arr: any) {
-    if (arr.length <= 0) return false;
-    for (let i = 0; i < arr.length; i++) {
-        if (arr[i].children) {
-            arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
-        }
+  if (arr.length <= 0) return false
+  for (let i = 0; i < arr.length; i++) {
+    if (arr[i].children) {
+      arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1))
     }
-    return arr;
+  }
+  return arr
 }
 
 /**
@@ -58,81 +58,81 @@ export function formatFlatteningRoutes(arr: any) {
  * @returns 返回将一维数组重新处理成 `定义动态路由(dynamicRoutes)` 的格式
  */
 export function formatTwoStageRoutes(arr: any) {
-    if (arr.length <= 0) return false;
-    const newArr: any = [];
-    const cacheList: Array<string> = [];
-    arr.forEach((v: any) => {
-        if (v.path === '/') {
-            newArr.push({
-                component: v.component,
-                name: v.name,
-                path: v.path,
-                redirect: v.redirect,
-                meta: v.meta,
-                children: []
-            });
-        } else {
-            // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用
-            // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
-            if (v.path.indexOf('/:') > -1) {
-                v.meta['isDynamic'] = true;
-                v.meta['isDynamicPath'] = v.path;
-            }
-            newArr[0].children.push({...v});
-            // 存 name 值,keep-alive 中 include 使用,实现路由的缓存
-            // 路径:/@/layout/routerView/parent.vue
-            if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive && v.component_name != "") {
-                cacheList.push(v.name);
-                const stores = useKeepALiveNames(pinia);
-                stores.setCacheKeepAlive(cacheList);
-            }
-        }
-    });
-    return newArr;
+  if (arr.length <= 0) return false
+  const newArr: any = []
+  const cacheList: Array<string> = []
+  arr.forEach((v: any) => {
+    if (v.path === '/') {
+      newArr.push({
+        component: v.component,
+        name: v.name,
+        path: v.path,
+        redirect: v.redirect,
+        meta: v.meta,
+        children: []
+      })
+    } else {
+      // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用
+      // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
+      if (v.path.indexOf('/:') > -1) {
+        v.meta['isDynamic'] = true
+        v.meta['isDynamicPath'] = v.path
+      }
+      newArr[0].children.push({...v})
+      // 存 name 值,keep-alive 中 include 使用,实现路由的缓存
+      // 路径:/@/layout/routerView/parent.vue
+      if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive && v.component_name != '') {
+        cacheList.push(v.name)
+        const stores = useKeepALiveNames(pinia)
+        stores.setCacheKeepAlive(cacheList)
+      }
+    }
+  })
+  return newArr
 }
 
 // 路由加载前
 router.beforeEach(async (to, from, next) => {
-    NProgress.configure({showSpinner: false});
-    if (to.meta.title) NProgress.start();
-    const token = Session.get('token');
-    if (to.path === '/login' && !token) {
-        next();
-        NProgress.done();
+  NProgress.configure({showSpinner: false})
+  if (to.meta.title) NProgress.start()
+  const token = Session.get('token')
+  if (to.path === '/login' && !token) {
+    next()
+    NProgress.done()
+  } else {
+    if (!token) {
+      next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`)
+      Session.clear()
+      NProgress.done()
+    } else if (token && to.path === '/login') {
+      next('/home')
+      NProgress.done()
     } else {
-        if (!token) {
-            next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`);
-            Session.clear();
-            NProgress.done();
-        } else if (token && to.path === '/login') {
-            next('/home');
-            NProgress.done();
+      const storesRoutesList = useRoutesList(pinia)
+      const {routesList} = storeToRefs(storesRoutesList)
+      if (routesList.value.length === 0) {
+        if (isRequestRoutes) {
+          // 后端控制路由:路由数据初始化,防止刷新时丢失
+          await initBackEndControlRoutes()
+          // 动态添加路由:防止非首页刷新时跳转回首页的问题
+          // 确保 addRoute() 时动态添加的路由已经被完全加载上去
+          next({...to, replace: true})
         } else {
-            const storesRoutesList = useRoutesList(pinia);
-            const {routesList} = storeToRefs(storesRoutesList);
-            if (routesList.value.length === 0) {
-                if (isRequestRoutes) {
-                    // 后端控制路由:路由数据初始化,防止刷新时丢失
-                    await initBackEndControlRoutes();
-                    // 动态添加路由:防止非首页刷新时跳转回首页的问题
-                    // 确保 addRoute() 时动态添加的路由已经被完全加载上去
-                    next({...to, replace: true});
-                } else {
-                    // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
-                    await initFrontEndControlRoutes();
-                    next({...to, replace: true});
-                }
-            } else {
-                next();
-            }
+          // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
+          await initFrontEndControlRoutes()
+          next({...to, replace: true})
         }
+      } else {
+        next()
+      }
     }
-});
+  }
+})
 
 // 路由加载后
 router.afterEach(() => {
-    NProgress.done();
-});
+  NProgress.done()
+})
 
 // 导出路由
-export default router;
+export default router

+ 15 - 0
src/theme/app.scss

@@ -570,3 +570,18 @@ body,
   border: none !important;
   border-bottom: 0.5px solid rgb(211, 211, 211) !important;
 }
+
+.no-hover-effect {
+  background-color: #f0f9eb;
+  color: #67c23a;
+  border-color: #b3e19d;
+  margin-top: -3px;
+}
+.no-hover-effect:hover,
+.no-hover-effect:focus,
+.no-hover-effect:active {
+  background-color: #f0f9eb !important;
+  color: #67c23a !important;
+  border-color: #b3e19d !important;
+}
+

+ 10 - 10
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/ads/api.ts

@@ -1,10 +1,10 @@
 import { request } from '/@/utils/service';
 import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
 
-export const apiPrefix = '/api/ad_manage/sbgroupdetail/';
+export const apiPrefix = '/api/ad_manage/sbgroupdetail/ads/';
 export function GetList(query: UserPageQuery) {
     return request({
-        url: apiPrefix + 'ads/list/',
+        url: apiPrefix + 'list/',
         method: 'get',
         params: query,
     })
@@ -49,11 +49,11 @@ export function getCardData(query: UserPageQuery) {
     })
   }
 
-  export function getLineData(query: UserPageQuery) {
-    query["dateRangeType"] = "D"
-    return request({
-      url: apiPrefix + "daily/",
-      method: 'GET',
-      params: query
-    })
-  }
+export function getLineData(query: UserPageQuery) {
+  query['dateRangeType'] = 'D'
+  return request({
+    url: apiPrefix + 'daily/',
+    method: 'GET',
+    params: query
+  })
+}

+ 29 - 12
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/ads/crud.tsx

@@ -27,16 +27,38 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 
 	return {
 		crudOptions: {
-			table: {},
+			table: {
+				height: 750,
+				headerCellStyle: {
+					backgroundColor: '#f6f7fa', // 直接设置背景颜色
+					height: '20px',
+					// border: '0.5px solid #ddd',
+				},
+				cellStyle: {
+					border: 'none',
+					borderBottom: '0.5px solid #ddd',
+				},
+			},
 			container: {
         fixedHeight: false
       },
 			actionbar: {
-				show: false,
+				show: true,
+				color: "#626aef",
 				buttons: {
 					add: {
 						show: false
-					}
+					},
+					create: {
+						text: '添加广告',
+						// type: 'primary',
+						color: "#626aef",
+						plain: true,
+						show: true,
+						click() {
+
+						}
+					},
 				}
 			},
 			search: {
@@ -88,16 +110,11 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 				},
 			},
 			columns: {
-        asin: {
-					title: 'asin',
-					column: {
-						width: "120px"
-					}
-				},
-				sku: {
-					title:'sku',
+        adGroupName: {
+					title: '广告组名称',
 					column: {
-						width: "180px"
+						width: 230,
+						fixed: 'left',
 					}
 				},
 				state: {

+ 40 - 28
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/index.vue

@@ -1,29 +1,32 @@
 <template>
   <div class="asj-container">
     <div class="asj-detail-header">
-      <span style="font-size: x-large; font-weight: bold; color: #0f1111;margin: 5px;"> 
+      <span style="font-size: x-large; font-weight: bold; color: #0f1111;margin: 5px;">
         <span> {{ adGroupInfo.adGroupName }} </span>
       </span>
       <div class="asj-detail-info">
-        <span>状态:{{ adGroupInfo.state }}</span>
-        <span>投放类型:{{ adGroupInfo.targetingType }}</span>
-        <span>默认竞价:{{ profile.currency_symbol + adGroupInfo.defaultBid }}</span>
-        <span>投放日期:{{ adGroupInfo.startDate }} ~ {{ adGroupInfo.endDate ?? '无结束日期' }}</span>
+        <span style="color: rgb(177, 177, 177);">状态: </span>
+        <span>
+          <el-button class="no-hover-effect" type="success" size="small" round plain>{{ dynStatusEnum[adGroupInfo.state] }}</el-button>
+        </span>
+        <span class="head-span">投放类型: </span> <span>{{ targetTypeEnum[adGroupInfo.creative_type] }}</span>
+        <!-- <span>默认竞价:{{ profile.currency_symbol + adGroupInfo.defaultBid }}</span> -->
+        <span class="head-span">投放日期: </span> <span>{{ adGroupInfo.startDate }} ~ {{ adGroupInfo.endDate ?? '无结束日期' }}</span>
       </div>
     </div>
     <el-tabs type="border-card" class="asj-detail-tabs" v-model="tabActiveName">
-      <el-tab-pane label="推广商品" name="adProducts">
-        <Ads v-if="tabActiveName==='adProducts'" :adGroupId="route.query.adGroupId"></Ads>
+      <el-tab-pane label="广告" name="ads">
+        <Ads v-if="tabActiveName==='ads'" :adGroupId="route.query.adGroupId"></Ads>
       </el-tab-pane>
-      <template v-if="route.query.targetingType === 'automatic'">
-        <el-tab-pane label="定向" name="tab2">
-          <AutoTarget v-if="tabActiveName === 'tab2'" :adGroupId="route.query.adGroupId">定向</AutoTarget>
-        </el-tab-pane>
-        <el-tab-pane label="否定投放" name="tab3">
-          <NegTarget v-if="tabActiveName === 'tab3'" :adGroupId="route.query.adGroupId">否定投放</NegTarget>
-        </el-tab-pane>
-      </template>
-      <template v-else-if="route.query.targetingType ==='product'">
+      <!--<template v-if="route.query.targetingType === 'automatic'">-->
+      <!--  <el-tab-pane label="定向" name="tab2">-->
+      <!--    <AutoTarget v-if="tabActiveName === 'tab2'" :adGroupId="route.query.adGroupId">定向</AutoTarget>-->
+      <!--  </el-tab-pane>-->
+      <!--  <el-tab-pane label="否定投放" name="tab3">-->
+      <!--    <NegTarget v-if="tabActiveName === 'tab3'" :adGroupId="route.query.adGroupId">否定投放</NegTarget>-->
+      <!--  </el-tab-pane>-->
+      <!--</template>-->
+      <template v-if="route.query.targetingType ==='target'">
         <el-tab-pane label="商品投放" name="tab2">
           <ManualTarget v-if="tabActiveName === 'tab2'" :adGroupId="route.query.adGroupId">商品投放</ManualTarget>
         </el-tab-pane>
@@ -38,21 +41,20 @@
         <el-tab-pane label="否定词" name="tab3">
           <NegKeyword v-if="tabActiveName === 'tab3'" :ad-group-id="route.query.adGroupId">否定词</NegKeyword>
         </el-tab-pane>
+        <el-tab-pane label="搜索关键词" name="searchTerm">
+          <SearchTerm v-if="tabActiveName === 'searchTerm'" :adGroupId="route.query.adGroupId" />
+        </el-tab-pane>
       </template>
-      <el-tab-pane label="搜索关键词" name="searchTerm">
-        <SearchTerm v-if="tabActiveName === 'searchTerm'" :adGroupId="route.query.adGroupId" />
-      </el-tab-pane>
     </el-tabs>
   </div>
 </template>
 
 <script lang="ts" setup>
-import { Ref, ref, onMounted, computed } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-import { GetObj } from './api'
-import { useShopInfo } from '/@/stores/shopInfo'
-// import { usePublicData } from '/@/stores/publicData'
-import { storeToRefs } from 'pinia'
+import {onMounted, ref, Ref} from 'vue'
+import {useRoute} from 'vue-router'
+import {GetObj} from './api'
+import {useShopInfo} from '/@/stores/shopInfo'
+import {storeToRefs} from 'pinia'
 import Ads from './ads/index.vue'
 import SearchTerm from './searchTerm/index.vue'
 import Keyword from './keyword/index.vue'
@@ -61,8 +63,11 @@ import ManualTarget from './manualTarget/index.vue'
 import NegProduct from './negProduct/index.vue'
 import NegKeyword from './negKeyword/index.vue'
 import NegTarget from './negTarget/index.vue'
+import {dynStatusEnum, targetTypeEnum} from '/@/views/adManage/utils/enum'
+// import { usePublicData } from '/@/stores/publicData'
 
-const tabActiveName = ref('adProducts')
+
+const tabActiveName = ref('ads')
 const shopInfo = useShopInfo()
 const { profile } = storeToRefs(shopInfo)
 const route = useRoute()
@@ -71,10 +76,17 @@ const adGroupInfo: Ref<SpAdGroup> = ref({})
 onMounted(async () => {
   const resp = await GetObj(route.query.adGroupId)
   adGroupInfo.value = resp.data
+  console.log(111, adGroupInfo.value)
 })
 
 </script>
 
 <style scoped>
-
-</style>
+.head-span {
+  color: rgb(177, 177, 177);
+  margin-left: 40px;
+}
+:deep(.el-tabs--border-card) {
+  border: none;
+}
+</style>

+ 18 - 1
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/keyword/api.ts

@@ -1,7 +1,7 @@
 import { request } from '/@/utils/service';
 import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
 
-export const apiPrefix = '/api/ad_manage/sbgroupdetail/targets/';
+export const apiPrefix = '/api/ad_manage/sbgroupdetail/keywords/';
 export function GetList(query: UserPageQuery) {
     return request({
         url: apiPrefix + 'list/',
@@ -9,3 +9,20 @@ export function GetList(query: UserPageQuery) {
         params: query,
     })
 }
+
+export function getCardData(query: UserPageQuery) {
+    return request({
+        url: apiPrefix + "total/",
+        method: 'GET',
+        params: query
+    })
+}
+
+export function getLineData(query: UserPageQuery) {
+    query["dateRangeType"] = "D"
+    return request({
+        url: apiPrefix + "daily/",
+        method: 'GET',
+        params: query
+    })
+}

+ 29 - 2
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/keyword/crud.tsx

@@ -17,12 +17,39 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 
   return {
     crudOptions: {
-      table: {},
+      table: {
+        height: 750,
+        headerCellStyle: {
+          backgroundColor: '#f6f7fa', // 直接设置背景颜色
+          height: '20px',
+          // border: '0.5px solid #ddd',
+        },
+        cellStyle: {
+          border: 'none',
+          borderBottom: '0.5px solid #ddd',
+        },
+      },
       container: {
         fixedHeight: false,
       },
       actionbar: {
-        show: false,
+        show: true,
+        color: "#626aef",
+        buttons: {
+          add: {
+            show: false
+          },
+          create: {
+            text: '添加关键词',
+            // type: 'primary',
+            color: "#626aef",
+            plain: true,
+            show: true,
+            click() {
+
+            }
+          },
+        }
       },
       search: {
         show: true,

+ 5 - 1
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/keyword/index.vue

@@ -4,7 +4,9 @@
       <template #search-left>
         <DateRangePicker v-model="dateRange"></DateRangePicker>
       </template>
-
+      <template #header-middle>
+        <DataTendencyChart :query="queryParams" :fetch-card="getCardData" :fetch-line="getLineData"> </DataTendencyChart>
+      </template>
       <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
         <DataCompare
           :field="field"
@@ -36,6 +38,8 @@ import { LocationQueryValue } from 'vue-router'
 import { BaseColumn } from '/@/views/adManage/utils/commonTabColumn.js'
 import DataCompare from '/@/components/dataCompare/index.vue'
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
+import {getCardData, getLineData} from '/@/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/keyword/api'
+import DataTendencyChart from '/@/views/adManage/sp/chartComponents/dataTendency.vue'
 
 interface Props {
   adGroupId: LocationQueryValue | LocationQueryValue[]

+ 1 - 1
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/negKeyword/api.ts

@@ -1,7 +1,7 @@
 import { request } from '/@/utils/service';
 import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
 
-export const apiPrefix = '/api/ad_manage/sbgroupdetail/negativekeyword/';
+export const apiPrefix = '/api/ad_manage/sbgroupdetail/negativekeywords/';
 export function GetList(query: UserPageQuery) {
     return request({
         url: apiPrefix + 'list/',

+ 39 - 15
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/negKeyword/crud.tsx

@@ -16,12 +16,39 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 
   return {
     crudOptions: {
-      table: {},
+      table: {
+        height: 750,
+        headerCellStyle: {
+          backgroundColor: '#f6f7fa', // 直接设置背景颜色
+          height: '20px',
+          // border: '0.5px solid #ddd',
+        },
+        cellStyle: {
+          border: 'none',
+          borderBottom: '0.5px solid #ddd',
+        },
+      },
       container: {
         fixedHeight: false,
       },
       actionbar: {
-        show: false,
+        show: true,
+        color: "#626aef",
+        buttons: {
+          add: {
+            show: false
+          },
+          create: {
+            text: '新建广告活动',
+            // type: 'primary',
+            color: "#626aef",
+            plain: true,
+            show: true,
+            click() {
+
+            }
+          },
+        }
       },
       search: {
         show: false,
@@ -34,16 +61,16 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 					}
 				}
       },
-      // toolbar: {
-      //   buttons: {
-      //     search: {
-      //       show: true,
-      //     },
-      //     compact: {
-      //       show: false,
-      //     },
-      //   },
-      // },
+      toolbar: {
+        buttons: {
+          search: {
+            show: true,
+          },
+          compact: {
+            show: false,
+          },
+        },
+      },
       request: {
         pageRequest,
       },
@@ -54,9 +81,6 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
         keywordText: {
           title: '否定词',
         },
-        matchType: {
-          title: '匹配类型',
-        },
       },
     },
   }

+ 1 - 1
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/searchTerm/api.ts

@@ -1,7 +1,7 @@
 import { request } from '/@/utils/service';
 import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
 
-export const apiPrefix = '/api/ad_manage/sbgroupdetail/searchterm/';
+export const apiPrefix = '/api/ad_manage/sbgroupdetail/searchwords/';
 export function GetList(query: UserPageQuery) {
     return request({
         url: apiPrefix + 'list/',

+ 16 - 12
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/searchTerm/crud.tsx

@@ -17,7 +17,18 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 
   return {
     crudOptions: {
-      table: {},
+      table: {
+        height: 750,
+        headerCellStyle: {
+          backgroundColor: '#f6f7fa', // 直接设置背景颜色
+          height: '20px',
+          // border: '0.5px solid #ddd',
+        },
+        cellStyle: {
+          border: 'none',
+          borderBottom: '0.5px solid #ddd',
+        },
+      },
       container: {
         fixedHeight: false,
       },
@@ -52,24 +63,17 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
         show: false,
       },
       columns: {
-        searchTerm: {
+        query: {
           title: '搜索词',
           column: {
             width: '200px',
             fixed: 'left',
           },
         },
-        targeting: {
-          title: '定向',
+        keywordText: {
+          title: '关键词',
           column: {
-            width: '200px'
-          },
-        },
-        matchType: {
-          title: '匹配类型',
-          column: {
-            width: '100px',
-            align: 'center'
+            width: '200px',
           },
         },
         ...BaseColumn,

+ 24 - 1
src/views/adManage/sb/campaigns/campaignDetail/adGroups/adGroupDetail/searchTerm/index.vue

@@ -5,6 +5,16 @@
         <DateRangePicker v-model="dateRange"></DateRangePicker>
       </template>
 
+      <template #cell_query="scope">
+        <el-tooltip effect="dark" :content="scope.row.query" placement="top">
+          <div class="en-text">{{ scope.row.query }}</div>
+        </el-tooltip>
+      </template>
+      <template #cell_keywordText="scope">
+        <el-tooltip effect="dark" :content="scope.row.keywordText" placement="top">
+            <div class="en-text">{{ scope.row.keywordText }}</div>
+        </el-tooltip>
+      </template>
       <template v-for="field of Object.keys(BaseColumn)" #[`cell_${field}`]="scope">
         <DataCompare
           :field="field"
@@ -64,4 +74,17 @@ watch(
 )
 </script>
 
-<style scoped></style>
+<style scoped>
+.en-text {
+  max-width: 100%;
+  font-size: 13px;
+  font-weight: 420;
+  word-break: break-word;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: normal;
+  display: -webkit-box;
+  -webkit-line-clamp: 1;
+  -webkit-box-orient: vertical;
+}
+</style>

+ 1 - 0
src/views/adManage/sb/campaigns/campaignDetail/adGroups/index.vue

@@ -78,4 +78,5 @@ watch(
   -webkit-line-clamp: 1;
   -webkit-box-orient: vertical;
 }
+
 </style>

+ 8 - 9
src/views/adManage/sb/campaigns/campaignDetail/index.vue

@@ -5,12 +5,15 @@
         <span> {{ campaignInfo.campaignName }}</span>
       </span>
       <div class="asj-detail-info">
-        <span style="color: rgb(177, 177, 177)">状态:</span> <el-button type="success" round plain size="small" style="margin-top: -3px">{{ dynStatusEnum[campaignInfo.state] }}</el-button><!--({{ campaignInfo.servingStatus }})-->
-        <span class="head-span">预算:</span> <span>{{ profile.currency_symbol + campaignInfo.budget }} | {{ campaignInfo.budgetType }}</span>
+        <span style="color: rgb(177, 177, 177)">状态: </span>
+        <span>
+          <el-button class="no-hover-effect" type="success" round plain size="small" style="margin-top: -3px">{{ dynStatusEnum[campaignInfo.state] }}</el-button>
+        </span><!--({{ campaignInfo.servingStatus }})-->
+        <span class="head-span">预算: </span> <span>{{ profile.currency_symbol + campaignInfo.budget }} | {{ campaignInfo.budgetType }}</span>
         <!-- <span>投放类型:{{ campaignInfo.targetingType }}</span> -->
-        <span class="head-span">投放日期:</span> <span>{{ campaignInfo.startDate }} ~ {{ campaignInfo.endDate ?? '无结束日期' }}</span>
-        <span class="head-span">广告组合:</span> <span>{{ campaignInfo?.portfolioName }}</span>
-        <span class="head-span">竞价:</span> <span>{{ getEnumLabel(dynBidOptimizationEnum, campaignInfo.bidOptimization) }}</span>
+        <span class="head-span">投放日期: </span> <span>{{ campaignInfo.startDate }} ~ {{ campaignInfo.endDate ?? '无结束日期' }}</span>
+        <span class="head-span">广告组合: </span> <span>{{ campaignInfo?.portfolioName }}</span>
+        <span class="head-span">竞价: </span> <span>{{ getEnumLabel(dynBidOptimizationEnum, campaignInfo.bidOptimization) }}</span>
       </div>
     </div>
     <el-tabs type="border-card" class="asj-detail-tabs" v-model="tabActiveName">
@@ -26,10 +29,6 @@
       <el-tab-pane label="广告位" name="placement">
         <Placement :campaignId="route.query.campaignId" v-if="tabActiveName==='placement'"/>
       </el-tab-pane>
-      <el-tab-pane label="否定投放" name="negative">
-        否定投放
-      </el-tab-pane>
-      <!-- <el-tab-pane label="操作日志" :lazy="true"></el-tab-pane> -->
     </el-tabs>
   </div>
 </template>

+ 2 - 2
src/views/adManage/sb/campaigns/index.vue

@@ -47,7 +47,7 @@
           :show-compare="showCompare"/>
 			</template>
 			<template #toolbar-left>
-				<div class="campare-switch">
+				<div class="compare-switch">
 					<span>数据对比 </span>
 					<el-switch v-model="showCompare" size="small" />
 				</div>
@@ -101,7 +101,7 @@ watch(queryParams, async () => {
 </script>
 
 <style lang="scss" scoped>
-.campare-switch {
+.compare-switch {
 	flex: none;
 }
 

+ 3 - 3
src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/ads/api.ts → src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/adProducts/api.ts

@@ -1,10 +1,10 @@
 import { request } from '/@/utils/service';
 import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
 
-export const apiPrefix = '/api/ad_manage/spgroupdetail/';
+export const apiPrefix = '/api/ad_manage/spgroupdetail/adproduct/';
 export function GetList(query: UserPageQuery) {
     return request({
-        url: apiPrefix + 'ads/list/',
+        url: apiPrefix + 'list/',
         method: 'get',
         params: query,
     })
@@ -48,7 +48,7 @@ export function getCardData(query: UserPageQuery) {
         params: query
     })
   }
-  
+
   export function getLineData(query: UserPageQuery) {
     query["dateRangeType"] = "D"
     return request({

+ 0 - 0
src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/ads/crud.tsx → src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/adProducts/crud.tsx


+ 0 - 0
src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/ads/index.vue → src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/adProducts/index.vue


+ 4 - 4
src/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="asj-container">
     <div class="asj-detail-header">
-      <span style="font-size: x-large; font-weight: bold; color: #0f1111;margin: 5px;"> 
+      <span style="font-size: x-large; font-weight: bold; color: #0f1111;margin: 5px;">
         <span> {{ adGroupInfo.adGroupName }} </span>
       </span>
       <div class="asj-detail-info">
@@ -13,7 +13,7 @@
     </div>
     <el-tabs type="border-card" class="asj-detail-tabs" v-model="tabActiveName">
       <el-tab-pane label="推广商品" name="adProducts">
-        <Ads v-if="tabActiveName==='adProducts'" :adGroupId="route.query.adGroupId"></Ads>
+        <AdProducts v-if="tabActiveName==='adProducts'" :adGroupId="route.query.adGroupId"></AdProducts>
       </el-tab-pane>
       <template v-if="route.query.targetingType === 'automatic'">
         <el-tab-pane label="定向" name="tab2">
@@ -53,7 +53,7 @@ import { GetObj } from './api'
 import { useShopInfo } from '/@/stores/shopInfo'
 // import { usePublicData } from '/@/stores/publicData'
 import { storeToRefs } from 'pinia'
-import Ads from './ads/index.vue'
+import AdProducts from '/@/views/adManage/sp/campaigns/campaignDetail/adGroups/adGroupDetail/adProducts/index.vue'
 import SearchTerm from './searchTerm/index.vue'
 import Keyword from './keyword/index.vue'
 import AutoTarget from './autoTarget/index.vue'
@@ -77,4 +77,4 @@ onMounted(async () => {
 
 <style scoped>
 
-</style>
+</style>

+ 6 - 0
src/views/adManage/utils/enum.ts

@@ -83,6 +83,12 @@ export const dynStatusEnum = {
     'ENABLED' : '投放中',
     'DISABLED' : '禁用'
   }
+export const targetTypeEnum = {
+  'PRODUCT_COLLECTION': '商品集',
+  'VIDEO': '视频',
+  'BRAND_VIDEO': '品牌视频',
+  'STORE_SPOTLIGHT': '店铺关注(STORE_SPOTLIGHT)'
+}
 
 export const spCampaignPlacementEnum = [
   {label: '搜索结果顶部', value: 'top'},