# 任务 - [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5) - [x] 联调:IBS 7.20.0 版本联调,HCDN业务标准化接入-典基平面接入与基础数据模型扩展。(张鹏豪 5) - [x] 开发:monitor 邮件问题,新增日志及 sendIllegalDomainEmail 测试接口。(张鹏豪 1) - [x] 测试:新增的参数“IsCreditControl”为非枚举值时,增加校验。(郑子雯 1) - [x] 测试:企业月流量中分发平面下拉框信息与实际分发平面信息不对等。(李英浩 0.5) # 日志 现在想要讨论一个新功能的方案,关于配置。也是代理工具主要的一个部分。 当前我有两个主要的功能模块: 1. 控制(这个模块填写的配置链接获取的必须是完整的配置包含节点信息的。) 2. 日志 首先节点的来源从一个 clash 订阅获取,这里我我希望实现类似于 Sub-Store 那种效果(此项目在 D:\MyCode\Study\Sub-Store 中,你可以翻看实现逻辑),这个功能点就是从一个 clash 顺利转换出各种协议的 sing-box 节点备用。 用户可以提供一个自己的预填模版(没有节点信息):类似: ``` { "inbounds": [ { "tag": "mixed-in", "type": "mixed", "listen": "127.0.0.1", "listen_port": 20122 }, { "tag": "tun-in", "type": "tun", "address": ["172.18.0.1/30"], "auto_route": true, "strict_route": true, "route_exclude_address": ["111.1.51.182/32", "112.17.28.117/32"], "stack": "mixed", "platform": { "http_proxy": { "enabled": true, "server": "127.0.0.1", "server_port": 20122 } } } ], "outbounds": [ { "tag": "默认", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "✈️ Telegram", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "▶️ YouTube", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "📺 Netflix", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "🌐 Google", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "🤖 AI", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "💭 X", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "♾️ Meta", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "🎬 TikTok", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益" ] }, { "tag": "💰 PayPal", "type": "selector", "interrupt_exist_connections": true, "outbounds": [ "默认", "🇺🇸 美国", "🇭🇰 香港", "🇹🇼 台湾", "🇸🇬 新加坡", "🇯🇵 日本", "公益", "直连" ] }, { "tag": "🇺🇸 美国", "type": "selector", "interrupt_exist_connections": true, "outbounds": ["🇺🇸 美国自动♻️"] }, { "tag": "🇭🇰 香港", "type": "selector", "interrupt_exist_connections": true, "outbounds": ["🇭🇰 香港自动♻️"] }, { "tag": "🇹🇼 台湾", "type": "selector", "interrupt_exist_connections": true, "outbounds": [] }, { "tag": "🇸🇬 新加坡", "type": "selector", "interrupt_exist_connections": true, "outbounds": [] }, { "tag": "🇯🇵 日本", "type": "selector", "interrupt_exist_connections": true, "outbounds": [] }, { "tag": "🇺🇸 美国自动♻️", "type": "urltest", "outbounds": [], "url": "http://www.apple.com/library/test/success.html", "interrupt_exist_connections": true }, { "tag": "🇭🇰 香港自动♻️", "type": "urltest", "outbounds": [], "url": "http://www.apple.com/library/test/success.html", "interrupt_exist_connections": true }, { "tag": "公益", "type": "selector", "interrupt_exist_connections": true, "outbounds": [] }, { "tag": "直连", "type": "direct" } ], "route": { "rules": [ { "action": "hijack-dns", "port": 53 }, { "action": "reject", "network": "udp", "port": 443 }, { "action": "sniff" }, { "action": "reject", "protocol": "quic" }, { "action": "hijack-dns", "protocol": "dns" }, { "type": "logical", "mode": "or", "rules": [ { "domain_suffix": ["excalicode.org"] }, { "ip_cidr": ["82.158.226.4"] } ], "outbound": "直连" }, { "rule_set": ["Telegram", "Telegram_Ip"], "outbound": "✈️ Telegram" }, { "rule_set": ["Youtube"], "outbound": "▶️ YouTube" }, { "rule_set": ["Netflix"], "outbound": "📺 Netflix" }, { "rule_set": ["Google"], "outbound": "🌐 Google" }, { "rule_set": ["OpenAI", "Claude", "Gemini"], "outbound": "🤖 AI" }, { "rule_set": ["X"], "outbound": "💭 X" }, { "rule_set": ["FaceBook"], "outbound": "♾️ Meta" }, { "rule_set": ["TikTok"], "outbound": "🎬 TikTok" }, { "rule_set": ["PayPal"], "outbound": "💰 PayPal" }, { "rule_set": [ "GeoSite-Private", "GeoSite-CN", "GeoIP-Private", "GeoIP-CN" ], "outbound": "直连" } ], "rule_set": [ { "tag": "Work", "type": "remote", "url": "https://raw.githubusercontent.com/Docker7530/netbox/refs/heads/main/sing-box/rule_set/work.srs", "download_detour": "默认" }, { "tag": "Telegram", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-telegram.srs", "download_detour": "默认" }, { "tag": "Telegram_Ip", "type": "remote", "url": "https://raw.githubusercontent.com/DustinWin/ruleset_geodata/refs/heads/sing-box-ruleset/telegramip.srs", "download_detour": "默认" }, { "tag": "Youtube", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-youtube.srs", "download_detour": "默认" }, { "tag": "Netflix", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-netflix.srs", "download_detour": "默认" }, { "tag": "Google", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-google.srs", "download_detour": "默认" }, { "tag": "OpenAI", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-openai.srs", "download_detour": "默认" }, { "tag": "Claude", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-anthropic.srs", "download_detour": "默认" }, { "tag": "Gemini", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-google-gemini.srs", "download_detour": "默认" }, { "tag": "X", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-x.srs", "download_detour": "默认" }, { "tag": "FaceBook", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-facebook.srs", "download_detour": "默认" }, { "tag": "TikTok", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-tiktok.srs", "download_detour": "默认" }, { "tag": "PayPal", "type": "remote", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-paypal.srs", "download_detour": "默认" }, { "tag": "GeoSite-Private", "type": "remote", "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/private.srs", "download_detour": "默认" }, { "tag": "GeoSite-CN", "type": "remote", "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/cn.srs", "download_detour": "默认" }, { "tag": "GeoIP-Private", "type": "remote", "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geoip/private.srs", "download_detour": "默认" }, { "tag": "GeoIP-CN", "type": "remote", "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geoip/cn.srs", "download_detour": "默认" } ], "auto_detect_interface": true, "default_domain_resolver": { "server": "Local-DNS" } }, "dns": { "servers": [ { "tag": "Local-DNS", "type": "https", "domain_resolver": "Hosts", "server": "doh.pub" }, { "tag": "Fakeip-DNS", "type": "fakeip", "inet4_range": "198.18.0.0/15", "inet6_range": "fc00::/18" }, { "tag": "Work-Test-DNS", "type": "udp", "server": "172.22.102.231", "bind_interface": "wg0" }, { "tag": "Work-Oa-DNS", "type": "udp", "server": "10.54.2.232", "bind_interface": "wg0" }, { "tag": "Hosts", "type": "hosts", "predefined": { "doh.pub": ["1.12.12.21", "120.53.53.53"] } } ], "rules": [ { "domain": ["koms.komect.net"], "server": "Work-Oa-DNS" }, { "rule_set": ["Work"], "server": "Work-Test-DNS" }, { "rule_set": ["GeoSite-Private", "GeoSite-CN"], "server": "Local-DNS" }, { "query_type": ["A", "AAAA"], "server": "Fakeip-DNS" } ], "strategy": "prefer_ipv4" }, "experimental": { "clash_api": { "external_controller": "0.0.0.0:9595", "external_ui": "ui", "external_ui_download_url": "https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip", "external_ui_download_detour": "默认", "secret": "" }, "cache_file": { "enabled": true, "store_fakeip": true, "store_rdrc": true } } } ``` 这个东西先设计为通过 URL 拉取的形式吧类似与这种: ``` https://raw.githubusercontent.com/Docker7530/netbox/refs/heads/main/sing-box/config/config_sub.json ``` 然后重点来了,我想给用户一个脚本区域。实现节点和模版配置的拼接类似: ``` const CONFIG = { name: "all", type: "collection", includeUnsupportedProxy: false, groups: [ { outbound: "🇭🇰 香港", tags: String.raw`^(?!.*公益).*(港|hk|hongkong|kong kong|🇭🇰)`, }, { outbound: "🇹🇼 台湾", tags: String.raw`^(?!.*公益).*(台|tw|taiwan|🇹🇼)`, }, { outbound: "🇯🇵 日本", tags: String.raw`^(?!.*公益).*(日本|jp|japan|🇯🇵)`, }, { outbound: "🇸🇬 新加坡", tags: String.raw`^(?!.*公益).*(新|sg|singapore|🇸🇬)`, }, { outbound: "🇺🇸 美国", tags: String.raw`^(?!.*公益).*(美|us|unitedstates|united states|🇺🇸)`, }, { outbound: "公益", tags: String.raw`公益` }, ], }; const args = (typeof $arguments === "object" && $arguments) || {}; const subscriptionName = (typeof args.name === "string" && args.name.trim()) || CONFIG.name; const t = args.type?.trim?.().toLowerCase?.(); const subscriptionType = t === "s" || t === "subscription" ? "subscription" : CONFIG.type; const rawConfig = $content ?? $files?.[0]; const parser = ProxyUtils.JSON5 || JSON; const config = parser.parse(rawConfig); if (!Array.isArray(config.outbounds)) { throw new TypeError("配置文件格式错误: outbounds 字段缺失或不是数组"); } const proxies = await produceArtifact({ name: subscriptionName, type: subscriptionType, platform: "sing-box", produceType: "internal", produceOpts: { "include-unsupported-proxy": CONFIG.includeUnsupportedProxy, }, }); const rules = CONFIG.groups.map((rule) => ({ outboundReg: new RegExp(rule.outbound, "i"), tagReg: new RegExp(rule.tags, "i"), })); for (const outbound of config.outbounds) { if (!Array.isArray(outbound.outbounds)) continue; const targetRules = rules.filter(({ outboundReg }) => outboundReg.test(outbound.tag) ); for (const { tagReg } of targetRules) { const matchedTags = proxies .filter(({ tag }) => tagReg.test(tag)) .map(({ tag }) => tag); if (matchedTags.length > 0) { outbound.outbounds.push(...matchedTags); } else if (!outbound.outbounds.includes("直连")) { outbound.outbounds.push("直连"); } } } config.outbounds.push(...proxies); $content = JSON.stringify(config, null, 2); ``` 这是我在 substore 的实现效果,你可以更具咋们当前的项目设计一下这个脚本操作怎么暴露给用户合适。更高级,现代化,符合咋们的项目。 然后还有个问题,这里生成的配置怎么和 控制模块结合,是以控制模块选择应用的形式还是怎么合适。先出一版设计方案。 --- 招聘【全栈工程师】全职/兼职 1. 工作内容:宠物类小程序全栈维护,前端后端及开发 bug 修复 2. 工作待遇:工资面谈,创始股权激励 3. 要求:熟悉 ai 工作原理,有 5 年以上全栈经验,5-10 年技术开发经验 4. 工作时间:弹性工作制,时间灵活 5. 工作地点:接受线上办公 6. 联系方式:18613375551 --- ``` curl --location 'http://localhost:8082/api/monitor/ops/illegal/domain/email/send?email=15033848944%40163.com' \ --header 'Content-Type: application/json' \ --data '[ { "provider": "阿里云", "domain": "example.com" }, { "provider": "腾讯云", "domain": "test.com" } ]' ``` # 总结