diff --git a/uniapp/youjiala/src/components/family-tree-home/family-tree-home.vue b/uniapp/youjiala/src/components/family-tree-home/family-tree-home.vue
index c7379dd..0fa13db 100644
--- a/uniapp/youjiala/src/components/family-tree-home/family-tree-home.vue
+++ b/uniapp/youjiala/src/components/family-tree-home/family-tree-home.vue
@@ -17,7 +17,7 @@ import { StorageUsageData } from "@/data/auto/storageUsageData";
import { useLocale } from "uview-pro";
import { computed, onMounted, ref } from "vue";
import { brandGlyph } from "@/common/brand";
-import { buildChunkFileName, uploadFile } from "@/common/http.interceptor";
+import { buildChunkFileName, requestBuffer, uploadFile } from "@/common/http.interceptor";
import { userTypeGlyph, userTypePillBg } from "@/common/userTypeIcons";
import { useIdCardVerify, useThemeGradient, useThemeTokens } from "@/composables";
import { useArticles } from "@/composables/useArticles";
@@ -40,6 +40,7 @@ import dmsFileService from "@/service/master/dmsFileService";
import { useLoginProfileStore } from "@/stores";
import { pageUrl } from "@/router/routes";
import { chooseFiles } from "@/utils/chooseFiles";
+import { saveFileBytes } from "@/utils/dmsBytes";
import { absoluteFileUrl, backupFileUrl } from "@/utils/fileUrl";
/** ready:组件挂载完成通知(时序口径见文件底部 onMounted 注释) */
@@ -128,12 +129,42 @@ const storageBarWidth = computed(() => {
const userTypeIcon = computed(() => userTypeGlyph(currentType.value));
const userTypeBg = computed(() => userTypePillBg(currentType.value));
/** 网盘存储卡图标:内联云形 SVG(同 treeGlyph 套路),绿描边置于柔光圆内(存储卡为浅色渐变描边底) */
-const cloudGlyph = `data:image/svg+xml,${encodeURIComponent([
+const cloudSvg = [
"",
-].join(""))}`;
+].join("");
+const cloudGlyph = `data:image/svg+xml,${encodeURIComponent(cloudSvg)}`;
+
+/** 仅 H5 的「下载 App」图标:内联下箭头 SVG(绿描边,放在「网盘存储空间」标题旁),点击从 /FileServer 下载 youjiala.apk */
+const downloadSvg = [
+ "",
+].join("");
+const downloadGlyph = `data:image/svg+xml,${encodeURIComponent(downloadSvg)}`;
+
+// #ifdef H5
+/** H5 下载 App 安装包:复用网盘 file 页同一条下载链——requestBuffer 按当前线路取字节
+ * (后端报错回的是 JSON,按 content-type 转成错误提示,不会跳错误页),saveFileBytes 走 blob 落盘 */
+async function onDownloadApp(): Promise {
+ uni.showLoading({ title: t("storage.downloadingApp"), mask: true });
+ try {
+ const bytes = await requestBuffer({ url: "/FileServer/youjiala.apk", method: "GET" });
+ await saveFileBytes({ bytes, name: "youjiala.apk" });
+ uni.showToast({ title: t("storage.downloadStarted"), icon: "none" });
+ }
+ catch {
+ // requestBuffer 内部已 notifyError 弹示失败原因,这里只收尾
+ }
+ finally {
+ uni.hideLoading();
+ }
+}
+// #endif
/** 未认证底部弹层:单击「未认证」徽标从底部弹出身份证认证,复用 useIdCardVerify(与身份验证页同一套流程) */
const idPopup = ref(false);
@@ -1625,9 +1656,14 @@ defineExpose({
{{ t("storage.title") }}
+
+
+
+
+
{{ storagePercentText
- }}
+ }}
{{ articlesApi.plainText(row.Brief, 100) || t("article.noBrief")
- }}
+ }}
@@ -1786,7 +1822,7 @@ defineExpose({
{{ t("FamilyTreePage.managerTag")
- }}
+ }}
@@ -1893,7 +1929,7 @@ defineExpose({
{{ t("FamilyTreePage.currentPerson")
- }}
+ }}
@@ -1908,7 +1944,7 @@ defineExpose({
{{ personChipText(currentPerson)
- }}
+ }}
@@ -1951,12 +1987,12 @@ defineExpose({
{{ t("FamilyTreePage.spouseTitle")
- }}{{ spouseMaps.length }}
+ }}{{ spouseMaps.length }}
{{ t("FamilyTreePage.addSpouse") }}
{{ t("FamilyTreePage.spouseEmpty")
- }}
+ }}
@@ -1992,13 +2028,13 @@ defineExpose({
{{ t("FamilyTreePage.childTitle")
- }}{{ childMaps.length }}
+ }}{{ childMaps.length }}
{{ t("FamilyTreePage.addChildBtn") }}
{{ t("FamilyTreePage.childEmpty")
- }}
+ }}
@@ -2038,7 +2074,7 @@ defineExpose({
{{ t("FamilyTreePage.permPending")
- }}{{ pendingPermissions.length }}
+ }}{{ pendingPermissions.length }}
{{ record.UserLocalName ||
@@ -2062,10 +2098,10 @@ defineExpose({
{{ t("FamilyTreePage.permManager")
- }}{{ managerPermissions.length }}
+ }}{{ managerPermissions.length }}
{{ t("FamilyTreePage.permEmpty")
- }}
+ }}
{{ record.UserLocalName ||
record.UserName
@@ -2300,7 +2336,7 @@ defineExpose({
{{ record.SpouseSurname }}{{ record.SpouseGenealogyName }}
{{ genderText(personGender(record.SpouseId, record.Gender))
- }}
+ }}
@@ -2337,7 +2373,7 @@ defineExpose({
{{ t("FamilyTreePage.marryDate") }}
{{ datePart(record.MarryDate) || t("AdminPage.notSetTip")
- }}
+ }}
@@ -2353,7 +2389,7 @@ defineExpose({
{{
datePart(record.DivorceDate) || t("AdminPage.notSetTip")
- }}
+ }}
@@ -2439,7 +2475,7 @@ defineExpose({
{{ record.ChildrenSurname }}{{ record.ChildrenGenealogyName }}
{{ genderText(personGender(record.ChildrenId, record.Gender))
- }}
+ }}
@@ -2550,7 +2586,7 @@ defineExpose({
{{ record.UserLocalName || record.UserName }}
{{
record.ManagerIndc === "Y" ? t("FamilyTreePage.managerTag") : t("FamilyTreePage.memberTag")
- }}
+ }}
@@ -2727,7 +2763,7 @@ defineExpose({
{{ t("FamilyTreePage.exchangeFileLoading")
- }}
+ }}
{{ t(imScope === "SUB" ?
"FamilyTreePage.exchangeFileEmptySub" : "FamilyTreePage.exchangeFileEmpty") }}
{{ t("FamilyTreePage.exchangeFileLoading") }}
{{ t("FamilyTreePage.exchangeBackupEmpty")
- }}
+ }}
@@ -2814,7 +2850,7 @@ defineExpose({
@@ -2932,6 +2968,22 @@ defineExpose({
pointer-events: none;
}
+/* 仅 H5 下载 App 图标:放在「网盘存储空间」标题旁,绿描边 + 柔光圆底(与 sicon 同色系,白卡可见) */
+.home-card__dlapp {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 44rpx;
+ height: 44rpx;
+ border-radius: 50%;
+ background: var(--fg-soft, #e6f6ec);
+}
+
+.home-card__dlapp-icon {
+ width: 28rpx;
+ height: 28rpx;
+}
+
.home-card__avatar {
position: relative;
z-index: 1;
diff --git a/uniapp/youjiala/src/locale/lang/en-US.json b/uniapp/youjiala/src/locale/lang/en-US.json
index ca23cdd..86d5faa 100644
--- a/uniapp/youjiala/src/locale/lang/en-US.json
+++ b/uniapp/youjiala/src/locale/lang/en-US.json
@@ -10,7 +10,10 @@
"typeVip": "VIP",
"typeSvip": "SVIP",
"avatarUploadedTip": "Avatar updated",
- "avatarUploadFailed": "Avatar upload failed"
+ "avatarUploadFailed": "Avatar upload failed",
+ "downloadApp": "Download App",
+ "downloadingApp": "Downloading…",
+ "downloadStarted": "Downloading youjiala.apk…"
},
"article": {
"title": "Family Culture",
diff --git a/uniapp/youjiala/src/locale/lang/zh-CN.json b/uniapp/youjiala/src/locale/lang/zh-CN.json
index fb69669..6f56f89 100644
--- a/uniapp/youjiala/src/locale/lang/zh-CN.json
+++ b/uniapp/youjiala/src/locale/lang/zh-CN.json
@@ -10,7 +10,10 @@
"typeVip": "VIP",
"typeSvip": "SVIP",
"avatarUploadedTip": "头像已更新",
- "avatarUploadFailed": "头像上传失败"
+ "avatarUploadFailed": "头像上传失败",
+ "downloadApp": "下载 App",
+ "downloadingApp": "正在下载…",
+ "downloadStarted": "开始下载 youjiala.apk…"
},
"article": {
"title": "有家文化传承",