فهرست منبع

落地页提交

xia 4 سال پیش
والد
کامیت
60e4ca3b2f

+ 31 - 5
src/api/index.ts

@@ -25,7 +25,7 @@ import {
   AccountPlanConfig,
   IGZHItem,
   IDomainItem,
-  IPBookItem
+  IPBookItem,
 } from "@/types/api";
 
 /**
@@ -49,7 +49,7 @@ export const getDeliveryBookList = (
   }> = { page: 1 }
 ): AxiosPromise<IList<IDeliveryBook>> => {
   return axios("/getUserDeliveryBooks", {
-    params: query
+    params: query,
   });
 };
 
@@ -496,7 +496,7 @@ export const onUpdateOfficialReportType = (
 ) => {
   return axios.post("/channel/switchReportModule", {
     channel_id,
-    report_module
+    report_module,
   });
 };
 
@@ -530,8 +530,24 @@ export const getLandingBooks = (
     params: {
       official_name,
       book_name,
-      page_size: 999
-    }
+      page_size: 999,
+    },
+  });
+};
+
+/**
+ * 获取封面列表
+ * @param type
+ * @param category
+ * @returns
+ */
+export const getLandingPic = (type?: any, category?: any, page?: any): any => {
+  return axios("/landingPage/documents", {
+    params: {
+      type,
+      category,
+      page,
+    },
   });
 };
 
@@ -550,3 +566,13 @@ export const onUpload = (
   formData.append("type", type);
   return axios.post("/landingPage/upload", formData);
 };
+
+/**
+ * 模板列表
+ * @param type
+ * @param category
+ * @returns
+ */
+export const getLandingTempalte = (): any => {
+  return axios("/landingPage/bodyTemplates");
+};

BIN
src/assets/checked.png


+ 3 - 1
src/plugins/install.ts

@@ -24,7 +24,8 @@ import {
   Affix,
   Descriptions,
   Steps,
-  Upload
+  Upload,
+  List
 } from "ant-design-vue";
 
 import VueClipboard3 from "./vue-clipboard";
@@ -65,6 +66,7 @@ const install = (app: App<Element>) => {
     .use(Descriptions)
     .use(Drawer)
     .use(Steps)
+    .use(List)
     .use(Upload);
 };
 

+ 1 - 1
src/views/put/landing/add.vue

@@ -35,7 +35,7 @@ const LandingAddPage = defineComponent({
   },
   setup() {
     const state = reactive({
-      stepCurrent: 0,
+      stepCurrent: 1,
       stepComponent: ["step-one", "step-two"],
       forms: ref<Record<string, any>>({})
     });

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

@@ -118,7 +118,7 @@ import { IDomainItem, IGZHItem, IPBookItem } from "@/types/api";
 const StepOne = defineComponent({
   name: "StepOne",
   components: {
-    ImageUpload
+    ImageUpload,
   },
   props: {},
   emits: ["next"],
@@ -143,43 +143,43 @@ const StepOne = defineComponent({
         jump_type: "copy_name",
         sub_img: "",
         gzh_img: "",
-        content: ""
-      }
+        content: "",
+      },
     });
 
     const formsRules = reactive({
       title: [{ required: true, trigger: "blur", message: "请输入落地页名称" }],
       gzh_name: [
-        { required: true, trigger: "change", message: "请选择公众号" }
+        { required: true, trigger: "change", message: "请选择公众号" },
       ],
       domain: [
         {
           required: true,
           trigger: "change",
-          message: "请选择域名"
-        }
+          message: "请选择域名",
+        },
       ],
       bid: [
         {
           required: true,
           type: "number",
           trigger: "change",
-          message: "请选择推广书籍"
-        }
+          message: "请选择推广书籍",
+        },
       ],
       link_source: [
         {
           required: true,
           trigger: "change",
-          message: "请选择渠道"
-        }
+          message: "请选择渠道",
+        },
       ],
       sub_img: [
         {
           required: true,
-          message: "请上传关注图片"
-        }
-      ]
+          message: "请上传关注图片",
+        },
+      ],
     });
 
     const { validate, validateInfos } = useForm(state.forms, formsRules);
