Преглед на файлове

feat(price-approval):价格审批模块下直销、供货、成本查看功能添加

xinyan преди 5 месеца
родител
ревизия
91bef660d0

+ 53 - 35
src/stores/countryInfo.ts

@@ -1,40 +1,58 @@
 // 列出国家信息的pinia
 export const useCountryInfoStore = defineStore('countryInfo', () => {
-  const Countries = [
-    { name: '美国', code: 'US', color: '#3C3B6E' }, // 深蓝色
-    { name: '英国', code: 'UK', color: '#00247D' }, // 深蓝色
-    { name: '德国', code: 'DE', color: '#000000' }, // 黑色
-    { name: '法国', code: 'FR', color: '#002395' }, // 深蓝色
-    { name: '西班牙', code: 'ES', color: '#AA151B' }, // 红色
-    { name: '意大利', code: 'IT', color: '#008C45' }, // 绿色
-    { name: '日本', code: 'JP', color: '#BC002D' }, // 红色
-    { name: '加拿大', code: 'CA', color: '#FF0000' }, // 红色
-    { name: '比利时', code: 'BE', color: '#FFD700' }, // 金色
-    { name: '荷兰', code: 'NL', color: '#21468B' }, // 深蓝色
-    { name: '巴西', code: 'BR', color: '#009C3B' },
-    { name: '澳大利亚', code: 'AU', color: '#002868' }, // 深蓝色
-    { name: '俄罗斯', code: 'RU', color: '#0033A0' }, // 深蓝色
-    { name: '墨西哥', code: 'MX', color: '#006847' }, // 绿色
-    { name: '沙特阿拉伯', code: 'SA', color: '#006C35' }, // 绿色
-    { name: '阿联酋', code: 'AE', color: '#00732F' }, // 绿色
-    { name: '澳洲', code: 'AU', color: '#002868' }, // 深蓝色
-    { name: '波兰', code: 'PL', color: '#D22630' }, // 红色
-    { name: '菲律宾', code: 'PH', color: '#0038A8' }, // 蓝色
-    { name: '韩国', code: 'KR', color: '#003478' }, // 深蓝色
-    { name: '马来西亚', code: 'MY', color: '#010066' }, // 深蓝色
-    { name: '葡萄牙', code: 'PT', color: '#006600' }, // 绿色
-    { name: '泰国', code: 'TH', color: '#A51931' }, // 红色
-    { name: '新加坡', code: 'SG', color: '#ED2939' }, // 红色
-  ];
+	const Countries = [
+		{ name: '美国', code: 'US', color: '#3C3B6E' }, // 深蓝色
+		{ name: '英国', code: 'UK', color: '#00247D' }, // 深蓝色
+		{ name: '德国', code: 'DE', color: '#000000' }, // 黑色
+		{ name: '法国', code: 'FR', color: '#002395' }, // 深蓝色
+		{ name: '西班牙', code: 'ES', color: '#AA151B' }, // 红色
+		{ name: '意大利', code: 'IT', color: '#008C45' }, // 绿色
+		{ name: '日本', code: 'JP', color: '#BC002D' }, // 红色
+		{ name: '加拿大', code: 'CA', color: '#FF0000' }, // 红色
+		{ name: '比利时', code: 'BE', color: '#FFD700' }, // 金色
+		{ name: '荷兰', code: 'NL', color: '#21468B' }, // 深蓝色
+		{ name: '巴西', code: 'BR', color: '#009C3B' },
+		{ name: '澳大利亚', code: 'AU', color: '#002868' }, // 深蓝色
+		{ name: '俄罗斯', code: 'RU', color: '#0033A0' }, // 深蓝色
+		{ name: '墨西哥', code: 'MX', color: '#006847' }, // 绿色
+		{ name: '沙特阿拉伯', code: 'SA', color: '#006C35' }, // 绿色
+		{ name: '阿联酋', code: 'AE', color: '#00732F' }, // 绿色
+		{ name: '澳洲', code: 'AU', color: '#002868' }, // 深蓝色
+		{ name: '波兰', code: 'PL', color: '#D22630' }, // 红色
+		{ name: '菲律宾', code: 'PH', color: '#0038A8' }, // 蓝色
+		{ name: '韩国', code: 'KR', color: '#003478' }, // 深蓝色
+		{ name: '马来西亚', code: 'MY', color: '#010066' }, // 深蓝色
+		{ name: '葡萄牙', code: 'PT', color: '#006600' }, // 绿色
+		{ name: '泰国', code: 'TH', color: '#A51931' }, // 红色
+		{ name: '新加坡', code: 'SG', color: '#ED2939' }, // 红色
+	];
 
-  const Region = [
-    { name: '北美站', code: 'NA', color: '#3C3B6E' }, // 深蓝色
-    { name: '欧洲站', code: 'EU', color: '#00247D' }, // 深蓝色
-    { name: '日本站', code: 'JP', color: '#BC002D' }, // 红色
-    { name: '澳大利亚站', code: 'AU', color: '#002868' }, // 深蓝色
-    { name: '新加坡站', code: 'SG', color: '#ED2939' }, // 红色
-    { name: '中东站', code: 'ME', color: '#006C35' }, // 绿色
-  ]
+	const Region = [
+		{ name: '北美站', code: 'NA', color: '#3C3B6E' }, // 深蓝色
+		{ name: '欧洲站', code: 'EU', color: '#00247D' }, // 深蓝色
+		{ name: '日本站', code: 'JP', color: '#BC002D' }, // 红色
+		{ name: '澳大利亚站', code: 'AU', color: '#002868' }, // 深蓝色
+		{ name: '新加坡站', code: 'SG', color: '#ED2939' }, // 红色
+		{ name: '中东站', code: 'ME', color: '#006C35' }, // 绿色
+	];
 
-  return { Countries, Region };
+	const CurrencyCodes = [
+		{ code: 'USD', color: '#4B9CD3' }, // 浅蓝
+		{ code: 'EUR', color: '#A0A0A0' }, // 灰色
+		{ code: 'GBP', color: '#00247D' }, // 深蓝
+		{ code: 'CAD', color: '#D95F0E' }, // 橙色
+		{ code: 'JPY', color: '#BC002D' }, // 红色
+		{ code: 'AUD', color: '#008C45' }, // 绿色
+		{ code: 'KRW', color: '#3B5C8A' }, // 深蓝
+		{ code: 'PHP', color: '#5F9EA0' }, // 青色
+		{ code: 'SGD', color: '#ED2939' }, // 红色
+		{ code: 'MYR', color: '#FFB84D' }, // 黄色
+		{ code: 'THB', color: '#A51931' }, // 深红
+		{ code: 'CNY', color: '#C60000' }, // 红色
+		{ code: 'AED', color: '#FFD700' }, // 金色
+		{ code: 'SAR', color: '#006C35' }, // 深绿色
+		{ code: 'PLN', color: '#D22630' }, // 红色
+	];
+
+	return { Countries, Region, CurrencyCodes };
 });

+ 82 - 64
src/views/price-approval/Columns.ts

