zen-gitsync 2.0.7 → 2.0.8

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-B1vQ6PC_.js"></script>
9
- <link rel="modulepreload" crossorigin href="/assets/vendor-BmPvvgTD.js">
8
+ <script type="module" crossorigin src="/assets/index-P9BcPWc5.js"></script>
9
+ <link rel="modulepreload" crossorigin href="/assets/vendor-eqaTZKOh.js">
10
10
  <link rel="stylesheet" crossorigin href="/assets/vendor-Dp0FkvMe.css">
11
- <link rel="stylesheet" crossorigin href="/assets/index-CC5qWyQ-.css">
11
+ <link rel="stylesheet" crossorigin href="/assets/index-C3BbS3PG.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="app"></div>
@@ -369,7 +369,28 @@ async function startUIServer() {
369
369
  }
370
370
  })
371
371
 
372
- // 保存描述模板
372
+ // 保存默认提交信息
373
+ app.post('/api/config/saveDefaultMessage', express.json(), async (req, res) => {
374
+ try {
375
+ const { defaultCommitMessage } = req.body
376
+
377
+ if (!defaultCommitMessage) {
378
+ return res.status(400).json({ success: false, error: '缺少必要参数' })
379
+ }
380
+
381
+ const config = await configManager.loadConfig()
382
+
383
+ // 更新默认提交信息
384
+ config.defaultCommitMessage = defaultCommitMessage
385
+ await configManager.saveConfig(config)
386
+
387
+ res.json({ success: true })
388
+ } catch (error) {
389
+ res.status(500).json({ success: false, error: error.message })
390
+ }
391
+ })
392
+
393
+ // 保存模板
373
394
  app.post('/api/config/save-template', express.json(), async (req, res) => {
374
395
  try {
375
396
  const { template, type } = req.body
@@ -402,6 +423,17 @@ async function startUIServer() {
402
423
  config.scopeTemplates.push(template)
403
424
  await configManager.saveConfig(config)
404
425
  }
426
+ } else if (type === 'message') {
427
+ // 确保提交信息模板数组存在
428
+ if (!config.messageTemplates) {
429
+ config.messageTemplates = []
430
+ }
431
+
432
+ // 检查是否已存在相同模板
433
+ if (!config.messageTemplates.includes(template)) {
434
+ config.messageTemplates.push(template)
435
+ await configManager.saveConfig(config)
436
+ }
405
437
  } else {
406
438
  return res.status(400).json({ success: false, error: '不支持的模板类型' })
407
439
  }
@@ -412,7 +444,7 @@ async function startUIServer() {
412
444
  }
413
445
  })
414
446
 
415
- // 删除描述模板
447
+ // 删除模板
416
448
  app.post('/api/config/delete-template', express.json(), async (req, res) => {
417
449
  try {
418
450
  const { template, type } = req.body
@@ -441,6 +473,15 @@ async function startUIServer() {
441
473
  await configManager.saveConfig(config)
442
474
  }
443
475
  }
476
+ } else if (type === 'message') {
477
+ // 确保提交信息模板数组存在
478
+ if (config.messageTemplates) {
479
+ const index = config.messageTemplates.indexOf(template)
480
+ if (index !== -1) {
481
+ config.messageTemplates.splice(index, 1)
482
+ await configManager.saveConfig(config)
483
+ }
484
+ }
444
485
  } else {
445
486
  return res.status(400).json({ success: false, error: '不支持的模板类型' })
446
487
  }
@@ -488,6 +529,19 @@ async function startUIServer() {
488
529
  } else {
489
530
  return res.status(404).json({ success: false, error: '模板列表不存在' })
490
531
  }
532
+ } else if (type === 'message') {
533
+ // 确保提交信息模板数组存在
534
+ if (config.messageTemplates) {
535
+ const index = config.messageTemplates.indexOf(oldTemplate)
536
+ if (index !== -1) {
537
+ config.messageTemplates[index] = newTemplate
538
+ await configManager.saveConfig(config)
539
+ } else {
540
+ return res.status(404).json({ success: false, error: '未找到原模板' })
541
+ }
542
+ } else {
543
+ return res.status(404).json({ success: false, error: '模板列表不存在' })
544
+ }
491
545
  } else {
492
546
  return res.status(400).json({ success: false, error: '不支持的模板类型' })
493
547
  }
@@ -592,10 +646,30 @@ async function startUIServer() {
592
646
  // 推送更改
593
647
  app.post('/api/push', async (req, res) => {
594
648
  try {
595
- await execGitCommand('git push');
596
- res.json({ success: true });
649
+ const { stdout } = await execGitCommand('git push');
650
+ res.json({ success: true, message: stdout });
597
651
  } catch (error) {
598
- res.status(500).json({ error: error.message });
652
+ res.status(500).json({ success: false, error: error.message });
653
+ }
654
+ });
655
+
656
+ // 添加git pull API端点
657
+ app.post('/api/pull', async (req, res) => {
658
+ try {
659
+ const { stdout } = await execGitCommand('git pull');
660
+ res.json({ success: true, message: stdout });
661
+ } catch (error) {
662
+ res.status(500).json({ success: false, error: error.message });
663
+ }
664
+ });
665
+
666
+ // 添加git fetch --all API端点
667
+ app.post('/api/fetch-all', async (req, res) => {
668
+ try {
669
+ const { stdout } = await execGitCommand('git fetch --all');
670
+ res.json({ success: true, message: stdout });
671
+ } catch (error) {
672
+ res.status(500).json({ success: false, error: error.message });
599
673
  }
600
674
  });
601
675
 
@@ -612,10 +686,25 @@ async function startUIServer() {
612
686
  const message = req.query.message || '';
613
687
  const dateFrom = req.query.dateFrom || '';
614
688
  const dateTo = req.query.dateTo || '';
689
+ const branch = req.query.branch ? req.query.branch.split(',') : [];
615
690
 
616
691
  // 构建Git命令选项
617
692
  let commandOptions = [];
618
693
 
694
+ // 修改分支筛选处理 - 使用正确的引用格式
695
+ if (branch.length > 0) {
696
+ // 不再简单拼接分支名,而是将它们作为引用路径处理
697
+ // 如果指定了分支,不再使用--all参数,而是直接用分支名
698
+ commandOptions = commandOptions.filter(opt => opt !== '--all');
699
+
700
+ // 将分支名格式化为Git可理解的引用格式
701
+ const branchRefs = branch.map(b => b.trim()).join(' ');
702
+
703
+ // 直接将分支名作为命令参数,并确保后面添加 -- 分隔符防止歧义
704
+ return executeGitLogCommand(res, branchRefs, author, message, dateFrom, dateTo, limit, skip, req.query.all === 'true');
705
+ }
706
+
707
+ // 如果没有指定分支,则使用--all参数
619
708
  // 作者筛选(支持多作者,使用正则表达式OR操作)
620
709
  if (author.length > 0) {
621
710
  // 过滤掉空作者
@@ -689,47 +778,130 @@ async function startUIServer() {
689
778
  totalCommits = 0;
690
779
  }
691
780
 
692
- // 替换提交记录之间的换行符
693
- logOutput = logOutput.replace(/\n(?=[a-f0-9]{40}\|)/g, "<<<RECORD_SEPARATOR>>>");
694
-
695
- // 按分隔符拆分日志条目
696
- const logEntries = logOutput.split("<<<RECORD_SEPARATOR>>>");
697
-
698
- // 处理每个日志条目
699
- const data = logEntries.map(entry => {
700
- const parts = entry.split('|');
701
- if (parts.length >= 5) {
702
- return {
703
- hash: parts[0],
704
- author: parts[1],
705
- email: parts[2],
706
- date: parts[3],
707
- message: parts[4],
708
- branch: parts[5] || ''
709
- };
781
+ processAndSendLogOutput(res, logOutput, totalCommits, page, limit);
782
+ } catch (error) {
783
+ console.error('获取Git日志失败:', error);
784
+ res.status(500).json({ error: '获取日志失败: ' + error.message });
785
+ }
786
+ });
787
+
788
+ // 抽取执行Git日志命令的函数
789
+ async function executeGitLogCommand(res, branchRefs, author, message, dateFrom, dateTo, limit, skip, isAll) {
790
+ try {
791
+ // 构建命令选项
792
+ const commandOptions = [];
793
+
794
+ // 作者筛选
795
+ if (author.length > 0) {
796
+ const validAuthors = author.filter(a => a.trim() !== '');
797
+
798
+ if (validAuthors.length === 1) {
799
+ commandOptions.push(`--author="${validAuthors[0].trim()}"`);
800
+ } else if (validAuthors.length > 1) {
801
+ const authorPattern = validAuthors.map(a => a.trim()).join('\\|');
802
+ commandOptions.push(`--author="${authorPattern}"`);
710
803
  }
711
- return null;
712
- }).filter(item => item !== null);
804
+ }
713
805
 
714
- // 计算是否有更多数据
715
- // 修复:使用总记录数和已获取记录总数来判断
716
- const hasMore = req.query.all === 'true' ? false : (skip + data.length < totalCommits);
806
+ // 日期范围筛选
807
+ if (dateFrom && dateTo) {
808
+ commandOptions.push(`--after="${dateFrom}" --before="${dateTo} 23:59:59"`);
809
+ } else if (dateFrom) {
810
+ commandOptions.push(`--after="${dateFrom}"`);
811
+ } else if (dateTo) {
812
+ commandOptions.push(`--before="${dateTo} 23:59:59"`);
813
+ }
717
814
 
718
- console.log(`分页查询 - 页码: ${page}, 每页数量: ${limit}, 跳过: ${skip}, 总数: ${totalCommits}, 返回数量: ${data.length}, 是否有更多: ${hasMore}`);
815
+ // 提交信息筛选
816
+ if (message) {
817
+ commandOptions.push(`--grep="${message}"`);
818
+ }
719
819
 
720
- // 返回提交历史数据,包括是否有更多数据的标志
721
- res.json({
722
- data: data,
723
- total: totalCommits,
724
- page: page,
725
- limit: limit,
726
- hasMore: hasMore
727
- });
820
+ // 限制选项
821
+ const limitOption = isAll ? '' : `-n ${limit} --skip=${skip}`;
822
+
823
+ // 合并所有选项
824
+ const options = [...commandOptions, limitOption].filter(Boolean).join(' ');
825
+
826
+ // 准备分支引用,确保它们被正确识别为分支而不是文件名
827
+ // 使用 refs/heads/ 前缀明确指示这是分支
828
+ const formattedBranchRefs = branchRefs.split(' ')
829
+ .map(branch => {
830
+ // 检查是否已经是完整引用
831
+ if (branch.startsWith('refs/') || branch.includes('/')) {
832
+ return branch;
833
+ }
834
+ // 添加refs/heads/前缀
835
+ return `refs/heads/${branch}`;
836
+ })
837
+ .join(' ');
838
+
839
+ // 构建执行的命令
840
+ const command = `git log ${formattedBranchRefs} --pretty=format:"%H|%an|%ae|%ad|%B|%D" --date=short ${options}`;
841
+ console.log(`执行Git命令(带分支引用): ${command}`);
842
+
843
+ // 执行命令
844
+ const { stdout: logOutput } = await execGitCommand(command);
845
+
846
+ // 获取总提交数
847
+ let totalCommits = 0;
848
+ try {
849
+ // 构建计数命令
850
+ const countCommand = `git rev-list ${formattedBranchRefs} --count ${commandOptions.join(' ')}`;
851
+ console.log(`执行计数命令(分支): ${countCommand}`);
852
+
853
+ const { stdout: countOutput } = await execGitCommand(countCommand);
854
+ totalCommits = parseInt(countOutput.trim());
855
+ } catch (error) {
856
+ console.error('获取提交总数失败:', error);
857
+ totalCommits = 0;
858
+ }
859
+
860
+ processAndSendLogOutput(res, logOutput, totalCommits, skip / limit + 1, limit);
728
861
  } catch (error) {
729
- console.error('获取Git日志失败:', error);
862
+ console.error('执行Git日志命令失败:', error);
730
863
  res.status(500).json({ error: '获取日志失败: ' + error.message });
731
864
  }
732
- });
865
+ }
866
+
867
+ // 抽取处理输出并发送响应的函数
868
+ function processAndSendLogOutput(res, logOutput, totalCommits, page, limit) {
869
+ // 替换提交记录之间的换行符
870
+ logOutput = logOutput.replace(/\n(?=[a-f0-9]{40}\|)/g, "<<<RECORD_SEPARATOR>>>");
871
+
872
+ // 按分隔符拆分日志条目
873
+ const logEntries = logOutput.split("<<<RECORD_SEPARATOR>>>");
874
+
875
+ // 处理每个日志条目
876
+ const data = logEntries.map(entry => {
877
+ const parts = entry.split('|');
878
+ if (parts.length >= 5) {
879
+ return {
880
+ hash: parts[0],
881
+ author: parts[1],
882
+ email: parts[2],
883
+ date: parts[3],
884
+ message: parts[4],
885
+ branch: parts[5] || ''
886
+ };
887
+ }
888
+ return null;
889
+ }).filter(item => item !== null);
890
+
891
+ // 计算是否有更多数据
892
+ const hasMore = page * limit < totalCommits;
893
+
894
+ console.log(`分页查询 - 页码: ${page}, 每页数量: ${limit}, 总数: ${totalCommits}, 返回数量: ${data.length}, 是否有更多: ${hasMore}`);
895
+
896
+ // 返回提交历史数据,包括是否有更多数据的标志
897
+ res.json({
898
+ data: data,
899
+ total: totalCommits,
900
+ page: page,
901
+ limit: limit,
902
+ hasMore: hasMore
903
+ });
904
+ }
733
905
 
