feat: 查价页优化,销售产品可改代码,分区导入跳过重复
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0d5ebdb591
commit
63c7e4ab6f
@ -117,6 +117,7 @@ export async function postForewarningServiceKpiAreaGetKpiAreaInfos(
|
|||||||
export type KpiAreaInfoImportResult = {
|
export type KpiAreaInfoImportResult = {
|
||||||
successCount: number
|
successCount: number
|
||||||
failCount: number
|
failCount: number
|
||||||
|
skipCount: number
|
||||||
failures: Array<{ rowNumber: number; reason: string }>
|
failures: Array<{ rowNumber: number; reason: string }>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +262,7 @@ export async function importKpiAreaInfo(
|
|||||||
return {
|
return {
|
||||||
successCount: Number(d.successCount ?? d.SuccessCount ?? 0),
|
successCount: Number(d.successCount ?? d.SuccessCount ?? 0),
|
||||||
failCount: Number(d.failCount ?? d.FailCount ?? 0),
|
failCount: Number(d.failCount ?? d.FailCount ?? 0),
|
||||||
|
skipCount: Number(d.skipCount ?? d.SkipCount ?? 0),
|
||||||
failures,
|
failures,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,6 +62,11 @@ export async function updateSalesProduct(body: Record<string, any> & { id: numbe
|
|||||||
assertBusinessOk(res.data)
|
assertBusinessOk(res.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateSalesProductCode(body: { id: number | string; productCode: string }) {
|
||||||
|
const res = await axiosInstance.post(omsUrl('/channel/sales-product/product-code/update'), body)
|
||||||
|
assertBusinessOk(res.data)
|
||||||
|
}
|
||||||
|
|
||||||
export async function deleteSalesProduct(id: number | string) {
|
export async function deleteSalesProduct(id: number | string) {
|
||||||
const res = await axiosInstance.post(omsUrl('/channel/sales-product/delete'), { id })
|
const res = await axiosInstance.post(omsUrl('/channel/sales-product/delete'), { id })
|
||||||
assertBusinessOk(res.data)
|
assertBusinessOk(res.data)
|
||||||
|
|||||||
@ -656,6 +656,7 @@ const CORE_GROUPS: PageButtonGroup[] = [
|
|||||||
{ code: 'AddProduct', name: '新增产品' },
|
{ code: 'AddProduct', name: '新增产品' },
|
||||||
{ code: 'Create', name: '新增' },
|
{ code: 'Create', name: '新增' },
|
||||||
{ code: 'Update', name: '修改' },
|
{ code: 'Update', name: '修改' },
|
||||||
|
{ code: 'UpdateCode', name: '修改产品代码' },
|
||||||
{ code: 'Delete', name: '删除' },
|
{ code: 'Delete', name: '删除' },
|
||||||
{ code: 'EditPrice', name: '编辑' },
|
{ code: 'EditPrice', name: '编辑' },
|
||||||
{ code: 'Save', name: '保存' },
|
{ code: 'Save', name: '保存' },
|
||||||
|
|||||||
@ -2368,7 +2368,7 @@ export default {
|
|||||||
'order.priceCheck.form.destinationCountry.placeholder': 'Please select',
|
'order.priceCheck.form.destinationCountry.placeholder': 'Please select',
|
||||||
'order.priceCheck.form.shippingMethod': 'Shipping method',
|
'order.priceCheck.form.shippingMethod': 'Shipping method',
|
||||||
'order.priceCheck.form.shippingMethod.placeholder': 'Please select',
|
'order.priceCheck.form.shippingMethod.placeholder': 'Please select',
|
||||||
'order.priceCheck.form.channel': 'Channel',
|
'order.priceCheck.form.channel': 'Route',
|
||||||
'order.priceCheck.form.channel.placeholder': 'All',
|
'order.priceCheck.form.channel.placeholder': 'All',
|
||||||
'order.priceCheck.form.cargoWeight': 'Cargo weight',
|
'order.priceCheck.form.cargoWeight': 'Cargo weight',
|
||||||
'order.priceCheck.form.cargoWeight.placeholder': 'Please enter weight (KG)',
|
'order.priceCheck.form.cargoWeight.placeholder': 'Please enter weight (KG)',
|
||||||
@ -2389,7 +2389,7 @@ export default {
|
|||||||
'order.priceCheck.form.postalCode': 'Postal code',
|
'order.priceCheck.form.postalCode': 'Postal code',
|
||||||
'order.priceCheck.form.postalCode.tip': 'more accurate',
|
'order.priceCheck.form.postalCode.tip': 'more accurate',
|
||||||
'order.priceCheck.form.postalCode.placeholder': 'Optional — improves zoning',
|
'order.priceCheck.form.postalCode.placeholder': 'Optional — improves zoning',
|
||||||
'order.priceCheck.form.moreFilters': 'More filters',
|
'order.priceCheck.form.moreFilters': 'More',
|
||||||
'order.priceCheck.form.activeFilters': '{count} selected',
|
'order.priceCheck.form.activeFilters': '{count} selected',
|
||||||
'order.priceCheck.form.clearFilters': 'Clear',
|
'order.priceCheck.form.clearFilters': 'Clear',
|
||||||
'order.priceCheck.form.removeFilter': 'Remove filter',
|
'order.priceCheck.form.removeFilter': 'Remove filter',
|
||||||
@ -2465,9 +2465,9 @@ export default {
|
|||||||
'order.priceCheck.table.viewDetail': 'Details',
|
'order.priceCheck.table.viewDetail': 'Details',
|
||||||
'order.priceCheck.table.viewGuide': 'Channel guide',
|
'order.priceCheck.table.viewGuide': 'Channel guide',
|
||||||
'order.priceCheck.table.viewGuideHint': 'Click to view route guide',
|
'order.priceCheck.table.viewGuideHint': 'Click to view route guide',
|
||||||
'order.priceCheck.table.customsOrderNow': 'Place order',
|
'order.priceCheck.table.customsOrderNow': 'Go to order',
|
||||||
'order.priceCheck.table.orderNow': 'Place order',
|
'order.priceCheck.table.orderNow': 'Go to order',
|
||||||
'order.priceCheck.table.askAi': 'Ask AI',
|
'order.priceCheck.table.askAi': 'Ask advisor',
|
||||||
'order.priceCheck.table.askAiCanShip': 'Can this ship?',
|
'order.priceCheck.table.askAiCanShip': 'Can this ship?',
|
||||||
'order.priceCheck.table.askAiCheaper': 'Anything cheaper?',
|
'order.priceCheck.table.askAiCheaper': 'Anything cheaper?',
|
||||||
'order.priceCheck.table.empty': 'No matching quotes',
|
'order.priceCheck.table.empty': 'No matching quotes',
|
||||||
@ -5171,7 +5171,13 @@ export default {
|
|||||||
'channel.salesProducts.placeholder.productDescription': 'Customer-facing description (optional)',
|
'channel.salesProducts.placeholder.productDescription': 'Customer-facing description (optional)',
|
||||||
'channel.salesProducts.placeholder.preStorageScript': 'Script before order persistence (optional)',
|
'channel.salesProducts.placeholder.preStorageScript': 'Script before order persistence (optional)',
|
||||||
'channel.salesProducts.tip.productCode':
|
'channel.salesProducts.tip.productCode':
|
||||||
'Rule: region/country code + 01 line/02 express/03 postal/04 packet + other.\nExample: US04-5DAY\nNot editable after create; uppercase letters, digits, and - only',
|
'Rule: region/country code + 01 line/02 express/03 postal/04 packet + other.\nExample: US04-5DAY\nUppercase letters, digits, and - only; can be changed later via the edit action',
|
||||||
|
'channel.salesProducts.form.editProductCode': 'Edit',
|
||||||
|
'channel.salesProducts.modal.editProductCodeTitle': 'Edit product code',
|
||||||
|
'channel.salesProducts.modal.editProductCodeHint':
|
||||||
|
'Updates the sales-product master code only. Historical orders keep the old code; quoting and place-order use the new one.',
|
||||||
|
'channel.salesProducts.messages.productCodeRequired': 'Enter a product code',
|
||||||
|
'channel.salesProducts.messages.productCodeUpdated': 'Product code updated',
|
||||||
'channel.salesProducts.tip.productName':
|
'channel.salesProducts.tip.productName':
|
||||||
'Rule: region/country + product type description + other.\nExample: US air packet-5 days',
|
'Rule: region/country + product type description + other.\nExample: US air packet-5 days',
|
||||||
'channel.salesProducts.tip.group': 'Used for website/admin grouping, e.g. express parcel',
|
'channel.salesProducts.tip.group': 'Used for website/admin grouping, e.g. express parcel',
|
||||||
@ -5558,7 +5564,7 @@ export default {
|
|||||||
'channel.area.message.deleteFailed': 'Delete failed. Please try again later.',
|
'channel.area.message.deleteFailed': 'Delete failed. Please try again later.',
|
||||||
'channel.area.import.modalTitle': 'Import area details',
|
'channel.area.import.modalTitle': 'Import area details',
|
||||||
'channel.area.import.tip':
|
'channel.area.import.tip':
|
||||||
'Download the template first. Country code is required (country name is filled from the code). Put match dimension/mode codes from the Enum sheet. One row, one dimension: postcode rules if filled; state only = state match; state+city = city match; empty = country fallback.',
|
'Download the template first. Import is incremental: exact duplicate rules in this area are skipped, not overwritten. Country code is required (country name is filled from the code). Put match dimension/mode codes from the Enum sheet. One row, one dimension: postcode rules if filled; state only = state match; state+city = city match; empty = country fallback.',
|
||||||
'channel.area.import.downloadTemplate': 'Download template',
|
'channel.area.import.downloadTemplate': 'Download template',
|
||||||
'channel.area.import.submit': 'Import',
|
'channel.area.import.submit': 'Import',
|
||||||
'channel.area.import.downloadSuccess': 'Template downloaded',
|
'channel.area.import.downloadSuccess': 'Template downloaded',
|
||||||
@ -5569,7 +5575,7 @@ export default {
|
|||||||
'channel.area.import.failed': 'Import failed',
|
'channel.area.import.failed': 'Import failed',
|
||||||
'channel.area.import.partialSuccess': 'Some rows failed. See details below.',
|
'channel.area.import.partialSuccess': 'Some rows failed. See details below.',
|
||||||
'channel.area.import.allFailed': 'Import failed. Please check the file.',
|
'channel.area.import.allFailed': 'Import failed. Please check the file.',
|
||||||
'channel.area.import.resultSummary': '{success} succeeded, {fail} failed',
|
'channel.area.import.resultSummary': '{success} succeeded, {skip} duplicate skipped, {fail} failed',
|
||||||
'channel.area.import.failRow': 'Row {row}: {reason}',
|
'channel.area.import.failRow': 'Row {row}: {reason}',
|
||||||
'channel.area.export.success': 'Exported {count} row(s)',
|
'channel.area.export.success': 'Exported {count} row(s)',
|
||||||
'channel.area.export.failed': 'Export failed',
|
'channel.area.export.failed': 'Export failed',
|
||||||
|
|||||||
@ -2254,7 +2254,7 @@ export default {
|
|||||||
'order.priceCheck.form.destinationCountry.placeholder': '请选择',
|
'order.priceCheck.form.destinationCountry.placeholder': '请选择',
|
||||||
'order.priceCheck.form.shippingMethod': '运输方式',
|
'order.priceCheck.form.shippingMethod': '运输方式',
|
||||||
'order.priceCheck.form.shippingMethod.placeholder': '请选择',
|
'order.priceCheck.form.shippingMethod.placeholder': '请选择',
|
||||||
'order.priceCheck.form.channel': '渠道',
|
'order.priceCheck.form.channel': '线路',
|
||||||
'order.priceCheck.form.channel.placeholder': '全部',
|
'order.priceCheck.form.channel.placeholder': '全部',
|
||||||
'order.priceCheck.form.cargoWeight': '货物重量',
|
'order.priceCheck.form.cargoWeight': '货物重量',
|
||||||
'order.priceCheck.form.cargoWeight.placeholder': '请输入重量(KG)',
|
'order.priceCheck.form.cargoWeight.placeholder': '请输入重量(KG)',
|
||||||
@ -2275,7 +2275,7 @@ export default {
|
|||||||
'order.priceCheck.form.postalCode': '邮编',
|
'order.priceCheck.form.postalCode': '邮编',
|
||||||
'order.priceCheck.form.postalCode.tip': '更准',
|
'order.priceCheck.form.postalCode.tip': '更准',
|
||||||
'order.priceCheck.form.postalCode.placeholder': '选填,补全更准确',
|
'order.priceCheck.form.postalCode.placeholder': '选填,补全更准确',
|
||||||
'order.priceCheck.form.moreFilters': '更多条件',
|
'order.priceCheck.form.moreFilters': '更多',
|
||||||
'order.priceCheck.form.activeFilters': '已选 {count} 项',
|
'order.priceCheck.form.activeFilters': '已选 {count} 项',
|
||||||
'order.priceCheck.form.clearFilters': '清空',
|
'order.priceCheck.form.clearFilters': '清空',
|
||||||
'order.priceCheck.form.removeFilter': '移除条件',
|
'order.priceCheck.form.removeFilter': '移除条件',
|
||||||
@ -2351,9 +2351,9 @@ export default {
|
|||||||
'order.priceCheck.table.viewDetail': '详情',
|
'order.priceCheck.table.viewDetail': '详情',
|
||||||
'order.priceCheck.table.viewGuide': '渠道说明',
|
'order.priceCheck.table.viewGuide': '渠道说明',
|
||||||
'order.priceCheck.table.viewGuideHint': '点击查看线路说明',
|
'order.priceCheck.table.viewGuideHint': '点击查看线路说明',
|
||||||
'order.priceCheck.table.customsOrderNow': '立刻下单',
|
'order.priceCheck.table.customsOrderNow': '去下单',
|
||||||
'order.priceCheck.table.orderNow': '立刻下单',
|
'order.priceCheck.table.orderNow': '去下单',
|
||||||
'order.priceCheck.table.askAi': '问 AI',
|
'order.priceCheck.table.askAi': '问顾问',
|
||||||
'order.priceCheck.table.askAiCanShip': '这个能不能发?',
|
'order.priceCheck.table.askAiCanShip': '这个能不能发?',
|
||||||
'order.priceCheck.table.askAiCheaper': '有没有更便宜?',
|
'order.priceCheck.table.askAiCheaper': '有没有更便宜?',
|
||||||
'order.priceCheck.table.empty': '暂无匹配报价',
|
'order.priceCheck.table.empty': '暂无匹配报价',
|
||||||
@ -5206,7 +5206,13 @@ export default {
|
|||||||
'channel.salesProducts.placeholder.productDescription': '面向客户的产品说明(选填)',
|
'channel.salesProducts.placeholder.productDescription': '面向客户的产品说明(选填)',
|
||||||
'channel.salesProducts.placeholder.preStorageScript': '订单落库前执行的脚本(选填)',
|
'channel.salesProducts.placeholder.preStorageScript': '订单落库前执行的脚本(选填)',
|
||||||
'channel.salesProducts.tip.productCode':
|
'channel.salesProducts.tip.productCode':
|
||||||
'命名规则:地区/国家代码 + 01专线/02快递/03邮政/04小包 + 其他。\n示例:US04-5DAY\n创建后不可修改;仅支持大写字母、数字和 -',
|
'命名规则:地区/国家代码 + 01专线/02快递/03邮政/04小包 + 其他。\n示例:US04-5DAY\n仅支持大写字母、数字和 -;创建后可通过修改入口单独改代码',
|
||||||
|
'channel.salesProducts.form.editProductCode': '修改',
|
||||||
|
'channel.salesProducts.modal.editProductCodeTitle': '修改产品代码',
|
||||||
|
'channel.salesProducts.modal.editProductCodeHint':
|
||||||
|
'仅改销售产品主数据代码。历史订单仍保留原代码;下单、查价将使用新代码。',
|
||||||
|
'channel.salesProducts.messages.productCodeRequired': '请输入产品代码',
|
||||||
|
'channel.salesProducts.messages.productCodeUpdated': '产品代码已更新',
|
||||||
'channel.salesProducts.tip.productName':
|
'channel.salesProducts.tip.productName':
|
||||||
'命名规则:地区/国家 + 产品类型描述 + 其他。\n示例:美国空运小包-5日达',
|
'命名规则:地区/国家 + 产品类型描述 + 其他。\n示例:美国空运小包-5日达',
|
||||||
'channel.salesProducts.tip.group': '用于官网/后台分组展示,如专线小包',
|
'channel.salesProducts.tip.group': '用于官网/后台分组展示,如专线小包',
|
||||||
@ -5569,7 +5575,7 @@ export default {
|
|||||||
'channel.area.search.button.query': '查询',
|
'channel.area.search.button.query': '查询',
|
||||||
'channel.area.search.button.reset': '重置',
|
'channel.area.search.button.reset': '重置',
|
||||||
'channel.area.import.modalTitle': '导入分区明细',
|
'channel.area.import.modalTitle': '导入分区明细',
|
||||||
'channel.area.import.tip': '请先下载模板。国家代码必填(无需填国家名称,导入时按代码自动带出)。匹配维度、匹配方式请填 Sheet「枚举值」中的编码。一行一个维度:填邮编则为邮编规则(只填起始=前缀;起止相同=精确;起止不同=闭区间);不填邮编只填州=州匹配;州+城市=城市匹配;都空=仅国家兜底。',
|
'channel.area.import.tip': '请先下载模板。导入为增量写入:与本分区已有规则完全相同的行会跳过,不会覆盖。国家代码必填(无需填国家名称,导入时按代码自动带出)。匹配维度、匹配方式请填 Sheet「枚举值」中的编码。一行一个维度:填邮编则为邮编规则(只填起始=前缀;起止相同=精确;起止不同=闭区间);不填邮编只填州=州匹配;州+城市=城市匹配;都空=仅国家兜底。',
|
||||||
'channel.area.import.downloadTemplate': '下载模板',
|
'channel.area.import.downloadTemplate': '下载模板',
|
||||||
'channel.area.import.submit': '开始导入',
|
'channel.area.import.submit': '开始导入',
|
||||||
'channel.area.import.downloadSuccess': '模板下载成功',
|
'channel.area.import.downloadSuccess': '模板下载成功',
|
||||||
@ -5580,7 +5586,7 @@ export default {
|
|||||||
'channel.area.import.failed': '导入失败',
|
'channel.area.import.failed': '导入失败',
|
||||||
'channel.area.import.partialSuccess': '部分行导入失败,请查看失败明细',
|
'channel.area.import.partialSuccess': '部分行导入失败,请查看失败明细',
|
||||||
'channel.area.import.allFailed': '导入失败,请检查文件内容',
|
'channel.area.import.allFailed': '导入失败,请检查文件内容',
|
||||||
'channel.area.import.resultSummary': '成功 {success} 条,失败 {fail} 条',
|
'channel.area.import.resultSummary': '成功 {success} 条,跳过重复 {skip} 条,失败 {fail} 条',
|
||||||
'channel.area.import.failRow': '第 {row} 行:{reason}',
|
'channel.area.import.failRow': '第 {row} 行:{reason}',
|
||||||
'channel.area.export.success': '已导出 {count} 条',
|
'channel.area.export.success': '已导出 {count} 条',
|
||||||
'channel.area.export.failed': '导出失败',
|
'channel.area.export.failed': '导出失败',
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
{{
|
{{
|
||||||
t('channel.area.import.resultSummary', {
|
t('channel.area.import.resultSummary', {
|
||||||
success: importResult.successCount,
|
success: importResult.successCount,
|
||||||
|
skip: importResult.skipCount,
|
||||||
fail: importResult.failCount,
|
fail: importResult.failCount,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
@ -117,7 +118,7 @@
|
|||||||
try {
|
try {
|
||||||
const result = await importKpiAreaInfo(areaId.value, selectedFile.value);
|
const result = await importKpiAreaInfo(areaId.value, selectedFile.value);
|
||||||
importResult.value = result;
|
importResult.value = result;
|
||||||
if (result.successCount > 0) {
|
if (result.successCount > 0 || result.skipCount > 0) {
|
||||||
emit('success');
|
emit('success');
|
||||||
}
|
}
|
||||||
if (result.failCount === 0) {
|
if (result.failCount === 0) {
|
||||||
@ -125,7 +126,7 @@
|
|||||||
visible.value = false;
|
visible.value = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (result.successCount > 0) {
|
if (result.successCount > 0 || result.skipCount > 0) {
|
||||||
Message.warning(t('channel.area.import.partialSuccess'));
|
Message.warning(t('channel.area.import.partialSuccess'));
|
||||||
} else {
|
} else {
|
||||||
Message.error(t('channel.area.import.allFailed'));
|
Message.error(t('channel.area.import.allFailed'));
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
saveSalesProductCustomerGuide,
|
saveSalesProductCustomerGuide,
|
||||||
toggleSalesProductPriceStatus,
|
toggleSalesProductPriceStatus,
|
||||||
updateSalesProduct,
|
updateSalesProduct,
|
||||||
|
updateSalesProductCode,
|
||||||
updateSalesProductPrice,
|
updateSalesProductPrice,
|
||||||
} from '@/api/channel/salesProduct';
|
} from '@/api/channel/salesProduct';
|
||||||
import { getLabelTemplateList } from '@/api/channel/labelTemplate';
|
import { getLabelTemplateList } from '@/api/channel/labelTemplate';
|
||||||
@ -154,6 +155,9 @@
|
|||||||
const customerGuideSaving = ref(false);
|
const customerGuideSaving = ref(false);
|
||||||
const customerGuidePanelRef = ref<InstanceType<typeof MarkdownDocPanel> | null>(null);
|
const customerGuidePanelRef = ref<InstanceType<typeof MarkdownDocPanel> | null>(null);
|
||||||
const savingConfig = ref(false);
|
const savingConfig = ref(false);
|
||||||
|
const productCodeModalVisible = ref(false);
|
||||||
|
const productCodeDraft = ref('');
|
||||||
|
const savingProductCode = ref(false);
|
||||||
|
|
||||||
function parseAdditionalServiceCodes(raw: unknown): string[] {
|
function parseAdditionalServiceCodes(raw: unknown): string[] {
|
||||||
if (Array.isArray(raw)) {
|
if (Array.isArray(raw)) {
|
||||||
@ -252,6 +256,42 @@
|
|||||||
.replace(/[^A-Z0-9-]/g, '');
|
.replace(/[^A-Z0-9-]/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openProductCodeModal() {
|
||||||
|
if (selectedProduct.value == null) return;
|
||||||
|
productCodeDraft.value = normalizeBizCode(formData.productCode);
|
||||||
|
productCodeModalVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSaveProductCode() {
|
||||||
|
const pid = selectedProduct.value;
|
||||||
|
if (pid == null) return;
|
||||||
|
const next = normalizeBizCode(productCodeDraft.value);
|
||||||
|
if (!next) {
|
||||||
|
Message.warning(t('channel.salesProducts.messages.productCodeRequired'));
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
savingProductCode.value = true;
|
||||||
|
try {
|
||||||
|
await updateSalesProductCode({ id: pid, productCode: next });
|
||||||
|
formData.productCode = next;
|
||||||
|
const hit = productList.value.find((p: any) => p.id === pid);
|
||||||
|
if (hit?.raw) {
|
||||||
|
hit.raw.productCode = next;
|
||||||
|
hit.raw.ProductCode = next;
|
||||||
|
}
|
||||||
|
if (configFormBaseline.value) {
|
||||||
|
configFormBaseline.value = { ...configFormBaseline.value, productCode: next };
|
||||||
|
}
|
||||||
|
productCodeModalVisible.value = false;
|
||||||
|
Message.success(t('channel.salesProducts.messages.productCodeUpdated'));
|
||||||
|
} catch (e: any) {
|
||||||
|
Message.error(e?.message || '修改产品代码失败');
|
||||||
|
return Promise.reject(e);
|
||||||
|
} finally {
|
||||||
|
savingProductCode.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const selectedProductContext = computed(() => {
|
const selectedProductContext = computed(() => {
|
||||||
const pid = selectedProduct.value;
|
const pid = selectedProduct.value;
|
||||||
if (pid == null) return null;
|
if (pid == null) return null;
|
||||||
@ -4014,10 +4054,18 @@
|
|||||||
</template>
|
</template>
|
||||||
<icon-question-circle class="tip-icon" />
|
<icon-question-circle class="tip-icon" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="product-code-edit-icon"
|
||||||
|
:aria-label="t('channel.salesProducts.form.editProductCode')"
|
||||||
|
@click.stop="openProductCodeModal"
|
||||||
|
>
|
||||||
|
<icon-edit />
|
||||||
|
</button>
|
||||||
</label>
|
</label>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formData.productCode"
|
v-model="formData.productCode"
|
||||||
:placeholder="t('channel.salesProducts.form.placeholder.input')"
|
:placeholder="t('channel.salesProducts.placeholder.productCode')"
|
||||||
class="form-input"
|
class="form-input"
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
@ -5487,6 +5535,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="productCodeModalVisible"
|
||||||
|
:title="t('channel.salesProducts.modal.editProductCodeTitle')"
|
||||||
|
width="420px"
|
||||||
|
:mask-closable="false"
|
||||||
|
:ok-loading="savingProductCode"
|
||||||
|
@ok="handleSaveProductCode"
|
||||||
|
@cancel="productCodeModalVisible = false"
|
||||||
|
>
|
||||||
|
<p class="product-code-edit-hint">{{ t('channel.salesProducts.modal.editProductCodeHint') }}</p>
|
||||||
|
<a-input
|
||||||
|
:model-value="productCodeDraft"
|
||||||
|
:placeholder="t('channel.salesProducts.placeholder.productCode')"
|
||||||
|
allow-clear
|
||||||
|
@update:model-value="(v) => (productCodeDraft = normalizeBizCode(v))"
|
||||||
|
@press-enter="handleSaveProductCode"
|
||||||
|
/>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
<ChannelReferencePreviewModal ref="referencePreviewRef" :dict-label-fn="dictLabelByType" />
|
<ChannelReferencePreviewModal ref="referencePreviewRef" :dict-label-fn="dictLabelByType" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -5691,6 +5758,31 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.product-code-edit-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--app-primary-color, #007979);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-code-edit-hint {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
.form-input,
|
.form-input,
|
||||||
.form-select,
|
.form-select,
|
||||||
.form-textarea {
|
.form-textarea {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { IconDown } from '@arco-design/web-vue/es/icon'
|
import IconTabService from '@/assets/icons/h5/tab-service.svg'
|
||||||
|
|
||||||
defineOptions({ name: 'PriceCheckQuoteResultCard' })
|
defineOptions({ name: 'PriceCheckQuoteResultCard' })
|
||||||
|
|
||||||
@ -328,13 +328,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="quote-card__actions" @click.stop>
|
<div class="quote-card__actions" @click.stop>
|
||||||
<button type="button" class="ops-btn ops-btn--primary" @click="emit('order')">
|
<a-dropdown trigger="click" position="bl">
|
||||||
{{ t('order.priceCheck.table.orderNow') }}
|
<button
|
||||||
</button>
|
type="button"
|
||||||
<a-dropdown trigger="click" position="br">
|
class="advisor-icon-btn"
|
||||||
<button type="button" class="ops-btn ops-btn--ghost">
|
:aria-label="t('order.priceCheck.table.askAi')"
|
||||||
{{ t('order.priceCheck.table.askAi') }}
|
>
|
||||||
<icon-down style="margin-left: 2px" />
|
<IconTabService class="advisor-icon-btn__icon" />
|
||||||
</button>
|
</button>
|
||||||
<template #content>
|
<template #content>
|
||||||
<a-doption @click="emit('ask', 'canShip')">
|
<a-doption @click="emit('ask', 'canShip')">
|
||||||
@ -345,6 +345,9 @@
|
|||||||
</a-doption>
|
</a-doption>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
|
<button type="button" class="ops-btn ops-btn--primary" @click="emit('order')">
|
||||||
|
{{ t('order.priceCheck.table.orderNow') }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
@ -666,25 +669,18 @@
|
|||||||
|
|
||||||
.quote-card__actions {
|
.quote-card__actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
align-items: stretch;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
min-width: 88px;
|
|
||||||
|
|
||||||
:deep(.arco-dropdown-open),
|
:deep(.arco-dropdown-open),
|
||||||
:deep(.arco-trigger),
|
:deep(.arco-trigger),
|
||||||
> :deep(.arco-dropdown-trigger),
|
> :deep(.arco-dropdown-trigger),
|
||||||
> .arco-dropdown-open {
|
> .arco-dropdown-open {
|
||||||
width: 100%;
|
display: inline-flex;
|
||||||
display: block;
|
flex-shrink: 0;
|
||||||
}
|
|
||||||
|
|
||||||
> :deep(span),
|
|
||||||
> :deep(div) {
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,36 +688,54 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
|
||||||
height: 28px;
|
|
||||||
padding: 0 10px;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-size: 12px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
|
|
||||||
&--ghost {
|
|
||||||
background: transparent;
|
|
||||||
border-color: var(--color-border-2);
|
|
||||||
color: var(--color-text-2);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: var(--app-primary-color, #007979);
|
|
||||||
border-color: color-mix(in srgb, var(--app-primary-color, #007979) 35%, var(--color-border-2));
|
|
||||||
background: color-mix(in srgb, var(--app-primary-color, #007979) 4%, transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--primary {
|
&--primary {
|
||||||
|
min-width: 88px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-radius: 6px;
|
||||||
background: var(--app-primary-color, #007979);
|
background: var(--app-primary-color, #007979);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 1px 2px color-mix(in srgb, var(--app-primary-color, #007979) 28%, transparent);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
filter: brightness(1.04);
|
filter: brightness(1.06);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.advisor-icon-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--app-primary-color, #007979);
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: color-mix(in srgb, var(--app-primary-color, #007979) 8%, transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.advisor-icon-btn__icon {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.quote-card__fee-pop {
|
.quote-card__fee-pop {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -799,7 +813,7 @@
|
|||||||
|
|
||||||
.quote-card__actions {
|
.quote-card__actions {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
justify-content: flex-end;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,13 +824,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.quote-card__actions {
|
.quote-card__actions {
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ops-btn--primary {
|
.ops-btn--primary {
|
||||||
flex: 1;
|
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { IconDown, IconSearch } from '@arco-design/web-vue/es/icon'
|
import { IconClose, IconDown, IconSearch } from '@arco-design/web-vue/es/icon'
|
||||||
import SlidingTabs from '@/components/SlidingTabs/index.vue'
|
import SlidingTabs from '@/components/SlidingTabs/index.vue'
|
||||||
import type { PriceCheckShippingGroup } from '@/api/order'
|
import type { PriceCheckShippingGroup } from '@/api/order'
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ function clearSelection(e: Event) {
|
|||||||
aria-label="clear"
|
aria-label="clear"
|
||||||
@click="clearSelection"
|
@click="clearSelection"
|
||||||
>
|
>
|
||||||
×
|
<icon-close />
|
||||||
</button>
|
</button>
|
||||||
<icon-down class="trigger-icon" />
|
<icon-down class="trigger-icon" />
|
||||||
</div>
|
</div>
|
||||||
@ -233,20 +233,23 @@ function clearSelection(e: Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trigger-clear {
|
.trigger-clear {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 18px;
|
width: 16px;
|
||||||
height: 18px;
|
height: 16px;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 50%;
|
background: transparent;
|
||||||
background: var(--color-fill-4);
|
color: var(--color-text-3);
|
||||||
color: #fff;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 16px;
|
line-height: 1;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--color-text-3);
|
color: var(--color-text-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@
|
|||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
destinationCountry: '',
|
destinationCountry: '',
|
||||||
shippingMethod: '',
|
shippingMethod: '',
|
||||||
cargoWeight: '',
|
cargoWeight: '1',
|
||||||
length: '',
|
length: '',
|
||||||
width: '',
|
width: '',
|
||||||
height: '',
|
height: '',
|
||||||
@ -92,18 +92,6 @@
|
|||||||
const couponInstanceId = ref<number | undefined>(undefined);
|
const couponInstanceId = ref<number | undefined>(undefined);
|
||||||
const availableCoupons = ref<CouponAvailableOutput[]>([]);
|
const availableCoupons = ref<CouponAvailableOutput[]>([]);
|
||||||
|
|
||||||
const advancedActiveCount = computed(() => {
|
|
||||||
let n = 0;
|
|
||||||
if (formData.shippingMethod) n += 1;
|
|
||||||
if (formData.cargoType) n += 1;
|
|
||||||
if (formData.warehouseId != null) n += 1;
|
|
||||||
if (hasFullDimensions() || hasPartialDimensions()) n += 1;
|
|
||||||
if (String(formData.destinationProvince || '').trim()) n += 1;
|
|
||||||
if (String(formData.destinationCity || '').trim()) n += 1;
|
|
||||||
if (couponInstanceId.value) n += 1;
|
|
||||||
return n;
|
|
||||||
});
|
|
||||||
|
|
||||||
const needPostalHint = computed(() => {
|
const needPostalHint = computed(() => {
|
||||||
if (!hasQueried.value) return false;
|
if (!hasQueried.value) return false;
|
||||||
if (String(formData.postalCode || '').trim()) return false;
|
if (String(formData.postalCode || '').trim()) return false;
|
||||||
@ -125,7 +113,6 @@
|
|||||||
| 'destinationCity'
|
| 'destinationCity'
|
||||||
| 'cargoType'
|
| 'cargoType'
|
||||||
| 'warehouse'
|
| 'warehouse'
|
||||||
| 'shipping'
|
|
||||||
| 'coupon';
|
| 'coupon';
|
||||||
value?: string | number;
|
value?: string | number;
|
||||||
};
|
};
|
||||||
@ -181,17 +168,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formData.shippingMethod) {
|
|
||||||
const flat = (shippingMethodGroups.value || []).flatMap((g) => g.products || []);
|
|
||||||
const hit = flat.find((it) => it.productCode === formData.shippingMethod);
|
|
||||||
chips.push({
|
|
||||||
key: 'shipping',
|
|
||||||
kind: 'shipping',
|
|
||||||
value: formData.shippingMethod,
|
|
||||||
label: hit?.label || formData.shippingMethod,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (couponInstanceId.value) {
|
if (couponInstanceId.value) {
|
||||||
const c = availableCoupons.value.find((x) => (x.id ?? x.Id) === couponInstanceId.value);
|
const c = availableCoupons.value.find((x) => (x.id ?? x.Id) === couponInstanceId.value);
|
||||||
const name = String(c?.templateName ?? c?.TemplateName ?? '').trim();
|
const name = String(c?.templateName ?? c?.TemplateName ?? '').trim();
|
||||||
@ -229,10 +205,6 @@
|
|||||||
formData.warehouseId = undefined;
|
formData.warehouseId = undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (chip.kind === 'shipping') {
|
|
||||||
formData.shippingMethod = '';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (chip.kind === 'coupon') {
|
if (chip.kind === 'coupon') {
|
||||||
couponInstanceId.value = undefined;
|
couponInstanceId.value = undefined;
|
||||||
}
|
}
|
||||||
@ -246,7 +218,6 @@
|
|||||||
formData.destinationCity = '';
|
formData.destinationCity = '';
|
||||||
formData.cargoType = '';
|
formData.cargoType = '';
|
||||||
formData.warehouseId = undefined;
|
formData.warehouseId = undefined;
|
||||||
formData.shippingMethod = '';
|
|
||||||
couponInstanceId.value = undefined;
|
couponInstanceId.value = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,14 +592,15 @@
|
|||||||
availableCoupons.value = coupons ?? [];
|
availableCoupons.value = coupons ?? [];
|
||||||
hintBannerDismissed.value = false;
|
hintBannerDismissed.value = false;
|
||||||
queryResults.value = processQueryResults(items || []);
|
queryResults.value = processQueryResults(items || []);
|
||||||
selectedGuideRecord.value = null;
|
|
||||||
resetRecommendState();
|
resetRecommendState();
|
||||||
sortMode.value = 'recommend';
|
sortMode.value = 'recommend';
|
||||||
currentPage.value = 1;
|
currentPage.value = 1;
|
||||||
recalcLoadingKeys.value = {};
|
recalcLoadingKeys.value = {};
|
||||||
if (!queryResults.value.length) {
|
if (!queryResults.value.length) {
|
||||||
|
selectedGuideRecord.value = null;
|
||||||
applyPriceCheckFailures(failures ?? []);
|
applyPriceCheckFailures(failures ?? []);
|
||||||
} else {
|
} else {
|
||||||
|
selectedGuideRecord.value = sortedResults.value[0] ?? queryResults.value[0];
|
||||||
clearPriceCheckFailures();
|
clearPriceCheckFailures();
|
||||||
Message.success(t('order.priceCheck.message.querySuccess', { count: queryResults.value.length }));
|
Message.success(t('order.priceCheck.message.querySuccess', { count: queryResults.value.length }));
|
||||||
}
|
}
|
||||||
@ -648,7 +620,7 @@
|
|||||||
Object.assign(formData, {
|
Object.assign(formData, {
|
||||||
destinationCountry: '',
|
destinationCountry: '',
|
||||||
shippingMethod: '',
|
shippingMethod: '',
|
||||||
cargoWeight: '',
|
cargoWeight: '1',
|
||||||
length: '',
|
length: '',
|
||||||
width: '',
|
width: '',
|
||||||
height: '',
|
height: '',
|
||||||
@ -1001,6 +973,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row form-row-primary">
|
<div class="form-row form-row-primary">
|
||||||
|
<div class="form-item form-item-channel">
|
||||||
|
<label class="form-label">{{ $t('order.priceCheck.form.channel') }}</label>
|
||||||
|
<ShippingMethodTabSelect
|
||||||
|
v-model="formData.shippingMethod"
|
||||||
|
:groups="shippingMethodGroups"
|
||||||
|
:loading="optionsLoading"
|
||||||
|
:placeholder="$t('order.priceCheck.form.channel.placeholder')"
|
||||||
|
class="form-select"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-item form-item-country">
|
<div class="form-item form-item-country">
|
||||||
<label class="form-label required">{{ $t('order.priceCheck.form.destinationCountry') }}</label>
|
<label class="form-label required">{{ $t('order.priceCheck.form.destinationCountry') }}</label>
|
||||||
<a-select
|
<a-select
|
||||||
@ -1035,21 +1018,21 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-item">
|
<div ref="postalInputRef" class="form-item form-item-compact">
|
||||||
<label class="form-label required">{{ $t('order.priceCheck.form.cargoWeight') }}</label>
|
<label class="form-label">{{ $t('order.priceCheck.form.postalCode') }}</label>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formData.cargoWeight"
|
v-model="formData.postalCode"
|
||||||
:placeholder="$t('order.priceCheck.form.cargoWeight.placeholder')"
|
:placeholder="$t('order.priceCheck.form.postalCode.placeholder')"
|
||||||
class="form-input"
|
class="form-input"
|
||||||
@press-enter="handleQuery"
|
@press-enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref="postalInputRef" class="form-item">
|
<div class="form-item form-item-compact">
|
||||||
<label class="form-label">{{ $t('order.priceCheck.form.postalCode') }}</label>
|
<label class="form-label required">{{ $t('order.priceCheck.form.cargoWeight') }}</label>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formData.postalCode"
|
v-model="formData.cargoWeight"
|
||||||
:placeholder="$t('order.priceCheck.form.postalCode.placeholder')"
|
:placeholder="$t('order.priceCheck.form.cargoWeight.placeholder')"
|
||||||
class="form-input"
|
class="form-input"
|
||||||
@press-enter="handleQuery"
|
@press-enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
@ -1071,10 +1054,7 @@
|
|||||||
{{ $t('order.priceCheck.actions.reset') }}
|
{{ $t('order.priceCheck.actions.reset') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<button type="button" class="advanced-toggle-btn" @click="showAdvanced = !showAdvanced">
|
<button type="button" class="advanced-toggle-btn" @click="showAdvanced = !showAdvanced">
|
||||||
<span>
|
<span>{{ $t('order.priceCheck.form.moreFilters') }}</span>
|
||||||
{{ $t('order.priceCheck.form.moreFilters') }}
|
|
||||||
<span v-if="advancedActiveCount" class="advanced-count">{{ advancedActiveCount }}</span>
|
|
||||||
</span>
|
|
||||||
<icon-up v-if="showAdvanced" />
|
<icon-up v-if="showAdvanced" />
|
||||||
<icon-down v-else />
|
<icon-down v-else />
|
||||||
</button>
|
</button>
|
||||||
@ -1110,10 +1090,10 @@
|
|||||||
<icon-close />
|
<icon-close />
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="filter-summary-bar__clear" @click="clearAdvancedConditions">
|
||||||
|
{{ $t('order.priceCheck.form.clearFilters') }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="filter-summary-bar__clear" @click="clearAdvancedConditions">
|
|
||||||
{{ $t('order.priceCheck.form.clearFilters') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-show="showAdvanced" class="form-row form-row-advanced">
|
<div v-show="showAdvanced" class="form-row form-row-advanced">
|
||||||
@ -1183,17 +1163,6 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-item">
|
|
||||||
<label class="form-label">{{ $t('order.priceCheck.form.channel') }}</label>
|
|
||||||
<ShippingMethodTabSelect
|
|
||||||
v-model="formData.shippingMethod"
|
|
||||||
:groups="shippingMethodGroups"
|
|
||||||
:loading="optionsLoading"
|
|
||||||
:placeholder="$t('order.priceCheck.form.channel.placeholder')"
|
|
||||||
class="form-select"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-item">
|
<div class="form-item">
|
||||||
<label class="form-label">{{ $t('order.priceCheck.form.cargoType') }}</label>
|
<label class="form-label">{{ $t('order.priceCheck.form.cargoType') }}</label>
|
||||||
<a-select
|
<a-select
|
||||||
@ -1365,8 +1334,8 @@
|
|||||||
background-color: var(--app-page-bg);
|
background-color: var(--app-page-bg);
|
||||||
}
|
}
|
||||||
.price-check-layout { display: flex; gap: 12px; flex: 1; min-height: 0; min-width: 0; }
|
.price-check-layout { display: flex; gap: 12px; flex: 1; min-height: 0; min-width: 0; }
|
||||||
.price-check-main { flex: 7 1 0; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 12px; overflow: hidden; }
|
.price-check-main { flex: 5 1 0; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 12px; overflow: hidden; }
|
||||||
.price-check-aside { flex: 3 1 0; min-width: 300px; min-height: 0; display: flex; flex-direction: column; > * { flex: 1; min-height: 0; } }
|
.price-check-aside { flex: 3 1 0; min-width: 340px; min-height: 0; display: flex; flex-direction: column; > * { flex: 1; min-height: 0; } }
|
||||||
.liquid-panel {
|
.liquid-panel {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
@ -1439,8 +1408,9 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
.form-row { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
|
.form-row { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
|
||||||
.form-row-primary, .form-row-advanced { overflow-x: auto; padding-bottom: 2px; -webkit-overflow-scrolling: touch; }
|
.form-row-primary, .form-row-advanced { overflow-x: auto; padding-bottom: 2px; -webkit-overflow-scrolling: touch; }
|
||||||
|
.form-row-primary { flex-wrap: nowrap; }
|
||||||
.form-row-advanced {
|
.form-row-advanced {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
@ -1543,23 +1513,9 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
&:hover { color: var(--app-primary-color, #007979); }
|
&:hover { color: var(--app-primary-color, #007979); }
|
||||||
}
|
}
|
||||||
.advanced-count {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin-left: 4px;
|
|
||||||
padding: 0 4px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: rgba(0, 121, 121, 0.1);
|
|
||||||
color: var(--app-primary-color, #007979);
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 16px;
|
|
||||||
}
|
|
||||||
.form-hint { margin: 0; color: var(--color-text-3); font-size: 12px; line-height: 1.3; }
|
.form-hint { margin: 0; color: var(--color-text-3); font-size: 12px; line-height: 1.3; }
|
||||||
.form-item {
|
.form-item {
|
||||||
display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; width: 168px; min-width: 140px;
|
display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; width: 148px; min-width: 132px;
|
||||||
&.dimensions-group { width: 260px; min-width: 220px; }
|
&.dimensions-group { width: 260px; min-width: 220px; }
|
||||||
&.button-group { width: auto; min-width: 0; flex-shrink: 0; }
|
&.button-group { width: auto; min-width: 0; flex-shrink: 0; }
|
||||||
.button-group-row {
|
.button-group-row {
|
||||||
@ -1570,7 +1526,9 @@
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
&.form-item-country { width: 280px; min-width: 240px; flex-shrink: 0; }
|
&.form-item-country { width: 240px; min-width: 200px; flex-shrink: 0; }
|
||||||
|
&.form-item-channel { width: 220px; min-width: 180px; flex-shrink: 0; }
|
||||||
|
&.form-item-compact { width: 112px; min-width: 100px; }
|
||||||
}
|
}
|
||||||
.country-shortcuts {
|
.country-shortcuts {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user