Pārlūkot izejas kodu

🎨 投放书籍 添加

晓晓晓晓丶vv 4 gadi atpakaļ
vecāks
revīzija
9fb306dade

+ 12 - 0
src/api/index.ts

@@ -110,3 +110,15 @@ export const getADPlanlist = (
 export const getPlatforms = (): AxiosPromise<IPlatform[]> => {
   return axios("/simplePlatforms");
 };
+
+/**
+ * 添加投放书籍
+ * @param data
+ */
+export const addDeliveryBook = (data: {
+  delivery_bid: string | number;
+  official_id: string | number;
+  platform: string;
+}) => {
+  return axios.post("/addDeliveryBook", data);
+};

+ 2 - 0
src/global.d.ts

@@ -1,3 +1,4 @@
+import { MessageApi } from "ant-design-vue/lib/message";
 import { ModalFunc, ModalFuncProps } from "ant-design-vue/lib/modal/Modal";
 import { ComponentCustomProperties } from "vue";
 
@@ -8,5 +9,6 @@ declare module "@vue/runtime-core" {
       container?: HTMLElement
     ): Promise<ClipboardJS.Event>;
     $confirm(options: ModalFuncProps): ModalFunc;
+    $message: MessageApi;
   }
 }

+ 2 - 0
src/plugins/install.ts

