小说网站前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
主管理员 b20db35afc fix: 修复用户信息显示问题并更新API基础URL 1 month ago
..
README.md 1 4 months ago
auth.js refactor(auth): 移除小程序登录接口并优化手机验证码发送 4 months ago
bookshelf.js feat: 新增微信支付组件和用户信息管理功能 4 months ago
home.js feat: 添加章节订阅功能及暗黑模式支持 2 months ago
index.js fix: 修复用户信息显示问题并更新API基础URL 1 month ago
modules.js feat: 新增微信支付组件和用户信息管理功能 4 months ago
sms.js 1 4 months ago
types.ts 1 4 months ago
user.js refactor(auth): 移除小程序登录接口并优化手机验证码发送 4 months ago

README.md

API 接口文档

本目录包含了小说阅读平台的所有API接口封装,基于后端Swagger API文档自动生成。

📐 架构设计

🎯 设计原则

本项目采用 纯净API + 状态管理分离 的架构设计:

  • API层:只负责HTTP请求,不包含任何业务逻辑
  • Store层:负责状态管理和业务逻辑处理
  • 组件层:调用API获取数据,通过Store管理状态

🏗️ 分层架构

┌─────────────────┐
│   Component     │  ← 调用API,处理响应,更新Store
├─────────────────┤
│     Store       │  ← 状态管理 + 业务逻辑
├─────────────────┤
│      API        │  ← 纯净HTTP请求
├─────────────────┤
│   Axios/HTTP    │  ← 网络请求
└─────────────────┘

文件结构

src/api/
├── index.js           # Axios实例配置和拦截器(纯净)
├── auth.js            # 授权登录相关接口(纯净)
├── home.js            # 首页相关接口(纯净)
├── bookshelf.js       # 书架相关接口(纯净)
├── user.js            # 用户相关接口(纯净)
├── sms.js             # 短信验证码接口(纯净)
├── modules.js         # 模块统一导出
├── types.ts           # TypeScript类型定义
├── usage-example.js   # 使用示例
├── api.json           # Swagger API文档
└── README.md          # 说明文档

src/store/
└── index.js           # 状态管理 + 业务逻辑

🚀 快速开始

基础使用模式

// 1. 导入API和Store
import { authApi } from '@/api/modules';
import { useMainStore } from '@/store';

// 2. 在组件中使用
export default {
  setup() {
    const store = useMainStore();
    
    const handleLogin = async (formData) => {
      try {
        // 调用纯净API
        const response = await authApi.phoneLogin(formData);
        
        // 处理响应,更新状态
        if (response.success) {
          store.handleLoginSuccess(response.result);
          // 登录成功后的其他操作...
        }
      } catch (error) {
        // 错误处理...
      }
    };
    
    return { handleLogin };
  }
};

🔧 核心功能

1. 纯净API接口

所有API方法都是纯函数,只返回HTTP响应数据:

// ✅ 正确:纯净的API调用
const response = await authApi.phoneLogin({ phone, code });
// response 是原始的API响应数据

// ❌ 错误:API不再自动处理状态
// API方法不会自动保存token或更新用户状态

2. Store状态管理

所有状态变更都通过Store方法处理:

const store = useMainStore();

// 处理登录成功
store.handleLoginSuccess(result);

// 处理用户信息更新  
store.handleUserInfoUpdate(userInfo);

// 处理401错误(通常由axios拦截器自动调用)
store.handle401Error();

// 手动清除认证状态
store.clearAuthStatus();

// 手动登出
store.logout();

3. 自动错误处理

401错误由axios拦截器自动处理:

// axios拦截器自动处理401错误
api.interceptors.response.use(
  response => response,
  error => {
    if (error.response.status === 401) {
      // 自动调用store的错误处理方法
      store.handle401Error();
    }
    return Promise.reject(error);
  }
);

📚 使用示例

登录流程

import { authApi } from '@/api/modules';
import { useMainStore } from '@/store';

export async function login(phoneData) {
  const store = useMainStore();
  
  try {
    // 1. 调用API
    const response = await authApi.phoneLogin(phoneData);
    
    // 2. 检查响应
    if (response.success && response.result) {
      // 3. 更新状态
      store.handleLoginSuccess(response.result);
      return response.result;
    } else {
      throw new Error(response.message || '登录失败');
    }
  } catch (error) {
    console.error('登录失败:', error.message);
    throw error;
  }
}

