Browse Source

任务列表

xiuli.gao 1 year ago
parent
commit
095fcf5017

+ 325 - 0
src/components/businessMoudle/adTask/detail/index.vue

@@ -0,0 +1,325 @@
1
+<template>
2
+  <Drawer :drawerShow="drawer_show" @close="closeDrawer" drawerSize="70%" :headerSlotFlag="true">
3
+    <template v-slot:headerSlot>
4
+      <div class="flex_between">
5
+        <h4 class="lMar10 c-000 f22 c-theme_text">{{ '详情' }}</h4>
6
+        <el-icon class="pointer" @click="closeDrawer">
7
+          <CloseBold />
8
+        </el-icon>
9
+      </div>
10
+    </template>
11
+    <template v-slot:content>
12
+      <div class="container" v-loading="loading">
13
+        <el-collapse v-model="activeNames" @change="handleCollapseChange">
14
+          <el-collapse-item title="任务基本信息" name="1">
15
+            <div class="flexWrap">
16
+              <div class="base-info">
17
+                <div class="label">任务名称:</div>
18
+                <div class="con">{{ task_info?.info?.name }}</div>
19
+              </div>
20
+              <div class="base-info">
21
+                <div class="label">账户:</div>
22
+                <el-tooltip effect="dark" placement="top">
23
+                  <template #content><span
24
+                      v-html="task_info?.info?.account?.map((v) => `${v.account_name}(${v.account_id})<br/>`).join('')"></span></template>
25
+                  <div class="con">
26
+                    <span v-for="(item, index) in task_info?.info?.account">{{ item.account_name }}
27
+                      <em v-if="index != task_info?.info?.account?.length - 1">、</em>
28
+                    </span>
29
+                  </div>
30
+                </el-tooltip>
31
+              </div>
32
+              <div class="base-info">
33
+                <div class="label">提交广告计划数:</div>
34
+                <div class="con">{{ task_info?.info?.camp_count }}</div>
35
+              </div>
36
+              <div class="base-info">
37
+                <div class="label">提交广告数:</div>
38
+                <div class="con">{{ task_info?.info?.ad_count }}</div>
39
+              </div>
40
+              <div class="base-info">
41
+                <div class="label">提交规则:</div>
42
+                <div class="con">{{ task_info?.info?.comtype == '1' ? '立即提交' : task_info?.info?.comtype == '2' ? '定时提交' :
43
+                  '' }}</div>
44
+              </div>
45
+              <div class="base-info">
46
+                <div class="label">开始执行时间:</div>
47
+                <div class="con">{{ task_info?.info?.dotime }}</div>
48
+              </div>
49
+            </div>
50
+          </el-collapse-item>
51
+        </el-collapse>
52
+        <!-- tab切换 -->
53
+        <div class="menu bMar15">
54
+          <div :class="['menu-item', tab == item.value ? 'menu-item-active' : '']" v-for="item in tab_list" @click="handleSelect(item.value)">{{ item.label
55
+          }}</div>
56
+        </div>
57
+        <!-- 提交信息 -->
58
+        <template v-if="tab == 1">
59
+          <el-table ref="tableRef" :data="task_info?.list" :header-cell-style="tableHeaderStyle"
60
+          border empty-text="暂无数据" max-height="70vh">
61
+          <template v-for="item in tableInfo.descol">
62
+            <el-table-column :fixed="item.fixed" :prop="item.prop" :min-width="item.width ? item.width : '80px'">
63
+              <template #header>
64
+                <div class="flex">
65
+                  <span>{{ item.label }}</span>
66
+                </div>
67
+              </template>
68
+              <template #default="scope">
69
+                <!-- 提交状态 -->
70
+                <div v-if="item.prop == 'status'">
71
+                  <span
72
+                    :class="['task-status', 'rMar10', scope.row.status == 2 && (scope.row.fail_num == 0 ? 'success' : 'fail')]">
73
+                    <span class="icon task-status--finish-icon"></span>
74
+                    <span class="task-status--finish-font">{{ scope.row.status == 0 ? '待提交' : scope.row.status == 1 ?
75
+                      '提交中' :
76
+                      scope.row.status == 2 ? '提交完成' : '' }} </span>
77
+                  </span>
78
+                  <span class="opt-link" v-if="scope.row.status == 2"> 成功:{{ scope.row.success_num }} 失败:{{
79
+                    scope.row.fail_num
80
+                  }} </span>
81
+                </div>
82
+                <!-- 其他 -->
83
+                <div class="cellDiv" v-else>
84
+                  <el-tooltip :disabled="!(scope.row[item.prop] && scope.row[item.prop].length > 30)" effect="dark"
85
+                    :content="scope.row[item.prop] + ''">
86
+                    <div class="clampTwo line21" style="flex: 1">
87
+                      {{ scope.row[item.prop] || scope.row[item.prop] == 0 ? scope.row[item.prop] : '-' }}
88
+                    </div>
89
+                  </el-tooltip>
90
+                </div>
91
+              </template>
92
+            </el-table-column>
93
+          </template>
94
+        </el-table>
95
+        </template>
96
+        <!-- 执行记录 -->
97
+        <template v-if="tab == 2">
98
+          <el-table ref="tableRef" :data="tableInfo.taskRecordList" :header-cell-style="tableHeaderStyle"
99
+          border empty-text="暂无数据" max-height="70vh">
100
+          <template v-for="item in tableInfo.recordDescol">
101
+            <el-table-column :fixed="item.fixed" :prop="item.prop" :min-width="item.width ? item.width : '80px'">
102
+              <template #header>
103
+                <div class="flex">
104
+                  <span>{{ item.label }}</span>
105
+                </div>
106
+              </template>
107
+              <template #default="scope">
108
+                <!-- 提交状态 -->
109
+                <div v-if="item.prop == 'status'">
110
+                  <span
111
+                    :class="['task-status', 'rMar10', scope.row.status == 2 && (scope.row.fail_num == 0 ? 'success' : 'fail')]">
112
+                    <span class="icon task-status--finish-icon"></span>
113
+                    <span class="task-status--finish-font">{{ scope.row.status == 0 ? '待提交' : scope.row.status == 1 ?
114
+                      '提交中' :
115
+                      scope.row.status == 2 ? '提交完成' : '' }} </span>
116
+                  </span>
117
+                </div>
118
+                <!-- 其他 -->
119
+                <div class="cellDiv" v-else>
120
+                  <el-tooltip :disabled="!(scope.row[item.prop] && scope.row[item.prop].length > 30)" effect="dark"
121
+                    :content="scope.row[item.prop] + ''">
122
+                    <div class="clampTwo line21" style="flex: 1">
123
+                      {{ scope.row[item.prop] || scope.row[item.prop] == 0 ? scope.row[item.prop] : '-' }}
124
+                    </div>
125
+                  </el-tooltip>
126
+                </div>
127
+              </template>
128
+            </el-table-column>
129
+          </template>
130
+        </el-table>
131
+        </template>
132
+      </div>
133
+    </template>
134
+  </Drawer>
135
+</template>
136
+<script setup lang="ts">
137
+import Drawer from '@/components/capsulationMoudle/_drawer.vue'
138
+import { reactive, ref } from 'vue';
139
+import { taskDetail, taskRecord } from '../ts/api'
140
+import { exportDefine } from '../ts/define';
141
+
142
+const loading = ref(false)
143
+const drawer_show = ref(false)
144
+const task_id = ref()
145
+const task_info = ref()
146
+const activeNames = ref(["1"])
147
+const tab = ref(1)
148
+const tab_list = [
149
+  { label: '提交信息', value: 1 },
150
+  { label: '执行记录', value: 2 },
151
+]
152
+const tableInfo:any = reactive({
153
+  taskRecordList:[],//执行记录
154
+  descol: [
155
+    { prop: 'account_name', label: '账户', fixed: '', width: '120' },
156
+    { prop: 'optimization_goal', label: '转化目标', fixed: '' },
157
+    { prop: 'deep_conversion_spec_goal', label: '深度转化目标', fixed: '' },
158
+    { prop: 'bid_amount', label: '转化目标出价', fixed: '' },
159
+    { prop: 'deep_bid_amount', label: '深度转化目标出价', fixed: '' },
160
+    { prop: 'ad_count', label: '新建广告数', fixed: '' },
161
+    { prop: 'status', label: '提交结果', fixed: '' ,width: '140' },
162
+  ],
163
+  recordDescol: [
164
+    { prop: 'created_at', label: '创建时间', fixed: ''},
165
+    { prop: 'ad_count', label: '提交广告数', fixed: ''},
166
+    { prop: 'status', label: '状态', fixed: ''},
167
+  ]
168
+})
169
+const {
170
+  tableHeaderStyle,
171
+} = exportDefine()
172
+
173
+/**获取任务详情 */
174
+const getTaskDetail = () => {
175
+  loading.value = true
176
+  taskDetail({
177
+    task_id: task_id.value,
178
+  }).then((res) => {
179
+    loading.value = false
180
+    task_info.value = res
181
+  }).catch(() => { loading.value = false })
182
+}
183
+
184
+/**获取执行记录 */
185
+const getTaskRecord = () => {
186
+  loading.value = true
187
+  taskRecord({task_id: task_id.value}).then((res:any)=>{
188
+    loading.value = false
189
+    if(res){
190
+      tableInfo.taskRecordList = [res]
191
+    }
192
+  }).catch(()=>{ loading.value = false})
193
+}
194
+
195
+/**点击切换 */
196
+const handleSelect = (key: any) => {
197
+  if(key != tab.value && key == 2) {
198
+    getTaskRecord()
199
+  }
200
+  tab.value = key
201
+}
202
+
203
+/**折叠面板 */
204
+const handleCollapseChange = (val: string[]) => {
205
+  console.log(val)
206
+}
207
+
208
+/**关闭Detail */
209
+const closeDrawer = () => {
210
+  drawer_show.value = false
211
+  tab.value = 1;
212
+}
213
+
214
+const switchShow = (val: boolean, id: any) => {
215
+  drawer_show.value = val
216
+  task_id.value = id
217
+  if (val) {
218
+    getTaskDetail()
219
+  }
220
+}
221
+// 父组件共享值
222
+defineExpose({
223
+  switchShow,
224
+});
225
+</script>
226
+<style scoped lang="scss">
227
+:deep(.el-collapse-item__header) {
228
+  color: #333;
229
+  font-weight: bold;
230
+  font-size: 16px;
231
+}
232
+
233
+:deep(.el-collapse-item__arrow) {
234
+  color: #333;
235
+}
236
+
237
+:deep(.el-collapse-item__wrap) {
238
+  border-bottom: 0;
239
+}
240
+
241
+.container {
242
+  min-height: 80vh;
243
+  margin-top: -20px;
244
+}
245
+
246
+.base-info {
247
+  display: flex;
248
+  align-items: center;
249
+  width: 50%;
250
+
251
+  .label,
252
+  .con {
253
+    line-height: 31px;
254
+    overflow: hidden;
255
+    font-size: 12px;
256
+    line-height: 31px;
257
+    color: #444;
258
+    text-overflow: ellipsis;
259
+    white-space: nowrap;
260
+  }
261
+
262
+  .label {
263
+    width: 100px;
264
+  }
265
+}
266
+
267
+.menu {
268
+  display: flex;
269
+  align-items: center;
270
+  border-bottom: 1px solid #ebeef5;
271
+  height: 40px;
272
+
273
+  .menu-item {
274
+    font-size: 16px;
275
+    color: #333;
276
+    font-weight: bold;
277
+    margin-right: 40px;
278
+    cursor: pointer;
279
+
280
+    &.menu-item-active {
281
+      color: #3173FF;
282
+      position: relative;
283
+
284
+      &::after {
285
+        content: "";
286
+        position: absolute;
287
+        left: 0;
288
+        bottom: -13px;
289
+        width: 100%;
290
+        height: 2px;
291
+        background-color: #3173FF;
292
+        z-index: 1;
293
+      }
294
+    }
295
+  }
296
+}
297
+.task-status {
298
+  .icon {
299
+    display: inline-block;
300
+    width: 7px;
301
+    height: 7px;
302
+    margin-right: 8px;
303
+    border-radius: 50%;
304
+  }
305
+
306
+  &.success {
307
+    .icon {
308
+      background-color: #28ba52;
309
+    }
310
+
311
+    color: #28ba52;
312
+  }
313
+
314
+  &.fail {
315
+    .icon {
316
+      background-color: #ec5f2e;
317
+    }
318
+
319
+    color: #ec5f2e;
320
+  }
321
+}
322
+.opt-link {
323
+  color: #197afb;
324
+  text-decoration: none;
325
+}</style>

