Browse Source

供应商两个模块

asd26269546 2 years ago
parent
commit
e7ba142a33

+ 25 - 1
src/assets/css/index.scss

@@ -168,4 +168,28 @@ li {
     top: 0;
     height: 70px;
     line-height: 70px;
-}
+}
+
+.commons-item-title-delete{
+    background-color: #f2f2f2;
+    height: 30px;
+    line-height: 30px;
+    padding: 0 10px!important;
+    margin: 0 10px;
+    .delete{
+        width: 30px!important;
+        font-size: 12px;
+        
+    }
+}
+
+.van-cell-group--inset{
+    margin: 0!important;
+    border-radius:0!important;
+}
+
+.van-form{
+    margin-top: 6px!important;
+    border:0!important;
+}
+

+ 22 - 0
src/components/cascaderCity/index.vue

@@ -0,0 +1,22 @@
+<template>
+    <van-cascader
+        v-model="formData.city"
+        title="请选择所在地区"
+        :options="areaInfo"
+        @close="showArea = false"
+        @change="cityOnChange"
+        @finish="getAreaInfo"
+    />
+</template>
+
+<script lang="setup">
+import { ref, getCurrentInstance, onMounted } from "vue";
+import { showSuccessToast, showToast } from "vant";
+import { useRoute } from "vue-router";
+import { showLoadingToast, closeToast,showNotify  } from 'vant';
+    
+</script>
+
+<style lang="scss" scoped>
+    
+</style>

+ 26 - 1
src/router/index.js

