diff --git a/uniapp/youjiala/.env b/uniapp/youjiala/.env
new file mode 100644
index 0000000..b8f79d8
--- /dev/null
+++ b/uniapp/youjiala/.env
@@ -0,0 +1,24 @@
+# ============================================================================
+# 全站共享的环境变量:Vite 先读 .env,再由 .env.[mode] 覆盖同名项
+#
+# 这里只放「换环境要动、换设备不用动」的后端根地址;品牌文案(Title/Copy/Beian)
+# 仍然留在 src/policy/custom/webSitePolicy.ts 的常量里,不进 .env。
+#
+# mode 由 uni 命令决定:
+# uni / uni -p mp-weixin / uni -p app => development => .env + .env.development
+# uni build / uni build -p xxx => production => .env + .env.production
+# 读取方:src/policy/custom/webSitePolicy.ts(变量缺失时回落到文件内的默认常量)
+# 类型声明:src/types/env.d.ts
+#
+# 前端产物人人可读,本文件禁止出现任何密钥或凭据。
+# 个人机器差异请写 .env.local / .env.development.local(已被 .gitignore 的 *.local 忽略)。
+# ============================================================================
+
+# 发布构建使用的后端根地址(生产 / UAT 部署)
+VITE_WEB_API_ROOT=https://uat.youjiala.com
+
+# 开发构建使用的后端根地址(H5 联调,默认连宿主机本地后端)
+VITE_WEB_API_ROOT_DEV=http://localhost:5235
+
+# App 端开发构建使用的后端根地址:真机与模拟器上没有宿主机 localhost,改连局域网或 UAT
+VITE_WEB_API_ROOT_DEV_APP=https://uat.youjiala.com
diff --git a/uniapp/youjiala/.env.development b/uniapp/youjiala/.env.development
new file mode 100644
index 0000000..40938d6
--- /dev/null
+++ b/uniapp/youjiala/.env.development
@@ -0,0 +1,4 @@
+# 开发构建(mode=development)专用覆盖:只列与 .env 不同的项,其余继承 .env。
+# 本机后端不跑在 5235、或要改连远程 dev 库时,改这里;也可以另建
+# .env.development.local 做个人覆盖,不要把本机地址提交上来。
+VITE_WEB_API_ROOT_DEV=http://localhost:5235
diff --git a/uniapp/youjiala/.env.production b/uniapp/youjiala/.env.production
new file mode 100644
index 0000000..58e2205
--- /dev/null
+++ b/uniapp/youjiala/.env.production
@@ -0,0 +1,4 @@
+# 发布构建(mode=production)专用覆盖:只列与 .env 不同的项,其余继承 .env。
+# App 端发布同样连这个地址(发布构建不走 DEV_APP 那条条件编译分支)。
+# 换成正式生产域名时只改这一行,源码里的默认常量保留作 fallback。
+VITE_WEB_API_ROOT=https://uat.youjiala.com
diff --git a/uniapp/youjiala/.gitignore b/uniapp/youjiala/.gitignore
index c3ce243..9f1575f 100644
--- a/uniapp/youjiala/.gitignore
+++ b/uniapp/youjiala/.gitignore
@@ -4,11 +4,12 @@ logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
+pnpm-lock.yaml
+yarn.lock
dist
docs
*.local
diff --git a/uniapp/youjiala/.npmrc b/uniapp/youjiala/.npmrc
deleted file mode 100644
index d8b8386..0000000
--- a/uniapp/youjiala/.npmrc
+++ /dev/null
@@ -1,3 +0,0 @@
-strict-peer-dependencies=false
-auto-install-peers=true
-shamefully-hoist=true
diff --git a/uniapp/youjiala/README-pnpm.md b/uniapp/youjiala/README-pnpm.md
deleted file mode 100644
index 224227a..0000000
--- a/uniapp/youjiala/README-pnpm.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# 使用 pnpm 管理依赖
-
-本项目为 pnpm 依赖管理。
-
-## 常用命令
-
-- 安装依赖:
- ```bash
- pnpm install
- ```
-- 启动开发:
-
- ```bash
- # 运行h5
- pnpm dev:h5
-
- # 运行微信小程序
- pnpm dev:mp-weixin
-
- # 运行安卓APP
- pnpm dev:app-android
- ```
-
-- 构建生产包:
-
- ```bash
- # 运行h5
- pnpm build:h5
-
- # 运行微信小程序
- pnpm build:mp-weixin
-
- # 运行安卓APP
- pnpm build:app-android
- ```
-
-- 添加依赖:
- ```bash
- pnpm add <包名>
- ```
-- 删除依赖:
- ```bash
- pnpm remove <包名>
- ```
-
-## 说明
-
-- 已自动生成 `pnpm-lock.yaml`,请勿手动修改。
-- 如遇 node_modules 兼容问题,可先删除 node_modules 和 pnpm-lock.yaml 后重新 `pnpm install`。
-- 推荐全员统一使用 pnpm,避免包管理混乱。
diff --git a/uniapp/youjiala/README.en.md b/uniapp/youjiala/README.en.md
deleted file mode 100644
index 60f5845..0000000
--- a/uniapp/youjiala/README.en.md
+++ /dev/null
@@ -1,275 +0,0 @@
-
-
- English
- 中文
-
-
-
-
-
-uView Pro
-uni-app Vue3 Multi-platform Rapid Development UI Framework
-
-
-
-[](https://gitee.com/anyup/uView-Pro)
-[](https://gitee.com/anyup/uView-Pro)
-[](https://github.com/anyup/uView-Pro)
-[](https://github.com/anyup/uView-Pro)
-[](https://github.com/anyup/uView-Pro/issues)
-[](https://www.npmjs.com/package/uview-pro)
-[](https://uviewpro.cn)
-[](https://nodejs.org/)
-[](https://pnpm.io/)
-[](https://en.wikipedia.org/wiki/MIT_License)
-
-
-
-## Description
-
-uView UI is an excellent UI framework in the [uni-app](https://uniapp.dcloud.io/) ecosystem, providing comprehensive components and handy tools for efficient development.
-
-uView Pro is a uni-app ecosystem framework that fully supports Vue3.0 and TypeScript. The baseline version of uView Pro is modified based on uView 1.8.8, completely reconstructed using TypeScript, and now fully supports uni-app Vue3.0.
-
-## [Official Documentation: https://uviewpro.cn](https://uviewpro.cn)
-
-## [Quick Start Template: https://starter.uviewpro.cn](https://starter.uviewpro.cn)
-
-## Features
-
-- Compatible with Android, iOS, WeChat Mini Programs, H5, QQ Mini Programs, Baidu Mini Programs, Alipay Mini Programs, and Toutiao Mini Programs
-- 70+ selected components, rich in functionality, multi-end compatibility, quick integration, and ready to use out of the box
-- Numerous handy JS tools for efficient development
-- A variety of commonly used pages and layouts, allowing you to focus on logic and achieve more with less effort
-- Detailed documentation and modern demo effects
-- On-demand import, streamlined bundle size
-
-## HarmonyOS Preview
-
-The uView Pro HarmonyOS application has officially been launched in the Huawei App Market, providing you with a complete business scenario demonstration platform. It includes a component library, template samples, scenario cases, and supports one-click copying and downloading to help developers quickly get started and experience the practical value of the components!
-
-> System requirements: Only supported on HarmonyOS 5.0 and above devices
-
-
-
-  |
-
-
- HarmonyOS (Scan with browse) |
-
-
-
-## Mobile Preview
-
-You can scan the following QR codes with **WeChat** or **mobile browser** to view the best demo effect.
-
-
-
-  |
-  |
-  |
-  |
-
-
- WeChat Mini Program (Scan with WeChat) |
- AliPay Mini Program (Scan with AliPay) |
- H5 (Scan with browser) |
- Android (Scan with browser) |
-
-
-
-To run the sample project, please [download the source code](https://github.com/anyup/uview-pro) and execute the following commands in the project root directory:
-
-```bash
-pnpm install
-pnpm dev
-```
-
-For more running and building commands, please refer to the [pnpm Running Guide](README-pnpm.md)
-
-## Links
-
-- [Github](https://github.com/anyup/uview-pro)
-- [Gitee](https://gitee.com/anyup/uview-pro)
-- [Official Documentation](https://uviewpro.cn)
-- [Changelog](https://github.com/anyup/uView-Pro/blob/master/src/uni_modules/uview-pro/changelog.md)
-
-## Communication & Feedback
-
-uView Pro WeChat Group: [Click to Join](https://uviewpro.cn/zh/resource/about.html)
-
-uView Pro QQ Group: [Click to Join](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=98nSVDldWEbDdq4lxiP4aL7uATfMSlI6&authKey=G2yQJ5MQiKzMldaxBsIfKt17NuJuUw8Fr6zdKLggc6NZXgw4BVbqkU2U3EE994yd&noverify=0&group_code=811732166)
-
-
-
-  |
-  |
-
-
- WeChat Group
|
- QQ Group
|
-
-
-
-## About PR
-
-We are very happy to accept high-quality PRs from everyone. However, please note that uView Pro needs to be compatible with multiple platforms (Mini Programs, H5, iOS App, Android App), including nvue and vue pages.
-
-Therefore, before you fix bugs and submit PRs, please try your best to test compatibility on these platforms. It would be best to include test screenshots to facilitate review. Thank you very much!
-
-## Installation And Configuration
-
-uView Pro supports both `npm` and `uni_modules` installation methods, and the configuration is highly consistent. No matter which method you use, you can use easycom for automatic component import, greatly improving development efficiency. The following is a unified configuration guide:
-
-### 1. Install uView Pro
-
-- npm installation:
-
-```bash
-npm install uview-pro
-# or
-yarn add uview-pro
-# or
-pnpm add uview-pro
-```
-
-- uni_modules installation:
-
-Download from HBuilderX plugin market or manually, and place uView Pro in the `uni_modules` directory.
-
-[Plugin Market: https://ext.dcloud.net.cn/plugin?id=24633](https://ext.dcloud.net.cn/plugin?id=24633)
-
-### 2. Import uView Pro main library
-
-Import and register uView Pro in `main.ts`:
-
-```js
-// main.ts
-import { createSSRApp } from 'vue';
-// npm method
-import uViewPro from 'uview-pro';
-// uni_modules method
-// import uViewPro from "@/uni_modules/uview-pro";
-
-export function createApp() {
- const app = createSSRApp(App);
- app.use(uViewPro);
- return {
- app
- };
-}
-```
-
-### 3. Import global styles
-
-Import theme styles in `uni.scss`:
-
-```scss
-/* uni.scss */
-// npm method
-@import 'uview-pro/theme.scss';
-// uni_modules method
-// @import "@/uni_modules/uview-pro/theme.scss";
-```
-
-Import base styles at the top of `App.vue`:
-
-```scss
-
-```
-
-### 4. Configure easycom for automatic component import
-
-Configure easycom rules in `pages.json` for automatic component import:
-
-```json
-// pages.json
-{
- "easycom": {
- "autoscan": true,
- "custom": {
- // npm method
- "^u-(.*)": "uview-pro/components/u-$1/u-$1.vue"
- // uni_modules method
- // "^u-(.*)": "@/uni_modules/uview-pro/components/u-$1/u-$1.vue"
- }
- },
- "pages": [
- // ...
- ]
-}
-```
-
-**Tips**
-
-- 1. After modifying the `easycom` rules, you need to restart HX or recompile the project.
-- 2. Please ensure there is only one easycom field in `pages.json`, otherwise please merge multiple rules yourself.
-- 3. It must be placed inside `custom`, otherwise it will not take effect.
-
-### 5. Volar Type Support
-
-For global Volar type support in CLI projects, add the following to `tsconfig.json`:
-
-```json
-{
- "compilerOptions": {
- // npm method
- "types": ["uview-pro/types"]
- // uni_modules method
- // "types": ["@/uni_modules/uview-pro/types"]
- }
-}
-```
-
-> HBuilderX projects do not support the types configuration in tsconfig.json. CLI projects are recommended to configure for the best TS experience.
-
-### 6. Component Usage
-
-After configuration, you can use uView Pro components directly in SFC without import or components registration:
-
-```vue
-
- Button
-
-```
-
-See [Quick Start](https://uviewpro.cn/zh/components/quickstart.html) for more details.
-
-## Donate to uView Pro
-
-The documentation and framework source code of uView Pro are developed based on uView UI and are therefore open source and free. If you think uView Pro has helped your development work, you can donate to support uView Pro. There is no threshold for donation, even a cup of cola is appreciated (believe me, this is more meaningful than tipping a streamer).
-
-
-
-  |
-  |
-
-
- WeChat
|
- Alipay
|
-
-
-
-## Contributors
-
-
-
-
-
-## License
-
-uView Pro follows the [MIT](https://en.wikipedia.org/wiki/MIT_License) open source license, which means you do not need to pay any fees or obtain authorization to use uView Pro in your products.
-
-## Acknowledgements
-
-Special thanks to the uView UI development team, all contributors to uView UI, and all contributors to uView Pro.
-
-- [Github](https://github.com/anyup/uview-pro)
-- [Gitee](https://gitee.com/anyup/uview-pro)
-- [uView UI 1.0](https://github.com/umicro/uView)
-- [uView UI 2.0](https://github.com/umicro/uView2.0)
diff --git a/uniapp/youjiala/README.md b/uniapp/youjiala/README.md
index b7c7454..446cad6 100644
--- a/uniapp/youjiala/README.md
+++ b/uniapp/youjiala/README.md
@@ -1,272 +1,87 @@
-
-
- English
- 中文
-
+# 有家相册(uni-app 跨端前端)
-
-
-
-uView Pro
-uni-app Vue3 多平台快速开发的 UI 框架
+家庭相册、家族树与文档共享的 uni-app 前端:一套源码出 H5、微信小程序、App 三端。
+业务后端是 CloudBuilder(.NET),本仓库的前身是旧管理端 WebVue 的迁移工程。
-
+## 技术栈
-[](https://gitee.com/anyup/uView-Pro)
-[](https://gitee.com/anyup/uView-Pro)
-[](https://github.com/anyup/uView-Pro)
-[](https://github.com/anyup/uView-Pro)
-[](https://github.com/anyup/uView-Pro/issues)
-[](https://www.npmjs.com/package/uview-pro)
-[](https://uviewpro.cn)
-[](https://nodejs.org/)
-[](https://pnpm.io/)
-[](https://en.wikipedia.org/wiki/MIT_License)
+Vue 3 + TypeScript + Vite + uni-app + uview-pro + Pinia + vue-i18n。
+**包管理器统一使用 npm**(脚手架附带的 pnpm 配置已移除,请勿提交 `pnpm-lock.yaml`)。
-
+## 环境要求
-## 说明
+- Node >= 18
+- npm >= 9
-`uView UI`,是 [uni-app](https://uniapp.dcloud.io/) 生态优秀的 UI 框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水。
-
-`uView Pro`,是全面支持 Vue3.0、TypeScript 的 uni-app 生态框架,uView Pro 的基线版本是基于 uView 1.8.8 修改,使用 TypeScript 完全重构,目前已全面支持 uni-app Vue3.0。
-
-## [组件库文档:https://uviewpro.cn](https://uviewpro.cn)
-
-## [快速启动模板:https://starter.uviewpro.cn](https://starter.uviewpro.cn)
-
-## 特性
-
-- 兼容安卓,iOS,微信小程序,H5,QQ 小程序,百度小程序,支付宝小程序,头条小程序
-- 70+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
-- 众多贴心的 JS 利器,让您飞镖在手,召之即来,百步穿杨
-- 众多的常用页面和布局,让您专注逻辑,事半功倍
-- 详尽的文档支持,现代化的演示效果
-- 按需引入,精简打包体积
-
-## 鸿蒙预览
-
-🎉🎉 uView Pro 鸿蒙端应用已正式上线华为鸿蒙应用市场,为您提供完整的业务场景演示平台,包含组件库、模板示例、场景案例等,支持一键复制下载,帮助开发者快速上手并体验组件的实际应用价值!
-
-> 系统要求:仅支持 HarmonyOS 5.0 及以上版本设备
-
-
-
-  |
-
-
- 鸿蒙应用 (浏览器扫码) |
-
-
-
-## 手机预览
-
-您可以通过**微信**或**手机浏览器**扫描以下二维码,查看最佳的演示效果。
-
-
-
-  |
-  |
-  |
-  |
-
-
- 微信小程序 (微信扫码) |
- 支付宝小程序 (支付宝扫码) |
- H5 (浏览器扫码) |
- Android (浏览器扫码) |
-
-
-
-运行示例工程,请[下载源码](https://github.com/anyup/uview-pro)后,在项目根目录执行以下命令:
+## 快速开始
```bash
-pnpm install
-pnpm dev
+npm install
+
+npm run dev # H5,默认连本机后端
+npm run dev:mp-weixin # 微信小程序:产物在 dist/build/mp-weixin,用微信开发者工具导入该目录
+npm run dev:app # App:产物在 dist/dev/app,再用 HBuilderX 打包运行
```
-更多运行和构建命令参考:[pnpm 运行指南](README-pnpm.md)
+发布构建与检查:
-## 链接
+| 命令 | 作用 |
+| --- | --- |
+| `npm run build` | H5 发布构建 |
+| `npm run build:mp-weixin` | 微信小程序发布构建 |
+| `npm run build:app` | App 发布构建 |
+| `npm run type-check` | vue-tsc 全量类型检查 |
+| `npm run lint` / `npm run lint:fix` | ESLint 检查 / 自动修复 |
-- [Github](https://github.com/anyup/uview-pro)
-- [Gitee](https://gitee.com/anyup/uview-pro)
-- [官方文档](https://uviewpro.cn)
-- [更新日志](https://github.com/anyup/uView-Pro/blob/master/src/uni_modules/uview-pro/changelog.md)
+## 后端地址(.env 分层)
-## 交流反馈
+换环境只改项目根的 `.env` / `.env.development` / `.env.production`,不要在代码里写死地址:
-`uView Pro` 微信交流群: [点击进入](https://uviewpro.cn/zh/resource/about.html)
+| 变量 | 生效场景 | 缺省回落值 |
+| --- | --- | --- |
+| `VITE_WEB_API_ROOT` | 发布构建 | `https://uat.youjiala.com` |
+| `VITE_WEB_API_ROOT_DEV` | 开发构建(H5) | `http://localhost:5235` |
+| `VITE_WEB_API_ROOT_DEV_APP` | 开发构建(App 真机/模拟器) | `https://uat.youjiala.com` |
-`uView Pro` QQ 交流群: [点击进入](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=98nSVDldWEbDdq4lxiP4aL7uATfMSlI6&authKey=G2yQJ5MQiKzMldaxBsIfKt17NuJuUw8Fr6zdKLggc6NZXgw4BVbqkU2U3EE994yd&noverify=0&group_code=811732166)
+变量缺失时由 `src/policy/custom/webSitePolicy.ts` 的常量兜底,删掉 `.env` 也能构建出可用产物。
+取值口径、新增变量的步骤与三端差异见 [src/md/environment.md](src/md/environment.md)。
-
-
-  |
-  |
-
-
- 微信群
|
- QQ群
|
-
-
+## 目录速览
-## 关于 PR
-
-我们非常乐意接受各位的优质 PR,但在此之前我希望您了解 `uView Pro` 是一个需要兼容多个平台的(小程序、h5、iOS App、Android App)包括 nvue 页面、vue 页面。
-
-所以希望在您修复 bug 并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢!
-
-## 安装配置
-
-`uView Pro` 支持 `npm` 和 `uni_modules` 两种主流安装方式,配置方式高度一致。无论采用哪种方式,均可通过 `easycom` 实现组件自动引入,极大提升开发效率。以下为统一的配置说明:
-
-### 1. 安装 uView Pro
-
-- npm 安装:
-
-```bash
-npm install uview-pro
-# 或
-yarn add uview-pro
-# 或
-pnpm add uview-pro
+```
+src/
+├── api/ service/ 后端接口封装(service/* 由代码生成器维护)
+├── common/ 请求拦截器、全局错误边界、样式与常量
+├── pages/ 页面:login / dashboard / error(page401,403,404)
+├── permission/ 权限内核与页面权限表
+├── policy/custom/ 站点配置(.env 的 fallback)
+├── router/ 路径别名、导航拦截器
+├── stores/ Pinia
+├── md/ 工程文档(下表)
+└── manifest.json 三端应用身份(appid / bundleName)
```
-- uni_modules 安装:
+## 改代码前先读的文档
-通过 HBuilderX 插件市场或手动下载,将 uView Pro 放入 `uni_modules` 目录。
+| 文档 | 讲什么 |
+| --- | --- |
+| [src/md/environment.md](src/md/environment.md) | .env 分层、mode 映射、三端读取差异 |
+| [src/md/error-handling.md](src/md/error-handling.md) | 全局错误边界与「已提示过就不再打扰」的口径 |
+| [src/md/permission.md](src/md/permission.md) | 权限模型、页面权限表、菜单可见性 |
+| [src/md/page-routing.md](src/md/page-routing.md) | 路由别名、导航拦截、错误页跳转链 |
-[插件市场:https://ext.dcloud.net.cn/plugin?id=24633](https://ext.dcloud.net.cn/plugin?id=24633)
+代码风格由 ESLint 约束,但 IDE 里同时生效的 Prettier 与它存在少量对撞规则(箭头括号、运算符换行位置);
+冲突写法已在文档里给了规避方式,遇到 `--fix` 反复回退请改写构造而不是硬碰。
-### 2. 引入 uView Pro 主库
+## 待替换的应用身份
-在 `main.ts` 中引入并注册 uView Pro:
+`src/manifest.json` 与 `harmony-configs/build-profile.json5` 里的脚手架身份已清成占位,正式发布前需逐项替换:
-```js
-// npm 方式
-import uViewPro from 'uview-pro'
-import { createSSRApp } from 'vue'
-// uni_modules 方式
-// import uViewPro from "@/uni_modules/uview-pro";
+- DCloud `appid`:当前为占位 `__UNI__YJL0001`,需在 HBuilderX 登录自有账号后重新领取
+- 微信小程序 `appid`:故意留空(构建时回落为 `touristappid`,只能本地预览),发布前换成自有 AppID
+- 鸿蒙 `bundleName`:当前 `com.youjiala.app`,需与华为侧注册的包名一致
+- 鸿蒙签名材料路径:`harmony-configs/build-profile.json5` 里指向 `./signing/youjiala.*`,需放入自有证书
-export function createApp() {
- const app = createSSRApp(App)
- app.use(uViewPro)
- return {
- app
- }
-}
-```
+## 许可
-### 3. 引入全局样式
-
-在 `uni.scss` 中引入主题样式:
-
-```scss
-/* npm 方式 */
-@import 'uview-pro/theme.scss';
-/* uni_modules 方式 */
-/* @import "@/uni_modules/uview-pro/theme.scss"; */
-```
-
-在 `App.vue` 首行引入基础样式:
-
-```scss
-
-```
-
-### 4. 配置 easycom 自动引入组件
-
-在 `pages.json` 中配置 `easycom` 规则,实现组件自动引入:
-
-```json
-{
- "easycom": {
- "autoscan": true,
- "custom": {
- // npm 方式
- "^u-(.*)": "uview-pro/components/u-$1/u-$1.vue"
- // uni_modules 方式
- // "^u-(.*)": "@/uni_modules/uview-pro/components/u-$1/u-$1.vue"
- }
- },
- "pages": []
-}
-```
-
-**温馨提示**
-
-- 1.修改 `easycom` 规则后需重启 HX 或重新编译项目。
-- 2.请确保 `pages.json` 中只有一个 easycom 字段,否则请自行合并多个规则。
-- 3.一定要放在 `custom` 内,否则无效。
-
-### 5. Volar 类型提示支持
-
-如需在 `CLI` 项目中获得 `Volar` 的全局类型提示,请在 `tsconfig.json` 中添加:
-
-```json
-{
- "compilerOptions": {
- // npm 方式
- "types": ["uview-pro/types"]
- // uni_modules 方式
- // "types": ["@/uni_modules/uview-pro/types"]
- }
-}
-```
-
-> HBuilderX 项目暂不支持 `tsconfig.json` 的 `types` 配置,`CLI` 项目推荐配置以获得最佳 `TS` 体验。
-
-### 6. 组件使用
-
-配置完成后,无需 `import` 和 `components` 注册,可直接在 `SFC` 中使用 `uView Pro` 组件:
-
-```vue
-
-
- 按钮
-
-
-```
-
-请通过[快速上手](https://uviewpro.cn/zh/components/quickstart.html)了解更详细的内容
-
-## 捐赠 uView Pro
-
-`uView Pro` 文档内容和框架源码基于 `uView UI` 二次开发,因此全部开源免费,如果您认为 `uView Pro` 帮到了您的开发工作,您可以捐赠 `uView Pro` 的研发工作,捐赠无门槛,哪怕是一杯可乐也好(相信这比打赏主播更有意义)。
-
-
-
-  |
-  |
-
-
- 微信
|
- 支付宝
|
-
-
-
-## 贡献者
-
-
-
-
-
-## 版权信息
-
-`uView Pro` 遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将 `uView Pro` 应用到您的产品中。
-
-## 鸣谢
-
-再次感谢 `uView UI` 开发团队,以及所有为 `uView UI` 的贡献者,以及所有为 `uView Pro` 的贡献者。
-
-- [Github](https://github.com/anyup/uview-pro)
-- [Gitee](https://gitee.com/anyup/uview-pro)
-- [uView UI 1.0](https://github.com/umicro/uView)
-- [uView UI 2.0](https://github.com/umicro/uView2.0)
+界面组件库 uview-pro 与其脚手架遵循 MIT(见 `LICENSE`);业务代码版权归本项目所有。
diff --git a/uniapp/youjiala/harmony-configs/build-profile.json5 b/uniapp/youjiala/harmony-configs/build-profile.json5
index fdd507a..74b2083 100644
--- a/uniapp/youjiala/harmony-configs/build-profile.json5
+++ b/uniapp/youjiala/harmony-configs/build-profile.json5
@@ -5,12 +5,12 @@
name: 'default',
type: 'HarmonyOS',
material: {
- certpath: 'D:/workspace/anyup/uView-Pro-Starter/docs/uviewpro.cer',
- keyAlias: 'uviewpro',
+ certpath: './signing/youjiala.cer',
+ keyAlias: 'youjiala',
keyPassword: '',
- profile: 'D:/workspace/anyup/uView-Pro-Starter/docs/uviewpro_prodRelease.p7b',
+ profile: './signing/youjiala_prodRelease.p7b',
signAlg: 'SHA256withECDSA',
- storeFile: 'D:/workspace/anyup/uView-Pro-Starter/docs/uviewpro.p12',
+ storeFile: './signing/youjiala.p12',
storePassword: ''
}
},
@@ -18,13 +18,13 @@
name: 'release',
type: 'HarmonyOS',
material: {
- storeFile: 'D:/workspace/anyup/uView-Pro-Starter/docs/uviewpro.p12',
+ storeFile: './signing/youjiala.p12',
storePassword: '',
- keyAlias: 'uviewpro',
+ keyAlias: 'youjiala',
keyPassword: '',
signAlg: 'SHA256withECDSA',
- profile: 'D:/workspace/anyup/uView-Pro-Starter/docs/uviewpro_prodRelease.p7b',
- certpath: 'D:/workspace/anyup/uView-Pro-Starter/docs/uviewpro.cer'
+ profile: './signing/youjiala_prodRelease.p7b',
+ certpath: './signing/youjiala.cer'
}
}
],
diff --git a/uniapp/youjiala/package.json b/uniapp/youjiala/package.json
index ced722c..a2f9214 100644
--- a/uniapp/youjiala/package.json
+++ b/uniapp/youjiala/package.json
@@ -3,10 +3,12 @@
"type": "module",
"version": "1.0.0",
"private": true,
- "packageManager": "pnpm@10.34.5",
+ "overrides": {
+ "unconfig": "7.3.2"
+ },
"engines": {
"node": ">=18.0.0",
- "pnpm": ">=10.0.0"
+ "npm": ">=9.0.0"
},
"scripts": {
"dev": "uni",
diff --git a/uniapp/youjiala/pnpm-workspace.yaml b/uniapp/youjiala/pnpm-workspace.yaml
deleted file mode 100644
index 876e89d..0000000
--- a/uniapp/youjiala/pnpm-workspace.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-allowBuilds:
- '@uni-helper/unocss-preset-uni': true
- bufferutil: true
- core-js: true
- esbuild: true
- vue-demi: true
-overrides:
- unconfig: 7.3.2
diff --git a/uniapp/youjiala/src/App.root.vue b/uniapp/youjiala/src/App.root.vue
index 170344c..e4eb6f2 100644
--- a/uniapp/youjiala/src/App.root.vue
+++ b/uniapp/youjiala/src/App.root.vue
@@ -1,25 +1,9 @@
-
-
-
+
diff --git a/uniapp/youjiala/src/App.vue b/uniapp/youjiala/src/App.vue
index acdf559..95f10a4 100644
--- a/uniapp/youjiala/src/App.vue
+++ b/uniapp/youjiala/src/App.vue
@@ -1,7 +1,12 @@
+
+
+
+
+
+
+
+```
+
+数据级判定(同一功能在不同群组/目录下动作不同):
+
+```ts
+const { can, canOperate } = usePermission();
+can("amend", "FamilyGroup", familyId); // 只查 PermissionDependents
+canOperate("Approval", "PublishPhoto"); // 走 operate -> dependent 那条线
+```
+
+---
+
+## 5. 两套失败策略:路由 fail-open,按钮 fail-closed
+
+这不是不一致,是故意的。
+
+| 层 | 判定入口 | 档案缺失/权限清单为空时 | 理由 |
+| --- | --- | --- | --- |
+| 路由 | `canVisitPage()` | **放行**(fail-open) | 档案来自本地缓存,一旦被写坏或尚未水合,严格模式会把所有人挡在 403 外面——那时用户连"能不能重新登录"都点不到。真正的安全边界始终在后端(每个接口都有 `[PermissionOperate]`) |
+| 按钮 | `usePagePermission()` / `usePermission()` | **不显示**(fail-closed) | 多挡一个按钮只是少个入口;误放一个按钮,点了只会收到 403 |
+
+`permissionInfoUnusable()` 只认一个信号:`Permissions` 数组缺失或长度为 0。它**不**区分"这人真没权限"和"档案坏了"——前端分不出来,所以把这个歧义交给后端裁决,而不是自己猜。
+
+由此推出两条排查纪律:
+
+- 页面进不去,先看 `PAGE_PERMISSIONS` 有没有登记错权限名(登记错 = 该页对所有人 403,除非档案是空的)。
+- 按钮不见了,先 `usePermission().granted()` 打印实际授权,再对照后端组授权。
+
+---
+
+## 6. 新增页面时怎么登记权限
+
+```
+1. 拿到权限名:后端 security_permission.permission_name(权威清单)
+ 或 security_permission_function_map(function_name <-> permission_name <-> page_name)
+2. 写进 src/router/routes.ts 的 PAGE_PERMISSIONS:
+ export const PAGE_PERMISSIONS: Partial> = {
+ albumList: "PublishPhoto", // 单个
+ preview: ["PublishPhoto", "FamilyGroup"], // 数组 = 任一命中即放行
+ };
+3. 页面里用 usePagePermission("albumList") 控制按钮,不要自己写权限名
+```
+
+三条纪律:
+
+- **权限名必须是后端库里的原文**,大小写、拼写逐字一致。写错不会编译报错,只会让该页对所有人 403(§5 已述)。
+- **能不登记就不登记**。欢迎页、错误页、纯展示页都不该绑权限;绑一个库里全 `N` 的权限(如 `Welcome`)等于自断门路。
+- **权限名不散落在页面里**。页面只引用 `PageName`,名字集中在 `PAGE_PERMISSIONS`,这样"哪些页面受权限管"是一张可审阅的表,而不是 grep 全项目。
+
+### 6.1 跨端注意
+
+- **小程序不支持自定义指令**,所以不要写 `v-perm`/`v-auth` 之类的指令(App 端同样受编译期限制)。本项目统一用 composable + `v-if`,三端一致。
+- 判定不碰 `uni.*` API,也不碰请求层,所以 `permission-kernel.ts` 可以在 node 下直接跑(§7)。
+- 无 `router.beforeEach`:路由级判定只有 `nav-guard` 的两条链路(拦截器 + 页面 `onShow` 复核),权限层挂在它的第三步,顺序固定在 401 之后——未登录时档案通常也是空的,先给 401 才谈得上"去登录"。
+
+### 6.2 为什么不用已经在手里的 `PermissionFunctionMaps` 生成登记表
+
+登录档案已经带了 `PermissionFunctionMaps[]`(`{PermissionName, FunctionName, PageName}`),看起来可以直接推导出 `PAGE_PERMISSIONS`。**不能**:后端构造它时 `join info.Permissions`(`PermissionContext.cs:68-73`),只包含**当前用户已授权**的权限。用它登记,"该页需要但当前用户没有"的权限名会直接缺席 → 该页变成不校验 → 谁都能进,恰好把权限体系掏空。
+
+它的正确用途在别处:**登记与排查时的"页面名 <-> 权限名"反查表**(`security_permission_function_map` 视图,字段只有 `PermissionName/FunctionName/PageName`)。它画不出菜单——没有 `FunctionLocalName/FunctionEngName`、没有 `Icon`、没有 `Orderby`、没有父子层级,做菜单要用下面 §8 说的 `FindMenuByUsername`。
+
+---
+
+## 7. 校验:内核是可执行的
+
+项目还没接测试运行器,所以 `permission-kernel.spec.ts` 写成"能被 esbuild 打包、node 直接跑"的形态。跑法(PowerShell,项目根目录):
+
+```powershell
+& "C:\Program Files\nodejs\node.exe" ".\node_modules\esbuild\bin\esbuild" `
+ src\permission\permission-kernel.spec.ts --bundle --platform=node --format=cjs `
+ --alias:@=./src --outfile="$env:TEMP\permission-kernel.spec.cjs" --log-level=warning
+& "C:\Program Files\nodejs\node.exe" "$env:TEMP\permission-kernel.spec.cjs" 2>&1 `
+ | Out-File -Encoding utf8 "$env:TEMP\perm-run.log"
+"RUN_EXIT=$LASTEXITCODE"
+```
+
+`RUN_EXIT=0` 且日志尾部为 `permission-kernel: 59 assertions passed` 即通过(断言失败会打印 `FAIL <用例名>` 并以非零退出,不会"跑了但没人看输出")。
+
+覆盖的 10 组语义:`view` 必须检 `ViewIndc`、四动作互相独立、多用户组授权 OR 合并、数据级不回退、严格比较(小写 `y`/大小写/不 trim)、档案缺失或损坏不抛异常、`canAny` 数组与空串、未授予权限返回全 `false`、`grantedPermissions` 清单、`canOperate` 全操作映射(含 `Submit` 命中与 `Approval` 未挂)。
+
+将来引入 vitest,只需把 `check()` 换成 `expect()`,用例本身不动。**判定语义改动必须先加用例再改代码**——`canView` 那条修复就是靠用例钉住的,光读代码很容易自我说服"应该没问题"。
+
+### 7.2 端到端实测(H5 dev + 真实后端,账号 001)
+
+`PAGE_PERMISSIONS` 是空表,路由级 403 在日常代码里走不到,所以验证时临时往表里塞值、跑完再回滚。方法:`npm run dev:h5`(5173)+ 后端 5235,浏览器真机登录,观察地址栏与 console。三轮结论:
+
+| 临时绑定 | 预期 | 实测 |
+| --- | --- | --- |
+| `dashboard: "TEMP_E2E_NOT_EXIST"` | 登录后与冷启动深链都进不去 | ✅ 两条链路都落 `/error/page403?from=/dashboard`,0 console error;401→403 的 `?from=` 传递与"重新登录带 redirect"一并复验 |
+| `dashboard: "Welcome"`(库里真实存在,但 `view_indc='N'`) | 仍拦 | ✅ 登录后 2.5s 落到 403。**这就是 §3.1 那条修复的端到端实证**——旧前端在此处会误放行,然后满屏接口 403 |
+| `dashboard: ["PublishVideo", "PublishPhoto"]`(均 `Y|Y|Y|Y`) | 放行 | ✅ 登录跳转与冷启动深链都正常进 `/dashboard`,0 error / 0 warn;顺带在页面运行时直呼线上内核复现了数组 OR 语义:`canAny(view, ["TEMP_NO_SUCH","PublishPhoto"]) -> true`、`canAny(view, ["TEMP_NO_SUCH"]) -> false` |
+
+三轮都只用临时值,`PAGE_PERMISSIONS` 现已回滚为 `{}`。**验证权限层时不要只看"能不能进",必须同时看 console**——拦截逻辑本身没问题时,残余故障通常表现为多打了几个接口或重复跳转。
+
+顺带发现并修掉一个既有缺陷(与权限无关,但正是这轮端到端才暴露的):登录页缺 `?redirect=` 时,`resolvePageName("")` 会经 `normalizePath("") -> "/" -> "login"` 返回真值,于是 `login.vue` 的 `onLoad` 把默认落地地址覆盖成空串,`uni.reLaunch({url: ""})` 直接 `fail: Missing required args "url"`,用户登录成功后卡在登录页。修复分两处:`routes.ts` 的 `resolvePageName` 对空地址早退返回 `null`(源头),`login.vue` 追加 `!isAuthFree(name)`(不让手敲的 `?redirect=/` 把自己跳回登录页)。
+
+### 7.3 改完权限层必跑的四步(本机实测耗时约 2 分钟)
+
+项目根目录,PowerShell。`node` 必须用绝对路径(PATH 上那个是吞输出的垫片):
+
+```powershell
+$n = 'C:\Program Files\nodejs\node.exe'
+# 1) 内核语义(§7) 期望 SPEC_EXIT=0 且日志含 "59 assertions passed"
+& $n ".\node_modules\esbuild\bin\esbuild" src\permission\permission-kernel.spec.ts --bundle --platform=node --format=cjs --alias:@=./src --outfile="$env:TEMP\permission-kernel.spec.cjs" --log-level=warning
+& $n "$env:TEMP\permission-kernel.spec.cjs" 2>&1 | Out-File -Encoding utf8 "$env:TEMP\perm-run.log"; "SPEC_EXIT=$LASTEXITCODE"
+# 2) 类型(含 IDE 误报的裁决) 期望 VTSC_EXIT=0 且 VTSC_BYTES=0
+& $n ".\node_modules\vue-tsc\bin\vue-tsc.js" --noEmit 2>&1 | Out-File -Encoding utf8 "$env:TEMP\vt.log"; "VTSC_EXIT=$LASTEXITCODE VTSC_BYTES=" + (Get-Item "$env:TEMP\vt.log").Length
+# 3) Lint(含 md 里的 ts 代码块) 期望 ESLINT_EXIT=0
+& $n ".\node_modules\eslint\bin\eslint.js" src -f stylish -o "$env:TEMP\lint.txt"; "ESLINT_EXIT=$LASTEXITCODE"
+# 4) 三端构建 期望三份日志都是 DONE Build complete.
+.\node_modules\.bin\uni.cmd build *> "$env:TEMP\b-h5.log"
+.\node_modules\.bin\uni.cmd build -p mp-weixin *> "$env:TEMP\b-mp.log"
+.\node_modules\.bin\uni.cmd build -p app *> "$env:TEMP\b-app.log"
+```
+
+**别把"没回显"当成"卡死"**:`uni.cmd` 的输出经 PowerShell 缓冲,三条链式命令跑完才一次性刷出来,中途取消会让你只看到 `ExitCode 130` 而看不到 `H5_EXIT=`。此时看两处实锤就够了:
+
+```powershell
+Get-Item "$env:TEMP\b-h5.log","$env:TEMP\b-mp.log","$env:TEMP\b-app.log" | Select-Object Length, LastWriteTime
+Select-String -Path "$env:TEMP\b-*.log" -Pattern 'Build complete'
+```
+
+三端单次构建各约 10 秒,整条链 35 秒上下;日志里有 `DONE Build complete.` 且 `dist\build\{h5,mp-weixin,app}` 的 `LastWriteTime` 是刚刚,就是成功。想确认权限层真的进了产物,搜后端 JSON 字段名(压缩后属性名不变):
+
+```powershell
+Get-ChildItem 'dist\build\mp-weixin' -Recurse -File -Include *.js | Select-String -Pattern 'PermissionDependents' -List
+```
+
+**别用 `Select-String -Path 'dist\build\mp-weixin\**\*.js'`**:PowerShell 的 `**` 通配在这里不递归,会给出假的"0 命中"(本轮就这样误判过一次"小程序产物没吃到 .env",实际是搜索方式错了)。
+
+改完请求层或全局错误边界,还要按 [error-handling.md §7.2](./error-handling.md) 在浏览器里跑一次探针:静态四步全绿也证明不了钩子会被触发。
+
+**两处刻意绕开外部格式化器的写法**(`permission-kernel.ts`):IDE 的 prettier 与项目 ESLint 在两个构造上各执一词,`--fix` 之后一保存又被改回去,来回拉锯且每次都以 `ESLINT_EXIT=1` 收场,所以直接换成两边都稳定的形态,而不是每次收尾都跑一遍 `--fix`:
+
+| 构造 | 冲突 | 现在的写法 |
+| --- | --- | --- |
+| `canAny` 的逐项判定 | prettier 给单参数箭头加括号,`style/arrow-parens`(项目规范:单参数必须省括号)又要去掉 | `for (const name of list)`,语义与 `some()` 的短路完全一致 |
+| `PermissionOperate` 联合类型 | 多行字面量联合的 `=` 位置:prettier 放行尾,`style/operator-linebreak` 放行首 | `PERMISSION_OPERATES` 用 `as const` 数组 + `(typeof ...)[number]` 派生,单行放得下;顺带得到可运行的枚举清单 |
+
+自查方法:连跑两遍 `eslint src`,中间 `Start-Sleep` 几秒等格式化器动手——两遍都 `EXIT=0` 才算真的稳定,只跑一遍容易把"刚被 --fix 修好、马上又会被格式化回去"误判成通过。
+
+---
+
+## 8. 已知缺口
+
+- **入口可见性这一层还没做(菜单/首页九宫格)**。权限的可见性分两层,本层只实现了第二层:
+
+ | 层 | 管什么 | 数据源 | 现状 |
+ | --- | --- | --- | --- |
+ | ① 入口可见性 | 首页列不列得出这个入口 | `POST /SecurityUser/FindMenuByUsername`(后端按用户权限过滤) | **未实现**:`dashboard.vue` 是空白占位页 |
+ | ② 页面可进入性 | 手输地址/深链跳过去能不能进 | `PAGE_PERMISSIONS` + `canVisitPage()` | 判定层就绪,登记表为空 |
+
+ 旧 WebVue 主要靠 ①:看不见的入口自然不会点,②只是补"手敲 URL"的漏洞。①的后端链路(`SecurityUserService.cs:232-248`)是 `用户名 -> security_user_actor -> security_actor_group -> security_group_permission -> security_permission_function_map -> security_function`,只返回本人被授权的功能,`UserId` 为空直接返回 null。
+ 两个接口都已随 service 层移植进来且**零调用者**:`securityUserService.FindMenuByUsername()`(返回 `SecurityFunctionResultData`,含 `SecurityFunctionDisplayData[]` 的 `FunctionLocalName/FunctionEngName/Icon/Orderby/PageUrl/PermissionName` 与 `SecurityFunctionMaps` 层级,正是旧 `layout/index.vue` 的 `initMenu()` 消费的形态)和 `securityFunctionService.FindMenus()`(`[AllowAnonymous]`、**不区分用户的全量表**,旧项目只用来全量注册路由,别拿它做过滤)。
+ 所以这一条缺口的真实含义是:等做首页入口时调 `FindMenuByUsername` 渲染,并用返回的 `PermissionName` 顺手校对 `PAGE_PERMISSIONS` 的登记;`stores/tabbar.ts` 的默认列表目前也是空的,等同一个数据源。
+- **数据级(dependent)判定尚无真实页面在用**:旧项目所有调用点都是单参形式,口子为 `Submit`/`Approval` 与将来的目录级授权保留。
+- **`PAGE_PERMISSIONS` 目前是空表**:现在只有 login / dashboard / 三个错误页,除 dashboard 有意不绑(§3.1)之外,其余页面还没迁进来。空表意味着路由级 403 实际上还没被任何页面触发,只能靠请求层的 HTTP 403。
+- **403 页的"返回首页"在首页本身被拦时会原地弹回一次**:`page403.vue` 的返回按钮走 `reLaunch(pageUrl("dashboard"))`,而 reLaunch 同样过 `nav-guard`;若 dashboard 恰好被绑了拿不到的权限,这次跳转会被再拦一次、弹回 403(实测是一次性弹回,不是死循环,因为 403 页自身在 `AUTH_FREE_PAGES` 里)。等真有页面登记权限时,这里应该改成"按 `PAGE_PERMISSIONS` 找第一个可达页"或直接隐藏该按钮。
+- **前端判定滞后于后端**:后端每次请求实时查库,前端读登录时的快照。管理员改了授权后,用户重新登录前看到的仍是旧按钮状态(可能点了才 403)。这是"权限随令牌下发"这个既有模型的代价,不是本层引入的。
+- **`SecurityUserPermissionInfo.UserGroups` 未参与判定**:后端也不用它做短路(只用于 join 出授权行),前端同样只用 `Permissions` / `PermissionDependents`。
+- **孤儿授权数据**:种子库里 `security_group_permission` 有 `abc` 组以及 `acc`/`PhotoPublish`/`AudioPublish`/`VideoPublish` 等权限名,而 `security_group` / `security_permission` 里查不到它们。判定层对此的表现是"多几行永远匹配不上的索引项",无害;但登记权限名时**不能以授权表的并集为准**,要以 `security_permission` 为准,否则会照抄到这些历史残留。
diff --git a/uniapp/youjiala/src/pages/error/page403.vue b/uniapp/youjiala/src/pages/error/page403.vue
index 1e15061..bd47e1a 100644
--- a/uniapp/youjiala/src/pages/error/page403.vue
+++ b/uniapp/youjiala/src/pages/error/page403.vue
@@ -1,7 +1,8 @@