Procházet zdrojové kódy

feat: 重构产品详情显示

laiqi před 11 měsíci
rodič
revize
17bb982ba6

+ 246 - 0
apps/web-ele/src/views/product-manage/detail.vue

@@ -0,0 +1,246 @@
+<script lang="ts" setup>
+import type { CustomerEntity } from '@vben/types';
+
+import { computed, ref } from 'vue';
+
+import { useVbenModal } from '@vben/common-ui';
+
+import { getProductDetailApi } from '#/api/product';
+import { getScqyDetailApi } from '#/api/scqy';
+import { getCustomerListApi } from '#/api/user';
+
+const data = ref<any>(null);
+const loading = ref(false);
+const scqyName = ref('');
+const merchantNames = ref<string[]>([]);
+
+// 产品基本信息
+const productInfo = computed(() => {
+  if (!data.value) return [];
+  return [
+    { label: '产品名称', value: data.value.productsname },
+    { label: '产品型号', value: data.value.productsmodel },
+    { label: '产品类别', value: data.value.productscategory },
+    { label: '机具类型', value: data.value.productsjjlx },
+    // { label: '品目', value: data.value.productspm },
+    {
+      label: '产品价格',
+      value: data.value.productsprice ? `¥${data.value.productsprice}` : '-',
+    },
+    // { label: '一级分类', value: data.value.productsfl1 },
+    // { label: '二级分类', value: data.value.productsfl2 },
+    { label: '创建时间', value: data.value.productsdate },
+  ];
+});
+
+// 补贴信息
+const subsidyInfo = computed(() => {
+  if (!data.value) return [];
+  return [
+    // { label: '分档名称', value: data.value.productsfdmc },
+    // { label: '分档编号', value: data.value.productsfdbh },
+    {
+      label: '中央补贴',
+      value: data.value.productszybt ? `¥${data.value.productszybt}` : '-',
+    },
+    {
+      label: '特殊县中央补贴',
+      value: data.value.productstsxzybt
+        ? `¥${data.value.productstsxzybt}`
+        : '-',
+    },
+  ];
+});
+
+// 生产企业信息
+const scqyInfo = computed(() => {
+  if (!data.value) return [];
+  return [{ label: '生产企业名称', value: scqyName.value || '未关联' }];
+});
+
+// 经销商信息
+const merchantsInfo = computed(() => {
+  if (merchantNames.value.length === 0) {
+    return [{ label: '关联经销商', value: '暂未关联任何经销商' }];
+  }
+  return merchantNames.value.map((name, index) => ({
+    label: `经销商 ${index + 1}`,
+    value: name,
+  }));
+});
+
+// 获取生产企业名称
+const fetchScqyName = async (scqyId: string) => {
+  if (!scqyId) {
+    scqyName.value = '未提供ID';
+    return;
+  }
+  try {
+    const res = await getScqyDetailApi({ scqyinfoid: scqyId });
+    scqyName.value = res.scqyinfomc || '未知企业';
+  } catch (error) {
+    console.error('获取生产企业名称失败:', error);
+    scqyName.value = '获取失败';
+  }
+};
+
+// 获取经销商名称
+const fetchMerchantNames = async (merchantIds: string) => {
+  if (!merchantIds) {
+    merchantNames.value = [];
+    return;
+  }
+  try {
+    const ids = merchantIds.split(',');
+    // 使用 getCustomerListApi 获取所有经销商数据
+    const res = await getCustomerListApi({
+      pageindex: 1,
+      rows: 999,
+      'usersnature.value': '经销商',
+    });
+    if (res.Data) {
+      // 从返回的列表中筛选出ID匹配的经销商
+      const matchedMerchants = res.Data.filter((merchant: CustomerEntity) =>
+        ids.includes(merchant.usersid),
+      );
+      merchantNames.value = matchedMerchants.map(
+        (m: CustomerEntity) => m.usersname || '未知经销商',
+      );
+    } else {
+      merchantNames.value = ['未能获取到经销商列表'];
+    }
+  } catch (error) {
+    console.error('获取经销商名称失败:', error);
+    merchantNames.value = ['获取经销商列表时出错'];
+  }
+};
+
+const [Modal, modalApi] = useVbenModal({
+  title: '产品详情',
+  class: 'w-10/12 max-w-6xl',
+  showCancelButton: false,
+  confirmText: '关闭',
+  onConfirm() {
+    modalApi.close();
+  },
+  async onOpenChange(isOpen) {
+    if (isOpen) {
+      const modalData = modalApi.getData();
+      if (modalData?.row?.productsid) {
+        try {
+          loading.value = true;
+          const detailData = await getProductDetailApi({
+            productsid: modalData.row.productsid,
+          });
+          data.value = detailData;
+
+          // 并行获取关联数据
+          await Promise.all([
+            fetchScqyName(detailData.productsscqyid),
+            fetchMerchantNames(detailData.productsmerchantid),
+          ]);
+        } catch (error) {
+          console.error('获取产品详情失败:', error);
+        } finally {
+          loading.value = false;
+        }
+      }
+    } else {
+      data.value = null;
+      scqyName.value = '';
+      merchantNames.value = [];
+      loading.value = false;
+    }
+  },
+});
+
+function openDetailModal(rowData: any) {
+  modalApi.setData({ row: rowData });
+  modalApi.open();
+}
+
+defineExpose({
+  openDetailModal,
+});
+</script>
+
+<template>
+  <Modal>
+    <div v-loading="loading" class="space-y-5 p-4">
+      <!-- 产品基本信息 -->
+      <div>
+        <el-divider content-position="left">
+          <span class="text-lg font-semibold text-gray-800">产品基本信息</span>
+        </el-divider>
+        <el-descriptions :column="3" border class="mb-4" label-width="140px">
+          <el-descriptions-item
+            v-for="item in productInfo"
+            :key="item.label"
+            :label="item.label"
+          >
+            <span>{{ item.value || '-' }}</span>
+          </el-descriptions-item>
+        </el-descriptions>
+      </div>
+
+      <!-- 补贴信息 -->
+      <div>
+        <el-divider content-position="left">
+          <span class="text-lg font-semibold text-gray-800">补贴信息</span>
+        </el-divider>
+        <el-descriptions :column="2" border class="mb-4" label-width="140px">
+          <el-descriptions-item
+            v-for="item in subsidyInfo"
+            :key="item.label"
+            :label="item.label"
+          >
+            <span>{{ item.value || '-' }}</span>
+          </el-descriptions-item>
+        </el-descriptions>
+      </div>
+
+      <!-- 生产企业信息 -->
+      <div>
+        <el-divider content-position="left">
+          <span class="text-lg font-semibold text-gray-800">
+            生产企业信息
+          </span>
+        </el-divider>
+        <el-descriptions :column="1" border class="mb-4" label-width="140px">
+          <el-descriptions-item
+            v-for="item in scqyInfo"
+            :key="item.label"
+            :label="item.label"
+          >
+            <span>{{ item.value || '-' }}</span>
+          </el-descriptions-item>
+        </el-descriptions>
+      </div>
+
+      <!-- 关联经销商信息 -->
+      <div>
+        <el-divider content-position="left">
+          <span class="text-lg font-semibold text-gray-800">
+            关联经销商信息
+          </span>
+        </el-divider>
+        <el-descriptions
+          :column="2"
+          border
+          class="mb-4"
+          label-width="140px"
+          v-if="merchantsInfo.length > 0"
+        >
+          <el-descriptions-item
+            v-for="item in merchantsInfo"
+            :key="item.label"
+            :label="item.label"
+          >
+            <span>{{ item.value || '-' }}</span>
+          </el-descriptions-item>
+        </el-descriptions>
+        <div v-else class="text-gray-500">暂未关联任何经销商</div>
+      </div>
+    </div>
+  </Modal>
+</template>

