From e3f7583c40456e00f979d899bfdb2883136afd42 Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 13 Mar 2026 02:29:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=A5=E5=8F=A3=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=94=AF=E6=8C=81=E6=90=9C=E7=B4=A2=E7=9A=84?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E7=BB=84=E4=BB=B6=EF=BC=8C=E6=8C=89=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=88=86=E7=BB=84=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Moka_全量API接口.xlsx | Bin 0 -> 25333 bytes client/src/components/ApiDebugger.jsx | 172 ++++++++++++++++++++++++-- server/import_templates.js | 77 ++++++++++++ server/init_admin_endpoints.js | 69 +++++++++++ server/package-lock.json | 106 +++++++++++++++- server/package.json | 3 +- 6 files changed, 416 insertions(+), 11 deletions(-) create mode 100644 Moka_全量API接口.xlsx create mode 100644 server/import_templates.js create mode 100644 server/init_admin_endpoints.js diff --git a/Moka_全量API接口.xlsx b/Moka_全量API接口.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d35cfc27d398c8eb5700158092d5e9ac3dcdd583 GIT binary patch literal 25333 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

D#Op7O8NVRHS9$R|uDyfRJCCzmp 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 literal 0 HcmV?d00001 diff --git a/client/src/components/ApiDebugger.jsx b/client/src/components/ApiDebugger.jsx index 62e3be5..c2646f6 100644 --- a/client/src/components/ApiDebugger.jsx +++ b/client/src/components/ApiDebugger.jsx @@ -32,6 +32,10 @@ const ApiDebugger = ({ onTitleChange, storageKey = 'tab_default' }) => { const [currentMatchIndex, setCurrentMatchIndex] = useState(0); const [matchCount, setMatchCount] = useState(0); + // Endpoint search state + const [endpointSearchQuery, setEndpointSearchQuery] = useState(''); + const [isEndpointDropdownOpen, setIsEndpointDropdownOpen] = useState(false); + // UX state const [copyResText, setCopyResText] = useState('复制结果'); const [copyCurlText, setCopyCurlText] = useState('复制 CURL'); @@ -102,7 +106,16 @@ const ApiDebugger = ({ onTitleChange, storageKey = 'tab_default' }) => { }; fetchInitialData(); - }, []); + + // Close dropdown when clicking outside + const handleClickOutside = (e) => { + if (isEndpointDropdownOpen && !e.target.closest('.form-group')) { + setIsEndpointDropdownOpen(false); + } + }; + document.addEventListener('click', handleClickOutside); + return () => document.removeEventListener('click', handleClickOutside); + }, [isEndpointDropdownOpen]); useEffect(() => { const tenant = tenants.find(t => t.id === parseInt(selectedTenantId)); @@ -428,10 +441,11 @@ const ApiDebugger = ({ onTitleChange, storageKey = 'tab_default' }) => { setQueryParamsError(''); }; - const handleEndpointChange = (e) => { - const endpointId = Number(e.target.value); + const handleEndpointChange = (endpointId) => { setSelectedEndpointId(endpointId); localStorage.setItem(`${storageKey}_endpointId`, endpointId); + setIsEndpointDropdownOpen(false); + setEndpointSearchQuery(''); const endpoint = endpoints.find(ep => ep.id === endpointId); if (endpoint) { @@ -452,6 +466,28 @@ const ApiDebugger = ({ onTitleChange, storageKey = 'tab_default' }) => { } }; + // Filter endpoints by search query + const searchFilteredEndpoints = useMemo(() => { + if (!endpointSearchQuery.trim()) return filteredEndpoints; + const query = endpointSearchQuery.toLowerCase(); + return filteredEndpoints.filter(ep => + ep.name.toLowerCase().includes(query) || + ep.method.toLowerCase().includes(query) || + (ep.module && ep.module.toLowerCase().includes(query)) + ); + }, [filteredEndpoints, endpointSearchQuery]); + + // Group endpoints by module + const groupedEndpoints = useMemo(() => { + const groups = {}; + searchFilteredEndpoints.forEach(ep => { + const module = ep.module || '其他'; + if (!groups[module]) groups[module] = []; + groups[module].push(ep); + }); + return groups; + }, [searchFilteredEndpoints]); + return (