@@ -20,7 +20,7 @@ const routes = [{
 		path: '/main',
 		name: 'main',
 		component: main,
-		redirect: '/main/equipment',
+		redirect: '/main/working',
 		children: [{
 				path: 'equipment',
 				name: '设备列表',
@@ -56,6 +56,31 @@ const routes = [{
 				name: '采购单',
 				component: () => import('../views/process/index.vue')
 			},
+			{
+				path: 'supplierConfig',
+				name: '供应商',
+				component: () => import('../views/procurementManagement/supplierConfig/index.vue')
+			},
+			{
+				path: 'supplierConfigAdd',
+				name: '供应商详情',
+				component: () => import('../views/procurementManagement/supplierConfig/add.vue')
+			},
+			{
+				path: 'priceConfig',
+				name: '供应价格',
+				component: () => import('../views/procurementManagement/priceConfig/index.vue')
+			},
+			{
+				path: 'priceConfigAdd',
+				name: '供应价格新增',
+				component: () => import('../views/procurementManagement/priceConfig/add.vue')
+			},
+			{
+				path: 'priceConfigEdit',
+				name: '供应价格编辑',
+				component: () => import('../views/procurementManagement/priceConfig/edit.vue')
+			},
 			//仓库模块
 			{
 				path: 'warehouseConfig',

+ 3 - 1
src/views/main.vue

@@ -6,7 +6,7 @@
 				<van-tabbar-item icon="search" to="/main/working">工作台</van-tabbar-item>
 				<van-tabbar-item
 					icon="friends-o"
-					:to="getUserInfo().tenantId != 'hmhjc' ? '/main/xiamenList' : '/main/equipment'"
+					:to="tenantId == 'xmhjc' ? '/main/xiamenList' : '/main/equipment'"
 				>物联网</van-tabbar-item>
 				<van-tabbar-item
 					icon="setting-o"
@@ -20,9 +20,11 @@
 <script setup>
 import { ref, getCurrentInstance } from 'vue'
 import { getUserInfo } from '@/utils/auth';
+
 import '../assets/icon/iconfont.css'
 import 'vant/lib/index.css';
 import axios from 'axios'
+const tenantId = getUserInfo().tenantId
 const proxy = getCurrentInstance().proxy
 const tabType = ref('home')
 </script>

+ 219 - 0
src/views/procurementManagement/priceConfig/add.vue

@@ -0,0 +1,219 @@
+<template>
+    <div class="form">
+      <van-nav-bar
+        title="供应价格"
+        left-text="返回"
+        left-arrow
+        @click-left="onClickLeft"
+      >
+      </van-nav-bar>
+      <van-form @submit="onSubmit" label-align="top" style="margin-top: 20px">
+        <van-cell-group inset>
+          <van-field
+            v-model="formData.supplierInfoName"
+            is-link
+            readonly
+            label="供应商"
+            placeholder="选择供应商"
+            @click="typeModal = true"
+            :rules="[{ required: true, message: '供应商不能为空' }]"
+            required
+          />
+          <van-popup v-model:show="typeModal" round position="bottom">
+            <van-picker
+              :columns="columns"
+              @cancel="typeModal = false"
+              @confirm="onConfirm"
+            />
+          </van-popup>
+          <!-- 明细列表 -->
+          <div v-for="(item, index) in list" :key="index">
+            <div class="row commons-item-title-delete">
+              <div class="title">明细{{ index + 1 }}</div>
+              <div
+                class="delete"
+                @click.native="handleDel(index)"
+                v-if="!route.query.id"
+              >
+                删除
+              </div>
+            </div>
+            <van-field
+              v-model="list[index].productInfoName"
+              is-link
+              readonly
+              label="物品名称"
+              placeholder="选择物品名称"
+              @click="handleSelect(index)"
+              :rules="[{ required: true, message: '物品名称不能为空' }]"
+              required
+            />
+  
+            <van-field
+              v-model="list[index].price"
+              label="供应单价"
+              placeholder="请输入供应单价"
+              :rules="[{ required: true, message: '供应单价不能为空' }]"
+              required
+            />
+          </div>
+          <van-popup v-model:show="typeModalOne" round position="bottom">
+            <van-picker
+              :columns="columnsOne"
+              @cancel="typeModalOne = false"
+              @confirm="(data) => onConfirmOne(data, index)"
+            />
+          </van-popup>
+        </van-cell-group>
+  
+        <div style="text-align: center; line-height: 28px" v-if="!route.query.id">
+          <van-button
+            icon="plus"
+            type="primary"
+            plain
+            size="mini"
+            style="margin-top: 10px"
+            @click="handleAddRow"
+            >添加明细</van-button
+          >
+        </div>
+  
+        <div style="margin: 16px" v-if="!route.query.id">
+          <van-button round block type="primary" native-type="submit">
+            提交
+          </van-button>
+        </div>
+      </van-form>
+    </div>
+  </template>
+  
+  <script setup>
+  import { ref, getCurrentInstance, onMounted } from "vue";
+  import { showSuccessToast, showFailToast } from "vant";
+  import { useRoute } from "vue-router";
+  
+  const proxy = getCurrentInstance().proxy;
+  const route = useRoute();
+  const showPicker = ref(false);
+  const typeModal = ref(false);
+  const typeModalOne = ref(false);
+  let selectIndex = ref(null);
+  const formData = ref({
+    supplierInfoId: "",
+    type: "1",
+    supplierInfoName: "",
+  });
+  const list = ref([]);
+  const handleAddRow = () => {
+    list.value.push({
+      productInfoId: "",
+      productInfoName: "",
+      price: "",
+    });
+  };
+  const getDict = () => {
+    proxy.post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
+      columns.value = res.data.rows.map((item) => {
+        return {
+          text: item.name,
+          value: item.id,
+        };
+      });
+      // formData.value.supplierInfoName = formData.value.supplierInfoId
+      //   ? columns.value.find((item) => item.value == formData.value.supplierInfoId).name
+      //   : null;
+    });
+  
+    proxy
+      .post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "1" })
+      .then((res) => {
+        columnsOne.value = res.data.rows.map((item) => {
+          return {
+            text: item.name,
+            value: item.id,
+          };
+        });
+        // formData.value.supplierInfoName = formData.value.supplierInfoId
+        //   ? columns.value.find((item) => item.value == formData.value.supplierInfoId).name
+        //   : null;
+      });
+  };
+  
+  const getDetails = (id) => {
+    proxy.post("/stockJournal/detail", { id }).then((res) => {
+      formData.value = res.data;
+      list.value = res.data.list.map((x) => ({
+        productInfoId: x.productInfoId,
+        productInfoName: x.productInfoName,
+        price: x.price,
+      }));
+    });
+  };
+  
+  const columns = ref([]);
+  const columnsOne = ref([]);
+  
+  const onConfirm = ({ selectedOptions }) => {
+    formData.value.supplierInfoId = selectedOptions[0].value;
+    formData.value.supplierInfoName = selectedOptions[0].text;
+    typeModal.value = false;
+  };
+  
+  const onConfirmOne = ({ selectedOptions }, index) => {
+    list.value[selectIndex.value].productInfoId = selectedOptions[0].value;
+    list.value[selectIndex.value].productInfoName = selectedOptions[0].text;
+    typeModalOne.value = false;
+  };
+  
+  const handleSelect = (index) => {
+    selectIndex.value = index;
+    typeModalOne.value = true;
+  };
+  
+  const handleDel = (index) => {
+    list.value.splice(index, 1);
+  };
+  
+  const onClickLeft = () => history.back();
+  
+  const onSubmit = () => {
+    console.log(list)
+    if (!list.value.length > 0) return showFailToast("请添加明细!");
+    formData.value.supplierPriceList = list.value.map((x) => ({
+      productInfoId: x.productInfoId,
+      price: x.price,
+    }));
+    proxy.post("/supplierPrice/" + route.query.type, formData.value).then(
+      (res) => {
+        setTimeout(() => {
+          showSuccessToast(route.query.type == "add" ? "添加成功" : "修改成功");
+          proxy.$router.push("/main/priceConfig");
+        }, 500);
+      },
+      (err) => {
+        return showFailToast(err.message);
+      }
+    );
+  };
+  onMounted(() => {
+    console.log(route.query)
+    formData.value = route.query;
+    getDict();
+  });
+  </script>
+  <style lang="scss" scoped>
+  .row {
+    display: flex;
+    padding: 5px 10px 0 10px;
+    justify-content: space-between;
+    align-items: center;
+    .title {
+      flex: 1;
+    }
+    .delete {
+      width: 20px;
+      cursor: pointer;
+      text-align: center;
+    }
+  }
+  </style>

+ 156 - 0
src/views/procurementManagement/priceConfig/edit.vue

@@ -0,0 +1,156 @@
+<template>
+    <div class="form">
+        <van-nav-bar title="供应价格" left-text="返回" left-arrow @click-left="onClickLeft">
+        </van-nav-bar>
+        <van-form @submit="editSubmit" label-align="top" style="margin-top: 20px">
+            <van-cell-group inset>
+                <van-field v-model="formData.supplierInfoName" is-link readonly label="供应商" placeholder="选择供应商"
+                    @click="typeModal = true" :rules="[{ required: true, message: '供应商不能为空' }]" required />
+                <van-popup v-model:show="typeModal" round position="bottom">
+                    <van-picker :columns="columns" @cancel="typeModal = false" @confirm="onConfirm" />
+                </van-popup>
+                <van-field v-model="formData.productInfoName" is-link readonly label="物品名称" placeholder="选择物品名称"
+                    @click="handleSelect(index)" :rules="[{ required: true, message: '物品名称不能为空' }]" required
+                    v-if="route.query.id" />
+
+                <van-field v-model="formData.price" label="供应单价" placeholder="请输入供应单价"
+                    :rules="[{ required: true, message: '供应单价不能为空' }]" required v-if="route.query.id" />
+                <!-- 明细列表 -->
+                <van-popup v-model:show="typeModalOne" round position="bottom">
+                    <van-picker :columns="columnsOne" @cancel="typeModalOne = false"
+                        @confirm="(data) => onConfirmOne(data, index)" />
+                </van-popup>
+            </van-cell-group>
+
+            
+
+            <div style="margin: 16px">
+                <van-button round block type="primary" native-type="submit">
+                    提交
+                </van-button>
+            </div>
+            
+        </van-form>
+    </div>
+</template>
+  
+<script setup>
+import { ref, getCurrentInstance, onMounted } from "vue";
+import { showSuccessToast, showFailToast } from "vant";
+import { useRoute } from "vue-router";
+import Edit from "@/views/product-material/material-classification/edit.vue";
+
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const showPicker = ref(false);
+const typeModal = ref(false);
+const typeModalOne = ref(false);
+let selectIndex = ref(null);
+const formData = ref({
+    supplierInfoId: "",
+    type: "1",
+    supplierInfoName: "",
+});
+const list = ref([]);
+const handleAddRow = () => {
+    list.value.push({
+        productInfoId: "",
+        productInfoName: "",
+        price: "",
+    });
+};
+const getDict = () => {
+    proxy.post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
+        columns.value = res.data.rows.map((item) => {
+            return {
+                text: item.name,
+                value: item.id,
+            };
+        });
+    });
+
+    proxy
+        .post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "1" })
+        .then((res) => {
+            columnsOne.value = res.data.rows.map((item) => {
+                return {
+                    text: item.name,
+                    value: item.id,
+                };
+            });
+        });
+};
+
+
+const columns = ref([]);
+const columnsOne = ref([]);
+
+const onConfirm = ({ selectedOptions }) => {
+    formData.value.supplierInfoId = selectedOptions[0].value;
+    formData.value.supplierInfoName = selectedOptions[0].text;
+    typeModal.value = false;
+};
+
+const onConfirmOne = ({selectedOptions}) => {
+    formData.value.productInfoId = selectedOptions[0].value;
+    formData.value.productInfoName = selectedOptions[0].text;
+    typeModalOne.value = false;
+};
+
+const handleSelect = (index) => {
+    typeModalOne.value = true;
+};
+
+const handleDel = (index) => {
+    list.value.splice(index, 1);
+};
+
+const onClickLeft = () => history.back();
+
+const editSubmit = () => {
+    console.log(formData.value)
+    console.log(route.query)
+    proxy.post("/supplierPrice/edit", formData.value).then(
+        (res) => {
+            setTimeout(() => {
+                showSuccessToast("修改成功");
+                proxy.$router.push("/main/priceConfig");
+            }, 500);
+        },
+        (err) => {
+            return showFailToast(err.message);
+        }
+    );
+};
+
+onMounted(() => {
+    console.log(route.query)
+    formData.value = {
+        supplierInfoName: route.query.supplierInfoName,
+        productInfoName: route.query.productInfoName,
+        id: route.query.id,
+        supplierInfoId: route.query.supplierInfoId,
+        productInfoId: route.query.productInfoId,
+        price: route.query.price,
+    }
+    getDict();
+});
+</script>
+<style lang="scss" scoped>
+.row {
+    display: flex;
+    padding: 5px 10px 0 10px;
+    justify-content: space-between;
+    align-items: center;
+
+    .title {
+        flex: 1;
+    }
+
+    .delete {
+        width: 20px;
+        cursor: pointer;
+        text-align: center;
+    }
+}
+</style>

