@yuku123/z-subscribe-frontend-component 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2951,9 +2951,7 @@ const { Header: Gs, Sider: Zs, Content: Qs } = nr, { Text: ea } = ee, { Title: t
|
|
|
2951
2951
|
Object.fromEntries(fs.map((e) => [e.type, e]));
|
|
2952
2952
|
const { Option: sa } = fe;
|
|
2953
2953
|
Q.TextArea, Q.TextArea;
|
|
2954
|
-
const { Text: aa, Paragraph: ia } = ee, { TextArea: la } = Q, { TextArea: ca } = Q, { Text: ua, Paragraph: da } = ee, { TextArea: fa } = Q, { Text: pa, Paragraph: ha } = ee, { Text: ma } = ee, { Text: ba } = ee, { TextArea: ya } = Q, { Text: ga, Paragraph: xa } = ee, { Text: Ea } = ee, { Text: wa } = ee, { Text: Ra } = ee, { Text: Sa } = ee
|
|
2955
|
-
common;
|
|
2956
|
-
const ps = {
|
|
2954
|
+
const { Text: aa, Paragraph: ia } = ee, { TextArea: la } = Q, { TextArea: ca } = Q, { Text: ua, Paragraph: da } = ee, { TextArea: fa } = Q, { Text: pa, Paragraph: ha } = ee, { Text: ma } = ee, { Text: ba } = ee, { TextArea: ya } = Q, { Text: ga, Paragraph: xa } = ee, { Text: Ea } = ee, { Text: wa } = ee, { Text: Ra } = ee, { Text: Sa } = ee, ps = {
|
|
2957
2955
|
STANDARD_JSON: { label: "标准 JSON", color: "blue" },
|
|
2958
2956
|
RSS_XML: { label: "RSS 2.0", color: "orange" },
|
|
2959
2957
|
ATOM_XML: { label: "Atom 1.0", color: "gold" },
|
|
@@ -48,4 +48,4 @@ React keys must be passed directly to JSX without using spread:
|
|
|
48
48
|
`);return o===-1?"":n.stack.slice(o+1)})();try{if(!r.stack)r.stack=s;else if(s){const o=s.indexOf(`
|
|
49
49
|
`),a=o===-1?-1:s.indexOf(`
|
|
50
50
|
`,o+1),f=a===-1?"":s.slice(a+1);String(r.stack).endsWith(f)||(r.stack+=`
|
|
51
|
-
`+s)}}catch{}}throw r}}_request(e,t){typeof e=="string"?(t=t||{},t.url=e):t=e||{},t=pe(this.defaults,t);const{transitional:r,paramsSerializer:n,headers:s}=t;r!==void 0&&Je.assertOptions(r,{silentJSONParsing:$.transitional($.boolean),forcedJSONParsing:$.transitional($.boolean),clarifyTimeoutError:$.transitional($.boolean),legacyInterceptorReqResOrdering:$.transitional($.boolean),advertiseZstdAcceptEncoding:$.transitional($.boolean),validateStatusUndefinedResolves:$.transitional($.boolean)},!1),n!=null&&(l.isFunction(n)?t.paramsSerializer={serialize:n}:Je.assertOptions(n,{encode:$.function,serialize:$.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),Je.assertOptions(t,{baseUrl:$.spelling("baseURL"),withXsrfToken:$.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let o=s&&l.merge(s.common,s[t.method]);s&&l.forEach(["delete","get","head","post","put","patch","query","common"],R=>{delete s[R]}),t.headers=M.concat(o,s);const a=[];let f=!0;this.interceptors.request.forEach(function(R){if(typeof R.runWhen=="function"&&R.runWhen(t)===!1)return;f=f&&R.synchronous;const N=t.transitional||et;N&&N.legacyInterceptorReqResOrdering?a.unshift(R.fulfilled,R.rejected):a.push(R.fulfilled,R.rejected)});const d=[];this.interceptors.response.forEach(function(R){d.push(R.fulfilled,R.rejected)});let g,b=0,x;if(!f){const R=[Qt.bind(this),void 0];for(R.unshift(...a),R.push(...d),x=R.length,g=Promise.resolve(t);b<x;)g=g.then(R[b++],R[b++]);return g}x=a.length;let O=t;for(;b<x;){const R=a[b++],N=a[b++];try{O=R(O)}catch(T){N.call(this,T);break}}try{g=Qt.call(this,O)}catch(R){return Promise.reject(R)}for(b=0,x=d.length;b<x;)g=g.then(d[b++],d[b++]);return g}getUri(e){e=pe(this.defaults,e);const t=qt(e.baseURL,e.url,e.allowAbsoluteUrls,e);return kt(t,e.params,e.paramsSerializer)}};l.forEach(["delete","get","head","options"],function(e){he.prototype[e]=function(t,r){return this.request(pe(r||{},{method:e,url:t,data:r&&l.hasOwnProp(r,"data")?r.data:void 0}))}}),l.forEach(["post","put","patch","query"],function(e){function t(r){return function(n,s,o){return this.request(pe(o||{},{method:e,headers:r?{"Content-Type":"multipart/form-data"}:{},url:n,data:s}))}}he.prototype[e]=t(),e!=="query"&&(he.prototype[e+"Form"]=t(!0))});let ys=class fr{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(s){r=s});const n=this;this.promise.then(s=>{if(!n._listeners)return;let o=n._listeners.length;for(;o-- >0;)n._listeners[o](s);n._listeners=null}),this.promise.then=s=>{let o;const a=new Promise(f=>{n.subscribe(f),o=f}).then(s);return a.cancel=function(){n.unsubscribe(o)},a},t(function(s,o,a){n.reason||(n.reason=new Ne(s,o,a),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const r=this._listeners.indexOf(t);r!==-1&&this._listeners.splice(r,1)}toAbortSignal(){const t=new AbortController,r=n=>{t.abort(n)};return this.subscribe(r),t.signal.unsubscribe=()=>this.unsubscribe(r),t.signal}static source(){let t;return{token:new fr(function(r){t=r}),cancel:t}}};function gs(e){return function(t){return e.apply(null,t)}}function Ss(e){return l.isObject(e)&&e.isAxiosError===!0}const at={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(at).forEach(([e,t])=>{at[t]=e});function tr(e){const t=new he(e),r=bt(he.prototype.request,t);return l.extend(r,he.prototype,t,{allOwnKeys:!0}),l.extend(r,t,null,{allOwnKeys:!0}),r.create=function(n){return tr(pe(e,n))},r}const F=tr(Ce);F.Axios=he,F.CanceledError=Ne,F.CancelToken=ys,F.isCancel=Bt,F.VERSION=st,F.toFormData=ze,F.AxiosError=w,F.Cancel=F.CanceledError,F.all=function(e){return Promise.all(e)},F.spread=gs,F.isAxiosError=Ss,F.mergeConfig=pe,F.AxiosHeaders=M,F.formToJSON=e=>Dt(l.isHTMLForm(e)?new FormData(e):e),F.getAdapter=Zt.getAdapter,F.HttpStatusCode=at,F.default=F;const{Axios:Ds,AxiosError:Bs,CanceledError:Us,isCancel:zs,CancelToken:Ms,VERSION:$s,all:qs,Cancel:Hs,isAxiosError:Js,spread:Ws,toFormData:Vs,AxiosHeaders:Xs,HttpStatusCode:Ks,formToJSON:Ys,getAdapter:Gs,mergeConfig:Zs,create:Qs}=F;function xs(e){if(e&&typeof e=="object"&&"code"in e&&"data"in e){const t=e;return t.code!==200?Promise.reject(new Error(t.message||"请求失败")):t.data}return e}function Es(e,t={}){const{tokenKey:r="token",userInfoKey:n="userInfo",unauthorizedRedirect:s="/login"}=t;e.interceptors.request.use(o=>{const a=localStorage.getItem(r);return a&&(o.headers.Authorization=`Bearer ${a}`),o}),e.interceptors.response.use(o=>xs(o.data),o=>{var a,f,d;return((a=o.response)==null?void 0:a.status)===401?(localStorage.removeItem(r),localStorage.removeItem(n),window.location.href=s):((f=o.response)==null?void 0:f.status)===403?console.error("没有权限访问该资源"):((d=o.response)==null?void 0:d.status)===500&&console.error("服务器内部错误"),Promise.reject(o)})}function rr(e={}){const t=F.create({baseURL:e.baseURL??"/api",timeout:e.timeout??1e4});return Es(t,{tokenKey:e.tokenKey,userInfoKey:e.userInfoKey,unauthorizedRedirect:e.unauthorizedRedirect}),t}const q=rr();rr();class eo extends I.Component{constructor(t){super(t),yr(this,"handleReset",()=>{this.setState({hasError:!1,error:null,errorInfo:null}),typeof this.props.onReset=="function"&&this.props.onReset()}),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,r){console.error("[ErrorBoundary] caught error:",t,r),this.setState({errorInfo:r})}render(){if(!this.state.hasError)return this.props.children;const{fallbackTitle:t="组件加载失败",fallbackDescription:r,showReload:n=!0}=this.props,s=this.state.error&&(this.state.error.message||String(this.state.error))||"未知错误";return Y.jsxs("div",{style:{padding:24,background:"#fff2f0",border:"1px solid #ffccc7",borderRadius:8,minHeight:200},children:[Y.jsx(c.Alert,{type:"error",showIcon:!0,icon:Y.jsx(D.BugOutlined,{}),message:t,description:Y.jsxs("div",{children:[Y.jsx("div",{style:{marginBottom:8},children:r||"当前组件发生了异常,已被错误边界捕获。其他功能仍可正常使用。"}),Y.jsx("div",{style:{fontFamily:"Menlo, Monaco, Consolas, monospace",fontSize:12,color:"#cf1322",background:"#fff",padding:8,borderRadius:4,border:"1px solid #ffccc7",wordBreak:"break-word",whiteSpace:"pre-wrap"},children:s})]})}),n&&Y.jsx(c.Space,{style:{marginTop:16},children:Y.jsx(c.Button,{icon:Y.jsx(D.ReloadOutlined,{}),onClick:this.handleReset,children:"重试"})})]})}}const{Title:to,Text:ro,Paragraph:no}=c.Typography;let ws="/api";function nr(){return F.create({baseURL:ws,timeout:15e3})}const Rs=nr();nr(),Rs.interceptors.request.use(e=>{const t=localStorage.getItem("token");return t&&(e.headers.Authorization=`Bearer ${t}`),e});const{Header:so,Sider:oo,Content:io}=c.Layout,{Text:ao}=c.Typography,{Title:lo,Text:co}=c.Typography,{Option:uo}=c.Select,{TextArea:fo}=c.Input,Ts=[{type:"STRING",label:"字符串",icon:Y.jsx(D.FileTextOutlined,{}),color:"#1677ff",desc:"短文本 (默认 VARCHAR 255)"},{type:"TEXT",label:"长文本",icon:Y.jsx(D.FileTextOutlined,{}),color:"#13c2c2",desc:"TEXT 类型, 无长度限制"},{type:"INT",label:"整数",icon:"#",color:"#722ed1",desc:"INT 整数"},{type:"LONG",label:"长整数",icon:"#",color:"#722ed1",desc:"BIGINT 长整数"},{type:"DECIMAL",label:"小数",icon:"0.00",color:"#eb2f96",desc:"DECIMAL 精确小数"},{type:"BOOLEAN",label:"布尔",icon:Y.jsx(D.CheckCircleOutlined,{}),color:"#52c41a",desc:"TINYINT(1) 是/否"},{type:"DATE",label:"日期",icon:"📅",color:"#fa8c16",desc:"DATE yyyy-MM-dd"},{type:"DATETIME",label:"日期时间",icon:"🕐",color:"#fa8c16",desc:"DATETIME yyyy-MM-dd HH:mm:ss"},{type:"JSON",label:"JSON",icon:"{}",color:"#2f54eb",desc:"JSON 字符串"},{type:"REF",label:"引用",icon:"🔗",color:"#8c8c8c",desc:"外键引用 BIGINT"}];Object.fromEntries(Ts.map(e=>[e.type,e]));const{Option:po}=c.Select;c.Input.TextArea,c.Input.TextArea;const{Text:ho,Paragraph:mo}=c.Typography,{TextArea:bo}=c.Input,{TextArea:yo}=c.Input,{Text:go,Paragraph:So}=c.Typography,{TextArea:xo}=c.Input,{Text:Eo,Paragraph:wo}=c.Typography,{Text:Ro}=c.Typography,{Text:To}=c.Typography,{TextArea:Oo}=c.Input,{Text:vo,Paragraph:jo}=c.Typography,{Text:_o}=c.Typography,{Text:Ao}=c.Typography,{Text:Co}=c.Typography,{Text:No}=c.Typography;common;const Os={STANDARD_JSON:{label:"标准 JSON",color:"blue"},RSS_XML:{label:"RSS 2.0",color:"orange"},ATOM_XML:{label:"Atom 1.0",color:"gold"},CUSTOM_SCRIPT:{label:"自定义脚本",color:"purple"},INTERNAL_BEAN:{label:"内部 Bean",color:"cyan"}},vs={PENDING_VERIFY:{color:"default",text:"待验证"},VERIFIED:{color:"green",text:"已验证"},INVALID_AUTH:{color:"red",text:"鉴权失败"},FATAL:{color:"red",text:"永久失败"},DISABLED:{color:"default",text:"已停用"}},sr={PENDING:{color:"default"},RUNNING:{color:"processing"},SUCCESS:{color:"green"},EMPTY:{color:"default"},FAILED:{color:"red"},FATAL:{color:"red"}};function or(){const e=re.useNavigate(),[t,r]=I.useState([]),[n,s]=I.useState(!1),[o,a]=I.useState(null),[f,d]=I.useState([]),[g,b]=I.useState({}),[x,O]=I.useState(null),[R,N]=I.useState([]),T=async()=>{s(!0);try{const S=await q.get("/subscribe/subscription/list");S&&S.success!==!1&&r(Array.isArray(S.data)?S.data:Array.isArray(S)?S:[])}catch(S){c.message.error("获取订阅列表失败: "+((S==null?void 0:S.message)||""))}finally{s(!1)}};I.useEffect(()=>{T()},[]);const B=S=>{c.Modal.confirm({title:"确认删除",icon:u.jsx(D.ExclamationCircleOutlined,{}),content:`确定要删除订阅 "${S.name}" 吗? 运行历史会保留.`,onOk:async()=>{try{const h=await q.delete(`/subscribe/subscription/${S.id}`);h&&h.success!==!1?(c.message.success("删除成功"),T()):c.message.error((h==null?void 0:h.message)||"删除失败")}catch(h){c.message.error("删除失败: "+((h==null?void 0:h.message)||""))}}})},y=async S=>{try{const h=await q.post(`/subscribe/subscription/${S}/enable`);h&&h.success!==!1?(c.message.success("已启用"),T()):c.message.error((h==null?void 0:h.message)||"启用失败")}catch(h){c.message.error("启用失败: "+((h==null?void 0:h.message)||""))}},m=async S=>{try{const h=await q.post(`/subscribe/subscription/${S}/disable`);h&&h.success!==!1?(c.message.success("已停用"),T()):c.message.error((h==null?void 0:h.message)||"停用失败")}catch(h){c.message.error("停用失败: "+((h==null?void 0:h.message)||""))}},p=async S=>{c.Modal.confirm({title:"手动触发",content:`将立即执行一次 "${S.name}" 的抽取, 同步返回 runId.`,onOk:async()=>{try{const h=await q.post(`/subscribe/subscription/${S.id}/trigger?triggerBy=ceo`);if(h&&(h.data!==void 0||h.success!==!1)){const L=h.data??h;c.message.success(`已触发, runId = ${L}`),k(S)}else c.message.error((h==null?void 0:h.message)||"触发失败")}catch(h){c.message.error("触发失败: "+((h==null?void 0:h.message)||""))}}})},v=async S=>{try{const h=await q.post(`/subscribe/subscription/${S.id}/dry-run`);a({sub:S,result:(h==null?void 0:h.data)??h})}catch(h){a({sub:S,result:{success:!1,errorMessage:(h==null?void 0:h.message)||"请求失败"}})}},k=async S=>{try{const h=await q.get(`/subscribe/run/list?subscriptionId=${S.id}&limit=20`),L=(h==null?void 0:h.data)??h??[];d(Array.isArray(L)?L:[]),O(null),b({}),N([]),a({sub:S,tab:"runs"})}catch{c.message.error("获取运行历史失败")}},ne=async S=>{if(g[S]){O(S);return}try{const h=await q.get(`/subscribe/run/${S}/items?limit=200`),L=(h==null?void 0:h.data)??h??[];b(J=>({...J,[S]:Array.isArray(L)?L:[]})),O(S)}catch{c.message.error("获取抽取项失败")}},me=[{title:"ID",dataIndex:"id",width:70},{title:"名称",dataIndex:"name",render:(S,h)=>u.jsxs(c.Space,{orientation:"vertical",size:0,children:[u.jsx("span",{style:{fontWeight:500},children:S}),h.description&&u.jsx("span",{style:{color:"#999",fontSize:12},children:h.description})]})},{title:"数据源",dataIndex:"sourceType",width:90,render:S=>u.jsx(c.Tag,{children:S})},{title:"抽取器",dataIndex:"extractorType",width:140,render:S=>{const h=Os[S]||{label:S,color:"default"};return u.jsx(c.Tag,{color:h.color,children:h.label})}},{title:"Cron",dataIndex:"cronExpr",width:150,render:S=>u.jsx("code",{style:{fontSize:12},children:S})},{title:"状态",dataIndex:"status",width:110,render:S=>{const h=vs[S]||{color:"default",text:S};return u.jsx(c.Tag,{color:h.color,children:h.text})}},{title:"启用",dataIndex:"enabled",width:80,render:(S,h)=>S?u.jsx(c.Tag,{color:"green",children:"是"}):u.jsx(c.Tag,{children:"否"})},{title:"最近 run",dataIndex:"lastStatus",width:110,render:(S,h)=>{var L;return S?u.jsx(c.Tooltip,{title:h.lastError||"",children:u.jsx(c.Tag,{color:((L=sr[S])==null?void 0:L.color)||"default",children:S})}):u.jsx("span",{style:{color:"#ccc"},children:"-"})}},{title:"累计",width:130,render:(S,h)=>u.jsxs(c.Space,{size:4,children:[u.jsxs(c.Tag,{color:"green",children:["✓ ",h.successCountTotal||0]}),u.jsxs(c.Tag,{color:"red",children:["✗ ",h.failCountTotal||0]})]})},{title:"操作",width:280,fixed:"right",render:(S,h)=>u.jsxs(c.Space,{size:4,wrap:!0,children:[u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.EditOutlined,{}),onClick:()=>e(`/subscribe/edit/${h.id}`),children:"编辑"}),u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.ThunderboltOutlined,{}),onClick:()=>v(h),children:"试运行"}),u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.PlayCircleOutlined,{}),onClick:()=>p(h),children:"触发"}),u.jsx(c.Button,{type:"link",size:"small",onClick:()=>k(h),children:"历史"}),h.enabled?u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.PauseCircleOutlined,{}),onClick:()=>m(h.id),children:"停用"}):u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.CheckCircleOutlined,{}),onClick:()=>y(h.id),children:"启用"}),u.jsx(c.Popconfirm,{title:"确认删除?",onConfirm:()=>B(h),okText:"删除",cancelText:"取消",children:u.jsx(c.Button,{type:"link",size:"small",danger:!0,icon:u.jsx(D.DeleteOutlined,{}),children:"删除"})})]})}];return u.jsxs("div",{style:{padding:24},children:[u.jsxs(c.Card,{title:u.jsxs(c.Space,{children:[u.jsx(D.ApiOutlined,{}),"订阅中心 - 数据源订阅"]}),extra:u.jsxs(c.Space,{children:[u.jsx(c.Button,{icon:u.jsx(D.ReloadOutlined,{}),onClick:T,children:"刷新"}),u.jsx(c.Button,{type:"primary",icon:u.jsx(D.PlusOutlined,{}),onClick:()=>e("/subscribe/new"),children:"新建订阅"})]}),children:[u.jsx(c.Alert,{type:"info",showIcon:!0,style:{marginBottom:16},message:"订阅中心负责把三方 / 内部 / RSS 等数据源按 Cron 定时抽取, 归一化后落到本地, 供 CEO 立项和 Agent 协作使用."}),u.jsx(c.Table,{rowKey:"id",columns:me,dataSource:t,loading:n,scroll:{x:1400},size:"middle",pagination:{pageSize:20,showSizeChanger:!0,showTotal:S=>`共 ${S} 条`}})]}),u.jsx(c.Drawer,{title:o!=null&&o.sub?`试运行 - ${o.sub.name}`:"运行历史",open:!!o,onClose:()=>a(null),width:900,children:(o==null?void 0:o.tab)==="runs"?u.jsx(c.Tabs,{activeKey:x?"items":"list",onChange:S=>S==="list"&&O(null),items:[{key:"list",label:`运行列表 (${f.length})`,children:u.jsx(c.Table,{rowKey:"id",size:"small",dataSource:f,pagination:!1,onRow:S=>({onClick:()=>ne(S.id)}),columns:[{title:"runId",dataIndex:"id",width:70},{title:"计划",dataIndex:"scheduledAt",width:160,render:S=>S?new Date(S).toLocaleString():"-"},{title:"耗时(ms)",dataIndex:"durationMs",width:90},{title:"状态",dataIndex:"status",width:90,render:S=>{var h;return u.jsx(c.Tag,{color:(h=sr[S])==null?void 0:h.color,children:S})}},{title:"拉取/成功/重复/死信",width:200,render:(S,h)=>`${h.fetchedCount} / ${h.successCount} / ${h.duplicateCount||0} / ${h.deadLetterCount}`},{title:"错误",dataIndex:"errorMessage",render:S=>S?u.jsx("span",{style:{color:"#cf1322",fontSize:12},children:S}):"-"}]})},{key:"items",label:x?`run#${x} 抽取项`:"抽取项",disabled:!x,children:u.jsxs(c.Space,{orientation:"vertical",style:{width:"100%"},children:[u.jsxs(c.Space,{children:[u.jsxs(c.Tag,{color:"blue",children:["已选 ",R.length," 条"]}),u.jsxs(c.Button,{size:"small",type:"primary",icon:u.jsx(D.ProjectOutlined,{}),disabled:R.length===0,onClick:()=>{const S=R.join(",");e(`/project/new?subscriptionId=${o.sub.id}&itemIds=${S}`)},children:["用所选 ",R.length," 条立项"]})]}),u.jsx(c.Table,{rowKey:"id",size:"small",dataSource:g[x]||[],pagination:{pageSize:20},rowSelection:{selectedRowKeys:R,onChange:N},columns:[{title:"id",dataIndex:"dedupKey",width:180,ellipsis:!0},{title:"title",dataIndex:"normalized",render:S=>{try{return JSON.parse(S).title||"(无标题)"}catch{return S}}},{title:"link",dataIndex:"normalized",render:S=>{try{const h=JSON.parse(S);return h.link?u.jsx("a",{href:h.link,target:"_blank",children:"↗"}):"-"}catch{return"-"}}},{title:"状态",dataIndex:"status",width:110,render:S=>u.jsx(c.Tag,{children:S})}]})]})}]}):u.jsx(js,{result:o==null?void 0:o.result})})]})}function js({result:e}){return e?e.success?u.jsxs(c.Space,{orientation:"vertical",style:{width:"100%"},size:"middle",children:[u.jsx(c.Card,{size:"small",title:"调用结果",children:u.jsxs(c.Space,{size:"large",wrap:!0,children:[u.jsxs("span",{children:[u.jsx("b",{children:"HTTP:"})," ",e.httpStatus||"-"]}),u.jsxs("span",{children:[u.jsx("b",{children:"耗时:"})," ",e.latencyMs,"ms"]}),u.jsxs("span",{children:[u.jsx("b",{children:"大小:"})," ",e.responseSize,"B"]}),u.jsxs("span",{children:[u.jsx("b",{children:"样本:"})," ",e.sampleCount," 条"]})]})}),e.firstItem&&u.jsx(c.Card,{size:"small",title:"第一条样本 (归一化后)",children:u.jsx("pre",{style:{background:"#f5f5f5",padding:12,borderRadius:4,maxHeight:300,overflow:"auto"},children:JSON.stringify(e.firstItem,null,2)})}),e.responsePreview&&u.jsx(c.Card,{size:"small",title:"响应预览 (前 4KB)",children:u.jsx("pre",{style:{background:"#f5f5f5",padding:12,borderRadius:4,maxHeight:300,overflow:"auto",fontSize:12},children:e.responsePreview})}),e.fieldErrors&&e.fieldErrors.length>0&&u.jsx(c.Alert,{type:"warning",showIcon:!0,message:"字段问题",description:u.jsx("ul",{children:e.fieldErrors.map((t,r)=>u.jsx("li",{children:t},r))})})]}):u.jsx(c.Alert,{type:"error",showIcon:!0,message:"试运行失败",description:e.errorMessage||"未知错误"}):null}const _s=[{value:"STANDARD_JSON",label:"标准 JSON (按统一契约返回的 JSON)"},{value:"RSS_XML",label:"RSS 2.0 (XML feed)"},{value:"ATOM_XML",label:"Atom 1.0 (XML feed)"},{value:"CUSTOM_SCRIPT",label:"自定义脚本 (z-script 平台)"},{value:"INTERNAL_BEAN",label:"内部 Bean (我们自己的模块, 暂未启用)"}],As=[{value:"NONE",label:"无鉴权"},{value:"BEARER",label:"Bearer (Authorization: Bearer xxx)"},{value:"API_KEY",label:"API Key (Authorization: xxx)"},{value:"BASIC",label:"Basic (user:password base64)"}],Cs=[{label:"每 5 分钟",value:"0 */5 * * * ?"},{label:"每 15 分钟",value:"0 */15 * * * ?"},{label:"每小时",value:"0 0 * * * ?"},{label:"每 6 小时",value:"0 0 */6 * * ?"},{label:"每天 8 点",value:"0 0 8 * * ?"}];function lt(){const{id:e}=re.useParams(),t=re.useNavigate(),r=!!e,[n]=c.Form.useForm(),[s,o]=I.useState(!1),[a,f]=I.useState(!1),[d,g]=I.useState([]),[b,x]=I.useState([]),O=c.Form.useWatch("sourceType",n),R=c.Form.useWatch("extractorType",n),N=c.Form.useWatch("authType",n);I.useEffect(()=>{T(),B(),r&&y()},[e]);const T=async()=>{try{const p=await q.get("/secret/list"),v=(p==null?void 0:p.data)??p??[];g(Array.isArray(v)?v:[])}catch{}},B=async()=>{try{const p=await q.get("/script/list"),v=(p==null?void 0:p.data)??p??[];x(Array.isArray(v)?v.filter(k=>k.status===1):[])}catch{}},y=async()=>{o(!0);try{const p=await q.get(`/subscribe/subscription/${e}`),v=(p==null?void 0:p.data)??p;v&&n.setFieldsValue({...v,enabled:v.enabled===1||v.enabled===!0})}catch(p){c.message.error("加载订阅失败: "+((p==null?void 0:p.message)||""))}finally{o(!1)}},m=async()=>{try{const p=await n.validateFields();f(!0);const v={...p,enabled:p.enabled?1:0};let k;if(r?k=await q.put("/subscribe/subscription",v):k=await q.post("/subscribe/subscription",v),k&&k.success===!1){c.message.error(k.message||"保存失败");return}c.message.success(r?"已更新 (注意: 修改 cron / url / 抽取器后会自动重置为 PENDING_VERIFY)":"已创建, 已自动验证"),t("/subscribe/list")}catch(p){p!=null&&p.errorFields?c.message.warning("请检查表单"):c.message.error("保存失败: "+((p==null?void 0:p.message)||""))}finally{f(!1)}};return u.jsx("div",{style:{padding:24},children:u.jsx(c.Card,{title:u.jsxs(c.Space,{children:[u.jsx(c.Button,{type:"text",icon:u.jsx(D.ArrowLeftOutlined,{}),onClick:()=>t("/subscribe/list")}),u.jsx(D.ApiOutlined,{}),r?`编辑订阅 #${e}`:"新建订阅"]}),extra:u.jsxs(c.Space,{children:[u.jsx(c.Button,{onClick:()=>t("/subscribe/list"),children:"取消"}),u.jsx(c.Button,{type:"primary",icon:u.jsx(D.SaveOutlined,{}),loading:a,onClick:m,children:"保存 (自动验证)"})]}),children:u.jsx(c.Spin,{spinning:s,children:u.jsxs(c.Form,{form:n,layout:"vertical",initialValues:{sourceType:"HTTP",httpMethod:"GET",authType:"NONE",extractorType:"STANDARD_JSON",enabled:!0,minIntervalSec:60,maxItemsPerRun:1e3,timeoutMs:15e3},children:[u.jsxs(c.Card,{type:"inner",title:"基本信息",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"名称",name:"name",rules:[{required:!0,message:"请输入名称"}],children:u.jsx(c.Input,{placeholder:"例如: GitHub PR 通知"})}),u.jsx(c.Form.Item,{label:"说明",name:"description",children:u.jsx(c.Input.TextArea,{rows:2,placeholder:"(可选)"})})]}),u.jsxs(c.Card,{type:"inner",title:"数据源",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"数据源形态",name:"sourceType",rules:[{required:!0}],children:u.jsxs(c.Radio.Group,{children:[u.jsx(c.Radio.Button,{value:"HTTP",children:"HTTP / HTTPS"}),u.jsx(c.Radio.Button,{value:"INTERNAL",disabled:!0,children:"内部 Bean (TODO)"})]})}),O==="HTTP"&&u.jsxs(u.Fragment,{children:[u.jsx(c.Form.Item,{label:"目标 URL",name:"targetUrl",rules:[{required:!0,message:"请输入 URL"}],children:u.jsx(c.Input,{placeholder:"https://api.github.com/repos/.../pulls?state=open"})}),u.jsxs(c.Space,{size:"large",style:{width:"100%"},children:[u.jsx(c.Form.Item,{label:"HTTP 方法",name:"httpMethod",children:u.jsx(c.Select,{style:{width:120},options:[{value:"GET",label:"GET"},{value:"POST",label:"POST"},{value:"PUT",label:"PUT"}]})}),u.jsx(c.Form.Item,{label:"超时 (ms)",name:"timeoutMs",children:u.jsx(c.InputNumber,{min:1e3,max:12e4,step:1e3})})]}),u.jsx(c.Form.Item,{label:"自定义 HTTP 头 (JSON)",name:"httpHeaders",children:u.jsx(c.Input.TextArea,{rows:2,placeholder:'{"X-Trace-Id":"abc"}'})}),u.jsx(c.Form.Item,{label:"请求体 (POST/PUT)",name:"requestBody",children:u.jsx(c.Input.TextArea,{rows:3,placeholder:"(可选)"})})]})]}),u.jsxs(c.Card,{type:"inner",title:"鉴权 (从 z-mist 拉取 secret)",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"鉴权方式",name:"authType",children:u.jsx(c.Select,{options:As})}),N&&N!=="NONE"&&u.jsx(c.Form.Item,{label:"z-mist 凭据引用",name:"authSecretKey",extra:"从密钥中心 (z-mist) 选一个 secret; secret 的解密值会作为 secret 注入",children:u.jsx(c.Select,{showSearch:!0,allowClear:!0,placeholder:"选择 secret (key)",options:d.map(p=>({value:p.secretKey,label:`${p.secretKey}${p.secretName?" ("+p.secretName+")":""}`}))})})]}),u.jsxs(c.Card,{type:"inner",title:"抽取器",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"抽取器类型",name:"extractorType",rules:[{required:!0}],extra:"STANDARD_JSON/RSS_XML/ATOM_XML 直接解析; CUSTOM_SCRIPT 调 z-script 平台",children:u.jsx(c.Select,{options:_s})}),R==="CUSTOM_SCRIPT"&&u.jsx(c.Form.Item,{label:"z-script 脚本",name:"extractorScriptCode",rules:[{required:!0,message:"请选择脚本"}],extra:"在 智能中心 > 脚本中心 维护脚本. 脚本返回 { items: [...], nextCursor: '...' }",children:u.jsx(c.Select,{showSearch:!0,placeholder:"选择已启用的脚本",options:b.map(p=>({value:p.scriptCode,label:`${p.scriptCode} (${p.dslType})${p.scriptName?" - "+p.scriptName:""}`}))})})]}),u.jsxs(c.Card,{type:"inner",title:"调度",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"Cron 表达式",name:"cronExpr",rules:[{required:!0,message:"请输入 Cron"}],extra:"Quartz 兼容, 例如 0 */5 * * * ? = 每 5 分钟",children:u.jsx(c.Input,{addonAfter:u.jsx(c.Select,{style:{width:140},placeholder:"常用",options:Cs,onChange:p=>n.setFieldValue("cronExpr",p),value:null})})}),u.jsxs(c.Space,{size:"large",children:[u.jsx(c.Form.Item,{label:"启用",name:"enabled",valuePropName:"checked",children:u.jsxs(c.Radio.Group,{children:[u.jsx(c.Radio.Button,{value:!0,children:"启用"}),u.jsx(c.Radio.Button,{value:!1,children:"停用"})]})}),u.jsx(c.Form.Item,{label:"最小间隔 (秒)",name:"minIntervalSec",extra:"距上次 run 至少 N 秒",children:u.jsx(c.InputNumber,{min:0,max:3600})}),u.jsx(c.Form.Item,{label:"单次最多条数",name:"maxItemsPerRun",children:u.jsx(c.InputNumber,{min:1,max:1e4})})]})]}),u.jsx(c.Alert,{type:"success",showIcon:!0,message:"保存后会自动 dry-run: 真实 HTTP 一次, 把响应喂给抽取器, 失败时订阅进入 INVALID_AUTH 状态, 不会自动调度."})]})})})})}const Ns={PENDING:"default",RUNNING:"processing",SUCCESS:"green",EMPTY:"default",FAILED:"red",FATAL:"red"};function ir(){const[e,t]=I.useState([]),[r,n]=I.useState(null),[s,o]=I.useState([]),[a,f]=I.useState([]),[d,g]=I.useState(null),[b,x]=I.useState(!1);I.useEffect(()=>{O()},[]),I.useEffect(()=>{r&&R(r)},[r]);const O=async()=>{try{const m=await q.get("/subscribe/subscription/list"),p=(m==null?void 0:m.data)??m??[];t(Array.isArray(p)?p:[]),Array.isArray(p)&&p.length>0&&n(p[0].id)}catch{c.message.error("加载订阅列表失败")}},R=async m=>{x(!0);try{const p=await q.get(`/subscribe/run/list?subscriptionId=${m}&limit=50`),v=(p==null?void 0:p.data)??p??[];o(Array.isArray(v)?v:[])}catch{c.message.error("加载运行历史失败")}finally{x(!1)}},N=async m=>{g(m);try{const p=await q.get(`/subscribe/run/${m}/items?limit=200`),v=(p==null?void 0:p.data)??p??[];f(Array.isArray(v)?v:[])}catch{c.message.error("加载抽取项失败")}},T=s.reduce((m,p)=>m+(p.successCount||0),0),B=s.reduce((m,p)=>m+(p.deadLetterCount||0),0),y=s.reduce((m,p)=>m+(p.duplicateCount||0),0);return u.jsx("div",{style:{padding:24},children:u.jsxs(c.Card,{title:u.jsxs(c.Space,{children:[u.jsx(D.ApiOutlined,{}),"订阅中心 - 运行历史"]}),extra:u.jsxs(c.Space,{children:[u.jsx(c.Select,{style:{width:280},placeholder:"选择订阅",value:r,onChange:n,options:e.map(m=>({value:m.id,label:m.name})),showSearch:!0,optionFilterProp:"label"}),u.jsxs("a",{onClick:()=>r&&R(r),children:[u.jsx(D.ReloadOutlined,{})," 刷新"]})]}),children:[u.jsxs(c.Row,{gutter:16,style:{marginBottom:16},children:[u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"run 总数",value:s.length})})}),u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"成功条数",value:T,valueStyle:{color:"#3f8600"}})})}),u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"死信条数",value:B,valueStyle:{color:"#cf1322"}})})}),u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"重复跳过",value:y})})})]}),u.jsxs(c.Row,{gutter:16,children:[u.jsx(c.Col,{span:12,children:u.jsx(c.Card,{type:"inner",title:`运行列表 (${s.length})`,size:"small",children:u.jsx(c.Table,{rowKey:"id",size:"small",loading:b,dataSource:s,pagination:{pageSize:10},onRow:m=>({onClick:()=>N(m.id),style:{cursor:"pointer",background:m.id===d?"#e6f7ff":""}}),columns:[{title:"ID",dataIndex:"id",width:60},{title:"计划",dataIndex:"scheduledAt",width:150,render:m=>m?new Date(m).toLocaleString():"-"},{title:"耗时",dataIndex:"durationMs",width:80},{title:"状态",dataIndex:"status",width:80,render:m=>u.jsx(c.Tag,{color:Ns[m],children:m})},{title:"拉取/成功/死信",width:150,render:(m,p)=>`${p.fetchedCount} / ${p.successCount} / ${p.deadLetterCount}`}]})})}),u.jsx(c.Col,{span:12,children:u.jsx(c.Card,{type:"inner",title:d?`run#${d} 抽取项 (${a.length})`:"抽取项",size:"small",children:a.length===0?u.jsx(c.Empty,{description:d?"该 run 无抽取项":"点击左侧 run 查看抽取项"}):u.jsx(c.Table,{rowKey:"id",size:"small",dataSource:a,pagination:{pageSize:10},columns:[{title:"id",dataIndex:"dedupKey",width:160,ellipsis:!0},{title:"title",dataIndex:"normalized",render:m=>{try{return JSON.parse(m).title||"(无标题)"}catch{return m}}},{title:"link",dataIndex:"normalized",width:60,render:m=>{try{const p=JSON.parse(m);return p.link?u.jsx("a",{href:p.link,target:"_blank",children:"↗"}):"-"}catch{return"-"}}},{title:"状态",dataIndex:"status",width:100,render:m=>u.jsx(c.Tag,{children:m})}]})})})]})]})})}function Ps(){return u.jsxs(re.Routes,{children:[u.jsx(re.Route,{index:!0,element:u.jsx(re.Navigate,{to:"list",replace:!0})}),u.jsx(re.Route,{path:"list",element:u.jsx(or,{})}),u.jsx(re.Route,{path:"new",element:u.jsx(lt,{})}),u.jsx(re.Route,{path:"edit/:id",element:u.jsx(lt,{})}),u.jsx(re.Route,{path:"runs",element:u.jsx(ir,{})})]})}X.RunHistory=ir,X.SubscribeApp=Ps,X.SubscriptionEdit=lt,X.SubscriptionList=or,Object.defineProperty(X,Symbol.toStringTag,{value:"Module"})}));
|
|
51
|
+
`+s)}}catch{}}throw r}}_request(e,t){typeof e=="string"?(t=t||{},t.url=e):t=e||{},t=pe(this.defaults,t);const{transitional:r,paramsSerializer:n,headers:s}=t;r!==void 0&&Je.assertOptions(r,{silentJSONParsing:$.transitional($.boolean),forcedJSONParsing:$.transitional($.boolean),clarifyTimeoutError:$.transitional($.boolean),legacyInterceptorReqResOrdering:$.transitional($.boolean),advertiseZstdAcceptEncoding:$.transitional($.boolean),validateStatusUndefinedResolves:$.transitional($.boolean)},!1),n!=null&&(l.isFunction(n)?t.paramsSerializer={serialize:n}:Je.assertOptions(n,{encode:$.function,serialize:$.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),Je.assertOptions(t,{baseUrl:$.spelling("baseURL"),withXsrfToken:$.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let o=s&&l.merge(s.common,s[t.method]);s&&l.forEach(["delete","get","head","post","put","patch","query","common"],R=>{delete s[R]}),t.headers=M.concat(o,s);const a=[];let f=!0;this.interceptors.request.forEach(function(R){if(typeof R.runWhen=="function"&&R.runWhen(t)===!1)return;f=f&&R.synchronous;const N=t.transitional||et;N&&N.legacyInterceptorReqResOrdering?a.unshift(R.fulfilled,R.rejected):a.push(R.fulfilled,R.rejected)});const d=[];this.interceptors.response.forEach(function(R){d.push(R.fulfilled,R.rejected)});let g,b=0,x;if(!f){const R=[Qt.bind(this),void 0];for(R.unshift(...a),R.push(...d),x=R.length,g=Promise.resolve(t);b<x;)g=g.then(R[b++],R[b++]);return g}x=a.length;let O=t;for(;b<x;){const R=a[b++],N=a[b++];try{O=R(O)}catch(T){N.call(this,T);break}}try{g=Qt.call(this,O)}catch(R){return Promise.reject(R)}for(b=0,x=d.length;b<x;)g=g.then(d[b++],d[b++]);return g}getUri(e){e=pe(this.defaults,e);const t=qt(e.baseURL,e.url,e.allowAbsoluteUrls,e);return kt(t,e.params,e.paramsSerializer)}};l.forEach(["delete","get","head","options"],function(e){he.prototype[e]=function(t,r){return this.request(pe(r||{},{method:e,url:t,data:r&&l.hasOwnProp(r,"data")?r.data:void 0}))}}),l.forEach(["post","put","patch","query"],function(e){function t(r){return function(n,s,o){return this.request(pe(o||{},{method:e,headers:r?{"Content-Type":"multipart/form-data"}:{},url:n,data:s}))}}he.prototype[e]=t(),e!=="query"&&(he.prototype[e+"Form"]=t(!0))});let ys=class fr{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(s){r=s});const n=this;this.promise.then(s=>{if(!n._listeners)return;let o=n._listeners.length;for(;o-- >0;)n._listeners[o](s);n._listeners=null}),this.promise.then=s=>{let o;const a=new Promise(f=>{n.subscribe(f),o=f}).then(s);return a.cancel=function(){n.unsubscribe(o)},a},t(function(s,o,a){n.reason||(n.reason=new Ne(s,o,a),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const r=this._listeners.indexOf(t);r!==-1&&this._listeners.splice(r,1)}toAbortSignal(){const t=new AbortController,r=n=>{t.abort(n)};return this.subscribe(r),t.signal.unsubscribe=()=>this.unsubscribe(r),t.signal}static source(){let t;return{token:new fr(function(r){t=r}),cancel:t}}};function gs(e){return function(t){return e.apply(null,t)}}function Ss(e){return l.isObject(e)&&e.isAxiosError===!0}const at={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(at).forEach(([e,t])=>{at[t]=e});function tr(e){const t=new he(e),r=bt(he.prototype.request,t);return l.extend(r,he.prototype,t,{allOwnKeys:!0}),l.extend(r,t,null,{allOwnKeys:!0}),r.create=function(n){return tr(pe(e,n))},r}const F=tr(Ce);F.Axios=he,F.CanceledError=Ne,F.CancelToken=ys,F.isCancel=Bt,F.VERSION=st,F.toFormData=ze,F.AxiosError=w,F.Cancel=F.CanceledError,F.all=function(e){return Promise.all(e)},F.spread=gs,F.isAxiosError=Ss,F.mergeConfig=pe,F.AxiosHeaders=M,F.formToJSON=e=>Dt(l.isHTMLForm(e)?new FormData(e):e),F.getAdapter=Zt.getAdapter,F.HttpStatusCode=at,F.default=F;const{Axios:Ds,AxiosError:Bs,CanceledError:Us,isCancel:zs,CancelToken:Ms,VERSION:$s,all:qs,Cancel:Hs,isAxiosError:Js,spread:Ws,toFormData:Vs,AxiosHeaders:Xs,HttpStatusCode:Ks,formToJSON:Ys,getAdapter:Gs,mergeConfig:Zs,create:Qs}=F;function xs(e){if(e&&typeof e=="object"&&"code"in e&&"data"in e){const t=e;return t.code!==200?Promise.reject(new Error(t.message||"请求失败")):t.data}return e}function Es(e,t={}){const{tokenKey:r="token",userInfoKey:n="userInfo",unauthorizedRedirect:s="/login"}=t;e.interceptors.request.use(o=>{const a=localStorage.getItem(r);return a&&(o.headers.Authorization=`Bearer ${a}`),o}),e.interceptors.response.use(o=>xs(o.data),o=>{var a,f,d;return((a=o.response)==null?void 0:a.status)===401?(localStorage.removeItem(r),localStorage.removeItem(n),window.location.href=s):((f=o.response)==null?void 0:f.status)===403?console.error("没有权限访问该资源"):((d=o.response)==null?void 0:d.status)===500&&console.error("服务器内部错误"),Promise.reject(o)})}function rr(e={}){const t=F.create({baseURL:e.baseURL??"/api",timeout:e.timeout??1e4});return Es(t,{tokenKey:e.tokenKey,userInfoKey:e.userInfoKey,unauthorizedRedirect:e.unauthorizedRedirect}),t}const q=rr();rr();class eo extends I.Component{constructor(t){super(t),yr(this,"handleReset",()=>{this.setState({hasError:!1,error:null,errorInfo:null}),typeof this.props.onReset=="function"&&this.props.onReset()}),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,r){console.error("[ErrorBoundary] caught error:",t,r),this.setState({errorInfo:r})}render(){if(!this.state.hasError)return this.props.children;const{fallbackTitle:t="组件加载失败",fallbackDescription:r,showReload:n=!0}=this.props,s=this.state.error&&(this.state.error.message||String(this.state.error))||"未知错误";return Y.jsxs("div",{style:{padding:24,background:"#fff2f0",border:"1px solid #ffccc7",borderRadius:8,minHeight:200},children:[Y.jsx(c.Alert,{type:"error",showIcon:!0,icon:Y.jsx(D.BugOutlined,{}),message:t,description:Y.jsxs("div",{children:[Y.jsx("div",{style:{marginBottom:8},children:r||"当前组件发生了异常,已被错误边界捕获。其他功能仍可正常使用。"}),Y.jsx("div",{style:{fontFamily:"Menlo, Monaco, Consolas, monospace",fontSize:12,color:"#cf1322",background:"#fff",padding:8,borderRadius:4,border:"1px solid #ffccc7",wordBreak:"break-word",whiteSpace:"pre-wrap"},children:s})]})}),n&&Y.jsx(c.Space,{style:{marginTop:16},children:Y.jsx(c.Button,{icon:Y.jsx(D.ReloadOutlined,{}),onClick:this.handleReset,children:"重试"})})]})}}const{Title:to,Text:ro,Paragraph:no}=c.Typography;let ws="/api";function nr(){return F.create({baseURL:ws,timeout:15e3})}const Rs=nr();nr(),Rs.interceptors.request.use(e=>{const t=localStorage.getItem("token");return t&&(e.headers.Authorization=`Bearer ${t}`),e});const{Header:so,Sider:oo,Content:io}=c.Layout,{Text:ao}=c.Typography,{Title:lo,Text:co}=c.Typography,{Option:uo}=c.Select,{TextArea:fo}=c.Input,Ts=[{type:"STRING",label:"字符串",icon:Y.jsx(D.FileTextOutlined,{}),color:"#1677ff",desc:"短文本 (默认 VARCHAR 255)"},{type:"TEXT",label:"长文本",icon:Y.jsx(D.FileTextOutlined,{}),color:"#13c2c2",desc:"TEXT 类型, 无长度限制"},{type:"INT",label:"整数",icon:"#",color:"#722ed1",desc:"INT 整数"},{type:"LONG",label:"长整数",icon:"#",color:"#722ed1",desc:"BIGINT 长整数"},{type:"DECIMAL",label:"小数",icon:"0.00",color:"#eb2f96",desc:"DECIMAL 精确小数"},{type:"BOOLEAN",label:"布尔",icon:Y.jsx(D.CheckCircleOutlined,{}),color:"#52c41a",desc:"TINYINT(1) 是/否"},{type:"DATE",label:"日期",icon:"📅",color:"#fa8c16",desc:"DATE yyyy-MM-dd"},{type:"DATETIME",label:"日期时间",icon:"🕐",color:"#fa8c16",desc:"DATETIME yyyy-MM-dd HH:mm:ss"},{type:"JSON",label:"JSON",icon:"{}",color:"#2f54eb",desc:"JSON 字符串"},{type:"REF",label:"引用",icon:"🔗",color:"#8c8c8c",desc:"外键引用 BIGINT"}];Object.fromEntries(Ts.map(e=>[e.type,e]));const{Option:po}=c.Select;c.Input.TextArea,c.Input.TextArea;const{Text:ho,Paragraph:mo}=c.Typography,{TextArea:bo}=c.Input,{TextArea:yo}=c.Input,{Text:go,Paragraph:So}=c.Typography,{TextArea:xo}=c.Input,{Text:Eo,Paragraph:wo}=c.Typography,{Text:Ro}=c.Typography,{Text:To}=c.Typography,{TextArea:Oo}=c.Input,{Text:vo,Paragraph:jo}=c.Typography,{Text:_o}=c.Typography,{Text:Ao}=c.Typography,{Text:Co}=c.Typography,{Text:No}=c.Typography,Os={STANDARD_JSON:{label:"标准 JSON",color:"blue"},RSS_XML:{label:"RSS 2.0",color:"orange"},ATOM_XML:{label:"Atom 1.0",color:"gold"},CUSTOM_SCRIPT:{label:"自定义脚本",color:"purple"},INTERNAL_BEAN:{label:"内部 Bean",color:"cyan"}},vs={PENDING_VERIFY:{color:"default",text:"待验证"},VERIFIED:{color:"green",text:"已验证"},INVALID_AUTH:{color:"red",text:"鉴权失败"},FATAL:{color:"red",text:"永久失败"},DISABLED:{color:"default",text:"已停用"}},sr={PENDING:{color:"default"},RUNNING:{color:"processing"},SUCCESS:{color:"green"},EMPTY:{color:"default"},FAILED:{color:"red"},FATAL:{color:"red"}};function or(){const e=re.useNavigate(),[t,r]=I.useState([]),[n,s]=I.useState(!1),[o,a]=I.useState(null),[f,d]=I.useState([]),[g,b]=I.useState({}),[x,O]=I.useState(null),[R,N]=I.useState([]),T=async()=>{s(!0);try{const S=await q.get("/subscribe/subscription/list");S&&S.success!==!1&&r(Array.isArray(S.data)?S.data:Array.isArray(S)?S:[])}catch(S){c.message.error("获取订阅列表失败: "+((S==null?void 0:S.message)||""))}finally{s(!1)}};I.useEffect(()=>{T()},[]);const B=S=>{c.Modal.confirm({title:"确认删除",icon:u.jsx(D.ExclamationCircleOutlined,{}),content:`确定要删除订阅 "${S.name}" 吗? 运行历史会保留.`,onOk:async()=>{try{const h=await q.delete(`/subscribe/subscription/${S.id}`);h&&h.success!==!1?(c.message.success("删除成功"),T()):c.message.error((h==null?void 0:h.message)||"删除失败")}catch(h){c.message.error("删除失败: "+((h==null?void 0:h.message)||""))}}})},y=async S=>{try{const h=await q.post(`/subscribe/subscription/${S}/enable`);h&&h.success!==!1?(c.message.success("已启用"),T()):c.message.error((h==null?void 0:h.message)||"启用失败")}catch(h){c.message.error("启用失败: "+((h==null?void 0:h.message)||""))}},m=async S=>{try{const h=await q.post(`/subscribe/subscription/${S}/disable`);h&&h.success!==!1?(c.message.success("已停用"),T()):c.message.error((h==null?void 0:h.message)||"停用失败")}catch(h){c.message.error("停用失败: "+((h==null?void 0:h.message)||""))}},p=async S=>{c.Modal.confirm({title:"手动触发",content:`将立即执行一次 "${S.name}" 的抽取, 同步返回 runId.`,onOk:async()=>{try{const h=await q.post(`/subscribe/subscription/${S.id}/trigger?triggerBy=ceo`);if(h&&(h.data!==void 0||h.success!==!1)){const L=h.data??h;c.message.success(`已触发, runId = ${L}`),k(S)}else c.message.error((h==null?void 0:h.message)||"触发失败")}catch(h){c.message.error("触发失败: "+((h==null?void 0:h.message)||""))}}})},v=async S=>{try{const h=await q.post(`/subscribe/subscription/${S.id}/dry-run`);a({sub:S,result:(h==null?void 0:h.data)??h})}catch(h){a({sub:S,result:{success:!1,errorMessage:(h==null?void 0:h.message)||"请求失败"}})}},k=async S=>{try{const h=await q.get(`/subscribe/run/list?subscriptionId=${S.id}&limit=20`),L=(h==null?void 0:h.data)??h??[];d(Array.isArray(L)?L:[]),O(null),b({}),N([]),a({sub:S,tab:"runs"})}catch{c.message.error("获取运行历史失败")}},ne=async S=>{if(g[S]){O(S);return}try{const h=await q.get(`/subscribe/run/${S}/items?limit=200`),L=(h==null?void 0:h.data)??h??[];b(J=>({...J,[S]:Array.isArray(L)?L:[]})),O(S)}catch{c.message.error("获取抽取项失败")}},me=[{title:"ID",dataIndex:"id",width:70},{title:"名称",dataIndex:"name",render:(S,h)=>u.jsxs(c.Space,{orientation:"vertical",size:0,children:[u.jsx("span",{style:{fontWeight:500},children:S}),h.description&&u.jsx("span",{style:{color:"#999",fontSize:12},children:h.description})]})},{title:"数据源",dataIndex:"sourceType",width:90,render:S=>u.jsx(c.Tag,{children:S})},{title:"抽取器",dataIndex:"extractorType",width:140,render:S=>{const h=Os[S]||{label:S,color:"default"};return u.jsx(c.Tag,{color:h.color,children:h.label})}},{title:"Cron",dataIndex:"cronExpr",width:150,render:S=>u.jsx("code",{style:{fontSize:12},children:S})},{title:"状态",dataIndex:"status",width:110,render:S=>{const h=vs[S]||{color:"default",text:S};return u.jsx(c.Tag,{color:h.color,children:h.text})}},{title:"启用",dataIndex:"enabled",width:80,render:(S,h)=>S?u.jsx(c.Tag,{color:"green",children:"是"}):u.jsx(c.Tag,{children:"否"})},{title:"最近 run",dataIndex:"lastStatus",width:110,render:(S,h)=>{var L;return S?u.jsx(c.Tooltip,{title:h.lastError||"",children:u.jsx(c.Tag,{color:((L=sr[S])==null?void 0:L.color)||"default",children:S})}):u.jsx("span",{style:{color:"#ccc"},children:"-"})}},{title:"累计",width:130,render:(S,h)=>u.jsxs(c.Space,{size:4,children:[u.jsxs(c.Tag,{color:"green",children:["✓ ",h.successCountTotal||0]}),u.jsxs(c.Tag,{color:"red",children:["✗ ",h.failCountTotal||0]})]})},{title:"操作",width:280,fixed:"right",render:(S,h)=>u.jsxs(c.Space,{size:4,wrap:!0,children:[u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.EditOutlined,{}),onClick:()=>e(`/subscribe/edit/${h.id}`),children:"编辑"}),u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.ThunderboltOutlined,{}),onClick:()=>v(h),children:"试运行"}),u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.PlayCircleOutlined,{}),onClick:()=>p(h),children:"触发"}),u.jsx(c.Button,{type:"link",size:"small",onClick:()=>k(h),children:"历史"}),h.enabled?u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.PauseCircleOutlined,{}),onClick:()=>m(h.id),children:"停用"}):u.jsx(c.Button,{type:"link",size:"small",icon:u.jsx(D.CheckCircleOutlined,{}),onClick:()=>y(h.id),children:"启用"}),u.jsx(c.Popconfirm,{title:"确认删除?",onConfirm:()=>B(h),okText:"删除",cancelText:"取消",children:u.jsx(c.Button,{type:"link",size:"small",danger:!0,icon:u.jsx(D.DeleteOutlined,{}),children:"删除"})})]})}];return u.jsxs("div",{style:{padding:24},children:[u.jsxs(c.Card,{title:u.jsxs(c.Space,{children:[u.jsx(D.ApiOutlined,{}),"订阅中心 - 数据源订阅"]}),extra:u.jsxs(c.Space,{children:[u.jsx(c.Button,{icon:u.jsx(D.ReloadOutlined,{}),onClick:T,children:"刷新"}),u.jsx(c.Button,{type:"primary",icon:u.jsx(D.PlusOutlined,{}),onClick:()=>e("/subscribe/new"),children:"新建订阅"})]}),children:[u.jsx(c.Alert,{type:"info",showIcon:!0,style:{marginBottom:16},message:"订阅中心负责把三方 / 内部 / RSS 等数据源按 Cron 定时抽取, 归一化后落到本地, 供 CEO 立项和 Agent 协作使用."}),u.jsx(c.Table,{rowKey:"id",columns:me,dataSource:t,loading:n,scroll:{x:1400},size:"middle",pagination:{pageSize:20,showSizeChanger:!0,showTotal:S=>`共 ${S} 条`}})]}),u.jsx(c.Drawer,{title:o!=null&&o.sub?`试运行 - ${o.sub.name}`:"运行历史",open:!!o,onClose:()=>a(null),width:900,children:(o==null?void 0:o.tab)==="runs"?u.jsx(c.Tabs,{activeKey:x?"items":"list",onChange:S=>S==="list"&&O(null),items:[{key:"list",label:`运行列表 (${f.length})`,children:u.jsx(c.Table,{rowKey:"id",size:"small",dataSource:f,pagination:!1,onRow:S=>({onClick:()=>ne(S.id)}),columns:[{title:"runId",dataIndex:"id",width:70},{title:"计划",dataIndex:"scheduledAt",width:160,render:S=>S?new Date(S).toLocaleString():"-"},{title:"耗时(ms)",dataIndex:"durationMs",width:90},{title:"状态",dataIndex:"status",width:90,render:S=>{var h;return u.jsx(c.Tag,{color:(h=sr[S])==null?void 0:h.color,children:S})}},{title:"拉取/成功/重复/死信",width:200,render:(S,h)=>`${h.fetchedCount} / ${h.successCount} / ${h.duplicateCount||0} / ${h.deadLetterCount}`},{title:"错误",dataIndex:"errorMessage",render:S=>S?u.jsx("span",{style:{color:"#cf1322",fontSize:12},children:S}):"-"}]})},{key:"items",label:x?`run#${x} 抽取项`:"抽取项",disabled:!x,children:u.jsxs(c.Space,{orientation:"vertical",style:{width:"100%"},children:[u.jsxs(c.Space,{children:[u.jsxs(c.Tag,{color:"blue",children:["已选 ",R.length," 条"]}),u.jsxs(c.Button,{size:"small",type:"primary",icon:u.jsx(D.ProjectOutlined,{}),disabled:R.length===0,onClick:()=>{const S=R.join(",");e(`/project/new?subscriptionId=${o.sub.id}&itemIds=${S}`)},children:["用所选 ",R.length," 条立项"]})]}),u.jsx(c.Table,{rowKey:"id",size:"small",dataSource:g[x]||[],pagination:{pageSize:20},rowSelection:{selectedRowKeys:R,onChange:N},columns:[{title:"id",dataIndex:"dedupKey",width:180,ellipsis:!0},{title:"title",dataIndex:"normalized",render:S=>{try{return JSON.parse(S).title||"(无标题)"}catch{return S}}},{title:"link",dataIndex:"normalized",render:S=>{try{const h=JSON.parse(S);return h.link?u.jsx("a",{href:h.link,target:"_blank",children:"↗"}):"-"}catch{return"-"}}},{title:"状态",dataIndex:"status",width:110,render:S=>u.jsx(c.Tag,{children:S})}]})]})}]}):u.jsx(js,{result:o==null?void 0:o.result})})]})}function js({result:e}){return e?e.success?u.jsxs(c.Space,{orientation:"vertical",style:{width:"100%"},size:"middle",children:[u.jsx(c.Card,{size:"small",title:"调用结果",children:u.jsxs(c.Space,{size:"large",wrap:!0,children:[u.jsxs("span",{children:[u.jsx("b",{children:"HTTP:"})," ",e.httpStatus||"-"]}),u.jsxs("span",{children:[u.jsx("b",{children:"耗时:"})," ",e.latencyMs,"ms"]}),u.jsxs("span",{children:[u.jsx("b",{children:"大小:"})," ",e.responseSize,"B"]}),u.jsxs("span",{children:[u.jsx("b",{children:"样本:"})," ",e.sampleCount," 条"]})]})}),e.firstItem&&u.jsx(c.Card,{size:"small",title:"第一条样本 (归一化后)",children:u.jsx("pre",{style:{background:"#f5f5f5",padding:12,borderRadius:4,maxHeight:300,overflow:"auto"},children:JSON.stringify(e.firstItem,null,2)})}),e.responsePreview&&u.jsx(c.Card,{size:"small",title:"响应预览 (前 4KB)",children:u.jsx("pre",{style:{background:"#f5f5f5",padding:12,borderRadius:4,maxHeight:300,overflow:"auto",fontSize:12},children:e.responsePreview})}),e.fieldErrors&&e.fieldErrors.length>0&&u.jsx(c.Alert,{type:"warning",showIcon:!0,message:"字段问题",description:u.jsx("ul",{children:e.fieldErrors.map((t,r)=>u.jsx("li",{children:t},r))})})]}):u.jsx(c.Alert,{type:"error",showIcon:!0,message:"试运行失败",description:e.errorMessage||"未知错误"}):null}const _s=[{value:"STANDARD_JSON",label:"标准 JSON (按统一契约返回的 JSON)"},{value:"RSS_XML",label:"RSS 2.0 (XML feed)"},{value:"ATOM_XML",label:"Atom 1.0 (XML feed)"},{value:"CUSTOM_SCRIPT",label:"自定义脚本 (z-script 平台)"},{value:"INTERNAL_BEAN",label:"内部 Bean (我们自己的模块, 暂未启用)"}],As=[{value:"NONE",label:"无鉴权"},{value:"BEARER",label:"Bearer (Authorization: Bearer xxx)"},{value:"API_KEY",label:"API Key (Authorization: xxx)"},{value:"BASIC",label:"Basic (user:password base64)"}],Cs=[{label:"每 5 分钟",value:"0 */5 * * * ?"},{label:"每 15 分钟",value:"0 */15 * * * ?"},{label:"每小时",value:"0 0 * * * ?"},{label:"每 6 小时",value:"0 0 */6 * * ?"},{label:"每天 8 点",value:"0 0 8 * * ?"}];function lt(){const{id:e}=re.useParams(),t=re.useNavigate(),r=!!e,[n]=c.Form.useForm(),[s,o]=I.useState(!1),[a,f]=I.useState(!1),[d,g]=I.useState([]),[b,x]=I.useState([]),O=c.Form.useWatch("sourceType",n),R=c.Form.useWatch("extractorType",n),N=c.Form.useWatch("authType",n);I.useEffect(()=>{T(),B(),r&&y()},[e]);const T=async()=>{try{const p=await q.get("/secret/list"),v=(p==null?void 0:p.data)??p??[];g(Array.isArray(v)?v:[])}catch{}},B=async()=>{try{const p=await q.get("/script/list"),v=(p==null?void 0:p.data)??p??[];x(Array.isArray(v)?v.filter(k=>k.status===1):[])}catch{}},y=async()=>{o(!0);try{const p=await q.get(`/subscribe/subscription/${e}`),v=(p==null?void 0:p.data)??p;v&&n.setFieldsValue({...v,enabled:v.enabled===1||v.enabled===!0})}catch(p){c.message.error("加载订阅失败: "+((p==null?void 0:p.message)||""))}finally{o(!1)}},m=async()=>{try{const p=await n.validateFields();f(!0);const v={...p,enabled:p.enabled?1:0};let k;if(r?k=await q.put("/subscribe/subscription",v):k=await q.post("/subscribe/subscription",v),k&&k.success===!1){c.message.error(k.message||"保存失败");return}c.message.success(r?"已更新 (注意: 修改 cron / url / 抽取器后会自动重置为 PENDING_VERIFY)":"已创建, 已自动验证"),t("/subscribe/list")}catch(p){p!=null&&p.errorFields?c.message.warning("请检查表单"):c.message.error("保存失败: "+((p==null?void 0:p.message)||""))}finally{f(!1)}};return u.jsx("div",{style:{padding:24},children:u.jsx(c.Card,{title:u.jsxs(c.Space,{children:[u.jsx(c.Button,{type:"text",icon:u.jsx(D.ArrowLeftOutlined,{}),onClick:()=>t("/subscribe/list")}),u.jsx(D.ApiOutlined,{}),r?`编辑订阅 #${e}`:"新建订阅"]}),extra:u.jsxs(c.Space,{children:[u.jsx(c.Button,{onClick:()=>t("/subscribe/list"),children:"取消"}),u.jsx(c.Button,{type:"primary",icon:u.jsx(D.SaveOutlined,{}),loading:a,onClick:m,children:"保存 (自动验证)"})]}),children:u.jsx(c.Spin,{spinning:s,children:u.jsxs(c.Form,{form:n,layout:"vertical",initialValues:{sourceType:"HTTP",httpMethod:"GET",authType:"NONE",extractorType:"STANDARD_JSON",enabled:!0,minIntervalSec:60,maxItemsPerRun:1e3,timeoutMs:15e3},children:[u.jsxs(c.Card,{type:"inner",title:"基本信息",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"名称",name:"name",rules:[{required:!0,message:"请输入名称"}],children:u.jsx(c.Input,{placeholder:"例如: GitHub PR 通知"})}),u.jsx(c.Form.Item,{label:"说明",name:"description",children:u.jsx(c.Input.TextArea,{rows:2,placeholder:"(可选)"})})]}),u.jsxs(c.Card,{type:"inner",title:"数据源",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"数据源形态",name:"sourceType",rules:[{required:!0}],children:u.jsxs(c.Radio.Group,{children:[u.jsx(c.Radio.Button,{value:"HTTP",children:"HTTP / HTTPS"}),u.jsx(c.Radio.Button,{value:"INTERNAL",disabled:!0,children:"内部 Bean (TODO)"})]})}),O==="HTTP"&&u.jsxs(u.Fragment,{children:[u.jsx(c.Form.Item,{label:"目标 URL",name:"targetUrl",rules:[{required:!0,message:"请输入 URL"}],children:u.jsx(c.Input,{placeholder:"https://api.github.com/repos/.../pulls?state=open"})}),u.jsxs(c.Space,{size:"large",style:{width:"100%"},children:[u.jsx(c.Form.Item,{label:"HTTP 方法",name:"httpMethod",children:u.jsx(c.Select,{style:{width:120},options:[{value:"GET",label:"GET"},{value:"POST",label:"POST"},{value:"PUT",label:"PUT"}]})}),u.jsx(c.Form.Item,{label:"超时 (ms)",name:"timeoutMs",children:u.jsx(c.InputNumber,{min:1e3,max:12e4,step:1e3})})]}),u.jsx(c.Form.Item,{label:"自定义 HTTP 头 (JSON)",name:"httpHeaders",children:u.jsx(c.Input.TextArea,{rows:2,placeholder:'{"X-Trace-Id":"abc"}'})}),u.jsx(c.Form.Item,{label:"请求体 (POST/PUT)",name:"requestBody",children:u.jsx(c.Input.TextArea,{rows:3,placeholder:"(可选)"})})]})]}),u.jsxs(c.Card,{type:"inner",title:"鉴权 (从 z-mist 拉取 secret)",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"鉴权方式",name:"authType",children:u.jsx(c.Select,{options:As})}),N&&N!=="NONE"&&u.jsx(c.Form.Item,{label:"z-mist 凭据引用",name:"authSecretKey",extra:"从密钥中心 (z-mist) 选一个 secret; secret 的解密值会作为 secret 注入",children:u.jsx(c.Select,{showSearch:!0,allowClear:!0,placeholder:"选择 secret (key)",options:d.map(p=>({value:p.secretKey,label:`${p.secretKey}${p.secretName?" ("+p.secretName+")":""}`}))})})]}),u.jsxs(c.Card,{type:"inner",title:"抽取器",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"抽取器类型",name:"extractorType",rules:[{required:!0}],extra:"STANDARD_JSON/RSS_XML/ATOM_XML 直接解析; CUSTOM_SCRIPT 调 z-script 平台",children:u.jsx(c.Select,{options:_s})}),R==="CUSTOM_SCRIPT"&&u.jsx(c.Form.Item,{label:"z-script 脚本",name:"extractorScriptCode",rules:[{required:!0,message:"请选择脚本"}],extra:"在 智能中心 > 脚本中心 维护脚本. 脚本返回 { items: [...], nextCursor: '...' }",children:u.jsx(c.Select,{showSearch:!0,placeholder:"选择已启用的脚本",options:b.map(p=>({value:p.scriptCode,label:`${p.scriptCode} (${p.dslType})${p.scriptName?" - "+p.scriptName:""}`}))})})]}),u.jsxs(c.Card,{type:"inner",title:"调度",style:{marginBottom:16},children:[u.jsx(c.Form.Item,{label:"Cron 表达式",name:"cronExpr",rules:[{required:!0,message:"请输入 Cron"}],extra:"Quartz 兼容, 例如 0 */5 * * * ? = 每 5 分钟",children:u.jsx(c.Input,{addonAfter:u.jsx(c.Select,{style:{width:140},placeholder:"常用",options:Cs,onChange:p=>n.setFieldValue("cronExpr",p),value:null})})}),u.jsxs(c.Space,{size:"large",children:[u.jsx(c.Form.Item,{label:"启用",name:"enabled",valuePropName:"checked",children:u.jsxs(c.Radio.Group,{children:[u.jsx(c.Radio.Button,{value:!0,children:"启用"}),u.jsx(c.Radio.Button,{value:!1,children:"停用"})]})}),u.jsx(c.Form.Item,{label:"最小间隔 (秒)",name:"minIntervalSec",extra:"距上次 run 至少 N 秒",children:u.jsx(c.InputNumber,{min:0,max:3600})}),u.jsx(c.Form.Item,{label:"单次最多条数",name:"maxItemsPerRun",children:u.jsx(c.InputNumber,{min:1,max:1e4})})]})]}),u.jsx(c.Alert,{type:"success",showIcon:!0,message:"保存后会自动 dry-run: 真实 HTTP 一次, 把响应喂给抽取器, 失败时订阅进入 INVALID_AUTH 状态, 不会自动调度."})]})})})})}const Ns={PENDING:"default",RUNNING:"processing",SUCCESS:"green",EMPTY:"default",FAILED:"red",FATAL:"red"};function ir(){const[e,t]=I.useState([]),[r,n]=I.useState(null),[s,o]=I.useState([]),[a,f]=I.useState([]),[d,g]=I.useState(null),[b,x]=I.useState(!1);I.useEffect(()=>{O()},[]),I.useEffect(()=>{r&&R(r)},[r]);const O=async()=>{try{const m=await q.get("/subscribe/subscription/list"),p=(m==null?void 0:m.data)??m??[];t(Array.isArray(p)?p:[]),Array.isArray(p)&&p.length>0&&n(p[0].id)}catch{c.message.error("加载订阅列表失败")}},R=async m=>{x(!0);try{const p=await q.get(`/subscribe/run/list?subscriptionId=${m}&limit=50`),v=(p==null?void 0:p.data)??p??[];o(Array.isArray(v)?v:[])}catch{c.message.error("加载运行历史失败")}finally{x(!1)}},N=async m=>{g(m);try{const p=await q.get(`/subscribe/run/${m}/items?limit=200`),v=(p==null?void 0:p.data)??p??[];f(Array.isArray(v)?v:[])}catch{c.message.error("加载抽取项失败")}},T=s.reduce((m,p)=>m+(p.successCount||0),0),B=s.reduce((m,p)=>m+(p.deadLetterCount||0),0),y=s.reduce((m,p)=>m+(p.duplicateCount||0),0);return u.jsx("div",{style:{padding:24},children:u.jsxs(c.Card,{title:u.jsxs(c.Space,{children:[u.jsx(D.ApiOutlined,{}),"订阅中心 - 运行历史"]}),extra:u.jsxs(c.Space,{children:[u.jsx(c.Select,{style:{width:280},placeholder:"选择订阅",value:r,onChange:n,options:e.map(m=>({value:m.id,label:m.name})),showSearch:!0,optionFilterProp:"label"}),u.jsxs("a",{onClick:()=>r&&R(r),children:[u.jsx(D.ReloadOutlined,{})," 刷新"]})]}),children:[u.jsxs(c.Row,{gutter:16,style:{marginBottom:16},children:[u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"run 总数",value:s.length})})}),u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"成功条数",value:T,valueStyle:{color:"#3f8600"}})})}),u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"死信条数",value:B,valueStyle:{color:"#cf1322"}})})}),u.jsx(c.Col,{span:6,children:u.jsx(c.Card,{children:u.jsx(c.Statistic,{title:"重复跳过",value:y})})})]}),u.jsxs(c.Row,{gutter:16,children:[u.jsx(c.Col,{span:12,children:u.jsx(c.Card,{type:"inner",title:`运行列表 (${s.length})`,size:"small",children:u.jsx(c.Table,{rowKey:"id",size:"small",loading:b,dataSource:s,pagination:{pageSize:10},onRow:m=>({onClick:()=>N(m.id),style:{cursor:"pointer",background:m.id===d?"#e6f7ff":""}}),columns:[{title:"ID",dataIndex:"id",width:60},{title:"计划",dataIndex:"scheduledAt",width:150,render:m=>m?new Date(m).toLocaleString():"-"},{title:"耗时",dataIndex:"durationMs",width:80},{title:"状态",dataIndex:"status",width:80,render:m=>u.jsx(c.Tag,{color:Ns[m],children:m})},{title:"拉取/成功/死信",width:150,render:(m,p)=>`${p.fetchedCount} / ${p.successCount} / ${p.deadLetterCount}`}]})})}),u.jsx(c.Col,{span:12,children:u.jsx(c.Card,{type:"inner",title:d?`run#${d} 抽取项 (${a.length})`:"抽取项",size:"small",children:a.length===0?u.jsx(c.Empty,{description:d?"该 run 无抽取项":"点击左侧 run 查看抽取项"}):u.jsx(c.Table,{rowKey:"id",size:"small",dataSource:a,pagination:{pageSize:10},columns:[{title:"id",dataIndex:"dedupKey",width:160,ellipsis:!0},{title:"title",dataIndex:"normalized",render:m=>{try{return JSON.parse(m).title||"(无标题)"}catch{return m}}},{title:"link",dataIndex:"normalized",width:60,render:m=>{try{const p=JSON.parse(m);return p.link?u.jsx("a",{href:p.link,target:"_blank",children:"↗"}):"-"}catch{return"-"}}},{title:"状态",dataIndex:"status",width:100,render:m=>u.jsx(c.Tag,{children:m})}]})})})]})]})})}function Ps(){return u.jsxs(re.Routes,{children:[u.jsx(re.Route,{index:!0,element:u.jsx(re.Navigate,{to:"list",replace:!0})}),u.jsx(re.Route,{path:"list",element:u.jsx(or,{})}),u.jsx(re.Route,{path:"new",element:u.jsx(lt,{})}),u.jsx(re.Route,{path:"edit/:id",element:u.jsx(lt,{})}),u.jsx(re.Route,{path:"runs",element:u.jsx(ir,{})})]})}X.RunHistory=ir,X.SubscribeApp=Ps,X.SubscriptionEdit=lt,X.SubscriptionList=or,Object.defineProperty(X,Symbol.toStringTag,{value:"Module"})}));
|