@@ -82,94 +82,112 @@ export const CostSelectColumns = [
 
 export const SupplyCheckColumns_Regular = [
 	{ type: 'seq', title: '序 号', width: 50, align: 'center' },
-	{ field: 'description', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true, slots: { default: 'description' } },
-	{ field: 'station', title: '销售模式', minWidth: 'auto', align: 'center', showOverflow: true, slots: { default:'station' } },
-	{ field: 'platform', title: '平 台', minWidth: 'auto', align: 'center', showOverflow: true, slots: { default: 'platform' } },
+	{ field: 'sku', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true,  },
+	{ field: 'sales_mode', title: '销售模式', minWidth: 'auto', align: 'center', showOverflow: true,  },
+	{ field: 'platform', title: '平 台', minWidth: 'auto', align: 'center', showOverflow: true, },
 	{ field: 'country_code', title: '国 家', minWidth: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '亚马逊最低售价', minWidth: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '供货价', minWidth: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '卖场参考价格', minWidth: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '卖场价格(不含VAT)', minWidth: 'auto', align: 'center', showOverflow: true,},
+	// { field: '', title: '亚马逊最低售价', minWidth: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'price_supply', title: '供货价', minWidth: 'auto', align: 'center', showOverflow: true,},
+	// { field: '', title: '卖场参考价格', minWidth: 'auto', align: 'center', showOverflow: true,},
+	// { field: '', title: '卖场价格(不含VAT)', minWidth: 'auto', align: 'center', showOverflow: true,},
 ]
 
 export const SupplyCheckColumns_Special = [
 	{ type: 'seq', title: '序 号', width: 50, align: 'center' },
-	{ field: '', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true, slots: { default: 'description' } },
-	{ field: '', title: '预估硬件成本', width: 'auto', align: 'center', showOverflow: true, slots: { default:'station' } },
-	{ field: '', title: '重量', width: 'auto', align: 'center', showOverflow: true, slots: { default:'station' } },
-	{ field: '', title: '出口报关价', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '进口关税', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '头程运费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '尾程费用', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '转发费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '运费(小计)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '广告费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: 'VAT', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '退货成本/翻新费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '仓储费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '成本合计', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '最低价格成本', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '亚马逊最低售价', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '供货价', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '卖场参考价格', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '卖场价格(不含VAT)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '卖场价格(含VAT)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '最低毛利率', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '汇率', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '日常活动售价(人民币)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '日常活动利润', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '日常活动毛利率', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'sku', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true},
+	{ field: 'platform', title: '平 台', width: 'auto', align: 'center', showOverflow: true, },
+	{ field: 'country_code', title: '国 家', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'country_code' },},
+	{ field: 'currency_code', title: '货币代码', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'currency_code' },},
+	{ field: 'estimated_cost', title: '预估硬件成本', width: 'auto', align: 'center', showOverflow: true ,slots: { default: 'estimated_cost' },},
+	{ field: 'weight', title: '重量(KG)', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'weight' },},
+	{ field: 'export_tax', title: '出口报关价', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'export_tax' },},
+	{ field: 'import_tax', title: '进口关税', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'import_tax' },},
+	{ field: 'first_cost', title: '头程运费', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'first_cost' },},
+	{ field: 'final_cost', title: '尾程费用', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'final_cost' },},
+
+	{ field: 'VAT_price_daily', title: '日常VAT', width: 'auto', align: 'center', showOverflow: true,slots:{ default: 'VAT_price_daily' },},
+	{ field: 'VAT_price_min', title: '最低VAT', width: 'auto', align: 'center', showOverflow: true,slots:{ default: 'VAT_price_min' },},
+	{ field: 'forwarding_fee', title: '转发费', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'forwarding_fee' },},
+	// { field: '', title: '运费(小计)', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'ad_budget', title: '广告费', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'ad_budget' },},
+	// { field: '', title: 'VAT', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'return_or_refurbishment', title: '退货成本/翻新费', width: 'auto', align: 'center', showOverflow: true,slots: { default:'return_or_refurbishment' },},
+	{ field: 'storage_charges', title: '仓储费', width: 'auto', align: 'center', showOverflow: true,slots: { default:'storage_charges' },},
+	{ field: 'brokerage', title: '佣 金', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'brokerage' },},
+	// { field: '', title: '成本合计', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'sales_mode', title: '销售模式', width: 'auto', align: 'center', showOverflow: true,slots: { default:'sales_mode' }},
+	{ field: 'price_min_cost', title: '最低售价成本', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_min_cost' },},
+
+	// { field: '', title: '亚马逊最低售价', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'price_supply', title: '供货价', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_supply' },},
+	// { field: '', title: '卖场参考价格', width: 'auto', align: 'center', showOverflow: true,},
+	// { field: '', title: '卖场价格(不含VAT)', width: 'auto', align: 'center', showOverflow: true,},
+	// { field: '', title: '卖场价格(含VAT)', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'gross_profit_margin', title: '毛利率', width: 'auto', align: 'center', showOverflow: true,slots:{default:'gross_profit_margin'},},
+	{ field: 'exchange_rate', title: '汇率', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'exchange_rate' },},
+	{ field: 'price_daily_rmb', title: '日常活动售价(人民币)', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_daily_rmb' },},
+
+	{ field: 'average_gross_profit', title: '平均毛利', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'average_gross_profit' },},
+	{ field: 'routine_activity_profit', title: '日常活动销售利润', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'routine_activity_profit' } },
+	{ field: 'gross_margin_daily', title: '日常活动毛利率', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'gross_margin_daily' },},
+	{ field: 'operate', fixed: 'right', title: '操 作', align: 'center', width: 90, slots: { default: 'operate' } }
 ]
 
 export const DirectSalesCheckColumns_Regular = [
 	{ type: 'seq', title: '序 号', width: 50, align: 'center' },
-	{ field: '', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true, slots: { default: 'description' } },
-	{ field: '', title: '销售模式', minWidth: 'auto', align: 'center', showOverflow: true, slots: { default:'station' } },
+	{ field: 'sku', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true, slots: { default: 'description' } },
+	{ field: 'sales_mode', title: '销售模式', minWidth: 'auto', align: 'center', showOverflow: true, slots: { default:'station' } },
 	{ field: 'platform', title: '平 台', minWidth: 'auto', align: 'center', showOverflow: true, slots: { default: 'platform' } },
 	{ field: 'country_code', title: '国 家', minWidth: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'price_show', title: '展示价格', minWidth: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '活动价格', minWidth: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '最低活动价格', minWidth: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'price_show', title: '展示价格(外币)', minWidth: 'auto', align: 'center', showOverflow: true,},
+	// { field: '', title: '活动价格', minWidth: 'auto', align: 'center', showOverflow: true,},
+	// { field: '', title: '最低活动价格', minWidth: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'price_daily', title: '日常活动售价(外币)', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'price_daily_rmb', title: '日常活动售价(人民币)', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'price_min', title: '最低售价(外币)', width: 'auto', align: 'center', showOverflow: true,},
 ]
 
 export const DirectSalesCheckColumns_Special = [
 	{ type: 'seq', title: '序 号', width: 50, align: 'center' },
-	{ field: 'sku', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true,  },
+	{ field: 'sku', title: 'SKU', minWidth: 300, align: 'center', showOverflow: true},
 	{ field: 'platform', title: '平 台', width: 'auto', align: 'center', showOverflow: true, },
 	{ field: 'country_code', title: '国 家', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'country_code' },},
-	{ field: 'currency_code', title: '货币代码', width: 'auto', align: 'center', showOverflow: true, },
-	{ field: 'estimated_cost', title: '预估硬件成本', width: 'auto', align: 'center', showOverflow: true,  },
-	{ field: 'weight', title: '重量(KG)', width: 'auto', align: 'center', showOverflow: true,  },
-	{ field: 'export_tax', title: '出口报关价', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'import_tax', title: '进口关税', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'first_cost', title: '头程运费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'final_cost', title: '尾程费用', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'VAT_price_daily', title: '日常VAT', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'VAT_price_min', title: '最低VAT', width: 'auto', align: 'center', showOverflow: true,},
-	// { field: '', title: '转发费', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'currency_code', title: '货币代码', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'currency_code' },},
+	{ field: 'estimated_cost', title: '预估硬件成本', width: 'auto', align: 'center', showOverflow: true ,slots: { default: 'estimated_cost' },},
+	{ field: 'weight', title: '重量(KG)', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'weight' },},
+	{ field: 'export_tax', title: '出口报关价', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'export_tax' },},
+	{ field: 'import_tax', title: '进口关税', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'import_tax' },},
+	{ field: 'first_cost', title: '头程运费', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'first_cost' },},
+	{ field: 'final_cost', title: '尾程费用', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'final_cost' },},
+
+	{ field: 'VAT_price_daily', title: '日常VAT', width: 'auto', align: 'center', showOverflow: true,slots:{ default: 'VAT_price_daily' },},
+	{ field: 'VAT_price_min', title: '最低VAT', width: 'auto', align: 'center', showOverflow: true,slots:{ default: 'VAT_price_min' },},
+	{ field: 'forwarding_fee', title: '转发费', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'forwarding_fee' },},
 	// { field: '', title: '运费(小计)', width: 'auto', align: 'center', showOverflow: true,},
 	{ field: 'ad_budget', title: '广告费', width: 'auto', align: 'center', showOverflow: true,},
 	// { field: '', title: 'VAT', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'return_or_refurbishment', title: '退货成本/翻新费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'storage_charges', title: '仓储费', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'brokerage', title: '佣 金', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'return_or_refurbishment', title: '退货成本/翻新费', width: 'auto', align: 'center', showOverflow: true,slots: { default:'return_or_refurbishment' },},
