Commit 777f5860c19de8e1d4a5027b54888f782246fa64

Authored by ljq
1 parent 19ef73f7

调度预案与调度操作记录

Showing 84 changed files with 7167 additions and 42 deletions
src/main/java/com/bsth/controller/realcontrol/ScheduleRealInfoController.java
... ... @@ -890,8 +890,8 @@ public class ScheduleRealInfoController extends BaseController<ScheduleRealInfo,
890 890 * @param ids
891 891 * @return
892 892 */
893   - @RequestMapping(value = "thissch/{ids}", method = RequestMethod.POST)
894   - public ScheduleRealInfo thissch(@RequestParam Integer ids){
895   - return scheduleRealInfoService.thissch(ids);
  893 + @RequestMapping(value = "thissch/{id}", method = RequestMethod.POST)
  894 + public ScheduleRealInfo thissch(@RequestParam Integer id){
  895 + return scheduleRealInfoService.thissch(id);
896 896 }
897 897 }
... ...
src/main/java/com/bsth/controller/zndd/LoggerZnddController.java
... ... @@ -2,10 +2,24 @@ package com.bsth.controller.zndd;
2 2  
3 3 import com.bsth.controller.BaseController;
4 4 import com.bsth.entity.zndd.LoggerZndd;
  5 +import com.bsth.service.zndd.LoggerZnddService;
  6 +import org.springframework.beans.factory.annotation.Autowired;
5 7 import org.springframework.web.bind.annotation.RequestMapping;
  8 +import org.springframework.web.bind.annotation.RequestParam;
6 9 import org.springframework.web.bind.annotation.RestController;
7 10  
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +
8 14 @RestController
9 15 @RequestMapping("logZndd")
10 16 public class LoggerZnddController extends BaseController<LoggerZndd, Integer> {
  17 +
  18 + @Autowired
  19 + LoggerZnddService loggerZnddService;
  20 + @RequestMapping("listall")
  21 + public List<Map<String, Object>> listAll(@RequestParam Map<String, Object> map){
  22 +
  23 + return loggerZnddService.listAll(map);
  24 + }
11 25 }
... ...
src/main/java/com/bsth/controller/zndd/ZnddYuAnConroller.java 0 → 100644
  1 +package com.bsth.controller.zndd;
  2 +
  3 +import com.bsth.controller.BaseController;
  4 +import com.bsth.entity.zndd.ZnddYuAn;
  5 +import com.bsth.service.zndd.ZnddYuAnService;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.web.bind.annotation.*;
  8 +
  9 +import java.util.Map;
  10 +
  11 +@RestController
  12 +@RequestMapping("zndya")
  13 +public class ZnddYuAnConroller extends BaseController<ZnddYuAn, Integer> {
  14 +
  15 + @Autowired
  16 + ZnddYuAnService znddYuAnService;
  17 +
  18 + //添加类型
  19 +
  20 + @RequestMapping(value = "/addMap", method = RequestMethod.POST)
  21 + public Map<String, Object> addMap(@RequestBody Map<String, Object> params){
  22 + return znddYuAnService.addMap(params);
  23 + }
  24 +}
... ...
src/main/java/com/bsth/data/zndd/AutomaticSch.java
... ... @@ -120,7 +120,7 @@ public class AutomaticSch {
120 120 }
121 121 }
122 122  
123   - ScheduleRealInfo sr = dayOfSchedule.findByNbbm("W8A-009").get(0);
  123 + ScheduleRealInfo sr = dayOfSchedule.findByNbbm("W8A-027").get(0);
124 124 ts(addStationPeople(sr, "DKL", 0L));//大客流
125 125  
126 126  
... ...
src/main/java/com/bsth/repository/zndd/ZnddYuAnRepository.java 0 → 100644
  1 +package com.bsth.repository.zndd;
  2 +
  3 +
  4 +import com.bsth.entity.zndd.ZnddYuAn;
  5 +import com.bsth.repository.BaseRepository;
  6 +import org.springframework.data.jpa.repository.Modifying;
  7 +import org.springframework.data.jpa.repository.Query;
  8 +import org.springframework.stereotype.Repository;
  9 +
  10 +@Repository
  11 +public interface ZnddYuAnRepository extends BaseRepository<ZnddYuAn, Integer> {
  12 + @Modifying
  13 + @Query(value="delete from ZnddYuAn sr where sr.type = ?1")
  14 + void deleteType(String type);
  15 +}
... ...
src/main/java/com/bsth/security/ResourcesConfig.java 0 → 100644
  1 +package com.bsth.security;
  2 +
  3 +import org.springframework.beans.factory.annotation.Value;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  6 +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7 +
  8 +/**
  9 + * 通用配置
  10 + *
  11 + * @author ruoyi
  12 + */
  13 +@Configuration
  14 +public class ResourcesConfig implements WebMvcConfigurer
  15 +{
  16 +
  17 + @Value("${dc.imgurl}")
  18 + private String imgurl; //存储图片地址
  19 + //映射图片地址
  20 + @Override
  21 + public void addResourceHandlers(ResourceHandlerRegistry registry)
  22 + {
  23 + /** 本地文件上传路径 */
  24 + registry.addResourceHandler("profile" + "/**")
  25 + .addResourceLocations("file:" + imgurl + "/");
  26 + }
  27 +
  28 +
  29 +}
0 30 \ No newline at end of file
... ...
src/main/java/com/bsth/service/zndd/LoggerZnddService.java
... ... @@ -3,5 +3,11 @@ package com.bsth.service.zndd;
3 3 import com.bsth.entity.zndd.LoggerZndd;
4 4 import com.bsth.service.BaseService;
5 5  
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
6 9 public interface LoggerZnddService extends BaseService<LoggerZndd, Integer> {
  10 +
  11 +
  12 + List<Map<String, Object>> listAll(Map<String, Object> map);
7 13 }
... ...
src/main/java/com/bsth/service/zndd/ZnddYuAnService.java 0 → 100644
  1 +package com.bsth.service.zndd;
  2 +
  3 +import com.bsth.entity.GeoPremise;
  4 +import com.bsth.entity.zndd.ZnddYuAn;
  5 +import com.bsth.service.BaseService;
  6 +
  7 +import java.util.Map;
  8 +
  9 +public interface ZnddYuAnService extends BaseService<ZnddYuAn, Integer> {
  10 +
  11 +
  12 + Map<String, Object> addMap(Map<String, Object> params);
  13 +}
... ...
src/main/java/com/bsth/service/zndd/impl/LoggerZnddServiceImpl.java
1 1 package com.bsth.service.zndd.impl;
2 2  
  3 +import com.bsth.entity.search.CustomerSpecs;
3 4 import com.bsth.entity.zndd.LoggerZndd;
  5 +import com.bsth.repository.zndd.LoggerZnddRepository;
4 6 import com.bsth.service.impl.BaseServiceImpl;
5 7 import com.bsth.service.zndd.LoggerZnddService;
  8 +import org.apache.poi.ss.formula.functions.T;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.data.domain.Pageable;
  11 +
  12 +import org.springframework.data.domain.Sort;
6 13 import org.springframework.stereotype.Service;
7 14  
  15 +import java.util.List;
  16 +import java.util.Map;
  17 +
8 18 @Service
9 19 public class LoggerZnddServiceImpl extends BaseServiceImpl<LoggerZndd, Integer> implements LoggerZnddService {
  20 +
  21 + @Autowired
  22 + LoggerZnddRepository loggerZnddRepository;
  23 + public List<Map<String, Object>> listAll(Map<String, Object> map){
  24 + loggerZnddRepository.findAll((Sort) map);
  25 +
  26 + return null;
  27 + }
10 28 }
... ...
src/main/java/com/bsth/service/zndd/impl/ZnddYuAnServiceImpl.java 0 → 100644
  1 +package com.bsth.service.zndd.impl;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.bsth.common.ResponseCode;
  6 +import com.bsth.entity.zndd.ZnddYuAn;
  7 +import com.bsth.repository.zndd.ZnddYuAnRepository;
  8 +import com.bsth.service.impl.BaseServiceImpl;
  9 +import com.bsth.service.zndd.ZnddYuAnService;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.stereotype.Service;
  14 +import org.springframework.transaction.annotation.Transactional;
  15 +
  16 +import java.util.Arrays;
  17 +import java.util.HashMap;
  18 +import java.util.List;
  19 +import java.util.Map;
  20 +
  21 +@Service
  22 +public class ZnddYuAnServiceImpl extends BaseServiceImpl<ZnddYuAn, Integer> implements ZnddYuAnService {
  23 +
  24 +
  25 + Logger logger = LoggerFactory.getLogger(this.getClass());
  26 + @Autowired
  27 + ZnddYuAnRepository znddYuAnRepository;
  28 +
  29 + @Override
  30 + @Transactional
  31 + public Map<String, Object> addMap(Map<String, Object> params){
  32 + Map<String, Object> rs = new HashMap<>();
  33 +
  34 + try {
  35 + List<Map> list = JSON.parseArray(params.get("data").toString(), Map.class);
  36 +
  37 + List<Map> listlineks = JSON.parseArray(params.get("links").toString(), Map.class);
  38 +
  39 + znddYuAnRepository.deleteType(params.get("type").toString());
  40 + for (Map m : list){
  41 + ZnddYuAn zya = new ZnddYuAn();
  42 + String s = JSONObject.toJSONString(m);
  43 + zya.setType(params.get("type").toString());
  44 + zya.setJsonDate(s);
  45 + zya.setTypes("0");
  46 + znddYuAnRepository.save(zya);
  47 + }
  48 + for (Map m : listlineks) {
  49 + ZnddYuAn zya = new ZnddYuAn();
  50 + String s = JSONObject.toJSONString(m);
  51 + zya.setType(params.get("type").toString());
  52 + zya.setJsonDate(s);
  53 + zya.setTypes("1");
  54 + znddYuAnRepository.save(zya);
  55 + }
  56 + rs.put("status", ResponseCode.SUCCESS);
  57 + }catch (Exception e){
  58 + logger.info("调度预案添加-"+e);
  59 + rs.put("ERROR", "操作失败,请检查数据是否有误!");
  60 + }
  61 +
  62 + return rs;
  63 + }
  64 +}
