本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等,旨在规范 API 开发,提高开发效率和代码质量。
template/uni-app/api/
├── activity.js # 活动相关接口
├── admin.js # 管理相关接口
├── api.js # 基础 API 配置
├── kefu.js # 客服相关接口
├── lottery.js # 抽奖相关接口
├── order.js # 订单相关接口
├── public.js # 公共接口
├── store.js # 商城相关接口
└── user.js # 用户相关接口
// 基础 API 配置
const baseURL = 'https://api.crmeb.net';
// 请求超时时间
const timeout = 10000;
// 请求拦截器
const requestInterceptor = (config) => {
// 添加 token
const token = uni.getStorageSync('token');
if (token) {
config.header['Authorization'] = `Bearer ${token}`;
}
// 添加设备信息
config.header['X-Device-Type'] = uni.getSystemInfoSync().platform;
return config;
};
// 响应拦截器
const responseInterceptor = (response) => {
const { data } = response;
// 统一处理错误
if (data.code !== 200) {
uni.showToast({
title: data.message || '请求失败',
icon: 'none'
});
// 处理登录过期
if (data.code === 401) {
uni.redirectTo({
url: '/pages/login/index'
});
}
return Promise.reject(data);
}
return data;
};
// 错误处理
const errorHandler = (error) => {
uni.showToast({
title: '网络错误,请稍后重试',
icon: 'none'
});
return Promise.reject(error);
};
// 导出配置
export default {
baseURL,
timeout,
requestInterceptor,
responseInterceptor,
errorHandler
};
// utils/request.js
import apiConfig from '../api/api';
class Request {
constructor() {
this.baseURL = apiConfig.baseURL;
this.timeout = apiConfig.timeout;
}
// 通用请求方法
request(options) {
return new Promise((resolve, reject) => {
// 应用请求拦截器
if (apiConfig.requestInterceptor) {
options = apiConfig.requestInterceptor(options);
}
uni.request({
url: this.baseURL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: options.header || {
'Content-Type': 'application/json'
},
timeout: this.timeout,
success: (response) => {
// 应用响应拦截器
if (apiConfig.responseInterceptor) {
try {
const result = apiConfig.responseInterceptor(response);
resolve(result);
} catch (error) {
reject(error);
}
} else {
resolve(response.data);
}
},
fail: (error) => {
// 应用错误处理器
if (apiConfig.errorHandler) {
apiConfig.errorHandler(error);
}
reject(error);
}
});
});
}
// GET 请求
get(url, params = {}) {
return this.request({
url,
method: 'GET',
data: params
});
}
// POST 请求
post(url, data = {}) {
return this.request({
url,
method: 'POST',
data
});
}
// PUT 请求
put(url, data = {}) {
return this.request({
url,
method: 'PUT',
data
});
}
// DELETE 请求
delete(url, params = {}) {
return this.request({
url,
method: 'DELETE',
data: params
});
}
}
export default new Request();
// api/user.js
import request from '../utils/request';
// 用户相关接口
export default {
// 登录
login: (data) => request.post('/api/user/login', data),
// 注册
register: (data) => request.post('/api/user/register', data),
// 获取用户信息
getUserInfo: () => request.get('/api/user/info'),
// 更新用户信息
updateUserInfo: (data) => request.put('/api/user/info', data),
// 修改密码
changePassword: (data) => request.post('/api/user/password', data),
// 获取地址列表
getAddressList: () => request.get('/api/user/address'),
// 添加地址
addAddress: (data) => request.post('/api/user/address', data),
// 更新地址
updateAddress: (id, data) => request.put(`/api/user/address/${id}`, data),
// 删除地址
deleteAddress: (id) => request.delete(`/api/user/address/${id}`),
// 设置默认地址
setDefaultAddress: (id) => request.put(`/api/user/address/${id}/default`)
};
<template>
<view class="user-info">
<view v-if="loading">加载中...</view>
<view v-else>
<image :src="userInfo.avatar" class="avatar"></image>
<view class="name">{{ userInfo.nickname }}</view>
<view class="mobile">{{ userInfo.mobile }}</view>
</view>
</view>
</template>
<script>
import userApi from '../../api/user';
export default {
data() {
return {
loading: false,
userInfo: {}
};
},
onLoad() {
this.getUserInfo();
},
methods: {
async getUserInfo() {
try {
this.loading = true;
const res = await userApi.getUserInfo();
this.userInfo = res.data;
} catch (error) {
console.error('获取用户信息失败:', error);
} finally {
this.loading = false;
}
}
}
};
</script>
<template>
<view class="address-item" v-for="item in addressList" :key="item.id">
<view class="address-info">
<view class="name">{{ item.name }} {{ item.mobile }}</view>
<view class="detail">{{ item.province }}{{ item.city }}{{ item.district }}{{ item.detail }}</view>
</view>
<view class="address-actions">
<button @click="editAddress(item)">编辑</button>
<button @click="deleteAddress(item.id)">删除</button>
<button v-if="!item.is_default" @click="setDefault(item.id)">设为默认</button>
</view>
</view>
</template>
<script>
import userApi from '../../api/user';
export default {
data() {
return {
addressList: []
};
},
mounted() {
this.getAddressList();
},
methods: {
async getAddressList() {
try {
const res = await userApi.getAddressList();
this.addressList = res.data;
} catch (error) {
console.error('获取地址列表失败:', error);
}
},
editAddress(item) {
uni.navigateTo({
url: `/pages/address/edit?id=${item.id}`
});
},
async deleteAddress(id) {
uni.showModal({
title: '提示',
content: '确定要删除这个地址吗?',
success: async (res) => {
if (res.confirm) {
try {
await userApi.deleteAddress(id);
uni.showToast({
title: '删除成功',
icon: 'success'
});
this.getAddressList();
} catch (error) {
console.error('删除地址失败:', error);
}
}
}
});
},
async setDefault(id) {
try {
await userApi.setDefaultAddress(id);
uni.showToast({
title: '设置成功',
icon: 'success'
});
this.getAddressList();
} catch (error) {
console.error('设置默认地址失败:', error);
}
}
}
};
</script>
user.jsgetUserInfo/api/user/info/api/v1/user/info成功响应:
{
"code": 200,
"message": "请求成功",
"data": {}
}
json
{
"code": 400,
"message": "请求失败",
"data": {}
}
本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等。遵循本文档的开发规范,可以提高 API 开发的效率和质量,确保应用的稳定性和可靠性。
随着业务的发展和技术的演进,API 开发流程也需要不断优化和调整,以适应新的业务需求和技术挑战。