chore: apply cargo fmt across workspace and update docs
- Run cargo fmt on all Rust crates for consistent formatting - Update CLAUDE.md with WASM plugin commands and dev.ps1 instructions - Update wiki: add WASM plugin architecture, rewrite dev environment docs - Minor frontend cleanup (unused imports)
This commit is contained in:
@@ -14,6 +14,7 @@ export interface UserInfo {
|
||||
avatar_url?: string;
|
||||
status: string;
|
||||
roles: RoleInfo[];
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface RoleInfo {
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface OrganizationInfo {
|
||||
level: number;
|
||||
sort_order: number;
|
||||
children: OrganizationInfo[];
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface CreateOrganizationRequest {
|
||||
@@ -24,6 +25,7 @@ export interface UpdateOrganizationRequest {
|
||||
name?: string;
|
||||
code?: string;
|
||||
sort_order?: number;
|
||||
version: number;
|
||||
}
|
||||
|
||||
// --- Department types ---
|
||||
@@ -38,6 +40,7 @@ export interface DepartmentInfo {
|
||||
path?: string;
|
||||
sort_order: number;
|
||||
children: DepartmentInfo[];
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface CreateDepartmentRequest {
|
||||
@@ -53,6 +56,7 @@ export interface UpdateDepartmentRequest {
|
||||
code?: string;
|
||||
manager_id?: string;
|
||||
sort_order?: number;
|
||||
version: number;
|
||||
}
|
||||
|
||||
// --- Position types ---
|
||||
@@ -64,6 +68,7 @@ export interface PositionInfo {
|
||||
code?: string;
|
||||
level: number;
|
||||
sort_order: number;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface CreatePositionRequest {
|
||||
@@ -78,6 +83,7 @@ export interface UpdatePositionRequest {
|
||||
code?: string;
|
||||
level?: number;
|
||||
sort_order?: number;
|
||||
version: number;
|
||||
}
|
||||
|
||||
// --- Organization API ---
|
||||
|
||||
@@ -7,6 +7,7 @@ export interface RoleInfo {
|
||||
code: string;
|
||||
description?: string;
|
||||
is_system: boolean;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface PermissionInfo {
|
||||
@@ -27,6 +28,7 @@ export interface CreateRoleRequest {
|
||||
export interface UpdateRoleRequest {
|
||||
name?: string;
|
||||
description?: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export async function listRoles(page = 1, pageSize = 20) {
|
||||
|
||||
@@ -22,6 +22,7 @@ export interface UpdateUserRequest {
|
||||
phone?: string;
|
||||
display_name?: string;
|
||||
status?: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export async function listUsers(page = 1, pageSize = 20, search = '') {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { Badge, List, Popover, Button, Empty, Typography, Space, theme } from 'antd';
|
||||
import { BellOutlined, CheckOutlined } from '@ant-design/icons';
|
||||
import { Badge, List, Popover, Button, Empty, Typography, theme } from 'antd';
|
||||
import { BellOutlined } from '@ant-design/icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useMessageStore } from '../stores/message';
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ const SidebarMenuItem = memo(function SidebarMenuItem({
|
||||
export default function MainLayout({ children }: { children: React.ReactNode }) {
|
||||
const { sidebarCollapsed, toggleSidebar, theme: themeMode, setTheme } = useAppStore();
|
||||
const { user, logout } = useAuthStore();
|
||||
const { token } = theme.useToken();
|
||||
theme.useToken();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const currentPath = location.pathname || '/';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Form, Input, Button, message, Divider } from 'antd';
|
||||
import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons';
|
||||
|
||||
@@ -10,8 +10,6 @@ import {
|
||||
Table,
|
||||
Popconfirm,
|
||||
message,
|
||||
Typography,
|
||||
Card,
|
||||
Empty,
|
||||
Tag,
|
||||
theme,
|
||||
@@ -52,7 +50,7 @@ export default function Organizations() {
|
||||
// --- Org tree state ---
|
||||
const [orgTree, setOrgTree] = useState<OrganizationInfo[]>([]);
|
||||
const [selectedOrg, setSelectedOrg] = useState<OrganizationInfo | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [, setLoading] = useState(false);
|
||||
|
||||
// --- Department tree state ---
|
||||
const [deptTree, setDeptTree] = useState<DepartmentInfo[]>([]);
|
||||
@@ -144,6 +142,7 @@ export default function Organizations() {
|
||||
name: values.name,
|
||||
code: values.code,
|
||||
sort_order: values.sort_order,
|
||||
version: editOrg.version,
|
||||
});
|
||||
message.success('组织更新成功');
|
||||
} else {
|
||||
|
||||
@@ -69,7 +69,7 @@ export default function Roles() {
|
||||
}) => {
|
||||
try {
|
||||
if (editRole) {
|
||||
await updateRole(editRole.id, values);
|
||||
await updateRole(editRole.id, { ...values, version: editRole.version });
|
||||
message.success('角色更新成功');
|
||||
} else {
|
||||
await createRole(values);
|
||||
|
||||
@@ -107,6 +107,7 @@ export default function Users() {
|
||||
display_name: values.display_name,
|
||||
email: values.email,
|
||||
phone: values.phone,
|
||||
version: editUser.version,
|
||||
};
|
||||
await updateUser(editUser.id, req);
|
||||
message.success('用户更新成功');
|
||||
@@ -144,7 +145,9 @@ export default function Users() {
|
||||
|
||||
const handleToggleStatus = async (id: string, status: string) => {
|
||||
try {
|
||||
await updateUser(id, { status });
|
||||
const user = users.find(u => u.id === id);
|
||||
if (!user) return;
|
||||
await updateUser(id, { status, version: user.version });
|
||||
message.success(status === 'disabled' ? '用户已禁用' : '用户已启用');
|
||||
fetchUsers();
|
||||
} catch {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { Tabs, theme } from 'antd';
|
||||
import { Tabs } from 'antd';
|
||||
import { PartitionOutlined, FileSearchOutlined, CheckSquareOutlined, MonitorOutlined } from '@ant-design/icons';
|
||||
import ProcessDefinitions from './workflow/ProcessDefinitions';
|
||||
import PendingTasks from './workflow/PendingTasks';
|
||||
@@ -8,8 +8,6 @@ import InstanceMonitor from './workflow/InstanceMonitor';
|
||||
|
||||
export default function Workflow() {
|
||||
const [activeKey, setActiveKey] = useState('definitions');
|
||||
const { token } = theme.useToken();
|
||||
const isDark = token.colorBgContainer === '#111827' || token.colorBgContainer === 'rgb(17, 24, 39)';
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { Table, Select, Input, Space, Tag, message, theme } from 'antd';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Table, Select, Input, Tag, message, theme } from 'antd';
|
||||
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
|
||||
import { listAuditLogs, type AuditLogItem, type AuditLogQuery } from '../../api/auditLogs';
|
||||
|
||||
@@ -53,12 +53,8 @@ export default function AuditLogViewer() {
|
||||
setLoading(false);
|
||||
}, []);
|
||||
|
||||
const isFirstRender = useRef(true);
|
||||
useEffect(() => {
|
||||
if (isFirstRender.current) {
|
||||
isFirstRender.current = false;
|
||||
fetchLogs(query);
|
||||
}
|
||||
fetchLogs(query);
|
||||
}, [query, fetchLogs]);
|
||||
|
||||
const handleFilterChange = (field: keyof AuditLogQuery, value: string | undefined) => {
|
||||
|
||||
@@ -50,7 +50,7 @@ export default function DictionaryManager() {
|
||||
setLoading(true);
|
||||
try {
|
||||
const result = await listDictionaries();
|
||||
setDictionaries(Array.isArray(result) ? result : result.items ?? []);
|
||||
setDictionaries(Array.isArray(result) ? result : result.data ?? []);
|
||||
} catch {
|
||||
message.error('加载字典列表失败');
|
||||
}
|
||||
|
||||
@@ -45,29 +45,6 @@ function flattenMenuTree(tree: MenuItem[]): MenuItem[] {
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Convert flat menu list to tree structure for Table children prop */
|
||||
function buildMenuTree(items: MenuItem[]): MenuItem[] {
|
||||
const map = new Map<string, MenuItem>();
|
||||
const roots: MenuItem[] = [];
|
||||
|
||||
const withChildren = items.map((item) => ({
|
||||
...item,
|
||||
children: [] as MenuItem[],
|
||||
}));
|
||||
|
||||
withChildren.forEach((item) => map.set(item.id, item));
|
||||
|
||||
withChildren.forEach((item) => {
|
||||
if (item.parent_id && map.has(item.parent_id)) {
|
||||
map.get(item.parent_id)!.children!.push(item);
|
||||
} else {
|
||||
roots.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return roots;
|
||||
}
|
||||
|
||||
/** Convert menu tree to TreeSelect data nodes */
|
||||
function toTreeSelectData(
|
||||
items: MenuItem[],
|
||||
@@ -91,7 +68,7 @@ const menuTypeLabels: Record<string, { text: string; color: string }> = {
|
||||
// --- Component ---
|
||||
|
||||
export default function MenuConfig() {
|
||||
const [menus, setMenus] = useState<MenuItem[]>([]);
|
||||
const [_menus, setMenus] = useState<MenuItem[]>([]);
|
||||
const [menuTree, setMenuTree] = useState<MenuItem[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
|
||||
@@ -57,7 +57,7 @@ export default function NumberingRules() {
|
||||
setLoading(true);
|
||||
try {
|
||||
const result = await listNumberingRules();
|
||||
setRules(Array.isArray(result) ? result : result.items ?? []);
|
||||
setRules(Array.isArray(result) ? result : result.data ?? []);
|
||||
} catch {
|
||||
message.error('加载编号规则失败');
|
||||
}
|
||||
|
||||
@@ -3,14 +3,13 @@ import { Form, Input, Select, Button, ColorPicker, message, Typography } from 'a
|
||||
import {
|
||||
getTheme,
|
||||
updateTheme,
|
||||
type ThemeConfig,
|
||||
} from '../../api/themes';
|
||||
|
||||
// --- Component ---
|
||||
|
||||
export default function ThemeSettings() {
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [, setLoading] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
const fetchTheme = useCallback(async () => {
|
||||
|
||||
@@ -86,7 +86,7 @@ export default function InstanceMonitor() {
|
||||
title: '确认挂起',
|
||||
content: '确定要挂起该流程实例吗?挂起后可通过"恢复"按钮继续执行。',
|
||||
okText: '确定挂起',
|
||||
okType: 'warning',
|
||||
okType: 'default',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
try {
|
||||
|
||||
@@ -162,7 +162,7 @@ export default function ProcessDesigner({ definitionId, onSave }: ProcessDesigne
|
||||
const flowNodes: NodeDef[] = nodes.map((n) => ({
|
||||
id: n.id,
|
||||
type: (n.data.nodeType as NodeDef['type']) || 'UserTask',
|
||||
name: n.data.name || String(n.data.label),
|
||||
name: String(n.data.name || n.data.label || ''),
|
||||
position: { x: Math.round(n.position.x), y: Math.round(n.position.y) },
|
||||
}));
|
||||
const flowEdges: EdgeDef[] = edges.map((e) => ({
|
||||
@@ -220,7 +220,7 @@ export default function ProcessDesigner({ definitionId, onSave }: ProcessDesigne
|
||||
<p style={{ fontWeight: 500, margin: '0 0 8px', fontSize: 12 }}>节点属性</p>
|
||||
<Input
|
||||
size="small"
|
||||
value={selectedNode.data.name || ''}
|
||||
value={String(selectedNode.data.name || '')}
|
||||
onChange={(e) => handleUpdateNodeName(e.target.value)}
|
||||
placeholder="节点名称"
|
||||
style={{ marginBottom: 8 }}
|
||||
|
||||
@@ -3,9 +3,9 @@ import react from "@vitejs/plugin-react";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react(), tailwindcss()],
|
||||
plugins: [react(), ...tailwindcss()],
|
||||
server: {
|
||||
port: 5173,
|
||||
port: 5174,
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: "http://localhost:3000",
|
||||
@@ -22,21 +22,19 @@ export default defineConfig({
|
||||
cssTarget: "chrome120",
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
"vendor-react": ["react", "react-dom", "react-router-dom"],
|
||||
"vendor-antd": ["antd", "@ant-design/icons"],
|
||||
"vendor-utils": ["axios", "zustand"],
|
||||
manualChunks(id) {
|
||||
if (id.includes("node_modules/react-dom") || id.includes("node_modules/react/") || id.includes("node_modules/react-router-dom")) {
|
||||
return "vendor-react";
|
||||
}
|
||||
if (id.includes("node_modules/antd") || id.includes("node_modules/@ant-design")) {
|
||||
return "vendor-antd";
|
||||
}
|
||||
if (id.includes("node_modules/axios") || id.includes("node_modules/zustand")) {
|
||||
return "vendor-utils";
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
minify: "terser",
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: true,
|
||||
drop_debugger: true,
|
||||
pure_funcs: ["console.log", "console.info", "console.debug"],
|
||||
},
|
||||
},
|
||||
sourcemap: false,
|
||||
reportCompressedSize: false,
|
||||
chunkSizeWarningLimit: 600,
|
||||
|
||||
Reference in New Issue
Block a user