// 后端 API 请求工具库 const { BASE_URL, API } = require('./config') /** * 封装 wx.request 为 Promise * @param {object} options - wx.request 参数 * @returns {Promise} 返回 result.data */ function request(options) { return new Promise((resolve, reject) => { wx.request({ timeout: 30000, ...options, success: (res) => { const result = res.data if (result && result.code === 0) { resolve(result.data) } else { reject(new Error(result ? result.message : '请求失败')) } }, fail: (err) => { console.error('请求失败', options.url, err) if (err.errMsg && err.errMsg.indexOf('timeout') !== -1) { reject(new Error('网络请求超时,请检查网络后重试')) } else { reject(new Error('网络异常,请检查网络连接')) } } }) }) } /** * 格式化时间戳为本地日期时间字符串 * @param {string|number} timestamp - 时间戳 * @returns {string} 格式化后的日期时间,如:2024/04/27 18:30:45 */ function formatDateTime(timestamp) { if (!timestamp) return '' const date = new Date(timestamp) const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') const hour = String(date.getHours()).padStart(2, '0') const minute = String(date.getMinutes()).padStart(2, '0') const second = String(date.getSeconds()).padStart(2, '0') return `${year}/${month}/${day} ${hour}:${minute}:${second}` } /** * 格式化记录中的时间字段 * @param {object} record - 含时间字段的记录 * @returns {object} 格式化后的记录 */ function formatRecord(record) { if (!record) return record const formatted = { ...record } if (record.createTime) { formatted.createTime = formatDateTime(record.createTime) } if (record.visitDate) { formatted.visitDate = formatDate(record.visitDate) } if (record.updateTime) { formatted.updateTime = formatDateTime(record.updateTime) } return formatted } /** * 格式化日期为 YYYY-MM-DD 格式 * @param {string|number|Date} date - 日期 * @returns {string} 格式化后的日期,如:2024-04-27 */ function formatDate(date) { if (!date) return '' const d = new Date(date) const year = d.getFullYear() const month = String(d.getMonth() + 1).padStart(2, '0') const day = String(d.getDate()).padStart(2, '0') return `${year}-${month}-${day}` } /** * 将后端 API 返回的预约记录映射为前端模板字段 * 后端: id, visitDate, visitTime → 前端: _id, date, time * @param {object} record - 后端返回的记录 * @returns {object} 映射后的记录 */ function mapApiRecord(record) { if (!record) return null return { ...record, _id: record.id, date: record.visitDate, time: record.visitTime, createTime: record.createTime, updateTime: record.updateTime } } /** * 预约相关 API */ const appointmentDB = { /** * 创建预约 * @param {object} data - 预约表单数据(需包含 openid) * @returns {Promise} 新记录 id */ async create(data) { const result = await request({ url: BASE_URL + API.APPOINTMENT_CREATE, method: 'POST', header: { 'content-type': 'application/json' }, data: { name: data.name, phone: data.phone, company: data.company, reason: data.reason, visitDate: data.date, visitTime: data.time, hostName: data.hostName, area: data.area, openid: data.openid } }) return result.id }, /** * 获取当前用户的预约列表(按创建时间倒序) * @param {string} openid * @returns {Promise} */ async getList(openid) { const list = await request({ url: BASE_URL + API.APPOINTMENT_LIST, method: 'GET', data: { openid } }) return (list || []).map(item => mapApiRecord(item)) }, /** * 获取当前用户最新一条预约 * @param {string} openid * @returns {Promise} */ async getLatest(openid) { const data = await request({ url: BASE_URL + API.APPOINTMENT_LATEST, method: 'GET', data: { openid } }) return mapApiRecord(data) || null }, /** * 取消预约 * @param {string} id - 预约记录 id * @param {string} openid - 当前用户 openid * @returns {Promise} 是否成功 */ async cancel(id, openid) { const result = await request({ url: BASE_URL + API.APPOINTMENT_CANCEL + '?id=' + encodeURIComponent(id) + '&openid=' + encodeURIComponent(openid), method: 'PUT' }) return result === true }, /** * 获取预约详情 * @param {string} id - 预约记录 id * @returns {Promise} */ async getDetail(id) { const data = await request({ url: BASE_URL + API.APPOINTMENT_DETAIL, method: 'GET', data: { id } }) return mapApiRecord(data) || null } } /** * 获取小程序码 * @param {string} scene - 场景值 * @param {string} page - 页面路径 * @returns {Promise} Base64图片数据 */ async function getWxacode(scene, page = 'pages/scan/result/index') { const envVersion = wx.getAccountInfoSync().miniProgram.envVersion const base64Data = await request({ url: BASE_URL + API.WXACODE, method: 'POST', header: { 'content-type': 'application/json' }, data: { scene, page, width: 430, envVersion } }) return `data:image/jpeg;base64,${base64Data}` } module.exports = { request, formatRecord, mapApiRecord, formatDateTime, formatDate, appointmentDB, getWxacode }