|
|
@@ -105,10 +105,10 @@ const router = useRouter();
|
|
|
// ---------------------------------------------------------------------------
|
|
|
// 常量
|
|
|
// ---------------------------------------------------------------------------
|
|
|
-/** module1_basic 字段标签 → 基本信息展示项 */
|
|
|
+/** module1_basic 字段标签 → 基本信息展示项(labels 含接口原文别名) */
|
|
|
const BASE_FIELD_META = [
|
|
|
{ key: "crop", labels: ["作物品种", "种植作物"], label: "种植作物:", actionInline: { key: "changeVariety", text: "更改品种" } },
|
|
|
- { key: "trait", labels: ["品种特质"], label: "品种特质:" },
|
|
|
+ { key: "trait", labels: ["品种特质", "品种优势"], label: "品种特质:" },
|
|
|
{ key: "phenology", labels: ["物候信息", "物候期"], label: "物候信息:", actionInline: { key: "adjustPhenology", text: "调整物候" } },
|
|
|
{ key: "soil", labels: ["土壤条件"], label: "土壤条件:", actionBlock: { key: "soilSense", text: "土壤感知" } },
|
|
|
{ key: "terrain", labels: ["地形条件"], label: "地形条件:", actionInline: { key: "editLocation", text: "修改定位" } },
|
|
|
@@ -171,19 +171,35 @@ function getSelectedFarm() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/** 解析 module1_basic 中 `**标签**:内容` 段落 */
|
|
|
+/** 解析 module1_basic:兼容 `**标签**:` 与纯文本 `标签:`(内容可跨行) */
|
|
|
function parseBasicSections(markdown = "") {
|
|
|
- const text = String(markdown).replace(/\r\n/g, "\n");
|
|
|
- const sections = {};
|
|
|
- const re = /\*\*([^*]+)\*\*[::]\s*/g;
|
|
|
- const matches = [...text.matchAll(re)];
|
|
|
- matches.forEach((match, index) => {
|
|
|
- const label = String(match[1] || "").trim();
|
|
|
- const start = match.index + match[0].length;
|
|
|
- const end = index + 1 < matches.length ? matches[index + 1].index : text.length;
|
|
|
- sections[label] = text.slice(start, end).trim();
|
|
|
- });
|
|
|
- return sections;
|
|
|
+ const text = String(markdown).replace(/\r\n/g, "\n").trim();
|
|
|
+ if (!text) return {};
|
|
|
+
|
|
|
+ const collect = (re) => {
|
|
|
+ const matches = [...text.matchAll(re)];
|
|
|
+ if (!matches.length) return null;
|
|
|
+ const sections = {};
|
|
|
+ matches.forEach((match, index) => {
|
|
|
+ const label = String(match[1] || "").trim();
|
|
|
+ const start = match.index + match[0].length;
|
|
|
+ const end = index + 1 < matches.length ? matches[index + 1].index : text.length;
|
|
|
+ if (label) sections[label] = text.slice(start, end).trim();
|
|
|
+ });
|
|
|
+ return sections;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 1) markdown:**作物品种**:xxx
|
|
|
+ const mdSections = collect(/\*\*([^*]+)\*\*[::]\s*/g);
|
|
|
+ if (mdSections) return mdSections;
|
|
|
+
|
|
|
+ // 2) 纯文本:作物品种:xxx(按已知标签切分,避免正文里的冒号误伤)
|
|
|
+ const knownLabels = [...new Set(BASE_FIELD_META.flatMap((meta) => meta.labels))];
|
|
|
+ const escaped = knownLabels
|
|
|
+ .map((label) => label.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
|
|
|
+ .join("|");
|
|
|
+ if (!escaped) return {};
|
|
|
+ return collect(new RegExp(`(?:^|\\n)(${escaped})[::]\\s*`, "g")) || {};
|
|
|
}
|
|
|
|
|
|
function findSectionValue(sections, labels) {
|
|
|
@@ -193,6 +209,25 @@ function findSectionValue(sections, labels) {
|
|
|
return "";
|
|
|
}
|
|
|
|
|
|
+function buildBaseInfoList(sections, report = {}) {
|
|
|
+ return BASE_FIELD_META.map((meta) => {
|
|
|
+ let value = findSectionValue(sections, meta.labels);
|
|
|
+ // 种植作物兜底:接口顶层 crop / variety
|
|
|
+ if (!value && meta.key === "crop") {
|
|
|
+ const crop = report.crop || "";
|
|
|
+ const variety = report.variety || "";
|
|
|
+ value = [crop, variety].filter(Boolean).join("-");
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ key: meta.key,
|
|
|
+ label: meta.label,
|
|
|
+ value: value || "—",
|
|
|
+ actionInline: meta.actionInline,
|
|
|
+ actionBlock: meta.actionBlock,
|
|
|
+ };
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
/** 轻量 markdown → HTML(标题 / 粗体 / 列表) */
|
|
|
function markdownToHtml(markdown = "") {
|
|
|
const escapeHtml = (str) =>
|
|
|
@@ -251,16 +286,6 @@ function markdownToHtml(markdown = "") {
|
|
|
return html.join("");
|
|
|
}
|
|
|
|
|
|
-function buildBaseInfoList(sections) {
|
|
|
- return BASE_FIELD_META.map((meta) => ({
|
|
|
- key: meta.key,
|
|
|
- label: meta.label,
|
|
|
- value: findSectionValue(sections, meta.labels) || "—",
|
|
|
- actionInline: meta.actionInline,
|
|
|
- actionBlock: meta.actionBlock,
|
|
|
- }));
|
|
|
-}
|
|
|
-
|
|
|
function applyReportData(report, farm) {
|
|
|
const region = report.region || farm.rawAddress || farm.farm_address || farm.city || "";
|
|
|
const farmName = farm.farm_name || farm.name || "";
|
|
|
@@ -272,7 +297,7 @@ function applyReportData(report, farm) {
|
|
|
activeVarietyId.value = varietyList.value[0].id;
|
|
|
|
|
|
const sections = parseBasicSections(report.module1_basic || "");
|
|
|
- baseInfoList.value = buildBaseInfoList(sections);
|
|
|
+ baseInfoList.value = buildBaseInfoList(sections, report);
|
|
|
|
|
|
moduleMarkdownMap.value = {
|
|
|
module2_weather: report.module2_weather || "",
|