+ 11 - 3
src/components/businessMoudle/adTask/index.vue

@@ -8,7 +8,7 @@
8 8
       :options="pageInfo.statusList" />
9 9
     <TimeScreen title="时间" selectWidth="260px" :haveQuick="false" :clearFlag="true" :valueIsKong="true" ref="timeRef"
10 10
       @init="() => init()"></TimeScreen>
11
-    <span class="pointer c-theme lMar10" @click="clearEvent">清空</span>
11
+    <span class="pointer c-theme lMar10" @click="()=>{clearEvent();init()}">清空</span>
12 12
   </div>
13 13
   <!-- 表格 -->
14 14
   <el-table v-loading="loading" ref="tableRef" :data="tableInfo.tableList" :header-cell-style="tableHeaderStyle"
@@ -47,7 +47,7 @@
47 47
             }} </span>
48 48
           </div>
49 49
           <div v-else-if="item.prop == 'operate'">
50
-            <span class="opt-link rMar10 pointer"> 详情 </span>
50
+            <span class="opt-link rMar10 pointer" @click="goDetail(scope.row.id)"> 详情 </span>
51 51
             <el-popconfirm title="确定要删除该任务?" @confirm="deleteTask(scope.row.id)">
52 52
               <template #reference>
53 53
                 <span class="opt-link pointer"> 删除 </span>