@@ -189,11 +189,11 @@ const StepOne = defineComponent({
         const [
           { data: official },
           { data: domains },
-          { data: books }
+          { data: books },
         ] = await Promise.all([
           getLandingOfficials(),
           getLandingDomains(),
-          getLandingBooks()
+          getLandingBooks(),
         ]);
         state.officials = official.list;
         state.domains = domains.list;
@@ -247,9 +247,9 @@ const StepOne = defineComponent({
       onDomainChange,
       onUploadChange,
       onBack,
-      onNextStep
+      onNextStep,
     };
-  }
+  },
 });
 
 export default StepOne;

+ 248 - 9
src/views/put/landing/stepComp/step-two.vue

@@ -14,7 +14,11 @@
                   style="width:638px"
                 />
               </div>
-              <a href="javascript:;" class="delete-text" v-show="idx > 0" @click="deleteLine(idx)"
+              <a
+                href="javascript:;"
+                class="delete-text"
+                v-show="idx > 0"
+                @click="deleteLine(idx)"
                 >删除</a
               >
             </div>
@@ -35,13 +39,97 @@
           </div>
         </div>
       </div>
+      <div class="edit-form-item">
+        <p class="edit-label">顶部图片</p>
+        <div class="choose-img">
+          <div v-show="!selectImg" class="black-chos" @click="showModel">
+            选择
+          </div>
+          <div class="img" v-show="selectImg">
+            <img :src="chooseImgUrl" style="width:100%" @click="showModel" />
+          </div>
+        </div>
+      </div>
+      <div class="edit-form-item">
+        <p class="edit-label">正文模板</p>
+        <div class="template-list">
+          <div
+            v-for="(item, index) in templateList"
+            v-html="item.content"
+            :key="index"
+            :class="[
+              'template-item',
+              index == templateChecked ? 'current' : '',
+            ]"
+            @click="chooseTemplate(item, index)"
+          ></div>
+        </div>
+      </div>
     </div>
+    <a-modal
+      v-model:visible="modelShow"
+      title="顶部图片"
+      @ok="handleSumbit"
+      :width="1000"
+    >
+      <a-tabs v-model:activeKey="activeKey" @change="loadMore(1, true)">
+        <a-tab-pane key="10" tab="女频"></a-tab-pane>
+        <a-tab-pane key="11" tab="男频"></a-tab-pane>
+        <a-tab-pane key="12" tab="活动"></a-tab-pane>
+      </a-tabs>
+      <div class="radio-grouped">
+        <a-radio-group
+          v-model:value="chooseType"
+          style="margin: 0 auto"
+          @change="loadMore(1, true)"
+        >
+          <a-radio-button value="1">现代</a-radio-button>
+          <a-radio-button value="2">古代</a-radio-button>
+        </a-radio-group>
+      </div>
+      <a-list
+        class="loadmore-list"
+        :loading="listLoading"
+        item-layout="horizontal"
+        :grid="{ gutter: 10, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: 6 }"
+        :data-source="dataList"
+      >
+        <template #loadMore>
+          <div
+            :style="{
+              textAlign: 'center',
+              marginTop: '12px',
+              height: '32px',
+              lineHeight: '32px',
+            }"
+          >
+            <a-button
+              v-show="!listLoading && showLoaderMore"
+              @click="loadMore()"
+              >加载更多</a-button
+            >
+          </div>
+        </template>
+        <template #renderItem="{ item, index }">
+          <a-list-item>
+            <div :class="['img-item', index == temChecked ? 'current' : '']">
+              <a-popover title="预览" trigger="click">
+                <template #content>
+                  <img :src="item.link" />
+                </template>
+                <img :src="item.link" @click="chooseImg(item, index)" />
+              </a-popover>
+            </div>
+          </a-list-item>
+        </template>
+      </a-list>
+    </a-modal>
   </div>
 </template>
 
 <script lang="ts">
