Bläddra i källkod

落地页添加

晓晓晓晓丶vv 4 år sedan
förälder
incheckning
cb4551655b

+ 39 - 1
src/api/index.ts

@@ -22,7 +22,10 @@ import {
   AdGroupData,
   AdgroupList,
   IUserAdmin,
-  AccountPlanConfig
+  AccountPlanConfig,
+  IGZHItem,
+  IDomainItem,
+  IPBookItem
 } from "@/types/api";
 
 /**
@@ -496,3 +499,38 @@ export const onUpdateOfficialReportType = (
     report_module
   });
 };
+
+/**
+ * 获取落地页公众号列表
+ * @returns
+ */
+export const getLandingOfficials = (): AxiosPromise<IList<IGZHItem>> => {
+  return axios("/landingPage/getGzh");
+};
+
+/**
+ * 获取落地页域名列表
+ * @returns
+ */
+export const getLandingDomains = (): AxiosPromise<IDomainItem[]> => {
+  return axios("/landingPage/domain");
+};
+
+/**
+ * 获取落地页推广书籍列表
+ * @param official_name
+ * @param book_name
+ * @returns
+ */
+export const getLandingBooks = (
+  official_name?: string,
+  book_name?: string
+): AxiosPromise<IList<IPBookItem>> => {
+  return axios("/landingPage/books", {
+    params: {
+      official_name,
+      book_name,
+      page_size: 999
+    }
+  });
+};

+ 4 - 2
src/plugins/install.ts

@@ -22,7 +22,8 @@ import {
   Tooltip,
   InputNumber,
   Affix,
-  Descriptions
+  Descriptions,
+  Steps
 } from "ant-design-vue";
 
 import VueClipboard3 from "./vue-clipboard";
@@ -61,7 +62,8 @@ const install = (app: App<Element>) => {
     .use(Switch)
     .use(Modal)
     .use(Descriptions)
-    .use(Drawer);
+    .use(Drawer)
+    .use(Steps);
 };
 
 export default install;

+ 16 - 0
src/types/api.d.ts

@@ -408,3 +408,19 @@ interface AccountPlanConfig {
   channel_id: number | string;
   report_module: string;
 }
+
+interface IGZHItem {
+  gzh_name: string;
+  gzh_code: string;
+  channel_id: number;
+}
+
+interface IDomainItem {
+  domain: string;
+  company_name: string;
+}
+
+interface IPBookItem {
+  bid: string | number;
+  book_name: string;
+}

+ 78 - 2
src/views/put/landing/add.vue

@@ -1,3 +1,79 @@
 <template>
-  <div>落地页添加</div>
-</template>
+  <div class="landing-add">
+    <div class="landing-container">
+      <div class="step-container">
+        <a-steps :current="stepCurrent">
+          <a-step title="填写基本信息" />
+          <a-step title="编辑内容" />
+        </a-steps>
+      </div>
+      <div class="step-content-container">
+        <component :is="stepComponent[stepCurrent]" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, reactive, toRefs, createVNode } from "vue";
+import { onBeforeRouteLeave } from "vue-router";
+import { Modal } from "ant-design-vue";
+import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
+
+import StepOne from "./stepComp/step-one.vue";
+import StepTwo from "./stepComp/step-two.vue";
+
+const LandingAddPage = defineComponent({
+  name: "LandingAddPage",
+  components: {
+    StepOne,
+    StepTwo
+  },
+  setup() {
+    const state = reactive({
+      stepCurrent: 0,
+      stepComponent: ["step-one", "step-two"]
+    });
+
+    onBeforeRouteLeave((_, __, next) => {
+      Modal.confirm({
+        title: "确认离开当前页面吗?",
+        content: "未保存的内容将会丢失",
+        icon: createVNode(ExclamationCircleOutlined),
+        onOk: () => {
+          next();
+        }
+      });
+    });
+
+    return {
+      ...toRefs(state)
+    };
+  }
+});
+
+export default LandingAddPage;
+</script>
+
+<style lang="scss">
+.landing-add {
+  padding: 22px;
+  min-height: 100%;
+
+  .landing-container {
+    height: inherit;
+    background: #fff;
+    box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.08);
+    padding: 16px;
+  }
+
+  .step-container {
+    padding: 20px 60px 36px;
+    border-bottom: 1px solid #e5e5e5;
+  }
+
+  .step-content-container {
+    padding: 20px 42px;
+  }
+}
+</style>

+ 158 - 0
src/views/put/landing/stepComp/step-one.vue