734
906
  // 获取文件差异
735
907
  app.get('/api/diff', async (req, res) => {
@@ -1,20 +0,0 @@
1
- import{d as ft,r as u,E as c,o as Ee,a as bt,l as Ct,b as Ne,c as Ae,w as Ie,e as St,f as m,g as d,h as e,i as t,j as ot,u as s,k as a,m as pt,n as Xe,p as at,q as _e,s as Tt,t as He,v as Ke,x as L,y as w,z as ee,A as de,B as vt,C as Qe,F as he,D as we,G as Oe,H as We,I as mt,J as gt,K as Je,L as De,M as Le,N as yt,O as Lt,P as ct,Q as Be,R as lt,S as Fe,T as ut,U as ht,V as nt,W as it,X as Me,Y as Vt,Z as et,_ as Rt,$ as xt,a0 as _t,a1 as wt,a2 as Bt,a3 as zt,a4 as Gt,a5 as Dt,a6 as At,a7 as dt,a8 as Et,a9 as jt,aa as Ut,ab as Pt,ac as Ot,ad as It,ae as Ft,af as ze,ag as Mt,ah as Nt,ai as Ht,aj as Wt,ak as Jt,al as Yt,am as qt}from"./vendor-BmPvvgTD.js";(function(){const p=document.createElement("link").relList;if(p&&p.supports&&p.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))h(l);new MutationObserver(l=>{for(const A of l)if(A.type==="childList")for(const G of A.addedNodes)G.tagName==="LINK"&&G.rel==="modulepreload"&&h(G)}).observe(document,{childList:!0,subtree:!0});function x(l){const A={};return l.integrity&&(A.integrity=l.integrity),l.referrerPolicy&&(A.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?A.credentials="include":l.crossOrigin==="anonymous"?A.credentials="omit":A.credentials="same-origin",A}function h(l){if(l.ep)return;l.ep=!0;const A=x(l);fetch(l.href,A)}})();const Re=ft("git",()=>{const le=u(""),p=u([]),x=u(""),h=u(""),l=u(!1),A=u(!1),G=u(!1),ae=u(0),Y=u(0),F=u(0),E=u(!1),D=u("");function I(){le.value="",p.value=[],x.value="",h.value="",l.value=!1,A.value=!1,G.value=!1,ae.value=0,Y.value=0,F.value=0,E.value=!1,D.value=""}async function oe(){if(G.value)try{const T=await(await fetch("/api/branch-status")).json();T&&(Y.value=T.ahead||0,F.value=T.behind||0,E.value=T.hasUpstream||!1,D.value=T.upstreamBranch||"")}catch(_){console.error("获取分支状态失败:",_),Y.value=0,F.value=0,E.value=!1,D.value=""}}async function Q(){const _=Date.now();if(_-ae.value<1e3)return console.log("使用缓存的Git仓库状态:",G.value?"是":"不是"),G.value;try{const q=await(await fetch("/api/current_directory")).json();return G.value=q.isGitRepo===!0,ae.value=_,console.log(`当前目录${G.value?"是":"不是"}Git仓库`),G.value}catch(T){return console.error("检查Git仓库状态失败:",T),G.value=!1,ae.value=_,!1}}async function j(){try{const T=await(await fetch("/api/branch")).json();T.branch&&(le.value=T.branch,await oe())}catch(_){console.error("获取分支信息失败:",_)}}async function U(){try{const T=await(await fetch("/api/branches")).json();T.branches&&Array.isArray(T.branches)&&(p.value=T.branches)}catch(_){console.error("获取所有分支信息失败:",_)}}async function M(_){console.log("切换到分支:",_);try{l.value=!0;const q=await(await fetch("/api/checkout",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({branch:_})})).json();return q.success?(c({message:`已切换到分支: ${_}`,type:"success"}),j(),!0):(c({message:`切换分支失败: ${q.error}`,type:"error"}),!1)}catch(T){return c({message:`切换分支失败: ${T.message}`,type:"error"}),!1}finally{l.value=!1}}async function N(){try{const T=await(await fetch("/api/user-info")).json();T.name&&T.email&&(x.value=T.name,h.value=T.email)}catch(_){console.error("获取用户信息失败:",_)}}async function te(_,T){if(!_.trim())return c({message:"分支名称不能为空",type:"warning"}),!1;try{A.value=!0;const se=await(await fetch("/api/create-branch",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({newBranchName:_,baseBranch:T||le.value})})).json();return se.success?(c({message:`已创建并切换到分支: ${_}`,type:"success"}),j(),U(),!0):(c({message:`创建分支失败: ${se.error}`,type:"error"}),!1)}catch(q){return c({message:`创建分支失败: ${q.message}`,type:"error"}),!1}finally{A.value=!1}}async function J(){await Q()?(j(),U(),N()):(le.value="",p.value=[],x.value="",h.value="")}async function ue(){try{const T=await(await fetch("/api/clear-user-config",{method:"POST"})).json();return T.success?(x.value="",h.value="",c({message:"已清除Git用户配置",type:"success"}),!0):(c({message:`清除配置失败: ${T.error}`,type:"error"}),!1)}catch(_){return c({message:`清除配置失败: ${_.message}`,type:"error"}),!1}}async function H(_,T){try{const se=await(await fetch("/api/restore-user-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:_,email:T})})).json();return se.success?(x.value=_,h.value=T,c({message:"已恢复Git用户配置",type:"success"}),!0):(c({message:`恢复配置失败: ${se.error}`,type:"error"}),!1)}catch(q){return c({message:`恢复配置失败: ${q.message}`,type:"error"}),!1}}return{currentBranch:le,allBranches:p,userName:x,userEmail:h,isChangingBranch:l,isCreatingBranch:A,isGitRepo:G,lastCheckedTime:ae,branchAhead:Y,branchBehind:F,hasUpstream:E,upstreamBranch:D,$reset:I,checkGitRepo:Q,getCurrentBranch:j,getAllBranches:U,changeBranch:M,getUserInfo:N,createBranch:te,loadInitialData:J,clearUserConfig:ue,restoreUserConfig:H,getBranchStatus:oe}}),tt=300,rt=ft("gitLog",()=>{const le=Re();let p=null;const x=u(!0),h=u([]),l=u({staged:[],unstaged:[],untracked:[]}),A=u(""),G=u([]),ae=u(!1),Y=u(!1),F=u(!1),E=u(!1),D=u(!1),I=u(!1);function oe(){p&&p.disconnect();try{const $="http://localhost:3000";if(console.log("尝试连接Socket.IO服务器:",$),p=Ct($,{reconnectionDelayMax:1e4,reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,timeout:2e4,autoConnect:!0,forceNew:!0,transports:["websocket","polling"]}),!p){console.error("Socket.IO初始化失败: socket为null");return}console.log("Socket.IO初始化成功,socket ID:",p.id||"未连接"),p.on("connect",()=>{console.log("成功连接到Socket.IO服务器"),x.value&&p&&p.emit("start_monitoring")}),p.on("disconnect",g=>{console.log("与Socket.IO服务器断开连接:",g)}),p.on("git_status_update",g=>{if(!x.value)return;console.log("收到Git状态更新通知:",new Date().toLocaleTimeString()),g.status&&(A.value=g.status),g.porcelain!==void 0&&j(g.porcelain),G.value.length>0&&U(!1)}),p.on("monitoring_status",g=>{console.log("文件监控状态:",g.active?"已启动":"已停止")}),p.on("connect_error",g=>{console.error("Socket连接错误:",g.message)}),p.on("connect_timeout",()=>{console.error("Socket连接超时")}),p.on("reconnect",g=>{console.log(`Socket重连成功,尝试次数: ${g}`),x.value&&(console.log("重连后重新发送start_monitoring请求"),p==null||p.emit("start_monitoring"))}),p.on("reconnect_attempt",g=>{console.log(`Socket尝试重连,第 ${g} 次尝试`)}),p.on("reconnect_error",g=>{console.error("Socket重连错误:",g.message)}),p.on("reconnect_failed",()=>{console.error("Socket重连失败,已达到最大重试次数")}),p&&!p.connected&&(console.log("Socket未连接,尝试手动连接..."),p.connect())}catch($){console.error("Socket.IO连接初始化失败:",$)}}function Q(){if(console.log("toggleAutoUpdate调用,当前值:",x.value),!p){console.error("无法切换自动更新状态: socket连接不存在"),c.error("无法连接到服务器,自动更新可能不会生效"),console.log("尝试重新建立socket连接..."),oe(),localStorage.setItem("zen-gitsync-auto-update",x.value.toString());return}try{x.value?(console.log("发送start_monitoring命令..."),p.emit("start_monitoring"),c.success("自动更新已启用")):(console.log("发送stop_monitoring命令..."),p.emit("stop_monitoring"),c.info("自动更新已禁用")),localStorage.setItem("zen-gitsync-auto-update",x.value.toString()),console.log("已保存自动更新设置到本地存储:",x.value)}catch($){console.error("切换自动更新状态时出错:",$),c.error(`切换自动更新失败: ${$.message}`)}}function j($){if($===void 0||$===""){G.value=[];return}const g=$.split(`
2
- `),Z=[];for(const ne of g){const ve=ne.match(/^([ MADRCU\?]{2})\s+(.+)$/);if(ve){let pe="";const b=ve[1],r=b.charAt(0),W=b.charAt(1);r==="A"||r==="M"||r==="D"||r==="R"?pe="added":r===" "&&W==="M"?pe="modified":r===" "&&W==="D"?pe="deleted":b==="??"?pe="untracked":pe="other",Z.push({path:ve[2],type:pe})}}G.value=Z}async function U($=!0){if(!le.isGitRepo){console.log("当前目录不是Git仓库,跳过加载提交历史");return}try{ae.value=!0,console.log("开始加载提交历史...");const g=new Date().getTime(),ne=await(await fetch(`/api/log?page=1&_t=${g}`)).json();ne&&ne.data&&Array.isArray(ne.data)?(h.value=[...ne.data],console.log(`提交历史加载完成,共 ${h.value.length} 条记录`)):(console.warn("API返回的提交历史格式不正确:",ne),h.value=[]),$&&c({message:"提交历史已更新",type:"success"})}catch(g){console.error("获取提交历史失败:",g),$&&c({message:`获取提交历史失败: ${g.message}`,type:"error"})}finally{ae.value=!1}}async function M(){if(!le.isGitRepo){console.log("当前目录不是Git仓库,跳过加载Git状态");return}try{Y.value=!0;const g=await(await fetch("/api/status")).json();g.status&&(A.value=g.status,l.value={staged:g.status.staged||[],unstaged:g.status.unstaged||[],untracked:g.status.untracked||[]}),await N()}catch($){console.error("获取Git状态失败:",$),c({message:`获取Git状态失败: ${$.message}`,type:"error"})}finally{Y.value=!1}}async function N(){if(console.log("开始获取Git状态(porcelain格式)..."),!le.isGitRepo){console.log("当前目录不是Git仓库,跳过加载Git状态");return}try{const g=await(await fetch("/api/status_porcelain")).json();g.status!==void 0?j(g.status):G.value=[]}catch($){console.error("获取Git状态(porcelain)失败:",$),c({message:`获取Git状态(porcelain)失败: ${$.message}`,type:"error"}),G.value=[]}}async function te(){if(!le.isGitRepo)return c.warning("当前目录不是Git仓库"),!1;try{F.value=!0;const g=await(await fetch("/api/add",{method:"POST"})).json();return g.success?(c({message:"文件已添加到暂存区",type:"success"}),M(),!0):(c({message:`添加文件失败: ${g.error}`,type:"error"}),!1)}catch($){return c({message:`添加文件失败: ${$.message}`,type:"error"}),!1}finally{F.value=!1}}async function J($){if(!le.isGitRepo)return c.warning("当前目录不是Git仓库"),!1;try{F.value=!0;const Z=await(await fetch("/api/add-file",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filePath:$})})).json();return Z.success?(c({message:"文件已暂存",type:"success"}),M(),!0):(c({message:`暂存文件失败: ${Z.error}`,type:"error"}),!1)}catch(g){return c({message:`暂存文件失败: ${g.message}`,type:"error"}),!1}finally{F.value=!1}}async function ue($){if(!le.isGitRepo)return c.warning("当前目录不是Git仓库"),!1;try{I.value=!0;const Z=await(await fetch("/api/unstage-file",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filePath:$})})).json();return Z.success?(c({message:"已取消暂存文件",type:"success"}),M(),!0):(c({message:`取消暂存失败: ${Z.error}`,type:"error"}),!1)}catch(g){return c({message:`取消暂存失败: ${g.message}`,type:"error"}),!1}finally{I.value=!1}}function H($){return new Promise(g=>setTimeout(g,$))}async function _($,g=!1){if(!le.isGitRepo)return c.warning("当前目录不是Git仓库"),!1;try{E.value=!0;const ne=await(await fetch("/api/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:$,hasNewlines:$.includes(`
3
- `),noVerify:g})})).json();return ne.success?(c({message:"提交成功",type:"success"}),M(),U(),!0):(c({message:`提交失败: ${ne.error}`,type:"error"}),!1)}catch(Z){return c({message:`提交失败: ${Z.message}`,type:"error"}),!1}finally{E.value=!1}}async function T(){if(!le.isGitRepo)return c.warning("当前目录不是Git仓库"),!1;try{D.value=!0;const g=await(await fetch("/api/push",{method:"POST"})).json();return g.success?(c({message:"推送成功",type:"success"}),M(),U(),!0):(c({message:`推送失败: ${g.error}`,type:"error"}),!1)}catch($){return c({message:`推送失败: ${$.message}`,type:"error"}),!1}finally{D.value=!1}}async function q($,g=!1){return await te()?(await H(tt),await _($,g)):!1}async function se($,g=!1){try{return!await te()||(await H(tt),!await _($,g))?!1:(await H(tt),await T())}catch(Z){try{(await(await fetch("/api/remove-lock",{method:"POST"})).json()).success&&c({message:"已清理锁定文件,请重试操作",type:"warning"})}catch(ne){console.error("清理锁定文件失败:",ne)}return c({message:`操作失败: ${Z.message}`,type:"error"}),!1}}async function ge(){if(!le.isGitRepo)return c.warning("当前目录不是Git仓库"),!1;try{I.value=!0;const g=await(await fetch("/api/reset-head",{method:"POST"})).json();return g.success?(c({message:"已重置暂存区",type:"success"}),M(),!0):(c({message:`重置暂存区失败: ${g.error}`,type:"error"}),!1)}catch($){return c({message:`重置暂存区失败: ${$.message}`,type:"error"}),!1}finally{I.value=!1}}async function ie($){if(!le.isGitRepo)return c.warning("当前目录不是Git仓库"),!1;try{I.value=!0;const Z=await(await fetch("/api/reset-to-remote",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({branch:$})})).json();return Z.success?(c({message:`已重置分支 ${$} 到远程状态`,type:"success"}),M(),U(),!0):(c({message:`重置分支失败: ${Z.error}`,type:"error"}),!1)}catch(g){return c({message:`重置分支失败: ${g.message}`,type:"error"}),!1}finally{I.value=!1}}return Ee(()=>{const $=localStorage.getItem("zen-gitsync-auto-update");$!==null&&(x.value=$==="true"),oe()}),bt(()=>{p&&(p.disconnect(),p=null)}),{log:h,status:l,statusText:A,fileList:G,isLoadingLog:ae,isLoadingStatus:Y,isAddingFiles:F,isResetting:I,isCommiting:E,isPushing:D,autoUpdateEnabled:x,fetchLog:U,fetchStatus:M,fetchStatusPorcelain:N,parseStatusPorcelain:j,addToStage:te,addFileToStage:J,unstageFile:ue,commitChanges:_,pushToRemote:T,addAndCommit:q,addCommitAndPush:se,resetHead:ge,resetToRemote:ie,toggleAutoUpdate:Q}}),Zt={class:"card"},Xt={class:"status-header"},Kt={class:"header-actions"},Qt={class:"card-content"},es={class:"current-directory"},ts={key:0,class:"status-box"},ss={class:"empty-status"},as={key:1},os={key:0,class:"branch-sync-status"},ls={class:"sync-status-content"},ns={class:"status-badges"},is={class:"badge-content"},rs={class:"badge-content"},cs={key:1,class:"git-status-message"},us={key:2,class:"file-list-container"},ds={key:0,class:"file-group"},fs={class:"file-list"},ps=["onClick"],vs={class:"file-info"},ms={class:"file-path-container"},gs={class:"file-name"},ys={class:"file-directory"},hs={class:"file-actions"},_s={key:1,class:"file-group"},ws={class:"file-list"},$s=["onClick"],ks={class:"file-info"},bs={class:"file-path-container"},Cs={class:"file-name"},Ss={class:"file-directory"},Ts={class:"file-actions"},Ls={key:2,class:"file-group"},Vs={class:"file-list"},Rs=["onClick"],xs={class:"file-info"},Bs={class:"file-path-container"},zs={class:"file-name"},Gs={class:"file-directory"},Ds={class:"file-actions"},As={key:3,class:"empty-status"},Es={class:"empty-icon"},js={class:"branch-info"},Us={key:0},Ps={key:0,class:"branch-sync-info warning"},Os={key:1,class:"branch-sync-info info"},Is={key:2,class:"branch-sync-info success"},Fs={class:"directory-buttons"},Ms={class:"browser-current-path"},Ns={key:0,class:"browser-error"},Hs={class:"directory-browser"},Ws={class:"browser-nav"},Js={class:"directory-items-container"},Ys={class:"directory-items"},qs=["onClick"],Zs={class:"diff-dialog-header"},Xs={class:"file-title"},Ks={class:"file-path"},Qs={class:"header-actions"},ea={class:"diff-content"},ta=["innerHTML"],sa={key:1,class:"no-diff"},aa={class:"file-navigation"},oa={class:"file-counter"},la=Ne({__name:"GitStatus",props:{initialDirectory:{type:String,default:""}},setup(le,{expose:p}){const x=le,h=rt(),l=Re(),A=Ae(()=>h.isLoadingStatus),G=u(""),ae=u(""),Y=u(!1),F=u(!1),E=u(-1),D=u(!1),I=u(""),oe=u(!1),Q=u(!1),j=u(""),U=u([]),M=u(!1),N=u(""),te=u(x.initialDirectory||"");async function J(){try{if(!te.value){const i=await(await fetch("/api/current_directory")).json();te.value=i.directory||"未知目录"}if(!l.isGitRepo)return;await h.fetchStatus(),await l.getBranchStatus(),c({message:"Git 状态已刷新",type:"success"})}catch(y){c({message:"刷新失败: "+y.message,type:"error"})}}function ue(y){if(!y)return"";const i=y.split(`
4
- `);function B(C){return C.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}return i.map(C=>{const z=B(C);return C.startsWith("diff --git")?`<div class="diff-header">${z}</div>`:C.startsWith("---")?`<div class="diff-old-file">${z}</div>`:C.startsWith("+++")?`<div class="diff-new-file">${z}</div>`:C.startsWith("@@")?`<div class="diff-hunk-header">${z}</div>`:C.startsWith("+")?`<div class="diff-added">${z}</div>`:C.startsWith("-")?`<div class="diff-removed">${z}</div>`:`<div class="diff-context">${z}</div>`}).join("")}async function H(y){try{F.value=!0,G.value=y,E.value=h.fileList.findIndex(B=>B.path===y);const i=h.fileList[E.value];if(i&&i.type==="untracked"){try{const C=await(await fetch(`/api/file-content?file=${encodeURIComponent(y)}`)).json();C.success&&C.content?ae.value=`diff --git a/${y} b/${y}
5
- 新文件: ${y}
6
- --- /dev/null
7
- +++ b/${y}
8
- @@ -0,0 +1,${C.content.split(`
9
- `).length} @@
10
- `+C.content.split(`
11
- `).map(z=>`+${z}`).join(`
12
- `):ae.value=`这是一个新文件,尚未被Git跟踪。
13
- 添加到暂存区后可以提交该文件。`}catch(B){console.error("获取未跟踪文件内容失败:",B),ae.value=`这是一个新文件,尚未被Git跟踪。
14
- 添加到暂存区后可以提交该文件。`}Y.value=!0}else{const C=await(await fetch(`/api/diff?file=${encodeURIComponent(y)}`)).json();ae.value=C.diff||"没有变更",Y.value=!0}}catch(i){c({message:"获取文件差异失败: "+i.message,type:"error"}),ae.value="获取差异失败: "+i.message}finally{F.value=!1}}async function _(){if(h.fileList.length===0||E.value<=0)return;const y=E.value-1,i=h.fileList[y];await H(i.path)}async function T(){if(h.fileList.length===0||E.value>=h.fileList.length-1)return;const y=E.value+1,i=h.fileList[y];await H(i.path)}function q(){I.value=te.value,D.value=!0}function se(){N.value="",j.value=I.value||te.value,Q.value=!0,ge(j.value)}async function ge(y){try{M.value=!0,N.value="";let i=y;/^[A-Za-z]:$/.test(i)&&(i+="/");const B=await fetch(`/api/browse_directory?path=${encodeURIComponent(i)}`);if(B.status===403){const z=await B.json();N.value=z.error||"目录浏览功能未启用";return}if(!B.ok){const z=await B.json();N.value=z.error||"获取目录内容失败";return}const C=await B.json();C.success?(U.value=C.items,j.value=C.currentPath):N.value=C.error||"获取目录内容失败"}catch(i){N.value=`获取目录内容失败: ${i.message}`}finally{M.value=!1}}function ie(){if(/^[A-Za-z]:$/.test(j.value)||/^[A-Za-z]:[\\/]$/.test(j.value)||j.value==="/")return;let y=j.value.split(/[/\\]/);y.pop();let i=y.join("/");y.length===1&&/^[A-Za-z]:$/.test(y[0])&&(i=y[0]+"/"),i&&ge(i)}function $(y){y.type==="directory"&&ge(y.path)}function g(){I.value=j.value,Q.value=!1}async function Z(){if(!I.value){c.warning("目录路径不能为空");return}try{oe.value=!0;const i=await(await fetch("/api/change_directory",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:I.value})})).json();i.success?(c.success("已切换工作目录"),te.value=i.directory,D.value=!1,l.isGitRepo=i.isGitRepo,i.isGitRepo?(await Promise.all([l.getCurrentBranch(),l.getAllBranches(),l.getUserInfo()]),await J()):(c.warning("当前目录不是一个Git仓库"),l.$reset())):c.error(i.error||"切换目录失败")}catch(y){c.error(`切换目录失败: ${y.message}`)}finally{oe.value=!1}}function ne(y){H(y.path)}async function ve(y){await h.addFileToStage(y)}async function pe(y){await h.unstageFile(y)}async function b(){await J()}async function r(y){try{await Fe.confirm(`确定要撤回文件 "${y}" 的所有修改吗?此操作无法撤销。`,"撤回修改",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"});const B=await(await fetch("/api/revert_file",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filePath:y})})).json();B.success?(c.success("已撤回文件修改"),await J()):c.error(B.error?`撤回失败: ${B.error}`:"撤回文件修改失败,请重试")}catch(i){if(i==="cancel"||i.message==="cancel")return;const B=i.message||"未知错误";B!=="undefined"?c.error(`撤回文件修改失败: ${B}`):c.error("撤回文件修改失败,请重试")}}function W(y){const i=y.split("/");return i[i.length-1]}function P(y){const i=y.split("/");return i.length<=1?"":i.slice(0,-1).join("/")}return Ee(()=>{J(),l.isGitRepo&&l.getBranchStatus()}),Ie(()=>h.autoUpdateEnabled,(y,i)=>{console.log(`自动更新状态变更: ${i} -> ${y}`),h.toggleAutoUpdate()},{immediate:!1}),p({refreshStatus:b}),(y,i)=>{const B=pt,C=ot,z=_e,X=He,re=vt,$e=St("ArrowDown"),K=Je,xe=gt,Ce=mt,Se=We,Ve=yt;return d(),m("div",Zt,[e("div",Xt,[i[6]||(i[6]=e("h2",null,"Git 状态",-1)),e("div",Kt,[t(C,{content:s(h).autoUpdateEnabled?"禁用自动更新文件状态":"启用自动更新文件状态",placement:"top","hide-after":1e3},{default:a(()=>[t(B,{modelValue:s(h).autoUpdateEnabled,"onUpdate:modelValue":i[0]||(i[0]=k=>s(h).autoUpdateEnabled=k),style:{"--el-switch-on-color":"#67C23A","--el-switch-off-color":"#909399","margin-right":"10px"},"inline-prompt":"","active-icon":s(at),"inactive-icon":s(Xe),class:"auto-update-switch"},null,8,["modelValue","active-icon","inactive-icon"])]),_:1},8,["content"]),t(C,{content:"刷新状态",placement:"top","hide-after":1e3},{default:a(()=>[t(z,{type:"primary",icon:s(Tt),circle:"",size:"small",onClick:b,loading:A.value},null,8,["icon","loading"])]),_:1})])]),e("div",Qt,[e("div",es,[t(X,null,{default:a(()=>[t(s(Ke))]),_:1}),e("span",null,L(te.value),1),t(z,{type:"primary",size:"small",onClick:q,plain:""},{default:a(()=>i[7]||(i[7]=[w(" 切换目录 ")])),_:1})]),s(l).isGitRepo?(d(),m("div",as,[s(l).hasUpstream&&(s(l).branchAhead>0||s(l).branchBehind>0)?(d(),m("div",os,[e("div",ls,[t(C,{content:"本地分支与远程分支的状态对比",placement:"top"},{default:a(()=>[e("div",ns,[s(l).branchAhead>0?(d(),de(re,{key:0,size:"small",type:"warning",class:"status-badge"},{default:a(()=>[e("span",is,[t(X,null,{default:a(()=>[t(s(Qe))]),_:1}),w(" 你的分支领先 'origin/"+L(s(l).currentBranch)+"' "+L(s(l).branchAhead)+" 个提交 ",1)])]),_:1})):ee("",!0),s(l).branchBehind>0?(d(),de(re,{key:1,size:"small",type:"info",class:"status-badge"},{default:a(()=>[e("span",rs,[t(X,null,{default:a(()=>[t($e)]),_:1}),w(" 你的分支落后 'origin/"+L(s(l).currentBranch)+"' "+L(s(l).branchBehind)+" 个提交 ",1)])]),_:1})):ee("",!0)])]),_:1})])])):ee("",!0),!s(l).hasUpstream||s(l).branchAhead===0&&s(l).branchBehind===0?(d(),m("div",cs,[e("p",null,[i[10]||(i[10]=w("当前工作在 ")),t(re,{size:"small",type:"success"},{default:a(()=>[w(L(s(l).currentBranch),1)]),_:1}),i[11]||(i[11]=w(" 分支"))])])):ee("",!0),s(h).fileList.length?(d(),m("div",us,[s(h).fileList.some(k=>k.type==="added")?(d(),m("div",ds,[i[13]||(i[13]=e("div",{class:"file-group-header"},"已暂存的更改",-1)),e("div",fs,[(d(!0),m(he,null,we(s(h).fileList.filter(k=>k.type==="added"),k=>(d(),m("div",{key:k.path,class:"file-item",onClick:v=>ne(k)},[e("div",vs,[e("div",ms,[e("span",gs,L(W(k.path)),1),e("span",ys,L(P(k.path)),1)])]),e("div",hs,[t(C,{content:"取消暂存",placement:"top","hide-after":1e3},{default:a(()=>[t(z,{type:"warning",size:"small",circle:"",onClick:Be(v=>pe(k.path),["stop"])},{default:a(()=>i[12]||(i[12]=[w("-")])),_:2},1032,["onClick"])]),_:2},1024)])],8,ps))),128))])])):ee("",!0),s(h).fileList.some(k=>k.type==="modified"||k.type==="deleted")?(d(),m("div",_s,[i[15]||(i[15]=e("div",{class:"file-group-header"},"未暂存的更改",-1)),e("div",ws,[(d(!0),m(he,null,we(s(h).fileList.filter(k=>k.type==="modified"||k.type==="deleted"),k=>(d(),m("div",{key:k.path,class:"file-item",onClick:v=>ne(k)},[e("div",ks,[e("div",{class:Le(["file-status-indicator",k.type])},null,2),e("div",bs,[e("span",Cs,L(W(k.path)),1),e("span",Ss,L(P(k.path)),1)])]),e("div",Ts,[t(C,{content:"添加到暂存区",placement:"top","hide-after":1e3},{default:a(()=>[t(z,{type:"success",size:"small",circle:"",onClick:Be(v=>ve(k.path),["stop"])},{default:a(()=>i[14]||(i[14]=[w("+")])),_:2},1032,["onClick"])]),_:2},1024),t(C,{content:"撤回修改",placement:"top","hide-after":1e3},{default:a(()=>[t(z,{type:"danger",size:"small",icon:s(lt),circle:"",onClick:Be(v=>r(k.path),["stop"])},null,8,["icon","onClick"])]),_:2},1024)])],8,$s))),128))])])):ee("",!0),s(h).fileList.some(k=>k.type==="untracked")?(d(),m("div",Ls,[i[18]||(i[18]=e("div",{class:"file-group-header"},"未跟踪的文件",-1)),e("div",Vs,[(d(!0),m(he,null,we(s(h).fileList.filter(k=>k.type==="untracked"),k=>(d(),m("div",{key:k.path,class:"file-item",onClick:v=>ne(k)},[e("div",xs,[i[16]||(i[16]=e("div",{class:"file-status-indicator untracked"},null,-1)),e("div",Bs,[e("span",zs,L(W(k.path)),1),e("span",Gs,L(P(k.path)),1)])]),e("div",Ds,[t(C,{content:"添加到暂存区",placement:"top","hide-after":1e3},{default:a(()=>[t(z,{type:"success",size:"small",circle:"",onClick:Be(v=>ve(k.path),["stop"])},{default:a(()=>i[17]||(i[17]=[w("+")])),_:2},1032,["onClick"])]),_:2},1024),t(C,{content:"删除文件",placement:"top","hide-after":1e3},{default:a(()=>[t(z,{type:"danger",size:"small",icon:s(Xe),circle:"",onClick:Be(v=>r(k.path),["stop"])},null,8,["icon","onClick"])]),_:2},1024)])],8,Rs))),128))])])):ee("",!0)])):s(l).isGitRepo?(d(),m("div",As,[e("div",Es,[t(X,null,{default:a(()=>[t(s(Oe))]),_:1})]),i[21]||(i[21]=e("div",{class:"empty-text"},"没有检测到任何更改",-1)),i[22]||(i[22]=e("div",{class:"empty-subtext"},"工作区是干净的",-1)),e("div",js,[e("p",null,[i[19]||(i[19]=w("当前工作在 ")),t(re,{size:"small",type:"success"},{default:a(()=>[w(L(s(l).currentBranch),1)]),_:1}),i[20]||(i[20]=w(" 分支"))]),s(l).hasUpstream?(d(),m("div",Us,[s(l).branchAhead>0?(d(),m("span",Ps,[t(X,null,{default:a(()=>[t(s(Qe))]),_:1}),w(" 你的分支领先 'origin/"+L(s(l).currentBranch)+"' "+L(s(l).branchAhead)+" 个提交 ",1)])):s(l).branchBehind>0?(d(),m("span",Os,[t(X,null,{default:a(()=>[t($e)]),_:1}),w(" 你的分支落后 'origin/"+L(s(l).currentBranch)+"' "+L(s(l).branchBehind)+" 个提交 ",1)])):(d(),m("span",Is,[t(X,null,{default:a(()=>[t(s(at))]),_:1}),w(" 你的分支与 'origin/"+L(s(l).currentBranch)+"' 同步 ",1)]))])):ee("",!0)])])):ee("",!0)])):(d(),m("div",ts,[e("div",ss,[i[9]||(i[9]=e("p",null,"当前目录不是Git仓库",-1)),t(z,{type:"primary",size:"small",onClick:q},{default:a(()=>i[8]||(i[8]=[w(" 切换目录 ")])),_:1})])]))]),t(Se,{modelValue:D.value,"onUpdate:modelValue":i[2]||(i[2]=k=>D.value=k),title:"切换工作目录",width:"500px"},{default:a(()=>[t(Ce,null,{default:a(()=>[t(xe,{label:"目录路径"},{default:a(()=>[t(K,{modelValue:I.value,"onUpdate:modelValue":i[1]||(i[1]=k=>I.value=k),placeholder:"请输入目录路径",clearable:""},null,8,["modelValue"]),e("div",Fs,[t(z,{onClick:se,type:"primary",plain:"",class:"no-padding-left"},{default:a(()=>[t(X,null,{default:a(()=>[t(s(Ke))]),_:1}),i[23]||(i[23]=w(" 浏览 "))]),_:1}),t(z,{onClick:Z,loading:oe.value,type:"primary"},{default:a(()=>i[24]||(i[24]=[w(" 切换 ")])),_:1},8,["loading"])])]),_:1})]),_:1})]),_:1},8,["modelValue"]),t(Se,{modelValue:Q.value,"onUpdate:modelValue":i[3]||(i[3]=k=>Q.value=k),title:"浏览目录",width:"600px"},{default:a(()=>[e("div",Ms,[e("span",null,"当前路径: "+L(j.value),1)]),N.value?(d(),m("div",Ns,L(N.value),1)):ee("",!0),De((d(),m("div",Hs,[e("div",Ws,[t(z,{onClick:ie,disabled:!j.value||M.value,size:"small",class:"no-padding-left"},{default:a(()=>[t(X,null,{default:a(()=>[t(s(Qe))]),_:1}),i[25]||(i[25]=w(" 上级目录 "))]),_:1},8,["disabled"]),t(z,{onClick:g,type:"primary",size:"small",class:"no-padding-left"},{default:a(()=>i[26]||(i[26]=[w(" 选择当前目录 ")])),_:1})]),e("div",Js,[e("ul",Ys,[(d(!0),m(he,null,we(U.value,k=>(d(),m("li",{key:k.path,class:Le(["directory-item",k.type]),onClick:v=>$(k)},[k.type==="directory"?(d(),de(X,{key:0},{default:a(()=>[t(s(Ke))]),_:1})):(d(),de(X,{key:1},{default:a(()=>[t(s(Oe))]),_:1})),e("span",null,L(k.name),1)],10,qs))),128))])])])),[[Ve,M.value]])]),_:1},8,["modelValue"]),t(Se,{modelValue:Y.value,"onUpdate:modelValue":i[5]||(i[5]=k=>Y.value=k),width:"85%",top:"5vh","destroy-on-close":"",class:"diff-dialog","show-close":!1,style:{height:"calc(100vh - 150px)"},"modal-append-to-body":!1,"close-on-click-modal":!1},{header:a(()=>[e("div",Zs,[e("div",Xs,[t(X,{class:"file-icon"},{default:a(()=>[t(s(Oe))]),_:1}),e("span",Ks,L(G.value),1)]),e("div",Qs,[t(z,{onClick:i[4]||(i[4]=k=>Y.value=!1),circle:"",size:"small",icon:s(Xe),class:"close-button"},null,8,["icon"])])])]),footer:a(()=>[e("div",aa,[t(z,{type:"primary",icon:s(Lt),onClick:_,disabled:E.value<=0||s(h).fileList.length===0,plain:"",class:"nav-button"},{default:a(()=>i[27]||(i[27]=[w(" 上一个文件 ")])),_:1},8,["icon","disabled"]),e("div",oa,[t(re,{type:"info",effect:"plain",class:"counter-tag"},{default:a(()=>[w(L(E.value+1)+" / "+L(s(h).fileList.length),1)]),_:1})]),t(z,{type:"primary",icon:s(ct),onClick:T,disabled:E.value>=s(h).fileList.length-1||s(h).fileList.length===0,plain:"",class:"nav-button"},{icon:a(()=>[t(X,{class:"el-icon--right"},{default:a(()=>[t(s(ct))]),_:1})]),default:a(()=>[i[28]||(i[28]=w(" 下一个文件 "))]),_:1},8,["icon","disabled"])])]),default:a(()=>[De((d(),m("div",ea,[ae.value?(d(),m("div",{key:0,innerHTML:ue(ae.value),class:"diff-formatted"},null,8,ta)):(d(),m("div",sa,"该文件没有差异或是新文件"))])),[[Ve,F.value]])]),_:1},8,["modelValue"])])}}}),Ye=(le,p)=>{const x=le.__vccOpts||le;for(const[h,l]of p)x[h]=l;return x},na=Ye(la,[["__scopeId","data-v-634304ba"]]),ia={key:0,class:"pushing-indicator"},ra={key:0,class:"push-success-indicator"},ca={class:"card-content"},ua={class:"layout-container"},da={key:0,class:"git-config-warning"},fa={class:"commit-section"},pa={class:"commit-options"},va={class:"options-row"},ma={class:"commit-mode-toggle"},ga={class:"no-verify-toggle"},ya={key:0,class:"commit-form"},ha={key:1,class:"standard-commit-form"},_a={class:"standard-commit-header"},wa={class:"scope-container"},$a={class:"description-container"},ka={class:"preview-section"},ba={class:"preview-content"},Ca={class:"preview-content code-command"},Sa={class:"actions-section"},Ta={class:"action-groups"},La={class:"operations-wrapper"},Va={class:"action-group"},Ra={class:"group-buttons"},xa={class:"action-group"},Ba={class:"group-buttons"},za={class:"action-group reset-group"},Ga={class:"group-buttons"},Da={class:"template-container"},Aa={class:"template-form"},Ea={class:"template-form-buttons"},ja={class:"template-list"},Ua={class:"template-content"},Pa={class:"template-actions"},Oa={class:"template-container"},Ia={class:"template-form"},Fa={class:"template-form-buttons"},Ma={class:"template-list"},Na={class:"template-content"},Ha={class:"template-actions"},Wa=Ne({__name:"CommitForm",setup(le){const p=rt(),x=Re(),h=u(""),l=u(!1),A=u(!1),G=u("输入提交信息..."),ae=u(""),Y=u(!1),F=u("feat"),E=u(""),D=u(""),I=u(""),oe=u(""),Q=u([]),j=u(!1),U=u(""),M=u(!1),N=u(""),te=u(-1),J=u([]),ue=u(!1),H=u(""),_=u(!1),T=u(""),q=u(-1),se=u(!1),ge=[{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: 构建/工具修改"}];Ie(Y,v=>{localStorage.setItem("zen-gitsync-standard-commit",v.toString())}),Ie(se,v=>{localStorage.setItem("zen-gitsync-skip-hooks",v.toString())});const ie=Ae(()=>{if(!Y.value)return h.value||ae.value;let v=`${F.value||""}`;return E.value&&(v+=`(${E.value})`),v+=`: ${D.value}`,I.value&&(v+=`
15
-
16
- ${I.value}`),oe.value&&(v+=`
17
-
18
- ${oe.value}`),v}),$=Ae(()=>{let v=`git commit -m "${ie.value}"`;return se.value&&(v+=" --no-verify"),v});async function g(){try{const n=await(await fetch("/api/config/getConfig")).json();G.value=`输入提交信息 (默认: ${n.defaultCommitMessage})`,ae.value=n.defaultCommitMessage||"",n.descriptionTemplates&&Array.isArray(n.descriptionTemplates)&&(Q.value=n.descriptionTemplates),n.scopeTemplates&&Array.isArray(n.scopeTemplates)&&(J.value=n.scopeTemplates)}catch(v){console.error("加载配置失败:",v)}}async function Z(){if(!U.value.trim()){c({message:"请输入模板内容",type:"warning"});return}try{if(M.value)await ne();else{if(Q.value.includes(U.value)){c({message:"该模板已存在",type:"warning"});return}Q.value.push(U.value);const n=await(await fetch("/api/config/save-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:U.value,type:"description"})})).json();n.success?(c({message:"模板保存成功!",type:"success"}),U.value=""):c({message:"模板保存失败: "+n.error,type:"error"})}}catch(v){c({message:"模板保存失败: "+v.message,type:"error"})}}async function ne(){try{if(te.value>=0){const v=N.value,n=U.value;Q.value[te.value]=n;const ye=await(await fetch("/api/config/update-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldTemplate:v,newTemplate:n,type:"description"})})).json();ye.success?(c({message:"模板更新成功!",type:"success"}),M.value=!1,N.value="",te.value=-1,U.value=""):c({message:"模板更新失败: "+ye.error,type:"error"})}}catch(v){c({message:"模板更新失败: "+v.message,type:"error"})}}function ve(v,n){M.value=!0,N.value=v,te.value=n,U.value=v}function pe(){M.value=!1,N.value="",te.value=-1,U.value=""}async function b(){if(!H.value.trim()){c({message:"请输入模板内容",type:"warning"});return}try{if(_.value)await r();else{if(J.value.includes(H.value)){c({message:"该模板已存在",type:"warning"});return}J.value.push(H.value);const n=await(await fetch("/api/config/save-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:H.value,type:"scope"})})).json();n.success?(c({message:"作用域模板保存成功!",type:"success"}),H.value=""):c({message:"作用域模板保存失败: "+n.error,type:"error"})}}catch(v){c({message:"作用域模板保存失败: "+v.message,type:"error"})}}async function r(){try{if(q.value>=0){const v=T.value,n=H.value;J.value[q.value]=n;const ye=await(await fetch("/api/config/update-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldTemplate:v,newTemplate:n,type:"scope"})})).json();ye.success?(c({message:"作用域模板更新成功!",type:"success"}),_.value=!1,T.value="",q.value=-1,H.value=""):c({message:"作用域模板更新失败: "+ye.error,type:"error"})}}catch(v){c({message:"作用域模板更新失败: "+v.message,type:"error"})}}function W(v,n){_.value=!0,T.value=v,q.value=n,H.value=v}function P(){_.value=!1,T.value="",q.value=-1,H.value=""}async function y(v){try{const n=Q.value.indexOf(v);n!==-1&&Q.value.splice(n,1);const ye=await(await fetch("/api/config/delete-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:v,type:"description"})})).json();ye.success?c({message:"模板删除成功!",type:"success"}):c({message:"模板删除失败: "+ye.error,type:"error"})}catch(n){c({message:"模板删除失败: "+n.message,type:"error"})}}async function i(v){try{const n=J.value.indexOf(v);n!==-1&&J.value.splice(n,1);const ye=await(await fetch("/api/config/delete-template",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({template:v,type:"scope"})})).json();ye.success?c({message:"作用域模板删除成功!",type:"success"}):c({message:"作用域模板删除失败: "+ye.error,type:"error"})}catch(n){c({message:"作用域模板删除失败: "+n.message,type:"error"})}}function B(v){D.value=v,j.value=!1}function C(v){E.value=v,ue.value=!1}function z(){j.value=!0}function X(){ue.value=!0}async function re(){try{await p.addToStage()&&p.fetchStatus()}catch(v){c({message:`添加文件失败: ${v.message}`,type:"error"})}}async function $e(){if(!ie.value.trim()){c({message:"提交信息不能为空",type:"warning"});return}try{await p.commitChanges(ie.value,se.value)&&(k(),p.fetchStatus(),p.fetchLog())}catch(v){c({message:`提交失败: ${v.message}`,type:"error"})}}function K(){A.value=!0,setTimeout(()=>{A.value=!1},2e3)}async function xe(){try{l.value=!0,await p.pushToRemote()&&(x.getCurrentBranch(),p.fetchLog(),l.value=!1,K())}catch(v){c({message:`推送失败: ${v.message}`,type:"error"}),l.value=!1}}async function Ce(){if(!ie.value.trim()){c({message:"提交信息不能为空",type:"warning"});return}try{await p.addAndCommit(ie.value,se.value),k(),p.fetchStatus(),p.fetchLog()}catch(v){c({message:`暂存并提交失败: ${v.message}`,type:"error"})}}async function Se(){if(!ie.value.trim()){c({message:"提交信息不能为空",type:"warning"});return}try{l.value=!0,await p.addCommitAndPush(ie.value,se.value),k(),x.getCurrentBranch(),p.fetchLog(),l.value=!1,K()}catch(v){c({message:`暂存、提交并推送失败: ${v.message}`,type:"error"}),l.value=!1}}async function Ve(){try{await Fe.confirm(`确定要重置当前分支 "${x.currentBranch}" 到远程状态吗?这将丢失所有未推送的提交和本地更改。`,"重置到远程分支",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}),await p.resetToRemote(x.currentBranch)&&(p.fetchStatus(),p.fetchLog())}catch(v){v!=="cancel"&&c({message:`重置到远程分支失败: ${v.message}`,type:"error"})}}function k(){h.value="",D.value="",I.value="",oe.value=""}return Ee(()=>{g();const v=localStorage.getItem("zen-gitsync-standard-commit");v!==null&&(Y.value=v==="true");const n=localStorage.getItem("zen-gitsync-skip-hooks");n!==null&&(se.value=n==="true")}),(v,n)=>{const Te=He,ye=ht,je=pt,ke=ot,be=Je,qe=nt,Ze=it,fe=_e,f=_t,o=Bt,R=wt,V=We;return d(),m("div",{class:Le(["card",{"is-pushing":s(p).isPushing||l.value}])},[n[38]||(n[38]=e("div",{class:"card-header"},[e("h2",null,"提交更改")],-1)),t(ut,{name:"el-fade-in-linear"},{default:a(()=>[l.value?(d(),m("div",ia,n[12]||(n[12]=[e("div",{class:"pushing-spinner"},[e("svg",{viewBox:"0 0 50 50",class:"circular"},[e("circle",{class:"path",cx:"25",cy:"25",r:"20",fill:"none"})])],-1),e("div",{class:"pushing-text"},"正在推送...",-1)]))):ee("",!0)]),_:1}),t(ut,{name:"el-fade-in-linear"},{default:a(()=>[A.value?(d(),m("div",ra,[t(Te,{class:"push-success-icon"},{default:a(()=>[t(s(at))]),_:1}),n[13]||(n[13]=e("div",{class:"push-success-text"},"推送成功!",-1))])):ee("",!0)]),_:1}),e("div",ca,[e("div",ua,[s(x).userName===""||s(x).userEmail===""?(d(),m("div",da,[t(ye,{title:"Git用户信息未配置",type:"warning",closable:!1,"show-icon":""},{default:a(()=>n[14]||(n[14]=[e("p",null,"您需要配置Git用户名和邮箱才能提交代码。请使用以下命令配置:",-1),e("pre",{class:"config-command"},`git config --global user.name "Your Name"
19
- git config --global user.email "your.email@example.com"`,-1)])),_:1})])):(d(),m(he,{key:1},[e("div",fa,[e("div",pa,[e("div",va,[e("div",ma,[t(je,{modelValue:Y.value,"onUpdate:modelValue":n[0]||(n[0]=S=>Y.value=S),"active-text":"标准化提交","inactive-text":"普通提交"},null,8,["modelValue"])]),e("div",ga,[t(ke,{content:"跳过 Git 钩子检查 (--no-verify)",placement:"top"},{default:a(()=>[t(je,{modelValue:se.value,"onUpdate:modelValue":n[1]||(n[1]=S=>se.value=S),"active-text":"跳过钩子 (--no-verify)"},null,8,["modelValue"])]),_:1})])])]),Y.value?(d(),m("div",ha,[e("div",_a,[t(Ze,{modelValue:F.value,"onUpdate:modelValue":n[3]||(n[3]=S=>F.value=S),placeholder:"提交类型",class:"type-select",clearable:""},{default:a(()=>[(d(),m(he,null,we(ge,S=>t(qe,{key:S.value,label:S.label,value:S.value},null,8,["label","value"])),64))]),_:1},8,["modelValue"]),e("div",wa,[t(be,{modelValue:E.value,"onUpdate:modelValue":n[4]||(n[4]=S=>E.value=S),placeholder:"作用域(可选)",class:"scope-input",clearable:""},null,8,["modelValue"]),t(fe,{type:"primary",icon:s(Me),circle:"",size:"small",class:"settings-button",onClick:X},null,8,["icon"])]),e("div",$a,[t(be,{modelValue:D.value,"onUpdate:modelValue":n[5]||(n[5]=S=>D.value=S),placeholder:"简短描述(必填)",class:"description-input",clearable:""},null,8,["modelValue"]),t(fe,{type:"primary",icon:s(Me),circle:"",size:"small",class:"settings-button",onClick:z},null,8,["icon"])])]),t(be,{modelValue:I.value,"onUpdate:modelValue":n[6]||(n[6]=S=>I.value=S),type:"textarea",rows:4,placeholder:"正文(可选):详细描述本次提交的内容和原因",class:"body-input",clearable:""},null,8,["modelValue"]),t(be,{modelValue:oe.value,"onUpdate:modelValue":n[7]||(n[7]=S=>oe.value=S),placeholder:"页脚(可选):如 Closes #123",class:"footer-input",clearable:""},null,8,["modelValue"]),e("div",ka,[n[15]||(n[15]=e("div",{class:"preview-title"},"提交信息预览:",-1)),e("pre",ba,L(ie.value),1),n[16]||(n[16]=e("div",{class:"preview-title",style:{"margin-top":"10px"}},"Git命令预览:",-1)),e("pre",Ca,L($.value),1)])])):(d(),m("div",ya,[t(be,{modelValue:h.value,"onUpdate:modelValue":n[2]||(n[2]=S=>h.value=S),placeholder:G.value,clearable:""},null,8,["modelValue","placeholder"])]))]),e("div",Sa,[n[27]||(n[27]=e("h3",null,"Git 操作",-1)),e("div",Ta,[e("div",La,[e("div",Va,[n[20]||(n[20]=e("div",{class:"group-title"},"基础操作",-1)),e("div",Ra,[t(ke,{content:"git add .",placement:"top",effect:"light","popper-class":"git-cmd-tooltip"},{default:a(()=>[t(fe,{type:"primary",onClick:re,loading:s(p).isAddingFiles,class:"action-button"},{default:a(()=>n[17]||(n[17]=[w(" 暂存更改 ")])),_:1},8,["loading"])]),_:1}),t(ke,{content:"git commit",placement:"top",effect:"light","popper-class":"git-cmd-tooltip"},{default:a(()=>[t(fe,{type:"primary",onClick:$e,loading:s(p).isLoadingStatus,class:"action-button"},{default:a(()=>n[18]||(n[18]=[w(" 提交 ")])),_:1},8,["loading"])]),_:1}),t(ke,{content:"git push",placement:"top",effect:"light","popper-class":"git-cmd-tooltip"},{default:a(()=>[t(fe,{type:"primary",icon:s(Vt),onClick:xe,loading:s(p).isPushing,class:Le(["action-button","push-button",{"is-loading":s(p).isPushing||l.value}])},{default:a(()=>n[19]||(n[19]=[w(" 推送 ")])),_:1},8,["icon","loading","class"])]),_:1})])]),e("div",xa,[n[23]||(n[23]=e("div",{class:"group-title"},"组合操作",-1)),e("div",Ba,[t(ke,{content:"git add + git commit",placement:"top",effect:"light","popper-class":"git-cmd-tooltip"},{default:a(()=>[t(fe,{type:"primary",icon:s(et),onClick:Ce,loading:s(p).isAddingFiles||s(p).isCommiting,class:"action-button"},{default:a(()=>n[21]||(n[21]=[w(" 暂存并提交 ")])),_:1},8,["icon","loading"])]),_:1}),t(ke,{content:"git add + git commit + git push",placement:"top",effect:"light","popper-class":"git-cmd-tooltip"},{default:a(()=>[t(fe,{type:"success",icon:s(Rt),onClick:Se,loading:s(p).isAddingFiles||s(p).isCommiting||s(p).isPushing,class:Le(["action-button","one-click-push",{"is-loading":s(p).isAddingFiles||s(p).isCommiting||s(p).isPushing}])},{default:a(()=>n[22]||(n[22]=[w(" 一键推送 ")])),_:1},8,["icon","loading","class"])]),_:1})])])]),e("div",za,[n[26]||(n[26]=e("div",{class:"group-title"},"重置操作",-1)),e("div",Ga,[t(ke,{content:"git reset HEAD",placement:"top",effect:"light","popper-class":"git-cmd-tooltip"},{default:a(()=>[t(fe,{type:"warning",icon:s(lt),onClick:s(p).resetHead,loading:s(p).isResetting,class:"action-button reset-button"},{default:a(()=>n[24]||(n[24]=[w(" 重置暂存区 ")])),_:1},8,["icon","onClick","loading"])]),_:1}),t(ke,{content:"git reset --hard origin/branch",placement:"top",effect:"light","popper-class":"git-cmd-tooltip"},{default:a(()=>[t(fe,{type:"danger",icon:s(xt),onClick:Ve,loading:s(p).isResetting,class:"action-button danger-button"},{default:a(()=>n[25]||(n[25]=[w(" 重置到远程 ")])),_:1},8,["icon","loading"])]),_:1})])])])])],64))]),t(V,{title:"简短描述模板设置",modelValue:j.value,"onUpdate:modelValue":n[9]||(n[9]=S=>j.value=S),width:"80vw",style:{height:"80vh"}},{default:a(()=>[e("div",Da,[e("div",Aa,[t(be,{modelValue:U.value,"onUpdate:modelValue":n[8]||(n[8]=S=>U.value=S),placeholder:M.value?"编辑模板内容":"输入新模板内容",class:"template-input",clearable:""},null,8,["modelValue","placeholder"]),e("div",Ea,[M.value?(d(),de(fe,{key:0,onClick:pe},{default:a(()=>n[28]||(n[28]=[w("取消")])),_:1})):ee("",!0),t(fe,{type:"primary",onClick:Z,disabled:!U.value.trim()},{default:a(()=>[w(L(M.value?"更新模板":"添加模板"),1)]),_:1},8,["disabled"])])]),e("div",ja,[n[32]||(n[32]=e("h3",null,"已保存模板",-1)),Q.value.length===0?(d(),de(f,{key:0,description:"暂无保存的模板"})):ee("",!0),(d(!0),m(he,null,we(Q.value,(S,ce)=>(d(),de(R,{key:ce,class:"template-item"},{default:a(()=>[t(o,{justify:"space-between",align:"middle",style:{width:"100%"}},{default:a(()=>[e("div",Ua,L(S),1),e("div",Pa,[t(fe,{type:"primary",size:"small",onClick:me=>B(S)},{default:a(()=>n[29]||(n[29]=[w("使用")])),_:2},1032,["onClick"]),t(fe,{type:"warning",size:"small",icon:s(et),onClick:me=>ve(S,ce)},{default:a(()=>n[30]||(n[30]=[w("编辑")])),_:2},1032,["icon","onClick"]),t(fe,{type:"danger",size:"small",onClick:me=>y(S)},{default:a(()=>n[31]||(n[31]=[w("删除")])),_:2},1032,["onClick"])])]),_:2},1024)]),_:2},1024))),128))])])]),_:1},8,["modelValue"]),t(V,{title:"作用域模板设置",modelValue:ue.value,"onUpdate:modelValue":n[11]||(n[11]=S=>ue.value=S),width:"80%",style:{height:"80vh"}},{default:a(()=>[e("div",Oa,[e("div",Ia,[t(be,{modelValue:H.value,"onUpdate:modelValue":n[10]||(n[10]=S=>H.value=S),placeholder:_.value?"编辑作用域模板内容":"输入新作用域模板",class:"template-input",clearable:""},null,8,["modelValue","placeholder"]),e("div",Fa,[_.value?(d(),de(fe,{key:0,onClick:P},{default:a(()=>n[33]||(n[33]=[w("取消")])),_:1})):ee("",!0),t(fe,{type:"primary",onClick:b,disabled:!H.value.trim()},{default:a(()=>[w(L(_.value?"更新模板":"添加模板"),1)]),_:1},8,["disabled"])])]),e("div",Ma,[n[37]||(n[37]=e("h3",null,"已保存作用域",-1)),J.value.length===0?(d(),de(f,{key:0,description:"暂无保存的作用域"})):ee("",!0),(d(!0),m(he,null,we(J.value,(S,ce)=>(d(),de(R,{key:ce,class:"template-item"},{default:a(()=>[t(o,{justify:"space-between",align:"middle",style:{width:"100%"}},{default:a(()=>[e("div",Na,L(S),1),e("div",Ha,[t(fe,{type:"primary",size:"small",onClick:me=>C(S)},{default:a(()=>n[34]||(n[34]=[w("使用")])),_:2},1032,["onClick"]),t(fe,{type:"warning",size:"small",icon:s(et),onClick:me=>W(S,ce)},{default:a(()=>n[35]||(n[35]=[w("编辑")])),_:2},1032,["icon","onClick"]),t(fe,{type:"danger",size:"small",onClick:me=>i(S)},{default:a(()=>n[36]||(n[36]=[w("删除")])),_:2},1032,["onClick"])])]),_:2},1024)]),_:2},1024))),128))])])]),_:1},8,["modelValue"])])],2)}}}),Ja=Ye(Wa,[["__scopeId","data-v-4745d233"]]),Ya={class:"card"},qa={key:0,class:"refresh-notification"},Za={class:"log-header"},Xa={class:"log-actions"},Ka={key:1,class:"filter-panel-header"},Qa={class:"filter-form"},eo={class:"filter-item"},to={class:"filter-item"},so={class:"filter-item"},ao={class:"filter-actions"},oo={key:0},lo={key:1},no={key:0,class:"graph-view"},io={key:0,class:"commit-count"},ro={class:"graph-controls"},co={class:"zoom-controls"},uo={class:"scale-info"},fo={key:1,class:"table-view-container"},po=["onClick"],vo={class:"author-name"},mo={key:0,class:"branch-container"},go={key:0,class:"load-more-container"},yo={class:"pagination-info"},ho={key:0,class:"loading-more"},_o={key:2,class:"no-more-data"},wo={key:0,class:"total-loaded"},$o={class:"commit-detail-container"},ko={key:0,class:"commit-info"},bo={class:"commit-info-header"},Co={class:"info-item"},So={class:"item-value"},To={class:"info-item"},Lo={class:"item-value"},Vo={class:"info-item"},Ro={class:"item-value"},xo={class:"commit-message-container"},Bo=["innerHTML"],zo={class:"commit-files-diff"},Go={class:"files-list"},Do={key:1},Ao=["onClick"],Eo={class:"file-diff"},jo={key:0},Uo={key:1},Po=["innerHTML"],Ge=.5,Pe=1.5,st=.1,Oo=Ne({__name:"LogList",setup(le,{expose:p}){const x=rt(),h=Re();let l=[];const A=u(l),G=u(""),ae=u(!1),Y=Ae(()=>x.isLoadingLog||ae.value),F=u(!1),E=u(0),D=u(!1),I=u(null),oe=u(1),Q=u(!0),j=u(!1),U=u(null),M=u(!1),N=u(null),te=u([]),J=u(""),ue=u(!1),H=u(""),_=u(1),T=u(!1),q=u(!1),se=u([]),ge=u(""),ie=u(null),$=u([]),g=u(!1),Z=u(0),ne=u(0),ve=u(null),pe=Ae(()=>A.value);async function b(f=!1,o=1){if(!Re().isGitRepo){G.value="当前目录不是Git仓库";return}try{o>1?j.value=!0:ae.value=!0,console.log(`加载提交历史: page=${o}, all=${f}`);const V=new URLSearchParams;V.append("page",o.toString()),V.append("all",f.toString()),se.value.length>0&&V.append("author",se.value.join(",")),ge.value&&V.append("message",ge.value),ie.value&&Array.isArray(ie.value)&&ie.value.length===2&&(V.append("dateFrom",ie.value[0]),V.append("dateTo",ie.value[1])),V.append("_t",Date.now().toString());const ce=await(await fetch(`/api/log?${V.toString()}`)).json();if(!ce||!ce.data||!Array.isArray(ce.data)){console.error("API返回的数据格式不正确:",ce),G.value="加载提交历史失败: 服务器返回数据格式不正确";return}const me=o>1;me?ce.data.forEach(O=>l.push(O)):(l.length=0,ce.data.forEach(O=>l.push(O))),A.value=[...l],oe.value=o,E.value=ce.total||l.length,Q.value=ce.hasMore===!0,Q.value||console.log("已加载所有提交记录"),me||(T.value=!0,setTimeout(()=>{T.value=!1},2e3)),!me&&D.value&&setTimeout(r,0),G.value=""}catch(V){G.value="加载提交历史失败: "+(V instanceof Error?V.message:String(V)),console.error("加载日志失败:",V),o>1&&(Q.value=!1)}finally{o>1?j.value=!1:ae.value=!1}}async function r(){if(console.log(`开始渲染图表...数据长度: ${l.length}`),!I.value){console.error("图表容器未找到");return}if(l.length===0){console.error("没有日志数据可渲染");return}try{I.value.innerHTML="",console.log(`创建gitgraph实例,分支: ${h.currentBranch||"main"}`);const f=Wt(I.value,{orientation:"vertical-reverse",template:"metro",author:"提交者 <committer@example.com>"}),o={},R=f.branch(h.currentBranch||"main");o[h.currentBranch||"main"]=R,console.log(`开始创建提交图...共${l.length}条提交`),l.forEach((V,S)=>{let ce=R;if(V.branch){const me=y(V.branch.split(",")[0]);o[me]||(o[me]=f.branch(me)),ce=o[me]}ce.commit({hash:V.hash,subject:V.message,author:`${V.author} <${V.email}>`}),S%10===0&&console.log(`已渲染 ${S+1}/${l.length} 个提交`)}),console.log("图表渲染完成"),setTimeout(()=>{Se()},100)}catch(f){console.error("渲染图表失败:",f),G.value="渲染图表失败: "+(f instanceof Error?f.message:String(f))}}function W(){D.value=!D.value,D.value&&l.length>0&&setTimeout(r,0)}function P(){b(!F.value)}function y(f){return f.includes("HEAD -> ")?f.replace("HEAD -> ",""):f.includes("origin/")?f:f.trim()}function i(f){return f.includes("HEAD")?"success":f.includes("origin/")?"warning":"info"}const B=u(null),C=u(null);function z(f){if(D.value||!Q.value||j.value||Y.value)return;const o=f.target,{scrollTop:R,scrollHeight:V,clientHeight:S}=o,ce=V-R-S;console.log("表格滚动:",{scrollTop:R,scrollHeight:V,clientHeight:S,scrollDistance:ce}),ce<=20&&(console.log("已滚动到底部,加载更多数据"),Te())}function X(){B.value&&(C.value=B.value.$el.querySelector(".el-table__body-wrapper"),C.value?(console.log("添加表格滚动监听"),C.value.addEventListener("scroll",z,!0)):console.error("未找到表格的body-wrapper元素"))}function re(){C.value&&(console.log("移除表格滚动监听"),C.value.removeEventListener("scroll",z,!0),C.value=null)}Ee(()=>{h.isGitRepo?(x.log.length>0?(console.log("使用已加载的日志数据"),l.length=0,x.log.forEach(f=>l.push(f)),E.value=x.log.length,D.value&&setTimeout(()=>{console.log(`准备渲染图表,数据长度: ${l.length}`),r()},100)):(console.log("初始加载日志数据"),b()),ke()):G.value="当前目录不是Git仓库",zt(()=>{setTimeout(()=>{X()},500)})}),Gt(()=>{re(),U.value!==null&&(window.clearInterval(U.value),U.value=null)});const $e=()=>{if(!h.isGitRepo){G.value="当前目录不是Git仓库";return}oe.value=1,Q.value=!0,b(F.value,1)};Ie(()=>x.log,f=>{console.log("监听到gitLogStore.log变化,更新图表数据");try{l.length=0,Array.isArray(f)&&f.forEach(o=>o&&l.push(o)),E.value=l.length,oe.value=1,A.value=[...l],T.value=!0,setTimeout(()=>{T.value=!1},2e3),console.log(`数据更新完成,共${A.value.length}条记录,准备渲染图表`),D.value&&l.length>0&&setTimeout(r,0)}catch(o){console.error("更新日志数据失败:",o)}},{immediate:!0}),p({refreshLog:$e});function K(){_.value<Pe&&(_.value=Math.min(Pe,_.value+st),Ce())}function xe(){_.value>Ge&&(_.value=Math.max(Ge,_.value-st),Ce())}function Ce(){if(!I.value)return;const f=I.value.querySelector("svg");f&&(f.style.transform=`scale(${_.value})`,f.style.transformOrigin="top left")}function Se(){if(!I.value)return;const f=I.value.querySelector("svg");if(!f)return;const o=f.getBoundingClientRect().width/_.value,R=I.value.clientWidth;o>R?_.value=Math.max(Ge,R/o):_.value=1,Ce()}async function Ve(f){if(f){N.value=f,M.value=!0,ue.value=!0,te.value=[],J.value="",H.value="",console.log("提交详情对象:",JSON.stringify(f,null,2)),console.log("哈希值类型和长度:",typeof f.hash,f.hash?f.hash.length:0),console.log("提交信息类型和长度:",typeof f.message,f.message?f.message.length:0),console.log("提交分支:",f.branch);try{if(console.log(`获取提交详情: ${f.hash}`),!f.hash||f.hash.length<7){console.error("无效的提交哈希值:",f.hash),J.value="无效的提交哈希值",ue.value=!1;return}const o=await fetch(`/api/commit-files?hash=${f.hash}`);console.log("API响应状态: ",o.status);const R=await o.json();console.log("文件列表数据: ",R),R.success&&Array.isArray(R.files)?(te.value=R.files,te.value.length>0?await k(f.hash,te.value[0]):(console.log("没有找到变更文件"),J.value="该提交没有变更文件")):(console.error("获取提交文件列表失败:",R.error||"未知错误"),J.value=`获取文件列表失败: ${R.error||"未知错误"}`)}catch(o){console.error("获取提交详情失败:",o),J.value=`获取提交详情失败: ${o.message}`}finally{ue.value=!1}}}async function k(f,o){ue.value=!0,H.value=o;try{console.log(`获取文件差异: hash=${f}, file=${o}`);const R=await fetch(`/api/commit-file-diff?hash=${f}&file=${encodeURIComponent(o)}`);console.log("差异API响应状态: ",R.status);const V=await R.json();console.log("差异数据: ",V.success,typeof V.diff),V.success?J.value=V.diff||"没有变更内容":(console.error("获取差异失败: ",V.error),J.value=`获取差异失败: ${V.error||"未知错误"}`)}catch(R){console.error("获取文件差异失败:",R),J.value=`获取差异失败: ${R.message}`}finally{ue.value=!1}}function v(f){if(!f)return"";const o=f.split(`
20
- `);function R(V){return V.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}return o.map(V=>{const S=R(V);return V.startsWith("diff --git")?`<div class="diff-header">${S}</div>`:V.startsWith("---")?`<div class="diff-old-file">${S}</div>`:V.startsWith("+++")?`<div class="diff-new-file">${S}</div>`:V.startsWith("@@")?`<div class="diff-hunk-header">${S}</div>`:V.startsWith("+")?`<div class="diff-added">${S}</div>`:V.startsWith("-")?`<div class="diff-removed">${S}</div>`:`<div class="diff-context">${S}</div>`}).join("")}function n(f){return f?(console.log("格式化前的提交信息:",f),console.log("提交信息中的换行符数量:",(f.match(/\n/g)||[]).length),f.trim()):"(无提交信息)"}function Te(){!Q.value||j.value||Y.value||(console.log(`加载更多日志,页码: ${oe.value+1}`),b(F.value,oe.value+1))}function ye(){se.value=[],ge.value="",ie.value=null,oe.value=1,b(F.value,1)}function je(){oe.value=1,b(F.value,1)}async function ke(){try{console.log("获取所有可用作者...");const o=await(await fetch("/api/authors")).json();o.success&&Array.isArray(o.authors)?($.value=o.authors.sort(),console.log(`获取到${$.value.length}位作者`)):(console.warn("从API获取作者列表失败,将从现有日志中提取作者列表"),be())}catch(f){console.error("获取作者列表失败:",f),be()}}function be(){const f=new Set;A.value.forEach(o=>{o.author&&f.add(o.author)}),$.value=Array.from(f).sort(),console.log(`从现有日志中提取了${$.value.length}位作者`)}function qe(f,o,R){console.log("handleContextMenu",f,o,R),R.preventDefault(),Z.value=R.clientY,ne.value=R.clientX,ve.value=f,g.value=!0;const V=()=>{g.value=!1,document.removeEventListener("click",V)};setTimeout(()=>{document.addEventListener("click",V)},0)}async function Ze(f){if(f)try{await Fe.confirm(`确定要撤销提交 ${f.hash.substring(0,7)} 吗?这将创建一个新的提交来撤销这次提交的更改。`,"撤销提交确认",{confirmButtonText:"确认",cancelButtonText:"取消",type:"warning"});const R=await(await fetch("/api/revert-commit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hash:f.hash})})).json();R.success?(c.success(R.message||"已成功撤销提交"),$e(),x.fetchStatus(),h.getBranchStatus()):c.error(R.error||"撤销提交失败")}catch(o){o!=="cancel"&&(console.error("撤销提交出错:",o),c.error("撤销提交失败: "+(o.message||o)))}}async function fe(f){if(f)try{await Fe.confirm(`确定要将提交 ${f.hash.substring(0,7)} Cherry-Pick 到当前分支吗?`,"Cherry-Pick确认",{confirmButtonText:"确认",cancelButtonText:"取消",type:"warning"});const R=await(await fetch("/api/cherry-pick-commit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hash:f.hash})})).json();R.success?(c.success(R.message||"已成功Cherry-Pick提交"),$e(),x.fetchStatus(),h.getBranchStatus()):c.error(R.error||"Cherry-Pick提交失败")}catch(o){o!=="cancel"&&(console.error("Cherry-Pick提交出错:",o),c.error("Cherry-Pick提交失败: "+(o.message||o)))}}return(f,o)=>{var me;const R=He,V=ot,S=_t,ce=yt;return d(),m(he,null,[e("div",Ya,[T.value?(d(),m("div",qa," 提交历史已刷新 ")):ee("",!0),e("div",Za,[o[11]||(o[11]=e("div",{class:"header-left"},[e("h2",null,"提交历史")],-1)),e("div",Xa,[D.value?ee("",!0):(d(),de(s(_e),{key:0,type:q.value?"primary":"default",size:"small",onClick:o[0]||(o[0]=O=>q.value=!q.value)},{icon:a(()=>[t(R,null,{default:a(()=>[t(s(At))]),_:1})]),default:a(()=>[o[10]||(o[10]=w(" 筛选 ")),pe.value.length!==A.value.length?(d(),de(s(Dt),{key:0,value:pe.value.length,class:"filter-badge"},null,8,["value"])):ee("",!0)]),_:1},8,["type"])),t(s(_e),{type:"primary",size:"small",onClick:W},{icon:a(()=>[t(R,null,{default:a(()=>[(d(),de(dt(D.value?s(Oe):s(Et))))]),_:1})]),default:a(()=>[w(" "+L(D.value?"表格视图":"图表视图"),1)]),_:1}),t(s(_e),{type:"primary",size:"small",onClick:P,loading:Y.value},{icon:a(()=>[t(R,null,{default:a(()=>[(d(),de(dt(F.value?s(jt):s(Ut))))]),_:1})]),default:a(()=>[w(" "+L(F.value?"显示分页加载 (每页100条)":"显示所有提交"),1)]),_:1},8,["loading"]),t(s(_e),{circle:"",size:"small",onClick:o[1]||(o[1]=O=>$e()),loading:Y.value,class:Le({"refresh-button-animated":T.value})},{default:a(()=>[t(R,null,{default:a(()=>[t(s(lt))]),_:1})]),_:1},8,["loading","class"])])]),q.value&&!D.value?(d(),m("div",Ka,[e("div",Qa,[e("div",eo,[o[12]||(o[12]=e("div",{class:"filter-label"},"作者:",-1)),t(s(it),{modelValue:se.value,"onUpdate:modelValue":o[2]||(o[2]=O=>se.value=O),placeholder:"选择作者",multiple:"",clearable:"",filterable:"",class:"filter-input",size:"small"},{default:a(()=>[(d(!0),m(he,null,we($.value,O=>(d(),de(s(nt),{key:O,label:O,value:O},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),e("div",to,[o[13]||(o[13]=e("div",{class:"filter-label"},"提交信息包含:",-1)),t(s(Je),{modelValue:ge.value,"onUpdate:modelValue":o[3]||(o[3]=O=>ge.value=O),placeholder:"关键词",clearable:"",class:"filter-input",size:"small"},null,8,["modelValue"])]),e("div",so,[o[14]||(o[14]=e("div",{class:"filter-label"},"日期范围:",-1)),t(s(Pt),{modelValue:ie.value,"onUpdate:modelValue":o[4]||(o[4]=O=>ie.value=O),type:"daterange","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期",format:"YYYY-MM-DD","value-format":"YYYY-MM-DD",class:"filter-input date-range",size:"small"},null,8,["modelValue"])]),e("div",ao,[t(s(_e),{type:"primary",size:"small",onClick:je},{default:a(()=>o[15]||(o[15]=[w("应用筛选")])),_:1}),t(s(_e),{type:"info",size:"small",onClick:ye},{default:a(()=>o[16]||(o[16]=[w("重置")])),_:1})])])])):ee("",!0),e("div",{class:Le(["content-area",{"with-filter":q.value&&!D.value}])},[G.value?(d(),m("div",oo,L(G.value),1)):(d(),m("div",lo,[D.value?(d(),m("div",no,[s(l).length>0?(d(),m("div",io," 显示 "+L(s(l).length)+" 条提交记录 "+L(F.value?"(全部)":"(分页加载,每页100条)"),1)):ee("",!0),e("div",ro,[e("div",co,[t(s(_e),{type:"primary",circle:"",size:"small",onClick:xe,disabled:_.value<=Ge},{default:a(()=>[t(R,null,{default:a(()=>[t(s(Ot))]),_:1})]),_:1},8,["disabled"]),t(s(It),{modelValue:_.value,"onUpdate:modelValue":o[5]||(o[5]=O=>_.value=O),min:Ge,max:Pe,step:st,onChange:Ce,class:"zoom-slider"},null,8,["modelValue"]),t(s(_e),{type:"primary",circle:"",size:"small",onClick:K,disabled:_.value>=Pe},{default:a(()=>[t(R,null,{default:a(()=>[t(s(Ft))]),_:1})]),_:1},8,["disabled"]),t(s(_e),{type:"primary",size:"small",onClick:Se},{default:a(()=>o[17]||(o[17]=[w(" 自适应大小 ")])),_:1})]),e("div",uo," 缩放: "+L(Math.round(_.value*100))+"% ",1)]),e("div",{ref_key:"graphContainer",ref:I,class:"graph-container"},null,512)])):(d(),m("div",fo,[De((d(),de(s(Mt),{ref_key:"tableRef",ref:B,data:pe.value,stripe:"",border:"",class:"log-table","empty-text":Y.value?"加载中...":"没有匹配的提交记录",height:"500",onRowContextmenu:qe},{default:a(()=>[t(s(ze),{label:"提交哈希",width:"100",resizable:""},{default:a(O=>[e("span",{class:"commit-hash",onClick:Ue=>Ve(O.row)},L(O.row.hash.substring(0,7)),9,po)]),_:1}),t(s(ze),{prop:"date",label:"日期",width:"120",resizable:""}),t(s(ze),{label:"作者",width:"120",resizable:""},{default:a(O=>[t(V,{content:O.row.email,placement:"top","hide-after":1e3},{default:a(()=>[e("span",vo,L(O.row.author),1)]),_:2},1032,["content"])]),_:1}),t(s(ze),{label:"分支",width:"180",resizable:""},{default:a(O=>[O.row.branch?(d(),m("div",mo,[(d(!0),m(he,null,we(O.row.branch.split(","),(Ue,kt)=>(d(),de(s(vt),{key:kt,size:"small",type:i(Ue),class:"branch-tag"},{default:a(()=>[w(L(y(Ue)),1)]),_:2},1032,["type"]))),128))])):ee("",!0)]),_:1}),t(s(ze),{prop:"message",label:"提交信息","min-width":"250"})]),_:1},8,["data","empty-text"])),[[ce,Y.value]]),F.value?ee("",!0):(d(),m("div",go,[e("div",yo,[e("span",null,"第 "+L(oe.value)+" 页 "+L(E.value>0?`/ 共 ${Math.ceil(E.value/100)||1} 页`:"")+" (总计 "+L(E.value)+" 条记录)",1)]),j.value?(d(),m("div",ho,o[18]||(o[18]=[e("div",{class:"loading-spinner"},null,-1),e("span",null,"加载更多...",-1)]))):Q.value?(d(),m("div",{key:1,class:"load-more-button",onClick:Te},o[19]||(o[19]=[e("span",null,"加载更多",-1)]))):(d(),m("div",_o,[o[20]||(o[20]=e("span",null,"没有更多数据了",-1)),A.value.length>0?(d(),m("span",wo,"(已加载 "+L(A.value.length)+" 条记录)",1)):ee("",!0)]))]))]))]))],2),t(s(We),{modelValue:M.value,"onUpdate:modelValue":o[6]||(o[6]=O=>M.value=O),title:`提交详情: ${(me=N.value)!=null&&me.hash?N.value.hash.substring(0,7):"未知"}`,width:"80%","destroy-on-close":"",class:"commit-detail-dialog"},{default:a(()=>[De((d(),m("div",$o,[N.value?(d(),m("div",ko,[e("div",bo,[e("div",Co,[o[21]||(o[21]=e("span",{class:"item-label"},"哈希:",-1)),e("span",So,L(N.value.hash),1)]),e("div",To,[o[22]||(o[22]=e("span",{class:"item-label"},"作者:",-1)),e("span",Lo,L(N.value.author)+" <"+L(N.value.email)+">",1)]),e("div",Vo,[o[23]||(o[23]=e("span",{class:"item-label"},"日期:",-1)),e("span",Ro,L(N.value.date),1)])]),e("div",xo,[o[24]||(o[24]=e("div",{class:"message-label"},"提交信息:",-1)),e("div",{class:"message-content",innerHTML:n(N.value.message).replace(/\n/g,"<br>")},null,8,Bo)])])):ee("",!0),e("div",zo,[e("div",Go,[o[25]||(o[25]=e("h3",null,"变更文件",-1)),te.value.length===0?(d(),de(S,{key:0,description:"没有找到变更文件"})):(d(),m("ul",Do,[(d(!0),m(he,null,we(te.value,O=>(d(),m("li",{key:O,class:Le({"active-file":O===H.value}),onClick:Ue=>k(N.value.hash,O)},L(O),11,Ao))),128))]))]),e("div",Eo,[H.value?(d(),m("h3",jo,"文件差异: "+L(H.value),1)):(d(),m("h3",Uo,"文件差异")),!J.value&&!ue.value?(d(),de(S,{key:2,description:"选择文件查看差异"})):J.value?(d(),m("div",{key:3,innerHTML:v(J.value),class:"diff-content"},null,8,Po)):ee("",!0)])])])),[[ce,ue.value]])]),_:1},8,["modelValue","title"])]),o[31]||(o[31]=w()),De(e("div",{class:"context-menu",style:Ht({top:Z.value+"px",left:ne.value+"px"})},[e("div",{class:"context-menu-item",onClick:o[7]||(o[7]=O=>Ve(ve.value))},o[26]||(o[26]=[e("i",{class:"el-icon-view"},null,-1),w(" 查看详情 ")])),o[29]||(o[29]=w()),e("div",{class:"context-menu-item",onClick:o[8]||(o[8]=O=>Ze(ve.value))},o[27]||(o[27]=[e("i",{class:"el-icon-delete"},null,-1),w(" 撤销提交 (Revert) ")])),o[30]||(o[30]=w()),e("div",{class:"context-menu-item",onClick:o[9]||(o[9]=O=>fe(ve.value))},o[28]||(o[28]=[e("i",{class:"el-icon-edit"},null,-1),w(" Cherry-Pick 到当前分支 ")]))],4),[[Nt,g.value]])],64)}}}),Io=Ye(Oo,[["__scopeId","data-v-958f3e72"]]),Fo="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",Mo={class:"main-header"},No={class:"header-left"},Ho=["src"],Wo={class:"header-info"},Jo={key:0,id:"user-info"},Yo={class:"user-name"},qo={class:"user-email"},Zo={key:1,id:"user-info"},Xo={class:"main-container"},Ko={key:0,class:"loading-container"},Qo={class:"loading-spinner"},el={key:1,class:"grid-layout"},tl={class:"git-status-panel"},sl={key:0,class:"commit-form-panel"},al={key:0,class:"card"},ol={class:"tips"},ll={key:1,class:"commit-form-panel"},nl={key:2,class:"log-list-panel"},il={class:"dialog-footer"},rl={class:"main-footer"},cl={key:0,class:"branch-info"},ul={class:"branch-wrapper"},dl={class:"dialog-footer"},fl=Ne({__name:"App",setup(le){const p=u(""),x=u(null),h=u(null),l=Re(),A=u(!1),G=u("");async function ae(){try{const r=await(await fetch("/api/config/getConfig")).json();p.value=`默认提交信息: ${r.defaultCommitMessage}`}catch(b){console.error("加载配置失败:",b)}}async function Y(){try{const r=await(await fetch("/api/current_directory")).json();return G.value=r.directory||"未知目录",r}catch(b){return console.error("获取当前目录失败:",b),{directory:"未知目录",isGitRepo:!1}}}Ee(async()=>{console.log("---------- 页面初始化开始 ----------");try{const[b,r]=await Promise.all([ae(),Y()]);l.isGitRepo=r.isGitRepo===!0,l.lastCheckedTime=Date.now(),l.isGitRepo?await Promise.all([l.getCurrentBranch(),l.getAllBranches(),l.getUserInfo()]):c.warning("当前目录不是Git仓库,部分功能将不可用")}catch(b){console.error("初始化失败:",b)}finally{A.value=!0,console.log("---------- 页面初始化完成 ----------"),setTimeout(()=>{ie()},100)}});const F=u(!1),E=u(""),D=u("");async function I(){await l.createBranch(E.value,D.value)&&(F.value=!1,E.value="",h.value&&h.value.refreshStatus(),x.value&&x.value.refreshLog())}function oe(){D.value=l.currentBranch,F.value=!0}async function Q(b){await l.changeBranch(b)&&(h.value&&h.value.refreshStatus(),x.value&&x.value.refreshLog())}const j=u(!1),U=u(""),M=u("");function N(){U.value=l.userName,M.value=l.userEmail,j.value=!0}async function te(){if(!U.value||!M.value){c.warning("用户名和邮箱不能为空");return}await l.restoreUserConfig(U.value,M.value)&&(j.value=!1)}async function J(){await l.clearUserConfig()&&(U.value="",M.value="")}let ue=!1,H=!1,_=0,T=0,q="",se="";function ge(){const b=document.querySelector(".grid-layout");if(!b)return;const r=getComputedStyle(b).gridTemplateColumns.split(" "),W=getComputedStyle(b).gridTemplateRows.split(" ");if(r.length>=3&&W.length>=3){const P=parseFloat(r[0]),y=parseFloat(r[2]),i=P+y,B=P/i,C=parseFloat(W[0]),z=parseFloat(W[2]),X=C+z,re=C/X;localStorage.setItem("zen-gitsync-layout-left-ratio",B.toString()),localStorage.setItem("zen-gitsync-layout-top-ratio",re.toString()),console.log(`布局比例已保存 - 左侧: ${(B*100).toFixed(0)}%, 上方: ${(re*100).toFixed(0)}%`)}}function ie(){const b=document.querySelector(".grid-layout");if(!b)return;const r=localStorage.getItem("zen-gitsync-layout-left-ratio"),W=localStorage.getItem("zen-gitsync-layout-top-ratio");if(r){const P=parseFloat(r),y=1-P;b.style.gridTemplateColumns=`${P}fr 8px ${y}fr`,console.log(`已恢复左侧比例: ${(P*100).toFixed(0)}%`)}else b.style.gridTemplateColumns="1fr 8px 3fr";if(W){const P=parseFloat(W),y=1-P;b.style.gridTemplateRows=`${P}fr 8px ${y}fr`,console.log(`已恢复上方比例: ${(P*100).toFixed(0)}%`)}}function $(b){var W;ue=!0,_=b.clientX;const r=document.querySelector(".grid-layout");q=getComputedStyle(r).gridTemplateColumns,(W=document.getElementById("v-resizer"))==null||W.classList.add("active"),document.addEventListener("mousemove",g),document.addEventListener("mouseup",Z),b.preventDefault()}function g(b){if(!ue)return;const r=document.querySelector(".grid-layout"),W=b.clientX-_,P=q.split(" ");if(P.length>=3){const y=parseFloat(P[0]),i=parseFloat(P[2]),B=y+i,C=(y+W/r.clientWidth*B)/B,z=1-C,X=.1,re=.5;C<X?r.style.gridTemplateColumns=`${X}fr 8px ${1-X}fr`:C>re?r.style.gridTemplateColumns=`${re}fr 8px ${1-re}fr`:r.style.gridTemplateColumns=`${C}fr 8px ${z}fr`}}function Z(){var b;ue=!1,(b=document.getElementById("v-resizer"))==null||b.classList.remove("active"),document.removeEventListener("mousemove",g),document.removeEventListener("mouseup",Z),ge()}function ne(b){var W;H=!0,T=b.clientY;const r=document.querySelector(".grid-layout");se=getComputedStyle(r).gridTemplateRows,(W=document.getElementById("h-resizer"))==null||W.classList.add("active"),document.addEventListener("mousemove",ve),document.addEventListener("mouseup",pe),b.preventDefault()}function ve(b){if(!H)return;const r=document.querySelector(".grid-layout"),W=b.clientY-T,P=se.split(" ");if(P.length>=3){const y=parseFloat(P[0]),i=parseFloat(P[2]),B=y+i,C=(y+W/r.clientHeight*B)/B,z=1-C,X=.2,re=.8;C<X?r.style.gridTemplateRows=`${X}fr 8px ${1-X}fr`:C>re?r.style.gridTemplateRows=`${re}fr 8px ${1-re}fr`:r.style.gridTemplateRows=`${C}fr 8px ${z}fr`}}function pe(){var b;H=!1,(b=document.getElementById("h-resizer"))==null||b.classList.remove("active"),document.removeEventListener("mousemove",ve),document.removeEventListener("mouseup",pe),ge()}return(b,r)=>{const W=He,P=_e,y=wt,i=Je,B=gt,C=nt,z=it,X=mt,re=We,$e=ht;return d(),m(he,null,[e("header",Mo,[e("div",No,[e("img",{src:s(Fo),alt:"Zen GitSync Logo",class:"logo"},null,8,Ho),r[9]||(r[9]=e("h1",null,"Zen GitSync UI",-1))]),e("div",Wo,[s(l).userName&&s(l).userEmail?(d(),m("div",Jo,[r[10]||(r[10]=e("span",{class:"user-label"},"用户:",-1)),e("span",Yo,L(s(l).userName),1),e("span",qo,"<"+L(s(l).userEmail)+">",1),t(P,{type:"primary",size:"small",onClick:N,class:"user-settings-btn",circle:""},{default:a(()=>[t(W,null,{default:a(()=>[t(s(Me))]),_:1})]),_:1})])):(d(),m("div",Zo,[r[11]||(r[11]=e("span",{class:"user-label"},"用户: ",-1)),r[12]||(r[12]=e("span",{class:"user-warning"},"未配置",-1)),t(P,{type:"primary",size:"small",onClick:N,class:"user-settings-btn",circle:""},{default:a(()=>[t(W,null,{default:a(()=>[t(s(Me))]),_:1})]),_:1})]))])]),e("main",Xo,[A.value?(d(),m("div",el,[e("div",tl,[t(na,{ref_key:"gitStatusRef",ref:h,"initial-directory":G.value},null,8,["initial-directory"])]),e("div",{class:"vertical-resizer",id:"v-resizer",onMousedown:$},null,32),s(l).isGitRepo?(d(),m("div",sl,[!s(l).userName||!s(l).userEmail?(d(),m("div",al,[r[18]||(r[18]=e("h2",null,"Git用户未配置",-1)),r[19]||(r[19]=e("p",null,"请先配置Git用户信息才能进行提交操作。",-1)),e("div",ol,[r[16]||(r[16]=e("h3",null,"您可以通过以下方式配置:",-1)),r[17]||(r[17]=e("ol",null,[e("li",null,"点击右上角的设置按钮,配置用户名和邮箱"),e("li",null,"或者使用命令行配置:"),e("div",{class:"code-block"},[w(' git config --global user.name "您的用户名"'),e("br"),w(' git config --global user.email "您的邮箱" ')])],-1)),t(P,{type:"primary",onClick:N},{default:a(()=>r[15]||(r[15]=[w(" 立即配置 ")])),_:1})])])):(d(),de(Ja,{key:1}))])):(d(),m("div",ll,r[20]||(r[20]=[e("div",{class:"card"},[e("h2",null,"Git仓库初始化"),e("p",null,"当前目录不是Git仓库,请先初始化Git仓库或切换到Git仓库目录。"),e("div",{class:"tips"},[e("h3",null,"可以使用以下命令初始化仓库:"),e("div",{class:"code-block"},"git init")])],-1)]))),e("div",{class:"horizontal-resizer",id:"h-resizer",onMousedown:ne},null,32),s(l).isGitRepo?(d(),m("div",nl,[t(Io,{ref_key:"logListRef",ref:x},null,512)])):ee("",!0),t(re,{modelValue:F.value,"onUpdate:modelValue":r[3]||(r[3]=K=>F.value=K),title:"创建新分支",width:"30%","destroy-on-close":""},{footer:a(()=>[e("span",il,[t(P,{onClick:r[2]||(r[2]=K=>F.value=!1)},{default:a(()=>r[21]||(r[21]=[w("取消")])),_:1}),t(P,{type:"primary",onClick:I,loading:s(l).isCreatingBranch},{default:a(()=>r[22]||(r[22]=[w(" 创建 ")])),_:1},8,["loading"])])]),default:a(()=>[t(X,{model:{newBranchName:E.value,selectedBaseBranch:D.value}},{default:a(()=>[t(B,{label:"新分支名称"},{default:a(()=>[t(i,{modelValue:E.value,"onUpdate:modelValue":r[0]||(r[0]=K=>E.value=K),placeholder:"请输入新分支名称"},null,8,["modelValue"])]),_:1}),t(B,{label:"基于分支"},{default:a(()=>[t(z,{modelValue:D.value,"onUpdate:modelValue":r[1]||(r[1]=K=>D.value=K),placeholder:"选择基础分支",style:{width:"100%"}},{default:a(()=>[(d(!0),m(he,null,we(s(l).allBranches,K=>(d(),de(C,{key:K,label:K,value:K},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["modelValue"])])):(d(),m("div",Ko,[t(y,{class:"loading-card"},{default:a(()=>[e("div",Qo,[t(W,{class:"is-loading"},{default:a(()=>r[13]||(r[13]=[e("svg",{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg"},[e("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})]),r[14]||(r[14]=e("div",{class:"loading-text"},"加载中...",-1))]),_:1})]))]),e("footer",rl,[s(l).currentBranch?(d(),m("div",cl,[e("div",ul,[r[24]||(r[24]=e("span",{class:"branch-label"},"当前分支:",-1)),t(z,{modelValue:s(l).currentBranch,"onUpdate:modelValue":r[4]||(r[4]=K=>s(l).currentBranch=K),size:"small",onChange:Q,loading:s(l).isChangingBranch,class:"branch-select"},{default:a(()=>[(d(!0),m(he,null,we(s(l).allBranches,K=>(d(),de(C,{key:K,label:K,value:K},null,8,["label","value"]))),128))]),_:1},8,["modelValue","loading"]),t(P,{type:"primary",size:"small",onClick:oe,class:"create-branch-btn"},{default:a(()=>[t(W,null,{default:a(()=>[t(s(Jt))]),_:1}),r[23]||(r[23]=w(" 新建分支 "))]),_:1})])])):ee("",!0),r[25]||(r[25]=e("div",{class:"footer-right"},null,-1))]),t(re,{modelValue:j.value,"onUpdate:modelValue":r[8]||(r[8]=K=>j.value=K),title:"Git用户设置",width:"30%","destroy-on-close":""},{footer:a(()=>[e("span",dl,[t(P,{type:"danger",onClick:J},{default:a(()=>r[27]||(r[27]=[w(" 清除配置 ")])),_:1}),t(P,{onClick:r[7]||(r[7]=K=>j.value=!1)},{default:a(()=>r[28]||(r[28]=[w("取消")])),_:1}),t(P,{type:"primary",onClick:te},{default:a(()=>r[29]||(r[29]=[w(" 保存 ")])),_:1})])]),default:a(()=>[t(X,null,{default:a(()=>[t(B,{label:"用户名"},{default:a(()=>[t(i,{modelValue:U.value,"onUpdate:modelValue":r[5]||(r[5]=K=>U.value=K),placeholder:"请输入Git用户名"},null,8,["modelValue"])]),_:1}),t(B,{label:"邮箱"},{default:a(()=>[t(i,{modelValue:M.value,"onUpdate:modelValue":r[6]||(r[6]=K=>M.value=K),placeholder:"请输入Git邮箱"},null,8,["modelValue"])]),_:1}),t(B,null,{default:a(()=>[t($e,{type:"info",closable:!1,"show-icon":""},{default:a(()=>r[26]||(r[26]=[w(" 这些设置将影响全局Git配置,对所有Git仓库生效。 ")])),_:1})]),_:1})]),_:1})]),_:1},8,["modelValue"])],64)}}}),pl=Ye(fl,[["__scopeId","data-v-8ba54a98"]]),$t=Yt(pl);$t.use(qt());$t.mount("#app");