获取数据流程

import { homeApi } from '@/api/modules';

export async function getBooks(params) {
  try {
    // 纯净的数据获取,不涉及状态管理
    const response = await homeApi.getNewList(params);
    
    if (response.success) {
      return response.result;
    } else {
      throw new Error(response.message || '获取失败');
    }
  } catch (error) {
    console.error('获取书籍失败:', error.message);
    throw error;
  }
}

用户信息更新

import { authApi } from '@/api/modules';
import { useMainStore } from '@/store';

export async function updateProfile(userInfo) {
  const store = useMainStore();
  
  try {
    // 1. 更新用户信息
    const updateResponse = await authApi.updateUserInfo(userInfo);
    
    if (updateResponse.success) {
      // 2. 重新获取最新信息
      const userResponse = await authApi.getUserByToken();
      
      if (userResponse.success) {
        // 3. 更新store状态
        store.handleUserInfoUpdate(userResponse.result);
        return userResponse.result;
      }
    }
    
    throw new Error(updateResponse.message || '更新失败');
  } catch (error) {
    console.error('更新用户信息失败:', error.message);
    throw error;
  }
}

🎨 在Vue组件中使用

<template>
  <div>
    <el-button @click="handleLogin" :loading="loading">
      登录
    </el-button>
    <div v-if="isLoggedIn">
      欢迎{{ store.user.name }}
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { authApi } from '@/api/modules';
import { useMainStore } from '@/store';
import { ElMessage } from 'element-plus';

const store = useMainStore();
const loading = ref(false);

// 响应式计算属性
const isLoggedIn = computed(() => store.isAuthenticated);

// 登录处理
const handleLogin = async () => {
  loading.value = true;
  
  try {
    const response = await authApi.phoneLogin({
      phone: '13800138000',
      code: '1234'
    });
    
    if (response.success) {
      store.handleLoginSuccess(response.result);
      ElMessage.success('登录成功');
    } else {
      throw new Error(response.message);
    }
  } catch (error) {
    ElMessage.error(error.message);
  } finally {
    loading.value = false;
  }
};

// 登出处理
const handleLogout = () => {
  store.logout();
  ElMessage.success('已登出');
};
</script>

📝 最佳实践

推荐做法

  1. 分离关注点:API只做请求,Store管理状态
  2. 统一错误处理:在组件层统一处理API错误
  3. 响应式状态:使用computed属性获取store状态
  4. 类型安全:使用TypeScript类型定义
// ✅ 好的做法
const response = await authApi.phoneLogin(params);
if (response.success) {
  store.handleLoginSuccess(response.result);
}

// ✅ 使用响应式状态
const isLoggedIn = computed(() => store.isAuthenticated);

避免的做法

  1. 在API中处理状态:不要在API方法中操作localStorage或store
  2. 直接操作状态:不要绕过store方法直接修改状态
  3. 混合关注点:不要在同一个方法中既请求数据又处理UI逻辑
// ❌ 不好的做法
const response = await authApi.phoneLogin(params);
// 不要直接操作localStorage
localStorage.setItem('token', response.result.token);

// ❌ 不要直接修改store状态
store.user = response.result.userInfo;

🛠️ 开发规范

API层规范

  • 所有方法都是纯函数,不包含副作用
  • 只返回HTTP响应数据,不处理业务逻辑
  • 不操作localStorage或其他全局状态
  • 保持接口签名简洁明确

Store层规范

  • 所有状态变更都通过action方法
  • 处理登录成功、用户信息更新等业务逻辑
  • 管理localStorage的读写
  • 处理错误状态和用户反馈

组件层规范

  • 调用API获取数据
  • 根据API响应调用相应的store方法
  • 处理用户交互和UI状态
  • 使用computed属性获取响应式状态

🔍 调试和排错

常见问题

  1. 401错误处理:由axios拦截器自动处理,会调用store.handle401Error()
  2. 状态不同步:确保所有状态变更都通过store方法
  3. 重复登录:检查是否正确调用了store.handleLoginSuccess()

调试技巧

// 开启详细日志
console.log('[Debug] API Response:', response);
console.log('[Debug] Store State:', store.$state);

// 检查登录状态
console.log('[Debug] Auth Status:', store.checkAuthStatus());

🔗 相关链接

这种架构设计确保了代码的可维护性、可测试性和扩展性,同时保持了各层职责的清晰分离。