+	{ field: 'storage_charges', title: '仓储费', width: 'auto', align: 'center', showOverflow: true,slots: { default:'storage_charges' },},
+	{ field: 'brokerage', title: '佣 金', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'brokerage' },},
 	// { field: '', title: '成本合计', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'sales_mode', title: '销售模式', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'price_min_cost', title: '最低售价成本', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'price_daily', title: '日常活动售价(外币)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'price_show', title: '展示价格(外币)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'price_daily_rate', title: '日常折扣', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'discount_min', title: '最低活动折扣', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'price_min', title: '最低售价(外币)', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'sales_mode', title: '销售模式', width: 'auto', align: 'center', showOverflow: true,slots: { default:'sales_mode' }},
+	{ field: 'price_min_cost', title: '最低售价成本', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_min_cost' },},
+
+	{ field: 'price_daily', title: '日常活动售价(外币)', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_daily' },},
+	{ field: 'price_show', title: '展示价格(外币)', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_show' },},
+	{ field: 'discount_daily', title: '日常折扣', width: 'auto', align: 'center', showOverflow: true,slots:{ default: 'discount_daily' },},
+	{ field: 'discount_min', title: '最低活动折扣', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'discount_min' },},
+	{ field: 'price_min', title: '最低售价(外币)', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_min' },},
 	// { field: '', title: '供货价', width: 'auto', align: 'center', showOverflow: true,},
 	// { field: '', title: '卖场参考价格', width: 'auto', align: 'center', showOverflow: true,},
 	// { field: '', title: '卖场价格(不含VAT)', width: 'auto', align: 'center', showOverflow: true,},
 	// { field: '', title: '卖场价格(含VAT)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'gross_profit_margin', title: '毛利率', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'exchange_rate', title: '汇率', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: 'price_daily_rmb', title: '日常活动售价(人民币)', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '日常活动利润', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '日常活动毛利率', width: 'auto', align: 'center', showOverflow: true,},
-	{ field: '', title: '平均利润', width: 'auto', align: 'center', showOverflow: true,},
+	{ field: 'gross_profit_margin', title: '毛利率', width: 'auto', align: 'center', showOverflow: true,slots:{default:'gross_profit_margin'},},
+	{ field: 'exchange_rate', title: '汇率', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'exchange_rate' },},
+	{ field: 'price_daily_rmb', title: '日常活动售价(人民币)', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'price_daily_rmb' },},
+
+	{ field: 'average_gross_profit', title: '平均毛利', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'average_gross_profit' },},
+	{ field: 'routine_activity_profit', title: '日常活动销售利润', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'routine_activity_profit' } },
+	{ field: 'gross_margin_daily', title: '日常活动毛利率', width: 'auto', align: 'center', showOverflow: true,slots: { default: 'gross_margin_daily' },},
 	{ field: 'operate', fixed: 'right', title: '操 作', align: 'center', width: 90, slots: { default: 'operate' } }
 ]

+ 18 - 1
src/views/price-approval/approval-review-supply/api.ts

