9
0

2 Commits 7156b6f663 ... 153cc20d06

Autor SHA1 Nachricht Datum
  林小张 153cc20d06 Merge remote-tracking branch 'origin/master' vor 1 Monat
  林小张 fa8d3878db 1-26-zl vor 2 Monaten

+ 193 - 0
src/api/partner.ts

@@ -0,0 +1,193 @@
+import request from '@/utils/request';
+
+// 获取当前用户的伙伴商信息
+export function getCurrentPartnerInfo() {
+  return request({
+    url: '/customer/partnerInfo/current',
+    method: 'get'
+  });
+}
+
+// 修改伙伴商基本信息
+export function updatePartnerInfo(data: any) {
+  return request({
+    url: '/customer/partnerInfo',
+    method: 'put',
+    data
+  });
+}
+
+// 获取伙伴商银行列表
+export function getPartnerBankList(partnerId: number) {
+  return request({
+    url: '/customer/partnerBank/list',
+    method: 'get',
+    params: { partnerId }
+  });
+}
+
+// 获取伙伴商联系人列表
+export function getPartnerContactsList(partnerId: number) {
+  return request({
+    url: '/customer/partnerContacts/list',
+    method: 'get',
+    params: { partnerId }
+  });
+}
+
+// 获取伙伴商合同列表
+export function getPartnerContractList(partnerId: number) {
+  return request({
+    url: '/customer/partnerContract/list',
+    method: 'get',
+    params: { partnerId }
+  });
+}
+
+// 获取伙伴商仓库列表
+export function getPartnerWarehouseList(partnerId: number) {
+  return request({
+    url: '/customer/partnerWarehouse/list',
+    method: 'get',
+    params: { partnerId }
+  });
+}
+
+// 获取伙伴商资质列表
+export function getPartnerQualificationList(partnerId: number) {
+  return request({
+    url: '/customer/partnerQualification/list',
+    method: 'get',
+    params: { partnerId }
+  });
+}
+
+// 新增伙伴商银行账户
+export function addPartnerBank(data: any) {
+  return request({
+    url: '/customer/partnerBank',
+    method: 'post',
+    data
+  });
+}
+
+// 修改伙伴商银行账户
+export function updatePartnerBank(data: any) {
+  return request({
+    url: '/customer/partnerBank',
+    method: 'put',
+    data
+  });
+}
+
+// 删除伙伴商银行账户
+export function deletePartnerBank(ids: number[]) {
+  return request({
+    url: `/customer/partnerBank/${ids.join(',')}`,
+    method: 'delete'
+  });
+}
+
+// 新增伙伴商联系人
+export function addPartnerContacts(data: any) {
+  return request({
+    url: '/customer/partnerContacts',
+    method: 'post',
+    data
+  });
+}
+
+// 修改伙伴商联系人
+export function updatePartnerContacts(data: any) {
+  return request({
+    url: '/customer/partnerContacts',
+    method: 'put',
+    data
+  });
+}
+
+// 删除伙伴商联系人
+export function deletePartnerContacts(ids: number[]) {
+  return request({
+    url: `/customer/partnerContacts/${ids.join(',')}`,
+    method: 'delete'
+  });
+}
+
+// 新增伙伴商合同
+export function addPartnerContract(data: any) {
+  return request({
+    url: '/customer/partnerContract',
+    method: 'post',
+    data
+  });
+}
+
+// 修改伙伴商合同
+export function updatePartnerContract(data: any) {
+  return request({
+    url: '/customer/partnerContract',
+    method: 'put',
+    data
+  });
+}
+
+// 删除伙伴商合同
+export function deletePartnerContract(ids: number[]) {
+  return request({
+    url: `/customer/partnerContract/${ids.join(',')}`,
+    method: 'delete'
+  });
+}
+
+// 新增伙伴商仓库
+export function addPartnerWarehouse(data: any) {
+  return request({
+    url: '/customer/partnerWarehouse',
+    method: 'post',
+    data
+  });
+}
+
+// 修改伙伴商仓库
+export function updatePartnerWarehouse(data: any) {
+  return request({
+    url: '/customer/partnerWarehouse',
+    method: 'put',
+    data
+  });
+}
+
+// 删除伙伴商仓库
+export function deletePartnerWarehouse(ids: number[]) {
+  return request({
+    url: `/customer/partnerWarehouse/${ids.join(',')}`,
+    method: 'delete'
+  });
+}
+
+// 新增伙伴商资质
+export function addPartnerQualification(data: any) {
+  return request({
+    url: '/customer/partnerQualification',
+    method: 'post',
+    data
+  });
+}
+
+// 修改伙伴商资质
+export function updatePartnerQualification(data: any) {
+  return request({
+    url: '/customer/partnerQualification',
+    method: 'put',
+    data
+  });
+}
+
+// 删除伙伴商资质
+export function deletePartnerQualification(ids: number[]) {
+  return request({
+    url: `/customer/partnerQualification/${ids.join(',')}`,
+    method: 'delete'
+  });
+}

