Selaa lähdekoodia

新增订单报备

hurx 15 tuntia sitten
vanhempi
sitoutus
c6439ae086

+ 41 - 0
src/api/partner/bank/index.ts

@@ -0,0 +1,41 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PartnerBankVO, PartnerBankForm, PartnerBankQuery } from './types';
+
+export function listPartnerBank(query: PartnerBankQuery): AxiosPromise<PartnerBankVO[]> {
+  return request({
+    url: '/customer/partnerBank/list',
+    method: 'get',
+    params: query
+  });
+}
+
+export function getPartnerBank(id: string | number): AxiosPromise<PartnerBankVO> {
+  return request({
+    url: '/customer/partnerBank/' + id,
+    method: 'get'
+  });
+}
+
+export function addPartnerBank(data: PartnerBankForm) {
+  return request({
+    url: '/customer/partnerBank',
+    method: 'post',
+    data: data
+  });
+}
+
+export function updatePartnerBank(data: PartnerBankForm) {
+  return request({
+    url: '/customer/partnerBank',
+    method: 'put',
+    data: data
+  });
+}
+
+export function delPartnerBank(ids: string | number | Array<string | number>) {
+  return request({
+    url: '/customer/partnerBank/' + ids,
+    method: 'delete'
+  });
+}

+ 38 - 0
src/api/partner/bank/types.ts

@@ -0,0 +1,38 @@
+export interface PartnerBankVO {
+  id: number | string;
+  partnerId: number | string;
+  account?: string;
+  registrationNumber?: string;
+  accountBankName?: string;
+  bankNumber?: string;
+  bankLocation?: string;
+  bankInterbankNumber?: string;
+  phone?: string;
+  address?: string;
+  status?: string;
+  remark?: string;
+  createTime?: string;
+}
+
+export interface PartnerBankForm {
+  id?: number | string;
+  partnerId: number | string;
+  account: string;
+  registrationNumber?: string;
+  bankId?: number | string;
+  accountBankName?: string;
+  bankNumber?: string;
+  bankLocation?: string;
+  bankInterbankNumber?: string;
+  phone?: string;
+  address?: string;
+  status?: string;
+  remark?: string;
+}
+
+export interface PartnerBankQuery {
+  pageNum?: number;
+  pageSize?: number;
+  partnerId?: number | string;
+  account?: string;
+}

+ 41 - 0
src/api/partner/contacts/index.ts

@@ -0,0 +1,41 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PartnerContactsVO, PartnerContactsForm, PartnerContactsQuery } from './types';
+
+export function listPartnerContacts(query: PartnerContactsQuery): AxiosPromise<PartnerContactsVO[]> {
+  return request({
+    url: '/customer/partnerContacts/list',
+    method: 'get',
+    params: query
+  });
+}
+
+export function getPartnerContacts(id: string | number): AxiosPromise<PartnerContactsVO> {
+  return request({
+    url: '/customer/partnerContacts/' + id,
+    method: 'get'
+  });
+}
+
+export function addPartnerContacts(data: PartnerContactsForm) {
+  return request({
+    url: '/customer/partnerContacts',
+    method: 'post',
+    data: data
+  });
+}
+
+export function updatePartnerContacts(data: PartnerContactsForm) {
+  return request({
+    url: '/customer/partnerContacts',
+    method: 'put',
+    data: data
+  });
+}
+
+export function delPartnerContacts(ids: string | number | Array<string | number>) {
+  return request({
+    url: '/customer/partnerContacts/' + ids,
+    method: 'delete'
+  });
+}

+ 29 - 0
src/api/partner/contacts/types.ts

@@ -0,0 +1,29 @@
+export interface PartnerContactsVO {
+  id: number | string;
+  partnerId: number | string;
+  name?: string;
+  phone?: string;
+  email?: string;
+  contactType?: number;
+  status?: string;
+  remark?: string;
+  createTime?: string;
+}
+
+export interface PartnerContactsForm {
+  id?: number | string;
+  partnerId: number | string;
+  name: string;
+  phone?: string;
+  email?: string;
+  contactType?: number;
+  status?: string;
+  remark?: string;
+}
+
+export interface PartnerContactsQuery {
+  pageNum?: number;
+  pageSize?: number;
+  partnerId?: number | string;
+  name?: string;
+}

+ 41 - 0
src/api/partner/contract/index.ts

@@ -0,0 +1,41 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PartnerContractVO, PartnerContractForm, PartnerContractQuery } from './types';
+
+export function listPartnerContract(query: PartnerContractQuery): AxiosPromise<PartnerContractVO[]> {
+  return request({
+    url: '/customer/partnerContract/list',
+    method: 'get',
+    params: query
+  });
+}
+
+export function getPartnerContract(id: string | number): AxiosPromise<PartnerContractVO> {
+  return request({
+    url: '/customer/partnerContract/' + id,
+    method: 'get'
+  });
+}
+
+export function addPartnerContract(data: PartnerContractForm) {
+  return request({
+    url: '/customer/partnerContract',
+    method: 'post',
+    data: data
+  });
+}
+
+export function updatePartnerContract(data: PartnerContractForm) {
+  return request({
+    url: '/customer/partnerContract',
+    method: 'put',
+    data: data
+  });
+}
+
+export function delPartnerContract(ids: string | number | Array<string | number>) {
+  return request({
+    url: '/customer/partnerContract/' + ids,
+    method: 'delete'
+  });
+}

+ 56 - 0
src/api/partner/contract/types.ts

@@ -0,0 +1,56 @@
+export interface PartnerContractVO {
+  id: number | string;
+  partnerId: number | string;
+  contractNo?: string;
+  cooperativeName?: string;
+  cooperationId?: number;
+  startTime?: string;
+  endTime?: string;
+  categories?: string;
+  fee?: number;
+  contractType?: number;
+  settlementCycle?: string;
+  salesTarget?: number;
+  area?: string;
+  contacts?: string;
+  phone?: string;
+  annex?: string;
+  importantTerms?: string;
+  contractStatus?: number;
+  rejectInfo?: string;
+  status?: string;
+  remark?: string;
+  createTime?: string;
+}
+
+export interface PartnerContractForm {
+  id?: number | string;
+  partnerId: number | string;
+  contractNo: string;
+  cooperativeName?: string;
+  cooperationId?: number;
+  startTime?: string;
+  endTime?: string;
+  categories?: string;
+  fee?: number;
+  contractType?: number;
+  settlementCycle?: string;
+  salesTarget?: number;
+  area?: string;
+  contacts?: string;
+  phone?: string;
+  annex?: string;
+  importantTerms?: string;
+  contractStatus?: number;
+  rejectInfo?: string;
+  status?: string;
+  remark?: string;
+}
+
+export interface PartnerContractQuery {
+  pageNum?: number;
+  pageSize?: number;
+  partnerId?: number | string;
+  contractNo?: string;
+  contractStatus?: number;
+}

+ 49 - 0
src/api/partner/merchant/index.ts

@@ -0,0 +1,49 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PartnerMerchantVO, PartnerMerchantForm, PartnerMerchantQuery } from './types';
+
+export function listPartnerMerchant(query: PartnerMerchantQuery): AxiosPromise<PartnerMerchantVO[]> {
+  return request({
+    url: '/customer/partnerInfo/list',
+    method: 'get',
+    params: query
+  });
+}
+
+export function getPartnerMerchant(id: string | number): AxiosPromise<PartnerMerchantVO> {
+  return request({
+    url: '/customer/partnerInfo/' + id,
+    method: 'get'
+  });
+}
+
+export function addPartnerMerchant(data: PartnerMerchantForm) {
+  return request({
+    url: '/customer/partnerInfo',
+    method: 'post',
+    data: data
+  });
+}
+
+export function updatePartnerMerchant(data: PartnerMerchantForm) {
+  return request({
+    url: '/customer/partnerInfo',
+    method: 'put',
+    data: data
+  });
+}
+
+export function delPartnerMerchant(ids: string | number | Array<string | number>) {
+  return request({
+    url: '/customer/partnerInfo/' + ids,
+    method: 'delete'
+  });
+}
+
+export function exportPartnerMerchant(query: PartnerMerchantQuery) {
+  return request({
+    url: '/customer/partnerInfo/export',
+    method: 'post',
+    data: query
+  });
+}

