admin-vue3/src/views/crm/business/components/BusinessProductForm.vue

201 lines
6.7 KiB
Vue

<template>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
v-loading="formLoading"
label-width="0px"
:inline-message="true"
:disabled="disabled"
>
<el-table :data="formData" class="-mt-10px">
<el-table-column label="序号" type="index" align="center" width="60" />
<el-table-column label="产品名称" align="center" prop="productName" />
<el-table-column label="产品类别" align="center" prop="category" width="160">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_CATEGORY" :value="scope.row.category" />
</template>
</el-table-column>
<el-table-column label="产品明细" align="center" prop="detailType" width="160">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_DETAIL_TYPE" :value="scope.row.detailType" />
</template>
</el-table-column>
<el-table-column label="单位" min-width="80">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="scope.row.productUnit" />
</template>
</el-table-column>
<el-table-column label="线上价格(元)" fixed="right" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.onlinePrice`" class="mb-0px!">
<el-input-number
v-model="row.onlinePrice"
controls-position="right"
:min="0.001"
:precision="2"
class="!w-100%"
/>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="线下价格(元)" fixed="right" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.offlinePrice`" class="mb-0px!">
<el-input-number
v-model="row.offlinePrice"
controls-position="right"
:min="0.001"
:precision="2"
class="!w-100%"
/>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="合计" prop="totalPrice" fixed="right" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.totalPrice`" class="mb-0px!">
<el-input disabled v-model="row.totalPrice" :formatter="erpPriceInputFormatter" />
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="60">
<template #default="{ $index }">
<el-button @click="handleDelete($index)" link>—</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
<el-row justify="center" class="mt-3" v-if="!disabled">
<el-button @click="handleAdd" type="primary" round>+ 添加产品</el-button>
</el-row>
<!-- 表单弹窗:添加/修改 -->
<ProductForm ref="productRef" @success="getList" />
</template>
<script setup lang="ts">
import { ref, watch, onMounted, defineProps, defineExpose, reactive } from 'vue';
import * as ProductApi from '@/api/crm/product';
import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils';
import ProductForm from '@/components/product/index.vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict';
const formLoading = ref(false); //
const formData = ref([]); //
const formRules = reactive({
productId: [{ required: true, message: '', trigger: 'blur' }],
businessPrice: [{ required: true, message: '', trigger: 'blur' }]
});
const formRef = ref(null); // Ref
const productList = ref<ProductApi.ProductVO[]>([]); // 产品列表
const props = defineProps<{
products: any[]; // 确保 products 是一个数组
disabled: boolean; // 确保 disabled 是一个布尔值
}>();
// 初始化设置产品项
watch(
() => props.products,
(val) => {
formData.value = val || []; // 确保 formData 是一个数组
},
{ immediate: true }
);
// 监听合同产品变化,计算合同产品总价
watch(
() => formData.value,
(val) => {
if (!val || val.length === 0) {
return;
}
// 循环处理
val.forEach((item) => {
if (item.offlinePrice != null && item.onlinePrice != null) {
item.totalPrice = item.offlinePrice + item.onlinePrice;
} else {
item.totalPrice = 0;
}
});
},
{ deep: true }
);
// 新增按钮操作
// const handleAdd = () => {
// const newRow = {
// id: undefined,
// productId: undefined,
// productName: undefined,
// productUnit: undefined, // 产品单位
// productNo: undefined, // 产品条码
// productPrice: undefined, // 产品价格
// onlinePrice: undefined, // 线上价格
// offlinePrice: undefined, // 线下价格
// totalPrice: undefined, // 总价
// businessPrice: undefined, // 合同价格
// count: 1 // 默认数量为 1
// };
// formData.value.push(newRow);
// };
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const getList = (val: []) => {
for(let i = formData.value.length - 1; i >= 0; i--) {
let obj = formData.value[i]
if(!val.some(v => v.id === obj.productId)) formData.value.splice(i, 1)
}
val.forEach(item => {
if(!formData.value.some(v => v.productId === item.id)) {
formData.value.push({
"productId": item.id,
"category": item.category,
"productName": item.name,
"detailType": item.detailType,
"productUnit": item.unit,
"onlinePrice": '',
"offlinePrice": ''
})
}
})
emit('success', formData.value)
}
const productRef = ref() // 表单 Ref
const handleAdd = () => {
productRef.value.open(formData.value)
}
// 删除按钮操作
const handleDelete = (index: number) => {
formData.value.splice(index, 1);
};
// 处理产品变更
const onChangeProduct = (productId, row) => {
const product = productList.value.find((item) => item.id === productId);
if (product) {
row.productId = product.id;
row.productName = product.name;
row.productCategoryId = product.categoryId; // 假设产品数据中有分类编号
row.productUnit = product.unit;
row.onlinePrice = product.onlinePrice;
row.offlinePrice = product.offlinePrice;
row.totalPrice = product.onlinePrice + product.offlinePrice; // 计算总价
row.productNo = product.no;
row.productPrice = product.price;
row.businessPrice = product.price;
}
};
// 表单校验
const validate = () => {
return formRef.value.validate()
};
defineExpose({ validate });
// 初始化
onMounted(async () => {
productList.value = await ProductApi.getProductSimpleList();
});
</script>