Browse Source

feat(config): 实现运费模板配置功能

新增企业运费模板的查询、新增与编辑功能,包括接口调用、表单结构更新和页面交互逻辑调整。
优化了配送距离、费用、重量等字段的输入方式,并支持根据企业选择自动回填模板数据。
同时修复了商品分类层级判断逻辑及标题显示问题。
zhangtao 1 month ago
parent
commit
a10848f10c

+ 1 - 1
.vscode/settings.json

@@ -3,7 +3,7 @@
     "source.fixAll.eslint": "explicit",
     "source.organizeImports": "never"
   },
-  "editor.formatOnSave": false,
+  "editor.formatOnSave": true,
   "eslint.validate": [
     "html",
     "css",

File diff suppressed because it is too large
+ 229 - 220
pnpm-lock.yaml


+ 37 - 0
src/service/api/common.ts

@@ -18,3 +18,40 @@ export function fetchUpload(data: File, config?: any) {
     ...config
   });
 }
+
+/**
+ * 企业ID查询运费模板
+ * @param channelId
+ * @returns
+ */
+export function fetchGetTransport(channelId: number) {
+  return request<Api.delivery.Transport2>({
+    url: `/platform/transport2/queryTransport2ByChannelId/${channelId}`,
+    method: 'get'
+  });
+}
+
+/**
+ *新增或更新运费模板
+ * @param data
+ * @returns
+ */
+export function fetchGetAddOrEditTransport(data: any) {
+  return request({
+    url: '/platform/transport2/addOrEdit',
+    method: 'post',
+    data
+  });
+}
+
+/**
+ * 后管端-企业运费列表
+ * @returns
+ */
+
+export function fetchChannelList() {
+  return request<{ records: Api.delivery.Transport2[] }>({
+    url: '/platform/transport2/transport2List',
+    method: 'get'
+  });
+}

+ 44 - 0
src/typings/api.d.ts