+ 35 - 0
src/api/partner/merchant/types.ts

@@ -0,0 +1,35 @@
+export interface PartnerMerchantVO {
+  id: number | string;
+  partnerNo: string;
+  partnerName: string;
+  company?: string;
+  partnerCooperateType?: number;
+  legal?: string;
+  telephone?: string;
+  fax?: string;
+  registerAddress?: string;
+  operatingAddress?: string;
+  remark?: string;
+  status?: string;
+  createTime?: string;
+}
+
+export interface PartnerMerchantForm {
+  id?: number | string;
+  partnerNo?: string;
+  partnerName: string;
+  company?: string;
+  partnerCooperateType?: number;
+  legal?: string;
+  telephone?: string;
+  fax?: string;
+  registerAddress?: string;
+  operatingAddress?: string;
+  remark?: string;
+  status?: string;
+}
+
+export interface PartnerMerchantQuery extends PageQuery {
+  partnerNo?: string;
+  partnerName?: string;
+}

+ 177 - 0
src/api/partner/prepared/index.ts

@@ -0,0 +1,177 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import {
+  PartnerPreparedVO,
+  PartnerPreparedForm,
+  PartnerPreparedQuery,
+  PartnerPreparedProductVO,
+  PartnerPreparedProductForm,
+  PartnerPreparedProductQuery
+} from './types';
+
+/**
+ * 查询伙伴商备货单列表
+ * @param query 查询参数
+ * @returns 备货单列表
+ */
+export function listPartnerPrepared(query: PartnerPreparedQuery): AxiosPromise<PartnerPreparedVO[]> {
+  return request({
+    url: '/customer/partnerPrepared/list',
+    method: 'get',
+    params: query
+  });
+}
+
+/**
+ * 查询伙伴商备货单详细
+ * @param id 备货单ID
+ * @returns 备货单详情
+ */
+export function getPartnerPrepared(id: number): AxiosPromise<PartnerPreparedVO> {
+  return request({
+    url: '/customer/partnerPrepared/' + id,
+    method: 'get'
+  });
+}
+
+/**
+ * 新增伙伴商备货单
+ * @param data 备货单数据
+ * @returns 结果
+ */
+export function addPartnerPrepared(data: PartnerPreparedForm) {
+  return request({
+    url: '/customer/partnerPrepared',
+    method: 'post',
+    data: data
+  });
+}
+
+/**
+ * 修改伙伴商备货单
+ * @param data 备货单数据
+ * @returns 结果
+ */
+export function updatePartnerPrepared(data: PartnerPreparedForm) {
+  return request({
+    url: '/customer/partnerPrepared',
+    method: 'put',
+    data: data
+  });
+}
+
+/**
+ * 删除伙伴商备货单
+ * @param id 备货单ID数组
+ * @returns 结果
+ */
+export function delPartnerPrepared(id: number | Array<number>) {
+  return request({
+    url: '/customer/partnerPrepared/' + id,
+    method: 'delete'
+  });
+}
+
+/**
+ * 导出伙伴商备货单
+ * @param query 查询参数
+ */
+export function exportPartnerPrepared(query: PartnerPreparedQuery) {
+  return request({
+    url: '/customer/partnerPrepared/export',
+    method: 'post',
+    data: query
+  });
+}
+
+// ==================== 产品明细接口 ====================
+
+/**
+ * 查询伙伴商备货单产品明细列表
+ * @param query 查询参数
+ * @returns 产品明细列表
+ */
+export function listPartnerPreparedProduct(query: PartnerPreparedProductQuery): AxiosPromise<PartnerPreparedProductVO[]> {
+  return request({
+    url: '/customer/partnerPreparedProduct/list',
+    method: 'get',
+    params: query
+  });
+}
+
+/**
+ * 查询伙伴商备货单产品明细详细
+ * @param id 产品明细ID
+ * @returns 产品明细详情
+ */
+export function getPartnerPreparedProduct(id: number): AxiosPromise<PartnerPreparedProductVO> {
+  return request({
+    url: '/customer/partnerPreparedProduct/' + id,
+    method: 'get'
+  });
+}
+
+/**
+ * 新增伙伴商备货单产品明细
+ * @param data 产品明细数据
+ * @returns 结果
+ */
+export function addPartnerPreparedProduct(data: PartnerPreparedProductForm) {
+  return request({
+    url: '/customer/partnerPreparedProduct',
+    method: 'post',
+    data: data
+  });
+}
+
+/**
+ * 修改伙伴商备货单产品明细
+ * @param data 产品明细数据
+ * @returns 结果
+ */
+export function updatePartnerPreparedProduct(data: PartnerPreparedProductForm) {
+  return request({
+    url: '/customer/partnerPreparedProduct',
+    method: 'put',
+    data: data
+  });
+}
+
+/**
+ * 删除伙伴商备货单产品明细
+ * @param id 产品明细ID数组
+ * @returns 结果
+ */
+export function delPartnerPreparedProduct(id: number | Array<number>) {
+  return request({
+    url: '/customer/partnerPreparedProduct/' + id,
+    method: 'delete'
+  });
+}
+
+/**
+ * 导出伙伴商备货单产品明细
+ * @param query 查询参数
+ */
+export function exportPartnerPreparedProduct(query: PartnerPreparedProductQuery) {
+  return request({
+    url: '/customer/partnerPreparedProduct/export',
+    method: 'post',
+    data: query
+  });
+}
+
+// ==================== 商品远程查询接口 ====================
+
+/**
+ * 查询商品列表(远程调用product模块)
+ * @param query 查询参数
+ * @returns 商品列表
+ */
+export function listSiteProducts(query: any) {
+  return request({
+    url: '/customer/productRemote/siteProductList',
+    method: 'get',
+    params: query
+  });
+}

+ 113 - 0
src/api/partner/prepared/types.ts

@@ -0,0 +1,113 @@
+/**
+ * 伙伴商备货单对象 partner_prepared
+ */
+export interface PartnerPreparedVO {
+  id?: number;
+  partnerId?: number;
+  preparedNo?: string;
+  cooperationCode?: string;
+  customerName?: string;
+  purchasingUnitName?: string;
+  amount?: number;
+  area?: string;
+  estimatedTime?: string;
+  dueDate?: string;
+  invoiceAttachment?: string;
+  purchasingUnit?: string;
+  person?: string;
+  deptName?: string;
+  phone?: string;
+  preparedStatus?: number;
+  dealStatus?: number;
+  reject?: string;
+  status?: string;
+  remark?: string;
+  createTime?: string;
+}
+
+/**
+ * 伙伴商备货单表单对象 partner_prepared
+ */
+export interface PartnerPreparedForm {
+  id?: number;
+  partnerId?: number;
+  preparedNo?: string;
+  cooperationCode?: string;
+  customerName?: string;
+  purchasingUnitName?: string;
+  amount?: number;
+  area?: string;
+  estimatedTime?: string;
+  dueDate?: string;
+  invoiceAttachment?: string;
+  purchasingUnit?: string;
+  person?: string;
+  deptName?: string;
+  phone?: string;
+  preparedStatus?: number;
+  dealStatus?: number;
+  reject?: string;
+  status?: string;
+  remark?: string;
+}
+
+/**
+ * 伙伴商备货单查询对象 partner_prepared
+ */
+export interface PartnerPreparedQuery extends PageQuery {
+  partnerId?: number;
+  preparedNo?: string;
+  cooperationCode?: string;
+  customerName?: string;
+  preparedStatus?: number;
+  dealStatus?: number;
+}
+
+/**
+ * 伙伴商备货单产品明细对象 partner_prepared_product
+ */
+export interface PartnerPreparedProductVO {
+  id?: number;
+  partnerPreparedId?: number;
+  productId?: number;
+  productNo?: string;
+  platformNo?: string;
+  productName?: string;
+  productImage?: string;
+  brand?: string;
+  category?: string;
+  quantity?: number;
+  price?: number;
+  amount?: number;
+  status?: string;
+  remark?: string;
+}
+
+/**
+ * 伙伴商备货单产品明细表单对象 partner_prepared_product
+ */
+export interface PartnerPreparedProductForm {
+  id?: number;
+  partnerPreparedId?: number;
+  productId?: number | string;
+  productNo?: string;
+  platformNo?: string;
+  productName?: string;
+  productImage?: string;
+  brand?: string;
+  category?: string;
+  unitPrice?: number;
+  price?: number;
+  quantity?: number;
+  amount?: number;
+  status?: string;
+  remark?: string;
+}
+
+/**
+ * 伙伴商备货单产品明细查询对象 partner_prepared_product
+ */
+export interface PartnerPreparedProductQuery extends PageQuery {
+  partnerPreparedId?: number;
+  productId?: number;
+}

