Files
senmesh-zc/deployment/iw/web/assets/user-CwyiWp7E.js
KodouWZF d39b3b035d feat(部署): 新增 deployment/ 内外网两套按侧部署包
按 demo/ 的写法把交付包改成「角色由目录决定」:iw/ 拷内网机、ow/ 拷外网机,
各自含镜像 tar、SQL、配置与 install.sh,install.sh 不再收 iw/ow 参数。

前端不再打进镜像,改为静态包放在 <侧>/web/ 只读挂进 nginx:1.27-alpine,
现场临时改页面直接替换文件 + restart web 即可。数据仍全部挂宿主机,
子目录命名与 deploy/offline 一致(pgdata/redis/mq/upload/logs/gate),
默认根改为包内 ./volumes,放数据盘只改 .env 的 SFILE_DATA_ROOT。

后端镜像 sfile-app:1.0.1 含传输优化那一批(实测组包 11.4×、解包 9.9×)。
出包脚本 deployment/scripts/build-package.sh 负责 jar→镜像→前端双包→sql→tar→VERSION。
2026-11-04 21:44:56 +08:00

4 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{t as e}from"./useQuery-dxbdhNvu.js";import{a as t,i as n,n as r,o as i,t as a}from"./select-stsOu5jD.js";import{i as o,n as s,r as c,t as l}from"./xlsx-DLapqJRf.js";import{t as u}from"./plus-BHIlMeNy.js";import{n as d,t as f}from"./search-BGsuWyQ1.js";import{t as p}from"./upload-Cr-BixPb.js";import{Lt as m,N as h,Qt as g,Rt as _,V as v,Vn as y,Zt as b,fn as x,ln as S,qn as C,yn as w,zn as T}from"./index-BaTxSAlR.js";import{n as E,r as D,t as O}from"./data-table-CEq6a930.js";import{t as k}from"./pagination-Bragnnjj.js";import{a as A,i as j,n as M,o as N,r as P,s as F,t as I}from"./dialog-CnxDxMp1.js";import{t as L}from"./textarea-Dyx6I5ZN.js";import{i as R,n as z,r as B,t as V}from"./tabs-DopbVsQe.js";import{n as H,r as U,t as W}from"./edit-user-dialog-DTs4QrEM.js";import{r as G}from"./org-CX5LJyS0.js";var K=x(`file-spreadsheet`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 13h2`,key:`yr2amv`}],[`path`,{d:`M14 13h2`,key:`un5t4a`}],[`path`,{d:`M8 17h2`,key:`2yhykz`}],[`path`,{d:`M14 17h2`,key:`10kma7`}]]),q=x(`list-plus`,[[`path`,{d:`M16 5H3`,key:`m91uny`}],[`path`,{d:`M11 12H3`,key:`51ecnj`}],[`path`,{d:`M16 19H3`,key:`zzsher`}],[`path`,{d:`M18 9v6`,key:`1twb98`}],[`path`,{d:`M21 12h-6`,key:`bt1uis`}]]),J=C(y(),1);const Y=t=>{var n,r,i;let[a,o]=(0,J.useState)({pageIndex:0,pageSize:10}),[s,c]=(0,J.useState)({}),l=e({queryKey:[`userList`,a,s],queryFn:()=>G({...s,pageSize:a.pageSize,pageNo:a.pageIndex+1}).then(e=>e.data)}),u=(e={})=>{let t={};Object.entries(e||{}).forEach(([e,n])=>{n!==``&&n!=null&&(t[e]=n)}),c(t),o(e=>({...e,pageIndex:0}))},d=t();return{pagination:a,table:E({data:(l==null||(n=l.data)==null?void 0:n.entityList)||[],columns:d,getCoreRowModel:D(),manualPagination:!1,rowCount:(l==null||(r=l.data)==null?void 0:r.totalCount)||0,pageCount:(l==null||(i=l.data)==null?void 0:i.pageCount)||0,onPaginationChange:o,autoResetPageIndex:!1,state:{pagination:a}}),query:l,search:u}};var X=C(T(),1),Z=/^1\d{10}$/,Q=500,ee=e=>{let t=[],n=[];return e.split(`
`).forEach(e=>{let r=e.trim();if(!r)return;let[i,...a]=r.split(/[,,\t\s]+/).filter(Boolean);if(!i||a.length===0){n.push({line:r,msg:`格式错误,应为「手机号,姓名」`});return}if(!Z.test(i)){n.push({line:r,msg:`手机号格式不正确`});return}t.push({phone:i,realName:a.join(` `),line:r})}),{rows:t,failed:n}},te=e=>{let t=[],n=[],r=(e||[]).map(e=>(e||[]).map(e=>String(e??``).trim())).filter(e=>e.some(e=>e!==``));return r.length>0&&r[0][0].includes(`手机`)&&(r=r.slice(1)),r.forEach(e=>{let r=e.join(`, `),[i,a]=e;if(!i||!a){n.push({line:r,msg:`格式错误,应为「手机号,姓名」`});return}if(!Z.test(i)){n.push({line:r,msg:`手机号格式不正确`});return}t.push({phone:i,realName:a,line:r})}),{rows:t,failed:n}};function ne({open:e,setOpen:t,refetch:n}){let[r,i]=(0,J.useState)(`text`),[a,u]=(0,J.useState)(``),[d,f]=(0,J.useState)(!1),[h,_]=(0,J.useState)([]),[v,y]=(0,J.useState)(``),[x,C]=(0,J.useState)({rows:[],failed:[]}),w=(0,J.useRef)(null);(0,J.useEffect)(()=>{e&&(i(`text`),u(``),f(!1),_([]),y(``),C({rows:[],failed:[]}))},[e]);let T=(0,J.useMemo)(()=>a.split(`
`).filter(e=>e.trim()).length,[a]),E=e=>{d||t(e)},D=()=>{let e=s.aoa_to_sheet([[`手机号`,`姓名`],[`13800000001`,`张三`],[`13800000002`,`李四`]]);e[`!cols`]=[{wch:20},{wch:24}];let t=s.book_new();s.book_append_sheet(t,e,`用户列表`),c(t,`批量创建用户模板.xlsx`)},O=async e=>{if(e)try{let t=l(await e.arrayBuffer(),{type:`array`}),n=t.Sheets[t.SheetNames[0]];if(!n){S.error(`文件中没有工作表`);return}let r=te(s.sheet_to_json(n,{header:1,defval:``}));if(r.rows.length===0&&r.failed.length===0){S.error(`文件中没有用户数据`);return}y(e.name),C(r)}catch{S.error(`文件解析失败,请使用下载的模板填写`)}finally{w.current&&(w.current.value=``)}};return(0,X.jsx)(I,{open:e,onOpenChange:E,children:(0,X.jsxs)(P,{className:`w-[480px] max-w-[calc(100%-2rem)]`,children:[(0,X.jsxs)(N,{children:[(0,X.jsx)(F,{children:h.length>0?`批量创建失败项`:`批量创建用户`}),(0,X.jsx)(j,{children:h.length>0?`以下 ${h.length} 条数据创建失败,修正后可重新提交`:`支持贴内容或上传 Excel 文件导入,每条用户为「手机号,姓名」`})]}),h.length>0?(0,X.jsx)(`div`,{className:`max-h-[320px] space-y-1 overflow-auto rounded-md border p-2 text-xs`,children:h.map((e,t)=>(0,X.jsxs)(`div`,{className:`flex items-start gap-2 rounded p-1.5 bg-red-50`,children:[(0,X.jsxs)(`span`,{className:`shrink-0 text-black/40`,children:[t+1,`.`]}),(0,X.jsx)(`span`,{className:`min-w-0 flex-1 break-all font-mono`,children:e.line}),(0,X.jsx)(`span`,{className:`shrink-0 text-red-600`,children:e.msg})]},`${e.line}-${t}`))}):(0,X.jsxs)(V,{value:r,onValueChange:e=>i(e),children:[(0,X.jsxs)(B,{className:`w-full mb-2`,children:[(0,X.jsx)(R,{value:`text`,disabled:d,className:`flex-1`,children:`贴内容导入`}),(0,X.jsx)(R,{value:`excel`,disabled:d,className:`flex-1`,children:`Excel 导入`})]}),(0,X.jsxs)(z,{value:`text`,className:`space-y-2`,children:[(0,X.jsx)(L,{value:a,onChange:e=>u(e.target.value),placeholder:`13800000001,张三
13800000002,李四`,className:`h-[240px] resize-none font-mono`,disabled:d}),(0,X.jsxs)(`div`,{className:`flex items-center justify-between text-xs text-black/50`,children:[(0,X.jsxs)(`span`,{children:[`已输入 `,T,` 条`]}),d&&(0,X.jsx)(`span`,{children:`正在创建...`})]})]}),(0,X.jsxs)(z,{value:`excel`,className:`space-y-2`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsxs)(g,{variant:`outline`,size:`sm`,onClick:D,disabled:d,className:`shrink-0`,children:[(0,X.jsx)(o,{}),`下载模板`]}),(0,X.jsxs)(g,{className:`flex-1`,size:`sm`,onClick:()=>{var e;return(e=w.current)==null?void 0:e.click()},disabled:d,children:[(0,X.jsx)(p,{}),x.rows.length>0||x.failed.length>0?`重新选择文件`:`选择文件`]}),(0,X.jsx)(`input`,{ref:w,type:`file`,accept:`.xlsx,.xls`,className:`hidden`,onChange:e=>{var t;return O((t=e.target.files)==null?void 0:t[0])},disabled:d})]}),v?(0,X.jsxs)(`div`,{className:`h-[200px] rounded-md border p-3 space-y-2 overflow-auto`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2 text-sm`,children:[(0,X.jsx)(K,{className:`size-4 text-green-600`}),(0,X.jsx)(`span`,{className:`break-all`,children:v})]}),(0,X.jsxs)(`div`,{className:`text-xs text-black/50`,children:[(0,X.jsxs)(`div`,{children:[`解析出有效数据`,` `,(0,X.jsx)(`span`,{className:`text-black font-medium`,children:x.rows.length}),` `,`条`,x.failed.length>0&&(0,X.jsxs)(X.Fragment,{children:[`,格式错误`,` `,(0,X.jsx)(`span`,{className:`text-red-600 font-medium`,children:x.failed.length}),` `,`条(提交后将展示明细)`]})]}),x.rows.length>0&&(0,X.jsxs)(`div`,{className:`mt-1 max-h-[130px] overflow-auto font-mono`,children:[x.rows.slice(0,5).map(e=>(0,X.jsxs)(`div`,{children:[e.phone,`, `,e.realName]},e.line)),x.rows.length>5&&(0,X.jsxs)(`div`,{children:[`...共 `,x.rows.length,` 条`]})]})]})]}):(0,X.jsxs)(`div`,{className:`h-[200px] rounded-md border border-dashed flex flex-col items-center justify-center gap-1 text-xs text-black/50`,children:[(0,X.jsx)(`span`,{children:`请先下载模板,按模板格式填写后上传`}),(0,X.jsxs)(`span`,{children:[`支持 .xlsx / .xls 文件,最多 `,Q,` 条`]})]}),(0,X.jsxs)(`div`,{className:`flex items-center justify-between text-xs text-black/50`,children:[(0,X.jsx)(`span`,{}),d&&(0,X.jsx)(`span`,{children:`正在创建...`})]})]})]}),(0,X.jsx)(A,{children:h.length>0?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(g,{variant:`outline`,onClick:()=>_([]),disabled:d,children:`返回修改`}),(0,X.jsx)(M,{asChild:!0,children:(0,X.jsx)(g,{children:`关闭`})})]}):(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(M,{asChild:!0,children:(0,X.jsx)(g,{variant:`outline`,disabled:d,children:`取消`})}),(0,X.jsxs)(g,{onClick:async()=>{let{rows:e,failed:i}=r===`text`?ee(a):x;if(e.length===0){i.length>0?_(i):S.error(r===`text`?`请输入用户数据`:`请先选择 Excel 文件`);return}if(e.length+i.length>Q){S.error(`单次批量创建不能超过 ${Q} 条`);return}f(!0);try{let r=await m(e.map(({phone:e,realName:t})=>({phone:e,realName:t}))),a=(r==null?void 0:r.data)||[],o=[...i];a.forEach((t,n)=>{if(!(t!=null&&t.success)){var r;o.push({line:((r=e[n])==null?void 0:r.line)??``,msg:(t==null?void 0:t.msg)||`创建失败`})}}),n==null||n(),o.length>0?(_(o),S.error(`创建完成:成功 ${a.length-(o.length-i.length)} 条,失败 ${o.length} 条`)):(S.success(`创建成功:共 ${a.length} 条`),t(!1))}catch{}finally{f(!1)}},disabled:d,children:[d&&(0,X.jsx)(b,{}),`开始创建`]})]})})]})})}const re=e=>{let{mutateAsync:t,isPending:n}=w({mutationFn:_,...e||{}});return{cancel:e=>{S.promise(t(e),{loading:`提交中...`,success:`操作成功`})},cancelIsPending:n}};function ie({open:e,setOpen:t,data:n,refetch:r}){let{cancel:i,cancelIsPending:a}=re({onSuccess(){r==null||r(),t(!1)}});return(0,X.jsx)(I,{open:e,onOpenChange:t,children:(0,X.jsxs)(P,{className:`w-[400px]`,children:[(0,X.jsxs)(N,{children:[(0,X.jsx)(F,{children:`您确定要注销该用户吗?`}),(0,X.jsx)(j,{children:`注销后,该用户将无法访问系统`}),(0,X.jsxs)(`div`,{className:`mt-1 flex items-center gap-1 text-sm p-2 rounded-md bg-gray-50`,children:[n==null?void 0:n.nickname,`(`,n==null?void 0:n.username,`)`]})]}),(0,X.jsxs)(A,{children:[(0,X.jsx)(M,{asChild:!0,children:(0,X.jsx)(g,{variant:`outline`,children:`取消`})}),(0,X.jsxs)(g,{type:`submit`,disabled:a,onClick:()=>{i(n==null?void 0:n.id)},children:[a&&(0,X.jsx)(b,{}),`确定`]})]})]})})}function $({handleCancelUser:e,handleEditUser:t,handleResetUserPassword:n,handleEnable:r,handleDisable:i}){return[{accessorKey:`username`,header:`用户名`,cell:({row:e})=>(0,X.jsx)(`div`,{children:e.getValue(`username`)})},{accessorKey:`realName`,header:`姓名`,cell:({row:e})=>(0,X.jsx)(`div`,{children:e.getValue(`realName`)})},{accessorKey:`enabled`,header:`启用状态`,cell:({row:e})=>Number(e.getValue(`status`))===3?(0,X.jsx)(h,{variant:`secondary`,className:`text-red-600`,children:`-`}):e.getValue(`enabled`)?(0,X.jsx)(h,{className:`bg-green-500/10 text-green-600`,children:`启用`}):(0,X.jsx)(h,{className:`bg-red-500/10 text-red-500`,children:`禁用`})},{accessorKey:`status`,header:`状态`,cell:({row:e})=>(0,X.jsx)(`div`,{className:`text-xs`,children:e.getValue(`status`)===1?(0,X.jsx)(h,{variant:`secondary`,children:`未激活`}):e.getValue(`status`)===2?(0,X.jsx)(h,{variant:`secondary`,className:`text-green-600`,children:`已激活`}):(0,X.jsx)(h,{variant:`secondary`,className:`text-red-600`,children:`已注销`})})},{accessorKey:`createTime`,header:`创建日期`,cell:({row:e})=>(0,X.jsx)(`div`,{children:e.getValue(`createTime`)})},{id:`actions`,enableHiding:!1,header:`操作`,cell:({row:a})=>{if(a.original.parentId===0)return null;let o=a.original;return(0,X.jsxs)(`div`,{className:`space-x-2`,children:[(0,X.jsx)(g,{size:`sm`,variant:`outline`,onClick:()=>t(o),children:`修改`}),(0,X.jsx)(g,{size:`sm`,variant:`outline`,onClick:()=>n(o),children:`重置密码`}),Number(o.status)!==3&&o.enabled&&(0,X.jsx)(g,{size:`sm`,variant:`outline`,onClick:()=>i(o),children:`禁用`}),Number(o.status)!==3&&!o.enabled&&(0,X.jsx)(g,{size:`sm`,variant:`outline`,onClick:()=>r(o),children:`启用`}),Number(o.status)!==3&&(0,X.jsx)(g,{size:`sm`,variant:`destructive`,onClick:()=>e(o),children:`注销`})]})}}]}function ae(){let[e,o]=(0,J.useState)(null),[s,c]=(0,J.useState)(!1),[l,p]=(0,J.useState)(!1),m=e=>{o(e),p(!0)},[h,_]=(0,J.useState)(!1),y=e=>{o(e),_(!0)},[b,x]=(0,J.useState)(!1),S=e=>{o(e),x(!0)},{enable:C,disable:w}=U({onSuccess:()=>A==null?void 0:A.refetch()}),T=e=>{C(e.id)},E=e=>{w(e.id)},{table:D,query:A,search:j}=Y(()=>$({handleCancelUser:S,handleEditUser:m,handleResetUserPassword:y,handleEnable:T,handleDisable:E})),M={username:``,realName:``,enabled:``,status:``},[N,P]=(0,J.useState)(M),F=(e,t)=>{P(n=>({...n,[e]:t}))};return(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(ne,{open:s,setOpen:c,refetch:A==null?void 0:A.refetch}),(0,X.jsx)(W,{open:l,setOpen:p,data:e,refetch:A==null?void 0:A.refetch}),(0,X.jsx)(H,{open:h,setOpen:_,data:e}),(0,X.jsx)(ie,{open:b,setOpen:x,data:e,refetch:A==null?void 0:A.refetch}),(0,X.jsxs)(`div`,{className:`p-4 box-border min-h-full space-y-4`,children:[(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`div`,{className:`text-lg`,children:`用户管理`}),(0,X.jsx)(`div`,{className:`text-xs text-black/50`,children:`管理单位用户信息`})]}),(0,X.jsxs)(`div`,{className:`p-4 rounded-lg border bg-white space-y-2`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,X.jsx)(v,{placeholder:`用户名`,className:`w-[140px]`,value:N.username,onChange:e=>F(`username`,e.target.value)}),(0,X.jsx)(v,{placeholder:`姓名`,className:`w-[120px]`,value:N.realName,onChange:e=>F(`realName`,e.target.value)}),(0,X.jsxs)(a,{value:N.enabled||`all`,onValueChange:e=>F(`enabled`,e===`all`?``:e),children:[(0,X.jsx)(t,{className:`w-[110px]`,children:(0,X.jsx)(i,{placeholder:`启用状态`})}),(0,X.jsxs)(r,{children:[(0,X.jsx)(n,{value:`all`,children:`启用状态`}),(0,X.jsx)(n,{value:`true`,children:`启用`}),(0,X.jsx)(n,{value:`false`,children:`禁用`})]})]}),(0,X.jsxs)(a,{value:N.status||`all`,onValueChange:e=>F(`status`,e===`all`?``:e),children:[(0,X.jsx)(t,{className:`w-[100px]`,children:(0,X.jsx)(i,{placeholder:`状态`})}),(0,X.jsxs)(r,{children:[(0,X.jsx)(n,{value:`all`,children:`状态`}),(0,X.jsx)(n,{value:`1`,children:`未激活`}),(0,X.jsx)(n,{value:`2`,children:`已激活`}),(0,X.jsx)(n,{value:`3`,children:`已注销`})]})]}),(0,X.jsxs)(g,{onClick:()=>{j({...N})},children:[(0,X.jsx)(f,{}),`查询`]}),(0,X.jsxs)(g,{variant:`outline`,onClick:()=>{P(M),j({})},children:[(0,X.jsx)(d,{}),`重置`]})]}),(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsxs)(g,{onClick:()=>m(),children:[(0,X.jsx)(u,{}),`新增`]}),(0,X.jsxs)(g,{variant:`outline`,onClick:()=>c(!0),children:[(0,X.jsx)(q,{}),`批量创建`]})]}),(0,X.jsxs)(`div`,{className:`relative overflow-hidden`,children:[(0,X.jsx)(O,{table:D,query:A}),(0,X.jsx)(k,{table:D,className:`justify-end p-2 sticky bottom-0 left-0 right-0 z-10 bg-white`})]})]})]})]})}export{ae as component,$ as useColumns};