diff --git a/README.md b/README.md index 2bf2fce..66dc1f2 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ youlai-app/ 如果这个项目对你有帮助,欢迎关注公众号、体验小程序,也可以添加作者微信交流技术、问题反馈、二次开发和商务合作。
-
+
diff --git a/components.d.ts b/components.d.ts
index 2b980a0..3e67f27 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -19,14 +19,11 @@ declare module 'vue' {
QiunError: typeof import('./src/components/qiun-error/qiun-error.vue')['default']
QiunLoading: typeof import('./src/components/qiun-loading/qiun-loading.vue')['default']
WdActionSheet: typeof import('@wot-ui/ui/components/wd-action-sheet/wd-action-sheet.vue')['default']
- WdBadge: typeof import('@wot-ui/ui/components/wd-badge/wd-badge.vue')['default']
WdButton: typeof import('@wot-ui/ui/components/wd-button/wd-button.vue')['default']
- WdCalendar: typeof import('@wot-ui/ui/components/wd-calendar/wd-calendar.vue')['default']
WdCard: typeof import('@wot-ui/ui/components/wd-card/wd-card.vue')['default']
WdCascader: typeof import('@wot-ui/ui/components/wd-cascader/wd-cascader.vue')['default']
WdCell: typeof import('@wot-ui/ui/components/wd-cell/wd-cell.vue')['default']
WdCellGroup: typeof import('@wot-ui/ui/components/wd-cell-group/wd-cell-group.vue')['default']
- WdCheckbox: typeof import('@wot-ui/ui/components/wd-checkbox/wd-checkbox.vue')['default']
WdCollapse: typeof import('@wot-ui/ui/components/wd-collapse/wd-collapse.vue')['default']
WdCollapseItem: typeof import('@wot-ui/ui/components/wd-collapse-item/wd-collapse-item.vue')['default']
WdConfigProvider: typeof import('@wot-ui/ui/components/wd-config-provider/wd-config-provider.vue')['default']
@@ -38,9 +35,6 @@ declare module 'vue' {
WdFab: typeof import('@wot-ui/ui/components/wd-fab/wd-fab.vue')['default']
WdForm: typeof import('@wot-ui/ui/components/wd-form/wd-form.vue')['default']
WdFormItem: typeof import('@wot-ui/ui/components/wd-form-item/wd-form-item.vue')['default']
- WdGap: typeof import('@wot-ui/ui/components/wd-gap/wd-gap.vue')['default']
- WdGrid: typeof import('@wot-ui/ui/components/wd-grid/wd-grid.vue')['default']
- WdGridItem: typeof import('@wot-ui/ui/components/wd-grid-item/wd-grid-item.vue')['default']
WdIcon: typeof import('@wot-ui/ui/components/wd-icon/wd-icon.vue')['default']
WdImgCropper: typeof import('@wot-ui/ui/components/wd-img-cropper/wd-img-cropper.vue')['default']
WdInput: typeof import('@wot-ui/ui/components/wd-input/wd-input.vue')['default']
@@ -53,7 +47,6 @@ declare module 'vue' {
WdRadioGroup: typeof import('@wot-ui/ui/components/wd-radio-group/wd-radio-group.vue')['default']
WdSearch: typeof import('@wot-ui/ui/components/wd-search/wd-search.vue')['default']
WdSelectPicker: typeof import('@wot-ui/ui/components/wd-select-picker/wd-select-picker.vue')['default']
- WdSwiper: typeof import('@wot-ui/ui/components/wd-swiper/wd-swiper.vue')['default']
WdSwitch: typeof import('@wot-ui/ui/components/wd-switch/wd-switch.vue')['default']
WdTabbar: typeof import('@wot-ui/ui/components/wd-tabbar/wd-tabbar.vue')['default']
WdTabbarItem: typeof import('@wot-ui/ui/components/wd-tabbar-item/wd-tabbar-item.vue')['default']
diff --git a/deploy.mjs b/deploy.mjs
new file mode 100644
index 0000000..1a9fc4a
--- /dev/null
+++ b/deploy.mjs
@@ -0,0 +1,31 @@
+/* eslint-disable no-console */
+/**
+ * 部署 H5 到服务器 | 用法:pnpm run deploy
+ *
+ * 前置:SSH 免密登录(只需一次)
+ * 1. 如果 %USERPROFILE%\.ssh\id_rsa 已存在跳过,否则 ssh-keygen -t rsa 回车到底
+ *
+ * 2. 拷贝公钥到服务器(会提示输一次服务器密码):
+ * Windows: type %USERPROFILE%\.ssh\id_rsa.pub | ssh root@server "cat >> ~/.ssh/authorized_keys"
+ * Mac: ssh-copy-id root@server
+ *
+ * 3. ssh root@server 输完不弹密码直接连上即成功
+ */
+import { execSync } from "node:child_process";
+
+const HOST = "www.youlai.tech";
+const USER = "root";
+const PORT = 1010;
+const TARGET = "/mnt/nginx/html/app";
+// =========================================================
+
+console.log("构建中...");
+execSync("pnpm build:h5", { stdio: "inherit" });
+
+console.log(`部署 → ${USER}@${HOST}:${TARGET}`);
+execSync(`scp -o StrictHostKeyChecking=no -P ${PORT} -r "dist/build/h5/." "${USER}@${HOST}:${TARGET}/"`, {
+ stdio: "inherit",
+ shell: true,
+});
+
+console.log("部署完成");
diff --git a/docs/images/qrcode/wechat-official.png b/docs/images/qrcode/wechat-official.png
deleted file mode 100644
index 54f1e17..0000000
Binary files a/docs/images/qrcode/wechat-official.png and /dev/null differ
diff --git a/package.json b/package.json
index 5f1e5bf..ff8051d 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"build:app-harmony": "uni build -p app-harmony",
"build:custom": "uni build -p",
"build:h5": "uni build --mode production",
+ "deploy": "node deploy.mjs",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp-baidu": "uni build -p mp-baidu",
diff --git a/public/favicon.ico b/public/favicon.ico
index 16fed5e..0a6744a 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/docs/images/preview/app-01.png b/public/images/preview/app-01.png
similarity index 100%
rename from docs/images/preview/app-01.png
rename to public/images/preview/app-01.png
diff --git a/docs/images/preview/app-02.png b/public/images/preview/app-02.png
similarity index 100%
rename from docs/images/preview/app-02.png
rename to public/images/preview/app-02.png
diff --git a/docs/images/preview/app-03.png b/public/images/preview/app-03.png
similarity index 100%
rename from docs/images/preview/app-03.png
rename to public/images/preview/app-03.png
diff --git a/docs/images/preview/app-04.png b/public/images/preview/app-04.png
similarity index 100%
rename from docs/images/preview/app-04.png
rename to public/images/preview/app-04.png
diff --git a/docs/images/qrcode/wechat-mp.jpg b/public/images/qrcode/wechat-mp.jpg
similarity index 100%
rename from docs/images/qrcode/wechat-mp.jpg
rename to public/images/qrcode/wechat-mp.jpg
diff --git a/public/images/qrcode/wechat-official.jpg b/public/images/qrcode/wechat-official.jpg
new file mode 100644
index 0000000..576f210
Binary files /dev/null and b/public/images/qrcode/wechat-official.jpg differ
diff --git a/docs/images/qrcode/wechat-personal.png b/public/images/qrcode/wechat-personal.png
similarity index 100%
rename from docs/images/qrcode/wechat-personal.png
rename to public/images/qrcode/wechat-personal.png
diff --git a/public/logo.png b/public/logo.png
new file mode 100644
index 0000000..ebfa2af
Binary files /dev/null and b/public/logo.png differ
diff --git a/src/api/auth.ts b/src/api/auth.ts
index 40a4e8b..4928476 100644
--- a/src/api/auth.ts
+++ b/src/api/auth.ts
@@ -51,6 +51,16 @@ export interface WxMaBindMobileData {
smsCode: string;
}
+/** APP 端扫码相关接口(scan/confirm/cancel)的响应 */
+export interface QrCodeScanResult {
+ /** 当前票据状态,APP 端扫码后流转为 SCANNED → CONFIRMED / CANCELED */
+ status: "SCANNED" | "CONFIRMED" | "CANCELED";
+ /** 脱敏昵称,scan 成功后返回,用于确认页展示请求登录的用户 */
+ nickname?: string;
+ /** 头像 URL,scan 成功后返回 */
+ avatar?: string;
+}
+
const AuthAPI = {
/**
* 获取图形验证码
@@ -169,6 +179,47 @@ const AuthAPI = {
data: { refreshToken },
});
},
+
+ // ============ 扫码登录 ============
+
+ /**
+ * 标记已扫码
+ *
+ * 把当前 APP 登录用户与票据绑定,PC 端 status 随即进入 SCANNED 并展示头像昵称
+ */
+ qrScan(ticket: string): Promise