+ 122 - 0
src/views/procurementManagement/priceConfig/index.vue

@@ -0,0 +1,122 @@
+<template>
+    <van-nav-bar
+      title="供应价格"
+      left-text=""
+      left-arrow
+      @click-left="onClickLeft"
+      @click-right="onClickRight"
+    >
+      <template #right> 添加 </template>
+    </van-nav-bar>
+    <van-search
+      v-model="req.keyword"
+      placeholder="请输入搜索关键词"
+      @search="onRefresh"
+    />
+    <van-pull-refresh v-model="loading" @refresh="onRefresh">
+      <div class="list">
+        <van-list
+          v-model:loading="loading"
+          :finished="finished"
+          finished-text="没有更多了"
+          @load="onLoad"
+          style="margin-bottom: 60px"
+        >
+          <commonList
+            :data="listData"
+            @onClick="toDtl"
+            :config="listConfig"
+          ></commonList>
+        </van-list>
+      </div>
+    </van-pull-refresh>
+  </template>
+  <script setup>
+  import { ref, getCurrentInstance, onMounted } from "vue";
+  import commonList from "@/components/common-list.vue";
+  import { useRoute } from "vue-router";
+  const loading = ref(false);
+  const router = useRoute();
+  const req = ref({
+    pageNum: 1,
+    type: "1",
+    keyword: null,
+  });
+  const finished = ref(false);
+  const proxy = getCurrentInstance().proxy;
+  const listData = ref([]);
+  
+  const listConfig = ref([
+    {
+      label: "供应商",
+      prop: "supplierName",
+    },
+    {
+      label: "物品名称",
+      prop: "productName",
+    },
+    {
+      label: "供应单价",
+      prop: "price",
+    },
+  ]);
+  const onRefresh = () => {
+    req.value.pageNum = 1;
+    finished.value = false;
+    getList("refresh");
+  };
+  const onLoad = () => {
+    getList();
+  };
+  
+  const onClickLeft = () => {
+    proxy.$router.push("/main/working");
+  }
+  
+  const onClickRight = () => {
+    proxy.$router.push({
+      path: "priceConfigAdd",
+      query: {
+        type:'add'
+      },
+    });
+  };
+  
+  const toDtl = (row) => {
+    proxy.$router.push({
+      path: "priceConfigEdit",
+      query: {
+        ...row,
+        type:'edit'
+      },
+    });
+  };
+  
+  const getList = (type) => {
+    loading.value = true;
+    proxy
+      .post("/supplierPrice/page", req.value)
+      .then((res) => {
+        console.log(req.value);
+        listData.value =
+          type === "refresh"
+            ? res.data.rows
+            : listData.value.concat(res.data.rows);
+        if (req.value.pageNum * 10 >= res.data.total) {
+          finished.value = true;
+        }
+        req.value.pageNum++;
+        loading.value = false;
+      })
+      .catch((err) => {
+        loading.value = false;
+      });
+  };
+  getList();
+  </script>
+  
+  <style lang="scss" scoped>
+  .list {
+    min-height: 70vh;
+  }
+  </style>

