| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- <template>
- <div class="app-container">
- <!-- 商品报价信息 -->
- <el-card shadow="never" class="form-card">
- <div class="section-title">
- <el-button type="primary" @click="handleAddProduct">添加商品报价</el-button>
- <el-button plain @click="handleDownloadTemplate">下载模板</el-button>
- <el-button plain @click="handleImportClick">导入</el-button>
- <input
- ref="fileInputRef"
- type="file"
- accept=".xlsx,.xls"
- style="display: none"
- @change="handleFileChange"
- />
- </div>
- <el-table :data="productList" border style="width: 100%; margin-top: 20px;">
- <el-table-column prop="productNo" label="产品编号" align="center" width="120" />
- <el-table-column label="产品图片" align="center" width="100">
- <template #default="scope">
- <el-image
- v-if="scope.row.productImage"
- :src="scope.row.productImage"
- style="width: 60px; height: 60px;"
- fit="cover"
- />
- </template>
- </el-table-column>
- <el-table-column prop="itemName" label="产品名称" align="center" show-overflow-tooltip />
- <el-table-column label="产品分类" align="center" width="180" show-overflow-tooltip>
- <template #default="scope">
- <span>{{ scope.row.topCategoryName }}-{{ scope.row.mediumCategoryName }}-{{ scope.row.bottomCategoryName }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="brandName" label="品牌" align="center" width="100" />
- <el-table-column prop="unitName" label="单位" align="center" width="80" />
- <el-table-column label="市场价" align="center" width="100">
- <template #default="scope">
- <span>¥{{ scope.row.marketPrice || '0.00' }}</span>
- </template>
- </el-table-column>
- <el-table-column label="官网价" align="center" width="100">
- <template #default="scope">
- <span>¥{{ scope.row.memberPrice || '0.00' }}</span>
- </template>
- </el-table-column>
- <el-table-column label="供应价(元)" align="center" width="120">
- <template #default="scope">
- <span>¥{{ scope.row.supplyPrice || '0.00' }}</span>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" width="100" fixed="right">
- <template #default="scope">
- <el-button link type="primary" @click="handleDeleteProduct(scope.row, scope.$index)">删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.pageNum"
- v-model:limit="queryParams.pageSize"
- @pagination="getProductData"
- />
- </el-card>
- <!-- 添加商品对话框 -->
- <Product
- v-model:visible="productDialog.visible"
- v-model:modelValue="productList"
- @confirm="handleProductConfirm"
- />
- </div>
- </template>
- <script setup lang="ts">
- import { ref, onMounted, reactive, getCurrentInstance } from 'vue';
- import { useRouter, useRoute } from 'vue-router';
- import { getContractProductList, delContracproductBySupplier, importTemplate, importData } from '@/api/product/contracproduct';
- import { ElMessage } from 'element-plus';
- import Product from './components/Product.vue';
- const { proxy } = getCurrentInstance() as any;
- const router = useRouter();
- const route = useRoute();
- const productList = ref<any[]>([]);
- const total = ref(0);
- const fileInputRef = ref<HTMLInputElement>();
- const queryParams = reactive({
- pageNum: 1,
- pageSize: 10
- });
- // 商品对话框相关
- const productDialog = reactive({
- visible: false
- });
- /** 返回上一页 */
- const goBack = () => {
- router.back();
- };
- /** 获取商品列表 */
- const getProductData = async () => {
- try {
- const res = await getContractProductList({
- supplierId: route.params.id,
- pageNum: queryParams.pageNum,
- pageSize: queryParams.pageSize
- } as any);
- productList.value = res.rows || []
- total.value = (res as any).total || 0;
- } catch (e) {
- console.error('获取商品列表失败:', e);
- ElMessage.error('获取商品列表失败');
- }
- };
- /** 添加商品 */
- const handleAddProduct = () => {
- productDialog.visible = true;
- };
- /** 删除商品 */
- const handleDeleteProduct = async (row: any, index: number) => {
- console.log('handleDeleteProduct', row, index);
- try {
- await proxy?.$modal.confirm('是否确认删除该商品报价数据项?');
- await delContracproductBySupplier(row.id, route.params.id as string);
- proxy?.$modal.msgSuccess('删除成功');
- await getProductData();
- } catch (e) {
- // 用户取消或请求失败时不提示
- }
- };
- /** 商品确认添加后,刷新列表 */
- const handleProductConfirm = () => {
- getProductData();
- };
- /** 下载导入模板 */
- const handleDownloadTemplate = async () => {
- try {
- const res = await importTemplate();
- const blob = new Blob([res as any], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
- const url = window.URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = url;
- link.download = '合同产品导入模板.xlsx';
- link.click();
- window.URL.revokeObjectURL(url);
- ElMessage.success('模板下载成功');
- } catch (e) {
- console.error('下载模板失败:', e);
- ElMessage.error('下载模板失败');
- }
- };
- /** 触发文件选择 */
- const handleImportClick = () => {
- fileInputRef.value?.click();
- };
- /** 导入文件 */
- const handleFileChange = async (event: Event) => {
- const input = event.target as HTMLInputElement;
- const file = input.files?.[0];
- if (!file) return;
- try {
- await proxy?.$modal.confirm('是否确认导入该文件中的商品数据?');
- await importData(file);
- proxy?.$modal.msgSuccess('导入成功');
- await getProductData();
- } catch (e) {
- // 用户取消或请求失败时不提示
- if (e !== 'cancel') {
- console.error('导入失败:', e);
- }
- } finally {
- // 重置文件选择,以便可以重复选择同一文件
- input.value = '';
- }
- };
- onMounted(() => {
- getProductData();
- });
- </script>
- <style scoped>
- .app-container {
- background: #f0f2f5;
- min-height: 100vh;
- padding: 0;
- }
- .detail-header {
- background: #fff;
- padding: 16px 24px;
- display: flex;
- align-items: center;
- border-bottom: 1px solid #e8e8e8;
- margin-bottom: 16px;
- }
- .back-icon {
- font-size: 18px;
- cursor: pointer;
- margin-right: 12px;
- color: #666;
- }
- .back-icon:hover {
- color: #409eff;
- }
- .header-title {
- font-weight: 500;
- color: #333;
- }
- .form-card {
- margin: 16px;
- padding: 24px;
- }
- .section-title {
- margin: 20px 0;
- padding-bottom: 12px;
- border-bottom: 1px solid #e8e8e8;
- }
- </style>
|