parent
							
								
									f9407ca8bc
								
							
						
					
					
						commit
						a24f08cbb0
					
				|  | @ -128,6 +128,82 @@ export function useFormSchema(): VbenFormSchema[] { | ||||||
|   ]; |   ]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** 采购订单项表格列定义 */ | ||||||
|  | export function usePurchaseOrderItemTableColumns(): VxeTableGridOptions['columns'] { | ||||||
|  |   return [ | ||||||
|  |     { type: 'seq', title: '序号', minWidth: 50 }, | ||||||
|  |     { | ||||||
|  |       field: 'productId', | ||||||
|  |       title: '产品名称', | ||||||
|  |       minWidth: 200, | ||||||
|  |       slots: { default: 'productId' }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'stockCount', | ||||||
|  |       title: '库存', | ||||||
|  |       minWidth: 80, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'productBarCode', | ||||||
|  |       title: '条码', | ||||||
|  |       minWidth: 120, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'productUnitName', | ||||||
|  |       title: '单位', | ||||||
|  |       minWidth: 80, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'count', | ||||||
|  |       title: '数量', | ||||||
|  |       minWidth: 120, | ||||||
|  |       slots: { default: 'count' }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'productPrice', | ||||||
|  |       title: '产品单价', | ||||||
|  |       minWidth: 120, | ||||||
|  |       slots: { default: 'productPrice' }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'totalProductPrice', | ||||||
|  |       title: '金额', | ||||||
|  |       minWidth: 120, | ||||||
|  |       formatter: 'formatAmount2', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'taxPercent', | ||||||
|  |       title: '税率(%)', | ||||||
|  |       minWidth: 100, | ||||||
|  |       slots: { default: 'taxPercent' }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'taxPrice', | ||||||
|  |       title: '税额', | ||||||
|  |       minWidth: 120, | ||||||
|  |       formatter: 'formatAmount2', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'totalPrice', | ||||||
|  |       title: '税额合计', | ||||||
|  |       minWidth: 120, | ||||||
|  |       formatter: 'formatAmount2', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'remark', | ||||||
|  |       title: '备注', | ||||||
|  |       minWidth: 150, | ||||||
|  |       slots: { default: 'remark' }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       title: '操作', | ||||||
|  |       width: 120, | ||||||
|  |       fixed: 'right', | ||||||
|  |       slots: { default: 'actions' }, | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** 列表的搜索表单 */ | /** 列表的搜索表单 */ | ||||||
| export function useGridFormSchema(): VbenFormSchema[] { | export function useGridFormSchema(): VbenFormSchema[] { | ||||||
|   return [ |   return [ | ||||||
|  |  | ||||||
|  | @ -1,148 +1,127 @@ | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import type { ErpPurchaseOrderApi } from '#/api/erp/purchase/order'; | import type { ErpPurchaseOrderApi } from '#/api/erp/purchase/order'; | ||||||
| 
 | 
 | ||||||
| import { ref, watch } from 'vue'; | import { nextTick, onMounted, ref, watch } from 'vue'; | ||||||
| 
 | 
 | ||||||
| import { erpPriceMultiply } from '@vben/utils'; | import { erpPriceMultiply } from '@vben/utils'; | ||||||
| 
 | 
 | ||||||
| import { Button, Input, InputNumber, Select, Table } from 'ant-design-vue'; | import { Input, InputNumber, Select } from 'ant-design-vue'; | ||||||
| 
 | 
 | ||||||
|  | import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; | ||||||
| import { getProductSimpleList } from '#/api/erp/product/product'; | import { getProductSimpleList } from '#/api/erp/product/product'; | ||||||
| import { getStockCountByProductId } from '#/api/erp/stock/stock'; | import { getStockCountByProductId } from '#/api/erp/stock/stock'; | ||||||
| 
 | 
 | ||||||
|  | import { usePurchaseOrderItemTableColumns } from '../data'; | ||||||
|  | 
 | ||||||
| const props = withDefaults(defineProps<Props>(), { | const props = withDefaults(defineProps<Props>(), { | ||||||
|   items: () => [], |   items: () => [], | ||||||
|   disabled: false, |   disabled: false, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const emit = defineEmits(['update:items']); | ||||||
|  | 
 | ||||||
| interface Props { | interface Props { | ||||||
|   items?: ErpPurchaseOrderApi.PurchaseOrderItem[]; |   items?: ErpPurchaseOrderApi.PurchaseOrderItem[]; | ||||||
|   disabled?: boolean; |   disabled?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const formData = ref<ErpPurchaseOrderApi.PurchaseOrderItem[]>([]); | const tableData = ref<ErpPurchaseOrderApi.PurchaseOrderItem[]>([]); | ||||||
| const productList = ref<any[]>([]); | const productOptions = ref<any[]>([]); | ||||||
| 
 | 
 | ||||||
|  | /** 表格配置 */ | ||||||
|  | const [Grid, gridApi] = useVbenVxeGrid({ | ||||||
|  |   gridOptions: { | ||||||
|  |     editConfig: { | ||||||
|  |       trigger: 'click', | ||||||
|  |       mode: 'cell', | ||||||
|  |     }, | ||||||
|  |     columns: usePurchaseOrderItemTableColumns(), | ||||||
|  |     data: tableData.value, | ||||||
|  |     border: true, | ||||||
|  |     showOverflow: true, | ||||||
|  |     autoResize: true, | ||||||
|  |     keepSource: true, | ||||||
|  |     rowConfig: { | ||||||
|  |       keyField: 'id', | ||||||
|  |     }, | ||||||
|  |     pagerConfig: { | ||||||
|  |       enabled: false, | ||||||
|  |     }, | ||||||
|  |     toolbarConfig: { | ||||||
|  |       enabled: false, | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | /** 监听外部传入的列数据 */ | ||||||
| watch( | watch( | ||||||
|   () => props.items, |   () => props.items, | ||||||
|   (val) => { |   async (items) => { | ||||||
|     formData.value = val || []; |     if (!items) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     await nextTick(); | ||||||
|  |     tableData.value = items; | ||||||
|  |     gridApi.grid.reloadData(tableData.value); | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     immediate: true, | ||||||
|   }, |   }, | ||||||
|   { immediate: true }, |  | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| // 初始化时加载产品列表 | /** 初始化 */ | ||||||
| const initProductList = async () => { | onMounted(async () => { | ||||||
|   if (productList.value.length === 0) { |   productOptions.value = await getProductSimpleList(); | ||||||
|     productList.value = await getProductSimpleList(); | }); | ||||||
|  | 
 | ||||||
|  | function handleAdd() { | ||||||
|  |   gridApi.grid.insertAt(null, -1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function handleDelete(row: ErpPurchaseOrderApi.PurchaseOrderItem) { | ||||||
|  |   gridApi.grid.remove(row); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function handleProductChange(productId: any, row: any) { | ||||||
|  |   const product = productOptions.value.find((p) => p.id === productId); | ||||||
|  |   if (!product) { | ||||||
|  |     return; | ||||||
|   } |   } | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| // 组件挂载时加载产品列表 |  | ||||||
| initProductList(); |  | ||||||
| 
 |  | ||||||
| const onChangeProduct = async (productId: number, index: number) => { |  | ||||||
|   const product = productList.value.find((item) => item.id === productId); |  | ||||||
|   if (!product) return; |  | ||||||
| 
 | 
 | ||||||
|   const stockCount = await getStockCountByProductId(productId); |   const stockCount = await getStockCountByProductId(productId); | ||||||
| 
 | 
 | ||||||
|   const item = formData.value[index]; |   row.productId = productId; | ||||||
|   if (item) { |   row.productUnitId = product.unitId; | ||||||
|     item.productId = productId; |   row.productBarCode = product.barCode; | ||||||
|     item.productUnitId = product.unitId; |   row.productUnitName = product.unitName; | ||||||
|     item.productBarCode = product.barCode; |   row.productName = product.name; | ||||||
|     item.productUnitName = product.unitName; |   row.stockCount = stockCount || 0; | ||||||
|     item.productName = product.name; |   row.productPrice = product.purchasePrice; | ||||||
|     item.stockCount = stockCount || 0; |   row.count = row.count || 1; | ||||||
|     item.productPrice = product.purchasePrice; |  | ||||||
| 
 | 
 | ||||||
|     calculatePrice(index); |   handlePriceChange(row); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function handlePriceChange(row: any) { | ||||||
|  |   if (row.productPrice && row.count) { | ||||||
|  |     row.totalProductPrice = erpPriceMultiply(row.productPrice, row.count) ?? 0; | ||||||
|  |     row.taxPrice = | ||||||
|  |       erpPriceMultiply(row.totalProductPrice, (row.taxPercent || 0) / 100) ?? 0; | ||||||
|  |     row.totalPrice = row.totalProductPrice + row.taxPrice; | ||||||
|   } |   } | ||||||
| }; |   handleUpdateValue(row); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| const calculatePrice = (index: number) => { | function handleUpdateValue(row: any) { | ||||||
|   const item = formData.value[index]; |   const index = tableData.value.findIndex((item) => item.id === row.id); | ||||||
|   if (item && item.productPrice && item.count) { |   if (index === -1) { | ||||||
|     item.totalProductPrice = erpPriceMultiply(item.productPrice, item.count); |     row.id = tableData.value.length + 1; | ||||||
|     item.taxPrice = erpPriceMultiply( |     tableData.value.push(row); | ||||||
|       item.totalProductPrice, |   } else { | ||||||
|       (item.taxPercent || 0) / 100, |     tableData.value[index] = row; | ||||||
|     ); |  | ||||||
|     item.totalPrice = item.totalProductPrice + item.taxPrice; |  | ||||||
|   } |   } | ||||||
| }; |   emit('update:items', tableData.value); | ||||||
| 
 | } | ||||||
| const onCountChange = (value: null | number, index: number) => { |  | ||||||
|   const item = formData.value[index]; |  | ||||||
|   if (item) { |  | ||||||
|     item.count = value || 0; |  | ||||||
|     calculatePrice(index); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const onPriceChange = (value: null | number, index: number) => { |  | ||||||
|   const item = formData.value[index]; |  | ||||||
|   if (item) { |  | ||||||
|     item.productPrice = value || 0; |  | ||||||
|     calculatePrice(index); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const onTaxPercentChange = (value: null | number, index: number) => { |  | ||||||
|   const item = formData.value[index]; |  | ||||||
|   if (item) { |  | ||||||
|     item.taxPercent = value || 0; |  | ||||||
|     calculatePrice(index); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const onRemarkChange = (value: string, index: number) => { |  | ||||||
|   const item = formData.value[index]; |  | ||||||
|   if (item) { |  | ||||||
|     item.remark = value; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const columns = [ |  | ||||||
|   { |  | ||||||
|     title: '产品名称', |  | ||||||
|     dataIndex: 'productName', |  | ||||||
|     key: 'productName', |  | ||||||
|     width: 200, |  | ||||||
|   }, |  | ||||||
|   { title: '库存', dataIndex: 'stockCount', key: 'stockCount', width: 80 }, |  | ||||||
|   { |  | ||||||
|     title: '条码', |  | ||||||
|     dataIndex: 'productBarCode', |  | ||||||
|     key: 'productBarCode', |  | ||||||
|     width: 120, |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     title: '单位', |  | ||||||
|     dataIndex: 'productUnitName', |  | ||||||
|     key: 'productUnitName', |  | ||||||
|     width: 80, |  | ||||||
|   }, |  | ||||||
|   { title: '数量', dataIndex: 'count', key: 'count', width: 120 }, |  | ||||||
|   { |  | ||||||
|     title: '产品单价', |  | ||||||
|     dataIndex: 'productPrice', |  | ||||||
|     key: 'productPrice', |  | ||||||
|     width: 120, |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     title: '金额', |  | ||||||
|     dataIndex: 'totalProductPrice', |  | ||||||
|     key: 'totalProductPrice', |  | ||||||
|     width: 120, |  | ||||||
|   }, |  | ||||||
|   { title: '税率(%)', dataIndex: 'taxPercent', key: 'taxPercent', width: 100 }, |  | ||||||
|   { title: '税额', dataIndex: 'taxPrice', key: 'taxPrice', width: 120 }, |  | ||||||
|   { title: '税额合计', dataIndex: 'totalPrice', key: 'totalPrice', width: 120 }, |  | ||||||
|   { title: '备注', dataIndex: 'remark', key: 'remark', width: 150 }, |  | ||||||
|   { title: '操作', key: 'operation', width: 120 }, |  | ||||||
| ]; |  | ||||||
| 
 | 
 | ||||||
| const getSummaries = (): { | const getSummaries = (): { | ||||||
|   count: number; |   count: number; | ||||||
|  | @ -153,16 +132,16 @@ const getSummaries = (): { | ||||||
| } => { | } => { | ||||||
|   const sums = { |   const sums = { | ||||||
|     productName: '合计', |     productName: '合计', | ||||||
|     count: formData.value.reduce((sum, item) => sum + (item.count || 0), 0), |     count: tableData.value.reduce((sum, item) => sum + (item.count || 0), 0), | ||||||
|     totalProductPrice: formData.value.reduce( |     totalProductPrice: tableData.value.reduce( | ||||||
|       (sum, item) => sum + (item.totalProductPrice || 0), |       (sum, item) => sum + (item.totalProductPrice || 0), | ||||||
|       0, |       0, | ||||||
|     ), |     ), | ||||||
|     taxPrice: formData.value.reduce( |     taxPrice: tableData.value.reduce( | ||||||
|       (sum, item) => sum + (item.taxPrice || 0), |       (sum, item) => sum + (item.taxPrice || 0), | ||||||
|       0, |       0, | ||||||
|     ), |     ), | ||||||
|     totalPrice: formData.value.reduce( |     totalPrice: tableData.value.reduce( | ||||||
|       (sum, item) => sum + (item.totalPrice || 0), |       (sum, item) => sum + (item.totalPrice || 0), | ||||||
|       0, |       0, | ||||||
|     ), |     ), | ||||||
|  | @ -170,37 +149,9 @@ const getSummaries = (): { | ||||||
|   return sums; |   return sums; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const handleAdd = async () => { |  | ||||||
|   await initProductList(); |  | ||||||
| 
 |  | ||||||
|   const newItem: ErpPurchaseOrderApi.PurchaseOrderItem = { |  | ||||||
|     id: undefined, |  | ||||||
|     orderId: undefined, |  | ||||||
|     productId: undefined, |  | ||||||
|     productUnitId: undefined, |  | ||||||
|     productPrice: undefined, |  | ||||||
|     count: 1, |  | ||||||
|     totalProductPrice: 0, |  | ||||||
|     taxPercent: 0, |  | ||||||
|     taxPrice: 0, |  | ||||||
|     totalPrice: 0, |  | ||||||
|     remark: undefined, |  | ||||||
|     productName: undefined, |  | ||||||
|     productBarCode: undefined, |  | ||||||
|     productUnitName: undefined, |  | ||||||
|     stockCount: 0, |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   formData.value.push(newItem); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const handleDelete = (index: number) => { |  | ||||||
|   formData.value.splice(index, 1); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const validate = async (): Promise<void> => { | const validate = async (): Promise<void> => { | ||||||
|   for (let i = 0; i < formData.value.length; i++) { |   for (let i = 0; i < tableData.value.length; i++) { | ||||||
|     const item = formData.value[i]; |     const item = tableData.value[i]; | ||||||
|     if (!item.productId) { |     if (!item.productId) { | ||||||
|       throw new Error(`第 ${i + 1} 行:产品不能为空`); |       throw new Error(`第 ${i + 1} 行:产品不能为空`); | ||||||
|     } |     } | ||||||
|  | @ -213,124 +164,73 @@ const validate = async (): Promise<void> => { | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const getData = (): ErpPurchaseOrderApi.PurchaseOrderItem[] => formData.value; | const getData = (): ErpPurchaseOrderApi.PurchaseOrderItem[] => tableData.value; | ||||||
| const init = ( | const init = ( | ||||||
|   items: ErpPurchaseOrderApi.PurchaseOrderItem[] | undefined, |   items: ErpPurchaseOrderApi.PurchaseOrderItem[] | undefined, | ||||||
| ): void => { | ): void => { | ||||||
|   formData.value = items || []; |   tableData.value = items || []; | ||||||
|  |   gridApi.grid.reloadData(tableData.value); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| defineExpose({ validate, getData, init }); | defineExpose({ validate, getData, init }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|   <div> |   <Grid class="w-full"> | ||||||
|     <div class="mb-4"> |     <template #productId="{ row }"> | ||||||
|       <Button v-if="!disabled" type="primary" @click="handleAdd" class="mb-2"> |  | ||||||
|         添加产品 |  | ||||||
|       </Button> |  | ||||||
|     </div> |  | ||||||
| 
 |  | ||||||
|     <Table |  | ||||||
|       :columns="columns" |  | ||||||
|       :data-source="formData" |  | ||||||
|       :pagination="false" |  | ||||||
|       bordered |  | ||||||
|       size="small" |  | ||||||
|       :scroll="{ x: 1400 }" |  | ||||||
|     > |  | ||||||
|       <template #bodyCell="{ column, record, index }"> |  | ||||||
|         <!-- 产品名称 --> |  | ||||||
|         <template v-if="column.key === 'productName'"> |  | ||||||
|       <Select |       <Select | ||||||
|         v-if="!disabled" |         v-if="!disabled" | ||||||
|             v-model:value="record.productId" |         v-model:value="row.productId" | ||||||
|  |         :options="productOptions" | ||||||
|  |         :field-names="{ label: 'name', value: 'id' }" | ||||||
|  |         style="width: 100%" | ||||||
|         placeholder="请选择产品" |         placeholder="请选择产品" | ||||||
|         show-search |         show-search | ||||||
|             :filter-option="false" |         @change="handleProductChange($event, row)" | ||||||
|             @change="(value) => onChangeProduct(value, index)" |       /> | ||||||
|             class="w-full" |       <span v-else>{{ row.productName || '-' }}</span> | ||||||
|           > |  | ||||||
|             <Select.Option |  | ||||||
|               v-for="product in productList" |  | ||||||
|               :key="product.id" |  | ||||||
|               :value="product.id" |  | ||||||
|             > |  | ||||||
|               {{ product.name }} |  | ||||||
|             </Select.Option> |  | ||||||
|           </Select> |  | ||||||
|           <span v-else>{{ record.productName || '-' }}</span> |  | ||||||
|     </template> |     </template> | ||||||
| 
 | 
 | ||||||
|         <!-- 数量 --> |     <template #count="{ row }"> | ||||||
|         <template v-if="column.key === 'count'"> |  | ||||||
|       <InputNumber |       <InputNumber | ||||||
|         v-if="!disabled" |         v-if="!disabled" | ||||||
|             v-model:value="record.count" |         v-model:value="row.count" | ||||||
|         :min="0" |         :min="0" | ||||||
|         :precision="2" |         :precision="2" | ||||||
|             @change="(value: number | null) => onCountChange(value, index)" |         @change="handlePriceChange(row)" | ||||||
|             class="w-full" |  | ||||||
|       /> |       /> | ||||||
|           <span v-else>{{ record.count || '-' }}</span> |       <span v-else>{{ row.count || '-' }}</span> | ||||||
|     </template> |     </template> | ||||||
| 
 | 
 | ||||||
|         <!-- 产品单价 --> |     <template #productPrice="{ row }"> | ||||||
|         <template v-if="column.key === 'productPrice'"> |  | ||||||
|       <InputNumber |       <InputNumber | ||||||
|         v-if="!disabled" |         v-if="!disabled" | ||||||
|             v-model:value="record.productPrice" |         v-model:value="row.productPrice" | ||||||
|         :min="0" |         :min="0" | ||||||
|         :precision="2" |         :precision="2" | ||||||
|             @change="(value: number | null) => onPriceChange(value, index)" |         @change="handlePriceChange(row)" | ||||||
|             class="w-full" |  | ||||||
|       /> |       /> | ||||||
|           <span v-else>{{ record.productPrice || '-' }}</span> |       <span v-else>{{ row.productPrice || '-' }}</span> | ||||||
|     </template> |     </template> | ||||||
| 
 | 
 | ||||||
|         <!-- 税率 --> |     <template #taxPercent="{ row }"> | ||||||
|         <template v-if="column.key === 'taxPercent'"> |  | ||||||
|       <InputNumber |       <InputNumber | ||||||
|         v-if="!disabled" |         v-if="!disabled" | ||||||
|             v-model:value="record.taxPercent" |         v-model:value="row.taxPercent" | ||||||
|         :min="0" |         :min="0" | ||||||
|         :max="100" |         :max="100" | ||||||
|         :precision="2" |         :precision="2" | ||||||
|             @change="(value: number | null) => onTaxPercentChange(value, index)" |         @change="handlePriceChange(row)" | ||||||
|             class="w-full" |  | ||||||
|       /> |       /> | ||||||
|           <span v-else>{{ record.taxPercent || '-' }}</span> |       <span v-else>{{ row.taxPercent || '-' }}</span> | ||||||
|     </template> |     </template> | ||||||
| 
 | 
 | ||||||
|         <!-- 备注 --> |     <template #remark="{ row }"> | ||||||
|         <template v-if="column.key === 'remark'"> |       <Input v-if="!disabled" v-model:value="row.remark" class="w-full" /> | ||||||
|           <Input |       <span v-else>{{ row.remark || '-' }}</span> | ||||||
|             v-if="!disabled" |  | ||||||
|             v-model:value="record.remark" |  | ||||||
|             @change=" |  | ||||||
|               (e: Event) => |  | ||||||
|                 onRemarkChange((e.target as HTMLInputElement).value, index) |  | ||||||
|             " |  | ||||||
|             class="w-full" |  | ||||||
|           /> |  | ||||||
|           <span v-else>{{ record.remark || '-' }}</span> |  | ||||||
|     </template> |     </template> | ||||||
| 
 | 
 | ||||||
|         <!-- 操作 --> |     <template #bottom> | ||||||
|         <template v-if="column.key === 'operation'"> |  | ||||||
|           <Button |  | ||||||
|             v-if="!disabled" |  | ||||||
|             type="link" |  | ||||||
|             danger |  | ||||||
|             size="small" |  | ||||||
|             @click="handleDelete(index)" |  | ||||||
|           > |  | ||||||
|             删除 |  | ||||||
|           </Button> |  | ||||||
|         </template> |  | ||||||
|       </template> |  | ||||||
|     </Table> |  | ||||||
| 
 |  | ||||||
|       <!-- 合计行 --> |       <!-- 合计行 --> | ||||||
|       <div class="mt-2 border bg-gray-50 p-2"> |       <div class="mt-2 border bg-gray-50 p-2"> | ||||||
|         <div class="flex justify-between text-sm"> |         <div class="flex justify-between text-sm"> | ||||||
|  | @ -343,5 +243,35 @@ defineExpose({ validate, getData, init }); | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|   </div> | 
 | ||||||
|  |       <TableAction | ||||||
|  |         v-if="!disabled" | ||||||
|  |         class="mt-4 flex justify-center" | ||||||
|  |         :actions="[ | ||||||
|  |           { | ||||||
|  |             label: '添加产品', | ||||||
|  |             type: 'default', | ||||||
|  |             onClick: handleAdd, | ||||||
|  |           }, | ||||||
|  |         ]" | ||||||
|  |       /> | ||||||
|  |     </template> | ||||||
|  | 
 | ||||||
|  |     <template #actions="{ row }"> | ||||||
|  |       <TableAction | ||||||
|  |         v-if="!disabled" | ||||||
|  |         :actions="[ | ||||||
|  |           { | ||||||
|  |             label: '删除', | ||||||
|  |             type: 'link', | ||||||
|  |             danger: true, | ||||||
|  |             popConfirm: { | ||||||
|  |               title: '确认删除该产品吗?', | ||||||
|  |               confirm: handleDelete.bind(null, row), | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         ]" | ||||||
|  |       /> | ||||||
|  |     </template> | ||||||
|  |   </Grid> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
|  | @ -67,6 +67,12 @@ watch( | ||||||
|   { deep: true }, |   { deep: true }, | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
|  | const handleUpdateItems = (items: ErpPurchaseOrderApi.PurchaseOrderItem[]) => { | ||||||
|  |   if (formData.value) { | ||||||
|  |     formData.value.items = items; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| const [Modal, modalApi] = useVbenModal({ | const [Modal, modalApi] = useVbenModal({ | ||||||
|   async onConfirm() { |   async onConfirm() { | ||||||
|     const { valid } = await formApi.validate(); |     const { valid } = await formApi.validate(); | ||||||
|  | @ -138,6 +144,7 @@ defineExpose({ modalApi }); | ||||||
|               ref="itemFormRef" |               ref="itemFormRef" | ||||||
|               :items="formData?.items || []" |               :items="formData?.items || []" | ||||||
|               :disabled="formType === 'detail'" |               :disabled="formType === 'detail'" | ||||||
|  |               @update:items="handleUpdateItems" | ||||||
|             /> |             /> | ||||||
|           </div> |           </div> | ||||||
|         </a-tab-pane> |         </a-tab-pane> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 nehc
						nehc