... ...
src/main/resources/static/pages/forms/zndd/logger_zndd.html
... ... @@ -50,7 +50,6 @@
50 50 <input class="btn btn-default" type="button" id="query" value="筛选"/>
51 51 <input class="btn btn-default" type="button" id="export" value="导出"/>
52 52 </div>
53   - <img src="/profile/avatar/2024/04/07/blob_20240407160316A002.png">
54 53 </form>
55 54 </div>
56 55 <div class="portlet-body">
... ... @@ -188,6 +187,11 @@
188 187 $get('/logZndd/all',{rq_eq:date,lineCode_eq:line,type:'query'},function(result){
189 188 $("#form_line").text(lineName);
190 189 $("#form_date").text(date);
  190 +
  191 + $.each(result, function(i, obj) {
  192 + obj.createDate = moment(obj.createDate).format("YYYY-MM-DD HH:mm:ss");
  193 + });
  194 +
191 195 // 把数据填充到模版中
192 196 var tbodyHtml = template('dailyInfo',{list:result});
193 197 // 把渲染好的模版html文本追加到表格中
... ... @@ -239,7 +243,7 @@
239 243 fgsdmDaily = $("#fgsdmDaily").val();
240 244 lineName=$("#select2-line-container").html();
241 245 var i = layer.load(2);
242   - $post('/znddLogger/list',{gsdmDaily:gsdmDaily,fgsdmDaily:fgsdmDaily,line:line,date:date,type:'export',lineName:lineName},function(result){
  246 + $get('/logZndd/listall',{rq_eq:date,lineCode_eq:line,type:'export'},function(result){
243 247 window.open("/downloadFile/download?fileName="
244 248 +moment(date).format("YYYYMMDD")+"-"+lineName+"-班次日报表");
245 249 layer.close(i);
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/Blueprint.Net.Server.csproj 0 → 100644
  1 +<Project Sdk="Microsoft.NET.Sdk.Web">
  2 +
  3 + <PropertyGroup>
  4 + <TargetFramework>net8.0</TargetFramework>
  5 + <Nullable>enable</Nullable>
  6 + <ImplicitUsings>enable</ImplicitUsings>
  7 + </PropertyGroup>
  8 +
  9 + <ItemGroup>
  10 + <PackageReference Include="FreeSql" Version="3.2.821" />
  11 + <PackageReference Include="FreeSql.Provider.Sqlite" Version="3.2.821" />
  12 + <PackageReference Include="FreeSql.Repository" Version="3.2.821" />
  13 + <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  14 + </ItemGroup>
  15 +
  16 +</Project>
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/Blueprint.Net.Server.sln 0 → 100644
  1 +
  2 +Microsoft Visual Studio Solution File, Format Version 12.00
  3 +# Visual Studio Version 17
  4 +VisualStudioVersion = 17.9.34622.214
  5 +MinimumVisualStudioVersion = 10.0.40219.1
  6 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blueprint.Net.Server", "Blueprint.Net.Server.csproj", "{650D80E6-03AB-40D8-A1DD-C9A42DF92249}"
  7 +EndProject
  8 +Global
  9 + GlobalSection(SolutionConfigurationPlatforms) = preSolution
  10 + Debug|Any CPU = Debug|Any CPU
  11 + Release|Any CPU = Release|Any CPU
  12 + EndGlobalSection
  13 + GlobalSection(ProjectConfigurationPlatforms) = postSolution
  14 + {650D80E6-03AB-40D8-A1DD-C9A42DF92249}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  15 + {650D80E6-03AB-40D8-A1DD-C9A42DF92249}.Debug|Any CPU.Build.0 = Debug|Any CPU
  16 + {650D80E6-03AB-40D8-A1DD-C9A42DF92249}.Release|Any CPU.ActiveCfg = Release|Any CPU
  17 + {650D80E6-03AB-40D8-A1DD-C9A42DF92249}.Release|Any CPU.Build.0 = Release|Any CPU
  18 + EndGlobalSection
  19 + GlobalSection(SolutionProperties) = preSolution
  20 + HideSolutionNode = FALSE
  21 + EndGlobalSection
  22 + GlobalSection(ExtensibilityGlobals) = postSolution
  23 + SolutionGuid = {6CE115DF-4AF8-4EB9-8A99-04F0BED024AC}
  24 + EndGlobalSection
  25 +EndGlobal
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/Controllers/BlueprintController.cs 0 → 100644
  1 +using Microsoft.AspNetCore.Mvc;
  2 +using System.Collections.Frozen;
  3 +using System.Linq;
  4 +using System.Xml.Linq;
  5 +using static FreeSql.Internal.GlobalFilter;
  6 +
  7 +namespace Blueprint.Net.Server.Controllers
  8 +{
  9 + [ApiController]
  10 + [Route("[controller]")]
  11 + public class BlueprintController(ILogger<BlueprintController> logger, IFreeSql fsql) : ControllerBase
  12 + {
  13 + private readonly ILogger<BlueprintController> _logger = logger;
  14 + private readonly IFreeSql _fsql = fsql;
  15 +
  16 + [HttpGet("GetProjects")]
  17 + public async Task<ActionResult<IEnumerable<Project>>> GetProjects()
  18 + {
  19 + var projects = await _fsql.Select<Project>()
  20 + .IncludeMany(p => p.Workspaces, a => a.IncludeMany(b => b.Links))
  21 + .IncludeMany(p => p.Workspaces, a => a.IncludeMany(b => b.Cards))
  22 + .IncludeMany(p => p.Workspaces, a => a.IncludeMany(b => b.Cards, c => c.IncludeMany(d => d.Nodes)))
  23 + .ToListAsync();
  24 +
  25 + List<long> linkIds = [];
  26 + List<long> workspaceIds = [];
  27 +
  28 + foreach (var project in projects)
  29 + {
  30 + foreach (var workspace in project.Workspaces)
  31 + {
  32 + workspaceIds.Add(workspace.Id);
  33 +
  34 + }
  35 + }
  36 +
  37 + var links = await _fsql.Select<Link>().Where(p => workspaceIds.Contains(p.WorkspaceId)).ToListAsync();
  38 +
  39 + foreach (var link in links)
  40 + {
  41 + linkIds.Add(link.SourceId);
  42 + linkIds.Add(link.TargetId);
  43 + }
  44 +
  45 + var nodeConnectInfos = await _fsql.Select<NodeConnectInfo>().Where(p => linkIds.Contains(p.Id)).ToListAsync();
  46 +
  47 + foreach (var project in projects)
  48 + {
  49 + foreach (var workspace in project.Workspaces)
  50 + {
  51 +
  52 + foreach (var link in links.Where(p => p.WorkspaceId == workspace.Id))
  53 + {
  54 + link.Source = nodeConnectInfos.FirstOrDefault(p => p.Id == link.SourceId) ?? new();
  55 + link.Target = nodeConnectInfos.FirstOrDefault(p => p.Id == link.TargetId) ?? new();
  56 +
  57 + workspace.Links.Add(link);
  58 + }
  59 + }
  60 + }
  61 +
  62 +
  63 + return Ok(projects);
  64 + }
  65 +
  66 + [HttpPost("Project")]
  67 + public async Task<ActionResult<Project>> Project([FromBody] Project project)
  68 + {
  69 +
  70 + var projectRepo = _fsql.GetRepository<Project>();
  71 +
  72 + projectRepo.DbContextOptions.EnableCascadeSave = true;
  73 +
  74 + project = await projectRepo.InsertOrUpdateAsync(project);
  75 + projectRepo.Attach(project);
  76 +
  77 + foreach (var workspaces in project.Workspaces)
  78 + {
  79 + foreach (var node in workspaces.Links)
  80 + {
  81 +
  82 + if (node.SourceId == 0)
  83 + {
  84 + node.SourceId = await _fsql.Insert(node.Source).ExecuteIdentityAsync();
  85 + node.Source.Id = node.SourceId;
  86 + }
  87 + else
  88 + {
  89 + await _fsql.Update<NodeConnectInfo>().SetSource(node.Source).Where(p => p.Id == node.SourceId).ExecuteAffrowsAsync();
  90 + }
  91 +
  92 + if (node.TargetId == 0)
  93 + {
  94 + node.TargetId = await _fsql.Insert(node.Target).ExecuteIdentityAsync();
  95 + node.Target.Id = node.TargetId;
  96 + }
  97 + else
  98 + {
  99 + await _fsql.Update<NodeConnectInfo>().SetSource(node.Target).Where(p => p.Id == node.TargetId).ExecuteAffrowsAsync();
  100 + }
  101 + }
  102 + }
  103 + await projectRepo.UpdateAsync(project);
  104 +
  105 + return Ok(project);
  106 +
  107 + }
  108 +
  109 +
  110 + [HttpDelete("DeleteProject/{id}")]
  111 + public async Task<IActionResult> DeleteProject(long id)
  112 + {
  113 +
  114 + var repo = _fsql.GetRepository<Project>();
  115 +
  116 + repo.DbContextOptions.EnableCascadeSave = true;
  117 +
  118 + var project = await repo.Select
  119 + .IncludeMany(p => p.Workspaces, a => a.IncludeMany(b => b.Cards, c => c.IncludeMany(d => d.Nodes)))
  120 + .IncludeMany(p => p.Workspaces, a => a.IncludeMany(b => b.Links))
  121 + .Where(p => p.Id == id)
  122 + .FirstAsync();
  123 +
  124 + var deleteIds = new List<long>();
  125 +
  126 + foreach (var workspace in project.Workspaces)
  127 + {
  128 + foreach (var node in workspace.Links)
  129 + {
  130 + deleteIds.Add(node.SourceId);
  131 + deleteIds.Add(node.TargetId);
  132 + }
  133 + }
  134 + await _fsql.Delete<NodeConnectInfo>().Where(p => deleteIds.Contains(p.Id)).ExecuteAffrowsAsync();
  135 +
  136 + var ret = await repo.DeleteAsync(project);
  137 + if (ret > 0)
  138 + return Ok();
  139 + return NotFound();
  140 + }
  141 + [HttpDelete("DeleteWorkspace/{id}")]
  142 + public async Task<IActionResult> DeleteWorkspace(long id)
  143 + {
  144 + var repo = _fsql.GetRepository<Workspace>();
  145 +
  146 + repo.DbContextOptions.EnableCascadeSave = true;
  147 +
  148 + var workspace = await repo.Select
  149 + .IncludeMany(p => p.Cards, a => a.IncludeMany(b => b.Nodes))
  150 + .IncludeMany(p => p.Links)
  151 + .Where(p => p.Id == id)
  152 + .FirstAsync();
  153 +
  154 +
  155 + var deleteIds = new List<long>();
  156 +
  157 + foreach (var node in workspace.Links)
  158 + {
  159 + deleteIds.Add(node.SourceId);
  160 + deleteIds.Add(node.TargetId);
  161 + }
  162 + await _fsql.Delete<NodeConnectInfo>().Where(p => deleteIds.Contains(p.Id)).ExecuteAffrowsAsync();
  163 +
  164 + var ret = await repo.DeleteAsync(workspace);
  165 + if (ret > 0)
  166 + return Ok();
  167 + return NotFound();
  168 + }
  169 +
  170 + [HttpDelete("DeleteLink/{id}")]
  171 + public async Task<IActionResult> DeleteLink(long id)
  172 + {
  173 + var repo = _fsql.GetRepository<Link>();
  174 +
  175 + repo.DbContextOptions.EnableCascadeSave = true;
  176 +
  177 + var link = await repo.Select.Where(p => p.Id == id).FirstAsync();
  178 +
  179 +
  180 + var deleteIds = new List<long>
  181 + {
  182 + link.SourceId,
  183 + link.TargetId
  184 + };
  185 +
  186 + await _fsql.Delete<NodeConnectInfo>().Where(p => deleteIds.Contains(p.Id)).ExecuteAffrowsAsync();
  187 +
  188 + var ret = await repo.DeleteAsync(link);
  189 + if (ret > 0)
  190 + return Ok();
  191 + return NotFound();
  192 + }
  193 +
  194 + [HttpDelete("DeleteCard/{id}")]
  195 + public async Task<IActionResult> DeleteCard(long id)
  196 + {
  197 + var repo = _fsql.GetRepository<Card>();
  198 +
  199 + repo.DbContextOptions.EnableCascadeSave = true;
  200 +
  201 + var card = await repo.Select.IncludeMany(p => p.Nodes).Where(p => p.Id == id).FirstAsync();
  202 +
  203 + var ret = await repo.DeleteAsync(card);
  204 + if (ret > 0)
  205 + return Ok();
  206 + return NotFound();
  207 + }
  208 +
  209 + }
  210 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/Models.cs 0 → 100644
  1 +using FreeSql.DataAnnotations;
  2 +using System.ComponentModel.DataAnnotations;
  3 +using System.Text.RegularExpressions;
  4 +
  5 +namespace Blueprint.Net.Server
  6 +{
  7 + public class Card
  8 + {
  9 + [Column(IsIdentity = true, IsPrimary = true)] public long Id { get; set; }
  10 + public long WorkspaceId { get; set; }
  11 + public int X { get; set; }
  12 + public int Y { get; set; }
  13 + public string Label { get; set; }
  14 + public string Type { get; set; }
  15 + [Navigate(nameof(CardNodeInfo.CardId))] public List<CardNodeInfo> Nodes { get; set; } = [];
  16 + public List<string> TitleBarColor { get; set; } = [];
  17 + }
  18 +
  19 + public class Link
  20 + {
  21 + [Column(IsIdentity = true, IsPrimary = true)] public long Id { get; set; }
  22 + public long WorkspaceId { get; set; }
  23 +
  24 + [Navigate(nameof(SourceId))] public NodeConnectInfo Source { get; set; }
  25 +
  26 + [Navigate(nameof(TargetId))] public NodeConnectInfo Target { get; set; }
  27 +
  28 + public long SourceId { get; set; }
  29 + public long TargetId { get; set; }
  30 +
  31 + }
  32 +
  33 + public class NodeConnectInfo
  34 + {
  35 + [Column(IsIdentity = true, IsPrimary = true)] public long Id { get; set; }
  36 + public string Node { get; set; }
  37 + public int X { get; set; }
  38 + public int Y { get; set; }
  39 + public string Color { get; set; }
  40 + public string EnumType { get; set; }
  41 + }
  42 +
  43 + public class CardNodeInfo
  44 + {
  45 + [Column(IsIdentity = true, IsPrimary = true)] public long Id { get; set; }
  46 +
  47 + public long CardId { get; set; }
  48 + public string Type { get; set; }
  49 + public int Level { get; set; }
  50 + public string EnumType { get; set; }
  51 + public string Color { get; set; }
  52 + public int? MultiConnected { get; set; }
  53 + public string Slot { get; set; }
  54 + public string Label { get; set; }
  55 + public string Value { get; set; }
  56 + }
  57 +
  58 +
  59 +
  60 +
  61 +
  62 + public class Project
  63 + {
  64 + [Column(IsIdentity = true, IsPrimary = true)] public long Id { get; set; }
  65 + public string Name { get; set; }
  66 + [Navigate(nameof(Workspace.ProjectId))] public List<Workspace> Workspaces { get; set; } = [];
  67 + }
  68 +
  69 + public class Workspace
  70 + {
  71 + [Column(IsIdentity = true, IsPrimary = true)] public long Id { get; set; }
  72 + public long ProjectId { get; set; }
  73 + public string Name { get; set; }
  74 + [Navigate(nameof(Card.WorkspaceId))] public List<Card> Cards { get; set; } = [];
  75 + [Navigate(nameof(Card.WorkspaceId))] public List<Link> Links { get; set; } = [];
  76 + }
  77 +
  78 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/Program.cs 0 → 100644
  1 +
  2 +namespace Blueprint.Net.Server
  3 +{
  4 + public class Program
  5 + {
  6 + public static void Main(string[] args)
  7 + {
  8 + var builder = WebApplication.CreateBuilder(args);
  9 +
  10 + // Add services to the container.
  11 +
  12 + builder.Services.AddControllers();
  13 + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
  14 + builder.Services.AddEndpointsApiExplorer();
  15 + builder.Services.AddSwaggerGen();
  16 +
  17 + builder.Services.AddSingleton(new FreeSql.FreeSqlBuilder()
  18 + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=blueprint.db")
  19 + .UseMonitorCommand(cmd => Console.WriteLine($"Sql:{cmd.CommandText}"))//监听SQL语句
  20 + .UseAutoSyncStructure(true) //自动同步实体结构到数据库,FreeSql不会扫描程序集,只有CRUD时才会生成表。
  21 + .Build());
  22 +
  23 + var app = builder.Build();
  24 +
  25 + // Configure the HTTP request pipeline.
  26 + if (app.Environment.IsDevelopment())
  27 + {
  28 + app.UseSwagger();
  29 + app.UseSwaggerUI();
  30 + }
  31 +
  32 + app.UseAuthorization();
  33 +
  34 + app.UseStaticFiles();
  35 +
  36 + app.MapControllers();
  37 +
  38 + app.Run();
  39 + }
  40 + }
  41 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/Properties/launchSettings.json 0 → 100644
  1 +{
  2 + "$schema": "http://json.schemastore.org/launchsettings.json",
  3 + "iisSettings": {
  4 + "windowsAuthentication": false,
  5 + "anonymousAuthentication": true,
  6 + "iisExpress": {
  7 + "applicationUrl": "http://localhost:19130",
  8 + "sslPort": 0
  9 + }
  10 + },
  11 + "profiles": {
  12 + "http": {
  13 + "commandName": "Project",
  14 + "dotnetRunMessages": true,
  15 + "launchBrowser": true,
  16 + "launchUrl": "swagger",
  17 + "applicationUrl": "http://localhost:5277",
  18 + "environmentVariables": {
  19 + "ASPNETCORE_ENVIRONMENT": "Development"
  20 + }
  21 + },
  22 + "IIS Express": {
  23 + "commandName": "IISExpress",
  24 + "launchBrowser": true,
  25 + "launchUrl": "swagger",
  26 + "environmentVariables": {
  27 + "ASPNETCORE_ENVIRONMENT": "Development"
  28 + }
  29 + }
  30 + }
  31 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/appsettings.Development.json 0 → 100644
  1 +{
  2 + "Logging": {
  3 + "LogLevel": {
  4 + "Default": "Information",
  5 + "Microsoft.AspNetCore": "Warning"
  6 + }
  7 + }
  8 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/appsettings.json 0 → 100644
  1 +{
  2 + "Logging": {
  3 + "LogLevel": {
  4 + "Default": "Information",
  5 + "Microsoft.AspNetCore": "Warning"
  6 + }
  7 + },
  8 + "AllowedHosts": "*"
  9 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Blueprint.Net.Server.deps.json 0 → 100644
  1 +{
  2 + "runtimeTarget": {
  3 + "name": ".NETCoreApp,Version=v8.0",
  4 + "signature": ""
  5 + },
  6 + "compilationOptions": {},
  7 + "targets": {
  8 + ".NETCoreApp,Version=v8.0": {
  9 + "Blueprint.Net.Server/1.0.0": {
  10 + "dependencies": {
  11 + "FreeSql": "3.2.821",
  12 + "FreeSql.Provider.Sqlite": "3.2.821",
  13 + "FreeSql.Repository": "3.2.821",
  14 + "Swashbuckle.AspNetCore": "6.4.0"
  15 + },
  16 + "runtime": {
  17 + "Blueprint.Net.Server.dll": {}
  18 + }
  19 + },
  20 + "FreeSql/3.2.821": {
  21 + "runtime": {
  22 + "lib/netstandard2.1/FreeSql.dll": {
  23 + "assemblyVersion": "3.2.821.0",
  24 + "fileVersion": "3.2.821.0"
  25 + }
  26 + },
  27 + "resources": {
  28 + "lib/netstandard2.1/zh-Hans/FreeSql.resources.dll": {
  29 + "locale": "zh-Hans"
  30 + }
  31 + }
  32 + },
  33 + "FreeSql.DbContext/3.2.821": {
  34 + "dependencies": {
  35 + "FreeSql": "3.2.821",
  36 + "Microsoft.Extensions.DependencyInjection": "8.0.0"
  37 + },
  38 + "runtime": {
  39 + "lib/net8.0/FreeSql.DbContext.dll": {
  40 + "assemblyVersion": "3.2.821.0",
  41 + "fileVersion": "3.2.821.0"
  42 + }
  43 + },
  44 + "resources": {
  45 + "lib/net8.0/zh-Hans/FreeSql.DbContext.resources.dll": {
  46 + "locale": "zh-Hans"
  47 + }
  48 + }
  49 + },
  50 + "FreeSql.Provider.Sqlite/3.2.821": {
  51 + "dependencies": {
  52 + "FreeSql": "3.2.821",
  53 + "System.Data.SQLite.Core": "1.0.115.5"
  54 + },
  55 + "runtime": {
  56 + "lib/netstandard2.0/FreeSql.Provider.Sqlite.dll": {
  57 + "assemblyVersion": "3.2.821.0",
  58 + "fileVersion": "3.2.821.0"
  59 + }
  60 + }
  61 + },
  62 + "FreeSql.Repository/3.2.821": {
  63 + "dependencies": {
  64 + "FreeSql.DbContext": "3.2.821"
  65 + },
  66 + "runtime": {
  67 + "lib/net8.0/FreeSql.Repository.dll": {
  68 + "assemblyVersion": "3.2.821.0",
  69 + "fileVersion": "3.2.821.0"
  70 + }
  71 + }
  72 + },
  73 + "Microsoft.Extensions.ApiDescription.Server/6.0.5": {},
  74 + "Microsoft.Extensions.DependencyInjection/8.0.0": {
  75 + "dependencies": {
  76 + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
  77 + }
  78 + },
  79 + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {},
  80 + "Microsoft.OpenApi/1.2.3": {
  81 + "runtime": {
  82 + "lib/netstandard2.0/Microsoft.OpenApi.dll": {
  83 + "assemblyVersion": "1.2.3.0",
  84 + "fileVersion": "1.2.3.0"
  85 + }
  86 + }
  87 + },
  88 + "Stub.System.Data.SQLite.Core.NetStandard/1.0.115.5": {
  89 + "runtime": {
  90 + "lib/netstandard2.1/System.Data.SQLite.dll": {
  91 + "assemblyVersion": "1.0.115.5",
  92 + "fileVersion": "1.0.115.5"
  93 + }
  94 + },
  95 + "runtimeTargets": {
  96 + "runtimes/linux-x64/native/SQLite.Interop.dll": {
  97 + "rid": "linux-x64",
  98 + "assetType": "native",
  99 + "fileVersion": "0.0.0.0"
  100 + },
  101 + "runtimes/osx-x64/native/SQLite.Interop.dll": {
  102 + "rid": "osx-x64",
  103 + "assetType": "native",
  104 + "fileVersion": "0.0.0.0"
  105 + },
  106 + "runtimes/win-x64/native/SQLite.Interop.dll": {
  107 + "rid": "win-x64",
  108 + "assetType": "native",
  109 + "fileVersion": "1.0.115.5"
  110 + },
  111 + "runtimes/win-x86/native/SQLite.Interop.dll": {
  112 + "rid": "win-x86",
  113 + "assetType": "native",
  114 + "fileVersion": "1.0.115.5"
  115 + }
  116 + }
  117 + },
  118 + "Swashbuckle.AspNetCore/6.4.0": {
  119 + "dependencies": {
  120 + "Microsoft.Extensions.ApiDescription.Server": "6.0.5",
  121 + "Swashbuckle.AspNetCore.Swagger": "6.4.0",
  122 + "Swashbuckle.AspNetCore.SwaggerGen": "6.4.0",
  123 + "Swashbuckle.AspNetCore.SwaggerUI": "6.4.0"
  124 + }
  125 + },
  126 + "Swashbuckle.AspNetCore.Swagger/6.4.0": {
  127 + "dependencies": {
  128 + "Microsoft.OpenApi": "1.2.3"
  129 + },
  130 + "runtime": {
  131 + "lib/net6.0/Swashbuckle.AspNetCore.Swagger.dll": {
  132 + "assemblyVersion": "6.4.0.0",
  133 + "fileVersion": "6.4.0.0"
  134 + }
  135 + }
  136 + },
  137 + "Swashbuckle.AspNetCore.SwaggerGen/6.4.0": {
  138 + "dependencies": {
  139 + "Swashbuckle.AspNetCore.Swagger": "6.4.0"
  140 + },
  141 + "runtime": {
  142 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerGen.dll": {
  143 + "assemblyVersion": "6.4.0.0",
  144 + "fileVersion": "6.4.0.0"
  145 + }
  146 + }
  147 + },
  148 + "Swashbuckle.AspNetCore.SwaggerUI/6.4.0": {
  149 + "runtime": {
  150 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerUI.dll": {
  151 + "assemblyVersion": "6.4.0.0",
  152 + "fileVersion": "6.4.0.0"
  153 + }
  154 + }
  155 + },
  156 + "System.Data.SQLite.Core/1.0.115.5": {
  157 + "dependencies": {
  158 + "Stub.System.Data.SQLite.Core.NetStandard": "1.0.115.5"
  159 + }
  160 + }
  161 + }
  162 + },
  163 + "libraries": {
  164 + "Blueprint.Net.Server/1.0.0": {
  165 + "type": "project",
  166 + "serviceable": false,
  167 + "sha512": ""
  168 + },
  169 + "FreeSql/3.2.821": {
  170 + "type": "package",
  171 + "serviceable": true,
  172 + "sha512": "sha512-bI/CTioEq4B9k5pqaZnXBSyJCIbHoUUTJGgQJF5osgq7/9kOxZo93hmZr8Vw6n5iFG5chx6wkcn4dnJJUsAEkA==",
  173 + "path": "freesql/3.2.821",
  174 + "hashPath": "freesql.3.2.821.nupkg.sha512"
  175 + },
  176 + "FreeSql.DbContext/3.2.821": {
  177 + "type": "package",
  178 + "serviceable": true,
  179 + "sha512": "sha512-wQWjKj7/2Iwzp5WxOE5WV/HmoVmj6fKPYGBxKB7JWxF7HudmXjeZS1Hll2ovQksqF/YujYf7SxGbDv5mU9qSGA==",
  180 + "path": "freesql.dbcontext/3.2.821",
  181 + "hashPath": "freesql.dbcontext.3.2.821.nupkg.sha512"
  182 + },
  183 + "FreeSql.Provider.Sqlite/3.2.821": {
  184 + "type": "package",
  185 + "serviceable": true,
  186 + "sha512": "sha512-vBvvq9mDz488XWYeNQSSt8t3FCKquS4DPab7hu7QVRF0ftXRAc6rRK5axFFJZjc5ABU7aIKtu1UiKQky8z/VnA==",
  187 + "path": "freesql.provider.sqlite/3.2.821",
  188 + "hashPath": "freesql.provider.sqlite.3.2.821.nupkg.sha512"
  189 + },
  190 + "FreeSql.Repository/3.2.821": {
  191 + "type": "package",
  192 + "serviceable": true,
  193 + "sha512": "sha512-cE/VG103FYXn2m63Xp7heYptPazNN+z+dUm9jZe2vNwV8LUCU3PbY04MD+liyQBCZ5WGCK70Pe4GXGfQzvRMLw==",
  194 + "path": "freesql.repository/3.2.821",
  195 + "hashPath": "freesql.repository.3.2.821.nupkg.sha512"
  196 + },
  197 + "Microsoft.Extensions.ApiDescription.Server/6.0.5": {
  198 + "type": "package",
  199 + "serviceable": true,
  200 + "sha512": "sha512-Ckb5EDBUNJdFWyajfXzUIMRkhf52fHZOQuuZg/oiu8y7zDCVwD0iHhew6MnThjHmevanpxL3f5ci2TtHQEN6bw==",
  201 + "path": "microsoft.extensions.apidescription.server/6.0.5",
  202 + "hashPath": "microsoft.extensions.apidescription.server.6.0.5.nupkg.sha512"
  203 + },
  204 + "Microsoft.Extensions.DependencyInjection/8.0.0": {
  205 + "type": "package",
  206 + "serviceable": true,
  207 + "sha512": "sha512-V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
  208 + "path": "microsoft.extensions.dependencyinjection/8.0.0",
  209 + "hashPath": "microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512"
  210 + },
  211 + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
  212 + "type": "package",
  213 + "serviceable": true,
  214 + "sha512": "sha512-cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==",
  215 + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0",
  216 + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512"
  217 + },
  218 + "Microsoft.OpenApi/1.2.3": {
  219 + "type": "package",
  220 + "serviceable": true,
  221 + "sha512": "sha512-Nug3rO+7Kl5/SBAadzSMAVgqDlfGjJZ0GenQrLywJ84XGKO0uRqkunz5Wyl0SDwcR71bAATXvSdbdzPrYRYKGw==",
  222 + "path": "microsoft.openapi/1.2.3",
  223 + "hashPath": "microsoft.openapi.1.2.3.nupkg.sha512"
  224 + },
  225 + "Stub.System.Data.SQLite.Core.NetStandard/1.0.115.5": {
  226 + "type": "package",
  227 + "serviceable": true,
  228 + "sha512": "sha512-WfrqQg6WL+r4H1sVKTenNj6ERLXUukUxqcjH1rqPqXadeIWccTVpydESieD7cZ/NWQVSKLYIHuoBX5du+BFhIQ==",
  229 + "path": "stub.system.data.sqlite.core.netstandard/1.0.115.5",
  230 + "hashPath": "stub.system.data.sqlite.core.netstandard.1.0.115.5.nupkg.sha512"
  231 + },
  232 + "Swashbuckle.AspNetCore/6.4.0": {
  233 + "type": "package",
  234 + "serviceable": true,
  235 + "sha512": "sha512-eUBr4TW0up6oKDA5Xwkul289uqSMgY0xGN4pnbOIBqCcN9VKGGaPvHX3vWaG/hvocfGDP+MGzMA0bBBKz2fkmQ==",
  236 + "path": "swashbuckle.aspnetcore/6.4.0",
  237 + "hashPath": "swashbuckle.aspnetcore.6.4.0.nupkg.sha512"
  238 + },
  239 + "Swashbuckle.AspNetCore.Swagger/6.4.0": {
  240 + "type": "package",
  241 + "serviceable": true,
  242 + "sha512": "sha512-nl4SBgGM+cmthUcpwO/w1lUjevdDHAqRvfUoe4Xp/Uvuzt9mzGUwyFCqa3ODBAcZYBiFoKvrYwz0rabslJvSmQ==",
  243 + "path": "swashbuckle.aspnetcore.swagger/6.4.0",
  244 + "hashPath": "swashbuckle.aspnetcore.swagger.6.4.0.nupkg.sha512"
  245 + },
  246 + "Swashbuckle.AspNetCore.SwaggerGen/6.4.0": {
  247 + "type": "package",
  248 + "serviceable": true,
  249 + "sha512": "sha512-lXhcUBVqKrPFAQF7e/ZeDfb5PMgE8n5t6L5B6/BQSpiwxgHzmBcx8Msu42zLYFTvR5PIqE9Q9lZvSQAcwCxJjw==",
  250 + "path": "swashbuckle.aspnetcore.swaggergen/6.4.0",
  251 + "hashPath": "swashbuckle.aspnetcore.swaggergen.6.4.0.nupkg.sha512"
  252 + },
  253 + "Swashbuckle.AspNetCore.SwaggerUI/6.4.0": {
  254 + "type": "package",
  255 + "serviceable": true,
  256 + "sha512": "sha512-1Hh3atb3pi8c+v7n4/3N80Jj8RvLOXgWxzix6w3OZhB7zBGRwsy7FWr4e3hwgPweSBpwfElqj4V4nkjYabH9nQ==",
  257 + "path": "swashbuckle.aspnetcore.swaggerui/6.4.0",
  258 + "hashPath": "swashbuckle.aspnetcore.swaggerui.6.4.0.nupkg.sha512"
  259 + },
  260 + "System.Data.SQLite.Core/1.0.115.5": {
  261 + "type": "package",
  262 + "serviceable": true,
  263 + "sha512": "sha512-vADIqqgpxaC5xR6qOV8/KMZkQeSDCfmmWpVOtQx0oEr3Yjq2XdTxX7+jfE4+oO2xPovAbYiz6Q5cLRbSsDkq6Q==",
  264 + "path": "system.data.sqlite.core/1.0.115.5",
  265 + "hashPath": "system.data.sqlite.core.1.0.115.5.nupkg.sha512"
  266 + }
  267 + }
  268 +}
0 269 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Blueprint.Net.Server.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Blueprint.Net.Server.exe 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Blueprint.Net.Server.pdb 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Blueprint.Net.Server.runtimeconfig.json 0 → 100644
  1 +{
  2 + "runtimeOptions": {
  3 + "tfm": "net8.0",
  4 + "frameworks": [
  5 + {
  6 + "name": "Microsoft.NETCore.App",
  7 + "version": "8.0.0"
  8 + },
  9 + {
  10 + "name": "Microsoft.AspNetCore.App",
  11 + "version": "8.0.0"
  12 + }
  13 + ],
  14 + "configProperties": {
  15 + "System.GC.Server": true,
  16 + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
  17 + }
  18 + }
  19 +}
0 20 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Blueprint.Net.Server.staticwebassets.runtime.json 0 → 100644
  1 +{"ContentRoots":["E:\\Code\\Blueprint\\Blueprint.Net.Server\\wwwroot\\"],"Root":{"Children":{"index.html":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"index.html"},"Patterns":null}},"Asset":null,"Patterns":[{"ContentRootIndex":0,"Pattern":"**","Depth":0}]}}
0 2 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/FreeSql.DbContext.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/FreeSql.Provider.Sqlite.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/FreeSql.Repository.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/FreeSql.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Microsoft.OpenApi.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Swashbuckle.AspNetCore.Swagger.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerGen.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerUI.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/System.Data.SQLite.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/appsettings.Development.json 0 → 100644
  1 +{
  2 + "Logging": {
  3 + "LogLevel": {
  4 + "Default": "Information",
  5 + "Microsoft.AspNetCore": "Warning"
  6 + }
  7 + }
  8 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/appsettings.json 0 → 100644
  1 +{
  2 + "Logging": {
  3 + "LogLevel": {
  4 + "Default": "Information",
  5 + "Microsoft.AspNetCore": "Warning"
  6 + }
  7 + },
  8 + "AllowedHosts": "*"
  9 +}
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/runtimes/linux-x64/native/SQLite.Interop.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/runtimes/osx-x64/native/SQLite.Interop.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/runtimes/win-x64/native/SQLite.Interop.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/runtimes/win-x86/native/SQLite.Interop.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/zh-Hans/FreeSql.DbContext.resources.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/bin/Debug/net8.0/zh-Hans/FreeSql.resources.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/blueprint.db 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Blueprint.Net.Server.csproj.nuget.dgspec.json 0 → 100644
  1 +{
  2 + "format": 1,
  3 + "restore": {
  4 + "E:\\Code\\Blueprint\\Blueprint.Net.Server\\Blueprint.Net.Server.csproj": {}
  5 + },
  6 + "projects": {
  7 + "E:\\Code\\Blueprint\\Blueprint.Net.Server\\Blueprint.Net.Server.csproj": {
  8 + "version": "1.0.0",
  9 + "restore": {
  10 + "projectUniqueName": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\Blueprint.Net.Server.csproj",
  11 + "projectName": "Blueprint.Net.Server",
  12 + "projectPath": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\Blueprint.Net.Server.csproj",
  13 + "packagesPath": "C:\\Users\\anan\\.nuget\\packages\\",
  14 + "outputPath": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\obj\\",
  15 + "projectStyle": "PackageReference",
  16 + "fallbackFolders": [
  17 + "C:\\Users\\anan\\AppData\\Roaming\\Godot\\mono\\GodotNuGetFallbackFolder",
  18 + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
  19 + ],
  20 + "configFilePaths": [
  21 + "C:\\Users\\anan\\AppData\\Roaming\\NuGet\\NuGet.Config",
  22 + "C:\\Users\\anan\\AppData\\Roaming\\NuGet\\config\\Godot.Offline.Config",
  23 + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
  24 + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
  25 + ],
  26 + "originalTargetFrameworks": [
  27 + "net8.0"
  28 + ],
  29 + "sources": {
  30 + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
  31 + "C:\\Program Files\\dotnet\\library-packs": {},
  32 + "https://api.nuget.org/v3/index.json": {}
  33 + },
  34 + "frameworks": {
  35 + "net8.0": {
  36 + "targetAlias": "net8.0",
  37 + "projectReferences": {}
  38 + }
  39 + },
  40 + "warningProperties": {
  41 + "warnAsError": [
  42 + "NU1605"
  43 + ]
  44 + },
  45 + "restoreAuditProperties": {
  46 + "enableAudit": "true",
  47 + "auditLevel": "low",
  48 + "auditMode": "direct"
  49 + }
  50 + },
  51 + "frameworks": {
  52 + "net8.0": {
  53 + "targetAlias": "net8.0",
  54 + "dependencies": {
  55 + "FreeSql": {
  56 + "target": "Package",
  57 + "version": "[3.2.821, )"
  58 + },
  59 + "FreeSql.Provider.Sqlite": {
  60 + "target": "Package",
  61 + "version": "[3.2.821, )"
  62 + },
  63 + "FreeSql.Repository": {
  64 + "target": "Package",
  65 + "version": "[3.2.821, )"
  66 + },
  67 + "Swashbuckle.AspNetCore": {
  68 + "target": "Package",
  69 + "version": "[6.4.0, )"
  70 + }
  71 + },
  72 + "imports": [
  73 + "net461",
  74 + "net462",
  75 + "net47",
  76 + "net471",
  77 + "net472",
  78 + "net48",
  79 + "net481"
  80 + ],
  81 + "assetTargetFallback": true,
  82 + "warn": true,
  83 + "frameworkReferences": {
  84 + "Microsoft.AspNetCore.App": {
  85 + "privateAssets": "none"
  86 + },
  87 + "Microsoft.NETCore.App": {
  88 + "privateAssets": "all"
  89 + }
  90 + },
  91 + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.201/PortableRuntimeIdentifierGraph.json"
  92 + }
  93 + }
  94 + }
  95 + }
  96 +}
0 97 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Blueprint.Net.Server.csproj.nuget.g.props 0 → 100644
  1 +<?xml version="1.0" encoding="utf-8" standalone="no"?>
  2 +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3 + <PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
  4 + <RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
  5 + <RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
  6 + <ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
  7 + <NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
  8 + <NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\anan\.nuget\packages\;C:\Users\anan\AppData\Roaming\Godot\mono\GodotNuGetFallbackFolder;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
  9 + <NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
  10 + <NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.9.1</NuGetToolVersion>
  11 + </PropertyGroup>
  12 + <ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
  13 + <SourceRoot Include="C:\Users\anan\.nuget\packages\" />
  14 + <SourceRoot Include="C:\Users\anan\AppData\Roaming\Godot\mono\GodotNuGetFallbackFolder\" />
  15 + <SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
  16 + </ItemGroup>
  17 + <ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
  18 + <Import Project="$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.props" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.props')" />
  19 + <Import Project="$(NuGetPackageRoot)swashbuckle.aspnetcore\6.4.0\build\Swashbuckle.AspNetCore.props" Condition="Exists('$(NuGetPackageRoot)swashbuckle.aspnetcore\6.4.0\build\Swashbuckle.AspNetCore.props')" />
  20 + </ImportGroup>
  21 + <PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
  22 + <PkgMicrosoft_Extensions_ApiDescription_Server Condition=" '$(PkgMicrosoft_Extensions_ApiDescription_Server)' == '' ">C:\Users\anan\.nuget\packages\microsoft.extensions.apidescription.server\6.0.5</PkgMicrosoft_Extensions_ApiDescription_Server>
  23 + </PropertyGroup>
  24 +</Project>
0 25 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Blueprint.Net.Server.csproj.nuget.g.targets 0 → 100644
  1 +<?xml version="1.0" encoding="utf-8" standalone="no"?>
  2 +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3 + <ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
  4 + <Import Project="$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.apidescription.server\6.0.5\build\Microsoft.Extensions.ApiDescription.Server.targets')" />
  5 + </ImportGroup>
  6 +</Project>
0 7 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs 0 → 100644
  1 +// <autogenerated />
  2 +using System;
  3 +using System.Reflection;
  4 +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/ApiEndpoints.json 0 → 100644
  1 +[
  2 + {
  3 + "ContainingType": "Blueprint.Net.Server.Controllers.BlueprintController",
  4 + "Method": "DeleteCard",
  5 + "RelativePath": "Blueprint/DeleteCard/{id}",
  6 + "HttpMethod": "DELETE",
  7 + "IsController": true,
  8 + "Order": 0,
  9 + "Parameters": [
  10 + {
  11 + "Name": "id",
  12 + "Type": "System.Int64",
  13 + "IsRequired": true
  14 + }
  15 + ],
  16 + "ReturnTypes": []
  17 + },
  18 + {
  19 + "ContainingType": "Blueprint.Net.Server.Controllers.BlueprintController",
  20 + "Method": "DeleteLink",
  21 + "RelativePath": "Blueprint/DeleteLink/{id}",
  22 + "HttpMethod": "DELETE",
  23 + "IsController": true,
  24 + "Order": 0,
  25 + "Parameters": [
  26 + {
  27 + "Name": "id",
  28 + "Type": "System.Int64",
  29 + "IsRequired": true
  30 + }
  31 + ],
  32 + "ReturnTypes": []
  33 + },
  34 + {
  35 + "ContainingType": "Blueprint.Net.Server.Controllers.BlueprintController",
  36 + "Method": "DeleteProject",
  37 + "RelativePath": "Blueprint/DeleteProject/{id}",
  38 + "HttpMethod": "DELETE",
  39 + "IsController": true,
  40 + "Order": 0,
  41 + "Parameters": [
  42 + {
  43 + "Name": "id",
  44 + "Type": "System.Int64",
  45 + "IsRequired": true
  46 + }
  47 + ],
  48 + "ReturnTypes": []
  49 + },
  50 + {
  51 + "ContainingType": "Blueprint.Net.Server.Controllers.BlueprintController",
  52 + "Method": "DeleteWorkspace",
  53 + "RelativePath": "Blueprint/DeleteWorkspace/{id}",
  54 + "HttpMethod": "DELETE",
  55 + "IsController": true,
  56 + "Order": 0,
  57 + "Parameters": [
  58 + {
  59 + "Name": "id",
  60 + "Type": "System.Int64",
  61 + "IsRequired": true
  62 + }
  63 + ],
  64 + "ReturnTypes": []
  65 + },
  66 + {
  67 + "ContainingType": "Blueprint.Net.Server.Controllers.BlueprintController",
  68 + "Method": "GetProjects",
  69 + "RelativePath": "Blueprint/GetProjects",
  70 + "HttpMethod": "GET",
  71 + "IsController": true,
  72 + "Order": 0,
  73 + "Parameters": [],
  74 + "ReturnTypes": [
  75 + {
  76 + "Type": "System.Collections.Generic.IEnumerable\u00601[[Blueprint.Net.Server.Project, Blueprint.Net.Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]",
  77 + "MediaTypes": [
  78 + "text/plain",
  79 + "application/json",
  80 + "text/json"
  81 + ],
  82 + "StatusCode": 200
  83 + }
  84 + ]
  85 + },
  86 + {
  87 + "ContainingType": "Blueprint.Net.Server.Controllers.BlueprintController",
  88 + "Method": "Project",
  89 + "RelativePath": "Blueprint/Project",
  90 + "HttpMethod": "POST",
  91 + "IsController": true,
  92 + "Order": 0,
  93 + "Parameters": [
  94 + {
  95 + "Name": "project",
  96 + "Type": "Blueprint.Net.Server.Project",
  97 + "IsRequired": true
  98 + }
  99 + ],
  100 + "ReturnTypes": [
  101 + {
  102 + "Type": "Blueprint.Net.Server.Project",
  103 + "MediaTypes": [
  104 + "text/plain",
  105 + "application/json",
  106 + "text/json"
  107 + ],
  108 + "StatusCode": 200
  109 + }
  110 + ]
  111 + }
  112 +]
0 113 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprin.F6C0E272.Up2Date 0 → 100644
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.AssemblyInfo.cs 0 → 100644
  1 +//------------------------------------------------------------------------------
  2 +// <auto-generated>
  3 +// This code was generated by a tool.
  4 +//
  5 +// Changes to this file may cause incorrect behavior and will be lost if
  6 +// the code is regenerated.
  7 +// </auto-generated>
  8 +//------------------------------------------------------------------------------
  9 +
  10 +using System;
  11 +using System.Reflection;
  12 +
  13 +[assembly: System.Reflection.AssemblyCompanyAttribute("Blueprint.Net.Server")]
  14 +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
  15 +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
  16 +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+21310e5f9b84d697cb0feff5b5ab032eedbd8151")]
  17 +[assembly: System.Reflection.AssemblyProductAttribute("Blueprint.Net.Server")]
  18 +[assembly: System.Reflection.AssemblyTitleAttribute("Blueprint.Net.Server")]
  19 +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
  20 +
  21 +// 由 MSBuild WriteCodeFragment 类生成。
  22 +
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.AssemblyInfoInputs.cache 0 → 100644
  1 +5eddb37dc7a53e4fa87096743c7acd0b6360a57b70e21a4550930a7499bb9c12
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.GeneratedMSBuildEditorConfig.editorconfig 0 → 100644
  1 +is_global = true
  2 +build_property.TargetFramework = net8.0
  3 +build_property.TargetPlatformMinVersion =
  4 +build_property.UsingMicrosoftNETSdkWeb = true
  5 +build_property.ProjectTypeGuids =
  6 +build_property.InvariantGlobalization =
  7 +build_property.PlatformNeutralAssembly =
  8 +build_property.EnforceExtendedAnalyzerRules =
  9 +build_property._SupportedPlatformList = Linux,macOS,Windows
  10 +build_property.RootNamespace = Blueprint.Net.Server
  11 +build_property.RootNamespace = Blueprint.Net.Server
  12 +build_property.ProjectDir = E:\Code\Blueprint\Blueprint.Net.Server\
  13 +build_property.EnableComHosting =
  14 +build_property.EnableGeneratedComInterfaceComImportInterop =
  15 +build_property.RazorLangVersion = 8.0
  16 +build_property.SupportLocalizedComponentNames =
  17 +build_property.GenerateRazorMetadataSourceChecksumAttributes =
  18 +build_property.MSBuildProjectDirectory = E:\Code\Blueprint\Blueprint.Net.Server
  19 +build_property._RazorSourceGeneratorDebug =
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.GlobalUsings.g.cs 0 → 100644
  1 +// <auto-generated/>
  2 +global using global::Microsoft.AspNetCore.Builder;
  3 +global using global::Microsoft.AspNetCore.Hosting;
  4 +global using global::Microsoft.AspNetCore.Http;
  5 +global using global::Microsoft.AspNetCore.Routing;
  6 +global using global::Microsoft.Extensions.Configuration;
  7 +global using global::Microsoft.Extensions.DependencyInjection;
  8 +global using global::Microsoft.Extensions.Hosting;
  9 +global using global::Microsoft.Extensions.Logging;
  10 +global using global::System;
  11 +global using global::System.Collections.Generic;
  12 +global using global::System.IO;
  13 +global using global::System.Linq;
  14 +global using global::System.Net.Http;
  15 +global using global::System.Net.Http.Json;
  16 +global using global::System.Threading;
  17 +global using global::System.Threading.Tasks;
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.MvcApplicationPartsAssemblyInfo.cache 0 → 100644
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.MvcApplicationPartsAssemblyInfo.cs 0 → 100644
  1 +//------------------------------------------------------------------------------
  2 +// <auto-generated>
  3 +// 此代码由工具生成。
  4 +// 运行时版本:4.0.30319.42000
  5 +//
  6 +// 对此文件的更改可能会导致不正确的行为,并且如果
  7 +// 重新生成代码,这些更改将会丢失。
  8 +// </auto-generated>
  9 +//------------------------------------------------------------------------------
  10 +
  11 +using System;
  12 +using System.Reflection;
  13 +
  14 +[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("Swashbuckle.AspNetCore.SwaggerGen")]
  15 +
  16 +// 由 MSBuild WriteCodeFragment 类生成。
  17 +
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.assets.cache 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.csproj.AssemblyReference.cache 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.csproj.BuildWithSkipAnalyzers 0 → 100644
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.csproj.CoreCompileInputs.cache 0 → 100644
  1 +e6649176d8592337858ccf92973fd389b3d88f5441cf720c89972060326574ca
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.csproj.FileListAbsolute.txt 0 → 100644
  1 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.csproj.AssemblyReference.cache
  2 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.GeneratedMSBuildEditorConfig.editorconfig
  3 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.AssemblyInfoInputs.cache
  4 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.AssemblyInfo.cs
  5 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.csproj.CoreCompileInputs.cache
  6 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.MvcApplicationPartsAssemblyInfo.cs
  7 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.MvcApplicationPartsAssemblyInfo.cache
  8 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.sourcelink.json
  9 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\appsettings.Development.json
  10 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\appsettings.json
  11 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Blueprint.Net.Server.exe
  12 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Blueprint.Net.Server.deps.json
  13 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Blueprint.Net.Server.runtimeconfig.json
  14 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Blueprint.Net.Server.dll
  15 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Blueprint.Net.Server.pdb
  16 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\FreeSql.dll
  17 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\FreeSql.Provider.Sqlite.dll
  18 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Microsoft.OpenApi.dll
  19 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\System.Data.SQLite.dll
  20 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Swashbuckle.AspNetCore.Swagger.dll
  21 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Swashbuckle.AspNetCore.SwaggerGen.dll
  22 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Swashbuckle.AspNetCore.SwaggerUI.dll
  23 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\zh-Hans\FreeSql.resources.dll
  24 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\runtimes\linux-x64\native\SQLite.Interop.dll
  25 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\runtimes\osx-x64\native\SQLite.Interop.dll
  26 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\runtimes\win-x64\native\SQLite.Interop.dll
  27 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\runtimes\win-x86\native\SQLite.Interop.dll
  28 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\staticwebassets.build.json
  29 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\staticwebassets.development.json
  30 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\staticwebassets\msbuild.Blueprint.Net.Server.Microsoft.AspNetCore.StaticWebAssets.props
  31 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\staticwebassets\msbuild.build.Blueprint.Net.Server.props
  32 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\staticwebassets\msbuild.buildMultiTargeting.Blueprint.Net.Server.props
  33 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\staticwebassets\msbuild.buildTransitive.Blueprint.Net.Server.props
  34 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\staticwebassets.pack.json
  35 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\scopedcss\bundle\Blueprint.Net.Server.styles.css
  36 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprin.F6C0E272.Up2Date
  37 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.dll
  38 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\refint\Blueprint.Net.Server.dll
  39 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.pdb
  40 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\Blueprint.Net.Server.genruntimeconfig.cache
  41 +E:\Code\Blueprint\Blueprint.Net.Server\obj\Debug\net8.0\ref\Blueprint.Net.Server.dll
  42 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\FreeSql.DbContext.dll
  43 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\FreeSql.Repository.dll
  44 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\zh-Hans\FreeSql.DbContext.resources.dll
  45 +E:\Code\Blueprint\Blueprint.Net.Server\bin\Debug\net8.0\Blueprint.Net.Server.staticwebassets.runtime.json
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.genruntimeconfig.cache 0 → 100644
  1 +8acfbde84a0808a05ea09472133bf8a326d26f20e0ddb65a94244d389946671b
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.pdb 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/Blueprint.Net.Server.sourcelink.json 0 → 100644
  1 +{"documents":{"E:\\Code\\Blueprint\\*":"https://raw.githubusercontent.com/anan1213095357/Blueprint/b65316686ddc54c7cc975c98021932eb8cd587e0/*"}}
0 2 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/apphost.exe 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/ref/Blueprint.Net.Server.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/refint/Blueprint.Net.Server.dll 0 → 100644
No preview for this file type
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/staticwebassets.build.json 0 → 100644
  1 +{
  2 + "Version": 1,
  3 + "Hash": "Pejh5880OWDtzUDeaYI0R3uZI5plIRGeOY+LIYo1sp8=",
  4 + "Source": "Blueprint.Net.Server",
  5 + "BasePath": "_content/Blueprint.Net.Server",
  6 + "Mode": "Default",
  7 + "ManifestType": "Build",
  8 + "ReferencedProjectsConfiguration": [],
  9 + "DiscoveryPatterns": [
  10 + {
  11 + "Name": "Blueprint.Net.Server\\wwwroot",
  12 + "Source": "Blueprint.Net.Server",
  13 + "ContentRoot": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\wwwroot\\",
  14 + "BasePath": "_content/Blueprint.Net.Server",
  15 + "Pattern": "**"
  16 + }
  17 + ],
  18 + "Assets": [
  19 + {
  20 + "Identity": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\wwwroot\\index.html",
  21 + "SourceId": "Blueprint.Net.Server",
  22 + "SourceType": "Discovered",
  23 + "ContentRoot": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\wwwroot\\",
  24 + "BasePath": "_content/Blueprint.Net.Server",
  25 + "RelativePath": "index.html",
  26 + "AssetKind": "All",
  27 + "AssetMode": "All",
  28 + "AssetRole": "Primary",
  29 + "AssetMergeBehavior": "PreferTarget",
  30 + "AssetMergeSource": "",
  31 + "RelatedAsset": "",
  32 + "AssetTraitName": "",
  33 + "AssetTraitValue": "",
  34 + "CopyToOutputDirectory": "Never",
  35 + "CopyToPublishDirectory": "PreserveNewest",
  36 + "OriginalItemSpec": "wwwroot\\index.html"
  37 + }
  38 + ]
  39 +}
0 40 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/staticwebassets.development.json 0 → 100644
  1 +{"ContentRoots":["E:\\Code\\Blueprint\\Blueprint.Net.Server\\wwwroot\\"],"Root":{"Children":{"index.html":{"Children":null,"Asset":{"ContentRootIndex":0,"SubPath":"index.html"},"Patterns":null}},"Asset":null,"Patterns":[{"ContentRootIndex":0,"Pattern":"**","Depth":0}]}}
0 2 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/staticwebassets.pack.json 0 → 100644
  1 +{
  2 + "Files": [
  3 + {
  4 + "Id": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\wwwroot\\index.html",
  5 + "PackagePath": "staticwebassets\\index.html"
  6 + },
  7 + {
  8 + "Id": "obj\\Debug\\net8.0\\staticwebassets\\msbuild.Blueprint.Net.Server.Microsoft.AspNetCore.StaticWebAssets.props",
  9 + "PackagePath": "build\\Microsoft.AspNetCore.StaticWebAssets.props"
  10 + },
  11 + {
  12 + "Id": "obj\\Debug\\net8.0\\staticwebassets\\msbuild.build.Blueprint.Net.Server.props",
  13 + "PackagePath": "build\\Blueprint.Net.Server.props"
  14 + },
  15 + {
  16 + "Id": "obj\\Debug\\net8.0\\staticwebassets\\msbuild.buildMultiTargeting.Blueprint.Net.Server.props",
  17 + "PackagePath": "buildMultiTargeting\\Blueprint.Net.Server.props"
  18 + },
  19 + {
  20 + "Id": "obj\\Debug\\net8.0\\staticwebassets\\msbuild.buildTransitive.Blueprint.Net.Server.props",
  21 + "PackagePath": "buildTransitive\\Blueprint.Net.Server.props"
  22 + }
  23 + ],
  24 + "ElementsToRemove": []
  25 +}
0 26 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/staticwebassets/msbuild.Blueprint.Net.Server.Microsoft.AspNetCore.StaticWebAssets.props 0 → 100644
  1 +<Project>
  2 + <ItemGroup>
  3 + <StaticWebAsset Include="$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\index.html))">
  4 + <SourceType>Package</SourceType>
  5 + <SourceId>Blueprint.Net.Server</SourceId>
  6 + <ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
  7 + <BasePath>_content/Blueprint.Net.Server</BasePath>
  8 + <RelativePath>index.html</RelativePath>
  9 + <AssetKind>All</AssetKind>
  10 + <AssetMode>All</AssetMode>
  11 + <AssetRole>Primary</AssetRole>
  12 + <RelatedAsset></RelatedAsset>
  13 + <AssetTraitName></AssetTraitName>
  14 + <AssetTraitValue></AssetTraitValue>
  15 + <CopyToOutputDirectory>Never</CopyToOutputDirectory>
  16 + <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
  17 + <OriginalItemSpec>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\staticwebassets\index.html))</OriginalItemSpec>
  18 + </StaticWebAsset>
  19 + </ItemGroup>
  20 +</Project>
0 21 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/staticwebassets/msbuild.build.Blueprint.Net.Server.props 0 → 100644
  1 +<Project>
  2 + <Import Project="Microsoft.AspNetCore.StaticWebAssets.props" />
  3 +</Project>
0 4 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/staticwebassets/msbuild.buildMultiTargeting.Blueprint.Net.Server.props 0 → 100644
  1 +<Project>
  2 + <Import Project="..\build\Blueprint.Net.Server.props" />
  3 +</Project>
0 4 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/Debug/net8.0/staticwebassets/msbuild.buildTransitive.Blueprint.Net.Server.props 0 → 100644
  1 +<Project>
  2 + <Import Project="..\buildMultiTargeting\Blueprint.Net.Server.props" />
  3 +</Project>
0 4 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/project.assets.json 0 → 100644
  1 +{
  2 + "version": 3,
  3 + "targets": {
  4 + "net8.0": {
  5 + "FreeSql/3.2.821": {
  6 + "type": "package",
  7 + "compile": {
  8 + "lib/netstandard2.1/FreeSql.dll": {
  9 + "related": ".pdb;.xml"
  10 + }
  11 + },
  12 + "runtime": {
  13 + "lib/netstandard2.1/FreeSql.dll": {
  14 + "related": ".pdb;.xml"
  15 + }
  16 + },
  17 + "resource": {
  18 + "lib/netstandard2.1/zh-Hans/FreeSql.resources.dll": {
  19 + "locale": "zh-Hans"
  20 + }
  21 + }
  22 + },
  23 + "FreeSql.DbContext/3.2.821": {
  24 + "type": "package",
  25 + "dependencies": {
  26 + "FreeSql": "3.2.821",
  27 + "Microsoft.Extensions.DependencyInjection": "8.0.0"
  28 + },
  29 + "compile": {
  30 + "lib/net8.0/FreeSql.DbContext.dll": {
  31 + "related": ".pdb;.xml"
  32 + }
  33 + },
  34 + "runtime": {
  35 + "lib/net8.0/FreeSql.DbContext.dll": {
  36 + "related": ".pdb;.xml"
  37 + }
  38 + },
  39 + "resource": {
  40 + "lib/net8.0/zh-Hans/FreeSql.DbContext.resources.dll": {
  41 + "locale": "zh-Hans"
  42 + }
  43 + }
  44 + },
  45 + "FreeSql.Provider.Sqlite/3.2.821": {
  46 + "type": "package",
  47 + "dependencies": {
  48 + "FreeSql": "3.2.821",
  49 + "System.Data.SQLite.Core": "1.0.115.5"
  50 + },
  51 + "compile": {
  52 + "lib/netstandard2.0/FreeSql.Provider.Sqlite.dll": {
  53 + "related": ".pdb"
  54 + }
  55 + },
  56 + "runtime": {
  57 + "lib/netstandard2.0/FreeSql.Provider.Sqlite.dll": {
  58 + "related": ".pdb"
  59 + }
  60 + }
  61 + },
  62 + "FreeSql.Repository/3.2.821": {
  63 + "type": "package",
  64 + "dependencies": {
  65 + "FreeSql.DbContext": "3.2.821"
  66 + },
  67 + "compile": {
  68 + "lib/net8.0/FreeSql.Repository.dll": {
  69 + "related": ".pdb"
  70 + }
  71 + },
  72 + "runtime": {
  73 + "lib/net8.0/FreeSql.Repository.dll": {
  74 + "related": ".pdb"
  75 + }
  76 + }
  77 + },
  78 + "Microsoft.Extensions.ApiDescription.Server/6.0.5": {
  79 + "type": "package",
  80 + "build": {
  81 + "build/Microsoft.Extensions.ApiDescription.Server.props": {},
  82 + "build/Microsoft.Extensions.ApiDescription.Server.targets": {}
  83 + },
  84 + "buildMultiTargeting": {
  85 + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.props": {},
  86 + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.targets": {}
  87 + }
  88 + },
  89 + "Microsoft.Extensions.DependencyInjection/8.0.0": {
  90 + "type": "package",
  91 + "dependencies": {
  92 + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
  93 + },
  94 + "compile": {
  95 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": {
  96 + "related": ".xml"
  97 + }
  98 + },
  99 + "runtime": {
  100 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": {
  101 + "related": ".xml"
  102 + }
  103 + },
  104 + "build": {
  105 + "buildTransitive/net6.0/_._": {}
  106 + }
  107 + },
  108 + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
  109 + "type": "package",
  110 + "compile": {
  111 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
  112 + "related": ".xml"
  113 + }
  114 + },
  115 + "runtime": {
  116 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
  117 + "related": ".xml"
  118 + }
  119 + },
  120 + "build": {
  121 + "buildTransitive/net6.0/_._": {}
  122 + }
  123 + },
  124 + "Microsoft.OpenApi/1.2.3": {
  125 + "type": "package",
  126 + "compile": {
  127 + "lib/netstandard2.0/Microsoft.OpenApi.dll": {
  128 + "related": ".pdb;.xml"
  129 + }
  130 + },
  131 + "runtime": {
  132 + "lib/netstandard2.0/Microsoft.OpenApi.dll": {
  133 + "related": ".pdb;.xml"
  134 + }
  135 + }
  136 + },
  137 + "Stub.System.Data.SQLite.Core.NetStandard/1.0.115.5": {
  138 + "type": "package",
  139 + "compile": {
  140 + "lib/netstandard2.1/System.Data.SQLite.dll": {
  141 + "related": ".dll.altconfig;.xml"
  142 + }
  143 + },
  144 + "runtime": {
  145 + "lib/netstandard2.1/System.Data.SQLite.dll": {
  146 + "related": ".dll.altconfig;.xml"
  147 + }
  148 + },
  149 + "runtimeTargets": {
  150 + "runtimes/linux-x64/native/SQLite.Interop.dll": {
  151 + "assetType": "native",
  152 + "rid": "linux-x64"
  153 + },
  154 + "runtimes/osx-x64/native/SQLite.Interop.dll": {
  155 + "assetType": "native",
  156 + "rid": "osx-x64"
  157 + },
  158 + "runtimes/win-x64/native/SQLite.Interop.dll": {
  159 + "assetType": "native",
  160 + "rid": "win-x64"
  161 + },
  162 + "runtimes/win-x86/native/SQLite.Interop.dll": {
  163 + "assetType": "native",
  164 + "rid": "win-x86"
  165 + }
  166 + }
  167 + },
  168 + "Swashbuckle.AspNetCore/6.4.0": {
  169 + "type": "package",
  170 + "dependencies": {
  171 + "Microsoft.Extensions.ApiDescription.Server": "6.0.5",
  172 + "Swashbuckle.AspNetCore.Swagger": "6.4.0",
  173 + "Swashbuckle.AspNetCore.SwaggerGen": "6.4.0",
  174 + "Swashbuckle.AspNetCore.SwaggerUI": "6.4.0"
  175 + },
  176 + "build": {
  177 + "build/Swashbuckle.AspNetCore.props": {}
  178 + }
  179 + },
  180 + "Swashbuckle.AspNetCore.Swagger/6.4.0": {
  181 + "type": "package",
  182 + "dependencies": {
  183 + "Microsoft.OpenApi": "1.2.3"
  184 + },
  185 + "compile": {
  186 + "lib/net6.0/Swashbuckle.AspNetCore.Swagger.dll": {
  187 + "related": ".pdb;.xml"
  188 + }
  189 + },
  190 + "runtime": {
  191 + "lib/net6.0/Swashbuckle.AspNetCore.Swagger.dll": {
  192 + "related": ".pdb;.xml"
  193 + }
  194 + },
  195 + "frameworkReferences": [
  196 + "Microsoft.AspNetCore.App"
  197 + ]
  198 + },
  199 + "Swashbuckle.AspNetCore.SwaggerGen/6.4.0": {
  200 + "type": "package",
  201 + "dependencies": {
  202 + "Swashbuckle.AspNetCore.Swagger": "6.4.0"
  203 + },
  204 + "compile": {
  205 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerGen.dll": {
  206 + "related": ".pdb;.xml"
  207 + }
  208 + },
  209 + "runtime": {
  210 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerGen.dll": {
  211 + "related": ".pdb;.xml"
  212 + }
  213 + }
  214 + },
  215 + "Swashbuckle.AspNetCore.SwaggerUI/6.4.0": {
  216 + "type": "package",
  217 + "compile": {
  218 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerUI.dll": {
  219 + "related": ".pdb;.xml"
  220 + }
  221 + },
  222 + "runtime": {
  223 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerUI.dll": {
  224 + "related": ".pdb;.xml"
  225 + }
  226 + },
  227 + "frameworkReferences": [
  228 + "Microsoft.AspNetCore.App"
  229 + ]
  230 + },
  231 + "System.Data.SQLite.Core/1.0.115.5": {
  232 + "type": "package",
  233 + "dependencies": {
  234 + "Stub.System.Data.SQLite.Core.NetStandard": "[1.0.115.5]"
  235 + }
  236 + }
  237 + }
  238 + },
  239 + "libraries": {
  240 + "FreeSql/3.2.821": {
  241 + "sha512": "bI/CTioEq4B9k5pqaZnXBSyJCIbHoUUTJGgQJF5osgq7/9kOxZo93hmZr8Vw6n5iFG5chx6wkcn4dnJJUsAEkA==",
  242 + "type": "package",
  243 + "path": "freesql/3.2.821",
  244 + "files": [
  245 + ".nupkg.metadata",
  246 + ".signature.p7s",
  247 + "freesql.3.2.821.nupkg.sha512",
  248 + "freesql.nuspec",
  249 + "lib/net40/FreeSql.dll",
  250 + "lib/net40/FreeSql.pdb",
  251 + "lib/net40/FreeSql.xml",
  252 + "lib/net40/zh-Hans/FreeSql.resources.dll",
  253 + "lib/net45/FreeSql.dll",
  254 + "lib/net45/FreeSql.pdb",
  255 + "lib/net45/FreeSql.xml",
  256 + "lib/net45/zh-Hans/FreeSql.resources.dll",
  257 + "lib/net451/FreeSql.dll",
  258 + "lib/net451/FreeSql.pdb",
  259 + "lib/net451/FreeSql.xml",
  260 + "lib/net451/zh-Hans/FreeSql.resources.dll",
  261 + "lib/netstandard2.0/FreeSql.dll",
  262 + "lib/netstandard2.0/FreeSql.pdb",
  263 + "lib/netstandard2.0/FreeSql.xml",
  264 + "lib/netstandard2.0/zh-Hans/FreeSql.resources.dll",
  265 + "lib/netstandard2.1/FreeSql.dll",
  266 + "lib/netstandard2.1/FreeSql.pdb",
  267 + "lib/netstandard2.1/FreeSql.xml",
  268 + "lib/netstandard2.1/zh-Hans/FreeSql.resources.dll",
  269 + "logo.png",
  270 + "readme.md"
  271 + ]
  272 + },
  273 + "FreeSql.DbContext/3.2.821": {
  274 + "sha512": "wQWjKj7/2Iwzp5WxOE5WV/HmoVmj6fKPYGBxKB7JWxF7HudmXjeZS1Hll2ovQksqF/YujYf7SxGbDv5mU9qSGA==",
  275 + "type": "package",
  276 + "path": "freesql.dbcontext/3.2.821",
  277 + "files": [
  278 + ".nupkg.metadata",
  279 + ".signature.p7s",
  280 + "freesql.dbcontext.3.2.821.nupkg.sha512",
  281 + "freesql.dbcontext.nuspec",
  282 + "lib/net40/FreeSql.DbContext.dll",
  283 + "lib/net40/FreeSql.DbContext.pdb",
  284 + "lib/net40/FreeSql.DbContext.xml",
  285 + "lib/net40/zh-Hans/FreeSql.DbContext.resources.dll",
  286 + "lib/net45/FreeSql.DbContext.dll",
  287 + "lib/net45/FreeSql.DbContext.pdb",
  288 + "lib/net45/FreeSql.DbContext.xml",
  289 + "lib/net45/zh-Hans/FreeSql.DbContext.resources.dll",
  290 + "lib/net5.0/FreeSql.DbContext.dll",
  291 + "lib/net5.0/FreeSql.DbContext.pdb",
  292 + "lib/net5.0/FreeSql.DbContext.xml",
  293 + "lib/net5.0/zh-Hans/FreeSql.DbContext.resources.dll",
  294 + "lib/net6.0/FreeSql.DbContext.dll",
  295 + "lib/net6.0/FreeSql.DbContext.pdb",
  296 + "lib/net6.0/FreeSql.DbContext.xml",
  297 + "lib/net6.0/zh-Hans/FreeSql.DbContext.resources.dll",
  298 + "lib/net7.0/FreeSql.DbContext.dll",
  299 + "lib/net7.0/FreeSql.DbContext.pdb",
  300 + "lib/net7.0/FreeSql.DbContext.xml",
  301 + "lib/net7.0/zh-Hans/FreeSql.DbContext.resources.dll",
  302 + "lib/net8.0/FreeSql.DbContext.dll",
  303 + "lib/net8.0/FreeSql.DbContext.pdb",
  304 + "lib/net8.0/FreeSql.DbContext.xml",
  305 + "lib/net8.0/zh-Hans/FreeSql.DbContext.resources.dll",
  306 + "lib/netcoreapp3.1/FreeSql.DbContext.dll",
  307 + "lib/netcoreapp3.1/FreeSql.DbContext.pdb",
  308 + "lib/netcoreapp3.1/FreeSql.DbContext.xml",
  309 + "lib/netcoreapp3.1/zh-Hans/FreeSql.DbContext.resources.dll",
  310 + "lib/netstandard2.0/FreeSql.DbContext.dll",
  311 + "lib/netstandard2.0/FreeSql.DbContext.pdb",
  312 + "lib/netstandard2.0/FreeSql.DbContext.xml",
  313 + "lib/netstandard2.0/zh-Hans/FreeSql.DbContext.resources.dll",
  314 + "lib/netstandard2.1/FreeSql.DbContext.dll",
  315 + "lib/netstandard2.1/FreeSql.DbContext.pdb",
  316 + "lib/netstandard2.1/FreeSql.DbContext.xml",
  317 + "lib/netstandard2.1/zh-Hans/FreeSql.DbContext.resources.dll",
  318 + "logo.png",
  319 + "readme.md"
  320 + ]
  321 + },
  322 + "FreeSql.Provider.Sqlite/3.2.821": {
  323 + "sha512": "vBvvq9mDz488XWYeNQSSt8t3FCKquS4DPab7hu7QVRF0ftXRAc6rRK5axFFJZjc5ABU7aIKtu1UiKQky8z/VnA==",
  324 + "type": "package",
  325 + "path": "freesql.provider.sqlite/3.2.821",
  326 + "files": [
  327 + ".nupkg.metadata",
  328 + ".signature.p7s",
  329 + "freesql.provider.sqlite.3.2.821.nupkg.sha512",
  330 + "freesql.provider.sqlite.nuspec",
  331 + "lib/net40/FreeSql.Provider.Sqlite.dll",
  332 + "lib/net40/FreeSql.Provider.Sqlite.pdb",
  333 + "lib/net45/FreeSql.Provider.Sqlite.dll",
  334 + "lib/net45/FreeSql.Provider.Sqlite.pdb",
  335 + "lib/netstandard2.0/FreeSql.Provider.Sqlite.dll",
  336 + "lib/netstandard2.0/FreeSql.Provider.Sqlite.pdb",
  337 + "logo.png",
  338 + "readme.md"
  339 + ]
  340 + },
  341 + "FreeSql.Repository/3.2.821": {
  342 + "sha512": "cE/VG103FYXn2m63Xp7heYptPazNN+z+dUm9jZe2vNwV8LUCU3PbY04MD+liyQBCZ5WGCK70Pe4GXGfQzvRMLw==",
  343 + "type": "package",
  344 + "path": "freesql.repository/3.2.821",
  345 + "files": [
  346 + ".nupkg.metadata",
  347 + ".signature.p7s",
  348 + "freesql.repository.3.2.821.nupkg.sha512",
  349 + "freesql.repository.nuspec",
  350 + "lib/net40/FreeSql.Repository.dll",
  351 + "lib/net40/FreeSql.Repository.pdb",
  352 + "lib/net45/FreeSql.Repository.dll",
  353 + "lib/net45/FreeSql.Repository.pdb",
  354 + "lib/net5.0/FreeSql.Repository.dll",
  355 + "lib/net5.0/FreeSql.Repository.pdb",
  356 + "lib/net6.0/FreeSql.Repository.dll",
  357 + "lib/net6.0/FreeSql.Repository.pdb",
  358 + "lib/net7.0/FreeSql.Repository.dll",
  359 + "lib/net7.0/FreeSql.Repository.pdb",
  360 + "lib/net8.0/FreeSql.Repository.dll",
  361 + "lib/net8.0/FreeSql.Repository.pdb",
  362 + "lib/netcoreapp3.1/FreeSql.Repository.dll",
  363 + "lib/netcoreapp3.1/FreeSql.Repository.pdb",
  364 + "lib/netstandard2.0/FreeSql.Repository.dll",
  365 + "lib/netstandard2.0/FreeSql.Repository.pdb",
  366 + "lib/netstandard2.1/FreeSql.Repository.dll",
  367 + "lib/netstandard2.1/FreeSql.Repository.pdb",
  368 + "logo.png",
  369 + "readme.md"
  370 + ]
  371 + },
  372 + "Microsoft.Extensions.ApiDescription.Server/6.0.5": {
  373 + "sha512": "Ckb5EDBUNJdFWyajfXzUIMRkhf52fHZOQuuZg/oiu8y7zDCVwD0iHhew6MnThjHmevanpxL3f5ci2TtHQEN6bw==",
  374 + "type": "package",
  375 + "path": "microsoft.extensions.apidescription.server/6.0.5",
  376 + "hasTools": true,
  377 + "files": [
  378 + ".nupkg.metadata",
  379 + ".signature.p7s",
  380 + "Icon.png",
  381 + "build/Microsoft.Extensions.ApiDescription.Server.props",
  382 + "build/Microsoft.Extensions.ApiDescription.Server.targets",
  383 + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.props",
  384 + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.targets",
  385 + "microsoft.extensions.apidescription.server.6.0.5.nupkg.sha512",
  386 + "microsoft.extensions.apidescription.server.nuspec",
  387 + "tools/Newtonsoft.Json.dll",
  388 + "tools/dotnet-getdocument.deps.json",
  389 + "tools/dotnet-getdocument.dll",
  390 + "tools/dotnet-getdocument.runtimeconfig.json",
  391 + "tools/net461-x86/GetDocument.Insider.exe",
  392 + "tools/net461-x86/GetDocument.Insider.exe.config",
  393 + "tools/net461-x86/Microsoft.Win32.Primitives.dll",
  394 + "tools/net461-x86/System.AppContext.dll",
  395 + "tools/net461-x86/System.Buffers.dll",
  396 + "tools/net461-x86/System.Collections.Concurrent.dll",
  397 + "tools/net461-x86/System.Collections.NonGeneric.dll",
  398 + "tools/net461-x86/System.Collections.Specialized.dll",
  399 + "tools/net461-x86/System.Collections.dll",
  400 + "tools/net461-x86/System.ComponentModel.EventBasedAsync.dll",
  401 + "tools/net461-x86/System.ComponentModel.Primitives.dll",
  402 + "tools/net461-x86/System.ComponentModel.TypeConverter.dll",
  403 + "tools/net461-x86/System.ComponentModel.dll",
  404 + "tools/net461-x86/System.Console.dll",
  405 + "tools/net461-x86/System.Data.Common.dll",
  406 + "tools/net461-x86/System.Diagnostics.Contracts.dll",
  407 + "tools/net461-x86/System.Diagnostics.Debug.dll",
  408 + "tools/net461-x86/System.Diagnostics.DiagnosticSource.dll",
  409 + "tools/net461-x86/System.Diagnostics.FileVersionInfo.dll",
  410 + "tools/net461-x86/System.Diagnostics.Process.dll",
  411 + "tools/net461-x86/System.Diagnostics.StackTrace.dll",
  412 + "tools/net461-x86/System.Diagnostics.TextWriterTraceListener.dll",
  413 + "tools/net461-x86/System.Diagnostics.Tools.dll",
  414 + "tools/net461-x86/System.Diagnostics.TraceSource.dll",
  415 + "tools/net461-x86/System.Diagnostics.Tracing.dll",
  416 + "tools/net461-x86/System.Drawing.Primitives.dll",
  417 + "tools/net461-x86/System.Dynamic.Runtime.dll",
  418 + "tools/net461-x86/System.Globalization.Calendars.dll",
  419 + "tools/net461-x86/System.Globalization.Extensions.dll",
  420 + "tools/net461-x86/System.Globalization.dll",
  421 + "tools/net461-x86/System.IO.Compression.ZipFile.dll",
  422 + "tools/net461-x86/System.IO.Compression.dll",
  423 + "tools/net461-x86/System.IO.FileSystem.DriveInfo.dll",
  424 + "tools/net461-x86/System.IO.FileSystem.Primitives.dll",
  425 + "tools/net461-x86/System.IO.FileSystem.Watcher.dll",
  426 + "tools/net461-x86/System.IO.FileSystem.dll",
  427 + "tools/net461-x86/System.IO.IsolatedStorage.dll",
  428 + "tools/net461-x86/System.IO.MemoryMappedFiles.dll",
  429 + "tools/net461-x86/System.IO.Pipes.dll",
  430 + "tools/net461-x86/System.IO.UnmanagedMemoryStream.dll",
  431 + "tools/net461-x86/System.IO.dll",
  432 + "tools/net461-x86/System.Linq.Expressions.dll",
  433 + "tools/net461-x86/System.Linq.Parallel.dll",
  434 + "tools/net461-x86/System.Linq.Queryable.dll",
  435 + "tools/net461-x86/System.Linq.dll",
  436 + "tools/net461-x86/System.Memory.dll",
  437 + "tools/net461-x86/System.Net.Http.dll",
  438 + "tools/net461-x86/System.Net.NameResolution.dll",
  439 + "tools/net461-x86/System.Net.NetworkInformation.dll",
  440 + "tools/net461-x86/System.Net.Ping.dll",
  441 + "tools/net461-x86/System.Net.Primitives.dll",
  442 + "tools/net461-x86/System.Net.Requests.dll",
  443 + "tools/net461-x86/System.Net.Security.dll",
  444 + "tools/net461-x86/System.Net.Sockets.dll",
  445 + "tools/net461-x86/System.Net.WebHeaderCollection.dll",
  446 + "tools/net461-x86/System.Net.WebSockets.Client.dll",
  447 + "tools/net461-x86/System.Net.WebSockets.dll",
  448 + "tools/net461-x86/System.Numerics.Vectors.dll",
  449 + "tools/net461-x86/System.ObjectModel.dll",
  450 + "tools/net461-x86/System.Reflection.Extensions.dll",
  451 + "tools/net461-x86/System.Reflection.Primitives.dll",
  452 + "tools/net461-x86/System.Reflection.dll",
  453 + "tools/net461-x86/System.Resources.Reader.dll",
  454 + "tools/net461-x86/System.Resources.ResourceManager.dll",
  455 + "tools/net461-x86/System.Resources.Writer.dll",
  456 + "tools/net461-x86/System.Runtime.CompilerServices.Unsafe.dll",
  457 + "tools/net461-x86/System.Runtime.CompilerServices.VisualC.dll",
  458 + "tools/net461-x86/System.Runtime.Extensions.dll",
  459 + "tools/net461-x86/System.Runtime.Handles.dll",
  460 + "tools/net461-x86/System.Runtime.InteropServices.RuntimeInformation.dll",
  461 + "tools/net461-x86/System.Runtime.InteropServices.dll",
  462 + "tools/net461-x86/System.Runtime.Numerics.dll",
  463 + "tools/net461-x86/System.Runtime.Serialization.Formatters.dll",
  464 + "tools/net461-x86/System.Runtime.Serialization.Json.dll",
  465 + "tools/net461-x86/System.Runtime.Serialization.Primitives.dll",
  466 + "tools/net461-x86/System.Runtime.Serialization.Xml.dll",
  467 + "tools/net461-x86/System.Runtime.dll",
  468 + "tools/net461-x86/System.Security.Claims.dll",
  469 + "tools/net461-x86/System.Security.Cryptography.Algorithms.dll",
  470 + "tools/net461-x86/System.Security.Cryptography.Csp.dll",
  471 + "tools/net461-x86/System.Security.Cryptography.Encoding.dll",
  472 + "tools/net461-x86/System.Security.Cryptography.Primitives.dll",
  473 + "tools/net461-x86/System.Security.Cryptography.X509Certificates.dll",
  474 + "tools/net461-x86/System.Security.Principal.dll",
  475 + "tools/net461-x86/System.Security.SecureString.dll",
  476 + "tools/net461-x86/System.Text.Encoding.Extensions.dll",
  477 + "tools/net461-x86/System.Text.Encoding.dll",
  478 + "tools/net461-x86/System.Text.RegularExpressions.dll",
  479 + "tools/net461-x86/System.Threading.Overlapped.dll",
  480 + "tools/net461-x86/System.Threading.Tasks.Parallel.dll",
  481 + "tools/net461-x86/System.Threading.Tasks.dll",
  482 + "tools/net461-x86/System.Threading.Thread.dll",
  483 + "tools/net461-x86/System.Threading.ThreadPool.dll",
  484 + "tools/net461-x86/System.Threading.Timer.dll",
  485 + "tools/net461-x86/System.Threading.dll",
  486 + "tools/net461-x86/System.ValueTuple.dll",
  487 + "tools/net461-x86/System.Xml.ReaderWriter.dll",
  488 + "tools/net461-x86/System.Xml.XDocument.dll",
  489 + "tools/net461-x86/System.Xml.XPath.XDocument.dll",
  490 + "tools/net461-x86/System.Xml.XPath.dll",
  491 + "tools/net461-x86/System.Xml.XmlDocument.dll",
  492 + "tools/net461-x86/System.Xml.XmlSerializer.dll",
  493 + "tools/net461-x86/netstandard.dll",
  494 + "tools/net461/GetDocument.Insider.exe",
  495 + "tools/net461/GetDocument.Insider.exe.config",
  496 + "tools/net461/Microsoft.Win32.Primitives.dll",
  497 + "tools/net461/System.AppContext.dll",
  498 + "tools/net461/System.Buffers.dll",
  499 + "tools/net461/System.Collections.Concurrent.dll",
  500 + "tools/net461/System.Collections.NonGeneric.dll",
  501 + "tools/net461/System.Collections.Specialized.dll",
  502 + "tools/net461/System.Collections.dll",
  503 + "tools/net461/System.ComponentModel.EventBasedAsync.dll",
  504 + "tools/net461/System.ComponentModel.Primitives.dll",
  505 + "tools/net461/System.ComponentModel.TypeConverter.dll",
  506 + "tools/net461/System.ComponentModel.dll",
  507 + "tools/net461/System.Console.dll",
  508 + "tools/net461/System.Data.Common.dll",
  509 + "tools/net461/System.Diagnostics.Contracts.dll",
  510 + "tools/net461/System.Diagnostics.Debug.dll",
  511 + "tools/net461/System.Diagnostics.DiagnosticSource.dll",
  512 + "tools/net461/System.Diagnostics.FileVersionInfo.dll",
  513 + "tools/net461/System.Diagnostics.Process.dll",
  514 + "tools/net461/System.Diagnostics.StackTrace.dll",
  515 + "tools/net461/System.Diagnostics.TextWriterTraceListener.dll",
  516 + "tools/net461/System.Diagnostics.Tools.dll",
  517 + "tools/net461/System.Diagnostics.TraceSource.dll",
  518 + "tools/net461/System.Diagnostics.Tracing.dll",
  519 + "tools/net461/System.Drawing.Primitives.dll",
  520 + "tools/net461/System.Dynamic.Runtime.dll",
  521 + "tools/net461/System.Globalization.Calendars.dll",
  522 + "tools/net461/System.Globalization.Extensions.dll",
  523 + "tools/net461/System.Globalization.dll",
  524 + "tools/net461/System.IO.Compression.ZipFile.dll",
  525 + "tools/net461/System.IO.Compression.dll",
  526 + "tools/net461/System.IO.FileSystem.DriveInfo.dll",
  527 + "tools/net461/System.IO.FileSystem.Primitives.dll",
  528 + "tools/net461/System.IO.FileSystem.Watcher.dll",
  529 + "tools/net461/System.IO.FileSystem.dll",
  530 + "tools/net461/System.IO.IsolatedStorage.dll",
  531 + "tools/net461/System.IO.MemoryMappedFiles.dll",
  532 + "tools/net461/System.IO.Pipes.dll",
  533 + "tools/net461/System.IO.UnmanagedMemoryStream.dll",
  534 + "tools/net461/System.IO.dll",
  535 + "tools/net461/System.Linq.Expressions.dll",
  536 + "tools/net461/System.Linq.Parallel.dll",
  537 + "tools/net461/System.Linq.Queryable.dll",
  538 + "tools/net461/System.Linq.dll",
  539 + "tools/net461/System.Memory.dll",
  540 + "tools/net461/System.Net.Http.dll",
  541 + "tools/net461/System.Net.NameResolution.dll",
  542 + "tools/net461/System.Net.NetworkInformation.dll",
  543 + "tools/net461/System.Net.Ping.dll",
  544 + "tools/net461/System.Net.Primitives.dll",
  545 + "tools/net461/System.Net.Requests.dll",
  546 + "tools/net461/System.Net.Security.dll",
  547 + "tools/net461/System.Net.Sockets.dll",
  548 + "tools/net461/System.Net.WebHeaderCollection.dll",
  549 + "tools/net461/System.Net.WebSockets.Client.dll",
  550 + "tools/net461/System.Net.WebSockets.dll",
  551 + "tools/net461/System.Numerics.Vectors.dll",
  552 + "tools/net461/System.ObjectModel.dll",
  553 + "tools/net461/System.Reflection.Extensions.dll",
  554 + "tools/net461/System.Reflection.Primitives.dll",
  555 + "tools/net461/System.Reflection.dll",
  556 + "tools/net461/System.Resources.Reader.dll",
  557 + "tools/net461/System.Resources.ResourceManager.dll",
  558 + "tools/net461/System.Resources.Writer.dll",
  559 + "tools/net461/System.Runtime.CompilerServices.Unsafe.dll",
  560 + "tools/net461/System.Runtime.CompilerServices.VisualC.dll",
  561 + "tools/net461/System.Runtime.Extensions.dll",
  562 + "tools/net461/System.Runtime.Handles.dll",
  563 + "tools/net461/System.Runtime.InteropServices.RuntimeInformation.dll",
  564 + "tools/net461/System.Runtime.InteropServices.dll",
  565 + "tools/net461/System.Runtime.Numerics.dll",
  566 + "tools/net461/System.Runtime.Serialization.Formatters.dll",
  567 + "tools/net461/System.Runtime.Serialization.Json.dll",
  568 + "tools/net461/System.Runtime.Serialization.Primitives.dll",
  569 + "tools/net461/System.Runtime.Serialization.Xml.dll",
  570 + "tools/net461/System.Runtime.dll",
  571 + "tools/net461/System.Security.Claims.dll",
  572 + "tools/net461/System.Security.Cryptography.Algorithms.dll",
  573 + "tools/net461/System.Security.Cryptography.Csp.dll",
  574 + "tools/net461/System.Security.Cryptography.Encoding.dll",
  575 + "tools/net461/System.Security.Cryptography.Primitives.dll",
  576 + "tools/net461/System.Security.Cryptography.X509Certificates.dll",
  577 + "tools/net461/System.Security.Principal.dll",
  578 + "tools/net461/System.Security.SecureString.dll",
  579 + "tools/net461/System.Text.Encoding.Extensions.dll",
  580 + "tools/net461/System.Text.Encoding.dll",
  581 + "tools/net461/System.Text.RegularExpressions.dll",
  582 + "tools/net461/System.Threading.Overlapped.dll",
  583 + "tools/net461/System.Threading.Tasks.Parallel.dll",
  584 + "tools/net461/System.Threading.Tasks.dll",
  585 + "tools/net461/System.Threading.Thread.dll",
  586 + "tools/net461/System.Threading.ThreadPool.dll",
  587 + "tools/net461/System.Threading.Timer.dll",
  588 + "tools/net461/System.Threading.dll",
  589 + "tools/net461/System.ValueTuple.dll",
  590 + "tools/net461/System.Xml.ReaderWriter.dll",
  591 + "tools/net461/System.Xml.XDocument.dll",
  592 + "tools/net461/System.Xml.XPath.XDocument.dll",
  593 + "tools/net461/System.Xml.XPath.dll",
  594 + "tools/net461/System.Xml.XmlDocument.dll",
  595 + "tools/net461/System.Xml.XmlSerializer.dll",
  596 + "tools/net461/netstandard.dll",
  597 + "tools/netcoreapp2.1/GetDocument.Insider.deps.json",
  598 + "tools/netcoreapp2.1/GetDocument.Insider.dll",
  599 + "tools/netcoreapp2.1/GetDocument.Insider.runtimeconfig.json",
  600 + "tools/netcoreapp2.1/System.Diagnostics.DiagnosticSource.dll"
  601 + ]
  602 + },
  603 + "Microsoft.Extensions.DependencyInjection/8.0.0": {
  604 + "sha512": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
  605 + "type": "package",
  606 + "path": "microsoft.extensions.dependencyinjection/8.0.0",
  607 + "files": [
  608 + ".nupkg.metadata",
  609 + ".signature.p7s",
  610 + "Icon.png",
  611 + "LICENSE.TXT",
  612 + "PACKAGE.md",
  613 + "THIRD-PARTY-NOTICES.TXT",
  614 + "buildTransitive/net461/Microsoft.Extensions.DependencyInjection.targets",
  615 + "buildTransitive/net462/_._",
  616 + "buildTransitive/net6.0/_._",
  617 + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.targets",
  618 + "lib/net462/Microsoft.Extensions.DependencyInjection.dll",
  619 + "lib/net462/Microsoft.Extensions.DependencyInjection.xml",
  620 + "lib/net6.0/Microsoft.Extensions.DependencyInjection.dll",
  621 + "lib/net6.0/Microsoft.Extensions.DependencyInjection.xml",
  622 + "lib/net7.0/Microsoft.Extensions.DependencyInjection.dll",
  623 + "lib/net7.0/Microsoft.Extensions.DependencyInjection.xml",
  624 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.dll",
  625 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.xml",
  626 + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll",
  627 + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.xml",
  628 + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.dll",
  629 + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.xml",
  630 + "microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512",
  631 + "microsoft.extensions.dependencyinjection.nuspec",
  632 + "useSharedDesignerContext.txt"
  633 + ]
  634 + },
  635 + "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
  636 + "sha512": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==",
  637 + "type": "package",
  638 + "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0",
  639 + "files": [
  640 + ".nupkg.metadata",
  641 + ".signature.p7s",
  642 + "Icon.png",
  643 + "LICENSE.TXT",
  644 + "PACKAGE.md",
  645 + "THIRD-PARTY-NOTICES.TXT",
  646 + "buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets",
  647 + "buildTransitive/net462/_._",
  648 + "buildTransitive/net6.0/_._",
  649 + "buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets",
  650 + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
  651 + "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
  652 + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
  653 + "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
  654 + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
  655 + "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
  656 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
  657 + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
  658 + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
  659 + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
  660 + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
  661 + "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
  662 + "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
  663 + "microsoft.extensions.dependencyinjection.abstractions.nuspec",
  664 + "useSharedDesignerContext.txt"
  665 + ]
  666 + },
  667 + "Microsoft.OpenApi/1.2.3": {
  668 + "sha512": "Nug3rO+7Kl5/SBAadzSMAVgqDlfGjJZ0GenQrLywJ84XGKO0uRqkunz5Wyl0SDwcR71bAATXvSdbdzPrYRYKGw==",
  669 + "type": "package",
  670 + "path": "microsoft.openapi/1.2.3",
  671 + "files": [
  672 + ".nupkg.metadata",
  673 + ".signature.p7s",
  674 + "lib/net46/Microsoft.OpenApi.dll",
  675 + "lib/net46/Microsoft.OpenApi.pdb",
  676 + "lib/net46/Microsoft.OpenApi.xml",
  677 + "lib/netstandard2.0/Microsoft.OpenApi.dll",
  678 + "lib/netstandard2.0/Microsoft.OpenApi.pdb",
  679 + "lib/netstandard2.0/Microsoft.OpenApi.xml",
  680 + "microsoft.openapi.1.2.3.nupkg.sha512",
  681 + "microsoft.openapi.nuspec"
  682 + ]
  683 + },
  684 + "Stub.System.Data.SQLite.Core.NetStandard/1.0.115.5": {
  685 + "sha512": "WfrqQg6WL+r4H1sVKTenNj6ERLXUukUxqcjH1rqPqXadeIWccTVpydESieD7cZ/NWQVSKLYIHuoBX5du+BFhIQ==",
  686 + "type": "package",
  687 + "path": "stub.system.data.sqlite.core.netstandard/1.0.115.5",
  688 + "files": [
  689 + ".nupkg.metadata",
  690 + ".signature.p7s",
  691 + "lib/netstandard2.0/System.Data.SQLite.dll",
  692 + "lib/netstandard2.0/System.Data.SQLite.dll.altconfig",
  693 + "lib/netstandard2.0/System.Data.SQLite.xml",
  694 + "lib/netstandard2.1/System.Data.SQLite.dll",
  695 + "lib/netstandard2.1/System.Data.SQLite.dll.altconfig",
  696 + "lib/netstandard2.1/System.Data.SQLite.xml",
  697 + "runtimes/linux-x64/native/SQLite.Interop.dll",
  698 + "runtimes/osx-x64/native/SQLite.Interop.dll",
  699 + "runtimes/win-x64/native/SQLite.Interop.dll",
  700 + "runtimes/win-x86/native/SQLite.Interop.dll",
  701 + "stub.system.data.sqlite.core.netstandard.1.0.115.5.nupkg.sha512",
  702 + "stub.system.data.sqlite.core.netstandard.nuspec"
  703 + ]
  704 + },
  705 + "Swashbuckle.AspNetCore/6.4.0": {
  706 + "sha512": "eUBr4TW0up6oKDA5Xwkul289uqSMgY0xGN4pnbOIBqCcN9VKGGaPvHX3vWaG/hvocfGDP+MGzMA0bBBKz2fkmQ==",
  707 + "type": "package",
  708 + "path": "swashbuckle.aspnetcore/6.4.0",
  709 + "files": [
  710 + ".nupkg.metadata",
  711 + ".signature.p7s",
  712 + "build/Swashbuckle.AspNetCore.props",
  713 + "swashbuckle.aspnetcore.6.4.0.nupkg.sha512",
  714 + "swashbuckle.aspnetcore.nuspec"
  715 + ]
  716 + },
  717 + "Swashbuckle.AspNetCore.Swagger/6.4.0": {
  718 + "sha512": "nl4SBgGM+cmthUcpwO/w1lUjevdDHAqRvfUoe4Xp/Uvuzt9mzGUwyFCqa3ODBAcZYBiFoKvrYwz0rabslJvSmQ==",
  719 + "type": "package",
  720 + "path": "swashbuckle.aspnetcore.swagger/6.4.0",
  721 + "files": [
  722 + ".nupkg.metadata",
  723 + ".signature.p7s",
  724 + "lib/net5.0/Swashbuckle.AspNetCore.Swagger.dll",
  725 + "lib/net5.0/Swashbuckle.AspNetCore.Swagger.pdb",
  726 + "lib/net5.0/Swashbuckle.AspNetCore.Swagger.xml",
  727 + "lib/net6.0/Swashbuckle.AspNetCore.Swagger.dll",
  728 + "lib/net6.0/Swashbuckle.AspNetCore.Swagger.pdb",
  729 + "lib/net6.0/Swashbuckle.AspNetCore.Swagger.xml",
  730 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.Swagger.dll",
  731 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.Swagger.pdb",
  732 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.Swagger.xml",
  733 + "lib/netstandard2.0/Swashbuckle.AspNetCore.Swagger.dll",
  734 + "lib/netstandard2.0/Swashbuckle.AspNetCore.Swagger.pdb",
  735 + "lib/netstandard2.0/Swashbuckle.AspNetCore.Swagger.xml",
  736 + "swashbuckle.aspnetcore.swagger.6.4.0.nupkg.sha512",
  737 + "swashbuckle.aspnetcore.swagger.nuspec"
  738 + ]
  739 + },
  740 + "Swashbuckle.AspNetCore.SwaggerGen/6.4.0": {
  741 + "sha512": "lXhcUBVqKrPFAQF7e/ZeDfb5PMgE8n5t6L5B6/BQSpiwxgHzmBcx8Msu42zLYFTvR5PIqE9Q9lZvSQAcwCxJjw==",
  742 + "type": "package",
  743 + "path": "swashbuckle.aspnetcore.swaggergen/6.4.0",
  744 + "files": [
  745 + ".nupkg.metadata",
  746 + ".signature.p7s",
  747 + "lib/net5.0/Swashbuckle.AspNetCore.SwaggerGen.dll",
  748 + "lib/net5.0/Swashbuckle.AspNetCore.SwaggerGen.pdb",
  749 + "lib/net5.0/Swashbuckle.AspNetCore.SwaggerGen.xml",
  750 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerGen.dll",
  751 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerGen.pdb",
  752 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerGen.xml",
  753 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.SwaggerGen.dll",
  754 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.SwaggerGen.pdb",
  755 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.SwaggerGen.xml",
  756 + "lib/netstandard2.0/Swashbuckle.AspNetCore.SwaggerGen.dll",
  757 + "lib/netstandard2.0/Swashbuckle.AspNetCore.SwaggerGen.pdb",
  758 + "lib/netstandard2.0/Swashbuckle.AspNetCore.SwaggerGen.xml",
  759 + "swashbuckle.aspnetcore.swaggergen.6.4.0.nupkg.sha512",
  760 + "swashbuckle.aspnetcore.swaggergen.nuspec"
  761 + ]
  762 + },
  763 + "Swashbuckle.AspNetCore.SwaggerUI/6.4.0": {
  764 + "sha512": "1Hh3atb3pi8c+v7n4/3N80Jj8RvLOXgWxzix6w3OZhB7zBGRwsy7FWr4e3hwgPweSBpwfElqj4V4nkjYabH9nQ==",
  765 + "type": "package",
  766 + "path": "swashbuckle.aspnetcore.swaggerui/6.4.0",
  767 + "files": [
  768 + ".nupkg.metadata",
  769 + ".signature.p7s",
  770 + "lib/net5.0/Swashbuckle.AspNetCore.SwaggerUI.dll",
  771 + "lib/net5.0/Swashbuckle.AspNetCore.SwaggerUI.pdb",
  772 + "lib/net5.0/Swashbuckle.AspNetCore.SwaggerUI.xml",
  773 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerUI.dll",
  774 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerUI.pdb",
  775 + "lib/net6.0/Swashbuckle.AspNetCore.SwaggerUI.xml",
  776 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.SwaggerUI.dll",
  777 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.SwaggerUI.pdb",
  778 + "lib/netcoreapp3.0/Swashbuckle.AspNetCore.SwaggerUI.xml",
  779 + "lib/netstandard2.0/Swashbuckle.AspNetCore.SwaggerUI.dll",
  780 + "lib/netstandard2.0/Swashbuckle.AspNetCore.SwaggerUI.pdb",
  781 + "lib/netstandard2.0/Swashbuckle.AspNetCore.SwaggerUI.xml",
  782 + "swashbuckle.aspnetcore.swaggerui.6.4.0.nupkg.sha512",
  783 + "swashbuckle.aspnetcore.swaggerui.nuspec"
  784 + ]
  785 + },
  786 + "System.Data.SQLite.Core/1.0.115.5": {
  787 + "sha512": "vADIqqgpxaC5xR6qOV8/KMZkQeSDCfmmWpVOtQx0oEr3Yjq2XdTxX7+jfE4+oO2xPovAbYiz6Q5cLRbSsDkq6Q==",
  788 + "type": "package",
  789 + "path": "system.data.sqlite.core/1.0.115.5",
  790 + "files": [
  791 + ".nupkg.metadata",
  792 + ".signature.p7s",
  793 + "system.data.sqlite.core.1.0.115.5.nupkg.sha512",
  794 + "system.data.sqlite.core.nuspec"
  795 + ]
  796 + }
  797 + },
  798 + "projectFileDependencyGroups": {
  799 + "net8.0": [
  800 + "FreeSql >= 3.2.821",
  801 + "FreeSql.Provider.Sqlite >= 3.2.821",
  802 + "FreeSql.Repository >= 3.2.821",
  803 + "Swashbuckle.AspNetCore >= 6.4.0"
  804 + ]
  805 + },
  806 + "packageFolders": {
  807 + "C:\\Users\\anan\\.nuget\\packages\\": {},
  808 + "C:\\Users\\anan\\AppData\\Roaming\\Godot\\mono\\GodotNuGetFallbackFolder": {},
  809 + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {}
  810 + },
  811 + "project": {
  812 + "version": "1.0.0",
  813 + "restore": {
  814 + "projectUniqueName": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\Blueprint.Net.Server.csproj",
  815 + "projectName": "Blueprint.Net.Server",
  816 + "projectPath": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\Blueprint.Net.Server.csproj",
  817 + "packagesPath": "C:\\Users\\anan\\.nuget\\packages\\",
  818 + "outputPath": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\obj\\",
  819 + "projectStyle": "PackageReference",
  820 + "fallbackFolders": [
  821 + "C:\\Users\\anan\\AppData\\Roaming\\Godot\\mono\\GodotNuGetFallbackFolder",
  822 + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
  823 + ],
  824 + "configFilePaths": [
  825 + "C:\\Users\\anan\\AppData\\Roaming\\NuGet\\NuGet.Config",
  826 + "C:\\Users\\anan\\AppData\\Roaming\\NuGet\\config\\Godot.Offline.Config",
  827 + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
  828 + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
  829 + ],
  830 + "originalTargetFrameworks": [
  831 + "net8.0"
  832 + ],
  833 + "sources": {
  834 + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
  835 + "C:\\Program Files\\dotnet\\library-packs": {},
  836 + "https://api.nuget.org/v3/index.json": {}
  837 + },
  838 + "frameworks": {
  839 + "net8.0": {
  840 + "targetAlias": "net8.0",
  841 + "projectReferences": {}
  842 + }
  843 + },
  844 + "warningProperties": {
  845 + "warnAsError": [
  846 + "NU1605"
  847 + ]
  848 + },
  849 + "restoreAuditProperties": {
  850 + "enableAudit": "true",
  851 + "auditLevel": "low",
  852 + "auditMode": "direct"
  853 + }
  854 + },
  855 + "frameworks": {
  856 + "net8.0": {
  857 + "targetAlias": "net8.0",
  858 + "dependencies": {
  859 + "FreeSql": {
  860 + "target": "Package",
  861 + "version": "[3.2.821, )"
  862 + },
  863 + "FreeSql.Provider.Sqlite": {
  864 + "target": "Package",
  865 + "version": "[3.2.821, )"
  866 + },
  867 + "FreeSql.Repository": {
  868 + "target": "Package",
  869 + "version": "[3.2.821, )"
  870 + },
  871 + "Swashbuckle.AspNetCore": {
  872 + "target": "Package",
  873 + "version": "[6.4.0, )"
  874 + }
  875 + },
  876 + "imports": [
  877 + "net461",
  878 + "net462",
  879 + "net47",
  880 + "net471",
  881 + "net472",
  882 + "net48",
  883 + "net481"
  884 + ],
  885 + "assetTargetFallback": true,
  886 + "warn": true,
  887 + "frameworkReferences": {
  888 + "Microsoft.AspNetCore.App": {
  889 + "privateAssets": "none"
  890 + },
  891 + "Microsoft.NETCore.App": {
  892 + "privateAssets": "all"
  893 + }
  894 + },
  895 + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.201/PortableRuntimeIdentifierGraph.json"
  896 + }
  897 + }
  898 + }
  899 +}
