本文目录导读:

我来为你全面讲解 PHP 岗位管理系统的开发,从需求分析到具体实现。
系统功能架构
核心功能模块
// 岗位管理系统功能结构 1. 岗位基础管理 - 岗位创建、编辑、删除 - 岗位编码生成 - 岗位状态管理 2. 岗位分类管理 - 部门分类 - 职级分类 - 岗位类型 3. 权限管理 - 岗位权限分配 - 数据权限控制 4. 人员关联 - 人员-岗位绑定 - 岗位编制管理
数据库设计
数据表结构
-- 岗位信息表 CREATE TABLE `positions` ( `id` int(11) NOT NULL AUTO_INCREMENT, `position_code` varchar(20) NOT NULL COMMENT '岗位编码', `position_name` varchar(50) NOT NULL COMMENT '岗位名称', `department_id` int(11) NOT NULL COMMENT '所属部门', `position_type` tinyint(4) DEFAULT '1' COMMENT '岗位类型:1管理岗 2技术岗 3职能岗', `position_level` varchar(20) DEFAULT NULL COMMENT '岗位职级', `head_count` int(11) DEFAULT '1' COMMENT '编制人数', `current_count` int(11) DEFAULT '0' COMMENT '在职人数', `description` text COMMENT '岗位描述', `requirements` text COMMENT '任职要求', `salary_min` decimal(10,2) DEFAULT NULL COMMENT '薪资下限', `salary_max` decimal(10,2) DEFAULT NULL COMMENT '薪资上限', `status` tinyint(4) DEFAULT '1' COMMENT '状态:1启用 0禁用', `created_by` int(11) DEFAULT NULL COMMENT '创建人', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_position_code` (`position_code`), KEY `idx_department` (`department_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='岗位信息表'; -- 岗位-用户关联表 CREATE TABLE `position_users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `position_id` int(11) NOT NULL, `user_id` int(11) NOT NULL, `is_primary` tinyint(1) DEFAULT '1' COMMENT '是否主岗位', `start_date` date DEFAULT NULL, `end_date` date DEFAULT NULL, `status` tinyint(4) DEFAULT '1', PRIMARY KEY (`id`), UNIQUE KEY `uk_position_user` (`position_id`,`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='岗位用户关联表';
核心代码实现
岗位管理控制器
<?php
namespace App\Controllers;
use App\Models\PositionModel;
use App\Helpers\Validator;
use App\Helpers\Response;
class PositionController extends BaseController
{
protected $positionModel;
public function __construct()
{
parent::__construct();
$this->positionModel = new PositionModel();
}
/**
* 岗位列表
*/
public function index()
{
$page = $_GET['page'] ?? 1;
$limit = $_GET['limit'] ?? 20;
$keyword = $_GET['keyword'] ?? '';
$departmentId = $_GET['department_id'] ?? '';
$status = $_GET['status'] ?? '';
$where = [];
if (!empty($keyword)) {
$where['position_name LIKE'] = "%{$keyword}%";
}
if (!empty($departmentId)) {
$where['department_id'] = $departmentId;
}
if ($status !== '') {
$where['status'] = $status;
}
$result = $this->positionModel->getList($where, $page, $limit);
return Response::success($result);
}
/**
* 创建岗位
*/
public function create()
{
// 权限检查
$this->checkPermission('position:create');
// 获取并验证数据
$data = [
'position_code' => $_POST['position_code'] ?? '',
'position_name' => $_POST['position_name'] ?? '',
'department_id' => $_POST['department_id'] ?? 0,
'position_type' => $_POST['position_type'] ?? 1,
'position_level' => $_POST['position_level'] ?? '',
'head_count' => $_POST['head_count'] ?? 1,
'description' => $_POST['description'] ?? '',
'requirements' => $_POST['requirements'] ?? '',
'salary_min' => $_POST['salary_min'] ?? 0,
'salary_max' => $_POST['salary_max'] ?? 0,
];
// 验证规则
$rules = [
'position_code' => 'required|max:20|unique:positions',
'position_name' => 'required|max:50',
'department_id' => 'required|numeric',
'head_count' => 'numeric|min:1',
'salary_min' => 'numeric|min:0',
'salary_max' => 'numeric|min:0'
];
$validator = new Validator();
if (!$validator->validate($data, $rules)) {
return Response::error($validator->getErrors(), 400);
}
$data['created_by'] = $_SESSION['user_id'];
$result = $this->positionModel->create($data);
if ($result) {
// 记录操作日志
$this->logOperation('create_position', $data['position_code']);
return Response::success(['id' => $result], '创建成功');
}
return Response::error('创建失败', 500);
}
/**
* 更新岗位
*/
public function update($id)
{
$this->checkPermission('position:update');
$position = $this->positionModel->find($id);
if (!$position) {
return Response::error('岗位不存在', 404);
}
$data = [
'position_name' => $_POST['position_name'] ?? $position['position_name'],
'position_type' => $_POST['position_type'] ?? $position['position_type'],
'position_level' => $_POST['position_level'] ?? $position['position_level'],
'head_count' => $_POST['head_count'] ?? $position['head_count'],
'description' => $_POST['description'] ?? $position['description'],
'requirements' => $_POST['requirements'] ?? $position['requirements'],
'salary_min' => $_POST['salary_min'] ?? $position['salary_min'],
'salary_max' => $_POST['salary_max'] ?? $position['salary_max'],
];
$result = $this->positionModel->update($id, $data);
if ($result) {
$this->logOperation('update_position', $position['position_code']);
return Response::success($data, '更新成功');
}
return Response::error('更新失败', 500);
}
/**
* 删除岗位
*/
public function delete($id)
{
$this->checkPermission('position:delete');
// 检查是否有关联人员
$userCount = $this->positionModel->getUsersCount($id);
if ($userCount > 0) {
return Response::error('该岗位已关联人员,无法删除', 400);
}
$result = $this->positionModel->delete($id);
if ($result) {
return Response::success(null, '删除成功');
}
return Response::error('删除失败', 500);
}
/**
* 岗位分配人员
*/
public function assignUsers($positionId)
{
$this->checkPermission('position:assign');
$userId = $_POST['user_id'] ?? 0;
$action = $_POST['action'] ?? 'assign'; // assign/remove
if ($action === 'assign') {
$result = $this->positionModel->assignUser($positionId, $userId);
} else {
$result = $this->positionModel->removeUser($positionId, $userId);
}
if ($result) {
return Response::success(null, '操作成功');
}
return Response::error('操作失败', 500);
}
/**
* 导出岗位列表
*/
public function export()
{
$this->checkPermission('position:export');
$positions = $this->positionModel->getAllForExport();
// 生成Excel
$fileName = '岗位列表_' . date('YmdHis') . '.xls';
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition: attachment; filename={$fileName}");
echo $this->generateExcelContent($positions);
}
}
岗位模型
<?php
namespace App\Models;
use App\Database\Database;
use PDO;
class PositionModel extends BaseModel
{
protected $table = 'positions';
/**
* 获取岗位列表(带部门信息)
*/
public function getList($where = [], $page = 1, $limit = 20)
{
$offset = ($page - 1) * $limit;
$sql = "SELECT p.*, d.department_name,
(p.head_count - p.current_count) as available_count
FROM positions p
LEFT JOIN departments d ON p.department_id = d.id";
$conditions = [];
$params = [];
foreach ($where as $field => $value) {
if (strpos($field, ' LIKE') !== false) {
$conditions[] = "p." . str_replace(' LIKE', '', $field) . " LIKE ?";
$params[] = $value;
} else {
$conditions[] = "p.{$field} = ?";
$params[] = $value;
}
}
if (!empty($conditions)) {
$sql .= " WHERE " . implode(" AND ", $conditions);
}
$sql .= " ORDER BY p.created_at DESC LIMIT ? OFFSET ?";
$params[] = $limit;
$params[] = $offset;
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
$list = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 获取总数
$countSql = "SELECT COUNT(*) FROM positions p";
if (!empty($conditions)) {
$countSql .= " WHERE " . implode(" AND ", $conditions);
}
$stmt = $this->db->prepare($countSql);
$stmt->execute(array_slice($params, 0, -2));
$total = $stmt->fetchColumn();
return [
'list' => $list,
'total' => $total,
'page' => $page,
'limit' => $limit
];
}
/**
* 分配用户到岗位
*/
public function assignUser($positionId, $userId)
{
try {
$this->db->beginTransaction();
// 检查编制
$position = $this->find($positionId);
if (!$position) {
throw new \Exception('岗位不存在');
}
if ($position['current_count'] >= $position['head_count']) {
throw new \Exception('岗位编制已满');
}
// 插入关联
$sql = "INSERT INTO position_users (position_id, user_id)
VALUES (?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute([$positionId, $userId]);
// 更新在职人数
$sql = "UPDATE positions SET current_count = current_count + 1
WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([$positionId]);
$this->db->commit();
return true;
} catch (\Exception $e) {
$this->db->rollBack();
throw $e;
}
}
/**
* 检查岗位编码唯一性
*/
public function checkCodeUnique($code, $excludeId = null)
{
$sql = "SELECT id FROM positions WHERE position_code = ?";
$params = [$code];
if ($excludeId) {
$sql .= " AND id != ?";
$params[] = $excludeId;
}
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return $stmt->fetchColumn() ? false : true;
}
/**
* 统计部门下岗位数
*/
public function countByDepartment($departmentId)
{
$sql = "SELECT COUNT(*) FROM positions WHERE department_id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([$departmentId]);
return $stmt->fetchColumn();
}
}
前端页面示例
<!-- 岗位列表页面 -->
<!DOCTYPE html>
<html>
<head>岗位管理</title>
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
</head>
<body>
<div id="app">
<el-container>
<el-header>
<h2>岗位管理</h2>
</el-header>
<el-main>
<!-- 搜索区域 -->
<el-form :inline="true" class="search-form">
<el-form-item label="岗位名称">
<el-input v-model="searchForm.keyword" placeholder="请输入岗位名称"></el-input>
</el-form-item>
<el-form-item label="部门">
<el-select v-model="searchForm.department" placeholder="请选择部门">
<el-option
v-for="item in departments"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="searchForm.status">
<el-option label="全部" value=""></el-option>
<el-option label="启用" value="1"></el-option>
<el-option label="禁用" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search">搜索</el-button>
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作按钮 -->
<div class="table-toolbar">
<el-button type="primary" @click="openCreateDialog">
<el-icon><Plus /></el-icon>新增岗位
</el-button>
<el-button @click="exportExcel">导出</el-button>
</div>
<!-- 表格 -->
<el-table :data="positionList" border stripe>
<el-table-column prop="position_code" label="岗位编码" width="120"></el-table-column>
<el-table-column prop="position_name" label="岗位名称" width="150"></el-table-column>
<el-table-column prop="department_name" label="所属部门"></el-table-column>
<el-table-column prop="position_type" label="岗位类型">
<template #default="{ row }">
<el-tag :type="getTypeTag(row.position_type)">
{{ getTypeName(row.position_type) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="head_count" label="编制人数" width="100"></el-table-column>
<el-table-column prop="current_count" label="在职人数" width="100"></el-table-column>
<el-table-column prop="position_level" label="职级" width="80"></el-table-column>
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<el-switch
v-model="row.status"
:active-value="1"
:inactive-value="0"
@change="changeStatus(row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="editPosition(row)">编辑</el-button>
<el-button link type="warning" @click="assignPerson(row)">人员分配</el-button>
<el-popconfirm
title="确定删除该岗位吗?"
@confirm="deletePosition(row.id)"
>
<template #reference>
<el-button link type="danger">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
v-model:current-page="page"
v-model:page-size="limit"
:total="total"
:page-sizes="[10, 20, 50, 100]"
@current-change="getList"
@size-change="getList">
</el-pagination>
</el-main>
</el-container>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model="dialogVisible"
:title="dialogType === 'create' ? '新增岗位' : '编辑岗位'"
width="600px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="岗位编码" prop="position_code">
<el-input v-model="formData.position_code" :disabled="dialogType === 'edit'"></el-input>
</el-form-item>
<el-form-item label="岗位名称" prop="position_name">
<el-input v-model="formData.position_name"></el-input>
</el-form-item>
<el-form-item label="所属部门" prop="department_id">
<el-select v-model="formData.department_id" placeholder="请选择部门">
<el-option
v-for="item in departments"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="岗位类型" prop="position_type">
<el-radio-group v-model="formData.position_type">
<el-radio :value="1">管理岗</el-radio>
<el-radio :value="2">技术岗</el-radio>
<el-radio :value="3">职能岗</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="岗位职级">
<el-select v-model="formData.position_level">
<el-option label="初级" value="初级"></el-option>
<el-option label="中级" value="中级"></el-option>
<el-option label="高级" value="高级"></el-option>
<el-option label="资深" value="资深"></el-option>
<el-option label="专家" value="专家"></el-option>
</el-select>
</el-form-item>
<el-form-item label="编制人数" prop="head_count">
<el-input-number v-model="formData.head_count" :min="1" :max="100"></el-input-number>
</el-form-item>
<el-form-item label="薪资范围">
<div class="salary-range">
<el-input-number
v-model="formData.salary_min"
:min="0"
:max="formData.salary_max">
</el-input-number>
<span class="divider">-</span>
<el-input-number
v-model="formData.salary_max"
:min="formData.salary_min">
</el-input-number>
<span class="unit">元/月</span>
</div>
</el-form-item>
<el-form-item label="岗位描述">
<el-input
v-model="formData.description"
type="textarea"
:rows="3">
</el-input>
</el-form-item>
<el-form-item label="任职要求">
<el-input
v-model="formData.requirements"
type="textarea"
:rows="3">
</el-input>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</template>
</el-dialog>
<!-- 人员分配对话框 -->
<el-dialog v-model="assignVisible" title="人员分配" width="500px">
<div v-if="currentPosition">
<h4>{{ currentPosition.position_name }}</h4>
<p>编制人数:{{ currentPosition.head_count }},当前人数:{{ currentPosition.current_count }}</p>
<el-divider></el-divider>
<h5>已分配人员</h5>
<el-table :data="assignedUsers">
<el-table-column prop="username" label="用户名"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column label="操作" width="80">
<template #default="{ row }">
<el-button
link
type="danger"
@click="removeUser(row.user_id)">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-divider></el-divider>
<h5>添加人员</h5>
<div class="user-search">
<el-select
v-model="selectedUser"
filterable
remote
:remote-method="searchUsers"
placeholder="搜索用户">
<el-option
v-for="item in availableUsers"
:key="item.id"
:label="`${item.name} (${item.username})`"
:value="item.id">
</el-option>
</el-select>
<el-button type="primary" @click="assignUser">添加</el-button>
</div>
</div>
</el-dialog>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/element-plus"></script>
<script>
// Vue 应用
const { createApp, ref, onMounted, reactive } = Vue;
const app = createApp({
setup() {
// 数据定义
const positionList = ref([]);
const departments = ref([]);
const total = ref(0);
const page = ref(1);
const limit = ref(20);
const searchForm = reactive({
keyword: '',
department: '',
status: ''
});
const dialogVisible = ref(false);
const dialogType = ref('create');
const formRef = ref(null);
const formData = reactive({
position_code: '',
position_name: '',
department_id: null,
position_type: 1,
position_level: '',
head_count: 1,
description: '',
requirements: '',
salary_min: 0,
salary_max: 0
});
const formRules = {
position_code: [
{ required: true, message: '请输入岗位编码', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在2-20个字符', trigger: 'blur' }
],
position_name: [
{ required: true, message: '请输入岗位名称', trigger: 'blur' }
],
department_id: [
{ required: true, message: '请选择部门', trigger: 'change' }
]
};
// 人员分配相关
const assignVisible = ref(false);
const currentPosition = ref(null);
const assignedUsers = ref([]);
const availableUsers = ref([]);
const selectedUser = ref(null);
// 方法定义
const getList = async () => {
const params = new URLSearchParams({
page: page.value,
limit: limit.value,
keyword: searchForm.keyword,
department_id: searchForm.department,
status: searchForm.status
});
try {
const response = await fetch(`/api/positions?${params}`);
const data = await response.json();
positionList.value = data.data.list;
total.value = data.data.total;
} catch (error) {
console.error('获取岗位列表失败:', error);
}
};
const getDepartments = async () => {
try {
const response = await fetch('/api/departments');
const data = await response.json();
departments.value = data.data;
} catch (error) {
console.error('获取部门列表失败:', error);
}
};
const openCreateDialog = () => {
dialogType.value = 'create';
Object.assign(formData, {
position_code: '',
position_name: '',
department_id: null,
position_type: 1,
position_level: '',
head_count: 1,
description: '',
requirements: '',
salary_min: 0,
salary_max: 0
});
dialogVisible.value = true;
};
const editPosition = (row) => {
dialogType.value = 'edit';
Object.assign(formData, row);
dialogVisible.value = true;
};
const submitForm = async () => {
try {
await formRef.value.validate();
const url = dialogType.value === 'create'
? '/api/positions'
: `/api/positions/${formData.id}`;
const method = dialogType.value === 'create' ? 'POST' : 'PUT';
const response = await fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
const data = await response.json();
if (data.code === 0) {
dialogVisible.value = false;
ElMessage.success(data.message);
getList();
} else {
ElMessage.error(data.message);
}
} catch (error) {
console.error('提交失败:', error);
}
};
const deletePosition = async (id) => {
try {
const response = await fetch(`/api/positions/${id}`, {
method: 'DELETE'
});
const data = await response.json();
if (data.code === 0) {
ElMessage.success('删除成功');
getList();
} else {
ElMessage.error(data.message);
}
} catch (error) {
console.error('删除失败:', error);
}
};
const assignPerson = (row) => {
currentPosition.value = row;
assignVisible.value = true;
getAssignedUsers(row.id);
};
const getAssignedUsers = async (positionId) => {
try {
const response = await fetch(`/api/positions/${positionId}/users`);
const data = await response.json();
assignedUsers.value = data.data;
} catch (error) {
console.error('获取已分配人员失败:', error);
}
};
const searchUsers = async (query) => {
try {
const response = await fetch(`/api/users/search?keyword=${query}`);
const data = await response.json();
availableUsers.value = data.data;
} catch (error) {
console.error('搜索用户失败:', error);
}
};
const assignUser = async () => {
if (!selectedUser.value) {
ElMessage.warning('请选择用户');
return;
}
try {
const response = await fetch(`/api/positions/${currentPosition.value.id}/assign`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_id: selectedUser.value,
action: 'assign'
})
});
const data = await response.json();
if (data.code === 0) {
ElMessage.success('添加成功');
getAssignedUsers(currentPosition.value.id);
getList();
selectedUser.value = null;
} else {
ElMessage.error(data.message);
}
} catch (error) {
console.error('添加人员失败:', error);
}
};
const removeUser = async (userId) => {
try {
const response = await fetch(`/api/positions/${currentPosition.value.id}/assign`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_id: userId,
action: 'remove'
})
});
const data = await response.json();
if (data.code === 0) {
ElMessage.success('移除成功');
getAssignedUsers(currentPosition.value.id);
getList();
} else {
ElMessage.error(data.message);
}
} catch (error) {
console.error('移除人员失败:', error);
}
};
const search = () => {
page.value = 1;
getList();
};
const resetSearch = () => {
searchForm.keyword = '';
searchForm.department = '';
searchForm.status = '';
getList();
};
const exportExcel = () => {
window.location.href = '/api/positions/export';
};
const getTypeName = (type) => {
const types = { 1: '管理岗', 2: '技术岗', 3: '职能岗' };
return types[type] || '未知';
};
const getTypeTag = (type) => {
const tags = { 1: 'danger', 2: 'success', 3: 'warning' };
return tags[type] || 'info';
};
// 生命周期
onMounted(() => {
getList();
getDepartments();
});
return {
positionList,
departments,
total,
page,
limit,
searchForm,
dialogVisible,
dialogType,
formRef,
formData,
formRules,
assignVisible,
currentPosition,
assignedUsers,
availableUsers,
selectedUser,
getList,
openCreateDialog,
editPosition,
submitForm,
deletePosition,
assignPerson,
searchUsers,
assignUser,
removeUser,
search,
resetSearch,
exportExcel,
getTypeName,
getTypeTag
};
}
});
app.use(ElementPlus);
app.mount('#app');
</script>
<style>
.search-form {
margin-bottom: 20px;
padding: 20px;
background: #f5f7fa;
border-radius: 4px;
}
.table-toolbar {
margin-bottom: 20px;
display: flex;
justify-content: space-between;
}
.salary-range {
display: flex;
align-items: center;
gap: 10px;
}
.divider {
color: #999;
}
.unit {
color: #666;
font-size: 14px;
}
.user-search {
display: flex;
gap: 10px;
}
.user-search .el-select {
flex: 1;
}
</style>
</body>
</html>
权限控制实现
<?php
namespace App\Helpers;
class AccessControl
{
/**
* 检查用户权限
*/
public static function checkPermission($permission)
{
if (!isset($_SESSION['user_id'])) {
header('HTTP/1.1 401 Unauthorized');
echo json_encode(['error' => '未登录']);
exit;
}
// 获取用户角色权限
$sql = "SELECT p.permission_code
FROM role_permissions rp
INNER JOIN permissions p ON rp.permission_id = p.id
INNER JOIN user_roles ur ON ur.role_id = rp.role_id
WHERE ur.user_id = ?";
$db = Database::getInstance();
$stmt = $db->prepare($sql);
$stmt->execute([$_SESSION['user_id']]);
$permissions = $stmt->fetchAll(PDO::FETCH_COLUMN);
if (!in_array($permission, $permissions)) {
header('HTTP/1.1 403 Forbidden');
echo json_encode(['error' => '没有权限']);
exit;
}
}
/**
* 数据权限过滤
*/
public static function dataScope($departmentId = '')
{
$userDept = $_SESSION['department_id'] ?? '';
$userLevel = $_SESSION['user_level'] ?? '';
// 超级管理员可查看所有数据
if ($userLevel === 'super') {
return '';
}
// 部门经理可查看本部门
if ($userLevel === 'manager') {
return "department_id = {$userDept}";
}
// 普通用户仅查看自己
if ($userLevel === 'user') {
return "created_by = {$_SESSION['user_id']}";
}
return '';
}
}
最佳实践与优化
安全性优化
// SQL注入防护
// 使用预处理语句
$stmt = $db->prepare("SELECT * FROM positions WHERE id = ?");
$stmt->execute([$id]);
// XSS防护
function sanitizeOutput($data) {
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}
// CSRF防护
function generateCSRFToken() {
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
性能优化
// 缓存热门岗位数据
class PositionCache {
public static function getHotPositions() {
$cacheKey = 'hot_positions';
$data = Redis::get($cacheKey);
if (!$data) {
$db = Database::getInstance();
$stmt = $db->query("SELECT * FROM positions WHERE status=1 ORDER BY view_count DESC LIMIT 10");
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
Redis::set($cacheKey, $data, 3600);
}
return $data;
}
}
日志记录
class OperationLog {
public static function record($action, $positionId) {
$logData = [
'user_id' => $_SESSION['user_id'],
'action' => $action,
'position_id' => $positionId,
'ip' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'timestamp' => date('Y-m-d H:i:s')
];
// 写入日志
$db = Database::getInstance();
$sql = "INSERT INTO operation_logs (user_id, action, position_id, ip, user_agent, created_at)
VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $db->prepare($sql);
$stmt->execute([
$logData['user_id'],
$logData['action'],
$logData['position_id'],
$logData['ip'],
$logData['user_agent'],
$logData['timestamp']
]);
}
}
这个岗位管理系统包含了完整的CRUD操作、人员分配、权限控制等核心功能,你可以根据实际需求扩展功能,如批量导入导出、岗位对比分析、审批流程等,如果需要特定功能的详细实现,请告诉我。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播