+ 293 - 0
src/views/procurementManagement/supplierConfig/add.vue

@@ -0,0 +1,293 @@
+<template>
+	<div class="form">
+		<van-nav-bar title="供应商管理" left-text="返回" left-arrow @click-left="onClickLeft"> </van-nav-bar>
+		<van-form @submit="onSubmit" label-align="top" style="margin-top: 20px; overflow-y: auto">
+			<van-cell-group inset>
+				<van-field v-model="formData.typeName" is-link readonly label="供应商类型" placeholder="请选择供应商类型"
+					@click="typeModal = true" :rules="[{ required: true, message: '供应商类型不能为空' }]" required />
+				<van-popup v-model:show="typeModal" position="bottom">
+					<van-picker :columns="classification" @confirm="onConfirmType" @cancel="typeModal = false" />
+				</van-popup>
+
+				<van-field v-model="formData.name" name="供应商名称" label="供应商名称" placeholder="请填写供应商名称"
+					:rules="[{ required: true, message: '供应商名称不能为空' }]" required />
+
+				<van-field v-model="formData.cityName" is-link readonly label="所在城市" placeholder="选择所在城市"
+					@click="cityModal = true" :rules="[{ required: true, message: '所在城市不能为空' }]" required />
+				<van-popup v-model:show="cityModal" round position="bottom">
+					<van-cascader v-model="formData.city" title="请选择所在地区" :options="areaInfo" @close="showArea = false"
+						@change="cityOnChange" @finish="getAreaInfo" />
+
+				</van-popup>
+				<van-field v-model="formData.areaDetail" rows="3" type="textarea" name="详细地址" label="详细地址"
+					placeholder="请填写详细地址" />
+
+				<van-field v-model="formData.contactPerson" name="联系人" label="联系人" placeholder="请填写联系人"
+					:rules="[{ required: true, message: '联系人不能为空' }]" required />
+
+				<van-field v-model="formData.contactNumber" name="联系电话" label="联系电话" placeholder="请填写联系电话"
+					:rules="[{ required: true, message: '联系电话不能为空' }]" required />
+				<van-field name="uploader" label="文件上传">
+					<template #input>
+						<van-uploader v-model="fileList" :after-read="afterRead" multiple :max-count="9"
+							:max-size="5 * 1024 * 1024" @oversize="onOversize" />
+					</template>
+				</van-field>
+			</van-cell-group>
+			<div style="margin: 16px">
+				<van-button round block type="primary" native-type="submit"> 提交 </van-button>
+			</div>
+		</van-form>
+	</div>
+</template>
+  
+<script setup>
+import { ref, getCurrentInstance, onMounted } from "vue";
+import { showSuccessToast, showToast } from "vant";
+import { useRoute } from "vue-router";
+import { showLoadingToast, closeToast, showNotify } from 'vant';
+
+const proxy = getCurrentInstance().proxy;
+const route = useRoute();
+const show = ref(false);
+const typeModal = ref(false);
+const cityModal = ref(false);
+const areaInfo = ref([]);
+const classification = ref([
+	{
+		text: "贸易商",
+		value: 1,
+	},
+	{
+		text: "工厂",
+		value: 2,
+	}
+]);
+const fieldNames = {
+	text: "label",
+	value: "id",
+};
+const typeList = ref([
+	{
+		text: "原料",
+		value: "1",
+	},
+	{
+		text: "辅料",
+		value: "2",
+	},
+	{
+		text: "配件",
+		value: "3",
+	},
+	{
+		text: "包材",
+		value: "4",
+	},
+	{
+		text: "其他",
+		value: "5",
+	},
+]);
+const unitList = ref([
+	{
+		text: "个",
+		value: "个",
+	},
+	{
+		text: "双",
+		value: "双",
+	},
+]);
+const formData = ref({
+	id: null,
+	definition: "2",
+	productClassifyId: null,
+	productClassifyName: null,
+	code: null,
+	customCode: null,
+	type: null,
+	typeName: null,
+	name: null,
+	spec: null,
+	unit: null,
+	remark: null,
+	fileList: [],
+});
+const onConfirmType = ({ selectedOptions }) => {
+	formData.value.type = selectedOptions[0].value;
+	formData.value.typeName = selectedOptions[0].text;
+	typeModal.value = false;
+};
+const cityOnChange = (selectedOptions) => {
+
+	getAreaInfo(selectedOptions)
+};
+const onConfirmCity = (selectedOptions) => {
+	console.log(selectedOptions)
+};
+
+const getAreaInfo = (selectedOptions) => {
+	showLoadingToast('加载中...');
+	proxy.post("/areaInfo/list", { parentId: selectedOptions.value }).then((res) => {
+		let countryIndex = selectedOptions.selectedOptions[0].index;
+		let provinceIndex = selectedOptions.tabIndex === 1 ? selectedOptions.selectedOptions[1].index : null;
+		let cityIndex = selectedOptions.tabIndex === 2 ? selectedOptions.selectedOptions[2].index : null;
+		//已经没有下级数据
+		if (res.data.length === 0) {
+			if (selectedOptions.tabIndex === 1) {
+				formData.value.cityName = selectedOptions.selectedOptions.map((item) => item.text).join(' ');
+				cityModal.value = false;
+				formData.value.selectedOptions = selectedOptions;
+				return;
+			}
+		}
+		if (selectedOptions.tabIndex === 2) {
+			formData.value.cityName = selectedOptions.selectedOptions.map((item) => item.text).join(' ');
+			cityModal.value = false;
+			formData.value.selectedOptions = selectedOptions;
+			return;
+		}
+		if (selectedOptions.tabIndex === 0) {
+			areaInfo.value[countryIndex].children = res.data.map((item, index) => {
+				return {
+					...item,
+					index: index,
+					text: item.name,
+					value: item.id,
+				};
+			});
+		} else if (selectedOptions.tabIndex === 1) {
+			areaInfo.value[countryIndex].children[provinceIndex].children = res.data.map((item, index) => {
+				return {
+					...item,
+					index: index,
+					text: item.name,
+					value: item.id,
+				};
+			});
+		} else if (selectedOptions.tabIndex === 2) {
+			areaInfo.value[countryIndex].children[provinceIndex].children[cityIndex].children = res.data.map((item, index) => {
+				return {
+					...item,
+					index: index,
+					text: item.name,
+					value: item.id,
+				};
+			});
+		}
+		console.log(areaInfo)
+		closeToast();
+	});
+};
+
+
+const fileList = ref([]);
+const afterRead = (file) => {
+	if (file && file.length > 0) {
+		for (let i = 0; i < file.length; i++) {
+			file[i].status = "uploading";
+			file[i].message = "上传中...";
+			proxy.post("/fileInfo/getSing", { fileName: file[i].file.name }).then(
+				(res) => {
+					let forms = new FormData();
+					forms.append("file", file[i].file);
+					proxy.post("https://winfaster.obs.cn-south-1.myhuaweicloud.com", { ...res.data.uploadBody, file: forms.get("file") }).then(
+						() => {
+							file[i].id = res.data.id;
+							file[i].url = res.data.fileUrl;
+							file[i].fileName = res.data.fileName;
+							delete file[i].status;
+							delete file[i].message;
+						},
+						() => {
+							file[i].status = "failed";
+							file[i].message = "上传失败";
+						}
+					);
+				},
+				() => {
+					file[i].status = "failed";
+					file[i].message = "上传失败";
+				}
+			);
+		}
+	} else {
+		file.status = "uploading";
+		file.message = "上传中...";
+		proxy.post("/fileInfo/getSing", { fileName: file.file.name }).then(
+			(res) => {
+				let forms = new FormData();
+				forms.append("file", file.file);
+				proxy.post("https://winfaster.obs.cn-south-1.myhuaweicloud.com", { ...res.data.uploadBody, file: forms.get("file") }).then(
+					() => {
+						file.id = res.data.id;
+						file.url = res.data.fileUrl;
+						file.fileName = res.data.fileName;
+						delete file.status;
+						delete file.message;
+					},
+					() => {
+						file.status = "failed";
+						file.message = "上传失败";
+					}
+				);
+			},
+			() => {
+				file.status = "failed";
+				file.message = "上传失败";
+			}
+		);
+	}
+};
+const onOversize = () => {
+	showToast("文件大小不能超过 5MB");
+};
+const onClickLeft = () => history.back();
+const onSubmit = () => {
+	if (fileList.value && fileList.value.length > 0) {
+		formData.value.fileList = fileList.value.map((item) => {
+			return {
+				id: item.id,
+				fileName: item.fileName,
+			};
+		});
+	} else {
+		formData.value.fileList = [];
+	}
+	console.log(formData.value.selectedOptions)
+	if(formData.value.selectedOptions) {
+		formData.value.countryId = formData.value.selectedOptions.selectedOptions[0].value;
+		formData.value.provinceId = formData.value.selectedOptions.tabIndex === 2 ? formData.value.selectedOptions.selectedOptions[1].value : null
+		formData.value.cityId = formData.value.selectedOptions.tabIndex === 1 ? 
+								formData.value.selectedOptions.selectedOptions[1].value : 
+								formData.value.selectedOptions.selectedOptions[2].value;
+	}
+	proxy.post("/supplierInfo/" + route.query.type, formData.value).then(() => {
+		showSuccessToast(route.query.type == 'add' ? '添加成功' : '修改成功');
+		setTimeout(() => {
+			history.back();
+		}, 500);
+	});
+};
+
+onMounted(() => {
+	proxy.post("/areaInfo/list", formData.value).then((res) => {
+		areaInfo.value = res.data.map((item, index) => {
+			return {
+				...item,
+				index: index,
+				text: item.chineseName,
+				value: item.id,
+				children: []
+			};
+		});
+	});
+	if(route.query.type == 'add') return
+	proxy.post("/supplierInfo/detail", { id: route.query.id }).then((res) => {
+		formData.value = res.data
+		formData.value.typeName = res.data.type == 1 ? '供应商' : '客户'
+	})
+});
+</script>
+  

