123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- <template>
- <div class="page-wrap page-wrap-account page-adplan">
- <tool-bar
- :text="['ad_id', 'advertiser_id', 'campaign_id']"
- :label="['计划名/ID', '账号名/ID', '广告组名称/ID']"
- :defaultVal="defaultToolvalue"
- v-model:loading="inSearching"
- @confirm="onSearch"
- >
- <div class="tool-bar-item" v-if="optionList.length > 0">
- <p class="label">计划状态</p>
- <a-select class="full-width" v-model:value="currentSelect">
- <a-select-option
- v-for="item in optionList"
- :value="item.name"
- :key="item.name"
- >{{ item.desc }}</a-select-option
- >
- </a-select>
- </div>
- </tool-bar>
- <div class="table-filter">
- <div class="item-right">
- <span class="label">数据类型</span>
- <a-select class="full-width" v-model:value="currentStats">
- <a-select-option
- v-for="item in statsList"
- :value="item.name"
- :key="item.name"
- >{{ item.desc }}</a-select-option
- >
- </a-select>
- </div>
- <div class="item-right">
- <span class="label">筛选条件:</span>
- <a-range-picker
- v-model:value="pickerFilter"
- @change="switchDate"
- :ranges="rangePick"
- format="YYYY/MM/DD"
- />
- </div>
- <a-button type="primary" @click="openBackDrawer">
- 回本数据
- </a-button>
- <a-button type="primary" @click="openCustomLine">
- 自定义列
- </a-button>
- </div>
- <a-table
- :columns="columns"
- :data-source="list"
- :pagination="tablePageOptions"
- :loading="loading.value"
- @change="handleTableChange"
- rowKey="id"
- bordered
- :scroll="{ x: 1800, y: 700 }"
- >
- <template #switch="{ text, record }">
- <a-switch
- v-model:checked="record.enable"
- @change="switchMethod(record)"
- />
- </template>
- <template #external_url="{ text, record }">
- <p @click="onGo(record)"><a>前往落地页链接</a></p>
- </template>
- <template #ad_name="{ text, record }">
- <p>账户名:{{ record.account_name }}</p>
- <p>广告名:{{ record.ad_name }}</p>
- <p>广告ID:{{ record.ad_id }}</p>
- </template>
- <template #dayt="{ text, record }">
- <a-popover title="回传配置" placement="left" trigger="click">
- <template #content>
- <div class="tab-list" style="width: 220px">
- <a-tabs size="small" @change="tabChangeBack">
- <a-tab-pane
- v-for="(d, i) in popForm"
- :key="i"
- :tab="d.desc"
- ></a-tab-pane>
- </a-tabs>
- </div>
- <div class="hover-content">
- <span class="label">回传条件</span
- ><a-select
- style="width: 150px"
- size="small"
- v-model:value="popForm[currentTbs].condition"
- >
- <a-select-option
- :value="item.name"
- v-for="item in popForm[currentTbs].report_conditions"
- >
- {{ item.desc }}
- </a-select-option>
- </a-select>
- </div>
- <div class="hover-content">
- <span class="label">回传开关</span>
- <a-switch
- v-model:checked="popForm[currentTbs].back_on"
- checked-children="开"
- un-checked-children="关"
- />
- </div>
- <div class="hover-content">
- <span class="label">回传比例</span
- ><a-input
- v-model:value="popForm[currentTbs].rate"
- size="small"
- style="width: 150px"
- type="number"
- placeholder="回传比例"
- >
- <template #suffix>
- <a-tooltip title="比例0-100">
- <info-circle-outlined style="color: rgba(0,0,0,.45)" />
- </a-tooltip>
- </template>
- </a-input>
- </div>
- <div class="hover-content">
- <span class="label">回传平台</span
- ><a-input
- v-model:value="popForm[currentTbs].back_platform"
- disabled
- size="small"
- style="width: 150px"
- />
- </div>
- <div
- class="hover-content"
- v-if="popForm[currentTbs].report_type == 'recharge'"
- >
- <span class="label">回传付费最低金额</span
- ><a-input
- v-model:value="popForm[currentTbs].price"
- size="small"
- style="width: 150px"
- type="number"
- placeholder="回传付费最低金额"
- />
- </div>
- <div class="hover-content">
- <span class="label">浮动回传比例</span
- ><a-input
- v-model:value="popForm[currentTbs].float_rate"
- size="small"
- style="width: 150px"
- type="number"
- placeholder="浮动回传比例"
- >
- <template #suffix>
- <a-tooltip title="浮动比例小于固定回传比例">
- <info-circle-outlined style="color: rgba(0,0,0,.45)" />
- </a-tooltip>
- </template>
- </a-input>
- </div>
- <div class="footer-slot">
- <a-popconfirm
- title="是否要修改回传配置?"
- ok-text="是"
- cancel-text="否"
- @confirm="confirmEdit"
- >
- <a-button
- type="primary"
- size="small"
- :disabled="!hasPopFormData"
- @click="editBackConfig"
- >
- 修改
- </a-button>
- </a-popconfirm>
- </div>
- </template>
- <p @click="getBackData(record)"><a>回传</a></p>
- </a-popover>
- <p @click="getregister(record)"><a>注册用户</a></p>
- <p @click="getmoreLineData(record)"><a>更多数据</a></p>
- </template>
- <template #cpa_bid="{ text, record }">
- <editable-cell
- :text="`${text}`"
- title="预算"
- @change="(val) => onCellChange(record, 'cpa_bid', val)"
- />
- </template>
- <template #budget="{ text, record }">
- <editable-cell
- :text="`${text}`"
- title="出价"
- @change="(val) => onCellChange(record, 'budget', val)"
- />
- </template>
- <template #opertate="{ text, record }">
- <p @click="openDrawer(record)"><a>操作日志</a></p>
- </template>
- </a-table>
- <a-drawer
- title="操作日志"
- placement="right"
- :closable="false"
- v-model:visible="visible"
- >
- <put-data :id="currentId"></put-data>
- </a-drawer>
- <a-drawer
- title="回本数据"
- placement="right"
- :closable="false"
- v-model:visible="visible1"
- >
- <put-count
- :ids="backData.ids"
- :begin_date="backData.begin_date"
- :end_date="backData.end_date"
- :field="backData.field"
- ></put-count>
- </a-drawer>
- <a-drawer
- title="补充数据"
- placement="right"
- :closable="false"
- v-model:visible="lineVisable"
- >
- <a-descriptions bordered title="扩展数据" size="small">
- <a-descriptions-item :label="item.title" v-for="item in innerClomuns">
- {{ temData[item.dataIndex] }}
- </a-descriptions-item>
- </a-descriptions>
- </a-drawer>
- <a-drawer
- title="注册用户"
- placement="right"
- :closable="false"
- v-model:visible="registerVisable"
- >
- <register-datad
- :ad_lid="register.ad_lid"
- :back_platform="register.back_platform"
- ></register-datad>
- </a-drawer>
- <!-- <a-modal v-model:visible="columnShow" title="自定义列" @ok="makeDine" :width="722">
- <custom-cloumn></custom-cloumn>
- </a-modal> -->
- </div>
- </template>
- <script lang="ts">
- import { defineComponent, reactive, toRefs, ref, unref, onMounted } from "vue";
- import moment from "moment";
- import ToolBar from "@/components/tool-bar/index.vue";
- import PutData from "@/views/put/put-log.vue";
- import CustomCloumn from "@/views/put/component/customClomu.vue";
- import useApp from "@/hooks/useApp";
- import PutCount from "@/views/put/put-ad-count.vue";
- import RegisterDatad from "@/views/put/register-data.vue";
- import EditableCell from "@/components/edit-cell/index.vue";
- import usePagination from "@/hooks/usePagination";
- import { picker } from "@/helper/config/range";
- import { InfoCircleOutlined } from "@ant-design/icons-vue";
- import {
- TableColumnOfPutAdPlan,
- ALLCloumnList,
- } from "../_pageOptions/table-put";
- import {
- getADPlanlist,
- getCustomColumn,
- adChangeMoney,
- adChangeCrem,
- statusChange,
- getAddStatus,
- getAdBackPlan,
- setBackConfig,
- getAdStatus,
- } from "@/api";
- import { ADPlanItem, PageOptions, PlanBack } from "@/types/api";
- const PutAdPlan = defineComponent({
- components: {
- ToolBar,
- EditableCell,
- PutData,
- PutCount,
- InfoCircleOutlined,
- RegisterDatad,
- CustomCloumn
- },
- setup() {
- let { loading, meta, tablePageOptions } = usePagination();
- const { router, route } = useApp();
- let list: any[] = [],
- opList: any[] = [],
- stList: any = [];
- const state = reactive({
- platform: "platform1",
- list: ref<ADPlanItem[]>([]),
- inSearching: false,
- loading,
- currentSelect: "AD_STATUS_DELIVERY_OK",
- picker: [],
- currentId: "",
- innerClomuns: ref<any[]>([]),
- lineVisable: false,
- defaultToolvalue: {},
- visible: false,
- popconfirmShow: false,
- showPop: false,
- visible1: false,
- registerVisable: false,
- columnShow:false,
- register: {
- ad_lid: 0,
- back_platform: "",
- },
- pickerFilter: [moment(), moment()],
- tablePageOptions,
- columns: list,
- temData: {},
- backData: {
- ids: "",
- begin_date: "",
- end_date: "",
- field: "",
- },
- currentTbs: 0,
- hasPopFormData: false,
- popForm: [
- {
- id: 0,
- back_on: false,
- rate: 0,
- condition: "",
- price: 0,
- float_rate: 0,
- },
- ],
- isInit: false,
- cost_order: 0,
- optionList: opList,
- statsList: stList,
- currentStats: "paid_order_amount",
- defaultColumns: TableColumnOfPutAdPlan,
- fields: {},
- rangePick: picker,
- });
- if (route.query && route.query.advertiser_id) {
- state.defaultToolvalue = {
- campaign_id: route.query.campaign_id,
- };
- state.fields = {
- campaign_id: route.query.campaign_id,
- };
- }
- getAddStatus().then((res) => {
- res.data.unshift({
- name: "",
- desc: "不限",
- });
- state.optionList = res.data;
- });
- const onSearch = async (fields: Record<string, string>) => {
- try {
- const { ad_id, campaign_id, status } = fields;
- state.fields = fields;
- const data = {
- ad_id,
- status: state.currentSelect,
- campaign_id,
- page: 1,
- };
- getData(data);
- } catch (e) {
- console.log(e);
- } finally {
- state.inSearching = false;
- }
- };
- const switchDate = (date: any, dateString: string) => {
- onSearch(state.fields);
- };
- const getData = (query?: any) => {
- const { pickerFilter } = state;
- let [begin_dates, end_dates] = pickerFilter;
- let begin_date = moment(begin_dates).format("YYYY-MM-DD");
- let end_date = moment(end_dates).format("YYYY-MM-DD");
- let data = Object.assign(
- {
- page: 1,
- status: "AD_STATUS_DELIVERY_OK",
- ...state.fields,
- },
- query || {},
- { begin_date, end_date, status: state.currentSelect },
- state.cost_order ? { cost_order: state.cost_order } : {}
- );
- getADPlanlist(data).then((res) => {
- let newList: any[] = res.data.list.map((item) => {
- item.enable = item.is_enable == 1 ? true : false;
- item.popShow = false;
- return item;
- });
- state.list = newList;
- meta.value = res.data.meta;
- state.inSearching = false;
- });
- };
- getAdStatus().then((res) => {
- state.statsList = res.data;
- });
- getCustomColumn().then((res) => {
- let columns: any[] = [];
- let blackList = [
- "email",
- "ad_name",
- "account_name",
- "ad_id",
- "delivery_platform",
- ];
- let extendList = [
- "campaign_name",
- "landing_type",
- "start_end_time",
- "pricing",
- "promotion_type",
- "delivery_range",
- "inventory_type",
- "convert_id",
- "external_actions",
- "ad_create_time",
- ];
- res.data.map((item: { desc: string; name: string }) => {
- let lolumnItem: {
- title: string;
- dataIndex: string;
- slots?: any;
- width?: string | number;
- sorter?: boolean;
- ellipsis?: boolean;
- } = {
- title: item.desc,
- dataIndex: item.name,
- width: 95,
- ellipsis: true,
- };
- if (item.name == "external_url") {
- lolumnItem.slots = { customRender: "external_url" };
- }
- if (item.name == "cpa_bid" || item.name == "budget") {
- lolumnItem.slots = { customRender: item.name };
- lolumnItem.width = 130;
- }
- if (item.name == "cost") {
- lolumnItem.sorter = true;
- }
- if (extendList.includes(item.name)) {
- state.innerClomuns.push(lolumnItem);
- }
- columns.push(lolumnItem);
- });
- let newColunms = columns.filter(
- (item) =>
- !blackList.includes(item.dataIndex) &&
- !extendList.includes(item.dataIndex)
- );
- state.columns = [];
- state.columns.push(...state.defaultColumns);
- state.columns.push(...newColunms);
- state.columns.push({
- title: "操作记录",
- dataIndex: "opertate",
- slots: { customRender: "opertate" },
- width: 100,
- });
- state.columns.push({
- title: "日志",
- dataIndex: "opertate",
- fixed: "right",
- slots: { customRender: "dayt" },
- width: 100,
- });
- });
- const setSateSwitch = (val: string, name: string) => {
- switch (val) {
- case "ascend":
- (state as any)[name] = 2;
- break;
- case "descend":
- (state as any)[name] = 1;
- break;
- default:
- (state as any)[name] = 0;
- }
- };
- const handleTableChange = (
- pagination: PageOptions,
- filters: any,
- sorter: any
- ) => {
- if (sorter.columnKey == "cost") {
- setSateSwitch(sorter.order, "cost_order");
- }
- const { current, pageSize, total } = pagination;
- getData({ page: current });
- };
- onMounted(() => {
- getData({
- campaign_id: route.query?.campaign_id ?? "",
- current: 1,
- });
- });
- return { ...toRefs(state), handleTableChange, onSearch, switchDate };
- },
- methods: {
- moment,
- onGo(record: any) {
- window.open(record.external_url);
- },
- getTest() {},
- openDrawer(record: any) {
- this.visible = true;
- this.currentId = record.ad_id;
- },
- handleVisibleChange(visibale: boolean) {
- if (!visibale) {
- this.popconfirmShow = false;
- return;
- }
- if (!this.hasPopFormData) {
- this.popconfirmShow = false;
- } else {
- this.popconfirmShow = true;
- }
- },
- getmoreLineData(record: any) {
- this.lineVisable = true;
- this.temData = record;
- },
- confirmEdit() {
- let { id, back_on, rate, condition, price, float_rate } = this.popForm[
- this.currentTbs
- ];
- if (float_rate && float_rate >= rate) {
- this.$message.error("浮动比例必须小于固定回传比例");
- return;
- }
- let data = {
- id,
- back_on: Number(back_on),
- rate,
- condition,
- price,
- float_rate,
- };
- setBackConfig(data).then((res) => {
- this.$message.success("修改成功!");
- });
- },
- getregister(record: any) {
- console.log(record);
- this.register.ad_lid = record.id;
- this.register.back_platform = record.delivery_platform;
- this.registerVisable = true;
- },
- onCellChange(record: any, dataIndex: string, value: string) {
- let ad_id = record.ad_id;
- if (dataIndex == "cpa_bid") {
- adChangeCrem({ ad_id, bid: Number(value) })
- .then((res) => {
- this.$message.success("修改成功!");
- })
- .catch((e) => {
- //location.reload();
- });
- }
- if (dataIndex == "budget") {
- adChangeMoney({ ad_id, budget: Number(value) })
- .then((res) => {
- this.$message.success("修改成功!");
- })
- .catch((e) => {
- //location.reload();
- });
- }
- },
- tabChangeBack(key: number) {
- this.currentTbs = key;
- },
- editBackConfig() {},
- switchMethod(record: any) {
- let ad_id = record.ad_id;
- statusChange({
- ad_id,
- status: record.enable ? "disable" : "enable",
- }).then((res) => {
- this.$message.success("修改广告状态成功!");
- });
- },
- openBackDrawer() {
- let ids = "";
- this.list.map((item: ADPlanItem) => {
- ids = ids + `,${item.id}`;
- });
- let [begin_dates, end_dates] = this.pickerFilter;
- let begin_date = moment(begin_dates).format("YYYY-MM-DD");
- let end_date = moment(end_dates).format("YYYY-MM-DD");
- this.backData.ids = ids.substring(1);
- this.backData.begin_date = begin_date;
- this.backData.end_date = end_date;
- this.backData.field = this.currentStats;
- this.visible1 = true;
- },
- getBackData(record: any) {
- getAdBackPlan({
- ad_lid: record.id,
- back_platform: record.delivery_platform,
- }).then((res) => {
- let list = res.data.map((r: PlanBack) => {
- r.price = r.extra?.price;
- r.float_rate = r.extra?.float_rate;
- r.back_on = !!Number(r.back_on);
- return r;
- });
- list.length > 0
- ? (this.hasPopFormData = true)
- : (this.hasPopFormData = false);
- this.popForm = list;
- });
- },
- },
- });
- export default PutAdPlan;
- </script>
- <style lang="scss">
- .table-filter {
- display: flex;
- justify-content: flex-end;
- padding: 5px 0 15px;
- align-items: center;
- }
- .ant-drawer-content-wrapper {
- width: 80vw !important;
- }
- .item-right {
- margin-right: 10px;
- display: flex;
- align-items: center;
- .ant-select {
- width: 100px;
- }
- .label {
- display: inline-block;
- min-width: 80px;
- }
- }
- .hover-content {
- margin: 8px 0 5px;
- display: flex;
- align-items: center;
- .label {
- padding-right: 15px;
- display: inline-block;
- max-width: 72px;
- width: 72px;
- }
- .ant-switch {
- width: 50px;
- }
- }
- .footer-slot {
- margin-top: 10px;
- button {
- margin-right: 10px;
- }
- }
- </style>
|