0 900 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/obj/project.nuget.cache 0 → 100644
  1 +{
  2 + "version": 2,
  3 + "dgSpecHash": "DA7OQW1R/bNe9e6/SrjHTvIq5zA0jn0hwqi81cixrmZ4iGKP5aTwTMcL2WpK4pbrz1wFsABnWSUlUdTKp7LCLw==",
  4 + "success": true,
  5 + "projectFilePath": "E:\\Code\\Blueprint\\Blueprint.Net.Server\\Blueprint.Net.Server.csproj",
  6 + "expectedPackageFiles": [
  7 + "C:\\Users\\anan\\.nuget\\packages\\freesql\\3.2.821\\freesql.3.2.821.nupkg.sha512",
  8 + "C:\\Users\\anan\\.nuget\\packages\\freesql.dbcontext\\3.2.821\\freesql.dbcontext.3.2.821.nupkg.sha512",
  9 + "C:\\Users\\anan\\.nuget\\packages\\freesql.provider.sqlite\\3.2.821\\freesql.provider.sqlite.3.2.821.nupkg.sha512",
  10 + "C:\\Users\\anan\\.nuget\\packages\\freesql.repository\\3.2.821\\freesql.repository.3.2.821.nupkg.sha512",
  11 + "C:\\Users\\anan\\.nuget\\packages\\microsoft.extensions.apidescription.server\\6.0.5\\microsoft.extensions.apidescription.server.6.0.5.nupkg.sha512",
  12 + "C:\\Users\\anan\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\8.0.0\\microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512",
  13 + "C:\\Users\\anan\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
  14 + "C:\\Users\\anan\\.nuget\\packages\\microsoft.openapi\\1.2.3\\microsoft.openapi.1.2.3.nupkg.sha512",
  15 + "C:\\Users\\anan\\.nuget\\packages\\stub.system.data.sqlite.core.netstandard\\1.0.115.5\\stub.system.data.sqlite.core.netstandard.1.0.115.5.nupkg.sha512",
  16 + "C:\\Users\\anan\\.nuget\\packages\\swashbuckle.aspnetcore\\6.4.0\\swashbuckle.aspnetcore.6.4.0.nupkg.sha512",
  17 + "C:\\Users\\anan\\.nuget\\packages\\swashbuckle.aspnetcore.swagger\\6.4.0\\swashbuckle.aspnetcore.swagger.6.4.0.nupkg.sha512",
  18 + "C:\\Users\\anan\\.nuget\\packages\\swashbuckle.aspnetcore.swaggergen\\6.4.0\\swashbuckle.aspnetcore.swaggergen.6.4.0.nupkg.sha512",
  19 + "C:\\Users\\anan\\.nuget\\packages\\swashbuckle.aspnetcore.swaggerui\\6.4.0\\swashbuckle.aspnetcore.swaggerui.6.4.0.nupkg.sha512",
  20 + "C:\\Users\\anan\\.nuget\\packages\\system.data.sqlite.core\\1.0.115.5\\system.data.sqlite.core.1.0.115.5.nupkg.sha512"
  21 + ],
  22 + "logs": []
  23 +}