@@ -470,12 +506,130 @@ const ApiDebugger = ({ onTitleChange, storageKey = 'tab_default' }) => {
- +
+
setIsEndpointDropdownOpen(!isEndpointDropdownOpen)} + style={{ + padding: '0.5rem', + border: '1px solid var(--border)', + borderRadius: '4px', + cursor: 'pointer', + backgroundColor: 'var(--bg)', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' + }} + > + + {selectedEndpointId + ? `[${endpoints.find(e => e.id === parseInt(selectedEndpointId))?.method}] ${endpoints.find(e => e.id === parseInt(selectedEndpointId))?.name}` + : '-- 请选择接口 --' + } + + +
+ {isEndpointDropdownOpen && ( +
+
+ setEndpointSearchQuery(e.target.value)} + onClick={(e) => e.stopPropagation()} + style={{ + width: '100%', + padding: '0.5rem', + border: '1px solid var(--border)', + borderRadius: '4px', + fontSize: '0.875rem' + }} + autoFocus + /> +
+
+ {Object.keys(groupedEndpoints).length === 0 ? ( +
+ 未找到匹配的接口 +
+ ) : ( + Object.entries(groupedEndpoints).map(([module, eps]) => ( +
+
+ {module} +
+ {eps.map(ep => ( +
handleEndpointChange(ep.id)} + style={{ + padding: '0.5rem 1rem', + cursor: 'pointer', + backgroundColor: selectedEndpointId === ep.id ? 'rgba(59, 130, 246, 0.1)' : 'transparent', + borderLeft: selectedEndpointId === ep.id ? '3px solid #3b82f6' : '3px solid transparent' + }} + onMouseEnter={(e) => { + if (selectedEndpointId !== ep.id) { + e.currentTarget.style.backgroundColor = 'rgba(0,0,0,0.05)'; + } + }} + onMouseLeave={(e) => { + if (selectedEndpointId !== ep.id) { + e.currentTarget.style.backgroundColor = 'transparent'; + } + }} + > +
+ + {ep.method} + + {ep.name} +
+
+ ))} +
+ )) + )} +
+
+ )} +
diff --git a/server/import_templates.js b/server/import_templates.js new file mode 100644 index 0000000..a579179 --- /dev/null +++ b/server/import_templates.js @@ -0,0 +1,77 @@ +const XLSX = require('xlsx'); +const pool = require('./db'); +const path = require('path'); + +async function importTemplates() { + try { + const filePath = path.join(__dirname, '../Moka_全量API接口.xlsx'); + console.log('读取文件:', filePath); + + const workbook = XLSX.readFile(filePath); + console.log(`共 ${workbook.SheetNames.length} 个 Sheet\n`); + + let totalSuccess = 0; + let totalError = 0; + + for (const sheetName of workbook.SheetNames) { + console.log(`\n=== 处理 Sheet: ${sheetName} ===`); + const sheet = workbook.Sheets[sheetName]; + const data = XLSX.utils.sheet_to_json(sheet); + console.log(`共 ${data.length} 条记录`); + + let successCount = 0; + let errorCount = 0; + + for (const row of data) { + try { + // Excel 列名映射 + const module = sheetName; // 使用 Sheet 名称作为业务模块 + const name = row['接口名称'] || ''; + const description = row['接口说明'] || null; + const url = row['请求地址'] || ''; + const body = row['请求体 Request Body'] || null; + + // 默认值 + const category = '旗舰版PP'; // 默认分类 + const method = 'POST'; // 默认 POST + const apiCode = null; + const userName = null; + + if (!name || !url) { + console.log(' 跳过无效记录 (缺少名称或URL):', name || '未命名'); + errorCount++; + continue; + } + + await pool.query( + `INSERT INTO endpoint_templates + (name, category, module, api_code, user_name, url, method, body, description) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, + [name, category, module, apiCode, userName, url, method, body, description] + ); + + successCount++; + console.log(` ✓ ${name}`); + } catch (err) { + errorCount++; + console.error(` ✗ 导入失败:`, err.message); + } + } + + console.log(`${sheetName}: 成功 ${successCount} 条, 失败 ${errorCount} 条`); + totalSuccess += successCount; + totalError += errorCount; + } + + console.log('\n========== 导入完成 =========='); + console.log(`总成功: ${totalSuccess} 条`); + console.log(`总失败: ${totalError} 条`); + + process.exit(0); + } catch (error) { + console.error('导入失败:', error); + process.exit(1); + } +} + +importTemplates(); diff --git a/server/init_admin_endpoints.js b/server/init_admin_endpoints.js new file mode 100644 index 0000000..2686b04 --- /dev/null +++ b/server/init_admin_endpoints.js @@ -0,0 +1,69 @@ +require('dotenv').config(); +const pool = require('./db'); + +async function initAdminEndpoints() { + try { + console.log('开始为 admin 账号初始化接口...\n'); + + // 模块名称到分类的映射 + const moduleToCategory = { + '组织接口API': '组织接口', + '职位职务接口API': '职位职务接口', + '人事接口API': '人事接口', + '假勤接口API': '假勤接口', + '薪酬接口API': '薪酬接口', + '绩效接口API': '绩效接口' + }; + + // 查询所有模板接口 + const [templates] = await pool.query( + 'SELECT * FROM endpoint_templates ORDER BY module, id' + ); + + console.log(`共找到 ${templates.length} 条模板接口\n`); + + let successCount = 0; + let errorCount = 0; + + for (const template of templates) { + try { + const category = moduleToCategory[template.module] || template.module; + + await pool.query( + `INSERT INTO endpoints + (user_id, name, category, module, api_code, user_name, url, method, body, description) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + [ + 'admin', + template.name, + '标品PP', // 接口类型固定为标品PP + category, // 使用映射后的分类 + template.api_code, + template.user_name, + template.url, + template.method, + template.body, + template.description + ] + ); + + successCount++; + console.log(`✓ [${category}] ${template.name}`); + } catch (err) { + errorCount++; + console.error(`✗ 导入失败: ${template.name}`, err.message); + } + } + + console.log('\n========== 初始化完成 =========='); + console.log(`成功: ${successCount} 条`); + console.log(`失败: ${errorCount} 条`); + + process.exit(0); + } catch (error) { + console.error('初始化失败:', error); + process.exit(1); + } +} + +initAdminEndpoints(); diff --git a/server/package-lock.json b/server/package-lock.json index 183de09..d405238 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -16,7 +16,8 @@ "dotenv": "^17.3.1", "express": "^5.2.1", "jsonwebtoken": "^9.0.3", - "mysql2": "^3.19.0" + "mysql2": "^3.19.0", + "xlsx": "^0.18.5" }, "devDependencies": { "nodemon": "^3.1.14" @@ -45,6 +46,15 @@ "node": ">= 0.6" } }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -211,6 +221,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -236,6 +259,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -305,6 +337,18 @@ "url": "https://opencollective.com/express" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -602,6 +646,15 @@ "node": ">= 0.6" } }, + "node_modules/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -1493,6 +1546,18 @@ "url": "https://github.com/mysqljs/sql-escaper?sponsor=1" } }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "license": "Apache-2.0", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -1593,11 +1658,50 @@ "node": ">= 0.8" } }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" + }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } } } } diff --git a/server/package.json b/server/package.json index 51e50d8..5b51171 100644 --- a/server/package.json +++ b/server/package.json @@ -7,7 +7,8 @@ "dotenv": "^17.3.1", "express": "^5.2.1", "jsonwebtoken": "^9.0.3", - "mysql2": "^3.19.0" + "mysql2": "^3.19.0", + "xlsx": "^0.18.5" }, "name": "server", "version": "1.0.0",