@@ -44,10 +44,27 @@ export function getDetail(query: any) {
 
 export function getOptions(query: any) {
 	return request({
-		url: '/api/pricing/price_cost/platform_country_code/',
+		url: '/api/pricing/price_cost/price_product_supply/box/',
 		method: 'GET',
 		params: query
 	});
 }
 
+export function exportData(query: any) {
+	return request({
+		url: apiPrefix + 'export_data/',
+		method: 'GET',
+		responseType: 'blob',
+		params: query
+	});
+}
+
+export function upload(body: any){
+	return request({
+		url: apiPrefix +'import_data/',
+		method: 'POST',
+		data: body,
+	});
+}
+
 

+ 54 - 81
src/views/price-approval/approval-review-supply/components/DataTable.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 /**
  * @Name: DataTable.vue
- * @Description:
+ * @Description:审批查看(供货)数据表格
  * @Author: xinyan
  */
 
@@ -10,22 +10,28 @@ import { ElMessage } from 'element-plus';
 import { usePagination } from '/@/utils/usePagination';
 import { useTableData } from '/@/utils/useTableData';
 import DataTableSlot from './DataTableSlot.vue';
+import { uesDownloadFile } from '/@/utils/useDownload';
+import { downloadFile } from '/@/utils/service';
 import PermissionButton from '/src/components/PermissionButton/index.vue';
 import ImportButton from '/src/components/ImportButton/index.vue';
 import VerticalDivider from '/src/components/VerticalDivider/index.vue';
-import EditDrawer from '/src/views/product-manage/product-list/component/EditDrawer.vue';
-import NoticeDialog from '/src/views/product-manage/product-list/component/NoticeDialog.vue';
 import * as api from '../api';
 import { useResponse } from '/@/utils/useResponse';
-import { CostDetailColumns, SupplyCheckColumns_Regular } from '/@/views/price-approval/Columns';
+import {
+	CostDetailColumns,
+	SupplyCheckColumns_Regular,
+	SupplyCheckColumns_Special,
+} from '/@/views/price-approval/Columns';
+import EditDrawer from '/@/views/price-approval/approval-review-supply/components/EditDrawer.vue';
 
 
 const router = useRouter();
 
 interface Parameter {
-  description: string;
-  platform: string;
-  station: string;
+	sku: string;
+	platform: string;
+	country_code: string;
+	sales_mode: string;
 }
 
 const queryParameter: Parameter | undefined = inject('query-parameter');
@@ -92,10 +98,15 @@ async function fetchList(isQuery = false) {
   gridOptions.data = [];
   gridOptions.columns = [];
 
-  const query = {};
+  const query = {
+		sku: queryParameter?.sku,
+		platform: queryParameter?.platform,
+		country_code: queryParameter?.country_code,
+		sales_mode: queryParameter?.sales_mode,
+	};
 
   await useTableData(api.getTableData, query, gridOptions);
-  if (gridOptions && gridOptions.data?.length) await gridRef.value.loadColumn(SupplyCheckColumns_Regular);
+  if (gridOptions && gridOptions.data?.length) await gridRef.value.loadColumn(SupplyCheckColumns_Special);
   gridOptions.showHeader = Boolean(gridOptions.data?.length);
 }
 
@@ -104,50 +115,25 @@ function handleRefresh() {
 }
 
 async function handleDownload() {
-  gridOptions.loading = true;
-  try {
-    const query = {
-      description: queryParameter?.description,
-      platform: queryParameter?.platform,
-      station: queryParameter?.station
-    };
-    const response = await api.exportData(query);
-    const url = window.URL.createObjectURL(new Blob([ response.data ]));
-    const link = document.createElement('a');
-    link.href = url;
-    link.setAttribute('download', '商品列表数据.xlsx');
-    document.body.appendChild(link);
-    link.click();
-    ElMessage.success('数据导出成功!');
-  } catch (error) {
-    ElMessage.error('数据导出失败,请重试!');
-    console.error(error);
-  } finally {
-    gridOptions.loading = false; // 结束加载状态
-  }
+	gridOptions.loading = true;
+	try {
+		await uesDownloadFile({
+			apiMethod: api.exportData,
+			queryParams: {
+				sku: queryParameter?.sku,
+				platform: queryParameter?.platform,
+				country_code:queryParameter?.country_code,
+				sales_mode: queryParameter?.sales_mode,
+			},
+			fileName: '审批查看(供货)数据.xlsx',
+			successMessage: () => ElMessage.success('数据导出成功!'),
+			errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
+		});
+	} finally {
+		gridOptions.loading = false;
+	}
 }
 
-function selectChangeEvent({ checked, row }: any) {
-  if (checked) {
-    checkedList.value.add(row.id); // 获取单个数据
-  } else {
-    checkedList.value.delete(row.id);
-  }
-}
-
-function selectAllChangeEvent({ checked }: any) {
-  const $grid = gridRef.value;
-  if ($grid) {
-    const records = $grid.getData(); // 获取所有数据
-    if (checked) {
-      records.forEach((item: any) => {
-        checkedList.value.add(item.id);
-      });
-    } else {
-      checkedList.value.clear();
-    }
-  }
-}
 
 function handleCreate() {
   router.push({ path: '/addPage', query: { type: 'supply' } });
@@ -167,18 +153,18 @@ async function singleDelete(row: any) {
 }
 
 function downloadTemplate() {
-  // const url = '/api/choice/reviews_monitor/import_data/';
-  // const fileName = '审批查看(供货)模板.xlsx';
-  //
-  // if (url) {
-  // 	downloadFile({
-  // 		url,
-  // 		method: 'GET',
-  // 		filename: fileName,
-  // 	});
-  // } else {
-  // 	console.error('未知的模板类型:', templateType.value);
-  // }
+  const url = '/api/pricing/price_product_supply/import_data/';
+  const fileName = '审批查看(供货)模板.xlsx';
+
+  if (url) {
+  	downloadFile({
+  		url,
+  		method: 'GET',
+  		filename: fileName,
+  	});
+  } else {
+  	console.error('未知的模板类型:', templateType.value);
+  }
 }
 
 const gridEvents = {
@@ -191,7 +177,7 @@ const gridEvents = {
 
 function cellStyle() {
   return {
-    fontWeight: 500
+    fontWeight: 500,
   };
 }
 
@@ -199,27 +185,15 @@ defineExpose({ fetchList });
 </script>
 
 <template>
-  <vxe-grid ref="gridRef" :cell-style="cellStyle" v-bind="gridOptions" v-on="gridEvents"
-            @checkbox-change="selectChangeEvent" @checkbox-all="selectAllChangeEvent">
+  <vxe-grid ref="gridRef" :cell-style="cellStyle" v-bind="gridOptions" v-on="gridEvents">
     <!-- 工具栏左侧 -->
     <template #toolbar_buttons>
       <div class="flex gap-2">
-        <!--<div>-->
-        <!--	<el-popconfirm :icon="InfoFilled" icon-color="#626AEF" title="你确定要删除此项吗?" width="220" @confirm="batchDelete">-->
-        <!--		<template #reference>-->
-        <!--			<PermissionButton :disabled="!checkedList.size" :icon="Delete" plain round type="danger"> 批量删除 </PermissionButton>-->
-        <!--		</template>-->
-        <!--		<template #actions="{ confirm, cancel }">-->
-        <!--			<el-button size="small" @click="cancel">No!</el-button>-->
-        <!--			<el-button size="small" type="danger" @click="confirm">Yes?</el-button>-->
-        <!--		</template>-->
-        <!--	</el-popconfirm>-->
-        <!--</div>-->
         <div>
           <PermissionButton :icon="Plus" plain round type="primary" @click="handleCreate">新 增</PermissionButton>
         </div>
         <div class="custom-el-input">
-          <el-select v-model="templateType" style="width: 190px">
+          <el-select v-model="templateType" style="width: 200px">
             <template #prefix>
               <div class="flex items-center">
                 <el-button
@@ -234,7 +208,7 @@ defineExpose({ fetchList });
                 <VerticalDivider style="margin-left: 7px" />
               </div>
             </template>
-            <el-option label="成本查看模板" value="cost" />
+            <el-option label="审批查看(供货)" value="cost" />
           </el-select>
         </div>
         <VerticalDivider class="px-1" style="margin-left: 7px" />
@@ -271,12 +245,11 @@ defineExpose({ fetchList });
       <el-empty description="暂无数据" />
     </template>
     <!-- 自定义列插槽 -->
-    <template v-for="col in CostDetailColumns" #[`${col.field}`]="{ row }">
+    <template v-for="col in SupplyCheckColumns_Special" #[`${col.field}`]="{ row }">
       <DataTableSlot :field="col.field" :row="row" @edit-row="handleEdit" @handle-delete="singleDelete" />
     </template>
   </vxe-grid>
   <EditDrawer v-if="editOpen" v-model="editOpen" :row-data="rowData" @refresh="handleRefresh" />
-  <NoticeDialog v-if="dialogVisible" v-model="dialogVisible" :row-data="rowData" />
 </template>
 
 <style scoped>

+ 78 - 43
src/views/price-approval/approval-review-supply/components/DataTableSlot.vue

@@ -1,68 +1,103 @@
 <script lang="ts" setup>
 /**
  * @Name: DataTableSlot.vue
- * @Description:
+ * @Description: 审批查看(供货) 插槽
  * @Author: xinyan
  */
 
 import { hasPermission } from '/@/utils/hasPermission';
 import { Delete, InfoFilled, Operation } from '@element-plus/icons-vue';
 import PermissionButton from '/@/components/PermissionButton/index.vue';
-
+import { useCountryInfoStore } from '/@/stores/countryInfo';
 
 const props = defineProps<{
-  row: any;
-  field: any;
+	row: any;
+	field: any;
 }>();
 const { row, field } = props;
 
-const emit = defineEmits([ 'edit-row', 'handle-delete', 'handle-manage', 'show-detail' ]);
+const emit = defineEmits(['edit-row', 'handle-delete', 'handle-manage', 'show-detail']);
+
+const countryInfoStore = useCountryInfoStore();
+const country = countryInfoStore.Countries.find((c) => c.name == row.country_code);
+const color = country ? country.color : '#3875F6';
+
+const currency = countryInfoStore.CurrencyCodes.find((c) => c.code == row.currency_code);
+const currencyColor = currency ? currency.color : '#626AEF';
+
+// 日常活动销售利润 = 日常活动售价(人民币)-出口报关价-头程运费-尾程费用-转发费-广告费-退货成本-VAT-仓储费-佣金
+const routine_activity_profit = computed(
+	() =>
+		row.price_daily_rmb -
+		(row.export_tax + row.first_cost + row.final_cost +row.forwarding_fee+ row.ad_budget + row.return_or_refurbishment + row.storage_charges + row.brokerage)
+);
+
+// 日常活动毛利率 = 日常活动销售利润/日常活动售价(人民币)
+const gross_margin_daily = computed(() => routine_activity_profit.value / row.price_daily_rmb);
+
+// 平均毛利 = 0.8*日常活动毛利率 + 0.2*毛利率
+const average_gross_profit = computed(() => 0.8*gross_margin_daily.value +0.2*row.gross_profit_margin);
 
 function handleEdit() {
-  emit('edit-row', row);
+	emit('edit-row', row);
 }
 
 function onConfirm() {
-  emit('handle-delete', row);
+	emit('handle-delete', row);
 }
-
 </script>
 
 <template>
-  <div class="font-medium">
-    <div v-if="field === 'operate'">
-      <div class="flex justify-center gap-2">
-        <div v-if="hasPermission('SkuAttrUpdate')">
-          <PermissionButton circle plain type="warning" @click="handleEdit">
-            <el-icon>
-              <Operation />
-            </el-icon>
-          </PermissionButton>
-        </div>
-        <div v-if="hasPermission('SkuAttrDelete')">
-          <el-popconfirm :icon="InfoFilled" icon-color="#626AEF" title="你确定要删除此项吗?" width="220"
-                         @confirm="onConfirm">
-            <template #reference>
-              <PermissionButton circle plain type="danger">
-                <el-icon>
-                  <Delete />
-                </el-icon>
-              </PermissionButton>
-            </template>
-            <template #actions="{ confirm, cancel }">
-              <el-button size="small" @click="cancel">No!</el-button>
-              <el-button size="small" type="danger" @click="confirm"> Yes?</el-button>
-            </template>
-          </el-popconfirm>
-        </div>
-      </div>
-    </div>
-    <div v-else>
-      {{ row[field] || '-' }}
-    </div>
-  </div>
+	<div class="font-medium">
+		<div v-if="field === 'operate'">
+			<div class="flex justify-center gap-2">
+				<div v-if="hasPermission('SkuAttrUpdate')">
+					<PermissionButton circle plain type="warning" @click="handleEdit">
+						<el-icon>
+							<Operation />
+						</el-icon>
+					</PermissionButton>
+				</div>
+				<div v-if="hasPermission('SkuAttrDelete')">
+					<el-popconfirm :icon="InfoFilled" icon-color="#626AEF" title="你确定要删除此项吗?" width="220" @confirm="onConfirm">
+						<template #reference>
+							<PermissionButton circle plain type="danger">
+								<el-icon>
+									<Delete />
+								</el-icon>
+							</PermissionButton>
+						</template>
+						<template #actions="{ confirm, cancel }">
+							<el-button size="small" @click="cancel">No!</el-button>
+							<el-button size="small" type="danger" @click="confirm"> Yes?</el-button>
+						</template>
+					</el-popconfirm>
+				</div>
+			</div>
+		</div>
+		<div v-else-if="field === 'average_gross_profit'">
+			{{ average_gross_profit || '-'}}
+		</div>
+		<div v-else-if="field === 'routine_activity_profit'">
+			{{ routine_activity_profit || '-'}}
+		</div>
+		<div v-else-if="field === 'gross_margin_daily'">
+			{{ gross_margin_daily || '-'}}
+		</div>
+		<div v-else-if="field === 'country_code'">
+			<el-tag :disable-transitions="true" :style="{ color: color, borderColor: color }" effect="plain" round>
+				{{ country ? country.name : '-' }}
+			</el-tag>
+		</div>
+		<div v-else-if="field === 'currency_code'">
+			<el-tag :disable-transitions="true" :style="{ color: currencyColor, borderColor: currencyColor }" effect="plain" round>
+				{{ currency ? currency.code : '-' }}
+			</el-tag>
+		</div>
+		<div v-else>
+			{{ row[field] || '-' }}
+		</div>
+	</div>
 </template>
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 188 - 0
src/views/price-approval/approval-review-supply/components/EditDrawer.vue

@@ -0,0 +1,188 @@
+<script lang="ts" setup>
+/**
+ * @Name: EditDrawer.vue
+ * @Description: 价格审批(供货)- 编辑抽屉
+ * @Author: xinyan
+ */
+
+import { ElMessage, FormInstance, FormRules } from 'element-plus';
+import { Close, Finished } from '@element-plus/icons-vue';
+import { useResponse } from '/@/utils/useResponse';
+import * as api from '../api';
+import { getCurrencyCodeOptions } from '/@/views/price-approval/api';
+
+
+const countryOptions = <Ref>inject('countryOptions');
+console.log("=>(EditDrawer.vue:16) countryOptions", countryOptions);
+const btnLoading = ref(false);
+
+const editOpen = defineModel({ default: false });
+
+const editDrawer = <Ref>useTemplateRef('editDrawer');
+
+const currencyCodeOptions = ref([]);
+
+const props: any = defineProps({
+	rowData: Object
+});
+const { rowData } = props;
+
+const emit = defineEmits([ 'refresh' ]);
+
+interface RuleForm {
+	sku: string;
+	weight: string;
+	platform: string;
+	country_code: string;
+	currency_code: string;
+	estimated_cost: string;
+	price_show: string;
+	price_daily: string;
+	price_min: string;
+	final_cost: string;
+	sales_mode: string;
+	cost: string;
+}
+
+const ruleFormRef = ref<FormInstance>();
+const ruleForm = reactive<RuleForm>({
+	sku: rowData.sku,
+	weight: rowData.weight,
+	platform: rowData.platform,
+	country_code: rowData.country_code,
+	currency_code: rowData.currency_code,
+	estimated_cost: rowData.estimated_cost,
+	price_show: rowData.price_show,
+	price_daily: rowData.price_daily,
+	price_min: rowData.price_min,
+	final_cost: rowData.final_cost,
+	sales_mode: rowData.sales_mode,
+	cost: rowData.cost
+});
+
+const rules = reactive<FormRules<RuleForm>>({
+	sku: [ { required: true, message: '请输入SKU', trigger: 'blur' } ],
+	platform: [ { required: true, message: '请输入平台', trigger: 'blur' } ],
+	country_code: [ { required: true, message: '请输入国家', trigger: 'blur' } ],
+	currency_code: [ { required: true, message: '请选择货币代码', trigger: 'change' } ],
+	estimated_cost: [ { required: true, message: '请输入预估成本', trigger: 'blur' } ]
+});
+
+onBeforeMount(() => {
+	fetchCurrencyCodeOptions();
+});
+
+async function fetchCurrencyCodeOptions() {
+	const res = await useResponse(getCurrencyCodeOptions);
+	currencyCodeOptions.value = res.data.currency_code;
+}
+
+const submitForm = async (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	await formEl.validate(async (valid, fields) => {
+		if (valid) {
+			try {
+				const res = await useResponse(api.updateRow, { id: rowData?.id, ...ruleForm }, btnLoading);
+				if (res && res.code == 2000) {
+					editOpen.value = false;
+					ElMessage.success({ message: '编辑成功', plain: true, icon: 'Operation' });
+					emit('refresh');
+				}
+			} catch (error) {
+				console.error('Error==>', error);
+			}
+		} else {
+			console.log('error submit!', fields);
+		}
+	});
+};
+
+function closeDrawer() {
+	editDrawer.value.handleClose();
+}
+</script>
+
+<template>
+	<div class="drawer-container">
+		<el-drawer
+			ref="editDrawer"
+			v-model="editOpen"
+			:close-on-click-modal="false"
+			:close-on-press-escape="false"
+			:title="`审批查看(直销) - 编辑 `"
+			size="30%"
+		>
+			<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" class="mx-2.5 mt-7" label-position="top"
+							 label-width="auto" status-icon>
+				<el-row :gutter="20">
+					<el-col :span="12">
+						<el-form-item class="font-medium" label="SKU" prop="sku">
+							<el-input v-model="ruleForm.sku" placeholder="请输入SKU" />
+						</el-form-item>
+						<el-form-item class="font-medium" label="平 台" prop="platform">
+							<el-input v-model="ruleForm.platform" placeholder="请输入平台"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="货币代码" prop="currency_code">
+							<el-select v-model="ruleForm.currency_code" placeholder="请选择货币代码">
+								<el-option v-for="item in currencyCodeOptions" :label="item" :value="item" />
+							</el-select>
+						</el-form-item>
+						<el-form-item class="font-medium" label="展示价格(外币)" prop="price_show">
+							<el-input v-model="ruleForm.price_show" placeholder="请输入展示价格(外币)"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="最低售价(外币)" prop="price_min">
+							<el-input v-model="ruleForm.price_min" placeholder="请输入最低售价(外币)"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="销售模式" prop="sales_mode">
+							<el-select v-model="ruleForm.sales_mode" clearable placeholder="请选择销售模式">
+								<el-option label="线上" value="线上"></el-option>
+								<el-option label="线下" value="线下"></el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item class="font-medium" label="重量(KG)" prop="weight">
+							<el-input v-model="ruleForm.weight" placeholder="请输入重量"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="国 家" prop="country_code">
+							<el-select v-model="ruleForm.country_code" placeholder="请选择国家">
+								<el-option v-for="item in countryOptions" :key="item" :label="item" :value="item"></el-option>
+							</el-select>
+						</el-form-item>
+						<el-form-item class="font-medium" label="预估硬件成本" prop="estimated_cost">
+							<el-input v-model="ruleForm.estimated_cost" placeholder="请输入预估硬件成本"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="日常活动售价(外币)" prop="price_daily">
+							<el-input v-model="ruleForm.price_daily" placeholder="请输入展示价格(外币)"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="尾程费用(外币)" prop="final_cost">
+							<el-input v-model="ruleForm.final_cost" placeholder="请输入尾程费用(外币)"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="成本" prop="cost">
+							<el-input v-model="ruleForm.cost" placeholder="请输入成本"></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-form-item>
+					<el-divider />
+					<div class="flex flex-1 justify-end">
+						<el-button :icon="Close" @click="closeDrawer">取 消</el-button>
+						<el-button :icon="Finished" :loading="btnLoading" type="primary" @click="submitForm(ruleFormRef)"> 确 定
+						</el-button>
+					</div>
+				</el-form-item>
+			</el-form>
+		</el-drawer>
+	</div>
+</template>
+
+<style scoped>
+.drawer-container :deep(.el-drawer__header) {
+	border-bottom: none;
+	font-weight: 500;
+}
+
+.drawer-container :deep(.el-drawer__title) {
+	font-size: 18px;
+}
+</style>

+ 2 - 1
src/views/price-approval/approval-review-supply/index.vue

@@ -95,7 +95,8 @@ async function resetParameter() {
 								<div class="flex items-center">
 									<span class="mr-2">销售模式</span>
 									<el-select v-model="formInline.sales_mode" clearable placeholder="请选择销售模式">
-										<el-option></el-option>
+										<el-option label="线上" value="线上"></el-option>
+										<el-option label="线下" value="线下"></el-option>
 									</el-select>
 								</div>
 							</el-col>

+ 18 - 0
src/views/price-approval/cost-detail/api.ts

@@ -51,4 +51,22 @@ export function getCostOptions(query: any) {
 	});
 }
 
+export function exportData(query: any) {
+	return request({
+		url: apiPrefix + 'export_data/',
+		method: 'GET',
+		responseType: 'blob',
+		params: query
+	});
+}
+
+export function upload(body: any){
+	return request({
+		url: apiPrefix +'import_data/',
+		method: 'POST',
+		data: body,
+	});
+}
+
+
 

+ 28 - 51
src/views/price-approval/cost-detail/component/DataTable.vue

@@ -19,6 +19,7 @@ import { useResponse } from '/@/utils/useResponse';
 import { CostDetailColumns } from '/@/views/price-approval/Columns';
 import CreateDialog from '/@/views/price-approval/cost-detail/component/CreateDialog.vue';
 import EditDrawer from '/@/views/price-approval/cost-detail/component/EditDrawer.vue';
+import { downloadFile } from '/@/utils/service';
 
 interface Parameter {
 	description: string;
@@ -113,43 +114,21 @@ function handleRefresh() {
 }
 
 async function handleDownload() {
-	// gridOptions.loading = true;
-	// try {
-	// 	await uesDownloadFile({
-	// 		apiMethod: api.exportData,
-	// 		queryParams: {
-	// 			description: queryParameter?.description,
-	// 			platform: queryParameter?.platform,
-	// 			station: queryParameter?.station,
-	// 		},
-	// 		fileName: '成本查看数据.xlsx', // 自定义文件名
-	// 		successMessage: () => ElMessage.success('数据导出成功!'),
-	// 		errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
-	// 	});
-	// } finally {
-	// 	gridOptions.loading = false; // 结束加载状态
-	// }
-}
-
-function selectChangeEvent({ checked, row }: any) {
-	if (checked) {
-		checkedList.value.add(row.id); // 获取单个数据
-	} else {
-		checkedList.value.delete(row.id);
-	}
-}
-
-function selectAllChangeEvent({ checked }: any) {
-	const $grid = gridRef.value;
-	if ($grid) {
-		const records = $grid.getData(); // 获取所有数据
-		if (checked) {
-			records.forEach((item: any) => {
-				checkedList.value.add(item.id);
-			});
-		} else {
-			checkedList.value.clear();
-		}
+	gridOptions.loading = true;
+	try {
+		await uesDownloadFile({
+			apiMethod: api.exportData,
+			queryParams: {
+				description: queryParameter?.description,
+				platform: queryParameter?.platform,
+				station: queryParameter?.station,
+			},
+			fileName: '成本查看数据.xlsx', // 自定义文件名
+			successMessage: () => ElMessage.success('数据导出成功!'),
+			errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
+		});
+	} finally {
+		gridOptions.loading = false; // 结束加载状态
 	}
 }
 
@@ -171,18 +150,18 @@ async function singleDelete(row: any) {
 }
 
 function downloadTemplate() {
-	// const url = '/api/choice/reviews_monitor/import_data/';
-	// const fileName = '商品监控模板.xlsx';
-	//
-	// if (url) {
-	// 	downloadFile({
-	// 		url,
-	// 		method: 'GET',
-	// 		filename: fileName,
-	// 	});
-	// } else {
-	// 	console.error('未知的模板类型:', templateType.value);
-	// }
+	const url = '/api/pricing/price_cost/import_data/';
+	const fileName = '成本查看模板.xlsx';
+
+	if (url) {
+		downloadFile({
+			url,
+			method: 'GET',
+			filename: fileName,
+		});
+	} else {
+		console.error('未知的模板类型:', templateType.value);
+	}
 }
 
 const gridEvents = {
@@ -208,8 +187,6 @@ defineExpose({ fetchList });
 		:cell-style="cellStyle"
 		v-bind="gridOptions"
 		v-on="gridEvents"
-		@checkbox-change="selectChangeEvent"
-		@checkbox-all="selectAllChangeEvent"
 	>
 		<!-- 工具栏左侧 -->
 		<template #toolbar_buttons>

+ 18 - 1
src/views/price-approval/direct-sales/api.ts

@@ -28,8 +28,25 @@ export function deleteRow(body: any) {
 
 export function getOptions(query: any) {
 	return request({
-		url: '/api/pricing/price_cost/platform_country_code/',
+		url: '/api/pricing/price_cost/price_product_direct/box/',
 		method: 'GET',
 		params: query
 	});
+}
+
+export function exportData(query: any) {
+	return request({
+		url: apiPrefix + 'export_data/',
+		method: 'GET',
+		responseType: 'blob',
+		params: query
+	});
+}
+
+export function upload(body: any){
+	return request({
+		url: apiPrefix +'import_data/',
+		method: 'POST',
+		data: body,
+	});
 }

+ 31 - 32
src/views/price-approval/direct-sales/component/DataTable.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 /**
  * @Name: DataTable.vue
- * @Description:
+ * @Description: 审批查看(直销)数据表格
  * @Author: xinyan
  */
 
@@ -112,23 +112,23 @@ function handleRefresh() {
 }
 
 async function handleDownload() {
-  // gridOptions.loading = true;
-  // try {
-  // 	await uesDownloadFile({
-  // 		apiMethod: api.exportData, // 调用的 API 方法
-  // 		queryParams: {
-  // 			sku: queryParameter?.sku,
-  // 			platform: queryParameter?.platform,
-  // 			country_code:queryParameter?.country_code,
-  // 			sales_mode: queryParameter?.sales_mode,
-  // 		},
-  // 		fileName: '审批查看(直销)数据.xlsx', // 自定义文件名
-  // 		successMessage: () => ElMessage.success('数据导出成功!'),
-  // 		errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
-  // 	});
-  // } finally {
-  // 	gridOptions.loading = false; // 结束加载状态
-  // }
+  gridOptions.loading = true;
+  try {
+  	await uesDownloadFile({
+  		apiMethod: api.exportData,
+  		queryParams: {
+  			sku: queryParameter?.sku,
+  			platform: queryParameter?.platform,
+  			country_code:queryParameter?.country_code,
+  			sales_mode: queryParameter?.sales_mode,
+  		},
+  		fileName: '审批查看(直销)数据.xlsx',
+  		successMessage: () => ElMessage.success('数据导出成功!'),
+  		errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
+  	});
+  } finally {
+  	gridOptions.loading = false;
+  }
 }
 
 function handleCreate() {
@@ -149,18 +149,18 @@ async function singleDelete(row: any) {
 }
 
 function downloadTemplate() {
-  // const url = '/api/choice/reviews_monitor/import_data/';
-  // const fileName = '审批查看(直销)模板.xlsx';
-  //
-  // if (url) {
-  // 	downloadFile({
-  // 		url,
-  // 		method: 'GET',
-  // 		filename: fileName,
-  // 	});
-  // } else {
-  // 	console.error('未知的模板类型:', templateType.value);
-  // }
+  const url = '/api/pricing/price_product_direct/import_data/';
+  const fileName = '审批查看(直销)模板.xlsx';
+
+  if (url) {
+  	downloadFile({
+  		url,
+  		method: 'GET',
+  		filename: fileName,
+  	});
+  } else {
+  	console.error('未知的模板类型:', templateType.value);
+  }
 }
 
 const gridEvents = {
@@ -181,8 +181,7 @@ defineExpose({ fetchList });
 </script>
 
 <template>
-  <vxe-grid ref="gridRef" :cell-style="cellStyle" v-bind="gridOptions" v-on="gridEvents"
-            @checkbox-change="selectChangeEvent" @checkbox-all="selectAllChangeEvent">
+  <vxe-grid ref="gridRef" :cell-style="cellStyle" v-bind="gridOptions" v-on="gridEvents">
     <!-- 工具栏左侧 -->
     <template #toolbar_buttons>
       <div class="flex gap-2">

+ 51 - 48
src/views/price-approval/direct-sales/component/DataTableSlot.vue

@@ -10,69 +10,72 @@ import { Delete, InfoFilled, Operation } from '@element-plus/icons-vue';
 import PermissionButton from '/@/components/PermissionButton/index.vue';
 import { useCountryInfoStore } from '/@/stores/countryInfo';
 
-
 const props = defineProps<{
-  row: any;
-  field: any;
+	row: any;
+	field: any;
 }>();
 const { row, field } = props;
 
-const emit = defineEmits([ 'edit-row', 'handle-delete', 'handle-manage', 'show-detail' ]);
+const emit = defineEmits(['edit-row', 'handle-delete', 'handle-manage', 'show-detail']);
 
 const countryInfoStore = useCountryInfoStore();
-const country = countryInfoStore.Countries.find(c => c.code == row.country_code);
+const country = countryInfoStore.Countries.find((c) => c.name == row.country_code);
 const color = country ? country.color : '#3875F6';
 
+const currency = countryInfoStore.CurrencyCodes.find((c) => c.code == row.currency_code);
+const currencyColor = currency ? currency.color : '#626AEF';
+
 function handleEdit() {
-  emit('edit-row', row);
+	emit('edit-row', row);
 }
 
 function onConfirm() {
-  emit('handle-delete', row);
+	emit('handle-delete', row);
 }
-
 </script>
 
 <template>
-  <div class="font-medium">
-    <div v-if="field === 'operate'">
-      <div class="flex justify-center gap-2">
-        <div v-if="hasPermission('SkuAttrUpdate')">
-          <PermissionButton circle plain type="warning" @click="handleEdit">
-            <el-icon>
-              <Operation />
-            </el-icon>
-          </PermissionButton>
-        </div>
-        <div v-if="hasPermission('SkuAttrDelete')">
-          <el-popconfirm :icon="InfoFilled" icon-color="#626AEF" title="你确定要删除此项吗?" width="220"
-                         @confirm="onConfirm">
-            <template #reference>
-              <PermissionButton circle plain type="danger">
-                <el-icon>
-                  <Delete />
-                </el-icon>
-              </PermissionButton>
-            </template>
-            <template #actions="{ confirm, cancel }">
-              <el-button size="small" @click="cancel">No!</el-button>
-              <el-button size="small" type="danger" @click="confirm"> Yes?</el-button>
-            </template>
-          </el-popconfirm>
-        </div>
-      </div>
-    </div>
-    <div v-else-if="field === 'country_code'">
-      <el-tag :disable-transitions="true" :style="{ color: color, borderColor: color }" effect="plain" round>
-        {{ country ? country.name : '-' }}
-      </el-tag>
-    </div>
-    <div v-else>
-      {{ row[field] || '-' }}
-    </div>
-  </div>
+	<div class="font-medium">
+		<div v-if="field === 'operate'">
+			<div class="flex justify-center gap-2">
+				<div v-if="hasPermission('SkuAttrUpdate')">
+					<PermissionButton circle plain type="warning" @click="handleEdit">
+						<el-icon>
+							<Operation />
+						</el-icon>
+					</PermissionButton>
+				</div>
+				<div v-if="hasPermission('SkuAttrDelete')">
+					<el-popconfirm :icon="InfoFilled" icon-color="#626AEF" title="你确定要删除此项吗?" width="220" @confirm="onConfirm">
+						<template #reference>
+							<PermissionButton circle plain type="danger">
+								<el-icon>
+									<Delete />
+								</el-icon>
+							</PermissionButton>
+						</template>
+						<template #actions="{ confirm, cancel }">
+							<el-button size="small" @click="cancel">No!</el-button>
+							<el-button size="small" type="danger" @click="confirm"> Yes?</el-button>
+						</template>
+					</el-popconfirm>
+				</div>
+			</div>
+		</div>
+		<div v-else-if="field === 'country_code'">
+			<el-tag :disable-transitions="true" :style="{ color: color, borderColor: color }" effect="plain" round>
+				{{ country ? country.name : '-' }}
+			</el-tag>
+		</div>
+		<div v-else-if="field === 'currency_code'">
+			<el-tag :disable-transitions="true" :style="{ color: currencyColor, borderColor: currencyColor }" effect="plain" round>
+				{{ currency ? currency.code : '-' }}
+			</el-tag>
+		</div>
+		<div v-else>
+			{{ row[field] || '-' }}
+		</div>
+	</div>
 </template>
 
-<style scoped>
-
-</style>
+<style scoped></style>

+ 70 - 40
src/views/price-approval/direct-sales/component/EditDrawer.vue

@@ -9,15 +9,19 @@ import { ElMessage, FormInstance, FormRules } from 'element-plus';
 import { Close, Finished } from '@element-plus/icons-vue';
 import { useResponse } from '/@/utils/useResponse';
 import * as api from '../api';
+import { getCurrencyCodeOptions } from '/@/views/price-approval/api';
 
 
 const countryOptions = <Ref>inject('countryOptions');
+console.log("=>(EditDrawer.vue:16) countryOptions", countryOptions);
 const btnLoading = ref(false);
 
 const editOpen = defineModel({ default: false });
 
 const editDrawer = <Ref>useTemplateRef('editDrawer');
 
+const currencyCodeOptions = ref([]);
+
 const props: any = defineProps({
   rowData: Object
 });
@@ -56,7 +60,22 @@ const ruleForm = reactive<RuleForm>({
   cost: rowData.cost
 });
 
-const rules = reactive<FormRules<RuleForm>>({});
+const rules = reactive<FormRules<RuleForm>>({
+	sku: [ { required: true, message: '请输入SKU', trigger: 'blur' } ],
+	platform: [ { required: true, message: '请输入平台', trigger: 'blur' } ],
+	country_code: [ { required: true, message: '请输入国家', trigger: 'blur' } ],
+	currency_code: [ { required: true, message: '请选择货币代码', trigger: 'change' } ],
+	estimated_cost: [ { required: true, message: '请输入预估成本', trigger: 'blur' } ]
+});
+
+onBeforeMount(() => {
+	fetchCurrencyCodeOptions();
+});
+
+async function fetchCurrencyCodeOptions() {
+	const res = await useResponse(getCurrencyCodeOptions);
+	currencyCodeOptions.value = res.data.currency_code;
+}
 
 const submitForm = async (formEl: FormInstance | undefined) => {
   if (!formEl) return;
@@ -90,49 +109,60 @@ function closeDrawer() {
         v-model="editOpen"
         :close-on-click-modal="false"
         :close-on-press-escape="false"
-        :title="`成本查看 - 编辑 `"
+        :title="`审批查看(直销) - 编辑 `"
         size="30%"
     >
       <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" class="mx-2.5 mt-7" label-position="top"
                label-width="auto" status-icon>
-        <el-form-item class="font-medium" label="SKU" prop="sku">
-          <el-input v-model="ruleForm.sku" placeholder="请输入SKU" />
-        </el-form-item>
-        <el-form-item class="font-medium" label="重量(KG)" prop="weight">
-          <el-input v-model="ruleForm.weight" placeholder="请输入重量"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="平 台" prop="platform">
-          <el-input v-model="ruleForm.platform" placeholder="请输入平台"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="国 家" prop="country_code">
-          <el-select v-model="ruleForm.currency_code" placeholder="请选择货币代码">
-            <el-option v-for="item in countryOptions" :key="item" :label="item" :value="item"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item class="font-medium" label="货币代码" prop="currency_code">
-          <el-input v-model="ruleForm.currency_code" placeholder="请输入货币代码"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="预估硬件成本" prop="estimated_cost">
-          <el-input v-model="ruleForm.estimated_cost" placeholder="请输入预估硬件成本"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="展示价格(外币)" prop="price_show">
-          <el-input v-model="ruleForm.price_show" placeholder="请输入展示价格(外币)"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="日常活动售价(外币)" prop="price_daily">
-          <el-input v-model="ruleForm.price_daily" placeholder="请输入展示价格(外币)"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="最低售价(外币)" prop="price_min">
-          <el-input v-model="ruleForm.price_min" placeholder="请输入最低售价(外币)"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="尾程费用(外币)" prop="final_cost">
-          <el-input v-model="ruleForm.final_cost" placeholder="请输入尾程费用(外币)"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="销售模式" prop="sales_mode">
-          <el-input v-model="ruleForm.sales_mode" placeholder="请输入销售模式"></el-input>
-        </el-form-item>
-        <el-form-item class="font-medium" label="成本" prop="cost">
-          <el-input v-model="ruleForm.cost" placeholder="请输入成本"></el-input>
-        </el-form-item>
+				<el-row :gutter="20">
+					<el-col :span="12">
+						<el-form-item class="font-medium" label="SKU" prop="sku">
+							<el-input v-model="ruleForm.sku" placeholder="请输入SKU" />
+						</el-form-item>
+						<el-form-item class="font-medium" label="平 台" prop="platform">
+							<el-input v-model="ruleForm.platform" placeholder="请输入平台"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="货币代码" prop="currency_code">
+							<el-select v-model="ruleForm.currency_code" placeholder="请选择货币代码">
+								<el-option v-for="item in currencyCodeOptions" :label="item" :value="item" />
+							</el-select>
+						</el-form-item>
+						<el-form-item class="font-medium" label="展示价格(外币)" prop="price_show">
+							<el-input v-model="ruleForm.price_show" placeholder="请输入展示价格(外币)"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="最低售价(外币)" prop="price_min">
+							<el-input v-model="ruleForm.price_min" placeholder="请输入最低售价(外币)"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="销售模式" prop="sales_mode">
+							<el-select v-model="ruleForm.sales_mode" clearable placeholder="请选择销售模式">
+								<el-option label="线上" value="线上"></el-option>
+								<el-option label="线下" value="线下"></el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item class="font-medium" label="重量(KG)" prop="weight">
+							<el-input v-model="ruleForm.weight" placeholder="请输入重量"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="国 家" prop="country_code">
+							<el-select v-model="ruleForm.country_code" placeholder="请选择国家">
+								<el-option v-for="item in countryOptions" :key="item" :label="item" :value="item"></el-option>
+							</el-select>
+						</el-form-item>
+						<el-form-item class="font-medium" label="预估硬件成本" prop="estimated_cost">
+							<el-input v-model="ruleForm.estimated_cost" placeholder="请输入预估硬件成本"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="日常活动售价(外币)" prop="price_daily">
+							<el-input v-model="ruleForm.price_daily" placeholder="请输入展示价格(外币)"></el-input>
+						</el-form-item>
+						<el-form-item class="font-medium" label="尾程费用(外币)" prop="final_cost">
+						<el-input v-model="ruleForm.final_cost" placeholder="请输入尾程费用(外币)"></el-input>
+					</el-form-item>
+						<el-form-item class="font-medium" label="成本" prop="cost">
+							<el-input v-model="ruleForm.cost" placeholder="请输入成本"></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
         <el-form-item>
           <el-divider />
           <div class="flex flex-1 justify-end">

+ 3 - 3
src/views/product-manage/competitor-monitor/component/DataTable.vue

@@ -140,7 +140,7 @@ async function handleDownload() {
 	gridOptions.loading = true;
 	try {
 		await uesDownloadFile({
-			apiMethod: api.exportData, // 调用的 API 方法
+			apiMethod: api.exportData,
 			queryParams: {
 				country_code: queryParameter?.country,
 				goods__brand: queryParameter?.brand,
@@ -154,12 +154,12 @@ async function handleDownload() {
 				goods__all_reviews: queryParameter?.commentNumber,
 				goods__all_score: queryParameter?.displayScore
 			},
-			fileName: '竞品监控数据.xlsx', // 自定义文件名
+			fileName: '竞品监控数据.xlsx',
 			successMessage: () => ElMessage.success('数据导出成功!'),
 			errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
 		});
 	} finally {
-		gridOptions.loading = false; // 结束加载状态
+		gridOptions.loading = false;
 	}
 }
 

+ 3 - 3
src/views/product-manage/product-list/component/DataTable.vue

@@ -133,7 +133,7 @@ async function handleDownload() {
 	gridOptions.loading = true;
 	try {
 		await uesDownloadFile({
-			apiMethod: api.exportData, // 调用的 API 方法
+			apiMethod: api.exportData,
 			queryParams: {
 				country_code: queryParameter?.country,
 				brand: queryParameter?.brand,
@@ -145,12 +145,12 @@ async function handleDownload() {
 				is_competitors: queryParameter?.isCompetitors,
 				platform_number: queryParameter?.platformNumber
 			},
-			fileName: '商品列表数据.xlsx', // 自定义文件名
+			fileName: '商品列表数据.xlsx',
 			successMessage: () => ElMessage.success('数据导出成功!'),
 			errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
 		});
 	} finally {
-		gridOptions.loading = false; // 结束加载状态
+		gridOptions.loading = false;
 	}
 }
 

+ 3 - 3
src/views/product-manage/product-monitor/component/DataTable.vue

@@ -136,7 +136,7 @@ async function handleDownload() {
 	gridOptions.loading = true;
 	try {
 		await uesDownloadFile({
-			apiMethod: api.exportData, // 调用的 API 方法
+			apiMethod: api.exportData,
 			queryParams: {
 				country_code: queryParameter?.country,
 				brand: queryParameter?.brand,
@@ -150,12 +150,12 @@ async function handleDownload() {
 				commentNumber: queryParameter?.commentNumber,
 				displayScore: queryParameter?.displayScore
 			},
-			fileName: '商品监控数据.xlsx', // 自定义文件名
+			fileName: '商品监控数据.xlsx',
 			successMessage: () => ElMessage.success('数据导出成功!'),
 			errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
 		});
 	} finally {
-		gridOptions.loading = false; // 结束加载状态
+		gridOptions.loading = false;
 	}
 }
 

+ 3 - 3
src/views/store-manage/online-merchandise/component/DataTable.vue

@@ -111,7 +111,7 @@ async function handleDownload() {
 	gridOptions.loading = true;
 	try {
 		await uesDownloadFile({
-			apiMethod: api.exportData, // 调用的 API 方法
+			apiMethod: api.exportData,
 			queryParams: {
 				asin: queryParameter?.asin,
 				sku: queryParameter?.sku,
@@ -122,12 +122,12 @@ async function handleDownload() {
 				status: queryParameter?.status,
 				platform_number: queryParameter?.platformId,
 			},
-			fileName: '在线商品数据.xlsx', // 自定义文件名
+			fileName: '在线商品数据.xlsx',
 			successMessage: () => ElMessage.success('数据导出成功!'),
 			errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
 		});
 	} finally {
-		gridOptions.loading = false; // 结束加载状态
+		gridOptions.loading = false;
 	}
 }