📖 快速接入
🗂️ 全部接口0
🧪 接口文档 + 测试
🚀 前端快速接入后端
本页面(http://ptjob.qxnav.com/)既是 API 文档,也是后端服务本身。前端直接调用
api.php?a=模块.方法 即可。① 基础信息
| Base URL | http://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
workeragentmerchant
agent
merchant
worker
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.request 或 Taro.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. 登录小程序后台 → 开发管理 → 开发设置 → 服务器域名,把
2. 必须使用 HTTPS(请先在宝塔面板给 ptjob.qxnav.com 申请 Let's Encrypt 证书)
3. 本地调试可在开发者工具右上角勾选「不校验合法域名」跳过检查
1. 登录小程序后台 → 开发管理 → 开发设置 → 服务器域名,把
https://ptjob.qxnav.com 加到「request 合法域名」2. 必须使用 HTTPS(请先在宝塔面板给 ptjob.qxnav.com 申请 Let's Encrypt 证书)
3. 本地调试可在开发者工具右上角勾选「不校验合法域名」跳过检查
🔐 Token 管理 & 多身份说明
登录流程
- 调用
auth.login→ 返回data.token和data.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 个接口,按模块分组。点击任意接口行跳转至详细文档和在线测试页。
从左侧或"全部接口"页选择一个接口查看详情 →