@@ -950,6 +950,50 @@ declare namespace Api {
     }
   }
   namespace delivery {
+    interface Transport2 {
+      /**
+       * 订单需要满多少
+       */
+      amount: number;
+      /**
+       * 渠道ID
+       */
+      channelId: number;
+      /**
+       * 创建时间
+       */
+      createTime: string;
+      /**
+       * 配送距离
+       */
+      distance: number;
+      /**
+       * 费用(元/20kg)
+       */
+      freightFee: number;
+      /**
+       * 配送费
+       */
+      piece: number;
+      /**
+       * 店铺id
+       */
+      shopId: number;
+      /**
+       * 运费模板名称
+       */
+      transName: string;
+      /**
+       * 运费模板id
+       */
+      transportId: number;
+      /**
+       * 重量限制
+       */
+      weight: number;
+      [property: string]: any;
+    }
+
     interface devList {
       /**
        * 公司主页

+ 81 - 38
src/views/config/fright-config/index.vue

@@ -1,35 +1,24 @@
 <script setup lang="tsx">
 import { ref } from 'vue';
-import { NDynamicInput, NInput, NInputNumber } from 'naive-ui';
+import { NDynamicInput, NInputNumber, NSelect } from 'naive-ui';
 import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
+import { fetchChannelList, fetchGetAddOrEditTransport, fetchGetTransport } from '@/service/api/common';
 import { useTabStore } from '@/store/modules/tab';
 import { useForm } from '@/components/zt/Form/hooks/useForm';
-import { ApiSelect } from '@/components/zt/ApiSelect';
+const isSubmit = ref(false);
 const tabStore = useTabStore();
 interface Options {
   value: any;
   index: number;
 }
 const ChannelOptions = ref<Api.goods.Channel[]>([]);
-const [registerForm, { getFieldsValue, validate }] = useForm({
+const [registerForm, { getFieldsValue, validate, setFieldsValue }] = useForm({
   schemas: [
     {
-      field: '1',
+      field: 'id',
       component: 'NInput',
-      label: '配送距离',
-      required: true,
-      render({ model, field }) {
-        return (
-          <div class={'w200px xl:w700px'}>
-            <NInput
-              placeholder={'请输入配送距离'}
-              value={model[field]}
-              onUpdate:value={val => (model[field] = val)}
-              v-slots={{ prefix: () => '大于', suffix: () => 'km' }}
-            ></NInput>
-          </div>
-        );
-      }
+      label: 'false',
+      show: false
     },
     {
       field: 'name',
@@ -42,6 +31,7 @@ const [registerForm, { getFieldsValue, validate }] = useForm({
               <div class={'w-200px text-center'}> 企业 </div>
               <div class={'ml-3 w-200px text-center'}> 费用(元) </div>
               <div class={'ml-3 w-200px text-center'}> 重量(kg) </div>
+              <div class={'ml-3 w-200px text-center'}> 分单(km) </div>
             </div>
             <NDynamicInput
               value={model[field]}
@@ -54,7 +44,7 @@ const [registerForm, { getFieldsValue, validate }] = useForm({
         );
       },
       required: true,
-      defaultValue: [{ Enterprise: null, Cost: 1 }]
+      defaultValue: []
     }
   ],
   labelWidth: 120,
@@ -70,36 +60,63 @@ function handleCreatInput(model: any, field: any, row: Options) {
   return (
     <div class={'flex items-center'}>
       <div class={'w-200px'}>
-        <ApiSelect
-          value={model[field][row.index].Enterprise}
-          api={fetchGetAllChannelList}
-          labelFeild="channelName"
-          valueFeild="id"
-          getOptions={handleGetOptions}
+        <NSelect
+          value={model[field][row.index].channelId}
+          labelField="channelName"
+          valueField="id"
+          options={ChannelOptions.value}
           onUpdate:value={vlaue => {
-            model[field][row.index].Enterprise = vlaue;
+            ChannelOptions.value.map(it => {
+              if (it.id == model[field][row.index].channelId) {
+                it.disabled = false;
+              }
+              return it;
+            });
+            model[field][row.index].channelId = vlaue ? Number(vlaue) : undefined;
+            handleGetChannelId(vlaue, row.index);
+          }}
+          onUpdate:show={value => {
+            ChannelOptions.value.map(it => {
+              if (it.id == model[field][row.index].channelId) {
+                if (value) {
+                  it.disabled = false;
+                }
+                if (!value) {
+                  it.disabled = true;
+                }
+              }
+              return it;
+            });
           }}
-        ></ApiSelect>
+        ></NSelect>
       </div>
       <div class={'ml-3 w-200px'}>
         <NInputNumber
-          value={model[field][row.index].Cost}
+          value={model[field][row.index].freightFee}
           min={1}
           onUpdate:value={value => {
-            model[field][row.index].Cost = value;
+            model[field][row.index].freightFee = value;
           }}
         ></NInputNumber>
       </div>
       <div class={'ml-3 w-200px'}>
         <NInputNumber
-          value={model[field][row.index].Cost}
+          value={model[field][row.index].weight}
           min={1}
           onUpdate:value={value => {
-            model[field][row.index].Cost = value;
+            model[field][row.index].weight = value;
           }}
           v-slots={{ prefix: () => '每', suffix: () => 'Kg' }}
         ></NInputNumber>
       </div>
+      <div class={'ml-3 w-200px'}>
+        <NInputNumber
+          placeholder={'请输入配送距离'}
+          value={model[field][row.index].distance}
+          onUpdate:value={val => (model[field][row.index].distance = val)}
+          v-slots={{ prefix: () => '大于', suffix: () => 'km' }}
+        ></NInputNumber>
+      </div>
     </div>
   );
 }
@@ -107,19 +124,45 @@ function close() {
   tabStore.removeTab(tabStore.activeTabId);
 }
 
+async function getChannelList() {
+  const { data } = await fetchGetAllChannelList();
+  if (!data) return;
+  ChannelOptions.value = data;
+}
+getChannelList();
+
+async function getData() {
+  const { data } = await fetchChannelList();
+  if (data) {
+    setFieldsValue({ name: data.records });
+  }
+}
+getData();
 function handleAdd() {
   return {
-    Enterprise: null,
-    Cost: 1
+    channelId: null,
+    freightFee: 1,
+    distance: null,
+    weight: 10
   };
 }
-function handleGetOptions(options: Api.goods.Channel[]) {
-  ChannelOptions.value = options;
-}
+
 async function save() {
   await validate();
+  isSubmit.value = true;
+  const form = getFieldsValue();
+  await fetchGetAddOrEditTransport(form);
+  isSubmit.value = false;
+  getData();
+}
+async function handleGetChannelId(channelId: number, idx: number) {
+  const res = await fetchGetTransport(channelId);
   const form = getFieldsValue();
-  console.log(form);
+  const newName = JSON.parse(JSON.stringify(form.name));
+  newName[idx].distance = res.data?.distance;
+  newName[idx].freightFee = res.data?.freightFee;
+  newName[idx].weight = res.data?.weight;
+  setFieldsValue({ name: newName });
 }
 </script>
 
@@ -132,7 +175,7 @@ async function save() {
       <template #footer>
         <NSpace justify="end">
           <NButton size="small" @click="close">关闭</NButton>
-          <NButton type="primary" size="small" @click="save">保存</NButton>
+          <NButton type="primary" size="small" :loading="isSubmit" @click="save">保存</NButton>
         </NSpace>
       </template>
     </NCard>

+ 5 - 5
src/views/goods/desk-category/index.vue

@@ -187,12 +187,12 @@ const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
     width: 230,
     render: row => (
       <div class="flex-center gap-8px">
-        {row.level == 1 && (
+        {row.level == 2 && (
           <NButton type="primary" size="small" quaternary onClick={() => add(row)}>
             添加三级分类
           </NButton>
         )}
-        {row.level == 2 && (
+        {row.level == 3 && (
           <NButton type="primary" size="small" quaternary onClick={() => handleOpenRelatedGoods(row)}>
             关联商品
           </NButton>
@@ -203,7 +203,7 @@ const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
           </NButton>
         }
 
-        {row.level == 2 && (
+        {row.level == 3 && (
           <NButton type="primary" size="small" quaternary onClick={() => del(row)}>
             删除
           </NButton>
@@ -293,7 +293,7 @@ async function handleSubmit(file: File) {
 }
 function edit(row: Api.goods.ShopCategory) {
   openModalForm(row);
-  setModalProps({ title: `修改${Number(row.level) + 1}级分类` });
+  setModalProps({ title: `修改${Number(row.level)}级分类` });
   setModalFormValue({ ...row, label: row.label });
 }
 function add(row: Api.goods.ShopCategory) {
@@ -336,7 +336,7 @@ async function handleSubmitForm() {
   const form = await getModalFormValue();
   const level = form.level;
   const { error } =
-    level != 2 ? await fetchUpdateCategory(form) : await fetchAddCategory({ ...form, shopId: getSearchForm().shopId });
+    level != 3 ? await fetchUpdateCategory(form) : await fetchAddCategory({ ...form, shopId: getSearchForm().shopId });
   if (!error) {
     closeModalForm();
     getData();

Some files were not shown because too many files changed in this diff