fix:1.修复职业管理页面生成权限问题,兼容旧项目

This commit is contained in:
xiamuceer
2025-12-23 09:28:24 +08:00
parent b7d3ddf364
commit a5788e75ae
3 changed files with 20 additions and 76 deletions
+8
View File
@@ -360,6 +360,14 @@ MuMuAINovel/
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 提交 Pull Request
### 贡献者
感谢所有为本项目做出贡献的开发者!
<a href="https://github.com/xiamuceer-j/MuMuAINovel/graphs/contributors">
<img src="https://contrib.rocks/image?repo=xiamuceer-j/MuMuAINovel" />
</a>
## 📝 许可证
本项目采用 [GNU General Public License v3.0](LICENSE)
-56
View File
@@ -191,62 +191,6 @@ ORDER BY cc.career_type DESC, cc.created_at;
COMMENT ON VIEW v_character_career_details IS '角色职业详细信息视图';
-- ===== 5. 插入测试数据(可选) =====
-- 这里可以插入一些示例职业数据用于测试
-- 注意:project_id需要替换为实际存在的项目ID
/*
-- 示例:修仙类主职业
INSERT INTO careers (id, project_id, name, type, description, category, stages, max_stage, requirements, special_abilities, worldview_rules, source)
VALUES (
gen_random_uuid()::text,
'YOUR_PROJECT_ID_HERE',
'剑修',
'main',
'以剑入道,追求极致剑意,是修仙界最强大的战斗职业之一。',
'战斗系',
'[
{"level": 1, "name": "炼气期", "description": "初窥门径,凝聚剑气"},
{"level": 2, "name": "筑基期", "description": "根基稳固,剑气成形"},
{"level": 3, "name": "金丹期", "description": "凝结金丹,剑意初显"},
{"level": 4, "name": "元婴期", "description": "元婴成就,剑意大成"},
{"level": 5, "name": "化神期", "description": "化神蜕变,剑道通神"},
{"level": 6, "name": "炼虚期", "description": "炼虚合道,剑破虚空"},
{"level": 7, "name": "合体期", "description": "天人合一,剑心合道"},
{"level": 8, "name": "大乘期", "description": "大乘境界,剑开天地"},
{"level": 9, "name": "渡劫期", "description": "渡劫飞升,剑斩天劫"},
{"level": 10, "name": "仙人", "description": "飞升成仙,剑意永恒"}
]',
10,
'需要剑道天赋,坚韧不拔的意志',
'剑气纵横、剑意凌云、御剑飞行',
'符合修仙世界观,属于正统修炼体系',
'ai'
);
-- 示例:副职业
INSERT INTO careers (id, project_id, name, type, description, category, stages, max_stage, requirements, special_abilities, source)
VALUES (
gen_random_uuid()::text,
'YOUR_PROJECT_ID_HERE',
'炼丹师',
'sub',
'精通丹药炼制,能够炼制各种增强修为、疗伤、辅助的丹药。',
'生产系',
'[
{"level": 1, "name": "学徒", "description": "初学炼丹,成功率较低"},
{"level": 2, "name": "初级炼丹师", "description": "可炼制基础丹药"},
{"level": 3, "name": "中级炼丹师", "description": "可炼制进阶丹药"},
{"level": 4, "name": "高级炼丹师", "description": "可炼制高级丹药"},
{"level": 5, "name": "宗师级炼丹师", "description": "炉火纯青,可炼制顶级丹药"}
]',
5,
'需要对火候的精准掌控和丰富的药材知识',
'丹药炼制、药性分析、丹劫应对',
'ai'
);
*/
-- ===== 完成提示 =====
DO $$
BEGIN
+12 -20
View File
@@ -2,14 +2,12 @@ import { useState, useEffect } from 'react';
import { Button, Modal, Form, Input, Select, message, Row, Col, Empty, Tabs, Card, Tag, Space, Divider, Typography, InputNumber } from 'antd';
import { ThunderboltOutlined, PlusOutlined, EditOutlined, DeleteOutlined, TrophyOutlined } from '@ant-design/icons';
import { useParams } from 'react-router-dom';
import axios from 'axios';
import api from '../services/api';
import SSEProgressModal from '../components/SSEProgressModal';
const { TextArea } = Input;
const { Title, Text, Paragraph } = Typography;
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';
interface CareerStage {
level: number;
name: string;
@@ -56,14 +54,13 @@ export default function Careers() {
const fetchCareers = async () => {
try {
setLoading(true);
const response = await axios.get(`${API_BASE_URL}/api/careers`, {
params: { project_id: projectId },
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
const response: any = await api.get('/careers', {
params: { project_id: projectId }
});
setMainCareers(response.data.main_careers || []);
setSubCareers(response.data.sub_careers || []);
setMainCareers(response.main_careers || []);
setSubCareers(response.sub_careers || []);
} catch (error: any) {
message.error(error.response?.data?.detail || '获取职业列表失败');
console.error('获取职业列表失败:', error);
} finally {
setLoading(false);
}
@@ -112,17 +109,13 @@ export default function Careers() {
};
if (editingCareer) {
await axios.put(`${API_BASE_URL}/api/careers/${editingCareer.id}`, data, {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
});
await api.put(`/careers/${editingCareer.id}`, data);
message.success('职业更新成功');
} else {
await axios.post(`${API_BASE_URL}/api/careers`, {
await api.post('/careers', {
...data,
project_id: projectId,
source: 'manual'
}, {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
});
message.success('职业创建成功');
}
@@ -141,9 +134,7 @@ export default function Careers() {
content: '确定要删除这个职业吗?如果有角色使用了该职业,将无法删除。',
onOk: async () => {
try {
await axios.delete(`${API_BASE_URL}/api/careers/${id}`, {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
});
await api.delete(`/careers/${id}`);
message.success('职业删除成功');
fetchCareers();
} catch (error: any) {
@@ -161,13 +152,14 @@ export default function Careers() {
try {
const eventSource = new EventSource(
`${API_BASE_URL}/api/careers/generate-system?` +
`/api/careers/generate-system?` +
new URLSearchParams({
project_id: projectId || '',
main_career_count: values.main_career_count.toString(),
sub_career_count: values.sub_career_count.toString(),
enable_mcp: 'false'
}).toString()
}).toString(),
{ withCredentials: true }
);
eventSource.onmessage = (event) => {