@@ -73,6 +73,8 @@
73 73
   </div>
74 74
   <!-- 修改任务名称 -->
75 75
   <EditTaskName ref="EditTaskNameRef" @confirm="EditTaskNameConfig"></EditTaskName>
76
+  <!-- 任务详情 -->
77
+  <Detail ref="DetailRef"></Detail>
76 78
 </template>
77 79
 <script setup lang="ts">
78 80
 import Input from '@/components/capsulationMoudle/_input.vue'
@@ -83,8 +85,10 @@ import { onBeforeMount } from 'vue'
83 85
 import { getTaskList, adTaskDel, adTaskEdit } from './ts/api'
84 86
 import { ElMessage } from 'element-plus'
85 87
 import EditTaskName from './dialog/editTaskName.vue'
88
+import Detail from './detail/index.vue'
86 89
 
87 90
 const {
91
+  DetailRef,
88 92
   EditTaskNameRef,
89 93
   InputRef_text,
90 94
   acRef,
@@ -117,7 +121,6 @@ const init = (page?: number) => {
117 121
   }
118 122
   getTaskList(paramsModel).then((res: any) => {
119 123
     loading.value = false
120
-    console.log(res)
121 124
     tableInfo.tableList = res.data;
122 125
     tableInfo.total = res.pageInfo.total;
123 126
     tableInfo.totalPages = res.pageInfo.totalPages;
@@ -130,6 +133,11 @@ const handleCurrentChange = (val) => {
130 133
   init(val)
131 134
 }
132 135
 
136
+/**详情 */
137
+const goDetail = (id) => {
138
+  DetailRef.value?.switchShow(true,id)
139
+}
140
+
133 141
 /**删除任务 */
134 142
 const deleteTask = (id) => {
135 143
   loading.value = true

+ 17 - 1
src/components/businessMoudle/adTask/ts/api.ts

@@ -62,7 +62,23 @@ interface IAdTaskEdit {
62 62
 }
63 63
 export function adTaskEdit(params: IAdTaskEdit) {
64 64
   return new Promise(async (resolve,reject)=>{
65
-    const res: any = await http.post('api/ad/adTaskEdit', params)
65
+    const res: any = await http.post('/api/ad/adTaskEdit', params)
66
+    if (res.errNo == 0) {
67
+      resolve(res.rst)
68
+    } else {
69
+      ElMessage.error(res.errMsg)
70
+      reject()
71
+    }
72
+  })
73
+}
74
+
75
+/**广告任务详情 */
76
+interface ITaskDetail {
77
+  task_id: string
78
+}
79
+export function taskDetail(params: ITaskDetail) {
80
+  return new Promise(async (resolve,reject)=>{
81
+    const res: any = await http.get('/api/ad/taskDetail', params)
66 82
     if (res.errNo == 0) {
67 83
       resolve(res.rst)
68 84
     } else {

+ 9 - 9
src/components/businessMoudle/adTask/ts/define.ts

@@ -9,6 +9,7 @@ const acRef = ref<{value:any}>()
9 9
 const statusRef = ref<{value:any}>()
10 10
 const timeRef = ref<{dateVal:any}>()
11 11
 const EditTaskNameRef = ref<{ switchShow: (val: Boolean, info?: any) => void }>()
12
+const DetailRef = ref<{ switchShow: (val: Boolean, info?: any) => void }>()
12 13
 const loading = ref(false)
13 14
 
14 15
 const tableInfo = reactive({
@@ -33,9 +34,9 @@ const tableInfo = reactive({
33 34
 const pageInfo = reactive({
34 35
   acList:[],
35 36
   statusList:[
36
-      {value:1,label:'所有未删除'},
37
-      {value:2,label:'启用'},
38
-      {value:3,label:'暂停'},
37
+      {value:0,label:'待提交'},
38
+      {value:1,label:'提交中'},
39
+      {value:2,label:'提交完成'},
39 40
   ],
40 41
   ad_statusList:[]
41 42
 })
@@ -62,16 +63,15 @@ const init_acList = async () => {
62 63
 }
63 64
 
64 65
 const clearEvent = () => {
65
-  nextTick(()=>{
66
-    InputRef_text.value!.value = ''
67
-    acRef.value!.value = []
68
-    statusRef.value!.value = ''
69
-    timeRef.value!.dateVal = ''
70
-  })
66
+  InputRef_text.value!.value = ''
67
+  acRef.value!.value = []
68
+  statusRef.value!.value = ''
69
+  timeRef.value!.dateVal = ''
71 70
 }
72 71
 
73 72
 export const exportDefine = () => {
74 73
   return {
74
+    DetailRef,
75 75
     EditTaskNameRef,
76 76
     InputRef_text,
77 77
     acRef,