-import { defineComponent, reactive, ref, toRefs } from "vue";
-
+import { defineComponent, reactive, ref, toRefs, onMounted } from "vue";
+import { getLandingPic, getLandingTempalte } from "@/api";
 const StepTwo = defineComponent({
   name: "StepTwo",
   setup(props, { emit }) {
@@ -52,6 +140,20 @@ const StepTwo = defineComponent({
           content: "sadassssssssssssssssasdsaddasdas",
         },
       ]),
+      modelShow: false,
+      selectImg: false,
+      activeKey: "10",
+      chooseType: "1",
+      currentPage: 1,
+      listLoading: false,
+      showLoaderMore: true,
+      dataList: [],
+      chooseImgUrl: "",
+      temItem: ref<any>({}),
+      temChecked: ref<any>(null),
+      templateItemChecked: ref<any>({}),
+      templateChecked: ref<any>(null),
+      templateList: ref<any[]>([]),
     });
     const addNewCharpt = () => {
       let data = {
@@ -60,13 +162,65 @@ const StepTwo = defineComponent({
       };
       state.charptList.push(data);
     };
-    const deleteLine = (idx:number) =>{
-      state.charptList.splice(idx,1)
-    }
+    const deleteLine = (idx: number) => {
+      state.charptList.splice(idx, 1);
+    };
+    //弹窗
+    const showModel = () => {
+      state.modelShow = true;
+      loadMore();
+    };
+    //选择图片
+    const chooseImg = (item: any, idx: number) => {
+      state.temItem = item;
+      state.temChecked = idx;
+    };
+    onMounted(() => {
+      getTemList();
+    });
+    //模板列表
+    const getTemList = () => {
+      getLandingTempalte().then((res: any) => {
+        state.templateList = res.data.list;
+      });
+    };
+    //选择正文模板
+    const chooseTemplate = (item: any, index: number) => {
+      state.templateItemChecked = item;
+      state.templateChecked = index;
+    };
+    //加载更多
+    const loadMore = (page?: number, clear?: boolean) => {
+      if (clear) {
+        state.temItem = {};
+        state.temChecked = null;
+        state.dataList = [];
+      }
+      getLandingPic(
+        state.activeKey,
+        state.chooseType,
+        page ?? state.currentPage
+      ).then((res: any) => {
+        state.dataList = state.dataList.concat(res.data.list);
+        state.currentPage = res.data.meta.current_page + 1;
+        if (res.data.meta.is_end) state.showLoaderMore = false;
+      });
+    };
+    //选择顶部图
+    const handleSumbit = () => {
+      state.chooseImgUrl = state.temItem.link;
+      state.selectImg = true;
+      state.modelShow = false;
+    };
     return {
       ...toRefs(state),
       addNewCharpt,
-      deleteLine
+      deleteLine,
+      handleSumbit,
+      showModel,
+      loadMore,
+      chooseImg,
+      chooseTemplate,
     };
   },
 });