+ 177 - 0
src/views/partner/info/components/Bank.vue

@@ -0,0 +1,177 @@
+<template>
+  <div class="bank">
+    <div class="toolbar">
+      <el-button type="primary" @click="handleAdd">新增</el-button>
+    </div>
+    <el-table :data="bankList" border>
+      <el-table-column prop="accountBankName" label="开户银行名称" />
+      <el-table-column prop="account" label="开户名称" />
+      <el-table-column prop="bankNumber" label="银行账号" />
+      <el-table-column prop="bankLocation" label="开户银行所在地" />
+      <el-table-column label="操作" width="150">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+      <el-form :model="formData" label-width="140px">
+        <el-form-item label="开户银行名称">
+          <el-input v-model="formData.accountBankName" />
+        </el-form-item>
+        <el-form-item label="开户名称">
+          <el-input v-model="formData.account" />
+        </el-form-item>
+        <el-form-item label="银行账号">
+          <el-input v-model="formData.bankNumber" />
+        </el-form-item>
+        <el-form-item label="开户银行所在地">
+          <el-input v-model="formData.bankLocation" />
+        </el-form-item>
+        <el-form-item label="财务登记号">
+          <el-input v-model="formData.registrationNumber" />
+        </el-form-item>
+        <el-form-item label="银行联行号">
+          <el-input v-model="formData.bankInterbankNumber" />
+        </el-form-item>
+        <el-form-item label="联系电话">
+          <el-input v-model="formData.phone" />
+        </el-form-item>
+        <el-form-item label="地址">
+          <el-input v-model="formData.address" />
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input v-model="formData.remark" type="textarea" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleSubmit">确定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { getCurrentPartnerInfo, getPartnerBankList, addPartnerBank, updatePartnerBank, deletePartnerBank } from '@/api/partner';
+
+const bankList = ref([]);
+const loading = ref(false);
+const dialogVisible = ref(false);
+const dialogTitle = ref('');
+const formData = ref({
+  id: null,
+  partnerId: null,
+  accountBankName: '',
+  account: '',
+  bankNumber: '',
+  bankLocation: '',
+  registrationNumber: '',
+  bankInterbankNumber: '',
+  phone: '',
+  address: '',
+  remark: ''
+});
+
+const fetchBankList = async () => {
+  loading.value = true;
+  try {
+    const partnerResponse = await getCurrentPartnerInfo();
+    if (partnerResponse.code === 200 && partnerResponse.data) {
+      const partnerId = partnerResponse.data.id;
+      formData.value.partnerId = partnerId;
+      const response = await getPartnerBankList(partnerId);
+      if (response.code === 200) {
+        bankList.value = response.rows || response.data || [];
+      }
+    }
+  } catch (error) {
+    console.error('获取银行列表失败', error);
+    ElMessage.error('获取银行列表失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleAdd = () => {
+  dialogTitle.value = '新增银行账户';
+  formData.value = {
+    id: null,
+    partnerId: formData.value.partnerId,
+    accountBankName: '',
+    account: '',
+    bankNumber: '',
+    bankLocation: '',
+    registrationNumber: '',
+    bankInterbankNumber: '',
+    phone: '',
+    address: '',
+    remark: ''
+  };
+  dialogVisible.value = true;
+};
+
+const handleEdit = (row: any) => {
+  dialogTitle.value = '编辑银行账户';
+  formData.value = { ...row };
+  dialogVisible.value = true;
+};
+
+const handleDelete = (row: any) => {
+  ElMessageBox.confirm('确定要删除该银行账户吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      const response = await deletePartnerBank([row.id]);
+      if (response.code === 200) {
+        ElMessage.success('删除成功');
+        fetchBankList();
+      } else {
+        ElMessage.error(response.msg || '删除失败');
+      }
+    } catch (error) {
+      console.error('删除失败', error);
+      ElMessage.error('删除失败');
+    }
+  });
+};
+
+const handleSubmit = async () => {
+  try {
+    const apiCall = formData.value.id ? updatePartnerBank : addPartnerBank;
+    const response = await apiCall(formData.value);
+    if (response.code === 200) {
+      ElMessage.success(formData.value.id ? '修改成功' : '新增成功');
+      dialogVisible.value = false;
+      fetchBankList();
+    } else {
+      ElMessage.error(response.msg || '操作失败');
+    }
+  } catch (error) {
+    console.error('操作失败', error);
+    ElMessage.error('操作失败');
+  }
+};
+
+onMounted(() => {
+  fetchBankList();
+});
+</script>
+
+<style scoped lang="scss">
+.bank {
+  padding: 20px;
+}
+
+.toolbar {
+  margin-bottom: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 204 - 0
src/views/partner/info/components/BasicInfo.vue

@@ -0,0 +1,204 @@
+<template>
+  <div class="basic-info">
+    <div class="info-header">
+      <h3>企业基本信息 / 伙伴商编号:{{ partnerInfo.partnerNo || '-' }}</h3>
+      <div class="header-actions">
+        <template v-if="!isEditing">
+          <el-button type="primary" @click="handleEdit">编辑</el-button>
+        </template>
+        <template v-else>
+          <el-button @click="handleCancel">取消</el-button>
+          <el-button type="primary" @click="handleSave">保存</el-button>
+        </template>
+      </div>
+    </div>
+
+    <el-form :model="partnerInfo" label-width="120px" :disabled="!isEditing">
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="伙伴商全称">
+            <el-input v-model="partnerInfo.partnerName" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="伙伴商编号">
+            <el-input v-model="partnerInfo.partnerNo" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="公司简称">
+            <el-input v-model="partnerInfo.company" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="合作型态">
+            <el-select v-if="isEditing" v-model="partnerInfo.partnerCooperateType" placeholder="请选择">
+              <el-option label="伙伴商" :value="0" />
+              <el-option label="经销商" :value="1" />
+              <el-option label="代理商" :value="2" />
+            </el-select>
+            <el-input v-else :value="formatCooperateType(partnerInfo.partnerCooperateType)" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="法人代表">
+            <el-input v-model="partnerInfo.legal" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="固定电话">
+            <el-input v-model="partnerInfo.telephone" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="传真号码">
+            <el-input v-model="partnerInfo.fax" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="16">
+          <el-form-item label="公司注册地址">
+            <el-input v-model="partnerInfo.registerAddress" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="24">
+          <el-form-item label="分司注册地址">
+            <el-input v-model="partnerInfo.operatingAddress" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="24">
+          <el-form-item label="备注">
+            <el-input v-model="partnerInfo.remark" type="textarea" :rows="3" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+
+    <div v-if="loading" class="loading">加载中...</div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+import { ElMessage } from 'element-plus';
+import { getCurrentPartnerInfo, updatePartnerInfo } from '@/api/partner';
+
+const partnerInfo = ref({
+  id: null,
+  partnerNo: '',
+  partnerName: '',
+  company: '',
+  partnerCooperateType: '',
+  legal: '',
+  telephone: '',
+  fax: '',
+  registerAddress: '',
+  operatingAddress: '',
+  remark: ''
+});
+
+const originalData = ref({});
+const loading = ref(false);
+const isEditing = ref(false);
+
+// 合作型态字典转换
+const formatCooperateType = (type: number) => {
+  const typeMap: Record<number, string> = {
+    0: '伙伴商',
+    1: '经销商',
+    2: '代理商'
+  };
+  return typeMap[type] || type;
+};
+
+const fetchPartnerInfo = async () => {
+  loading.value = true;
+  try {
+    const response = await getCurrentPartnerInfo();
+    if (response.code === 200) {
+      partnerInfo.value = response.data;
+      originalData.value = { ...response.data };
+    } else {
+      ElMessage.error(response.msg || '获取伙伴商信息失败');
+    }
+  } catch (error) {
+    console.error('获取伙伴商信息失败', error);
+    ElMessage.error('获取伙伴商信息失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleEdit = () => {
+  isEditing.value = true;
+  originalData.value = { ...partnerInfo.value };
+};
+
+const handleCancel = () => {
+  partnerInfo.value = { ...originalData.value };
+  isEditing.value = false;
+};
+
+const handleSave = async () => {
+  try {
+    const response = await updatePartnerInfo(partnerInfo.value);
+    if (response.code === 200) {
+      ElMessage.success('保存成功');
+      isEditing.value = false;
+      fetchPartnerInfo();
+    } else {
+      ElMessage.error(response.msg || '保存失败');
+    }
+  } catch (error) {
+    console.error('保存失败', error);
+    ElMessage.error('保存失败');
+  }
+};
+
+onMounted(() => {
+  fetchPartnerInfo();
+});
+</script>
+
+<style scoped lang="scss">
+.basic-info {
+  padding: 20px;
+}
+
+.info-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding-bottom: 10px;
+  border-bottom: 1px solid #eee;
+
+  h3 {
+    margin: 0;
+    font-size: 16px;
+    color: #333;
+  }
+
+  .header-actions {
+    display: flex;
+    gap: 10px;
+  }
+}
+
+.loading {
+  text-align: center;
+  padding: 20px;
+  color: #999;
+}
+</style>

+ 160 - 0
src/views/partner/info/components/Contacts.vue

@@ -0,0 +1,160 @@
+<template>
+  <div class="contacts">
+    <div class="toolbar">
+      <el-button type="primary" @click="handleAdd">新增</el-button>
+    </div>
+    <el-table :data="contactsList" border>
+      <el-table-column prop="name" label="联系人姓名" />
+      <el-table-column prop="phone" label="联系电话" />
+      <el-table-column prop="email" label="电子邮箱" />
+      <el-table-column prop="contactType" label="联系人类型" />
+      <el-table-column label="操作" width="150">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+      <el-form :model="formData" label-width="120px">
+        <el-form-item label="联系人姓名">
+          <el-input v-model="formData.name" />
+        </el-form-item>
+        <el-form-item label="联系电话">
+          <el-input v-model="formData.phone" />
+        </el-form-item>
+        <el-form-item label="电子邮箱">
+          <el-input v-model="formData.email" />
+        </el-form-item>
+        <el-form-item label="联系人类型">
+          <el-select v-model="formData.contactType" placeholder="请选择">
+            <el-option label="主要联系人" :value="1" />
+            <el-option label="次要联系人" :value="2" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input v-model="formData.remark" type="textarea" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleSubmit">确定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { getCurrentPartnerInfo, getPartnerContactsList, addPartnerContacts, updatePartnerContacts, deletePartnerContacts } from '@/api/partner';
+
+const contactsList = ref([]);
+const loading = ref(false);
+const dialogVisible = ref(false);
+const dialogTitle = ref('');
+const formData = ref({
+  id: null,
+  partnerId: null,
+  name: '',
+  phone: '',
+  email: '',
+  contactType: null,
+  remark: ''
+});
+
+const fetchContactsList = async () => {
+  loading.value = true;
+  try {
+    const partnerResponse = await getCurrentPartnerInfo();
+    if (partnerResponse.code === 200 && partnerResponse.data) {
+      const partnerId = partnerResponse.data.id;
+      formData.value.partnerId = partnerId;
+      const response = await getPartnerContactsList(partnerId);
+      if (response.code === 200) {
+        contactsList.value = response.rows || response.data || [];
+      }
+    }
+  } catch (error) {
+    console.error('获取联系人列表失败', error);
+    ElMessage.error('获取联系人列表失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleAdd = () => {
+  dialogTitle.value = '新增联系人';
+  formData.value = {
+    id: null,
+    partnerId: formData.value.partnerId,
+    name: '',
+    phone: '',
+    email: '',
+    contactType: null,
+    remark: ''
+  };
+  dialogVisible.value = true;
+};
+
+const handleEdit = (row: any) => {
+  dialogTitle.value = '编辑联系人';
+  formData.value = { ...row };
+  dialogVisible.value = true;
+};
+
+const handleDelete = (row: any) => {
+  ElMessageBox.confirm('确定要删除该联系人吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      const response = await deletePartnerContacts([row.id]);
+      if (response.code === 200) {
+        ElMessage.success('删除成功');
+        fetchContactsList();
+      } else {
+        ElMessage.error(response.msg || '删除失败');
+      }
+    } catch (error) {
+      console.error('删除失败', error);
+      ElMessage.error('删除失败');
+    }
+  });
+};
+
+const handleSubmit = async () => {
+  try {
+    const apiCall = formData.value.id ? updatePartnerContacts : addPartnerContacts;
+    const response = await apiCall(formData.value);
+    if (response.code === 200) {
+      ElMessage.success(formData.value.id ? '修改成功' : '新增成功');
+      dialogVisible.value = false;
+      fetchContactsList();
+    } else {
+      ElMessage.error(response.msg || '操作失败');
+    }
+  } catch (error) {
+    console.error('操作失败', error);
+    ElMessage.error('操作失败');
+  }
+};
+
+onMounted(() => {
+  fetchContactsList();
+});
+</script>
+
+<style scoped lang="scss">
+.contacts {
+  padding: 20px;
+}
+
+.toolbar {
+  margin-bottom: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 172 - 0
src/views/partner/info/components/Contract.vue

@@ -0,0 +1,172 @@
+<template>
+  <div class="contract">
+    <div class="toolbar">
+      <el-button type="primary" @click="handleAdd">新增</el-button>
+    </div>
+    <el-table :data="contractList" border>
+      <el-table-column prop="contractNo" label="合同编号" />
+      <el-table-column prop="cooperativeName" label="合作项目名称" />
+      <el-table-column prop="startTime" label="合作开始时间" />
+      <el-table-column prop="endTime" label="合作结束时间" />
+      <el-table-column label="操作" width="150">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+      <el-form :model="formData" label-width="140px">
+        <el-form-item label="合同编号">
+          <el-input v-model="formData.contractNo" />
+        </el-form-item>
+        <el-form-item label="合作项目名称">
+          <el-input v-model="formData.cooperativeName" />
+        </el-form-item>
+        <el-form-item label="合作开始时间">
+          <el-date-picker v-model="formData.startTime" type="date" placeholder="选择日期" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="合作结束时间">
+          <el-date-picker v-model="formData.endTime" type="date" placeholder="选择日期" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="合作包类">
+          <el-input v-model="formData.categories" />
+        </el-form-item>
+        <el-form-item label="联系人">
+          <el-input v-model="formData.contacts" />
+        </el-form-item>
+        <el-form-item label="联系电话">
+          <el-input v-model="formData.phone" />
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input v-model="formData.remark" type="textarea" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleSubmit">确定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { getCurrentPartnerInfo, getPartnerContractList, addPartnerContract, updatePartnerContract, deletePartnerContract } from '@/api/partner';
+
+const contractList = ref([]);
+const loading = ref(false);
+const dialogVisible = ref(false);
+const dialogTitle = ref('');
+const formData = ref({
+  id: null,
+  partnerId: null,
+  contractNo: '',
+  cooperativeName: '',
+  startTime: null,
+  endTime: null,
+  categories: '',
+  contacts: '',
+  phone: '',
+  remark: ''
+});
+
+const fetchContractList = async () => {
+  loading.value = true;
+  try {
+    const partnerResponse = await getCurrentPartnerInfo();
+    if (partnerResponse.code === 200 && partnerResponse.data) {
+      const partnerId = partnerResponse.data.id;
+      formData.value.partnerId = partnerId;
+      const response = await getPartnerContractList(partnerId);
+      if (response.code === 200) {
+        contractList.value = response.rows || response.data || [];
+      }
+    }
+  } catch (error) {
+    console.error('获取合同列表失败', error);
+    ElMessage.error('获取合同列表失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleAdd = () => {
+  dialogTitle.value = '新增合同';
+  formData.value = {
+    id: null,
+    partnerId: formData.value.partnerId,
+    contractNo: '',
+    cooperativeName: '',
+    startTime: null,
+    endTime: null,
+    categories: '',
+    contacts: '',
+    phone: '',
+    remark: ''
+  };
+  dialogVisible.value = true;
+};
+
+const handleEdit = (row: any) => {
+  dialogTitle.value = '编辑合同';
+  formData.value = { ...row };
+  dialogVisible.value = true;
+};
+
+const handleDelete = (row: any) => {
+  ElMessageBox.confirm('确定要删除该合同吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      const response = await deletePartnerContract([row.id]);
+      if (response.code === 200) {
+        ElMessage.success('删除成功');
+        fetchContractList();
+      } else {
+        ElMessage.error(response.msg || '删除失败');
+      }
+    } catch (error) {
+      console.error('删除失败', error);
+      ElMessage.error('删除失败');
+    }
+  });
+};
+
+const handleSubmit = async () => {
+  try {
+    const apiCall = formData.value.id ? updatePartnerContract : addPartnerContract;
+    const response = await apiCall(formData.value);
+    if (response.code === 200) {
+      ElMessage.success(formData.value.id ? '修改成功' : '新增成功');
+      dialogVisible.value = false;
+      fetchContractList();
+    } else {
+      ElMessage.error(response.msg || '操作失败');
+    }
+  } catch (error) {
+    console.error('操作失败', error);
+    ElMessage.error('操作失败');
+  }
+};
+
+onMounted(() => {
+  fetchContractList();
+});
+</script>
+
+<style scoped lang="scss">
+.contract {
+  padding: 20px;
+}
+
+.toolbar {
+  margin-bottom: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 63 - 0
src/views/partner/info/components/Qualification.vue

@@ -0,0 +1,63 @@
+<template>
+  <div class="qualification">
+    <el-table :data="qualificationList" border>
+      <el-table-column prop="qualificationType" label="资质类型" />
+      <el-table-column prop="qualificationNo" label="资质证书编号" />
+      <el-table-column prop="authority" label="签发机构" />
+      <el-table-column prop="deadline" label="截止日期" />
+      <el-table-column label="操作" width="150">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleView(scope.row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+import { ElMessage } from 'element-plus';
+import { getCurrentPartnerInfo, getPartnerQualificationList } from '@/api/partner';
+
+const qualificationList = ref([]);
+const loading = ref(false);
+
+const handleView = (row: any) => {
+  console.log('查看资质', row);
+};
+
+const fetchQualificationList = async () => {
+  loading.value = true;
+  try {
+    const partnerResponse = await getCurrentPartnerInfo();
+    if (partnerResponse.code === 200 && partnerResponse.data) {
+      const partnerId = partnerResponse.data.id;
+      const response = await getPartnerQualificationList(partnerId);
+      if (response.code === 200) {
+        qualificationList.value = response.rows || response.data || [];
+      }
+    }
+  } catch (error) {
+    console.error('获取资质列表失败', error);
+    ElMessage.error('获取资质列表失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+onMounted(() => {
+  fetchQualificationList();
+});
+</script>
+
+<style scoped lang="scss">
+.qualification {
+  padding: 20px;
+}
+
+.toolbar {
+  margin-bottom: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 176 - 0
src/views/partner/info/components/Warehouse.vue

@@ -0,0 +1,176 @@
+<template>
+  <div class="warehouse">
+    <div class="toolbar">
+      <el-button type="primary" @click="handleAdd">新增</el-button>
+    </div>
+    <el-table :data="warehouseList" border>
+      <el-table-column prop="name" label="仓库名称" />
+      <el-table-column prop="warehouseLocation" label="所在地区" />
+      <el-table-column prop="warehouseAddress" label="所在地址" />
+      <el-table-column prop="warehouseContacts" label="仓库联系人" />
+      <el-table-column prop="phone" label="联系电话" />
+      <el-table-column label="操作" width="150">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+      <el-form :model="formData" label-width="120px">
+        <el-form-item label="仓库名称">
+          <el-input v-model="formData.name" />
+        </el-form-item>
+        <el-form-item label="仓库性质">
+          <el-select v-model="formData.warehouseNature" placeholder="请选择">
+            <el-option label="自有" :value="1" />
+            <el-option label="租赁" :value="2" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="所在地区">
+          <el-input v-model="formData.warehouseLocation" />
+        </el-form-item>
+        <el-form-item label="所在地址">
+          <el-input v-model="formData.warehouseAddress" />
+        </el-form-item>
+        <el-form-item label="仓库面积(m2)">
+          <el-input v-model="formData.warehouseArea" />
+        </el-form-item>
+        <el-form-item label="仓库联系人">
+          <el-input v-model="formData.warehouseContacts" />
+        </el-form-item>
+        <el-form-item label="联系电话">
+          <el-input v-model="formData.phone" />
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input v-model="formData.remark" type="textarea" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleSubmit">确定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { getCurrentPartnerInfo, getPartnerWarehouseList, addPartnerWarehouse, updatePartnerWarehouse, deletePartnerWarehouse } from '@/api/partner';
+
+const warehouseList = ref([]);
+const loading = ref(false);
+const dialogVisible = ref(false);
+const dialogTitle = ref('');
+const formData = ref({
+  id: null,
+  partnerId: null,
+  name: '',
+  warehouseNature: null,
+  warehouseLocation: '',
+  warehouseAddress: '',
+  warehouseArea: '',
+  warehouseContacts: '',
+  phone: '',
+  remark: ''
+});
+
+const fetchWarehouseList = async () => {
+  loading.value = true;
+  try {
+    const partnerResponse = await getCurrentPartnerInfo();
+    if (partnerResponse.code === 200 && partnerResponse.data) {
+      const partnerId = partnerResponse.data.id;
+      formData.value.partnerId = partnerId;
+      const response = await getPartnerWarehouseList(partnerId);
+      if (response.code === 200) {
+        warehouseList.value = response.rows || response.data || [];
+      }
+    }
+  } catch (error) {
+    console.error('获取仓库列表失败', error);
+    ElMessage.error('获取仓库列表失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleAdd = () => {
+  dialogTitle.value = '新增仓库';
+  formData.value = {
+    id: null,
+    partnerId: formData.value.partnerId,
+    name: '',
+    warehouseNature: null,
+    warehouseLocation: '',
+    warehouseAddress: '',
+    warehouseArea: '',
+    warehouseContacts: '',
+    phone: '',
+    remark: ''
+  };
+  dialogVisible.value = true;
+};
+
+const handleEdit = (row: any) => {
+  dialogTitle.value = '编辑仓库';
+  formData.value = { ...row };
+  dialogVisible.value = true;
+};
+
+const handleDelete = (row: any) => {
+  ElMessageBox.confirm('确定要删除该仓库吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      const response = await deletePartnerWarehouse([row.id]);
+      if (response.code === 200) {
+        ElMessage.success('删除成功');
+        fetchWarehouseList();
+      } else {
+        ElMessage.error(response.msg || '删除失败');
+      }
+    } catch (error) {
+      console.error('删除失败', error);
+      ElMessage.error('删除失败');
+    }
+  });
+};
+
+const handleSubmit = async () => {
+  try {
+    const apiCall = formData.value.id ? updatePartnerWarehouse : addPartnerWarehouse;
+    const response = await apiCall(formData.value);
+    if (response.code === 200) {
+      ElMessage.success(formData.value.id ? '修改成功' : '新增成功');
+      dialogVisible.value = false;
+      fetchWarehouseList();
+    } else {
+      ElMessage.error(response.msg || '操作失败');
+    }
+  } catch (error) {
+    console.error('操作失败', error);
+    ElMessage.error('操作失败');
+  }
+};
+
+onMounted(() => {
+  fetchWarehouseList();
+});
+</script>
+
+<style scoped lang="scss">
+.warehouse {
+  padding: 20px;
+}
+
+.toolbar {
+  margin-bottom: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 38 - 0
src/views/partner/info/index.vue

@@ -0,0 +1,38 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeName" type="card">
+      <el-tab-pane label="基本信息" name="basic">
+        <BasicInfo />
+      </el-tab-pane>
+      <el-tab-pane label="银行管理" name="bank">
+        <Bank />
+      </el-tab-pane>
+      <el-tab-pane label="联系管理" name="contacts">
+        <Contacts />
+      </el-tab-pane>
+      <el-tab-pane label="合同管理" name="contract">
+        <Contract />
+      </el-tab-pane>
+      <el-tab-pane label="仓库管理" name="warehouse">
+        <Warehouse />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script setup lang="ts" name="PartnerInfo">
+import { ref } from 'vue';
+import BasicInfo from './components/BasicInfo.vue';
+import Bank from './components/Bank.vue';
+import Contacts from './components/Contacts.vue';
+import Contract from './components/Contract.vue';
+import Warehouse from './components/Warehouse.vue';
+
+const activeName = ref('basic');
+</script>
+
+<style scoped lang="scss">
+.app-container {
+  padding: 20px;
+}
+</style>

+ 185 - 0
src/views/partner/qualification/index.vue

@@ -0,0 +1,185 @@
+<template>
+  <div class="app-container">
+    <div class="qualification-header">
+      <h3>资质管理</h3>
+      <el-button type="primary" @click="handleAdd">新增资质</el-button>
+    </div>
+
+    <el-table :data="qualificationList" border>
+      <el-table-column type="index" label="序号" width="60" />
+      <el-table-column prop="qualificationNo" label="资质编号" />
+      <el-table-column prop="qualificationType" label="资质类型">
+        <template #default="scope">
+          {{ formatQualificationType(scope.row.qualificationType) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="authority" label="签发机构" />
+      <el-table-column prop="deadline" label="截止日期" />
+      <el-table-column label="操作" width="150">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleEdit(scope.row)">修改</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+      <el-form :model="formData" label-width="120px">
+        <el-form-item label="资质类型">
+          <el-select v-model="formData.qualificationType" placeholder="请选择">
+            <el-option label="营业执照" :value="1" />
+            <el-option label="资质证书" :value="2" />
+            <el-option label="其他" :value="3" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="资质证书编号">
+          <el-input v-model="formData.qualificationNo" />
+        </el-form-item>
+        <el-form-item label="签发机构">
+          <el-input v-model="formData.authority" />
+        </el-form-item>
+        <el-form-item label="截止日期">
+          <el-date-picker v-model="formData.deadline" type="date" placeholder="选择日期" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input v-model="formData.remark" type="textarea" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="handleSubmit">确定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts" name="PartnerQualification">
+import { ref, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { getCurrentPartnerInfo, getPartnerQualificationList, addPartnerQualification, updatePartnerQualification, deletePartnerQualification } from '@/api/partner';
+
+const qualificationList = ref([]);
+const loading = ref(false);
+const dialogVisible = ref(false);
+const dialogTitle = ref('');
+const formData = ref({
+  id: null,
+  partnerId: null,
+  qualificationType: null,
+  qualificationNo: '',
+  authority: '',
+  deadline: null,
+  remark: ''
+});
+
+// 资质类型字典转换
+const formatQualificationType = (type: number) => {
+  const typeMap: Record<number, string> = {
+    1: '营业执照',
+    2: '资质证书',
+    3: '其他'
+  };
+  return typeMap[type] || type;
+};
+
+const fetchQualificationList = async () => {
+  loading.value = true;
+  try {
+    const partnerResponse = await getCurrentPartnerInfo();
+    if (partnerResponse.code === 200 && partnerResponse.data) {
+      const partnerId = partnerResponse.data.id;
+      formData.value.partnerId = partnerId;
+      const response = await getPartnerQualificationList(partnerId);
+      if (response.code === 200) {
+        qualificationList.value = response.rows || response.data || [];
+      }
+    }
+  } catch (error) {
+    console.error('获取资质列表失败', error);
+    ElMessage.error('获取资质列表失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleAdd = () => {
+  dialogTitle.value = '新增资质';
+  formData.value = {
+    id: null,
+    partnerId: formData.value.partnerId,
+    qualificationType: null,
+    qualificationNo: '',
+    authority: '',
+    deadline: null,
+    remark: ''
+  };
+  dialogVisible.value = true;
+};
+
+const handleEdit = (row: any) => {
+  dialogTitle.value = '编辑资质';
+  formData.value = { ...row };
+  dialogVisible.value = true;
+};
+
+const handleDelete = (row: any) => {
+  ElMessageBox.confirm('确定要删除该资质吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      const response = await deletePartnerQualification([row.id]);
+      if (response.code === 200) {
+        ElMessage.success('删除成功');
+        fetchQualificationList();
+      } else {
+        ElMessage.error(response.msg || '删除失败');
+      }
+    } catch (error) {
+      console.error('删除失败', error);
+      ElMessage.error('删除失败');
+    }
+  });
+};
+
+const handleSubmit = async () => {
+  try {
+    const apiCall = formData.value.id ? updatePartnerQualification : addPartnerQualification;
+    const response = await apiCall(formData.value);
+    if (response.code === 200) {
+      ElMessage.success(formData.value.id ? '修改成功' : '新增成功');
+      dialogVisible.value = false;
+      fetchQualificationList();
+    } else {
+      ElMessage.error(response.msg || '操作失败');
+    }
+  } catch (error) {
+    console.error('操作失败', error);
+    ElMessage.error('操作失败');
+  }
+};
+
+onMounted(() => {
+  fetchQualificationList();
+});
+</script>
+
+<style scoped lang="scss">
+.app-container {
+  padding: 20px;
+}
+
+.qualification-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+
+  h3 {
+    margin: 0;
+    font-size: 16px;
+    color: #333;
+  }
+}
+</style>