diff --git a/app.js b/app.js index cf443c5..2360b59 100644 --- a/app.js +++ b/app.js @@ -1,13 +1,10 @@ -// app.js -const request = require('./utils/http.js'); - +//app.js App({ onLaunch() { // 展示本地存储能力 - const logs = wx.getStorageSync('logs') || [] - logs.unshift(Date.now()) - wx.setStorageSync('logs', logs) - + // const logs = wx.getStorageSync('logs') || [] + // logs.unshift(Date.now()) + // wx.setStorageSync('logs', logs) // 登录 wx.login({ success: res => { @@ -16,6 +13,6 @@ App({ }) }, globalData: { - userInfo: null + userInfo: null, } }) \ No newline at end of file diff --git a/app.json b/app.json index 7508301..35a1cbc 100644 --- a/app.json +++ b/app.json @@ -1,14 +1,17 @@ { - "pages": [ - "pages/index/index" - ], - "window": { - "navigationBarTextStyle": "black", - "navigationBarTitleText": "Weixin", - "navigationBarBackgroundColor": "#ffffff" - }, - "style": "v2", - "componentFramework": "glass-easel", - "sitemapLocation": "sitemap.json", - "lazyCodeLoading": "requiredComponents" -} + "pages": [ + "pages/index/index" + ], + "window": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "Weixin", + "navigationBarBackgroundColor": "#ffffff" + }, + "style": "v2", + "componentFramework": "glass-easel", + "sitemapLocation": "sitemap.json", + "lazyCodeLoading": "requiredComponents", + "useExtendedLib": { + "weui": true + } +} \ No newline at end of file diff --git a/app.wxss b/app.wxss index 06c6fc9..60fcf5b 100644 --- a/app.wxss +++ b/app.wxss @@ -3,8 +3,7 @@ height: 100%; display: flex; flex-direction: column; - align-items: center; + align-items: flex-start; justify-content: space-between; - padding: 200rpx 0; box-sizing: border-box; -} +} diff --git a/pages/index/index.js b/pages/index/index.js index afd82da..a167428 100644 --- a/pages/index/index.js +++ b/pages/index/index.js @@ -1,6 +1,6 @@ -// index.js -const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0' var app = getApp(); +var defaultAvatarUrl = ''; +import AuthService from '../../utils/api/testapi'; Page({ data: { @@ -13,10 +13,22 @@ Page({ canIUseGetUserProfile: wx.canIUse('getUserProfile'), canIUseNicknameComp: wx.canIUse('input.type.nickname'), }, + onLoad() { + console.log(wx.getUserProfile) + }, + getUserPhoneNumber(e) { + console.log(e.detail) + }, bindViewTap() { - wx.navigateTo({ - url: '../logs/logs' - }) + AuthService.login({ + name: '223', + pwd: '1234' + }) + .then(res => { + console.log(res) + }, err => { + console.log(err) + }) }, onChooseAvatar(e) { const { diff --git a/pages/index/index.json b/pages/index/index.json index b55b5a2..fcb1cdc 100644 --- a/pages/index/index.json +++ b/pages/index/index.json @@ -1,4 +1,5 @@ { - "usingComponents": { - } + "usingComponents": { + "mp-icon": "weui-miniprogram/icon/icon" + } } \ No newline at end of file diff --git a/pages/index/index.wxml b/pages/index/index.wxml index 637743e..ef4d586 100644 --- a/pages/index/index.wxml +++ b/pages/index/index.wxml @@ -1,6 +1,13 @@ - + + + + + + + + sss \ No newline at end of file diff --git a/pages/index/index.wxss b/pages/index/index.wxss index 1ebed4b..8a18a97 100644 --- a/pages/index/index.wxss +++ b/pages/index/index.wxss @@ -7,6 +7,9 @@ page { .scrollarea { flex: 1; overflow-y: hidden; + height: 100vh; + width: 100vw; + overflow: hidden; } .userinfo { diff --git a/project.private.config.json b/project.private.config.json index b4b90e6..9266258 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -2,6 +2,7 @@ "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", "projectname": "gov_propagandize", "setting": { - "compileHotReLoad": true + "compileHotReLoad": true, + "urlCheck": false } } \ No newline at end of file diff --git a/utils/api/testapi.js b/utils/api/testapi.js index f40593d..7b70902 100644 --- a/utils/api/testapi.js +++ b/utils/api/testapi.js @@ -1,83 +1,44 @@ -// 引入 request 文件 -import request from '@/utils/request'; +import { + request +} from "../http"; -// 以下 api 为示例,实际与项目相匹配 +// 管理地址,个人习惯,喜欢的下载request参数中也行 +const apiPath = { + login: "/api/v1/login" +} +class AuthService { + static login(data) { + // 按住ctrl点击wx.request进入ts声明看options的类型,method是均大写的,对应即可 + return request(apiPath.login, "GET", data) -// 分页查询学习列表 -export const pageStudyInfo = (params) => { - return request({ - url: '/study/studyInfo/page', - method: 'GET', - data: params - }); -}; + // 由于request的参数顺序第四个才是查询参数,所以如果需要传递,第三个传输传空对象即可 + // return request(apiPath.login, "GET", {}, data) + } +} -// 查询学习列表 -export const listStudyInfo = (params) => { - return request({ - url: '/study/studyInfo/list', - method: 'GET', - data: params - }); -}; - -// 获取学习列表详细信息 -export const studyInfoById = (id) => { - return request({ - url: `/study/studyInfo/${id}`, - method: 'GET', - }); -}; - -// 增加学习列表 -export const saveStudyInfo = (params) => { - return request({ - url: '/study/studyInfo', - method: 'POST', - data: params - }); -}; - -// 修改学习列表 -export const updateStudyInfo = (params) => { - return request({ - url: '/study/studyInfo', - method: 'PUT', - data: params - }); -}; - -// 删除学习列表 -export const deleteStudyInfo = (id) => { - return request({ - url: `/study/studyInfo/delete?id=${id}`, - method: 'DELETE', - }); -}; +export default AuthService; +// import AuthService from "../../service/AuthService"; +// // 导入封装好的服务层 - - - -// Page({ -// data: { -// studyList: [] -// }, - -// onLoad: function () { -// this.getStudyList(); -// }, - -// getStudyList: async function () { -// try { -// const res = await pageStudyInfo(this.data.queryParams); -// console.log(res.data.records); -// this.setData({ -// studyList: res.data.records -// }); -// } catch (error) { -// console.error(error); -// } +// // 其他代码省略 +// page({ +// // Promise语法 +// submitForm(){ +// AuthService.login({username:"a",password:"2"}).then(res=>{ +// // 干点别的 +// },err=>{ +// // 出错了干点啥 +// }) +// }, +// // async-await语法糖 +// async asycsubmitForm(){ +// try{ +// const res = await AuthService.login({username:"abc",password:"123"}); +// // 干点别的 +// }catch(err){ +// // 错了干点啥? // } -// }); \ No newline at end of file +// } +// }) \ No newline at end of file diff --git a/utils/cache.js b/utils/cache.js new file mode 100644 index 0000000..329b603 --- /dev/null +++ b/utils/cache.js @@ -0,0 +1,53 @@ +// 缓存工具类 +const CACHE_PREFIX = 'daqi_'; +const DEFAULT_CACHE_TIME = 5 * 60 * 1000; // 默认缓存5分钟 + +class Cache { + /** + * 设置缓存 + * @param {string} key 缓存键 + * @param {any} value 缓存值 + * @param {number} expire 过期时间(毫秒) + */ + static set(key, value, expire = DEFAULT_CACHE_TIME) { + const data = { + value, + expire: expire ? new Date().getTime() + expire : null + }; + wx.setStorageSync(CACHE_PREFIX + key, JSON.stringify(data)); + } + + /** + * 获取缓存 + * @param {string} key 缓存键 + * @returns {any} 缓存值 + */ + static get(key) { + const data = wx.getStorageSync(CACHE_PREFIX + key); + if (!data) return null; + + const cache = JSON.parse(data); + if (cache.expire && cache.expire < new Date().getTime()) { + wx.removeStorageSync(CACHE_PREFIX + key); + return null; + } + return cache.value; + } + + /** + * 删除缓存 + * @param {string} key 缓存键 + */ + static remove(key) { + wx.removeStorageSync(CACHE_PREFIX + key); + } + + /** + * 清空所有缓存 + */ + static clear() { + wx.clearStorageSync(); + } +} + +module.exports = Cache; diff --git a/utils/format.js b/utils/format.js new file mode 100644 index 0000000..cf79084 --- /dev/null +++ b/utils/format.js @@ -0,0 +1,59 @@ +const { formatNumber } = require('./date'); + +// 格式化金额 +const formatAmount = (amount, decimals = 2) => { + if (!amount && amount !== 0) return '--'; + return Number(amount).toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ','); +}; + +// 格式化数量(支持万、亿单位) +const formatQuantity = (num) => { + if (!num && num !== 0) return '--'; + if (num >= 100000000) { + return (num / 100000000).toFixed(2) + '亿'; + } + if (num >= 10000) { + return (num / 10000).toFixed(2) + '万'; + } + return formatNumber(num); +}; + +// 格式化文件大小 +const formatFileSize = (bytes) => { + if (!bytes && bytes !== 0) return '--'; + const units = ['B', 'KB', 'MB', 'GB', 'TB']; + let num = bytes; + let index = 0; + while (num >= 1024 && index < units.length - 1) { + num /= 1024; + index++; + } + return num.toFixed(2) + units[index]; +}; + +// 格式化手机号 +const formatPhone = (phone) => { + if (!phone) return ''; + return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'); +}; + +// 格式化身份证号 +const formatIdCard = (idCard) => { + if (!idCard) return ''; + return idCard.replace(/(\d{4})\d{10}(\d{4})/, '$1**********$2'); +}; + +// 格式化银行卡号 +const formatBankCard = (cardNo) => { + if (!cardNo) return ''; + return cardNo.replace(/(\d{4})\d+(\d{4})/, '$1 **** **** $2'); +}; + +module.exports = { + formatAmount, + formatQuantity, + formatFileSize, + formatPhone, + formatIdCard, + formatBankCard +}; diff --git a/utils/http.js b/utils/http.js index a61fc07..ef42c1b 100644 --- a/utils/http.js +++ b/utils/http.js @@ -1,86 +1,67 @@ -// 全局请求封装 -const base_url = 'http://localhost:996'; +// 定义api服务地址 +const baseUrl = 'http://dev.com:12345'; -export default (params) => { - let url = params.url; - let method = params.method || "GET"; - let data = params.data || {}; - let header = {}; +/** + * 传入请求参数,返回Promise支持链试调用 + * @param url 请求地址 + * @param method 请求方法类型,不传入默认是"GET" + * @param data 请求体数据 + * @param params 请求参数 + */ +function request(url, method = "GET", data = {}, params = {}) { + const header = { + "content-type": "application/json" + // 有其他content-type需求加点逻辑判断处理即可 + } + //TODO 获取token,有就丢进请求头 + // const tokenString = wx.getStorageSync("access_token"); + // if (tokenString) { + // header.Authorization = `Bearer ${tokenString}`; + // } + return new Promise(function (resolve, reject) { + // 判断是否传递了query参数,有则进行地址拼接 + // if (params) { + // url += "?" + urlEncode(params) + // } + wx.showLoading({ + title: '加载中...', + mask: true //显示蒙层 + }) + wx.request({ + url: baseUrl + url, + timeout: 8000, + method, + data, + dataType: "json", // 微信官方文档中介绍会对数据进行一次JSON.parse + header, + success(res) { + wx.hideLoading(); + console.log(res); + // HTTP状态码为200才视为成功 + if (res.statusCode === 200) { + // 真正的数据响应体中还有一层success字段判断业务状态,按实际情况处理 + if (res.data.success) { + resolve(res.data.result) + } else { + // 业务判断错误 + reject(res) + } + } else { + // wx.request的特性,只要有响应就会走success回调,所以在这里判断状态,非200的均视为请求失败 + reject(res) + } + }, + fail(err) { + wx.hideLoading(); + // 断网、服务器挂了都会fail回调,直接reject即可 + reject(err) + } + }) + }) +} - if (method == "POST") { - header = { - 'content-type': 'application/json' - }; - } - - // 获取本地token - const token = wx.getStorageSync("token"); - if (token) { - header['Authorization'] = 'Bearer ' + token; - } - - return new Promise((resolve, reject) => { - wx.request({ - url: base_url + url, - method: method, - header: header, - data: data, - success(response) { - const res = response.data; - if (res.statusCode == 200) { - resolve(res); - } else { - wx.clearStorageSync(); - switch (res.statusCode) { - case 401: - wx.showModal({ - title: "提示", - content: "请登录", - showCancel: false, - success(res) { - setTimeout(() => { - wx.navigateTo({ - url: "/pages/login/index", - }); - }, 1000); - }, - }); - break; - case 404: - wx.showToast({ - title: '请求地址不存在...', - duration: 2000, - }); - break; - default: - wx.showToast({ - title: '请重试...', - duration: 2000, - }); - break; - } - } - }, - fail(err) { - console.log(err); - if (err.errMsg.indexOf('request:fail') !== -1) { - wx.showToast({ - title: '网络异常', - icon: "error", - duration: 2000 - }); - } else { - wx.showToast({ - title: '未知异常', - duration: 2000 - }); - } - reject(err); - }, - complete() { - wx.hideLoading(); - wx.hideToast(); - } - }); - }).catch((e) => {}); -}; \ No newline at end of file +// 导出请求和服务地址 +export { + request, + baseUrl +} \ No newline at end of file diff --git a/utils/storage.js b/utils/storage.js new file mode 100644 index 0000000..800bc52 --- /dev/null +++ b/utils/storage.js @@ -0,0 +1,75 @@ +/** + * 存储管理工具 + */ + +const STORAGE_PREFIX = 'enterprise_'; + +// 获取完整的存储键名 +const getFullKey = (key) => { + return `${STORAGE_PREFIX}${key}`; +}; + +// 设置存储 +const set = (key, data) => { + try { + const fullKey = getFullKey(key); + wx.setStorageSync(fullKey, data); + return true; + } catch (error) { + console.error('Storage set error:', error); + return false; + } +}; + +// 获取存储 +const get = (key, defaultValue = null) => { + try { + const fullKey = getFullKey(key); + const value = wx.getStorageSync(fullKey); + return value || defaultValue; + } catch (error) { + console.error('Storage get error:', error); + return defaultValue; + } +}; + +// 移除存储 +const remove = (key) => { + try { + const fullKey = getFullKey(key); + wx.removeStorageSync(fullKey); + return true; + } catch (error) { + console.error('Storage remove error:', error); + return false; + } +}; + +// 清除所有存储 +const clear = () => { + try { + wx.clearStorageSync(); + return true; + } catch (error) { + console.error('Storage clear error:', error); + return false; + } +}; + +// 获取存储信息 +const info = () => { + try { + return wx.getStorageInfoSync(); + } catch (error) { + console.error('Storage info error:', error); + return null; + } +}; + +module.exports = { + set, + get, + remove, + clear, + info +}; diff --git a/utils/validator.js b/utils/validator.js new file mode 100644 index 0000000..adab592 --- /dev/null +++ b/utils/validator.js @@ -0,0 +1,43 @@ +// 手机号验证 +const isValidPhone = (phone) => { + return /^1[3-9]\d{9}$/.test(phone); +}; + +// 邮箱验证 +const isValidEmail = (email) => { + return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email); +}; + +// URL验证 +const isValidUrl = (url) => { + try { + new URL(url); + return true; + } catch { + return false; + } +}; + +// 身份证号验证 +const isValidIdCard = (idCard) => { + return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(idCard); +}; + +// 企业统一社会信用代码验证 +const isValidCreditCode = (creditCode) => { + return /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/.test(creditCode); +}; + +// 密码强度验证(至少包含数字和字母,长度8-20位) +const isValidPassword = (password) => { + return /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,20}$/.test(password); +}; + +module.exports = { + isValidPhone, + isValidEmail, + isValidUrl, + isValidIdCard, + isValidCreditCode, + isValidPassword +};