Просмотр исходного кода

Merge branch 'dev-cmn' of https://s-20coaj910c.zht2.com/cmy/data-marketing-platform into dev-ly

luoy 2 дней назад
Родитель
Сommit
d9cad7b049

+ 15 - 0
src/api/marketing/apps.ts

@@ -189,4 +189,19 @@ export const getPushPage = (data: Object) => {
 		method: 'post',
 		data,
 	});
+};
+
+/**
+ * 分页查询手动推送记录
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @param pageNum	页码
+ * @param pageSize	每页条数
+ */
+export const getHandPushPage = (data: Object) => {
+	return request({
+		url: '/marketing/handPush/page',
+		method: 'post',
+		data,
+	});
 };

+ 272 - 0
src/views/marketing/push-logs/index.vue

@@ -0,0 +1,272 @@
+<template>
+  <div class="layout-padding">
+    <div class="layout-padding-auto layout-padding-view">
+      <el-row shadow="hover" class="ml10">
+        <el-form :inline="true" :model="state.queryForm" @keyup.enter="query" ref="queryRef">
+          <!-- <el-form-item :label="'规则名称'" prop="ruleName">
+            <el-input :placeholder="'请输入规则名称'" v-model="state.queryForm.ruleName" />
+          </el-form-item>
+          <el-form-item :label="'触发信息'" prop="triggerCondition">
+            <el-input :placeholder="'请输入触发信息'" v-model="state.queryForm.triggerCondition" />
+          </el-form-item> -->
+          <el-form-item :label="'推送时间'" prop="createTime">
+            <el-date-picker :disabled-date="disabledDate" :end-placeholder="'结束日期'" :start-placeholder="'开始日期'"
+              format="YYYY-MM-DD" range-separator="至" type="daterange" v-model="state.queryForm.createTime" />
+          </el-form-item>
+          <el-form-item>
+            <el-button @click="query" class="ml10" icon="search" type="primary">
+              {{ t('common.queryBtn') }}
+            </el-button>
+            <el-button @click="resetQuery" icon="Refresh">{{ t('common.resetBtn') }}</el-button>
+          </el-form-item>
+        </el-form>
+      </el-row>
+
+      <el-table ref="tableRef" :data="state.dataList" row-key="id" style="width: 100%" v-loading="state.loading" border
+        :cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle?.headerCellStyle">
+        <!-- <el-table-column :formatter="statusFormatter" :label="'推送IP'" prop="pushIP" min-width="200"
+          show-overflow-tooltip></el-table-column>
+        <el-table-column :formatter="statusFormatter" :label="'推送域名'" prop="pushDomain" min-width="200"
+          show-overflow-tooltip></el-table-column> -->
+        <el-table-column :formatter="statusFormatter" :label="'推送内容'" prop="pushContent" min-width="200"
+          show-overflow-tooltip>
+          <template #default="{ row }">
+            <el-image v-if="row.pushType" :src="row.pushContent" style="width: 100px; height: 100px;" />
+            <div v-else>{{ row.pushContent }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column :formatter="statusFormatter" :label="'推送方式'" prop="pushType" min-width="200"
+          show-overflow-tooltip>
+          <template #default="{ row }">
+            {{pushMode.filter(item => item.value == row.pushAction)[0]?.label}}
+          </template>
+        </el-table-column>
+        <el-table-column :formatter="statusFormatter" :label="'推送频率'" prop="pushFrequency" min-width="120"
+          show-overflow-tooltip>
+          <template #default="{ row }">
+						{{ formatNum(row.pushFrequency) }}
+					</template>
+        </el-table-column>
+        <el-table-column :formatter="statusFormatter" :label="'推送时间'" prop="createTime" min-width="200"
+          show-overflow-tooltip></el-table-column>
+        <el-table-column :formatter="statusFormatter" :label="'延时推送'" prop="delayPush" min-width="100"
+          show-overflow-tooltip>
+					<template #default="{ row }">
+						{{ row.delayPush }}s
+					</template>
+        </el-table-column>
+        <el-table-column :formatter="statusFormatter" :label="'推送状态'" prop="pushStatus" min-width="120"
+          show-overflow-tooltip>
+          <template #default="{ row }">
+            {{ row.pushStatus ? '已推送' : '未推送' }}
+          </template>
+        </el-table-column>
+        <el-table-column :formatter="statusFormatter" :label="'推送详情'" prop="pushDetail" min-width="250">
+          <template #default="{ row }">
+            <div class="trigger-info" @click="showTriggerInfo(row)">
+              {{ row.pushDetail }}
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination @current-change="currentChangeHandle" @size-change="sizeChangeHandle" v-bind="state.pagination" />
+    </div>
+
+    <dataInfoModal ref="richContentDialogRef"></dataInfoModal>
+  </div>
+</template>
+
+<script lang="ts" name="marketingApps" setup>
+import { getHandPushPage } from '/@/api/marketing/apps';
+import { BasicTableProps, useTable } from '/@/hooks/table';
+import { useI18n } from 'vue-i18n';
+import { ref, reactive, onMounted, defineAsyncComponent } from 'vue'
+const dataInfoModal = defineAsyncComponent(() => import('/@/views/marketing/data/dataInfoModal.vue'));
+import { ElImage } from 'element-plus';
+import { fetchItemList } from '/@/api/admin/dict';
+import { formatDate } from '/@/utils/formatTime';
+
+const { t } = useI18n();
+
+const getDataListWithProcess = (params: any): Promise<any> => {
+  return new Promise((resolve, reject) => {
+    console.log(params, 'params');
+    const data = {
+        ...params,
+        pageNum: params.current,
+        pageSize: params.size,
+        endTime: params.createTime ? formatDate(params.createTime[0], 'YYYY-mm-dd') : '',
+        createTime: params.createTime ? formatDate(params.createTime[1], 'YYYY-mm-dd') : '',
+    }
+    delete data.current;
+    delete data.size;
+    delete data.ascs;
+    delete data.descs;
+
+    getHandPushPage(data).then((res: any) => {
+      console.log(res, 'res');
+      try {
+        if (res.data && res.data.records && res.data.records.length > 0) {
+          res.data.records = res.data.records.map((item: any) => {
+            let parsedData: any = null;
+            try {
+              if (item.triggerCondition) {
+                parsedData = JSON.parse(item.triggerCondition);
+              }
+            } catch (error) {
+              console.warn('解析触发器条件失败:', item.triggerCondition, error);
+            }
+
+            return {
+              ...item,
+              _keywords: parsedData?.keywords || [],
+              _ip: parsedData?.ip || '',
+              _domain: parsedData?.domain || ''
+            };
+          });
+        }
+        resolve(res);
+      } catch (error: any) {
+        console.error('数据处理失败:', error);
+        reject(error);
+      }
+    }).catch((error: any) => {
+      reject(error);
+    });
+  });
+};
+
+// 定义变量内容
+const tableRef = ref();
+const queryRef = ref();
+const state: BasicTableProps = reactive<BasicTableProps>({
+  pageList: getDataListWithProcess,
+  createdIsNeed: false,
+  queryForm: {
+    ruleName: '',
+    triggerCondition: '',
+  },
+  pagination: {
+    current: 1,
+    size: 10,
+    total: 0,
+    pageSizes: [5, 10, 20, 50, 100]
+  },
+});
+const pushMode = ref<any>([]);
+const disabledDate = (time: Date) => {
+  return time.getTime() > Date.now();
+}
+
+interface SourceData {
+  ruleName: string;
+  triggerCondition: string;
+  triggerTime: string;
+  pushStatus: string;
+  pushContent: string;
+  pushFrequency: string;
+  pushTime: string;
+}
+
+const richContentDialogRef = ref();
+const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
+
+// 搜索事件
+const query = (refresh: boolean = false) => {
+  state.dataList = [];
+  getDataList(refresh);
+};
+
+// 清空搜索条件
+const resetQuery = () => {
+  queryRef.value.resetFields();
+  state.dataList = [];
+  getDataList();
+};
+
+const statusFormatter = (row: any, column: any, cellValue: any, index: any) => {
+  return cellValue || '--';
+}
+
+const showTriggerInfo = (row: any) => {
+  // 信息详情弹窗
+  richContentDialogRef.value.openDialog(
+    row.pushDetail,
+    {
+      createTime: row.createTime,
+      triggerKeyword: row._keywords
+    }
+  )
+}
+
+const getFetchItemList = async () => {
+  const res = await fetchItemList({
+    dictType: 'pushMode',
+  });
+
+  pushMode.value = res.data.records.map((item: any) => ({
+    label: item.description,
+    value: item.value
+  }));
+  console.log(pushMode, 'pushMode');
+}
+
+// 格式化数据展示
+const formatNum = (value: string | number = 0) => {
+	let num = Number(value);
+	if (num > 0 && num < 1) {
+		return (num * 100).toFixed(0) + '%';
+	} else if (num >= 1 && num < 10000) {
+		return '每'+num+'次推送';
+	}
+	return '--';
+};
+
+onMounted(() => {
+  getFetchItemList();
+  query();
+});
+
+</script>
+<style scoped lang="scss">
+:deep(.el-link__inner) {
+  display: inline-block;
+  width: 100%;
+  justify-content: start;
+}
+
+:deep(.el-link.is-underline:hover:after) {
+  display: none;
+}
+
+.table-tabs {
+  margin-bottom: 10px;
+}
+
+.trigger-info {
+  overflow: hidden;
+  text-align: center;
+  width: 100%;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+  color: #409eff;
+  cursor: pointer;
+}
+
+.header-wrapper {
+  display: inline-flex;
+  align-items: center;
+}
+
+.header-icon {
+  margin-left: 5px;
+  color: #999;
+  font-size: 14px;
+  cursor: help;
+
+  &:hover {
+    color: #409eff;
+  }
+}
+</style>

+ 14 - 5
src/views/marketing/record/index.vue

@@ -30,13 +30,13 @@
             <div v-else>{{ row.pushContent }}</div>
           </template>
         </el-table-column>
-        <el-table-column :formatter="statusFormatter" :label="'推送方式'" prop="pushType" min-width="100"
+        <el-table-column :formatter="statusFormatter" :label="'推送方式'" prop="pushType" min-width="150"
           show-overflow-tooltip>
           <template #default="{ row }">
               {{ pushMode.filter(item => item.value == row.pushAction)[0]?.label }}
           </template>
         </el-table-column>
-        <el-table-column :formatter="statusFormatter" :label="'推送频率'" prop="pushFrequency" min-width="120"
+        <el-table-column :formatter="statusFormatter" :label="'推送频率'" prop="pushFrequency" min-width="100"
           show-overflow-tooltip>
         </el-table-column>
         <el-table-column :formatter="statusFormatter" :label="'推送时间'" prop="createTime" min-width="200"
@@ -58,8 +58,7 @@
             </div>
           </template>
         </el-table-column>
-        <el-table-column :formatter="statusFormatter" :label="'触发记录'" prop="pushDetail" min-width="250"
-          show-overflow-tooltip>
+        <el-table-column :formatter="statusFormatter" :label="'触发记录'" prop="pushDetail" min-width="250">
           <template #default="{ row }">
             <div class="trigger-info" @click="showTriggerInfo(row)">
               {{ row.pushDetail }}
@@ -87,8 +86,18 @@ import { fetchItemList } from '/@/api/admin/dict';
 const { t } = useI18n();
 
 const getDataListWithProcess = (params: any): Promise<any> => {
+  const data = {
+    ...params,
+    pageNum: params.current,
+    pageSize: params.size,
+  }
+
+  delete data.current;
+  delete data.size;
+  delete data.ascs;
+  delete data.descs;
   return new Promise((resolve, reject) => {
-    getPushPage(params).then((res: any) => {
+    getPushPage(data).then((res: any) => {
       console.log(res, 'res');
       try {
         if (res.data && res.data.records && res.data.records.length > 0) {