本帖最后由 bdxs2019 于 2026-6-12 22:47 编辑
之前用HTML写的2个小工具,功能等等都不是很理想
1、https://www.52pojie.cn/thread-2056057-1-1.html
2、https://www.52pojie.cn/thread-2055533-1-1.html
这次做了个团队的,免费开源,支持本地和服务器部署:
待办事项团队版 v1.0.0-beta源码下载:
团队计划管理.zip
(282.04 KB, 下载次数: 0)
说明:
0、数据库文件在根目录sql.sql
1、代码完全开源,可自行二开
2、根目录附带了部署教程,含宝塔和PHPStudy的部署教程DEPLOY.md---论坛里也有很多教程
3、由于测试版,可能有未知错误,可反馈,陆续修复
特色功能:
1、日报 周报 月报支持获取完成任务事项提交,可补充说明
2、支持任务跨天执行
3、支持系统提醒及邮件双重提醒(可开启微信邮件提醒功能)
4、单个任务支持1个主负责人+多人协助
5、单个任务支持一次性、每天、每周、每月执行,无需重复定制
6、系统设置里支持隐藏周六、周日、晚上时间段
7、支持深浅色功能切换
8、系统名称、logo可以自定义
部分功能界面欣赏:
简介
一款面向中小团队的计划管理与工作日志一体化平台,支持公司级、部门级、个人多维度任务编排,搭配日报 / 周报 / 月报撰写与多级点评机制,帮助团队高效协作、透明化管理。核心功能仪表盘- 今日 / 本周任务概览,支持在仪表盘点击圆圈快速完成 / 恢复任务
- 待办统计卡片(今日待办、已延期、即将到期、即将开始/结束、日志未写)
- 任务列表按日期分组展示,显示优先级、状态、负责人
计划体系- 多视角切换:日视图 / 周视图 / 月视图
- 三级计划类型:公司级、部门级、个人
- 任务属性:标题、描述、时间段(上午/下午/晚上)、起止时间、优先级(高/中/低)、负责人
- 协助人员:每项任务可添加多位协助人员
- 跨天任务:支持多日期跨度,在日历视图中连续展示
- 内联修改、拖拽排序、快速完成
- 任务筛选与关键词搜索
工作日志- 日报 / 周报 / 月报撰写,系统自动汇总对应时段内完成的任务清单
- 多级点评机制:部门主管点评本部门员工日志,管理员可追加点评,多条点评互不覆盖
- 待点评侧边栏提示,支持按状态筛选
提醒中心- 今日待办、已延期、即将到期、即将开始/结束、本周任务、日志未写
- 按优先级和日期排序,一键跳转处理
组织架构- 岗位权限:自定义岗位,细粒度权限控制(查看/添加/编辑/删除 + 协助人员/日志点评独立开关)
- 数据范围:仅自己 / 本部门 / 全部数据
- 部门管理、员工管理
- 头像上传(MIME 类型校验)
操作日志- 记录管理员关键操作(创建/编辑/删除任务、日志、部门、岗位、用户等)
- 按操作类型筛选、关键词搜索、分页查看
- 记录操作人、IP、时间
系统设置- 基本信息:系统名称、副标题、Logo、Favicon
- 邮件通知:SMTP 配置、提醒通知开关、每日提醒时间、测试邮件
- 显示设置:浅色/深色主题、周起始日、每页条数、周视图列隐藏
[PHP] 纯文本查看 复制代码 <?php
/**
* PlanFlow - 入口文件 / 路由分发
* 访问方式: index.php?page=xxx
*/
require_once __DIR__ . '/functions.php';
// 一次性迁移:清除数据库中留存的 ui-avatars.com 默认头像URL
try {
$migDb = getDB();
$migDb->exec("UPDATE users SET avatar = NULL WHERE avatar LIKE 'https://ui-avatars.com/%'");
} catch (Exception $e) {}
// 自动建表:操作日志
try {
$migDb = getDB();
$migDb->exec("CREATE TABLE IF NOT EXISTS `operation_logs` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL COMMENT '操作用户ID',
`username` varchar(64) DEFAULT '' COMMENT '操作用户姓名',
`action` varchar(64) NOT NULL COMMENT '操作动作',
`target` varchar(255) DEFAULT '' COMMENT '操作对象',
`detail` text COMMENT '操作详情',
`ip` varchar(45) DEFAULT '' COMMENT 'IP地址',
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_action` (`action`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表'");
} catch (Exception $e) {}
session_start();
$page = $_GET['page'] ?? 'dashboard';
// API路由
if ($page === 'api') {
// API返回纯JSON,禁止任何HTML/错误输出污染响应
ini_set('display_errors', '0');
ini_set('log_errors', '1');
set_error_handler(function($errno, $errstr, $errfile, $errline) {
error_log("PHP Warning: $errstr in $errfile:$errline");
return true;
});
set_exception_handler(function($e) {
while (ob_get_level()) ob_end_clean();
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['success' => false, 'message' => '服务器内部错误: ' . $e->getMessage(), 'code' => 500], JSON_UNESCAPED_UNICODE);
});
ob_start();
$api = $_GET['api'] ?? '';
$apiFile = __DIR__ . '/api/' . $api . '.php';
try {
if (file_exists($apiFile)) {
require_once $apiFile;
} else {
response_json(['success' => false, 'message' => 'API接口不存在'], 404);
}
} catch (Throwable $e) {
while (ob_get_level()) ob_end_clean();
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['success' => false, 'message' => $e->getMessage(), 'code' => 500], JSON_UNESCAPED_UNICODE);
}
exit;
}
// 页面路由
$routes = [
'dashboard' => 'views/dashboard.php',
'plans' => 'views/plans.php',
'plan_manage' => 'views/plan_manage.php',
'logs' => 'views/logs.php',
'board' => 'views/board.php',
'org' => 'views/org.php',
'reports' => 'views/reports.php',
'settings' => 'views/settings.php',
'profile' => 'views/profile.php',
'login' => 'views/login.php',
'oplogs' => 'views/oplogs.php',
];
$viewFile = $routes[$page] ?? 'views/dashboard.php';
// 检查登录(登录页除外)
if ($page !== 'login' && !isLoggedIn()) {
header('Location: index.php?page=login');
exit;
}
if (file_exists(__DIR__ . '/' . $viewFile)) {
require_once __DIR__ . '/' . $viewFile;
} else {
http_response_code(404);
echo '页面不存在';
}
|