2266 lines
83 KiB
JavaScript
2266 lines
83 KiB
JavaScript
"use strict";
|
||
const common_vendor = require("../../common/vendor.js");
|
||
const tongji_composables_useDietAi = require("../composables/useDietAi.js");
|
||
if (!Math) {
|
||
(TongjiIcon + SugarTreeGraphic)();
|
||
}
|
||
const SugarTreeGraphic = () => "../components/SugarTreeGraphic.js";
|
||
const TongjiIcon = () => "../components/TongjiIcon.js";
|
||
const VIEWER_KEY_STORAGE = "tongji_viewer_key_v1";
|
||
const _sfc_main = {
|
||
__name: "index",
|
||
setup(__props) {
|
||
const { proxy } = common_vendor.getCurrentInstance();
|
||
function formatUserMessage(msg, fallback = "") {
|
||
if (msg == null || msg === "")
|
||
return fallback;
|
||
if (typeof msg === "string")
|
||
return msg;
|
||
if (typeof msg === "number" || typeof msg === "boolean")
|
||
return String(msg);
|
||
if (Array.isArray(msg)) {
|
||
const parts = msg.map((item) => {
|
||
if (item == null)
|
||
return "";
|
||
if (typeof item === "string")
|
||
return item;
|
||
if (typeof item === "number" || typeof item === "boolean")
|
||
return String(item);
|
||
if (typeof item === "object") {
|
||
return item.msg || item.message || item.error || item.title || item.label || "";
|
||
}
|
||
return String(item);
|
||
}).filter(Boolean);
|
||
return parts.length ? parts.join(";") : fallback;
|
||
}
|
||
if (typeof msg === "object") {
|
||
return msg.msg || msg.message || msg.error || msg.title || msg.label || fallback;
|
||
}
|
||
return String(msg);
|
||
}
|
||
function showUserToast(title, options = {}) {
|
||
const text = formatUserMessage(title, "");
|
||
if (!text)
|
||
return;
|
||
common_vendor.index.showToast({
|
||
title: text,
|
||
icon: options.icon || "none",
|
||
duration: options.duration
|
||
});
|
||
}
|
||
const diagnosisId = common_vendor.ref(0);
|
||
const patientId = common_vendor.ref(0);
|
||
const patientName = common_vendor.ref("");
|
||
const age = common_vendor.ref(0);
|
||
const gender = common_vendor.ref(0);
|
||
const {
|
||
dietAiRecommend,
|
||
dietAiLoading,
|
||
dietAiStreaming,
|
||
dietAiReplacing,
|
||
dietAiStreamField,
|
||
dietAiAskText,
|
||
dietAiAsking,
|
||
dietAiAskResult,
|
||
hasDietAiMealContent,
|
||
fetchDietAiRecommend,
|
||
refreshDietAiRecommend,
|
||
askDietAiFood,
|
||
onDietAiAskInput,
|
||
applyDietAiToForm,
|
||
openDietForm
|
||
} = tongji_composables_useDietAi.useDietAi(proxy, { diagnosisId, showUserToast, formatUserMessage });
|
||
const dietAnalysisList = common_vendor.computed(() => {
|
||
const list = dietAiRecommend.value && Array.isArray(dietAiRecommend.value.analysis) ? dietAiRecommend.value.analysis : [];
|
||
return list.filter((s) => s && typeof s === "object");
|
||
});
|
||
const hasDietAnalysis = common_vendor.computed(() => dietAnalysisList.value.length > 0);
|
||
const dietExercise = common_vendor.computed(() => {
|
||
const ex = dietAiRecommend.value && dietAiRecommend.value.exercise;
|
||
return ex && typeof ex === "object" && Array.isArray(ex.items) && ex.items.length ? ex : null;
|
||
});
|
||
function dietRateClass(rate) {
|
||
const n = Number(rate);
|
||
if (!Number.isFinite(n))
|
||
return "rate-mid";
|
||
if (n >= 80)
|
||
return "rate-good";
|
||
if (n >= 50)
|
||
return "rate-mid";
|
||
return "rate-low";
|
||
}
|
||
function dietAvgText(v) {
|
||
return v == null || v === "" ? "—" : v;
|
||
}
|
||
const authChecking = common_vendor.ref(false);
|
||
const userMobile = common_vendor.ref("");
|
||
const phoneGateVisible = common_vendor.ref(false);
|
||
const phoneGateSex = common_vendor.ref(0);
|
||
const phoneBinding = common_vendor.ref(false);
|
||
const loading = common_vendor.ref(false);
|
||
const cardsLoading = common_vendor.ref(false);
|
||
const cards = common_vendor.ref([]);
|
||
const rangeMode = common_vendor.ref("7");
|
||
const rangeOptions = [
|
||
{ value: "7", label: "最近 7 天" },
|
||
{ value: "30", label: "最近 30 天" }
|
||
];
|
||
const bloodRecords = common_vendor.ref([]);
|
||
const dietRecords = common_vendor.ref([]);
|
||
const exerciseRecords = common_vendor.ref([]);
|
||
const trackingNotes = common_vendor.ref([]);
|
||
const hoverInfo = common_vendor.ref(null);
|
||
let hoverTimer = null;
|
||
const chartSeriesVisible = common_vendor.ref({ fasting: true, postprandial: true });
|
||
let canvasNode = null;
|
||
let canvasCtx = null;
|
||
let canvasWidth = 0;
|
||
let canvasHeight = 0;
|
||
let canvasDpr = 1;
|
||
let chartCoords = null;
|
||
common_vendor.computed(() => age.value > 0 ? `${age.value} 岁` : "");
|
||
common_vendor.computed(() => {
|
||
const map = { 1: "男", 2: "女" };
|
||
return map[Number(gender.value)] || "";
|
||
});
|
||
const rangeText = common_vendor.computed(() => {
|
||
const opt = rangeOptions.find((o) => o.value === rangeMode.value);
|
||
return opt ? opt.label : "";
|
||
});
|
||
function formatDate(date) {
|
||
const y = date.getFullYear();
|
||
const m = String(date.getMonth() + 1).padStart(2, "0");
|
||
const d = String(date.getDate()).padStart(2, "0");
|
||
return `${y}-${m}-${d}`;
|
||
}
|
||
function parseDate(str) {
|
||
if (!str)
|
||
return /* @__PURE__ */ new Date();
|
||
const [y, m, d] = str.split("-").map(Number);
|
||
return new Date(y, (m || 1) - 1, d || 1);
|
||
}
|
||
const currentRange = common_vendor.computed(() => {
|
||
const days = rangeMode.value === "30" ? 30 : 7;
|
||
const end = /* @__PURE__ */ new Date();
|
||
end.setHours(0, 0, 0, 0);
|
||
const start = new Date(end);
|
||
start.setDate(start.getDate() - (days - 1));
|
||
return { start: formatDate(start), end: formatDate(end) };
|
||
});
|
||
const visibleDates = common_vendor.computed(() => {
|
||
const { start, end } = currentRange.value;
|
||
if (!start || !end)
|
||
return [];
|
||
const dates = [];
|
||
const cursor = parseDate(end);
|
||
const lower = parseDate(start).getTime();
|
||
while (cursor.getTime() >= lower) {
|
||
dates.push(formatDate(cursor));
|
||
cursor.setDate(cursor.getDate() - 1);
|
||
}
|
||
return dates;
|
||
});
|
||
const chartDates = common_vendor.computed(() => [...visibleDates.value].reverse());
|
||
function toNumber(v) {
|
||
if (v === null || v === void 0 || v === "")
|
||
return null;
|
||
const n = Number(v);
|
||
return Number.isFinite(n) && n !== 0 ? n : null;
|
||
}
|
||
function getBloodSugarThresholds(ageValue) {
|
||
const a = Number(ageValue);
|
||
if (!Number.isFinite(a) || a <= 0)
|
||
return { fasting: 7, postprandial: 10 };
|
||
if (a < 50)
|
||
return { fasting: 7, postprandial: 9 };
|
||
return { fasting: 8, postprandial: 10 };
|
||
}
|
||
function isHighFasting(v) {
|
||
const n = toNumber(v);
|
||
const t = getBloodSugarThresholds(age.value);
|
||
return n !== null && t !== null && n >= t.fasting;
|
||
}
|
||
function isHighPostprandial(v) {
|
||
const n = toNumber(v);
|
||
const t = getBloodSugarThresholds(age.value);
|
||
return n !== null && t !== null && n >= t.postprandial;
|
||
}
|
||
function isHighBp(row) {
|
||
if (!row)
|
||
return false;
|
||
const s = toNumber(row.systolic_pressure);
|
||
const d = toNumber(row.diastolic_pressure);
|
||
return s !== null && s > 140 || d !== null && d > 90;
|
||
}
|
||
function formatBp(row) {
|
||
const s = row == null ? void 0 : row.systolic_pressure;
|
||
const d = row == null ? void 0 : row.diastolic_pressure;
|
||
if ((s === null || s === void 0 || s === "" || s === 0) && (d === null || d === void 0 || d === "" || d === 0))
|
||
return "—";
|
||
return `${s || "—"} / ${d || "—"}`;
|
||
}
|
||
const intensityTextMap = { 1: "低强度", 2: "中强度", 3: "高强度" };
|
||
const bloodByDate = common_vendor.computed(() => {
|
||
const map = {};
|
||
for (const r of bloodRecords.value) {
|
||
const date = String(r.record_date || "");
|
||
if (!date)
|
||
continue;
|
||
if (!map[date]) {
|
||
map[date] = {
|
||
record_date: date,
|
||
record_time: r.record_time || "",
|
||
fasting_blood_sugar: "",
|
||
postprandial_blood_sugar: "",
|
||
other_blood_sugar: "",
|
||
systolic_pressure: "",
|
||
diastolic_pressure: "",
|
||
western_medicine: "",
|
||
insulin: "",
|
||
remark: ""
|
||
};
|
||
}
|
||
const merged = map[date];
|
||
const fields = ["fasting_blood_sugar", "postprandial_blood_sugar", "other_blood_sugar", "systolic_pressure", "diastolic_pressure", "western_medicine", "insulin", "remark"];
|
||
for (const f of fields) {
|
||
if ((merged[f] === "" || merged[f] === null || merged[f] === void 0) && r[f] !== "" && r[f] !== null && r[f] !== void 0) {
|
||
merged[f] = r[f];
|
||
}
|
||
}
|
||
}
|
||
for (const date in map) {
|
||
const m = map[date];
|
||
m.isHighFasting = isHighFasting(m.fasting_blood_sugar);
|
||
m.isHighPostprandial = isHighPostprandial(m.postprandial_blood_sugar);
|
||
m.isHighOther = isHighPostprandial(m.other_blood_sugar);
|
||
m.isHighBp = isHighBp(m);
|
||
m.bpText = formatBp(m);
|
||
}
|
||
return map;
|
||
});
|
||
common_vendor.computed(() => {
|
||
const map = {};
|
||
for (const r of dietRecords.value) {
|
||
const date = String(r.record_date || "");
|
||
if (!date || map[date])
|
||
continue;
|
||
map[date] = r;
|
||
}
|
||
return map;
|
||
});
|
||
common_vendor.computed(() => {
|
||
const map = {};
|
||
for (const r of exerciseRecords.value) {
|
||
const date = String(r.record_date || "");
|
||
if (!date || map[date])
|
||
continue;
|
||
const item = { ...r };
|
||
item.intensityText = intensityTextMap[Number(r.intensity)] || "";
|
||
map[date] = item;
|
||
}
|
||
return map;
|
||
});
|
||
common_vendor.computed(() => {
|
||
const map = {};
|
||
for (const r of trackingNotes.value) {
|
||
const date = String(r.note_date || "");
|
||
if (!date || map[date])
|
||
continue;
|
||
map[date] = r;
|
||
}
|
||
return map;
|
||
});
|
||
const weekdayNames = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
|
||
function getWeekday(dateStr) {
|
||
return weekdayNames[parseDate(dateStr).getDay()] || "";
|
||
}
|
||
const todayStr = common_vendor.computed(() => formatDate(/* @__PURE__ */ new Date()));
|
||
common_vendor.computed(() => {
|
||
const result = [];
|
||
for (const date of visibleDates.value) {
|
||
const blood = bloodByDate.value[date];
|
||
if (!blood)
|
||
continue;
|
||
const hasSugar = toNumber(blood.fasting_blood_sugar) !== null || toNumber(blood.postprandial_blood_sugar) !== null || toNumber(blood.other_blood_sugar) !== null;
|
||
if (!hasSugar)
|
||
continue;
|
||
const [y, m, d] = date.split("-");
|
||
result.push({
|
||
date,
|
||
dateLabel: `${m}-${d}`,
|
||
weekday: getWeekday(date),
|
||
isToday: date === todayStr.value,
|
||
blood
|
||
});
|
||
}
|
||
return result;
|
||
});
|
||
const bloodHasData = common_vendor.computed(() => {
|
||
return chartDates.value.some((date) => {
|
||
const b = bloodByDate.value[date];
|
||
return b && (toNumber(b.fasting_blood_sugar) !== null || toNumber(b.postprandial_blood_sugar) !== null);
|
||
});
|
||
});
|
||
const bloodRecordDayCount = common_vendor.computed(() => {
|
||
return chartDates.value.filter((date) => {
|
||
const b = bloodByDate.value[date];
|
||
return b && (toNumber(b.fasting_blood_sugar) !== null || toNumber(b.postprandial_blood_sugar) !== null);
|
||
}).length;
|
||
});
|
||
const bloodHighDayCount = common_vendor.computed(() => {
|
||
return chartDates.value.filter((date) => {
|
||
const b = bloodByDate.value[date];
|
||
return b && (b.isHighFasting || b.isHighPostprandial);
|
||
}).length;
|
||
});
|
||
const bloodNormalDayCount = common_vendor.computed(() => bloodRecordDayCount.value - bloodHighDayCount.value);
|
||
function makeTrend(curr, prev, precision = 1) {
|
||
if (curr == null || prev == null)
|
||
return null;
|
||
const diff = Number(curr) - Number(prev);
|
||
if (!Number.isFinite(diff))
|
||
return null;
|
||
const abs = Math.abs(diff);
|
||
const dir = abs < 0.01 ? "flat" : diff > 0 ? "up" : "down";
|
||
const sign = dir === "up" ? "+" : dir === "down" ? "-" : "";
|
||
const deltaText = dir === "flat" ? "持平" : `${sign}${abs.toFixed(precision)}`;
|
||
return { dir, delta: abs, deltaText, prev };
|
||
}
|
||
function findPrev(field, beforeDate) {
|
||
const dates = chartDates.value;
|
||
const idx = dates.indexOf(beforeDate);
|
||
if (idx <= 0)
|
||
return null;
|
||
for (let i = idx - 1; i >= 0; i--) {
|
||
const b = bloodByDate.value[dates[i]];
|
||
if (!b)
|
||
continue;
|
||
const v = toNumber(b[field]);
|
||
if (v !== null)
|
||
return { date: dates[i], value: v };
|
||
}
|
||
return null;
|
||
}
|
||
const latestStat = common_vendor.computed(() => {
|
||
const dates = [...chartDates.value].reverse();
|
||
const dummy = { value: "—", date: "暂无记录", isHigh: false, trend: null };
|
||
const result = { fasting: { ...dummy }, postprandial: { ...dummy }, other: { ...dummy } };
|
||
for (const date of dates) {
|
||
const b = bloodByDate.value[date];
|
||
if (!b)
|
||
continue;
|
||
if (result.fasting.value === "—" && toNumber(b.fasting_blood_sugar) !== null) {
|
||
const cur = toNumber(b.fasting_blood_sugar);
|
||
const prev = findPrev("fasting_blood_sugar", date);
|
||
result.fasting = {
|
||
value: String(b.fasting_blood_sugar),
|
||
date: date.slice(5),
|
||
isHigh: b.isHighFasting,
|
||
trend: prev ? makeTrend(cur, prev.value) : null
|
||
};
|
||
}
|
||
if (result.postprandial.value === "—" && toNumber(b.postprandial_blood_sugar) !== null) {
|
||
const cur = toNumber(b.postprandial_blood_sugar);
|
||
const prev = findPrev("postprandial_blood_sugar", date);
|
||
result.postprandial = {
|
||
value: String(b.postprandial_blood_sugar),
|
||
date: date.slice(5),
|
||
isHigh: b.isHighPostprandial,
|
||
trend: prev ? makeTrend(cur, prev.value) : null
|
||
};
|
||
}
|
||
if (result.other.value === "—" && toNumber(b.other_blood_sugar) !== null) {
|
||
const cur = toNumber(b.other_blood_sugar);
|
||
const prev = findPrev("other_blood_sugar", date);
|
||
result.other = {
|
||
value: String(b.other_blood_sugar),
|
||
date: date.slice(5),
|
||
isHigh: b.isHighOther,
|
||
trend: prev ? makeTrend(cur, prev.value) : null
|
||
};
|
||
}
|
||
if (result.fasting.value !== "—" && result.postprandial.value !== "—" && result.other.value !== "—")
|
||
break;
|
||
}
|
||
return result;
|
||
});
|
||
function elderMetricFromBlood(blood, field, label) {
|
||
if (!blood)
|
||
return { label, value: "—", isHigh: false };
|
||
const num = toNumber(blood[field]);
|
||
if (num === null)
|
||
return { label, value: "—", isHigh: false };
|
||
const isHigh = field === "fasting_blood_sugar" ? blood.isHighFasting : field === "postprandial_blood_sugar" ? blood.isHighPostprandial : blood.isHighOther;
|
||
return { label, value: String(blood[field]), isHigh: !!isHigh };
|
||
}
|
||
const todayBlood = common_vendor.computed(() => bloodByDate.value[todayStr.value] || null);
|
||
const elderFasting = common_vendor.computed(
|
||
() => elderMetricFromBlood(todayBlood.value, "fasting_blood_sugar", "空腹")
|
||
);
|
||
const elderPostprandial = common_vendor.computed(
|
||
() => elderMetricFromBlood(todayBlood.value, "postprandial_blood_sugar", "餐后")
|
||
);
|
||
let authSessionPromise = null;
|
||
function hasAuthToken() {
|
||
return !!String(common_vendor.index.getStorageSync("token") || "").trim();
|
||
}
|
||
function clearAuthStorage() {
|
||
common_vendor.index.removeStorageSync("token");
|
||
authSessionPromise = null;
|
||
}
|
||
function wxLoginGetCode() {
|
||
return new Promise((resolve, reject) => {
|
||
common_vendor.index.login({
|
||
provider: "weixin",
|
||
success: (res) => {
|
||
if (res && res.code)
|
||
resolve(res.code);
|
||
else
|
||
reject(new Error("微信登录未返回 code"));
|
||
},
|
||
fail: reject
|
||
});
|
||
});
|
||
}
|
||
async function mnpLoginWithCode(code) {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/login/mnpLogin",
|
||
method: "POST",
|
||
data: { code }
|
||
}, false);
|
||
if (res && res.code === 1 && res.data && res.data.token) {
|
||
common_vendor.index.setStorageSync("token", res.data.token);
|
||
common_vendor.index.setStorageSync("userData", res.data);
|
||
return res.data;
|
||
}
|
||
clearAuthStorage();
|
||
throw new Error(formatUserMessage(res == null ? void 0 : res.msg, "登录失败"));
|
||
}
|
||
async function doWxLogin() {
|
||
const code = await wxLoginGetCode();
|
||
await mnpLoginWithCode(code);
|
||
return hasAuthToken();
|
||
}
|
||
async function verifyOrLogin() {
|
||
if (!hasAuthToken()) {
|
||
return doWxLogin();
|
||
}
|
||
try {
|
||
const res = await proxy.apiUrl({ url: "/api/user/info", method: "POST" }, false);
|
||
if (res && res.code === 1 && res.data) {
|
||
common_vendor.index.setStorageSync("userData", res.data);
|
||
return true;
|
||
}
|
||
} catch (e) {
|
||
}
|
||
clearAuthStorage();
|
||
try {
|
||
return await doWxLogin();
|
||
} catch (e2) {
|
||
return false;
|
||
}
|
||
}
|
||
async function ensureLoggedIn() {
|
||
if (authSessionPromise) {
|
||
return authSessionPromise;
|
||
}
|
||
authSessionPromise = verifyOrLogin().then((ok) => {
|
||
if (!ok)
|
||
authSessionPromise = null;
|
||
return !!ok;
|
||
}).catch(() => {
|
||
authSessionPromise = null;
|
||
return false;
|
||
});
|
||
return authSessionPromise;
|
||
}
|
||
async function fetchCardList() {
|
||
if (!hasAuthToken())
|
||
return [];
|
||
cardsLoading.value = true;
|
||
try {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/tcm/getCardList",
|
||
method: "GET",
|
||
data: {}
|
||
}, false);
|
||
if (res && res.code === 1 && Array.isArray(res.data)) {
|
||
cards.value = res.data;
|
||
return res.data;
|
||
}
|
||
cards.value = [];
|
||
return [];
|
||
} catch (e) {
|
||
cards.value = [];
|
||
return [];
|
||
} finally {
|
||
cardsLoading.value = false;
|
||
}
|
||
}
|
||
async function applyCard(card) {
|
||
if (!card || !hasAuthToken())
|
||
return;
|
||
diagnosisId.value = Number(card.id) || 0;
|
||
patientId.value = Number(card.patient_id) || 0;
|
||
patientName.value = card.patient_name || "";
|
||
age.value = Number(card.age) || 0;
|
||
gender.value = Number(card.gender) || 0;
|
||
}
|
||
function readUserMobile() {
|
||
try {
|
||
const userData = common_vendor.index.getStorageSync("userData") || {};
|
||
userMobile.value = String(userData.mobile || userData.phone || "").trim();
|
||
} catch (e) {
|
||
userMobile.value = "";
|
||
}
|
||
return userMobile.value;
|
||
}
|
||
function syncPhoneGateSexFromUser() {
|
||
try {
|
||
const userData = common_vendor.index.getStorageSync("userData") || {};
|
||
const sex = Number(userData.sex);
|
||
phoneGateSex.value = sex === 1 || sex === 2 ? sex : 0;
|
||
} catch (e) {
|
||
phoneGateSex.value = 0;
|
||
}
|
||
}
|
||
function openPhoneGate() {
|
||
syncPhoneGateSexFromUser();
|
||
phoneGateVisible.value = true;
|
||
}
|
||
async function refreshUserMobile() {
|
||
try {
|
||
const res = await proxy.apiUrl({ url: "/api/user/info", method: "POST" }, false);
|
||
if (res && res.code === 1 && res.data) {
|
||
common_vendor.index.setStorageSync("userData", res.data);
|
||
userMobile.value = String(res.data.mobile || res.data.phone || "").trim();
|
||
}
|
||
} catch (e) {
|
||
}
|
||
return userMobile.value;
|
||
}
|
||
async function ensureDailyContextByPhone(sex) {
|
||
if (diagnosisId.value)
|
||
return true;
|
||
const payload = {};
|
||
const sexVal = sex ?? phoneGateSex.value;
|
||
if (sexVal === 1 || sexVal === 2) {
|
||
payload.sex = sexVal;
|
||
}
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/tcm/dailyEnsurePhoneContext",
|
||
method: "POST",
|
||
data: payload
|
||
}, false);
|
||
if (res && res.code === 1 && res.data && res.data.diagnosis_id) {
|
||
await applyCard({
|
||
id: res.data.diagnosis_id,
|
||
patient_id: res.data.patient_id,
|
||
patient_name: res.data.patient_name || "",
|
||
age: res.data.age || 0,
|
||
gender: res.data.gender || 0
|
||
});
|
||
if (res.data.created) {
|
||
await fetchCardList();
|
||
}
|
||
return true;
|
||
}
|
||
if (res && res.data && res.data.need_mobile) {
|
||
return "need_mobile";
|
||
}
|
||
showUserToast(formatUserMessage(res == null ? void 0 : res.msg, "无法开始录入"));
|
||
return false;
|
||
}
|
||
async function ensureCanRecordGlucose() {
|
||
if (diagnosisId.value)
|
||
return true;
|
||
readUserMobile();
|
||
if (!userMobile.value) {
|
||
openPhoneGate();
|
||
return false;
|
||
}
|
||
const ok = await ensureDailyContextByPhone();
|
||
if (ok === "need_mobile") {
|
||
openPhoneGate();
|
||
return false;
|
||
}
|
||
return !!ok;
|
||
}
|
||
function closePhoneGate() {
|
||
if (phoneBinding.value)
|
||
return;
|
||
phoneGateVisible.value = false;
|
||
}
|
||
async function onPhoneGateAuthorize(e) {
|
||
const detail = (e == null ? void 0 : e.detail) || {};
|
||
if (detail.errMsg && !String(detail.errMsg).includes("ok")) {
|
||
showUserToast("需要授权手机号后才能录入血糖");
|
||
return;
|
||
}
|
||
const code = detail.code;
|
||
if (!code) {
|
||
showUserToast("获取手机号失败,请重试");
|
||
return;
|
||
}
|
||
if (phoneGateSex.value !== 1 && phoneGateSex.value !== 2) {
|
||
showUserToast("请先选择性别");
|
||
return;
|
||
}
|
||
phoneBinding.value = true;
|
||
try {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/user/getMobileByMnp",
|
||
method: "POST",
|
||
data: { code, sex: phoneGateSex.value }
|
||
}, false);
|
||
if (!res || res.code !== 1) {
|
||
showUserToast(formatUserMessage(res == null ? void 0 : res.msg, "绑定手机号失败"));
|
||
return;
|
||
}
|
||
await refreshUserMobile();
|
||
phoneGateVisible.value = false;
|
||
const ok = await ensureDailyContextByPhone(phoneGateSex.value);
|
||
if (ok === true) {
|
||
await openInputForm(true);
|
||
} else if (ok === "need_mobile") {
|
||
openPhoneGate();
|
||
}
|
||
} catch (err) {
|
||
showUserToast("网络异常,请稍后再试");
|
||
} finally {
|
||
phoneBinding.value = false;
|
||
}
|
||
}
|
||
async function onSelectCard(card) {
|
||
if (!card || Number(card.id) === Number(diagnosisId.value))
|
||
return;
|
||
bloodRecords.value = [];
|
||
dietRecords.value = [];
|
||
exerciseRecords.value = [];
|
||
trackingNotes.value = [];
|
||
hoverInfo.value = null;
|
||
await applyCard(card);
|
||
fetchAll();
|
||
}
|
||
async function fetchAll() {
|
||
if (!hasAuthToken() || !diagnosisId.value)
|
||
return;
|
||
loading.value = true;
|
||
const { start, end } = currentRange.value;
|
||
try {
|
||
const [winRes, noteRes] = await Promise.all([
|
||
proxy.apiUrl({
|
||
url: "/api/tcm/dailyTrackingWindow",
|
||
method: "GET",
|
||
data: {
|
||
diagnosis_id: diagnosisId.value,
|
||
patient_id: patientId.value || 0,
|
||
start_date: start,
|
||
end_date: end
|
||
}
|
||
}, false),
|
||
proxy.apiUrl({
|
||
url: "/api/tcm/dailyTrackingNotes",
|
||
method: "GET",
|
||
data: {
|
||
diagnosis_id: diagnosisId.value,
|
||
patient_id: patientId.value || 0
|
||
}
|
||
}, false)
|
||
]);
|
||
if (winRes && winRes.code === 1) {
|
||
const d = winRes.data || {};
|
||
bloodRecords.value = Array.isArray(d.blood_records) ? d.blood_records : [];
|
||
dietRecords.value = Array.isArray(d.diet_records) ? d.diet_records : [];
|
||
exerciseRecords.value = Array.isArray(d.exercise_records) ? d.exercise_records : [];
|
||
if (d.diagnosis) {
|
||
if (!patientName.value)
|
||
patientName.value = d.diagnosis.patient_name || "";
|
||
if (!age.value)
|
||
age.value = Number(d.diagnosis.age) || 0;
|
||
if (!gender.value)
|
||
gender.value = Number(d.diagnosis.gender) || 0;
|
||
if (!patientId.value)
|
||
patientId.value = Number(d.diagnosis.patient_id) || 0;
|
||
}
|
||
} else {
|
||
bloodRecords.value = [];
|
||
dietRecords.value = [];
|
||
exerciseRecords.value = [];
|
||
if (winRes == null ? void 0 : winRes.msg)
|
||
showUserToast(winRes.msg);
|
||
}
|
||
if (noteRes && noteRes.code === 1) {
|
||
const list = Array.isArray(noteRes.data) ? noteRes.data : [];
|
||
trackingNotes.value = list.filter((it) => visibleDates.value.includes(String((it == null ? void 0 : it.note_date) || "")));
|
||
} else {
|
||
trackingNotes.value = [];
|
||
}
|
||
await fetchDietAiRecommend(false);
|
||
} catch (e) {
|
||
common_vendor.index.showToast({ title: "加载失败,请稍后再试", icon: "none" });
|
||
} finally {
|
||
loading.value = false;
|
||
await common_vendor.nextTick$1();
|
||
scheduleChartRedraw();
|
||
if (ttsAutoPlay.value && !recordOverlayOpen.value) {
|
||
const token = ++ttsAutoToken;
|
||
setTimeout(() => {
|
||
if (token === ttsAutoToken && !recordOverlayOpen.value)
|
||
speakLatestSummary();
|
||
}, 350);
|
||
}
|
||
}
|
||
}
|
||
function onChangeRange(value) {
|
||
if (rangeMode.value === value)
|
||
return;
|
||
rangeMode.value = value;
|
||
fetchAll();
|
||
}
|
||
async function goMorePage() {
|
||
if (!diagnosisId.value) {
|
||
const ok = await ensureCanRecordGlucose();
|
||
if (!ok || !diagnosisId.value)
|
||
return;
|
||
}
|
||
common_vendor.index.navigateTo({ url: "/tongji/pages/more" });
|
||
}
|
||
function buildTimeGreetingMeta(hour = (/* @__PURE__ */ new Date()).getHours()) {
|
||
const h = Number(hour) || 0;
|
||
if (h < 5)
|
||
return { text: "夜深了", icon: "moon" };
|
||
if (h < 11)
|
||
return { text: "早上好", icon: "sun" };
|
||
if (h < 13)
|
||
return { text: "中午好", icon: "sun" };
|
||
if (h < 18)
|
||
return { text: "下午好", icon: "sun" };
|
||
if (h < 22)
|
||
return { text: "晚上好", icon: "sunset" };
|
||
return { text: "夜深了", icon: "moon" };
|
||
}
|
||
const timeGreetingMeta = common_vendor.computed(() => buildTimeGreetingMeta());
|
||
function dayHasBloodRecord(key) {
|
||
const b = bloodByDate.value[key];
|
||
if (!b)
|
||
return false;
|
||
return toNumber(b.fasting_blood_sugar) !== null || toNumber(b.postprandial_blood_sugar) !== null || toNumber(b.other_blood_sugar) !== null;
|
||
}
|
||
function dayCoverageLevel(key) {
|
||
const b = bloodByDate.value[key];
|
||
if (!b)
|
||
return 0;
|
||
const fields = ["fasting_blood_sugar", "postprandial_blood_sugar", "other_blood_sugar"];
|
||
const score = fields.filter((f) => toNumber(b[f]) !== null).length;
|
||
if (score === 0)
|
||
return 0;
|
||
if (score === 1)
|
||
return 1;
|
||
if (score === 2)
|
||
return 2;
|
||
return 3;
|
||
}
|
||
const todayChecked = common_vendor.computed(() => dayHasBloodRecord(todayStr.value));
|
||
common_vendor.computed(() => {
|
||
const today = /* @__PURE__ */ new Date();
|
||
let count = 0;
|
||
let startedFromYesterday = false;
|
||
for (let i = 0; i < 90; i++) {
|
||
const d = new Date(today);
|
||
d.setDate(today.getDate() - i);
|
||
const key = formatDate(d);
|
||
const has = dayHasBloodRecord(key);
|
||
if (has) {
|
||
count++;
|
||
} else {
|
||
if (i === 0) {
|
||
startedFromYesterday = true;
|
||
continue;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return { days: count, startedFromYesterday };
|
||
});
|
||
const last7Dots = common_vendor.computed(() => {
|
||
const arr = [];
|
||
const today = /* @__PURE__ */ new Date();
|
||
const wkChars = ["日", "一", "二", "三", "四", "五", "六"];
|
||
for (let i = 6; i >= 0; i--) {
|
||
const d = new Date(today);
|
||
d.setDate(today.getDate() - i);
|
||
const key = formatDate(d);
|
||
arr.push({
|
||
date: key,
|
||
label: wkChars[d.getDay()],
|
||
isToday: i === 0,
|
||
hasRecord: dayHasBloodRecord(key)
|
||
});
|
||
}
|
||
return arr;
|
||
});
|
||
common_vendor.computed(() => last7Dots.value.filter((d) => d.hasRecord).length);
|
||
function dayHasFastingRecord(key) {
|
||
const b = bloodByDate.value[key];
|
||
return !!(b && toNumber(b.fasting_blood_sugar) !== null);
|
||
}
|
||
function dayHasPostprandialRecord(key) {
|
||
const b = bloodByDate.value[key];
|
||
return !!(b && toNumber(b.postprandial_blood_sugar) !== null);
|
||
}
|
||
function dayIsCompleteRecord(key) {
|
||
return dayHasFastingRecord(key) && dayHasPostprandialRecord(key);
|
||
}
|
||
common_vendor.computed(() => last7Dots.value.filter((d) => dayIsCompleteRecord(d.date)).length);
|
||
const heatmapWeeks = common_vendor.computed(() => {
|
||
const dates = chartDates.value;
|
||
if (!dates || !dates.length)
|
||
return [];
|
||
const sorted = [...dates].sort();
|
||
const first = new Date(sorted[0]);
|
||
const last = new Date(sorted[sorted.length - 1]);
|
||
const firstDow = (first.getDay() + 6) % 7;
|
||
const lastDow = (last.getDay() + 6) % 7;
|
||
const gridStart = new Date(first);
|
||
gridStart.setDate(first.getDate() - firstDow);
|
||
const gridEnd = new Date(last);
|
||
gridEnd.setDate(last.getDate() + (6 - lastDow));
|
||
const totalDays = Math.round((gridEnd - gridStart) / 864e5) + 1;
|
||
const weeks = [];
|
||
let cur = new Date(gridStart);
|
||
for (let w = 0; w < Math.ceil(totalDays / 7); w++) {
|
||
const week = [];
|
||
for (let i = 0; i < 7; i++) {
|
||
const key = formatDate(cur);
|
||
const inRange = sorted.includes(key);
|
||
week.push({
|
||
date: key,
|
||
day: cur.getDate(),
|
||
inRange,
|
||
isToday: key === todayStr.value,
|
||
level: inRange ? dayCoverageLevel(key) : -1
|
||
});
|
||
cur.setDate(cur.getDate() + 1);
|
||
}
|
||
weeks.push(week);
|
||
}
|
||
return weeks;
|
||
});
|
||
common_vendor.computed(() => {
|
||
let c = 0;
|
||
for (const w of heatmapWeeks.value)
|
||
for (const c2 of w)
|
||
if (c2.inRange && c2.level > 0)
|
||
c++;
|
||
return c;
|
||
});
|
||
common_vendor.computed(() => {
|
||
let c = 0;
|
||
for (const w of heatmapWeeks.value)
|
||
for (const c2 of w)
|
||
if (c2.inRange)
|
||
c++;
|
||
return c;
|
||
});
|
||
common_vendor.computed(() => {
|
||
const weeks = heatmapWeeks.value;
|
||
if (!weeks.length)
|
||
return "";
|
||
const counter = /* @__PURE__ */ new Map();
|
||
for (const w of weeks) {
|
||
for (const c of w) {
|
||
if (!c.inRange)
|
||
continue;
|
||
const [y2, m2] = c.date.split("-");
|
||
const key = `${y2}-${m2}`;
|
||
counter.set(key, (counter.get(key) || 0) + 1);
|
||
}
|
||
}
|
||
if (!counter.size) {
|
||
const first = weeks[0][0].date.split("-");
|
||
return `${Number(first[0])}年${Number(first[1])}月`;
|
||
}
|
||
let best = "";
|
||
let bestCount = -1;
|
||
for (const [k, v] of counter) {
|
||
if (v > bestCount) {
|
||
best = k;
|
||
bestCount = v;
|
||
}
|
||
}
|
||
const [y, m] = best.split("-");
|
||
return `${Number(y)}年${Number(m)}月`;
|
||
});
|
||
const todayText = common_vendor.computed(() => {
|
||
const d = /* @__PURE__ */ new Date();
|
||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||
const day = String(d.getDate()).padStart(2, "0");
|
||
const weekdays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
|
||
return `${d.getFullYear()}-${m}-${day} ${weekdays[d.getDay()]}`;
|
||
});
|
||
const emptyInputForm = () => ({
|
||
visible: false,
|
||
loading: false,
|
||
submitting: false,
|
||
id: 0,
|
||
fasting_blood_sugar: "",
|
||
postprandial_blood_sugar: "",
|
||
other_blood_sugar: "",
|
||
remark: ""
|
||
});
|
||
const inputForm = common_vendor.ref(emptyInputForm());
|
||
function prepareRecordOverlay() {
|
||
canvasCtx = null;
|
||
canvasNode = null;
|
||
ttsStop();
|
||
}
|
||
function onInputField(field, e) {
|
||
var _a;
|
||
const val = ((_a = e == null ? void 0 : e.detail) == null ? void 0 : _a.value) ?? "";
|
||
inputForm.value[field] = val;
|
||
}
|
||
async function openInputForm(skipEnsure = false) {
|
||
const token = common_vendor.index.getStorageSync("token");
|
||
if (!token) {
|
||
showUserToast("请先登录后再录入");
|
||
return;
|
||
}
|
||
if (!skipEnsure) {
|
||
const can = await ensureCanRecordGlucose();
|
||
if (!can)
|
||
return;
|
||
}
|
||
if (!diagnosisId.value) {
|
||
showUserToast("请先授权手机号");
|
||
return;
|
||
}
|
||
prepareRecordOverlay();
|
||
inputForm.value = { ...emptyInputForm(), visible: true, loading: true };
|
||
try {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/tcm/dailyTodayBloodRecord",
|
||
method: "GET",
|
||
data: { diagnosis_id: diagnosisId.value }
|
||
}, false);
|
||
if (res && res.code === 1 && res.data && res.data.record) {
|
||
const r = res.data.record;
|
||
inputForm.value.id = Number(r.id) || 0;
|
||
inputForm.value.fasting_blood_sugar = numToStr(r.fasting_blood_sugar);
|
||
inputForm.value.postprandial_blood_sugar = numToStr(r.postprandial_blood_sugar);
|
||
inputForm.value.other_blood_sugar = numToStr(r.other_blood_sugar);
|
||
inputForm.value.remark = String(r.remark || "");
|
||
}
|
||
} catch (e) {
|
||
} finally {
|
||
inputForm.value.loading = false;
|
||
}
|
||
}
|
||
function numToStr(v) {
|
||
if (v === null || v === void 0 || v === "" || v === 0 || v === "0")
|
||
return "";
|
||
if (typeof v === "object")
|
||
return "";
|
||
return String(v);
|
||
}
|
||
function closeInputForm() {
|
||
if (inputForm.value.submitting)
|
||
return;
|
||
inputForm.value.visible = false;
|
||
common_vendor.nextTick$1(() => scheduleChartRedraw());
|
||
}
|
||
const recordOverlayOpen = common_vendor.computed(() => inputForm.value.visible || phoneGateVisible.value);
|
||
async function submitInputForm() {
|
||
if (inputForm.value.submitting || inputForm.value.loading)
|
||
return;
|
||
const f = inputForm.value;
|
||
const hasAny = [
|
||
f.fasting_blood_sugar,
|
||
f.postprandial_blood_sugar,
|
||
f.other_blood_sugar
|
||
].some((v) => v !== "" && v !== null && Number(v) > 0) || !!(f.remark && f.remark.trim());
|
||
if (!hasAny) {
|
||
common_vendor.index.showToast({ title: "请至少填写一项数据", icon: "none" });
|
||
return;
|
||
}
|
||
inputForm.value.submitting = true;
|
||
try {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/tcm/dailySaveBloodRecord",
|
||
method: "POST",
|
||
data: {
|
||
diagnosis_id: diagnosisId.value,
|
||
fasting_blood_sugar: f.fasting_blood_sugar,
|
||
postprandial_blood_sugar: f.postprandial_blood_sugar,
|
||
other_blood_sugar: f.other_blood_sugar,
|
||
remark: f.remark
|
||
}
|
||
}, false);
|
||
if (res && res.code === 1) {
|
||
showUserToast(res.msg || "已保存", { icon: "success" });
|
||
inputForm.value.visible = false;
|
||
await fetchAll();
|
||
} else {
|
||
showUserToast(res && res.msg || "保存失败");
|
||
}
|
||
} catch (e) {
|
||
common_vendor.index.showToast({ title: "网络异常,请稍后再试", icon: "none" });
|
||
} finally {
|
||
inputForm.value.submitting = false;
|
||
}
|
||
}
|
||
function deleteInputRecord() {
|
||
if (!inputForm.value.id || inputForm.value.submitting)
|
||
return;
|
||
common_vendor.index.showModal({
|
||
title: "删除确认",
|
||
content: "确定删除今天已录入的数据吗?删除后无法恢复。",
|
||
confirmColor: "#dc2626",
|
||
success: async (m) => {
|
||
if (!m.confirm)
|
||
return;
|
||
inputForm.value.submitting = true;
|
||
try {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/tcm/dailyDeleteBloodRecord",
|
||
method: "POST",
|
||
data: {
|
||
diagnosis_id: diagnosisId.value,
|
||
id: inputForm.value.id
|
||
}
|
||
}, false);
|
||
if (res && res.code === 1) {
|
||
common_vendor.index.showToast({ title: "已删除", icon: "success" });
|
||
inputForm.value.visible = false;
|
||
fetchAll();
|
||
} else {
|
||
showUserToast(res && res.msg || "删除失败");
|
||
}
|
||
} catch (e) {
|
||
common_vendor.index.showToast({ title: "网络异常,请稍后再试", icon: "none" });
|
||
} finally {
|
||
inputForm.value.submitting = false;
|
||
}
|
||
}
|
||
});
|
||
}
|
||
const ttsEnabled = common_vendor.ref(true);
|
||
const ttsAutoPlay = common_vendor.ref(false);
|
||
const ttsSpeaking = common_vendor.ref(false);
|
||
let ttsAudioCtx = null;
|
||
let ttsAutoToken = 0;
|
||
function teardownTtsAudio() {
|
||
if (ttsAudioCtx) {
|
||
try {
|
||
ttsAudioCtx.stop();
|
||
} catch (e) {
|
||
}
|
||
try {
|
||
ttsAudioCtx.destroy && ttsAudioCtx.destroy();
|
||
} catch (e) {
|
||
}
|
||
ttsAudioCtx = null;
|
||
}
|
||
}
|
||
function ttsStop() {
|
||
teardownTtsAudio();
|
||
ttsSpeaking.value = false;
|
||
}
|
||
function normalizeTtsText(text) {
|
||
if (text == null)
|
||
return "";
|
||
if (typeof text === "string")
|
||
return text.replace(/\s+/g, " ").trim();
|
||
if (Array.isArray(text)) {
|
||
return text.map((item) => {
|
||
if (typeof item === "string")
|
||
return item;
|
||
if (item && typeof item === "object") {
|
||
return item.title || item.label || item.desc || item.msg || item.message || "";
|
||
}
|
||
return formatUserMessage(item, "");
|
||
}).filter(Boolean).join(",");
|
||
}
|
||
if (typeof text === "object") {
|
||
return text.title || text.label || text.desc || text.msg || text.message || "";
|
||
}
|
||
return formatUserMessage(text, "");
|
||
}
|
||
function ttsSpeak(text) {
|
||
if (!ttsEnabled.value)
|
||
return;
|
||
const content = normalizeTtsText(text);
|
||
if (!content)
|
||
return;
|
||
ttsStop();
|
||
try {
|
||
const plugin = requirePlugin("WechatSI");
|
||
ttsSpeaking.value = true;
|
||
plugin.textToSpeech({
|
||
lang: "zh_CN",
|
||
tts: true,
|
||
content,
|
||
success: (res) => {
|
||
if (!res || !res.filename) {
|
||
ttsSpeaking.value = false;
|
||
return;
|
||
}
|
||
teardownTtsAudio();
|
||
ttsAudioCtx = common_vendor.index.createInnerAudioContext();
|
||
ttsAudioCtx.src = res.filename;
|
||
ttsAudioCtx.obeyMuteSwitch = false;
|
||
ttsAudioCtx.onPlay(() => {
|
||
ttsSpeaking.value = true;
|
||
});
|
||
ttsAudioCtx.onEnded(() => {
|
||
ttsSpeaking.value = false;
|
||
});
|
||
ttsAudioCtx.onError(() => {
|
||
ttsSpeaking.value = false;
|
||
});
|
||
ttsAudioCtx.onStop(() => {
|
||
ttsSpeaking.value = false;
|
||
});
|
||
ttsAudioCtx.play();
|
||
},
|
||
fail: (err) => {
|
||
ttsSpeaking.value = false;
|
||
common_vendor.index.__f__("warn", "at tongji/pages/index.vue:2103", "WechatSI textToSpeech failed", err);
|
||
common_vendor.index.showToast({ title: "语音不可用,请检查网络/插件", icon: "none", duration: 2e3 });
|
||
}
|
||
});
|
||
return;
|
||
} catch (e) {
|
||
common_vendor.index.__f__("warn", "at tongji/pages/index.vue:2109", "WechatSI plugin not available", e);
|
||
}
|
||
showUserToast(content, { duration: 3200 });
|
||
}
|
||
function readableNumber(v) {
|
||
if (v === null || v === void 0 || v === "")
|
||
return "";
|
||
return String(v).replace(/(\d+)\.(\d+)/g, (_, a, b) => `${a}点${b}`);
|
||
}
|
||
function buildLatestSummaryText() {
|
||
const f = latestStat.value.fasting;
|
||
const p = latestStat.value.postprandial;
|
||
const o = latestStat.value.other;
|
||
const head = `${patientName.value || "您"}的最新血糖情况:`;
|
||
const lines = [];
|
||
if (f && f.value !== "—") {
|
||
let line = `空腹血糖 ${readableNumber(f.value)} 毫摩每升`;
|
||
if (f.isHigh)
|
||
line += ",偏高,请遵医嘱。";
|
||
else
|
||
line += "。";
|
||
if (f.trend && f.trend.dir !== "flat") {
|
||
line += `比上次${f.trend.dir === "up" ? "升高" : "下降"} ${readableNumber(f.trend.delta.toFixed(1))}。`;
|
||
}
|
||
lines.push(line);
|
||
}
|
||
if (p && p.value !== "—") {
|
||
let line = `餐后血糖 ${readableNumber(p.value)} 毫摩每升`;
|
||
if (p.isHigh)
|
||
line += ",偏高,请注意饮食。";
|
||
else
|
||
line += "。";
|
||
if (p.trend && p.trend.dir !== "flat") {
|
||
line += `比上次${p.trend.dir === "up" ? "升高" : "下降"} ${readableNumber(p.trend.delta.toFixed(1))}。`;
|
||
}
|
||
lines.push(line);
|
||
}
|
||
if (o && o.value !== "—") {
|
||
let line = `其他时段血糖 ${readableNumber(o.value)} 毫摩每升`;
|
||
if (o.isHigh)
|
||
line += ",偏高,请遵医嘱。";
|
||
else
|
||
line += "。";
|
||
if (o.trend && o.trend.dir !== "flat") {
|
||
line += `比上次${o.trend.dir === "up" ? "升高" : "下降"} ${readableNumber(o.trend.delta.toFixed(1))}。`;
|
||
}
|
||
lines.push(line);
|
||
}
|
||
if (!lines.length) {
|
||
return `${patientName.value || "您"}近期暂无血糖记录。`;
|
||
}
|
||
return head + lines.join(" ");
|
||
}
|
||
function speakLatestSummary() {
|
||
const text = buildLatestSummaryText();
|
||
if (text)
|
||
ttsSpeak(text);
|
||
}
|
||
function ensureCanvas() {
|
||
return new Promise((resolve) => {
|
||
if (canvasCtx) {
|
||
resolve();
|
||
return;
|
||
}
|
||
const query = common_vendor.index.createSelectorQuery().in(proxy);
|
||
query.select("#bloodWaveChart").fields({ node: true, size: true }).exec((res) => {
|
||
const item = res && res[0];
|
||
if (!item || !item.node) {
|
||
resolve();
|
||
return;
|
||
}
|
||
canvasNode = item.node;
|
||
canvasCtx = canvasNode.getContext("2d");
|
||
try {
|
||
canvasDpr = common_vendor.index.getSystemInfoSync().pixelRatio || 1;
|
||
} catch (e) {
|
||
canvasDpr = 1;
|
||
}
|
||
canvasWidth = item.width;
|
||
canvasHeight = item.height;
|
||
canvasNode.width = canvasWidth * canvasDpr;
|
||
canvasNode.height = canvasHeight * canvasDpr;
|
||
canvasCtx.scale(canvasDpr, canvasDpr);
|
||
resolve();
|
||
});
|
||
});
|
||
}
|
||
let redrawScheduled = false;
|
||
function scheduleChartRedraw() {
|
||
if (redrawScheduled)
|
||
return;
|
||
redrawScheduled = true;
|
||
setTimeout(async () => {
|
||
redrawScheduled = false;
|
||
await ensureCanvas();
|
||
drawChart();
|
||
}, 60);
|
||
}
|
||
function buildSeries(field) {
|
||
return chartDates.value.map((date) => {
|
||
const b = bloodByDate.value[date];
|
||
return b ? toNumber(b[field]) : null;
|
||
});
|
||
}
|
||
function computeYRange(...seriesList) {
|
||
const values = seriesList.flat().filter((v) => v !== null);
|
||
if (!values.length)
|
||
return { yMin: 4, yMax: 12 };
|
||
let min = Math.min(...values);
|
||
let max = Math.max(...values);
|
||
const span = max - min;
|
||
if (span < 2) {
|
||
min = Math.max(0, min - 1);
|
||
max = max + 1;
|
||
} else {
|
||
min = Math.max(0, min - span * 0.2);
|
||
max = max + span * 0.2;
|
||
}
|
||
min = Math.max(2, Math.floor(min));
|
||
max = Math.min(28, Math.ceil(max));
|
||
if (max - min < 4)
|
||
max = min + 4;
|
||
return { yMin: min, yMax: max };
|
||
}
|
||
function drawChart() {
|
||
if (!canvasCtx || !canvasWidth || !canvasHeight)
|
||
return;
|
||
const ctx = canvasCtx;
|
||
const w = canvasWidth;
|
||
const h = canvasHeight;
|
||
ctx.clearRect(0, 0, w, h);
|
||
const padding = { left: 40, right: 18, top: 26, bottom: 36 };
|
||
const cw = w - padding.left - padding.right;
|
||
const ch = h - padding.top - padding.bottom;
|
||
const fastingSeries = buildSeries("fasting_blood_sugar");
|
||
const postSeries = buildSeries("postprandial_blood_sugar");
|
||
const n = chartDates.value.length;
|
||
const threshold = getBloodSugarThresholds(age.value);
|
||
const seriesDefs = [
|
||
{
|
||
key: "fasting",
|
||
data: fastingSeries,
|
||
color: "#204E2B",
|
||
fillTop: "rgba(32,78,43,0.18)",
|
||
fillBottom: "rgba(32,78,43,0)",
|
||
label: "空腹",
|
||
highThreshold: threshold ? threshold.fasting : null
|
||
},
|
||
{
|
||
key: "postprandial",
|
||
data: postSeries,
|
||
color: "#D97706",
|
||
fillTop: "rgba(217,119,6,0.18)",
|
||
fillBottom: "rgba(217,119,6,0)",
|
||
label: "餐后",
|
||
highThreshold: threshold ? threshold.postprandial : null
|
||
}
|
||
];
|
||
const visibleDefs = seriesDefs.filter((item) => chartSeriesVisible.value[item.key]);
|
||
const rangeSources = visibleDefs.length ? visibleDefs.map((item) => item.data) : [fastingSeries, postSeries];
|
||
const { yMin, yMax } = computeYRange(...rangeSources);
|
||
const valueToY = (v) => padding.top + ch * (1 - (v - yMin) / (yMax - yMin));
|
||
ctx.fillStyle = "#fbfcfd";
|
||
ctx.fillRect(padding.left, padding.top, cw, ch);
|
||
if (threshold) {
|
||
const yThr = valueToY(threshold.fasting);
|
||
const top = Math.max(padding.top, Math.min(yThr, padding.top + ch));
|
||
if (top > padding.top) {
|
||
const dangerGrad = ctx.createLinearGradient(0, padding.top, 0, top);
|
||
dangerGrad.addColorStop(0, "rgba(254, 226, 226, 0.55)");
|
||
dangerGrad.addColorStop(1, "rgba(254, 226, 226, 0.15)");
|
||
ctx.fillStyle = dangerGrad;
|
||
ctx.fillRect(padding.left, padding.top, cw, top - padding.top);
|
||
}
|
||
}
|
||
ctx.strokeStyle = "#eef2f5";
|
||
ctx.lineWidth = 1;
|
||
const yTicks = 4;
|
||
for (let i = 0; i <= yTicks; i++) {
|
||
const y = padding.top + ch * i / yTicks;
|
||
ctx.beginPath();
|
||
ctx.moveTo(padding.left, y);
|
||
ctx.lineTo(padding.left + cw, y);
|
||
ctx.stroke();
|
||
}
|
||
ctx.font = "bold 12px sans-serif";
|
||
ctx.fillStyle = "#64748b";
|
||
ctx.textAlign = "right";
|
||
ctx.textBaseline = "middle";
|
||
for (let i = 0; i <= yTicks; i++) {
|
||
const y = padding.top + ch * i / yTicks;
|
||
const v = yMax - (yMax - yMin) * i / yTicks;
|
||
ctx.fillText(v.toFixed(1), padding.left - 8, y);
|
||
}
|
||
ctx.font = "bold 12px sans-serif";
|
||
ctx.fillStyle = "#475569";
|
||
ctx.textAlign = "center";
|
||
ctx.textBaseline = "top";
|
||
if (n > 0) {
|
||
const maxLabels = n > 20 ? 5 : 6;
|
||
const labelStep = Math.max(1, Math.ceil(n / maxLabels));
|
||
chartDates.value.forEach((date, i) => {
|
||
if (i !== 0 && i !== n - 1 && i % labelStep !== 0)
|
||
return;
|
||
const x = n === 1 ? padding.left + cw / 2 : padding.left + cw * i / (n - 1);
|
||
ctx.fillText(date.slice(5), x, padding.top + ch + 8);
|
||
});
|
||
}
|
||
if (threshold) {
|
||
const y = valueToY(threshold.fasting);
|
||
if (y >= padding.top && y <= padding.top + ch) {
|
||
ctx.strokeStyle = "#fda4af";
|
||
ctx.lineWidth = 1;
|
||
try {
|
||
ctx.setLineDash([6, 5]);
|
||
} catch (e) {
|
||
}
|
||
ctx.beginPath();
|
||
ctx.moveTo(padding.left, y);
|
||
ctx.lineTo(padding.left + cw, y);
|
||
ctx.stroke();
|
||
try {
|
||
ctx.setLineDash([]);
|
||
} catch (e) {
|
||
}
|
||
ctx.font = "bold 11px sans-serif";
|
||
ctx.fillStyle = "#dc2626";
|
||
ctx.textAlign = "left";
|
||
ctx.textBaseline = "middle";
|
||
ctx.fillText(`空腹阈 ${threshold.fasting}`, padding.left + 6, y - 9);
|
||
}
|
||
}
|
||
const xAt = (i) => n === 1 ? padding.left + cw / 2 : padding.left + cw * i / (n - 1);
|
||
const coordByKey = { fasting: [], postprandial: [] };
|
||
const showDots = n <= 10;
|
||
seriesDefs.forEach((meta) => {
|
||
const projected = meta.data.map((v, i) => ({
|
||
x: xAt(i),
|
||
y: v === null ? null : valueToY(v),
|
||
value: v
|
||
}));
|
||
coordByKey[meta.key] = projected;
|
||
if (!chartSeriesVisible.value[meta.key])
|
||
return;
|
||
const segments = [];
|
||
let cur = [];
|
||
projected.forEach((p) => {
|
||
if (p.y !== null)
|
||
cur.push(p);
|
||
else if (cur.length) {
|
||
segments.push(cur);
|
||
cur = [];
|
||
}
|
||
});
|
||
if (cur.length)
|
||
segments.push(cur);
|
||
segments.forEach((seg) => {
|
||
if (seg.length === 1) {
|
||
ctx.fillStyle = meta.color;
|
||
ctx.beginPath();
|
||
ctx.arc(seg[0].x, seg[0].y, 4, 0, Math.PI * 2);
|
||
ctx.fill();
|
||
return;
|
||
}
|
||
const drawPath = () => {
|
||
ctx.beginPath();
|
||
ctx.moveTo(seg[0].x, seg[0].y);
|
||
for (let i = 0; i < seg.length - 1; i++) {
|
||
const p0 = seg[i - 1] || seg[i];
|
||
const p1 = seg[i];
|
||
const p2 = seg[i + 1];
|
||
const p3 = seg[i + 2] || seg[i + 1];
|
||
const cp1x = p1.x + (p2.x - p0.x) / 6;
|
||
const cp1y = p1.y + (p2.y - p0.y) / 6;
|
||
const cp2x = p2.x - (p3.x - p1.x) / 6;
|
||
const cp2y = p2.y - (p3.y - p1.y) / 6;
|
||
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, p2.x, p2.y);
|
||
}
|
||
};
|
||
drawPath();
|
||
ctx.lineTo(seg[seg.length - 1].x, padding.top + ch);
|
||
ctx.lineTo(seg[0].x, padding.top + ch);
|
||
ctx.closePath();
|
||
const grad = ctx.createLinearGradient(0, padding.top, 0, padding.top + ch);
|
||
grad.addColorStop(0, meta.fillTop);
|
||
grad.addColorStop(1, meta.fillBottom);
|
||
ctx.fillStyle = grad;
|
||
ctx.fill();
|
||
drawPath();
|
||
ctx.strokeStyle = meta.color;
|
||
ctx.lineWidth = 2.4;
|
||
ctx.lineCap = "round";
|
||
ctx.lineJoin = "round";
|
||
ctx.stroke();
|
||
if (showDots) {
|
||
seg.forEach((p) => {
|
||
ctx.beginPath();
|
||
ctx.arc(p.x, p.y, 3, 0, Math.PI * 2);
|
||
ctx.fillStyle = "#ffffff";
|
||
ctx.fill();
|
||
ctx.strokeStyle = meta.color;
|
||
ctx.lineWidth = 1.8;
|
||
ctx.stroke();
|
||
});
|
||
}
|
||
});
|
||
let maxIdx = -1;
|
||
let maxVal = -Infinity;
|
||
projected.forEach((p, i) => {
|
||
if (p.value != null && p.value > maxVal) {
|
||
maxVal = p.value;
|
||
maxIdx = i;
|
||
}
|
||
});
|
||
if (maxIdx >= 0) {
|
||
const p = projected[maxIdx];
|
||
const isHigh = meta.highThreshold != null && p.value >= meta.highThreshold;
|
||
ctx.beginPath();
|
||
ctx.arc(p.x, p.y, 5, 0, Math.PI * 2);
|
||
ctx.fillStyle = isHigh ? "#dc2626" : meta.color;
|
||
ctx.fill();
|
||
ctx.strokeStyle = "#ffffff";
|
||
ctx.lineWidth = 2.5;
|
||
ctx.stroke();
|
||
const labelText = String(p.value);
|
||
ctx.font = "bold 12px sans-serif";
|
||
const textWidth = ctx.measureText(labelText).width;
|
||
const padX = 8;
|
||
const padY = 5;
|
||
const boxWidth = textWidth + padX * 2;
|
||
const boxHeight = 14 + padY * 2;
|
||
let labelX = p.x;
|
||
let labelAbove = true;
|
||
if (p.y - 12 - boxHeight - 4 < padding.top)
|
||
labelAbove = false;
|
||
let labelY = labelAbove ? p.y - 12 - boxHeight / 2 : p.y + 12 + boxHeight / 2;
|
||
if (labelX - boxWidth / 2 < padding.left + 2)
|
||
labelX = padding.left + boxWidth / 2 + 2;
|
||
if (labelX + boxWidth / 2 > padding.left + cw - 2)
|
||
labelX = padding.left + cw - boxWidth / 2 - 2;
|
||
ctx.fillStyle = isHigh ? "#dc2626" : meta.color;
|
||
ctx.fillRect(labelX - boxWidth / 2, labelY - boxHeight / 2, boxWidth, boxHeight);
|
||
ctx.fillStyle = "#ffffff";
|
||
ctx.textAlign = "center";
|
||
ctx.textBaseline = "middle";
|
||
ctx.fillText(labelText, labelX, labelY);
|
||
}
|
||
});
|
||
chartCoords = {
|
||
padding,
|
||
cw,
|
||
ch,
|
||
n,
|
||
fasting: coordByKey.fasting,
|
||
postprandial: coordByKey.postprandial
|
||
};
|
||
}
|
||
function toggleChartSeries(key) {
|
||
if (key !== "fasting" && key !== "postprandial")
|
||
return;
|
||
chartSeriesVisible.value[key] = !chartSeriesVisible.value[key];
|
||
hoverInfo.value = null;
|
||
scheduleChartRedraw();
|
||
}
|
||
function onChartTouch(e) {
|
||
if (!chartCoords || !canvasWidth)
|
||
return;
|
||
if (!chartDates.value.length)
|
||
return;
|
||
let touchX = 0;
|
||
let touchY = 0;
|
||
if (e && e.touches && e.touches[0]) {
|
||
touchX = e.touches[0].x ?? e.touches[0].clientX ?? 0;
|
||
touchY = e.touches[0].y ?? e.touches[0].clientY ?? 0;
|
||
}
|
||
const { padding, cw, n } = chartCoords;
|
||
if (touchX < padding.left || touchX > padding.left + cw) {
|
||
return;
|
||
}
|
||
const ratio = n <= 1 ? 0 : (touchX - padding.left) / cw;
|
||
let idx = Math.round(ratio * (n - 1));
|
||
if (idx < 0)
|
||
idx = 0;
|
||
if (idx > n - 1)
|
||
idx = n - 1;
|
||
const date = chartDates.value[idx];
|
||
const fp = chartSeriesVisible.value.fasting ? chartCoords.fasting[idx] : null;
|
||
const pp = chartSeriesVisible.value.postprandial ? chartCoords.postprandial[idx] : null;
|
||
const anchorX = (fp == null ? void 0 : fp.x) ?? (pp == null ? void 0 : pp.x) ?? padding.left + cw * (idx / Math.max(1, n - 1));
|
||
const left = Math.max(8, Math.min(canvasWidth - 130, anchorX - 60));
|
||
const top = Math.max(4, touchY - 70);
|
||
hoverInfo.value = {
|
||
date: date.slice(5),
|
||
fasting: (fp == null ? void 0 : fp.value) ?? null,
|
||
postprandial: (pp == null ? void 0 : pp.value) ?? null,
|
||
left,
|
||
top
|
||
};
|
||
if (hoverTimer)
|
||
clearTimeout(hoverTimer);
|
||
hoverTimer = setTimeout(() => {
|
||
hoverInfo.value = null;
|
||
}, 2500);
|
||
}
|
||
common_vendor.watch(rangeMode, () => {
|
||
scheduleChartRedraw();
|
||
});
|
||
function readUserContext() {
|
||
try {
|
||
const userData = common_vendor.index.getStorageSync("userData");
|
||
if (userData && userData.diagnosis) {
|
||
if (!patientId.value)
|
||
patientId.value = Number(userData.diagnosis.patient_id) || 0;
|
||
if (!diagnosisId.value)
|
||
diagnosisId.value = Number(userData.diagnosis.id) || 0;
|
||
if (!patientName.value)
|
||
patientName.value = userData.diagnosis.patient_name || "";
|
||
if (!age.value)
|
||
age.value = Number(userData.diagnosis.age) || 0;
|
||
if (!gender.value)
|
||
gender.value = Number(userData.diagnosis.gender) || 0;
|
||
}
|
||
} catch (e) {
|
||
}
|
||
}
|
||
async function bootstrap(options) {
|
||
options = options || {};
|
||
const inviteCode = String(options.invite_code || "").trim();
|
||
if (options.from === "share" && inviteCode) {
|
||
authChecking.value = false;
|
||
await bootstrapInviteViewer(inviteCode);
|
||
return;
|
||
}
|
||
isInviteViewer.value = false;
|
||
authChecking.value = true;
|
||
const passedDiagnosisId = Number(options.diagnosis_id || options.id || 0);
|
||
Number(options.patient_id || 0);
|
||
options.patient_name ? decodeURIComponent(String(options.patient_name)) : "";
|
||
Number(options.age) || 0;
|
||
Number(options.gender) || 0;
|
||
const loggedIn = await ensureLoggedIn();
|
||
if (!loggedIn || !hasAuthToken()) {
|
||
authChecking.value = false;
|
||
showUserToast("登录失败,请稍后重试");
|
||
return;
|
||
}
|
||
readUserContext();
|
||
const list = await fetchCardList();
|
||
if (Array.isArray(list) && list.length > 0) {
|
||
let target = null;
|
||
if (passedDiagnosisId) {
|
||
target = list.find((c) => Number(c.id) === Number(passedDiagnosisId));
|
||
}
|
||
if (!target)
|
||
target = list[0];
|
||
await applyCard(target);
|
||
} else {
|
||
diagnosisId.value = 0;
|
||
patientId.value = 0;
|
||
patientName.value = "";
|
||
age.value = 0;
|
||
gender.value = 0;
|
||
readUserMobile();
|
||
if (userMobile.value) {
|
||
await ensureDailyContextByPhone();
|
||
}
|
||
}
|
||
authChecking.value = false;
|
||
if (diagnosisId.value) {
|
||
await fetchAll();
|
||
}
|
||
}
|
||
common_vendor.onLoad((options) => {
|
||
bootstrap(options);
|
||
});
|
||
common_vendor.onShow(() => {
|
||
if (authChecking.value)
|
||
return;
|
||
common_vendor.nextTick$1(() => scheduleChartRedraw());
|
||
});
|
||
common_vendor.onPullDownRefresh(async () => {
|
||
if (isInviteViewer.value) {
|
||
const code = invitePreview.value.invite_code;
|
||
if (code)
|
||
await bootstrapInviteViewer(code);
|
||
} else if (await ensureLoggedIn()) {
|
||
await fetchAll();
|
||
}
|
||
common_vendor.index.stopPullDownRefresh();
|
||
});
|
||
common_vendor.onHide(() => {
|
||
ttsStop();
|
||
});
|
||
common_vendor.onUnload(() => {
|
||
ttsStop();
|
||
});
|
||
const isInviteViewer = common_vendor.ref(false);
|
||
const inviteLoading = common_vendor.ref(false);
|
||
const inviteError = common_vendor.ref("");
|
||
const invitePreview = common_vendor.ref({});
|
||
const inviteLiking = common_vendor.ref(false);
|
||
const inviteLikeNickname = common_vendor.ref("家人");
|
||
const inviteHeartBurst = common_vendor.ref(false);
|
||
const familyNicknameOptions = ["家人", "亲友", "老伴", "子女"];
|
||
function hapticLight() {
|
||
try {
|
||
common_vendor.index.vibrateShort({ type: "light" });
|
||
} catch (e) {
|
||
}
|
||
}
|
||
function getViewerKey() {
|
||
try {
|
||
let key = common_vendor.index.getStorageSync(VIEWER_KEY_STORAGE);
|
||
if (!key) {
|
||
key = `v_${Date.now()}_${Math.random().toString(36).slice(2, 12)}`;
|
||
common_vendor.index.setStorageSync(VIEWER_KEY_STORAGE, key);
|
||
}
|
||
return String(key).slice(0, 64);
|
||
} catch (e) {
|
||
return `v_${Date.now()}`;
|
||
}
|
||
}
|
||
const inviteTreeLevel = common_vendor.computed(() => Number(invitePreview.value.tree_level) || 0);
|
||
const inviteDailyRecords = common_vendor.computed(() => {
|
||
const list = invitePreview.value.daily_records;
|
||
return Array.isArray(list) ? list : [];
|
||
});
|
||
function formatInviteSugar(v) {
|
||
if (v == null || v === "")
|
||
return "—";
|
||
return String(v);
|
||
}
|
||
const INVITE_TREE_WHISPERS = [
|
||
"Ta 正在努力控糖,您的鼓励很重要。",
|
||
"好习惯比完美数值更珍贵,一起加油。",
|
||
"每天记一笔,就是在照顾未来的自己。",
|
||
"点赞一下,让 Ta 知道家人在身边。"
|
||
];
|
||
function onInviteTreeWhisper() {
|
||
const line = INVITE_TREE_WHISPERS[Math.floor(Math.random() * INVITE_TREE_WHISPERS.length)];
|
||
showUserToast(line, { duration: 2800 });
|
||
hapticLight();
|
||
}
|
||
async function bootstrapInviteViewer(inviteCode) {
|
||
isInviteViewer.value = true;
|
||
inviteLoading.value = true;
|
||
inviteError.value = "";
|
||
invitePreview.value = {};
|
||
inviteHeartBurst.value = false;
|
||
try {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/tcm/dailySharePreview",
|
||
method: "GET",
|
||
data: {
|
||
invite_code: inviteCode,
|
||
viewer_key: getViewerKey()
|
||
}
|
||
}, false);
|
||
if (res && res.code === 1 && res.data) {
|
||
invitePreview.value = res.data;
|
||
} else {
|
||
inviteError.value = formatUserMessage(res && res.msg, "邀请码无效或已过期");
|
||
}
|
||
} catch (e) {
|
||
inviteError.value = "加载失败,请稍后再试";
|
||
} finally {
|
||
inviteLoading.value = false;
|
||
}
|
||
}
|
||
async function onFamilyLike() {
|
||
const code = invitePreview.value.invite_code;
|
||
if (!code || inviteLiking.value)
|
||
return;
|
||
if (invitePreview.value.liked_by_me) {
|
||
showUserToast("您今天已经点过赞啦");
|
||
return;
|
||
}
|
||
inviteLiking.value = true;
|
||
try {
|
||
const res = await proxy.apiUrl({
|
||
url: "/api/tcm/dailyFamilyLike",
|
||
method: "POST",
|
||
data: {
|
||
invite_code: code,
|
||
viewer_key: getViewerKey(),
|
||
nickname: inviteLikeNickname.value
|
||
}
|
||
}, false);
|
||
if (res && res.code === 1 && res.data) {
|
||
const data = res.data;
|
||
const alreadyLiked = !!data.already_liked;
|
||
invitePreview.value = {
|
||
...invitePreview.value,
|
||
like_count: Number(data.like_count) || 0,
|
||
liked_by_me: true
|
||
};
|
||
if (alreadyLiked) {
|
||
showUserToast(data.praise_message || "您今天已经点过赞啦");
|
||
return;
|
||
}
|
||
inviteHeartBurst.value = true;
|
||
setTimeout(() => {
|
||
inviteHeartBurst.value = false;
|
||
}, 900);
|
||
hapticLight();
|
||
triggerCelebrate("鼓励已送达", data.praise_message || "谢谢您的点赞");
|
||
} else {
|
||
showUserToast(res && res.msg || "点赞失败");
|
||
}
|
||
} catch (e) {
|
||
showUserToast("点赞失败,请稍后再试");
|
||
} finally {
|
||
inviteLiking.value = false;
|
||
}
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return common_vendor.e({
|
||
a: isInviteViewer.value
|
||
}, isInviteViewer.value ? common_vendor.e({
|
||
b: common_vendor.p({
|
||
name: "view",
|
||
size: "md",
|
||
color: "#FFFFFF"
|
||
}),
|
||
c: common_vendor.t(invitePreview.value.viewer_notice || "近7日稳糖记录"),
|
||
d: common_vendor.t(invitePreview.value.expires_hint || "邀请码仅今日有效"),
|
||
e: invitePreview.value.patient_label
|
||
}, invitePreview.value.patient_label ? {
|
||
f: common_vendor.p({
|
||
name: "users",
|
||
size: "sm",
|
||
color: "#A5F3FC"
|
||
}),
|
||
g: common_vendor.t(invitePreview.value.patient_label)
|
||
} : {}, {
|
||
h: inviteLoading.value
|
||
}, inviteLoading.value ? {} : invitePreview.value.invite_code ? common_vendor.e({
|
||
j: common_vendor.p({
|
||
name: "ticket",
|
||
size: "md",
|
||
color: "#204E2B"
|
||
}),
|
||
k: common_vendor.t(invitePreview.value.invite_code),
|
||
l: common_vendor.p({
|
||
level: inviteTreeLevel.value,
|
||
size: "md"
|
||
}),
|
||
m: common_vendor.o(onInviteTreeWhisper, "87"),
|
||
n: common_vendor.t(invitePreview.value.tree_title || "控糖树"),
|
||
o: common_vendor.t(invitePreview.value.tree_desc || ""),
|
||
p: common_vendor.t(invitePreview.value.week_label || ""),
|
||
q: common_vendor.p({
|
||
name: "calendar",
|
||
size: "sm",
|
||
color: "#204E2B"
|
||
}),
|
||
r: common_vendor.t(invitePreview.value.record_days),
|
||
s: common_vendor.p({
|
||
name: "check-circle",
|
||
size: "sm",
|
||
color: "#386641"
|
||
}),
|
||
t: common_vendor.t(invitePreview.value.complete_days),
|
||
v: common_vendor.p({
|
||
name: "flame",
|
||
size: "sm",
|
||
color: "#EA580C"
|
||
}),
|
||
w: common_vendor.t(invitePreview.value.streak_days),
|
||
x: invitePreview.value.quote
|
||
}, invitePreview.value.quote ? {
|
||
y: common_vendor.t(invitePreview.value.quote)
|
||
} : {}, {
|
||
z: common_vendor.p({
|
||
name: "glucose",
|
||
size: "md",
|
||
color: "#386641"
|
||
}),
|
||
A: !inviteDailyRecords.value.length
|
||
}, !inviteDailyRecords.value.length ? {
|
||
B: common_vendor.p({
|
||
name: "minus",
|
||
size: "lg",
|
||
color: "#94A3B8"
|
||
})
|
||
} : {
|
||
C: common_vendor.f(inviteDailyRecords.value, (day, idx, i0) => {
|
||
return common_vendor.e({
|
||
a: day.has_record ? 1 : "",
|
||
b: idx < inviteDailyRecords.value.length - 1
|
||
}, idx < inviteDailyRecords.value.length - 1 ? {} : {}, {
|
||
c: common_vendor.t(day.date_label),
|
||
d: common_vendor.t(day.weekday),
|
||
e: day.has_record
|
||
}, day.has_record ? common_vendor.e({
|
||
f: common_vendor.t(formatInviteSugar(day.fasting)),
|
||
g: day.fasting_high ? 1 : "",
|
||
h: day.fasting != null
|
||
}, day.fasting != null ? {} : {}, {
|
||
i: day.fasting_high
|
||
}, day.fasting_high ? {
|
||
j: "612eeee9-9-" + i0,
|
||
k: common_vendor.p({
|
||
name: "alert-triangle",
|
||
size: "sm",
|
||
color: "#DC2626"
|
||
})
|
||
} : {}, {
|
||
l: common_vendor.t(formatInviteSugar(day.postprandial)),
|
||
m: day.postprandial_high ? 1 : "",
|
||
n: day.postprandial != null
|
||
}, day.postprandial != null ? {} : {}, {
|
||
o: day.postprandial_high
|
||
}, day.postprandial_high ? {
|
||
p: "612eeee9-10-" + i0,
|
||
q: common_vendor.p({
|
||
name: "alert-triangle",
|
||
size: "sm",
|
||
color: "#DC2626"
|
||
})
|
||
} : {}, {
|
||
r: day.bp_text
|
||
}, day.bp_text ? common_vendor.e({
|
||
s: common_vendor.t(day.bp_text),
|
||
t: day.bp_high ? 1 : "",
|
||
v: day.bp_high
|
||
}, day.bp_high ? {
|
||
w: "612eeee9-11-" + i0,
|
||
x: common_vendor.p({
|
||
name: "alert-triangle",
|
||
size: "sm",
|
||
color: "#DC2626"
|
||
})
|
||
} : {}) : {}) : {
|
||
y: "612eeee9-12-" + i0,
|
||
z: common_vendor.p({
|
||
name: "minus",
|
||
size: "sm",
|
||
color: "#94A3B8"
|
||
})
|
||
}, {
|
||
A: day.date,
|
||
B: !day.has_record ? 1 : "",
|
||
C: idx === inviteDailyRecords.value.length - 1 ? 1 : ""
|
||
});
|
||
})
|
||
}, {
|
||
D: common_vendor.p({
|
||
name: "heart",
|
||
size: "md",
|
||
color: "#386641"
|
||
}),
|
||
E: common_vendor.t(invitePreview.value.like_count || 0),
|
||
F: common_vendor.f(familyNicknameOptions, (n, k0, i0) => {
|
||
return {
|
||
a: common_vendor.t(n),
|
||
b: n,
|
||
c: inviteLikeNickname.value === n ? 1 : "",
|
||
d: common_vendor.o(($event) => inviteLikeNickname.value = n, n)
|
||
};
|
||
}),
|
||
G: !invitePreview.value.liked_by_me
|
||
}, !invitePreview.value.liked_by_me ? {
|
||
H: common_vendor.p({
|
||
name: "heart",
|
||
size: "md",
|
||
color: "#FFFFFF"
|
||
})
|
||
} : {}, {
|
||
I: common_vendor.t(invitePreview.value.liked_by_me ? "今日已点赞,谢谢您的鼓励" : "送 Ta 一份鼓励"),
|
||
J: invitePreview.value.liked_by_me ? 1 : "",
|
||
K: inviteLiking.value ? 1 : "",
|
||
L: inviteHeartBurst.value ? 1 : "",
|
||
M: common_vendor.o(onFamilyLike, "5e"),
|
||
N: common_vendor.p({
|
||
name: "activity",
|
||
size: "sm",
|
||
color: "#64748B"
|
||
})
|
||
}) : {
|
||
O: common_vendor.p({
|
||
name: "alert-triangle",
|
||
size: "xl",
|
||
color: "#DC2626"
|
||
}),
|
||
P: common_vendor.t(inviteError.value || "邀请码无效或已过期")
|
||
}, {
|
||
i: invitePreview.value.invite_code
|
||
}) : {}, {
|
||
Q: authChecking.value && !isInviteViewer.value
|
||
}, authChecking.value && !isInviteViewer.value ? {} : {}, {
|
||
R: !isInviteViewer.value && !authChecking.value
|
||
}, !isInviteViewer.value && !authChecking.value ? common_vendor.e({
|
||
S: common_vendor.t(timeGreetingMeta.value.text),
|
||
T: common_vendor.t(patientName.value || "您好"),
|
||
U: common_vendor.t(todayChecked.value ? "今日血糖已记录" : "今日还没记血糖"),
|
||
V: common_vendor.n(todayChecked.value ? "is-done" : "is-pending"),
|
||
W: cards.value.length > 1
|
||
}, cards.value.length > 1 ? {
|
||
X: common_vendor.f(cards.value, (card, k0, i0) => {
|
||
return {
|
||
a: common_vendor.t(card.patient_name || "就诊卡"),
|
||
b: card.id,
|
||
c: Number(card.id) === Number(diagnosisId.value) ? 1 : "",
|
||
d: common_vendor.o(($event) => onSelectCard(card), card.id)
|
||
};
|
||
})
|
||
} : {}, {
|
||
Y: common_vendor.p({
|
||
name: "plus",
|
||
size: "lg",
|
||
color: "#FFFFFF"
|
||
}),
|
||
Z: common_vendor.o(($event) => openInputForm(), "0b"),
|
||
aa: common_vendor.p({
|
||
name: ttsSpeaking.value ? "pause" : "volume",
|
||
size: "md",
|
||
color: "#204E2B"
|
||
}),
|
||
ab: common_vendor.t(ttsSpeaking.value ? "停止朗读" : "朗读血糖"),
|
||
ac: ttsSpeaking.value ? 1 : "",
|
||
ad: !ttsEnabled.value ? 1 : "",
|
||
ae: common_vendor.o(($event) => ttsSpeaking.value ? ttsStop() : speakLatestSummary(), "0e"),
|
||
af: diagnosisId.value
|
||
}, diagnosisId.value ? common_vendor.e({
|
||
ag: common_vendor.t(rangeText.value),
|
||
ah: !chartSeriesVisible.value.fasting ? 1 : "",
|
||
ai: common_vendor.o(($event) => toggleChartSeries("fasting"), "91"),
|
||
aj: !chartSeriesVisible.value.postprandial ? 1 : "",
|
||
ak: common_vendor.o(($event) => toggleChartSeries("postprandial"), "df"),
|
||
al: bloodHasData.value && bloodHighDayCount.value > 0
|
||
}, bloodHasData.value && bloodHighDayCount.value > 0 ? {
|
||
am: common_vendor.t(bloodHighDayCount.value),
|
||
an: common_vendor.t(bloodNormalDayCount.value),
|
||
ao: common_vendor.t(bloodRecordDayCount.value)
|
||
} : {}, {
|
||
ap: !recordOverlayOpen.value
|
||
}, !recordOverlayOpen.value ? {
|
||
aq: common_vendor.o(onChartTouch, "28"),
|
||
ar: common_vendor.o(onChartTouch, "83")
|
||
} : {}, {
|
||
as: recordOverlayOpen.value
|
||
}, recordOverlayOpen.value ? {} : {}, {
|
||
at: !bloodHasData.value && !loading.value && !recordOverlayOpen.value
|
||
}, !bloodHasData.value && !loading.value && !recordOverlayOpen.value ? {} : {}, {
|
||
av: hoverInfo.value && !recordOverlayOpen.value
|
||
}, hoverInfo.value && !recordOverlayOpen.value ? common_vendor.e({
|
||
aw: common_vendor.t(hoverInfo.value.date),
|
||
ax: hoverInfo.value.fasting != null
|
||
}, hoverInfo.value.fasting != null ? {
|
||
ay: common_vendor.t(hoverInfo.value.fasting)
|
||
} : {}, {
|
||
az: hoverInfo.value.postprandial != null
|
||
}, hoverInfo.value.postprandial != null ? {
|
||
aA: common_vendor.t(hoverInfo.value.postprandial)
|
||
} : {}, {
|
||
aB: hoverInfo.value.left + "px",
|
||
aC: hoverInfo.value.top + "px"
|
||
}) : {}, {
|
||
aD: common_vendor.f(rangeOptions, (opt, k0, i0) => {
|
||
return {
|
||
a: common_vendor.t(opt.label),
|
||
b: opt.value,
|
||
c: rangeMode.value === opt.value ? 1 : "",
|
||
d: common_vendor.o(($event) => onChangeRange(opt.value), opt.value)
|
||
};
|
||
})
|
||
}) : {}, {
|
||
aE: common_vendor.t(elderFasting.value.label),
|
||
aF: common_vendor.t(elderFasting.value.value),
|
||
aG: elderFasting.value.value !== "—"
|
||
}, elderFasting.value.value !== "—" ? {} : {}, {
|
||
aH: elderFasting.value.isHigh
|
||
}, elderFasting.value.isHigh ? {} : {}, {
|
||
aI: elderFasting.value.isHigh ? 1 : "",
|
||
aJ: common_vendor.t(elderPostprandial.value.label),
|
||
aK: common_vendor.t(elderPostprandial.value.value),
|
||
aL: elderPostprandial.value.value !== "—"
|
||
}, elderPostprandial.value.value !== "—" ? {} : {}, {
|
||
aM: elderPostprandial.value.isHigh
|
||
}, elderPostprandial.value.isHigh ? {} : {}, {
|
||
aN: elderPostprandial.value.isHigh ? 1 : "",
|
||
aO: common_vendor.o(goMorePage, "ee"),
|
||
aP: diagnosisId.value
|
||
}, diagnosisId.value ? common_vendor.e({
|
||
aQ: common_vendor.p({
|
||
name: "sparkles",
|
||
size: "md",
|
||
color: "#ffffff"
|
||
}),
|
||
aR: common_vendor.unref(dietAiLoading) ? 1 : "",
|
||
aS: common_vendor.p({
|
||
name: "refresh",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
}),
|
||
aT: common_vendor.t(common_vendor.unref(dietAiLoading) ? "生成中" : "换一换"),
|
||
aU: common_vendor.unref(dietAiLoading) ? 1 : "",
|
||
aV: common_vendor.o((...args) => common_vendor.unref(refreshDietAiRecommend) && common_vendor.unref(refreshDietAiRecommend)(...args), "8d"),
|
||
aW: common_vendor.unref(dietAiLoading) && !common_vendor.unref(hasDietAiMealContent) && !common_vendor.unref(dietAiStreaming) && !common_vendor.unref(dietAiReplacing)
|
||
}, common_vendor.unref(dietAiLoading) && !common_vendor.unref(hasDietAiMealContent) && !common_vendor.unref(dietAiStreaming) && !common_vendor.unref(dietAiReplacing) ? {
|
||
aX: common_vendor.f(3, (n, k0, i0) => {
|
||
return {
|
||
a: "sk-" + n
|
||
};
|
||
})
|
||
} : common_vendor.e({
|
||
aY: common_vendor.unref(dietAiStreaming)
|
||
}, common_vendor.unref(dietAiStreaming) ? {} : {}, {
|
||
aZ: common_vendor.p({
|
||
name: "sun",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
}),
|
||
ba: common_vendor.t(common_vendor.unref(dietAiRecommend).breakfast || (common_vendor.unref(dietAiLoading) ? "…" : "—")),
|
||
bb: common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "breakfast"
|
||
}, common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "breakfast" ? {} : {}, {
|
||
bc: common_vendor.unref(dietAiRecommend).drinks || common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "drinks"
|
||
}, common_vendor.unref(dietAiRecommend).drinks || common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "drinks" ? common_vendor.e({
|
||
bd: common_vendor.p({
|
||
name: "droplet",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
}),
|
||
be: common_vendor.t(common_vendor.unref(dietAiRecommend).drinks || "…"),
|
||
bf: common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "drinks"
|
||
}, common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "drinks" ? {} : {}) : {}, {
|
||
bg: common_vendor.p({
|
||
name: "sunset",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
}),
|
||
bh: common_vendor.t(common_vendor.unref(dietAiRecommend).lunch || (common_vendor.unref(dietAiLoading) ? "…" : "—")),
|
||
bi: common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "lunch"
|
||
}, common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "lunch" ? {} : {}, {
|
||
bj: common_vendor.p({
|
||
name: "moon",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
}),
|
||
bk: common_vendor.t(common_vendor.unref(dietAiRecommend).dinner || (common_vendor.unref(dietAiLoading) ? "…" : "—")),
|
||
bl: common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "dinner"
|
||
}, common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "dinner" ? {} : {}, {
|
||
bm: common_vendor.unref(dietAiRecommend).tips || common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "tips"
|
||
}, common_vendor.unref(dietAiRecommend).tips || common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "tips" ? common_vendor.e({
|
||
bn: common_vendor.p({
|
||
name: "info",
|
||
size: "sm",
|
||
color: "#386641"
|
||
}),
|
||
bo: common_vendor.t(common_vendor.unref(dietAiRecommend).tips || "…"),
|
||
bp: common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "tips"
|
||
}, common_vendor.unref(dietAiLoading) && common_vendor.unref(dietAiStreamField) === "tips" ? {} : {}) : {}, {
|
||
bq: common_vendor.unref(dietAiRecommend).avoid && common_vendor.unref(dietAiRecommend).avoid.length
|
||
}, common_vendor.unref(dietAiRecommend).avoid && common_vendor.unref(dietAiRecommend).avoid.length ? {
|
||
br: common_vendor.p({
|
||
name: "alert-triangle",
|
||
size: "sm",
|
||
color: "#b91c1c"
|
||
}),
|
||
bs: common_vendor.f(common_vendor.unref(dietAiRecommend).avoid, (item, idx, i0) => {
|
||
return {
|
||
a: common_vendor.t(item),
|
||
b: "avoid-" + idx
|
||
};
|
||
})
|
||
} : {}, {
|
||
bt: !common_vendor.unref(dietAiLoading)
|
||
}, !common_vendor.unref(dietAiLoading) ? {
|
||
bv: common_vendor.o((...args) => common_vendor.unref(applyDietAiToForm) && common_vendor.unref(applyDietAiToForm)(...args), "df"),
|
||
bw: common_vendor.o((...args) => common_vendor.unref(openDietForm) && common_vendor.unref(openDietForm)(...args), "1f")
|
||
} : {}, {
|
||
bx: common_vendor.unref(dietAiStreaming) ? 1 : ""
|
||
}), {
|
||
by: dietExercise.value
|
||
}, dietExercise.value ? common_vendor.e({
|
||
bz: common_vendor.p({
|
||
name: "activity",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
}),
|
||
bA: common_vendor.t(dietExercise.value.level_label),
|
||
bB: common_vendor.n("lv-" + dietExercise.value.level),
|
||
bC: dietExercise.value.headline
|
||
}, dietExercise.value.headline ? {
|
||
bD: common_vendor.t(dietExercise.value.headline)
|
||
} : {}, {
|
||
bE: common_vendor.f(dietExercise.value.items, (it, idx, i0) => {
|
||
return {
|
||
a: common_vendor.t(idx + 1),
|
||
b: common_vendor.t(it),
|
||
c: "ex-" + idx
|
||
};
|
||
}),
|
||
bF: dietExercise.value.intensity
|
||
}, dietExercise.value.intensity ? {
|
||
bG: common_vendor.p({
|
||
name: "flame",
|
||
size: "sm",
|
||
color: "#d97706"
|
||
}),
|
||
bH: common_vendor.t(dietExercise.value.intensity)
|
||
} : {}, {
|
||
bI: dietExercise.value.note
|
||
}, dietExercise.value.note ? {
|
||
bJ: common_vendor.t(dietExercise.value.note)
|
||
} : {}, {
|
||
bK: common_vendor.n("lv-" + dietExercise.value.level)
|
||
}) : {}, {
|
||
bL: common_vendor.unref(dietAiAskText),
|
||
bM: common_vendor.o((...args) => common_vendor.unref(onDietAiAskInput) && common_vendor.unref(onDietAiAskInput)(...args), "95"),
|
||
bN: common_vendor.o((...args) => common_vendor.unref(askDietAiFood) && common_vendor.unref(askDietAiFood)(...args), "4b"),
|
||
bO: !common_vendor.unref(dietAiAsking)
|
||
}, !common_vendor.unref(dietAiAsking) ? {
|
||
bP: common_vendor.p({
|
||
name: "sparkles",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
})
|
||
} : {}, {
|
||
bQ: common_vendor.t(common_vendor.unref(dietAiAsking) ? "…" : "问 AI"),
|
||
bR: common_vendor.unref(dietAiAsking) ? 1 : "",
|
||
bS: common_vendor.o((...args) => common_vendor.unref(askDietAiFood) && common_vendor.unref(askDietAiFood)(...args), "e7"),
|
||
bT: common_vendor.unref(dietAiAsking) || common_vendor.unref(dietAiAskResult).advice
|
||
}, common_vendor.unref(dietAiAsking) || common_vendor.unref(dietAiAskResult).advice ? common_vendor.e({
|
||
bU: common_vendor.unref(dietAiAskResult).level_label
|
||
}, common_vendor.unref(dietAiAskResult).level_label ? {
|
||
bV: common_vendor.t(common_vendor.unref(dietAiAskResult).level_label),
|
||
bW: common_vendor.n("lv-" + (common_vendor.unref(dietAiAskResult).level || "unknown"))
|
||
} : {}, {
|
||
bX: common_vendor.t(common_vendor.unref(dietAiAskResult).advice || (common_vendor.unref(dietAiAsking) ? "正在想…" : "")),
|
||
bY: common_vendor.unref(dietAiAsking)
|
||
}, common_vendor.unref(dietAiAsking) ? {} : {}, {
|
||
bZ: common_vendor.unref(dietAiAskResult).portion
|
||
}, common_vendor.unref(dietAiAskResult).portion ? {
|
||
ca: common_vendor.t(common_vendor.unref(dietAiAskResult).portion)
|
||
} : {}, {
|
||
cb: common_vendor.n("lv-" + (common_vendor.unref(dietAiAskResult).level || "unknown"))
|
||
}) : {}, {
|
||
cc: hasDietAnalysis.value
|
||
}, hasDietAnalysis.value ? {
|
||
cd: common_vendor.p({
|
||
name: "activity",
|
||
size: "sm",
|
||
color: "#386641"
|
||
}),
|
||
ce: common_vendor.f(dietAnalysisList.value, (s, i, i0) => {
|
||
return common_vendor.e({
|
||
a: common_vendor.t(s.label),
|
||
b: s.record_days > 0
|
||
}, s.record_days > 0 ? {
|
||
c: common_vendor.t(s.compliance),
|
||
d: common_vendor.n(dietRateClass(s.compliance)),
|
||
e: common_vendor.t(s.high_days),
|
||
f: s.high_days > 0 ? 1 : "",
|
||
g: common_vendor.t(dietAvgText(s.fasting_avg)),
|
||
h: common_vendor.t(dietAvgText(s.postprandial_avg)),
|
||
i: common_vendor.t(s.record_days)
|
||
} : {
|
||
j: "612eeee9-31-" + i0,
|
||
k: common_vendor.p({
|
||
name: "minus",
|
||
size: "sm",
|
||
color: "#94A3B8"
|
||
})
|
||
}, {
|
||
l: "an-" + i
|
||
});
|
||
})
|
||
} : {}, {
|
||
cf: common_vendor.unref(dietAiRecommend).rules_summary || common_vendor.unref(dietAiRecommend).disclaimer
|
||
}, common_vendor.unref(dietAiRecommend).rules_summary || common_vendor.unref(dietAiRecommend).disclaimer ? common_vendor.e({
|
||
cg: common_vendor.unref(dietAiRecommend).rules_summary
|
||
}, common_vendor.unref(dietAiRecommend).rules_summary ? {
|
||
ch: common_vendor.t(common_vendor.unref(dietAiRecommend).rules_summary)
|
||
} : {}, {
|
||
ci: common_vendor.unref(dietAiRecommend).disclaimer
|
||
}, common_vendor.unref(dietAiRecommend).disclaimer ? {
|
||
cj: common_vendor.t(common_vendor.unref(dietAiRecommend).disclaimer)
|
||
} : {}) : {}) : {}, {
|
||
ck: phoneGateVisible.value
|
||
}, phoneGateVisible.value ? {
|
||
cl: common_vendor.o(closePhoneGate, "fe"),
|
||
cm: phoneGateSex.value === 1 ? 1 : "",
|
||
cn: common_vendor.o(($event) => phoneGateSex.value = 1, "2b"),
|
||
co: phoneGateSex.value === 2 ? 1 : "",
|
||
cp: common_vendor.o(($event) => phoneGateSex.value = 2, "aa"),
|
||
cq: phoneBinding.value,
|
||
cr: phoneBinding.value || !phoneGateSex.value,
|
||
cs: common_vendor.o(onPhoneGateAuthorize, "ef"),
|
||
ct: common_vendor.o(() => {
|
||
}, "f6"),
|
||
cv: common_vendor.o(closePhoneGate, "8a")
|
||
} : {}, {
|
||
cw: inputForm.value.visible
|
||
}, inputForm.value.visible ? common_vendor.e({
|
||
cx: common_vendor.t(inputForm.value.id ? "修改今日血糖" : "录入今日血糖"),
|
||
cy: common_vendor.t(todayText.value),
|
||
cz: common_vendor.t(patientName.value || "本人"),
|
||
cA: common_vendor.o(closeInputForm, "5d"),
|
||
cB: inputForm.value.loading
|
||
}, inputForm.value.loading ? {} : {
|
||
cC: inputForm.value.fasting_blood_sugar,
|
||
cD: common_vendor.o(($event) => onInputField("fasting_blood_sugar", $event), "0e"),
|
||
cE: inputForm.value.postprandial_blood_sugar,
|
||
cF: common_vendor.o(($event) => onInputField("postprandial_blood_sugar", $event), "7e"),
|
||
cG: inputForm.value.other_blood_sugar,
|
||
cH: common_vendor.o(($event) => onInputField("other_blood_sugar", $event), "a1"),
|
||
cI: inputForm.value.remark,
|
||
cJ: common_vendor.o(($event) => onInputField("remark", $event), "bd")
|
||
}, {
|
||
cK: inputForm.value.id
|
||
}, inputForm.value.id ? {
|
||
cL: inputForm.value.submitting ? 1 : "",
|
||
cM: common_vendor.o(deleteInputRecord, "d3")
|
||
} : {}, {
|
||
cN: common_vendor.t(inputForm.value.submitting ? "提交中…" : inputForm.value.id ? "保存修改" : "提交录入"),
|
||
cO: inputForm.value.submitting || inputForm.value.loading ? 1 : "",
|
||
cP: common_vendor.o(submitInputForm, "ec"),
|
||
cQ: common_vendor.o(() => {
|
||
}, "c3"),
|
||
cR: common_vendor.o(closeInputForm, "b5")
|
||
}) : {}) : {}, {
|
||
cS: isInviteViewer.value ? 1 : ""
|
||
});
|
||
};
|
||
}
|
||
};
|
||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-612eeee9"]]);
|
||
_sfc_main.__runtimeHooks = 2;
|
||
wx.createPage(MiniProgramPage);
|
||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/tongji/pages/index.js.map
|