瀏覽代碼

Merge branch 'master' of qk:zhuishuyun/precise_delivery_distribution_front

gdy96 4 年之前
父節點
當前提交
f3d052857a

+ 10 - 0
prod.config.js

@@ -9,6 +9,7 @@ const externals = isProd
       vuex: "Vuex",
       "vue-router": "VueRouter",
       axios: "axios",
+      clipboard: "Clipboard",
     }
   : {};
 
@@ -40,6 +41,14 @@ const optimization = {
         chunks: "all",
         reuseExistingChunk: true,
       },
+      antDesignVue: {
+        name: "chunk-antdv",
+        test: /[\\/]node_modules[\\/]ant-design-vue[\\/]/,
+        chunks: "initial",
+        priority: 120,
+        reuseExistingChunk: true,
+        enforce: true,
+      },
       styles: {
         name: "styles",
         test: /\.(sa|sc|c)ss$/,
@@ -74,6 +83,7 @@ const cdns = {
       `${ossCDN}/library/vuex.next.min.js`,
       `${ossCDN}/library/vue-router.next.min.js`,
       `${ossCDN}/library/axios.min.js`,
+      `${ossCDN}/library/clipboard.min.js`,
     ],
   },
 };

+ 18 - 0
src/api/index.ts

@@ -145,3 +145,21 @@ export const addDeliveryBook = (data: {
 export const logout = () => {
   return axios("/logout");
 };
+
+/**
+ * 停止投放书籍
+ * @param id 记录id
+ */
+export const onStopDeliveryBook = (id: number) => {
+  return axios("/stopDeliveryBook", { params: { id } });
+};
+
+
+
+/**
+ * 自定义列
+ * @param null
+ */
+export const getCustomColumn = () => {
+  return axios("/ad/adFields");
+};

+ 5 - 0
src/components/confirm-button/index.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="confirm-button">
     <a-button :type="type"
+              :disabled="disabled"
               @click.stop="onConfirm">{{label}}</a-button>
   </div>
 </template>
@@ -18,6 +19,10 @@ const ConfirmButton = defineComponent({
       type: String,
       default: "primary",
     },
+    disabled: {
+      type: Boolean,
+      default: false,
+    },
     confirmTitle: {
       type: String,
       default: "请确认您的操作",

+ 20 - 0
src/hooks/useReset.ts

@@ -0,0 +1,20 @@
+const fieldType = {
+  "[object Object]": {},
+  "[object Array]": [],
+  "[object Number]": "",
+  "[object String]": "",
+  "[object Boolean]": false,
+};
+
+const useReset = <T extends Record<string, any>>(fields: T): T => {
+  const typeString = Object.prototype.toString;
+
+  Object.keys(fields).forEach((field) => {
+    const type = typeString.call(fields[field] as T[keyof T]);
+    (fields[field] as T[keyof T]) = (<Record<string, any>>fieldType)[type];
+  });
+
+  return fields as T;
+};
+
+export default useReset;

+ 2 - 0
src/plugins/vue-qrcode.ts

@@ -20,6 +20,7 @@ const bind = async (
 ) => {
   console.log("mounted:", binding);
   const qrText = binding.value;
+  if (!qrText) return;
   if (typeof qrText === "string") {
     const code = await QRCode.toDataURL(qrText);
     insertQrCode2Element(el, code);
@@ -30,6 +31,7 @@ const update = async (el: HTMLElement | Element, binding: DirectiveBinding) => {
   if (binding.oldValue === binding.value) return;
   console.log("update:", binding);
   const qrText = binding.value;
+  if (!qrText) return;
   if (typeof qrText === "string") {
     const code = await QRCode.toDataURL(qrText);
     insertQrCode2Element(el, code);

+ 8 - 4
src/views/_pageOptions/table-put.ts

@@ -1,5 +1,9 @@
 export const TableColumnOfPutBooks = [
   {
+    title: "ID",
+    dataIndex: "id",
+  },
+  {
     title: "公众号名称",
     dataIndex: "official_name",
   },
@@ -142,8 +146,8 @@ export const TableColumnOfPutAdPlan = [
   },
   {
     fixed: "left",
-    title: "账户ID",
-    dataIndex: "account_id",
+    title: "账户",
+    dataIndex: "account_name",
     width: 120,
   },
   {
@@ -154,8 +158,8 @@ export const TableColumnOfPutAdPlan = [
   },
   {
     fixed: "left",
-    title: "用户名",
-    dataIndex: "user_name",
+    title: "广告名",
+    dataIndex: "ad_name",
     width: 150,
   },
 ];

+ 2 - 2
src/views/account/account.vue

@@ -70,9 +70,9 @@ const Account = defineComponent({
       onLoadOfficials();
     };
 
-    const onLoadOfficials = (query?: { page: number }) => {
+    const onLoadOfficials = (query?: { current: number }) => {
       let params = state.query;
-      if (query) params.page = query.page;
+      if (query) params.page = query.current;
       loading.value = true;
       getOfficialAccounts(params).then(({ data }) => {
         state.list = data.list;

+ 27 - 25
src/views/put/put-ad-plan.vue

@@ -1,7 +1,9 @@
 <template>
   <div class="page-wrap page-wrap-account">
-    <tool-bar :text="['account_name', 'email', 'ad_name', 'campaign_name']"
-              :label="['账户名', '邮箱', '计划名称', '广告组名称']">
+    <tool-bar
+      :text="['account_name', 'email', 'ad_name', 'campaign_name']"
+      :label="['账户名', '邮箱', '计划名称', '广告组名称']"
+    >
       <template #picker>
         <p class="label">日期</p>
         <a-range-picker />
@@ -13,21 +15,15 @@
         </a-select>
       </div> -->
     </tool-bar>
-    <a-table :columns="columns"
-             :data-source="list"
-             :pagination="tablePageOptions"
-             :loading="loading.value"
-             @change="handleTableChange"
-             rowKey="id"
-             :scroll="{ x: 2500 }"></a-table>
-
-    <a-modal title="Title"
-             :visible="visible"
-             :confirm-loading="confirmLoading"
-             @ok="handleOk"
-             @cancel="handleCancel">
-      <p>{{ ModalText }}</p>
-    </a-modal>
+    <a-table
+      :columns="columns"
+      :data-source="list"
+      :pagination="tablePageOptions"
+      :loading="loading.value"
+      @change="handleTableChange"
+      rowKey="id"
+      :scroll="{ x: 2500 }"
+    ></a-table>
   </div>
 </template>
 
@@ -41,7 +37,7 @@ import {
   ALLCloumnList,
 } from "../_pageOptions/table-put";
 
-import { getADPlanlist } from "@/api";
+import { getADPlanlist, getCustomColumn } from "@/api";
 
 import { ADPlanItem, PageOptions } from "@/types/api";
 
@@ -56,12 +52,10 @@ const PutAdPlan = defineComponent({
       list: ref<ADPlanItem[]>([]),
       inSearching: false,
       loading,
-      visible: false,
-      confirmLoading: false,
       tablePageOptions,
       columns: TableColumnOfPutAdPlan,
     });
-    state.columns.push(...(ALLCloumnList as any[]));
+
     const onSearch = async (fields: Record<string, string>) => {
       try {
         const {
@@ -96,9 +90,17 @@ const PutAdPlan = defineComponent({
       state.list = res.data.list;
     });
 
-    const handleOk = () => {};
-
-    const handleCancel = () => {};
+    getCustomColumn().then((res) => {
+      let columns: any[] = [];
+      res.data.map((item: { desc: string; name: string }) => {
+        let lolumnItem = {
+          title: item.desc,
+          dataIndex: item.name,
+        };
+        columns.push(lolumnItem);
+      });
+      state.columns.push(...columns);
+    });
 
     const handleTableChange = (pagination: PageOptions) => {
       const { current, pageSize, total } = pagination;
@@ -107,7 +109,7 @@ const PutAdPlan = defineComponent({
         meta.value = res.data.meta;
       });
     };
-    return { ...toRefs(state), handleTableChange, handleOk, handleCancel };
+    return { ...toRefs(state), handleTableChange };
   },
 });
 

+ 42 - 18
src/views/put/put-book.vue

@@ -12,20 +12,29 @@
              :pagination="tablePageOptions"
              :loading="loading"
              :columns="columns"
-             :data-source="list"></a-table>
+             :data-source="list"
+             @change="onBookLoaded">
+      <template #operator="{record}">
+        <confirm-button :label="record.status ? '停止' : '已停止'"
+                        :disabled="!record.status"
+                        type="link"
+                        confirm-content="确定要停止该条内容吗?"
+                        @click="onStop(record)" />
+      </template>
+    </a-table>
     <!-- 添加 -->
     <a-modal title="投放书籍添加"
              width="400px"
+             destroy-on-close
              v-model:visible="open"
-             :confirm-loading="addFormState.inConfirm"
-             :after-close="onReset"
+             :confirm-loading="inConfirm"
              @ok="onAdd">
       <a-form :model="addFormState"
               :labelCol="labelCol"
               :wrapperCol="wrapperCol">
         <a-form-item label="公众号名称">
           <a-select v-model:value="addFormState.official_id">
-            <a-select-option v-for="official in addFormState.officials"
+            <a-select-option v-for="official in officials"
                              :key="official.value"
                              :value="official.value">
               {{official.label}}
@@ -51,7 +60,7 @@
         </a-form-item>
         <a-form-item label="流量平台">
           <a-select v-model:value="addFormState.platform">
-            <a-select-option v-for="platform in addFormState.platforms"
+            <a-select-option v-for="platform in platforms"
                              :key="platform.value"
                              :value="platform.value">
               {{platform.label}}
@@ -74,20 +83,28 @@ import {
 } from "vue";
 
 import ToolBar from "@/components/tool-bar/index.vue";
+import ConfirmButton from "@/components/confirm-button/index.vue";
 
 import useApp from "@/hooks/useApp";
 import usePagination from "@/hooks/usePagination";
 import useFormLayout from "@/hooks/useFormLayout";
 import useDebounceFn from "@/hooks/useDebounceFn";
 import useValidate from "@/hooks/useValidate";
+import useReset from "@/hooks/useReset";
 
-import { getDeliveryBookList, getBooksByName, addDeliveryBook } from "@/api";
+import {
+  getDeliveryBookList,
+  getBooksByName,
+  addDeliveryBook,
+  onStopDeliveryBook,
+} from "@/api";
 import { TableColumnOfPutBooks } from "../_pageOptions/table-put";
 import { IBookSearchResult, IDeliveryBook } from "@/types/api";
 
 const PutBooks = defineComponent({
   components: {
     ToolBar,
+    ConfirmButton,
   },
   setup() {
     let { loading, meta, tablePageOptions } = usePagination();
@@ -96,8 +113,11 @@ const PutBooks = defineComponent({
     const { labelCol, wrapperCol } = useFormLayout();
 
     const state = reactive({
+      officials: computed(() => store.getters.officials),
+      platforms: computed(() => store.getters.platforms),
       searching: false,
       open: false,
+      inConfirm: false,
       list: ref<IDeliveryBook[]>([]),
       columns: TableColumnOfPutBooks,
       official_name: "",
@@ -105,13 +125,10 @@ const PutBooks = defineComponent({
     });
 
     const addFormState = reactive({
-      officials: computed(() => store.getters.officials),
-      platforms: computed(() => store.getters.platforms),
       official_id: "",
       book: ref<Partial<IBookSearchResult>>({}),
       platform: "",
       books: ref<IBookSearchResult[]>([]),
-      inConfirm: false,
     });
 
     const onSearch = (fields: Record<string, string>) => {
@@ -121,14 +138,15 @@ const PutBooks = defineComponent({
       onBookLoaded();
     };
 
-    const onBookLoaded = async (query?: { page: 1 }) => {
+    const onBookLoaded = async (query?: { current: 1 }) => {
       try {
+        console.log(query);
         loading.value = true;
         const { official_name, book_name } = state;
         const { data } = await getDeliveryBookList({
           official_name,
           book_name,
-          page: query?.page ?? 1,
+          page: query?.current ?? 1,
         });
         state.list = data.list;
         meta.value = data.meta;
@@ -139,8 +157,9 @@ const PutBooks = defineComponent({
       }
     };
 
-    // 添加书籍弹窗
+    // 弹窗书籍搜索
     const onBookSearch = useDebounceFn(async (keywords: string) => {
+      addFormState.books.length = 0;
       if (!keywords) return;
       const { data } = await getBooksByName(keywords);
       addFormState.books.push(...data.list);
@@ -162,13 +181,14 @@ const PutBooks = defineComponent({
       onBookSearch,
       onSearch,
       onBookCheck,
+      onBookLoaded,
     };
   },
   methods: {
     async onAdd() {
       try {
         // TODO 没做字段校验 字段校验封装
-        this.addFormState.inConfirm = true;
+        this.inConfirm = true;
         const { official_id, platform, book } = this.addFormState;
         // useValidate({ official_id, platform });
         await addDeliveryBook(
@@ -180,17 +200,21 @@ const PutBooks = defineComponent({
         );
         this.open = false;
         this.$message.success("添加成功");
+        this.onBookLoaded();
+        this.addFormState = useReset(this.addFormState);
       } catch (error) {
         console.log("error while add delivery book");
         error.message && this.$message.error(error.message);
       } finally {
-        this.addFormState.inConfirm = false;
+        this.inConfirm = false;
       }
     },
-    onReset() {
-      this.addFormState.official_id = "";
-      this.addFormState.platform = "";
-      this.addFormState.book = {};
+    onStop(data: IDeliveryBook) {
+      const { id } = data;
+      onStopDeliveryBook(id).then((_) => {
+        this.$message.success("停止成功");
+        this.onBookLoaded();
+      });
     },
   },
 });

+ 1 - 0
vue.config.js

@@ -51,6 +51,7 @@ module.exports = {
       // config.entry("index").add("babel-polyfill");
       prodConfig.uploadAssetsToOSS(config);
       // prodConfig.assetsGzip(config);
+      config.optimization.delete("splitChunks");
       config.plugin("html").tap((args) => {
         // 加上属性引号
         args[0].minify.removeAttributeQuotes = false;