@@ -0,0 +1,158 @@
+<template>
+  <div class="step-one-container">
+    <a-form
+      :label-col="{ span: 2 }"
+      :wrapper-col="{ offset: 1, span: 12 }"
+      :colon="false"
+    >
+      <a-form-item label="落地页名称">
+        <a-input placeholder="请输入落地页名称" v-model:value="forms.title" />
+      </a-form-item>
+      <a-form-item label="公众号">
+        <a-select
+          placeholder="请选择公众号"
+          v-model:value="forms.gzh_name"
+          @change="onGzhChange"
+        >
+          <template v-for="official in officials" :key="official.gzh_name">
+            <a-select-option :value="official.gzh_name">
+              {{ official.gzh_name }}
+            </a-select-option>
+          </template>
+        </a-select>
+      </a-form-item>
+      <a-form-item label="微信号">
+        <a-input placeholder="请输入微信号" disabled :value="forms.gzh_code" />
+      </a-form-item>
+      <a-form-item label="域名">
+        <a-select
+          placeholder="请选择域名"
+          v-model:value="forms.domain"
+          @change="onDomainChange"
+        >
+          <template v-for="domain in domains" :key="domain.domain">
+            <a-select-option :value="domain.domain">
+              {{ domain.domain }}
+            </a-select-option>
+          </template>
+        </a-select>
+      </a-form-item>
+      <a-form-item label="推广书籍">
+        <a-select placeholder="请选择需要推广的书籍" v-model:value="forms.bid">
+          <template v-for="book in books" :key="book.bid">
+            <a-select-option :value="book.bid">
+              {{ book.book_name }}
+            </a-select-option>
+          </template>
+        </a-select>
+      </a-form-item>
+      <a-form-item label="公司主体">
+        <a-input
+          placeholder="请输入公司主体"
+          disabled
+          :value="forms.company_name"
+        />
+        <!-- <a-select placeholder="请选择公司主体">
+          <a-select-option value="1">1</a-select-option>
+          <a-select-option value="2">2</a-select-option>
+        </a-select> -->
+      </a-form-item>
+      <a-form-item label="渠道">
+        <a-select placeholder="请选择渠道">
+          <a-select-option value="1">1</a-select-option>
+          <a-select-option value="2">2</a-select-option>
+        </a-select>
+      </a-form-item>
+      <a-form-item label="公众号后缀">
+        <a-radio-group v-model:value="forms.gzh_suffix_mode">
+          <a-radio :value="0">无后缀</a-radio>
+          <a-radio :value="3">官方后缀(推荐)</a-radio>
+        </a-radio-group>
+      </a-form-item>
+      <a-form-item label="跳转类型">
+        <a-radio-group v-model:value="forms.jump_type">
+          <a-radio value="copy_name">文本粘贴</a-radio>
+          <a-radio value="xcx">小程序</a-radio>
+        </a-radio-group>
+      </a-form-item>
+      <a-form-item label="关注图片"></a-form-item>
+      <a-form-item label="公众号头像"></a-form-item>
+      <a-form-item label="简介">
+        <a-textarea v-model="forms.name"></a-textarea>
+      </a-form-item>
+    </a-form>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, reactive, ref, toRefs } from "vue";
+
+import { getLandingBooks, getLandingDomains, getLandingOfficials } from "@/api";
+import { IDomainItem, IGZHItem, IPBookItem } from "@/types/api";
+
+const StepOne = defineComponent({
+  name: "StepOne",
+  props: {},
+  emits: [],
+  setup(props, { emit }) {
+    const state = reactive({
+      officials: ref<IGZHItem[]>([]),
+      domains: ref<IDomainItem[]>([]),
+      books: ref<IPBookItem[]>([]),
+      forms: {
+        title: "",
+        name: "",
+        gzh_code: "",
+        gzh_name: "",
+        bid: "",
+        channel_id: "",
+        domain: "",
+        company_name: "",
+        link_source: "",
+        gzh_suffix_mode: 0,
+        gzh_suffix: "",
+        jump_type: "copy_name",
+        sub_img: "",
+        gzh_img: "",
+        content: ""
+      }
+    });
+
+    const initConfigData = async () => {
+      try {
+        const [
+          { data: official },
+          { data: domains },
+          { data: books }
+        ] = await Promise.all([
+          getLandingOfficials(),
+          getLandingDomains(),
+          getLandingBooks()
+        ]);
+        state.officials = official.list;
+        state.domains = domains;
+        state.books = books.list;
+      } catch (error) {
+        console.log("error happened in initLandingConfig:", error.message);
+      }
+    };
+
+    initConfigData();
+
+    const onGzhChange = (name: string) => {
+      const target = state.officials.find((gzh) => gzh.gzh_name === name);
+      state.forms.channel_id = target!.channel_id.toString() ?? "";
+      state.forms.gzh_code = target!.gzh_code ?? "";
+    };
+
+    const onDomainChange = (domain: string) => {
+      const target = state.domains.find((item) => item.domain === domain);
+      state.forms.company_name = target!.company_name ?? "";
+    };
+
+    return { ...toRefs(state), onGzhChange, onDomainChange };
+  }
+});
+
+export default StepOne;
+</script>

+ 13 - 0
src/views/put/landing/stepComp/step-two.vue

@@ -0,0 +1,13 @@
+<template>
+  <div>步骤二</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+
+const StepTwo = defineComponent({
+  name: "StepTwo"
+});
+
+export default StepTwo;
+</script>