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 { + return request({ + url: `${AUTH_BASE_URL}/qr-code/scan`, + method: "POST", + data: { ticket }, + }); + }, + + /** + * 确认登录 + * + * 真正的授权动作,授权后 PC 端 status 进入 CONFIRMED,可换取会话令牌 + */ + qrConfirm(ticket: string): Promise { + return request({ + url: `${AUTH_BASE_URL}/qr-code/confirm`, + method: "POST", + data: { ticket }, + }); + }, + + /** + * 取消登录 + * + * 撤回本次扫码,PC 端 status 进入 CANCELED + */ + qrCancel(ticket: string): Promise { + return request({ + url: `${AUTH_BASE_URL}/qr-code/cancel`, + method: "POST", + data: { ticket }, + }); + }, }; export default AuthAPI; diff --git a/src/pages.json b/src/pages.json index 61e64e8..5b10247 100644 --- a/src/pages.json +++ b/src/pages.json @@ -210,6 +210,15 @@ "style": { "navigationBarTitleText": "字典数据" } + }, + { + "path": "pages/qr-code-confirm/index", + "type": "page", + "name": "qr-code-confirm", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "" + } } ], "subPackages": [], diff --git a/src/pages/login/index.vue b/src/pages/login/index.vue index 974dd41..a55aaf7 100644 --- a/src/pages/login/index.vue +++ b/src/pages/login/index.vue @@ -21,7 +21,7 @@