0 24 \ No newline at end of file
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/wwwroot/carddesign.html 0 → 100644
  1 +<!DOCTYPE html>
  2 +<html lang="en">
  3 +<head>
  4 + <meta charset="UTF-8">
  5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6 + <title>Card Editor</title>
  7 +
  8 +
  9 +
  10 + <style>
  11 + body {
  12 + font-family: Arial, sans-serif;
  13 + }
  14 +
  15 + .container {
  16 + max-width: 800px;
  17 + margin: auto;
  18 + padding: 20px;
  19 + }
  20 +
  21 + .json-output {
  22 + background-color: #f4f4f4;
  23 + border: 1px solid #ddd;
  24 + padding: 10px;
  25 + margin-top: 20px;
  26 + }
  27 +
  28 + input, select, button {
  29 + padding: 8px;
  30 + margin-top: 5px;
  31 + width: 100%;
  32 + }
  33 +
  34 + button {
  35 + cursor: pointer;
  36 + }
  37 +
  38 + svg {
  39 + background-color: #333;
  40 + border: 1px solid #ccc;
  41 + padding: 30px;
  42 + }
  43 + </style>
  44 +</head>
  45 +<body>
  46 + <div class="container">
  47 + <h1>Card Editor</h1>
  48 + <form id="cardForm">
  49 + <label for="id">Card ID:</label>
  50 + <input type="text" id="id" name="id" required>
  51 +
  52 + <label for="label">Label:</label>
  53 + <input type="text" id="label" name="label" required>
  54 +
  55 + <label for="type">Type:</label>
  56 + <input type="text" id="type" name="type" required>
  57 +
  58 + <label for="titleBarColor">Title Bar Color (comma-separated):</label>
  59 + <input type="text" id="titleBarColor" name="titleBarColor" required>
  60 +
  61 + <h3>Nodes</h3>
  62 + <div id="nodesContainer">
  63 + <!-- Node inputs will be added here -->
  64 + </div>
  65 + <button type="button" onclick="addNode()">Add Node</button>
  66 + <button type="submit">Update Card JSON</button>
  67 + </form>
  68 +
  69 + <div class="json-output" id="jsonOutput"></div>
  70 +
  71 + <!-- SVG container for drawing the card -->
  72 + <svg id="svgContainer" width="200" height="300"></svg>
  73 + </div>
  74 +
  75 + <script type="text/javascript">
  76 + var card = {
  77 + id: 'card0',
  78 + x: 0,
  79 + y: 0,
  80 + label: 'Start',
  81 + type: "start",
  82 + nodes: [{
  83 + type: "out",
  84 + level: 0,
  85 + label: 'call',
  86 + enumType: 'call',
  87 + color: '#fff',
  88 + multiConnected: 1
  89 + }],
  90 + titleBarColor: ['#84fab0', '#8fd3f4']
  91 + };
  92 +
  93 + function updateForm() {
  94 + document.getElementById('id').value = card.id;
  95 + document.getElementById('label').value = card.label;
  96 + document.getElementById('type').value = card.type;
  97 + document.getElementById('titleBarColor').value = card.titleBarColor.join(', ');
  98 +
  99 + const nodesContainer = document.getElementById('nodesContainer');
  100 + nodesContainer.innerHTML = '';
  101 + card.nodes.forEach((node, index) => {
  102 + addNode(node, index);
  103 + });
  104 + }
  105 +
  106 + function addNode(node = {}, index = card.nodes.length) {
  107 + const container = document.createElement('div');
  108 + container.innerHTML = `
  109 + <label>Node ${index + 1}</label>
  110 + <select name="nodeType-${index}">
  111 + <option value="in" ${node.type === 'in' ? 'selected' : ''}>In</option>
  112 + <option value="out" ${node.type === 'out' ? 'selected' : ''}>Out</option>
  113 + </select>
  114 + <input type="number" placeholder="Level" value="${node.level || 0}" name="nodeLevel-${index}">
  115 + <input type="text" placeholder="Enum Type" value="${node.enumType || ''}" name="nodeEnumType-${index}">
  116 + <input type="text" placeholder="Label" value="${node.label || ''}" name="nodeLabel-${index}">
  117 + <input type="text" placeholder="Color" value="${node.color || ''}" name="nodeColor-${index}">
  118 + <input type="number" placeholder="Multi Connected" value="${node.multiConnected || 0}" name="nodeMultiConnected-${index}">
  119 + <button type="button" onclick="removeNode(${index})">Remove Node</button>
  120 + `;
  121 + document.getElementById('nodesContainer').appendChild(container);
  122 + }
  123 +
  124 + function removeNode(index) {
  125 + card.nodes.splice(index, 1);
  126 + updateForm(); // Refresh the form and JSON output
  127 + drawCard();
  128 + }
  129 +
  130 + document.getElementById('cardForm').onsubmit = function (event) {
  131 + event.preventDefault();
  132 + card.id = document.getElementById('id').value;
  133 + card.label = document.getElementById('label').value;
  134 + card.type = document.getElementById('type').value;
  135 + card.titleBarColor = document.getElementById('titleBarColor').value.split(',').map(color => color.trim());
  136 +
  137 + card.nodes = [];
  138 + const nodes = document.querySelectorAll('#nodesContainer > div');
  139 + nodes.forEach((node, index) => {
  140 + card.nodes.push({
  141 + type: document.querySelector(`[name="nodeType-${index}"]`).value,
  142 + level: parseInt(document.querySelector(`[name="nodeLevel-${index}"]`).value),
  143 + enumType: document.querySelector(`[name="nodeEnumType-${index}"]`).value,
  144 + label: document.querySelector(`[name="nodeLabel-${index}"]`).value,
  145 + color: document.querySelector(`[name="nodeColor-${index}"]`).value,
  146 + multiConnected: parseInt(document.querySelector(`[name="nodeMultiConnected-${index}"]`).value)
  147 + });
  148 + });
  149 +
  150 + updateJSONOutput();
  151 + drawCard();
  152 + };
  153 +
  154 + function updateJSONOutput() {
  155 + document.getElementById('jsonOutput').textContent = JSON.stringify(card, null, 2);
  156 + }
  157 +
  158 + function drawCard() {
  159 + const cardsContainer = document.getElementById('svgContainer');
  160 + cardsContainer.innerHTML = ''; // 清除现有的卡片
  161 +
  162 + //创建标题栏渐变色
  163 + const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
  164 + const linearGradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
  165 + linearGradient.setAttribute('id', `titleGradient-${card.id}`);
  166 + linearGradient.setAttribute('x1', '0%'); // 渐变起点的x坐标
  167 + linearGradient.setAttribute('y1', '100%'); // 渐变起点的y坐标
  168 + linearGradient.setAttribute('x2', '100%'); // 渐变终点的x坐标
  169 + linearGradient.setAttribute('y2', '0%'); // 渐变终点的y坐标
  170 +
  171 + const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  172 + stop1.setAttribute('offset', '10%');
  173 + stop1.setAttribute('style', `stop-color: ${card.titleBarColor[0]}; stop-opacity: 1`);
  174 + linearGradient.appendChild(stop1);
  175 +
  176 + const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  177 + stop2.setAttribute('offset', '100%');
  178 + stop2.setAttribute('style', `stop-color: ${card.titleBarColor[1]}; stop-opacity: 1`);
  179 + linearGradient.appendChild(stop2);
  180 +
  181 + defs.appendChild(linearGradient);
  182 + cardsContainer.appendChild(defs);
  183 +
  184 +
  185 +
  186 + const nodeSpacing = 50;
  187 + const topBottomPadding = 20;
  188 + const titleBarHeight = 30; // 标题栏高度
  189 + const maxLevel = Math.max(...card.nodes.map(node => node.level)) + 1;
  190 + const cardHeight = maxLevel * nodeSpacing + topBottomPadding * 2 + titleBarHeight;
  191 +
  192 + const group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
  193 + group.setAttribute('class', 'draggable card-container');
  194 + group.setAttribute('data-id', card.id);
  195 + group.setAttribute('user-select', 'none');
  196 + group.setAttribute('transform', `translate(${card.x},${card.y})`);
  197 +
  198 + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  199 + rect.setAttribute('fill', '#222');
  200 + rect.setAttribute('width', 150);
  201 + rect.setAttribute('style', 'cursor: auto;');
  202 + rect.setAttribute('height', cardHeight);
  203 + rect.setAttribute('rx', 10); // 圆角
  204 + rect.setAttribute('ry', 10);
  205 + group.appendChild(rect);
  206 +
  207 + // 使用path绘制带有指定圆角的矩形
  208 + // 创建标题栏
  209 + const titleBarWidth = 150;
  210 + const borderRadius = 10; // 圆角大小
  211 + const titleBar = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  212 + const dValue = `M 0,${borderRadius}
  213 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},-${borderRadius}
  214 + h ${titleBarWidth - borderRadius * 2}
  215 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},${borderRadius}
  216 + v ${titleBarHeight - borderRadius}
  217 + h -${titleBarWidth}
  218 + z`;
  219 + titleBar.setAttribute('class', 'card');
  220 + titleBar.setAttribute('d', dValue);
  221 + titleBar.setAttribute('fill', `url(#titleGradient-${card.id})`);
  222 + group.appendChild(titleBar);
  223 +
  224 + const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  225 + text.setAttribute('x', titleBarWidth / 2);
  226 + text.setAttribute('y', titleBarHeight / 2);
  227 + text.setAttribute('text-anchor', 'middle');
  228 + text.setAttribute('alignment-baseline', 'middle');
  229 + text.textContent = card.label;
  230 + group.appendChild(text);
  231 +
  232 + card.nodes.forEach((node, index) => {
  233 +
  234 +
  235 + const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  236 + circle.setAttribute('class', 'node');
  237 + circle.setAttribute('cx', node.type === 'in' ? 0 : 150);
  238 + circle.setAttribute('cy', topBottomPadding + titleBarHeight + (node.level + 1) *
  239 + nodeSpacing - (nodeSpacing / 2));
  240 + circle.setAttribute('r', 7);
  241 + circle.setAttribute('fill', node.color);
  242 + circle.setAttribute('data-card-id', card.id);
  243 + circle.setAttribute('data-node-id', `${card.id}-node${index + 1}`);
  244 + group.appendChild(circle);
  245 +
  246 + let labelX = node.type === 'in' ? 12 : 138; // 基本的X坐标
  247 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 21;
  248 +
  249 + // 创建SVG文本元素
  250 + const multiConnectedLabel = document.createElementNS('http://www.w3.org/2000/svg',
  251 + 'text');
  252 + multiConnectedLabel.setAttribute('x', labelX);
  253 + multiConnectedLabel.setAttribute('y', labelY);
  254 + multiConnectedLabel.setAttribute('text-anchor', 'middle');
  255 + multiConnectedLabel.setAttribute('fill', '#aaa');
  256 + multiConnectedLabel.setAttribute('style', 'font-size: 8px;');
  257 + multiConnectedLabel.setAttribute('alignment-baseline', 'hanging');
  258 +
  259 +
  260 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  261 + let estimatedTextLength;
  262 + if (node.multiConnected == undefined) {
  263 + estimatedTextLength = 20
  264 + multiConnectedLabel.textContent = 'N';
  265 + } else {
  266 + estimatedTextLength = node.multiConnected.length;
  267 + multiConnectedLabel.textContent = node.multiConnected;
  268 + }
  269 +
  270 + // 确保文本不会超出卡片右边界
  271 + if (labelX + estimatedTextLength / 2 > 150) {
  272 + labelX = 150 - estimatedTextLength / 2;
  273 + nodeLabel.setAttribute('x', labelX);
  274 + }
  275 +
  276 + // 确保文本不会超出卡片左边界
  277 + if (labelX - estimatedTextLength / 2 < 0) {
  278 + labelX = estimatedTextLength / 2;
  279 + nodeLabel.setAttribute('x', labelX);
  280 + }
  281 +
  282 + group.appendChild(multiConnectedLabel);
  283 +
  284 + if (node.label != undefined) {
  285 + // 计算文本标签的位置
  286 + let labelX = node.type === 'in' ? 15 : 135; // 基本的X坐标
  287 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 40;
  288 +
  289 + // 创建SVG文本元素
  290 + const nodeLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  291 + nodeLabel.setAttribute('x', labelX);
  292 + nodeLabel.setAttribute('y', labelY); // 在节点下方留出一定空间
  293 + nodeLabel.setAttribute('text-anchor', 'middle'); // 文本居中对齐
  294 + nodeLabel.setAttribute('fill', '#aaa'); // 文本居中对齐
  295 + nodeLabel.setAttribute('alignment-baseline', 'hanging');
  296 + nodeLabel.textContent = node.label;
  297 +
  298 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  299 + const estimatedTextLength = node.label.length * 10; // 估算每个字符6像素宽
  300 +
  301 + // 确保文本不会超出卡片右边界
  302 + if (labelX + estimatedTextLength / 2 > 150) {
  303 + labelX = 150 - estimatedTextLength / 2;
  304 + nodeLabel.setAttribute('x', labelX);
  305 + }
  306 +
  307 + // 确保文本不会超出卡片左边界
  308 + if (labelX - estimatedTextLength / 2 < 0) {
  309 + labelX = estimatedTextLength / 2;
  310 + nodeLabel.setAttribute('x', labelX);
  311 + }
  312 +
  313 + group.appendChild(nodeLabel);
  314 +
  315 + }
  316 +
  317 + switch (node.slot) {
  318 + case 'input':
  319 + const foreignObject = document.createElementNS('http://www.w3.org/2000/svg',
  320 + 'foreignObject');
  321 + foreignObject.setAttribute('x', 0);
  322 + foreignObject.setAttribute('y', topBottomPadding + titleBarHeight + node.level *
  323 + nodeSpacing + 12);
  324 + foreignObject.setAttribute('width', 130); // 保持原始宽度
  325 + foreignObject.setAttribute('height', nodeSpacing - 24); // 保持原始高度,减去的24像素为上下内边距之和
  326 + const input = document.createElement('input');
  327 + input.type = 'text';
  328 + if (node.value == undefined) {
  329 + node.value = '';
  330 + }
  331 + input.value = node.value;
  332 + input.addEventListener('input', function () {
  333 + node.value = input.value;
  334 + });
  335 + // Set adjusted input styles
  336 + input.style.width = '110px';
  337 + input.style.height = '100%';
  338 + input.style.marginLeft = '20px';
  339 + input.style.borderRadius = '5px';
  340 + input.style.border = '1px solid white';
  341 + input.style.backgroundColor = '#222';
  342 + input.style.color = 'white';
  343 + input.style.fontSize = '1em';
  344 + input.style.padding = '0px'; // 可能需要调整或去除内边距以适应固定尺寸
  345 + input.style.boxSizing = 'border-box'; // 确保宽高包含内容、内边距和边框
  346 +
  347 + // Change border color on focus and blur
  348 + input.addEventListener('focus', () => {
  349 + input.style.outline = 'none'; // Remove default focus outline
  350 + input.style.borderColor =
  351 + 'white'; // Keep border color white on focus
  352 + });
  353 +
  354 + input.addEventListener('blur', () => {
  355 + input.style.borderColor =
  356 + 'white'; // Revert to white when not focused
  357 + });
  358 +
  359 + // 阻止事件冒泡
  360 + input.addEventListener('click', function (event) {
  361 + event.stopPropagation();
  362 + });
  363 +
  364 + input.addEventListener('mousedown', function (event) {
  365 + event.stopPropagation();
  366 + });
  367 +
  368 + input.addEventListener('touchstart', function (event) {
  369 + event.stopPropagation();
  370 + });
  371 +
  372 + foreignObject.appendChild(input);
  373 + group.appendChild(foreignObject);
  374 + break;
  375 + }
  376 +
  377 +
  378 +
  379 + });
  380 +
  381 + const deleteIcon = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  382 + deleteIcon.setAttribute('class', 'card-delete-icon');
  383 + deleteIcon.setAttribute('x', 125);
  384 + deleteIcon.setAttribute('y', 5); // 使其贴近标题栏的右上角
  385 + deleteIcon.setAttribute('width', 20);
  386 + deleteIcon.setAttribute('height', 20);
  387 + deleteIcon.setAttribute('fill', 'transparent');
  388 + deleteIcon.setAttribute('data-card-id', card.id);
  389 + deleteIcon.setAttribute('style', 'cursor: pointer;');
  390 + group.appendChild(de,eIcon);
  391 +
  392 + const delText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  393 + delText.setAttribute('x', 135);
  394 + delText.setAttribute('y', 20); // 调整位置以垂直居中
  395 + delText.setAttribute('text-anchor', 'middle');
  396 + delText.setAttribute('fill', 'white');
  397 + delText.setAttribute('font-size', '16px'); // 适当调整字体大小以适应图标
  398 + delText.setAttribute('pointer-events', 'none'); // 确保点击事件只触发于删除图标上
  399 + delText.textContent = '×';
  400 + group.appendChild(delText);
  401 +
  402 + cardsContainer.appendChild(group);
  403 +
  404 + attachNodeEventListeners();
  405 + }
  406 +
  407 +
  408 +
  409 +
  410 +
  411 + updateForm();
  412 + updateJSONOutput();
  413 + drawCard();
  414 + </script>
  415 +</body>
  416 +</html>