@@ -7,6 +7,7 @@ import {
   Input,
   Layout,
   Menu,
+  message,
   Modal,
   Popover,
   Select,
@@ -21,6 +22,7 @@ import { ModalConfirmKey } from "./injectionKey";
 const install = (app: App<Element>) => {
   app.provide(ModalConfirmKey, Modal.confirm);
   app.config.globalProperties.$confirm = Modal.confirm;
+  app.config.globalProperties.$message = message;
 
   return app
     .use(VueClipboard3)

+ 1 - 1
src/router/async.ts

@@ -15,7 +15,7 @@ const PutBook: RouteConfig = {
   meta: {
     title: "投放书籍",
   },
-  component: () => import("@/views/put/put-book"),
+  component: () => import("@/views/put/put-book.vue"),
 };
 
 const PutAdAccount: RouteConfig = {

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

@@ -9,8 +9,8 @@
         <a-select class="full-width"
                   v-model:value="query.platform">
           <a-select-option v-for="platform in platforms"
-                           :key="platform.name"
-                           :value="platform.name">{{platform.desc}}</a-select-option>
+                           :key="platform.value"
+                           :value="platform.value">{{platform.label}}</a-select-option>
         </a-select>
       </div>
     </tool-bar>

+ 0 - 149
src/views/put/put-book.tsx

@@ -1,149 +0,0 @@
-import { defineComponent, reactive, ref } from "vue";
-
-import ToolBar from "@/components/tool-bar/index.vue";
-
-import usePagination from "@/hooks/usePagination";
-import useFormLayout from "@/hooks/useFormLayout";
-import useDebounceFn from "@/hooks/useDebounceFn";
-
-import { getDeliveryBookList, getBooksByName } from "@/api";
-import { TableColumnOfPutBooks } from "../_pageOptions/table-put";
-import { IBookSearchResult, IDeliveryBook } from "@/types/api";
-
-// TODO 结构待优化
-
-const PutBooks = defineComponent({
-  components: {
-    ToolBar,
-  },
-  setup() {
-    let { loading, meta, tablePageOptions } = usePagination();
-
-    const { labelCol, wrapperCol } = useFormLayout();
-
-    const state = reactive({
-      inSearching: false,
-      open: false,
-      list: ref<IDeliveryBook[]>([]),
-      columns: TableColumnOfPutBooks,
-    });
-
-    const addFormState = reactive({
-      official_id: 0,
-      book: ref<Partial<IBookSearchResult>>({}),
-      platforms: 0,
-      books: ref<IBookSearchResult[]>([]),
-    });
-
-    const onSearch = async (fields: Record<string, string>) => {
-      try {
-        const { official_name, book_name } = fields;
-        const { data } = await getDeliveryBookList({
-          official_name,
-          book_name,
-          page: 1,
-        });
-        state.list = data.list;
-        meta = data.meta;
-      } catch (e) {
-        console.log(e);
-      } finally {
-        state.inSearching = false;
-      }
-    };
-
-    // 添加书籍弹窗
-    const renderAddForm = () => {
-      const onBookSearch = useDebounceFn(async (keywords: string) => {
-        if (!keywords) return;
-        const { data } = await getBooksByName(keywords);
-        addFormState.books.push(...data.list);
-      }, 500);
-
-      const onBookCheck = (value: number, options: any) => {
-        addFormState.book = options.key;
-      };
-
-      const ok = () => {
-        console.log("ok");
-      };
-
-      const renderSearchBooksList = () => {
-        return addFormState.books.map((book) => (
-          <a-select-option value={book.bid} key={book}>
-            {book.name}
-          </a-select-option>
-        ));
-      };
-
-      return (
-        <a-modal
-          title="投放书籍添加"
-          width="400px"
-          v-model={[state.open, "visible"]}
-          onOk={ok}
-        >
-          <a-form
-            model={addFormState}
-            labelCol={labelCol}
-            wrapperCol={wrapperCol}
-          >
-            <a-form-item label="公众号名称">
-              <a-select v-model={[addFormState.official_id, "value"]}>
-                <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
-                show-search
-                placeholder="请输入要搜索的书名"
-                not-found-content="暂无数据"
-                default-active-first-option={false}
-                filter-option={false}
-                show-arrow={false}
-                value={addFormState.book.bid}
-                onSearch={onBookSearch}
-                onChange={onBookCheck}
-              >
-                {renderSearchBooksList()}
-              </a-select>
-            </a-form-item>
-            <a-form-item label="流量平台">
-              <a-select v-model={[addFormState.platforms, "value"]}>
-                <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>
-        </a-modal>
-      );
-    };
-
-    return () => (
-      <div class="page-wrap page-wrap-put-books">
-        <tool-bar
-          text={["official_name", "book_name"]}
-          label={["公众号名称", "书名"]}
-          v-model={[state.inSearching, "loading"]}
-          onConfirm={onSearch}
-        />
-        <div class="operator-bar">
-          <a-button type="primary" onClick={() => (state.open = true)}>
-            添加
-          </a-button>
-        </div>
-        <a-table
-          row-key="id"
-          pagination={tablePageOptions}
-          loading={loading.value}
-          columns={state.columns}
-          data-source={state.list}
-        ></a-table>
-        {renderAddForm()}
-      </div>
-    );
-  },
-});
-
-export default PutBooks;

+ 170 - 0
src/views/put/put-book.vue

@@ -0,0 +1,170 @@
+<template>
+  <div class="page-wrap page-wrap-put-books">
+    <tool-bar :text="['official_name', 'book_name']"
+              :label="['公众号名称', '书名']"
+              v-model:loading="inSearching"
+              @confirm="onSearch" />
+    <div class="operator-bar">
+      <a-button type="primary"
+                @click="open = true">添加</a-button>
+    </div>
+    <a-table row-key="id"
+             :pagination="tablePageOptions"
+             :loading="loading"
+             :columns="columns"
+             :data-source="list"></a-table>
+    <!-- 添加 -->
+    <a-modal title="投放书籍添加"
+             width="400px"
+             :confirm-loading="addFormState.inConfirm"
+             v-model:visible="open"
+             @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"
+                             :key="official.value"
+                             :value="official.value">
+              {{official.label}}
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="书籍">
+          <a-select show-search
+                    placeholder="请输入要搜索的书名"
+                    not-found-content="暂无数据"
+                    :default-active-first-option="false"
+                    :filter-option="false"
+                    :show-arrow="false"
+                    :value="addFormState.book.bid"
+                    @search="onBookSearch"
+                    @change="onBookCheck">
+            <a-select-option v-for="book in addFormState.books"
+                             :value="book.bid"
+                             :key="book.bid">
+              {{book.name}}
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="流量平台">
+          <a-select v-model:value="addFormState.platform">
+            <a-select-option v-for="platform in addFormState.platforms"
+                             :key="platform.value"
+                             :value="platform.value">
+              {{platform.label}}
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+      </a-form>
+    </a-modal>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, reactive, ref, computed, toRefs } from "vue";
+
+import ToolBar from "@/components/tool-bar/index.vue";
+
+import useApp from "@/hooks/useApp";
+import usePagination from "@/hooks/usePagination";
+import useFormLayout from "@/hooks/useFormLayout";
+import useDebounceFn from "@/hooks/useDebounceFn";
+
+import { getDeliveryBookList, getBooksByName, addDeliveryBook } from "@/api";
+import { TableColumnOfPutBooks } from "../_pageOptions/table-put";
+import { IBookSearchResult, IDeliveryBook } from "@/types/api";
+
+const PutBooks = defineComponent({
+  components: {
+    ToolBar,
+  },
+  setup() {
+    let { loading, meta, tablePageOptions } = usePagination();
+
+    const { store } = useApp();
+    const { labelCol, wrapperCol } = useFormLayout();
+
+    const state = reactive({
+      inSearching: false,
+      open: false,
+      list: ref<IDeliveryBook[]>([]),
+      columns: TableColumnOfPutBooks,
+    });
+
+    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 = async (fields: Record<string, string>) => {
+      try {
+        const { official_name, book_name } = fields;
+        const { data } = await getDeliveryBookList({
+          official_name,
+          book_name,
+          page: 1,
+        });
+        state.list = data.list;
+        meta = data.meta;
+      } catch (e) {
+        console.log(e);
+      } finally {
+        state.inSearching = false;
+      }
+    };
+
+    // 添加书籍弹窗
+    const onBookSearch = useDebounceFn(async (keywords: string) => {
+      if (!keywords) return;
+      const { data } = await getBooksByName(keywords);
+      addFormState.books.push(...data.list);
+    }, 500);
+
+    const onBookCheck = (value: number, options: any) => {
+      addFormState.book = options.key;
+    };
+
+    return {
+      ...toRefs(state),
+      addFormState,
+      loading,
+      tablePageOptions,
+      labelCol,
+      wrapperCol,
+      onBookSearch,
+      onSearch,
+      onBookCheck,
+    };
+  },
+  methods: {
+    async onAdd() {
+      try {
+        // TODO 没做字段校验 字段校验封装
+        this.addFormState.inConfirm = true;
+        const { official_id, platform, book } = this.addFormState;
+        await addDeliveryBook({
+          delivery_bid: book.id!,
+          official_id,
+          platform,
+        });
+        this.open = false;
+        this.$message.success("添加成功");
+      } catch (error) {
+        console.log("error while add delivery book", error);
+        this.$message.error("添加失败!");
+      } finally {
+        this.addFormState.inConfirm = false;
+      }
+    },
+  },
+});
+
+export default PutBooks;
+</script>