@yuku123/z-task-frontend-component 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ import {useEffect, useState} from 'react'
2
+ import {Card, Table, Button, Modal, Form, Input, Select, Space, message, Tag} from 'antd'
3
+ import {PlusOutlined, CheckOutlined} from '@ant-design/icons'
4
+ import {taskApi} from '../api'
5
+
6
+ /**
7
+ * 任务管理 (从 z-opc-main-starter-frontend/src/pages/task/task/TaskList.jsx 迁入).
8
+ *
9
+ * Props:
10
+ * - apiBaseURL?: string 后端 baseURL, 默认 '/api'
11
+ */
12
+ export default function TaskList({apiBaseURL}) {
13
+ const [projects, setProjects] = useState([])
14
+ const [projectId, setProjectId] = useState(null)
15
+ const [tasks, setTasks] = useState([])
16
+ const [loading, setLoading] = useState(false)
17
+ const [modalOpen, setModalOpen] = useState(false)
18
+ const [form] = Form.useForm()
19
+
20
+ const loadProjects = async () => {
21
+ try {
22
+ const res = await taskApi.listMyProjects()
23
+ const list = res?.data || res || []
24
+ setProjects(list)
25
+ if (list.length > 0 && !projectId) setProjectId(list[0].id)
26
+ } catch (e) {
27
+ message.error('加载项目失败: ' + (e?.message || e))
28
+ }
29
+ }
30
+
31
+ const loadTasks = async (pid) => {
32
+ if (!pid) { setTasks([]); return }
33
+ setLoading(true)
34
+ try {
35
+ const res = await taskApi.listTasksByProject(pid)
36
+ setTasks(res?.data || res || [])
37
+ } catch (e) {
38
+ message.error('加载任务失败: ' + (e?.message || e))
39
+ } finally {
40
+ setLoading(false)
41
+ }
42
+ }
43
+
44
+ useEffect(() => { loadProjects() }, [])
45
+ useEffect(() => { loadTasks(projectId) }, [projectId])
46
+
47
+ const onCreate = () => {
48
+ if (!projectId) {
49
+ message.warning('请先选择项目')
50
+ return
51
+ }
52
+ form.resetFields()
53
+ form.setFieldsValue({projectId, listId: 1, status: 1, priority: 1})
54
+ setModalOpen(true)
55
+ }
56
+
57
+ const onSubmit = async () => {
58
+ try {
59
+ const values = await form.validateFields()
60
+ await taskApi.createTask(values)
61
+ message.success('任务已创建')
62
+ setModalOpen(false)
63
+ loadTasks(projectId)
64
+ } catch (e) {
65
+ if (e?.errorFields) return
66
+ message.error('创建失败: ' + (e?.message || e))
67
+ }
68
+ }
69
+
70
+ const onComplete = async (id) => {
71
+ try {
72
+ await taskApi.completeTask(id)
73
+ message.success('任务已完成')
74
+ loadTasks(projectId)
75
+ } catch (e) {
76
+ message.error('操作失败: ' + (e?.message || e))
77
+ }
78
+ }
79
+
80
+ const columns = [
81
+ {title: 'ID', dataIndex: 'id', width: 60},
82
+ {title: '标题', dataIndex: 'title'},
83
+ {title: '项目ID', dataIndex: 'projectId', width: 80},
84
+ {title: '状态', dataIndex: 'status', width: 100,
85
+ render: (s) => {
86
+ const map = {0: '待办', 1: '进行中', 2: '已完成'}
87
+ const color = {0: 'default', 1: 'blue', 2: 'green'}[s] || 'default'
88
+ return <Tag color={color}>{map[s] || s}</Tag>
89
+ },
90
+ },
91
+ {title: '优先级', dataIndex: 'priority', width: 80},
92
+ {title: '截止时间', dataIndex: 'dueDate', width: 180},
93
+ {
94
+ title: '操作', width: 200, fixed: 'right',
95
+ render: (_, row) => (
96
+ <Space>
97
+ <Button size="small" type="primary" icon={<CheckOutlined/>}
98
+ onClick={() => onComplete(row.id)}
99
+ disabled={row.status === 2}>
100
+ 完成
101
+ </Button>
102
+ </Space>
103
+ ),
104
+ },
105
+ ]
106
+
107
+ return (
108
+ <div>
109
+ <Card
110
+ title="任务管理"
111
+ extra={
112
+ <Space>
113
+ <span>项目:</span>
114
+ <Select
115
+ value={projectId}
116
+ onChange={setProjectId}
117
+ style={{width: 240}}
118
+ placeholder="选择项目"
119
+ options={projects.map(p => ({label: p.name, value: p.id}))}
120
+ />
121
+ <Button type="primary" icon={<PlusOutlined/>} onClick={onCreate}>新建任务</Button>
122
+ </Space>
123
+ }
124
+ >
125
+ <Table
126
+ rowKey="id"
127
+ columns={columns}
128
+ dataSource={tasks}
129
+ loading={loading}
130
+ pagination={{pageSize: 10}}
131
+ />
132
+ </Card>
133
+
134
+ <Modal
135
+ title="新建任务"
136
+ open={modalOpen}
137
+ onCancel={() => setModalOpen(false)}
138
+ onOk={onSubmit}
139
+ destroyOnHidden
140
+ >
141
+ <Form form={form} layout="vertical" preserve={false}>
142
+ <Form.Item name="title" label="任务标题" rules={[{required: true, message: '请输入任务标题'}]}>
143
+ <Input placeholder="例如: 实现 xx 功能"/>
144
+ </Form.Item>
145
+ <Form.Item name="projectId" label="所属项目" rules={[{required: true}]}>
146
+ <Select
147
+ options={projects.map(p => ({label: p.name, value: p.id}))}
148
+ placeholder="从数据库捞出的项目列表"
149
+ />
150
+ </Form.Item>
151
+ <Form.Item name="listId" label="列表ID" rules={[{required: true}]}>
152
+ <Input type="number" placeholder="默认 1"/>
153
+ </Form.Item>
154
+ <Form.Item name="priority" label="优先级" initialValue={1}>
155
+ <Select options={[{label: '低', value: 1}, {label: '中', value: 2}, {label: '高', value: 3}]}/>
156
+ </Form.Item>
157
+ </Form>
158
+ </Modal>
159
+ </div>
160
+ )
161
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export {default as TaskCard} from './components/TaskCard'
2
+ export {default as TaskTable} from './components/TaskTable'
3
+ export {default as ProjectSelect} from './components/ProjectSelect'
4
+ export {default as ProjectList} from './components/ProjectList'
5
+ export {default as TaskList} from './components/TaskList'
6
+ export {default as TaskApp} from './components/TaskApp'
7
+ export {taskApi} from './api'
package/src/index.js CHANGED
@@ -3,4 +3,13 @@
3
3
  */
4
4
  export {default as TaskCard} from './components/TaskCard'
5
5
  export {default as TaskTable} from './components/TaskTable'
6
- export {default as ProjectSelect} from './components/ProjectSelect'
6
+ export {default as ProjectSelect} from './components/ProjectSelect'
7
+
8
+ // 业务页面 (FEATURE015+ 后从 z-opc-main-starter-frontend 迁入)
9
+ export {default as ProjectList} from './components/ProjectList'
10
+ export {default as TaskList} from './components/TaskList'
11
+ export {default as TaskApp} from './components/TaskApp'
12
+
13
+ // API 客户端
14
+ export {taskApi} from './api'
15
+ export {default as api} from './api'
@@ -0,0 +1,76 @@
1
+ /**
2
+ * 兼容垫片: 之前在 z-opc-main-starter-frontend/services/ 里的所有 axios 客户端
3
+ * 这里直接 re-export z-frontend-common 的 utils/request, 并提供 makeApi 工具.
4
+ */
5
+ import request, {authRequest, setupInterceptors} from '../utils/request'
6
+ export {request as default, authRequest, setupInterceptors}
7
+
8
+ function makeApi(name) {
9
+ return {
10
+ list: (params) => request.get(`/${name}/list`, {params}).then(r => r.data),
11
+ page: (params) => request.get(`/${name}/page`, {params}).then(r => r.data),
12
+ get: (id) => request.get(`/${name}/${id}`).then(r => r.data),
13
+ create: (data) => request.post(`/${name}`, data).then(r => r.data),
14
+ update: (id, data) => request.put(`/${name}/${id}`, data).then(r => r.data),
15
+ delete: (id) => request.delete(`/${name}/${id}`).then(r => r.data),
16
+ }
17
+ }
18
+
19
+ export const configApi = makeApi('config')
20
+ export const approvalApi = makeApi('approval')
21
+ export const designerApi = makeApi('designer')
22
+ export const mcpApi = makeApi('mcp')
23
+ export const mockPlatformApi = makeApi('mock')
24
+ export const namingApi = makeApi('naming')
25
+ export const opsApi = makeApi('ops')
26
+ export const ossApi = makeApi('oss')
27
+ export const scriptApi = makeApi('script')
28
+ export const skillApi = makeApi('skill')
29
+ export const agentApi = makeApi('agent')
30
+ export const flowApi = makeApi('flow')
31
+ export const traceApi = makeApi('trace')
32
+ export const llmApi = makeApi('llm')
33
+ export const productApi = makeApi('product')
34
+ export const sceneApi = makeApi('scene')
35
+ export const ctcAcAccountApi = makeApi('ctc/ac/accounts')
36
+ export const ctcAcLoginLogApi = makeApi('ctc/ac/login-log')
37
+ export const ctcAcTenantApi = makeApi('ctc/ac/tenants')
38
+ export const ctcAcDomainApi = makeApi('ctc/ac/domains')
39
+ export const ctcAcOrgApi = makeApi('ctc/ac/orgs')
40
+ export const ctcAcDeptApi = makeApi('ctc/ac/depts')
41
+ export const ctcAcGroupApi = makeApi('ctc/ac/groups')
42
+ export const ctcAuthorizationApi = makeApi('ctc/authorization')
43
+ export const metaAppApi = makeApi('meta-app')
44
+ export const jobApi = makeApi('schedule/job')
45
+ export const webideApi = makeApi('webide')
46
+ export const privateConfigApi = makeApi('private-config')
47
+ export const ctcSurlApi = makeApi('ctc/surl')
48
+ export const ctcUserApi = makeApi('ctc/user')
49
+ export const agentTeamApi = makeApi('agent/team')
50
+ export const workspaceApi = makeApi('agent/team/workspace')
51
+
52
+ // === 项目 / 任务 / 鉴权 ===
53
+ export const login = (data) => request.post('/ctc/auth/login', data).then(r => r.data)
54
+ export const getCurrentUser = () => {
55
+ try { return Promise.resolve(JSON.parse(localStorage.getItem('userInfo') || 'null')) }
56
+ catch { return Promise.resolve(null) }
57
+ }
58
+ export const switchTenant = (tenantCode, domainCode) =>
59
+ authRequest.post('/ctc/auth/switch-tenant', {tenantCode: tenantCode || '', domainCode: domainCode || ''}).then(r => r.data)
60
+ export const listMyProjects = () => authRequest.get('/project/user/list').then(r => r.data)
61
+ export const createProject = (data) => request.post('/project', data).then(r => r.data)
62
+ export const updateProject = (id, data) => request.put(`/project/${id}`, data).then(r => r.data)
63
+ export const archiveProject = (id) => request.put(`/project/${id}/archive`).then(r => r.data)
64
+ export const listTasksByProject = (projectId) => request.get('/task/project/list', {params: {projectId}}).then(r => r.data)
65
+ export const createTask = (data) => request.post('/task', data).then(r => r.data)
66
+ export const completeTask = (id) => request.post('/task/complete', null, {params: {taskId: id}}).then(r => r.data)
67
+ export const moveTask = (taskId, targetListId, position) =>
68
+ request.put('/task/move', null, {params: {taskId, targetListId, position}}).then(r => r.data)
69
+ export const listTasksByList = (listId) => request.get('/task/list', {params: {listId}}).then(r => r.data)
70
+ export const getDomainByTenantCode = async () => [{domainCode: 'default', domainName: '默认域'}]
71
+ export const getTenantList = async () => []
72
+ export const getDynamicMenu = async () => []
73
+ export const userOrgRelApi = {
74
+ usersByDept: () => Promise.resolve([]),
75
+ usersByGroup: () => Promise.resolve([]),
76
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 兼容垫片: 从 @yuku123/z-frontend-common re-export
3
+ * 历史上各业务页面的 import 路径是 '../../../utils/request',保留这个 shim.
4
+ */
5
+ export {request as default, authRequest, ctcRequest, createRequest, setupInterceptors} from '@yuku123/z-frontend-common'