From 484b39cf90142e91e410f4b3f1c2182a94414bb5 Mon Sep 17 00:00:00 2001 From: yansongda Date: Sat, 4 Nov 2023 23:00:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=20weui=20=E7=9A=84?= =?UTF-8?q?=20toptips=EF=BC=8C=E7=BB=99=E4=BA=88=E6=9B=B4=E5=A5=BD?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=20(#7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- miniprogram/api/shorturl.ts | 8 ++--- miniprogram/api/totp.ts | 22 ++++++------ miniprogram/api/user.ts | 14 ++++---- miniprogram/constant/app.ts | 2 +- miniprogram/constant/error.ts | 10 +++--- miniprogram/interface/error.ts | 8 +---- miniprogram/models/error.ts | 33 ++++++------------ miniprogram/pages/shorturl/index.json | 4 ++- miniprogram/pages/shorturl/index.ts | 21 +++++------- miniprogram/pages/shorturl/index.wxml | 2 ++ miniprogram/pages/totp/edit.json | 2 ++ miniprogram/pages/totp/edit.ts | 49 ++++++++++++++++++--------- miniprogram/pages/totp/edit.wxml | 5 +++ miniprogram/pages/totp/index.json | 3 +- miniprogram/pages/totp/index.ts | 49 ++++++++++++++++----------- miniprogram/pages/totp/index.wxml | 2 ++ miniprogram/pages/user/edit.json | 4 ++- miniprogram/pages/user/edit.ts | 30 ++++++++-------- miniprogram/pages/user/edit.wxml | 2 ++ miniprogram/utils/http.ts | 32 ++++++++++------- 20 files changed, 168 insertions(+), 134 deletions(-) diff --git a/miniprogram/api/shorturl.ts b/miniprogram/api/shorturl.ts index a61b85d..aeec42b 100644 --- a/miniprogram/api/shorturl.ts +++ b/miniprogram/api/shorturl.ts @@ -1,16 +1,16 @@ import http from '@utils/http' import { URL } from '@constant/shortlink' import { CODE } from '@constant/error' -import { HttpApiError } from '@models/error' +import { HttpError } from '@models/error' import logger from '@utils/logger' const create = async (link: string) => { try { return await http.post(URL.CREATE, {link} as IShortlinkCreateRequest) } catch (e) { - logger.error('创建短链接失败', e.code, e.message) - - return Promise.reject(new HttpApiError(CODE.HTTP_API_SHORTLINK_CREATE)) + logger.error('创建短链接失败', e) + + throw new HttpError(CODE.HTTP_API_SHORTLINK_CREATE, e.message); } } diff --git a/miniprogram/api/totp.ts b/miniprogram/api/totp.ts index 1baf87f..49f9d64 100644 --- a/miniprogram/api/totp.ts +++ b/miniprogram/api/totp.ts @@ -1,16 +1,16 @@ import http from '@utils/http' import { URL } from '@constant/totp' import { CODE } from '@constant/error' -import { HttpApiError } from '@models/error' +import { HttpError } from '@models/error' import logger from '@utils/logger' const all = async () => { try { return await http.post(URL.ALL) } catch (e) { - logger.error('查询 TOTP 列表失败', e.code, e.message) + logger.error('查询 TOTP 列表失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_TOTP_ALL)) + throw new HttpError(CODE.HTTP_API_TOTP_ALL, e.message) } } @@ -18,9 +18,9 @@ const detail = async (id: number) => { try { return await http.post(URL.DETAIL, {id} as ITotpDetailRequest) } catch (e) { - logger.error('查询 TOTP 详情失败', e.code, e.message) + logger.error('查询 TOTP 详情失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_TOTP_DETAIL)) + throw new HttpError(CODE.HTTP_API_TOTP_DETAIL, e.message) } } @@ -28,9 +28,9 @@ const create = async (uri: string) => { try { return await http.post(URL.CREATE, {uri} as ITotpCreateRequest) } catch (e) { - logger.error('创建 TOTP 失败', e.code, e.message) + logger.error('创建 TOTP 失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_TOTP_CREATE)) + throw new HttpError(CODE.HTTP_API_TOTP_CREATE, e.message) } } @@ -38,9 +38,9 @@ const update = async (data: ITotpUpdateRequest) => { try { return await http.post(URL.UPDATE, data) } catch (e) { - logger.error('更新 TOTP 信息失败', e.code, e.message) + logger.error('更新 TOTP 信息失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_TOTP_UPDATE)) + throw new HttpError(CODE.HTTP_API_TOTP_UPDATE, e.message) } } @@ -48,9 +48,9 @@ const deleteTotp = async (id: number) => { try { return await http.post(URL.DELETE, {id} as ITotpDeleteRequest) } catch (e) { - logger.error('删除 TOTP 失败', e.code, e.message) + logger.error('删除 TOTP 失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_TOTP_ALL)) + throw new HttpError(CODE.HTTP_API_TOTP_ALL, e.message) } } diff --git a/miniprogram/api/user.ts b/miniprogram/api/user.ts index 5d2b69c..a58badd 100644 --- a/miniprogram/api/user.ts +++ b/miniprogram/api/user.ts @@ -2,15 +2,15 @@ import http from '@utils/http' import { URL } from '@constant/user' import { CODE } from '@constant/error' import logger from '@utils/logger' -import { HttpApiError } from '@models/error' +import { HttpError } from '@models/error' const login = async (code: string) => { try { return await http.post(URL.LOGIN, {code} as IUserLoginRequest, false, false) } catch (e) { - logger.error('登录接口请求失败', e.code, e.message) + logger.error('登录接口请求失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_USER_LOGIN)) + throw new HttpError(CODE.HTTP_API_USER_LOGIN, e.message) } } @@ -18,9 +18,9 @@ const detail = async () => { try { return await http.post(URL.DETAIL) } catch (e) { - logger.error('查询用户详情失败', e.code, e.message) + logger.error('查询用户详情失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_USER_DETAIL)) + throw new HttpError(CODE.HTTP_API_USER_DETAIL, e.message) } } @@ -28,9 +28,9 @@ const update = async (updated: IUserUpdateRequest) => { try { return await http.post(URL.UPDATE, updated) } catch (e) { - logger.error('更新用户信息失败', e.code, e.message) + logger.error('更新用户信息失败', e) - return Promise.reject(new HttpApiError(CODE.HTTP_API_USER_UPDATE)) + throw new HttpError(CODE.HTTP_API_USER_UPDATE, e.message) } } diff --git a/miniprogram/constant/app.ts b/miniprogram/constant/app.ts index 1734ed8..4c8d32e 100644 --- a/miniprogram/constant/app.ts +++ b/miniprogram/constant/app.ts @@ -4,7 +4,7 @@ const STORAGE = { } const URL = { - BASE: 'https://miniprogram.ysdor.cn', + BASE: 'https://miniprogram.yanda.net.cn', } export { STORAGE, URL } \ No newline at end of file diff --git a/miniprogram/constant/error.ts b/miniprogram/constant/error.ts index 67ad432..00f20b1 100644 --- a/miniprogram/constant/error.ts +++ b/miniprogram/constant/error.ts @@ -9,8 +9,6 @@ const CODE = { LOGIN: 1000, // http 调用错误 HTTP: 2000, - // http 业务错误 - HTTP_API: 2001, // http 内部参数错误 HTTP_PARAMS: 2002, // http 业务错误 - 用户接口 @@ -36,7 +34,6 @@ const MESSAGE = { [CODE.LOGIN]: '登录失败', [CODE.HTTP]: '网络请求失败', [CODE.HTTP_PARAMS]: '内部参数错误', - [CODE.HTTP_API]: '业务处理失败', [CODE.HTTP_API_USER_LOGIN]: '业务登录失败', [CODE.HTTP_API_USER_DETAIL]: '查询详情失败', [CODE.HTTP_API_USER_UPDATE]: '更新失败', @@ -48,4 +45,9 @@ const MESSAGE = { [CODE.HTTP_API_SHORTLINK_CREATE]: '生成失败', } -export { CODE, MESSAGE } \ No newline at end of file +const WECHAT_MESSAGE = { + 3: '系统权限未授予微信', + 5: '请求超时', +} + +export { CODE, MESSAGE, WECHAT_MESSAGE } \ No newline at end of file diff --git a/miniprogram/interface/error.ts b/miniprogram/interface/error.ts index 75b6d3c..9c7ef12 100644 --- a/miniprogram/interface/error.ts +++ b/miniprogram/interface/error.ts @@ -4,18 +4,12 @@ interface IERROR { } interface ILoginError extends IERROR { - describe?: string, } interface IHttpError extends IERROR { - describe?: string, url?: string, headers?: IRequestHeaders, - timeout?: number, -} - -interface IHttpApiError extends IERROR { query?: IRequestQuery, data?: IRequestData, - headers?: IRequestHeaders, + timeout?: number, } diff --git a/miniprogram/models/error.ts b/miniprogram/models/error.ts index ddd6313..434de1b 100644 --- a/miniprogram/models/error.ts +++ b/miniprogram/models/error.ts @@ -5,45 +5,34 @@ class EError extends Error implements IERROR { constructor(code?: number, message?: string) { super() - + this.code = code || CODE.UNKNOWN - this.message = message || MESSAGE[this.code] + this.message = message || MESSAGE[this.code] || MESSAGE[CODE.UNKNOWN] } } -class WeixinError extends EError {} +class WeixinError extends EError { + constructor(code?: number, message?: string) { + super(code || CODE.WEIXIN, message) + } +} class LoginError extends EError implements ILoginError { - describe?: string; - - constructor(describe?: string, code?: number, message?: string) { + constructor(code?: number, message?: string) { super(code || CODE.LOGIN, message) - - this.describe = describe } } class HttpError extends EError implements IHttpError { - describe?: string; url?: string; headers?: IRequestHeaders; - timeout?: number; - - constructor(describe?: string, code?: number, message?: string) { - super(code || CODE.HTTP, message) - - this.describe = describe - } -} - -class HttpApiError extends EError implements IHttpApiError { query?: IRequestQuery; data?: IRequestData; - headers?: IRequestHeaders; + timeout?: number; constructor(code?: number, message?: string) { - super(code || CODE.HTTP_API, message) + super(code || CODE.HTTP, message) } } -export { EError, WeixinError, LoginError, HttpError, HttpApiError } \ No newline at end of file +export { EError, WeixinError, LoginError, HttpError } \ No newline at end of file diff --git a/miniprogram/pages/shorturl/index.json b/miniprogram/pages/shorturl/index.json index 2a7fefb..853909c 100644 --- a/miniprogram/pages/shorturl/index.json +++ b/miniprogram/pages/shorturl/index.json @@ -1,4 +1,6 @@ { - "usingComponents": {}, + "usingComponents": { + "mp-toptips": "weui-miniprogram/toptips/toptips" + }, "navigationBarTitleText": "短链生成" } \ No newline at end of file diff --git a/miniprogram/pages/shorturl/index.ts b/miniprogram/pages/shorturl/index.ts index 1501eeb..f7da8c7 100644 --- a/miniprogram/pages/shorturl/index.ts +++ b/miniprogram/pages/shorturl/index.ts @@ -2,27 +2,22 @@ import api from '@api/shorturl' Page({ data: { + toptipError: '', link: '', shortlink: '' }, async submit(e: any) { - await wx.showToast({title: '生成中', icon: 'loading', mask: true, duration: 3000}) + await wx.showLoading({title: '生成中', mask: true}) const { link } = e.detail.value - const { shortlink } = await api.create(link) - - if ((shortlink ?? '') == '') { - await wx.showToast({title: '生成失败', icon: 'error'}) - return; - } - - this.setData({ - link, - shortlink, + api.create(link).then(({shortlink}) => { + this.setData({link, shortlink}) + }).catch((e) => { + this.setData({toptipError: e.message}); + }).finally(async () => { + await wx.hideLoading(); }) - - await wx.hideToast() }, async copy() { if (this.data.shortlink == '') { diff --git a/miniprogram/pages/shorturl/index.wxml b/miniprogram/pages/shorturl/index.wxml index 8c918c3..9f1b86d 100644 --- a/miniprogram/pages/shorturl/index.wxml +++ b/miniprogram/pages/shorturl/index.wxml @@ -1,3 +1,5 @@ + +
diff --git a/miniprogram/pages/totp/edit.json b/miniprogram/pages/totp/edit.json index 77bc680..971b43c 100644 --- a/miniprogram/pages/totp/edit.json +++ b/miniprogram/pages/totp/edit.json @@ -1,5 +1,7 @@ { "usingComponents": { + "mp-dialog": "weui-miniprogram/dialog/dialog", + "mp-toptips": "weui-miniprogram/toptips/toptips" }, "navigationBarTitleText": "备注身份验证器" } \ No newline at end of file diff --git a/miniprogram/pages/totp/edit.ts b/miniprogram/pages/totp/edit.ts index 4371e7c..bfb87b6 100644 --- a/miniprogram/pages/totp/edit.ts +++ b/miniprogram/pages/totp/edit.ts @@ -2,6 +2,9 @@ import api from '@api/totp' Page({ data: { + toptipError: '', + dialogShow: false, + dialogButtons: [{"text": "取消"}, {"text": "重试"}], id: 0, issuer: '', username: '', @@ -10,30 +13,44 @@ Page({ this.data.id = Number(query.id || 0) }, async onShow() { - const {id, issuer, username} = await api.detail(this.data.id) + await wx.showLoading({title: '加载中'}) - this.setData({ - id, - issuer: issuer ?? '', - username: username ?? '', - }) + api.detail(this.data.id).then(({id, issuer, username}) => { + this.setData({id, issuer: issuer ?? '', username: username ?? ''}) + }).catch(() => { + this.setData({dialogShow: true}) + }).finally(() => wx.hideLoading()) }, async submit(e: any) { await wx.showToast({title: '更新中', icon: 'loading', mask: true, duration: 3000}) - await api.update({id: this.data.id, ...e.detail.value} as ITotpUpdateRequest) - - wx.showToast({ - title: '修改成功', - icon: 'success', - success: () => { - setTimeout(() => { - wx.navigateBack() - }, 1500); - } + api.update({id: this.data.id, ...e.detail.value} as ITotpUpdateRequest) + .then(() => { + wx.showToast({ + title: '修改成功', + icon: 'success', + mask: true, + success: () => { + setTimeout(() => wx.navigateBack(), 1500); + } + }) + }).catch(() => { + this.setData({toptipError: e.message}) }) }, async cancel() { await wx.navigateBack() + }, + dialogTap(e: any) { + this.setData({dialogShow: false}) + + const {index} = e.detail + + if (index === 1) { + this.onShow() + } + }, + dialogClose() { + this.setData({dialogShow: false}) } }) \ No newline at end of file diff --git a/miniprogram/pages/totp/edit.wxml b/miniprogram/pages/totp/edit.wxml index b251733..85a2a43 100644 --- a/miniprogram/pages/totp/edit.wxml +++ b/miniprogram/pages/totp/edit.wxml @@ -1,3 +1,8 @@ + + + 请问是否重试? + + diff --git a/miniprogram/pages/totp/index.json b/miniprogram/pages/totp/index.json index bd6b601..56a534e 100644 --- a/miniprogram/pages/totp/index.json +++ b/miniprogram/pages/totp/index.json @@ -1,7 +1,8 @@ { "usingComponents": { "mp-icon": "weui-miniprogram/icon/icon", - "mp-loading": "weui-miniprogram/loading/loading" + "mp-toptips": "weui-miniprogram/toptips/toptips", + "mp-dialog": "weui-miniprogram/dialog/dialog" }, "navigationBarTitleText": "TOTP身份验证器" } \ No newline at end of file diff --git a/miniprogram/pages/totp/index.ts b/miniprogram/pages/totp/index.ts index 28ae1e5..b584320 100644 --- a/miniprogram/pages/totp/index.ts +++ b/miniprogram/pages/totp/index.ts @@ -4,6 +4,7 @@ import { WeixinError } from '@models/error' Page({ data: { + toptipError: '', remainSeconds: 30, items: [] as ITotpItem[], intervalIdentity: 0, @@ -15,6 +16,8 @@ Page({ this.timing() if (this.data.isScanQrCode) { + this.data.isScanQrCode = false + return; } @@ -52,19 +55,21 @@ Page({ async all() { await wx.showLoading({title: '加载中'}) - const response = await api.all() - - const items: ITotpItem[] = [] - response.forEach((v: ITotpItemResponse) => { - items.push({ - isTouchMove: false, - ...v + api.all().then((response) => { + const items: ITotpItem[] = [] + response.forEach((v: ITotpItemResponse) => { + items.push({ + isTouchMove: false, + ...v + }) }) + + this.setData({items}) + }).catch((e) => { + this.setData({toptipError: e.message}) + }).finally(async () => { + await wx.hideLoading() }) - - this.setData({items}) - - await wx.hideLoading() }, async create() { this.data.isScanQrCode = true @@ -73,22 +78,28 @@ Page({ this.data.isScanQrCode = false - await api.create(scan.result) - - await this.all() + api.create(scan.result).catch(async (e) => { + this.setData({toptipError: e.message}) + await this.all() + }) }, async edit(e: any) { - await wx.navigateTo({url: '/pages/totp/edit?id=' + e.currentTarget.dataset.id}) - this.clearInterval() + + await wx.navigateTo({url: '/pages/totp/edit?id=' + e.currentTarget.dataset.id}) }, async delete(e: any) { const result = await wx.showModal({title: '是否确定删除?', content: '删除后数据不可恢复'}) - if (result.confirm) { - await api.deleteTotp(e.currentTarget.dataset.id) - await this.all() + if (result.cancel) { + return; } + + api.deleteTotp(e.currentTarget.dataset.id).catch((e) => { + this.setData({toptipError: e.message}) + }).finally(async () => { + await this.all() + }) }, clearInterval() { clearInterval(this.data.intervalIdentity) diff --git a/miniprogram/pages/totp/index.wxml b/miniprogram/pages/totp/index.wxml index 252a615..4d3c00b 100644 --- a/miniprogram/pages/totp/index.wxml +++ b/miniprogram/pages/totp/index.wxml @@ -1,3 +1,5 @@ + + 暂无数据 diff --git a/miniprogram/pages/user/edit.json b/miniprogram/pages/user/edit.json index 8835af0..96ea0eb 100644 --- a/miniprogram/pages/user/edit.json +++ b/miniprogram/pages/user/edit.json @@ -1,3 +1,5 @@ { - "usingComponents": {} + "usingComponents": { + "mp-toptips": "weui-miniprogram/toptips/toptips" + } } \ No newline at end of file diff --git a/miniprogram/pages/user/edit.ts b/miniprogram/pages/user/edit.ts index 3f3c0e3..1a1c24f 100644 --- a/miniprogram/pages/user/edit.ts +++ b/miniprogram/pages/user/edit.ts @@ -5,6 +5,7 @@ const app = getApp() Page({ data: { + toptipError: '', avatar: app.globalData.user.avatar, nickname: app.globalData.user.nickname, slogan: app.globalData.user.slogan, @@ -25,7 +26,7 @@ Page({ filePath: res.tempFilePath, encoding: 'base64', success: async (res: any) => { - this.setData({ avatar: "data:image/png;base64," + res.data }) + this.setData({ avatar: "data:image/jpeg;base64," + res.data }) await wx.hideLoading() } @@ -34,19 +35,20 @@ Page({ async submit(e: any) { await wx.showToast({title: '更新中', icon: 'loading', mask: true, duration: 3000}) - await api.update(e.detail.value as IUserUpdateRequest) - - // 同步完成之后更新下全局的用户信息状态 - await utils.sync() - - wx.showToast({ - title: '修改成功', - icon: 'success', - success: () => { - setTimeout(() => { - wx.navigateBack() - }, 1500); - } + api.update(e.detail.value as IUserUpdateRequest).catch((e) => { + this.setData({toptipError: e.message}) + }).then(async () => { + // 同步完成之后更新下全局的用户信息状态 + await utils.sync() + + wx.showToast({ + title: '修改成功', + icon: 'success', + mask: true, + success: () => { + setTimeout(() => wx.navigateBack(), 1000); + } + }) }) }, async cancel() { diff --git a/miniprogram/pages/user/edit.wxml b/miniprogram/pages/user/edit.wxml index 655d5c2..a365a0f 100644 --- a/miniprogram/pages/user/edit.wxml +++ b/miniprogram/pages/user/edit.wxml @@ -1,3 +1,5 @@ + + diff --git a/miniprogram/utils/http.ts b/miniprogram/utils/http.ts index 31b4fe3..214c407 100644 --- a/miniprogram/utils/http.ts +++ b/miniprogram/utils/http.ts @@ -1,6 +1,6 @@ import { URL } from '@constant/app' -import { CODE, MESSAGE } from '@constant/error' -import { HttpError, HttpApiError, LoginError } from '@models/error' +import { CODE, WECHAT_MESSAGE } from '@constant/error' +import { HttpError, LoginError } from '@models/error' import userUtils from '@utils/user' import logger from '@utils/logger' @@ -46,7 +46,7 @@ const request = (request: IRequest, mustOpenId?: boolean): Promise => { } const wxRequest = (request: IRequest) => { - logger.info('请求接口', request) + logger.info('请求接口', request.url.indexOf('users/update') === -1 ? request : '用户更新') return new Promise((resolve, reject) => { wx.request({ @@ -54,33 +54,35 @@ const wxRequest = (request: IRequest) => { data: request.data || {}, header: request.headers ?? {}, timeout: request.timeout || 3000, - method: request.method || 'POST', + method: request.method || 'GET', success: (res: any) => { logger.info('接口请求成功', request.url.indexOf('users/detail') === -1 ? res : '用户详情') - if (res.data.code == 0) { + if (Number(res.data.code) === 0) { resolve(res.data.data) } - reject(new HttpApiError(res.data.code as number, res.data.message as string)) + reject(new HttpError(parseInt(res.data.code), res.data.message as string)) }, - fail: (err) => { + fail: (err: any) => { logger.warning('接口请求失败', err) - reject(new HttpError(err.errMsg)) + reject(new HttpError(err.errno, WECHAT_MESSAGE[err.errno as keyof typeof WECHAT_MESSAGE] || ('接口请求失败:' + err.errMsg))) }, }) }) } const wxUpload = (request: IRequest) => { + logger.info('请求上传接口', request.url, request.headers) + return new Promise((resolve, reject) => { const filePath: string = request.data?.filePath ?? '' const name: string = request.data?.name ?? '' const formData: IRequestData = request.data ?? {} if (!filePath || !name) { - reject(new HttpError(MESSAGE[CODE.HTTP_API])) + reject(new HttpError(CODE.HTTP_PARAMS)) } delete formData.filePath @@ -94,25 +96,29 @@ const wxUpload = (request: IRequest) => { header: request.headers ?? {}, timeout: request.timeout || 10000, success: (res: any) => { + logger.info('接口请求成功', res) + if (res.data.code == 0) { resolve(res.data.data) } - reject(new HttpApiError(res.data.code as number, res.data.message as string)) + reject(new HttpError(parseInt(res.data.code), res.data.message as string)) }, fail: (err) => { - reject(new HttpError(err.errMsg)) + logger.warning('接口请求失败', err) + + reject(new HttpError(undefined, '接口请求失败:' + err.errMsg)) }, }) }) } const post = (url: string, data?: IRequestData, isUploadFile?: boolean, mustOpenId?: boolean): Promise => { - return request({url, data, isUploadFile} as IRequest, mustOpenId) + return request({url, data, isUploadFile, method: 'POST'} as IRequest, mustOpenId) } const get = (url: string, query?: IRequestQuery, mustOpenId?: boolean): Promise => { - return request({url, query} as IRequest, mustOpenId) + return request({url, query, method: 'GET'} as IRequest, mustOpenId) } export default { request, post, get }