《微信小程序》第六章:参数定义与管理

系列文章

《微信小程序》https://blog.csdn.net/sen_shan/category_13069009.html

第五章:登录-API封装https://blog.csdn.net/sen_shan/article/details/153963486?spm=1011.2415.3001.5331

文章目录

目录

系列文章

文章目录

前言

参数定义

请求修改

调试与测试


前言

本文介绍了微信小程序中参数统一管理的实现方案。核心内容包括:

1)通过src/config/index.ts文件实现多环境配置管理,自动区分开发/测试/生产环境;

2)实例request.ts中应用

参数定义

建立src/config/index.ts文件

javascript 复制代码
// src/config/index.ts
type EnvFile = 'dev' | 'test' | 'prod'

function getEnv(): EnvFile { 
	// #ifdef H5
	  const m = import.meta.env.MODE   // vite 环境变量
	  if (m === 'production') return 'prod'
	  if (m === 'test' || m === 'gray') return 'test'
	  return 'dev'
	  // #endif
	
	  // #ifndef H5
	  const v = uni.getAccountInfoSync().miniProgram.envVersion
	  if (v === 'release') return 'prod'
	  if (v === 'trial') return 'test'
	  return 'dev'          // develop / experience
	  // #endif
}

/* 1. 与环境无关的常量 */
const COMMON = {
  TIMEOUT: 15000,
  PAGE_SIZE: 20,
  MAX_RETRY: 3,
  // 任意其他固定值
} as const

/* 2. 与环境有关的差异配置 */
const ENV_CONFIG = {
  dev: {
    API_BASE_URL: 'http://127.0.0.1:8080',
    API_KEY: 'ae139f8f6a8efc2a74a1e852c5cdaa43',
    TRACK_URL: 'http://127.0.0.1:8080',
    ENABLE_VCONSOLE: true,
  },
  test: {
    API_BASE_URL: 'https://test-api.xxx.com',
    API_KEY: 'test-key-123456',
    TRACK_URL: 'https://test-track.xxx.com',
    ENABLE_VCONSOLE: true,
  },
  prod: {
    API_BASE_URL: 'https://api.xxx.com',
    API_KEY: 'prod-key-abcdef',
    TRACK_URL: 'https://track.xxx.com',
    ENABLE_VCONSOLE: false,
  },
} as const

/* 3. 合并后一次性导出 */
export default {
  ...COMMON,
  ...ENV_CONFIG[getEnv()],
} as const

作 用:

根据运行平台与构建环境自动选取对应的后端地址、密钥及功能开关,并统一导出只读常量供全局使用。

核心思路

  1. 先判断平台

H5:读取 Vite 注入的 import.meta.env.MODE

小程序:读取微信/支付宝等宿主提供的 uni.getAccountInfoSync().miniProgram.envVersion

  1. 再映射到 3 套环境

dev | test | prod

  1. 最后把「与环境无关的常量」+「当前环境变量」合并成单例导出

请求修改

修改src\utils\request.ts文件

javascript 复制代码
import config from '@/src/config/index'
/* 配置 ------------------------------------------------------------------ */
const BASE_URL: string = config.API_BASE_URL //'http://8.130.11.167:8080'// 替换你的后端域名
const API_KEY: string = config.API_KEY
const TIMEOUT = config.TIMEOUT // ms

配置导入说明

  1. 配置来源

代码中所有 BASE_URL / API_KEY / TIMEOUT 等常量均统一从 @/src/config/index 自动读取。

该文件会根据运行平台(H5 / 小程序)与构建环境(dev / test / prod)动态返回对应的域名、密钥及功能开关,业务层无需再写 if/else 判断环境。

若后台域名或密钥发生变更,只需修改 src/config/index.ts ,无需逐文件替换。

完整代码如下:

javascript 复制代码
// 顶部引入
import { toastError } from './toast'
import config from '@/src/config/index'
/* 配置 ------------------------------------------------------------------ */
const BASE_URL: string = config.API_BASE_URL //'http://8.130.11.167:8080'// 替换你的后端域名
const API_KEY: string = config.API_KEY
const TIMEOUT = config.TIMEOUT // ms

/* 类型定义 --------------------------------------------------------------- */
export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'

export interface RequestOptions<T = any> {
  url: string
  method?: Method
  data?: T
  headers?: Record<string, string>
  noToken?: boolean // 跳过 token
  noBaseURL?: boolean // 跳过 baseURL
  timeout?: number
}

// 后端统一返回格式(按你的实际改)
export interface HttpResponse<T = any> {
  status_code: number
  status:string
  message: string
  data: T
}

