PageSourceSearch

https://16x.ai/assets/SipLinesPage-CaHaGD08.js

js 16x.ai collected 2026-10-05 13:26:03 UTC 11,489 bytes, 1 lines download raw bytes

1import{c as Q,h as Y,l as d,j as e,Q as $}from"./index-B7gsrJMq.js";import{A as q,r,B as b,E as T,M as R,j as c,i as z,S as H}from"./vendor-antd-snxaH4_5.js";import{R as K}from"./refresh-cw-DuAXkPDy.js";import{P as V}from"./pencil-AFqGRE1T.js";import{E as X}from"./eye-VU8HAzl8.js";import{T as Z}from"./trash-2-DslqjX-l.js";import{S as ee}from"./save-C5axMCtP.js";import"./vendor-sip-B-XYNw9E.js";const se=[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],te=Q("eye-off",se),ae={inbound:"呼入",outbound:"呼出",all:"全部"},re=[{value:"random",label:"随机拨打 — 从可用线路中随机选择一条"},{value:"most_recent",label:"最近拨打 — 优先选择最近使用过的线路"},{value:"longest_idle",label:"最长空闲 — 优先选择最久未使用的线路"}];function pe(){const{theme:a}=Y(),{message:i}=q.useApp(),[u,j]=r.useState("lines"),[v,I]=r.useState([]),[L,M]=r.useState(!0),[f,h]=r.useState(!1),[x,g]=r.useState(null),[N,S]=r.useState({}),[w,C]=r.useState({}),[t,l]=r.useState({name:"",ip:"",port:"5060",sipUsername:"",sipPassword:"",callDirection:"all",status:"active",country:"",numbers:"",prefix:"",registerEnabled:!1}),[_,P]=r.useState(!1),[y,k]=r.useState("random"),[D,E]=r.useState(!1),m=r.useCallback(async()=>{try{I(await d.sipLines.list())}catch{}M(!1)},[]),O=r.useCallback(async()=>{try{const s=await d.systemSettings.get();if(s?.sip_line_rule){const n=JSON.parse(s.sip_line_rule);k(n.strategy||"random")}}catch{}},[]);r.useEffect(()=>{m()},[m]);const B=()=>{g(null),l({name:"",ip:"",port:"5060",sipUsername:"",sipPassword:"",callDirection:"all",status:"active",country:"",numbers:"",prefix:"",registerEnabled:!1}),h(!0)},U=s=>{g(s),l({name:s.name||"",ip:s.ip||"",port:String(s.port||5060),sipUsername:s.sipUsername||"",sipPassword:"",callDirection:s.callDirection||"all",status:s.status||"active",country:s.country||"",numbers:Array.isArray(s.numbers)?s.numbers.join(", "):(s.numbers||"").replace(/[\[\]"]/g,""),prefix:s.prefix||"",registerEnabled:!!s.registerEnabled}),h(!0)},F=async()=>{if(!t.name||!t.ip){i.error("名称、IP 为必填");return}P(!0);try{const s={...t,port:parseInt(t.port)||5060,numbers:t.numbers.split(",").map(n=>n.trim()).filter(Boolean)};s.registerEnabled=t.registerEnabled?1:0,t.sipPassword&&(s.sipPassword=t.sipPassword),x&&!t.sipPassword&&delete s.sipPassword,x?(await d.sipLines.update(x.id,s),i.success("已更新")):(await d.sipLines.create(s),i.success("已创建")),h(!1),m()}catch(s){i.error(s?.message||"保存失败")}P(!1)},G=async s=>{R.confirm({title:"确认删除?",content:"删除后不可恢复",okText:"删除",okType:"danger",cancelText:"取消",onOk:async()=>{await d.sipLines.delete(s),m(),i.success("已删除")}})},J=async s=>{if(w[s]){C(n=>{const p={...n};return delete p[s],p}),S(n=>({...n,[s]:!1}));return}try{const{password:n}=await d.sipLines.getPassword(s);C(p=>({...p,[s]:n})),S(p=>({...p,[s]:!0}))}catch{i.error("获取密码失败")}},W=async()=>{E(!0);try{await d.systemSettings.put("sip_line_rule",JSON.stringify({strategy:y})),i.success("线路规则已保存")}catch(s){i.error(s?.message||"保存失败")}E(!1)},o={backgroundColor:a.inputBg,borderColor:a.inputBorder,color:a.textPrimary,fontFeatureSettings:a.fontFeatureSettings},A=s=>({padding:"6px 16px",border:"none",borderRadius:6,cursor:"pointer",fontSize:13,fontWeight:500,backgroundColor:u===s?a.brand:"transparent",color:u===s?"#fff":a.textSecondary});return e.jsxs("div",{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-5",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{type:"button",style:A("lines"),onClick:()=>{j("lines"),m()},children:"线路管理"}),e.jsx("button",{type:"button",style:A("rules"),onClick:()=>{j("rules"),O()},children:"线路规则"})]}),u==="lines"&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(b,{icon:e.jsx(K,{size:14}),onClick:m,size:"small",children:"刷新"}),e.jsx(b,{type:"primary",icon:e.jsx($,{size:14}),onClick:B,size:"small",children:"新增线路"})]})]}),u==="lines"&&e.jsx("div",{className:"overflow-x-auto rounded-lg border",style:{borderColor:a.border},children:e.jsxs("table",{className:"w-full text-sm",style:{color:a.textPrimary},children:[e.jsx("thead",{style:{backgroundColor:a.bgAlt},children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"名称"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"IP:端口"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"SIP 用户"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"国家"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"号码"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"方向"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"状态"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"注册"}),e.jsx("th",{className:"text-left px-3 py-2.5 font-medium",children:"操作"})]})}),e.jsx("tbody",{children:L?e.jsx("tr",{children:e.jsx("td",{colSpan:9,className:"text-center py-8",style:{color:a.textMuted},children:"加载中..."})}):v.length===0?e.jsx("tr",{children:e.jsx("td",{colSpan:9,className:"text-center py-8",style:{color:a.textMuted},children:"暂无线路,点击「新增线路」添加"})}):v.map(s=>e.jsxs("tr",{className:"border-t",style:{borderColor:a.border},children:[e.jsx("td",{className:"px-3 py-2.5 font-medium",children:s.name}),e.jsxs("td",{className:"px-3 py-2.5",style:{color:a.textSecondary},children:[s.ip,":",s.port]}),e.jsxs("td",{className:"px-3 py-2.5",style:{fontFamily:"monospace",fontSize:12},children:[s.sipUsername,N[s.id]&&e.jsxs("span",{className:"ml-1",style:{color:a.textMuted},children:["/ ",w[s.id]||"***"]}
1)]}),e.jsx("td",{className:"px-3 py-2.5",children:s.country||"-"}),e.jsx("td",{className:"px-3 py-2.5",style:{color:a.textSecondary,fontSize:12,maxWidth:120,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:Array.isArray(s.numbers)?s.numbers.join(", "):s.numbers||"-"}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsx("span",{className:"px-2 py-0.5 rounded text-xs",style:{backgroundColor:a.bgAlt},children:ae[s.callDirection]||s.callDirection})}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsx("span",{className:"px-2 py-0.5 rounded text-xs font-medium",style:{backgroundColor:s.status==="active"?"#ecfdf5":"#f1f5f9",color:s.status==="active"?"#10b981":"#94a3b8"},children:s.status==="active"?"可用":"不可用"})}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsx("span",{className:"px-2 py-0.5 rounded text-xs",style:{backgroundColor:"#f1f5f9",color:s.registerEnabled?"#6366f1":"#94a3b8"},children:s.registerEnabled?"是":"否"})}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsxs("div",{className:"flex gap-1",children:[e.jsx("button",{onClick:()=>U(s),className:"p-1.5 rounded hover:bg-[var(--color-bg-secondary)]",title:"编辑",children:e.jsx(V,{size:14})}),e.jsx("button",{onClick:()=>J(s.id),className:"p-1.5 rounded hover:bg-[var(--color-bg-secondary)]",title:"查看密码",children:N[s.id]?e.jsx(te,{size:14}):e.jsx(X,{size:14})}),e.jsx("button",{onClick:()=>G(s.id),className:"p-1.5 rounded hover:bg-red-50",style:{color:a.danger},title:"删除",children:e.jsx(Z,{size:14})})]})})]},s.id))})]})}),u==="rules"&&e.jsxs("div",{className:"rounded-lg border p-6",style:{borderColor:a.border,backgroundColor:a.bgAlt},children:[e.jsx("h3",{className:"text-base font-semibold mb-4",style:{color:a.textPrimary},children:"线路选择策略"}),e.jsx("p",{className:"text-xs mb-5",style:{color:a.textMuted},children:"当匹配到多条可用线路时,按以下策略选择一条进行外呼。"}),e.jsx(T.Group,{value:y,onChange:s=>k(s.target.value),children:e.jsx("div",{className:"space-y-3",children:re.map(s=>e.jsxs("div",{className:"flex items-start gap-3 p-3 rounded-lg border",style:{borderColor:y===s.value?a.brand:a.border,backgroundColor:y===s.value?`${a.brand}08`:a.inputBg},children:[e.jsx(T,{value:s.value}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium",style:{color:a.textPrimary},children:s.label.split(" — ")[0]}),e.jsx("div",{className:"text-xs mt-0.5",style:{color:a.textMuted},children:s.label.split(" — ")[1]})]})]},s.value))})}),e.jsx("div",{className:"mt-5",children:e.jsx(b,{type:"primary",icon:e.jsx(ee,{size:14}),onClick:W,loading:D,children:"保存规则"})})]}),f&&e.jsx(R,{title:x?"编辑线路":"新增线路",open:f,onCancel:()=>h(!1),onOk:F,confirmLoading:_,okText:"保存",cancelText:"取消",width:560,children:e.jsxs("div",{className:"grid grid-cols-2 gap-3 mt-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"名称 *"}),e.jsx(c,{value:t.name,onChange:s=>l({...t,name:s.target.value}),placeholder:"线路名称",style:o})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"国家"}),e.jsx(c,{value:t.country,onChange:s=>l({...t,country:s.target.value}),placeholder:"CN",style:o})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"IP *"}),e.jsx(c,{value:t.ip,onChange:s=>l({...t,ip:s.target.value}),placeholder:"192.168.1.1",style:o})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"端口"}),e.jsx(c,{value:t.port,onChange:s=>l({...t,port:s.target.value}),placeholder:"5060",style:o})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"SIP 用户名"}),e.jsx(c,{value:t.sipUsername,onChange:s=>l({...t,sipUsername:s.target.value}),placeholder:"sip user",style:o})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"text-xs mb-1",children:["SIP 密码 ",x&&"(留空不修改)"]}),e.jsx(c.Password,{value:t.sipPassword,onChange:s=>l({...t,sipPassword:s.target.value}),placeholder:x?"留空不修改":"sip password",style:o})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"呼叫方向"}),e.jsx(z,{value:t.callDirection,onChange:s=>l({...t,callDirection:s}),style:{width:"100%"},options:[{value:"all",label:"全部"},{value:"outbound",label:"呼出"},{value:"inbound",label:"呼入"}]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"状态"}),e.jsx(z,{value:t.status,onChange:s=>l({...t,status:s}),style:{width:"100%"},options:[{value:"active",label:"可用"},{value:"inactive",label:"不可用"}]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs mb-1",children:"是否需要注册"}),e.jsx(H,{checked:t.registerEnabled,onChange:s=>l({...t,registerEnabled:s})}),e.jsx("span",{className:"text-xs ml-2",style:{color:a.textSecondary},children:t.registerEnabled?"需要注册":"不需要注册"})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx("div",{className:"text-xs mb-1",children:"号码列表(逗号分隔)"}),e.jsx(c,{value:t.numbers,onChange:s=>l({...t,numbers:s.target.value}),placeholder:"+8613800138000, +8613800138001",style:o})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx("div",{className:"text-xs mb-1",children:"呼叫前缀"}),e.jsx(c,{value:t.prefix,onChange:s=>l({...t,prefix:s.target.value}),placeholder:"+86",style:o})]})]})})]})}export{pe as SipLinesPage};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.