zen-gitsync 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,10 +5,10 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Zen-GitSync - Git同步工具</title>
8
- <script type="module" crossorigin src="/assets/index-DBck3u67.js"></script>
9
- <link rel="modulepreload" crossorigin href="/assets/vendor-CdJ34PvS.js">
8
+ <script type="module" crossorigin src="/assets/index-CALk9kKc.js"></script>
9
+ <link rel="modulepreload" crossorigin href="/assets/vendor-BfXVsoKv.js">
10
10
  <link rel="stylesheet" crossorigin href="/assets/vendor-Dp0FkvMe.css">
11
- <link rel="stylesheet" crossorigin href="/assets/index-D5irnfho.css">
11
+ <link rel="stylesheet" crossorigin href="/assets/index-D3zIiSNw.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="app"></div>
@@ -156,10 +156,10 @@ async function startUIServer() {
156
156
  // 获取Git用户配置信息
157
157
  app.get('/api/user-info', async (req, res) => {
158
158
  try {
159
- // 获取用户名
160
- const { stdout: userName } = await execGitCommand('git config user.name');
161
- // 获取用户邮箱
162
- const { stdout: userEmail } = await execGitCommand('git config user.email');
159
+ // 获取全局用户名
160
+ const { stdout: userName } = await execGitCommand('git config --global user.name');
161
+ // 获取全局用户邮箱
162
+ const { stdout: userEmail } = await execGitCommand('git config --global user.email');
163
163
 
164
164
  res.json({
165
165
  name: userName.trim(),
@@ -630,6 +630,90 @@ async function startUIServer() {
630
630
  }
631
631
  });
632
632
 
633
+ // 添加清理Git锁定文件的接口
634
+ app.post('/api/remove-lock', async (req, res) => {
635
+ try {
636
+ const gitDir = path.join(process.cwd(), '.git')
637
+ const indexLockFile = path.join(gitDir, 'index.lock')
638
+
639
+ // 检查文件是否存在
640
+ try {
641
+ await fs.access(indexLockFile)
642
+ // 如果文件存在,尝试删除它
643
+ await fs.unlink(indexLockFile)
644
+ res.json({ success: true, message: '已清理锁定文件' })
645
+ } catch (error) {
646
+ // 如果文件不存在,也返回成功
647
+ if (error.code === 'ENOENT') {
648
+ res.json({ success: true, message: '没有发现锁定文件' })
649
+ } else {
650
+ throw error
651
+ }
652
+ }
653
+ } catch (error) {
654
+ console.error('清理锁定文件失败:', error)
655
+ res.status(500).json({
656
+ success: false,
657
+ error: `清理锁定文件失败: ${error.message}`
658
+ })
659
+ }
660
+ })
661
+
662
+ // 清除Git用户配置
663
+ app.post('/api/clear-user-config', async (req, res) => {
664
+ try {
665
+ // 检查全局配置是否存在,如果存在才删除
666
+ try {
667
+ const { stdout: userName } = await execGitCommand('git config --global user.name');
668
+ if (userName.trim()) {
669
+ await execGitCommand('git config --global --unset user.name');
670
+ }
671
+ } catch (error) {
672
+ console.log('全局用户名配置检查失败,可能不存在:', error.message);
673
+ // 忽略错误继续执行
674
+ }
675
+
676
+ try {
677
+ const { stdout: userEmail } = await execGitCommand('git config --global user.email');
678
+ if (userEmail.trim()) {
679
+ await execGitCommand('git config --global --unset user.email');
680
+ }
681
+ } catch (error) {
682
+ console.log('全局邮箱配置检查失败,可能不存在:', error.message);
683
+ // 忽略错误继续执行
684
+ }
685
+
686
+ res.json({ success: true, message: '已清除全局Git用户配置' });
687
+ } catch (error) {
688
+ res.status(500).json({
689
+ success: false,
690
+ error: `清除全局Git用户配置失败: ${error.message}`
691
+ });
692
+ }
693
+ });
694
+
695
+ // 恢复Git用户配置
696
+ app.post('/api/restore-user-config', async (req, res) => {
697
+ try {
698
+ const { name, email } = req.body;
699
+ if (!name || !email) {
700
+ return res.status(400).json({
701
+ success: false,
702
+ error: '需要提供用户名和邮箱'
703
+ });
704
+ }
705
+
706
+ await execGitCommand(`git config --global user.name "${name}"`);
707
+ await execGitCommand(`git config --global user.email "${email}"`);
708
+ res.json({ success: true, message: '已更新全局Git用户配置' });
709
+ } catch (error) {
710
+ res.status(500).json({
711
+ success: false,
712
+ error: `更新全局Git用户配置失败: ${error.message}`
713
+ });
714
+ }
715
+ });
716
+
633
717
  // Socket.io 实时更新
634
718
  // io.on('connection', (socket) => {
635
719
  // console.log('客户端已连接');
@@ -1 +0,0 @@
1
- .card[data-v-1eb3fdac]{background-color:#fff;border-radius:8px;box-shadow:0 2px 12px #0000001a;padding:20px;margin-bottom:20px}.status-header[data-v-1eb3fdac]{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.status-header h2[data-v-1eb3fdac]{margin:0}.status-box[data-v-1eb3fdac]{white-space:pre-wrap;font-family:monospace;background-color:#f5f7fa;padding:15px;border-radius:4px;margin-bottom:15px;max-height:300px;overflow-y:auto}.file-list[data-v-1eb3fdac]{max-height:300px;overflow-y:auto}.file-item[data-v-1eb3fdac]{padding:8px 12px;margin-bottom:5px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:space-between}.file-item[data-v-1eb3fdac]:hover{background-color:#f5f7fa}.file-info[data-v-1eb3fdac]{display:flex;align-items:center;flex-grow:1}.file-actions[data-v-1eb3fdac]{margin-left:10px;opacity:.5;transition:opacity .2s}.file-item:hover .file-actions[data-v-1eb3fdac]{opacity:1}.file-type[data-v-1eb3fdac]{font-size:12px;padding:2px 6px;border-radius:10px;margin-right:10px;flex-shrink:0}.added .file-type[data-v-1eb3fdac]{background-color:#e1f3d8;color:#67c23a}.modified .file-type[data-v-1eb3fdac]{background-color:#e6f1fc;color:#409eff}.deleted .file-type[data-v-1eb3fdac]{background-color:#fef0f0;color:#f56c6c}.untracked .file-type[data-v-1eb3fdac]{background-color:#fdf6ec;color:#e6a23c}.file-path[data-v-1eb3fdac]{font-family:monospace;word-break:break-all}.diff-content[data-v-1eb3fdac]{font-family:monospace;white-space:pre-wrap;max-height:60vh;overflow-y:auto;padding:10px;background-color:#f5f7fa;border-radius:4px}.diff-formatted[data-v-1eb3fdac]{font-size:14px;line-height:1.5}.file-navigation[data-v-1eb3fdac]{display:flex;justify-content:center;align-items:center;margin-top:15px}.file-counter[data-v-1eb3fdac]{margin:0 15px;font-size:14px;color:#606266}.current-directory[data-v-1eb3fdac]{display:flex;align-items:center;margin-bottom:15px;padding:8px 12px;background-color:#f5f7fa;border-radius:4px;font-family:monospace}.current-directory .el-icon[data-v-1eb3fdac]{margin-right:8px;color:#409eff}.current-directory span[data-v-1eb3fdac]{flex-grow:1;word-break:break-all;margin-right:10px}.browser-current-path[data-v-1eb3fdac]{margin-bottom:10px;font-size:14px;color:#606266;background-color:#f5f7fa;padding:8px 12px;border-radius:4px;font-family:monospace;word-break:break-all}.browser-error[data-v-1eb3fdac]{margin-bottom:10px;color:#f56c6c;padding:8px 12px;background-color:#fef0f0;border-radius:4px}.directory-browser[data-v-1eb3fdac]{padding:10px;max-height:400px;overflow-y:auto}.browser-nav[data-v-1eb3fdac]{margin-bottom:10px;display:flex;justify-content:space-between}.directory-items[data-v-1eb3fdac]{list-style:none;padding:0;margin:0}.directory-item[data-v-1eb3fdac]{padding:8px 12px;margin-bottom:5px;border-radius:4px;cursor:pointer;display:flex;align-items:center}.directory-item[data-v-1eb3fdac]:hover{background-color:#f5f7fa}.directory-item.directory[data-v-1eb3fdac]{color:#409eff}.directory-item.file[data-v-1eb3fdac]{color:#606266}.directory-item .el-icon[data-v-1eb3fdac]{margin-right:10px}.directory-item span[data-v-1eb3fdac]{font-family:monospace;word-break:break-all}.directory-buttons[data-v-1eb3fdac]{display:flex;gap:10px;margin-top:10px}.no-padding-left[data-v-1eb3fdac]{padding-left:8px!important}.diff-header{font-weight:700;background-color:#e6f1fc;padding:3px;margin:5px 0}.diff-old-file,.diff-new-file{color:#888}.diff-hunk-header{color:#6f42c1}.diff-added{background-color:#e6ffed;color:#28a745}.diff-removed{background-color:#ffeef0;color:#d73a49}.diff-context{color:#444}.card[data-v-34334c1f]{background-color:#fff;border-radius:5px;box-shadow:0 2px 5px #0000001a;margin-bottom:20px;padding:20px}.commit-form[data-v-34334c1f]{display:flex;margin-bottom:15px;gap:10px}.git-actions[data-v-34334c1f]{margin-top:20px;display:flex;flex-direction:column;gap:10px}.action-row[data-v-34334c1f]{display:flex;gap:10px;flex-wrap:wrap}.standard-commit-form[data-v-34334c1f]{display:flex;flex-direction:column;gap:15px;margin-bottom:15px}.standard-commit-header[data-v-34334c1f]{display:flex;gap:10px;width:100%}.type-select[data-v-34334c1f]{width:120px;flex-shrink:0}.scope-container[data-v-34334c1f]{display:flex;align-items:center;gap:5px;flex-grow:0;width:200px}.scope-input[data-v-34334c1f]{flex-grow:1}.description-container[data-v-34334c1f]{display:flex;align-items:center;gap:5px;flex-grow:1}.description-input[data-v-34334c1f]{flex-grow:1;min-width:200px}.settings-button[data-v-34334c1f]{flex-shrink:0}.preview-section[data-v-34334c1f]{background-color:#f5f7fa;padding:10px;border-radius:4px}.preview-title[data-v-34334c1f]{font-weight:700;margin-bottom:5px}.preview-content[data-v-34334c1f]{white-space:pre-wrap;font-family:monospace;margin:0;padding:10px;background-color:#ebeef5;border-radius:4px}.template-container[data-v-34334c1f]{display:flex;flex-direction:column;height:calc(85vh - 100px);overflow-y:auto}.template-form[data-v-34334c1f]{margin-bottom:20px}.template-list[data-v-34334c1f]{flex:1;overflow-y:auto}.template-input[data-v-34334c1f]{flex-grow:1}.template-list[data-v-34334c1f]{overflow-y:auto;height:100%}.template-item[data-v-34334c1f]{margin-bottom:10px}.template-item[data-v-34334c1f]:hover{background-color:#f5f7fa}.template-content[data-v-34334c1f]{flex-grow:1;margin-right:10px;word-break:break-all}.template-actions[data-v-34334c1f]{display:flex;gap:5px;justify-content:flex-end;min-width:120px;flex-shrink:0}.options-row[data-v-34334c1f]{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px}.code-command[data-v-34334c1f]{background-color:#2d2d2d;color:#f8f8f2;font-family:Courier New,Courier,monospace;padding:10px;border-radius:4px;overflow-x:auto;white-space:pre;font-size:14px}@media (max-width: 768px){.action-row[data-v-34334c1f]{flex-direction:column}}.log-header[data-v-45e00b57]{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.log-actions[data-v-45e00b57]{display:flex;gap:8px}.branch-container[data-v-45e00b57]{display:flex;flex-wrap:wrap;gap:4px}.branch-tag[data-v-45e00b57]{margin-right:4px}.commit-count[data-v-45e00b57]{margin-bottom:10px;font-size:14px;color:#606266;text-align:right}.graph-container[data-v-45e00b57]{width:100%;height:600px;overflow:auto;border:1px solid #ebeef5;border-radius:4px;padding:10px;background-color:#fff;position:relative}.graph-container svg[data-v-45e00b57]{transform-origin:top left;transition:transform .2s ease}.graph-view[data-v-45e00b57]{width:100%}.graph-controls[data-v-45e00b57]{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.zoom-controls[data-v-45e00b57]{display:flex;gap:8px}.zoom-slider[data-v-45e00b57]{width:200px}.scale-info[data-v-45e00b57]{font-size:14px;color:#606266}body{font-family:Arial,sans-serif;margin:0;padding:0;background-color:#f5f5f5}.container{margin:0 auto;padding:20px 30px}.main-header{background-color:#24292e;color:#fff;padding:15px 20px;display:flex;justify-content:space-between;align-items:center}.header-left{display:flex;align-items:center;gap:10px}.logo{height:32px;width:auto}h1{margin:0;font-size:24px}.header-info{display:flex;flex-direction:column;align-items:flex-end;gap:5px}#branch-info,#user-info{background-color:#ffffff1a;padding:4px 8px;border-radius:4px;font-size:14px}.branch-label,.user-label,.user-name{font-weight:700;margin-right:5px}.user-email{color:#e0e0e0}.branch-name{font-family:monospace}.card{background-color:#fff;border-radius:5px;box-shadow:0 2px 5px #0000001a;margin-bottom:20px;padding:20px}.status-box{background-color:#f6f8fa;border:1px solid #e1e4e8;border-radius:3px;padding:15px;white-space:pre-wrap;font-family:monospace;max-height:300px;overflow-y:auto}.layout-container{display:flex;gap:20px}.left-panel{flex:0 0 30%;max-width:30%}.right-panel{flex:0 0 70%;max-width:70%}@media (max-width: 768px){.layout-container{flex-direction:column}.left-panel,.right-panel{flex:0 0 100%;max-width:100%}.header-left{gap:8px}.logo{height:24px}h1{font-size:20px}}.commit-form{display:flex;margin-bottom:15px}.log-item{padding:10px 0;border-bottom:1px solid #eee}.log-item:last-child{border-bottom:none}.log-hash{color:#6f42c1;font-family:monospace}.log-author,.log-date{color:#6a737d}.log-message{font-weight:700}.log-branch{display:inline-block;background-color:#0366d6;color:#fff;border-radius:3px;padding:2px 6px;margin-left:8px;font-size:12px}.branch-select{width:150px;margin-left:5px}.branch-select :deep(.el-input__inner){background-color:#ffffff1a;color:#fff;border:none}.branch-select :deep(.el-input__suffix){color:#fff}.tips{margin-top:20px;padding:15px;background-color:#f5f7fa;border-radius:5px;border-left:4px solid #409eff}.tips h3{margin-top:0;font-size:16px;margin-bottom:10px}.code-block{background-color:#2d2d2d;color:#f8f8f2;font-family:monospace;padding:10px 15px;border-radius:4px;margin-bottom:10px}.loading-container{display:flex;justify-content:center;align-items:center;min-height:400px}.loading-card{width:300px;text-align:center;padding:30px}.loading-spinner{font-size:48px;margin-bottom:20px;color:#409eff}.loading-text{font-size:18px;color:#606266}.logo[data-v-7161cf53]{will-change:filter;transition:filter .3s}.logo[data-v-7161cf53]:hover{filter:drop-shadow(0 0 2em #42b883aa)}.main-footer[data-v-7161cf53]{background-color:#24292e;color:#fff;padding:10px 20px;display:flex;justify-content:space-between;align-items:center;position:fixed;bottom:0;left:0;right:0;z-index:100}.branch-info[data-v-7161cf53]{display:flex;align-items:center}.footer-right[data-v-7161cf53]{color:#ffffffb3;font-size:12px}
@@ -1,8 +0,0 @@
1
- import{d as He,r,E as o,a as _e,c as he,o as we,b as T,e as f,f as l,g as te,h as s,i as Je,w as c,u as d,j as De,t as R,k as se,l as x,m as We,F as ae,n as le,p as Le,q as Ze,s as qe,v as Ae,x as xe,y as ct,z as Ue,A as ee,B as ut,C as Ke,D as dt,G as pt,H as ft,I as Qe,J as Xe,K as Re,L as ze,M as mt,N as Ye,O as et,P as Ie,Q as tt,R as vt,S as gt,T as yt,U as st,V as ht,W as Fe,X as _t,Y as wt,Z as $t,_ as pe,$ as Ct,a0 as kt,a1 as bt,a2 as St,a3 as Tt}from"./vendor-CdJ34PvS.js";(function(){const I=document.createElement("link").relList;if(I&&I.supports&&I.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))V(t);new MutationObserver(t=>{for(const y of t)if(y.type==="childList")for(const k of y.addedNodes)k.tagName==="LINK"&&k.rel==="modulepreload"&&V(k)}).observe(document,{childList:!0,subtree:!0});function m(t){const y={};return t.integrity&&(y.integrity=t.integrity),t.referrerPolicy&&(y.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?y.credentials="include":t.crossOrigin==="anonymous"?y.credentials="omit":y.credentials="same-origin",y}function V(t){if(t.ep)return;t.ep=!0;const y=m(t);fetch(t.href,y)}})();const ie=He("git",()=>{const P=r(""),I=r([]),m=r(""),V=r(""),t=r(!1),y=r(!1),k=r(!1),_=r(0);async function N(){const g=Date.now();if(g-_.value<1e3)return console.log("使用缓存的Git仓库状态:",k.value?"是":"不是"),k.value;try{const D=await(await fetch("/api/current_directory")).json();return k.value=D.isGitRepo===!0,_.value=g,console.log(`当前目录${k.value?"是":"不是"}Git仓库`),k.value}catch(h){return console.error("检查Git仓库状态失败:",h),k.value=!1,_.value=g,!1}}async function A(){try{const h=await(await fetch("/api/branch")).json();h.branch&&(P.value=h.branch)}catch(g){console.error("获取分支信息失败:",g)}}async function E(){try{const h=await(await fetch("/api/branches")).json();h.branches&&Array.isArray(h.branches)&&(I.value=h.branches)}catch(g){console.error("获取所有分支信息失败:",g)}}async function M(g){console.log("切换到分支:",g);try{t.value=!0;const D=await(await fetch("/api/checkout",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({branch:g})})).json();return D.success?(o({message:`已切换到分支: ${g}`,type:"success"}),A(),!0):(o({message:`切换分支失败: ${D.error}`,type:"error"}),!1)}catch(h){return o({message:`切换分支失败: ${h.message}`,type:"error"}),!1}finally{t.value=!1}}async function b(){try{const h=await(await fetch("/api/user-info")).json();h.name&&h.email&&(m.value=h.name,V.value=h.email)}catch(g){console.error("获取用户信息失败:",g)}}async function S(g,h){if(!g.trim())return o({message:"分支名称不能为空",type:"warning"}),!1;try{y.value=!0;const i=await(await fetch("/api/create-branch",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({newBranchName:g,baseBranch:h||P.value})})).json();return i.success?(o({message:`已创建并切换到分支: ${g}`,type:"success"}),A(),E(),!0):(o({message:`创建分支失败: ${i.error}`,type:"error"}),!1)}catch(D){return o({message:`创建分支失败: ${D.message}`,type:"error"}),!1}finally{y.value=!1}}async function z(){await N()?(A(),E(),b()):(P.value="",I.value=[],m.value="",V.value="")}return{currentBranch:P,allBranches:I,userName:m,userEmail:V,isChangingBranch:t,isCreatingBranch:y,isGitRepo:k,lastCheckedTime:_,checkGitRepo:N,getCurrentBranch:A,getAllBranches:E,changeBranch:M,getUserInfo:b,createBranch:S,loadInitialData:z}}),Ee=He("gitLog",()=>{const P=ie(),I=r([]),m=r({staged:[],unstaged:[],untracked:[]}),V=r(!1),t=r(!1),y=r(!1),k=r(!1);async function _(){if(!P.isGitRepo){console.log("当前目录不是Git仓库,跳过加载提交历史");return}try{V.value=!0,console.log("开始加载提交历史...");const a=await(await fetch("/api/log")).json();a.log&&Array.isArray(a.log)&&(I.value=a.log),console.log(`提交历史加载完成,共 ${I.value.length} 条记录`)}catch(i){console.error("获取提交历史失败:",i),o({message:`获取提交历史失败: ${i.message}`,type:"error"})}finally{V.value=!1}}async function N(){if(!P.isGitRepo){console.log("当前目录不是Git仓库,跳过加载Git状态");return}try{t.value=!0;const a=await(await fetch("/api/status")).json();a.status&&(m.value={staged:a.status.staged||[],unstaged:a.status.unstaged||[],untracked:a.status.untracked||[]})}catch(i){console.error("获取Git状态失败:",i),o({message:`获取Git状态失败: ${i.message}`,type:"error"})}finally{t.value=!1}}async function A(){if(!P.isGitRepo)return o.warning("当前目录不是Git仓库"),!1;try{y.value=!0;const a=await(await fetch("/api/add",{method:"POST"})).json();return a.success?(o({message:"文件已添加到暂存区",type:"success"}),N(),!0):(o({message:`添加文件失败: ${a.error}`,type:"error"}),!1)}catch(i){return o({message:`添加文件失败: ${i.message}`,type:"error"}),!1}finally{y.value=!1}}async function E(i,a=!1){if(!P.isGitRepo)return o.warning("当前目录不是Git仓库"),!1;try{const q=await(await fetch("/api/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:i,hasNewlines:i.includes(`
2
- `),noVerify:a})})).json();return q.success?(o({message:"提交成功",type:"success"}),N(),_(),!0):(o({message:`提交失败: ${q.error}`,type:"error"}),!1)}catch(w){return o({message:`提交失败: ${w.message}`,type:"error"}),!1}}async function M(){if(!P.isGitRepo)return o.warning("当前目录不是Git仓库"),!1;try{const a=await(await fetch("/api/push",{method:"POST"})).json();return a.success?(o({message:"推送成功",type:"success"}),_(),!0):(o({message:`推送失败: ${a.error}`,type:"error"}),!1)}catch(i){return o({message:`推送失败: ${i.message}`,type:"error"}),!1}}async function b(i,a=!1){try{return await A()?await E(i,a):!1}catch(w){return o({message:`暂存并提交失败: ${w.message}`,type:"error"}),!1}}async function S(i,a=!1){try{if(!await b(i,a))return!1;const q=await M();return q&&setTimeout(()=>{console.log("刷新提交历史..."),_()},300),q}catch(w){return o({message:`暂存、提交并推送失败: ${w.message}`,type:"error"}),!1}}async function z(){if(!P.isGitRepo)return o.warning("当前目录不是Git仓库"),!1;try{k.value=!0;const a=await(await fetch("/api/reset-head",{method:"POST"})).json();return a.success?(o({message:"已重置暂存区",type:"success"}),N(),!0):(o({message:`重置暂存区失败: ${a.error}`,type:"error"}),!1)}catch(i){return o({message:`重置暂存区失败: ${i.message}`,type:"error"}),!1}finally{k.value=!1}}async function g(i){if(!P.isGitRepo)return o.warning("当前目录不是Git仓库"),!1;try{k.value=!0;const w=await(await fetch("/api/reset-to-remote",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({branch:i})})).json();return w.success?(o({message:`已重置分支 ${i} 到远程状态`,type:"success"}),N(),_(),!0):(o({message:`重置分支失败: ${w.error}`,type:"error"}),!1)}catch(a){return o({message:`重置分支失败: ${a.message}`,type:"error"}),!1}finally{k.value=!1}}async function h(i){if(!P.isGitRepo)return o.warning("当前目录不是Git仓库"),!1;try{const w=await(await fetch("/api/stage",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({files:i})})).json();return w.success?(o({message:"暂存文件成功",type:"success"}),N(),!0):(o({message:`暂存文件失败: ${w.error}`,type:"error"}),!1)}catch(a){return o({message:`暂存文件失败: ${a.message}`,type:"error"}),!1}}async function D(i){if(!P.isGitRepo)return o.warning("当前目录不是Git仓库"),!1;try{const w=await(await fetch("/api/unstage",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({files:i})})).json();return w.success?(o({message:"取消暂存成功",type:"success"}),N(),!0):(o({message:`取消暂存失败: ${w.error}`,type:"error"}),!1)}catch(a){return o({message:`取消暂存失败: ${a.message}`,type:"error"}),!1}}return{log:I,status:m,isLoadingLog:V,isLoadingStatus:t,isAddingFiles:y,isResetting:k,fetchLog:_,fetchStatus:N,addToStage:A,commitChanges:E,pushToRemote:M,addAndCommit:b,addCommitAndPush:S,resetHead:z,resetToRemote:g,stageFiles:h,unstageFiles:D}}),Vt={class:"card"},Gt={class:"current-directory"},Bt={class:"status-header"},Dt={class:"status-box"},jt={key:0,class:"file-list"},xt=["onClick"],Rt={class:"file-type"},zt={class:"file-path"},Lt={class:"file-actions"},At={class:"directory-buttons"},Et={class:"browser-current-path"},Ot={key:0,class:"browser-error"},Pt={class:"directory-browser"},Mt={class:"browser-nav"},Nt={class:"directory-items"},Ut=["onClick"],It={class:"diff-content"},Ft=["innerHTML"],Ht={key:1,class:"no-diff"},Jt={class:"file-navigation"},Wt={class:"file-counter"},Zt=_e({__name:"GitStatus",props:{initialDirectory:{type:String,default:""}},setup(P,{expose:I}){const m=P,V=Ee(),t=ie(),y=r("加载中..."),k=he(()=>V.isLoadingStatus),_=r([]),N=r(""),A=r(""),E=r(!1),M=r(!1),b=r(-1),S=r(!1),z=r(""),g=r(!1),h=r(!1),D=r(""),i=r([]),a=r(!1),w=r("");function q(v){if(v===void 0)return;const u=v.split(`
3
- `),O=[];for(const G of u){const J=G.match(/^([ MADRCU\?]{2})\s+(.+)$/);if(J){let Y="";const Q=J[1].trim();Q==="M"||Q==="MM"||Q==="AM"||Q==="RM"?Y="modified":Q==="A"||Q==="AA"?Y="added":Q==="D"||Q==="AD"||Q==="DA"?Y="deleted":Q==="??"?Y="untracked":Y="other",O.push({path:J[2],type:Y})}}_.value=O}const W=r(m.initialDirectory||"");async function K(){try{if(!W.value){const Y=await(await fetch("/api/current_directory")).json();W.value=Y.directory||"未知目录"}if(!t.isGitRepo){y.value="当前目录不是一个Git仓库",_.value=[];return}const u=await(await fetch("/api/status")).json();y.value=u.status;const G=await(await fetch("/api/status_porcelain")).json();q(G.status),o({message:"Git 状态已刷新",type:"success"})}catch(v){y.value="加载状态失败: "+v.message,_.value=[],o({message:"刷新失败: "+v.message,type:"error"})}}function H(v){if(!v)return"";const u=v.split(`
4
- `);function O(G){return G.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}return u.map(G=>{const J=O(G);return G.startsWith("diff --git")?`<div class="diff-header">${J}</div>`:G.startsWith("---")?`<div class="diff-old-file">${J}</div>`:G.startsWith("+++")?`<div class="diff-new-file">${J}</div>`:G.startsWith("@@")?`<div class="diff-hunk-header">${J}</div>`:G.startsWith("+")?`<div class="diff-added">${J}</div>`:G.startsWith("-")?`<div class="diff-removed">${J}</div>`:`<div class="diff-context">${J}</div>`}).join("")}async function p(v){try{M.value=!0,N.value=v,b.value=_.value.findIndex(G=>G.path===v);const O=await(await fetch(`/api/diff?file=${encodeURIComponent(v)}`)).json();A.value=O.diff||"没有变更",E.value=!0}catch(u){o({message:"获取文件差异失败: "+u.message,type:"error"}),A.value="获取差异失败: "+u.message}finally{M.value=!1}}async function B(){if(_.value.length===0||b.value<=0)return;const v=b.value-1,u=_.value[v];await p(u.path)}async function L(){if(_.value.length===0||b.value>=_.value.length-1)return;const v=b.value+1,u=_.value[v];await p(u.path)}function j(){z.value=W.value,S.value=!0}function $(){w.value="",D.value=z.value||W.value,h.value=!0,F(D.value)}async function F(v){try{a.value=!0,w.value="";let u=v;/^[A-Za-z]:$/.test(u)&&(u+="/");const O=await fetch(`/api/browse_directory?path=${encodeURIComponent(u)}`);if(O.status===403){const J=await O.json();w.value=J.error||"目录浏览功能未启用";return}if(!O.ok){const J=await O.json();w.value=J.error||"获取目录内容失败";return}const G=await O.json();G.success?(i.value=G.items,D.value=G.currentPath):w.value=G.error||"获取目录内容失败"}catch(u){w.value=`获取目录内容失败: ${u.message}`}finally{a.value=!1}}function oe(){if(/^[A-Za-z]:$/.test(D.value)||/^[A-Za-z]:[\\/]$/.test(D.value)||D.value==="/")return;let v=D.value.split(/[/\\]/);v.pop();let u=v.join("/");v.length===1&&/^[A-Za-z]:$/.test(v[0])&&(u=v[0]+"/"),u&&F(u)}function Ce(v){v.type==="directory"&&F(v.path)}function ke(){z.value=D.value,h.value=!1}async function be(){if(!z.value){o.warning("目录路径不能为空");return}try{g.value=!0;const u=await(await fetch("/api/change_directory",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:z.value})})).json();u.success?(o.success("已切换工作目录"),W.value=u.directory,S.value=!1,t.isGitRepo=u.isGitRepo,u.isGitRepo?(await Promise.all([t.getCurrentBranch(),t.getAllBranches(),t.getUserInfo()]),await K()):(o.warning("当前目录不是一个Git仓库"),y.value="当前目录不是一个Git仓库",_.value=[],t.$reset())):o.error(u.error||"切换目录失败")}catch(v){o.error(`切换目录失败: ${v.message}`)}finally{g.value=!1}}function Se(v){p(v.path)}function Te(v){switch(v){case"added":return"新增";case"modified":return"修改";case"deleted":return"删除";case"untracked":return"未跟踪";default:return"其他"}}async function me(){await K()}async function Ve(v){try{await Re.confirm(`确定要撤回文件 "${v}" 的所有修改吗?此操作无法撤销。`,"撤回修改",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"});const O=await(await fetch("/api/revert_file",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filePath:v})})).json();O.success?(o.success("已撤回文件修改"),await K()):o.error(O.error||"撤回文件修改失败")}catch(u){u.message!=="cancel"&&o.error(`撤回文件修改失败: ${u.message}`)}}return we(()=>{K()}),I({refreshStatus:me}),(v,u)=>{const O=Je,G=se,J=Xe,Y=Ae,Q=qe,Ge=Ze,ce=Le,ve=Ke;return f(),T("div",Vt,[l("div",Gt,[s(O,null,{default:c(()=>[s(d(De))]),_:1}),l("span",null,R(W.value),1),s(G,{type:"primary",size:"small",onClick:j,plain:""},{default:c(()=>u[4]||(u[4]=[x(" 切换目录 ")])),_:1})]),l("div",Bt,[u[5]||(u[5]=l("h2",null,"Git 状态(git status)",-1)),s(G,{type:"primary",icon:d(We),circle:"",size:"small",onClick:me,loading:k.value},null,8,["icon","loading"])]),l("div",Dt,R(y.value),1),_.value.length?(f(),T("div",jt,[(f(!0),T(ae,null,le(_.value,U=>(f(),T("div",{key:U.path,class:Ue(["file-item",U.type])},[l("div",{class:"file-info",onClick:ge=>Se(U)},[l("span",Rt,R(Te(U.type)),1),l("span",zt,R(U.path),1)],8,xt),l("div",Lt,[s(J,{content:"撤回修改",placement:"top","hide-after":1e3},{default:c(()=>[s(G,{type:"danger",size:"small",icon:d(Qe),circle:"",onClick:ft(ge=>Ve(U.path),["stop"])},null,8,["icon","onClick"])]),_:2},1024)])],2))),128))])):te("",!0),s(ce,{modelValue:S.value,"onUpdate:modelValue":u[1]||(u[1]=U=>S.value=U),title:"切换工作目录",width:"500px"},{default:c(()=>[s(Ge,null,{default:c(()=>[s(Q,{label:"目录路径"},{default:c(()=>[s(Y,{modelValue:z.value,"onUpdate:modelValue":u[0]||(u[0]=U=>z.value=U),placeholder:"请输入目录路径",clearable:""},null,8,["modelValue"]),l("div",At,[s(G,{onClick:$,type:"primary",plain:"",class:"no-padding-left"},{default:c(()=>[s(O,null,{default:c(()=>[s(d(De))]),_:1}),u[6]||(u[6]=x(" 浏览 "))]),_:1}),s(G,{onClick:be,loading:g.value,type:"primary"},{default:c(()=>u[7]||(u[7]=[x(" 切换 ")])),_:1},8,["loading"])])]),_:1})]),_:1})]),_:1},8,["modelValue"]),s(ce,{modelValue:h.value,"onUpdate:modelValue":u[2]||(u[2]=U=>h.value=U),title:"浏览目录",width:"600px"},{default:c(()=>[l("div",Et,[l("span",null,"当前路径: "+R(D.value),1)]),w.value?(f(),T("div",Ot,R(w.value),1)):te("",!0),xe((f(),T("div",Pt,[l("div",Mt,[s(G,{onClick:oe,disabled:!D.value||a.value,size:"small",class:"no-padding-left"},{default:c(()=>[s(O,null,{default:c(()=>[s(d(ct))]),_:1}),u[8]||(u[8]=x(" 上级目录 "))]),_:1},8,["disabled"]),s(G,{onClick:ke,type:"primary",size:"small",class:"no-padding-left"},{default:c(()=>u[9]||(u[9]=[x(" 选择当前目录 ")])),_:1})]),l("ul",Nt,[(f(!0),T(ae,null,le(i.value,U=>(f(),T("li",{key:U.path,class:Ue(["directory-item",U.type]),onClick:ge=>Ce(U)},[U.type==="directory"?(f(),ee(O,{key:0},{default:c(()=>[s(d(De))]),_:1})):(f(),ee(O,{key:1},{default:c(()=>[s(d(ut))]),_:1})),l("span",null,R(U.name),1)],10,Ut))),128))])])),[[ve,a.value]])]),_:1},8,["modelValue"]),s(ce,{modelValue:E.value,"onUpdate:modelValue":u[3]||(u[3]=U=>E.value=U),title:`文件差异: ${N.value}`,width:"80%","destroy-on-close":""},{default:c(()=>[xe((f(),T("div",It,[A.value?(f(),T("div",{key:0,innerHTML:H(A.value),class:"diff-formatted"},null,8,Ft)):(f(),T("div",Ht,"该文件没有差异或是新文件"))])),[[ve,M.value]]),l("div",Jt,[s(G,{icon:d(dt),onClick:B,disabled:b.value<=0||_.value.length===0,circle:""},null,8,["icon","disabled"]),l("span",Wt,R(b.value+1)+" / "+R(_.value.length),1),s(G,{icon:d(pt),onClick:L,disabled:b.value>=_.value.length-1||_.value.length===0,circle:""},null,8,["icon","disabled"])])]),_:1},8,["modelValue","title"])])}}}),$e=(P,I)=>{const m=P.__vccOpts||P;for(const[V,t]of I)m[V]=t;return m},qt=$e(Zt,[["__scopeId","data-v-1eb3fdac"]]),Kt={class:"card"},Qt={class:"commit-options"},Xt={class:"options-row"},Yt={class:"commit-mode-toggle"},es={class:"no-verify-toggle"},ts={key:0,class:"commit-form"},ss={key:1,class:"standard-commit-form"},as={class:"standard-commit-header"},os={class:"scope-container"},ls={class:"description-container"},ns={class:"preview-section"},rs={class:"preview-content"},is={class:"preview-content code-command"},cs={class:"git-actions"},us={class:"action-row"},ds={class:"action-row"},ps={class:"action-row"},fs={class:"template-container"},ms={class:"template-form"},vs={class:"template-form-buttons"},gs={class:"template-list"},ys={class:"template-content"},hs={class:"template-actions"},_s={class:"template-container"},ws={class:"template-form"},$s={class:"template-form-buttons"},Cs={class:"template-list"},ks={class:"template-content"},bs={class:"template-actions"},Ss=_e({__name:"CommitForm",emits:["commit-success","push-success","status-update"],setup(P,{emit:I}){const m=Ee(),V=ie(),t=I,y=r(""),k=r(!1),_=r(!1),N=r("输入提交信息..."),A=r(""),E=r(!1),M=r("feat"),b=r(""),S=r(""),z=r(""),g=r(""),h=r([]),D=r(!1),i=r(""),a=r(!1),w=r(""),q=r(-1),W=r([]),K=r(!1),H=r(""),p=r(!1),B=r(""),L=r(-1),j=r(!1),$=[{value:"feat",label:"feat: 新功能"},{value:"fix",label:"fix: 修复bug"},{value:"docs",label:"docs: 文档修改"},{value:"style",label:"style: 样式修改"},{value:"refactor",label:"refactor: 代码重构"},{value:"test",label:"test: 测试代码"},{value:"chore",label:"chore: 构建/工具修改"}];ze(E,n=>{localStorage.setItem("zen-gitsync-standard-commit",n.toString())}),ze(j,n=>{localStorage.setItem("zen-gitsync-skip-hooks",n.toString())});const F=he(()=>{if(!E.value)return y.value||A.value;let n=`${M.value||""}`;return b.value&&(n+=`(${b.value})`),n+=`: ${S.value}`,z.value&&(n+=`
5
-
6
- ${z.value}`),g.value&&(n+=`
7
-
8
- ${g.value}`),n}),oe=he(()=>{let n=`git commit -m "${F.value}"`;return j.value&&(n+=" --no-verify"),n});async function Ce(){try{const e=await(await fetch("/api/config/getConfig")).json();N.value=`输入提交信息 (默认: ${e.defaultCommitMessage})`,A.value=e.defaultCommitMessage||"",e.descriptionTemplates&&Array.isArray(e.descriptionTemplates)&&(h.value=e.descriptionTemplates),e.scopeTemplates&&Array.isArray(e.scopeTemplates)&&(W.value=e.scopeTemplates)}catch(n){console.error("加载配置失败:",n)}}async function ke(){if(!i.value.trim()){o({message:"请输入模板内容",type:"warning"});return}try{if(a.value)await be();else{if(h.value.includes(i.value)){o({message:"该模板已存在",type:"warning"});return}h.value.push(i.value);const e=await(await fetch("/api/config/save-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:i.value,type:"description"})})).json();e.success?(o({message:"模板保存成功!",type:"success"}),i.value=""):o({message:"模板保存失败: "+e.error,type:"error"})}}catch(n){o({message:"模板保存失败: "+n.message,type:"error"})}}async function be(){try{if(q.value>=0){const n=w.value,e=i.value;h.value[q.value]=e;const X=await(await fetch("/api/config/update-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldTemplate:n,newTemplate:e,type:"description"})})).json();X.success?(o({message:"模板更新成功!",type:"success"}),a.value=!1,w.value="",q.value=-1,i.value=""):o({message:"模板更新失败: "+X.error,type:"error"})}}catch(n){o({message:"模板更新失败: "+n.message,type:"error"})}}function Se(n,e){a.value=!0,w.value=n,q.value=e,i.value=n}function Te(){a.value=!1,w.value="",q.value=-1,i.value=""}async function me(){if(!H.value.trim()){o({message:"请输入模板内容",type:"warning"});return}try{if(p.value)await Ve();else{if(W.value.includes(H.value)){o({message:"该模板已存在",type:"warning"});return}W.value.push(H.value);const e=await(await fetch("/api/config/save-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:H.value,type:"scope"})})).json();e.success?(o({message:"作用域模板保存成功!",type:"success"}),H.value=""):o({message:"作用域模板保存失败: "+e.error,type:"error"})}}catch(n){o({message:"作用域模板保存失败: "+n.message,type:"error"})}}async function Ve(){try{if(L.value>=0){const n=B.value,e=H.value;W.value[L.value]=e;const X=await(await fetch("/api/config/update-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldTemplate:n,newTemplate:e,type:"scope"})})).json();X.success?(o({message:"作用域模板更新成功!",type:"success"}),p.value=!1,B.value="",L.value=-1,H.value=""):o({message:"作用域模板更新失败: "+X.error,type:"error"})}}catch(n){o({message:"作用域模板更新失败: "+n.message,type:"error"})}}function v(n,e){p.value=!0,B.value=n,L.value=e,H.value=n}function u(){p.value=!1,B.value="",L.value=-1,H.value=""}async function O(n){try{const e=h.value.indexOf(n);e!==-1&&h.value.splice(e,1);const X=await(await fetch("/api/config/delete-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:n,type:"description"})})).json();X.success?o({message:"模板删除成功!",type:"success"}):o({message:"模板删除失败: "+X.error,type:"error"})}catch(e){o({message:"模板删除失败: "+e.message,type:"error"})}}async function G(n){try{const e=W.value.indexOf(n);e!==-1&&W.value.splice(e,1);const X=await(await fetch("/api/config/delete-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:n,type:"scope"})})).json();X.success?o({message:"作用域模板删除成功!",type:"success"}):o({message:"作用域模板删除失败: "+X.error,type:"error"})}catch(e){o({message:"作用域模板删除失败: "+e.message,type:"error"})}}function J(n){S.value=n,D.value=!1}function Y(n){b.value=n,K.value=!1}function Q(){D.value=!0}function Ge(){K.value=!0}async function ce(){try{await m.addToStage()&&t("status-update")}catch(n){o({message:`添加文件失败: ${n.message}`,type:"error"})}}async function ve(){if(!F.value.trim()){o({message:"提交信息不能为空",type:"warning"});return}try{await m.commitChanges(F.value,j.value)&&(Be(),t("commit-success"),t("status-update"))}catch(n){o({message:`提交失败: ${n.message}`,type:"error"})}}async function U(){try{k.value=!0,await m.pushToRemote()&&(t("push-success"),t("status-update"))}catch(n){o({message:`推送失败: ${n.message}`,type:"error"})}finally{k.value=!1}}async function ge(){if(!F.value.trim()){o({message:"提交信息不能为空",type:"warning"});return}try{await m.addAndCommit(F.value,j.value)&&(Be(),t("commit-success"),t("status-update"))}catch(n){o({message:`暂存并提交失败: ${n.message}`,type:"error"})}}async function ot(){if(!F.value.trim()){o({message:"提交信息不能为空",type:"warning"});return}try{_.value=!0,await m.addCommitAndPush(F.value,j.value)&&(Be(),t("commit-success"),setTimeout(()=>{t("push-success")},300),t("status-update"))}catch(n){o({message:`暂存、提交并推送失败: ${n.message}`,type:"error"})}finally{_.value=!1}}async function lt(){try{await Re.confirm("确定要重置暂存区吗?这将取消所有已暂存的更改,但不会影响工作区的文件。","重置暂存区",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}),await m.resetHead()&&t("status-update")}catch(n){n!=="cancel"&&o({message:`重置暂存区失败: ${n.message}`,type:"error"})}}async function nt(){try{await Re.confirm(`确定要重置当前分支 "${V.currentBranch}" 到远程状态吗?这将丢失所有未推送的提交和本地更改。`,"重置到远程分支",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}),await m.resetToRemote(V.currentBranch)&&t("status-update")}catch(n){n!=="cancel"&&o({message:`重置到远程分支失败: ${n.message}`,type:"error"})}}function Be(){y.value="",S.value="",z.value="",g.value=""}return we(()=>{Ce();const n=localStorage.getItem("zen-gitsync-standard-commit");n!==null&&(E.value=n==="true");const e=localStorage.getItem("zen-gitsync-skip-hooks");e!==null&&(j.value=e==="true")}),(n,e)=>{const re=mt,X=Xe,ne=Ae,rt=et,it=Ye,Z=se,Oe=yt,Pe=ht,Me=st,Ne=Le;return f(),T("div",Kt,[e[31]||(e[31]=l("h2",null,"提交更改",-1)),l("div",Qt,[l("div",Xt,[l("div",Yt,[s(re,{modelValue:E.value,"onUpdate:modelValue":e[0]||(e[0]=C=>E.value=C),"active-text":"标准化提交","inactive-text":"普通提交"},null,8,["modelValue"])]),l("div",es,[s(X,{content:"跳过 Git 钩子检查 (--no-verify)",placement:"top"},{default:c(()=>[s(re,{modelValue:j.value,"onUpdate:modelValue":e[1]||(e[1]=C=>j.value=C),"active-text":"跳过钩子 (--no-verify)"},null,8,["modelValue"])]),_:1})])])]),E.value?(f(),T("div",ss,[l("div",as,[s(it,{modelValue:M.value,"onUpdate:modelValue":e[3]||(e[3]=C=>M.value=C),placeholder:"提交类型",class:"type-select",clearable:""},{default:c(()=>[(f(),T(ae,null,le($,C=>s(rt,{key:C.value,label:C.label,value:C.value},null,8,["label","value"])),64))]),_:1},8,["modelValue"]),l("div",os,[s(ne,{modelValue:b.value,"onUpdate:modelValue":e[4]||(e[4]=C=>b.value=C),placeholder:"作用域(可选)",class:"scope-input",clearable:""},null,8,["modelValue"]),s(Z,{type:"primary",icon:d(Ie),circle:"",size:"small",class:"settings-button",onClick:Ge},null,8,["icon"])]),l("div",ls,[s(ne,{modelValue:S.value,"onUpdate:modelValue":e[5]||(e[5]=C=>S.value=C),placeholder:"简短描述(必填)",class:"description-input",clearable:""},null,8,["modelValue"]),s(Z,{type:"primary",icon:d(Ie),circle:"",size:"small",class:"settings-button",onClick:Q},null,8,["icon"])])]),s(ne,{modelValue:z.value,"onUpdate:modelValue":e[6]||(e[6]=C=>z.value=C),type:"textarea",rows:4,placeholder:"正文(可选):详细描述本次提交的内容和原因",class:"body-input",clearable:""},null,8,["modelValue"]),s(ne,{modelValue:g.value,"onUpdate:modelValue":e[7]||(e[7]=C=>g.value=C),placeholder:"页脚(可选):如 Closes #123",class:"footer-input",clearable:""},null,8,["modelValue"]),l("div",ns,[e[12]||(e[12]=l("div",{class:"preview-title"},"提交信息预览:",-1)),l("pre",rs,R(F.value),1),e[13]||(e[13]=l("div",{class:"preview-title",style:{"margin-top":"10px"}},"Git命令预览:",-1)),l("pre",is,R(oe.value),1)])])):(f(),T("div",ts,[s(ne,{modelValue:y.value,"onUpdate:modelValue":e[2]||(e[2]=C=>y.value=C),placeholder:N.value,clearable:""},null,8,["modelValue","placeholder"])])),l("div",cs,[l("div",us,[s(Z,{type:"primary",onClick:ce,loading:d(m).isAddingFiles,icon:d(tt)},{default:c(()=>e[14]||(e[14]=[x(" 添加到暂存区(git add .) ")])),_:1},8,["loading","icon"]),s(Z,{type:"primary",onClick:ve,loading:d(m).isLoadingStatus},{default:c(()=>e[15]||(e[15]=[x(" 提交(git commit) ")])),_:1},8,["loading"]),s(Z,{type:"success",onClick:U,icon:d(vt),loading:k.value},{default:c(()=>e[16]||(e[16]=[x(" 推送(git push) ")])),_:1},8,["icon","loading"])]),l("div",ds,[s(Z,{type:"warning",onClick:ge},{default:c(()=>e[17]||(e[17]=[x(" 添加并提交(git add+commit) ")])),_:1}),s(Z,{type:"danger",onClick:ot,loading:_.value},{default:c(()=>e[18]||(e[18]=[x(" 添加、提交并推送(git add+commit+push) ")])),_:1},8,["loading"])]),l("div",ps,[s(Z,{type:"info",onClick:lt,loading:d(m).isResetting,icon:d(We)},{default:c(()=>e[19]||(e[19]=[x(" 重置暂存区(git reset HEAD) ")])),_:1},8,["loading","icon"]),s(Z,{type:"info",onClick:nt,loading:d(m).isResetting,icon:d(gt)},{default:c(()=>e[20]||(e[20]=[x(" 重置到远程(git reset --hard origin/branch) ")])),_:1},8,["loading","icon"])])]),s(Ne,{title:"简短描述模板设置",modelValue:D.value,"onUpdate:modelValue":e[9]||(e[9]=C=>D.value=C),width:"80vw",style:{height:"80vh"}},{default:c(()=>[l("div",fs,[l("div",ms,[s(ne,{modelValue:i.value,"onUpdate:modelValue":e[8]||(e[8]=C=>i.value=C),placeholder:a.value?"编辑模板内容":"输入新模板内容",class:"template-input",clearable:""},null,8,["modelValue","placeholder"]),l("div",vs,[a.value?(f(),ee(Z,{key:0,onClick:Te},{default:c(()=>e[21]||(e[21]=[x("取消")])),_:1})):te("",!0),s(Z,{type:"primary",onClick:ke,disabled:!i.value.trim()},{default:c(()=>[x(R(a.value?"更新模板":"添加模板"),1)]),_:1},8,["disabled"])])]),l("div",gs,[e[25]||(e[25]=l("h3",null,"已保存模板",-1)),h.value.length===0?(f(),ee(Oe,{key:0,description:"暂无保存的模板"})):te("",!0),(f(!0),T(ae,null,le(h.value,(C,ue)=>(f(),ee(Me,{key:ue,class:"template-item"},{default:c(()=>[s(Pe,{justify:"space-between",align:"middle",style:{width:"100%"}},{default:c(()=>[l("div",ys,R(C),1),l("div",hs,[s(Z,{type:"primary",size:"small",onClick:de=>J(C)},{default:c(()=>e[22]||(e[22]=[x("使用")])),_:2},1032,["onClick"]),s(Z,{type:"warning",size:"small",icon:d(Fe),onClick:de=>Se(C,ue)},{default:c(()=>e[23]||(e[23]=[x("编辑")])),_:2},1032,["icon","onClick"]),s(Z,{type:"danger",size:"small",onClick:de=>O(C)},{default:c(()=>e[24]||(e[24]=[x("删除")])),_:2},1032,["onClick"])])]),_:2},1024)]),_:2},1024))),128))])])]),_:1},8,["modelValue"]),s(Ne,{title:"作用域模板设置",modelValue:K.value,"onUpdate:modelValue":e[11]||(e[11]=C=>K.value=C),width:"80%",style:{height:"80vh"}},{default:c(()=>[l("div",_s,[l("div",ws,[s(ne,{modelValue:H.value,"onUpdate:modelValue":e[10]||(e[10]=C=>H.value=C),placeholder:p.value?"编辑作用域模板内容":"输入新作用域模板",class:"template-input",clearable:""},null,8,["modelValue","placeholder"]),l("div",$s,[p.value?(f(),ee(Z,{key:0,onClick:u},{default:c(()=>e[26]||(e[26]=[x("取消")])),_:1})):te("",!0),s(Z,{type:"primary",onClick:me,disabled:!H.value.trim()},{default:c(()=>[x(R(p.value?"更新模板":"添加模板"),1)]),_:1},8,["disabled"])])]),l("div",Cs,[e[30]||(e[30]=l("h3",null,"已保存作用域",-1)),W.value.length===0?(f(),ee(Oe,{key:0,description:"暂无保存的作用域"})):te("",!0),(f(!0),T(ae,null,le(W.value,(C,ue)=>(f(),ee(Me,{key:ue,class:"template-item"},{default:c(()=>[s(Pe,{justify:"space-between",align:"middle",style:{width:"100%"}},{default:c(()=>[l("div",ks,R(C),1),l("div",bs,[s(Z,{type:"primary",size:"small",onClick:de=>Y(C)},{default:c(()=>e[27]||(e[27]=[x("使用")])),_:2},1032,["onClick"]),s(Z,{type:"warning",size:"small",icon:d(Fe),onClick:de=>v(C,ue)},{default:c(()=>e[28]||(e[28]=[x("编辑")])),_:2},1032,["icon","onClick"]),s(Z,{type:"danger",size:"small",onClick:de=>G(C)},{default:c(()=>e[29]||(e[29]=[x("删除")])),_:2},1032,["onClick"])])]),_:2},1024)]),_:2},1024))),128))])])]),_:1},8,["modelValue"])])}}}),Ts=$e(Ss,[["__scopeId","data-v-34334c1f"]]),Vs={class:"card"},Gs={class:"log-header"},Bs={class:"log-actions"},Ds={key:0},js={key:1},xs={key:0,class:"graph-view"},Rs={key:0,class:"commit-count"},zs={class:"graph-controls"},Ls={class:"zoom-controls"},As={class:"scale-info"},Es={key:1},Os={key:0,class:"commit-count"},Ps={key:0,class:"branch-container"},fe=.5,ye=1.5,je=.1,Ms=_e({__name:"LogList",setup(P,{expose:I}){const m=Ee(),V=ie();let t=[];const y=r(t),k=r(""),_=r(!1),N=he(()=>m.isLoadingLog||_.value),A=r(!1),E=r(0),M=r(!0),b=r(null),S=r(1);async function z(p=!1){if(!ie().isGitRepo){k.value="当前目录不是Git仓库";return}try{A.value=p,_.value=!0;const L=p?"/api/log?all=true&graph=true":"/api/log?graph=true";console.log(`加载日志数据: ${L}`);const $=await(await fetch(L)).json();if(t.length=0,Array.isArray($))console.log(`日志加载完成: 共${$.length}条记录`),$.forEach(F=>t.push(F)),E.value=$.length;else if($.log&&Array.isArray($.log))console.log(`日志加载完成: 共${$.log.length}条记录`),$.log.forEach(F=>t.push(F)),E.value=$.log.length;else{console.error("未知的日志数据格式:",$),k.value="日志数据格式错误";return}y.value=[...t],console.log(`logsData长度: ${t.length}`),M.value&&setTimeout(g,0),k.value=""}catch(L){k.value="加载提交历史失败: "+(L instanceof Error?L.message:String(L)),console.error("加载日志失败:",L)}finally{_.value=!1}}async function g(){if(console.log(`开始渲染图表...数据长度: ${t.length}`),!b.value){console.error("图表容器未找到");return}if(t.length===0){console.error("没有日志数据可渲染");return}try{b.value.innerHTML="",console.log(`创建gitgraph实例,分支: ${V.currentBranch||"main"}`);const p=bt(b.value,{orientation:"vertical-reverse",template:"metro",author:"提交者 <committer@example.com>"}),B={},L=p.branch(V.currentBranch||"main");B[V.currentBranch||"main"]=L,console.log(`开始创建提交图...共${t.length}条提交`),t.forEach((j,$)=>{let F=L;if(j.branch){const oe=i(j.branch.split(",")[0]);B[oe]||(B[oe]=p.branch(oe)),F=B[oe]}F.commit({hash:j.hash,subject:j.message,author:`${j.author} <${j.email}>`}),$%10===0&&console.log(`已渲染 ${$+1}/${t.length} 个提交`)}),console.log("图表渲染完成"),setTimeout(()=>{H()},100)}catch(p){console.error("渲染图表失败:",p),k.value="渲染图表失败: "+(p instanceof Error?p.message:String(p))}}function h(){M.value=!M.value,M.value&&t.length>0&&setTimeout(g,0)}function D(){z(!A.value)}function i(p){return p.includes("HEAD -> ")?p.replace("HEAD -> ",""):p.includes("origin/")?p:p.trim()}function a(p){return p.includes("HEAD")?"success":p.includes("origin/")?"warning":"info"}we(()=>{V.isGitRepo?m.log.length>0?(console.log("使用已加载的日志数据"),t.length=0,m.log.forEach(p=>t.push(p)),E.value=m.log.length,M.value&&setTimeout(()=>{console.log(`准备渲染图表,数据长度: ${t.length}`),g()},100)):(console.log("初始加载日志数据"),z()):k.value="当前目录不是Git仓库"});const w=()=>{if(!V.isGitRepo){k.value="当前目录不是Git仓库";return}z(A.value)};ze(()=>m.log,p=>{console.log("监听到gitLogStore.log变化,更新图表数据"),t.length=0,p.forEach(B=>t.push(B)),E.value=p.length;try{y.value=[...t]}catch(B){console.warn("无法更新logs.value:",B)}console.log(`数据更新完成,准备渲染图表(${t.length}条记录)`),M.value&&t.length>0&&setTimeout(g,0)}),I({refreshLog:w});function q(){S.value<ye&&(S.value=Math.min(ye,S.value+je),K())}function W(){S.value>fe&&(S.value=Math.max(fe,S.value-je),K())}function K(){if(!b.value)return;const p=b.value.querySelector("svg");p&&(p.style.transform=`scale(${S.value})`,p.style.transformOrigin="top left")}function H(){if(!b.value)return;const p=b.value.querySelector("svg");if(!p)return;const B=p.getBoundingClientRect().width/S.value,L=b.value.clientWidth;B>L?S.value=Math.max(fe,L/B):S.value=1,K()}return(p,B)=>{const L=Ke;return f(),T("div",Vs,[l("div",Gs,[B[2]||(B[2]=l("h2",null,"提交历史",-1)),l("div",Bs,[s(d(se),{type:"primary",size:"small",onClick:h},{default:c(()=>[x(R(M.value?"表格视图":"图表视图"),1)]),_:1}),s(d(se),{type:"primary",size:"small",onClick:D,loading:N.value},{default:c(()=>[x(R(A.value?"显示最近30条":"显示所有提交"),1)]),_:1},8,["loading"]),s(d(se),{icon:d(Qe),circle:"",size:"small",onClick:B[0]||(B[0]=j=>w()),loading:N.value},null,8,["icon","loading"])])]),k.value?(f(),T("div",Ds,R(k.value),1)):(f(),T("div",js,[M.value?(f(),T("div",xs,[d(t).length>0?(f(),T("div",Rs," 显示 "+R(d(t).length)+" 条提交记录 "+R(A.value?"(全部)":"(最近30条)"),1)):te("",!0),l("div",zs,[l("div",Ls,[s(d(se),{type:"primary",icon:d(_t),circle:"",size:"small",onClick:W,disabled:S.value<=fe},null,8,["icon","disabled"]),s(d(wt),{modelValue:S.value,"onUpdate:modelValue":B[1]||(B[1]=j=>S.value=j),min:fe,max:ye,step:je,onChange:K,class:"zoom-slider"},null,8,["modelValue"]),s(d(se),{type:"primary",icon:d($t),circle:"",size:"small",onClick:q,disabled:S.value>=ye},null,8,["icon","disabled"]),s(d(se),{type:"primary",size:"small",onClick:H},{default:c(()=>B[3]||(B[3]=[x(" 自适应大小 ")])),_:1})]),l("div",As," 缩放: "+R(Math.round(S.value*100))+"% ",1)]),l("div",{ref_key:"graphContainer",ref:b,class:"graph-container"},null,512)])):(f(),T("div",Es,[y.value.length>0?(f(),T("div",Os," 显示 "+R(y.value.length)+" 条提交记录 "+R(A.value?"(全部)":"(最近30条)"),1)):te("",!0),xe((f(),ee(d(kt),{data:y.value,style:{width:"100%"},stripe:"",border:""},{default:c(()=>[s(d(pe),{prop:"hash",label:"提交哈希",width:"100",resizable:""}),s(d(pe),{prop:"date",label:"日期",width:"180",resizable:""}),s(d(pe),{label:"作者",width:"200",resizable:""},{default:c(j=>[x(R(j.row.author)+" <"+R(j.row.email)+"> ",1)]),_:1}),s(d(pe),{label:"分支",width:"180",resizable:""},{default:c(j=>[j.row.branch?(f(),T("div",Ps,[(f(!0),T(ae,null,le(j.row.branch.split(","),($,F)=>(f(),ee(d(Ct),{key:F,size:"small",type:a($),class:"branch-tag"},{default:c(()=>[x(R(i($)),1)]),_:2},1032,["type"]))),128))])):te("",!0)]),_:1}),s(d(pe),{prop:"message",label:"提交信息","min-width":"250"})]),_:1},8,["data"])),[[L,N.value]])]))]))])}}}),Ns=$e(Ms,[["__scopeId","data-v-45e00b57"]]),Us="data:image/svg+xml,%3csvg%20width='200'%20height='200'%20viewBox='0%200%20200%20200'%20xmlns='http://www.w3.org/2000/svg'%3e%3c!--%20主分支%20--%3e%3cline%20x1='40'%20y1='40'%20x2='40'%20y2='160'%20stroke='%2334495e'%20stroke-width='8'%20stroke-linecap='round'%20/%3e%3c!--%20特性分支%20--%3e%3cpath%20d='M40,70%20C60,70%2080,90%2080,110%20L80,130'%20stroke='%233498db'%20stroke-width='8'%20stroke-linecap='round'%20stroke-linejoin='round'%20fill='none'%20/%3e%3c!--%20开发分支%20--%3e%3cpath%20d='M40,100%20C60,100%20100,110%20100,130%20L100,160'%20stroke='%232ecc71'%20stroke-width='8'%20stroke-linecap='round'%20stroke-linejoin='round'%20fill='none'%20/%3e%3c!--%20修复分支%20--%3e%3cpath%20d='M40,130%20C60,130%20120,140%20120,160'%20stroke='%23e74c3c'%20stroke-width='8'%20stroke-linecap='round'%20stroke-linejoin='round'%20fill='none'%20/%3e%3c!--%20合并点%20--%3e%3cpath%20d='M80,130%20C80,145%2060,145%2040,145'%20stroke='%233498db'%20stroke-width='8'%20stroke-linecap='round'%20stroke-linejoin='round'%20fill='none'%20/%3e%3c!--%20节点%20--%3e%3ccircle%20cx='40'%20cy='40'%20r='10'%20fill='%2334495e'%20/%3e%3ccircle%20cx='40'%20cy='70'%20r='10'%20fill='%2334495e'%20/%3e%3ccircle%20cx='40'%20cy='100'%20r='10'%20fill='%2334495e'%20/%3e%3ccircle%20cx='40'%20cy='130'%20r='10'%20fill='%2334495e'%20/%3e%3ccircle%20cx='40'%20cy='145'%20r='10'%20fill='%2334495e'%20/%3e%3ccircle%20cx='40'%20cy='160'%20r='10'%20fill='%2334495e'%20/%3e%3ccircle%20cx='80'%20cy='130'%20r='10'%20fill='%233498db'%20/%3e%3ccircle%20cx='100'%20cy='160'%20r='10'%20fill='%232ecc71'%20/%3e%3ccircle%20cx='120'%20cy='160'%20r='10'%20fill='%23e74c3c'%20/%3e%3c/svg%3e",Is={class:"main-header"},Fs={class:"header-left"},Hs=["src"],Js={class:"header-info"},Ws={key:0,id:"user-info"},Zs={class:"user-name"},qs={class:"user-email"},Ks={class:"container"},Qs={key:0,class:"loading-container"},Xs={class:"loading-spinner"},Ys={key:1,class:"layout-container"},ea={class:"left-panel"},ta={key:0,class:"right-panel"},sa={key:1,class:"right-panel"},aa={class:"dialog-footer"},oa={class:"main-footer"},la={key:0,class:"branch-info"},na=_e({__name:"App",setup(P){const I=r(""),m=r(null),V=r(null),t=ie(),y=r(!1),k=r("");async function _(){try{const a=await(await fetch("/api/config/getConfig")).json();I.value=`默认提交信息: ${a.defaultCommitMessage}`}catch(i){console.error("加载配置失败:",i)}}async function N(){try{const a=await(await fetch("/api/current_directory")).json();return k.value=a.directory||"未知目录",a}catch(i){return console.error("获取当前目录失败:",i),{directory:"未知目录",isGitRepo:!1}}}we(async()=>{console.log("---------- 页面初始化开始 ----------");try{const[i,a]=await Promise.all([_(),N()]);t.isGitRepo=a.isGitRepo===!0,t.lastCheckedTime=Date.now(),t.isGitRepo?await Promise.all([t.getCurrentBranch(),t.getAllBranches(),t.getUserInfo()]):o.warning("当前目录不是Git仓库,部分功能将不可用")}catch(i){console.error("初始化失败:",i)}finally{y.value=!0,console.log("---------- 页面初始化完成 ----------")}});function A(){V.value&&V.value.refreshStatus(),m.value&&m.value.refreshLog()}function E(){t.getCurrentBranch(),m.value&&m.value.refreshLog()}function M(){V.value&&V.value.refreshStatus()}const b=r(!1),S=r(""),z=r("");async function g(){await t.createBranch(S.value,z.value)&&(b.value=!1,S.value="",V.value&&V.value.refreshStatus(),m.value&&m.value.refreshLog())}function h(){z.value=t.currentBranch,b.value=!0}async function D(i){await t.changeBranch(i)&&(V.value&&V.value.refreshStatus(),m.value&&m.value.refreshLog())}return(i,a)=>{const w=Je,q=st,W=Ae,K=qe,H=et,p=Ye,B=Ze,L=se,j=Le;return f(),T(ae,null,[l("header",Is,[l("div",Fs,[l("img",{src:d(Us),alt:"Zen GitSync Logo",class:"logo"},null,8,Hs),a[5]||(a[5]=l("h1",null,"Zen GitSync UI",-1))]),l("div",Js,[d(t).userName&&d(t).userEmail?(f(),T("div",Ws,[a[6]||(a[6]=l("span",{class:"user-label"},"用户:",-1)),l("span",Zs,R(d(t).userName),1),l("span",qs,"<"+R(d(t).userEmail)+">",1)])):te("",!0)])]),l("div",Ks,[y.value?(f(),T("div",Ys,[l("div",ea,[s(qt,{ref_key:"gitStatusRef",ref:V,"initial-directory":k.value},null,8,["initial-directory"])]),d(t).isGitRepo?(f(),T("div",ta,[s(Ts,{onCommitSuccess:A,onPushSuccess:E,onStatusUpdate:M}),s(Ns,{ref_key:"logListRef",ref:m},null,512)])):(f(),T("div",sa,a[9]||(a[9]=[l("div",{class:"card"},[l("h2",null,"Git仓库初始化"),l("p",null,"当前目录不是Git仓库,请先初始化Git仓库或切换到Git仓库目录。"),l("div",{class:"tips"},[l("h3",null,"可以使用以下命令初始化仓库:"),l("div",{class:"code-block"},"git init")])],-1)]))),s(j,{modelValue:b.value,"onUpdate:modelValue":a[3]||(a[3]=$=>b.value=$),title:"创建新分支",width:"30%","destroy-on-close":""},{footer:c(()=>[l("span",aa,[s(L,{onClick:a[2]||(a[2]=$=>b.value=!1)},{default:c(()=>a[10]||(a[10]=[x("取消")])),_:1}),s(L,{type:"primary",onClick:g,loading:d(t).isCreatingBranch},{default:c(()=>a[11]||(a[11]=[x(" 创建 ")])),_:1},8,["loading"])])]),default:c(()=>[s(B,{model:{newBranchName:S.value,selectedBaseBranch:z.value}},{default:c(()=>[s(K,{label:"新分支名称"},{default:c(()=>[s(W,{modelValue:S.value,"onUpdate:modelValue":a[0]||(a[0]=$=>S.value=$),placeholder:"请输入新分支名称"},null,8,["modelValue"])]),_:1}),s(K,{label:"基于分支"},{default:c(()=>[s(p,{modelValue:z.value,"onUpdate:modelValue":a[1]||(a[1]=$=>z.value=$),placeholder:"选择基础分支",style:{width:"100%"}},{default:c(()=>[(f(!0),T(ae,null,le(d(t).allBranches,$=>(f(),ee(H,{key:$,label:$,value:$},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["modelValue"])])):(f(),T("div",Qs,[s(q,{class:"loading-card"},{default:c(()=>[l("div",Xs,[s(w,{class:"is-loading"},{default:c(()=>a[7]||(a[7]=[l("svg",{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},[l("path",{fill:"currentColor",d:"M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z"})],-1)])),_:1})]),a[8]||(a[8]=l("div",{class:"loading-text"},"加载中...",-1))]),_:1})]))]),l("footer",oa,[d(t).currentBranch?(f(),T("div",la,[a[12]||(a[12]=l("span",{class:"branch-label"},"当前分支:",-1)),s(p,{modelValue:d(t).currentBranch,"onUpdate:modelValue":a[4]||(a[4]=$=>d(t).currentBranch=$),size:"small",onChange:D,loading:d(t).isChangingBranch,class:"branch-select"},{default:c(()=>[(f(!0),T(ae,null,le(d(t).allBranches,$=>(f(),ee(H,{key:$,label:$,value:$},null,8,["label","value"]))),128))]),_:1},8,["modelValue","loading"]),s(L,{type:"primary",size:"small",onClick:h,style:{"margin-left":"5px"}},{default:c(()=>[s(w,null,{default:c(()=>[s(d(tt))]),_:1})]),_:1})])):te("",!0),a[13]||(a[13]=l("div",{class:"footer-right"},null,-1))])],64)}}}),ra=$e(na,[["__scopeId","data-v-7161cf53"]]),at=St(ra);at.use(Tt());at.mount("#app");