+ 41 - 0
src/api/partner/qualification/index.ts

@@ -0,0 +1,41 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PartnerQualificationVO, PartnerQualificationForm, PartnerQualificationQuery } from './types';
+
+export function listPartnerQualification(query: PartnerQualificationQuery): AxiosPromise<PartnerQualificationVO[]> {
+  return request({
+    url: '/customer/partnerQualification/list',
+    method: 'get',
+    params: query
+  });
+}
+
+export function getPartnerQualification(id: string | number): AxiosPromise<PartnerQualificationVO> {
+  return request({
+    url: '/customer/partnerQualification/' + id,
+    method: 'get'
+  });
+}
+
+export function addPartnerQualification(data: PartnerQualificationForm) {
+  return request({
+    url: '/customer/partnerQualification',
+    method: 'post',
+    data: data
+  });
+}
+
+export function updatePartnerQualification(data: PartnerQualificationForm) {
+  return request({
+    url: '/customer/partnerQualification',
+    method: 'put',
+    data: data
+  });
+}
+
+export function delPartnerQualification(ids: string | number | Array<string | number>) {
+  return request({
+    url: '/customer/partnerQualification/' + ids,
+    method: 'delete'
+  });
+}

+ 32 - 0
src/api/partner/qualification/types.ts

@@ -0,0 +1,32 @@
+export interface PartnerQualificationVO {
+  id: number | string;
+  partnerId: number | string;
+  qualificationNo?: string;
+  qualificationType?: number;
+  authority?: string;
+  deadline?: string;
+  annex?: string;
+  status?: string;
+  remark?: string;
+  createTime?: string;
+}
+
+export interface PartnerQualificationForm {
+  id?: number | string;
+  partnerId: number | string;
+  qualificationNo: string;
+  qualificationType: number;
+  authority?: string;
+  deadline?: string;
+  annex?: string;
+  status?: string;
+  remark?: string;
+}
+
+export interface PartnerQualificationQuery {
+  pageNum?: number;
+  pageSize?: number;
+  partnerId?: number | string;
+  qualificationType?: number;
+  status?: string;
+}

+ 41 - 0
src/api/partner/user/index.ts

@@ -0,0 +1,41 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PartnerUserVO, PartnerUserForm, PartnerUserQuery } from './types';
+
+export function listPartnerUser(query: PartnerUserQuery): AxiosPromise<PartnerUserVO[]> {
+  return request({
+    url: '/customer/partnerUser/list',
+    method: 'get',
+    params: query
+  });
+}
+
+export function getPartnerUser(id: string | number): AxiosPromise<PartnerUserVO> {
+  return request({
+    url: '/customer/partnerUser/' + id,
+    method: 'get'
+  });
+}
+
+export function addPartnerUser(data: PartnerUserForm) {
+  return request({
+    url: '/customer/partnerUser',
+    method: 'post',
+    data: data
+  });
+}
+
+export function updatePartnerUser(data: PartnerUserForm) {
+  return request({
+    url: '/customer/partnerUser',
+    method: 'put',
+    data: data
+  });
+}
+
+export function delPartnerUser(ids: string | number | Array<string | number>) {
+  return request({
+    url: '/customer/partnerUser/' + ids,
+    method: 'delete'
+  });
+}

+ 37 - 0
src/api/partner/user/types.ts

@@ -0,0 +1,37 @@
+export interface PartnerUserVO {
+  id: number | string;
+  partnerId: number | string;
+  loginUser?: string;
+  name?: string;
+  email?: string;
+  phone?: string;
+  duties?: string;
+  roleName?: string;
+  roleId?: number;
+  status?: string;
+  remark?: string;
+  createTime?: string;
+}
+
+export interface PartnerUserForm {
+  id?: number | string;
+  partnerId: number | string;
+  loginUser: string;
+  name: string;
+  email?: string;
+  phone?: string;
+  duties?: string;
+  roleName?: string;
+  roleId?: number;
+  password?: string;
+  status?: string;
+  remark?: string;
+}
+
+export interface PartnerUserQuery {
+  pageNum?: number;
+  pageSize?: number;
+  partnerId?: number | string;
+  loginUser?: string;
+  name?: string;
+}

+ 41 - 0
src/api/partner/warehouse/index.ts

@@ -0,0 +1,41 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PartnerWarehouseVO, PartnerWarehouseForm, PartnerWarehouseQuery } from './types';
+
+export function listPartnerWarehouse(query: PartnerWarehouseQuery): AxiosPromise<PartnerWarehouseVO[]> {
+  return request({
+    url: '/customer/partnerWarehouse/list',
+    method: 'get',
+    params: query
+  });
+}
+
+export function getPartnerWarehouse(id: string | number): AxiosPromise<PartnerWarehouseVO> {
+  return request({
+    url: '/customer/partnerWarehouse/' + id,
+    method: 'get'
+  });
+}
+
+export function addPartnerWarehouse(data: PartnerWarehouseForm) {
+  return request({
+    url: '/customer/partnerWarehouse',
+    method: 'post',
+    data: data
+  });
+}
+
+export function updatePartnerWarehouse(data: PartnerWarehouseForm) {
+  return request({
+    url: '/customer/partnerWarehouse',
+    method: 'put',
+    data: data
+  });
+}
+
+export function delPartnerWarehouse(ids: string | number | Array<string | number>) {
+  return request({
+    url: '/customer/partnerWarehouse/' + ids,
+    method: 'delete'
+  });
+}

+ 37 - 0
src/api/partner/warehouse/types.ts

@@ -0,0 +1,37 @@
+export interface PartnerWarehouseVO {
+  id: number | string;
+  partnerId: number | string;
+  name?: string;
+  warehouseNature?: number;
+  warehouseLocation?: string;
+  warehouseAddress?: string;
+  warehouseArea?: string;
+  warehouseContacts?: string;
+  phone?: string;
+  annex?: string;
+  status?: string;
+  remark?: string;
+  createTime?: string;
+}
+
+export interface PartnerWarehouseForm {
+  id?: number | string;
+  partnerId: number | string;
+  name: string;
+  warehouseNature?: number;
+  warehouseLocation?: string;
+  warehouseAddress?: string;
+  warehouseArea?: string;
+  warehouseContacts?: string;
+  phone?: string;
+  annex?: string;
+  status?: string;
+  remark?: string;
+}
+
+export interface PartnerWarehouseQuery {
+  pageNum?: number;
+  pageSize?: number;
+  partnerId?: number | string;
+  name?: string;
+}

+ 966 - 0
src/views/report/order/index.vue

