diff --git a/frontend/nginx/default.conf.template b/frontend/nginx/default.conf.template index f8e57b79..048b537d 100644 --- a/frontend/nginx/default.conf.template +++ b/frontend/nginx/default.conf.template @@ -7,6 +7,20 @@ server { resolver ${RESOLVER} valid=30s ipv6=off; + # 静态资源:命中直接返回文件并长时间缓存;缺失返回 404,绝不回退成 HTML, + # 避免 CDN/网关把误回退的 index.html 当资源缓存造成 MIME 报错。 + location /assets/ { + try_files $uri =404; + expires 1y; + add_header Cache-Control "public, max-age=31536000, immutable"; + access_log off; + } + + # index.html 不缓存,保证每次回源拿到最新 hash 引用。 + location = /index.html { + add_header Cache-Control "no-cache"; + } + location / { try_files $uri $uri/ /index.html; } diff --git a/frontend/src/pages/Expansion.tsx b/frontend/src/pages/Expansion.tsx index fbf77836..4c9e072a 100644 --- a/frontend/src/pages/Expansion.tsx +++ b/frontend/src/pages/Expansion.tsx @@ -99,6 +99,7 @@ type ChannelExportFieldKey = | "province" | "city" | "officeAddress" + | "coverageItems" | "certificationLevel" | "channelIndustry" | "channelAttribute" @@ -387,6 +388,23 @@ function normalizeExportText(value?: string | number | boolean | null) { return normalized; } +// 后端 coverageItems 形如「省份|城市,省份|城市」,导出时转为「省份-城市、省份-城市」。 +function formatCoverageItemsExport(value?: string) { + if (!value?.trim()) { + return ""; + } + return value + .split(",") + .map((part) => { + const [province, city] = part.split("|"); + const p = province?.trim() || ""; + const c = city?.trim() || ""; + return c ? `${p}-${c}` : p; + }) + .filter(Boolean) + .join("、"); +} + function normalizeExportNumber(value?: string | number | null) { if (value === null || value === undefined) { return undefined; @@ -824,7 +842,9 @@ function buildChannelExportColumns(isOptions: ExpansionDictOption[]): Array normalizeExportText(item.name) }, { key: "province", label: "省份", value: (item) => normalizeExportText(item.province) }, + { key: "city", label: "市", value: (item) => normalizeExportText(item.city) }, { key: "officeAddress", label: "办公地址", kind: "longText", value: (item) => normalizeExportText(item.officeAddress) }, + { key: "coverageItems", label: "覆盖地市", value: (item) => formatCoverageItemsExport(item.coverageItems) }, { key: "channelIndustry", label: "聚焦行业", value: (item) => normalizeExportText(item.channelIndustry) }, { key: "certificationLevel", label: "汇智内部认证级别", value: (item) => normalizeExportText(item.certificationLevel) }, { key: "channelAttribute", label: "渠道属性", value: (item) => normalizeExportText(item.channelAttribute) }, @@ -839,7 +859,6 @@ function buildChannelExportColumns(isOptions: ExpansionDictOption[]): Array formatExportContactListCell(item.contacts, wecomLabelByValue) }, { key: "followUps", label: "跟进记录", kind: "followup", value: (item) => formatExportFollowUps(item.followUps) }, { key: "channelCode", label: "编码", value: (item) => normalizeExportText(item.channelCode) }, - { key: "city", label: "市", value: (item) => normalizeExportText(item.city) }, { key: "relatedProjectAmount", label: "跟进项目金额", numFmt: "#,##0.00", value: (item) => sumRelatedProjectAmount(item.relatedProjects) ?? "" }, { key: "notes", label: "备注说明", kind: "longText", value: (item) => normalizeExportText(item.notes) }, { key: "owner", label: "创建人", value: (item) => normalizeExportText(item.owner) }, @@ -851,6 +870,7 @@ function buildChannelExportColumns(isOptions: ExpansionDictOption[]): Array