选择接口查看 URL
📖 快速接入
🗂️ 全部接口0
🧪 接口文档 + 测试

🚀 前端快速接入后端

本页面(http://ptjob.qxnav.com/)既是 API 文档,也是后端服务本身。前端直接调用 api.php?a=模块.方法 即可。

① 基础信息

Base URLhttp://ptjob.qxnav.com
接口格式GET /api.php?a=模块.方法POST /api.php?a=模块.方法
GET 参数Query String:?a=jobs.list&page=1&pageSize=10
POST 参数JSON Body:Content-Type: application/json
鉴权方式请求头:Authorization: Bearer <token>
或 Query:?token=xxx(不推荐)
CORS✅ 后端已配置 Access-Control-Allow-Origin: *,跨域无限制
字符编码UTF-8,返回中文无需编码

② 统一响应格式

所有接口返回统一 JSON 结构:

{
  "code": 0,        // 0=成功,非0=失败
  "msg":  "ok",     // 消息描述(失败时为错误原因)
  "data": { ... }   // 返回数据(失败时通常为 null)
}

③ 错误码说明

code说明前端处理建议
0成功正常使用 res.data
1通用业务失败提示用户 res.msg
401未登录 / Token 过期清除本地 Token,跳转登录页
403无权限(缺少对应角色身份)提示「无权限执行该操作」,引导去申请/绑定身份

④ 测试账号(密码均为 zhangwen

admin admin 超级管理员
workeragentmerchant zwf234 三身份一体(推荐测试)
agent lijingli 金牌中介
merchant meichu 商家
worker wangxiaoming 求职者
💡 提示:database.sql 中默认密码是 bcrypt 占位 hash,如果登录报"密码错误",请执行:
php -r "echo password_hash('zhangwen', PASSWORD_DEFAULT);" 把生成的 hash 更新到 users.password 字段。

📦 方案 1:原生 fetch 封装(推荐 Web 项目)

零依赖,任何浏览器/H5/小程序环境都能用
// ============ api.js ============
const BASE_URL = 'http://ptjob.qxnav.com';
const TOKEN_KEY = 'ptjob_token';

// 统一请求封装
async function request(action, params = {}, method = null) {
  const autoMethod = method || (Object.keys(params).length ? 'POST' : 'GET');
  let url = `${BASE_URL}/api.php?a=${action}`;
  const headers = { 'Content-Type': 'application/json' };
  const token = localStorage.getItem(TOKEN_KEY);
  if (token) headers['Authorization'] = 'Bearer ' + token;

  const opts = { method: autoMethod, headers };

  if (autoMethod === 'GET') {
    const qs = new URLSearchParams(params).toString();
    if (qs) url += '&' + qs;
  } else {
    opts.body = JSON.stringify(params);
  }

  try {
    const res = await fetch(url, opts);
    // 注意:根据经验,如果返回的 Content-Type 不是 application/json
    // 很可能是路由404 / PHP报错页,先读text避免 JSON.parse 崩溃
    const text = await res.text();
    let data;
    try { data = JSON.parse(text); }
    catch {
      console.error('[API] 非 JSON 响应(疑似路由/PHP错误):', text.slice(0, 200));
      return { code: 999, msg: '服务器返回了非 JSON 内容:' + text.slice(0, 80), data: null };
    }

    // 统一错误处理
    if (data.code === 401) {
      localStorage.removeItem(TOKEN_KEY);
      if (!location.pathname.includes('/login')) location.href = '/login';
    }
    if (data.code === 403) {
      alert('无权限执行该操作');
    }
    return data;
  } catch (e) {
    return { code: 998, msg: '网络错误:' + e.message, data: null };
  }
}

// ============ 使用示例 ============

// 1) 登录 - 获取 token(会自动保存到 localStorage)
async function login() {
  const res = await request('auth.login', {
    username: 'zwf234',
    password: 'zhangwen',
    // roles: ['worker', 'merchant']  // 多身份账号可选指定
  });
  if (res.code === 0) {
    localStorage.setItem(TOKEN_KEY, res.data.token);
    console.log('登录成功,用户信息:', res.data.user);
  } else {
    console.error('登录失败:', res.msg);
  }
}

// 2) 首页数据(无需登录)
async function loadHome() {
  const res = await request('home.index');
  if (res.code === 0) {
    console.log('岗位列表:', res.data.jobs);
    console.log('活动:', res.data.events);
    console.log('分类:', res.data.categories);
  }
}

// 3) 岗位列表(分页 + 搜索)
async function loadJobs(page = 1, pageSize = 10, kw = '') {
  return await request('jobs.list', { page, pageSize, kw });
}

// 4) 工人报名(需要登录)
async function applyJob(jobId) {
  return await request('jobs.apply', { job_id: jobId });
}

// 5) 商家发布岗位(需要登录 + merchant 身份)
async function createJob(job) {
  return await request('jobs.create', job);
}

// 6) 订单结算 / 佣金流水等带身份的接口
async function getWorkerSalary() { return await request('worker.salary'); }
async function getAgentIncome() { return await request('agent.incomeList'); }
async function getMerchantOverview() { return await request('merchant.overview'); }
async function getAdminOverview()  { return await request('admin.overview'); }

📦 方案 2:Axios 封装(Vue/React 项目)

// ============ request.js ============
import axios from 'axios';

const service = axios.create({
  baseURL: 'http://ptjob.qxnav.com',
  timeout: 10000,
  headers: { 'Content-Type': 'application/json' },
});

// 请求拦截器:自动附加 Token
service.interceptors.request.use(config => {
  const token = localStorage.getItem('ptjob_token');
  if (token) config.headers.Authorization = 'Bearer ' + token;
  // action 统一挂到 params 上,让 ?a=xxx 出现在 URL
  return config;
});

// 响应拦截器:统一处理 code
service.interceptors.response.use(
  resp => {
    const data = resp.data;
    if (data.code === 401) {
      localStorage.removeItem('ptjob_token');
      location.href = '/login';
    }
    if (data.code === 403) alert('无权限');
    return data;  // 直接返回 {code,msg,data},调用处不必 .data.data
  },
  err => ({ code: 999, msg: err.message, data: null })
);

// 统一调用:api('auth.login', {username,password})
export default function api(action, params = {}, method = null) {
  const autoMethod = method || (Object.keys(params).length ? 'post' : 'get');
  return service({
    method: autoMethod,
    url: '/api.php',
    params: { a: action },              // GET & POST 都把 a 放 query
    data: autoMethod === 'post' ? params : undefined,
    paramsSerializer: { serialize: p => new URLSearchParams(p).toString() },
  });
}

// ============ 使用示例 ============
// import api from './request';
// const res = await api('auth.login', { username:'zwf234', password:'zhangwen' });
// if (res.code === 0) localStorage.setItem('ptjob_token', res.data.token);

📱 方案 3:微信小程序 / Taro / uni-app

本项目 README 明确说明是"兼职灵活用工小程序"后端,小程序端用 wx.requestTaro.request 接入
// ============ utils/request.js(原生小程序 / Taro 通用)============
const BASE_URL = 'https://ptjob.qxnav.com';  // 小程序必须 HTTPS + 后台配置 request 合法域名

export default function request(action, params = {}) {
  const method = Object.keys(params).length ? 'POST' : 'GET';
  return new Promise((resolve) => {
    wx.request({
      url: `${BASE_URL}/api.php?a=${action}`,
      method,
      header: {
        'content-type': 'application/json',
        'Authorization': 'Bearer ' + (wx.getStorageSync('ptjob_token') || ''),
      },
      data: method === 'POST' ? params : params,  // GET 也可以把参数扔 data,wx 自动拼 query
      success: (res) => {
        // statusCode 非 200 处理
        if (res.statusCode !== 200) {
          resolve({ code: 999, msg: `HTTP ${res.statusCode}`, data: null });
          return;
        }
        const data = res.data;
        if (!data || typeof data !== 'object' || typeof data.code === 'undefined') {
          console.error('[API] 响应异常:', JSON.stringify(data).slice(0, 200));
          resolve({ code: 999, msg: '服务器响应格式异常', data: null });
          return;
        }
        if (data.code === 401) {
          wx.removeStorageSync('ptjob_token');
          wx.navigateTo({ url: '/pages/login/login' });
        }
        resolve(data);
      },
      fail: (err) => resolve({ code: 998, msg: err.errMsg || '网络错误', data: null }),
    });
  });
}

// ============ 使用 ============
// import request from './utils/request';
//
// // 登录
// const res = await request('auth.login', { username: 'zwf234', password: 'zhangwen' });
// if (res.code === 0) {
//   wx.setStorageSync('ptjob_token', res.data.token);
//   wx.setStorageSync('user', res.data.user);
// }
//
// // 首页
// const home = await request('home.index');
//
// // 岗位列表(GET 参数自动拼到 URL)
// const jobs = await request('jobs.list', { page: 1, pageSize: 10, kw: '餐饮' });
//
// // 报名
// const apply = await request('jobs.apply', { job_id: 7 });
⚠️ 小程序部署注意:
1. 登录小程序后台 → 开发管理 → 开发设置 → 服务器域名,把 https://ptjob.qxnav.com 加到「request 合法域名」
2. 必须使用 HTTPS(请先在宝塔面板给 ptjob.qxnav.com 申请 Let's Encrypt 证书)
3. 本地调试可在开发者工具右上角勾选「不校验合法域名」跳过检查

🔐 Token 管理 & 多身份说明

登录流程

  • 调用 auth.login → 返回 data.tokendata.user
  • 保存 token 到 localStorage(Web)或 wx.setStorageSync(小程序)
  • 有效期 7 天(JWT exp 字段),过期接口返回 code=401

一个账号多身份(核心设计)

  • 每个用户可同时拥有 worker agent merchant admin 中的多个身份
  • 登录时可选 roles: ['worker','merchant'] 过滤(不传则返回所有身份)
  • 后续需要时可调用 auth.bindRole 追加身份
  • 调用身份相关接口时,只要 token 中包含对应角色即可(比如 zwf234 既能发岗位也能报名)

🧩 典型业务调用流程

流程 1:求职者找工作

// 1. 打开首页
await request('home.index');

// 2. 浏览岗位(搜索/分类/日期过滤)
await request('jobs.list', { page:1, pageSize:10, category:'餐饮' });

// 3. 岗位详情
await request('jobs.detail', { id: 7 });

// 4. 登录(首次操作)
const res = await request('auth.login', { username:'wangxiaoming', password:'zhangwen' });
localStorage.setItem('ptjob_token', res.data.token);

// 5. 报名岗位
await request('jobs.apply', { job_id: 7 });

// 6. 查看我的报名
await request('worker.orderList', { status: 'accepted' });

// 7. 上班签到
await request('worker.checkin', { application_id: 1, type: 'in',  lat: 30.123, lng: 114.123 });
await request('worker.checkin', { application_id: 1, type: 'out', lat: 30.123, lng: 114.123 });

// 8. 查看工资结算
await request('worker.salary');

流程 2:商家发布岗位 & 审核报名

// 1. 登录(merchant 身份)
await request('auth.login', { username:'meichu', password:'zhangwen' });

// 2. 发布岗位
await request('jobs.create', {
  title: '奶茶店兼职员工', category: '餐饮',
  salary: 22, salary_unit: '小时',
  work_address: '本市大学城茶百道',
  work_date: '2026-08-20',
  work_time_start: '10:00', work_time_end: '22:00',
  need_count: 2, description: '点单、制作奶茶',
  requirements: '年龄 18-25,有健康证',
});

// 3. 查看自己的岗位
await request('jobs.mine');

// 4. 查看报名者
await request('merchant.applicants', { job_id: 7 });

// 5. 录用 / 拒绝
await request('merchant.reviewApplication', { application_id: 1, status: 'accepted' });
// status = accepted | rejected

// 6. 考勤 & 结算
await request('merchant.attendance', { date: '2026-08-20' });
await request('merchant.orders');
await request('merchant.overview');  // 数据看板

流程 3:中介锁客 & 提现

await request('auth.login', { username:'lijingli', password:'zhangwen' });
await request('agent.overview');         // 数据看板
await request('agent.customers');        // 锁客列表
await request('agent.team');             // 团队成员
await request('agent.incomeList');       // 佣金流水
await request('agent.withdraw', {        // 申请提现
  amount: 1000,
  bank_name: '建设银行',
  bank_account: '6217...',
  bank_holder: '李某某',
});

🛠️ 常见问题

Q1: 登录报「密码错误」

database.sql 里的密码是占位 bcrypt hash。执行以下命令生成真实 hash 后 UPDATE users SET password='真实hash' WHERE username='zwf234';

php -r "echo password_hash('zhangwen', PASSWORD_DEFAULT);"

Q2: 前端报 Unexpected token < in JSON at position 0

接口返回了 HTML(404 页 / PHP 错误页),不是 JSON。检查:① URL 是否包含 ?a=模块.方法;② 服务器 Nginx/PHP 是否正常运行;③ 使用顶部封装代码中「先读 text 再 parse」的容错写法。

Q3: 小程序请求失败,报"合法域名"错误

开发工具勾选「不校验合法域名」临时跳过;上线前在小程序后台把 https://ptjob.qxnav.com 加到 request 合法域名。

Q4: 调用需要登录的接口返回 401

① Token 过期(有效期 7 天),需重新登录;② 请求头没有带 Authorization: Bearer xxx

🗂️ 全部接口清单

0 个接口,按模块分组。点击任意接口行跳转至详细文档和在线测试页。
从左侧或"全部接口"页选择一个接口查看详情 →