+ 123 - 0
src/views/procurementManagement/supplierConfig/index.vue

@@ -0,0 +1,123 @@
+<template>
+    <van-nav-bar title="供应商信息" left-text="" left-arrow @click-left="onClickLeft" @click-right="onClickRight">
+      <template #right> 添加 </template>
+    </van-nav-bar>
+    <van-search v-model="req.keyword" placeholder="请输入搜索关键词" @search="onRefresh" />
+    <van-pull-refresh v-model="loading" @refresh="onRefresh">
+      <div class="list">
+        <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad" style="margin-bottom: 60px">
+          <commonList :data="listData" @onClick="toDtl" :config="listConfig"></commonList>
+        </van-list>
+      </div>
+    </van-pull-refresh>
+  </template>
+  <script setup>
+  import { ref, getCurrentInstance } from "vue";
+  import commonList from "@/components/common-list.vue";
+  import { useRoute } from "vue-router";
+  
+  const loading = ref(false);
+  const router = useRoute();
+  const req = ref({
+    pageNum: 1,
+    keyword: null,
+    definition: "2",
+  });
+  const finished = ref(false);
+  const proxy = getCurrentInstance().proxy;
+  const listData = ref([]);
+  const classification = ref([]);
+  const listConfig = ref([
+    {
+      label: "供应商类型",
+      prop: "typeName",
+    },
+    {
+      label: "供应商名称",
+      prop: "name",
+    },
+    {
+      label: "联系人信息",
+      prop: "contactPerson",
+    },
+  ]);
+  const onRefresh = () => {
+    req.value.pageNum = 1;
+    finished.value = false;
+    getList("refresh");
+  };
+  const onLoad = () => {
+    getClassification();
+  };
+  const onClickLeft = () => proxy.$router.push("/main/working");
+  const onClickRight = () => {
+    proxy.$router.push({
+      path: "supplierConfigAdd",
+      query: {
+          type: 'add'
+      },
+    });
+  };
+  const toDtl = (row) => {
+    proxy.$router.push({
+      path: "supplierConfigAdd",
+      query: {
+        id: row.id,
+        type: 'edit'
+      },
+    });
+  };
+  const treeToList = (arr) => {
+    let res = []; // 用于存储递归结果(扁平数据)
+    // 递归函数
+    let fn = (source) => {
+      source.forEach((el) => {
+        res.push(el);
+        el.children && el.children.length > 0 ? fn(el.children) : ""; // 子级递归
+      });
+    };
+    fn(arr);
+    return res;
+  };
+  const getClassification = () => {
+    if (classification.value && classification.value.length > 0) {
+      getList();
+    } else {
+      proxy.post("/productClassify/tree", { parentId: "", name: "", definition: "2" }).then((res) => {
+        classification.value = treeToList(res.data);
+        getList();
+      });
+    }
+  };
+  const getList = (type) => {
+    loading.value = true;
+    proxy
+      .post("/supplierInfo/page", req.value)
+      .then((res) => {
+        res.data.rows = res.data.rows.map((item) => {
+          
+          return {
+            ...item,
+            contactPersonInfo: item.contactPerson + ' ' + item.contactPhone,
+            typeName: item.type === 1 ? '贸易商' : '工厂',
+          };
+        });
+        listData.value = type === "refresh" ? res.data.rows : listData.value.concat(res.data.rows);
+        if (req.value.pageNum * 10 >= res.data.total) {
+          finished.value = true;
+        }
+        req.value.pageNum++;
+        loading.value = false;
+      })
+      .catch((err) => {
+        loading.value = false;
+      });
+  };
+  </script>
+  
+  <style lang="scss" scoped>
+  .list {
+    min-height: 70vh;
+  }
+  </style>
+  

+ 5 - 0
yarn.lock

@@ -1309,6 +1309,11 @@
   dependencies:
     "@types/node" "*"
 
+"@vant/area-data@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmmirror.com/@vant/area-data/-/area-data-1.4.1.tgz#b4f1bce05dbb147dc08fd2ed9b2a0f63d3329b29"
+  integrity sha512-D8zI/rfxREhnIKGoYzsEJZ73fte4JARhFeFftLIH7ynu1sPrCBEgPkLEbwPyvw3VC4JdSIuzaK5uOhu+BcoPXw==
+
 "@vant/popperjs@^1.3.0":
   version "1.3.0"
   resolved "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz#e0eff017124b5b2352ef3b36a6df06277f4400f2"