待办事项暂未完全实现
This commit is contained in:
parent
e03da9a405
commit
4ff8b0b7a0
Binary file not shown.
BIN
XNSimHtml/assets/icons/png/check-square.png
Normal file
BIN
XNSimHtml/assets/icons/png/check-square.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
XNSimHtml/assets/icons/png/check-square_b.png
Normal file
BIN
XNSimHtml/assets/icons/png/check-square_b.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@ -144,6 +144,9 @@ class ContentArea extends HTMLElement {
|
||||
case 'system-log':
|
||||
contentElement = document.createElement('system-log');
|
||||
break;
|
||||
case 'todo':
|
||||
contentElement = document.createElement('todo-component');
|
||||
break;
|
||||
default:
|
||||
contentElement = document.createElement('div');
|
||||
contentElement.textContent = '正在开发中...';
|
||||
|
@ -154,9 +154,9 @@ class SubToolbar extends HTMLElement {
|
||||
<img src="assets/icons/png/clock.png" alt="更新记录" class="icon">
|
||||
更新记录
|
||||
</div>
|
||||
<div class="sub-item" data-icon="server">
|
||||
<img src="assets/icons/png/server.png" alt="系统信息" class="icon">
|
||||
系统信息
|
||||
<div class="sub-item" data-icon="check-square">
|
||||
<img src="assets/icons/png/check-square.png" alt="待办事项" class="icon">
|
||||
待办事项
|
||||
</div>
|
||||
<div class="sub-item" data-icon="help">
|
||||
<img src="assets/icons/png/help.png" alt="帮助" class="icon">
|
||||
@ -214,6 +214,10 @@ class SubToolbar extends HTMLElement {
|
||||
</div>
|
||||
<!-- 监控子菜单 -->
|
||||
<div class="sub-menu" data-parent="monitor">
|
||||
<div class="sub-item" data-icon="server">
|
||||
<img src="assets/icons/png/server.png" alt="资源监控" class="icon">
|
||||
资源监控
|
||||
</div>
|
||||
<div class="sub-item" data-icon="desktop">
|
||||
<img src="assets/icons/png/desktop.png" alt="仿真监控" class="icon">
|
||||
仿真监控
|
||||
|
311
XNSimHtml/components/todo-component.js
Normal file
311
XNSimHtml/components/todo-component.js
Normal file
@ -0,0 +1,311 @@
|
||||
class TodoComponent extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
this.todos = [];
|
||||
this.selectedProject = null;
|
||||
this.selectedSubproject = null;
|
||||
this.expandedProjects = new Set();
|
||||
}
|
||||
|
||||
async fetchTodos() {
|
||||
try {
|
||||
const response = await fetch('/api/todos');
|
||||
if (!response.ok) {
|
||||
throw new Error('获取待办事项失败');
|
||||
}
|
||||
this.todos = await response.json();
|
||||
this.render();
|
||||
} catch (error) {
|
||||
console.error('获取待办事项时发生错误:', error);
|
||||
this.showError('获取待办事项失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
|
||||
showError(message) {
|
||||
const errorDiv = document.createElement('div');
|
||||
errorDiv.className = 'error-message';
|
||||
errorDiv.textContent = message;
|
||||
this.shadowRoot.appendChild(errorDiv);
|
||||
}
|
||||
|
||||
// 构建项目树结构
|
||||
buildProjectTree() {
|
||||
const tree = {};
|
||||
this.todos.forEach(todo => {
|
||||
const project = todo.project || '其它';
|
||||
const subproject = todo.subproject || '其它';
|
||||
|
||||
if (!tree[project]) {
|
||||
tree[project] = {
|
||||
name: project,
|
||||
subprojects: {}
|
||||
};
|
||||
}
|
||||
if (!tree[project].subprojects[subproject]) {
|
||||
tree[project].subprojects[subproject] = {
|
||||
name: subproject,
|
||||
todos: []
|
||||
};
|
||||
}
|
||||
tree[project].subprojects[subproject].todos.push(todo);
|
||||
});
|
||||
return tree;
|
||||
}
|
||||
|
||||
// 渲染项目树
|
||||
renderProjectTree(tree) {
|
||||
const treeContainer = document.createElement('div');
|
||||
treeContainer.className = 'project-tree';
|
||||
|
||||
Object.values(tree).forEach(project => {
|
||||
const projectNode = document.createElement('div');
|
||||
projectNode.className = 'project-node';
|
||||
|
||||
const projectHeader = document.createElement('div');
|
||||
projectHeader.className = 'project-header';
|
||||
projectHeader.innerHTML = `
|
||||
<div class="project-header-content">
|
||||
<span class="expand-icon ${this.expandedProjects.has(project.name) ? 'expanded' : ''}">▶</span>
|
||||
<span class="project-name">${project.name}</span>
|
||||
<span class="todo-count">(${Object.values(project.subprojects).reduce((sum, sub) =>
|
||||
sum + sub.todos.length, 0)})</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
projectHeader.addEventListener('click', () => {
|
||||
this.selectedProject = project.name;
|
||||
this.selectedSubproject = null;
|
||||
this.render();
|
||||
});
|
||||
|
||||
const expandButton = projectHeader.querySelector('.expand-icon');
|
||||
expandButton.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (this.expandedProjects.has(project.name)) {
|
||||
this.expandedProjects.delete(project.name);
|
||||
} else {
|
||||
this.expandedProjects.add(project.name);
|
||||
}
|
||||
this.render();
|
||||
});
|
||||
|
||||
const subprojectsContainer = document.createElement('div');
|
||||
subprojectsContainer.className = 'subprojects-container';
|
||||
subprojectsContainer.style.display = this.expandedProjects.has(project.name) ? 'block' : 'none';
|
||||
|
||||
Object.values(project.subprojects).forEach(subproject => {
|
||||
const subprojectNode = document.createElement('div');
|
||||
subprojectNode.className = 'subproject-node';
|
||||
subprojectNode.innerHTML = `
|
||||
<span class="subproject-name">${subproject.name}</span>
|
||||
<span class="todo-count">(${subproject.todos.length})</span>
|
||||
`;
|
||||
|
||||
subprojectNode.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
this.selectedProject = project.name;
|
||||
this.selectedSubproject = subproject.name;
|
||||
this.render();
|
||||
});
|
||||
|
||||
subprojectsContainer.appendChild(subprojectNode);
|
||||
});
|
||||
|
||||
projectNode.appendChild(projectHeader);
|
||||
projectNode.appendChild(subprojectsContainer);
|
||||
treeContainer.appendChild(projectNode);
|
||||
});
|
||||
|
||||
return treeContainer;
|
||||
}
|
||||
|
||||
// 过滤待办事项
|
||||
filterTodos() {
|
||||
if (!this.selectedProject) {
|
||||
return this.todos;
|
||||
}
|
||||
|
||||
return this.todos.filter(todo => {
|
||||
const matchesProject = todo.project === this.selectedProject;
|
||||
if (!this.selectedSubproject) {
|
||||
return matchesProject;
|
||||
}
|
||||
return matchesProject && todo.subproject === this.selectedSubproject;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
// 清空现有内容
|
||||
this.shadowRoot.innerHTML = '';
|
||||
|
||||
// 添加样式
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.container {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.project-tree {
|
||||
width: 250px;
|
||||
background: #f8f9fa;
|
||||
border-right: 1px solid #e9ecef;
|
||||
padding: 15px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.todo-container {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.project-node {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.project-header {
|
||||
padding: 8px;
|
||||
background: #e9ecef;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.project-header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.project-header:hover {
|
||||
background: #dee2e6;
|
||||
}
|
||||
.expand-icon {
|
||||
font-size: 12px;
|
||||
transition: transform 0.2s;
|
||||
color: #495057;
|
||||
}
|
||||
.expand-icon.expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.subprojects-container {
|
||||
margin-left: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.subproject-node {
|
||||
padding: 6px 8px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.subproject-node:hover {
|
||||
background: #e9ecef;
|
||||
}
|
||||
.todo-count {
|
||||
font-size: 0.9em;
|
||||
color: #6c757d;
|
||||
}
|
||||
.todo-item {
|
||||
background: #fff;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
||||
}
|
||||
.todo-item h3 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #212529;
|
||||
}
|
||||
.todo-item p {
|
||||
margin: 5px 0;
|
||||
color: #495057;
|
||||
}
|
||||
.todo-item .status {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.9em;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.todo-item .status.completed {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
.todo-item .status.pending {
|
||||
background: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
.todo-item .meta {
|
||||
font-size: 0.85em;
|
||||
color: #6c757d;
|
||||
margin-top: 10px;
|
||||
border-top: 1px solid #e9ecef;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.error-message {
|
||||
color: #721c24;
|
||||
padding: 10px;
|
||||
background: #f8d7da;
|
||||
border-radius: 4px;
|
||||
margin: 10px;
|
||||
}
|
||||
.selected {
|
||||
background: #cfe2ff !important;
|
||||
}
|
||||
`;
|
||||
this.shadowRoot.appendChild(style);
|
||||
|
||||
// 创建主容器
|
||||
const container = document.createElement('div');
|
||||
container.className = 'container';
|
||||
|
||||
// 构建并渲染项目树
|
||||
const tree = this.buildProjectTree();
|
||||
const treeContainer = this.renderProjectTree(tree);
|
||||
container.appendChild(treeContainer);
|
||||
|
||||
// 创建待办事项列表容器
|
||||
const todosContainer = document.createElement('div');
|
||||
todosContainer.className = 'todo-container';
|
||||
|
||||
// 渲染过滤后的待办事项
|
||||
const filteredTodos = this.filterTodos();
|
||||
filteredTodos.forEach(todo => {
|
||||
const todoElement = document.createElement('div');
|
||||
todoElement.className = 'todo-item';
|
||||
|
||||
// 格式化日期
|
||||
const createdDate = new Date(todo.created_at).toLocaleString('zh-CN');
|
||||
const scheDate = new Date(todo.sche_time).toLocaleString('zh-CN');
|
||||
const completeDate = todo.complete_time ?
|
||||
new Date(todo.complete_time).toLocaleString('zh-CN') : '未完成';
|
||||
|
||||
todoElement.innerHTML = `
|
||||
<h3>${todo.title}</h3>
|
||||
<p>${todo.text || '无详细描述'}</p>
|
||||
<p>项目:${todo.project}</p>
|
||||
<p>子项目:${todo.subproject}</p>
|
||||
<p>执行人:${todo.exeuser || '未分配'}</p>
|
||||
<p>计划时间:${scheDate}</p>
|
||||
<div class="status ${todo.completed ? 'completed' : 'pending'}">
|
||||
${todo.completed ? '已完成' : '进行中'}
|
||||
</div>
|
||||
<div class="meta">
|
||||
<p>创建人:${todo.adduser}</p>
|
||||
<p>创建时间:${createdDate}</p>
|
||||
<p>完成时间:${completeDate}</p>
|
||||
</div>
|
||||
`;
|
||||
todosContainer.appendChild(todoElement);
|
||||
});
|
||||
|
||||
container.appendChild(todosContainer);
|
||||
this.shadowRoot.appendChild(container);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// 组件被添加到DOM时获取数据
|
||||
this.fetchTodos();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('todo-component', TodoComponent);
|
0
XNSimHtml/data/xnsim.db
Normal file
0
XNSimHtml/data/xnsim.db
Normal file
@ -32,6 +32,9 @@
|
||||
<script src="components/user-management.js"></script>
|
||||
<script src="components/model-development.js"></script>
|
||||
<script src="components/service-development.js"></script>
|
||||
<script src="components/header-tools.js"></script>
|
||||
<script src="components/qa-component.js"></script>
|
||||
<script src="components/todo-component.js" type="module"></script>
|
||||
<style>
|
||||
.icon {
|
||||
width: 24px;
|
||||
@ -206,8 +209,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="components/header-tools.js"></script>
|
||||
<script src="components/qa-component.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const tabsContainer = document.querySelector('tabs-container');
|
||||
@ -317,10 +318,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理系统信息标签页
|
||||
if (title === '系统信息') {
|
||||
// 处理资源监控标签页
|
||||
if (title === '资源监控') {
|
||||
const id = 'system-info';
|
||||
tabsContainer.createTab(id, title, icon, parentText, parentTool);
|
||||
contentArea.loadContent(id);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -332,6 +334,14 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理待办事项标签页
|
||||
if (title === '待办事项') {
|
||||
const id = 'todo';
|
||||
tabsContainer.createTab(id, title, icon, parentText, parentTool);
|
||||
contentArea.loadContent(id);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理帮助标签页
|
||||
if (title === '帮助') {
|
||||
const id = 'help';
|
||||
@ -457,7 +467,7 @@
|
||||
'概览': 'dashboard',
|
||||
'更新记录': 'clock',
|
||||
'运行日志': 'file',
|
||||
'系统信息': 'server',
|
||||
'资源监控': 'server',
|
||||
'帮助': 'help',
|
||||
'Q&A': 'question',
|
||||
'运行环境配置': 'chip',
|
||||
|
50
XNSimHtml/routes/todos.js
Normal file
50
XNSimHtml/routes/todos.js
Normal file
@ -0,0 +1,50 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { getTodos, addTodo, updateTodoStatus, deleteTodo } = require('../utils/db-utils');
|
||||
|
||||
// 获取所有待办事项
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const todos = await getTodos();
|
||||
res.json(todos);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 添加新的待办事项
|
||||
router.post('/', async (req, res) => {
|
||||
try {
|
||||
const todoData = req.body;
|
||||
const result = await addTodo(todoData);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
console.error('添加待办事项失败:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 更新待办事项状态
|
||||
router.put('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { title, text, exeuser, sche_time, completed } = req.body;
|
||||
const result = await updateTodoStatus(id, completed, exeuser, title, text, sche_time);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 删除待办事项
|
||||
router.delete('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const result = await deleteTodo(id);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
22
XNSimHtml/routes/users.js
Normal file
22
XNSimHtml/routes/users.js
Normal file
@ -0,0 +1,22 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { getUsers } = require('../utils/db-utils');
|
||||
|
||||
// 获取所有用户信息
|
||||
router.get('/users', async (req, res) => {
|
||||
try {
|
||||
const users = await getUsers();
|
||||
res.json({
|
||||
success: true,
|
||||
users: users
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取用户信息失败'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
@ -22,6 +22,8 @@ const productsRoutes = require('./routes/products');
|
||||
const interfaceRoutes = require('./routes/interface-config');
|
||||
const icdImportRoutes = require('./routes/icd-import');
|
||||
const qaRoutes = require('./routes/qa');
|
||||
const todoRoutes = require('./routes/todos');
|
||||
const userRoutes = require('./routes/users');
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
@ -75,6 +77,8 @@ app.use('/api', productsRoutes);
|
||||
app.use('/api/interface', interfaceRoutes);
|
||||
app.use('/api/icd', icdImportRoutes);
|
||||
app.use('/api/qa', qaRoutes);
|
||||
app.use('/api/todos', todoRoutes);
|
||||
app.use('/api', userRoutes);
|
||||
|
||||
// 主页路由
|
||||
app.get('/', (req, res) => {
|
||||
|
@ -1184,6 +1184,233 @@ function deleteAnswer(answerId) {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有待办事项
|
||||
function getTodos() {
|
||||
try {
|
||||
const xnCorePath = getXNCorePath();
|
||||
if (!xnCorePath) {
|
||||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||||
}
|
||||
|
||||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||||
if (!dbPath) {
|
||||
throw new Error('无法找到数据库文件');
|
||||
}
|
||||
|
||||
// 打开数据库连接
|
||||
const db = new Database(dbPath, { readonly: true });
|
||||
|
||||
// 创建todos表(如果不存在)
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS todos (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
project TEXT NOT NULL DEFAULT '其它',
|
||||
subproject TEXT NOT NULL DEFAULT '其它',
|
||||
title TEXT NOT NULL,
|
||||
text TEXT,
|
||||
adduser TEXT NOT NULL,
|
||||
exeuser TEXT,
|
||||
completed BOOLEAN DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
sche_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
complete_time DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`).run();
|
||||
|
||||
const todos = db.prepare('SELECT * FROM todos ORDER BY created_at DESC').all();
|
||||
db.close();
|
||||
|
||||
return todos;
|
||||
} catch (error) {
|
||||
console.error('获取待办事项失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加待办事项
|
||||
function addTodo(todoData) {
|
||||
try {
|
||||
if (!todoData.title) {
|
||||
throw new Error('待办事项标题不能为空');
|
||||
}
|
||||
|
||||
const xnCorePath = getXNCorePath();
|
||||
if (!xnCorePath) {
|
||||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||||
}
|
||||
|
||||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||||
if (!dbPath) {
|
||||
throw new Error('无法找到数据库文件');
|
||||
}
|
||||
|
||||
// 打开数据库连接
|
||||
const db = new Database(dbPath);
|
||||
|
||||
const result = db.prepare(`
|
||||
INSERT INTO todos (
|
||||
project, subproject, title, text, adduser,
|
||||
completed, created_at, sche_time
|
||||
) VALUES (?, ?, ?, ?, ?, 0, CURRENT_TIMESTAMP, ?)
|
||||
`).run(
|
||||
todoData.project || '其它',
|
||||
todoData.subproject || '其它',
|
||||
todoData.title,
|
||||
todoData.text || '',
|
||||
todoData.adduser || '系统',
|
||||
todoData.sche_time || new Date().toISOString()
|
||||
);
|
||||
|
||||
db.close();
|
||||
|
||||
if (result.changes > 0) {
|
||||
return {
|
||||
success: true,
|
||||
id: result.lastInsertRowid,
|
||||
message: '待办事项添加成功'
|
||||
};
|
||||
} else {
|
||||
throw new Error('待办事项添加失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加待办事项失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新待办事项状态
|
||||
function updateTodoStatus(id, completed, exeuser, title, text, sche_time) {
|
||||
try {
|
||||
const xnCorePath = getXNCorePath();
|
||||
if (!xnCorePath) {
|
||||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||||
}
|
||||
|
||||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||||
if (!dbPath) {
|
||||
throw new Error('无法找到数据库文件');
|
||||
}
|
||||
|
||||
// 打开数据库连接
|
||||
const db = new Database(dbPath);
|
||||
|
||||
const result = db.prepare(`
|
||||
UPDATE todos
|
||||
SET completed = ?,
|
||||
exeuser = ?,
|
||||
title = ?,
|
||||
text = ?,
|
||||
sche_time = ?,
|
||||
complete_time = CASE WHEN ? = 1 THEN CURRENT_TIMESTAMP ELSE complete_time END
|
||||
WHERE id = ?
|
||||
`).run(
|
||||
completed ? 1 : 0,
|
||||
exeuser || null,
|
||||
title,
|
||||
text || '',
|
||||
sche_time || null,
|
||||
completed ? 1 : 0,
|
||||
id
|
||||
);
|
||||
|
||||
db.close();
|
||||
|
||||
if (result.changes > 0) {
|
||||
return {
|
||||
success: true,
|
||||
message: '待办事项更新成功'
|
||||
};
|
||||
} else {
|
||||
throw new Error('待办事项不存在');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('更新待办事项失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 删除待办事项
|
||||
function deleteTodo(id) {
|
||||
try {
|
||||
const xnCorePath = getXNCorePath();
|
||||
if (!xnCorePath) {
|
||||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||||
}
|
||||
|
||||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||||
if (!dbPath) {
|
||||
throw new Error('无法找到数据库文件');
|
||||
}
|
||||
|
||||
// 打开数据库连接
|
||||
const db = new Database(dbPath);
|
||||
|
||||
const result = db.prepare('DELETE FROM todos WHERE id = ?').run(id);
|
||||
db.close();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: result.changes > 0 ? '待办事项删除成功' : '待办事项不存在或已被删除'
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('删除待办事项失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有用户信息
|
||||
function getUsers() {
|
||||
try {
|
||||
const xnCorePath = getXNCorePath();
|
||||
if (!xnCorePath) {
|
||||
throw new Error('XNCore环境变量未设置,无法获取数据库路径');
|
||||
}
|
||||
|
||||
const dbPath = xnCorePath + '/database/XNSim.db';
|
||||
if (!dbPath) {
|
||||
throw new Error('无法找到数据库文件');
|
||||
}
|
||||
|
||||
// 打开数据库连接
|
||||
const db = new Database(dbPath, { readonly: true });
|
||||
|
||||
// 创建users表(如果不存在)
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
access_level INTEGER DEFAULT 1,
|
||||
full_name TEXT,
|
||||
phone TEXT,
|
||||
email TEXT,
|
||||
department TEXT,
|
||||
position TEXT
|
||||
)
|
||||
`).run();
|
||||
|
||||
const users = db.prepare(`
|
||||
SELECT
|
||||
id,
|
||||
username,
|
||||
access_level,
|
||||
full_name,
|
||||
phone,
|
||||
email,
|
||||
department,
|
||||
position
|
||||
FROM users
|
||||
ORDER BY id ASC
|
||||
`).all();
|
||||
|
||||
db.close();
|
||||
|
||||
return users;
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getATAChapters,
|
||||
getModelsByChapterId,
|
||||
@ -1203,5 +1430,10 @@ module.exports = {
|
||||
createQuestion,
|
||||
addAnswer,
|
||||
deleteQuestion,
|
||||
deleteAnswer
|
||||
deleteAnswer,
|
||||
getTodos,
|
||||
addTodo,
|
||||
updateTodoStatus,
|
||||
deleteTodo,
|
||||
getUsers
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user