... ...
src/main/resources/static/pages/zndd_yuan/Blueprint.Net.Server/wwwroot/index.html 0 → 100644
  1 +<!--
  2 +<!DOCTYPE html>
  3 +<html lang="zh-cn">
  4 +
  5 + <head>
  6 + <meta charset="UTF-8">
  7 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8 + <title>Blueprint</title>
  9 + <style>
  10 + body,
  11 + html {
  12 + margin: 0;
  13 + padding: 0;
  14 + width: 100%;
  15 + height: 100%;
  16 + overflow: hidden;
  17 + }
  18 +
  19 + /* 弹窗容器样式 */
  20 + #card-creation-modal {
  21 + border: 1px solid #444;
  22 + background: linear-gradient(145deg, #333, #555);
  23 + padding: 5px;
  24 + z-index: 100;
  25 + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  26 + border-radius: 5px;
  27 + overflow: hidden;
  28 + margin: 0;
  29 + user-select: none;
  30 + }
  31 +
  32 + #card-type-list {
  33 +
  34 + padding-left: 0px;
  35 + }
  36 +
  37 + /* 列表项基础样式 */
  38 + #card-type-list li {
  39 + list-style: none;
  40 + /* 去除列表项目符号 */
  41 + padding: 8px 15px;
  42 + /* 减少垂直内边距使其更紧凑 */
  43 + border-bottom: 1px solid #666;
  44 + /* 暗色底部边框线 */
  45 + color: #ddd;
  46 + /* 暗色系字体颜色 */
  47 + cursor: pointer;
  48 + /* 鼠标指针样式 */
  49 + margin-left: 0;
  50 + /* 消除左边间隙 */
  51 +
  52 + }
  53 +
  54 + /* 列表项高亮样式 */
  55 + #card-type-list li:hover,
  56 + #card-type-list li:focus {
  57 + background-color: #777;
  58 + /* 暗色背景颜色 */
  59 + color: #fff;
  60 + /* 高亮字体颜色 */
  61 + }
  62 +
  63 + /* 最后一个列表项的底部边框 */
  64 + #card-type-list li:last-child {
  65 + border-bottom: none;
  66 + }
  67 +
  68 + .grid-background {
  69 + background-color: #292929;
  70 + background-image:
  71 + linear-gradient(to right, black 1px, transparent 1px),
  72 + linear-gradient(to bottom, black 1px, transparent 1px),
  73 + linear-gradient(to right, #404040 1px, transparent 1px),
  74 + linear-gradient(to bottom, #404040 1px, transparent 1px);
  75 + background-size:
  76 + 100px 100px,
  77 + 100px 100px,
  78 + 10px 10px,
  79 + 10px 10px;
  80 + width: 100%;
  81 + height: 100%;
  82 + }
  83 +
  84 + .draggable {
  85 + cursor: grab;
  86 + }
  87 +
  88 + .node {
  89 +
  90 + cursor: pointer;
  91 + }
  92 +
  93 + .link {
  94 + stroke: black;
  95 + stroke-width: 2;
  96 + }
  97 +
  98 + .card {
  99 + /* fill: lightgrey;
  100 + stroke: black; */
  101 +
  102 + stroke-width: 1;
  103 + user-select: none;
  104 + }
  105 +
  106 + text {
  107 + pointer-events: none;
  108 + user-select: none;
  109 + }
  110 + </style>
  111 + </head>
  112 +
  113 + <body>
  114 + &lt;!&ndash; 弹窗容器 &ndash;&gt;
  115 + <div id="card-creation-modal"
  116 + style="display:none; position: absolute; border: 1px solid #ccc; background-color: #fff; padding: 10px; z-index: 100;">
  117 + &lt;!&ndash; 搜索结果列表 &ndash;&gt;
  118 + <ul id="card-type-list"></ul>
  119 + </div>
  120 +
  121 +
  122 +
  123 + <svg style="width: 100%;height: 100%;" id="svgContainer" class="grid-background">
  124 + <g id="linksContainer"></g> &lt;!&ndash; 用于存放线条 &ndash;&gt;
  125 + <g id="cardsContainer"></g> &lt;!&ndash; 用于存放卡片 &ndash;&gt;
  126 + </svg>
  127 +
  128 + <script>
  129 + let cards = [{
  130 + id: 'card0',
  131 + x: 0,
  132 + y: 0,
  133 + label: 'Start',
  134 + type: "start",
  135 + nodes: [{
  136 + type: "out",
  137 + level: 0,
  138 + enumType: 'call',
  139 + color: '#fff',
  140 + multiConnected: 1
  141 + }, ],
  142 + titleBarColor: ['#84fab0', '#8fd3f4']
  143 + },
  144 + {
  145 + id: 'card1',
  146 + x: 100,
  147 + y: 200,
  148 + label: 'Condition',
  149 + type: "condition",
  150 + nodes: [{
  151 + type: "in",
  152 + level: 0,
  153 + enumType: 'call',
  154 + color: '#fff'
  155 + },
  156 + {
  157 + type: "in",
  158 + level: 1,
  159 + enumType: 'int',
  160 + color: '#28C76F',
  161 + slot: 'input',
  162 + label: 'int',
  163 + multiConnected: 1
  164 + },
  165 + {
  166 + type: "in",
  167 + level: 2,
  168 + enumType: 'int',
  169 + color: '#28C76F',
  170 + slot: 'input',
  171 + label: 'int',
  172 + multiConnected: 1
  173 + },
  174 + {
  175 + type: "out",
  176 + level: 0,
  177 + enumType: 'call',
  178 + color: '#fff'
  179 + },
  180 + {
  181 + type: "out",
  182 + level: 1,
  183 + enumType: 'bool',
  184 + color: '#0396FF',
  185 + label: 'bool',
  186 + multiConnected: 1
  187 + },
  188 + ],
  189 + titleBarColor: ['#fccb90', '#d57eeb']
  190 + },
  191 + {
  192 + id: 'card2',
  193 + x: 300,
  194 + y: 400,
  195 + label: 'BoolToString',
  196 + type: "call",
  197 + nodes: [{
  198 + type: "in",
  199 + level: 0,
  200 + enumType: 'call',
  201 + color: '#fff'
  202 + },
  203 + {
  204 + type: "in",
  205 + level: 1,
  206 + enumType: 'bool',
  207 + color: '#0396FF',
  208 + label: 'bool',
  209 + multiConnected: 1
  210 + },
  211 + {
  212 + type: "out",
  213 + level: 0,
  214 + enumType: 'call',
  215 + color: '#fff'
  216 + },
  217 + {
  218 + type: "out",
  219 + level: 1,
  220 + enumType: 'string',
  221 + color: '#DE4313',
  222 + label: 'string',
  223 + multiConnected: 1
  224 + }
  225 + ],
  226 + titleBarColor: ['#3C8CE7', '#00EAFF']
  227 +
  228 + },
  229 + {
  230 + id: 'card3',
  231 + x: 100,
  232 + y: 300,
  233 + label: 'Print',
  234 + type: "print",
  235 + nodes: [{
  236 + type: "in",
  237 + level: 0,
  238 + enumType: 'call',
  239 + color: '#fff'
  240 + },
  241 + {
  242 + type: "in",
  243 + level: 1,
  244 + enumType: 'string',
  245 + color: '#DE4313',
  246 + label: 'string',
  247 + multiConnected: 1
  248 + }
  249 + ],
  250 + titleBarColor: ['#f6d365', '#fda085']
  251 + }
  252 + ];
  253 +
  254 +
  255 + let links = [];
  256 + let currentLink = null;
  257 + let isDragging = false;
  258 + let isLinking = false;
  259 + let dragOffsetX, dragOffsetY;
  260 + let currentCard;
  261 +
  262 + function init() {
  263 + drawLinks();
  264 + drawCards();
  265 + attachEventListeners();
  266 + }
  267 +
  268 + function drawCards() {
  269 + const cardsContainer = document.getElementById('cardsContainer');
  270 + cardsContainer.innerHTML = ''; // 清除现有的卡片
  271 +
  272 + cards.forEach(card => {
  273 +
  274 + //创建标题栏渐变色
  275 + const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
  276 + const linearGradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
  277 + linearGradient.setAttribute('id', `titleGradient-${card.id}`);
  278 + linearGradient.setAttribute('x1', '0%'); // 渐变起点的x坐标
  279 + linearGradient.setAttribute('y1', '100%'); // 渐变起点的y坐标
  280 + linearGradient.setAttribute('x2', '100%'); // 渐变终点的x坐标
  281 + linearGradient.setAttribute('y2', '0%'); // 渐变终点的y坐标
  282 +
  283 + const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  284 + stop1.setAttribute('offset', '10%');
  285 + stop1.setAttribute('style', `stop-color: ${card.titleBarColor[0]}; stop-opacity: 1`);
  286 + linearGradient.appendChild(stop1);
  287 +
  288 + const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  289 + stop2.setAttribute('offset', '100%');
  290 + stop2.setAttribute('style', `stop-color: ${card.titleBarColor[1]}; stop-opacity: 1`);
  291 + linearGradient.appendChild(stop2);
  292 +
  293 + defs.appendChild(linearGradient);
  294 + cardsContainer.appendChild(defs);
  295 +
  296 +
  297 +
  298 + const nodeSpacing = 50;
  299 + const topBottomPadding = 20;
  300 + const titleBarHeight = 30; // 标题栏高度
  301 + const maxLevel = Math.max(...card.nodes.map(node => node.level)) + 1;
  302 + const cardHeight = maxLevel * nodeSpacing + topBottomPadding * 2 + titleBarHeight;
  303 +
  304 + const group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
  305 + group.setAttribute('class', 'draggable card-container');
  306 + group.setAttribute('data-id', card.id);
  307 + group.setAttribute('user-select', 'none');
  308 + group.setAttribute('transform', `translate(${card.x},${card.y})`);
  309 +
  310 + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  311 + rect.setAttribute('fill', '#222');
  312 + rect.setAttribute('width', 150);
  313 + rect.setAttribute('style', 'cursor: auto;');
  314 + rect.setAttribute('height', cardHeight);
  315 + rect.setAttribute('rx', 10); // 圆角
  316 + rect.setAttribute('ry', 10);
  317 + group.appendChild(rect);
  318 +
  319 + // 使用path绘制带有指定圆角的矩形
  320 + // 创建标题栏
  321 + const titleBarWidth = 150;
  322 + const borderRadius = 10; // 圆角大小
  323 + const titleBar = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  324 + const dValue = `M 0,${borderRadius}
  325 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},-${borderRadius}
  326 + h ${titleBarWidth - borderRadius * 2}
  327 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},${borderRadius}
  328 + v ${titleBarHeight - borderRadius}
  329 + h -${titleBarWidth}
  330 + z`;
  331 + titleBar.setAttribute('class', 'card');
  332 + titleBar.setAttribute('d', dValue);
  333 + titleBar.setAttribute('fill', `url(#titleGradient-${card.id})`);
  334 + group.appendChild(titleBar);
  335 +
  336 + const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  337 + text.setAttribute('x', titleBarWidth / 2);
  338 + text.setAttribute('y', titleBarHeight / 2);
  339 + text.setAttribute('text-anchor', 'middle');
  340 + text.setAttribute('alignment-baseline', 'middle');
  341 + text.textContent = card.label;
  342 + group.appendChild(text);
  343 +
  344 + card.nodes.forEach((node, index) => {
  345 +
  346 +
  347 + const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  348 + circle.setAttribute('class', 'node');
  349 + circle.setAttribute('cx', node.type === 'in' ? 0 : 150);
  350 + circle.setAttribute('cy', topBottomPadding + titleBarHeight + (node.level + 1) *
  351 + nodeSpacing - (nodeSpacing / 2));
  352 + circle.setAttribute('r', 7);
  353 + circle.setAttribute('fill', node.color);
  354 + circle.setAttribute('data-card-id', card.id);
  355 + circle.setAttribute('data-node-id', `${card.id}-node${index + 1}`);
  356 + group.appendChild(circle);
  357 +
  358 + let labelX = node.type === 'in' ? 12 : 138; // 基本的X坐标
  359 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 21;
  360 +
  361 + // 创建SVG文本元素
  362 + const multiConnectedLabel = document.createElementNS('http://www.w3.org/2000/svg',
  363 + 'text');
  364 + multiConnectedLabel.setAttribute('x', labelX);
  365 + multiConnectedLabel.setAttribute('y', labelY);
  366 + multiConnectedLabel.setAttribute('text-anchor', 'middle');
  367 + multiConnectedLabel.setAttribute('fill', '#aaa');
  368 + multiConnectedLabel.setAttribute('style', 'font-size: 8px;');
  369 + multiConnectedLabel.setAttribute('alignment-baseline', 'hanging');
  370 +
  371 +
  372 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  373 + let estimatedTextLength;
  374 + if (node.multiConnected == undefined) {
  375 + estimatedTextLength = 20
  376 + multiConnectedLabel.textContent = 'N';
  377 + } else {
  378 + estimatedTextLength = node.multiConnected.length;
  379 + multiConnectedLabel.textContent = node.multiConnected;
  380 + }
  381 +
  382 + // 确保文本不会超出卡片右边界
  383 + if (labelX + estimatedTextLength / 2 > 150) {
  384 + labelX = 150 - estimatedTextLength / 2;
  385 + nodeLabel.setAttribute('x', labelX);
  386 + }
  387 +
  388 + // 确保文本不会超出卡片左边界
  389 + if (labelX - estimatedTextLength / 2 < 0) {
  390 + labelX = estimatedTextLength / 2;
  391 + nodeLabel.setAttribute('x', labelX);
  392 + }
  393 +
  394 + group.appendChild(multiConnectedLabel);
  395 +
  396 + if (node.label != undefined) {
  397 + // 计算文本标签的位置
  398 + let labelX = node.type === 'in' ? 15 : 135; // 基本的X坐标
  399 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 40;
  400 +
  401 + // 创建SVG文本元素
  402 + const nodeLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  403 + nodeLabel.setAttribute('x', labelX);
  404 + nodeLabel.setAttribute('y', labelY); // 在节点下方留出一定空间
  405 + nodeLabel.setAttribute('text-anchor', 'middle'); // 文本居中对齐
  406 + nodeLabel.setAttribute('fill', '#aaa'); // 文本居中对齐
  407 + nodeLabel.setAttribute('alignment-baseline', 'hanging');
  408 + nodeLabel.textContent = node.label;
  409 +
  410 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  411 + const estimatedTextLength = node.label.length * 10; // 估算每个字符6像素宽
  412 +
  413 + // 确保文本不会超出卡片右边界
  414 + if (labelX + estimatedTextLength / 2 > 150) {
  415 + labelX = 150 - estimatedTextLength / 2;
  416 + nodeLabel.setAttribute('x', labelX);
  417 + }
  418 +
  419 + // 确保文本不会超出卡片左边界
  420 + if (labelX - estimatedTextLength / 2 < 0) {
  421 + labelX = estimatedTextLength / 2;
  422 + nodeLabel.setAttribute('x', labelX);
  423 + }
  424 +
  425 + group.appendChild(nodeLabel);
  426 +
  427 + }
  428 +
  429 + switch (node.slot) {
  430 + case 'input':
  431 + const foreignObject = document.createElementNS('http://www.w3.org/2000/svg',
  432 + 'foreignObject');
  433 + foreignObject.setAttribute('x', 0);
  434 + foreignObject.setAttribute('y', topBottomPadding + titleBarHeight + node.level *
  435 + nodeSpacing + 12);
  436 + foreignObject.setAttribute('width', 130); // 保持原始宽度
  437 + foreignObject.setAttribute('height', nodeSpacing - 24); // 保持原始高度,减去的24像素为上下内边距之和
  438 + const input = document.createElement('input');
  439 + input.type = 'text';
  440 + if (node.value == undefined) {
  441 + node.value = '';
  442 + }
  443 + input.value = node.value;
  444 + input.addEventListener('input', function() {
  445 + node.value = input.value;
  446 + });
  447 + // Set adjusted input styles
  448 + input.style.width = '110px';
  449 + input.style.height = '100%';
  450 + input.style.marginLeft = '20px';
  451 + input.style.borderRadius = '5px';
  452 + input.style.border = '1px solid white';
  453 + input.style.backgroundColor = '#222';
  454 + input.style.color = 'white';
  455 + input.style.fontSize = '1em';
  456 + input.style.padding = '0px'; // 可能需要调整或去除内边距以适应固定尺寸
  457 + input.style.boxSizing = 'border-box'; // 确保宽高包含内容、内边距和边框
  458 +
  459 + // Change border color on focus and blur
  460 + input.addEventListener('focus', () => {
  461 + input.style.outline = 'none'; // Remove default focus outline
  462 + input.style.borderColor =
  463 + 'white'; // Keep border color white on focus
  464 + });
  465 +
  466 + input.addEventListener('blur', () => {
  467 + input.style.borderColor =
  468 + 'white'; // Revert to white when not focused
  469 + });
  470 +
  471 + // 阻止事件冒泡
  472 + input.addEventListener('click', function(event) {
  473 + event.stopPropagation();
  474 + });
  475 +
  476 + input.addEventListener('mousedown', function(event) {
  477 + event.stopPropagation();
  478 + });
  479 +
  480 + input.addEventListener('touchstart', function(event) {
  481 + event.stopPropagation();
  482 + });
  483 +
  484 + foreignObject.appendChild(input);
  485 + group.appendChild(foreignObject);
  486 + break;
  487 + }
  488 +
  489 +
  490 +
  491 + });
  492 +
  493 + const deleteIcon = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  494 + deleteIcon.setAttribute('class', 'card-delete-icon');
  495 + deleteIcon.setAttribute('x', 125);
  496 + deleteIcon.setAttribute('y', 5); // 使其贴近标题栏的右上角
  497 + deleteIcon.setAttribute('width', 20);
  498 + deleteIcon.setAttribute('height', 20);
  499 + deleteIcon.setAttribute('fill', 'transparent');
  500 + deleteIcon.setAttribute('data-card-id', card.id);
  501 + deleteIcon.setAttribute('style', 'cursor: pointer;');
  502 + group.appendChild(deleteIcon);
  503 +
  504 + const delText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  505 + delText.setAttribute('x', 135);
  506 + delText.setAttribute('y', 20); // 调整位置以垂直居中
  507 + delText.setAttribute('text-anchor', 'middle');
  508 + delText.setAttribute('fill', 'white');
  509 + delText.setAttribute('font-size', '16px'); // 适当调整字体大小以适应图标
  510 + delText.setAttribute('pointer-events', 'none'); // 确保点击事件只触发于删除图标上
  511 + delText.textContent = '×';
  512 + group.appendChild(delText);
  513 +
  514 + cardsContainer.appendChild(group);
  515 + });
  516 +
  517 + attachNodeEventListeners();
  518 + }
  519 +
  520 +
  521 +
  522 + function drawLinks() {
  523 + const linksContainer = document.getElementById('linksContainer');
  524 + linksContainer.innerHTML = ''; // 清除现有的线条
  525 + // 清除旧的删除图标
  526 + document.querySelectorAll('.delete-icon').forEach(icon => icon.remove());
  527 +
  528 + links.forEach((link, index) => {
  529 + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  530 + //path.setAttribute('class', 'link');
  531 + path.setAttribute('stroke', link.target.color)
  532 + path.setAttribute('stroke-width', 5)
  533 + path.setAttribute('fill', 'none');
  534 +
  535 +
  536 + const isCallType = link.source.enumType === 'call';
  537 + if (isCallType) {
  538 + path.setAttribute('stroke-dasharray', '10');
  539 + path.setAttribute('stroke-dashoffset', '0');
  540 +
  541 + // Add animation element to the path for dashed lines
  542 + const animate = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
  543 + animate.setAttribute('attributeName', 'stroke-dashoffset');
  544 + animate.setAttribute('dur', '0.5s');
  545 + animate.setAttribute('repeatCount', 'indefinite');
  546 + animate.setAttribute('from', '20');
  547 + animate.setAttribute('to', '0');
  548 + path.appendChild(animate);
  549 + }
  550 +
  551 +
  552 + let dist;
  553 + // 使用动态计算的控制点距离来定义曲线,根据源点和终点的X坐标差异动态计算控制点的距离
  554 + if (link.source.type === 'out') {
  555 + if (link.source.x - link.target.x > 0) {
  556 + dist = 200; // 如果终点在源点的左侧,控制点距离更远
  557 + } else {
  558 + dist = Math.abs(link.target.x - link.source.x) * 0.3; // 否则,根据两点间的距离调整控制点距离
  559 + }
  560 + const d =
  561 + `M${link.source.x} ${link.source.y} C${link.source.x + dist} ${link.source.y} ${link.target.x - dist} ${link.target.y} ${link.target.x} ${link.target.y}`;
  562 + path.setAttribute('d', d);
  563 + linksContainer.appendChild(path);
  564 + } else {
  565 + if (link.target.x - link.source.x > 0) {
  566 + dist = 200; // 如果终点在源点的右侧,控制点距离更远
  567 + } else {
  568 + dist = Math.abs(link.target.x - link.source.x) * 0.3; // 否则,根据两点间的距离调整控制点距离
  569 + }
  570 + const d =
  571 + `M${link.source.x} ${link.source.y} C${link.source.x - dist} ${link.source.y} ${link.target.x + dist} ${link.target.y} ${link.target.x} ${link.target.y}`;
  572 + path.setAttribute('d', d);
  573 + linksContainer.appendChild(path);
  574 + }
  575 +
  576 +
  577 + // 计算中点
  578 + const midX = (link.source.x + link.target.x) / 2;
  579 + const midY = (link.source.y + link.target.y) / 2;
  580 +
  581 + // 绘制删除图标
  582 + const deleteIcon = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  583 + deleteIcon.setAttribute('class', 'delete-icon');
  584 + deleteIcon.setAttribute('cx', midX);
  585 + deleteIcon.setAttribute('cy', midY);
  586 + deleteIcon.setAttribute('style', "cursor: pointer;");
  587 + deleteIcon.setAttribute('r', 10);
  588 + deleteIcon.setAttribute('fill', 'red');
  589 + deleteIcon.setAttribute('data-link-level', index); // 用于标识该删除图标对应的线
  590 + linksContainer.appendChild(deleteIcon);
  591 +
  592 + // 可以选择添加一个×文本在圆圈中间
  593 + const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  594 + text.setAttribute('x', midX);
  595 + text.setAttribute('y', midY + 5); // 轻微调整以垂直居中
  596 + text.setAttribute('text-anchor', 'middle');
  597 + text.setAttribute('fill', 'white');
  598 + text.setAttribute('font-size', '15px');
  599 + text.setAttribute('pointer-events', 'none'); // 确保点击事件只触发于圆圈上
  600 + text.textContent = '×';
  601 + linksContainer.appendChild(text);
  602 +
  603 + });
  604 + }
  605 +
  606 + // 定义变量来追踪是否正在拖动以及拖动的起始位置
  607 + let isPanning = false;
  608 + let startPan = {
  609 + x: 0,
  610 + y: 0
  611 + };
  612 +
  613 + // 用于调整SVG视图窗口的变量
  614 + let currentPan = {
  615 + x: 0,
  616 + y: 0
  617 + };
  618 +
  619 + function attachEventListeners() {
  620 +
  621 + const svgContainer = document.getElementById('svgContainer');
  622 + document.querySelectorAll('.link').forEach(link => {
  623 + link.addEventListener('contextmenu', function(e) {
  624 + e.preventDefault(); // 阻止默认的右键菜单
  625 + const linkId = e.target.getAttribute('data-link-id'); // 确保你在绘制线条时添加了 data-link-id 属性
  626 + showContextMenu(e.clientX, e.clientY, linkId);
  627 + });
  628 + });
  629 + document.getElementById('svgContainer').addEventListener('click', function(e) {
  630 + if (e.target.classList.contains('delete-icon')) {
  631 + // 获取点击的删除图标对应的线的索引
  632 + const linkIndex = e.target.getAttribute('data-link-level');
  633 + // 从数组中移除该线
  634 + links.splice(linkIndex, 1);
  635 + // 重新绘制剩余的线和删除图标
  636 + drawLinks();
  637 + drawCards(); // 如果你的线条与卡片有关联,可能需要重新绘制卡片以更新视图
  638 + } else if (e.target.classList.contains('card-delete-icon')) {
  639 + // 获取点击的删除图标对应的卡片ID
  640 + const cardId = e.target.getAttribute('data-card-id');
  641 + // 从`cards`数组中移除对应的卡片
  642 + cards = cards.filter(card => card.id !== cardId);
  643 + // 同时移除所有与该卡片连接的线
  644 + links = links.filter(link => !(link.source.node.startsWith(cardId) || (link.target && link.target
  645 + .node.startsWith(cardId))));
  646 + // 重新绘制卡片和线
  647 + drawLinks();
  648 + drawCards();
  649 + } else {
  650 + let targetCardContainer = e.target.closest('.card-container');
  651 + if (targetCardContainer) {
  652 + const cardId = targetCardContainer.getAttribute('data-id');
  653 + // 将SVG元素移动到最后,使其在视觉上显示在最前面
  654 + targetCardContainer.parentNode.appendChild(targetCardContainer);
  655 +
  656 + // 更新cards数组,将点击的卡片移动到数组的末尾
  657 + const cardIndex = cards.findIndex(card => card.id === cardId);
  658 + if (cardIndex > -1) {
  659 + const card = cards.splice(cardIndex, 1)[0];
  660 + cards.push(card);
  661 + }
  662 +
  663 + // 这里不需要立即调用drawCards或drawLinks,
  664 + // 除非你需要根据cards数组的新顺序进行其他更新
  665 + }
  666 + }
  667 + });
  668 +
  669 + svgContainer.addEventListener('contextmenu', function(e) {
  670 + e.preventDefault(); // 阻止右键菜单
  671 + });
  672 +
  673 + svgContainer.addEventListener('mousedown', e => {
  674 +
  675 + // 检查是否是鼠标右键点击
  676 +
  677 + const target = e.target;
  678 + if (e.button === 2) {
  679 + isPanning = true;
  680 + startPan.x = e.clientX - currentPan.x;
  681 + startPan.y = e.clientY - currentPan.y;
  682 + } else if (target
  683 +
  684 + .classList.contains('card') || target.tagName === 'text') {
  685 + const cardContainer = target.closest('.card-container');
  686 + const cardId = cardContainer.getAttribute('data-id');
  687 + startDragCard(e, cardId);
  688 + }
  689 + });
  690 + document.addEventListener('mousemove', e => {
  691 + if (isPanning) {
  692 + // 正确计算新的视图窗口位置
  693 + currentPan.x = e.clientX - startPan.x;
  694 + currentPan.y = e.clientY - startPan.y;
  695 +
  696 + // 正确调整SVG的viewBox来实现拖动效果
  697 + // 这里需要更新的是开始拖动的点,而不是当前的点,因此我们反向更新
  698 + svgContainer.setAttribute('viewBox',
  699 + `${-currentPan.x} ${-currentPan.y} ${svgContainer.clientWidth} ${svgContainer.clientHeight}`
  700 + );
  701 + svgContainer.style.backgroundPosition = `${currentPan.x % 100}px ${currentPan.y % 100}px`;
  702 + } else if (isDragging) {
  703 + moveCard(e);
  704 + } else if (isLinking && currentLink) {
  705 + updateLink(e);
  706 + }
  707 + });
  708 +
  709 + document.addEventListener('mouseup', e => {
  710 + if (e.button === 2) {
  711 + console.log(currentPan);
  712 + isPanning = false;
  713 + } else if (isDragging) {
  714 + endDragCard();
  715 + } else if (isLinking) {
  716 + endDragLink(e);
  717 + }
  718 + });
  719 + }
  720 +
  721 + function startDragCard(e, cardId) {
  722 + isDragging = true;
  723 + const card = cards.find(c => c.id === cardId);
  724 + currentCard = card;
  725 +
  726 + const svgRect = svgContainer.getBoundingClientRect();
  727 + dragOffsetX = e.clientX - svgRect.left - card.x;
  728 + dragOffsetY = e.clientY - svgRect.top - card.y;
  729 + }
  730 +
  731 + function moveCard(e) {
  732 + const svgRect = svgContainer.getBoundingClientRect();
  733 + currentCard.x = e.clientX - svgRect.left - dragOffsetX;
  734 + currentCard.y = e.clientY - svgRect.top - dragOffsetY;
  735 +
  736 + // Update link positions associated with the currentCard
  737 + links.forEach(link => {
  738 + if (link.source.node.startsWith(currentCard.id)) {
  739 + // 根据节点ID更新链接的源位置
  740 + const nodeIndex = parseInt(link.source.node.split('-node')[1]) - 1;
  741 + const nodeConfig = currentCard.nodes[nodeIndex]; // 获取当前节点的配置
  742 + const nodeSpacing = 50; // 节点间隔,应与drawCards函数中使用的相同
  743 + const topBottomPadding = 20; // 顶部和底部的边距,应与drawCards函数中使用的相同
  744 + link.source.x = currentCard.x + (nodeConfig.type === "in" ? 0 : 150); // 根据节点类型调整x坐标
  745 + link.source.y = 30 + currentCard.y + topBottomPadding + (nodeConfig.level + 1) * nodeSpacing - (
  746 + nodeSpacing / 2); // 根据节点的index调整y坐标
  747 + }
  748 + if (link.target && link.target.node.startsWith(currentCard.id)) {
  749 + // 根据节点ID更新链接的目标位置
  750 + const nodeIndex = parseInt(link.target.node.split('-node')[1]) - 1;
  751 + const nodeConfig = currentCard.nodes[nodeIndex]; // 获取当前节点的配置
  752 + link.target.x = currentCard.x + (nodeConfig.type === "in" ? 0 : 150); // 根据节点类型调整x坐标
  753 + link.target.y = 30 + currentCard.y + 20 + (nodeConfig.level + 1) * 50 - (50 /
  754 + 2); // 根据节点的index调整y坐标
  755 + }
  756 + });
  757 +
  758 + drawLinks(); // Redraw links to reflect updated positions
  759 + drawCards(); // Redraw cards and nodes
  760 + }
  761 +
  762 +
  763 +
  764 + function endDragCard() {
  765 + isDragging = false;
  766 + }
  767 +
  768 + function getNodeCurrentConnections(nodeId) {
  769 + let count = 0;
  770 + links.forEach(link => {
  771 + if (link.source.node === nodeId || (link.target && link.target.node === nodeId)) {
  772 + count++;
  773 + }
  774 + });
  775 + return count;
  776 + }
  777 +
  778 + function startDragLink(e) {
  779 + e.stopPropagation(); // Prevent card drag
  780 +
  781 + const nodeId = e.target.getAttribute('data-node-id');
  782 + const cardId = e.target.getAttribute('data-card-id');
  783 + const card = cards.find(c => c.id === cardId);
  784 + const nodeElement = e.target;
  785 + const node = card.nodes.find(n => `${card.id}-node${card.nodes.indexOf(n) + 1}` === nodeId);
  786 +
  787 +
  788 + // 检查源节点是否允许发起新的连接
  789 + const currentConnections = getNodeCurrentConnections(nodeId);
  790 + if (node.multiConnected !== -1 && currentConnections >= node.multiConnected) {
  791 + console.log('此节点不允许更多的连接。');
  792 + return; // 不允许创建新的连接
  793 + }
  794 + isLinking = true;
  795 +
  796 + const svgRect = svgContainer.getBoundingClientRect();
  797 + const nodeX = e.clientX - svgRect.left;
  798 + const nodeY = e.clientY - svgRect.top;
  799 +
  800 + currentLink = {
  801 + source: {
  802 + node: nodeId,
  803 + x: nodeX,
  804 + y: nodeY,
  805 + color: nodeElement.getAttribute('fill'),
  806 + type: node.type,
  807 + enumType: node.enumType
  808 + },
  809 + target: null
  810 + };
  811 + }
  812 +
  813 + function updateLink(e) {
  814 + const svgRect = svgContainer.getBoundingClientRect();
  815 + currentLink.target = {
  816 + x: e.clientX - svgRect.left,
  817 + y: e.clientY - svgRect.top
  818 + };
  819 + drawCurrentLink();
  820 + }
  821 +
  822 + function endDragLink(e) {
  823 + isLinking = false;
  824 + const svgRect = svgContainer.getBoundingClientRect();
  825 + const x = e.clientX - svgRect.left;
  826 + const y = e.clientY - svgRect.top;
  827 +
  828 + // 默认情况下,假设目标节点就是e.target
  829 + let targetNode = e.target;
  830 +
  831 + // 检查e.target是否是我们期望的节点类型,如果不是,则尝试使用document.elementFromPoint
  832 + if (!targetNode.classList.contains('node')) {
  833 + e.target.style.display = 'none';
  834 + targetNode = document.elementFromPoint(e.clientX, e.clientY);
  835 + e.target.style.display = '';
  836 + }
  837 +
  838 + let validTargetFound = false;
  839 +
  840 + // 进行节点的有效性判断
  841 + if (targetNode && targetNode.classList.contains('node')) {
  842 + const sourceNodeId = currentLink.source.node;
  843 + const targetNodeId = targetNode.getAttribute('data-node-id');
  844 +
  845 + // 从节点ID分解出卡片ID和节点索引
  846 + const sourceNodeParts = sourceNodeId.split('-node');
  847 + const targetNodeParts = targetNodeId.split('-node');
  848 + const sourceCard = cards.find(card => card.id === sourceNodeParts[0]);
  849 + const targetCard = cards.find(card => card.id === targetNodeParts[0]);
  850 +
  851 + // 根据节点ID找到对应的节点对象
  852 + const sourceNodeIndex = parseInt(sourceNodeParts[1]) - 1;
  853 + const targetNodeIndex = parseInt(targetNodeParts[1]) - 1;
  854 + const sourceNode = sourceCard.nodes[sourceNodeIndex];
  855 + const targetNodeObj = targetCard.nodes[targetNodeIndex];
  856 +
  857 + // 检查目标节点是否允许接受新的连接
  858 + const targetCurrentConnections = getNodeCurrentConnections(targetNodeId);
  859 + if (targetNodeObj.multiConnected !== -1 && targetCurrentConnections >= targetNodeObj.multiConnected) {
  860 + console.log('目标节点不允许更多的连接。');
  861 + // 移除临时绘制的连接线
  862 + const tempLink = document.querySelector('.temp-link');
  863 + if (tempLink) {
  864 + tempLink.remove();
  865 + }
  866 + currentLink = null;
  867 + drawLinks();
  868 + return;
  869 + }
  870 + // 确保目标节点不是起始节点自身,避免自连接
  871 + if (currentLink.source.node !== targetNodeId && sourceNode.enumType === targetNodeObj.enumType) {
  872 + validTargetFound = true;
  873 + currentLink.source.enumType = sourceNode.enumType;
  874 + currentLink.source.x = currentLink.source.x - currentPan.x;
  875 + currentLink.source.y = currentLink.source.y - currentPan.y;
  876 + // 更新连接的目标信息,并保存该连接
  877 + links.push({
  878 + ...currentLink,
  879 + target: {
  880 + node: targetNodeId,
  881 + x: x - currentPan.x,
  882 + y: y - currentPan.y,
  883 + color: sourceNode.color,
  884 + enumType: sourceNode.enumType
  885 + }
  886 + });
  887 + }
  888 + } else {
  889 + const sourceNodeId = currentLink.source.node;
  890 + const sourceNodeParts = sourceNodeId.split('-node');
  891 + const sourceCard = cards.find(card => card.id === sourceNodeParts[0]);
  892 + const sourceNodeIndex = parseInt(sourceNodeParts[1]) - 1;
  893 + const sourceNode = sourceCard.nodes[sourceNodeIndex];
  894 + currentLink.source.enumType = sourceNode.enumType;
  895 + showCardCreationModal(e.clientX, e.clientY, currentLink.source);
  896 +
  897 + }
  898 +
  899 + const tempLink = document.querySelector('.temp-link');
  900 + if (tempLink) {
  901 + tempLink.remove();
  902 + }
  903 + currentLink = null;
  904 + drawLinks();
  905 + }
  906 +
  907 +
  908 +
  909 +
  910 +
  911 +
  912 + // 更新drawCurrentLink函数,增加线宽
  913 + // 更新drawCurrentLink函数,增加线宽
  914 + function drawCurrentLink() {
  915 + const tempLink = document.querySelector('.temp-link');
  916 + if (tempLink) tempLink.remove();
  917 +
  918 + if (!currentLink || !currentLink.target) return;
  919 +
  920 + const svgContainer = document.getElementById('svgContainer');
  921 + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  922 + path.setAttribute('class', 'temp-link');
  923 + // 设置等宽线属性
  924 + path.setAttribute('stroke', currentLink.source.color);
  925 + path.setAttribute('stroke-width', 5);
  926 + path.setAttribute('fill', 'none');
  927 +
  928 + // 计算考虑了平移偏移的起点和终点
  929 + const adjustedSourceX = currentLink.source.x - currentPan.x;
  930 + const adjustedSourceY = currentLink.source.y - currentPan.y;
  931 + const adjustedTargetX = currentLink.target.x - currentPan.x;
  932 + const adjustedTargetY = currentLink.target.y - currentPan.y;
  933 +
  934 + // 更新路径以使用调整后的坐标
  935 + if (currentLink.source.type === 'out') {
  936 + const d =
  937 + `M${adjustedSourceX},${adjustedSourceY} C${adjustedSourceX + 100},${adjustedSourceY} ${adjustedTargetX - 100},${adjustedTargetY} ${adjustedTargetX},${adjustedTargetY}`;
  938 + path.setAttribute('d', d);
  939 + } else {
  940 + const d =
  941 + `M${adjustedSourceX},${adjustedSourceY} C${adjustedSourceX - 100},${adjustedSourceY} ${adjustedTargetX + 100},${adjustedTargetY} ${adjustedTargetX},${adjustedTargetY}`;
  942 + path.setAttribute('d', d);
  943 + }
  944 +
  945 + svgContainer.appendChild(path);
  946 + }
  947 +
  948 + function attachNodeEventListeners() {
  949 + document.querySelectorAll('.node').forEach(node => {
  950 + node.addEventListener('mousedown', startDragLink);
  951 + });
  952 + }
  953 +
  954 + function populateCardTypeList(mouseX, mouseY, sourceNode) {
  955 + const listElement = document.getElementById('card-type-list');
  956 + listElement.innerHTML = ''; // 清空现有列表项
  957 + const addedTypes = new Set();
  958 +
  959 + cards.forEach(card => {
  960 + if (!addedTypes.has(card.type)) {
  961 + const listItem = document.createElement('li');
  962 + listItem.tabIndex = 0; // 使元素能够获得焦点,以便能够监听键盘事件
  963 + listItem.textContent = card.label; // 使用卡片的标签或类型
  964 + listItem.onclick = function() {
  965 + createNewCard(card, mouseX, mouseY, sourceNode);
  966 + hideCardCreationModal(); // 新建卡片后隐藏模态框
  967 + };
  968 + listItem.onkeydown = function(event) {
  969 + if (event.key === 'Enter') {
  970 + createNewCard(card, mouseX, mouseY, sourceNode);
  971 + hideCardCreationModal(); // 新建卡片后隐藏模态框
  972 + }
  973 + };
  974 + listElement.appendChild(listItem);
  975 + addedTypes.add(card.type);
  976 + }
  977 + });
  978 + }
  979 +
  980 +
  981 + function showCardCreationModal(mouseX, mouseY, sourceNode) {
  982 + populateCardTypeList(mouseX, mouseY, sourceNode); // 填充卡片类型列表
  983 + const modal = document.getElementById('card-creation-modal');
  984 + // 在这里添加取消按钮
  985 + if (!document.getElementById('cancel-btn')) {
  986 + const cancelButton = document.createElement('button');
  987 + cancelButton.id = 'cancel-btn';
  988 + cancelButton.textContent = '取消';
  989 + cancelButton.onclick = function() {
  990 + hideCardCreationModal();
  991 + };
  992 + modal.appendChild(cancelButton);
  993 + }
  994 +
  995 +
  996 +
  997 + // 设置弹出框的位置
  998 + modal.style.left = mouseX + 'px';
  999 + modal.style.top = mouseY + 'px';
  1000 + modal.style.display = 'block'; // 显示弹窗
  1001 + }
  1002 +
  1003 + function createNewCard(cardTemplate, mouseX, mouseY, sourceNode) {
  1004 + const newCard = {
  1005 + ...cardTemplate,
  1006 + nodes: JSON.parse(JSON.stringify(cardTemplate.nodes)), // 深拷贝nodes属性
  1007 + id: 'card' + (cards.length + 1)
  1008 + };
  1009 + // 将每个node的value设置为空字符串
  1010 + newCard.nodes.forEach(node => {
  1011 + node.value = '';
  1012 + });
  1013 + newCard.x = mouseX - 75 - currentPan.x; // 调整为鼠标中心
  1014 + newCard.y = mouseY - 15 - currentPan.y; // 调整为鼠标中心
  1015 + cards.push(newCard); // 将新创建的卡片添加到卡片列表中
  1016 +
  1017 + // 如果提供了sourceNode,找到新卡片的合适target node并创建连接
  1018 + if (sourceNode) {
  1019 + sourceNode.x -= currentPan.x;
  1020 + sourceNode.y -= currentPan.y;
  1021 + let targetNode = newCard.nodes.find(node => node.enumType === sourceNode.enumType && node.type === 'in');
  1022 + if (targetNode) {
  1023 + links.push({
  1024 + source: sourceNode,
  1025 + target: {
  1026 + node: `${newCard.id}-node${newCard.nodes.indexOf(targetNode) + 1}`,
  1027 + x: newCard.x + (targetNode.type === 'in' ? 0 : 150),
  1028 + y: newCard.y + 30 + 20 + (targetNode.level + 1) * 50 - 25,
  1029 + color: targetNode.color,
  1030 + enumType: targetNode.enumType
  1031 + }
  1032 + });
  1033 + }
  1034 + }
  1035 +
  1036 +
  1037 + drawLinks();
  1038 + drawCards();
  1039 + }
  1040 +
  1041 +
  1042 +
  1043 + function hideCardCreationModal() {
  1044 + const modal = document.getElementById('card-creation-modal');
  1045 + modal.style.display = 'none'; // 隐藏弹窗
  1046 + }
  1047 +
  1048 + init();
  1049 + </script>
  1050 + </body>
  1051 +
  1052 +</html>-->
... ...
src/main/resources/static/pages/zndd_yuan/DKL.html 0 → 100644
  1 +<!-- 片段标题 START -->
  2 +<div class="page-head">
  3 + <div class="page-title">
  4 + <h1>调度预案配置</h1>
  5 + </div>
  6 +</div>
  7 +
  8 + <!-- 弹窗容器 -->
  9 + <div id="card-creation-modal"
  10 + style="display:none; position: absolute; border: 1px solid #ccc; background-color: #fff; padding: 10px; z-index: 100;">
  11 + <!-- 搜索结果列表 -->
  12 + <ul id="card-type-list"></ul>
  13 + </div>
  14 + <div>
  15 + <button id="saves">保存</button>
  16 +
  17 + </div>
  18 + <div>
  19 + <select name="destroy" class="form-control" id="destroySelect">
  20 + <option value="DKL">-- 大客流 --</option>
  21 + <option value="WD">-- 误点 --</option>
  22 + </select>
  23 + </div>
  24 + <div style="height: 80%">
  25 + <svg style="width: 100%;height: 100%;" id="svgContainer" class="grid-background">
  26 + <g id="linksContainer"></g> <!-- 用于存放线条 -->
  27 + <g id="cardsContainer"></g> <!-- 用于存放卡片 -->
  28 + </svg>
  29 + </div>
  30 +
  31 +<script>
  32 + var cards = [
  33 + {
  34 + id: 'card0',
  35 + x: 0,
  36 + y: 0,
  37 + label: '开始类型',
  38 + type: "开始类型",
  39 + nodes: [ {
  40 + type: "out",
  41 + level: 0,
  42 + enumType: 'call',
  43 + color: '#3C8CE7',
  44 + slot: 'input',
  45 + }
  46 + ],
  47 + titleBarColor: ['#84fab0', '#8fd3f4']
  48 + },{
  49 + id: 'card1',
  50 + x: 100,
  51 + y: 220,
  52 + label: '流程',
  53 + type: "流程",
  54 + nodes: [{
  55 + type: "in",
  56 + level: 0,
  57 + enumType: 'call',
  58 + color: '#fff'
  59 + },
  60 + {
  61 + type: "out",
  62 + level: 0,
  63 + enumType: 'call',
  64 + color: '#3C8CE7',
  65 + slot: 'input',
  66 + },
  67 + ],
  68 + titleBarColor: ['#fccb90', '#d57eeb']
  69 + },{
  70 + id: 'card2',
  71 + x: 100,
  72 + y: 300,
  73 + label: '结束',
  74 + type: "流程y",
  75 + nodes: [{
  76 + type: "in",
  77 + level: 0,
  78 + enumType: 'call',
  79 + color: '#fff',
  80 + slot: 'input',
  81 + }
  82 + ],
  83 + titleBarColor: ['#f6d365', '#fda085']
  84 + }
  85 + ];
  86 +
  87 + var cardsbei = [
  88 + {
  89 + id: 'card0',
  90 + x: 0,
  91 + y: 0,
  92 + label: '开始类型',
  93 + type: "开始类型",
  94 + nodes: [ {
  95 + type: "out",
  96 + level: 0,
  97 + enumType: 'call',
  98 + color: '#3C8CE7',
  99 + slot: 'input',
  100 + }
  101 + ],
  102 + titleBarColor: ['#84fab0', '#8fd3f4']
  103 + },{
  104 + id: 'cardc',
  105 + x: 100,
  106 + y: 220,
  107 + label: '流程',
  108 + type: "流程",
  109 + nodes: [{
  110 + type: "in",
  111 + level: 0,
  112 + enumType: 'call',
  113 + color: '#fff'
  114 + },
  115 + {
  116 + type: "out",
  117 + level: 0,
  118 + enumType: 'call',
  119 + color: '#3C8CE7',
  120 + slot: 'input',
  121 + },
  122 + ],
  123 + titleBarColor: ['#fccb90', '#d57eeb']
  124 + },{
  125 + id: 'card3',
  126 + x: 100,
  127 + y: 300,
  128 + label: '结束',
  129 + type: "流程y",
  130 + nodes: [{
  131 + type: "in",
  132 + level: 0,
  133 + enumType: 'call',
  134 + color: '#fff',
  135 + slot: 'input',
  136 + }
  137 + ],
  138 + titleBarColor: ['#f6d365', '#fda085']
  139 + }
  140 + ];
  141 + var links = [];
  142 + var currentLink = null;
  143 + var isDragging = false;
  144 + var isLinking = false;
  145 + var dragOffsetX, dragOffsetY;
  146 + var currentCard;
  147 +
  148 +
  149 + $("#destroySelect").on('change',function(){
  150 + var fn = $('#destroySelect').val();
  151 +
  152 + $.get('/zndya/all',{type_eq: fn},function(datas){
  153 + var ts = [];
  154 + var link = [];
  155 + for (var c in datas){
  156 + if(datas[c].types == 0){
  157 + ts.push(JSON.parse(datas[c].jsonDate));
  158 + }else {
  159 + link.push(JSON.parse(datas[c].jsonDate));
  160 + }
  161 +
  162 + }
  163 + debugger
  164 + if (ts.length > 0) {
  165 + cards = ts;
  166 + links = link;
  167 + }else {
  168 + cards = cardsbei;
  169 + links = [];
  170 + }
  171 +
  172 +
  173 + drawLinks();
  174 + drawCards();
  175 + attachEventListeners();
  176 + });
  177 + })
  178 +
  179 + function init() {
  180 +
  181 + $.get('/zndya/all',{type_eq: 'DKL'},function(datas){
  182 + var ts = [];
  183 + var link = [];
  184 + for (var c in datas){
  185 + if(datas[c].types == 0){
  186 + ts.push(JSON.parse(datas[c].jsonDate));
  187 + }else {
  188 + link.push(JSON.parse(datas[c].jsonDate));
  189 + }
  190 +
  191 + }
  192 + if (ts.length > 0) {
  193 + cards = ts;
  194 + links = link;
  195 + }else {
  196 + cards = cardsbei;
  197 + links = [];
  198 + }
  199 +
  200 +
  201 + drawLinks();
  202 + drawCards();
  203 + attachEventListeners();
  204 + });
  205 +
  206 + }
  207 +
  208 + function drawCards() {
  209 + const cardsContainer = document.getElementById('cardsContainer');
  210 + cardsContainer.innerHTML = ''; // 清除现有的卡片
  211 +
  212 + cards.forEach(card => {
  213 +
  214 + //创建标题栏渐变色
  215 + const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
  216 + const linearGradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
  217 + linearGradient.setAttribute('id', `titleGradient-${card.id}`);
  218 + linearGradient.setAttribute('x1', '0%'); // 渐变起点的x坐标
  219 + linearGradient.setAttribute('y1', '100%'); // 渐变起点的y坐标
  220 + linearGradient.setAttribute('x2', '100%'); // 渐变终点的x坐标
  221 + linearGradient.setAttribute('y2', '0%'); // 渐变终点的y坐标
  222 +
  223 + const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  224 + stop1.setAttribute('offset', '10%');
  225 + stop1.setAttribute('style', `stop-color: ${card.titleBarColor[0]}; stop-opacity: 1`);
  226 + linearGradient.appendChild(stop1);
  227 +
  228 + const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  229 + stop2.setAttribute('offset', '100%');
  230 + stop2.setAttribute('style', `stop-color: ${card.titleBarColor[1]}; stop-opacity: 1`);
  231 + linearGradient.appendChild(stop2);
  232 +
  233 + defs.appendChild(linearGradient);
  234 + cardsContainer.appendChild(defs);
  235 +
  236 +
  237 +
  238 + const nodeSpacing = 50;
  239 + const topBottomPadding = 20;
  240 + const titleBarHeight = 30; // 标题栏高度
  241 + const maxLevel = Math.max(...card.nodes.map(node => node.level)) + 1;
  242 + const cardHeight = maxLevel * nodeSpacing + topBottomPadding * 2 + titleBarHeight;
  243 +
  244 + const group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
  245 + group.setAttribute('class', 'draggable card-container');
  246 + group.setAttribute('data-id', card.id);
  247 + group.setAttribute('user-select', 'none');
  248 + group.setAttribute('transform', `translate(${card.x},${card.y})`);
  249 +
  250 + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  251 + rect.setAttribute('fill', '#222');
  252 + rect.setAttribute('width', 150);
  253 + rect.setAttribute('style', 'cursor: auto;');
  254 + rect.setAttribute('height', cardHeight);
  255 + rect.setAttribute('rx', 10); // 圆角
  256 + rect.setAttribute('ry', 10);
  257 + group.appendChild(rect);
  258 +
  259 + // 使用path绘制带有指定圆角的矩形
  260 + // 创建标题栏
  261 + const titleBarWidth = 150;
  262 + const borderRadius = 10; // 圆角大小
  263 + const titleBar = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  264 + const dValue = `M 0,${borderRadius}
  265 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},-${borderRadius}
  266 + h ${titleBarWidth - borderRadius * 2}
  267 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},${borderRadius}
  268 + v ${titleBarHeight - borderRadius}
  269 + h -${titleBarWidth}
  270 + z`;
  271 + titleBar.setAttribute('class', 'card');
  272 + titleBar.setAttribute('d', dValue);
  273 + titleBar.setAttribute('fill', `url(#titleGradient-${card.id})`);
  274 + group.appendChild(titleBar);
  275 +
  276 + const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  277 + text.setAttribute('x', titleBarWidth / 2);
  278 + text.setAttribute('y', titleBarHeight / 2);
  279 + text.setAttribute('text-anchor', 'middle');
  280 + text.setAttribute('alignment-baseline', 'middle');
  281 + text.textContent = card.label;
  282 + group.appendChild(text);
  283 +
  284 + card.nodes.forEach((node, index) => {
  285 +
  286 +
  287 + const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  288 + circle.setAttribute('class', 'node');
  289 + circle.setAttribute('cx', node.type === 'in' ? 0 : 150);
  290 + circle.setAttribute('cy', topBottomPadding + titleBarHeight + (node.level + 1) *
  291 + nodeSpacing - (nodeSpacing / 2));
  292 + circle.setAttribute('r', 7);
  293 + circle.setAttribute('fill', node.color);
  294 + circle.setAttribute('data-card-id', card.id);
  295 + circle.setAttribute('data-node-id', `${card.id}-node${index + 1}`);
  296 + group.appendChild(circle);
  297 +
  298 + var labelX = node.type === 'in' ? 12 : 138; // 基本的X坐标
  299 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 21;
  300 +
  301 + // 创建SVG文本元素
  302 + const multiConnectedLabel = document.createElementNS('http://www.w3.org/2000/svg',
  303 + 'text');
  304 + multiConnectedLabel.setAttribute('x', labelX);
  305 + multiConnectedLabel.setAttribute('y', labelY);
  306 + multiConnectedLabel.setAttribute('text-anchor', 'middle');
  307 + multiConnectedLabel.setAttribute('fill', '#aaa');
  308 + multiConnectedLabel.setAttribute('style', 'font-size: 8px;');
  309 + multiConnectedLabel.setAttribute('alignment-baseline', 'hanging');
  310 +
  311 +
  312 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  313 + var estimatedTextLength;
  314 + if (node.multiConnected == undefined) {
  315 + estimatedTextLength = 20
  316 + multiConnectedLabel.textContent = 'N';
  317 + } else {
  318 + estimatedTextLength = node.multiConnected.length;
  319 + multiConnectedLabel.textContent = node.multiConnected;
  320 + }
  321 +
  322 + // 确保文本不会超出卡片右边界
  323 + if (labelX + estimatedTextLength / 2 > 150) {
  324 + labelX = 150 - estimatedTextLength / 2;
  325 + nodeLabel.setAttribute('x', labelX);
  326 + }
  327 +
  328 + // 确保文本不会超出卡片左边界
  329 + if (labelX - estimatedTextLength / 2 < 0) {
  330 + labelX = estimatedTextLength / 2;
  331 + nodeLabel.setAttribute('x', labelX);
  332 + }
  333 +
  334 + group.appendChild(multiConnectedLabel);
  335 +
  336 + if (node.label != undefined) {
  337 + // 计算文本标签的位置
  338 + var labelX = node.type === 'in' ? 15 : 135; // 基本的X坐标
  339 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 40;
  340 +
  341 + // 创建SVG文本元素
  342 + const nodeLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  343 + nodeLabel.setAttribute('x', labelX);
  344 + nodeLabel.setAttribute('y', labelY); // 在节点下方留出一定空间
  345 + nodeLabel.setAttribute('text-anchor', 'middle'); // 文本居中对齐
  346 + nodeLabel.setAttribute('fill', '#aaa'); // 文本居中对齐
  347 + nodeLabel.setAttribute('alignment-baseline', 'hanging');
  348 + nodeLabel.textContent = node.label;
  349 +
  350 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  351 + const estimatedTextLength = node.label.length * 10; // 估算每个字符6像素宽
  352 +
  353 + // 确保文本不会超出卡片右边界
  354 + if (labelX + estimatedTextLength / 2 > 150) {
  355 + labelX = 150 - estimatedTextLength / 2;
  356 + nodeLabel.setAttribute('x', labelX);
  357 + }
  358 +
  359 + // 确保文本不会超出卡片左边界
  360 + if (labelX - estimatedTextLength / 2 < 0) {
  361 + labelX = estimatedTextLength / 2;
  362 + nodeLabel.setAttribute('x', labelX);
  363 + }
  364 +
  365 + group.appendChild(nodeLabel);
  366 +
  367 + }
  368 +
  369 + switch (node.slot) {
  370 + case 'input':
  371 + const foreignObject = document.createElementNS('http://www.w3.org/2000/svg',
  372 + 'foreignObject');
  373 + foreignObject.setAttribute('x', 0);
  374 + foreignObject.setAttribute('y', topBottomPadding + titleBarHeight + node.level *
  375 + nodeSpacing + 12);
  376 + foreignObject.setAttribute('width', 130); // 保持原始宽度
  377 + foreignObject.setAttribute('height', nodeSpacing - 24); // 保持原始高度,减去的24像素为上下内边距之和
  378 + const input = document.createElement('input');
  379 + input.type = 'text';
  380 + if (node.value == undefined) {
  381 + node.value = '';
  382 + }
  383 + input.value = node.value;
  384 + input.addEventListener('input', function() {
  385 + node.value = input.value;
  386 + });
  387 + // Set adjusted input styles
  388 + input.style.width = '110px';
  389 + input.style.height = '100%';
  390 + input.style.marginLeft = '20px';
  391 + input.style.borderRadius = '5px';
  392 + input.style.border = '1px solid white';
  393 + input.style.backgroundColor = '#222';
  394 + input.style.color = 'white';
  395 + input.style.fontSize = '1em';
  396 + input.style.padding = '0px'; // 可能需要调整或去除内边距以适应固定尺寸
  397 + input.style.boxSizing = 'border-box'; // 确保宽高包含内容、内边距和边框
  398 +
  399 + // Change border color on focus and blur
  400 + input.addEventListener('focus', () => {
  401 + input.style.outline = 'none'; // Remove default focus outline
  402 + input.style.borderColor =
  403 + 'white'; // Keep border color white on focus
  404 + });
  405 +
  406 + input.addEventListener('blur', () => {
  407 + input.style.borderColor =
  408 + 'white'; // Revert to white when not focused
  409 + });
  410 +
  411 + // 阻止事件冒泡
  412 + input.addEventListener('click', function(event) {
  413 + event.stopPropagation();
  414 + });
  415 +
  416 + input.addEventListener('mousedown', function(event) {
  417 + event.stopPropagation();
  418 + });
  419 +
  420 + input.addEventListener('touchstart', function(event) {
  421 + event.stopPropagation();
  422 + });
  423 +
  424 + foreignObject.appendChild(input);
  425 + group.appendChild(foreignObject);
  426 + break;
  427 + }
  428 +
  429 +
  430 +
  431 + });
  432 +
  433 + const deleteIcon = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  434 + deleteIcon.setAttribute('class', 'card-delete-icon');
  435 + deleteIcon.setAttribute('x', 125);
  436 + deleteIcon.setAttribute('y', 5); // 使其贴近标题栏的右上角
  437 + deleteIcon.setAttribute('width', 20);
  438 + deleteIcon.setAttribute('height', 20);
  439 + deleteIcon.setAttribute('fill', 'transparent');
  440 + deleteIcon.setAttribute('data-card-id', card.id);
  441 + deleteIcon.setAttribute('style', 'cursor: pointer;');
  442 + group.appendChild(deleteIcon);
  443 +
  444 + const delText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  445 + delText.setAttribute('x', 135);
  446 + delText.setAttribute('y', 20); // 调整位置以垂直居中
  447 + delText.setAttribute('text-anchor', 'middle');
  448 + delText.setAttribute('fill', 'white');
  449 + delText.setAttribute('font-size', '16px'); // 适当调整字体大小以适应图标
  450 + delText.setAttribute('pointer-events', 'none'); // 确保点击事件只触发于删除图标上
  451 + delText.textContent = '×';
  452 + group.appendChild(delText);
  453 +
  454 + cardsContainer.appendChild(group);
  455 + });
  456 +
  457 + attachNodeEventListeners();
  458 + }
  459 +
  460 +
  461 +
  462 + function drawLinks() {
  463 + const linksContainer = document.getElementById('linksContainer');
  464 + linksContainer.innerHTML = ''; // 清除现有的线条
  465 + // 清除旧的删除图标
  466 + document.querySelectorAll('.delete-icon').forEach(icon => icon.remove());
  467 +
  468 + links.forEach((link, index) => {
  469 + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  470 + //path.setAttribute('class', 'link');
  471 + path.setAttribute('stroke', link.target.color)
  472 + path.setAttribute('stroke-width', 5)
  473 + path.setAttribute('fill', 'none');
  474 +
  475 +
  476 + const isCallType = link.source.enumType === 'call';
  477 + if (isCallType) {
  478 + path.setAttribute('stroke-dasharray', '10');
  479 + path.setAttribute('stroke-dashoffset', '0');
  480 +
  481 + // Add animation element to the path for dashed lines
  482 + const animate = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
  483 + animate.setAttribute('attributeName', 'stroke-dashoffset');
  484 + animate.setAttribute('dur', '0.5s');
  485 + animate.setAttribute('repeatCount', 'indefinite');
  486 + animate.setAttribute('from', '20');
  487 + animate.setAttribute('to', '0');
  488 + path.appendChild(animate);
  489 + }
  490 +
  491 +
  492 + var dist;
  493 + // 使用动态计算的控制点距离来定义曲线,根据源点和终点的X坐标差异动态计算控制点的距离
  494 + if (link.source.type === 'out') {
  495 + if (link.source.x - link.target.x > 0) {
  496 + dist = 200; // 如果终点在源点的左侧,控制点距离更远
  497 + } else {
  498 + dist = Math.abs(link.target.x - link.source.x) * 0.3; // 否则,根据两点间的距离调整控制点距离
  499 + }
  500 + const d =
  501 + `M${link.source.x} ${link.source.y} C${link.source.x + dist} ${link.source.y} ${link.target.x - dist} ${link.target.y} ${link.target.x} ${link.target.y}`;
  502 + path.setAttribute('d', d);
  503 + linksContainer.appendChild(path);
  504 + } else {
  505 + if (link.target.x - link.source.x > 0) {
  506 + dist = 200; // 如果终点在源点的右侧,控制点距离更远
  507 + } else {
  508 + dist = Math.abs(link.target.x - link.source.x) * 0.3; // 否则,根据两点间的距离调整控制点距离
  509 + }
  510 + const d =
  511 + `M${link.source.x} ${link.source.y} C${link.source.x - dist} ${link.source.y} ${link.target.x + dist} ${link.target.y} ${link.target.x} ${link.target.y}`;
  512 + path.setAttribute('d', d);
  513 + linksContainer.appendChild(path);
  514 + }
  515 +
  516 +
  517 + // 计算中点
  518 + const midX = (link.source.x + link.target.x) / 2;
  519 + const midY = (link.source.y + link.target.y) / 2;
  520 +
  521 + // 绘制删除图标
  522 + const deleteIcon = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  523 + deleteIcon.setAttribute('class', 'delete-icon');
  524 + deleteIcon.setAttribute('cx', midX);
  525 + deleteIcon.setAttribute('cy', midY);
  526 + deleteIcon.setAttribute('style', "cursor: pointer;");
  527 + deleteIcon.setAttribute('r', 10);
  528 + deleteIcon.setAttribute('fill', 'red');
  529 + deleteIcon.setAttribute('data-link-level', index); // 用于标识该删除图标对应的线
  530 + linksContainer.appendChild(deleteIcon);
  531 +
  532 + // 可以选择添加一个×文本在圆圈中间
  533 + const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  534 + text.setAttribute('x', midX);
  535 + text.setAttribute('y', midY + 5); // 轻微调整以垂直居中
  536 + text.setAttribute('text-anchor', 'middle');
  537 + text.setAttribute('fill', 'white');
  538 + text.setAttribute('font-size', '15px');
  539 + text.setAttribute('pointer-events', 'none'); // 确保点击事件只触发于圆圈上
  540 + text.textContent = '×';
  541 + linksContainer.appendChild(text);
  542 +
  543 + });
  544 + }
  545 +
  546 + // 定义变量来追踪是否正在拖动以及拖动的起始位置
  547 + var isPanning = false;
  548 + var startPan = {
  549 + x: 0,
  550 + y: 0
  551 + };
  552 +
  553 + // 用于调整SVG视图窗口的变量
  554 + var currentPan = {
  555 + x: 0,
  556 + y: 0
  557 + };
  558 +
  559 + function attachEventListeners() {
  560 +
  561 + const svgContainer = document.getElementById('svgContainer');
  562 + document.querySelectorAll('.link').forEach(link => {
  563 + link.addEventListener('contextmenu', function(e) {
  564 + e.preventDefault(); // 阻止默认的右键菜单
  565 + const linkId = e.target.getAttribute('data-link-id'); // 确保你在绘制线条时添加了 data-link-id 属性
  566 + showContextMenu(e.clientX, e.clientY, linkId);
  567 + });
  568 + });
  569 + document.getElementById('svgContainer').addEventListener('click', function(e) {
  570 + if (e.target.classList.contains('delete-icon')) {
  571 + // 获取点击的删除图标对应的线的索引
  572 + const linkIndex = e.target.getAttribute('data-link-level');
  573 + // 从数组中移除该线
  574 + links.splice(linkIndex, 1);
  575 + // 重新绘制剩余的线和删除图标
  576 + drawLinks();
  577 + drawCards(); // 如果你的线条与卡片有关联,可能需要重新绘制卡片以更新视图
  578 + } else if (e.target.classList.contains('card-delete-icon')) {
  579 + // 获取点击的删除图标对应的卡片ID
  580 + const cardId = e.target.getAttribute('data-card-id');
  581 + // 从`cards`数组中移除对应的卡片
  582 + cards = cards.filter(card => card.id !== cardId);
  583 + // 同时移除所有与该卡片连接的线
  584 + links = links.filter(link => !(link.source.node.startsWith(cardId) || (link.target && link.target
  585 + .node.startsWith(cardId))));
  586 + // 重新绘制卡片和线
  587 + drawLinks();
  588 + drawCards();
  589 + } else {
  590 + var targetCardContainer = e.target.closest('.card-container');
  591 + if (targetCardContainer) {
  592 + const cardId = targetCardContainer.getAttribute('data-id');
  593 + // 将SVG元素移动到最后,使其在视觉上显示在最前面
  594 + targetCardContainer.parentNode.appendChild(targetCardContainer);
  595 +
  596 + // 更新cards数组,将点击的卡片移动到数组的末尾
  597 + const cardIndex = cards.findIndex(card => card.id === cardId);
  598 + if (cardIndex > -1) {
  599 + const card = cards.splice(cardIndex, 1)[0];
  600 + cards.push(card);
  601 + }
  602 +
  603 + // 这里不需要立即调用drawCards或drawLinks,
  604 + // 除非你需要根据cards数组的新顺序进行其他更新
  605 + }
  606 + }
  607 + });
  608 +
  609 + svgContainer.addEventListener('contextmenu', function(e) {
  610 + e.preventDefault(); // 阻止右键菜单
  611 + });
  612 +
  613 + svgContainer.addEventListener('mousedown', e => {
  614 +
  615 + // 检查是否是鼠标右键点击
  616 +
  617 + const target = e.target;
  618 + if (e.button === 2) {
  619 + isPanning = true;
  620 + startPan.x = e.clientX - currentPan.x;
  621 + startPan.y = e.clientY - currentPan.y;
  622 + } else if (target.classList.contains('card') || target.tagName === 'text') {
  623 + const cardContainer = target.closest('.card-container');
  624 + const cardId = cardContainer.getAttribute('data-id');
  625 + startDragCard(e, cardId);
  626 + }
  627 + });
  628 + document.addEventListener('mousemove', e => {
  629 + if (isPanning) {
  630 + // 正确计算新的视图窗口位置
  631 + currentPan.x = e.clientX - startPan.x;
  632 + currentPan.y = e.clientY - startPan.y;
  633 +
  634 + // 正确调整SVG的viewBox来实现拖动效果
  635 + // 这里需要更新的是开始拖动的点,而不是当前的点,因此我们反向更新
  636 + svgContainer.setAttribute('viewBox',
  637 + `${-currentPan.x} ${-currentPan.y} ${svgContainer.clientWidth} ${svgContainer.clientHeight}`
  638 + );
  639 + svgContainer.style.backgroundPosition = `${currentPan.x % 100}px ${currentPan.y % 100}px`;
  640 + } else if (isDragging) {
  641 + debugger
  642 + moveCard(e);
  643 + } else if (isLinking && currentLink) {
  644 + updateLink(e);
  645 + }
  646 + });
  647 +
  648 + document.addEventListener('mouseup', e => {
  649 + if (e.button === 2) {
  650 + console.log(currentPan);
  651 + isPanning = false;
  652 + } else if (isDragging) {
  653 + endDragCard();
  654 + } else if (isLinking) {
  655 + endDragLink(e);
  656 + }
  657 + });
  658 + }
  659 +
  660 + function startDragCard(e, cardId) {
  661 + isDragging = true;
  662 + const card = cards.find(c => c.id === cardId);
  663 + currentCard = card;
  664 +
  665 + const svgRect = svgContainer.getBoundingClientRect();
  666 + dragOffsetX = e.clientX - svgRect.left - card.x;
  667 + dragOffsetY = e.clientY - svgRect.top - card.y;
  668 + }
  669 +
  670 + function moveCard(e) {
  671 + const svgRect = svgContainer.getBoundingClientRect();
  672 + currentCard.x = e.clientX - svgRect.left - dragOffsetX;
  673 + currentCard.y = e.clientY - svgRect.top - dragOffsetY;
  674 +
  675 + // Update link positions associated with the currentCard
  676 + links.forEach(link => {
  677 + if (link.source.node.startsWith(currentCard.id)) {
  678 + // 根据节点ID更新链接的源位置
  679 + const nodeIndex = parseInt(link.source.node.split('-node')[1]) - 1;
  680 + const nodeConfig = currentCard.nodes[nodeIndex]; // 获取当前节点的配置
  681 + const nodeSpacing = 50; // 节点间隔,应与drawCards函数中使用的相同
  682 + const topBottomPadding = 20; // 顶部和底部的边距,应与drawCards函数中使用的相同
  683 + link.source.x = currentCard.x + (nodeConfig.type === "in" ? 0 : 150); // 根据节点类型调整x坐标
  684 + link.source.y = 30 + currentCard.y + topBottomPadding + (nodeConfig.level + 1) * nodeSpacing - (
  685 + nodeSpacing / 2); // 根据节点的index调整y坐标
  686 + }
  687 + if (link.target && link.target.node.startsWith(currentCard.id)) {
  688 + // 根据节点ID更新链接的目标位置
  689 + const nodeIndex = parseInt(link.target.node.split('-node')[1]) - 1;
  690 + const nodeConfig = currentCard.nodes[nodeIndex]; // 获取当前节点的配置
  691 + link.target.x = currentCard.x + (nodeConfig.type === "in" ? 0 : 150); // 根据节点类型调整x坐标
  692 + link.target.y = 30 + currentCard.y + 20 + (nodeConfig.level + 1) * 50 - (50 /
  693 + 2); // 根据节点的index调整y坐标
  694 + }
  695 + });
  696 +
  697 + drawLinks(); // Redraw links to reflect updated positions
  698 + drawCards(); // Redraw cards and nodes
  699 + }
  700 +
  701 +
  702 +
  703 + function endDragCard() {
  704 + isDragging = false;
  705 + }
  706 +
  707 + function getNodeCurrentConnections(nodeId) {
  708 + var count = 0;
  709 + links.forEach(link => {
  710 + if (link.source.node === nodeId || (link.target && link.target.node === nodeId)) {
  711 + count++;
  712 + }
  713 + });
  714 + return count;
  715 + }
  716 +
  717 + function startDragLink(e) {
  718 + e.stopPropagation(); // Prevent card drag
  719 +
  720 + const nodeId = e.target.getAttribute('data-node-id');
  721 + const cardId = e.target.getAttribute('data-card-id');
  722 + const card = cards.find(c => c.id === cardId);
  723 + const nodeElement = e.target;
  724 + const node = card.nodes.find(n => `${card.id}-node${card.nodes.indexOf(n) + 1}` === nodeId);
  725 +
  726 +
  727 + // 检查源节点是否允许发起新的连接
  728 + const currentConnections = getNodeCurrentConnections(nodeId);
  729 + if (node.multiConnected !== -1 && currentConnections >= node.multiConnected) {
  730 + console.log('此节点不允许更多的连接。');
  731 + return; // 不允许创建新的连接
  732 + }
  733 + isLinking = true;
  734 +
  735 + const svgRect = svgContainer.getBoundingClientRect();
  736 + const nodeX = e.clientX - svgRect.left;
  737 + const nodeY = e.clientY - svgRect.top;
  738 +
  739 + currentLink = {
  740 + source: {
  741 + node: nodeId,
  742 + x: nodeX,
  743 + y: nodeY,
  744 + color: nodeElement.getAttribute('fill'),
  745 + type: node.type,
  746 + enumType: node.enumType
  747 + },
  748 + target: null
  749 + };
  750 + }
  751 +
  752 + function updateLink(e) {
  753 + const svgRect = svgContainer.getBoundingClientRect();
  754 + currentLink.target = {
  755 + x: e.clientX - svgRect.left,
  756 + y: e.clientY - svgRect.top
  757 + };
  758 + drawCurrentLink();
  759 + }
  760 +
  761 + function endDragLink(e) {
  762 + isLinking = false;
  763 + const svgRect = svgContainer.getBoundingClientRect();
  764 + const x = e.clientX - svgRect.left;
  765 + const y = e.clientY - svgRect.top;
  766 +
  767 + // 默认情况下,假设目标节点就是e.target
  768 + var targetNode = e.target;
  769 +
  770 + // 检查e.target是否是我们期望的节点类型,如果不是,则尝试使用document.elementFromPoint
  771 + if (!targetNode.classList.contains('node')) {
  772 + e.target.style.display = 'none';
  773 + targetNode = document.elementFromPoint(e.clientX, e.clientY);
  774 + e.target.style.display = '';
  775 + }
  776 +
  777 + var validTargetFound = false;
  778 +
  779 + // 进行节点的有效性判断
  780 + if (targetNode && targetNode.classList.contains('node')) {
  781 + const sourceNodeId = currentLink.source.node;
  782 + const targetNodeId = targetNode.getAttribute('data-node-id');
  783 +
  784 + // 从节点ID分解出卡片ID和节点索引
  785 + const sourceNodeParts = sourceNodeId.split('-node');
  786 + const targetNodeParts = targetNodeId.split('-node');
  787 + const sourceCard = cards.find(card => card.id === sourceNodeParts[0]);
  788 + const targetCard = cards.find(card => card.id === targetNodeParts[0]);
  789 +
  790 + // 根据节点ID找到对应的节点对象
  791 + const sourceNodeIndex = parseInt(sourceNodeParts[1]) - 1;
  792 + const targetNodeIndex = parseInt(targetNodeParts[1]) - 1;
  793 + const sourceNode = sourceCard.nodes[sourceNodeIndex];
  794 + const targetNodeObj = targetCard.nodes[targetNodeIndex];
  795 +
  796 + // 检查目标节点是否允许接受新的连接
  797 + const targetCurrentConnections = getNodeCurrentConnections(targetNodeId);
  798 + if (targetNodeObj.multiConnected !== -1 && targetCurrentConnections >= targetNodeObj.multiConnected) {
  799 + console.log('目标节点不允许更多的连接。');
  800 + // 移除临时绘制的连接线
  801 + const tempLink = document.querySelector('.temp-link');
  802 + if (tempLink) {
  803 + tempLink.remove();
  804 + }
  805 + currentLink = null;
  806 + drawLinks();
  807 + return;
  808 + }
  809 + // 确保目标节点不是起始节点自身,避免自连接
  810 + if (currentLink.source.node !== targetNodeId && sourceNode.enumType === targetNodeObj.enumType) {
  811 + validTargetFound = true;
  812 + currentLink.source.enumType = sourceNode.enumType;
  813 + currentLink.source.x = currentLink.source.x - currentPan.x;
  814 + currentLink.source.y = currentLink.source.y - currentPan.y;
  815 + // 更新连接的目标信息,并保存该连接
  816 + links.push({
  817 + ...currentLink,
  818 + target: {
  819 + node: targetNodeId,
  820 + x: x - currentPan.x,
  821 + y: y - currentPan.y,
  822 + color: sourceNode.color,
  823 + enumType: sourceNode.enumType
  824 + }
  825 + });
  826 + }
  827 + } else {
  828 + const sourceNodeId = currentLink.source.node;
  829 + const sourceNodeParts = sourceNodeId.split('-node');
  830 + const sourceCard = cards.find(card => card.id === sourceNodeParts[0]);
  831 + const sourceNodeIndex = parseInt(sourceNodeParts[1]) - 1;
  832 + const sourceNode = sourceCard.nodes[sourceNodeIndex];
  833 + currentLink.source.enumType = sourceNode.enumType;
  834 + showCardCreationModal(e.clientX, e.clientY, currentLink.source);
  835 +
  836 + }
  837 +
  838 + const tempLink = document.querySelector('.temp-link');
  839 + if (tempLink) {
  840 + tempLink.remove();
  841 + }
  842 + currentLink = null;
  843 + drawLinks();
  844 + }
  845 +
  846 + // 更新drawCurrentLink函数,增加线宽
  847 + // 更新drawCurrentLink函数,增加线宽
  848 + function drawCurrentLink() {
  849 + const tempLink = document.querySelector('.temp-link');
  850 + if (tempLink) tempLink.remove();
  851 +
  852 + if (!currentLink || !currentLink.target) return;
  853 +
  854 + const svgContainer = document.getElementById('svgContainer');
  855 + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  856 + path.setAttribute('class', 'temp-link');
  857 + // 设置等宽线属性
  858 + path.setAttribute('stroke', currentLink.source.color);
  859 + path.setAttribute('stroke-width', 5);
  860 + path.setAttribute('fill', 'none');
  861 +
  862 + // 计算考虑了平移偏移的起点和终点
  863 + const adjustedSourceX = currentLink.source.x - currentPan.x;
  864 + const adjustedSourceY = currentLink.source.y - currentPan.y;
  865 + const adjustedTargetX = currentLink.target.x - currentPan.x;
  866 + const adjustedTargetY = currentLink.target.y - currentPan.y;
  867 +
  868 + // 更新路径以使用调整后的坐标
  869 + if (currentLink.source.type === 'out') {
  870 + const d =
  871 + `M${adjustedSourceX},${adjustedSourceY} C${adjustedSourceX + 100},${adjustedSourceY} ${adjustedTargetX - 100},${adjustedTargetY} ${adjustedTargetX},${adjustedTargetY}`;
  872 + path.setAttribute('d', d);
  873 + } else {
  874 + const d =
  875 + `M${adjustedSourceX},${adjustedSourceY} C${adjustedSourceX - 100},${adjustedSourceY} ${adjustedTargetX + 100},${adjustedTargetY} ${adjustedTargetX},${adjustedTargetY}`;
  876 + path.setAttribute('d', d);
  877 + }
  878 +
  879 + svgContainer.appendChild(path);
  880 + }
  881 +
  882 + function attachNodeEventListeners() {
  883 + document.querySelectorAll('.node').forEach(node => {
  884 + node.addEventListener('mousedown', startDragLink);
  885 + });
  886 + }
  887 +
  888 + function populateCardTypeList(mouseX, mouseY, sourceNode) {
  889 + const listElement = document.getElementById('card-type-list');
  890 + listElement.innerHTML = ''; // 清空现有列表项
  891 + const addedTypes = new Set();
  892 + //节点列表
  893 + cardsbei.forEach(card => {
  894 + if (!addedTypes.has(card.type)) {
  895 + const listItem = document.createElement('li');
  896 + listItem.tabIndex = 0; // 使元素能够获得焦点,以便能够监听键盘事件
  897 + listItem.textContent = card.label; // 使用卡片的标签或类型
  898 + listItem.onclick = function() {
  899 + createNewCard(card, mouseX, mouseY, sourceNode);
  900 + hideCardCreationModal(); // 新建卡片后隐藏模态框
  901 + };
  902 + listItem.onkeydown = function(event) {
  903 + if (event.key === 'Enter') {
  904 + createNewCard(card, mouseX, mouseY, sourceNode);
  905 + hideCardCreationModal(); // 新建卡片后隐藏模态框
  906 + }
  907 + };
  908 + listElement.appendChild(listItem);
  909 + addedTypes.add(card.type);
  910 + }
  911 + });
  912 + }
  913 +
  914 +
  915 + function showCardCreationModal(mouseX, mouseY, sourceNode) {
  916 + populateCardTypeList(mouseX, mouseY, sourceNode); // 填充卡片类型列表
  917 + const modal = document.getElementById('card-creation-modal');
  918 + // 在这里添加取消按钮
  919 + if (!document.getElementById('cancel-btn')) {
  920 + const cancelButton = document.createElement('button');
  921 + cancelButton.id = 'cancel-btn';
  922 + cancelButton.textContent = '取消';
  923 + cancelButton.onclick = function() {
  924 + hideCardCreationModal();
  925 + };
  926 + modal.appendChild(cancelButton);
  927 + }
  928 +
  929 +
  930 +
  931 + // 设置弹出框的位置
  932 + modal.style.left = mouseX + 'px';
  933 + modal.style.top = mouseY + 'px';
  934 + modal.style.display = 'block'; // 显示弹窗
  935 + }
  936 +
  937 + function createNewCard(cardTemplate, mouseX, mouseY, sourceNode) {
  938 + debugger
  939 + var carrdid = [];
  940 + cards.forEach(card => {
  941 + carrdid.push(card.id.replace('card',''));
  942 + })
  943 +
  944 + const newCard = {
  945 + ...cardTemplate,
  946 + nodes: JSON.parse(JSON.stringify(cardTemplate.nodes)), // 深拷贝nodes属性
  947 + id: 'card' + (Math.max.apply(null, carrdid) + 1)
  948 + };
  949 + // 将每个node的value设置为空字符串
  950 + newCard.nodes.forEach(node => {
  951 + node.value = '';
  952 + });
  953 + newCard.x = mouseX - 75 - currentPan.x; // 调整为鼠标中心
  954 + newCard.y = mouseY - 15 - currentPan.y; // 调整为鼠标中心
  955 + cards.push(newCard); // 将新创建的卡片添加到卡片列表中
  956 +
  957 + // 如果提供了sourceNode,找到新卡片的合适target node并创建连接
  958 + if (sourceNode) {
  959 + sourceNode.x -= currentPan.x;
  960 + sourceNode.y -= currentPan.y;
  961 + var targetNode = newCard.nodes.find(node => node.enumType === sourceNode.enumType && node.type === 'in');
  962 + if (targetNode) {
  963 + links.push({
  964 + source: sourceNode,
  965 + target: {
  966 + node: `${newCard.id}-node${newCard.nodes.indexOf(targetNode) + 1}`,
  967 + x: newCard.x + (targetNode.type === 'in' ? 0 : 150),
  968 + y: newCard.y + 30 + 20 + (targetNode.level + 1) * 50 - 25,
  969 + color: targetNode.color,
  970 + enumType: targetNode.enumType
  971 + }
  972 + });
  973 + }
  974 + }
  975 +
  976 +
  977 + drawLinks();
  978 + drawCards();
  979 + }
  980 +
  981 +
  982 +
  983 + function hideCardCreationModal() {
  984 + const modal = document.getElementById('card-creation-modal');
  985 + modal.style.display = 'none'; // 隐藏弹窗
  986 + }
  987 +
  988 + init();
  989 +
  990 + $("#saves").on('click', function() {
  991 + var s = cards;
  992 + var type = $('#destroySelect').val();
  993 + var datas = {
  994 + type : type,
  995 + data: JSON.stringify(cards),
  996 + links : JSON.stringify(links)
  997 + }
  998 +
  999 + $.ajax('/zndya/addMap', {
  1000 + method: 'POST',
  1001 + data: JSON.stringify(datas),
  1002 + contentType: 'application/json',
  1003 + success: function (result) {
  1004 + if(result.status != null) {
  1005 + // 弹出添加成功提示消息
  1006 + layer.msg('添加成功...');
  1007 + } else {
  1008 + // 弹出添加失败提示消息
  1009 + layer.msg(result.ERROR);
  1010 + }
  1011 + }
  1012 + });
  1013 +
  1014 + });
  1015 +
  1016 +
  1017 +
  1018 +</script>
  1019 +<style>
  1020 + body,
  1021 + html {
  1022 + margin: 0;
  1023 + padding: 0;
  1024 + width: 100%;
  1025 + height: 100%;
  1026 + overflow: hidden;
  1027 + }
  1028 +
  1029 + /* 弹窗容器样式 */
  1030 + #card-creation-modal {
  1031 + border: 1px solid #444;
  1032 + background: linear-gradient(145deg, #333, #555);
  1033 + padding: 5px;
  1034 + z-index: 100;
  1035 + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  1036 + border-radius: 5px;
  1037 + overflow: hidden;
  1038 + margin: 0;
  1039 + user-select: none;
  1040 + }
  1041 +
  1042 + #card-type-list {
  1043 +
  1044 + padding-left: 0px;
  1045 + }
  1046 +
  1047 + /* 列表项基础样式 */
  1048 + #card-type-list li {
  1049 + list-style: none;
  1050 + /* 去除列表项目符号 */
  1051 + padding: 8px 15px;
  1052 + /* 减少垂直内边距使其更紧凑 */
  1053 + border-bottom: 1px solid #666;
  1054 + /* 暗色底部边框线 */
  1055 + color: #ddd;
  1056 + /* 暗色系字体颜色 */
  1057 + cursor: pointer;
  1058 + /* 鼠标指针样式 */
  1059 + margin-left: 0;
  1060 + /* 消除左边间隙 */
  1061 +
  1062 + }
  1063 +
  1064 + /* 列表项高亮样式 */
  1065 + #card-type-list li:hover,
  1066 + #card-type-list li:focus {
  1067 + background-color: #777;
  1068 + /* 暗色背景颜色 */
  1069 + color: #fff;
  1070 + /* 高亮字体颜色 */
  1071 + }
  1072 +
  1073 + /* 最后一个列表项的底部边框 */
  1074 + #card-type-list li:last-child {
  1075 + border-bottom: none;
  1076 + }
  1077 +
  1078 + .grid-background {
  1079 + background-color: #292929;
  1080 + background-image:
  1081 + linear-gradient(to right, black 1px, transparent 1px),
  1082 + linear-gradient(to bottom, black 1px, transparent 1px),
  1083 + linear-gradient(to right, #404040 1px, transparent 1px),
  1084 + linear-gradient(to bottom, #404040 1px, transparent 1px);
  1085 + background-size:
  1086 + 100px 100px,
  1087 + 100px 100px,
  1088 + 10px 10px,
  1089 + 10px 10px;
  1090 + width: 100%;
  1091 + height: 100%;
  1092 + }
  1093 +
  1094 + .draggable {
  1095 + cursor: grab;
  1096 + }
  1097 +
  1098 + .node {
  1099 +
  1100 + cursor: pointer;
  1101 + }
  1102 +
  1103 + .link {
  1104 + stroke: black;
  1105 + stroke-width: 2;
  1106 + }
  1107 +
  1108 + .card {
  1109 + /* fill: lightgrey;
  1110 + stroke: black; */
  1111 +
  1112 + stroke-width: 1;
  1113 + user-select: none;
  1114 + }
  1115 +
  1116 + text {
  1117 + pointer-events: none;
  1118 + user-select: none;
  1119 + }
  1120 +</style>
... ...
src/main/resources/static/pages/zndd_yuan/demo.html 0 → 100644
  1 +<!DOCTYPE html>
  2 +<html lang="zh-cn">
  3 +
  4 + <head>
  5 + <meta charset="UTF-8">
  6 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7 + <title>Blueprint</title>
  8 + <style>
  9 + body,
  10 + html {
  11 + margin: 0;
  12 + padding: 0;
  13 + width: 100%;
  14 + height: 100%;
  15 + overflow: hidden;
  16 + }
  17 +
  18 + /* 弹窗容器样式 */
  19 + #card-creation-modal {
  20 + border: 1px solid #444;
  21 + background: linear-gradient(145deg, #333, #555);
  22 + padding: 5px;
  23 + z-index: 100;
  24 + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  25 + border-radius: 5px;
  26 + overflow: hidden;
  27 + margin: 0;
  28 + user-select: none;
  29 + }
  30 +
  31 + #card-type-list {
  32 +
  33 + padding-left: 0px;
  34 + }
  35 +
  36 + /* 列表项基础样式 */
  37 + #card-type-list li {
  38 + list-style: none;
  39 + /* 去除列表项目符号 */
  40 + padding: 8px 15px;
  41 + /* 减少垂直内边距使其更紧凑 */
  42 + border-bottom: 1px solid #666;
  43 + /* 暗色底部边框线 */
  44 + color: #ddd;
  45 + /* 暗色系字体颜色 */
  46 + cursor: pointer;
  47 + /* 鼠标指针样式 */
  48 + margin-left: 0;
  49 + /* 消除左边间隙 */
  50 +
  51 + }
  52 +
  53 + /* 列表项高亮样式 */
  54 + #card-type-list li:hover,
  55 + #card-type-list li:focus {
  56 + background-color: #777;
  57 + /* 暗色背景颜色 */
  58 + color: #fff;
  59 + /* 高亮字体颜色 */
  60 + }
  61 +
  62 + /* 最后一个列表项的底部边框 */
  63 + #card-type-list li:last-child {
  64 + border-bottom: none;
  65 + }
  66 +
  67 + .grid-background {
  68 + background-color: #292929;
  69 + background-image:
  70 + linear-gradient(to right, black 1px, transparent 1px),
  71 + linear-gradient(to bottom, black 1px, transparent 1px),
  72 + linear-gradient(to right, #404040 1px, transparent 1px),
  73 + linear-gradient(to bottom, #404040 1px, transparent 1px);
  74 + background-size:
  75 + 100px 100px,
  76 + 100px 100px,
  77 + 10px 10px,
  78 + 10px 10px;
  79 + width: 100%;
  80 + height: 100%;
  81 + }
  82 +
  83 + .draggable {
  84 + cursor: grab;
  85 + }
  86 +
  87 + .node {
  88 +
  89 + cursor: pointer;
  90 + }
  91 +
  92 + .link {
  93 + stroke: black;
  94 + stroke-width: 2;
  95 + }
  96 +
  97 + .card {
  98 + /* fill: lightgrey;
  99 + stroke: black; */
  100 +
  101 + stroke-width: 1;
  102 + user-select: none;
  103 + }
  104 +
  105 + text {
  106 + pointer-events: none;
  107 + user-select: none;
  108 + }
  109 + </style>
  110 + </head>
  111 +
  112 + <body>
  113 + <!-- 弹窗容器 -->
  114 + <div id="card-creation-modal"
  115 + style="display:none; position: absolute; border: 1px solid #ccc; background-color: #fff; padding: 10px; z-index: 100;">
  116 + <!-- 搜索结果列表 -->
  117 + <ul id="card-type-list"></ul>
  118 + </div>
  119 +
  120 +
  121 +
  122 + <svg style="width: 100%;height: 100%;" id="svgContainer" class="grid-background">
  123 + <g id="linksContainer"></g> <!-- 用于存放线条 -->
  124 + <g id="cardsContainer"></g> <!-- 用于存放卡片 -->
  125 + </svg>
  126 +
  127 + <script>
  128 + var cards = [{
  129 + id: 'card0',
  130 + x: 0,
  131 + y: 0,
  132 + label: 'Start',
  133 + type: "start",
  134 + nodes: [{
  135 + type: "out",
  136 + level: 0,
  137 + enumType: 'call',
  138 + color: '#fff',
  139 + multiConnected: 1
  140 + }, ],
  141 + titleBarColor: ['#84fab0', '#8fd3f4']
  142 + },
  143 + {
  144 + id: 'card1',
  145 + x: 100,
  146 + y: 200,
  147 + label: 'Condition',
  148 + type: "condition",
  149 + nodes: [{
  150 + type: "in",
  151 + level: 0,
  152 + enumType: 'call',
  153 + color: '#fff'
  154 + },
  155 + {
  156 + type: "in",
  157 + level: 1,
  158 + enumType: 'int',
  159 + color: '#28C76F',
  160 + slot: 'input',
  161 + label: 'int',
  162 + multiConnected: 1
  163 + },
  164 + {
  165 + type: "in",
  166 + level: 2,
  167 + enumType: 'int',
  168 + color: '#28C76F',
  169 + slot: 'input',
  170 + label: 'int',
  171 + multiConnected: 1
  172 + },
  173 + {
  174 + type: "out",
  175 + level: 0,
  176 + enumType: 'call',
  177 + color: '#fff'
  178 + },
  179 + {
  180 + type: "out",
  181 + level: 1,
  182 + enumType: 'bool',
  183 + color: '#0396FF',
  184 + label: 'bool',
  185 + multiConnected: 1
  186 + },
  187 + ],
  188 + titleBarColor: ['#fccb90', '#d57eeb']
  189 + },
  190 + {
  191 + id: 'card2',
  192 + x: 300,
  193 + y: 400,
  194 + label: 'BoolToString',
  195 + type: "call",
  196 + nodes: [{
  197 + type: "in",
  198 + level: 0,
  199 + enumType: 'call',
  200 + color: '#fff'
  201 + },
  202 + {
  203 + type: "in",
  204 + level: 1,
  205 + enumType: 'bool',
  206 + color: '#0396FF',
  207 + label: 'bool',
  208 + multiConnected: 1
  209 + },
  210 + {
  211 + type: "out",
  212 + level: 0,
  213 + enumType: 'call',
  214 + color: '#fff'
  215 + },
  216 + {
  217 + type: "out",
  218 + level: 1,
  219 + enumType: 'string',
  220 + color: '#DE4313',
  221 + label: 'string',
  222 + multiConnected: 1
  223 + }
  224 + ],
  225 + titleBarColor: ['#3C8CE7', '#00EAFF']
  226 +
  227 + },
  228 + {
  229 + id: 'card3',
  230 + x: 100,
  231 + y: 300,
  232 + label: 'Print',
  233 + type: "print",
  234 + nodes: [{
  235 + type: "in",
  236 + level: 0,
  237 + enumType: 'call',
  238 + color: '#fff'
  239 + },
  240 + {
  241 + type: "in",
  242 + level: 1,
  243 + enumType: 'string',
  244 + color: '#DE4313',
  245 + label: 'string',
  246 + multiConnected: 1
  247 + }
  248 + ],
  249 + titleBarColor: ['#f6d365', '#fda085']
  250 + }
  251 + ];
  252 +
  253 +
  254 + var links = [];
  255 + var currentLink = null;
  256 + var isDragging = false;
  257 + var isLinking = false;
  258 + var dragOffsetX, dragOffsetY;
  259 + var currentCard;
  260 +
  261 + function init() {
  262 + drawLinks();
  263 + drawCards();
  264 + attachEventListeners();
  265 + }
  266 +
  267 + function drawCards() {
  268 + const cardsContainer = document.getElementById('cardsContainer');
  269 + cardsContainer.innerHTML = ''; // 清除现有的卡片
  270 +
  271 + cards.forEach(card => {
  272 +
  273 + //创建标题栏渐变色
  274 + const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
  275 + const linearGradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
  276 + linearGradient.setAttribute('id', `titleGradient-${card.id}`);
  277 + linearGradient.setAttribute('x1', '0%'); // 渐变起点的x坐标
  278 + linearGradient.setAttribute('y1', '100%'); // 渐变起点的y坐标
  279 + linearGradient.setAttribute('x2', '100%'); // 渐变终点的x坐标
  280 + linearGradient.setAttribute('y2', '0%'); // 渐变终点的y坐标
  281 +
  282 + const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  283 + stop1.setAttribute('offset', '10%');
  284 + stop1.setAttribute('style', `stop-color: ${card.titleBarColor[0]}; stop-opacity: 1`);
  285 + linearGradient.appendChild(stop1);
  286 +
  287 + const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
  288 + stop2.setAttribute('offset', '100%');
  289 + stop2.setAttribute('style', `stop-color: ${card.titleBarColor[1]}; stop-opacity: 1`);
  290 + linearGradient.appendChild(stop2);
  291 +
  292 + defs.appendChild(linearGradient);
  293 + cardsContainer.appendChild(defs);
  294 +
  295 +
  296 +
  297 + const nodeSpacing = 50;
  298 + const topBottomPadding = 20;
  299 + const titleBarHeight = 30; // 标题栏高度
  300 + const maxLevel = Math.max(...card.nodes.map(node => node.level)) + 1;
  301 + const cardHeight = maxLevel * nodeSpacing + topBottomPadding * 2 + titleBarHeight;
  302 +
  303 + const group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
  304 + group.setAttribute('class', 'draggable card-container');
  305 + group.setAttribute('data-id', card.id);
  306 + group.setAttribute('user-select', 'none');
  307 + group.setAttribute('transform', `translate(${card.x},${card.y})`);
  308 +
  309 + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  310 + rect.setAttribute('fill', '#222');
  311 + rect.setAttribute('width', 150);
  312 + rect.setAttribute('style', 'cursor: auto;');
  313 + rect.setAttribute('height', cardHeight);
  314 + rect.setAttribute('rx', 10); // 圆角
  315 + rect.setAttribute('ry', 10);
  316 + group.appendChild(rect);
  317 +
  318 + // 使用path绘制带有指定圆角的矩形
  319 + // 创建标题栏
  320 + const titleBarWidth = 150;
  321 + const borderRadius = 10; // 圆角大小
  322 + const titleBar = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  323 + const dValue = `M 0,${borderRadius}
  324 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},-${borderRadius}
  325 + h ${titleBarWidth - borderRadius * 2}
  326 + a ${borderRadius},${borderRadius} 0 0 1 ${borderRadius},${borderRadius}
  327 + v ${titleBarHeight - borderRadius}
  328 + h -${titleBarWidth}
  329 + z`;
  330 + titleBar.setAttribute('class', 'card');
  331 + titleBar.setAttribute('d', dValue);
  332 + titleBar.setAttribute('fill', `url(#titleGradient-${card.id})`);
  333 + group.appendChild(titleBar);
  334 +
  335 + const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  336 + text.setAttribute('x', titleBarWidth / 2);
  337 + text.setAttribute('y', titleBarHeight / 2);
  338 + text.setAttribute('text-anchor', 'middle');
  339 + text.setAttribute('alignment-baseline', 'middle');
  340 + text.textContent = card.label;
  341 + group.appendChild(text);
  342 +
  343 + card.nodes.forEach((node, index) => {
  344 +
  345 +
  346 + const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  347 + circle.setAttribute('class', 'node');
  348 + circle.setAttribute('cx', node.type === 'in' ? 0 : 150);
  349 + circle.setAttribute('cy', topBottomPadding + titleBarHeight + (node.level + 1) *
  350 + nodeSpacing - (nodeSpacing / 2));
  351 + circle.setAttribute('r', 7);
  352 + circle.setAttribute('fill', node.color);
  353 + circle.setAttribute('data-card-id', card.id);
  354 + circle.setAttribute('data-node-id', `${card.id}-node${index + 1}`);
  355 + group.appendChild(circle);
  356 +
  357 + var labelX = node.type === 'in' ? 12 : 138; // 基本的X坐标
  358 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 21;
  359 +
  360 + // 创建SVG文本元素
  361 + const multiConnectedLabel = document.createElementNS('http://www.w3.org/2000/svg',
  362 + 'text');
  363 + multiConnectedLabel.setAttribute('x', labelX);
  364 + multiConnectedLabel.setAttribute('y', labelY);
  365 + multiConnectedLabel.setAttribute('text-anchor', 'middle');
  366 + multiConnectedLabel.setAttribute('fill', '#aaa');
  367 + multiConnectedLabel.setAttribute('style', 'font-size: 8px;');
  368 + multiConnectedLabel.setAttribute('alignment-baseline', 'hanging');
  369 +
  370 +
  371 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  372 + var estimatedTextLength;
  373 + if (node.multiConnected == undefined) {
  374 + estimatedTextLength = 20
  375 + multiConnectedLabel.textContent = 'N';
  376 + } else {
  377 + estimatedTextLength = node.multiConnected.length;
  378 + multiConnectedLabel.textContent = node.multiConnected;
  379 + }
  380 +
  381 + // 确保文本不会超出卡片右边界
  382 + if (labelX + estimatedTextLength / 2 > 150) {
  383 + labelX = 150 - estimatedTextLength / 2;
  384 + nodeLabel.setAttribute('x', labelX);
  385 + }
  386 +
  387 + // 确保文本不会超出卡片左边界
  388 + if (labelX - estimatedTextLength / 2 < 0) {
  389 + labelX = estimatedTextLength / 2;
  390 + nodeLabel.setAttribute('x', labelX);
  391 + }
  392 +
  393 + group.appendChild(multiConnectedLabel);
  394 +
  395 + if (node.label != undefined) {
  396 + // 计算文本标签的位置
  397 + var labelX = node.type === 'in' ? 15 : 135; // 基本的X坐标
  398 + const labelY = topBottomPadding + titleBarHeight + node.level * nodeSpacing + 40;
  399 +
  400 + // 创建SVG文本元素
  401 + const nodeLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  402 + nodeLabel.setAttribute('x', labelX);
  403 + nodeLabel.setAttribute('y', labelY); // 在节点下方留出一定空间
  404 + nodeLabel.setAttribute('text-anchor', 'middle'); // 文本居中对齐
  405 + nodeLabel.setAttribute('fill', '#aaa'); // 文本居中对齐
  406 + nodeLabel.setAttribute('alignment-baseline', 'hanging');
  407 + nodeLabel.textContent = node.label;
  408 +
  409 + // 计算文本的宽度(假定的,因为SVG没有直接获取文本宽度的方法)
  410 + const estimatedTextLength = node.label.length * 10; // 估算每个字符6像素宽
  411 +
  412 + // 确保文本不会超出卡片右边界
  413 + if (labelX + estimatedTextLength / 2 > 150) {
  414 + labelX = 150 - estimatedTextLength / 2;
  415 + nodeLabel.setAttribute('x', labelX);
  416 + }
  417 +
  418 + // 确保文本不会超出卡片左边界
  419 + if (labelX - estimatedTextLength / 2 < 0) {
  420 + labelX = estimatedTextLength / 2;
  421 + nodeLabel.setAttribute('x', labelX);
  422 + }
  423 +
  424 + group.appendChild(nodeLabel);
  425 +
  426 + }
  427 +
  428 + switch (node.slot) {
  429 + case 'input':
  430 + const foreignObject = document.createElementNS('http://www.w3.org/2000/svg',
  431 + 'foreignObject');
  432 + foreignObject.setAttribute('x', 0);
  433 + foreignObject.setAttribute('y', topBottomPadding + titleBarHeight + node.level *
  434 + nodeSpacing + 12);
  435 + foreignObject.setAttribute('width', 130); // 保持原始宽度
  436 + foreignObject.setAttribute('height', nodeSpacing - 24); // 保持原始高度,减去的24像素为上下内边距之和
  437 + const input = document.createElement('input');
  438 + input.type = 'text';
  439 + if (node.value == undefined) {
  440 + node.value = '';
  441 + }
  442 + input.value = node.value;
  443 + input.addEventListener('input', function() {
  444 + node.value = input.value;
  445 + });
  446 + // Set adjusted input styles
  447 + input.style.width = '110px';
  448 + input.style.height = '100%';
  449 + input.style.marginLeft = '20px';
  450 + input.style.borderRadius = '5px';
  451 + input.style.border = '1px solid white';
  452 + input.style.backgroundColor = '#222';
  453 + input.style.color = 'white';
  454 + input.style.fontSize = '1em';
  455 + input.style.padding = '0px'; // 可能需要调整或去除内边距以适应固定尺寸
  456 + input.style.boxSizing = 'border-box'; // 确保宽高包含内容、内边距和边框
  457 +
  458 + // Change border color on focus and blur
  459 + input.addEventListener('focus', () => {
  460 + input.style.outline = 'none'; // Remove default focus outline
  461 + input.style.borderColor =
  462 + 'white'; // Keep border color white on focus
  463 + });
  464 +
  465 + input.addEventListener('blur', () => {
  466 + input.style.borderColor =
  467 + 'white'; // Revert to white when not focused
  468 + });
  469 +
  470 + // 阻止事件冒泡
  471 + input.addEventListener('click', function(event) {
  472 + event.stopPropagation();
  473 + });
  474 +
  475 + input.addEventListener('mousedown', function(event) {
  476 + event.stopPropagation();
  477 + });
  478 +
  479 + input.addEventListener('touchstart', function(event) {
  480 + event.stopPropagation();
  481 + });
  482 +
  483 + foreignObject.appendChild(input);
  484 + group.appendChild(foreignObject);
  485 + break;
  486 + }
  487 +
  488 +
  489 +
  490 + });
  491 +
  492 + const deleteIcon = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  493 + deleteIcon.setAttribute('class', 'card-delete-icon');
  494 + deleteIcon.setAttribute('x', 125);
  495 + deleteIcon.setAttribute('y', 5); // 使其贴近标题栏的右上角
  496 + deleteIcon.setAttribute('width', 20);
  497 + deleteIcon.setAttribute('height', 20);
  498 + deleteIcon.setAttribute('fill', 'transparent');
  499 + deleteIcon.setAttribute('data-card-id', card.id);
  500 + deleteIcon.setAttribute('style', 'cursor: pointer;');
  501 + group.appendChild(deleteIcon);
  502 +
  503 + const delText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  504 + delText.setAttribute('x', 135);
  505 + delText.setAttribute('y', 20); // 调整位置以垂直居中
  506 + delText.setAttribute('text-anchor', 'middle');
  507 + delText.setAttribute('fill', 'white');
  508 + delText.setAttribute('font-size', '16px'); // 适当调整字体大小以适应图标
  509 + delText.setAttribute('pointer-events', 'none'); // 确保点击事件只触发于删除图标上
  510 + delText.textContent = '×';
  511 + group.appendChild(delText);
  512 +
  513 + cardsContainer.appendChild(group);
  514 + });
  515 +
  516 + attachNodeEventListeners();
  517 + }
  518 +
  519 +
  520 +
  521 + function drawLinks() {
  522 + const linksContainer = document.getElementById('linksContainer');
  523 + linksContainer.innerHTML = ''; // 清除现有的线条
  524 + // 清除旧的删除图标
  525 + document.querySelectorAll('.delete-icon').forEach(icon => icon.remove());
  526 +
  527 + links.forEach((link, index) => {
  528 + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  529 + //path.setAttribute('class', 'link');
  530 + path.setAttribute('stroke', link.target.color)
  531 + path.setAttribute('stroke-width', 5)
  532 + path.setAttribute('fill', 'none');
  533 +
  534 +
  535 + const isCallType = link.source.enumType === 'call';
  536 + if (isCallType) {
  537 + path.setAttribute('stroke-dasharray', '10');
  538 + path.setAttribute('stroke-dashoffset', '0');
  539 +
  540 + // Add animation element to the path for dashed lines
  541 + const animate = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
  542 + animate.setAttribute('attributeName', 'stroke-dashoffset');
  543 + animate.setAttribute('dur', '0.5s');
  544 + animate.setAttribute('repeatCount', 'indefinite');
  545 + animate.setAttribute('from', '20');
  546 + animate.setAttribute('to', '0');
  547 + path.appendChild(animate);
  548 + }
  549 +
  550 +
  551 + var dist;
  552 + // 使用动态计算的控制点距离来定义曲线,根据源点和终点的X坐标差异动态计算控制点的距离
  553 + if (link.source.type === 'out') {
  554 + if (link.source.x - link.target.x > 0) {
  555 + dist = 200; // 如果终点在源点的左侧,控制点距离更远
  556 + } else {
  557 + dist = Math.abs(link.target.x - link.source.x) * 0.3; // 否则,根据两点间的距离调整控制点距离
  558 + }
  559 + const d =
  560 + `M${link.source.x} ${link.source.y} C${link.source.x + dist} ${link.source.y} ${link.target.x - dist} ${link.target.y} ${link.target.x} ${link.target.y}`;
  561 + path.setAttribute('d', d);
  562 + linksContainer.appendChild(path);
  563 + } else {
  564 + if (link.target.x - link.source.x > 0) {
  565 + dist = 200; // 如果终点在源点的右侧,控制点距离更远
  566 + } else {
  567 + dist = Math.abs(link.target.x - link.source.x) * 0.3; // 否则,根据两点间的距离调整控制点距离
  568 + }
  569 + const d =
  570 + `M${link.source.x} ${link.source.y} C${link.source.x - dist} ${link.source.y} ${link.target.x + dist} ${link.target.y} ${link.target.x} ${link.target.y}`;
  571 + path.setAttribute('d', d);
  572 + linksContainer.appendChild(path);
  573 + }
  574 +
  575 +
  576 + // 计算中点
  577 + const midX = (link.source.x + link.target.x) / 2;
  578 + const midY = (link.source.y + link.target.y) / 2;
  579 +
  580 + // 绘制删除图标
  581 + const deleteIcon = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  582 + deleteIcon.setAttribute('class', 'delete-icon');
  583 + deleteIcon.setAttribute('cx', midX);
  584 + deleteIcon.setAttribute('cy', midY);
  585 + deleteIcon.setAttribute('style', "cursor: pointer;");
  586 + deleteIcon.setAttribute('r', 10);
  587 + deleteIcon.setAttribute('fill', 'red');
  588 + deleteIcon.setAttribute('data-link-level', index); // 用于标识该删除图标对应的线
  589 + linksContainer.appendChild(deleteIcon);
  590 +
  591 + // 可以选择添加一个×文本在圆圈中间
  592 + const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
  593 + text.setAttribute('x', midX);
  594 + text.setAttribute('y', midY + 5); // 轻微调整以垂直居中
  595 + text.setAttribute('text-anchor', 'middle');
  596 + text.setAttribute('fill', 'white');
  597 + text.setAttribute('font-size', '15px');
  598 + text.setAttribute('pointer-events', 'none'); // 确保点击事件只触发于圆圈上
  599 + text.textContent = '×';
  600 + linksContainer.appendChild(text);
  601 +
  602 + });
  603 + }
  604 +
  605 + // 定义变量来追踪是否正在拖动以及拖动的起始位置
  606 + var isPanning = false;
  607 + var startPan = {
  608 + x: 0,
  609 + y: 0
  610 + };
  611 +
  612 + // 用于调整SVG视图窗口的变量
  613 + var currentPan = {
  614 + x: 0,
  615 + y: 0
  616 + };
  617 +
  618 + function attachEventListeners() {
  619 +
  620 + const svgContainer = document.getElementById('svgContainer');
  621 + document.querySelectorAll('.link').forEach(link => {
  622 + link.addEventListener('contextmenu', function(e) {
  623 + e.preventDefault(); // 阻止默认的右键菜单
  624 + const linkId = e.target.getAttribute('data-link-id'); // 确保你在绘制线条时添加了 data-link-id 属性
  625 + showContextMenu(e.clientX, e.clientY, linkId);
  626 + });
  627 + });
  628 + document.getElementById('svgContainer').addEventListener('click', function(e) {
  629 + if (e.target.classList.contains('delete-icon')) {
  630 + // 获取点击的删除图标对应的线的索引
  631 + const linkIndex = e.target.getAttribute('data-link-level');
  632 + // 从数组中移除该线
  633 + links.splice(linkIndex, 1);
  634 + // 重新绘制剩余的线和删除图标
  635 + drawLinks();
  636 + drawCards(); // 如果你的线条与卡片有关联,可能需要重新绘制卡片以更新视图
  637 + } else if (e.target.classList.contains('card-delete-icon')) {
  638 + // 获取点击的删除图标对应的卡片ID
  639 + const cardId = e.target.getAttribute('data-card-id');
  640 + // 从`cards`数组中移除对应的卡片
  641 + cards = cards.filter(card => card.id !== cardId);
  642 + // 同时移除所有与该卡片连接的线
  643 + links = links.filter(link => !(link.source.node.startsWith(cardId) || (link.target && link.target
  644 + .node.startsWith(cardId))));
  645 + // 重新绘制卡片和线
  646 + drawLinks();
  647 + drawCards();
  648 + } else {
  649 + var targetCardContainer = e.target.closest('.card-container');
  650 + if (targetCardContainer) {
  651 + const cardId = targetCardContainer.getAttribute('data-id');
  652 + // 将SVG元素移动到最后,使其在视觉上显示在最前面
  653 + targetCardContainer.parentNode.appendChild(targetCardContainer);
  654 +
  655 + // 更新cards数组,将点击的卡片移动到数组的末尾
  656 + const cardIndex = cards.findIndex(card => card.id === cardId);
  657 + if (cardIndex > -1) {
  658 + const card = cards.splice(cardIndex, 1)[0];
  659 + cards.push(card);
  660 + }
  661 +
  662 + // 这里不需要立即调用drawCards或drawLinks,
  663 + // 除非你需要根据cards数组的新顺序进行其他更新
  664 + }
  665 + }
  666 + });
  667 +
  668 + svgContainer.addEventListener('contextmenu', function(e) {
  669 + e.preventDefault(); // 阻止右键菜单
  670 + });
  671 +
  672 + svgContainer.addEventListener('mousedown', e => {
  673 +
  674 + // 检查是否是鼠标右键点击
  675 +
  676 + const target = e.target;
  677 + if (e.button === 2) {
  678 + isPanning = true;
  679 + startPan.x = e.clientX - currentPan.x;
  680 + startPan.y = e.clientY - currentPan.y;
  681 + } else if (target
  682 +
  683 + .classList.contains('card') || target.tagName === 'text') {
  684 + const cardContainer = target.closest('.card-container');
  685 + const cardId = cardContainer.getAttribute('data-id');
  686 + startDragCard(e, cardId);
  687 + }
  688 + });
  689 + document.addEventListener('mousemove', e => {
  690 + if (isPanning) {
  691 + // 正确计算新的视图窗口位置
  692 + currentPan.x = e.clientX - startPan.x;
  693 + currentPan.y = e.clientY - startPan.y;
  694 +
  695 + // 正确调整SVG的viewBox来实现拖动效果
  696 + // 这里需要更新的是开始拖动的点,而不是当前的点,因此我们反向更新
  697 + svgContainer.setAttribute('viewBox',
  698 + `${-currentPan.x} ${-currentPan.y} ${svgContainer.clientWidth} ${svgContainer.clientHeight}`
  699 + );
  700 + svgContainer.style.backgroundPosition = `${currentPan.x % 100}px ${currentPan.y % 100}px`;
  701 + } else if (isDragging) {
  702 + moveCard(e);
  703 + } else if (isLinking && currentLink) {
  704 + updateLink(e);
  705 + }
  706 + });
  707 +
  708 + document.addEventListener('mouseup', e => {
  709 + if (e.button === 2) {
  710 + console.log(currentPan);
  711 + isPanning = false;
  712 + } else if (isDragging) {
  713 + endDragCard();
  714 + } else if (isLinking) {
  715 + endDragLink(e);
  716 + }
  717 + });
  718 + }
  719 +
  720 + function startDragCard(e, cardId) {
  721 + isDragging = true;
  722 + const card = cards.find(c => c.id === cardId);
  723 + currentCard = card;
  724 +
  725 + const svgRect = svgContainer.getBoundingClientRect();
  726 + dragOffsetX = e.clientX - svgRect.left - card.x;
  727 + dragOffsetY = e.clientY - svgRect.top - card.y;
  728 + }
  729 +
  730 + function moveCard(e) {
  731 + const svgRect = svgContainer.getBoundingClientRect();
  732 + currentCard.x = e.clientX - svgRect.left - dragOffsetX;
  733 + currentCard.y = e.clientY - svgRect.top - dragOffsetY;
  734 +
  735 + // Update link positions associated with the currentCard
  736 + links.forEach(link => {
  737 + if (link.source.node.startsWith(currentCard.id)) {
  738 + // 根据节点ID更新链接的源位置
  739 + const nodeIndex = parseInt(link.source.node.split('-node')[1]) - 1;
  740 + const nodeConfig = currentCard.nodes[nodeIndex]; // 获取当前节点的配置
  741 + const nodeSpacing = 50; // 节点间隔,应与drawCards函数中使用的相同
  742 + const topBottomPadding = 20; // 顶部和底部的边距,应与drawCards函数中使用的相同
  743 + link.source.x = currentCard.x + (nodeConfig.type === "in" ? 0 : 150); // 根据节点类型调整x坐标
  744 + link.source.y = 30 + currentCard.y + topBottomPadding + (nodeConfig.level + 1) * nodeSpacing - (
  745 + nodeSpacing / 2); // 根据节点的index调整y坐标
  746 + }
  747 + if (link.target && link.target.node.startsWith(currentCard.id)) {
  748 + // 根据节点ID更新链接的目标位置
  749 + const nodeIndex = parseInt(link.target.node.split('-node')[1]) - 1;
  750 + const nodeConfig = currentCard.nodes[nodeIndex]; // 获取当前节点的配置
  751 + link.target.x = currentCard.x + (nodeConfig.type === "in" ? 0 : 150); // 根据节点类型调整x坐标
  752 + link.target.y = 30 + currentCard.y + 20 + (nodeConfig.level + 1) * 50 - (50 /
  753 + 2); // 根据节点的index调整y坐标
  754 + }
  755 + });
  756 +
  757 + drawLinks(); // Redraw links to reflect updated positions
  758 + drawCards(); // Redraw cards and nodes
  759 + }
  760 +
  761 +
  762 +
  763 + function endDragCard() {
  764 + isDragging = false;
  765 + }
  766 +
  767 + function getNodeCurrentConnections(nodeId) {
  768 + var count = 0;
  769 + links.forEach(link => {
  770 + if (link.source.node === nodeId || (link.target && link.target.node === nodeId)) {
  771 + count++;
  772 + }
  773 + });
  774 + return count;
  775 + }
  776 +
  777 + function startDragLink(e) {
  778 + e.stopPropagation(); // Prevent card drag
  779 +
  780 + const nodeId = e.target.getAttribute('data-node-id');
  781 + const cardId = e.target.getAttribute('data-card-id');
  782 + const card = cards.find(c => c.id === cardId);
  783 + const nodeElement = e.target;
  784 + const node = card.nodes.find(n => `${card.id}-node${card.nodes.indexOf(n) + 1}` === nodeId);
  785 +
  786 +
  787 + // 检查源节点是否允许发起新的连接
  788 + const currentConnections = getNodeCurrentConnections(nodeId);
  789 + if (node.multiConnected !== -1 && currentConnections >= node.multiConnected) {
  790 + console.log('此节点不允许更多的连接。');
  791 + return; // 不允许创建新的连接
  792 + }
  793 + isLinking = true;
  794 +
  795 + const svgRect = svgContainer.getBoundingClientRect();
  796 + const nodeX = e.clientX - svgRect.left;
  797 + const nodeY = e.clientY - svgRect.top;
  798 +
  799 + currentLink = {
  800 + source: {
  801 + node: nodeId,
  802 + x: nodeX,
  803 + y: nodeY,
  804 + color: nodeElement.getAttribute('fill'),
  805 + type: node.type,
  806 + enumType: node.enumType
  807 + },
  808 + target: null
  809 + };
  810 + }
  811 +
  812 + function updateLink(e) {
  813 + const svgRect = svgContainer.getBoundingClientRect();
  814 + currentLink.target = {
  815 + x: e.clientX - svgRect.left,
  816 + y: e.clientY - svgRect.top
  817 + };
  818 + drawCurrentLink();
  819 + }
  820 +
  821 + function endDragLink(e) {
  822 + isLinking = false;
  823 + const svgRect = svgContainer.getBoundingClientRect();
  824 + const x = e.clientX - svgRect.left;
  825 + const y = e.clientY - svgRect.top;
  826 +
  827 + // 默认情况下,假设目标节点就是e.target
  828 + var targetNode = e.target;
  829 +
  830 + // 检查e.target是否是我们期望的节点类型,如果不是,则尝试使用document.elementFromPoint
  831 + if (!targetNode.classList.contains('node')) {
  832 + e.target.style.display = 'none';
  833 + targetNode = document.elementFromPoint(e.clientX, e.clientY);
  834 + e.target.style.display = '';
  835 + }
  836 +
  837 + var validTargetFound = false;
  838 +
  839 + // 进行节点的有效性判断
  840 + if (targetNode && targetNode.classList.contains('node')) {
  841 + const sourceNodeId = currentLink.source.node;
  842 + const targetNodeId = targetNode.getAttribute('data-node-id');
  843 +
  844 + // 从节点ID分解出卡片ID和节点索引
  845 + const sourceNodeParts = sourceNodeId.split('-node');
  846 + const targetNodeParts = targetNodeId.split('-node');
  847 + const sourceCard = cards.find(card => card.id === sourceNodeParts[0]);
  848 + const targetCard = cards.find(card => card.id === targetNodeParts[0]);
  849 +
  850 + // 根据节点ID找到对应的节点对象
  851 + const sourceNodeIndex = parseInt(sourceNodeParts[1]) - 1;
  852 + const targetNodeIndex = parseInt(targetNodeParts[1]) - 1;
  853 + const sourceNode = sourceCard.nodes[sourceNodeIndex];
  854 + const targetNodeObj = targetCard.nodes[targetNodeIndex];
  855 +
  856 + // 检查目标节点是否允许接受新的连接
  857 + const targetCurrentConnections = getNodeCurrentConnections(targetNodeId);
  858 + if (targetNodeObj.multiConnected !== -1 && targetCurrentConnections >= targetNodeObj.multiConnected) {
  859 + console.log('目标节点不允许更多的连接。');
  860 + // 移除临时绘制的连接线
  861 + const tempLink = document.querySelector('.temp-link');
  862 + if (tempLink) {
  863 + tempLink.remove();
  864 + }
  865 + currentLink = null;
  866 + drawLinks();
  867 + return;
  868 + }
  869 + // 确保目标节点不是起始节点自身,避免自连接
  870 + if (currentLink.source.node !== targetNodeId && sourceNode.enumType === targetNodeObj.enumType) {
  871 + validTargetFound = true;
  872 + currentLink.source.enumType = sourceNode.enumType;
  873 + currentLink.source.x = currentLink.source.x - currentPan.x;
  874 + currentLink.source.y = currentLink.source.y - currentPan.y;
  875 + // 更新连接的目标信息,并保存该连接
  876 + links.push({
  877 + ...currentLink,
  878 + target: {
  879 + node: targetNodeId,
  880 + x: x - currentPan.x,
  881 + y: y - currentPan.y,
  882 + color: sourceNode.color,
  883 + enumType: sourceNode.enumType
  884 + }
  885 + });
  886 + }
  887 + } else {
  888 + const sourceNodeId = currentLink.source.node;
  889 + const sourceNodeParts = sourceNodeId.split('-node');
  890 + const sourceCard = cards.find(card => card.id === sourceNodeParts[0]);
  891 + const sourceNodeIndex = parseInt(sourceNodeParts[1]) - 1;
  892 + const sourceNode = sourceCard.nodes[sourceNodeIndex];
  893 + currentLink.source.enumType = sourceNode.enumType;
  894 + showCardCreationModal(e.clientX, e.clientY, currentLink.source);
  895 +
  896 + }
  897 +
  898 + const tempLink = document.querySelector('.temp-link');
  899 + if (tempLink) {
  900 + tempLink.remove();
  901 + }
  902 + currentLink = null;
  903 + drawLinks();
  904 + }
  905 +
  906 +
  907 +
  908 +
  909 +
  910 +
  911 + // 更新drawCurrentLink函数,增加线宽
  912 + // 更新drawCurrentLink函数,增加线宽
  913 + function drawCurrentLink() {
  914 + const tempLink = document.querySelector('.temp-link');
  915 + if (tempLink) tempLink.remove();
  916 +
  917 + if (!currentLink || !currentLink.target) return;
  918 +
  919 + const svgContainer = document.getElementById('svgContainer');
  920 + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  921 + path.setAttribute('class', 'temp-link');
  922 + // 设置等宽线属性
  923 + path.setAttribute('stroke', currentLink.source.color);
  924 + path.setAttribute('stroke-width', 5);
  925 + path.setAttribute('fill', 'none');
  926 +
  927 + // 计算考虑了平移偏移的起点和终点
  928 + const adjustedSourceX = currentLink.source.x - currentPan.x;
  929 + const adjustedSourceY = currentLink.source.y - currentPan.y;
  930 + const adjustedTargetX = currentLink.target.x - currentPan.x;
  931 + const adjustedTargetY = currentLink.target.y - currentPan.y;
  932 +
  933 + // 更新路径以使用调整后的坐标
  934 + if (currentLink.source.type === 'out') {
  935 + const d =
  936 + `M${adjustedSourceX},${adjustedSourceY} C${adjustedSourceX + 100},${adjustedSourceY} ${adjustedTargetX - 100},${adjustedTargetY} ${adjustedTargetX},${adjustedTargetY}`;
  937 + path.setAttribute('d', d);
  938 + } else {
  939 + const d =
  940 + `M${adjustedSourceX},${adjustedSourceY} C${adjustedSourceX - 100},${adjustedSourceY} ${adjustedTargetX + 100},${adjustedTargetY} ${adjustedTargetX},${adjustedTargetY}`;
  941 + path.setAttribute('d', d);
  942 + }
  943 +
  944 + svgContainer.appendChild(path);
  945 + }
  946 +
  947 + function attachNodeEventListeners() {
  948 + document.querySelectorAll('.node').forEach(node => {
  949 + node.addEventListener('mousedown', startDragLink);
  950 + });
  951 + }
  952 +
  953 + function populateCardTypeList(mouseX, mouseY, sourceNode) {
  954 + const listElement = document.getElementById('card-type-list');
  955 + listElement.innerHTML = ''; // 清空现有列表项
  956 + const addedTypes = new Set();
  957 +
  958 + cards.forEach(card => {
  959 + if (!addedTypes.has(card.type)) {
  960 + const listItem = document.createElement('li');
  961 + listItem.tabIndex = 0; // 使元素能够获得焦点,以便能够监听键盘事件
  962 + listItem.textContent = card.label; // 使用卡片的标签或类型
  963 + listItem.onclick = function() {
  964 + createNewCard(card, mouseX, mouseY, sourceNode);
  965 + hideCardCreationModal(); // 新建卡片后隐藏模态框
  966 + };
  967 + listItem.onkeydown = function(event) {
  968 + if (event.key === 'Enter') {
  969 + createNewCard(card, mouseX, mouseY, sourceNode);
  970 + hideCardCreationModal(); // 新建卡片后隐藏模态框
  971 + }
  972 + };
  973 + listElement.appendChild(listItem);
  974 + addedTypes.add(card.type);
  975 + }
  976 + });
  977 + }
  978 +
  979 +
  980 + function showCardCreationModal(mouseX, mouseY, sourceNode) {
  981 + populateCardTypeList(mouseX, mouseY, sourceNode); // 填充卡片类型列表
  982 + const modal = document.getElementById('card-creation-modal');
  983 + // 在这里添加取消按钮
  984 + if (!document.getElementById('cancel-btn')) {
  985 + const cancelButton = document.createElement('button');
  986 + cancelButton.id = 'cancel-btn';
  987 + cancelButton.textContent = '取消';
  988 + cancelButton.onclick = function() {
  989 + hideCardCreationModal();
  990 + };
  991 + modal.appendChild(cancelButton);
  992 + }
  993 +
  994 +
  995 +
  996 + // 设置弹出框的位置
  997 + modal.style.left = mouseX + 'px';
  998 + modal.style.top = mouseY + 'px';
  999 + modal.style.display = 'block'; // 显示弹窗
  1000 + }
  1001 +
  1002 + function createNewCard(cardTemplate, mouseX, mouseY, sourceNode) {
  1003 + const newCard = {
  1004 + ...cardTemplate,
  1005 + nodes: JSON.parse(JSON.stringify(cardTemplate.nodes)), // 深拷贝nodes属性
  1006 + id: 'card' + (cards.length + 1)
  1007 + };
  1008 + // 将每个node的value设置为空字符串
  1009 + newCard.nodes.forEach(node => {
  1010 + node.value = '';
  1011 + });
  1012 + newCard.x = mouseX - 75 - currentPan.x; // 调整为鼠标中心
  1013 + newCard.y = mouseY - 15 - currentPan.y; // 调整为鼠标中心
  1014 + cards.push(newCard); // 将新创建的卡片添加到卡片列表中
  1015 +
  1016 + // 如果提供了sourceNode,找到新卡片的合适target node并创建连接
  1017 + if (sourceNode) {
  1018 + sourceNode.x -= currentPan.x;
  1019 + sourceNode.y -= currentPan.y;
  1020 + var targetNode = newCard.nodes.find(node => node.enumType === sourceNode.enumType && node.type === 'in');
  1021 + if (targetNode) {
  1022 + links.push({
  1023 + source: sourceNode,
  1024 + target: {
  1025 + node: `${newCard.id}-node${newCard.nodes.indexOf(targetNode) + 1}`,
  1026 + x: newCard.x + (targetNode.type === 'in' ? 0 : 150),
  1027 + y: newCard.y + 30 + 20 + (targetNode.level + 1) * 50 - 25,
  1028 + color: targetNode.color,
  1029 + enumType: targetNode.enumType
  1030 + }
  1031 + });
  1032 + }
  1033 + }
  1034 +
  1035 +
  1036 + drawLinks();
  1037 + drawCards();
  1038 + }
  1039 +
  1040 +
  1041 +
  1042 + function hideCardCreationModal() {
  1043 + const modal = document.getElementById('card-creation-modal');
  1044 + modal.style.display = 'none'; // 隐藏弹窗
  1045 + }
  1046 +
  1047 + init();
  1048 + </script>
  1049 + </body>
  1050 +
  1051 +</html>
... ...
src/main/resources/static/real_control_v2/js/zndd/data_zndd.js
... ... @@ -17,31 +17,32 @@ var gb_dataZndd = (function (){
17 17 var timelist = [],interval;
18 18 var dataMap = new Map();
19 19 var leftTime = 1000 * 20;//剩余的毫秒数
20   - var timeType = false
21 20 var sop = function (data) {
22 21  
23 22 //时间格式化
24 23 data.types = codes[data.type];
25   - debugger
  24 +
26 25 if (data.type == 'YCSF' && ycsf_sx(data.lineCode) == false){
27 26 return
28 27 }
29   - if (data.type == 'SFTZ_1' && ycsf_sx(data.lineCode) == false){
  28 + if (data.type == 'SFTZ_1' && sf_tz(data.lineCode) == false){
30 29 return
31 30 }
32 31  
33 32  
  33 +
34 34 var stm = moment(new Date());
35 35 data.uuid = data.uuid + "uuid";//会出现纯数字 key取不到
36   -
  36 +
37 37 data.datarq = stm.format('HH时mm分ss秒');
38 38 dataMap.set(data.uuid,data);
  39 + if (data.type == 'DKL'){
  40 + configureDkl();
  41 + return;
  42 + }
39 43  
40   - //
41   -
42 44 configure();
43   -
44   -
  45 +
45 46 //配置 随到随发 配置div方案
46 47 function configure(){
47 48  
... ... @@ -64,8 +65,16 @@ var gb_dataZndd = (function (){
64 65  
65 66 //gb_tts.audition(msg, 1.2); //语音播报
66 67 }
67   -
68   -
  68 +
  69 + function configureDkl(){
  70 + var htmlStr = template('zndd_plat_msg_template_dkl', data);
  71 + var items = $pop.find('.multi_plat_msg_zndd'), len = items.length;
  72 + if (len >= max)
  73 + return
  74 +
  75 + $pop.append(htmlStr);
  76 + }
  77 +
69 78 };
70 79  
71 80 var close = true; //关闭弹出框的时候不弹出
... ... @@ -73,17 +82,31 @@ var gb_dataZndd = (function (){
73 82 $(this).parent().parent().remove();
74 83 if (close) close = false
75 84 });
76   - $pop.on('click', '.multi_plat_config .msg-times', function () {
  85 +
  86 +
  87 + var closetwo = true; //关闭弹出框的时候不弹出
  88 + $pop.on('click', '.multi_plat_msg_zndd .msg-times', function () {
77 89 $(this).parent().parent().remove();
78   - if (close) close = false
  90 + if (closetwo) closetwo = false
79 91 });
80 92  
81 93  
82 94 //1078路,1135路,南临专线,临港4路,浦东111路,浦东74路,临港13路,申港3路,浦东29路,新芦专线
83 95 function ycsf_sx(line){
84 96 var t =['12101','200828','230308','220826','201012','10636','60033','88814','88818','180926','191221','210821','230311','230329','803111'];
85   - debugger
86   - for (let lines in t){
  97 +
  98 + for (var lines in t){
  99 + if(line == t[lines])
  100 + return true;
  101 + }
  102 + return false;
  103 + }
  104 +
  105 + //1078路,1135路,南临专线,临港4路,浦东111路,浦东74路,临港13路,申港3路,浦东29路,新芦专线
  106 + function sf_tz(line){
  107 + var t =['80301'];
  108 +
  109 + for (var lines in t){
87 110 if(line == t[lines])
88 111 return true;
89 112 }
... ... @@ -153,6 +176,33 @@ var gb_dataZndd = (function (){
153 176 data: sch
154 177 }, {center: true, bgclose: false, modal: true});
155 178 });
  179 +
  180 +
  181 +
  182 +
  183 + //临加班次
  184 + $pop.on('click', '.multi_plat_msg_zndd', function () {
  185 +
  186 + if (!closetwo) {closetwo = true;return;}
  187 + var that = $(this);
  188 + var data = returnDate(that);
  189 + var sch = dataMap.get(that.data('uuid'));
  190 + var typeindex = typesx(data.type);
  191 + if (typeindex == null)
  192 + return;
  193 +
  194 + for(var i = 0;i < timelist.length; i++) {
  195 + if (timelist[i].ele == that.data('uuid')){
  196 + timelist.splice(i--, 1);
  197 + }
  198 + };
  199 +
  200 + folder = '/real_control_v2/zndd/type';
  201 + open_modal(folder + '/'+typeindex, {
  202 + data: sch
  203 + }, {center: true, bgclose: false, modal: true});
  204 + });
  205 +
156 206  
157 207  
158 208 function typesx(type){
... ... @@ -166,10 +216,8 @@ var gb_dataZndd = (function (){
166 216 case 'DJG':
167 217 return 'djg1.html';
168 218 break;
169   - case 'MZ':
170   - return 'mz.html';
171   - break;
172 219 case 'DKL':
  220 + return 'dkl.html';
173 221 break;
174 222 case 'FCJG':
175 223 return 'fcjg.html';
... ... @@ -257,7 +305,7 @@ var gb_dataZndd = (function (){
257 305  
258 306 //定时器自动提交
259 307 function TimeChick(ele){
260   - debugger
  308 +
261 309 var thisall= $("#"+ele).parent();
262 310 var sch = dataMap.get(thisall.data('uuid'));
263 311 if (thisall.length == 0) return;
... ... @@ -285,7 +333,7 @@ var gb_dataZndd = (function (){
285 333 notify_succ('撤销实发操作成功!');
286 334 });
287 335 } else if (type == "SFTZ_1"){
288   - debugger
  336 +
289 337 gb_common.$post('/realSchedule/realOutAdjust_zndd', {
290 338 id: sch.sch.id,
291 339 remarks:'自动调度实发未发-车辆掉线',
... ...
src/main/resources/static/real_control_v2/main.html
... ... @@ -300,23 +300,16 @@
300 300 <!--<div id="timer"></div>-->
301 301 </div>
302 302  
303   -<script id="zndd_plat_msg_template" type="text/html">
304   - <div class="multi_plat_msg_zndd" >
305   - <span class="title">{{lineName}} ----</span>
306   - <span class="title">{{datarq}} ----</span>
307   - <span class="title">{{types}}</span>
308   - <select id="selc" class="form-control">
309   - <option value="X1">添加临加正常班次</option>
310   - <option value="X2">添加临加区间班次</option>
311   - <option value="X3">添加临加直放班次</option>
312   - <option value="X4">添加临加放站班次</option>
313   - </select>
314   - <form class="form-horizontal" role="form" id="excelFile" method="post"
315   - action="" enctype="multipart/form-data"></form>
316   -
317   - <button id="submit" data-linecode="{{lineCode}}" data-statione="{{station}}" data-numtype="{{numType}}"
318   - data-xlname="{{lineName}}" data-xldir="{{xlDir}}" data-rqstr="{{rqStr}}"
319   - data-rq="{{rq}}" data-stationname="{{stationName}}">确定执行</button>
  303 +<script id="zndd_plat_msg_template_dkl" type="text/html">
  304 + <div class="multi_plat_msg_zndd" data-linecode="{{lineCode}}" data-type="{{type}}" data-station="{{station}}" data-stationname="{{stationName}}" data-uuid="{{uuid}}">
  305 + <div class="msg-popup warning-color">
  306 + <div class="msg-times" style="cursor: pointer;">×</div>
  307 + <span class="title">{{lineName}} ----</span>
  308 + <span class="title">{{datarq}} ----</span>
  309 + <span class="title">{{types}}</span>
  310 + <div> 点击查看预案</div>
  311 +
  312 + </div>
320 313 </div>
321 314  
322 315  
... ...
src/main/resources/static/real_control_v2/zndd/type/djg1.html 0 → 100644
  1 +<div class="uk-modal ct-form-modal ct_move_modal" id="schedule-addsch-modal">
  2 + <div class="uk-modal-dialog" style="width: 1400px;">
  3 + <a href="" class="uk-modal-close uk-close"></a>
  4 + <div class="uk-modal-header">
  5 + <h2>新增临加班次</h2></div>
  6 + <div class="uk-grid uk-width-2-5" style="float: left">
  7 + <div class="uk-width-5-5">
  8 + <form class="uk-form uk-form-horizontal"> </form>
  9 + <div>
  10 +
  11 +
  12 + </div>
  13 + </div>
  14 + </div>
  15 + <div class="uk-grid uk-width-3-5 lj_1" >
  16 + <div class="uk-width-1-4">
  17 + <ul data-uk-switcher="{connect:'#tempScheduleContent'}" class="uk-nav uk-nav-side left_tabs_lg">
  18 + <li data-handle="toAndFro"><a>1、往返</a></li>
  19 + <li data-handle="normal"><a>2、临加班次</a></li>
  20 + <!-- <li data-handle="parkToPark"><a>3、场到场</a></li>-->
  21 + </ul>
  22 + </div>
  23 + <div class="uk-width-3-4">
  24 + <ul id="tempScheduleContent" class="uk-switcher">
  25 + <li class="toAndFroCont"></li>
  26 + <li class="normalCont"></li>
  27 + <li class="parkToParkCont"></li>
  28 + </ul>
  29 + </div>
  30 + </div>
  31 +
  32 + <div class="uk-grid uk-width-3-5 lj_2" style="display: none; padding-left: 100px">
  33 + <div class="uk-width-1-1" id ="tempsdsf"></div>
  34 +
  35 + </div>
  36 +
  37 + </div>
  38 +
  39 + <script>
  40 + (function () {
  41 + var modal = '#schedule-addsch-modal',
  42 + sch, stationRoutes, parks, information, carsArray, st_park_data,conf;
  43 +
  44 + $(modal).on('init', function (e, data) {
  45 + e.stopPropagation();
  46 + sch = data.data;
  47 + sch.xlBm = sch.lineCode;
  48 +
  49 + var formHtml = template('djg-form-temp', sch);
  50 + $('form', modal).html(formHtml);
  51 + //切换
  52 +
  53 +
  54 +
  55 +
  56 +
  57 + //参数改变
  58 + $('form[name=yjtkForm] input', modal).on('blur', function () {
  59 + var field = $(this).attr('name');
  60 + var val = $(this).val();
  61 + if (conf[field] != val) {
  62 + var data = $('form[name=yjtkForm]', modal).serializeJSON();
  63 + data.lineCode = conf.line.lineCode;
  64 + gb_common.$post('/lineConfig/yjtkSet', data, function (rs) {
  65 + conf = rs.conf;
  66 + notify_succ('调整随到随发参数');
  67 + });
  68 + }
  69 + });
  70 +
  71 +
  72 + $("#destroySelect").on('change',function(){
  73 + let fn = $('#destroySelect').val();
  74 + if (fn == "0"){
  75 + $(".lj_1").css({
  76 + display: ''
  77 + });
  78 + $(".lj_2").css({
  79 + display: 'none'
  80 + });
  81 + }else {
  82 + $(".lj_1").css({
  83 + display: 'none'
  84 + });
  85 + $(".lj_2").css({
  86 + display: ''
  87 + });
  88 + $.get('/lineConfig/getByLineCode', {lineCode: sch.lineCode}, function (datan) {
  89 + var formHtmls = template('buffer_config_form-temp1', datan);
  90 + conf = datan;
  91 + $('#tempsdsf', modal).html(formHtmls);
  92 + $('[name=enableYjtk]', modal).on('change', function () {
  93 + if($(this).val() == '1'){
  94 + enableYjtkForm();
  95 + }
  96 + else
  97 + disabledYjtkForm();
  98 + });
  99 + });
  100 + }
  101 + })
  102 + //站到场数据
  103 + st_park_data = gb_data_basic.get_stat_park_data()[sch.xlBm];
  104 + //站点路由
  105 + stationRoutes = gb_common.groupBy(gb_data_basic.stationRoutes(sch.xlBm).sort(function (a, b) {
  106 + return a.stationRouteCode - b.stationRouteCode;
  107 + }), 'directions');
  108 + //停车场
  109 + parks = gb_data_basic.simpleParksArray();
  110 + //线路标准
  111 + information = gb_data_basic.getLineInformation(sch.xlBm);
  112 + //停车场排序,常用的放前面
  113 + parks = sort_parks(parks, information, st_park_data);
  114 + //车辆信息
  115 + carsArray = gb_data_basic.carsArray();
  116 +
  117 + var st_doms = gb_schedule_context_menu.get_add_sch_doms_v2();
  118 +
  119 +
  120 + $.post('/realSchedule/thissch/'+sch.id, function(res) {
  121 + //to and fro
  122 + $('.toAndFroCont', modal).html(st_doms.two_way_dom)
  123 + .trigger('init', {sch: res, submitFun: submit_temp_schedule_form, stationRoutes: stationRoutes});
  124 +
  125 + //normal
  126 + $('.normalCont', modal).html(st_doms.normal_dom)
  127 + .trigger('init', {sch: res, submitFun: submit_temp_schedule_form});
  128 + });
  129 +
  130 + });
  131 +
  132 + //init-autoCom
  133 + $(modal).on('init-autoCom', '.add-sch-form', function () {
  134 + //车辆
  135 + if(carsArray)
  136 + gb_common.carAutocomplete($('.car-autocom', this), carsArray);
  137 + //驾驶员
  138 + gb_common.personAutocomplete($('.jsy-autocom', this));
  139 + //售票员
  140 + gb_common.personAutocomplete($('.spy-autocom', this));
  141 + //备注补全
  142 + gb_common.remarksAutocomplete($('.remarks-autocom', this));
  143 + });
  144 +
  145 + //班次类型 和 上下行 切换事件
  146 + $(modal).on('change', '.add-sch-form [name=bcType],.add-sch-form [name=xlDir]', reCalcInputs_type);
  147 + //起终点站改变事件
  148 + $(modal).on('change', '[name=qdzCode],[name=zdzCode]', reCalcInputs_station);
  149 + //开始时间和公里改变
  150 + $(modal).on('input', '.add-sch-form [name=fcsj],.add-sch-form [name=jhlc]', reCalcEndTime);
  151 +
  152 +
  153 + function reCalcInputs_type() {
  154 + var f = $(this).parents('.add-sch-form');
  155 + var bcType_e = $('[name=bcType]', f)
  156 + , xlDir_e = $('[name=xlDir]', f);
  157 +
  158 + var routes = stationRoutes[xlDir_e.val()]
  159 + , lastCode = routes[routes.length - 1].stationCode
  160 + , opts = '', park_opts = '';
  161 + //station options
  162 + $.each(routes, function () {
  163 + opts += '<option value="' + this.stationCode + '">' + this.stationName + '</option>'
  164 + });
  165 + //park options
  166 + for(var i=0,p;p=parks[i++];)
  167 + park_opts += '<option value="' + p.code + '">' + p.name + '</option>';
  168 +
  169 + var qdz = $('[name=qdzCode]', f), zdz = $('[name=zdzCode]', f);
  170 + //var time, mileage;
  171 + switch (bcType_e.val()) {
  172 + case 'out':
  173 + qdz.html(park_opts).val(information.carPark);
  174 + zdz.html(opts);
  175 + break;
  176 + case 'in':
  177 + qdz.html(opts);
  178 + zdz.html(park_opts).val(information.carPark);
  179 + break;
  180 + default:
  181 + qdz.html(opts);
  182 + zdz.html(opts).val(lastCode);
  183 + }
  184 +
  185 + zdz.trigger('change');
  186 + f.trigger('ct_callback');
  187 + }
  188 +
  189 + function reCalcInputs_station() {
  190 + var f = $(this).parents('form'),
  191 + bcType = $('[name=bcType]', f).val(),
  192 + qdzCode = $('[name=qdzCode]', f).val(),
  193 + zdzCode =$('[name=zdzCode]', f).val(),
  194 + startDate = $('[name=fcsj]', f).val(),
  195 + upDown = $('[name=xlDir]', f).val(), mileage, time;
  196 +
  197 + //从站到场里获取数据
  198 + var stp = search_st_park(f);
  199 + if(stp){
  200 + mileage=bcType=='in'?stp['mileage1']:stp['mileage2'];
  201 + time=bcType=='in'?stp['time1']:stp['time2'];
  202 + }
  203 + else{
  204 + switch (upDown + '_' + bcType) {
  205 + case '0_out'://上行出场
  206 + mileage = information.upOutMileage;
  207 + time = information.upOutTimer;
  208 + break;
  209 + case '1_out'://下行出场
  210 + mileage = information.downOutMileage;
  211 + time = information.downOutTimer;
  212 + break;
  213 + case '0_in'://上行进场
  214 + mileage = information.upInMileage;
  215 + time = information.upInTimer;
  216 + break;
  217 + case '1_in'://下行进场
  218 + mileage = information.downInMileage;
  219 + time = information.downInTimer;
  220 + break;
  221 + default:
  222 +
  223 + var qc_time=upDown==0?information.upTravelTime:information.downTravelTime,
  224 + qc_mileage=upDown==0?information.upMileage:information.downMileage, _type;
  225 + if(is_normal_sch(f)){
  226 + _type='normal';
  227 + mileage=qc_mileage;
  228 + }
  229 + else{
  230 + _type='region';
  231 + mileage = calcMileage(stationRoutes[upDown], qdzCode, zdzCode);
  232 + }
  233 +
  234 + time = gb_common.mul(gb_common.accDiv(qc_time, qc_mileage), mileage);
  235 + if(bcType!='ldks' && bcType!='major' && bcType!='venting')
  236 + $('[name=bcType]', f).val(_type);
  237 + }
  238 + }
  239 +
  240 + $('[name=jhlc]', f).val(mileage);
  241 + var et = moment(startDate, 'HH:mm').add(time, 'minutes');
  242 + $f('zdsj', f).val(et.format('HH:mm'));
  243 + f.trigger('ct_callback');
  244 + }
  245 +
  246 +
  247 + function reCalcEndTime() {
  248 + var f = $(this).parents('.add-sch-form')
  249 + , startDate = $f('fcsj', f).val()//开始时间
  250 + , mileage = $f('jhlc', f).val()//公里
  251 + , type2 = $f('bcType', f).val(),//班次类型
  252 + upDown = $('[name=xlDir]', f).val();
  253 + if (!startDate || !mileage)
  254 + return;
  255 +
  256 + var time;
  257 + //从站到场里获取数据
  258 + var stp = search_st_park(f);
  259 + if(stp){
  260 + time=type2=='in'?stp['time1']:stp['time2'];
  261 + }
  262 + else{
  263 + if (type2 == 'in')
  264 + time = upDown == 0 ? information.upInTimer : information.downInTimer;
  265 + else if (type2 == 'out')
  266 + time = upDown == 0 ? information.upOutTimer : information.downOutTimer;
  267 + else{
  268 + var qc_time=upDown==0?information.upTravelTime:information.downTravelTime,
  269 + qc_mileage=upDown==0?information.upMileage:information.downMileage;
  270 +
  271 + time = gb_common.mul(gb_common.accDiv(qc_time, qc_mileage), mileage);
  272 + }
  273 + }
  274 +
  275 + var et = moment(startDate, 'HH:mm').add(time, 'minutes');
  276 + $f('zdsj', f).val(et.format('HH:mm'));
  277 + f.trigger('ct_callback');
  278 + }
  279 +
  280 + function is_normal_sch(f) {
  281 + var qdzCode = $('[name=qdzCode]', f).val(),
  282 + zdzCode =$('[name=zdzCode]', f).val(),
  283 + upDown = $('[name=xlDir]', f).val(),
  284 + rts = stationRoutes[upDown];
  285 +
  286 + if(rts[0].stationCode == qdzCode
  287 + && rts[rts.length - 1].stationCode == zdzCode)
  288 + return true;
  289 + else
  290 + return false;
  291 + }
  292 +
  293 + function isInOut(bcType) {
  294 + return bcType=='in' || bcType=='out';
  295 + }
  296 +
  297 + /**
  298 + * 计算线路上站点间公里
  299 + */
  300 + function calcMileage(rts, s, e) {
  301 + var mileage = 0, flag, code;
  302 + $.each(rts, function () {
  303 + code = this['stationCode'];
  304 + if (flag)
  305 + mileage = gb_common.accAdd(mileage, this.distances);
  306 + if (code == s)
  307 + flag = true;
  308 + if (code == e)
  309 + return false;
  310 + });
  311 + return mileage;
  312 + }
  313 +
  314 + function search_st_park(f) {
  315 + if(!st_park_data)
  316 + return;
  317 + var stp;
  318 + var qdSelect=$f('qdzCode', f)[0],zdSelect=$f('zdzCode', f)[0];
  319 +
  320 + if(qdSelect.options.selectedIndex < 0 || zdSelect.options.selectedIndex < 0)
  321 + return;
  322 + var qdzName=qdSelect.options[qdSelect.options.selectedIndex].text,
  323 + zdzName=zdSelect.options[zdSelect.options.selectedIndex].text,
  324 + type2 = $f('bcType', f).val();
  325 +
  326 + if(!isInOut(type2))
  327 + return;
  328 +
  329 + $.each(st_park_data, function () {
  330 + if((type2=='in' && this.stationName==qdzName && this.parkName==zdzName)
  331 + || (type2=='out' && this.stationName==zdzName && this.parkName==qdzName)){
  332 + stp = this;
  333 + return false;
  334 + }
  335 + });
  336 +
  337 + return stp;
  338 + }
  339 +
  340 + /**
  341 + * 停车场排序
  342 + * @param parks 停车场 code 2 name
  343 + * @param information 线路标准
  344 + * @param st_park_data 站到场
  345 + */
  346 + function sort_parks(parks, information, st_park_data) {
  347 + var array = [], names=[];
  348 + for(var code in parks){
  349 + array.push({code: code, name: parks[code]});
  350 + }
  351 +
  352 + if(st_park_data && st_park_data.length > 0){
  353 + $.each(st_park_data, function () {
  354 + names.push(this.parkName);
  355 + });
  356 + }
  357 +
  358 + //debugger
  359 + array.sort(function (a, b) {
  360 + if(a.code==information.carPark)
  361 + return -1;
  362 + if(b.code==information.carPark)
  363 + return 1;
  364 +
  365 + var ai = names.indexOf(a.name),
  366 + bi = names.indexOf(b.name);
  367 +
  368 + if(ai!=-1 && bi==-1)
  369 + return -1;
  370 + else if(ai==-1 && bi!=-1)
  371 + return 1;
  372 + else
  373 + return $.trim(a.name).localeCompare($.trim(b.name), 'zh-CN');
  374 + });
  375 + return array;
  376 + }
  377 +
  378 + function $f(name, f) {
  379 + return $('[name=' + name + ']', f);
  380 + }
  381 +
  382 + /**
  383 + * 提交表单
  384 + */
  385 + function submit_temp_schedule_form(data, cb, err) {
  386 + if (!data.lpName) {
  387 + notify_err('路牌信息缺失');
  388 + return;
  389 + }
  390 + data.xlBm = sch.xlBm;
  391 + data.xlName = sch.xlName;
  392 + //拆分驾驶员工号和姓名
  393 + data.jGh = data.jsy.split('/')[0];
  394 + data.jName = data.jsy.split('/')[1];
  395 + delete data.jsy;
  396 + //拆分售票员工号和姓名
  397 + if (data.spy != '') {
  398 + data.sGh = data.spy.split('/')[0];
  399 + data.sName = data.spy.split('/')[1];
  400 + delete data.spy;
  401 + }
  402 +
  403 + //公司信息
  404 + var line = gb_data_basic.findLineByCodes([data.xlBm]);
  405 + if(line && line.length > 0){
  406 + line = line[0];
  407 + data.xlName = line.name;
  408 + data.gsBm = line.company;
  409 + data.fgsBm = line.brancheCompany;
  410 + }
  411 +
  412 + gb_common.$post('/realSchedule', data, function (rs) {
  413 + notify_succ('新增临加班次成功');
  414 + cb && cb(rs);
  415 + }, err);
  416 + }
  417 +
  418 + function enableYjtkForm() {
  419 + var f = $('form[name=yjtkForm]', modal);
  420 + $('input', f).removeAttr('disabled');
  421 + //开始时间
  422 + if($('[name=yjtkStart]',f).val() == '')
  423 + $('[name=yjtkStart]',f).val('00:00');
  424 + if($('[name=yjtkEnd]',f).val() == '')
  425 + $('[name=yjtkEnd]',f).val('23:59');
  426 + var data = f.serializeJSON();
  427 + data.lineCode = conf.line.lineCode;
  428 + gb_common.$post('/lineConfig/yjtkSet', data, function (rs) {
  429 + conf = rs.conf;
  430 + notify_succ('启用随到随发');
  431 + });
  432 + }
  433 + function disabledYjtkForm() {
  434 + var f = $('form[name=yjtkForm]', modal);
  435 + $('input', f).attr('disabled', 'disabled');
  436 + //恢复val
  437 + $('[name=yjtkStart]',f).val(conf.yjtkStart);
  438 + $('[name=yjtkEnd]',f).val(conf.yjtkEnd);
  439 + $('[name=upStopMinute]',f).val(conf.upStopMinute);
  440 + $('[name=downStopMinute]',f).val(conf.downStopMinute);
  441 +
  442 + var data = {enableYjtk: 0, lineCode: conf.line.lineCode};
  443 + gb_common.$post('/lineConfig/yjtkSet', data, function (rs) {
  444 + conf = rs.conf;
  445 + notify_succ('禁用随到随发');
  446 + });
  447 + }
  448 +
  449 + })();
  450 + </script>
  451 +</div>
  452 +
  453 +<script id="djg-form-temp" type="text/html">
  454 + <input type="hidden" name="id" value=""/>
  455 +
  456 + <div class="uk-grid">
  457 + <div class="uk-width-4-2">
  458 + <div class="uk-form-row">
  459 + <h3>间隔情况</h3>
  460 + </div>
  461 + </div>
  462 + </div>
  463 + <div class="uk-grid">
  464 + <div class="uk-width-4-2">
  465 + <div class="uk-form-row">
  466 + <label class="uk-form-labels" >{{lineName}} -> 起点站开往终点站 出现大间隔</label>
  467 + </div>
  468 + </div>
  469 + </div>
  470 + <div>
  471 + <div class="uk-grid">
  472 + <div class="uk-width-1-2">
  473 + <div class="uk-form-row">
  474 + <label class="uk-form-label">当前车车号</label>
  475 + <div class="uk-form-controls">
  476 + <input value="{{lg.nbbm}}" disabled>
  477 + </div>
  478 + </div>
  479 + </div>
  480 + <div class="uk-width-1-2">
  481 + <div class="uk-form-row">
  482 + <label class="uk-form-label">前车车号</label>
  483 + <div class="uk-form-controls">
  484 + <input value="{{lg.beforeNbbm}}" disabled>
  485 + </div>
  486 + </div>
  487 + </div>
  488 + </div>
  489 + <div class="uk-grid">
  490 + <div class="uk-width-1-2">
  491 + <div class="uk-form-row">
  492 + <label class="uk-form-label">当前车站点</label>
  493 + <div class="uk-form-controls">
  494 + <input value="{{lg.stationName}}" disabled>
  495 + </div>
  496 + </div>
  497 + </div>
  498 + <div class="uk-width-1-2">
  499 + <div class="uk-form-row">
  500 + <label class="uk-form-label">前车站点</label>
  501 + <div class="uk-form-controls">
  502 + <input value="{{lg.beforeStationName}}" disabled>
  503 + </div>
  504 + </div>
  505 + </div>
  506 + </div>
  507 + <div class="uk-grid">
  508 + <div class="uk-width-1-2">
  509 + <div class="uk-form-row">
  510 + <label class="uk-form-label">当前车发车时间</label>
  511 + <div class="uk-form-controls">
  512 + <input value="{{lg.bcfcsj}}" disabled>
  513 + </div>
  514 + </div>
  515 + </div>
  516 + <div class="uk-width-1-2">
  517 + <div class="uk-form-row">
  518 + <label class="uk-form-label">前车发车时间</label>
  519 + <div class="uk-form-controls">
  520 + <input value="{{lg.beforeBcfcsj}}" disabled>
  521 + </div>
  522 + </div>
  523 + </div>
  524 + </div>
  525 + <div class="uk-grid">
  526 + <div class="uk-width-1-2">
  527 + <div class="uk-form-row">
  528 + <label class="uk-form-label">当前间隔分钟数</label>
  529 + <div class="uk-form-controls">
  530 + <input value="{{lg.intervalMinute}}" disabled>
  531 + </div>
  532 + </div>
  533 + </div>
  534 + <div class="uk-width-1-2">
  535 + <div class="uk-form-row">
  536 + <label class="uk-form-label">大间隔分钟数阀值</label>
  537 + <div class="uk-form-controls">
  538 + <input value="{{lg.largeGapConfigMinute}}" disabled>
  539 + </div>
  540 + </div>
  541 + </div>
  542 + </div>
  543 +
  544 +
  545 + <div class="uk-grid">
  546 + <div class="uk-width-2-2">
  547 + <div class="uk-form-row">
  548 + <label class="uk-form-label">选择方案</label>
  549 + <div class="uk-form-controls">
  550 + <select name="destroy" class="form-control" id="destroySelect">
  551 + <option value="0">-- 临加班次 --</option>
  552 + <option value="1">-- 随到随发 --</option>
  553 + </select>
  554 + </div>
  555 + </div>
  556 + </div>
  557 + </div>
  558 +
  559 + <div class="uk-grid">
  560 + <div class="uk-width-4-2">
  561 + <div class="uk-form-row">
  562 + <h3>方案优势</h3>
  563 + </div>
  564 + </div>
  565 + </div>
  566 +
  567 + <div class="uk-grid">
  568 + <div class="uk-width-1-2">
  569 + <div class="uk-form-row">
  570 + <label class="uk-form-label">间隔检测效率</label>
  571 + <div class="uk-form-controls">
  572 + <input value="50%" disabled>
  573 + </div>
  574 + </div>
  575 + </div>
  576 + <div class="uk-width-1-2">
  577 + <div class="uk-form-row">
  578 + <label class="uk-form-label">乘客满意度</label>
  579 + <div class="uk-form-controls">
  580 + <input value="10%" disabled>
  581 + </div>
  582 + </div>
  583 + </div>
  584 + </div>
  585 + </div>
  586 +</script>
  587 +
  588 +
  589 +<script id="buffer_config_form-temp1" type="text/html">
  590 + <div id="emergency_stop_panel">
  591 + <h3 class="btn_title_lines1">
  592 + <a class="uk-link-reset" >调整随到随发 </a>
  593 + </h3>
  594 + <div>
  595 + <form class="uk-form" name="yjtkForm">
  596 + <table>
  597 + <tr>
  598 + <td colspan="2">
  599 + 是否启用
  600 + <select class="z-depth-input" name="enableYjtk">
  601 + <option value="0" >禁用</option>
  602 + <option value="1" {{if enableYjtk}}selected{{/if}}>启用</option>
  603 + </select>
  604 + </td>
  605 + </tr>
  606 + <tr>
  607 + <td colspan="2">
  608 + 时间
  609 + <input type="time" value="{{yjtkStart}}" name="yjtkStart" {{if !enableYjtk}}disabled{{/if}}>至
  610 + <input type="time" value="{{yjtkEnd}}" name="yjtkEnd" {{if !enableYjtk}}disabled{{/if}}>
  611 + </td>
  612 + </tr>
  613 + <tr>
  614 + <td>
  615 + 上行停靠时间
  616 + <input type="number" value="{{upStopMinute}}" name="upStopMinute" {{if !enableYjtk}}disabled{{/if}}>分钟
  617 + </td>
  618 + </tr>
  619 + <tr>
  620 + <td>
  621 + 下行停靠时间
  622 + <input type="number" value="{{downStopMinute}}" name="downStopMinute" {{if !enableYjtk}}disabled{{/if}}>分钟
  623 + </td>
  624 + </tr>
  625 + </table>
  626 + </form>
  627 + </div>
  628 + </div>
  629 +</script>
  630 +<script>
  631 +
  632 +</script>
0 633 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/zndd/type/dkl.html 0 → 100644
  1 +<div class="uk-modal ct-form-modal ct_move_modal" id="schedule-addsch-modal">
  2 + <div class="uk-modal-dialog" style="width: 1400px;">
  3 + <a href="" class="uk-modal-close uk-close"></a>
  4 + <div class="uk-modal-header">
  5 + <h2>大客流</h2></div>
  6 + <div class="uk-grid uk-width-2-5" style="float: left">
  7 + <div class="uk-width-5-5">
  8 + <form class="uk-form uk-form-horizontal"> </form>
  9 + <div>
  10 +
  11 +
  12 + </div>
  13 + </div>
  14 + </div>
  15 + <div class="uk-grid uk-width-3-5 lj_1" >
  16 + <div class="uk-width-1-4">
  17 + <ul data-uk-switcher="{connect:'#tempScheduleContent'}" class="uk-nav uk-nav-side left_tabs_lg">
  18 + <li data-handle="toAndFro"><a>1、往返</a></li>
  19 + <li data-handle="normal"><a>2、临加班次</a></li>
  20 + <!-- <li data-handle="parkToPark"><a>3、场到场</a></li>-->
  21 + </ul>
  22 + </div>
  23 + <div class="uk-width-3-4">
  24 + <ul id="tempScheduleContent" class="uk-switcher">
  25 + <li class="toAndFroCont"></li>
  26 + <li class="normalCont"></li>
  27 + <li class="parkToParkCont"></li>
  28 + </ul>
  29 + </div>
  30 + </div>
  31 +
  32 + </div>
  33 +
  34 + <script>
  35 + (function () {
  36 + var modal = '#schedule-addsch-modal',
  37 + sch, stationRoutes, parks, information, carsArray, st_park_data,conf;
  38 +
  39 + $(modal).on('init', function (e, data) {
  40 + e.stopPropagation();
  41 + sch = data.data;
  42 + sch.xlBm = sch.lineCode;
  43 +
  44 + //站到场数据
  45 + st_park_data = gb_data_basic.get_stat_park_data()[sch.xlBm];
  46 + //站点路由
  47 + stationRoutes = gb_common.groupBy(gb_data_basic.stationRoutes(sch.xlBm).sort(function (a, b) {
  48 + return a.stationRouteCode - b.stationRouteCode;
  49 + }), 'directions');
  50 + let route = stationRoutes[sch.xlDir];
  51 + debugger
  52 + sch.startStation = route[0];
  53 + sch.stopStation = route[route.length - 1];
  54 + var formHtml = template('djg-form-temp', sch);
  55 + $('form', modal).html(formHtml);
  56 + //切换
  57 + $("#destroySelect").on('change',function(){
  58 + let fn = $('#destroySelect').val();
  59 + if (fn == "0"){
  60 + $('.video_1').css({display: ''});
  61 + $('.video_2').css({display: 'none'});
  62 +
  63 + }else {
  64 + $('.video_1').css({display: 'none'});
  65 + $('.video_2').css({display: ''});
  66 + }
  67 + })
  68 + $("#zhanOrche").on('change',function(){
  69 + let fn = $('#zhanOrche').val();
  70 + if (fn == "0"){
  71 + $('.car_s').css({display: 'none'});
  72 + $('.zt_s').css({display: ''});
  73 +
  74 + }else {
  75 + $('.car_s').css({display: ''});
  76 + $('.zt_s').css({display: 'none'});
  77 + }
  78 + })
  79 +
  80 +
  81 +
  82 + //停车场
  83 + parks = gb_data_basic.simpleParksArray();
  84 + //线路标准
  85 + information = gb_data_basic.getLineInformation(sch.xlBm);
  86 + //停车场排序,常用的放前面
  87 + parks = sort_parks(parks, information, st_park_data);
  88 + //车辆信息
  89 + carsArray = gb_data_basic.carsArray();
  90 +
  91 + var st_doms = gb_schedule_context_menu.get_add_sch_doms_v2();
  92 +
  93 + $.post('/realSchedule/thissch/'+sch.id, function(res) {
  94 + //to and fro
  95 + $('.toAndFroCont', modal).html(st_doms.two_way_dom)
  96 + .trigger('init', {sch: res, submitFun: submit_temp_schedule_form, stationRoutes: stationRoutes});
  97 +
  98 +
  99 + //normal
  100 + $('.normalCont', modal).html(st_doms.normal_dom)
  101 + .trigger('init', {sch: res, submitFun: submit_temp_schedule_form});
  102 + });
  103 +
  104 +
  105 +
  106 + });
  107 +
  108 + //init-autoCom
  109 + $(modal).on('init-autoCom', '.add-sch-form', function () {
  110 + //车辆
  111 + if(carsArray)
  112 + gb_common.carAutocomplete($('.car-autocom', this), carsArray);
  113 + //驾驶员
  114 + gb_common.personAutocomplete($('.jsy-autocom', this));
  115 + //售票员
  116 + gb_common.personAutocomplete($('.spy-autocom', this));
  117 + //备注补全
  118 + gb_common.remarksAutocomplete($('.remarks-autocom', this));
  119 + });
  120 +
  121 + //班次类型 和 上下行 切换事件
  122 + $(modal).on('change', '.add-sch-form [name=bcType],.add-sch-form [name=xlDir]', reCalcInputs_type);
  123 + //起终点站改变事件
  124 + $(modal).on('change', '[name=qdzCode],[name=zdzCode]', reCalcInputs_station);
  125 + //开始时间和公里改变
  126 + $(modal).on('input', '.add-sch-form [name=fcsj],.add-sch-form [name=jhlc]', reCalcEndTime);
  127 +
  128 +
  129 + function reCalcInputs_type() {
  130 + var f = $(this).parents('.add-sch-form');
  131 + var bcType_e = $('[name=bcType]', f)
  132 + , xlDir_e = $('[name=xlDir]', f);
  133 +
  134 + var routes = stationRoutes[xlDir_e.val()]
  135 + , lastCode = routes[routes.length - 1].stationCode
  136 + , opts = '', park_opts = '';
  137 + //station options
  138 + $.each(routes, function () {
  139 + opts += '<option value="' + this.stationCode + '">' + this.stationName + '</option>'
  140 + });
  141 + //park options
  142 + for(var i=0,p;p=parks[i++];)
  143 + park_opts += '<option value="' + p.code + '">' + p.name + '</option>';
  144 +
  145 + var qdz = $('[name=qdzCode]', f), zdz = $('[name=zdzCode]', f);
  146 + //var time, mileage;
  147 + switch (bcType_e.val()) {
  148 + case 'out':
  149 + qdz.html(park_opts).val(information.carPark);
  150 + zdz.html(opts);
  151 + break;
  152 + case 'in':
  153 + qdz.html(opts);
  154 + zdz.html(park_opts).val(information.carPark);
  155 + break;
  156 + default:
  157 + qdz.html(opts);
  158 + zdz.html(opts).val(lastCode);
  159 + }
  160 +
  161 + zdz.trigger('change');
  162 + f.trigger('ct_callback');
  163 + }
  164 +
  165 + function reCalcInputs_station() {
  166 + var f = $(this).parents('form'),
  167 + bcType = $('[name=bcType]', f).val(),
  168 + qdzCode = $('[name=qdzCode]', f).val(),
  169 + zdzCode =$('[name=zdzCode]', f).val(),
  170 + startDate = $('[name=fcsj]', f).val(),
  171 + upDown = $('[name=xlDir]', f).val(), mileage, time;
  172 +
  173 + //从站到场里获取数据
  174 + var stp = search_st_park(f);
  175 + if(stp){
  176 + mileage=bcType=='in'?stp['mileage1']:stp['mileage2'];
  177 + time=bcType=='in'?stp['time1']:stp['time2'];
  178 + }
  179 + else{
  180 + switch (upDown + '_' + bcType) {
  181 + case '0_out'://上行出场
  182 + mileage = information.upOutMileage;
  183 + time = information.upOutTimer;
  184 + break;
  185 + case '1_out'://下行出场
  186 + mileage = information.downOutMileage;
  187 + time = information.downOutTimer;
  188 + break;
  189 + case '0_in'://上行进场
  190 + mileage = information.upInMileage;
  191 + time = information.upInTimer;
  192 + break;
  193 + case '1_in'://下行进场
  194 + mileage = information.downInMileage;
  195 + time = information.downInTimer;
  196 + break;
  197 + default:
  198 +
  199 + var qc_time=upDown==0?information.upTravelTime:information.downTravelTime,
  200 + qc_mileage=upDown==0?information.upMileage:information.downMileage, _type;
  201 + if(is_normal_sch(f)){
  202 + _type='normal';
  203 + mileage=qc_mileage;
  204 + }
  205 + else{
  206 + _type='region';
  207 + mileage = calcMileage(stationRoutes[upDown], qdzCode, zdzCode);
  208 + }
  209 +
  210 + time = gb_common.mul(gb_common.accDiv(qc_time, qc_mileage), mileage);
  211 + if(bcType!='ldks' && bcType!='major' && bcType!='venting')
  212 + $('[name=bcType]', f).val(_type);
  213 + }
  214 + }
  215 +
  216 + $('[name=jhlc]', f).val(mileage);
  217 + var et = moment(startDate, 'HH:mm').add(time, 'minutes');
  218 + $f('zdsj', f).val(et.format('HH:mm'));
  219 + f.trigger('ct_callback');
  220 + }
  221 +
  222 +
  223 + function reCalcEndTime() {
  224 + var f = $(this).parents('.add-sch-form')
  225 + , startDate = $f('fcsj', f).val()//开始时间
  226 + , mileage = $f('jhlc', f).val()//公里
  227 + , type2 = $f('bcType', f).val(),//班次类型
  228 + upDown = $('[name=xlDir]', f).val();
  229 + if (!startDate || !mileage)
  230 + return;
  231 +
  232 + var time;
  233 + //从站到场里获取数据
  234 + var stp = search_st_park(f);
  235 + if(stp){
  236 + time=type2=='in'?stp['time1']:stp['time2'];
  237 + }
  238 + else{
  239 + if (type2 == 'in')
  240 + time = upDown == 0 ? information.upInTimer : information.downInTimer;
  241 + else if (type2 == 'out')
  242 + time = upDown == 0 ? information.upOutTimer : information.downOutTimer;
  243 + else{
  244 + var qc_time=upDown==0?information.upTravelTime:information.downTravelTime,
  245 + qc_mileage=upDown==0?information.upMileage:information.downMileage;
  246 +
  247 + time = gb_common.mul(gb_common.accDiv(qc_time, qc_mileage), mileage);
  248 + }
  249 + }
  250 +
  251 + var et = moment(startDate, 'HH:mm').add(time, 'minutes');
  252 + $f('zdsj', f).val(et.format('HH:mm'));
  253 + f.trigger('ct_callback');
  254 + }
  255 +
  256 + function is_normal_sch(f) {
  257 + var qdzCode = $('[name=qdzCode]', f).val(),
  258 + zdzCode =$('[name=zdzCode]', f).val(),
  259 + upDown = $('[name=xlDir]', f).val(),
  260 + rts = stationRoutes[upDown];
  261 +
  262 + if(rts[0].stationCode == qdzCode
  263 + && rts[rts.length - 1].stationCode == zdzCode)
  264 + return true;
  265 + else
  266 + return false;
  267 + }
  268 +
  269 + function isInOut(bcType) {
  270 + return bcType=='in' || bcType=='out';
  271 + }
  272 +
  273 + /**
  274 + * 计算线路上站点间公里
  275 + */
  276 + function calcMileage(rts, s, e) {
  277 + var mileage = 0, flag, code;
  278 + $.each(rts, function () {
  279 + code = this['stationCode'];
  280 + if (flag)
  281 + mileage = gb_common.accAdd(mileage, this.distances);
  282 + if (code == s)
  283 + flag = true;
  284 + if (code == e)
  285 + return false;
  286 + });
  287 + return mileage;
  288 + }
  289 +
  290 + function search_st_park(f) {
  291 + if(!st_park_data)
  292 + return;
  293 + var stp;
  294 + var qdSelect=$f('qdzCode', f)[0],zdSelect=$f('zdzCode', f)[0];
  295 +
  296 + if(qdSelect.options.selectedIndex < 0 || zdSelect.options.selectedIndex < 0)
  297 + return;
  298 + var qdzName=qdSelect.options[qdSelect.options.selectedIndex].text,
  299 + zdzName=zdSelect.options[zdSelect.options.selectedIndex].text,
  300 + type2 = $f('bcType', f).val();
  301 +
  302 + if(!isInOut(type2))
  303 + return;
  304 +
  305 + $.each(st_park_data, function () {
  306 + if((type2=='in' && this.stationName==qdzName && this.parkName==zdzName)
  307 + || (type2=='out' && this.stationName==zdzName && this.parkName==qdzName)){
  308 + stp = this;
  309 + return false;
  310 + }
  311 + });
  312 +
  313 + return stp;
  314 + }
  315 +
  316 + /**
  317 + * 停车场排序
  318 + * @param parks 停车场 code 2 name
  319 + * @param information 线路标准
  320 + * @param st_park_data 站到场
  321 + */
  322 + function sort_parks(parks, information, st_park_data) {
  323 + var array = [], names=[];
  324 + for(var code in parks){
  325 + array.push({code: code, name: parks[code]});
  326 + }
  327 +
  328 + if(st_park_data && st_park_data.length > 0){
  329 + $.each(st_park_data, function () {
  330 + names.push(this.parkName);
  331 + });
  332 + }
  333 +
  334 + //debugger
  335 + array.sort(function (a, b) {
  336 + if(a.code==information.carPark)
  337 + return -1;
  338 + if(b.code==information.carPark)
  339 + return 1;
  340 +
  341 + var ai = names.indexOf(a.name),
  342 + bi = names.indexOf(b.name);
  343 +
  344 + if(ai!=-1 && bi==-1)
  345 + return -1;
  346 + else if(ai==-1 && bi!=-1)
  347 + return 1;
  348 + else
  349 + return $.trim(a.name).localeCompare($.trim(b.name), 'zh-CN');
  350 + });
  351 + return array;
  352 + }
  353 +
  354 + function $f(name, f) {
  355 + return $('[name=' + name + ']', f);
  356 + }
  357 +
  358 + /**
  359 + * 提交表单
  360 + */
  361 + function submit_temp_schedule_form(data, cb, err) {
  362 + if (!data.lpName) {
  363 + notify_err('路牌信息缺失');
  364 + return;
  365 + }
  366 + data.xlBm = sch.xlBm;
  367 + data.xlName = sch.xlName;
  368 + //拆分驾驶员工号和姓名
  369 + data.jGh = data.jsy.split('/')[0];
  370 + data.jName = data.jsy.split('/')[1];
  371 + delete data.jsy;
  372 + //拆分售票员工号和姓名
  373 + if (data.spy != '') {
  374 + data.sGh = data.spy.split('/')[0];
  375 + data.sName = data.spy.split('/')[1];
  376 + delete data.spy;
  377 + }
  378 +
  379 + //公司信息
  380 + var line = gb_data_basic.findLineByCodes([data.xlBm]);
  381 + if(line && line.length > 0){
  382 + line = line[0];
  383 + data.xlName = line.name;
  384 + data.gsBm = line.company;
  385 + data.fgsBm = line.brancheCompany;
  386 + }
  387 +
  388 + gb_common.$post('/realSchedule', data, function (rs) {
  389 + notify_succ('新增临加班次成功');
  390 + cb && cb(rs);
  391 + }, err);
  392 + }
  393 +
  394 + })();
  395 + </script>
  396 +</div>
  397 +
  398 +<script id="djg-form-temp" type="text/html">
  399 + <input type="hidden" name="id" value=""/>
  400 +
  401 + <div class="uk-grid">
  402 + <div class="uk-width-4-2">
  403 + <div class="uk-form-row">
  404 + <h3>大客流信息</h3>
  405 + </div>
  406 + </div>
  407 + </div>
  408 + <div class="uk-grid">
  409 + <div class="uk-width-4-2">
  410 + <div class="uk-form-row">
  411 + <label class="uk-form-labels" >{{stopStation.stationName}}站点 出现大客流</label>
  412 + </div>
  413 + </div>
  414 +
  415 + </div>
  416 +
  417 + <div class="uk-grid">
  418 + <div class="uk-width-1-2">
  419 + <div class="uk-form-row">
  420 + <label class="uk-form-label">站点名称</label>
  421 + <div class="uk-form-controls">
  422 + <input type="time" value="XXXX" name="fcsj" disabled>
  423 + </div>
  424 + </div>
  425 + </div>
  426 + <div class="uk-width-1-2">
  427 + <div class="uk-form-row">
  428 + <label class="uk-form-label">站点人数</label>
  429 + <div class="uk-form-controls">
  430 + <input value="20" disabled>
  431 + </div>
  432 + </div>
  433 + </div>
  434 + </div>
  435 +
  436 + <div class="uk-grid">
  437 + <div class="uk-width-2-2">
  438 + <div class="uk-form-row">
  439 + <label class="uk-form-label">选择方案</label>
  440 + <div class="uk-form-controls">
  441 + <select name="destroy" class="form-control" id="destSelect">
  442 + <option value="0">-- 方案一 --</option>
  443 + </select>
  444 + </div>
  445 + </div>
  446 + </div>
  447 + </div>
  448 +
  449 +
  450 + <div class="uk-grid">
  451 + <div class="uk-width-2-2">
  452 + <div class="uk-form-row">
  453 + <label class="uk-form-label"></label>
  454 + <div class="uk-form-controls">
  455 + <select name="destroy" class="form-control" id="zhanOrche">
  456 + <option value="0">-- 站台 --</option>
  457 + <option value="1">-- 车辆 --</option>
  458 + </select>
  459 + </div>
  460 + </div>
  461 + </div>
  462 + </div>
  463 + <div class="uk-grid">
  464 + <div class="uk-width-1-2">
  465 + <div class="uk-form-row">
  466 + <label class="uk-form-label">车内人数</label>
  467 + <div class="uk-form-controls">
  468 + <input value="23" disabled>
  469 + </div>
  470 + </div>
  471 + </div>
  472 + <div class="uk-width-1-2">
  473 + <div class="uk-form-row">
  474 + <label class="uk-form-label">摄像</label>
  475 + <div class="uk-form-controls">
  476 + <select name="destroy" class="form-control" id="destroySelect">
  477 + <option value="0">-- 前车厢 --</option>
  478 + <option value="1">-- 后车厢 --</option>
  479 + </select>
  480 + </div>
  481 + </div>
  482 + </div>
  483 + </div>
  484 +
  485 + <div class="uk-grid zt_s">
  486 + <div class="uk-width-4-2">
  487 + <div class="uk-form-row img_1">
  488 + <img style="width: 100%" src="/profile/avat/2024/04/08/666.png" controls />
  489 +
  490 + </div>
  491 + </div>
  492 + </div>
  493 +
  494 +
  495 + <div class="uk-grid car_s" style="display:none">
  496 +
  497 + <div class="uk-width-1-1">
  498 + <div class="uk-form-row">
  499 + <label class="uk-form-label">车内视频:</label>
  500 + </div>
  501 + </div>
  502 + </div>
  503 + <div class="uk-grid car_s" style="display:none">
  504 + <div class="uk-width-4-2">
  505 + <div class="uk-form-row video_1">
  506 + <video id="myVideo" style="width: 100%" src="/real_control_v2/zndd/video/a.mp4" controls></video>
  507 + </div>
  508 + <div class="uk-form-row video_2" style="display: none">
  509 + <video id="myVideos" style="width: 100%" src="/real_control_v2/zndd/video/b.mp4" controls></video>
  510 + </div>
  511 + </div>
  512 + </div>
  513 +
  514 +
  515 +
  516 +</script>
  517 +<style>
  518 + .fanganys input{
  519 + text-align: center;
  520 + }
  521 +</style>
... ...