@yuku123/z-project-frontend-component 0.2.2 → 0.2.3
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: Bs, Sider: Ms, Content: zs } = Zt, { Text: qs } = X, { Title: $s
|
|
|
2951
2951
|
Object.fromEntries(ns.map((e) => [e.type, e]));
|
|
2952
2952
|
const { Option: Js } = Ve;
|
|
2953
2953
|
ne.TextArea, ne.TextArea;
|
|
2954
|
-
const { Text: Ks, Paragraph: Xs } = X, { TextArea: Ys } = ne, { TextArea: Gs } = ne, { Text: Zs, Paragraph: Qs } = X, { TextArea: ea } = ne, { Text: ta, Paragraph: ra } = X, { Text: na } = X, { Text: oa } = X, { TextArea: sa } = ne, { Text: aa, Paragraph: ia } = X, { Text: la } = X, { Text: ca } = X, { Text: ua } = X, { Text: fa } = X
|
|
2955
|
-
common;
|
|
2956
|
-
const os = {
|
|
2954
|
+
const { Text: Ks, Paragraph: Xs } = X, { TextArea: Ys } = ne, { TextArea: Gs } = ne, { Text: Zs, Paragraph: Qs } = X, { TextArea: ea } = ne, { Text: ta, Paragraph: ra } = X, { Text: na } = X, { Text: oa } = X, { TextArea: sa } = ne, { Text: aa, Paragraph: ia } = X, { Text: la } = X, { Text: ca } = X, { Text: ua } = X, { Text: fa } = X, os = {
|
|
2957
2955
|
OPEN: { color: "blue", text: "待开始" },
|
|
2958
2956
|
IN_PROGRESS: { color: "green", text: "进行中" },
|
|
2959
2957
|
COMPLETED: { color: "default", text: "已完成" },
|
|
@@ -48,4 +48,4 @@ React keys must be passed directly to JSX without using spread:
|
|
|
48
48
|
`);return s===-1?"":n.stack.slice(s+1)})();try{if(!r.stack)r.stack=o;else if(o){const s=o.indexOf(`
|
|
49
49
|
`),a=s===-1?-1:o.indexOf(`
|
|
50
50
|
`,s+1),c=a===-1?"":o.slice(a+1);String(r.stack).endsWith(c)||(r.stack+=`
|
|
51
|
-
`+o)}}catch{}}throw r}}_request(e,t){typeof e=="string"?(t=t||{},t.url=e):t=e||{},t=he(this.defaults,t);const{transitional:r,paramsSerializer:n,headers:o}=t;r!==void 0&&We.assertOptions(r,{silentJSONParsing:M.transitional(M.boolean),forcedJSONParsing:M.transitional(M.boolean),clarifyTimeoutError:M.transitional(M.boolean),legacyInterceptorReqResOrdering:M.transitional(M.boolean),advertiseZstdAcceptEncoding:M.transitional(M.boolean),validateStatusUndefinedResolves:M.transitional(M.boolean)},!1),n!=null&&(l.isFunction(n)?t.paramsSerializer={serialize:n}:We.assertOptions(n,{encode:M.function,serialize:M.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),We.assertOptions(t,{baseUrl:M.spelling("baseURL"),withXsrfToken:M.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let s=o&&l.merge(o.common,o[t.method]);o&&l.forEach(["delete","get","head","post","put","patch","query","common"],R=>{delete o[R]}),t.headers=U.concat(s,o);const a=[];let c=!0;this.interceptors.request.forEach(function(R){if(typeof R.runWhen=="function"&&R.runWhen(t)===!1)return;c=c&&R.synchronous;const A=t.transitional||et;A&&A.legacyInterceptorReqResOrdering?a.unshift(R.fulfilled,R.rejected):a.push(R.fulfilled,R.rejected)});const f=[];this.interceptors.response.forEach(function(R){f.push(R.fulfilled,R.rejected)});let g,u=0,m;if(!c){const R=[Zt.bind(this),void 0];for(R.unshift(...a),R.push(...f),m=R.length,g=Promise.resolve(t);u<m;)g=g.then(R[u++],R[u++]);return g}m=a.length;let x=t;for(;u<m;){const R=a[u++],A=a[u++];try{x=R(x)}catch(b){A.call(this,b);break}}try{g=Zt.call(this,x)}catch(R){return Promise.reject(R)}for(u=0,m=f.length;u<m;)g=g.then(f[u++],f[u++]);return g}getUri(e){e=he(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){me.prototype[e]=function(t,r){return this.request(he(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,o,s){return this.request(he(s||{},{method:e,headers:r?{"Content-Type":"multipart/form-data"}:{},url:n,data:o}))}}me.prototype[e]=t(),e!=="query"&&(me.prototype[e+"Form"]=t(!0))});let yo=class fr{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(o){r=o});const n=this;this.promise.then(o=>{if(!n._listeners)return;let s=n._listeners.length;for(;s-- >0;)n._listeners[s](o);n._listeners=null}),this.promise.then=o=>{let s;const a=new Promise(c=>{n.subscribe(c),s=c}).then(o);return a.cancel=function(){n.unsubscribe(s)},a},t(function(o,s,a){n.reason||(n.reason=new Pe(o,s,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 Eo(e){return function(t){return e.apply(null,t)}}function So(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 er(e){const t=new me(e),r=mt(me.prototype.request,t);return l.extend(r,me.prototype,t,{allOwnKeys:!0}),l.extend(r,t,null,{allOwnKeys:!0}),r.create=function(n){return er(he(e,n))},r}const I=er(Ce);I.Axios=me,I.CanceledError=Pe,I.CancelToken=yo,I.isCancel=Ft,I.VERSION=ot,I.toFormData=Me,I.AxiosError=S,I.Cancel=I.CanceledError,I.all=function(e){return Promise.all(e)},I.spread=Eo,I.isAxiosError=So,I.mergeConfig=he,I.AxiosHeaders=U,I.formToJSON=e=>Lt(l.isHTMLForm(e)?new FormData(e):e),I.getAdapter=Gt.getAdapter,I.HttpStatusCode=at,I.default=I;const{Axios:Io,AxiosError:Do,CanceledError:Lo,isCancel:Fo,CancelToken:Bo,VERSION:Uo,all:Mo,Cancel:zo,isAxiosError:qo,spread:$o,toFormData:Ho,AxiosHeaders:Wo,HttpStatusCode:Vo,formToJSON:Jo,getAdapter:Ko,mergeConfig:Xo,create:Yo}=I;function wo(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 Ro(e,t={}){const{tokenKey:r="token",userInfoKey:n="userInfo",unauthorizedRedirect:o="/login"}=t;e.interceptors.request.use(s=>{const a=localStorage.getItem(r);return a&&(s.headers.Authorization=`Bearer ${a}`),s}),e.interceptors.response.use(s=>wo(s.data),s=>{var a,c,f;return((a=s.response)==null?void 0:a.status)===401?(localStorage.removeItem(r),localStorage.removeItem(n),window.location.href=o):((c=s.response)==null?void 0:c.status)===403?console.error("没有权限访问该资源"):((f=s.response)==null?void 0:f.status)===500&&console.error("服务器内部错误"),Promise.reject(s)})}function tr(e={}){const t=I.create({baseURL:e.baseURL??"/api",timeout:e.timeout??1e4});return Ro(t,{tokenKey:e.tokenKey,userInfoKey:e.userInfoKey,unauthorizedRedirect:e.unauthorizedRedirect}),t}const oe=tr();tr();class Go extends N.Component{constructor(t){super(t),br(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,o=this.state.error&&(this.state.error.message||String(this.state.error))||"未知错误";return X.jsxs("div",{style:{padding:24,background:"#fff2f0",border:"1px solid #ffccc7",borderRadius:8,minHeight:200},children:[X.jsx(h.Alert,{type:"error",showIcon:!0,icon:X.jsx(D.BugOutlined,{}),message:t,description:X.jsxs("div",{children:[X.jsx("div",{style:{marginBottom:8},children:r||"当前组件发生了异常,已被错误边界捕获。其他功能仍可正常使用。"}),X.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:o})]})}),n&&X.jsx(h.Space,{style:{marginTop:16},children:X.jsx(h.Button,{icon:X.jsx(D.ReloadOutlined,{}),onClick:this.handleReset,children:"重试"})})]})}}const{Title:Zo,Text:Qo,Paragraph:es}=h.Typography;let xo="/api";function rr(){return I.create({baseURL:xo,timeout:15e3})}const Oo=rr();rr(),Oo.interceptors.request.use(e=>{const t=localStorage.getItem("token");return t&&(e.headers.Authorization=`Bearer ${t}`),e});const{Header:ts,Sider:rs,Content:ns}=h.Layout,{Text:os}=h.Typography,{Title:ss,Text:is}=h.Typography,{Option:as}=h.Select,{TextArea:ls}=h.Input,To=[{type:"STRING",label:"字符串",icon:X.jsx(D.FileTextOutlined,{}),color:"#1677ff",desc:"短文本 (默认 VARCHAR 255)"},{type:"TEXT",label:"长文本",icon:X.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:X.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(To.map(e=>[e.type,e]));const{Option:cs}=h.Select;h.Input.TextArea,h.Input.TextArea;const{Text:us,Paragraph:fs}=h.Typography,{TextArea:ds}=h.Input,{TextArea:ps}=h.Input,{Text:hs,Paragraph:ms}=h.Typography,{TextArea:gs}=h.Input,{Text:bs,Paragraph:ys}=h.Typography,{Text:Es}=h.Typography,{Text:Ss}=h.Typography,{TextArea:ws}=h.Input,{Text:Rs,Paragraph:xs}=h.Typography,{Text:Os}=h.Typography,{Text:Ts}=h.Typography,{Text:vs}=h.Typography,{Text:_s}=h.Typography;common;const vo={OPEN:{color:"blue",text:"待开始"},IN_PROGRESS:{color:"green",text:"进行中"},COMPLETED:{color:"default",text:"已完成"},ARCHIVED:{color:"default",text:"已归档"}};function nr(){const e=ee.useNavigate(),[t,r]=N.useState("mine"),[n,o]=N.useState([]),[s,a]=N.useState(!1),c=async()=>{a(!0);try{const u=t==="mine"?"/project/list/mine?limit=100":`/project/list/by-status?status=${t}&limit=100`,m=await oe.get(u),x=(m==null?void 0:m.data)??m??[];o(Array.isArray(x)?x:[])}catch(u){h.message.error("加载项目失败: "+((u==null?void 0:u.message)||""))}finally{a(!1)}};N.useEffect(()=>{c()},[t]);const f=async u=>{try{const m=await oe.post(`/project/${u}/status?status=COMPLETED`);m&&m.success!==!1&&(h.message.success("已标记完成"),c())}catch(m){h.message.error("操作失败: "+((m==null?void 0:m.message)||""))}},g=[{title:"ID",dataIndex:"id",width:60},{title:"名称",dataIndex:"name",render:(u,m)=>d.jsxs(h.Space,{orientation:"vertical",size:0,children:[d.jsx("a",{onClick:()=>e(`/project/${m.id}`),style:{fontWeight:500},children:u}),m.description&&d.jsx("span",{style:{color:"#999",fontSize:12},children:m.description})]})},{title:"来源",dataIndex:"sourceType",width:100,render:u=>d.jsx(h.Tag,{children:u})},{title:"订阅",dataIndex:"sourceSubscriptionId",width:80,render:u=>u?`#${u}`:d.jsx("span",{style:{color:"#ccc"},children:"-"})},{title:"状态",dataIndex:"status",width:100,render:u=>{const m=vo[u]||{color:"default",text:u};return d.jsx(h.Tag,{color:m.color,children:m.text})}},{title:"消息数",dataIndex:"messageCount",width:80},{title:"上下文",width:130,render:(u,m)=>d.jsx(h.Space,{size:4,children:d.jsxs(h.Tag,{color:"blue",children:[m.contextSize||0,"B"]})})},{title:"最近活动",dataIndex:"lastMessageAt",width:150,render:u=>u?new Date(u).toLocaleString():d.jsx("span",{style:{color:"#ccc"},children:"-"})},{title:"操作",width:160,render:(u,m)=>d.jsxs(h.Space,{size:4,children:[d.jsx(h.Button,{type:"link",size:"small",onClick:()=>e(`/project/${m.id}`),children:"对话"}),m.status!=="COMPLETED"&&m.status!=="ARCHIVED"&&d.jsx(h.Popconfirm,{title:"标记为已完成?",onConfirm:()=>f(m.id),children:d.jsx(h.Button,{type:"link",size:"small",icon:d.jsx(D.CheckCircleOutlined,{}),children:"完成"})})]})}];return d.jsx("div",{style:{padding:24},children:d.jsxs(h.Card,{title:d.jsxs(h.Space,{children:[d.jsx(D.ApiOutlined,{}),"项目中心 (CEO 立项 + Agent 对话)"]}),extra:d.jsxs(h.Space,{children:[d.jsx(h.Button,{icon:d.jsx(D.ReloadOutlined,{}),onClick:c,children:"刷新"}),d.jsx(h.Button,{type:"primary",icon:d.jsx(D.PlusOutlined,{}),onClick:()=>e("/project/new"),children:"新建项目"})]}),children:[d.jsx(h.Tabs,{activeKey:t,onChange:r,items:[{key:"mine",label:"我的进行中"},{key:"OPEN",label:"待开始"},{key:"IN_PROGRESS",label:"进行中"},{key:"COMPLETED",label:"已完成"}]}),d.jsx(h.Table,{rowKey:"id",columns:g,dataSource:n,loading:s,size:"middle",pagination:{pageSize:20}})]})})}const _o=[{value:"general",label:"通用助手"},{value:"analyst",label:"分析师"},{value:"writer",label:"写手"},{value:"pm",label:"产品经理"},{value:"ops",label:"运营"}];function or(){const e=ee.useNavigate(),[t]=ee.useSearchParams(),[r]=h.Form.useForm(),[n,o]=N.useState(!1),[s,a]=N.useState("from-subscribe"),[c,f]=N.useState([]),[g,u]=N.useState([]),[m,x]=N.useState(!1),[R,A]=N.useState([]),[b,k]=N.useState(null);N.useEffect(()=>{const E=t.get("subscriptionId"),P=t.get("itemIds");E&&(k(Number(E)),r.setFieldValue("sourceSubscriptionId",Number(E)),w(E)),P&&A(P.split(",").map(Number).filter(Boolean))},[t]),N.useEffect(()=>{p()},[]);const p=async()=>{try{const E=await oe.get("/subscribe/subscription/list"),P=(E==null?void 0:E.data)??E??[];f(Array.isArray(P)?P.filter(B=>B.status==="VERIFIED"):[])}catch{}},w=async E=>{x(!0);try{const P=await oe.get(`/subscribe/run/list?subscriptionId=${E}&limit=1`),B=(P==null?void 0:P.data)??P??[];if(B.length===0){u([]);return}const z=B[0],$=await oe.get(`/subscribe/run/${z.id}/items?limit=100`),H=($==null?void 0:$.data)??$??[];u(Array.isArray(H)?H:[])}catch{h.message.error("加载抽取项失败")}finally{x(!1)}},v=async()=>{try{const E=await r.validateFields();if(s==="from-subscribe"&&R.length===0){h.message.warning("请至少选 1 个 item");return}o(!0);const P={...E,sourceItemIds:s==="from-subscribe"?R.map(String):null},B=s==="from-subscribe"?"/project/create-from-items":"/project/create-manual",z=await oe.post(B,P);if(z&&z.success!==!1){const $=z.data??z;h.message.success("立项成功"),e(`/project/${$.id}`)}else h.message.error((z==null?void 0:z.message)||"立项失败")}catch(E){E!=null&&E.errorFields||h.message.error("立项失败: "+((E==null?void 0:E.message)||""))}finally{o(!1)}};return d.jsx("div",{style:{padding:24},children:d.jsx(h.Card,{title:d.jsxs(h.Space,{children:[d.jsx(h.Button,{type:"text",icon:d.jsx(D.ArrowLeftOutlined,{}),onClick:()=>e("/project/list")}),d.jsx(D.ApiOutlined,{}),"新建项目 (立项)"]}),extra:d.jsxs(h.Space,{children:[d.jsx(h.Button,{onClick:()=>e("/project/list"),children:"取消"}),d.jsx(h.Button,{type:"primary",icon:d.jsx(D.SaveOutlined,{}),loading:n,onClick:v,children:"立项"})]}),children:d.jsxs(h.Form,{form:r,layout:"vertical",initialValues:{agentRole:"general"},children:[d.jsx(h.Form.Item,{label:"来源",children:d.jsxs(h.Radio.Group,{value:s,onChange:E=>a(E.target.value),children:[d.jsx(h.Radio.Button,{value:"from-subscribe",children:"从订阅线索立项 (主路径)"}),d.jsx(h.Radio.Button,{value:"manual",children:"手动立项 (无源数据)"})]})}),d.jsx(h.Form.Item,{label:"项目名称",name:"name",rules:[{required:!0,message:"请输入名称"}],children:d.jsx(h.Input,{placeholder:"例如: 跟进 GitHub 高优 Issue"})}),d.jsx(h.Form.Item,{label:"项目描述",name:"description",children:d.jsx(h.Input.TextArea,{rows:2,placeholder:"(可选) 这个项目要解决什么?"})}),s==="from-subscribe"&&d.jsxs(h.Card,{type:"inner",title:"源数据",style:{marginBottom:16},children:[d.jsx(h.Form.Item,{label:"选择订阅",name:"sourceSubscriptionId",rules:[{required:!0,message:"请选订阅"}],children:d.jsx(h.Select,{placeholder:"选择订阅 (拉取最近一次 run 的 items)",options:c.map(E=>({value:E.id,label:`#${E.id} ${E.name}`})),onChange:E=>{k(E),w(E),A([])}})}),b&&d.jsxs(h.Spin,{spinning:m,children:[d.jsxs("div",{style:{marginBottom:8},children:[d.jsxs(h.Tag,{color:"blue",children:["已选 ",R.length," / ",g.length]}),d.jsx(h.Button,{size:"small",onClick:()=>A(g.map(E=>E.id)),children:"全选"}),d.jsx(h.Button,{size:"small",onClick:()=>A([]),style:{marginLeft:4},children:"清空"})]}),d.jsx(h.Table,{rowKey:"id",size:"small",dataSource:g,pagination:{pageSize:10},rowSelection:{selectedRowKeys:R,onChange:A},columns:[{title:"id",dataIndex:"dedupKey",width:160,ellipsis:!0},{title:"title",dataIndex:"normalized",render:E=>{try{return JSON.parse(E).title||"(无)"}catch{return E}}},{title:"fetched",dataIndex:"fetchedAt",width:150,render:E=>E?new Date(E).toLocaleString():"-"}]})]})]}),d.jsxs(h.Card,{type:"inner",title:"Agent 配置",style:{marginBottom:16},children:[d.jsx(h.Form.Item,{label:"Agent 角色",name:"agentRole",extra:"决定 system prompt 的语气 / 视角",children:d.jsx(h.Select,{options:_o})}),d.jsx(h.Form.Item,{label:"模型 (可选)",name:"modelCode",extra:"留空走默认 (智能中心 LLM 凭证里第一个 enabled)",children:d.jsx(h.Input,{placeholder:"例如: gpt-4 / deepseek-chat"})})]}),d.jsx(h.Alert,{type:"info",showIcon:!0,message:"立项后源数据会被快照 (context_snapshot), 后续订阅更新不会影响项目上下文."})]})})})}const sr={USER:{color:"blue",icon:d.jsx(D.UserOutlined,{}),label:"CEO"},ASSISTANT:{color:"purple",icon:d.jsx(D.RobotOutlined,{}),label:"Agent"},SYSTEM:{color:"default",icon:null,label:"系统"}},jo={OPEN:{color:"blue",text:"待开始"},IN_PROGRESS:{color:"green",text:"进行中"},COMPLETED:{color:"default",text:"已完成"},ARCHIVED:{color:"default",text:"已归档"}};function ir(){const{id:e}=ee.useParams(),t=ee.useNavigate(),[r,n]=N.useState(null),[o,s]=N.useState([]),[a,c]=N.useState(""),[f,g]=N.useState(!1),u=N.useRef(null);N.useEffect(()=>{e&&m()},[e]),N.useEffect(()=>{u.current&&(u.current.scrollTop=u.current.scrollHeight)},[o]);const m=async()=>{try{const[b,k]=await Promise.all([oe.get(`/project/${e}`),oe.get(`/project/${e}/messages`)]);n((b==null?void 0:b.data)??b),s(Array.isArray((k==null?void 0:k.data)??k)?(k==null?void 0:k.data)??k:[])}catch{h.message.error("加载项目失败")}},x=async()=>{if(!a.trim())return;const b=a.trim();c(""),g(!0);const k={seq:-1,role:"USER",content:b,createdAt:new Date().toISOString()};s(p=>[...p,k]);try{const p=await oe.post(`/project/${e}/chat`,{message:b});if(p&&p.success!==!1){const v=(p.data??p).message;s(E=>[...E.filter(B=>B.seq!==-1),...v?[v]:[]]),setTimeout(m,100)}else h.message.error((p==null?void 0:p.message)||"发送失败")}catch(p){h.message.error("发送失败: "+((p==null?void 0:p.message)||""))}finally{g(!1)}},R=async()=>{try{const b=await oe.post(`/project/${e}/status?status=COMPLETED`);b&&b.success!==!1&&(h.message.success("已标记完成"),m())}catch{h.message.error("操作失败")}};if(!r)return d.jsx("div",{style:{padding:24},children:d.jsx(h.Spin,{})});const A=jo[r.status]||{color:"default",text:r.status};return d.jsxs("div",{style:{padding:24,height:"calc(100vh - 64px)",display:"flex",flexDirection:"column",gap:16},children:[d.jsxs(h.Card,{title:d.jsxs(h.Space,{children:[d.jsx(h.Button,{type:"text",icon:d.jsx(D.ArrowLeftOutlined,{}),onClick:()=>t("/project/list")}),d.jsx(D.ApiOutlined,{}),d.jsx("span",{style:{fontWeight:500},children:r.name}),d.jsx(h.Tag,{color:A.color,children:A.text})]}),extra:d.jsxs(h.Space,{children:[r.contextSize>0&&d.jsxs(h.Tag,{color:"blue",children:["上下文 ",r.contextSize," B"]}),d.jsx(h.Tag,{children:r.agentRole}),r.modelCode&&d.jsx(h.Tag,{color:"purple",children:r.modelCode}),r.status!=="COMPLETED"&&r.status!=="ARCHIVED"&&d.jsx(h.Popconfirm,{title:"标记完成?",onConfirm:R,children:d.jsx(h.Button,{icon:d.jsx(D.CheckCircleOutlined,{}),children:"标记完成"})})]}),children:[r.description&&d.jsx("div",{style:{color:"#666",marginBottom:8},children:r.description}),d.jsxs(h.Space,{size:"large",children:[d.jsx(h.Statistic,{title:"消息数",value:r.messageCount||0}),r.sourceSubscriptionId&&d.jsx(h.Statistic,{title:"来源订阅",value:`#${r.sourceSubscriptionId}`}),d.jsx(h.Statistic,{title:"立项",value:r.createdAt?new Date(r.createdAt).toLocaleString():"-"})]})]}),d.jsxs(h.Card,{style:{flex:1,display:"flex",flexDirection:"column"},bodyStyle:{flex:1,display:"flex",flexDirection:"column",padding:0},children:[d.jsx("div",{ref:u,style:{flex:1,overflow:"auto",padding:16,background:"#fafafa"},children:o.length===0?d.jsx(h.Empty,{description:"还没有消息, 跟 Agent 说点什么?"}):d.jsxs(h.Space,{orientation:"vertical",style:{width:"100%"},size:"middle",children:[o.map(b=>{const k=sr[b.role]||sr.SYSTEM,p=b.role==="USER";return d.jsx("div",{style:{display:"flex",justifyContent:p?"flex-end":"flex-start"},children:d.jsxs("div",{style:{maxWidth:"70%",background:p?"#1677ff":"#fff",color:p?"#fff":"#000",border:p?"none":"1px solid #e8e8e8",borderRadius:8,padding:"10px 14px",boxShadow:"0 1px 2px rgba(0,0,0,0.04)"},children:[d.jsx("div",{style:{fontSize:12,opacity:.7,marginBottom:4},children:d.jsxs(h.Space,{size:4,children:[k.icon,k.label,b.seq>0&&d.jsxs("span",{children:["#",b.seq]}),b.latencyMs>0&&d.jsxs("span",{children:["· ",b.latencyMs,"ms"]}),b.modelCode&&d.jsxs("span",{children:["· ",b.modelCode]})]})}),d.jsx("div",{style:{whiteSpace:"pre-wrap",wordBreak:"break-word"},children:b.content})]})},b.id||b.seq)}),f&&d.jsx("div",{style:{display:"flex",justifyContent:"flex-start"},children:d.jsxs("div",{style:{background:"#fff",border:"1px solid #e8e8e8",borderRadius:8,padding:"10px 14px"},children:[d.jsx(h.Spin,{size:"small"})," 思考中..."]})})]})}),r.status==="COMPLETED"||r.status==="ARCHIVED"?d.jsx(h.Alert,{style:{margin:12,marginBottom:0},type:"info",message:"项目已完成 / 归档, 不再接受新消息",showIcon:!0}):d.jsxs("div",{style:{borderTop:"1px solid #f0f0f0",padding:12,display:"flex",gap:8},children:[d.jsx(h.Input.TextArea,{value:a,onChange:b=>c(b.target.value),onPressEnter:b=>{b.shiftKey||(b.preventDefault(),x())},placeholder:"输入消息, Enter 发送 (Shift+Enter 换行)",autoSize:{minRows:1,maxRows:6},disabled:f}),d.jsx(h.Button,{type:"primary",icon:d.jsx(D.SendOutlined,{}),loading:f,onClick:x,disabled:!a.trim(),children:"发送"})]})]})]})}function Ao(){return d.jsxs(ee.Routes,{children:[d.jsx(ee.Route,{index:!0,element:d.jsx(ee.Navigate,{to:"list",replace:!0})}),d.jsx(ee.Route,{path:"list",element:d.jsx(nr,{})}),d.jsx(ee.Route,{path:"new",element:d.jsx(or,{})}),d.jsx(ee.Route,{path:":id",element:d.jsx(ir,{})})]})}J.ProjectApp=Ao,J.ProjectCreate=or,J.ProjectDetail=ir,J.ProjectList=nr,Object.defineProperty(J,Symbol.toStringTag,{value:"Module"})}));
|
|
51
|
+
`+o)}}catch{}}throw r}}_request(e,t){typeof e=="string"?(t=t||{},t.url=e):t=e||{},t=he(this.defaults,t);const{transitional:r,paramsSerializer:n,headers:o}=t;r!==void 0&&We.assertOptions(r,{silentJSONParsing:M.transitional(M.boolean),forcedJSONParsing:M.transitional(M.boolean),clarifyTimeoutError:M.transitional(M.boolean),legacyInterceptorReqResOrdering:M.transitional(M.boolean),advertiseZstdAcceptEncoding:M.transitional(M.boolean),validateStatusUndefinedResolves:M.transitional(M.boolean)},!1),n!=null&&(l.isFunction(n)?t.paramsSerializer={serialize:n}:We.assertOptions(n,{encode:M.function,serialize:M.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),We.assertOptions(t,{baseUrl:M.spelling("baseURL"),withXsrfToken:M.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let s=o&&l.merge(o.common,o[t.method]);o&&l.forEach(["delete","get","head","post","put","patch","query","common"],R=>{delete o[R]}),t.headers=U.concat(s,o);const a=[];let c=!0;this.interceptors.request.forEach(function(R){if(typeof R.runWhen=="function"&&R.runWhen(t)===!1)return;c=c&&R.synchronous;const A=t.transitional||et;A&&A.legacyInterceptorReqResOrdering?a.unshift(R.fulfilled,R.rejected):a.push(R.fulfilled,R.rejected)});const f=[];this.interceptors.response.forEach(function(R){f.push(R.fulfilled,R.rejected)});let g,u=0,m;if(!c){const R=[Zt.bind(this),void 0];for(R.unshift(...a),R.push(...f),m=R.length,g=Promise.resolve(t);u<m;)g=g.then(R[u++],R[u++]);return g}m=a.length;let x=t;for(;u<m;){const R=a[u++],A=a[u++];try{x=R(x)}catch(b){A.call(this,b);break}}try{g=Zt.call(this,x)}catch(R){return Promise.reject(R)}for(u=0,m=f.length;u<m;)g=g.then(f[u++],f[u++]);return g}getUri(e){e=he(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){me.prototype[e]=function(t,r){return this.request(he(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,o,s){return this.request(he(s||{},{method:e,headers:r?{"Content-Type":"multipart/form-data"}:{},url:n,data:o}))}}me.prototype[e]=t(),e!=="query"&&(me.prototype[e+"Form"]=t(!0))});let yo=class fr{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(o){r=o});const n=this;this.promise.then(o=>{if(!n._listeners)return;let s=n._listeners.length;for(;s-- >0;)n._listeners[s](o);n._listeners=null}),this.promise.then=o=>{let s;const a=new Promise(c=>{n.subscribe(c),s=c}).then(o);return a.cancel=function(){n.unsubscribe(s)},a},t(function(o,s,a){n.reason||(n.reason=new Pe(o,s,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 Eo(e){return function(t){return e.apply(null,t)}}function So(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 er(e){const t=new me(e),r=mt(me.prototype.request,t);return l.extend(r,me.prototype,t,{allOwnKeys:!0}),l.extend(r,t,null,{allOwnKeys:!0}),r.create=function(n){return er(he(e,n))},r}const I=er(Ce);I.Axios=me,I.CanceledError=Pe,I.CancelToken=yo,I.isCancel=Ft,I.VERSION=ot,I.toFormData=Me,I.AxiosError=S,I.Cancel=I.CanceledError,I.all=function(e){return Promise.all(e)},I.spread=Eo,I.isAxiosError=So,I.mergeConfig=he,I.AxiosHeaders=U,I.formToJSON=e=>Lt(l.isHTMLForm(e)?new FormData(e):e),I.getAdapter=Gt.getAdapter,I.HttpStatusCode=at,I.default=I;const{Axios:Io,AxiosError:Do,CanceledError:Lo,isCancel:Fo,CancelToken:Bo,VERSION:Uo,all:Mo,Cancel:zo,isAxiosError:qo,spread:$o,toFormData:Ho,AxiosHeaders:Wo,HttpStatusCode:Vo,formToJSON:Jo,getAdapter:Ko,mergeConfig:Xo,create:Yo}=I;function wo(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 Ro(e,t={}){const{tokenKey:r="token",userInfoKey:n="userInfo",unauthorizedRedirect:o="/login"}=t;e.interceptors.request.use(s=>{const a=localStorage.getItem(r);return a&&(s.headers.Authorization=`Bearer ${a}`),s}),e.interceptors.response.use(s=>wo(s.data),s=>{var a,c,f;return((a=s.response)==null?void 0:a.status)===401?(localStorage.removeItem(r),localStorage.removeItem(n),window.location.href=o):((c=s.response)==null?void 0:c.status)===403?console.error("没有权限访问该资源"):((f=s.response)==null?void 0:f.status)===500&&console.error("服务器内部错误"),Promise.reject(s)})}function tr(e={}){const t=I.create({baseURL:e.baseURL??"/api",timeout:e.timeout??1e4});return Ro(t,{tokenKey:e.tokenKey,userInfoKey:e.userInfoKey,unauthorizedRedirect:e.unauthorizedRedirect}),t}const oe=tr();tr();class Go extends N.Component{constructor(t){super(t),br(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,o=this.state.error&&(this.state.error.message||String(this.state.error))||"未知错误";return X.jsxs("div",{style:{padding:24,background:"#fff2f0",border:"1px solid #ffccc7",borderRadius:8,minHeight:200},children:[X.jsx(h.Alert,{type:"error",showIcon:!0,icon:X.jsx(D.BugOutlined,{}),message:t,description:X.jsxs("div",{children:[X.jsx("div",{style:{marginBottom:8},children:r||"当前组件发生了异常,已被错误边界捕获。其他功能仍可正常使用。"}),X.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:o})]})}),n&&X.jsx(h.Space,{style:{marginTop:16},children:X.jsx(h.Button,{icon:X.jsx(D.ReloadOutlined,{}),onClick:this.handleReset,children:"重试"})})]})}}const{Title:Zo,Text:Qo,Paragraph:es}=h.Typography;let xo="/api";function rr(){return I.create({baseURL:xo,timeout:15e3})}const Oo=rr();rr(),Oo.interceptors.request.use(e=>{const t=localStorage.getItem("token");return t&&(e.headers.Authorization=`Bearer ${t}`),e});const{Header:ts,Sider:rs,Content:ns}=h.Layout,{Text:os}=h.Typography,{Title:ss,Text:is}=h.Typography,{Option:as}=h.Select,{TextArea:ls}=h.Input,To=[{type:"STRING",label:"字符串",icon:X.jsx(D.FileTextOutlined,{}),color:"#1677ff",desc:"短文本 (默认 VARCHAR 255)"},{type:"TEXT",label:"长文本",icon:X.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:X.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(To.map(e=>[e.type,e]));const{Option:cs}=h.Select;h.Input.TextArea,h.Input.TextArea;const{Text:us,Paragraph:fs}=h.Typography,{TextArea:ds}=h.Input,{TextArea:ps}=h.Input,{Text:hs,Paragraph:ms}=h.Typography,{TextArea:gs}=h.Input,{Text:bs,Paragraph:ys}=h.Typography,{Text:Es}=h.Typography,{Text:Ss}=h.Typography,{TextArea:ws}=h.Input,{Text:Rs,Paragraph:xs}=h.Typography,{Text:Os}=h.Typography,{Text:Ts}=h.Typography,{Text:vs}=h.Typography,{Text:_s}=h.Typography,vo={OPEN:{color:"blue",text:"待开始"},IN_PROGRESS:{color:"green",text:"进行中"},COMPLETED:{color:"default",text:"已完成"},ARCHIVED:{color:"default",text:"已归档"}};function nr(){const e=ee.useNavigate(),[t,r]=N.useState("mine"),[n,o]=N.useState([]),[s,a]=N.useState(!1),c=async()=>{a(!0);try{const u=t==="mine"?"/project/list/mine?limit=100":`/project/list/by-status?status=${t}&limit=100`,m=await oe.get(u),x=(m==null?void 0:m.data)??m??[];o(Array.isArray(x)?x:[])}catch(u){h.message.error("加载项目失败: "+((u==null?void 0:u.message)||""))}finally{a(!1)}};N.useEffect(()=>{c()},[t]);const f=async u=>{try{const m=await oe.post(`/project/${u}/status?status=COMPLETED`);m&&m.success!==!1&&(h.message.success("已标记完成"),c())}catch(m){h.message.error("操作失败: "+((m==null?void 0:m.message)||""))}},g=[{title:"ID",dataIndex:"id",width:60},{title:"名称",dataIndex:"name",render:(u,m)=>d.jsxs(h.Space,{orientation:"vertical",size:0,children:[d.jsx("a",{onClick:()=>e(`/project/${m.id}`),style:{fontWeight:500},children:u}),m.description&&d.jsx("span",{style:{color:"#999",fontSize:12},children:m.description})]})},{title:"来源",dataIndex:"sourceType",width:100,render:u=>d.jsx(h.Tag,{children:u})},{title:"订阅",dataIndex:"sourceSubscriptionId",width:80,render:u=>u?`#${u}`:d.jsx("span",{style:{color:"#ccc"},children:"-"})},{title:"状态",dataIndex:"status",width:100,render:u=>{const m=vo[u]||{color:"default",text:u};return d.jsx(h.Tag,{color:m.color,children:m.text})}},{title:"消息数",dataIndex:"messageCount",width:80},{title:"上下文",width:130,render:(u,m)=>d.jsx(h.Space,{size:4,children:d.jsxs(h.Tag,{color:"blue",children:[m.contextSize||0,"B"]})})},{title:"最近活动",dataIndex:"lastMessageAt",width:150,render:u=>u?new Date(u).toLocaleString():d.jsx("span",{style:{color:"#ccc"},children:"-"})},{title:"操作",width:160,render:(u,m)=>d.jsxs(h.Space,{size:4,children:[d.jsx(h.Button,{type:"link",size:"small",onClick:()=>e(`/project/${m.id}`),children:"对话"}),m.status!=="COMPLETED"&&m.status!=="ARCHIVED"&&d.jsx(h.Popconfirm,{title:"标记为已完成?",onConfirm:()=>f(m.id),children:d.jsx(h.Button,{type:"link",size:"small",icon:d.jsx(D.CheckCircleOutlined,{}),children:"完成"})})]})}];return d.jsx("div",{style:{padding:24},children:d.jsxs(h.Card,{title:d.jsxs(h.Space,{children:[d.jsx(D.ApiOutlined,{}),"项目中心 (CEO 立项 + Agent 对话)"]}),extra:d.jsxs(h.Space,{children:[d.jsx(h.Button,{icon:d.jsx(D.ReloadOutlined,{}),onClick:c,children:"刷新"}),d.jsx(h.Button,{type:"primary",icon:d.jsx(D.PlusOutlined,{}),onClick:()=>e("/project/new"),children:"新建项目"})]}),children:[d.jsx(h.Tabs,{activeKey:t,onChange:r,items:[{key:"mine",label:"我的进行中"},{key:"OPEN",label:"待开始"},{key:"IN_PROGRESS",label:"进行中"},{key:"COMPLETED",label:"已完成"}]}),d.jsx(h.Table,{rowKey:"id",columns:g,dataSource:n,loading:s,size:"middle",pagination:{pageSize:20}})]})})}const _o=[{value:"general",label:"通用助手"},{value:"analyst",label:"分析师"},{value:"writer",label:"写手"},{value:"pm",label:"产品经理"},{value:"ops",label:"运营"}];function or(){const e=ee.useNavigate(),[t]=ee.useSearchParams(),[r]=h.Form.useForm(),[n,o]=N.useState(!1),[s,a]=N.useState("from-subscribe"),[c,f]=N.useState([]),[g,u]=N.useState([]),[m,x]=N.useState(!1),[R,A]=N.useState([]),[b,k]=N.useState(null);N.useEffect(()=>{const E=t.get("subscriptionId"),P=t.get("itemIds");E&&(k(Number(E)),r.setFieldValue("sourceSubscriptionId",Number(E)),w(E)),P&&A(P.split(",").map(Number).filter(Boolean))},[t]),N.useEffect(()=>{p()},[]);const p=async()=>{try{const E=await oe.get("/subscribe/subscription/list"),P=(E==null?void 0:E.data)??E??[];f(Array.isArray(P)?P.filter(B=>B.status==="VERIFIED"):[])}catch{}},w=async E=>{x(!0);try{const P=await oe.get(`/subscribe/run/list?subscriptionId=${E}&limit=1`),B=(P==null?void 0:P.data)??P??[];if(B.length===0){u([]);return}const z=B[0],$=await oe.get(`/subscribe/run/${z.id}/items?limit=100`),H=($==null?void 0:$.data)??$??[];u(Array.isArray(H)?H:[])}catch{h.message.error("加载抽取项失败")}finally{x(!1)}},v=async()=>{try{const E=await r.validateFields();if(s==="from-subscribe"&&R.length===0){h.message.warning("请至少选 1 个 item");return}o(!0);const P={...E,sourceItemIds:s==="from-subscribe"?R.map(String):null},B=s==="from-subscribe"?"/project/create-from-items":"/project/create-manual",z=await oe.post(B,P);if(z&&z.success!==!1){const $=z.data??z;h.message.success("立项成功"),e(`/project/${$.id}`)}else h.message.error((z==null?void 0:z.message)||"立项失败")}catch(E){E!=null&&E.errorFields||h.message.error("立项失败: "+((E==null?void 0:E.message)||""))}finally{o(!1)}};return d.jsx("div",{style:{padding:24},children:d.jsx(h.Card,{title:d.jsxs(h.Space,{children:[d.jsx(h.Button,{type:"text",icon:d.jsx(D.ArrowLeftOutlined,{}),onClick:()=>e("/project/list")}),d.jsx(D.ApiOutlined,{}),"新建项目 (立项)"]}),extra:d.jsxs(h.Space,{children:[d.jsx(h.Button,{onClick:()=>e("/project/list"),children:"取消"}),d.jsx(h.Button,{type:"primary",icon:d.jsx(D.SaveOutlined,{}),loading:n,onClick:v,children:"立项"})]}),children:d.jsxs(h.Form,{form:r,layout:"vertical",initialValues:{agentRole:"general"},children:[d.jsx(h.Form.Item,{label:"来源",children:d.jsxs(h.Radio.Group,{value:s,onChange:E=>a(E.target.value),children:[d.jsx(h.Radio.Button,{value:"from-subscribe",children:"从订阅线索立项 (主路径)"}),d.jsx(h.Radio.Button,{value:"manual",children:"手动立项 (无源数据)"})]})}),d.jsx(h.Form.Item,{label:"项目名称",name:"name",rules:[{required:!0,message:"请输入名称"}],children:d.jsx(h.Input,{placeholder:"例如: 跟进 GitHub 高优 Issue"})}),d.jsx(h.Form.Item,{label:"项目描述",name:"description",children:d.jsx(h.Input.TextArea,{rows:2,placeholder:"(可选) 这个项目要解决什么?"})}),s==="from-subscribe"&&d.jsxs(h.Card,{type:"inner",title:"源数据",style:{marginBottom:16},children:[d.jsx(h.Form.Item,{label:"选择订阅",name:"sourceSubscriptionId",rules:[{required:!0,message:"请选订阅"}],children:d.jsx(h.Select,{placeholder:"选择订阅 (拉取最近一次 run 的 items)",options:c.map(E=>({value:E.id,label:`#${E.id} ${E.name}`})),onChange:E=>{k(E),w(E),A([])}})}),b&&d.jsxs(h.Spin,{spinning:m,children:[d.jsxs("div",{style:{marginBottom:8},children:[d.jsxs(h.Tag,{color:"blue",children:["已选 ",R.length," / ",g.length]}),d.jsx(h.Button,{size:"small",onClick:()=>A(g.map(E=>E.id)),children:"全选"}),d.jsx(h.Button,{size:"small",onClick:()=>A([]),style:{marginLeft:4},children:"清空"})]}),d.jsx(h.Table,{rowKey:"id",size:"small",dataSource:g,pagination:{pageSize:10},rowSelection:{selectedRowKeys:R,onChange:A},columns:[{title:"id",dataIndex:"dedupKey",width:160,ellipsis:!0},{title:"title",dataIndex:"normalized",render:E=>{try{return JSON.parse(E).title||"(无)"}catch{return E}}},{title:"fetched",dataIndex:"fetchedAt",width:150,render:E=>E?new Date(E).toLocaleString():"-"}]})]})]}),d.jsxs(h.Card,{type:"inner",title:"Agent 配置",style:{marginBottom:16},children:[d.jsx(h.Form.Item,{label:"Agent 角色",name:"agentRole",extra:"决定 system prompt 的语气 / 视角",children:d.jsx(h.Select,{options:_o})}),d.jsx(h.Form.Item,{label:"模型 (可选)",name:"modelCode",extra:"留空走默认 (智能中心 LLM 凭证里第一个 enabled)",children:d.jsx(h.Input,{placeholder:"例如: gpt-4 / deepseek-chat"})})]}),d.jsx(h.Alert,{type:"info",showIcon:!0,message:"立项后源数据会被快照 (context_snapshot), 后续订阅更新不会影响项目上下文."})]})})})}const sr={USER:{color:"blue",icon:d.jsx(D.UserOutlined,{}),label:"CEO"},ASSISTANT:{color:"purple",icon:d.jsx(D.RobotOutlined,{}),label:"Agent"},SYSTEM:{color:"default",icon:null,label:"系统"}},jo={OPEN:{color:"blue",text:"待开始"},IN_PROGRESS:{color:"green",text:"进行中"},COMPLETED:{color:"default",text:"已完成"},ARCHIVED:{color:"default",text:"已归档"}};function ir(){const{id:e}=ee.useParams(),t=ee.useNavigate(),[r,n]=N.useState(null),[o,s]=N.useState([]),[a,c]=N.useState(""),[f,g]=N.useState(!1),u=N.useRef(null);N.useEffect(()=>{e&&m()},[e]),N.useEffect(()=>{u.current&&(u.current.scrollTop=u.current.scrollHeight)},[o]);const m=async()=>{try{const[b,k]=await Promise.all([oe.get(`/project/${e}`),oe.get(`/project/${e}/messages`)]);n((b==null?void 0:b.data)??b),s(Array.isArray((k==null?void 0:k.data)??k)?(k==null?void 0:k.data)??k:[])}catch{h.message.error("加载项目失败")}},x=async()=>{if(!a.trim())return;const b=a.trim();c(""),g(!0);const k={seq:-1,role:"USER",content:b,createdAt:new Date().toISOString()};s(p=>[...p,k]);try{const p=await oe.post(`/project/${e}/chat`,{message:b});if(p&&p.success!==!1){const v=(p.data??p).message;s(E=>[...E.filter(B=>B.seq!==-1),...v?[v]:[]]),setTimeout(m,100)}else h.message.error((p==null?void 0:p.message)||"发送失败")}catch(p){h.message.error("发送失败: "+((p==null?void 0:p.message)||""))}finally{g(!1)}},R=async()=>{try{const b=await oe.post(`/project/${e}/status?status=COMPLETED`);b&&b.success!==!1&&(h.message.success("已标记完成"),m())}catch{h.message.error("操作失败")}};if(!r)return d.jsx("div",{style:{padding:24},children:d.jsx(h.Spin,{})});const A=jo[r.status]||{color:"default",text:r.status};return d.jsxs("div",{style:{padding:24,height:"calc(100vh - 64px)",display:"flex",flexDirection:"column",gap:16},children:[d.jsxs(h.Card,{title:d.jsxs(h.Space,{children:[d.jsx(h.Button,{type:"text",icon:d.jsx(D.ArrowLeftOutlined,{}),onClick:()=>t("/project/list")}),d.jsx(D.ApiOutlined,{}),d.jsx("span",{style:{fontWeight:500},children:r.name}),d.jsx(h.Tag,{color:A.color,children:A.text})]}),extra:d.jsxs(h.Space,{children:[r.contextSize>0&&d.jsxs(h.Tag,{color:"blue",children:["上下文 ",r.contextSize," B"]}),d.jsx(h.Tag,{children:r.agentRole}),r.modelCode&&d.jsx(h.Tag,{color:"purple",children:r.modelCode}),r.status!=="COMPLETED"&&r.status!=="ARCHIVED"&&d.jsx(h.Popconfirm,{title:"标记完成?",onConfirm:R,children:d.jsx(h.Button,{icon:d.jsx(D.CheckCircleOutlined,{}),children:"标记完成"})})]}),children:[r.description&&d.jsx("div",{style:{color:"#666",marginBottom:8},children:r.description}),d.jsxs(h.Space,{size:"large",children:[d.jsx(h.Statistic,{title:"消息数",value:r.messageCount||0}),r.sourceSubscriptionId&&d.jsx(h.Statistic,{title:"来源订阅",value:`#${r.sourceSubscriptionId}`}),d.jsx(h.Statistic,{title:"立项",value:r.createdAt?new Date(r.createdAt).toLocaleString():"-"})]})]}),d.jsxs(h.Card,{style:{flex:1,display:"flex",flexDirection:"column"},bodyStyle:{flex:1,display:"flex",flexDirection:"column",padding:0},children:[d.jsx("div",{ref:u,style:{flex:1,overflow:"auto",padding:16,background:"#fafafa"},children:o.length===0?d.jsx(h.Empty,{description:"还没有消息, 跟 Agent 说点什么?"}):d.jsxs(h.Space,{orientation:"vertical",style:{width:"100%"},size:"middle",children:[o.map(b=>{const k=sr[b.role]||sr.SYSTEM,p=b.role==="USER";return d.jsx("div",{style:{display:"flex",justifyContent:p?"flex-end":"flex-start"},children:d.jsxs("div",{style:{maxWidth:"70%",background:p?"#1677ff":"#fff",color:p?"#fff":"#000",border:p?"none":"1px solid #e8e8e8",borderRadius:8,padding:"10px 14px",boxShadow:"0 1px 2px rgba(0,0,0,0.04)"},children:[d.jsx("div",{style:{fontSize:12,opacity:.7,marginBottom:4},children:d.jsxs(h.Space,{size:4,children:[k.icon,k.label,b.seq>0&&d.jsxs("span",{children:["#",b.seq]}),b.latencyMs>0&&d.jsxs("span",{children:["· ",b.latencyMs,"ms"]}),b.modelCode&&d.jsxs("span",{children:["· ",b.modelCode]})]})}),d.jsx("div",{style:{whiteSpace:"pre-wrap",wordBreak:"break-word"},children:b.content})]})},b.id||b.seq)}),f&&d.jsx("div",{style:{display:"flex",justifyContent:"flex-start"},children:d.jsxs("div",{style:{background:"#fff",border:"1px solid #e8e8e8",borderRadius:8,padding:"10px 14px"},children:[d.jsx(h.Spin,{size:"small"})," 思考中..."]})})]})}),r.status==="COMPLETED"||r.status==="ARCHIVED"?d.jsx(h.Alert,{style:{margin:12,marginBottom:0},type:"info",message:"项目已完成 / 归档, 不再接受新消息",showIcon:!0}):d.jsxs("div",{style:{borderTop:"1px solid #f0f0f0",padding:12,display:"flex",gap:8},children:[d.jsx(h.Input.TextArea,{value:a,onChange:b=>c(b.target.value),onPressEnter:b=>{b.shiftKey||(b.preventDefault(),x())},placeholder:"输入消息, Enter 发送 (Shift+Enter 换行)",autoSize:{minRows:1,maxRows:6},disabled:f}),d.jsx(h.Button,{type:"primary",icon:d.jsx(D.SendOutlined,{}),loading:f,onClick:x,disabled:!a.trim(),children:"发送"})]})]})]})}function Ao(){return d.jsxs(ee.Routes,{children:[d.jsx(ee.Route,{index:!0,element:d.jsx(ee.Navigate,{to:"list",replace:!0})}),d.jsx(ee.Route,{path:"list",element:d.jsx(nr,{})}),d.jsx(ee.Route,{path:"new",element:d.jsx(or,{})}),d.jsx(ee.Route,{path:":id",element:d.jsx(ir,{})})]})}J.ProjectApp=Ao,J.ProjectCreate=or,J.ProjectDetail=ir,J.ProjectList=nr,Object.defineProperty(J,Symbol.toStringTag,{value:"Module"})}));
|