@@ -74,13 +228,88 @@ const StepTwo = defineComponent({
 export default StepTwo;
 </script>
 <style lang="scss" scoped>
+.loadmore-list {
+  margin-top: 30px;
+  .img-item {
+    width: 144px;
+    height: 144px;
+    background: #ffffff;
+    border-radius: 6px;
+    overflow: hidden;
+    position: relative;
+    image {
+      width: 144px;
+    }
+    &.current {
+      border: 2px solid #006eff;
+      &::after {
+        position: absolute;
+        width: 0;
+        height: 0;
+        border-top: 20px solid #006eff;
+        border-left: 20px solid transparent;
+        display: block;
+        content: "";
+        top: 0;
+        right: 0;
+      }
+    }
+  }
+}
+.template-list {
+  width: 726px;
+  height: 366px;
+  background: #f7f7f7;
+  max-height: 366px;
+  overflow-y: scroll;
+  position: relative;
+  padding: 24px 110px;
+  .template-item {
+    margin: 25px 0;
+    background: #fff;
+    position: relative;
+    &.current {
+      border-radius: 6px;
+      border: 2px solid #006eff;
+      &::after {
+        display: block;
+        content: "";
+        position: absolute;
+        right: 8px;
+        top: 8px;
+        width: 20px;
+        height: 20px;
+        z-index: 10;
+        background-image: url('../../../../assets/checked.png');
+        background-repeat: no-repeat;
+        background-size: cover;
+      }
+    }    
+  }
+}
+.choose-img {
+  .img {
+    width: 144px;
+    height: 144px;
+    overflow: hidden;
+    line-height: 144px;
+    image {
+      display: inline-block;
+      vertical-align: middle;
+      line-height: initial;
+    }
+  }
+}
+.radio-grouped {
+  text-align: center;
+}
 .edit-form {
   .add-item {
     width: 270px;
     height: 40px;
     line-height: 35px;
     color: #006eff;
-    font-size: 16px;
+    font-size: 14px;
     text-align: center;
     background: #ffffff;
     border-radius: 3px;
@@ -88,9 +317,18 @@ export default StepTwo;
     margin: 15px auto 0;
   }
   .edit-form-item {
-    font-size: 16px;
+    font-size: 14px;
     display: flex;
     align-items: center;
+    margin-bottom: 40px;
+    .black-chos {
+      background-color: #f7f7f7;
+      width: 100px;
+      height: 100px;
+      text-align: center;
+      line-height: 100px;
+      color: #d8d8d8;
+    }
     hr {
       margin-bottom: 25px;
       border: none;
@@ -99,6 +337,7 @@ export default StepTwo;
     }
     .edit-label {
       margin-right: 15px;
+      width: 100px;
     }
     .form-content {
       padding: 30px 50px;

+ 20 - 14
vue.config.js

@@ -1,5 +1,8 @@
 const prodConfig = require("./prod.config");
-
+const path = require("path");
+function resolve(dir) {
+  return path.join(__dirname, dir);
+}
 module.exports = {
   publicPath: process.env.VUE_APP_PUB_URL,
   assetsDir: prodConfig.assetsDir,
@@ -9,27 +12,27 @@ module.exports = {
     proxy: {
       "/api": {
         target: process.env.MAIN_API_URL,
-        changeOrigin: true
-      }
+        changeOrigin: true,
+      },
     },
-    disableHostCheck: true
+    disableHostCheck: true,
   },
   css: {
     sourceMap: false,
     loaderOptions: {
       scss: {
-        prependData: `@import "~@/scss/variables.scss";`
+        prependData: `@import "~@/scss/variables.scss";`,
       },
       less: {
         lessOptions: {
           modifyVars: {
             "primary-color": "#39a4ff",
-            "link-color": "#39a4ff"
+            "link-color": "#39a4ff",
           },
-          javascriptEnabled: true
-        }
-      }
-    }
+          javascriptEnabled: true,
+        },
+      },
+    },
   },
   configureWebpack: {
     devtool: "source-map",
@@ -37,14 +40,17 @@ module.exports = {
     optimization: prodConfig.optimization,
     plugins: prodConfig.plugins,
     resolve: {
-      extensions: [".js", ".vue", ".json", ".ts"]
+      extensions: [".js", ".vue", ".json", ".ts"],
     },
     performance: {
-      hints: false
-    }
+      hints: false,
+    },
   },
   chainWebpack: (config) => {
     // * 移除prefetch和preload
+    config.resolve.alias
+      .set("@", resolve("src"))
+      .set("assets", resolve("src/assets"));
     config.plugins.delete("prefetch");
     config.plugins.delete("preload");
     if (process.env.NODE_ENV === "production") {
@@ -59,5 +65,5 @@ module.exports = {
         return args;
       });
     }
-  }
+  },
 };