+ 5 - 2
apps/web-ele/src/views/product-manage/index.vue

@@ -20,6 +20,7 @@ import {
 import { $t } from '#/locales';
 
 import AddLinkModal from './add-link-modal.vue';
+import ProductDetail from './detail.vue';
 import ProductForm from './form.vue';
 
 // 获取用户信息
@@ -27,6 +28,7 @@ const userStore = useUserStore();
 
 // 新增关联组件ref
 const addLinkModalRef = ref<InstanceType<typeof AddLinkModal>>();
+const detailModalRef = ref<InstanceType<typeof ProductDetail>>();
 
 const formOptions: VbenFormProps = {
   // 默认展开
@@ -209,8 +211,7 @@ function handleEdit(row: any) {
 
 /* 详情 */
 function handleDetail(row: any) {
-  modalApi.setState({ showCancelButton: false });
-  modalApi.setData({ formType: 'detail', row }).open();
+  detailModalRef.value?.openDetailModal(row);
 }
 
 function formatMoney(row: any) {
@@ -360,5 +361,7 @@ function handleAddLinkFinish() {
 
     <!-- 新增关联弹窗组件 -->
     <AddLinkModal ref="addLinkModalRef" @finish="handleAddLinkFinish" />
+    <!-- 详情弹窗组件 -->
+    <ProductDetail ref="detailModalRef" />
   </Page>
 </template>