@@ -0,0 +1,966 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div v-show="showSearch" class="mb-[10px]">
+        <el-card shadow="hover">
+          <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="120">
+            <el-form-item label="报备单号" prop="preparedNo">
+              <el-input v-model="queryParams.preparedNo" placeholder="请输入" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="合作项目/平台" prop="cooperationCode">
+              <el-select v-model="queryParams.cooperationCode" placeholder="请选择" clearable>
+                <el-option v-for="dict in cooperation_code" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="伙伴商名称" prop="customerName">
+              <el-input v-model="queryParams.customerName" placeholder="请输入" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="报备状态" prop="preparedStatus">
+              <el-select v-model="queryParams.preparedStatus" placeholder="请选择" clearable>
+                <el-option v-for="dict in prepared_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="成交状态" prop="dealStatus">
+              <el-select v-model="queryParams.dealStatus" placeholder="请选择" clearable>
+                <el-option v-for="dict in deal_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="handleQuery">搜索</el-button>
+              <el-button @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+        </el-card>
+      </div>
+    </transition>
+
+    <el-card shadow="hover">
+      <template #header>
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd">新增报备</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain :disabled="single" icon="Edit" @click="handleUpdate()">修改</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain :disabled="multiple" icon="Delete" @click="handleDelete()">删除</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
+          </el-col>
+          <right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table
+        v-loading="loading"
+        border
+        :data="orderList"
+        @selection-change="handleSelectionChange"
+        row-key="id"
+        :expand-row-keys="expandedRows"
+        @expand-change="handleExpandChange"
+      >
+        <el-table-column type="expand">
+          <template #default="scope">
+            <div style="padding: 10px 50px; background: #f5f7fa">
+              <el-table :data="scope.row.products || []" border size="small">
+                <el-table-column label="产品编号" prop="productNo" width="120" />
+                <el-table-column label="产品名称" prop="productName" min-width="150" />
+                <el-table-column label="数量" prop="quantity" width="80" align="center" />
+                <el-table-column label="单价" prop="price" width="100" align="center" />
+              </el-table>
+              <el-empty v-if="!scope.row.products?.length" description="暂无商品" :image-size="60" />
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="报备单号" align="center" prop="preparedNo" min-width="160" />
+        <el-table-column label="合作项目/平台" align="center" prop="cooperationCode" min-width="120">
+          <template #default="scope">
+            <el-tag type="success" size="small">{{ getDictLabel(cooperation_code, scope.row.cooperationCode) }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="金额" align="center" prop="amount" min-width="80" />
+        <el-table-column label="创建时间" align="center" prop="createTime" min-width="160" />
+        <el-table-column label="报备到期日" align="center" prop="dueDate" min-width="120">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="报备状态" align="center" prop="preparedStatus" min-width="80">
+          <template #default="scope">
+            <el-checkbox :model-value="scope.row.preparedStatus === 1" disabled />
+          </template>
+        </el-table-column>
+        <el-table-column label="成交状态" align="center" prop="dealStatus" min-width="80">
+          <template #default="scope">
+            <el-checkbox :model-value="scope.row.dealStatus === 2" disabled />
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" min-width="200">
+          <template #default="scope">
+            <div style="display: flex; flex-wrap: wrap; gap: 4px; justify-content: center">
+              <el-button link type="primary" @click="handleUpdate(scope.row)">编辑</el-button>
+              <el-button link type="success" @click="handleSubmit(scope.row)">提交</el-button>
+              <el-button link type="danger" @click="handleReject(scope.row)">驳回</el-button>
+              <el-button link type="primary" @click="handleConfirm(scope.row)">确认</el-button>
+              <el-button link type="info" @click="handleViewAttachment(scope.row)">查看附件</el-button>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
+    </el-card>
+
+    <el-drawer v-model="dialog.visible" :title="dialog.title" direction="rtl" size="75%" @close="cancel" :close-on-click-modal="true">
+      <el-form ref="orderFormRef" :model="form" :rules="rules" label-width="120px">
+        <!-- 基本信息 -->
+        <el-divider content-position="left">
+          <span style="font-size: 16px; font-weight: 500">📋 基本信息</span>
+        </el-divider>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="合作项目/伙伴" prop="cooperationCode">
+              <el-select v-model="form.cooperationCode" placeholder="请选择合作项目/伙伴" style="width: 100%">
+                <el-option v-for="dict in cooperation_code" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+
+          <el-col :span="8">
+            <el-form-item label="活动截止日期" prop="dueDate">
+              <el-date-picker v-model="form.dueDate" type="date" placeholder="请选择活动截止日期" value-format="YYYY-MM-DD" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="金额" prop="amount">
+              <el-input v-model="form.amount" placeholder="请输入金额" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="设计下单时间" prop="estimatedTime">
+              <el-date-picker
+                v-model="form.estimatedTime"
+                type="date"
+                placeholder="请选择设计下单时间"
+                value-format="YYYY-MM-DD"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="报备到期日" prop="dueDate">
+              <el-date-picker v-model="form.dueDate" type="date" placeholder="请选择报备到期日" value-format="YYYY-MM-DD" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="联系地址" prop="area">
+              <el-input v-model="form.area" placeholder="请输入联系地址" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="发票附件" prop="invoiceAttachment">
+              <el-upload
+                class="upload-demo"
+                :action="uploadAction"
+                :headers="uploadHeaders"
+                :on-success="handleUploadSuccess"
+                :on-error="handleUploadError"
+                :file-list="fileList"
+                :limit="5"
+                :on-exceed="handleExceed"
+              >
+                <el-button size="small" type="primary">合同上传</el-button>
+              </el-upload>
+              <div style="color: #999; font-size: 12px; margin-top: 4px">支持jpg/png/pdf/xlsx等文件,最多5个</div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <!-- 状态信息(仅编辑时显示) -->
+        <template v-if="form.id">
+          <el-divider content-position="left">
+            <span style="font-size: 16px; font-weight: 500">📊 状态信息</span>
+          </el-divider>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="报备状态" prop="preparedStatus">
+                <el-select v-model="form.preparedStatus" disabled style="width: 100%">
+                  <el-option v-for="dict in prepared_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="成交状态" prop="dealStatus">
+                <el-select v-model="form.dealStatus" disabled style="width: 100%">
+                  <el-option v-for="dict in deal_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </template>
+
+        <!-- 客户信息 -->
+        <el-divider content-position="left">
+          <span style="font-size: 16px; font-weight: 500">👥 客户信息</span>
+        </el-divider>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="采购单位" prop="purchasingUnit">
+              <el-input v-model="form.purchasingUnit" placeholder="请输入采购单位" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="下单人" prop="person">
+              <el-input v-model="form.person" placeholder="请输入下单人" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="下单日期" prop="estimatedTime">
+              <el-date-picker v-model="form.estimatedTime" type="date" placeholder="请选择下单日期" value-format="YYYY-MM-DD" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="下单手机号" prop="phone">
+              <el-input v-model="form.phone" placeholder="请输入下单手机号" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <!-- 报备商品信息 -->
+        <el-divider content-position="left">
+          <span style="font-size: 16px; font-weight: 500">📦 报备商品信息</span>
+        </el-divider>
+        <div style="margin-bottom: 10px">
+          <el-button type="primary" icon="Plus" @click="handleAddProduct">新增商品</el-button>
+          <el-button type="success" icon="Upload" @click="handleImportProduct">导入商品</el-button>
+        </div>
+        <el-table :data="productList" border style="width: 100%">
+          <el-table-column label="产品编号" align="center" prop="productNo" />
+          <el-table-column label="平台编号" align="center" prop="platformNo" />
+          <el-table-column label="产品名称" align="center" prop="productName" />
+          <el-table-column label="产品图片" align="center" prop="productImage">
+            <template #default="scope">
+              <el-image v-if="scope.row.productImage" :src="scope.row.productImage" style="width: 50px; height: 50px" fit="cover" />
+              <span v-else>-</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="品牌" align="center" prop="brand" width="150" />
+          <el-table-column label="品类" align="center" prop="category" width="100" />
+          <el-table-column label="单价" align="center" prop="price" width="100" />
+          <el-table-column label="数量" align="center" prop="quantity" width="100" />
+          <el-table-column label="金额" align="center" prop="amount" width="100" />
+        </el-table>
+        <el-empty v-if="!productList.length" description="暂无数据" :image-size="100" style="margin: 20px 0" />
+      </el-form>
+      <template #footer>
+        <div style="text-align: right">
+          <el-button @click="cancel">取消</el-button>
+          <el-button type="primary" @click="submitForm">提交</el-button>
+        </div>
+      </template>
+    </el-drawer>
+
+    <el-dialog v-model="auditDialog.visible" title="订单报备审核" width="600px" append-to-body @close="cancelAudit">
+      <el-form ref="auditFormRef" :model="auditForm" :rules="auditRules" label-width="100px">
+        <el-form-item label="审核结果" prop="status">
+          <el-radio-group v-model="auditForm.status">
+            <el-radio :label="1">通过</el-radio>
+            <el-radio :label="2">驳回</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="审核意见" prop="auditRemark">
+          <el-input v-model="auditForm.auditRemark" type="textarea" :rows="4" placeholder="请输入审核意见" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancelAudit">取 消</el-button>
+          <el-button type="primary" @click="submitAudit">确 定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 商品选择抽屉 -->
+    <el-drawer v-model="productDrawer.visible" title="商品信息" direction="rtl" size="60%" :close-on-click-modal="true">
+      <div style="margin-bottom: 20px; display: flex; gap: 10px">
+        <el-select v-model="productQuery.cooperationCode" placeholder="请选择" clearable style="width: 200px">
+          <el-option v-for="dict in cooperation_code" :key="dict.value" :label="dict.label" :value="dict.value" />
+        </el-select>
+        <el-input v-model="productQuery.productNo" placeholder="请输入" clearable style="width: 200px" />
+        <el-button type="primary" @click="searchProducts">搜索</el-button>
+        <el-button @click="resetProductQuery">重置</el-button>
+        <el-button style="margin-left: auto">展开</el-button>
+      </div>
+
+      <el-table :data="availableProducts" border @selection-change="handleProductSelectionChange" max-height="750">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="合作项目/平台" align="center" prop="cooperationCode" width="120" />
+        <el-table-column label="商品编号" align="center" prop="productNo" width="120">
+          <template #default="scope">
+            <span style="color: #409eff">{{ scope.row.productNo }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="平台编号" align="center" prop="platformNo" width="100" />
+        <el-table-column label="商品图片" align="center" prop="productImage" width="80">
+          <template #default="scope">
+            <el-image v-if="scope.row.productImage" :src="scope.row.productImage" style="width: 50px; height: 50px" fit="cover" />
+            <span v-else>--</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="商品信息" align="center" prop="productName" min-width="180" show-overflow-tooltip />
+        <el-table-column label="商品类别" align="center" prop="category" width="100" />
+        <el-table-column label="单位" align="center" prop="unit" width="60" />
+        <el-table-column label="SKU价格" align="center" width="120">
+          <template #default="scope">
+            <div style="text-align: left; line-height: 1.8">
+              <div style="color: #909399; font-size: 12px">市场价:¥{{ scope.row.marketPrice }}</div>
+              <div style="color: #f56c6c; font-size: 12px">会员价:¥{{ scope.row.memberPrice }}</div>
+              <div style="color: #67c23a; font-size: 12px">底价:¥{{ scope.row.basePrice }}</div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="库存数量" align="center" width="100">
+          <template #default="scope">
+            <div style="text-align: left; line-height: 1.8">
+              <div style="color: #f56c6c; font-size: 12px">库存总数:{{ scope.row.stockTotal || 0 }}</div>
+              <div style="color: #67c23a; font-size: 12px">可售库存:{{ scope.row.stockAvailable || 0 }}</div>
+              <div style="color: #909399; font-size: 12px">成本库存:{{ scope.row.stockCost || 0 }}</div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="上下架状态" align="center" width="100">
+          <template #default="scope">
+            <el-tag :type="scope.row.shelfStatus === 1 ? 'success' : 'info'" size="small">
+              {{ scope.row.shelfStatus === 1 ? '上架' : '下架' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <el-pagination
+        v-model:current-page="productQuery.pageNum"
+        v-model:page-size="productQuery.pageSize"
+        :total="productTotal"
+        :page-sizes="[10, 20, 50, 100]"
+        layout="total, sizes, prev, pager, next, jumper"
+        @size-change="searchProducts"
+        @current-change="searchProducts"
+        style="margin-top: 20px; justify-content: center"
+      />
+
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="productDrawer.visible = false">取 消</el-button>
+          <el-button type="primary" @click="confirmAddProducts">确 定</el-button>
+        </div>
+      </template>
+    </el-drawer>
+
+    <!-- 附件查看抽屉 -->
+    <el-drawer v-model="attachmentDrawer.visible" title="查看附件" direction="rtl" size="50%" :close-on-click-modal="true">
+      <el-table :data="attachmentDrawer.attachments" border style="width: 100%">
+        <el-table-column label="附件名称" prop="name" width="150" />
+        <el-table-column label="附件预览" align="center" width="200">
+          <template #default="scope">
+            <el-image
+              v-if="scope.row.url.match(/\.(jpg|jpeg|png|gif|webp)$/i)"
+              :src="scope.row.url"
+              style="width: 100px; height: 100px"
+              fit="cover"
+              :preview-src-list="attachmentDrawer.attachments.map((a: any) => a.url)"
+            />
+            <span v-else>不支持预览</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="150">
+          <template #default="scope">
+            <el-button link type="primary" @click="window.open(scope.row.url, '_blank')">下载</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-empty v-if="!attachmentDrawer.attachments.length" description="暂无附件" :image-size="100" style="margin: 20px 0" />
+    </el-drawer>
+  </div>
+</template>
+
+<script setup name="OrderReport" lang="ts">
+import { getCurrentInstance, reactive, ref, toRefs, computed } from 'vue';
+import {
+  listPartnerPrepared,
+  getPartnerPrepared,
+  addPartnerPrepared,
+  updatePartnerPrepared,
+  delPartnerPrepared,
+  exportPartnerPrepared,
+  listPartnerPreparedProduct,
+  addPartnerPreparedProduct,
+  delPartnerPreparedProduct,
+  listSiteProducts
+} from '@/api/partner/prepared';
+import { getCurrentPartnerInfo } from '@/api/partner';
+import { PartnerPreparedVO, PartnerPreparedForm, PartnerPreparedQuery } from '@/api/partner/prepared/types';
+import { ComponentInternalInstance } from 'vue';
+import { getToken } from '@/utils/auth';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+// 获取字典数据
+const { cooperation_code, prepared_status, deal_status } = toRefs<any>(proxy?.useDict('cooperation_code', 'prepared_status', 'deal_status'));
+
+const orderList = ref([]);
+const productList = ref([]);
+const availableProducts = ref([]);
+const selectedProducts = ref([]);
+const loading = ref(true);
+const productTotal = ref(0);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const expandedRows = ref<string[]>([]);
+const fileList = ref<any[]>([]);
+const partnerId = ref(0);
+
+// 文件上传配置
+const uploadAction = computed(() => import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload?clientid=' + import.meta.env.VITE_APP_CLIENT_ID);
+const uploadHeaders = computed(() => ({
+  Authorization: 'Bearer ' + getToken()
+}));
+
+/** 获取字典标签 */
+function getDictLabel(dictList: any[], value: any) {
+  if (!dictList || !value) return '';
+  const dict = dictList.find((d: any) => d.value === value);
+  return dict?.label || value;
+}
+
+/** 展开行变化 */
+async function handleExpandChange(row: any, expandedRowsList: any[]) {
+  expandedRows.value = expandedRowsList.map((r: any) => r.id);
+  // 如果是展开,加载商品数据
+  if (expandedRowsList.includes(row) && !row.products) {
+    const productRes: any = await listPartnerPreparedProduct({ partnerPreparedId: row.id, pageNum: 1, pageSize: 100 });
+    const products = productRes.rows || [];
+    // 根据 productId 查询商品详情
+    if (products.length > 0) {
+      const siteProductRes: any = await listSiteProducts({ pageNum: 1, pageSize: 1000 });
+      const siteProducts = siteProductRes.data?.rows || [];
+      row.products = products.map((item: any) => {
+        const siteProduct = siteProducts.find((p: any) => p.id == item.productId);
+        return {
+          ...item,
+          productNo: siteProduct?.productNo || '',
+          productName: siteProduct?.productName || ''
+        };
+      });
+    } else {
+      row.products = [];
+    }
+  }
+}
+
+/** 提交按钮 */
+function handleSubmit(row: any) {
+  proxy?.$modal
+    .confirm('是否确认提交该订单报备?')
+    .then(() => {
+      const updateData: PartnerPreparedForm = {
+        id: row.id,
+        preparedStatus: 0 // 提交后变为待审核
+      };
+      return updatePartnerPrepared(updateData);
+    })
+    .then(() => {
+      proxy?.$modal.msgSuccess('提交成功');
+      getList();
+    })
+    .catch(() => {});
+}
+
+/** 确认按钮 */
+function handleConfirm(row: any) {
+  proxy?.$modal
+    .confirm('是否确认该订单报备?')
+    .then(() => {
+      const updateData: PartnerPreparedForm = {
+        id: row.id,
+        preparedStatus: 1, // 已通过
+        dealStatus: 2 // 已完成
+      };
+      return updatePartnerPrepared(updateData);
+    })
+    .then(() => {
+      proxy?.$modal.msgSuccess('确认成功');
+      getList();
+    })
+    .catch(() => {});
+}
+
+const data = reactive({
+  form: {} as PartnerPreparedForm,
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    preparedNo: undefined,
+    cooperationCode: undefined,
+    customerName: undefined,
+    preparedStatus: undefined,
+    dealStatus: undefined
+  } as PartnerPreparedQuery,
+  rules: {
+    customerName: [{ required: true, message: '客户名称不能为空', trigger: 'blur' }]
+  },
+  dialog: {
+    visible: false,
+    title: ''
+  },
+  auditDialog: {
+    visible: false
+  },
+  productDrawer: {
+    visible: false
+  },
+  attachmentDrawer: {
+    visible: false,
+    attachments: []
+  },
+  productQuery: {
+    pageNum: 1,
+    pageSize: 10,
+    cooperationCode: undefined,
+    productNo: undefined
+  },
+  auditForm: {
+    id: undefined,
+    status: 1,
+    auditRemark: ''
+  },
+  auditRules: {
+    status: [{ required: true, message: '请选择审核结果', trigger: 'change' }],
+    auditRemark: [{ required: true, message: '审核意见不能为空', trigger: 'blur' }]
+  }
+});
+
+const { queryParams, form, rules, dialog, auditDialog, productDrawer, attachmentDrawer, productQuery, auditForm, auditRules } = toRefs(data);
+
+const queryFormRef = ref();
+const orderFormRef = ref();
+const auditFormRef = ref();
+
+const getCurrentPartner = async () => {
+  const partnerResponse = await getCurrentPartnerInfo();
+  if (partnerResponse.code === 200 && partnerResponse.data) {
+    partnerId.value = partnerResponse.data.id;
+    form.value.partnerId = partnerResponse.data.id;
+  }
+};
+
+function getList() {
+  loading.value = true;
+  listPartnerPrepared(queryParams.value)
+    .then((res: any) => {
+      orderList.value = res.rows;
+      total.value = res.total;
+      loading.value = false;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
+}
+
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+function resetQuery() {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+function reset() {
+  form.value = {
+    id: undefined,
+    partnerId: partnerId.value,
+    preparedNo: undefined,
+    cooperationCode: undefined,
+    customerName: undefined,
+    purchasingUnitName: undefined,
+    amount: undefined,
+    area: undefined,
+    estimatedTime: undefined,
+    dueDate: undefined,
+    invoiceAttachment: undefined,
+    purchasingUnit: undefined,
+    person: undefined,
+    deptName: undefined,
+    phone: undefined,
+    preparedStatus: undefined,
+    dealStatus: undefined,
+    reject: undefined,
+    status: '0',
+    remark: undefined
+  };
+  productList.value = [];
+  orderFormRef.value?.resetFields();
+}
+
+function handleAdd() {
+  reset();
+  dialog.value.visible = true;
+  dialog.value.title = '新增订单报备';
+}
+
+function handleUpdate(row?: any) {
+  reset();
+  const id = row?.id || ids.value[0];
+  getPartnerPrepared(id).then((res: any) => {
+    // 使用 Object.assign 更新 form.value,而不是直接替换
+    Object.assign(form.value, res.data);
+
+    // 加载已有附件到文件列表
+    if (res.data.invoiceAttachment) {
+      const urls = res.data.invoiceAttachment.split(',');
+      fileList.value = urls.map((url: string, index: number) => ({
+        name: `附件${index + 1}`,
+        url: url
+      }));
+    } else {
+      fileList.value = [];
+    }
+
+    dialog.value.visible = true;
+    dialog.value.title = '修改订单报备';
+    // 加载产品明细
+    listPartnerPreparedProduct({ partnerPreparedId: id, pageNum: 1, pageSize: 100 }).then(async (productRes: any) => {
+      const products = productRes.rows || [];
+      // 根据 productId 查询商品详情补充显示信息
+      if (products.length > 0) {
+        // 获取所有商品信息
+        const siteProductRes: any = await listSiteProducts({ pageNum: 1, pageSize: 1000 });
+        const siteProducts = siteProductRes.data?.rows || [];
+        // 合并商品信息
+        productList.value = products.map((item: any) => {
+          const siteProduct = siteProducts.find((p: any) => p.id == item.productId);
+          return {
+            ...item,
+            productNo: siteProduct?.productNo || '',
+            productName: siteProduct?.productName || '',
+            productImage: siteProduct?.productImage || '',
+            category: siteProduct?.isSelf === 1 ? '自营商品' : '非自营商品',
+            platformNo: ''
+          };
+        });
+      } else {
+        productList.value = [];
+      }
+    });
+  });
+}
+
+function submitForm() {
+  orderFormRef.value?.validate((valid: boolean) => {
+    if (valid) {
+      form.value.partnerId = partnerId.value;
+      if (form.value.id) {
+        // 修改订单
+        updatePartnerPrepared(form.value)
+          .then(() => {
+            // 保存商品列表
+            return saveProductList(form.value.id as number);
+          })
+          .then(() => {
+            proxy?.$modal.msgSuccess('修改成功');
+            dialog.value.visible = false;
+            getList();
+          });
+      } else {
+        // 新增订单
+        addPartnerPrepared(form.value)
+          .then((res: any) => {
+            console.log(res);
+            const orderId = res.data;
+            // 保存商品列表
+            return saveProductList(orderId);
+          })
+          .then(() => {
+            proxy?.$modal.msgSuccess('新增成功');
+            dialog.value.visible = false;
+            getList();
+          });
+      }
+    }
+  });
+}
+
+/** 保存商品列表 */
+async function saveProductList(partnerPreparedId: number) {
+  if (!productList.value.length) return;
+
+  // 逐个保存商品(如果是新增的商品)
+  for (const product of productList.value) {
+    if (!product.id) {
+      // 新增商品 - 只传必要字段
+      await addPartnerPreparedProduct({
+        partnerPreparedId: partnerPreparedId,
+        productId: product.productId,
+        quantity: product.quantity || 1,
+        price: product.price || 0
+      });
+    }
+  }
+}
+
+function cancel() {
+  dialog.value.visible = false;
+  reset();
+}
+
+function handleDelete(row?: any) {
+  const orderIds = row?.id || ids.value;
+  proxy?.$modal
+    .confirm('是否确认删除订单报备编号为"' + orderIds + '"的数据项?')
+    .then(() => {
+      return delPartnerPrepared(orderIds);
+    })
+    .then(() => {
+      proxy?.$modal.msgSuccess('删除成功');
+      getList();
+    })
+    .catch(() => {});
+}
+
+function handleExport() {
+  exportPartnerPrepared(queryParams.value).then((response: any) => {
+    proxy?.$download.zip(response.data, `prepared_${new Date().getTime()}.xlsx`);
+  });
+}
+
+function handleSelectionChange(selection: any[]) {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length !== 1;
+  multiple.value = !selection.length;
+}
+
+function handleAudit(row: any) {
+  auditForm.value.id = row.id;
+  auditForm.value.status = 1;
+  auditForm.value.auditRemark = '';
+  auditDialog.value.visible = true;
+}
+
+function submitAudit() {
+  auditFormRef.value?.validate((valid: boolean) => {
+    if (valid) {
+      const updateData: PartnerPreparedForm = {
+        id: auditForm.value.id,
+        preparedStatus: auditForm.value.status,
+        reject: auditForm.value.status === 2 ? auditForm.value.auditRemark : undefined
+      };
+      updatePartnerPrepared(updateData).then(() => {
+        proxy?.$modal.msgSuccess('审核成功');
+        auditDialog.value.visible = false;
+        getList();
+      });
+    }
+  });
+}
+
+function cancelAudit() {
+  auditDialog.value.visible = false;
+  auditForm.value = {
+    id: undefined,
+    status: 1,
+    auditRemark: ''
+  };
+}
+
+function handleVerify(row: any) {
+  proxy?.$modal
+    .confirm('是否确认核实该订单报备?')
+    .then(() => {
+      const updateData: PartnerPreparedForm = {
+        id: row.id,
+        preparedStatus: 1
+      };
+      return updatePartnerPrepared(updateData);
+    })
+    .then(() => {
+      proxy?.$modal.msgSuccess('核实成功');
+      getList();
+    });
+}
+
+function handleReject(row: any) {
+  proxy?.$modal
+    .confirm('是否确认驳回该订单报备?')
+    .then(() => {
+      const updateData: PartnerPreparedForm = {
+        id: row.id,
+        preparedStatus: 2,
+        reject: '驳回'
+      };
+      return updatePartnerPrepared(updateData);
+    })
+    .then(() => {
+      proxy?.$modal.msgSuccess('驳回成功');
+      getList();
+    })
+    .catch(() => {});
+}
+
+function handleViewAttachment(row: any) {
+  if (row.invoiceAttachment) {
+    // 解析附件URL列表
+    const urls = row.invoiceAttachment.split(',').filter(Boolean);
+    attachmentDrawer.value.attachments = urls.map((url: string, index: number) => ({
+      name: `附件${index + 1}`,
+      url: url.trim()
+    }));
+    attachmentDrawer.value.visible = true;
+  } else {
+    proxy?.$modal.msgWarning('该订单暂无附件');
+  }
+}
+
+/** 文件上传成功 */
+function handleUploadSuccess(response: any, file: any, fileListParam: any[]) {
+  console.log('上传成功回调 - response:', response);
+  console.log('上传成功回调 - file:', file);
+  console.log('上传成功回调 - fileListParam:', fileListParam);
+
+  if (response.code === 200) {
+    // 更新 fileList
+    fileList.value = fileListParam;
+    // 收集所有已上传成功的文件URL
+    const urls = fileListParam
+      .filter((f: any) => f.response?.code === 200 || f.url)
+      .map((f: any) => f.response?.data?.url || f.url)
+      .filter(Boolean);
+
+    console.log('提取的URLs:', urls);
+    form.value.invoiceAttachment = urls.join(',');
+    console.log('保存到表单的附件:', form.value.invoiceAttachment);
+
+    proxy?.$modal.msgSuccess('文件上传成功');
+  } else {
+    proxy?.$modal.msgError(response.msg || '文件上传失败');
+  }
+}
+
+/** 文件上传失败 */
+function handleUploadError() {
+  proxy?.$modal.msgError('文件上传失败,请重试');
+}
+
+/** 文件数量超出限制 */
+function handleExceed() {
+  proxy?.$modal.msgWarning('最多只能上传5个文件');
+}
+
+function handleAddProduct() {
+  productDrawer.value.visible = true;
+  searchProducts();
+}
+
+function handleImportProduct() {
+  proxy?.$modal.msg('导入商品功能开发中...');
+}
+
+function searchProducts() {
+  listSiteProducts(productQuery.value)
+    .then((res: any) => {
+      availableProducts.value = (res.data?.rows || []).map((item: any) => ({
+        id: item.id,
+        cooperationCode: '--',
+        productNo: item.productNo,
+        platformNo: '--',
+        productImage: item.productImage,
+        productName: item.productName,
+        category: item.isSelf === 1 ? '自营商品' : '非自营商品',
+        unit: item.unitName || '包',
+        marketPrice: item.marketPrice,
+        memberPrice: item.memberPrice,
+        basePrice: item.minSellingPrice,
+        stockTotal: item.totalInventory || 0,
+        stockAvailable: item.nowInventory || 0,
+        stockCost: item.virtualInventory || 0,
+        shelfStatus: item.productStatus
+      }));
+      productTotal.value = res.data?.total || 0;
+    })
+    .catch(() => {
+      availableProducts.value = [];
+      productTotal.value = 0;
+    });
+}
+
+function resetProductQuery() {
+  productQuery.value = {
+    pageNum: 1,
+    pageSize: 10,
+    cooperationCode: undefined,
+    productNo: undefined
+  };
+  searchProducts();
+}
+
+function handleProductSelectionChange(selection: any[]) {
+  selectedProducts.value = selection;
+}
+
+function confirmAddProducts() {
+  if (selectedProducts.value.length === 0) {
+    proxy?.$modal.msgWarning('请至少选择一个商品');
+    return;
+  }
+
+  let addedCount = 0;
+  // 将选中的商品添加到产品列表
+  selectedProducts.value.forEach((product: any) => {
+    const exists = productList.value.find((p: any) => p.productId === product.id);
+    if (!exists) {
+      const price = product.memberPrice || 0;
+      productList.value.push({
+        productId: product.id,
+        productNo: product.productNo,
+        platformNo: product.platformNo || '',
+        productName: product.productName,
+        productImage: product.productImage,
+        brand: '',
+        category: product.category,
+        price: price,
+        quantity: 1,
+        amount: price
+      });
+      addedCount++;
+    }
+  });
+
+  if (addedCount > 0) {
+    proxy?.$modal.msgSuccess(`成功添加 ${addedCount} 个商品`);
+  } else {
+    proxy?.$modal.msgWarning('所选商品已存在于列表中');
+  }
+  productDrawer.value.visible = false;
+  selectedProducts.value = [];
+}
+onMounted(() => {
+  getCurrentPartner();
+  getList();
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 385 - 0
src/views/report/product/index.vue

@@ -0,0 +1,385 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div v-show="showSearch" class="mb-[10px]">
+        <el-card shadow="hover">
+          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
+            <el-form-item label="商品编号" prop="productNo">
+              <el-input v-model="queryParams.productNo" placeholder="请输入商品编号" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="商品名称" prop="productName">
+              <el-input v-model="queryParams.productName" placeholder="请输入商品名称" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="报备状态" prop="status">
+              <el-select v-model="queryParams.status" placeholder="请选择报备状态" clearable>
+                <el-option label="待审核" value="0" />
+                <el-option label="已通过" value="1" />
+                <el-option label="已驳回" value="2" />
+              </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="handleQuery">搜索</el-button>
+              <el-button @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+        </el-card>
+      </div>
+    </transition>
+
+    <el-card shadow="hover">
+      <template #header>
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd">新增报备</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain :disabled="single" icon="Edit" @click="handleUpdate()">修改</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain :disabled="multiple" icon="Delete" @click="handleDelete()">删除</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
+          </el-col>
+          <right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" border :data="productList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="商品编号" align="center" prop="productNo" width="150" />
+        <el-table-column label="商品名称" align="center" prop="productName" :show-overflow-tooltip="true" width="180" />
+        <el-table-column label="商品分类" align="center" prop="categoryName" width="120" />
+        <el-table-column label="品牌" align="center" prop="brandName" width="120" />
+        <el-table-column label="规格型号" align="center" prop="specification" width="150" />
+        <el-table-column label="报备价格" align="center" prop="reportPrice" width="120">
+          <template #default="scope">
+            <span>¥{{ scope.row.reportPrice }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="报备状态" align="center" prop="status" width="100">
+          <template #default="scope">
+            <el-tag v-if="scope.row.status === 0" type="warning">待审核</el-tag>
+            <el-tag v-else-if="scope.row.status === 1" type="success">已通过</el-tag>
+            <el-tag v-else-if="scope.row.status === 2" type="danger">已驳回</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="报备人" align="center" prop="reportUser" width="120" />
+        <el-table-column label="报备时间" align="center" prop="reportTime" width="180" />
+        <el-table-column label="审核人" align="center" prop="auditUser" width="120" />
+        <el-table-column label="审核时间" align="center" prop="auditTime" width="180" />
+        <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
+        <el-table-column label="操作" align="center" width="180" fixed="right" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-button link type="primary" @click="handleUpdate(scope.row)">详情</el-button>
+            <el-button link type="primary" @click="handleAudit(scope.row)" v-if="scope.row.status === 0">审核</el-button>
+            <el-button link type="primary" @click="handleDelete(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
+    </el-card>
+
+    <el-dialog v-model="dialog.visible" :title="dialog.title" width="900px" append-to-body @close="cancel">
+      <el-form ref="productFormRef" :model="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="商品编号" prop="productNo">
+              <el-input v-model="form.productNo" placeholder="请输入商品编号" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="商品名称" prop="productName">
+              <el-input v-model="form.productName" placeholder="请输入商品名称" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="商品分类" prop="categoryName">
+              <el-input v-model="form.categoryName" placeholder="请输入商品分类" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="品牌" prop="brandName">
+              <el-input v-model="form.brandName" placeholder="请输入品牌" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="规格型号" prop="specification">
+              <el-input v-model="form.specification" placeholder="请输入规格型号" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="报备价格" prop="reportPrice">
+              <el-input-number v-model="form.reportPrice" :min="0" :precision="2" placeholder="请输入报备价格" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="供应商" prop="supplierName">
+              <el-input v-model="form.supplierName" placeholder="请输入供应商" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="生产厂家" prop="manufacturer">
+              <el-input v-model="form.manufacturer" placeholder="请输入生产厂家" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="商品描述" prop="description">
+              <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入商品描述" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="备注" prop="remark">
+              <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancel">取 消</el-button>
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <el-dialog v-model="auditDialog.visible" title="商品报备审核" width="600px" append-to-body @close="cancelAudit">
+      <el-form ref="auditFormRef" :model="auditForm" :rules="auditRules" label-width="100px">
+        <el-form-item label="审核结果" prop="status">
+          <el-radio-group v-model="auditForm.status">
+            <el-radio :label="1">通过</el-radio>
+            <el-radio :label="2">驳回</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="审核意见" prop="auditRemark">
+          <el-input v-model="auditForm.auditRemark" type="textarea" :rows="4" placeholder="请输入审核意见" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancelAudit">取 消</el-button>
+          <el-button type="primary" @click="submitAudit">确 定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="ProductReport" lang="ts">
+import { getCurrentInstance, reactive, ref, toRefs } from 'vue';
+
+const { proxy } = getCurrentInstance() as any;
+
+const productList = ref([]);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const data = reactive({
+  form: {} as any,
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    productNo: undefined,
+    productName: undefined,
+    status: undefined
+  },
+  rules: {
+    productNo: [{ required: true, message: '商品编号不能为空', trigger: 'blur' }],
+    productName: [{ required: true, message: '商品名称不能为空', trigger: 'blur' }],
+    categoryName: [{ required: true, message: '商品分类不能为空', trigger: 'blur' }],
+    reportPrice: [{ required: true, message: '报备价格不能为空', trigger: 'blur' }]
+  },
+  dialog: {
+    visible: false,
+    title: ''
+  },
+  auditDialog: {
+    visible: false
+  },
+  auditForm: {
+    id: undefined,
+    status: 1,
+    auditRemark: ''
+  },
+  auditRules: {
+    status: [{ required: true, message: '请选择审核结果', trigger: 'change' }],
+    auditRemark: [{ required: true, message: '审核意见不能为空', trigger: 'blur' }]
+  }
+});
+
+const { queryParams, form, rules, dialog, auditDialog, auditForm, auditRules } = toRefs(data);
+
+const queryFormRef = ref();
+const productFormRef = ref();
+const auditFormRef = ref();
+
+function getList() {
+  loading.value = true;
+  setTimeout(() => {
+    productList.value = [
+      {
+        id: 1,
+        productNo: 'PRD202401210001',
+        productName: '测试商品A',
+        categoryName: '电子产品',
+        brandName: '品牌A',
+        specification: '型号X1',
+        reportPrice: 1200.00,
+        status: 0,
+        reportUser: '张三',
+        reportTime: '2024-01-21 10:00:00',
+        auditUser: '',
+        auditTime: '',
+        supplierName: '供应商A',
+        manufacturer: '厂家A',
+        description: '高品质电子产品',
+        remark: '测试商品报备'
+      },
+      {
+        id: 2,
+        productNo: 'PRD202401210002',
+        productName: '测试商品B',
+        categoryName: '家电',
+        brandName: '品牌B',
+        specification: '型号Y2',
+        reportPrice: 3500.00,
+        status: 1,
+        reportUser: '李四',
+        reportTime: '2024-01-20 14:30:00',
+        auditUser: '王五',
+        auditTime: '2024-01-20 16:00:00',
+        supplierName: '供应商B',
+        manufacturer: '厂家B',
+        description: '智能家电产品',
+        remark: '重要商品'
+      }
+    ] as any;
+    total.value = 2;
+    loading.value = false;
+  }, 500);
+}
+
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+function resetQuery() {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+function reset() {
+  form.value = {
+    id: undefined,
+    productNo: undefined,
+    productName: undefined,
+    categoryName: undefined,
+    brandName: undefined,
+    specification: undefined,
+    reportPrice: undefined,
+    supplierName: undefined,
+    manufacturer: undefined,
+    description: undefined,
+    remark: undefined
+  };
+  productFormRef.value?.resetFields();
+}
+
+function handleAdd() {
+  reset();
+  dialog.value.visible = true;
+  dialog.value.title = '新增商品报备';
+}
+
+function handleUpdate(row?: any) {
+  reset();
+  const id = row?.id || ids.value[0];
+  dialog.value.visible = true;
+  dialog.value.title = '修改商品报备';
+  form.value = { ...row };
+}
+
+function submitForm() {
+  productFormRef.value?.validate((valid: boolean) => {
+    if (valid) {
+      proxy?.$modal.msgSuccess('提交成功');
+      dialog.value.visible = false;
+      getList();
+    }
+  });
+}
+
+function cancel() {
+  dialog.value.visible = false;
+  reset();
+}
+
+function handleDelete(row?: any) {
+  const productIds = row?.id || ids.value;
+  proxy?.$modal
+    .confirm('是否确认删除商品报备编号为"' + productIds + '"的数据项?')
+    .then(() => {
+      proxy?.$modal.msgSuccess('删除成功');
+      getList();
+    })
+    .catch(() => {});
+}
+
+function handleExport() {
+  proxy?.$modal.confirm('是否确认导出所有商品报备数据项?').then(() => {
+    proxy?.$modal.msgSuccess('导出成功');
+  });
+}
+
+function handleSelectionChange(selection: any[]) {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length !== 1;
+  multiple.value = !selection.length;
+}
+
+function handleAudit(row: any) {
+  auditForm.value.id = row.id;
+  auditForm.value.status = 1;
+  auditForm.value.auditRemark = '';
+  auditDialog.value.visible = true;
+}
+
+function submitAudit() {
+  auditFormRef.value?.validate((valid: boolean) => {
+    if (valid) {
+      proxy?.$modal.msgSuccess('审核成功');
+      auditDialog.value.visible = false;
+      getList();
+    }
+  });
+}
+
+function cancelAudit() {
+  auditDialog.value.visible = false;
+  auditForm.value = {
+    id: undefined,
+    status: 1,
+    auditRemark: ''
+  };
+}
+
+getList();
+</script>
+
+<style scoped lang="scss"></style>