| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>灵越智报 - 智能报告生成平台</title>
- <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;600;700&display=swap" rel="stylesheet">
- <style>
- :root {
- --primary: #1890ff;
- --primary-dark: #096dd9;
- --primary-light: #e6f7ff;
- --primary-gradient: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
- --white: #ffffff;
- --bg: #f5f7fa;
- --border: #e8e8e8;
- --text1: #262626;
- --text2: #595959;
- --text3: #8c8c8c;
- --success: #52c41a;
- --warning: #faad14;
- --danger: #ff4d4f;
- --ai-gradient: linear-gradient(135deg, #1890ff 0%, #722ed1 100%);
- --data-gradient: linear-gradient(135deg, #52c41a 0%, #13c2c2 100%);
- }
- * { margin: 0; padding: 0; box-sizing: border-box; }
- body { font-family: 'Noto Sans SC', sans-serif; background: var(--bg); color: var(--text1); font-size: 14px; line-height: 1.6; height: 100vh; overflow: hidden; }
-
- /* 全局头部 */
- .header { position: fixed; top: 0; left: 0; right: 0; height: 56px; background: var(--white); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 20px; z-index: 1000; }
- .header-left { display: flex; align-items: center; gap: 20px; }
- .logo { display: flex; align-items: center; gap: 8px; font-size: 17px; font-weight: 600; color: var(--primary); cursor: pointer; }
- .logo-icon { width: 32px; height: 32px; background: var(--primary-gradient); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white; font-size: 18px; }
- .search-box { position: relative; width: 320px; }
- .search-input { width: 100%; height: 36px; padding: 0 14px 0 36px; border: 1px solid var(--border); border-radius: 18px; font-size: 13px; background: var(--bg); outline: none; transition: all 0.2s; }
- .search-input:focus { background: var(--white); border-color: var(--primary); }
- .search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--text3); }
- .header-right { display: flex; align-items: center; gap: 10px; }
- .hd-btn { position: relative; width: 36px; height: 36px; border: none; background: transparent; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; color: var(--text2); transition: all 0.2s; }
- .hd-btn:hover { background: var(--bg); color: var(--primary); }
- .badge { position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px; background: var(--danger); color: white; border-radius: 8px; font-size: 10px; display: flex; align-items: center; justify-content: center; }
- .user-menu { display: flex; align-items: center; gap: 6px; padding: 4px 8px 4px 4px; border-radius: 20px; cursor: pointer; }
- .user-menu:hover { background: var(--bg); }
- .avatar { width: 30px; height: 30px; border-radius: 50%; background: var(--primary-gradient); color: white; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 12px; }
- .user-name { font-size: 13px; font-weight: 500; }
- /* 侧边栏 */
- .sidebar { position: fixed; top: 56px; left: 0; width: 200px; height: calc(100vh - 56px); background: var(--white); border-right: 1px solid var(--border); display: flex; flex-direction: column; transition: width 0.3s; z-index: 900; }
- .sidebar.hidden { display: none; }
- .sidebar-menu { flex: 1; padding: 10px; overflow-y: auto; }
- .menu-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 8px; cursor: pointer; transition: all 0.2s; margin-bottom: 2px; position: relative; }
- .menu-item:hover { background: var(--primary-light); color: var(--primary); }
- .menu-item.active { background: var(--primary-light); color: var(--primary); }
- .menu-item.active::before { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 3px; height: 18px; background: var(--primary); border-radius: 0 2px 2px 0; }
- .menu-icon { font-size: 16px; }
- .menu-text { font-size: 13px; font-weight: 500; }
- .menu-badge { min-width: 18px; height: 18px; padding: 0 5px; background: var(--primary); color: white; border-radius: 9px; font-size: 10px; display: flex; align-items: center; justify-content: center; }
- .menu-divider { height: 1px; background: var(--border); margin: 10px 0; }
- /* 主内容 */
- .main { margin-left: 200px; margin-top: 56px; height: calc(100vh - 56px); overflow-y: auto; }
- .page { display: none; padding: 20px; }
- .page.active { display: block; }
- /* 通用组件 */
- .card { background: var(--white); border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
- .btn { display: inline-flex; align-items: center; gap: 4px; padding: 7px 14px; border: 1px solid var(--border); background: var(--white); border-radius: 6px; cursor: pointer; font-size: 12px; transition: all 0.2s; }
- .btn:hover { border-color: var(--primary); color: var(--primary); }
- .btn-primary { background: var(--primary-gradient); color: white; border: none; }
- .btn-primary:hover { box-shadow: 0 4px 12px rgba(24,144,255,0.4); }
- /* 首页样式 */
- .welcome h1 { font-size: 24px; font-weight: 600; margin-bottom: 4px; }
- .welcome h1 span { background: var(--ai-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
- .welcome p { color: var(--text2); }
- .stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 20px 0; }
- .stat-card { padding: 18px; cursor: pointer; transition: all 0.3s; }
- .stat-card:hover { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0,0,0,0.1); }
- .stat-icon { width: 40px; height: 40px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 20px; margin-bottom: 10px; }
- .stat-icon.blue { background: linear-gradient(135deg, #e6f7ff, #bae7ff); }
- .stat-icon.purple { background: linear-gradient(135deg, #f9f0ff, #efdbff); }
- .stat-icon.green { background: linear-gradient(135deg, #f6ffed, #d9f7be); }
- .stat-icon.orange { background: linear-gradient(135deg, #fff7e6, #ffe7ba); }
- .stat-value { font-size: 26px; font-weight: 700; }
- .stat-label { font-size: 13px; color: var(--text2); margin-bottom: 6px; }
- .stat-trend { font-size: 12px; }
- .stat-trend.up { color: var(--success); }
- /* AI对话入口 */
- .ai-card { padding: 20px; margin-bottom: 20px; }
- .ai-welcome { background: linear-gradient(135deg, #f0f7ff, #f5f0ff); border-radius: 10px; padding: 16px; margin-bottom: 16px; }
- .ai-avatar { width: 44px; height: 44px; background: var(--ai-gradient); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 22px; margin-bottom: 10px; }
- .ai-title { font-size: 14px; font-weight: 600; margin-bottom: 8px; }
- .ai-list { list-style: none; margin-bottom: 10px; }
- .ai-list li { color: var(--text2); padding: 3px 0; font-size: 13px; }
- .ai-list li::before { content: '•'; color: var(--primary); margin-right: 8px; }
- .ai-tip { font-size: 12px; color: var(--text3); padding: 8px 12px; background: rgba(255,255,255,0.7); border-radius: 6px; border-left: 3px solid var(--primary); }
- .ai-input-wrap { position: relative; margin-bottom: 14px; }
- .ai-input { width: 100%; height: 46px; padding: 0 100px 0 18px; border: 2px solid var(--border); border-radius: 23px; font-size: 14px; outline: none; transition: all 0.3s; }
- .ai-input:focus { border-color: var(--primary); }
- .ai-input-btns { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); display: flex; gap: 4px; }
- .ai-input-btn { width: 32px; height: 32px; border: none; background: transparent; border-radius: 50%; cursor: pointer; font-size: 16px; color: var(--text3); }
- .ai-input-btn:hover { background: var(--bg); color: var(--primary); }
- .ai-input-btn.send { background: var(--primary-gradient); color: white; display: none; }
- .ai-input-btn.send.show { display: flex; align-items: center; justify-content: center; }
- .thinking-modes { display: flex; gap: 8px; flex-wrap: wrap; }
- .mode-btn { padding: 6px 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 18px; font-size: 12px; cursor: pointer; }
- .mode-btn:hover { border-color: var(--primary); background: var(--primary-light); }
- .mode-btn.active { background: var(--primary-light); border-color: var(--primary); color: var(--primary); }
- /* 模板区 */
- .section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
- .section-title { font-size: 15px; font-weight: 600; }
- .section-link { font-size: 13px; color: var(--primary); cursor: pointer; }
- .tpl-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 14px; }
- .tpl-card { overflow: hidden; cursor: pointer; transition: all 0.3s; }
- .tpl-card:hover { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0,0,0,0.1); }
- .tpl-preview { height: 100px; background: linear-gradient(135deg, #f5f7fa, #e8ecf0); display: flex; align-items: center; justify-content: center; font-size: 36px; }
- .tpl-info { padding: 14px; }
- .tpl-name { font-weight: 600; margin-bottom: 6px; }
- .tpl-meta { display: flex; gap: 12px; font-size: 11px; color: var(--text3); margin-bottom: 10px; }
- .tpl-tags { display: flex; gap: 4px; margin-bottom: 10px; }
- .tpl-tag { padding: 2px 6px; background: var(--primary-light); color: var(--primary); border-radius: 3px; font-size: 10px; }
- .tpl-tag.hot { background: #fff1f0; color: var(--danger); }
- .tpl-btn { width: 100%; padding: 8px; background: var(--primary-gradient); color: white; border: none; border-radius: 6px; font-size: 12px; cursor: pointer; }
- .quick-actions { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
- .quick-action { display: flex; align-items: center; gap: 12px; padding: 16px; border: 2px dashed var(--border); border-radius: 10px; cursor: pointer; }
- .quick-action:hover { border-color: var(--primary); background: var(--primary-light); }
- .quick-action-icon { width: 40px; height: 40px; background: var(--bg); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 20px; }
- </style>
- </head>
- <body>
- <!-- 头部 -->
- <header class="header" id="mainHeader">
- <div class="header-left">
- <div class="logo" onclick="goHome()">
- <div class="logo-icon">📊</div>
- <span>灵越智报</span>
- </div>
- <div class="search-box">
- <span class="search-icon">🔍</span>
- <input type="text" class="search-input" placeholder="搜索报告、模板...">
- </div>
- </div>
- <div class="header-right">
- <button class="hd-btn" onclick="toggleNotif()">🔔<span class="badge">3</span></button>
- <div class="user-menu" onclick="showToast('个人中心', 'info')">
- <div class="avatar">张</div>
- <span class="user-name">张三</span>
- </div>
- </div>
- </header>
- <!-- 侧边栏 -->
- <aside class="sidebar" id="sidebar">
- <nav class="sidebar-menu">
- <div class="menu-item active" data-page="home" onclick="navTo('home')">
- <span class="menu-icon">🏠</span>
- <span class="menu-text">首页</span>
- </div>
- <div class="menu-item" onclick="openEditor()">
- <span class="menu-icon">➕</span>
- <span class="menu-text">新建报告</span>
- </div>
- <div class="menu-item" data-page="reports" onclick="navTo('reports')">
- <span class="menu-icon">📋</span>
- <span class="menu-text">报告记录</span>
- <span class="menu-badge">12</span>
- </div>
- <div class="menu-item" data-page="templates" onclick="navTo('templates')">
- <span class="menu-icon">🎨</span>
- <span class="menu-text">模板管理</span>
- </div>
- <div class="menu-item" data-page="datasources" onclick="navTo('datasources')">
- <span class="menu-icon">🔗</span>
- <span class="menu-text">数据源</span>
- </div>
- <div class="menu-divider"></div>
- <div class="menu-item" onclick="showToast('帮助中心', 'info')">
- <span class="menu-icon">❓</span>
- <span class="menu-text">帮助中心</span>
- </div>
- </nav>
- </aside>
- <!-- 主内容区 -->
- <main class="main" id="mainContent">
- <!-- 首页 -->
- <div class="page active" id="page-home">
- <div class="welcome">
- <h1>早上好,张三!<span>智能报告,洞察未来。</span></h1>
- <p>今天是个创作的好日子,开始您的智能报告之旅吧</p>
- </div>
- <div class="stats-grid">
- <div class="stat-card card" onclick="navTo('reports')">
- <div class="stat-icon blue">📄</div>
- <div class="stat-value">12</div>
- <div class="stat-label">我的报告</div>
- <div class="stat-trend up">↑ 3 本周新增</div>
- </div>
- <div class="stat-card card" onclick="navTo('templates')">
- <div class="stat-icon purple">🎨</div>
- <div class="stat-value">15</div>
- <div class="stat-label">可用模板</div>
- <div class="stat-trend up">↑ 2 新增</div>
- </div>
- <div class="stat-card card">
- <div class="stat-icon green">📚</div>
- <div class="stat-value">48</div>
- <div class="stat-label">知识文档</div>
- <div class="stat-trend">📁 1.2GB</div>
- </div>
- <div class="stat-card card" onclick="toggleFab()">
- <div class="stat-icon orange">💰</div>
- <div class="stat-value">¥127.50</div>
- <div class="stat-label">本月消耗</div>
- <div class="stat-trend">↓ 12%</div>
- </div>
- </div>
- <div class="ai-card card">
- <div class="ai-welcome">
- <div class="ai-avatar">🤖</div>
- <div class="ai-title">你好!我是灵越AI助手,可以帮你:</div>
- <ul class="ai-list">
- <li>快速生成各类报告</li>
- <li>分析和解读数据</li>
- <li>回答业务相关问题</li>
- </ul>
- <div class="ai-tip">试试输入:"帮我生成一份智慧园区建设项目可行性研究报告"</div>
- </div>
- <div class="ai-input-wrap">
- <input type="text" class="ai-input" placeholder="输入您的需求,或 @知识库 引用资料..." id="homeAiInput" oninput="toggleSendBtn()">
- <div class="ai-input-btns">
- <button class="ai-input-btn">🎤</button>
- <button class="ai-input-btn">📎</button>
- <button class="ai-input-btn send" id="homeSendBtn" onclick="handleHomeAi()">➤</button>
- </div>
- </div>
- <div class="thinking-modes">
- <div class="mode-btn active" onclick="setMode(this)">🧠 深度思考</div>
- <div class="mode-btn" onclick="setMode(this)">⚡ 快速回答</div>
- <div class="mode-btn" onclick="setMode(this)">🌐 联网搜索</div>
- <div class="mode-btn" onclick="setMode(this)">📊 数据分析</div>
- </div>
- </div>
- <div class="section-header">
- <h2 class="section-title">📋 推荐模板</h2>
- <span class="section-link" onclick="navTo('templates')">查看全部 →</span>
- </div>
- <div class="tpl-grid">
- <div class="tpl-card card" onclick="openEditor()">
- <div class="tpl-preview">📊</div>
- <div class="tpl-info">
- <div class="tpl-name">市场分析报告</div>
- <div class="tpl-meta"><span>📊 128次</span><span>⭐ 4.8</span></div>
- <div class="tpl-tags"><span class="tpl-tag">官方</span><span class="tpl-tag hot">热门</span></div>
- <button class="tpl-btn">使用此模板</button>
- </div>
- </div>
- <div class="tpl-card card" onclick="openEditor()">
- <div class="tpl-preview">🏢</div>
- <div class="tpl-info">
- <div class="tpl-name">可行性研究报告</div>
- <div class="tpl-meta"><span>📊 96次</span><span>⭐ 4.9</span></div>
- <div class="tpl-tags"><span class="tpl-tag">官方</span><span class="tpl-tag hot">热门</span></div>
- <button class="tpl-btn">使用此模板</button>
- </div>
- </div>
- <div class="tpl-card card" onclick="openEditor()">
- <div class="tpl-preview">📅</div>
- <div class="tpl-info">
- <div class="tpl-name">项目周报</div>
- <div class="tpl-meta"><span>📊 256次</span><span>⭐ 4.9</span></div>
- <div class="tpl-tags"><span class="tpl-tag">官方</span></div>
- <button class="tpl-btn">使用此模板</button>
- </div>
- </div>
- </div>
- <div class="quick-actions">
- <div class="quick-action" onclick="showToast('上传模板', 'info')">
- <div class="quick-action-icon">📤</div>
- <span>上传新模板</span>
- </div>
- <div class="quick-action" onclick="showToast('创建模板', 'info')">
- <div class="quick-action-icon">🛠️</div>
- <span>创建新模板</span>
- </div>
- </div>
- </div>
- <!-- 报告记录页 -->
- <div class="page" id="page-reports">
- <h2 style="margin-bottom:16px">📋 报告记录</h2>
- <div style="display:flex;gap:12px;margin-bottom:16px;">
- <select style="padding:8px 12px;border:1px solid var(--border);border-radius:6px;font-size:13px;background:var(--white);"><option>全部状态</option><option>初稿</option><option>审核中</option><option>已定稿</option></select>
- <input type="text" placeholder="🔍 搜索报告..." style="flex:1;max-width:280px;padding:8px 12px;border:1px solid var(--border);border-radius:6px;font-size:13px;">
- <div style="margin-left:auto;display:flex;gap:6px;">
- <button class="btn" style="background:var(--primary-light);border-color:var(--primary);color:var(--primary)">全部</button>
- <button class="btn">本周</button>
- <button class="btn">本月</button>
- </div>
- </div>
- <div style="display:flex;flex-direction:column;gap:12px;">
- <div class="card" style="padding:18px;">
- <div style="display:flex;align-items:center;gap:12px;margin-bottom:10px;">
- <span style="font-size:22px;">📄</span>
- <span style="flex:1;font-size:15px;font-weight:600;">智慧园区建设项目可行性研究报告</span>
- <span style="padding:4px 10px;background:#f6ffed;color:var(--success);border-radius:12px;font-size:11px;">已定稿</span>
- </div>
- <div style="display:flex;gap:20px;font-size:12px;color:var(--text2);margin-bottom:12px;">
- <span>📅 2025-12-30</span><span>👤 张三</span><span>🏢 华南事业部</span>
- </div>
- <div style="display:flex;gap:8px;">
- <button class="btn btn-primary" onclick="openEditor()">查看</button>
- <button class="btn" onclick="openEditor()">编辑</button>
- <button class="btn" onclick="showToast('导出PDF成功', 'success')">导出</button>
- </div>
- </div>
- <div class="card" style="padding:18px;">
- <div style="display:flex;align-items:center;gap:12px;margin-bottom:10px;">
- <span style="font-size:22px;">📄</span>
- <span style="flex:1;font-size:15px;font-weight:600;">Q4市场分析报告</span>
- <span style="padding:4px 10px;background:#fffbe6;color:var(--warning);border-radius:12px;font-size:11px;">审核中</span>
- </div>
- <div style="display:flex;gap:20px;font-size:12px;color:var(--text2);margin-bottom:12px;">
- <span>📅 2025-12-28</span><span>👤 张三</span>
- </div>
- <div style="display:flex;gap:8px;">
- <button class="btn btn-primary" onclick="openEditor()">查看</button>
- <button class="btn" onclick="showToast('已发送催办', 'success')">催办</button>
- </div>
- </div>
- </div>
- </div>
- <!-- 模板管理页 -->
- <div class="page" id="page-templates">
- <h2 style="margin-bottom:16px">🎨 模板管理</h2>
- <div style="display:flex;gap:12px;margin-bottom:16px;">
- <input type="text" placeholder="🔍 搜索模板..." style="width:280px;padding:8px 12px;border:1px solid var(--border);border-radius:6px;font-size:13px;">
- <div style="display:flex;gap:6px;">
- <span style="padding:8px 16px;background:var(--primary);color:white;border-radius:18px;font-size:12px;cursor:pointer;">全部</span>
- <span style="padding:8px 16px;background:var(--bg);border-radius:18px;font-size:12px;cursor:pointer;">官方模板</span>
- <span style="padding:8px 16px;background:var(--bg);border-radius:18px;font-size:12px;cursor:pointer;">我的模板</span>
- </div>
- <button class="btn btn-primary" style="margin-left:auto;">➕ 创建模板</button>
- </div>
- <div style="display:grid;grid-template-columns:repeat(4,1fr);gap:14px;">
- <div class="tpl-card card" onclick="openEditor()"><div class="tpl-preview">📊</div><div class="tpl-info"><div class="tpl-name">市场分析报告</div><div class="tpl-meta"><span>📊 128次</span></div><div class="tpl-tags"><span class="tpl-tag">官方</span><span class="tpl-tag hot">热门</span></div><button class="tpl-btn">使用</button></div></div>
- <div class="tpl-card card" onclick="openEditor()"><div class="tpl-preview">🏢</div><div class="tpl-info"><div class="tpl-name">可行性研究报告</div><div class="tpl-meta"><span>📊 96次</span></div><div class="tpl-tags"><span class="tpl-tag">官方</span></div><button class="tpl-btn">使用</button></div></div>
- <div class="tpl-card card" onclick="openEditor()"><div class="tpl-preview">📅</div><div class="tpl-info"><div class="tpl-name">项目周报</div><div class="tpl-meta"><span>📊 256次</span></div><div class="tpl-tags"><span class="tpl-tag">官方</span></div><button class="tpl-btn">使用</button></div></div>
- <div class="tpl-card card" onclick="openEditor()"><div class="tpl-preview">💼</div><div class="tpl-info"><div class="tpl-name">尽职调查报告</div><div class="tpl-meta"><span>📊 45次</span></div><div class="tpl-tags"><span class="tpl-tag">行业</span></div><button class="tpl-btn">使用</button></div></div>
- </div>
- </div>
- <!-- 数据源管理页 -->
- <div class="page" id="page-datasources">
- <h2 style="margin-bottom:16px">🔗 数据源管理</h2>
- <div style="display:flex;gap:12px;margin-bottom:16px;">
- <input type="text" placeholder="🔍 搜索数据源..." style="width:280px;padding:8px 12px;border:1px solid var(--border);border-radius:6px;font-size:13px;">
- <button class="btn btn-primary" style="margin-left:auto;">➕ 添加数据源</button>
- </div>
- <div style="display:flex;flex-direction:column;gap:12px;">
- <div class="card" style="padding:18px;">
- <div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
- <div style="width:44px;height:44px;background:var(--primary-light);border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:22px;">🗄️</div>
- <div style="flex:1;"><div style="font-size:15px;font-weight:600;">销售数据库</div><div style="font-size:12px;color:var(--text3);">MySQL · db.company.com:3306</div></div>
- <div style="font-size:12px;color:var(--success);">● 已连接</div>
- </div>
- <div style="display:flex;gap:8px;"><button class="btn">测试连接</button><button class="btn">同步数据</button><button class="btn">查看数据表</button></div>
- </div>
- <div class="card" style="padding:18px;">
- <div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
- <div style="width:44px;height:44px;background:#f6ffed;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:22px;">🌐</div>
- <div style="flex:1;"><div style="font-size:15px;font-weight:600;">市场数据API</div><div style="font-size:12px;color:var(--text3);">REST API · api.marketdata.com</div></div>
- <div style="font-size:12px;color:var(--success);">● 已连接</div>
- </div>
- <div style="display:flex;gap:8px;"><button class="btn">测试接口</button><button class="btn">查看文档</button></div>
- </div>
- </div>
- </div>
- </main>
- <style>
- /* === 编辑器专用样式 === */
- .editor-page { display: none; position: fixed; top: 56px; left: 0; right: 0; bottom: 0; flex-direction: column; background: var(--bg); z-index: 800; }
- .editor-page.active { display: flex; }
- /* 编辑器工具栏 */
- .editor-toolbar { height: 56px; background: var(--white); border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 16px; gap: 16px; flex-shrink: 0; }
- .back-btn { display: flex; align-items: center; gap: 4px; padding: 8px 12px; border: none; background: transparent; border-radius: 6px; cursor: pointer; font-size: 13px; color: var(--text2); }
- .back-btn:hover { background: var(--bg); color: var(--primary); }
- .report-title-input { border: none; background: transparent; font-size: 15px; font-weight: 600; padding: 8px 12px; border-radius: 6px; min-width: 300px; outline: none; }
- .report-title-input:hover { background: var(--bg); }
- .report-title-input:focus { background: var(--white); box-shadow: 0 0 0 2px var(--primary-light); }
- .save-status { display: flex; align-items: center; gap: 4px; font-size: 13px; color: var(--success); }
- .toolbar-right { margin-left: auto; display: flex; gap: 10px; align-items: center; }
- .toolbar-btn { display: flex; align-items: center; gap: 6px; padding: 8px 16px; border: 1px solid var(--border); background: var(--white); border-radius: 6px; cursor: pointer; font-size: 13px; color: var(--text1); transition: all 0.2s; }
- .toolbar-btn:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-light); }
- .toolbar-btn.primary { background: var(--primary); color: white; border: none; }
- .toolbar-btn.primary:hover { background: var(--primary-dark); }
- .toolbar-btn .icon { font-size: 14px; }
- .toolbar-divider { width: 1px; height: 24px; background: var(--border); }
- /* 编辑器主体 */
- .editor-body { flex: 1; display: flex; overflow: hidden; }
- /* 左侧项目文件面板 */
- .left-panel { width: 260px; background: var(--white); border-right: 1px solid var(--border); display: flex; flex-direction: column; }
- .panel-header { padding: 14px 16px; border-bottom: 1px solid var(--border); font-size: 13px; font-weight: 600; color: var(--text1); display: flex; align-items: center; justify-content: space-between; }
- .file-count { font-size: 12px; color: var(--text3); font-weight: normal; }
- .panel-body { flex: 1; overflow-y: auto; padding: 12px; }
- /* 上传区 */
- .upload-zone { border: 2px dashed var(--border); border-radius: 10px; padding: 24px 16px; text-align: center; cursor: pointer; margin-bottom: 16px; transition: all 0.2s; }
- .upload-zone:hover { border-color: var(--primary); background: var(--primary-light); }
- .upload-icon { font-size: 32px; margin-bottom: 8px; color: var(--text3); }
- .upload-text { font-size: 13px; color: var(--text2); margin-bottom: 4px; }
- .upload-hint { font-size: 11px; color: var(--text3); }
- /* 文件分组 */
- .file-group { margin-bottom: 16px; }
- .file-group-header { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text3); margin-bottom: 8px; padding: 0 4px; }
- .file-group-header .count { background: var(--bg); padding: 1px 6px; border-radius: 8px; font-size: 10px; }
- /* 文件项 - 解析中状态 */
- .file-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--white); border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; cursor: pointer; transition: all 0.2s; }
- .file-item:hover { border-color: var(--primary); background: var(--primary-light); }
- .file-item.active { border-color: var(--primary); background: var(--primary-light); }
- .file-icon { font-size: 28px; flex-shrink: 0; }
- .file-icon.pdf { color: #ff4d4f; }
- .file-icon.docx { color: #1890ff; }
- .file-icon.xlsx { color: #52c41a; }
- .file-icon.md { color: #8c8c8c; }
- .file-info { flex: 1; min-width: 0; }
- .file-name { font-size: 12px; font-weight: 500; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
- .file-meta { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--text3); }
- .file-status { font-size: 11px; white-space: nowrap; }
- .file-status.parsing { color: var(--primary); }
- .file-status.done { color: var(--success); }
- /* 中间编辑区 */
- .center-panel { flex: 1; display: flex; flex-direction: column; background: var(--white); overflow: hidden; }
- /* 编辑器顶部标题栏 */
- .editor-title-bar { padding: 16px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }
- .editor-main-title { font-size: 18px; font-weight: 600; flex: 1; }
- .view-toggle { display: flex; align-items: center; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
- .view-btn { padding: 8px 16px; border: none; background: var(--white); font-size: 13px; cursor: pointer; color: var(--text2); display: flex; align-items: center; gap: 6px; transition: all 0.2s; }
- .view-btn:first-child { border-right: 1px solid var(--border); }
- .view-btn:hover { background: var(--bg); }
- .view-btn.active { background: var(--primary-light); color: var(--primary); font-weight: 500; }
- .graph-btn { width: 36px; height: 36px; border: 1px solid var(--border); background: var(--white); border-radius: 6px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; margin-left: 8px; transition: all 0.2s; }
- .graph-btn:hover { border-color: var(--primary); background: var(--primary-light); }
- /* 图谱弹窗 */
- .graph-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: none; align-items: center; justify-content: center; z-index: 2000; }
- .graph-modal.show { display: flex; }
- .graph-container { width: 900px; height: 600px; background: var(--white); border-radius: 16px; overflow: hidden; display: flex; flex-direction: column; }
- .graph-header { padding: 16px 20px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
- .graph-title { font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
- .graph-close { width: 32px; height: 32px; border: none; background: var(--bg); border-radius: 50%; cursor: pointer; font-size: 16px; display: flex; align-items: center; justify-content: center; }
- .graph-close:hover { background: var(--danger); color: white; }
- .graph-body { flex: 1; position: relative; background: linear-gradient(135deg, #f8fafc 0%, #f0f4f8 100%); }
- .graph-legend { position: absolute; top: 16px; left: 16px; background: var(--white); border-radius: 8px; padding: 12px 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
- .legend-title { font-size: 12px; font-weight: 600; margin-bottom: 8px; color: var(--text2); }
- .legend-item { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--text2); margin-bottom: 4px; }
- .legend-dot { width: 12px; height: 12px; border-radius: 50%; }
- .legend-dot.entity { background: var(--primary); }
- .legend-dot.concept { background: #722ed1; }
- .legend-dot.data { background: var(--success); }
- .legend-dot.location { background: var(--warning); }
- /* 图谱节点 */
- .graph-node { position: absolute; display: flex; flex-direction: column; align-items: center; cursor: pointer; transition: transform 0.2s; }
- .graph-node:hover { transform: scale(1.1); }
- .node-circle { width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 24px; color: white; box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
- .node-circle.primary { background: linear-gradient(135deg, #1890ff, #096dd9); }
- .node-circle.purple { background: linear-gradient(135deg, #722ed1, #531dab); }
- .node-circle.green { background: linear-gradient(135deg, #52c41a, #389e0d); }
- .node-circle.orange { background: linear-gradient(135deg, #faad14, #d48806); }
- .node-circle.center { width: 80px; height: 80px; font-size: 32px; }
- .node-label { margin-top: 6px; font-size: 11px; font-weight: 500; color: var(--text1); white-space: nowrap; background: var(--white); padding: 2px 8px; border-radius: 10px; box-shadow: 0 1px 4px rgba(0,0,0,0.1); }
- /* 连接线 SVG */
- .graph-lines { position: absolute; inset: 0; pointer-events: none; }
- /* 图谱视图切换按钮 */
- .graph-view-btn { padding: 8px 14px; border: none; background: var(--white); font-size: 12px; cursor: pointer; color: var(--text2); display: flex; align-items: center; gap: 4px; transition: all 0.2s; }
- .graph-view-btn:first-child { border-right: 1px solid var(--border); }
- .graph-view-btn:hover { background: var(--bg); }
- .graph-view-btn.active { background: var(--primary-light); color: var(--primary); font-weight: 500; }
- /* 列表视图 */
- .graph-list-body { flex: 1; display: flex; flex-direction: column; background: var(--white); overflow: hidden; }
- .list-filter-tag { padding: 6px 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 14px; font-size: 11px; cursor: pointer; transition: all 0.2s; }
- .list-filter-tag:hover { border-color: var(--primary); }
- .list-filter-tag.active { background: var(--primary); color: white; border-color: var(--primary); }
- .list-group { margin-bottom: 20px; }
- .list-group-header { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; margin-bottom: 10px; color: var(--text1); }
- .list-group-dot { width: 10px; height: 10px; border-radius: 50%; }
- .list-group-count { font-size: 11px; color: var(--text3); font-weight: normal; background: var(--bg); padding: 2px 8px; border-radius: 10px; }
- .list-item { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--bg); border-radius: 10px; margin-bottom: 8px; cursor: pointer; transition: all 0.2s; }
- .list-item:hover { background: var(--primary-light); transform: translateX(4px); }
- .list-item-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
- .list-item-info { flex: 1; min-width: 0; }
- .list-item-name { font-size: 13px; font-weight: 600; margin-bottom: 2px; }
- .list-item-desc { font-size: 11px; color: var(--text3); }
- .list-item-relations { display: flex; gap: 6px; flex-wrap: wrap; }
- .relation-tag { padding: 3px 8px; background: var(--white); border-radius: 4px; font-size: 10px; color: var(--text2); }
- /* 编辑器内容区 */
- .editor-scroll { flex: 1; overflow-y: auto; padding: 24px 32px; }
- .editor-content { max-width: 800px; margin: 0 auto; }
- .editor-content h1 { font-size: 24px; font-weight: 700; margin-bottom: 24px; color: var(--text1); }
- .editor-content h2 { font-size: 18px; font-weight: 600; margin: 28px 0 16px; color: var(--text1); }
- .editor-content h3 { font-size: 15px; font-weight: 600; margin: 20px 0 12px; color: var(--text1); }
- .editor-content p { margin-bottom: 16px; line-height: 1.8; color: var(--text1); }
- /* 实体高亮标记 - 蓝色边框样式 */
- /* 正文实体高亮标签 - 基础样式 */
- .entity-highlight { display: inline; padding: 2px 8px; border-radius: 4px; cursor: pointer; transition: all 0.2s; font-weight: 500; }
-
- /* 实体类型颜色 - 与右侧要素管理对应 */
- .entity-highlight { border: 1px solid var(--primary); color: var(--primary); background: rgba(24,144,255,0.1); } /* 默认蓝色-核心实体 */
- .entity-highlight:hover { background: var(--primary); color: white; }
-
- .entity-highlight.entity { border-color: var(--primary); color: var(--primary); background: rgba(24,144,255,0.1); }
- .entity-highlight.entity:hover { background: var(--primary); color: white; }
-
- .entity-highlight.concept { border-color: #722ed1; color: #722ed1; background: rgba(114,46,209,0.1); }
- .entity-highlight.concept:hover { background: #722ed1; color: white; }
-
- .entity-highlight.data { border-color: #52c41a; color: #52c41a; background: rgba(82,196,26,0.1); }
- .entity-highlight.data:hover { background: #52c41a; color: white; }
-
- .entity-highlight.location { border-color: #faad14; color: #d48806; background: rgba(250,173,20,0.1); }
- .entity-highlight.location:hover { background: #faad14; color: white; }
-
- .entity-highlight.asset { border-color: #eb2f96; color: #eb2f96; background: rgba(235,47,150,0.1); }
- .entity-highlight.asset:hover { background: #eb2f96; color: white; }
- /* AI优化建议卡片 */
- .ai-suggestion-card { background: #fffbf0; border: 1px solid #ffe7ba; border-radius: 10px; padding: 16px; margin: 16px 0; }
- .ai-suggestion-header { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
- .ai-suggestion-icon { font-size: 18px; }
- .ai-suggestion-title { font-size: 14px; font-weight: 600; color: var(--warning); }
- .ai-suggestion-content { font-size: 13px; line-height: 1.7; color: var(--text1); margin-bottom: 12px; }
- .ai-suggestion-actions { display: flex; gap: 8px; }
- .suggest-btn { padding: 6px 14px; border-radius: 6px; font-size: 12px; cursor: pointer; transition: all 0.2s; }
- .suggest-btn.accept { background: var(--primary); color: white; border: none; }
- .suggest-btn.accept:hover { background: var(--primary-dark); }
- .suggest-btn.ignore { background: var(--white); color: var(--text2); border: 1px solid var(--border); }
- .suggest-btn.ignore:hover { border-color: var(--text2); }
- /* 数据表格 */
- .data-table-card { background: var(--white); border: 1px solid var(--border); border-radius: 10px; margin: 16px 0; overflow: hidden; }
- .data-table-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); }
- .data-table-title { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; }
- .data-table-source { font-size: 11px; color: var(--text3); }
- .data-table { width: 100%; border-collapse: collapse; }
- .data-table th { background: var(--bg); padding: 10px 16px; text-align: left; font-size: 12px; font-weight: 600; color: var(--text2); border-bottom: 1px solid var(--border); }
- .data-table td { padding: 10px 16px; font-size: 13px; border-bottom: 1px solid var(--border); }
- .data-table tr:last-child td { border-bottom: none; }
- .data-table tr:hover td { background: var(--primary-light); }
- /* 右侧AI助手面板 */
- .right-panel { width: 380px; background: var(--white); border-left: 1px solid var(--border); display: flex; flex-direction: column; }
- /* 要素管理区 */
- .element-section { padding: 16px; border-bottom: 1px solid var(--border); }
- .element-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
- .element-title { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
- .element-count { font-size: 11px; color: var(--text3); font-weight: normal; }
- /* 要素标签容器 - 固定高度可滚动 */
- .element-tags-wrap { display: flex; flex-wrap: wrap; gap: 8px; max-height: 180px; overflow-y: auto; padding-right: 4px; }
- .element-tags-wrap::-webkit-scrollbar { width: 4px; }
- .element-tags-wrap::-webkit-scrollbar-track { background: var(--bg); border-radius: 2px; }
- .element-tags-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
- .element-tags-wrap::-webkit-scrollbar-thumb:hover { background: var(--text3); }
- /* 要素标签样式 */
- .element-tag { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 16px; font-size: 12px; cursor: grab; transition: all 0.2s; user-select: none; }
- .element-tag:hover { border-color: var(--primary); background: var(--primary-light); transform: translateY(-1px); }
- .element-tag:active { cursor: grabbing; }
- .element-tag.dragging { opacity: 0.5; }
- .element-tag .tag-icon { font-size: 12px; }
- .element-tag .tag-name { font-weight: 500; }
- .element-tag.entity { border-left: 3px solid var(--primary); }
- .element-tag.concept { border-left: 3px solid #722ed1; }
- .element-tag.data { border-left: 3px solid var(--success); }
- .element-tag.location { border-left: 3px solid var(--warning); }
- .element-tag.asset { border-left: 3px solid #eb2f96; }
- .element-hint { font-size: 11px; color: var(--text3); margin-top: 10px; text-align: center; }
- /* 要素详情弹出框 */
- .element-popover { position: fixed; width: 280px; background: var(--white); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.15); z-index: 2000; display: none; }
- .element-popover.show { display: block; }
- .popover-header { padding: 12px 14px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; }
- .popover-icon { width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 16px; }
- .popover-icon.entity { background: linear-gradient(135deg, #e6f7ff, #bae7ff); }
- .popover-icon.data { background: linear-gradient(135deg, #f6ffed, #d9f7be); }
- .popover-icon.location { background: linear-gradient(135deg, #fff7e6, #ffe7ba); }
- .popover-icon.asset { background: linear-gradient(135deg, #fff0f6, #ffd6e7); }
- .popover-title { font-size: 14px; font-weight: 600; flex: 1; }
- .popover-close { width: 24px; height: 24px; border: none; background: var(--bg); border-radius: 50%; cursor: pointer; font-size: 12px; }
- .popover-close:hover { background: var(--danger); color: white; }
- .popover-body { padding: 14px; }
- .popover-section { margin-bottom: 10px; }
- .popover-label { font-size: 10px; color: var(--text3); margin-bottom: 4px; text-transform: uppercase; }
- .popover-value { font-size: 12px; color: var(--text1); }
- .popover-relations { display: flex; flex-wrap: wrap; gap: 6px; }
- .popover-relation { padding: 4px 8px; background: var(--bg); border-radius: 4px; font-size: 11px; cursor: pointer; }
- .popover-relation:hover { background: var(--primary-light); color: var(--primary); }
- .popover-actions { display: flex; gap: 8px; margin-top: 12px; }
- .popover-actions .btn { flex: 1; justify-content: center; font-size: 12px; }
- /* 拖拽放置提示 */
- .editor-content.drag-over { background: linear-gradient(135deg, rgba(24,144,255,0.05), rgba(24,144,255,0.1)); }
- .editor-content.drag-over::after { content: '释放鼠标插入要素'; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 12px 24px; background: var(--primary); color: white; border-radius: 8px; font-size: 14px; z-index: 100; }
- /* AI助手区 */
- .ai-assistant { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-height: 0; }
- .ai-header { padding: 12px 16px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
- .ai-avatar-sm { width: 36px; height: 36px; background: var(--ai-gradient); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
- .ai-info { flex: 1; }
- .ai-name { font-size: 14px; font-weight: 600; }
- .ai-status { font-size: 11px; color: var(--success); }
- /* AI Tab切换 */
- .ai-tabs { display: flex; border-bottom: 1px solid var(--border); flex-shrink: 0; }
- .ai-tab { flex: 1; padding: 10px; text-align: center; font-size: 12px; cursor: pointer; color: var(--text2); border-bottom: 2px solid transparent; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 4px; }
- .ai-tab:hover { color: var(--primary); }
- .ai-tab.active { color: var(--primary); border-bottom-color: var(--primary); }
- /* AI消息区 */
- .ai-messages { flex: 1; overflow-y: auto; padding: 16px; min-height: 0; }
- .msg { display: flex; gap: 10px; margin-bottom: 16px; }
- .msg.user { flex-direction: row-reverse; }
- .msg-avatar { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; flex-shrink: 0; }
- .msg.ai .msg-avatar { background: var(--ai-gradient); color: white; }
- .msg.user .msg-avatar { background: var(--primary); color: white; }
- .msg-bubble { max-width: 85%; padding: 10px 14px; border-radius: 12px; font-size: 13px; line-height: 1.6; }
- .msg.ai .msg-bubble { background: var(--bg); border-radius: 4px 12px 12px 12px; }
- .msg.user .msg-bubble { background: var(--primary); color: white; border-radius: 12px 4px 12px 12px; }
- /* 内容建议卡片 */
- .content-suggestion { background: linear-gradient(135deg, #f0f7ff, #f5f0ff); border: 1px solid #d6e4ff; border-radius: 10px; padding: 14px; margin: 12px 0; }
- .content-suggestion-header { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
- .content-suggestion-title { font-size: 13px; font-weight: 600; color: var(--primary); }
- .content-suggestion-body { font-size: 12px; line-height: 1.7; color: var(--text1); margin-bottom: 12px; }
- .content-suggestion-list { list-style: none; margin-bottom: 12px; }
- .content-suggestion-list li { padding: 4px 0; font-size: 12px; color: var(--text2); }
- .content-suggestion-list li::before { content: '•'; color: var(--primary); margin-right: 8px; }
- .content-suggestion-actions { display: flex; gap: 8px; }
- /* AI输入区 - 底部固定 */
- .ai-input-area { padding: 12px 16px; border-top: 1px solid var(--border); background: var(--white); flex-shrink: 0; }
- .ai-input-box { background: var(--bg); border: 1px solid var(--border); border-radius: 20px; transition: all 0.2s; }
- .ai-input-box:focus-within { border-color: var(--primary); background: var(--white); box-shadow: 0 0 0 3px rgba(24,144,255,0.1); }
- .ai-input-box textarea { width: 100%; border: none; background: transparent; resize: none; outline: none; font-size: 13px; line-height: 1.5; padding: 10px 16px; min-height: 40px; max-height: 80px; font-family: inherit; border-radius: 20px; display: block; }
- .ai-input-box textarea::placeholder { color: var(--text3); }
- .ai-input-hint { display: flex; align-items: center; justify-content: space-between; padding: 8px 4px 0; font-size: 10px; color: var(--text3); }
- /* 要素标签容器 */
- .element-section { border-bottom: 1px solid var(--border); }
- .element-header { padding: 14px 16px; display: flex; align-items: center; justify-content: space-between; }
- .element-title { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
- .element-count { font-size: 11px; color: var(--text3); font-weight: normal; }
- .element-body { padding: 0 16px 14px; }
- /* 动画 */
- @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
- .parsing-anim { animation: pulse 1.5s infinite; }
- /* 可编辑内容区 */
- .editor-content[contenteditable="true"] { outline: none; }
- .editor-content[contenteditable="true"]:focus { background: #fafbfc; }
- .editor-content[contenteditable="true"] ::selection { background: rgba(24,144,255,0.2); }
- /* 段落编辑效果 */
- .editor-content p, .editor-content h1, .editor-content h2, .editor-content h3, .editor-content li {
- position: relative; border-radius: 6px; transition: all 0.2s; padding: 4px 8px; margin-left: -8px; margin-right: -8px;
- }
- .editor-content p:focus, .editor-content h1:focus, .editor-content h2:focus, .editor-content h3:focus, .editor-content li:focus,
- .editor-content p.editing, .editor-content h1.editing, .editor-content h2.editing, .editor-content h3.editing, .editor-content li.editing {
- background: linear-gradient(135deg, rgba(24,144,255,0.08), rgba(24,144,255,0.04));
- box-shadow: inset 0 0 0 1px rgba(24,144,255,0.2);
- }
- .editor-content p:hover, .editor-content h1:hover, .editor-content h2:hover, .editor-content h3:hover, .editor-content li:hover {
- background: rgba(0,0,0,0.02);
- }
- /* 右键菜单 */
- .context-menu { position: fixed; min-width: 180px; background: var(--white); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.15); z-index: 3000; display: none; overflow: hidden; }
- .context-menu.show { display: block; }
- .context-menu-item { display: flex; align-items: center; gap: 10px; padding: 10px 14px; font-size: 13px; cursor: pointer; transition: all 0.15s; }
- .context-menu-item:hover { background: var(--primary-light); color: var(--primary); }
- .context-menu-item .icon { font-size: 14px; width: 20px; text-align: center; }
- .context-menu-item .shortcut { margin-left: auto; font-size: 11px; color: var(--text3); }
- .context-menu-divider { height: 1px; background: var(--border); margin: 4px 0; }
- /* AI结果确认弹窗 */
- .ai-confirm-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: none; align-items: center; justify-content: center; z-index: 3500; }
- .ai-confirm-modal.show { display: flex; }
- .ai-confirm-card { width: 520px; background: var(--white); border-radius: 14px; overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,0.2); }
- .ai-confirm-header { padding: 16px 20px; background: linear-gradient(135deg, #f0f7ff, #e6fffb); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }
- .ai-confirm-icon { width: 40px; height: 40px; background: var(--white); border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
- .ai-confirm-title { flex: 1; }
- .ai-confirm-title h3 { font-size: 15px; font-weight: 600; margin-bottom: 2px; }
- .ai-confirm-title span { font-size: 11px; color: var(--text3); }
- .ai-confirm-close { width: 28px; height: 28px; border: none; background: rgba(0,0,0,0.05); border-radius: 50%; cursor: pointer; font-size: 14px; }
- .ai-confirm-close:hover { background: var(--danger); color: white; }
- .ai-confirm-body { padding: 20px; }
- .ai-confirm-section { margin-bottom: 16px; }
- .ai-confirm-label { font-size: 12px; font-weight: 500; color: var(--text2); margin-bottom: 8px; display: flex; align-items: center; gap: 6px; }
- .ai-confirm-text { padding: 12px 14px; border-radius: 8px; font-size: 13px; line-height: 1.7; }
- .ai-confirm-text.original { background: var(--bg); color: var(--text2); text-decoration: line-through; }
- .ai-confirm-text.result { background: linear-gradient(135deg, #f6ffed, #e6fffb); border: 1px solid #b7eb8f; color: var(--text1); }
- .ai-confirm-diff { display: flex; align-items: center; justify-content: center; padding: 8px 0; color: var(--success); font-size: 20px; }
- .ai-confirm-footer { padding: 16px 20px; border-top: 1px solid var(--border); display: flex; gap: 10px; justify-content: flex-end; background: var(--bg); }
- .ai-confirm-footer .btn { min-width: 100px; justify-content: center; }
- /* 标记为要素弹窗 */
- .mark-entity-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: none; align-items: center; justify-content: center; z-index: 3500; }
- .mark-entity-modal.show { display: flex; }
- .mark-entity-card { width: 400px; background: var(--white); border-radius: 14px; overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,0.2); }
- .mark-entity-header { padding: 16px 20px; background: linear-gradient(135deg, #f9f0ff, #fff0f6); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }
- .mark-entity-body { padding: 20px; }
- .mark-entity-preview { padding: 12px 16px; background: var(--primary-light); border: 1px dashed var(--primary); border-radius: 8px; font-size: 14px; font-weight: 500; color: var(--primary); text-align: center; margin-bottom: 16px; }
- .mark-entity-types { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }
- .mark-entity-type { flex: 1; min-width: 45%; padding: 12px; border: 1px solid var(--border); border-radius: 8px; cursor: pointer; transition: all 0.2s; text-align: center; }
- .mark-entity-type:hover { border-color: var(--primary); background: var(--primary-light); }
- .mark-entity-type.selected { border-color: var(--primary); background: var(--primary-light); box-shadow: 0 0 0 2px rgba(24,144,255,0.2); }
- .mark-entity-type .type-icon { font-size: 24px; margin-bottom: 4px; }
- .mark-entity-type .type-name { font-size: 12px; font-weight: 500; }
- .mark-entity-footer { padding: 16px 20px; border-top: 1px solid var(--border); display: flex; gap: 10px; justify-content: flex-end; background: var(--bg); }
- /* 实体标签编辑弹窗 */
- .entity-edit-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: none; align-items: center; justify-content: center; z-index: 2500; }
- .entity-edit-modal.show { display: flex; }
- .entity-edit-card { width: 420px; background: var(--white); border-radius: 14px; overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,0.2); }
- .entity-edit-header { padding: 16px 20px; background: linear-gradient(135deg, #f0f7ff, #f5f0ff); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }
- .entity-edit-icon { width: 40px; height: 40px; background: var(--white); border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
- .entity-edit-title { flex: 1; }
- .entity-edit-title h3 { font-size: 15px; font-weight: 600; margin-bottom: 2px; }
- .entity-edit-title span { font-size: 11px; color: var(--text3); }
- .entity-edit-close { width: 28px; height: 28px; border: none; background: rgba(0,0,0,0.05); border-radius: 50%; cursor: pointer; font-size: 14px; }
- .entity-edit-close:hover { background: var(--danger); color: white; }
- .entity-edit-body { padding: 20px; }
- .entity-edit-section { margin-bottom: 16px; }
- .entity-edit-section:last-child { margin-bottom: 0; }
- .entity-edit-label { font-size: 12px; font-weight: 500; color: var(--text2); margin-bottom: 8px; display: flex; align-items: center; gap: 6px; }
- .entity-edit-input { width: 100%; padding: 10px 14px; border: 1px solid var(--border); border-radius: 8px; font-size: 14px; outline: none; transition: all 0.2s; }
- .entity-edit-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(24,144,255,0.1); }
- .entity-edit-input:disabled { background: var(--bg); color: var(--text3); }
- .entity-edit-row { display: flex; gap: 12px; }
- .entity-edit-row .entity-edit-section { flex: 1; }
- /* 数据关系表格 */
- .entity-relation-table { width: 100%; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
- .entity-relation-table th { background: var(--bg); padding: 10px 12px; text-align: left; font-size: 12px; font-weight: 500; color: var(--text2); border-bottom: 1px solid var(--border); }
- .entity-relation-table td { padding: 10px 12px; font-size: 13px; border-bottom: 1px solid var(--border); }
- .entity-relation-table tr:last-child td { border-bottom: none; }
- .entity-relation-table .original { color: var(--text3); }
- .entity-relation-table .current { color: var(--primary); font-weight: 500; }
- .entity-relation-table .editable { background: var(--primary-light); border-radius: 4px; padding: 4px 8px; }
- .entity-edit-footer { padding: 16px 20px; border-top: 1px solid var(--border); display: flex; gap: 10px; justify-content: flex-end; background: var(--bg); }
- .entity-edit-footer .btn { min-width: 80px; justify-content: center; }
- </style>
- <!-- 编辑器页面 -->
- <div class="editor-page" id="page-editor">
- <!-- 编辑器工具栏 -->
- <div class="editor-toolbar">
- <button class="back-btn" onclick="closeEditor()">← 返回</button>
- <input type="text" class="report-title-input" value="智慧园区建设项目可行性研究报告">
- <span class="save-status">✓ 已保存</span>
- <div class="toolbar-right">
- <button class="toolbar-btn" onclick="showToast('查看版本历史', 'info')">
- <span class="icon">🕐</span>
- <span>版本</span>
- </button>
- <button class="toolbar-btn" onclick="showToast('协作设置', 'info')">
- <span class="icon">👥</span>
- <span>协作</span>
- </button>
- <button class="toolbar-btn" onclick="showToast('分享链接已复制', 'success')">
- <span class="icon">🔗</span>
- <span>分享</span>
- </button>
- <button class="toolbar-btn" onclick="showExportMenu(this)">
- <span class="icon">📤</span>
- <span>导出</span>
- <span style="font-size:10px;margin-left:2px;">▾</span>
- </button>
- <div class="toolbar-divider"></div>
- <button class="toolbar-btn primary" onclick="showToast('保存成功', 'success')">
- <span class="icon">💾</span>
- <span>保存</span>
- </button>
- </div>
- </div>
- <!-- 编辑器主体 -->
- <div class="editor-body">
- <!-- 左侧项目文件面板 -->
- <div class="left-panel">
- <div class="panel-header">
- <span>📁 项目文件</span>
- <span class="file-count">5个文件</span>
- </div>
- <div class="panel-body">
- <!-- 上传区 -->
- <div class="upload-zone" onclick="simulateUpload()">
- <div class="upload-icon">📄</div>
- <div class="upload-text">拖拽或点击上传</div>
- <div class="upload-hint">支持 PDF / Word / Excel / MD</div>
- </div>
- <!-- 解析中文件组 -->
- <div class="file-group">
- <div class="file-group-header">
- <span>📥 解析中</span>
- <span class="count">2</span>
- </div>
- <div class="file-item" id="parsingFile1">
- <span class="file-icon pdf">📕</span>
- <div class="file-info">
- <div class="file-name">市场调研数据.pdf</div>
- <div class="file-meta">
- <span>5.8 MB</span>
- <span class="file-status parsing parsing-anim">📊 解析中 65%</span>
- </div>
- </div>
- </div>
- <div class="file-item">
- <span class="file-icon pdf">📕</span>
- <div class="file-info">
- <div class="file-name">技术方案说明.pdf</div>
- <div class="file-meta">
- <span>3.6 MB</span>
- <span class="file-status parsing parsing-anim">📊 解析中 30%</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 已完成文件组 -->
- <div class="file-group">
- <div class="file-group-header">
- <span style="color:var(--success)">✅ 已完成</span>
- <span class="count">3</span>
- </div>
- <div class="file-item active" onclick="highlightFile(this)">
- <span class="file-icon docx">📘</span>
- <div class="file-info">
- <div class="file-name">项目可行性研究报告.docx</div>
- <div class="file-meta">
- <span>2.4 MB</span>
- <span class="file-status done">✓ 已完成</span>
- </div>
- </div>
- </div>
- <div class="file-item" onclick="highlightFile(this)">
- <span class="file-icon xlsx">📗</span>
- <div class="file-info">
- <div class="file-name">财务预测表.xlsx</div>
- <div class="file-meta">
- <span>1.2 MB</span>
- <span class="file-status done">✓ 已完成</span>
- </div>
- </div>
- </div>
- <div class="file-item" onclick="highlightFile(this)">
- <span class="file-icon md">📄</span>
- <div class="file-info">
- <div class="file-name">会议纪要.md</div>
- <div class="file-meta">
- <span>48 KB</span>
- <span class="file-status done">✓ 已完成</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 中间编辑区 -->
- <div class="center-panel">
- <div class="editor-title-bar">
- <div class="editor-main-title">智慧园区建设项目可行性研究报告</div>
- <div class="view-toggle">
- <button class="view-btn active" id="viewOriginal" onclick="switchView('original')">📄 原文</button>
- <button class="view-btn" id="viewMarked" onclick="switchView('marked')">🏷️ 标记</button>
- </div>
- <button class="graph-btn" onclick="showGraphModal()" title="查看知识图谱">🔗</button>
- </div>
- <div class="editor-scroll">
- <!-- 原文视图 -->
- <div class="editor-content" id="contentOriginal" contenteditable="true" oncontextmenu="showContextMenu(event)">
- <h1>智慧园区建设项目可行性研究报告</h1>
- <h2>一、项目背景</h2>
- <p>随着数字经济的快速发展,智慧园区已成为推动产业升级和城市现代化的重要载体。本项目旨在构建集智能化管理、低碳绿色、产业协同于一体的新型智慧园区。</p>
- <h3>1.1 行业现状</h3>
- <p>根据最新市场调研数据显示,2024年中国智慧园区市场规模已达到1,789亿元,同比增长18%,预计2025年将突破2,100亿元。</p>
- <!-- 数据表格 -->
- <div class="data-table-card">
- <div class="data-table-header">
- <div class="data-table-title">
- <span>📊</span>
- <span>市场规模数据</span>
- </div>
- <div class="data-table-source">来源: 市场调研数据.pdf</div>
- </div>
- <table class="data-table">
- <thead>
- <tr>
- <th>年份</th>
- <th>市场规模(亿元)</th>
- <th>同比增长</th>
- </tr>
- </thead>
- <tbody>
- <tr><td>2022</td><td>1,280</td><td>15.2%</td></tr>
- <tr><td>2023</td><td>1,516</td><td>18.4%</td></tr>
- <tr><td>2024</td><td>1,789</td><td>18.0%</td></tr>
- <tr><td>2025E</td><td>2,100</td><td>17.4%</td></tr>
- </tbody>
- </table>
- </div>
- <h2>二、项目概述</h2>
- <p>本项目位于华南地区核心区域,规划总面积约50万平方米,预计总投资12.5亿元。项目将分三期建设,首期重点打造智能制造产业集群和数字服务中心。</p>
- <h3>2.1 建设目标</h3>
- <p>通过三年建设周期,实现以下核心目标:</p>
- <ul style="margin-left:20px;margin-bottom:16px;line-height:2;">
- <li>入驻企业数量达到200家以上</li>
- <li>年产值突破50亿元</li>
- <li>创造就业岗位8000个</li>
- <li>获得国家级智慧园区认证</li>
- </ul>
- </div>
- <!-- 标记视图 -->
- <div class="editor-content" id="contentMarked" style="display:none;" contenteditable="true" oncontextmenu="showContextMenu(event)">
- <h1>智慧园区建设项目可行性研究报告</h1>
- <h2>一、项目背景</h2>
- <p>随着数字经济的快速发展,<span class="entity-highlight entity" onclick="showEntityEditModal(event, 'smartpark')" contenteditable="false">智慧园区</span>已成为推动<span class="entity-highlight concept" onclick="showEntityEditModal(event, 'upgrade')" contenteditable="false">产业升级</span>和<span class="entity-highlight concept" onclick="showEntityEditModal(event, 'modern')" contenteditable="false">城市现代化</span>的重要载体。本项目旨在构建集<span class="entity-highlight concept" onclick="showEntityEditModal(event, 'ai')" contenteditable="false">智能化管理</span>、<span class="entity-highlight concept" onclick="showEntityEditModal(event, 'green')" contenteditable="false">低碳绿色</span>、产业协同于一体的新型智慧园区。</p>
- <!-- AI优化建议卡片 - 只在标记视图显示 -->
- <div class="ai-suggestion-card" id="aiSuggestionCard" contenteditable="false">
- <div class="ai-suggestion-header">
- <span class="ai-suggestion-icon">💡</span>
- <span class="ai-suggestion-title">AI 优化建议</span>
- </div>
- <div class="ai-suggestion-content">
- 此处可补充具体的政策文件引用,增强论述的权威性。已从《市场调研数据.pdf》中提取到《"十四五"数字经济发展规划》等相关政策信息。
- </div>
- <div class="ai-suggestion-actions">
- <button class="suggest-btn accept" onclick="acceptSuggestion()">✓ 采纳建议</button>
- <button class="suggest-btn ignore" onclick="ignoreSuggestion()">✕ 忽略</button>
- </div>
- </div>
- <h3>1.1 行业现状</h3>
- <p>根据最新市场调研数据显示,2024年中国<span class="entity-highlight entity" onclick="showEntityEditModal(event, 'smartpark')" contenteditable="false">智慧园区</span>市场规模已达到<span class="entity-highlight data" onclick="showEntityEditModal(event, 'data1')" contenteditable="false">1,789亿元</span>,同比增长<span class="entity-highlight data" onclick="showEntityEditModal(event, 'data2')" contenteditable="false">18%</span>,预计2025年将突破2,100亿元。</p>
- <!-- 数据表格 -->
- <div class="data-table-card" contenteditable="false">
- <div class="data-table-header">
- <div class="data-table-title">
- <span>📊</span>
- <span>市场规模数据</span>
- </div>
- <div class="data-table-source">来源: 市场调研数据.pdf</div>
- </div>
- <table class="data-table">
- <thead>
- <tr>
- <th>年份</th>
- <th>市场规模(亿元)</th>
- <th>同比增长</th>
- </tr>
- </thead>
- <tbody>
- <tr><td>2022</td><td>1,280</td><td>15.2%</td></tr>
- <tr><td>2023</td><td>1,516</td><td>18.4%</td></tr>
- <tr><td>2024</td><td>1,789</td><td>18.0%</td></tr>
- <tr><td>2025E</td><td>2,100</td><td>17.4%</td></tr>
- </tbody>
- </table>
- </div>
- <h2>二、项目概述</h2>
- <p>本项目位于<span class="entity-highlight location" onclick="showEntityEditModal(event, 'location')" contenteditable="false">华南地区</span>核心区域,规划总面积约<span class="entity-highlight data" onclick="showEntityEditModal(event, 'data4')" contenteditable="false">50万平方米</span>,预计总投资<span class="entity-highlight data" onclick="showEntityEditModal(event, 'data3')" contenteditable="false">12.5亿元</span>。项目将分三期建设,首期重点打造<span class="entity-highlight concept" onclick="showEntityEditModal(event, 'manufacture')" contenteditable="false">智能制造产业集群</span>和<span class="entity-highlight concept" onclick="showEntityEditModal(event, 'digital')" contenteditable="false">数字服务中心</span>。</p>
- <h3>2.1 建设目标</h3>
- <p>通过三年建设周期,实现以下核心目标:</p>
- <ul style="margin-left:20px;margin-bottom:16px;line-height:2;">
- <li>入驻企业数量达到<span class="entity-highlight" onclick="showEntityInfo('200家')">200家</span>以上</li>
- <li>年产值突破<span class="entity-highlight" onclick="showEntityInfo('50亿元')">50亿元</span></li>
- <li>创造就业岗位<span class="entity-highlight" onclick="showEntityInfo('8000个')">8000个</span></li>
- <li>获得<span class="entity-highlight" onclick="showEntityInfo('国家级智慧园区认证')">国家级智慧园区认证</span></li>
- </ul>
- </div>
- </div>
- </div>
- <!-- 右侧AI助手面板 -->
- <div class="right-panel">
- <!-- 要素管理区 -->
- <div class="element-section">
- <div class="element-header">
- <div class="element-title">
- <span>🏷️</span>
- <span>要素管理</span>
- <span class="element-count">(15个)</span>
- </div>
- <span style="font-size:11px;color:var(--primary);cursor:pointer;" onclick="showGraphModal()">查看图谱 →</span>
- </div>
-
- <!-- 要素标签容器 - 固定高度可滚动 -->
- <div class="element-tags-wrap" id="elementTagsWrap">
- <span class="element-tag entity" draggable="true" ondragstart="handleTagDragStart(event, '智慧园区')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'smartpark')">
- <span class="tag-icon">🏢</span>
- <span class="tag-name">智慧园区</span>
- </span>
- <span class="element-tag concept" draggable="true" ondragstart="handleTagDragStart(event, '产业升级')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'upgrade')">
- <span class="tag-icon">📈</span>
- <span class="tag-name">产业升级</span>
- </span>
- <span class="element-tag concept" draggable="true" ondragstart="handleTagDragStart(event, '城市现代化')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'modern')">
- <span class="tag-icon">🌆</span>
- <span class="tag-name">城市现代化</span>
- </span>
- <span class="element-tag concept" draggable="true" ondragstart="handleTagDragStart(event, '智能化管理')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'ai')">
- <span class="tag-icon">🤖</span>
- <span class="tag-name">智能化管理</span>
- </span>
- <span class="element-tag concept" draggable="true" ondragstart="handleTagDragStart(event, '低碳绿色')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'green')">
- <span class="tag-icon">🌱</span>
- <span class="tag-name">低碳绿色</span>
- </span>
- <span class="element-tag location" draggable="true" ondragstart="handleTagDragStart(event, '华南地区')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'location')">
- <span class="tag-icon">📍</span>
- <span class="tag-name">华南地区</span>
- </span>
- <span class="element-tag data" draggable="true" ondragstart="handleTagDragStart(event, '1,789亿元')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'data1')">
- <span class="tag-icon">💰</span>
- <span class="tag-name">1,789亿元</span>
- </span>
- <span class="element-tag data" draggable="true" ondragstart="handleTagDragStart(event, '18%')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'data2')">
- <span class="tag-icon">📊</span>
- <span class="tag-name">18%</span>
- </span>
- <span class="element-tag data" draggable="true" ondragstart="handleTagDragStart(event, '12.5亿元')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'data3')">
- <span class="tag-icon">💵</span>
- <span class="tag-name">12.5亿元</span>
- </span>
- <span class="element-tag data" draggable="true" ondragstart="handleTagDragStart(event, '50万平方米')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'data4')">
- <span class="tag-icon">📐</span>
- <span class="tag-name">50万m²</span>
- </span>
- <!-- 更多标签(滚动可见) -->
- <span class="element-tag data" draggable="true" ondragstart="handleTagDragStart(event, '200家')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'data5')">
- <span class="tag-icon">🏭</span>
- <span class="tag-name">200家</span>
- </span>
- <span class="element-tag data" draggable="true" ondragstart="handleTagDragStart(event, '50亿元')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'data6')">
- <span class="tag-icon">💎</span>
- <span class="tag-name">50亿元</span>
- </span>
- <span class="element-tag data" draggable="true" ondragstart="handleTagDragStart(event, '8000个')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'data7')">
- <span class="tag-icon">👥</span>
- <span class="tag-name">8000个岗位</span>
- </span>
- <span class="element-tag asset" draggable="true" ondragstart="handleTagDragStart(event, '[柱状图]')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'chart')">
- <span class="tag-icon">📊</span>
- <span class="tag-name">趋势图</span>
- </span>
- <span class="element-tag asset" draggable="true" ondragstart="handleTagDragStart(event, '[结论模板]')" ondragend="handleTagDragEnd(event)" onclick="showTagPopover(event, 'template')">
- <span class="tag-icon">📝</span>
- <span class="tag-name">结论模板</span>
- </span>
- </div>
- <div class="element-hint">💡 点击查看详情,拖拽插入正文</div>
- </div>
- <!-- 要素详情弹出框 -->
- <div class="element-popover" id="elementPopover">
- <div class="popover-header">
- <div class="popover-icon entity" id="popoverIcon">🏢</div>
- <div class="popover-title" id="popoverTitle">智慧园区</div>
- <button class="popover-close" onclick="hideTagPopover()">×</button>
- </div>
- <div class="popover-body">
- <div class="popover-section">
- <div class="popover-label">类型</div>
- <div class="popover-value" id="popoverType">核心实体</div>
- </div>
- <div class="popover-section">
- <div class="popover-label">来源</div>
- <div class="popover-value" id="popoverSource">项目可行性研究报告.docx</div>
- </div>
- <div class="popover-section">
- <div class="popover-label">关联要素</div>
- <div class="popover-relations" id="popoverRelations">
- <span class="popover-relation">→ 产业升级</span>
- <span class="popover-relation">→ 城市现代化</span>
- </div>
- </div>
- <div class="popover-actions">
- <button class="btn" onclick="showToast('已定位到文档', 'info');hideTagPopover();">📍 定位</button>
- <button class="btn btn-primary" onclick="insertTagToEditor();hideTagPopover();">➕ 插入</button>
- </div>
- </div>
- </div>
- <!-- AI助手区 -->
- <div class="ai-assistant">
- <div class="ai-header">
- <div class="ai-avatar-sm">🤖</div>
- <div class="ai-info">
- <div class="ai-name">灵越 AI 助手</div>
- <div class="ai-status">● 已加载项目上下文</div>
- </div>
- </div>
- <!-- AI Tab切换 -->
- <div class="ai-tabs">
- <div class="ai-tab active" onclick="switchAiTab(this, 'chat')">💬 对话</div>
- <div class="ai-tab" onclick="switchAiTab(this, 'suggest')">💡 建议</div>
- <div class="ai-tab" onclick="switchAiTab(this, 'memory')">🧠 记忆</div>
- </div>
- <!-- 消息区 -->
- <div class="ai-messages" id="aiMessages">
- <div class="msg ai">
- <div class="msg-avatar">🤖</div>
- <div class="msg-bubble">您好!我已分析上传的5份文档,构建了项目知识图谱。有什么可以帮您的?</div>
- </div>
- <div class="msg user">
- <div class="msg-avatar">张</div>
- <div class="msg-bubble">帮我补充市场分析部分的竞争格局内容</div>
- </div>
- <div class="msg ai">
- <div class="msg-avatar">🤖</div>
- <div class="msg-bubble">好的,我已从《市场调研数据.pdf》中提取了竞争格局相关数据。建议如下:</div>
- </div>
- <!-- 内容建议卡片 -->
- <div class="content-suggestion">
- <div class="content-suggestion-header">
- <span>✨</span>
- <span class="content-suggestion-title">内容建议</span>
- </div>
- <div class="content-suggestion-body">建议在市场分析部分增加竞争格局分析章节:</div>
- <ul class="content-suggestion-list">
- <li>主要竞争对手市占率对比</li>
- <li>竞争优势SWOT分析</li>
- <li>差异化竞争策略</li>
- </ul>
- <div class="content-suggestion-actions">
- <button class="suggest-btn accept" onclick="acceptContentSuggestion()">✓ 采纳</button>
- <button class="suggest-btn ignore" onclick="showToast('已忽略', 'info')">✕ 忽略</button>
- </div>
- </div>
- </div>
- <!-- 输入区 - 底部固定 -->
- <div class="ai-input-area">
- <div class="ai-input-box">
- <textarea id="aiTextarea" placeholder="输入指令,按 Enter 发送..." rows="1" onkeydown="handleAiKey(event)" oninput="autoResizeTextarea(this)"></textarea>
- </div>
- <div class="ai-input-hint">
- <span>按 Enter 发送,Shift+Enter 换行</span>
- <span>@引用上下文</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 知识图谱弹窗 -->
- <div class="graph-modal" id="graphModal">
- <div class="graph-container">
- <div class="graph-header">
- <div class="graph-title">
- <span>🔗</span>
- <span>标记要素关系图谱</span>
- <span style="font-size:12px;color:var(--text3);font-weight:normal;margin-left:8px;">共 15 个实体 · 23 条关系</span>
- </div>
- <div style="display:flex;align-items:center;gap:12px;">
- <!-- 视图切换 -->
- <div style="display:flex;border:1px solid var(--border);border-radius:6px;overflow:hidden;">
- <button class="graph-view-btn active" id="graphViewBtn" onclick="switchGraphView('graph')">
- <span>🔗</span> 图谱
- </button>
- <button class="graph-view-btn" id="listViewBtn" onclick="switchGraphView('list')">
- <span>📋</span> 列表
- </button>
- </div>
- <button class="graph-close" onclick="closeGraphModal()">×</button>
- </div>
- </div>
- <!-- 图谱视图 -->
- <div class="graph-body" id="graphViewBody">
- <!-- 图例 -->
- <div class="graph-legend">
- <div class="legend-title">图例说明</div>
- <div class="legend-item"><span class="legend-dot entity"></span>核心实体</div>
- <div class="legend-item"><span class="legend-dot concept"></span>概念/技术</div>
- <div class="legend-item"><span class="legend-dot data"></span>数据/指标</div>
- <div class="legend-item"><span class="legend-dot location"></span>地点/组织</div>
- </div>
- <!-- 连接线 -->
- <svg class="graph-lines" width="100%" height="100%">
- <line x1="450" y1="280" x2="250" y2="150" stroke="#1890ff" stroke-width="2" stroke-opacity="0.3"/>
- <line x1="450" y1="280" x2="650" y2="150" stroke="#1890ff" stroke-width="2" stroke-opacity="0.3"/>
- <line x1="450" y1="280" x2="200" y2="320" stroke="#722ed1" stroke-width="2" stroke-opacity="0.3"/>
- <line x1="450" y1="280" x2="700" y2="320" stroke="#722ed1" stroke-width="2" stroke-opacity="0.3"/>
- <line x1="450" y1="280" x2="280" y2="450" stroke="#52c41a" stroke-width="2" stroke-opacity="0.3"/>
- <line x1="450" y1="280" x2="620" y2="450" stroke="#52c41a" stroke-width="2" stroke-opacity="0.3"/>
- <line x1="450" y1="280" x2="450" y2="480" stroke="#faad14" stroke-width="2" stroke-opacity="0.3"/>
- <line x1="250" y1="150" x2="200" y2="320" stroke="#e8e8e8" stroke-width="1.5"/>
- <line x1="650" y1="150" x2="700" y2="320" stroke="#e8e8e8" stroke-width="1.5"/>
- <line x1="200" y1="320" x2="280" y2="450" stroke="#e8e8e8" stroke-width="1.5"/>
- <line x1="700" y1="320" x2="620" y2="450" stroke="#e8e8e8" stroke-width="1.5"/>
- </svg>
- <!-- 节点 -->
- <div class="graph-node" style="left:410px;top:240px;" onclick="showToast('智慧园区 - 核心实体', 'info')">
- <div class="node-circle primary center">🏢</div>
- <div class="node-label">智慧园区</div>
- </div>
- <div class="graph-node" style="left:220px;top:110px;" onclick="showToast('产业升级 - 概念', 'info')">
- <div class="node-circle purple">📈</div>
- <div class="node-label">产业升级</div>
- </div>
- <div class="graph-node" style="left:620px;top:110px;" onclick="showToast('城市现代化 - 概念', 'info')">
- <div class="node-circle purple">🌆</div>
- <div class="node-label">城市现代化</div>
- </div>
- <div class="graph-node" style="left:160px;top:280px;" onclick="showToast('智能化管理 - 技术', 'info')">
- <div class="node-circle purple">🤖</div>
- <div class="node-label">智能化管理</div>
- </div>
- <div class="graph-node" style="left:670px;top:280px;" onclick="showToast('低碳绿色 - 概念', 'info')">
- <div class="node-circle green">🌱</div>
- <div class="node-label">低碳绿色</div>
- </div>
- <div class="graph-node" style="left:240px;top:410px;" onclick="showToast('1,789亿元 - 市场规模数据', 'info')">
- <div class="node-circle green">💰</div>
- <div class="node-label">1,789亿元</div>
- </div>
- <div class="graph-node" style="left:580px;top:410px;" onclick="showToast('18% - 增长率数据', 'info')">
- <div class="node-circle green">📊</div>
- <div class="node-label">18%增长率</div>
- </div>
- <div class="graph-node" style="left:410px;top:440px;" onclick="showToast('华南地区 - 地点', 'info')">
- <div class="node-circle orange">📍</div>
- <div class="node-label">华南地区</div>
- </div>
- <div class="graph-node" style="left:100px;top:180px;" onclick="showToast('50万平方米 - 面积数据', 'info')">
- <div class="node-circle green" style="width:45px;height:45px;font-size:16px;">📐</div>
- <div class="node-label">50万m²</div>
- </div>
- <div class="graph-node" style="left:780px;top:200px;" onclick="showToast('12.5亿元 - 投资额', 'info')">
- <div class="node-circle green" style="width:45px;height:45px;font-size:16px;">💵</div>
- <div class="node-label">12.5亿元</div>
- </div>
- </div>
- <!-- 列表视图 -->
- <div class="graph-list-body" id="listViewBody" style="display:none;">
- <!-- 筛选栏 -->
- <div style="padding:16px 20px;border-bottom:1px solid var(--border);display:flex;gap:12px;align-items:center;">
- <input type="text" placeholder="🔍 搜索实体..." style="flex:1;max-width:280px;padding:8px 12px;border:1px solid var(--border);border-radius:6px;font-size:13px;outline:none;">
- <div style="display:flex;gap:6px;">
- <span class="list-filter-tag active" onclick="filterListType(this, 'all')">全部</span>
- <span class="list-filter-tag" onclick="filterListType(this, 'entity')">核心实体</span>
- <span class="list-filter-tag" onclick="filterListType(this, 'concept')">概念/技术</span>
- <span class="list-filter-tag" onclick="filterListType(this, 'data')">数据/指标</span>
- <span class="list-filter-tag" onclick="filterListType(this, 'location')">地点/组织</span>
- </div>
- </div>
- <!-- 列表内容 -->
- <div style="flex:1;overflow-y:auto;padding:16px 20px;">
- <!-- 核心实体组 -->
- <div class="list-group">
- <div class="list-group-header">
- <span class="list-group-dot" style="background:var(--primary);"></span>
- <span>核心实体</span>
- <span class="list-group-count">1</span>
- </div>
- <div class="list-item" onclick="showToast('定位到: 智慧园区', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #e6f7ff, #bae7ff);color:var(--primary);">🏢</div>
- <div class="list-item-info">
- <div class="list-item-name">智慧园区</div>
- <div class="list-item-desc">出现 5 次 · 关联 8 个实体</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 产业升级</span>
- <span class="relation-tag">→ 城市现代化</span>
- <span class="relation-tag">+6</span>
- </div>
- </div>
- </div>
- <!-- 概念/技术组 -->
- <div class="list-group">
- <div class="list-group-header">
- <span class="list-group-dot" style="background:#722ed1;"></span>
- <span>概念/技术</span>
- <span class="list-group-count">4</span>
- </div>
- <div class="list-item" onclick="showToast('定位到: 产业升级', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f9f0ff, #efdbff);color:#722ed1;">📈</div>
- <div class="list-item-info">
- <div class="list-item-name">产业升级</div>
- <div class="list-item-desc">出现 2 次 · 关联 3 个实体</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 智慧园区</span>
- <span class="relation-tag">→ 智能化管理</span>
- </div>
- </div>
- <div class="list-item" onclick="showToast('定位到: 城市现代化', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f9f0ff, #efdbff);color:#722ed1;">🌆</div>
- <div class="list-item-info">
- <div class="list-item-name">城市现代化</div>
- <div class="list-item-desc">出现 1 次 · 关联 2 个实体</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 智慧园区</span>
- </div>
- </div>
- <div class="list-item" onclick="showToast('定位到: 智能化管理', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f9f0ff, #efdbff);color:#722ed1;">🤖</div>
- <div class="list-item-info">
- <div class="list-item-name">智能化管理</div>
- <div class="list-item-desc">出现 3 次 · 关联 4 个实体</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 智慧园区</span>
- <span class="relation-tag">→ 低碳绿色</span>
- </div>
- </div>
- <div class="list-item" onclick="showToast('定位到: 低碳绿色', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f6ffed, #d9f7be);color:var(--success);">🌱</div>
- <div class="list-item-info">
- <div class="list-item-name">低碳绿色</div>
- <div class="list-item-desc">出现 2 次 · 关联 2 个实体</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 智慧园区</span>
- </div>
- </div>
- </div>
- <!-- 数据/指标组 -->
- <div class="list-group">
- <div class="list-group-header">
- <span class="list-group-dot" style="background:var(--success);"></span>
- <span>数据/指标</span>
- <span class="list-group-count">6</span>
- </div>
- <div class="list-item" onclick="showToast('定位到: 1,789亿元', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f6ffed, #d9f7be);color:var(--success);">💰</div>
- <div class="list-item-info">
- <div class="list-item-name">1,789亿元</div>
- <div class="list-item-desc">市场规模 · 来源: 市场调研数据.pdf</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 智慧园区</span>
- </div>
- </div>
- <div class="list-item" onclick="showToast('定位到: 18%增长率', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f6ffed, #d9f7be);color:var(--success);">📊</div>
- <div class="list-item-info">
- <div class="list-item-name">18%</div>
- <div class="list-item-desc">同比增长率 · 来源: 市场调研数据.pdf</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 1,789亿元</span>
- </div>
- </div>
- <div class="list-item" onclick="showToast('定位到: 50万平方米', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f6ffed, #d9f7be);color:var(--success);">📐</div>
- <div class="list-item-info">
- <div class="list-item-name">50万平方米</div>
- <div class="list-item-desc">规划面积 · 来源: 项目可行性研究报告.docx</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 华南地区</span>
- </div>
- </div>
- <div class="list-item" onclick="showToast('定位到: 12.5亿元', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #f6ffed, #d9f7be);color:var(--success);">💵</div>
- <div class="list-item-info">
- <div class="list-item-name">12.5亿元</div>
- <div class="list-item-desc">总投资额 · 来源: 财务预测表.xlsx</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 智慧园区</span>
- </div>
- </div>
- </div>
- <!-- 地点/组织组 -->
- <div class="list-group">
- <div class="list-group-header">
- <span class="list-group-dot" style="background:var(--warning);"></span>
- <span>地点/组织</span>
- <span class="list-group-count">2</span>
- </div>
- <div class="list-item" onclick="showToast('定位到: 华南地区', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #fff7e6, #ffe7ba);color:var(--warning);">📍</div>
- <div class="list-item-info">
- <div class="list-item-name">华南地区</div>
- <div class="list-item-desc">出现 3 次 · 关联 4 个实体</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 智慧园区</span>
- <span class="relation-tag">→ 50万m²</span>
- </div>
- </div>
- <div class="list-item" onclick="showToast('定位到: 华南事业部', 'info')">
- <div class="list-item-icon" style="background:linear-gradient(135deg, #fff7e6, #ffe7ba);color:var(--warning);">🏛️</div>
- <div class="list-item-info">
- <div class="list-item-name">华南事业部</div>
- <div class="list-item-desc">组织机构 · 项目负责部门</div>
- </div>
- <div class="list-item-relations">
- <span class="relation-tag">→ 张三</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 右键菜单 -->
- <div class="context-menu" id="contextMenu">
- <div class="context-menu-item" onclick="execContextAction('copy')">
- <span class="icon">📋</span>
- <span>复制</span>
- <span class="shortcut">Ctrl+C</span>
- </div>
- <div class="context-menu-item" onclick="execContextAction('cut')">
- <span class="icon">✂️</span>
- <span>剪切</span>
- <span class="shortcut">Ctrl+X</span>
- </div>
- <div class="context-menu-item" onclick="execContextAction('paste')">
- <span class="icon">📄</span>
- <span>粘贴</span>
- <span class="shortcut">Ctrl+V</span>
- </div>
- <div class="context-menu-divider"></div>
- <div class="context-menu-item" onclick="execContextAction('polish')">
- <span class="icon">✨</span>
- <span>AI 润色</span>
- </div>
- <div class="context-menu-item" onclick="execContextAction('spell')">
- <span class="icon">📝</span>
- <span>检查拼写</span>
- </div>
- <div class="context-menu-divider"></div>
- <div class="context-menu-item" onclick="execContextAction('mark')">
- <span class="icon">🏷️</span>
- <span>标记为要素</span>
- </div>
- <div class="context-menu-item" onclick="execContextAction('quote')">
- <span class="icon">💬</span>
- <span>引用到AI助手</span>
- </div>
- </div>
- <!-- AI结果确认弹窗 -->
- <div class="ai-confirm-modal" id="aiConfirmModal">
- <div class="ai-confirm-card">
- <div class="ai-confirm-header">
- <div class="ai-confirm-icon" id="aiConfirmIcon">✨</div>
- <div class="ai-confirm-title">
- <h3 id="aiConfirmTitle">AI 润色结果</h3>
- <span id="aiConfirmSubtitle">请确认是否应用以下修改</span>
- </div>
- <button class="ai-confirm-close" onclick="closeAiConfirmModal()">×</button>
- </div>
- <div class="ai-confirm-body">
- <div class="ai-confirm-section">
- <div class="ai-confirm-label">📄 原文内容</div>
- <div class="ai-confirm-text original" id="aiConfirmOriginal">原始文本内容</div>
- </div>
- <div class="ai-confirm-diff">↓</div>
- <div class="ai-confirm-section">
- <div class="ai-confirm-label">✨ <span id="aiConfirmResultLabel">润色结果</span></div>
- <div class="ai-confirm-text result" id="aiConfirmResult">润色后的文本内容</div>
- </div>
- </div>
- <div class="ai-confirm-footer">
- <button class="btn" onclick="closeAiConfirmModal()">取消</button>
- <button class="btn btn-primary" onclick="applyAiResult()">✓ 确认替换</button>
- </div>
- </div>
- </div>
- <!-- 标记为要素弹窗 -->
- <div class="mark-entity-modal" id="markEntityModal">
- <div class="mark-entity-card">
- <div class="mark-entity-header">
- <div class="ai-confirm-icon">🏷️</div>
- <div class="ai-confirm-title">
- <h3>标记为要素</h3>
- <span>选择要素类型以创建标签</span>
- </div>
- <button class="ai-confirm-close" onclick="closeMarkEntityModal()">×</button>
- </div>
- <div class="mark-entity-body">
- <div class="mark-entity-preview" id="markEntityPreview">"选中的文本"</div>
- <div class="ai-confirm-label">选择要素类型</div>
- <div class="mark-entity-types" id="markEntityTypes">
- <div class="mark-entity-type selected" onclick="selectEntityType(this, 'entity')">
- <div class="type-icon">🏢</div>
- <div class="type-name">核心实体</div>
- </div>
- <div class="mark-entity-type" onclick="selectEntityType(this, 'concept')">
- <div class="type-icon">💡</div>
- <div class="type-name">概念/技术</div>
- </div>
- <div class="mark-entity-type" onclick="selectEntityType(this, 'data')">
- <div class="type-icon">📊</div>
- <div class="type-name">数据/指标</div>
- </div>
- <div class="mark-entity-type" onclick="selectEntityType(this, 'location')">
- <div class="type-icon">📍</div>
- <div class="type-name">地点/组织</div>
- </div>
- </div>
- </div>
- <div class="mark-entity-footer">
- <button class="btn" onclick="closeMarkEntityModal()">取消</button>
- <button class="btn btn-primary" onclick="confirmMarkEntity()">✓ 确认标记</button>
- </div>
- </div>
- </div>
- <!-- 实体标签编辑弹窗 -->
- <div class="entity-edit-modal" id="entityEditModal">
- <div class="entity-edit-card">
- <div class="entity-edit-header">
- <div class="entity-edit-icon" id="editEntityIcon">🏢</div>
- <div class="entity-edit-title">
- <h3 id="editEntityName">智慧园区</h3>
- <span id="editEntityType">核心实体 · 来自 项目可行性研究报告.docx</span>
- </div>
- <button class="entity-edit-close" onclick="closeEntityEditModal()">×</button>
- </div>
- <div class="entity-edit-body">
- <!-- 数据关系表 -->
- <div class="entity-edit-section">
- <div class="entity-edit-label">📊 数据关系</div>
- <table class="entity-relation-table">
- <thead>
- <tr>
- <th style="width:30%">属性</th>
- <th style="width:35%">原始值</th>
- <th style="width:35%">当前值</th>
- </tr>
- </thead>
- <tbody id="entityRelationBody">
- <tr>
- <td>标签名称</td>
- <td class="original">智慧园区</td>
- <td class="current"><span class="editable">智慧园区</span></td>
- </tr>
- <tr>
- <td>实体类型</td>
- <td class="original">核心实体</td>
- <td class="current">核心实体</td>
- </tr>
- <tr>
- <td>数据来源</td>
- <td class="original">项目报告.docx</td>
- <td class="current">项目报告.docx</td>
- </tr>
- </tbody>
- </table>
- </div>
- <!-- 编辑区域 -->
- <div class="entity-edit-row">
- <div class="entity-edit-section">
- <div class="entity-edit-label">🏷️ 标签值</div>
- <input type="text" class="entity-edit-input" id="editEntityValue" value="智慧园区">
- </div>
- <div class="entity-edit-section">
- <div class="entity-edit-label">📁 所属分类</div>
- <select class="entity-edit-input" id="editEntityCategory">
- <option value="entity" selected>核心实体</option>
- <option value="concept">概念/技术</option>
- <option value="data">数据/指标</option>
- <option value="location">地点/组织</option>
- </select>
- </div>
- </div>
- <!-- 关联要素 -->
- <div class="entity-edit-section">
- <div class="entity-edit-label">🔗 关联要素</div>
- <div id="editEntityRelations" style="display:flex;flex-wrap:wrap;gap:8px;">
- <span class="popover-relation" onclick="showToast('跳转到: 产业升级', 'info')">产业升级</span>
- <span class="popover-relation" onclick="showToast('跳转到: 城市现代化', 'info')">城市现代化</span>
- <span class="popover-relation" onclick="showToast('跳转到: 1,789亿元', 'info')">1,789亿元</span>
- <span style="padding:3px 8px;background:var(--primary-light);border-radius:4px;font-size:11px;color:var(--primary);cursor:pointer;" onclick="showToast('添加关联', 'info')">+ 添加</span>
- </div>
- </div>
- </div>
- <div class="entity-edit-footer">
- <button class="btn" onclick="showToast('已删除标记', 'info');closeEntityEditModal();">🗑️ 删除标记</button>
- <button class="btn" onclick="closeEntityEditModal()">取消</button>
- <button class="btn btn-primary" onclick="saveEntityEdit()">保存更改</button>
- </div>
- </div>
- </div>
- <!-- 导出菜单 -->
- <div id="exportMenu" style="position:fixed;background:var(--white);border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,0.15);min-width:180px;display:none;z-index:2001;overflow:hidden;">
- <div style="padding:12px 16px;cursor:pointer;font-size:13px;display:flex;align-items:center;gap:10px;transition:background 0.15s;" onmouseover="this.style.background='var(--primary-light)'" onmouseout="this.style.background=''" onclick="showToast('导出PDF成功', 'success');hideExportMenu()">
- <span>📄</span><span>导出为 PDF</span>
- </div>
- <div style="padding:12px 16px;cursor:pointer;font-size:13px;display:flex;align-items:center;gap:10px;transition:background 0.15s;" onmouseover="this.style.background='var(--primary-light)'" onmouseout="this.style.background=''" onclick="showToast('导出Word成功', 'success');hideExportMenu()">
- <span>📝</span><span>导出为 Word</span>
- </div>
- <div style="padding:12px 16px;cursor:pointer;font-size:13px;display:flex;align-items:center;gap:10px;transition:background 0.15s;" onmouseover="this.style.background='var(--primary-light)'" onmouseout="this.style.background=''" onclick="showToast('导出Markdown成功', 'success');hideExportMenu()">
- <span>📋</span><span>导出为 Markdown</span>
- </div>
- <div style="height:1px;background:var(--border);"></div>
- <div style="padding:12px 16px;cursor:pointer;font-size:13px;display:flex;align-items:center;gap:10px;transition:background 0.15s;" onmouseover="this.style.background='var(--primary-light)'" onmouseout="this.style.background=''" onclick="showToast('打印预览', 'info');hideExportMenu()">
- <span>🖨️</span><span>打印</span>
- </div>
- </div>
- <!-- FAB资源监控 -->
- <div style="position:fixed;bottom:24px;right:24px;z-index:1000;" id="fabContainer">
- <div id="fabPanel" style="position:absolute;bottom:60px;right:0;width:260px;background:var(--white);border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,0.15);display:none;overflow:hidden;">
- <div style="padding:14px 16px;background:var(--data-gradient);color:white;font-weight:600;font-size:13px;">📊 资源监控</div>
- <div style="padding:14px 16px;">
- <div style="margin-bottom:12px;">
- <div style="display:flex;justify-content:space-between;margin-bottom:4px;font-size:12px;"><span>Token 消耗</span><span style="font-weight:500;">15.6K / 20K</span></div>
- <div style="height:6px;background:var(--bg);border-radius:3px;"><div style="height:100%;width:78%;background:var(--warning);border-radius:3px;"></div></div>
- </div>
- <div style="margin-bottom:12px;">
- <div style="display:flex;justify-content:space-between;margin-bottom:4px;font-size:12px;"><span>GPU 显存</span><span style="font-weight:500;">3.6G / 8G</span></div>
- <div style="height:6px;background:var(--bg);border-radius:3px;"><div style="height:100%;width:45%;background:var(--success);border-radius:3px;"></div></div>
- </div>
- <div style="display:flex;justify-content:space-between;padding:10px;background:var(--bg);border-radius:8px;">
- <div style="text-align:center;"><div style="font-size:16px;font-weight:600;color:var(--primary);">¥3.12</div><div style="font-size:10px;color:var(--text3);">本次会话</div></div>
- <div style="text-align:center;"><div style="font-size:16px;font-weight:600;color:var(--primary);">¥127.50</div><div style="font-size:10px;color:var(--text3);">本月累计</div></div>
- </div>
- </div>
- </div>
- <button style="width:50px;height:50px;border-radius:50%;background:var(--data-gradient);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:20px;color:white;box-shadow:0 6px 20px rgba(82,196,26,0.35);" onclick="toggleFab()">📊</button>
- </div>
- <!-- Toast容器 -->
- <div id="toastBox" style="position:fixed;top:70px;right:24px;z-index:3000;display:flex;flex-direction:column;gap:8px;"></div>
- <!-- 通知面板 -->
- <div id="notifPanel" style="position:fixed;top:56px;right:0;width:360px;height:calc(100vh - 56px);background:var(--white);box-shadow:-4px 0 16px rgba(0,0,0,0.1);transform:translateX(100%);transition:transform 0.3s;z-index:999;display:flex;flex-direction:column;">
- <div style="padding:18px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;">
- <span style="font-size:15px;font-weight:600;">消息通知</span>
- <span style="font-size:12px;color:var(--primary);cursor:pointer;" onclick="showToast('已全部标为已读', 'success')">全部已读</span>
- </div>
- <div style="flex:1;overflow-y:auto;">
- <div style="padding:14px 18px;border-bottom:1px solid var(--border);background:var(--primary-light);cursor:pointer;" onclick="openEditor()">
- <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
- <span style="width:22px;height:22px;background:#f6ffed;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;">✅</span>
- <span style="flex:1;font-weight:500;font-size:13px;">文档解析完成</span>
- <span style="font-size:10px;color:var(--text3);">刚刚</span>
- </div>
- <div style="font-size:12px;color:var(--text2);">《市场调研数据.pdf》已解析完成,提取到35个实体</div>
- </div>
- <div style="padding:14px 18px;border-bottom:1px solid var(--border);cursor:pointer;">
- <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
- <span style="width:22px;height:22px;background:#fff7e6;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;">💬</span>
- <span style="flex:1;font-weight:500;font-size:13px;">李四评论了您的报告</span>
- <span style="font-size:10px;color:var(--text3);">2小时前</span>
- </div>
- <div style="font-size:12px;color:var(--text2);">建议补充竞争格局分析...</div>
- </div>
- </div>
- </div>
- <!-- 遮罩 -->
- <div id="overlay" style="position:fixed;inset:0;background:rgba(0,0,0,0.3);z-index:998;display:none;" onclick="closeAll()"></div>
- <script>
- // === 导航 ===
- function navTo(page) {
- document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
- document.querySelectorAll('.menu-item').forEach(m => m.classList.remove('active'));
- document.getElementById('page-' + page)?.classList.add('active');
- document.querySelector('[data-page="' + page + '"]')?.classList.add('active');
- document.getElementById('page-editor').classList.remove('active');
- document.getElementById('sidebar').classList.remove('hidden');
- document.getElementById('mainContent').style.display = '';
- closeAll();
- }
- function goHome() { navTo('home'); }
- // === 编辑器 ===
- function openEditor() {
- document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
- document.getElementById('page-editor').classList.add('active');
- document.getElementById('sidebar').classList.add('hidden');
- document.getElementById('mainContent').style.display = 'none';
- closeAll();
- }
- function closeEditor() { navTo('home'); }
- // === 通知 ===
- function toggleNotif() {
- const panel = document.getElementById('notifPanel');
- const overlay = document.getElementById('overlay');
- const isOpen = panel.style.transform === 'translateX(0%)';
- panel.style.transform = isOpen ? 'translateX(100%)' : 'translateX(0%)';
- overlay.style.display = isOpen ? 'none' : 'block';
- }
- // === FAB ===
- function toggleFab() {
- const panel = document.getElementById('fabPanel');
- panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
- }
- // === 思考模式 ===
- function setMode(el) {
- document.querySelectorAll('.mode-btn').forEach(b => b.classList.remove('active'));
- el.classList.add('active');
- showToast('已切换到 ' + el.textContent.trim(), 'success');
- }
- // === 首页AI输入 ===
- function toggleSendBtn() {
- const input = document.getElementById('homeAiInput');
- const btn = document.getElementById('homeSendBtn');
- btn.classList.toggle('show', input.value.trim().length > 0);
- }
- function handleHomeAi() {
- const input = document.getElementById('homeAiInput');
- if (input.value.trim()) {
- showToast('AI正在处理...', 'info');
- setTimeout(() => openEditor(), 1000);
- input.value = '';
- document.getElementById('homeSendBtn').classList.remove('show');
- }
- }
- // === 要素管理 ===
- // 要素数据
- const tagData = {
- smartpark: { icon: '🏢', type: 'entity', name: '智慧园区', typeText: '核心实体', source: '项目可行性研究报告.docx', relations: ['产业升级', '城市现代化', '智能化管理'] },
- upgrade: { icon: '📈', type: 'concept', name: '产业升级', typeText: '概念', source: '项目可行性研究报告.docx', relations: ['智慧园区', '城市现代化'] },
- modern: { icon: '🌆', type: 'concept', name: '城市现代化', typeText: '概念', source: '项目可行性研究报告.docx', relations: ['智慧园区', '产业升级'] },
- ai: { icon: '🤖', type: 'concept', name: '智能化管理', typeText: '技术', source: '技术方案说明.pdf', relations: ['智慧园区', '低碳绿色'] },
- green: { icon: '🌱', type: 'concept', name: '低碳绿色', typeText: '概念', source: '项目可行性研究报告.docx', relations: ['智慧园区'] },
- location: { icon: '📍', type: 'location', name: '华南地区', typeText: '地点', source: '项目可行性研究报告.docx', relations: ['智慧园区', '50万m²'] },
- data1: { icon: '💰', type: 'data', name: '1,789亿元', typeText: '市场规模', source: '市场调研数据.pdf', relations: ['智慧园区', '18%'] },
- data2: { icon: '📊', type: 'data', name: '18%', typeText: '增长率', source: '市场调研数据.pdf', relations: ['1,789亿元'] },
- data3: { icon: '💵', type: 'data', name: '12.5亿元', typeText: '总投资额', source: '财务预测表.xlsx', relations: ['华南地区'] },
- data4: { icon: '📐', type: 'data', name: '50万m²', typeText: '规划面积', source: '项目报告.docx', relations: ['华南地区'] },
- data5: { icon: '🏭', type: 'data', name: '200家', typeText: '企业数量', source: '项目报告.docx', relations: ['建设目标'] },
- data6: { icon: '💎', type: 'data', name: '50亿元', typeText: '年产值', source: '财务预测表.xlsx', relations: ['建设目标'] },
- data7: { icon: '👥', type: 'data', name: '8000个岗位', typeText: '就业岗位', source: '项目报告.docx', relations: ['建设目标'] },
- chart: { icon: '📊', type: 'asset', name: '趋势图', typeText: '图表资产', source: '资产库', relations: ['柱状图'] },
- template: { icon: '📝', type: 'asset', name: '结论模板', typeText: '文本模板', source: '资产库', relations: ['结论'] }
- };
- let currentTagName = '';
- function showTagPopover(event, tagId) {
- event.stopPropagation();
- const popover = document.getElementById('elementPopover');
- const data = tagData[tagId];
- if (!data) return;
- currentTagName = data.name;
- document.getElementById('popoverIcon').className = 'popover-icon ' + data.type;
- document.getElementById('popoverIcon').textContent = data.icon;
- document.getElementById('popoverTitle').textContent = data.name;
- document.getElementById('popoverType').textContent = data.typeText;
- document.getElementById('popoverSource').textContent = data.source;
-
- const relationsEl = document.getElementById('popoverRelations');
- relationsEl.innerHTML = data.relations.map(r =>
- `<span class="popover-relation" onclick="showToast('定位到: ${r}', 'info')">→ ${r}</span>`
- ).join('');
- const rect = event.currentTarget.getBoundingClientRect();
- popover.style.top = Math.min(rect.bottom + 8, window.innerHeight - 300) + 'px';
- popover.style.left = Math.min(rect.left, window.innerWidth - 300) + 'px';
- popover.classList.add('show');
- }
- function hideTagPopover() {
- document.getElementById('elementPopover').classList.remove('show');
- }
- function insertTagToEditor() {
- if (currentTagName) {
- showToast('已插入: ' + currentTagName, 'success');
- }
- }
- document.addEventListener('click', function(e) {
- if (!e.target.closest('.element-popover') && !e.target.closest('.element-tag')) {
- hideTagPopover();
- }
- });
- // === 标签拖拽功能 ===
- function handleTagDragStart(event, tagName) {
- currentTagName = tagName;
- event.currentTarget.classList.add('dragging');
- event.dataTransfer.setData('text/plain', tagName);
- event.dataTransfer.effectAllowed = 'copy';
-
- setTimeout(() => {
- document.querySelectorAll('.editor-content').forEach(el => {
- el.classList.add('drag-over');
- });
- }, 0);
- }
- function handleTagDragEnd(event) {
- event.currentTarget.classList.remove('dragging');
- document.querySelectorAll('.editor-content').forEach(el => {
- el.classList.remove('drag-over');
- });
- }
- // 编辑区放置事件
- document.addEventListener('DOMContentLoaded', function() {
- const editorContents = document.querySelectorAll('.editor-content');
- editorContents.forEach(editor => {
- editor.addEventListener('dragover', function(e) {
- e.preventDefault();
- e.dataTransfer.dropEffect = 'copy';
- });
-
- editor.addEventListener('drop', function(e) {
- e.preventDefault();
- const tagName = e.dataTransfer.getData('text/plain');
- if (tagName) {
- showToast('✓ 已插入要素: ' + tagName, 'success');
- }
- this.classList.remove('drag-over');
- });
- editor.addEventListener('dragleave', function(e) {
- if (!this.contains(e.relatedTarget)) {
- this.classList.remove('drag-over');
- }
- });
- });
- });
- // === 段落编辑效果 ===
- document.addEventListener('DOMContentLoaded', function() {
- // 为可编辑区域添加段落点击效果
- document.querySelectorAll('.editor-content[contenteditable="true"]').forEach(editor => {
- editor.addEventListener('click', function(e) {
- // 移除所有editing类
- this.querySelectorAll('.editing').forEach(el => el.classList.remove('editing'));
-
- // 找到点击的段落元素
- let target = e.target;
- while (target && target !== this) {
- if (['P', 'H1', 'H2', 'H3', 'LI'].includes(target.tagName)) {
- target.classList.add('editing');
- break;
- }
- target = target.parentElement;
- }
- });
- editor.addEventListener('blur', function() {
- this.querySelectorAll('.editing').forEach(el => el.classList.remove('editing'));
- });
- });
- });
- // === 右键菜单 ===
- let selectedText = '';
- let selectedRange = null;
- let currentAiAction = '';
- let aiResultText = '';
- let selectedEntityType = 'entity';
-
- function showContextMenu(event) {
- const selection = window.getSelection();
- selectedText = selection.toString().trim();
-
- if (selectedText.length > 0) {
- event.preventDefault();
- selectedRange = selection.getRangeAt(0).cloneRange();
-
- const menu = document.getElementById('contextMenu');
- menu.style.top = event.clientY + 'px';
- menu.style.left = event.clientX + 'px';
- menu.classList.add('show');
- }
- }
- function hideContextMenu() {
- document.getElementById('contextMenu').classList.remove('show');
- }
- function execContextAction(action) {
- hideContextMenu();
-
- switch(action) {
- case 'copy':
- document.execCommand('copy');
- showToast('已复制到剪贴板', 'success');
- break;
- case 'cut':
- document.execCommand('cut');
- showToast('已剪切', 'success');
- break;
- case 'paste':
- document.execCommand('paste');
- break;
- case 'polish':
- currentAiAction = 'polish';
- showToast('AI正在润色...', 'info');
- setTimeout(() => {
- // 模拟AI润色结果
- aiResultText = improveText(selectedText);
- showAiConfirmModal('✨', 'AI 润色结果', '请确认是否应用润色修改', '润色结果', selectedText, aiResultText);
- }, 1200);
- break;
- case 'spell':
- currentAiAction = 'spell';
- showToast('正在检查拼写...', 'info');
- setTimeout(() => {
- // 模拟拼写检查结果
- aiResultText = checkSpelling(selectedText);
- if (aiResultText === selectedText) {
- showToast('✓ 拼写检查完成,未发现错误', 'success');
- } else {
- showAiConfirmModal('📝', '拼写检查结果', '发现以下拼写问题,请确认修改', '修正结果', selectedText, aiResultText);
- }
- }, 1000);
- break;
- case 'mark':
- showMarkEntityModal(selectedText);
- break;
- case 'quote':
- quoteToAiAssistant(selectedText);
- break;
- }
- }
- // 模拟AI润色
- function improveText(text) {
- // 简单模拟润色效果
- const improvements = {
- '智慧园区': '新一代智慧园区',
- '快速发展': '蓬勃发展',
- '重要载体': '核心引擎和重要载体',
- '产业升级': '产业转型升级',
- '城市现代化': '新型城镇化建设'
- };
- let result = text;
- for (let [key, value] of Object.entries(improvements)) {
- if (text.includes(key)) {
- result = result.replace(key, value);
- }
- }
- if (result === text) {
- result = text + ',这一趋势将持续深化';
- }
- return result;
- }
- // 模拟拼写检查
- function checkSpelling(text) {
- // 简单模拟,实际应该对接拼写检查服务
- return text; // 返回原文表示无错误
- }
- // === AI确认弹窗 ===
- function showAiConfirmModal(icon, title, subtitle, resultLabel, original, result) {
- document.getElementById('aiConfirmIcon').textContent = icon;
- document.getElementById('aiConfirmTitle').textContent = title;
- document.getElementById('aiConfirmSubtitle').textContent = subtitle;
- document.getElementById('aiConfirmResultLabel').textContent = resultLabel;
- document.getElementById('aiConfirmOriginal').textContent = original;
- document.getElementById('aiConfirmResult').textContent = result;
- document.getElementById('aiConfirmModal').classList.add('show');
- }
- function closeAiConfirmModal() {
- document.getElementById('aiConfirmModal').classList.remove('show');
- }
- function applyAiResult() {
- if (selectedRange && aiResultText) {
- // 选中原范围
- const selection = window.getSelection();
- selection.removeAllRanges();
- selection.addRange(selectedRange);
-
- // 替换内容
- document.execCommand('insertText', false, aiResultText);
-
- showToast('✓ 已替换原文', 'success');
- }
- closeAiConfirmModal();
- }
- // === 标记为要素弹窗 ===
- function showMarkEntityModal(text) {
- document.getElementById('markEntityPreview').textContent = '"' + text + '"';
- // 重置选择
- document.querySelectorAll('.mark-entity-type').forEach(el => el.classList.remove('selected'));
- document.querySelector('.mark-entity-type').classList.add('selected');
- selectedEntityType = 'entity';
- document.getElementById('markEntityModal').classList.add('show');
- }
- function closeMarkEntityModal() {
- document.getElementById('markEntityModal').classList.remove('show');
- }
- function selectEntityType(el, type) {
- document.querySelectorAll('.mark-entity-type').forEach(t => t.classList.remove('selected'));
- el.classList.add('selected');
- selectedEntityType = type;
- }
- function confirmMarkEntity() {
- if (selectedRange && selectedText) {
- // 创建标签元素
- const selection = window.getSelection();
- selection.removeAllRanges();
- selection.addRange(selectedRange);
-
- // 获取类型图标和颜色类名
- const typeInfo = {
- entity: { icon: '🏢', class: 'entity' },
- concept: { icon: '💡', class: 'concept' },
- data: { icon: '📊', class: 'data' },
- location: { icon: '📍', class: 'location' }
- };
- const info = typeInfo[selectedEntityType] || typeInfo.entity;
-
- // 包装为高亮标签 - 带类型class
- const span = document.createElement('span');
- span.className = 'entity-highlight ' + info.class;
- span.setAttribute('contenteditable', 'false');
- span.setAttribute('onclick', `showEntityEditModal(event, 'new_${Date.now()}')`);
- span.textContent = selectedText;
-
- // 替换选中内容
- selectedRange.deleteContents();
- selectedRange.insertNode(span);
-
- // 添加到右侧要素列表
- addToElementTags(selectedText, selectedEntityType, info.icon);
-
- // 动态添加到entityEditData
- const newId = 'new_' + Date.now();
- entityEditData[newId] = {
- icon: info.icon,
- name: selectedText,
- type: selectedEntityType,
- typeText: { entity: '核心实体', concept: '概念/技术', data: '数据/指标', location: '地点/组织' }[selectedEntityType],
- source: '用户标记',
- originalValue: selectedText,
- relations: []
- };
-
- showToast('✓ 已标记为要素: ' + selectedText, 'success');
- }
- closeMarkEntityModal();
- }
- // 添加到右侧要素标签列表
- function addToElementTags(name, type, icon) {
- const container = document.getElementById('elementTagsWrap') || document.querySelector('.element-tags-wrap');
- if (container) {
- const tag = document.createElement('span');
- tag.className = 'element-tag ' + type;
- tag.setAttribute('draggable', 'true');
- tag.innerHTML = `<span class="tag-icon">${icon}</span><span class="tag-name">${name}</span>`;
- container.appendChild(tag);
- }
- }
- // 引用到AI助手
- function quoteToAiAssistant(text) {
- const aiMessages = document.getElementById('aiMessages');
- const quotedText = text.length > 50 ? text.substring(0, 50) + '...' : text;
- aiMessages.innerHTML += `
- <div class="msg user">
- <div class="msg-avatar">张</div>
- <div class="msg-bubble">
- <div style="padding:8px;background:rgba(255,255,255,0.5);border-radius:6px;margin-bottom:8px;font-size:12px;border-left:3px solid rgba(255,255,255,0.8);">
- 📝 引用: "${quotedText}"
- </div>
- 请基于这段内容帮我分析
- </div>
- </div>
- `;
- aiMessages.scrollTop = aiMessages.scrollHeight;
- showToast('已引用到AI助手', 'success');
-
- setTimeout(() => {
- aiMessages.innerHTML += `
- <div class="msg ai">
- <div class="msg-avatar">🤖</div>
- <div class="msg-bubble">好的,我已收到您引用的内容。这段文字主要描述了相关业务内容,我可以帮您:<br><br>1. 深入分析其含义<br>2. 扩展补充相关信息<br>3. 检查数据准确性<br><br>请问您需要哪方面的帮助?</div>
- </div>
- `;
- aiMessages.scrollTop = aiMessages.scrollHeight;
- }, 1200);
- }
- // 点击其他地方关闭右键菜单
- document.addEventListener('click', function(e) {
- if (!e.target.closest('.context-menu')) {
- hideContextMenu();
- }
- });
- // 点击弹窗外部关闭
- document.getElementById('aiConfirmModal')?.addEventListener('click', function(e) {
- if (e.target === this) closeAiConfirmModal();
- });
- document.getElementById('markEntityModal')?.addEventListener('click', function(e) {
- if (e.target === this) closeMarkEntityModal();
- });
- // === 实体标签编辑弹窗 ===
- const entityEditData = {
- smartpark: {
- icon: '🏢', name: '智慧园区', type: 'entity', typeText: '核心实体',
- source: '项目可行性研究报告.docx', originalValue: '智慧园区',
- relations: ['产业升级', '城市现代化', '智能化管理', '1,789亿元']
- },
- upgrade: {
- icon: '📈', name: '产业升级', type: 'concept', typeText: '概念',
- source: '项目可行性研究报告.docx', originalValue: '产业升级',
- relations: ['智慧园区', '城市现代化']
- },
- modern: {
- icon: '🌆', name: '城市现代化', type: 'concept', typeText: '概念',
- source: '项目可行性研究报告.docx', originalValue: '城市现代化',
- relations: ['智慧园区', '产业升级']
- },
- ai: {
- icon: '🤖', name: '智能化管理', type: 'concept', typeText: '技术',
- source: '技术方案说明.pdf', originalValue: '智能化管理',
- relations: ['智慧园区', '低碳绿色']
- },
- green: {
- icon: '🌱', name: '低碳绿色', type: 'concept', typeText: '概念',
- source: '项目可行性研究报告.docx', originalValue: '低碳绿色',
- relations: ['智慧园区']
- },
- location: {
- icon: '📍', name: '华南地区', type: 'location', typeText: '地点',
- source: '项目可行性研究报告.docx', originalValue: '华南地区',
- relations: ['智慧园区', '50万平方米', '12.5亿元']
- },
- data1: {
- icon: '💰', name: '1,789亿元', type: 'data', typeText: '市场规模',
- source: '市场调研数据.pdf', originalValue: '1,789亿元',
- relations: ['智慧园区', '18%', '2024年']
- },
- data2: {
- icon: '📊', name: '18%', type: 'data', typeText: '增长率',
- source: '市场调研数据.pdf', originalValue: '18%',
- relations: ['1,789亿元', '市场规模']
- },
- data3: {
- icon: '💵', name: '12.5亿元', type: 'data', typeText: '总投资额',
- source: '财务预测表.xlsx', originalValue: '12.5亿元',
- relations: ['华南地区', '智慧园区']
- },
- data4: {
- icon: '📐', name: '50万平方米', type: 'data', typeText: '规划面积',
- source: '项目可行性研究报告.docx', originalValue: '50万平方米',
- relations: ['华南地区']
- },
- manufacture: {
- icon: '🏭', name: '智能制造产业集群', type: 'concept', typeText: '产业',
- source: '项目可行性研究报告.docx', originalValue: '智能制造产业集群',
- relations: ['智慧园区', '数字服务中心']
- },
- digital: {
- icon: '💻', name: '数字服务中心', type: 'concept', typeText: '设施',
- source: '项目可行性研究报告.docx', originalValue: '数字服务中心',
- relations: ['智慧园区', '智能制造产业集群']
- }
- };
- let currentEditEntityId = null;
- function showEntityEditModal(event, entityId) {
- event.preventDefault();
- event.stopPropagation();
-
- const data = entityEditData[entityId];
- if (!data) return;
- currentEditEntityId = entityId;
- // 更新弹窗内容
- document.getElementById('editEntityIcon').textContent = data.icon;
- document.getElementById('editEntityName').textContent = data.name;
- document.getElementById('editEntityType').textContent = data.typeText + ' · 来自 ' + data.source;
- document.getElementById('editEntityValue').value = data.name;
- document.getElementById('editEntityCategory').value = data.type;
- // 更新数据关系表
- const tableBody = document.getElementById('entityRelationBody');
- tableBody.innerHTML = `
- <tr>
- <td>标签名称</td>
- <td class="original">${data.originalValue}</td>
- <td class="current"><span class="editable">${data.name}</span></td>
- </tr>
- <tr>
- <td>实体类型</td>
- <td class="original">${data.typeText}</td>
- <td class="current">${data.typeText}</td>
- </tr>
- <tr>
- <td>数据来源</td>
- <td class="original">${data.source}</td>
- <td class="current">${data.source}</td>
- </tr>
- <tr>
- <td>出现次数</td>
- <td class="original">-</td>
- <td class="current">${Math.floor(Math.random() * 5) + 1} 次</td>
- </tr>
- `;
- // 更新关联要素
- const relationsEl = document.getElementById('editEntityRelations');
- relationsEl.innerHTML = data.relations.map(r =>
- `<span class="popover-relation" onclick="showToast('跳转到: ${r}', 'info')">${r}</span>`
- ).join('') + `<span style="padding:3px 8px;background:var(--primary-light);border-radius:4px;font-size:11px;color:var(--primary);cursor:pointer;" onclick="showToast('添加关联', 'info')">+ 添加</span>`;
- // 显示弹窗
- document.getElementById('entityEditModal').classList.add('show');
- }
- function closeEntityEditModal() {
- document.getElementById('entityEditModal').classList.remove('show');
- currentEditEntityId = null;
- }
- function saveEntityEdit() {
- const newValue = document.getElementById('editEntityValue').value;
- const newCategory = document.getElementById('editEntityCategory').value;
-
- if (currentEditEntityId && entityEditData[currentEditEntityId]) {
- entityEditData[currentEditEntityId].name = newValue;
- entityEditData[currentEditEntityId].type = newCategory;
- showToast('✓ 标签已更新: ' + newValue, 'success');
- }
-
- closeEntityEditModal();
- }
- // 点击弹窗外部关闭
- document.getElementById('entityEditModal')?.addEventListener('click', function(e) {
- if (e.target === this) closeEntityEditModal();
- });
- // === AI对话 ===
- function handleAiKey(e) {
- if (e.key === 'Enter' && !e.shiftKey) {
- e.preventDefault();
- sendAiMsg();
- }
- }
- function autoResizeTextarea(el) {
- el.style.height = 'auto';
- el.style.height = Math.min(el.scrollHeight, 100) + 'px';
- }
- function sendAiMsg() {
- const textarea = document.getElementById('aiTextarea');
- const msg = textarea.value.trim();
- if (!msg) return;
- const container = document.getElementById('aiMessages');
- container.innerHTML += '<div class="msg user"><div class="msg-avatar">张</div><div class="msg-bubble">' + msg + '</div></div>';
- textarea.value = '';
- textarea.style.height = 'auto';
- container.scrollTop = container.scrollHeight;
- setTimeout(() => {
- container.innerHTML += '<div class="msg ai"><div class="msg-avatar">🤖</div><div class="msg-bubble">好的,我来帮您处理这个请求。基于已解析的文档,我找到了相关内容可以补充到报告中。</div></div>';
- container.scrollTop = container.scrollHeight;
- }, 1000);
- }
- // === 知识图谱弹窗 ===
- function showGraphModal() {
- document.getElementById('graphModal').classList.add('show');
- showToast('已加载标记要素关系图谱', 'info');
- }
- function closeGraphModal() {
- document.getElementById('graphModal').classList.remove('show');
- }
- // 图谱/列表视图切换
- function switchGraphView(view) {
- const graphBtn = document.getElementById('graphViewBtn');
- const listBtn = document.getElementById('listViewBtn');
- const graphBody = document.getElementById('graphViewBody');
- const listBody = document.getElementById('listViewBody');
- if (view === 'graph') {
- graphBtn.classList.add('active');
- listBtn.classList.remove('active');
- graphBody.style.display = 'block';
- listBody.style.display = 'none';
- } else {
- graphBtn.classList.remove('active');
- listBtn.classList.add('active');
- graphBody.style.display = 'none';
- listBody.style.display = 'flex';
- }
- }
- // 列表类型筛选
- function filterListType(el, type) {
- document.querySelectorAll('.list-filter-tag').forEach(t => t.classList.remove('active'));
- el.classList.add('active');
- showToast('筛选: ' + el.textContent, 'info');
- }
- // 点击弹窗外部关闭
- document.getElementById('graphModal')?.addEventListener('click', function(e) {
- if (e.target === this) closeGraphModal();
- });
- // === 导出菜单 ===
- function showExportMenu(btn) {
- const menu = document.getElementById('exportMenu');
- const rect = btn.getBoundingClientRect();
- menu.style.top = (rect.bottom + 8) + 'px';
- menu.style.right = (window.innerWidth - rect.right) + 'px';
- menu.style.display = 'block';
- }
- function hideExportMenu() {
- document.getElementById('exportMenu').style.display = 'none';
- }
- document.addEventListener('click', function(e) {
- if (!e.target.closest('[onclick*="showExportMenu"]') && !e.target.closest('#exportMenu')) {
- hideExportMenu();
- }
- });
- // === 视图切换 ===
- function switchView(view) {
- const originalBtn = document.getElementById('viewOriginal');
- const markedBtn = document.getElementById('viewMarked');
- const originalContent = document.getElementById('contentOriginal');
- const markedContent = document.getElementById('contentMarked');
- if (view === 'original') {
- originalBtn.classList.add('active');
- markedBtn.classList.remove('active');
- originalContent.style.display = 'block';
- markedContent.style.display = 'none';
- showToast('已切换到原文视图', 'info');
- } else {
- originalBtn.classList.remove('active');
- markedBtn.classList.add('active');
- originalContent.style.display = 'none';
- markedContent.style.display = 'block';
- showToast('已切换到标记视图 - 显示AI提取的实体标记', 'info');
- }
- }
- // === 文件高亮 ===
- function highlightFile(el) {
- document.querySelectorAll('.file-item').forEach(f => f.classList.remove('active'));
- el.classList.add('active');
- }
- // === 上传模拟 ===
- function simulateUpload() {
- showToast('请选择要上传的文件', 'info');
- }
- // === 实体信息 ===
- function showEntityInfo(entity) {
- showToast('实体: ' + entity, 'info');
- }
- // === AI建议 ===
- function acceptSuggestion() {
- showToast('✓ 已采纳建议,内容已更新', 'success');
- const card = document.getElementById('aiSuggestionCard');
- if (card) card.style.display = 'none';
- }
- function ignoreSuggestion() {
- showToast('已忽略建议', 'info');
- const card = document.getElementById('aiSuggestionCard');
- if (card) card.style.display = 'none';
- }
- function acceptContentSuggestion() {
- showToast('✓ 已添加竞争格局分析章节', 'success');
- }
- // === AI Tab切换 ===
- function switchAiTab(el, tab) {
- document.querySelectorAll('.ai-tab').forEach(t => t.classList.remove('active'));
- el.classList.add('active');
- showToast('切换到 ' + el.textContent.trim(), 'info');
- }
- function acceptContentSuggestion() {
- showToast('✓ 已添加竞争格局分析章节', 'success');
- }
- // === Toast ===
- function showToast(msg, type) {
- const box = document.getElementById('toastBox');
- const icons = { success: '✅', error: '❌', info: 'ℹ️' };
- const colors = { success: '#f6ffed', error: '#fff1f0', info: 'var(--primary-light)' };
- const textColors = { success: 'var(--success)', error: 'var(--danger)', info: 'var(--primary)' };
- const toast = document.createElement('div');
- toast.style.cssText = 'display:flex;align-items:center;gap:10px;padding:12px 18px;background:var(--white);border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,0.15);transform:translateX(120%);transition:transform 0.3s;min-width:240px;';
- toast.innerHTML = '<span style="width:24px;height:24px;border-radius:50%;background:' + colors[type] + ';color:' + textColors[type] + ';display:flex;align-items:center;justify-content:center;font-size:12px;">' + icons[type] + '</span><span style="font-size:13px;">' + msg + '</span>';
- box.appendChild(toast);
- setTimeout(() => toast.style.transform = 'translateX(0)', 10);
- setTimeout(() => {
- toast.style.transform = 'translateX(120%)';
- setTimeout(() => toast.remove(), 300);
- }, 3000);
- }
- // === 关闭所有 ===
- function closeAll() {
- document.getElementById('notifPanel').style.transform = 'translateX(100%)';
- document.getElementById('overlay').style.display = 'none';
- document.getElementById('fabPanel').style.display = 'none';
- }
- // === 初始化 ===
- setTimeout(() => showToast('欢迎使用灵越智报平台 🎉', 'success'), 500);
- // 更新欢迎语
- (function() {
- const hour = new Date().getHours();
- let greeting = '早上好';
- if (hour >= 12 && hour < 18) greeting = '下午好';
- else if (hour >= 18) greeting = '晚上好';
- const el = document.querySelector('.welcome h1');
- if (el) el.innerHTML = greeting + ',张三!<span>智能报告,洞察未来。</span>';
- })();
- // 模拟解析进度
- let progress1 = 65;
- setInterval(() => {
- progress1 += Math.random() * 3;
- if (progress1 >= 100) {
- progress1 = 100;
- const el = document.querySelector('#parsingFile1 .file-status');
- if (el) {
- el.textContent = '✓ 已完成';
- el.className = 'file-status done';
- }
- } else {
- const el = document.querySelector('#parsingFile1 .file-status');
- if (el && el.classList.contains('parsing')) {
- el.textContent = '📊 解析中 ' + Math.floor(progress1) + '%';
- }
- }
- }, 2000);
- </script>
- </body>
- </html>
|