/* 核心请求 --------------------------------------------------------------- */
export function request<R = any>(options: RequestOptions): Promise<HttpResponse<R>> {
  console.log(BASE_URL)
  console.log(API_KEY)
  return new Promise((resolve, reject) => {
    const token = uni.getStorageSync('token')
    const header: AnyObject = {
      'Content-Type': 'application/json; charset=utf-8',
      'x-api-key': API_KEY ,//'ae139f8f6a8efc2a74a1e852c5cdaa43',
      ...options.headers,
    }

    if (!options.noToken && token) header.Authorization = `Bearer ${token}`

    uni.request({
      url: options.noBaseURL ? options.url : `${BASE_URL}${options.url}`,
      method: options.method || 'GET',
      data: options.data || {},
      header,
      timeout: options.timeout || TIMEOUT,
      success: (res) => handleSuccess<R>(res, resolve, reject),
      fail: (err) => handleFail(err, reject),
    })
  })
}

/* 成功处理 --------------------------------------------------------------- */
function handleSuccess<R>(
  res: UniApp.RequestSuccessCallbackResult,
  resolve: (value: HttpResponse<R>) => void,
  reject: (reason?: any) => void,
) {
  const { statusCode, data } = res
  // 成功区间
  if (statusCode >= 200 && statusCode < 300) {
    const resp = data as HttpResponse<R>
    if (resp.status_code === 200) resolve(resp)
    else {
      toastError(resp.message)
      reject(resp)
    }
    return
  }
  // 401 登录态失效
  if (statusCode === 401) {
    const detail = (data as any)?.detail || '登录已过期'
    toastError(detail)
    uni.clearStorageSync()
    uni.reLaunch({ url: '/pages/login/index' })
    reject(new Error(detail))
    return
  }
  // 其他 4xx/5xx
  if (statusCode >= 300) {
    const detail = (data as any)?.detail || `请求失败(${statusCode})`
    toastError(detail)
    reject(new Error(detail))
    return
  }
}

/* 失败处理 --------------------------------------------------------------- */
function handleFail(err: any, reject: (reason?: any) => void) {
  toastError('网络异常')
  reject(err)
}

/* 上传文件 --------------------------------------------------------------- */
export function upload<R = any>(
  url: string,
  filePath: string,
  formData?: Record<string, any>,
  timeout = 30_000,
): Promise<R> {
  const token = uni.getStorageSync('token')
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: `${BASE_URL}${url}`,
      filePath,
      name: 'file',
      formData,
      header: { Authorization: `Bearer ${token}` },
      timeout,
      success: (res) => {
        const data: HttpResponse<R> = JSON.parse(res.data)
        if (data.status_code === 0) resolve(data.data)
        else {
          uni.showToast({ title: data.message || '上传失败', icon: 'none' })
          reject(data)
        }
      },
      fail: reject,
    })
  })
}

/* 导出别名(可选)-------------------------------------------------------- */
export const http = {
  get<R>(url: string, params?: any, returnData = true) {
    return request<R>({ url, data: params }).then(res =>
      returnData ? res.data : res
    )
  },
  post<R>(url: string, data?: any, returnData = true) {
    return request<R>({ url, method: 'POST', data }).then(res =>
      returnData ? res.data : res
    )
  },
  put<R>(url: string, data?: any, returnData = true) {
    return request<R>({ url, method: 'PUT', data }).then(res =>
      returnData ? res.data : res
    )
  },
  delete<R>(url: string, returnData = true) {
    return request<R>({ url, method: 'DELETE' }).then(res =>
      returnData ? res.data : res
    )
  }
}

调试与测试

1.HBuilderX :运行 → 运行至浏览器→Chrome

2.启动后按 F12 打开开发者工具

3.输入任意不存在的用户名及密码,观察登录接口返回

4.输入正确的账号与密码

相关推荐
拖孩17 小时前
流量主门槛从 500 降到 100,我的小程序上线 18 小时够到了线
前端·后端·微信小程序
云-缩影18 小时前
做微信小程序,自建服务器还是用云托管:技术选型对比
服务器·微信小程序·小程序
极限挑战哥1 天前
共享电单车联营平台分账架构实践:二清合规与自动分账零人工方案
java·大数据·人工智能·微信小程序·架构·微信公众平台
超级新零售2 天前
服装订货会数字化:商品版本、订单状态与后续配发数据如何衔接?
大数据·小程序·企业微信
云-缩影2 天前
拆解微信小程序后端架构:ECS、RDS、SSL 和 VPC 怎么配合
微信小程序·架构·ssl
拖孩2 天前
AI 帮我写的小程序上线 44 天:36 个人进了收银台,8 个人付钱
前端·后端·微信小程序
xiezhr2 天前
我用workBuddy开发了自己的第一个小程序并成功上线了
ai·小程序·ai agent·workbuddy
sinat_267611912 天前
用 AI 开发微信小程序(八):一个极简收纳工具的开发复盘
微信小程序·小程序
李纲明3 天前
微信小程序真机预览白屏或 request 失败:先核 request 合法域名与 TLS,再查体验版与本地缓存
缓存·微信小程序·小程序·小程序开发·devdiy·真机预览·合法域名