Compare commits

...

3 Commits

Author SHA1 Message Date
sion
e2624b845a Merge remote-tracking branch 'origin/main' 2026-04-05 19:44:57 +08:00
sion
2ea315cefb 111 2026-04-05 19:44:40 +08:00
sion
2fbc47117c 111 2026-04-05 19:43:31 +08:00
110 changed files with 1956 additions and 540 deletions

View File

@@ -75,9 +75,11 @@ class OrderFund {
final String username;
final int type; // 1=充值, 2=提现
final String amount;
final String? fee; // 手续费
final String? receivableAmount; // 应收款项
final int status;
// 充值状态: 1=待付款, 2=待确认, 3=已完成, 4=已驳回, 5=已取消
// 提现状态: 1=待审批, 2=已完成, 3=已驳回, 4=已取消
// 提现状态: 1=待审批, 2=已完成, 3=已驳回, 4=已取消, 5=待财务审核
final int? walletId; // 冷钱包ID(充值)
final String? walletAddress; // 钱包地址(充值/提现)
final String? withdrawContact; // 提现联系方式
@@ -95,6 +97,8 @@ class OrderFund {
required this.username,
required this.type,
required this.amount,
this.fee,
this.receivableAmount,
required this.status,
this.walletId,
this.walletAddress,
@@ -115,6 +119,8 @@ class OrderFund {
username: json['username'] as String? ?? '',
type: json['type'] as int? ?? 1,
amount: json['amount']?.toString() ?? '0.00',
fee: json['fee']?.toString(),
receivableAmount: json['receivableAmount']?.toString(),
status: json['status'] as int? ?? 1,
walletId: json['walletId'] as int?,
walletAddress: json['walletAddress'] as String?,
@@ -166,6 +172,8 @@ class OrderFund {
return '已驳回';
case 4:
return '已取消';
case 5:
return '待财务审核';
default:
return '未知';
}

View File

@@ -6,6 +6,7 @@ import 'package:google_fonts/google_fonts.dart';
import '../../../core/theme/app_color_scheme.dart';
import '../../../core/theme/app_spacing.dart';
import '../../../core/utils/toast_utils.dart';
import '../../../core/event/app_event_bus.dart';
import '../../../data/services/bonus_service.dart';
import '../../../providers/asset_provider.dart';
import '../../../providers/auth_provider.dart';
@@ -576,6 +577,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
if (response.success) {
context.read<AssetProvider>().refreshAll(force: true);
context.read<AppEventBus>().fire(AppEventType.assetChanged);
ToastUtils.show('领取成功100 USDT 已到账');
_loadData();
} else {
@@ -597,6 +599,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
if (response.success) {
context.read<AssetProvider>().refreshAll(force: true);
context.read<AppEventBus>().fire(AppEventType.assetChanged);
ToastUtils.show('领取成功100 USDT 已到账');
_loadData();
} else {

View File

@@ -29,7 +29,7 @@ class _FundOrderCard extends StatelessWidget {
return AppColorScheme.muted;
}
} else {
// 提现状态: 1=待审批, 2=已完成, 3=已驳回, 4=已取消
// 提现状态: 1=待审批, 2=已完成, 3=已驳回, 4=已取消, 5=待财务审核
switch (status) {
case 1:
return AppColorScheme.warning;
@@ -39,6 +39,8 @@ class _FundOrderCard extends StatelessWidget {
return AppColorScheme.error;
case 4:
return AppColorScheme.muted;
case 5:
return AppColorScheme.info;
default:
return AppColorScheme.muted;
}
@@ -71,6 +73,8 @@ class _FundOrderCard extends StatelessWidget {
return '已驳回';
case 4:
return '已取消';
case 5:
return '待财务审核';
default:
return '未知';
}
@@ -112,6 +116,22 @@ class _FundOrderCard extends StatelessWidget {
],
),
SizedBox(height: AppSpacing.sm),
if (!isDeposit && order.fee != null) ...[
Row(
children: [
Text('手续费(10%): ', style: theme.textTheme.muted),
Text('-${order.fee} USDT', style: theme.textTheme.small),
],
),
SizedBox(height: AppSpacing.xs),
Row(
children: [
Text('应收款项: ', style: theme.textTheme.muted),
Text('${order.receivableAmount ?? "0"} USDT', style: theme.textTheme.small.copyWith(fontWeight: FontWeight.bold)),
],
),
SizedBox(height: AppSpacing.sm),
],
Row(
children: [
Text('订单号: ', style: theme.textTheme.muted),

View File

@@ -1 +1 @@
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";import{r as s}from"./button-BTKRNUhQ.js";var c=n({__name:`AlertDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-description`,class:r(i(o)(`text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`AlertTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-title`,class:r(i(o)(`col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight`,s.class))},[a(n.$slots,`default`)],2))}}),u=s(`relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current`,{variants:{variant:{default:`bg-card text-card-foreground`,destructive:`text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90`}},defaultVariants:{variant:`default`}}),d=n({__name:`Alert`,props:{class:{type:[Boolean,null,String,Object,Array]},variant:{}},setup(n){let s=n;return(c,l)=>(e(),t(`div`,{"data-slot":`alert`,class:r(i(o)(i(u)({variant:n.variant}),s.class)),role:`alert`},[a(c.$slots,`default`)],2))}});export{l as n,c as r,d as t};
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{R as o}from"./index-axPHP3AB.js";import{r as s}from"./button-xrpYa8G4.js";var c=n({__name:`AlertDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-description`,class:r(i(o)(`text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`AlertTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`alert-title`,class:r(i(o)(`col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight`,s.class))},[a(n.$slots,`default`)],2))}}),u=s(`relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current`,{variants:{variant:{default:`bg-card text-card-foreground`,destructive:`text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90`}},defaultVariants:{variant:`default`}}),d=n({__name:`Alert`,props:{class:{type:[Boolean,null,String,Object,Array]},variant:{}},setup(n){let s=n;return(c,l)=>(e(),t(`div`,{"data-slot":`alert`,class:r(i(o)(i(u)({variant:n.variant}),s.class)),role:`alert`},[a(c.$slots,`default`)],2))}});export{l as n,c as r,d as t};

View File

@@ -1 +1 @@
import{A as e,I as t,Q as n,Y as r,_ as i,g as a,ut as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u,v as d}from"./dist-3yfE1dPa.js";import{J as f}from"./index-BpHHjIYv.js";import{i as p}from"./button-BTKRNUhQ.js";import{t as m}from"./useForwardExpose-CNhbE6SX.js";import{r as h}from"./AvatarImage-Ct5I9mHM.js";var g=s({__name:`AvatarFallback`,props:{delayMs:{type:Number,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let s=e,u=h();m();let f=o(s.delayMs===void 0);return r(e=>{if(s.delayMs&&d){let t=window.setTimeout(()=>{f.value=!0},s.delayMs);e(()=>{window.clearTimeout(t)})}}),(e,r)=>f.value&&c(u).imageLoadingStatus.value!==`loaded`?(t(),a(c(p),{key:0,"as-child":e.asChild,as:e.as},{default:n(()=>[l(e.$slots,`default`)]),_:3},8,[`as-child`,`as`])):i(`v-if`,!0)}}),_=s({__name:`AvatarFallback`,props:{delayMs:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(r){let i=r,o=u(i,`class`);return(r,s)=>(t(),a(c(g),e({"data-slot":`avatar-fallback`},c(o),{class:c(f)(`bg-muted flex size-full items-center justify-center rounded-full`,i.class)}),{default:n(()=>[l(r.$slots,`default`)]),_:3},16,[`class`]))}});export{_ as t};
import{A as e,I as t,Q as n,Y as r,_ as i,g as a,ut as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u,v as d}from"./dist-3yfE1dPa.js";import{R as f}from"./index-axPHP3AB.js";import{i as p}from"./button-xrpYa8G4.js";import{t as m}from"./useForwardExpose-B8uiQ7xX.js";import{r as h}from"./AvatarImage-Da9BQozn.js";var g=s({__name:`AvatarFallback`,props:{delayMs:{type:Number,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let s=e,u=h();m();let f=o(s.delayMs===void 0);return r(e=>{if(s.delayMs&&d){let t=window.setTimeout(()=>{f.value=!0},s.delayMs);e(()=>{window.clearTimeout(t)})}}),(e,r)=>f.value&&c(u).imageLoadingStatus.value!==`loaded`?(t(),a(c(p),{key:0,"as-child":e.asChild,as:e.as},{default:n(()=>[l(e.$slots,`default`)]),_:3},8,[`as-child`,`as`])):i(`v-if`,!0)}}),_=s({__name:`AvatarFallback`,props:{delayMs:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(r){let i=r,o=u(i,`class`);return(r,s)=>(t(),a(c(g),e({"data-slot":`avatar-fallback`},c(o),{class:c(f)(`bg-muted flex size-full items-center justify-center rounded-full`,i.class)}),{default:n(()=>[l(r.$slots,`default`)]),_:3},16,[`class`]))}});export{_ as t};

View File

@@ -1 +1 @@
import{$ as e,A as t,I as n,J as r,N as i,P as a,Q as o,Y as s,a as c,g as l,gt as u,m as d,ut as f,x as p,xt as m,yt as h,z as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{v as _}from"./dist-3yfE1dPa.js";import{J as v}from"./index-BpHHjIYv.js";import{O as y}from"./Teleport-qOjHMYM8.js";import{i as b}from"./button-BTKRNUhQ.js";import{t as x}from"./useForwardExpose-CNhbE6SX.js";var[S,C]=y(`AvatarRoot`),w=p({__name:`AvatarRoot`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){return x(),C({imageLoadingStatus:f(`idle`)}),(e,t)=>(n(),l(h(b),{"as-child":e.asChild,as:e.as},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`as-child`,`as`]))}});function T(e,t){return e?t?(e.src!==t&&(e.src=t),e.complete&&e.naturalWidth>0?`loaded`:`loading`):`error`:`idle`}function E(e,{referrerPolicy:t,crossOrigin:n}={}){let r=f(!1),o=f(null),c=d(()=>r.value?(!o.value&&_&&(o.value=new window.Image),o.value):null),l=f(T(c.value,e.value)),u=e=>()=>{r.value&&(l.value=e)};return i(()=>{r.value=!0,s(r=>{let i=c.value;if(!i)return;l.value=T(i,e.value);let a=u(`loaded`),o=u(`error`);i.addEventListener(`load`,a),i.addEventListener(`error`,o),t?.value&&(i.referrerPolicy=t.value),typeof n?.value==`string`&&(i.crossOrigin=n.value),r(()=>{i.removeEventListener(`load`,a),i.removeEventListener(`error`,o)})})}),a(()=>{r.value=!1}),l}var D=p({__name:`AvatarImage`,props:{src:{type:String,required:!0},referrerPolicy:{type:null,required:!1},crossOrigin:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`img`}},emits:[`loadingStatusChange`],setup(t,{emit:i}){let a=t,s=i,{src:d,referrerPolicy:f,crossOrigin:p}=u(a);x();let m=S(),_=E(d,{referrerPolicy:f,crossOrigin:p});return r(_,e=>{s(`loadingStatusChange`,e),e!==`idle`&&(m.imageLoadingStatus.value=e)},{immediate:!0}),(t,r)=>e((n(),l(h(b),{role:`img`,"as-child":t.asChild,as:t.as,src:h(d),referrerpolicy:h(f),crossorigin:h(p)},{default:o(()=>[g(t.$slots,`default`)]),_:3},8,[`as-child`,`as`,`src`,`referrerpolicy`,`crossorigin`])),[[c,h(_)===`loaded`]])}}),O=p({__name:`Avatar`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,r)=>(n(),l(h(w),{"data-slot":`avatar`,class:m(h(v)(`relative flex size-8 shrink-0 overflow-hidden rounded-full`,t.class))},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`class`]))}}),k=p({__name:`AvatarImage`,props:{src:{},referrerPolicy:{},crossOrigin:{},asChild:{type:Boolean},as:{}},setup(e){let r=e;return(e,i)=>(n(),l(h(D),t({"data-slot":`avatar-image`},r,{class:`aspect-square size-full`}),{default:o(()=>[g(e.$slots,`default`)]),_:3},16))}});export{O as n,S as r,k as t};
import{$ as e,A as t,I as n,J as r,N as i,P as a,Q as o,Y as s,a as c,g as l,gt as u,m as d,ut as f,x as p,xt as m,yt as h,z as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{v as _}from"./dist-3yfE1dPa.js";import{R as v}from"./index-axPHP3AB.js";import{O as y}from"./Teleport-f0-_cFyq.js";import{i as b}from"./button-xrpYa8G4.js";import{t as x}from"./useForwardExpose-B8uiQ7xX.js";var[S,C]=y(`AvatarRoot`),w=p({__name:`AvatarRoot`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){return x(),C({imageLoadingStatus:f(`idle`)}),(e,t)=>(n(),l(h(b),{"as-child":e.asChild,as:e.as},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`as-child`,`as`]))}});function T(e,t){return e?t?(e.src!==t&&(e.src=t),e.complete&&e.naturalWidth>0?`loaded`:`loading`):`error`:`idle`}function E(e,{referrerPolicy:t,crossOrigin:n}={}){let r=f(!1),o=f(null),c=d(()=>r.value?(!o.value&&_&&(o.value=new window.Image),o.value):null),l=f(T(c.value,e.value)),u=e=>()=>{r.value&&(l.value=e)};return i(()=>{r.value=!0,s(r=>{let i=c.value;if(!i)return;l.value=T(i,e.value);let a=u(`loaded`),o=u(`error`);i.addEventListener(`load`,a),i.addEventListener(`error`,o),t?.value&&(i.referrerPolicy=t.value),typeof n?.value==`string`&&(i.crossOrigin=n.value),r(()=>{i.removeEventListener(`load`,a),i.removeEventListener(`error`,o)})})}),a(()=>{r.value=!1}),l}var D=p({__name:`AvatarImage`,props:{src:{type:String,required:!0},referrerPolicy:{type:null,required:!1},crossOrigin:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`img`}},emits:[`loadingStatusChange`],setup(t,{emit:i}){let a=t,s=i,{src:d,referrerPolicy:f,crossOrigin:p}=u(a);x();let m=S(),_=E(d,{referrerPolicy:f,crossOrigin:p});return r(_,e=>{s(`loadingStatusChange`,e),e!==`idle`&&(m.imageLoadingStatus.value=e)},{immediate:!0}),(t,r)=>e((n(),l(h(b),{role:`img`,"as-child":t.asChild,as:t.as,src:h(d),referrerpolicy:h(f),crossorigin:h(p)},{default:o(()=>[g(t.$slots,`default`)]),_:3},8,[`as-child`,`as`,`src`,`referrerpolicy`,`crossorigin`])),[[c,h(_)===`loaded`]])}}),O=p({__name:`Avatar`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,r)=>(n(),l(h(w),{"data-slot":`avatar`,class:m(h(v)(`relative flex size-8 shrink-0 overflow-hidden rounded-full`,t.class))},{default:o(()=>[g(e.$slots,`default`)]),_:3},8,[`class`]))}}),k=p({__name:`AvatarImage`,props:{src:{},referrerPolicy:{},crossOrigin:{},asChild:{type:Boolean},as:{}},setup(e){let r=e;return(e,i)=>(n(),l(h(D),t({"data-slot":`avatar-image`},r,{class:`aspect-square size-full`}),{default:o(()=>[g(e.$slots,`default`)]),_:3},16))}});export{O as n,S as r,k as t};

View File

@@ -1 +1 @@
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-BpHHjIYv.js";import{i as l,r as u}from"./button-BTKRNUhQ.js";var d=u(`inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden`,{variants:{variant:{default:`border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90`,secondary:`border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90`,destructive:`border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground`}},defaultVariants:{variant:`default`}}),f=i({__name:`Badge`,props:{asChild:{type:Boolean},as:{},variant:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,f=s(u,`class`);return(s,p)=>(t(),r(a(l),e({"data-slot":`badge`,class:a(c)(a(d)({variant:i.variant}),u.class)},a(f)),{default:n(()=>[o(s.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{R as c}from"./index-axPHP3AB.js";import{i as l,r as u}from"./button-xrpYa8G4.js";var d=u(`inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden`,{variants:{variant:{default:`border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90`,secondary:`border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90`,destructive:`border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground`}},defaultVariants:{variant:`default`}}),f=i({__name:`Badge`,props:{asChild:{type:Boolean},as:{},variant:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,f=s(u,`class`);return(s,p)=>(t(),r(a(l),e({"data-slot":`badge`,class:a(c)(a(d)({variant:i.variant}),u.class)},a(f)),{default:n(()=>[o(s.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};

View File

@@ -1 +1 @@
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card`,class:r(i(o)(`bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{R as o}from"./index-axPHP3AB.js";var s=n({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card`,class:r(i(o)(`bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};

View File

@@ -1 +1 @@
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-content`,class:r(i(o)(`px-6`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{R as o}from"./index-axPHP3AB.js";var s=n({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-content`,class:r(i(o)(`px-6`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};

View File

@@ -1 +1 @@
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-header`,class:r(i(o)(`@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6`,s.class))},[a(n.$slots,`default`)],2))}}),c=n({__name:`CardDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`p`,{"data-slot":`card-description`,class:r(i(o)(`text-muted-foreground text-sm`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`h3`,{"data-slot":`card-title`,class:r(i(o)(`leading-none font-semibold`,s.class))},[a(n.$slots,`default`)],2))}});export{c as n,s as r,l as t};
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{R as o}from"./index-axPHP3AB.js";var s=n({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`card-header`,class:r(i(o)(`@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6`,s.class))},[a(n.$slots,`default`)],2))}}),c=n({__name:`CardDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`p`,{"data-slot":`card-description`,class:r(i(o)(`text-muted-foreground text-sm`,s.class))},[a(n.$slots,`default`)],2))}}),l=n({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`h3`,{"data-slot":`card-title`,class:r(i(o)(`leading-none font-semibold`,s.class))},[a(n.$slots,`default`)],2))}});export{c as n,s as r,l as t};

View File

@@ -1 +1 @@
import{A as e,C as t,I as n,Q as r,St as i,V as a,_ as o,b as s,g as c,m as l,o as u,s as d,x as f,yt as p,z as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as h,p as g}from"./dist-3yfE1dPa.js";import{o as _}from"./SelectValue-By3tfEiu.js";import{J as v}from"./index-BpHHjIYv.js";import{n as y,r as b}from"./VisuallyHidden-_sQ0xQ9O.js";import{O as x,T as S,g as C,y as w}from"./Teleport-qOjHMYM8.js";import{i as T}from"./button-BTKRNUhQ.js";import{t as E}from"./useForwardExpose-CNhbE6SX.js";import{t as D}from"./VisuallyHiddenInput-CE3zkTxY.js";import{t as O}from"./RovingFocusItem-BInhij-V.js";function k(e,t){return S(e)?!1:Array.isArray(e)?e.some(e=>b(e,t)):b(e,t)}var[A,j]=x(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=x(`CheckboxRoot`),I=f({inheritAttrs:!1,__name:`CheckboxRoot`,props:{defaultValue:{type:null,required:!1},modelValue:{type:null,required:!1,default:void 0},disabled:{type:Boolean,required:!1},value:{type:null,required:!1,default:`on`},id:{type:String,required:!1},trueValue:{type:null,required:!1,default:()=>!0},falseValue:{type:null,required:!1,default:()=>!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`},name:{type:String,required:!1},required:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(t,{emit:i}){let s=t,f=i,{forwardRef:h,currentElement:_}=E(),v=A(null),x=g(s,`modelValue`,f,{defaultValue:s.defaultValue??s.falseValue,passive:s.modelValue===void 0}),C=l(()=>v?.disabled.value||s.disabled),w=l(()=>b(x.value,s.trueValue)),j=l(()=>S(v?.modelValue.value)?x.value===`indeterminate`?`indeterminate`:w.value:k(v.modelValue.value,s.value));function P(){if(S(v?.modelValue.value))x.value===`indeterminate`?x.value=s.trueValue:x.value=w.value?s.falseValue:s.trueValue;else{let e=[...v.modelValue.value||[]];if(k(e,s.value)){let t=e.findIndex(e=>b(e,s.value));e.splice(t,1)}else e.push(s.value);v.modelValue.value=e}}let I=y(_),L=l(()=>s.id&&_.value?document.querySelector(`[for="${s.id}"]`)?.innerText:void 0);return F({disabled:C,state:j}),(t,i)=>(n(),c(a(p(v)?.rovingFocus.value?p(O):p(T)),e(t.$attrs,{id:t.id,ref:p(h),role:`checkbox`,"as-child":t.asChild,as:t.as,type:t.as===`button`?`button`:void 0,"aria-checked":p(M)(j.value)?`mixed`:j.value,"aria-required":t.required,"aria-label":t.$attrs[`aria-label`]||L.value,"data-state":p(N)(j.value),"data-disabled":C.value?``:void 0,disabled:C.value,focusable:p(v)?.rovingFocus.value?!C.value:void 0,onKeydown:u(d(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:r(()=>[m(t.$slots,`default`,{modelValue:p(x),state:j.value}),p(I)&&t.name&&!p(v)?(n(),c(p(D),{key:0,type:`checkbox`,checked:!!j.value,name:t.name,value:t.value,disabled:C.value,required:t.required},null,8,[`checked`,`name`,`value`,`disabled`,`required`])):o(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=f({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(t){let{forwardRef:i}=E(),a=P();return(t,o)=>(n(),c(p(C),{present:t.forceMount||p(M)(p(a).state.value)||p(a).state.value===!0},{default:r(()=>[s(p(T),e({ref:p(i),"data-state":p(N)(p(a).state.value),"data-disabled":p(a).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":t.asChild,as:t.as},t.$attrs),{default:r(()=>[m(t.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=f({__name:`Checkbox`,props:{defaultValue:{},modelValue:{},disabled:{type:Boolean},value:{},id:{},trueValue:{},falseValue:{},asChild:{type:Boolean},as:{},name:{},required:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:o}){let l=a,u=o,d=w(h(l,`class`),u);return(a,o)=>(n(),c(p(I),e({"data-slot":`checkbox`},p(d),{class:p(v)(`peer border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,l.class)}),{default:r(e=>[s(p(L),{"data-slot":`checkbox-indicator`,class:`grid place-content-center text-current transition-none`},{default:r(()=>[m(a.$slots,`default`,i(t(e)),()=>[s(p(_),{class:`size-3.5`})])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
import{A as e,C as t,I as n,Q as r,St as i,V as a,_ as o,b as s,g as c,m as l,o as u,s as d,x as f,yt as p,z as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as h,p as g}from"./dist-3yfE1dPa.js";import{o as _}from"./SelectValue-BbKWf16W.js";import{R as v}from"./index-axPHP3AB.js";import{n as y,r as b}from"./VisuallyHidden-CunWEljx.js";import{O as x,T as S,g as C,y as w}from"./Teleport-f0-_cFyq.js";import{i as T}from"./button-xrpYa8G4.js";import{t as E}from"./useForwardExpose-B8uiQ7xX.js";import{t as D}from"./VisuallyHiddenInput-Ev2SMjxs.js";import{t as O}from"./RovingFocusItem-D7JDj4yQ.js";function k(e,t){return S(e)?!1:Array.isArray(e)?e.some(e=>b(e,t)):b(e,t)}var[A,j]=x(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=x(`CheckboxRoot`),I=f({inheritAttrs:!1,__name:`CheckboxRoot`,props:{defaultValue:{type:null,required:!1},modelValue:{type:null,required:!1,default:void 0},disabled:{type:Boolean,required:!1},value:{type:null,required:!1,default:`on`},id:{type:String,required:!1},trueValue:{type:null,required:!1,default:()=>!0},falseValue:{type:null,required:!1,default:()=>!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`},name:{type:String,required:!1},required:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(t,{emit:i}){let s=t,f=i,{forwardRef:h,currentElement:_}=E(),v=A(null),x=g(s,`modelValue`,f,{defaultValue:s.defaultValue??s.falseValue,passive:s.modelValue===void 0}),C=l(()=>v?.disabled.value||s.disabled),w=l(()=>b(x.value,s.trueValue)),j=l(()=>S(v?.modelValue.value)?x.value===`indeterminate`?`indeterminate`:w.value:k(v.modelValue.value,s.value));function P(){if(S(v?.modelValue.value))x.value===`indeterminate`?x.value=s.trueValue:x.value=w.value?s.falseValue:s.trueValue;else{let e=[...v.modelValue.value||[]];if(k(e,s.value)){let t=e.findIndex(e=>b(e,s.value));e.splice(t,1)}else e.push(s.value);v.modelValue.value=e}}let I=y(_),L=l(()=>s.id&&_.value?document.querySelector(`[for="${s.id}"]`)?.innerText:void 0);return F({disabled:C,state:j}),(t,i)=>(n(),c(a(p(v)?.rovingFocus.value?p(O):p(T)),e(t.$attrs,{id:t.id,ref:p(h),role:`checkbox`,"as-child":t.asChild,as:t.as,type:t.as===`button`?`button`:void 0,"aria-checked":p(M)(j.value)?`mixed`:j.value,"aria-required":t.required,"aria-label":t.$attrs[`aria-label`]||L.value,"data-state":p(N)(j.value),"data-disabled":C.value?``:void 0,disabled:C.value,focusable:p(v)?.rovingFocus.value?!C.value:void 0,onKeydown:u(d(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:r(()=>[m(t.$slots,`default`,{modelValue:p(x),state:j.value}),p(I)&&t.name&&!p(v)?(n(),c(p(D),{key:0,type:`checkbox`,checked:!!j.value,name:t.name,value:t.value,disabled:C.value,required:t.required},null,8,[`checked`,`name`,`value`,`disabled`,`required`])):o(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=f({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(t){let{forwardRef:i}=E(),a=P();return(t,o)=>(n(),c(p(C),{present:t.forceMount||p(M)(p(a).state.value)||p(a).state.value===!0},{default:r(()=>[s(p(T),e({ref:p(i),"data-state":p(N)(p(a).state.value),"data-disabled":p(a).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":t.asChild,as:t.as},t.$attrs),{default:r(()=>[m(t.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=f({__name:`Checkbox`,props:{defaultValue:{},modelValue:{},disabled:{type:Boolean},value:{},id:{},trueValue:{},falseValue:{},asChild:{type:Boolean},as:{},name:{},required:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:o}){let l=a,u=o,d=w(h(l,`class`),u);return(a,o)=>(n(),c(p(I),e({"data-slot":`checkbox`},p(d),{class:p(v)(`peer border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,l.class)}),{default:r(e=>[s(p(L),{"data-slot":`checkbox-indicator`,class:`grid place-content-center text-current transition-none`},{default:r(()=>[m(a.$slots,`default`,i(t(e)),()=>[s(p(_),{class:`size-3.5`})])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};

View File

@@ -1 +1 @@
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-BpHHjIYv.js";import{b as l}from"./Teleport-qOjHMYM8.js";import{i as u}from"./button-BTKRNUhQ.js";import{t as d}from"./useForwardExpose-CNhbE6SX.js";import{d as f}from"./DialogTitle-Do1F-aV6.js";var p=i({__name:`DialogDescription`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`p`}},setup(i){let s=i;d();let c=f();return(i,l)=>(t(),r(a(u),e(s,{id:a(c).descriptionId}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`id`]))}}),m=i({__name:`DialogDescription`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,d=l(s(u,`class`));return(i,s)=>(t(),r(a(p),e({"data-slot":`dialog-description`},a(d),{class:a(c)(`text-muted-foreground text-sm`,u.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{p as n,m as t};
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{R as c}from"./index-axPHP3AB.js";import{b as l}from"./Teleport-f0-_cFyq.js";import{i as u}from"./button-xrpYa8G4.js";import{t as d}from"./useForwardExpose-B8uiQ7xX.js";import{d as f}from"./DialogTitle-vfkBik3a.js";var p=i({__name:`DialogDescription`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`p`}},setup(i){let s=i;d();let c=f();return(i,l)=>(t(),r(a(u),e(s,{id:a(c).descriptionId}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`id`]))}}),m=i({__name:`DialogDescription`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let u=i,d=l(s(u,`class`));return(i,s)=>(t(),r(a(p),e({"data-slot":`dialog-description`},a(d),{class:a(c)(`text-muted-foreground text-sm`,u.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{p as n,m as t};

View File

@@ -1 +1 @@
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as o}from"./index-BpHHjIYv.js";var s=n({__name:`DialogFooter`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`dialog-footer`,class:r(i(o)(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};
import{I as e,v as t,x as n,xt as r,yt as i,z as a}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{R as o}from"./index-axPHP3AB.js";var s=n({__name:`DialogFooter`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(n){let s=n;return(n,c)=>(e(),t(`div`,{"data-slot":`dialog-footer`,class:r(i(o)(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,s.class))},[a(n.$slots,`default`)],2))}});export{s as t};

View File

@@ -1 +1 @@
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,ut as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as d}from"./dist-3yfE1dPa.js";import{J as f}from"./index-BpHHjIYv.js";import{O as p,_ as m,b as h,d as g,g as _,l as v}from"./Teleport-qOjHMYM8.js";import{i as y}from"./button-BTKRNUhQ.js";import{t as b}from"./useForwardExpose-CNhbE6SX.js";var[x,S]=p([`MenuCheckboxItem`,`MenuRadioItem`],`MenuItemIndicatorContext`),C=c({__name:`MenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let t=x({modelValue:s(!1)});return(e,i)=>(n(),o(l(_),{present:e.forceMount||l(g)(l(t).modelValue.value)||l(t).modelValue.value===!0},{default:r(()=>[a(l(y),{as:e.as,"as-child":e.asChild,"data-state":l(v)(l(t).modelValue.value)},{default:r(()=>[u(e.$slots,`default`)]),_:3},8,[`as`,`as-child`,`data-state`])]),_:3},8,[`present`]))}}),[w,T]=p(`MenuGroup`),E=c({__name:`MenuGroup`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,a=m(void 0,`reka-menu-group`);return T({id:a}),(t,s)=>(n(),o(l(y),e({role:`group`},i,{"aria-labelledby":l(a)}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`aria-labelledby`]))}}),D=c({__name:`MenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`div`}},setup(t){let i=t,a=w({id:``});return(t,s)=>(n(),o(l(y),e(i,{id:l(a).id||void 0}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`id`]))}}),O=c({__name:`MenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t;return(t,a)=>(n(),o(l(y),e(i,{role:`separator`,"aria-orientation":`horizontal`}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16))}}),k=c({__name:`DropdownMenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(C),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),A=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(D),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),j=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(O),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),M=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=d(r,`class`);return(t,a)=>(n(),o(l(j),e({"data-slot":`dropdown-menu-separator`},l(i),{class:l(f)(`bg-border -mx-1 my-1 h-px`,r.class)}),null,16,[`class`]))}}),N=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]},inset:{type:Boolean}},setup(t){let i=t,a=h(d(i,`class`,`inset`));return(s,c)=>(n(),o(l(A),e({"data-slot":`dropdown-menu-label`,"data-inset":t.inset?``:void 0},l(a),{class:l(f)(`px-2 py-1.5 text-sm font-medium data-[inset]:pl-8`,i.class)}),{default:r(()=>[u(s.$slots,`default`)]),_:3},16,[`data-inset`,`class`]))}});export{S as a,E as i,M as n,k as r,N as t};
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,ut as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as d}from"./dist-3yfE1dPa.js";import{R as f}from"./index-axPHP3AB.js";import{O as p,_ as m,b as h,d as g,g as _,l as v}from"./Teleport-f0-_cFyq.js";import{i as y}from"./button-xrpYa8G4.js";import{t as b}from"./useForwardExpose-B8uiQ7xX.js";var[x,S]=p([`MenuCheckboxItem`,`MenuRadioItem`],`MenuItemIndicatorContext`),C=c({__name:`MenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let t=x({modelValue:s(!1)});return(e,i)=>(n(),o(l(_),{present:e.forceMount||l(g)(l(t).modelValue.value)||l(t).modelValue.value===!0},{default:r(()=>[a(l(y),{as:e.as,"as-child":e.asChild,"data-state":l(v)(l(t).modelValue.value)},{default:r(()=>[u(e.$slots,`default`)]),_:3},8,[`as`,`as-child`,`data-state`])]),_:3},8,[`present`]))}}),[w,T]=p(`MenuGroup`),E=c({__name:`MenuGroup`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,a=m(void 0,`reka-menu-group`);return T({id:a}),(t,s)=>(n(),o(l(y),e({role:`group`},i,{"aria-labelledby":l(a)}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`aria-labelledby`]))}}),D=c({__name:`MenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`div`}},setup(t){let i=t,a=w({id:``});return(t,s)=>(n(),o(l(y),e(i,{id:l(a).id||void 0}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16,[`id`]))}}),O=c({__name:`MenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t;return(t,a)=>(n(),o(l(y),e(i,{role:`separator`,"aria-orientation":`horizontal`}),{default:r(()=>[u(t.$slots,`default`)]),_:3},16))}}),k=c({__name:`DropdownMenuItemIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(C),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),A=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(D),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),j=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let a=e;return b(),(e,s)=>(n(),o(l(O),i(t(a)),{default:r(()=>[u(e.$slots,`default`)]),_:3},16))}}),M=c({__name:`DropdownMenuSeparator`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=d(r,`class`);return(t,a)=>(n(),o(l(j),e({"data-slot":`dropdown-menu-separator`},l(i),{class:l(f)(`bg-border -mx-1 my-1 h-px`,r.class)}),null,16,[`class`]))}}),N=c({__name:`DropdownMenuLabel`,props:{asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]},inset:{type:Boolean}},setup(t){let i=t,a=h(d(i,`class`,`inset`));return(s,c)=>(n(),o(l(A),e({"data-slot":`dropdown-menu-label`,"data-inset":t.inset?``:void 0},l(a),{class:l(f)(`px-2 py-1.5 text-sm font-medium data-[inset]:pl-8`,i.class)}),{default:r(()=>[u(s.$slots,`default`)]),_:3},16,[`data-inset`,`class`]))}});export{S as a,E as i,M as n,k as r,N as t};

View File

@@ -1 +1 @@
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,gt as s,h as c,m as l,x as u,yt as d,z as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as p,p as m}from"./dist-3yfE1dPa.js";import{t as h}from"./circle-Cc5GzalR.js";import{J as g}from"./index-BpHHjIYv.js";import{O as _,b as v,l as y,x as b,y as x}from"./Teleport-qOjHMYM8.js";import{a as S}from"./DropdownMenuTrigger-Dmk4lbKz.js";import{t as C}from"./useForwardExpose-CNhbE6SX.js";import{a as w,i as T,r as E}from"./DropdownMenuLabel-Bls_J4kr.js";var[D,O]=_(`MenuRadioGroup`),k=u({__name:`MenuRadioGroup`,props:{modelValue:{type:null,required:!1,default:``},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=a,l=v(p(s,[`modelValue`])),u=m(s,`modelValue`,c);return O({modelValue:u,onValueChange:e=>{u.value=e}}),(e,a)=>(n(),o(T,i(t(d(l))),{default:r(()=>[f(e.$slots,`default`,{modelValue:d(u)})]),_:3},16))}}),A=u({__name:`MenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(t,{emit:i}){let a=t,c=i,u=v(p(a,[`value`])),{value:m}=s(a),h=D(),g=l(()=>h.modelValue.value===m?.value);return w({modelValue:g}),(t,i)=>(n(),o(S,e({role:`menuitemradio`},d(u),{"aria-checked":g.value,"data-state":d(y)(g.value),onSelect:i[0]||=async e=>{c(`select`,e),d(h).onValueChange(d(m))}}),{default:r(()=>[f(t.$slots,`default`)]),_:3},16,[`aria-checked`,`data-state`]))}}),j=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=b(a);return C(),(e,a)=>(n(),o(d(k),i(t({...s,...d(c)})),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),M=u({__name:`DropdownMenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(e,{emit:a}){let s=x(e,a);return C(),(e,a)=>(n(),o(d(A),i(t(d(s))),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),N=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{},asChild:{type:Boolean},as:{}},emits:[`update:modelValue`],setup(t,{emit:i}){let a=x(t,i);return(t,i)=>(n(),o(d(j),e({"data-slot":`dropdown-menu-radio-group`},d(a)),{default:r(()=>[f(t.$slots,`default`)]),_:3},16))}}),P={class:`pointer-events-none absolute left-2 flex size-3.5 items-center justify-center`},F=u({__name:`DropdownMenuRadioItem`,props:{value:{},disabled:{type:Boolean},textValue:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`select`],setup(t,{emit:i}){let s=t,l=i,u=x(p(s,`class`),l);return(t,i)=>(n(),o(d(M),e({"data-slot":`dropdown-menu-radio-item`},d(u),{class:d(g)(`focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,s.class)}),{default:r(()=>[c(`span`,P,[a(d(E),null,{default:r(()=>[f(t.$slots,`indicator-icon`,{},()=>[a(d(h),{class:`size-2 fill-current`})])]),_:3})]),f(t.$slots,`default`)]),_:3},16,[`class`]))}});export{N as n,F as t};
import{A as e,C as t,I as n,Q as r,St as i,b as a,g as o,gt as s,h as c,m as l,x as u,yt as d,z as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as p,p as m}from"./dist-3yfE1dPa.js";import{t as h}from"./circle-Cc5GzalR.js";import{R as g}from"./index-axPHP3AB.js";import{O as _,b as v,l as y,x as b,y as x}from"./Teleport-f0-_cFyq.js";import{a as S}from"./DropdownMenuTrigger-CaEGJhbh.js";import{t as C}from"./useForwardExpose-B8uiQ7xX.js";import{a as w,i as T,r as E}from"./DropdownMenuLabel-BxrcQY1z.js";var[D,O]=_(`MenuRadioGroup`),k=u({__name:`MenuRadioGroup`,props:{modelValue:{type:null,required:!1,default:``},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=a,l=v(p(s,[`modelValue`])),u=m(s,`modelValue`,c);return O({modelValue:u,onValueChange:e=>{u.value=e}}),(e,a)=>(n(),o(T,i(t(d(l))),{default:r(()=>[f(e.$slots,`default`,{modelValue:d(u)})]),_:3},16))}}),A=u({__name:`MenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(t,{emit:i}){let a=t,c=i,u=v(p(a,[`value`])),{value:m}=s(a),h=D(),g=l(()=>h.modelValue.value===m?.value);return w({modelValue:g}),(t,i)=>(n(),o(S,e({role:`menuitemradio`},d(u),{"aria-checked":g.value,"data-state":d(y)(g.value),onSelect:i[0]||=async e=>{c(`select`,e),d(h).onValueChange(d(m))}}),{default:r(()=>[f(t.$slots,`default`)]),_:3},16,[`aria-checked`,`data-state`]))}}),j=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{type:null,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let s=e,c=b(a);return C(),(e,a)=>(n(),o(d(k),i(t({...s,...d(c)})),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),M=u({__name:`DropdownMenuRadioItem`,props:{value:{type:null,required:!0},disabled:{type:Boolean,required:!1},textValue:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`select`],setup(e,{emit:a}){let s=x(e,a);return C(),(e,a)=>(n(),o(d(A),i(t(d(s))),{default:r(()=>[f(e.$slots,`default`)]),_:3},16))}}),N=u({__name:`DropdownMenuRadioGroup`,props:{modelValue:{},asChild:{type:Boolean},as:{}},emits:[`update:modelValue`],setup(t,{emit:i}){let a=x(t,i);return(t,i)=>(n(),o(d(j),e({"data-slot":`dropdown-menu-radio-group`},d(a)),{default:r(()=>[f(t.$slots,`default`)]),_:3},16))}}),P={class:`pointer-events-none absolute left-2 flex size-3.5 items-center justify-center`},F=u({__name:`DropdownMenuRadioItem`,props:{value:{},disabled:{type:Boolean},textValue:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`select`],setup(t,{emit:i}){let s=t,l=i,u=x(p(s,`class`),l);return(t,i)=>(n(),o(d(M),e({"data-slot":`dropdown-menu-radio-item`},d(u),{class:d(g)(`focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,s.class)}),{default:r(()=>[c(`span`,P,[a(d(E),null,{default:r(()=>[f(t.$slots,`indicator-icon`,{},()=>[a(d(h),{class:`size-2 fill-current`})])]),_:3})]),f(t.$slots,`default`)]),_:3},16,[`class`]))}});export{N as n,F as t};

View File

@@ -1 +1 @@
import{$ as e,I as t,at as n,i as r,v as i,x as a,xt as o,yt as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as c}from"./dist-3yfE1dPa.js";import{J as l}from"./index-BpHHjIYv.js";var u=a({__name:`Input`,props:{defaultValue:{},modelValue:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:u}){let d=a,f=c(d,`modelValue`,u,{passive:!0,defaultValue:d.defaultValue});return(a,c)=>e((t(),i(`input`,{"onUpdate:modelValue":c[0]||=e=>n(f)?f.value=e:null,"data-slot":`input`,class:o(s(l)(`file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,`focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]`,`aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,d.class))},null,2)),[[r,s(f)]])}});export{u as t};
import{$ as e,I as t,at as n,i as r,v as i,x as a,xt as o,yt as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as c}from"./dist-3yfE1dPa.js";import{R as l}from"./index-axPHP3AB.js";var u=a({__name:`Input`,props:{defaultValue:{},modelValue:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(a,{emit:u}){let d=a,f=c(d,`modelValue`,u,{passive:!0,defaultValue:d.defaultValue});return(a,c)=>e((t(),i(`input`,{"onUpdate:modelValue":c[0]||=e=>n(f)?f.value=e:null,"data-slot":`input`,class:o(s(l)(`file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,`focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]`,`aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,d.class))},null,2)),[[r,s(f)]])}});export{u as t};

View File

@@ -1 +1 @@
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{J as c}from"./index-BpHHjIYv.js";import{i as l}from"./button-BTKRNUhQ.js";import{t as u}from"./useForwardExpose-CNhbE6SX.js";var d=i({__name:`Label`,props:{for:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`label`}},setup(i){let s=i;return u(),(i,c)=>(t(),r(a(l),e(s,{onMousedown:c[0]||=e=>{!e.defaultPrevented&&e.detail>1&&e.preventDefault()}}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16))}}),f=i({__name:`Label`,props:{for:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let l=i,u=s(l,`class`);return(i,s)=>(t(),r(a(d),e({"data-slot":`label`},a(u),{class:a(c)(`flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,l.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};
import{A as e,I as t,Q as n,g as r,x as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as s}from"./dist-3yfE1dPa.js";import{R as c}from"./index-axPHP3AB.js";import{i as l}from"./button-xrpYa8G4.js";import{t as u}from"./useForwardExpose-B8uiQ7xX.js";var d=i({__name:`Label`,props:{for:{type:String,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`label`}},setup(i){let s=i;return u(),(i,c)=>(t(),r(a(l),e(s,{onMousedown:c[0]||=e=>{!e.defaultPrevented&&e.detail>1&&e.preventDefault()}}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16))}}),f=i({__name:`Label`,props:{for:{},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(i){let l=i,u=s(l,`class`);return(i,s)=>(t(),r(a(d),e({"data-slot":`label`},a(u),{class:a(c)(`flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,l.class)}),{default:n(()=>[o(i.$slots,`default`)]),_:3},16,[`class`]))}});export{f as t};

View File

@@ -1 +1 @@
import{I as e,Q as t,b as n,g as r,gt as i,ut as a,x as o,yt as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as l}from"./dist-3yfE1dPa.js";import{D as u,O as d}from"./Teleport-qOjHMYM8.js";import{i as f}from"./button-BTKRNUhQ.js";import{o as p,u as m}from"./PopperContent-oFiuPLDs.js";var h=`rovingFocusGroup.onEntryFocus`,g={bubbles:!1,cancelable:!0},_={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function v(e,t){return t===`rtl`?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}function y(e,t,n){let r=v(e.key,n);if(!(t===`vertical`&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===`horizontal`&&[`ArrowUp`,`ArrowDown`].includes(r)))return _[r]}function b(e,t=!1){let n=u();for(let r of e)if(r===n||(r.focus({preventScroll:t}),u()!==n))return}function x(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var[S,C]=d(`RovingFocusGroup`),w=o({__name:`RovingFocusGroup`,props:{orientation:{type:String,required:!1,default:void 0},dir:{type:String,required:!1},loop:{type:Boolean,required:!1,default:!1},currentTabStopId:{type:[String,null],required:!1},defaultCurrentTabStopId:{type:String,required:!1},preventScrollOnEntryFocus:{type:Boolean,required:!1,default:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`entryFocus`,`update:currentTabStopId`],setup(o,{expose:u,emit:d}){let _=o,v=d,{loop:y,orientation:x,dir:S}=i(_),w=m(S),T=l(_,`currentTabStopId`,v,{defaultValue:_.defaultCurrentTabStopId,passive:_.currentTabStopId===void 0}),E=a(!1),D=a(!1),O=a(0),{getItems:k,CollectionSlot:A}=p({isProvider:!0});function j(e){let t=!D.value;if(e.currentTarget&&e.target===e.currentTarget&&t&&!E.value){let t=new CustomEvent(h,g);if(e.currentTarget.dispatchEvent(t),v(`entryFocus`,t),!t.defaultPrevented){let e=k().map(e=>e.ref).filter(e=>e.dataset.disabled!==``);b([e.find(e=>e.getAttribute(`data-active`)===``),e.find(e=>e.getAttribute(`data-highlighted`)===``),e.find(e=>e.id===T.value),...e].filter(Boolean),_.preventScrollOnEntryFocus)}}D.value=!1}function M(){setTimeout(()=>{D.value=!1},1)}return u({getItems:k}),C({loop:y,dir:w,orientation:x,currentTabStopId:T,onItemFocus:e=>{T.value=e},onItemShiftTab:()=>{E.value=!0},onFocusableItemAdd:()=>{O.value++},onFocusableItemRemove:()=>{O.value--}}),(i,a)=>(e(),r(s(A),null,{default:t(()=>[n(s(f),{tabindex:E.value||O.value===0?-1:0,"data-orientation":s(x),as:i.as,"as-child":i.asChild,dir:s(w),style:{outline:`none`},onMousedown:a[0]||=e=>D.value=!0,onMouseup:M,onFocus:j,onBlur:a[1]||=e=>E.value=!1},{default:t(()=>[c(i.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`as`,`as-child`,`dir`])]),_:3}))}});export{x as a,y as i,S as n,b as r,w as t};
import{I as e,Q as t,b as n,g as r,gt as i,ut as a,x as o,yt as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{p as l}from"./dist-3yfE1dPa.js";import{D as u,O as d}from"./Teleport-f0-_cFyq.js";import{i as f}from"./button-xrpYa8G4.js";import{o as p,u as m}from"./PopperContent-Wu1vPEc9.js";var h=`rovingFocusGroup.onEntryFocus`,g={bubbles:!1,cancelable:!0},_={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function v(e,t){return t===`rtl`?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}function y(e,t,n){let r=v(e.key,n);if(!(t===`vertical`&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===`horizontal`&&[`ArrowUp`,`ArrowDown`].includes(r)))return _[r]}function b(e,t=!1){let n=u();for(let r of e)if(r===n||(r.focus({preventScroll:t}),u()!==n))return}function x(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var[S,C]=d(`RovingFocusGroup`),w=o({__name:`RovingFocusGroup`,props:{orientation:{type:String,required:!1,default:void 0},dir:{type:String,required:!1},loop:{type:Boolean,required:!1,default:!1},currentTabStopId:{type:[String,null],required:!1},defaultCurrentTabStopId:{type:String,required:!1},preventScrollOnEntryFocus:{type:Boolean,required:!1,default:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`entryFocus`,`update:currentTabStopId`],setup(o,{expose:u,emit:d}){let _=o,v=d,{loop:y,orientation:x,dir:S}=i(_),w=m(S),T=l(_,`currentTabStopId`,v,{defaultValue:_.defaultCurrentTabStopId,passive:_.currentTabStopId===void 0}),E=a(!1),D=a(!1),O=a(0),{getItems:k,CollectionSlot:A}=p({isProvider:!0});function j(e){let t=!D.value;if(e.currentTarget&&e.target===e.currentTarget&&t&&!E.value){let t=new CustomEvent(h,g);if(e.currentTarget.dispatchEvent(t),v(`entryFocus`,t),!t.defaultPrevented){let e=k().map(e=>e.ref).filter(e=>e.dataset.disabled!==``);b([e.find(e=>e.getAttribute(`data-active`)===``),e.find(e=>e.getAttribute(`data-highlighted`)===``),e.find(e=>e.id===T.value),...e].filter(Boolean),_.preventScrollOnEntryFocus)}}D.value=!1}function M(){setTimeout(()=>{D.value=!1},1)}return u({getItems:k}),C({loop:y,dir:w,orientation:x,currentTabStopId:T,onItemFocus:e=>{T.value=e},onItemShiftTab:()=>{E.value=!0},onFocusableItemAdd:()=>{O.value++},onFocusableItemRemove:()=>{O.value--}}),(i,a)=>(e(),r(s(A),null,{default:t(()=>[n(s(f),{tabindex:E.value||O.value===0?-1:0,"data-orientation":s(x),as:i.as,"as-child":i.asChild,dir:s(w),style:{outline:`none`},onMousedown:a[0]||=e=>D.value=!0,onMouseup:M,onFocus:j,onBlur:a[1]||=e=>E.value=!1},{default:t(()=>[c(i.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`as`,`as-child`,`dir`])]),_:3}))}});export{x as a,y as i,S as n,b as r,w as t};

View File

@@ -1 +1 @@
import{I as e,N as t,P as n,Q as r,b as i,g as a,j as o,m as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{_ as d}from"./Teleport-qOjHMYM8.js";import{i as f}from"./button-BTKRNUhQ.js";import{o as p}from"./PopperContent-oFiuPLDs.js";import{a as m,i as h,n as g,r as _}from"./RovingFocusGroup--sGcMhFA.js";var v=c({__name:`RovingFocusItem`,props:{tabStopId:{type:String,required:!1},focusable:{type:Boolean,required:!1,default:!0},active:{type:Boolean,required:!1},allowShiftKey:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(c){let v=c,y=g(),b=d(),x=s(()=>v.tabStopId||b),S=s(()=>y.currentTabStopId.value===x.value),{getItems:C,CollectionItem:w}=p();t(()=>{v.focusable&&y.onFocusableItemAdd()}),n(()=>{v.focusable&&y.onFocusableItemRemove()});function T(e){if(e.key===`Tab`&&e.shiftKey){y.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=h(e,y.orientation.value,y.dir.value);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||!v.allowShiftKey&&e.shiftKey)return;e.preventDefault();let n=[...C().map(e=>e.ref).filter(e=>e.dataset.disabled!==``)];if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=y.loop.value?m(n,r+1):n.slice(r+1)}o(()=>_(n))}}return(t,n)=>(e(),a(l(w),null,{default:r(()=>[i(l(f),{tabindex:S.value?0:-1,"data-orientation":l(y).orientation.value,"data-active":t.active?``:void 0,"data-disabled":t.focusable?void 0:``,as:t.as,"as-child":t.asChild,onMousedown:n[0]||=e=>{t.focusable?l(y).onItemFocus(x.value):e.preventDefault()},onFocus:n[1]||=e=>l(y).onItemFocus(x.value),onKeydown:T},{default:r(()=>[u(t.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`data-active`,`data-disabled`,`as`,`as-child`])]),_:3}))}});export{v as t};
import{I as e,N as t,P as n,Q as r,b as i,g as a,j as o,m as s,x as c,yt as l,z as u}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{_ as d}from"./Teleport-f0-_cFyq.js";import{i as f}from"./button-xrpYa8G4.js";import{o as p}from"./PopperContent-Wu1vPEc9.js";import{a as m,i as h,n as g,r as _}from"./RovingFocusGroup-CoCJohzY.js";var v=c({__name:`RovingFocusItem`,props:{tabStopId:{type:String,required:!1},focusable:{type:Boolean,required:!1,default:!0},active:{type:Boolean,required:!1},allowShiftKey:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(c){let v=c,y=g(),b=d(),x=s(()=>v.tabStopId||b),S=s(()=>y.currentTabStopId.value===x.value),{getItems:C,CollectionItem:w}=p();t(()=>{v.focusable&&y.onFocusableItemAdd()}),n(()=>{v.focusable&&y.onFocusableItemRemove()});function T(e){if(e.key===`Tab`&&e.shiftKey){y.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=h(e,y.orientation.value,y.dir.value);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||!v.allowShiftKey&&e.shiftKey)return;e.preventDefault();let n=[...C().map(e=>e.ref).filter(e=>e.dataset.disabled!==``)];if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=y.loop.value?m(n,r+1):n.slice(r+1)}o(()=>_(n))}}return(t,n)=>(e(),a(l(w),null,{default:r(()=>[i(l(f),{tabindex:S.value?0:-1,"data-orientation":l(y).orientation.value,"data-active":t.active?``:void 0,"data-disabled":t.focusable?void 0:``,as:t.as,"as-child":t.asChild,onMousedown:n[0]||=e=>{t.focusable?l(y).onItemFocus(x.value):e.preventDefault()},onFocus:n[1]||=e=>l(y).onItemFocus(x.value),onKeydown:T},{default:r(()=>[u(t.$slots,`default`)]),_:3},8,[`tabindex`,`data-orientation`,`data-active`,`data-disabled`,`as`,`as-child`])]),_:3}))}});export{v as t};

View File

@@ -1 +1 @@
import{A as e,C as t,I as n,Q as r,St as i,g as a,m as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u}from"./dist-3yfE1dPa.js";import{J as d}from"./index-BpHHjIYv.js";import{i as f}from"./button-BTKRNUhQ.js";var p=s({__name:`BaseSeparator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,s=[`horizontal`,`vertical`];function u(e){return s.includes(e)}let d=o(()=>u(i.orientation)?i.orientation:`horizontal`),p=o(()=>d.value===`vertical`?i.orientation:void 0),m=o(()=>i.decorative?{role:`none`}:{"aria-orientation":p.value,role:`separator`});return(t,i)=>(n(),a(c(f),e({as:t.as,"as-child":t.asChild,"data-orientation":d.value},m.value),{default:r(()=>[l(t.$slots,`default`)]),_:3},16,[`as`,`as-child`,`data-orientation`]))}}),m=s({__name:`Separator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let o=e;return(e,s)=>(n(),a(p,i(t(o)),{default:r(()=>[l(e.$slots,`default`)]),_:3},16))}}),h=s({__name:`Separator`,props:{orientation:{default:`horizontal`},decorative:{type:Boolean,default:!0},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=u(r,`class`);return(t,o)=>(n(),a(c(m),e({"data-slot":`separator`},c(i),{class:c(d)(`bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,r.class)}),null,16,[`class`]))}});export{m as n,h as t};
import{A as e,C as t,I as n,Q as r,St as i,g as a,m as o,x as s,yt as c,z as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{b as u}from"./dist-3yfE1dPa.js";import{R as d}from"./index-axPHP3AB.js";import{i as f}from"./button-xrpYa8G4.js";var p=s({__name:`BaseSeparator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let i=t,s=[`horizontal`,`vertical`];function u(e){return s.includes(e)}let d=o(()=>u(i.orientation)?i.orientation:`horizontal`),p=o(()=>d.value===`vertical`?i.orientation:void 0),m=o(()=>i.decorative?{role:`none`}:{"aria-orientation":p.value,role:`separator`});return(t,i)=>(n(),a(c(f),e({as:t.as,"as-child":t.asChild,"data-orientation":d.value},m.value),{default:r(()=>[l(t.$slots,`default`)]),_:3},16,[`as`,`as-child`,`data-orientation`]))}}),m=s({__name:`Separator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(e){let o=e;return(e,s)=>(n(),a(p,i(t(o)),{default:r(()=>[l(e.$slots,`default`)]),_:3},16))}}),h=s({__name:`Separator`,props:{orientation:{default:`horizontal`},decorative:{type:Boolean,default:!0},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t,i=u(r,`class`);return(t,o)=>(n(),a(c(m),e({"data-slot":`separator`},c(i),{class:c(d)(`bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,r.class)}),null,16,[`class`]))}});export{m as n,h as t};

View File

@@ -1 +1 @@
import{I as e,h as t,v as n,x as r,xt as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as s}from"./index-BpHHjIYv.js";var c={"data-slot":`table-container`,class:`relative w-full overflow-auto`},l=r({__name:`Table`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let l=r;return(r,u)=>(e(),n(`div`,c,[t(`table`,{"data-slot":`table`,class:i(a(s)(`w-full caption-bottom text-sm`,l.class))},[o(r.$slots,`default`)],2)]))}}),u=r({__name:`TableBody`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tbody`,{"data-slot":`table-body`,class:i(a(s)(`[&_tr:last-child]:border-0`,r.class))},[o(t.$slots,`default`)],2))}}),d=r({__name:`TableCell`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`td`,{"data-slot":`table-cell`,class:i(a(s)(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}}),f=r({__name:`TableHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`thead`,{"data-slot":`table-header`,class:i(a(s)(`[&_tr]:border-b`,r.class))},[o(t.$slots,`default`)],2))}}),p=r({__name:`TableRow`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tr`,{"data-slot":`table-row`,class:i(a(s)(`hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors`,r.class))},[o(t.$slots,`default`)],2))}}),m=r({__name:`TableHead`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`th`,{"data-slot":`table-head`,class:i(a(s)(`text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}});export{u as a,d as i,p as n,l as o,f as r,m as t};
import{I as e,h as t,v as n,x as r,xt as i,yt as a,z as o}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{R as s}from"./index-axPHP3AB.js";var c={"data-slot":`table-container`,class:`relative w-full overflow-auto`},l=r({__name:`Table`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let l=r;return(r,u)=>(e(),n(`div`,c,[t(`table`,{"data-slot":`table`,class:i(a(s)(`w-full caption-bottom text-sm`,l.class))},[o(r.$slots,`default`)],2)]))}}),u=r({__name:`TableBody`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tbody`,{"data-slot":`table-body`,class:i(a(s)(`[&_tr:last-child]:border-0`,r.class))},[o(t.$slots,`default`)],2))}}),d=r({__name:`TableCell`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`td`,{"data-slot":`table-cell`,class:i(a(s)(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}}),f=r({__name:`TableHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`thead`,{"data-slot":`table-header`,class:i(a(s)(`[&_tr]:border-b`,r.class))},[o(t.$slots,`default`)],2))}}),p=r({__name:`TableRow`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`tr`,{"data-slot":`table-row`,class:i(a(s)(`hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors`,r.class))},[o(t.$slots,`default`)],2))}}),m=r({__name:`TableHead`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let r=t;return(t,c)=>(e(),n(`th`,{"data-slot":`table-head`,class:i(a(s)(`text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,r.class))},[o(t.$slots,`default`)],2))}});export{u as a,d as i,p as n,l as o,f as r,m as t};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{I as e,Q as t,_t as n,g as r,m as i,x as a,yt as o,z as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{i as c}from"./dist-3yfE1dPa.js";import{i as l}from"./button-BTKRNUhQ.js";function u(e){return typeof e==`string`?`'${e}'`:new d().serialize(e)}var d=function(){class e{#e=new Map;compare(e,t){let n=typeof e,r=typeof t;return n===`string`&&r===`string`?e.localeCompare(t):n===`number`&&r===`number`?e-t:String.prototype.localeCompare.call(this.serialize(e,!0),this.serialize(t,!0))}serialize(e,t){if(e===null)return`null`;switch(typeof e){case`string`:return t?e:`'${e}'`;case`bigint`:return`${e}n`;case`object`:return this.$object(e);case`function`:return this.$function(e)}return String(e)}serializeObject(e){let t=Object.prototype.toString.call(e);if(t!==`[object Object]`)return this.serializeBuiltInType(t.length<10?`unknown:${t}`:t.slice(8,-1),e);let n=e.constructor,r=n===Object||n===void 0?``:n.name;if(r!==``&&globalThis[r]===n)return this.serializeBuiltInType(r,e);if(typeof e.toJSON==`function`){let t=e.toJSON();return r+(typeof t==`object`&&t?this.$object(t):`(${this.serialize(t)})`)}return this.serializeObjectEntries(r,Object.entries(e))}serializeBuiltInType(e,t){let n=this[`$`+e];if(n)return n.call(this,t);if(typeof t?.entries==`function`)return this.serializeObjectEntries(e,t.entries());throw Error(`Cannot serialize ${e}`)}serializeObjectEntries(e,t){let n=Array.from(t).sort((e,t)=>this.compare(e[0],t[0])),r=`${e}{`;for(let e=0;e<n.length;e++){let[t,i]=n[e];r+=`${this.serialize(t,!0)}:${this.serialize(i)}`,e<n.length-1&&(r+=`,`)}return r+`}`}$object(e){let t=this.#e.get(e);return t===void 0&&(this.#e.set(e,`#${this.#e.size}`),t=this.serializeObject(e),this.#e.set(e,t)),t}$function(e){let t=Function.prototype.toString.call(e);return t.slice(-15)===`[native code] }`?`${e.name||``}()[native]`:`${e.name}(${e.length})${t.replace(/\s*\n\s*/g,``)}`}$Array(e){let t=`[`;for(let n=0;n<e.length;n++)t+=this.serialize(e[n]),n<e.length-1&&(t+=`,`);return t+`]`}$Date(e){try{return`Date(${e.toISOString()})`}catch{return`Date(null)`}}$ArrayBuffer(e){return`ArrayBuffer[${new Uint8Array(e).join(`,`)}]`}$Set(e){return`Set${this.$Array(Array.from(e).sort((e,t)=>this.compare(e,t)))}`}$Map(e){return this.serializeObjectEntries(`Map`,e.entries())}}for(let t of[`Error`,`RegExp`,`URL`])e.prototype[`$`+t]=function(e){return`${t}(${e})`};for(let t of[`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float32Array`,`Float64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`,`)}]`};for(let t of[`BigInt64Array`,`BigUint64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`n,`)}${e.length>0?`n`:``}]`};return e}();function f(e,t){return e===t||u(e)===u(t)}function p(e){return i(()=>n(e)?!!c(e)?.closest(`form`):!0)}var m=a({__name:`VisuallyHidden`,props:{feature:{type:String,required:!1,default:`focusable`},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(n){return(n,i)=>(e(),r(o(l),{as:n.as,"as-child":n.asChild,"aria-hidden":n.feature===`focusable`?`true`:void 0,"data-hidden":n.feature===`fully-hidden`?``:void 0,tabindex:n.feature===`fully-hidden`?`-1`:void 0,style:{position:`absolute`,border:0,width:`1px`,height:`1px`,padding:0,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,clipPath:`inset(50%)`,whiteSpace:`nowrap`,wordWrap:`normal`,top:`-1px`,left:`-1px`}},{default:t(()=>[s(n.$slots,`default`)]),_:3},8,[`as`,`as-child`,`aria-hidden`,`data-hidden`,`tabindex`]))}});export{p as n,f as r,m as t};
import{I as e,Q as t,_t as n,g as r,m as i,x as a,yt as o,z as s}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{i as c}from"./dist-3yfE1dPa.js";import{i as l}from"./button-xrpYa8G4.js";function u(e){return typeof e==`string`?`'${e}'`:new d().serialize(e)}var d=function(){class e{#e=new Map;compare(e,t){let n=typeof e,r=typeof t;return n===`string`&&r===`string`?e.localeCompare(t):n===`number`&&r===`number`?e-t:String.prototype.localeCompare.call(this.serialize(e,!0),this.serialize(t,!0))}serialize(e,t){if(e===null)return`null`;switch(typeof e){case`string`:return t?e:`'${e}'`;case`bigint`:return`${e}n`;case`object`:return this.$object(e);case`function`:return this.$function(e)}return String(e)}serializeObject(e){let t=Object.prototype.toString.call(e);if(t!==`[object Object]`)return this.serializeBuiltInType(t.length<10?`unknown:${t}`:t.slice(8,-1),e);let n=e.constructor,r=n===Object||n===void 0?``:n.name;if(r!==``&&globalThis[r]===n)return this.serializeBuiltInType(r,e);if(typeof e.toJSON==`function`){let t=e.toJSON();return r+(typeof t==`object`&&t?this.$object(t):`(${this.serialize(t)})`)}return this.serializeObjectEntries(r,Object.entries(e))}serializeBuiltInType(e,t){let n=this[`$`+e];if(n)return n.call(this,t);if(typeof t?.entries==`function`)return this.serializeObjectEntries(e,t.entries());throw Error(`Cannot serialize ${e}`)}serializeObjectEntries(e,t){let n=Array.from(t).sort((e,t)=>this.compare(e[0],t[0])),r=`${e}{`;for(let e=0;e<n.length;e++){let[t,i]=n[e];r+=`${this.serialize(t,!0)}:${this.serialize(i)}`,e<n.length-1&&(r+=`,`)}return r+`}`}$object(e){let t=this.#e.get(e);return t===void 0&&(this.#e.set(e,`#${this.#e.size}`),t=this.serializeObject(e),this.#e.set(e,t)),t}$function(e){let t=Function.prototype.toString.call(e);return t.slice(-15)===`[native code] }`?`${e.name||``}()[native]`:`${e.name}(${e.length})${t.replace(/\s*\n\s*/g,``)}`}$Array(e){let t=`[`;for(let n=0;n<e.length;n++)t+=this.serialize(e[n]),n<e.length-1&&(t+=`,`);return t+`]`}$Date(e){try{return`Date(${e.toISOString()})`}catch{return`Date(null)`}}$ArrayBuffer(e){return`ArrayBuffer[${new Uint8Array(e).join(`,`)}]`}$Set(e){return`Set${this.$Array(Array.from(e).sort((e,t)=>this.compare(e,t)))}`}$Map(e){return this.serializeObjectEntries(`Map`,e.entries())}}for(let t of[`Error`,`RegExp`,`URL`])e.prototype[`$`+t]=function(e){return`${t}(${e})`};for(let t of[`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float32Array`,`Float64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`,`)}]`};for(let t of[`BigInt64Array`,`BigUint64Array`])e.prototype[`$`+t]=function(e){return`${t}[${e.join(`n,`)}${e.length>0?`n`:``}]`};return e}();function f(e,t){return e===t||u(e)===u(t)}function p(e){return i(()=>n(e)?!!c(e)?.closest(`form`):!0)}var m=a({__name:`VisuallyHidden`,props:{feature:{type:String,required:!1,default:`focusable`},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(n){return(n,i)=>(e(),r(o(l),{as:n.as,"as-child":n.asChild,"aria-hidden":n.feature===`focusable`?`true`:void 0,"data-hidden":n.feature===`fully-hidden`?``:void 0,tabindex:n.feature===`fully-hidden`?`-1`:void 0,style:{position:`absolute`,border:0,width:`1px`,height:`1px`,padding:0,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,clipPath:`inset(50%)`,whiteSpace:`nowrap`,wordWrap:`normal`,top:`-1px`,left:`-1px`}},{default:t(()=>[s(n.$slots,`default`)]),_:3},8,[`as`,`as-child`,`aria-hidden`,`data-hidden`,`tabindex`]))}});export{p as n,f as r,m as t};

View File

@@ -1 +1 @@
import{A as e,I as t,J as n,R as r,_ as i,g as a,l as o,m as s,v as c,x as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as u}from"./VisuallyHidden-_sQ0xQ9O.js";import{s as d}from"./PopperContent-oFiuPLDs.js";var f=l({inheritAttrs:!1,__name:`VisuallyHiddenInputBubble`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(r){let i=r,{primitiveElement:o,currentElement:c}=d();return n(s(()=>i.checked??i.value),(e,t)=>{if(!c.value)return;let n=c.value,r=window.HTMLInputElement.prototype,i=Object.getOwnPropertyDescriptor(r,`value`).set;if(i&&e!==t){let t=new Event(`input`,{bubbles:!0}),r=new Event(`change`,{bubbles:!0});i.call(n,e),n.dispatchEvent(t),n.dispatchEvent(r)}}),(n,r)=>(t(),a(u,e({ref_key:`primitiveElement`,ref:o},{...i,...n.$attrs},{as:`input`}),null,16))}}),p=l({inheritAttrs:!1,__name:`VisuallyHiddenInput`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(n){let l=n,u=s(()=>typeof l.value==`object`&&Array.isArray(l.value)&&l.value.length===0&&l.required),d=s(()=>typeof l.value==`string`||typeof l.value==`number`||typeof l.value==`boolean`||l.value===null||l.value===void 0?[{name:l.name,value:l.value}]:typeof l.value==`object`&&Array.isArray(l.value)?l.value.flatMap((e,t)=>typeof e==`object`?Object.entries(e).map(([e,n])=>({name:`${l.name}[${t}][${e}]`,value:n})):{name:`${l.name}[${t}]`,value:e}):l.value!==null&&typeof l.value==`object`&&!Array.isArray(l.value)?Object.entries(l.value).map(([e,t])=>({name:`${l.name}[${e}]`,value:t})):[]);return(n,s)=>(t(),c(o,null,[i(` We render single input if it's required `),u.value?(t(),a(f,e({key:n.name},{...l,...n.$attrs},{name:n.name,value:n.value}),null,16,[`name`,`value`])):(t(!0),c(o,{key:1},r(d.value,r=>(t(),a(f,e({key:r.name},{ref_for:!0},{...l,...n.$attrs},{name:r.name,value:r.value}),null,16,[`name`,`value`]))),128))],2112))}});export{p as t};
import{A as e,I as t,J as n,R as r,_ as i,g as a,l as o,m as s,v as c,x as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as u}from"./VisuallyHidden-CunWEljx.js";import{s as d}from"./PopperContent-Wu1vPEc9.js";var f=l({inheritAttrs:!1,__name:`VisuallyHiddenInputBubble`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(r){let i=r,{primitiveElement:o,currentElement:c}=d();return n(s(()=>i.checked??i.value),(e,t)=>{if(!c.value)return;let n=c.value,r=window.HTMLInputElement.prototype,i=Object.getOwnPropertyDescriptor(r,`value`).set;if(i&&e!==t){let t=new Event(`input`,{bubbles:!0}),r=new Event(`change`,{bubbles:!0});i.call(n,e),n.dispatchEvent(t),n.dispatchEvent(r)}}),(n,r)=>(t(),a(u,e({ref_key:`primitiveElement`,ref:o},{...i,...n.$attrs},{as:`input`}),null,16))}}),p=l({inheritAttrs:!1,__name:`VisuallyHiddenInput`,props:{name:{type:String,required:!0},value:{type:null,required:!0},checked:{type:Boolean,required:!1,default:void 0},required:{type:Boolean,required:!1},disabled:{type:Boolean,required:!1},feature:{type:String,required:!1,default:`fully-hidden`}},setup(n){let l=n,u=s(()=>typeof l.value==`object`&&Array.isArray(l.value)&&l.value.length===0&&l.required),d=s(()=>typeof l.value==`string`||typeof l.value==`number`||typeof l.value==`boolean`||l.value===null||l.value===void 0?[{name:l.name,value:l.value}]:typeof l.value==`object`&&Array.isArray(l.value)?l.value.flatMap((e,t)=>typeof e==`object`?Object.entries(e).map(([e,n])=>({name:`${l.name}[${t}][${e}]`,value:n})):{name:`${l.name}[${t}]`,value:e}):l.value!==null&&typeof l.value==`object`&&!Array.isArray(l.value)?Object.entries(l.value).map(([e,t])=>({name:`${l.name}[${e}]`,value:t})):[]);return(n,s)=>(t(),c(o,null,[i(` We render single input if it's required `),u.value?(t(),a(f,e({key:n.name},{...l,...n.$attrs},{name:n.name,value:n.value}),null,16,[`name`,`value`])):(t(!0),c(o,{key:1},r(d.value,r=>(t(),a(f,e({key:r.name},{ref_for:!0},{...l,...n.$attrs},{name:r.name,value:r.value}),null,16,[`name`,`value`]))),128))],2112))}});export{p as t};

View File

@@ -1 +1 @@
import{I as e,Q as t,b as n,h as r,v as i,wt as a,x as o,y as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./button-BTKRNUhQ.js";import{t as u}from"./route-block-BCBU0UBp.js";var d={class:`max-w-2xl mx-auto text-center`},f={class:`font-bold text-8xl`},p={class:`mt-4 text-2xl font-bold`},m={class:`text-stone-400`},h={class:`mt-8`},g={class:`flex justify-center gap-2`},_=o({__name:`custom-error`,props:{code:{},subtitle:{},error:{}},setup(o){return(u,_)=>{let v=l;return e(),i(`div`,d,[r(`h1`,f,a(o.code),1),r(`h2`,p,a(o.subtitle),1),r(`p`,m,a(o.error),1),r(`footer`,h,[c(u.$slots,`default`,{},()=>[r(`div`,g,[n(v,{variant:`outline`,onClick:_[0]||=e=>u.$router.back()},{default:t(()=>[..._[2]||=[s(` Go Back `,-1)]]),_:1}),n(v,{onClick:_[1]||=e=>u.$router.push(`/`)},{default:t(()=>[..._[3]||=[s(` Back to Home `,-1)]]),_:1})])])])])}}}),v={class:`flex items-center justify-center h-screen`},y=o({__name:`[...path]`,setup(t){return(t,r)=>(e(),i(`div`,v,[n(_,{code:404,subtitle:`Page Not Found`,error:`The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.`})]))}});typeof u==`function`&&u(y);var b=y;export{b as default};
import{I as e,Q as t,b as n,h as r,v as i,wt as a,x as o,y as s,z as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./button-xrpYa8G4.js";import{t as u}from"./route-block-G560e8nk.js";var d={class:`max-w-2xl mx-auto text-center`},f={class:`font-bold text-8xl`},p={class:`mt-4 text-2xl font-bold`},m={class:`text-stone-400`},h={class:`mt-8`},g={class:`flex justify-center gap-2`},_=o({__name:`custom-error`,props:{code:{},subtitle:{},error:{}},setup(o){return(u,_)=>{let v=l;return e(),i(`div`,d,[r(`h1`,f,a(o.code),1),r(`h2`,p,a(o.subtitle),1),r(`p`,m,a(o.error),1),r(`footer`,h,[c(u.$slots,`default`,{},()=>[r(`div`,g,[n(v,{variant:`outline`,onClick:_[0]||=e=>u.$router.back()},{default:t(()=>[..._[2]||=[s(` Go Back `,-1)]]),_:1}),n(v,{onClick:_[1]||=e=>u.$router.push(`/`)},{default:t(()=>[..._[3]||=[s(` Back to Home `,-1)]]),_:1})])])])])}}}),v={class:`flex items-center justify-center h-screen`},y=o({__name:`[...path]`,setup(t){return(t,r)=>(e(),i(`div`,v,[n(_,{code:404,subtitle:`Page Not Found`,error:`The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.`})]))}});typeof u==`function`&&u(y);var b=y;export{b as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{K as r}from"./index-BpHHjIYv.js";import{t as i}from"./route-block-BCBU0UBp.js";var a={};function o(r,i){let a=e(`router-view`);return t(),n(a)}typeof i==`function`&&i(a);var s=r(a,[[`render`,o]]);export{s as default};
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{I as r}from"./index-axPHP3AB.js";import{t as i}from"./route-block-G560e8nk.js";var a={};function o(r,i){let a=e(`router-view`);return t(),n(a)}typeof i==`function`&&i(a);var s=r(a,[[`render`,o]]);export{s as default};

View File

@@ -1 +1 @@
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{K as r}from"./index-BpHHjIYv.js";var i={};function a(r,i){let a=e(`router-view`);return t(),n(a)}var o=r(i,[[`render`,a]]);export{o as default};
import{B as e,I as t,g as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{I as r}from"./index-axPHP3AB.js";var i={};function a(r,i){let a=e(`router-view`);return t(),n(a)}var o=r(i,[[`render`,a]]);export{o as default};

View File

@@ -1 +1 @@
import{A as e,I as t,Q as n,c as r,g as i,l as a,p as o,w as s,x as c,xt as l,yt as u,z as d}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{J as f,X as p}from"./index-BpHHjIYv.js";function m(e){return e?e.flatMap(e=>e.type===a?m(e.children):[e]):[]}var h=c({name:`PrimitiveSlot`,inheritAttrs:!1,setup(t,{attrs:n,slots:i}){return()=>{if(!i.default)return null;let t=m(i.default()),a=t.findIndex(e=>e.type!==r);if(a===-1)return t;let s=t[a];delete s.props?.ref;let c=s.props?e(n,s.props):n,l=o({...s,props:{}},c);return t.length===1?l:(t[a]=l,t)}}}),g=[`area`,`img`,`input`],_=c({name:`Primitive`,inheritAttrs:!1,props:{asChild:{type:Boolean,default:!1},as:{type:[String,Object],default:`div`}},setup(e,{attrs:t,slots:n}){let r=e.asChild?`template`:e.as;return typeof r==`string`&&g.includes(r)?()=>s(r,t):r===`template`?()=>s(h,t,{default:n.default}):()=>s(e.as,t,{default:n.default})}}),v=e=>typeof e==`boolean`?`${e}`:e===0?`0`:e,y=p,b=(e,t)=>n=>{if(t?.variants==null)return y(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=v(t)||v(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return y(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},x=c({__name:`Button`,props:{variant:{},size:{},class:{type:[Boolean,null,String,Object,Array]},asChild:{type:Boolean},as:{default:`button`}},setup(e){let r=e;return(a,o)=>(t(),i(u(_),{"data-slot":`button`,as:e.as,"as-child":e.asChild,class:l(u(f)(u(S)({variant:e.variant,size:e.size}),r.class))},{default:n(()=>[d(a.$slots,`default`)]),_:3},8,[`as`,`as-child`,`class`]))}}),S=b(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90`,destructive:`bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-9 px-4 py-2 has-[>svg]:px-3`,sm:`h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5`,lg:`h-10 rounded-md px-6 has-[>svg]:px-4`,icon:`size-9`,"icon-sm":`size-8`,"icon-lg":`size-10`}},defaultVariants:{variant:`default`,size:`default`}});export{h as a,_ as i,x as n,m as o,b as r,S as t};
import{A as e,I as t,Q as n,c as r,g as i,l as a,p as o,w as s,x as c,xt as l,yt as u,z as d}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{B as f,R as p}from"./index-axPHP3AB.js";function m(e){return e?e.flatMap(e=>e.type===a?m(e.children):[e]):[]}var h=c({name:`PrimitiveSlot`,inheritAttrs:!1,setup(t,{attrs:n,slots:i}){return()=>{if(!i.default)return null;let t=m(i.default()),a=t.findIndex(e=>e.type!==r);if(a===-1)return t;let s=t[a];delete s.props?.ref;let c=s.props?e(n,s.props):n,l=o({...s,props:{}},c);return t.length===1?l:(t[a]=l,t)}}}),g=[`area`,`img`,`input`],_=c({name:`Primitive`,inheritAttrs:!1,props:{asChild:{type:Boolean,default:!1},as:{type:[String,Object],default:`div`}},setup(e,{attrs:t,slots:n}){let r=e.asChild?`template`:e.as;return typeof r==`string`&&g.includes(r)?()=>s(r,t):r===`template`?()=>s(h,t,{default:n.default}):()=>s(e.as,t,{default:n.default})}}),v=e=>typeof e==`boolean`?`${e}`:e===0?`0`:e,y=f,b=(e,t)=>n=>{if(t?.variants==null)return y(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=v(t)||v(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return y(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},x=c({__name:`Button`,props:{variant:{},size:{},class:{type:[Boolean,null,String,Object,Array]},asChild:{type:Boolean},as:{default:`button`}},setup(e){let r=e;return(a,o)=>(t(),i(u(_),{"data-slot":`button`,as:e.as,"as-child":e.asChild,class:l(u(p)(u(S)({variant:e.variant,size:e.size}),r.class))},{default:n(()=>[d(a.$slots,`default`)]),_:3},8,[`as`,`as-child`,`class`]))}}),S=b(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90`,destructive:`bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-9 px-4 py-2 has-[>svg]:px-3`,sm:`h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5`,lg:`h-10 rounded-md px-6 has-[>svg]:px-4`,icon:`size-9`,"icon-sm":`size-8`,"icon-lg":`size-10`}},defaultVariants:{variant:`default`,size:`default`}});export{h as a,_ as i,x as n,m as o,b as r,S as t};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{B as e,I as t,Q as n,R as r,V as i,_ as a,b as o,g as s,h as c,l,m as u,v as d,wt as f,x as p,xt as m,y as h,yt as g,z as _}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as v}from"./chevrons-up-down-Bbw1im9J.js";import{J as y,N as b}from"./index-BpHHjIYv.js";import{n as x}from"./button-BTKRNUhQ.js";import{i as S,n as C,r as w,t as T}from"./DropdownMenuTrigger-Dmk4lbKz.js";var E={class:`text-2xl font-bold`},D={key:0,class:`text-muted-foreground`},O={class:`flex items-center gap-2 flex-wrap`},k=p({__name:`basic-header`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(n,r)=>(t(),d(`header`,{class:m(g(y)(`flex flex-col md:flex-row gap-2 justify-between py-2`,e.sticky?`sticky top-0 z-40 bg-background`:``))},[c(`main`,null,[c(`h1`,E,f(e.title),1),e.description?(t(),d(`p`,D,f(e.description),1)):a(``,!0)]),c(`aside`,O,[_(n.$slots,`actions`)])],2))}}),A={class:`py-4`},j=p({__name:`basic-page`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(r,i)=>(t(),d(`main`,null,[o(k,{title:e.title,description:e.description,sticky:e.sticky},{actions:n(()=>[_(r.$slots,`actions`)]),_:3},8,[`title`,`description`,`sticky`]),c(`main`,A,[_(r.$slots,`default`)])]))}}),M={class:`flex flex-col gap-2`},N=`text-primary font-semibold bg-primary/5`,P=p({__name:`two-col-aside`,props:{nav:{}},setup(a){let p=a,_=b(),y=u(()=>_.path),E=u(()=>p.nav.find(e=>e.url===y.value));return(a,u)=>{let _=e(`router-link`),b=x,D=T,O=C,k=w,A=S;return t(),d(`nav`,M,[(t(!0),d(l,null,r(p.nav,e=>(t(),s(_,{key:e.url,to:e.url,class:m([`items-center hidden px-2 py-1 rounded-md lg:flex hover:bg-primary/5`,e.url===g(y)?N:``])},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),c(`span`,null,f(e.title),1)]),_:2},1032,[`to`,`class`]))),128)),o(A,{class:`lg:hidden`},{default:n(()=>[o(D,{"as-child":``},{default:n(()=>[o(b,{variant:`outline`,class:`w-48 lg:hidden`},{default:n(()=>[(t(),s(i(g(E)?.icon),{class:`size-4 mr-1`})),c(`span`,null,f(g(E)?.title),1),o(g(v),{class:`size-4 ml-auto`})]),_:1})]),_:1}),o(k,{class:`w-48`,align:`start`},{default:n(()=>[(t(!0),d(l,null,r(p.nav,e=>(t(),s(O,{key:e.url,onClick:t=>a.$router.push(e.url)},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),h(` `+f(e.title),1)]),_:2},1032,[`onClick`]))),128))]),_:1})]),_:1})])}}}),F=p({__name:`two-col`,setup(e){return(e,n)=>(t(),d(`div`,{class:m(g(y)(`grid grid-cols-1 lg:grid-cols-[200px_1fr] gap-4 w-full`))},[c(`aside`,null,[_(e.$slots,`aside`)]),c(`section`,null,[_(e.$slots,`default`)])],2))}});export{P as n,j as r,F as t};
import{B as e,I as t,Q as n,R as r,V as i,_ as a,b as o,g as s,h as c,l,m as u,v as d,wt as f,x as p,xt as m,y as h,yt as g,z as _}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as v}from"./chevrons-up-down-Bbw1im9J.js";import{C as y,R as b}from"./index-axPHP3AB.js";import{n as x}from"./button-xrpYa8G4.js";import{i as S,n as C,r as w,t as T}from"./DropdownMenuTrigger-CaEGJhbh.js";var E={class:`text-2xl font-bold`},D={key:0,class:`text-muted-foreground`},O={class:`flex items-center gap-2 flex-wrap`},k=p({__name:`basic-header`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(n,r)=>(t(),d(`header`,{class:m(g(b)(`flex flex-col md:flex-row gap-2 justify-between py-2`,e.sticky?`sticky top-0 z-40 bg-background`:``))},[c(`main`,null,[c(`h1`,E,f(e.title),1),e.description?(t(),d(`p`,D,f(e.description),1)):a(``,!0)]),c(`aside`,O,[_(n.$slots,`actions`)])],2))}}),A={class:`py-4`},j=p({__name:`basic-page`,props:{title:{},description:{},sticky:{type:Boolean}},setup(e){return(r,i)=>(t(),d(`main`,null,[o(k,{title:e.title,description:e.description,sticky:e.sticky},{actions:n(()=>[_(r.$slots,`actions`)]),_:3},8,[`title`,`description`,`sticky`]),c(`main`,A,[_(r.$slots,`default`)])]))}}),M={class:`flex flex-col gap-2`},N=`text-primary font-semibold bg-primary/5`,P=p({__name:`two-col-aside`,props:{nav:{}},setup(a){let p=a,_=y(),b=u(()=>_.path),E=u(()=>p.nav.find(e=>e.url===b.value));return(a,u)=>{let _=e(`router-link`),y=x,D=T,O=C,k=w,A=S;return t(),d(`nav`,M,[(t(!0),d(l,null,r(p.nav,e=>(t(),s(_,{key:e.url,to:e.url,class:m([`items-center hidden px-2 py-1 rounded-md lg:flex hover:bg-primary/5`,e.url===g(b)?N:``])},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),c(`span`,null,f(e.title),1)]),_:2},1032,[`to`,`class`]))),128)),o(A,{class:`lg:hidden`},{default:n(()=>[o(D,{"as-child":``},{default:n(()=>[o(y,{variant:`outline`,class:`w-48 lg:hidden`},{default:n(()=>[(t(),s(i(g(E)?.icon),{class:`size-4 mr-1`})),c(`span`,null,f(g(E)?.title),1),o(g(v),{class:`size-4 ml-auto`})]),_:1})]),_:1}),o(k,{class:`w-48`,align:`start`},{default:n(()=>[(t(!0),d(l,null,r(p.nav,e=>(t(),s(O,{key:e.url,onClick:t=>a.$router.push(e.url)},{default:n(()=>[(t(),s(i(e.icon),{class:`size-4 mr-1`})),h(` `+f(e.title),1)]),_:2},1032,[`onClick`]))),128))]),_:1})]),_:1})])}}}),F=p({__name:`two-col`,setup(e){return(e,n)=>(t(),d(`div`,{class:m(g(b)(`grid grid-cols-1 lg:grid-cols-[200px_1fr] gap-4 w-full`))},[c(`aside`,null,[_(e.$slots,`aside`)]),c(`section`,null,[_(e.$slots,`default`)])],2))}});export{P as n,j as r,F as t};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
.marketing-header[data-v-8a713a75]{-webkit-backdrop-filter:saturate(50%)blur(4px);backdrop-filter:saturate(50%)blur(4px);background-size:4px 4px}
.marketing-header[data-v-bceee906]{-webkit-backdrop-filter:saturate(50%)blur(4px);backdrop-filter:saturate(50%)blur(4px);background-size:4px 4px}

View File

@@ -1 +1 @@
import{B as e,I as t,Q as n,R as r,b as i,g as a,h as o,l as s,v as c,wt as l,x as u,y as d,yt as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{o as p}from"./dist-3yfE1dPa.js";import{n as m,t as h}from"./toggle-theme-9ZMsSjs2.js";import{$ as g,K as _}from"./index-BpHHjIYv.js";import"./Teleport-qOjHMYM8.js";import{n as v}from"./button-BTKRNUhQ.js";import{n as y,t as b}from"./AvatarImage-Ct5I9mHM.js";var x={class:`min-h-18 flex items-center justify-between`},S={class:`flex items-center gap-2`},C=u({__name:`the-footer`,setup(e){let a=p(),l=[{name:`bluesky`,icon:`simple-icons:bluesky`,url:`https://bsky.app/profile/bitmc.bsky.social`},{name:`github`,icon:`simple-icons:github`,url:`https://www.github.com/whbbit1999/shadcn-vue-admin`},{name:`bilibili`,icon:`simple-icons:bilibili`,url:`https://space.bilibili.com/104376935`}];return(e,u)=>{let d=b,p=y,m=v;return t(),c(`footer`,x,[i(p,null,{default:n(()=>[i(d,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),u[0]||=o(`div`,null,`© 2025 Whbbit1999`,-1),o(`div`,S,[(t(),c(s,null,r(l,e=>i(m,{key:e.name,variant:`outline`,size:`icon`,as:`a`,href:e.url,target:`_blank`},{default:n(()=>[i(f(g),{icon:e.icon},null,8,[`icon`])]),_:2},1032,[`href`])),64))])])}}}),w={};function T(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-in`},{default:n(()=>[d(l(e.$t(`login`)),1)]),_:1})}var E=_(w,[[`render`,T]]),D={};function O(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-up`,variant:`outline`},{default:n(()=>[d(l(e.$t(`register`)),1)]),_:1})}var k=_(D,[[`render`,O]]),A={class:`h-14 flex items-center marketing-header sticky top-0 z-99`},j={class:`mr-2 hidden lg:flex lg:gap-2`},M={class:`flex gap-2`},N=_(u({__name:`the-header`,setup(r){let a=p();return(r,s)=>{let l=b,u=y,d=e(`router-link`);return t(),c(`header`,A,[i(d,{to:`/`,class:`flex items-center gap-2`},{default:n(()=>[i(u,null,{default:n(()=>[i(l,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),s[0]||=o(`span`,{class:`text-base font-bold`},`Shadcn Vue Admin`,-1)]),_:1}),s[1]||=o(`div`,{class:`flex-1`},null,-1),o(`div`,j,[i(E),i(k)]),o(`div`,M,[i(m),i(h)])])}}}),[[`__scopeId`,`data-v-8a713a75`]]),P={class:`container mx-auto`},F={class:`mx-2 lg:p-0`},I=u({__name:`marketing`,setup(n){return(n,r)=>{let a=e(`router-view`);return t(),c(`div`,P,[o(`div`,F,[i(N),o(`main`,null,[i(a)]),i(C)])])}}});export{I as default};
import{B as e,I as t,Q as n,R as r,b as i,g as a,h as o,l as s,v as c,wt as l,x as u,y as d,yt as f}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{o as p}from"./dist-3yfE1dPa.js";import{n as m,t as h}from"./toggle-theme-BwpYiWnH.js";import{I as g,U as _}from"./index-axPHP3AB.js";import"./Teleport-f0-_cFyq.js";import{n as v}from"./button-xrpYa8G4.js";import{n as y,t as b}from"./AvatarImage-Da9BQozn.js";var x={class:`min-h-18 flex items-center justify-between`},S={class:`flex items-center gap-2`},C=u({__name:`the-footer`,setup(e){let a=p(),l=[{name:`bluesky`,icon:`simple-icons:bluesky`,url:`https://bsky.app/profile/bitmc.bsky.social`},{name:`github`,icon:`simple-icons:github`,url:`https://www.github.com/whbbit1999/shadcn-vue-admin`},{name:`bilibili`,icon:`simple-icons:bilibili`,url:`https://space.bilibili.com/104376935`}];return(e,u)=>{let d=b,p=y,m=v;return t(),c(`footer`,x,[i(p,null,{default:n(()=>[i(d,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),u[0]||=o(`div`,null,`© 2025 Whbbit1999`,-1),o(`div`,S,[(t(),c(s,null,r(l,e=>i(m,{key:e.name,variant:`outline`,size:`icon`,as:`a`,href:e.url,target:`_blank`},{default:n(()=>[i(f(_),{icon:e.icon},null,8,[`icon`])]),_:2},1032,[`href`])),64))])])}}}),w={};function T(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-in`},{default:n(()=>[d(l(e.$t(`login`)),1)]),_:1})}var E=g(w,[[`render`,T]]),D={};function O(e,r){let i=v;return t(),a(i,{as:`a`,href:`/auth/sign-up`,variant:`outline`},{default:n(()=>[d(l(e.$t(`register`)),1)]),_:1})}var k=g(D,[[`render`,O]]),A={class:`h-14 flex items-center marketing-header sticky top-0 z-99`},j={class:`mr-2 hidden lg:flex lg:gap-2`},M={class:`flex gap-2`},N=g(u({__name:`the-header`,setup(r){let a=p();return(r,s)=>{let l=b,u=y,d=e(`router-link`);return t(),c(`header`,A,[i(d,{to:`/`,class:`flex items-center gap-2`},{default:n(()=>[i(u,null,{default:n(()=>[i(l,{src:`${f(a)===`dark`?`/logo.svg`:`/logo-black.svg`}`,alt:`Logo`},null,8,[`src`])]),_:1}),s[0]||=o(`span`,{class:`text-base font-bold`},`Shadcn Vue Admin`,-1)]),_:1}),s[1]||=o(`div`,{class:`flex-1`},null,-1),o(`div`,j,[i(E),i(k)]),o(`div`,M,[i(m),i(h)])])}}}),[[`__scopeId`,`data-v-bceee906`]]),P={class:`container mx-auto`},F={class:`mx-2 lg:p-0`},I=u({__name:`marketing`,setup(n){return(n,r)=>{let a=e(`router-view`);return t(),c(`div`,P,[o(`div`,F,[i(N),o(`main`,null,[i(a)]),i(C)])])}}});export{I as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{I as e,v as t,x as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as r}from"./route-block-BCBU0UBp.js";var i=n({__name:`index`,setup(n){return(n,r)=>(e(),t(`div`))}});typeof r==`function`&&r(i);var a=i;export{a as default};
import{I as e,v as t,x as n}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{t as r}from"./route-block-G560e8nk.js";var i=n({__name:`index`,setup(n){return(n,r)=>(e(),t(`div`))}});typeof r==`function`&&r(i);var a=i;export{a as default};

View File

@@ -1 +1 @@
import{I as e,Q as t,Y as n,_ as r,at as i,b as a,g as o,h as s,s as c,ut as l,v as u,wt as d,x as f,y as p,yt as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as h}from"./dist-3yfE1dPa.js";import{t as g}from"./eye-off-DDZmXXZv.js";import{P as _,q as v}from"./index-BpHHjIYv.js";import{n as y}from"./button-BTKRNUhQ.js";import{t as b}from"./Label-sjjJXKKd.js";import{t as x}from"./Input-DOTs5aTB.js";import"./monisuo-admin.api-DyXM8BcP.js";import{t as S}from"./use-auth-BEiiAXZl.js";import{t as C}from"./route-block-BCBU0UBp.js";import{t as w}from"./Card-o8MCRg3I.js";import{t as T}from"./CardContent-BXRdn2MY.js";import{r as E,t as D}from"./Alert-ChDGwKFB.js";import{n as O,r as k,t as A}from"./CardTitle-C-tfNzWl.js";var j=h(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),M=h(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),N=h(`user`,[[`path`,{d:`M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2`,key:`975kel`}],[`circle`,{cx:`12`,cy:`7`,r:`4`,key:`17ys0d`}]]),P={class:`min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-muted p-4`},F={class:`flex justify-center mb-4`},I={class:`size-12 rounded-xl bg-primary flex items-center justify-center`},L={class:`space-y-2`},R={class:`relative`},z={class:`space-y-2`},B={class:`relative`},V=f({__name:`sign-in`,setup(f){let h=l(``),C=l(``),V=l(!1),{login:H,loading:U,error:W,isLogin:G}=S(),K=_();n(()=>{m(G)&&K.push(`/monisuo/dashboard`)});async function q(){!h.value||!C.value||await H(h.value,C.value)}return(n,l)=>{let f=A,_=O,S=k,H=b,G=x,K=E,J=D,Y=v,X=y,Z=T,Q=w;return e(),u(`div`,P,[a(Q,{class:`w-full max-w-lg`},{default:t(()=>[a(S,{class:`space-y-1 text-center`},{default:t(()=>[s(`div`,F,[s(`div`,I,[a(m(M),{class:`size-6 text-primary-foreground`})])]),a(f,{class:`text-2xl font-bold`},{default:t(()=>[...l[3]||=[p(` Monisuo Admin `,-1)]]),_:1}),a(_,null,{default:t(()=>[...l[4]||=[p(` 管理员登录 `,-1)]]),_:1})]),_:1}),a(Z,null,{default:t(()=>[s(`form`,{onSubmit:c(q,[`prevent`]),class:`space-y-4`},[s(`div`,L,[a(H,{for:`username`},{default:t(()=>[...l[5]||=[p(`用户名`,-1)]]),_:1}),s(`div`,R,[a(m(N),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`username`,modelValue:m(h),"onUpdate:modelValue":l[0]||=e=>i(h)?h.value=e:null,type:`text`,placeholder:`请输入用户名`,class:`pl-9`,disabled:m(U)},null,8,[`modelValue`,`disabled`])])]),s(`div`,z,[a(H,{for:`password`},{default:t(()=>[...l[6]||=[p(`密码`,-1)]]),_:1}),s(`div`,B,[a(m(M),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`password`,modelValue:m(C),"onUpdate:modelValue":l[1]||=e=>i(C)?C.value=e:null,type:m(V)?`text`:`password`,placeholder:`请输入密码`,class:`pl-9 pr-9`,disabled:m(U)},null,8,[`modelValue`,`type`,`disabled`]),s(`button`,{type:`button`,class:`absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,onClick:l[2]||=e=>V.value=!m(V)},[m(V)?(e(),o(m(g),{key:1,class:`size-4`})):(e(),o(m(j),{key:0,class:`size-4`}))])])]),m(W)?(e(),o(J,{key:0,variant:`destructive`},{default:t(()=>[a(K,null,{default:t(()=>[p(d(m(W)),1)]),_:1})]),_:1})):r(``,!0),a(X,{type:`submit`,class:`w-full`,disabled:m(U)},{default:t(()=>[m(U)?(e(),o(Y,{key:0,class:`size-4 mr-2`})):r(``,!0),p(` `+d(m(U)?`登录中...`:`登录`),1)]),_:1},8,[`disabled`])],32)]),_:1})]),_:1})])}}});typeof C==`function`&&C(V);var H=V;export{H as default};
import{I as e,Q as t,Y as n,_ as r,at as i,b as a,g as o,h as s,s as c,ut as l,v as u,wt as d,x as f,y as p,yt as m}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as h}from"./dist-3yfE1dPa.js";import{t as g}from"./eye-off-DDZmXXZv.js";import{L as _,w as v}from"./index-axPHP3AB.js";import{n as y}from"./button-xrpYa8G4.js";import{t as b}from"./Label-BVKK717i.js";import{t as x}from"./Input-BTEnOeoJ.js";import"./monisuo-admin.api-D_Mn0eGz.js";import{t as S}from"./use-auth-DCvz6Dk0.js";import{t as C}from"./route-block-G560e8nk.js";import{t as w}from"./Card-C4ypPl9R.js";import{t as T}from"./CardContent-CjpRZuCW.js";import{r as E,t as D}from"./Alert-Djp0o4Fe.js";import{n as O,r as k,t as A}from"./CardTitle-CmtJJ__x.js";var j=h(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),M=h(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),N=h(`user`,[[`path`,{d:`M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2`,key:`975kel`}],[`circle`,{cx:`12`,cy:`7`,r:`4`,key:`17ys0d`}]]),P={class:`min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-muted p-4`},F={class:`flex justify-center mb-4`},I={class:`size-12 rounded-xl bg-primary flex items-center justify-center`},L={class:`space-y-2`},R={class:`relative`},z={class:`space-y-2`},B={class:`relative`},V=f({__name:`sign-in`,setup(f){let h=l(``),C=l(``),V=l(!1),{login:H,loading:U,error:W,isLogin:G}=S(),K=v();n(()=>{m(G)&&K.push(`/monisuo/dashboard`)});async function q(){!h.value||!C.value||await H(h.value,C.value)}return(n,l)=>{let f=A,v=O,S=k,H=b,G=x,K=E,J=D,Y=_,X=y,Z=T,Q=w;return e(),u(`div`,P,[a(Q,{class:`w-full max-w-lg`},{default:t(()=>[a(S,{class:`space-y-1 text-center`},{default:t(()=>[s(`div`,F,[s(`div`,I,[a(m(M),{class:`size-6 text-primary-foreground`})])]),a(f,{class:`text-2xl font-bold`},{default:t(()=>[...l[3]||=[p(` Monisuo Admin `,-1)]]),_:1}),a(v,null,{default:t(()=>[...l[4]||=[p(` 管理员登录 `,-1)]]),_:1})]),_:1}),a(Z,null,{default:t(()=>[s(`form`,{onSubmit:c(q,[`prevent`]),class:`space-y-4`},[s(`div`,L,[a(H,{for:`username`},{default:t(()=>[...l[5]||=[p(`用户名`,-1)]]),_:1}),s(`div`,R,[a(m(N),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`username`,modelValue:m(h),"onUpdate:modelValue":l[0]||=e=>i(h)?h.value=e:null,type:`text`,placeholder:`请输入用户名`,class:`pl-9`,disabled:m(U)},null,8,[`modelValue`,`disabled`])])]),s(`div`,z,[a(H,{for:`password`},{default:t(()=>[...l[6]||=[p(`密码`,-1)]]),_:1}),s(`div`,B,[a(m(M),{class:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),a(G,{id:`password`,modelValue:m(C),"onUpdate:modelValue":l[1]||=e=>i(C)?C.value=e:null,type:m(V)?`text`:`password`,placeholder:`请输入密码`,class:`pl-9 pr-9`,disabled:m(U)},null,8,[`modelValue`,`type`,`disabled`]),s(`button`,{type:`button`,class:`absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,onClick:l[2]||=e=>V.value=!m(V)},[m(V)?(e(),o(m(g),{key:1,class:`size-4`})):(e(),o(m(j),{key:0,class:`size-4`}))])])]),m(W)?(e(),o(J,{key:0,variant:`destructive`},{default:t(()=>[a(K,null,{default:t(()=>[p(d(m(W)),1)]),_:1})]),_:1})):r(``,!0),a(X,{type:`submit`,class:`w-full`,disabled:m(U)},{default:t(()=>[m(U)?(e(),o(Y,{key:0,class:`size-4 mr-2`})):r(``,!0),p(` `+d(m(U)?`登录中...`:`登录`),1)]),_:1},8,[`disabled`])],32)]),_:1})]),_:1})])}}});typeof C==`function`&&C(V);var H=V;export{H as default};

View File

@@ -1 +1 @@
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-qOjHMYM8.js";import{n as u}from"./button-BTKRNUhQ.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-DKtIxxgh.js";var g=o({__name:`task-delete`,props:{task:{}},setup(o){let g=o;function _(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(g.task,null,2)))})}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this task: `+a(o.task.id)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a task with the ID `+a(o.task.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:_},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-f0-_cFyq.js";import{n as u}from"./button-xrpYa8G4.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-7NZpSAOO.js";var g=o({__name:`task-delete`,props:{task:{}},setup(o){let g=o;function _(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(g.task,null,2)))})}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this task: `+a(o.task.id)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a task with the ID `+a(o.task.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:_},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{t as e}from"./task-resource-dialog-PGu3CACc.js";import"./Teleport-f0-_cFyq.js";import"./button-xrpYa8G4.js";import"./modal-7NZpSAOO.js";export{e as default};

View File

@@ -1 +0,0 @@
import{t as e}from"./task-resource-dialog-8MJRe8qY.js";import"./Teleport-qOjHMYM8.js";import"./button-BTKRNUhQ.js";import"./modal-DKtIxxgh.js";export{e as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{I as e,Q as t,at as n,b as r,g as i,h as a,wt as o,x as s,y as c,yt as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as u,o as d}from"./dist-3yfE1dPa.js";import{$ as f,I as p,L as m,R as h}from"./index-BpHHjIYv.js";import{n as g}from"./button-BTKRNUhQ.js";import{i as _,n as v,r as y,t as b}from"./DropdownMenuTrigger-Dmk4lbKz.js";import{n as x,t as S}from"./DropdownMenuLabel-Bls_J4kr.js";import{n as C,t as w}from"./DropdownMenuRadioItem-QlCzvFJ2.js";var T=u(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),E=u(`sun-moon`,[[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M14.837 16.385a6 6 0 1 1-7.223-7.222c.624-.147.97.66.715 1.248a4 4 0 0 0 5.26 5.259c.589-.255 1.396.09 1.248.715`,key:`xlf6rm`}],[`path`,{d:`M16 12a4 4 0 0 0-4-4`,key:`6vsxu`}],[`path`,{d:`m19 5-1.256 1.256`,key:`1yg6a6`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}]]),D=u(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),O=s({__name:`language-change`,setup(s){let{locale:u}=h();function d(){u.value=`en`,m.value=`en`}function v(e){if(typeof e!=`string`||!p.has(e)){d();return}u.value=e,m.value=e}return(s,d)=>{let p=g,m=b,h=S,T=x,E=w,D=C,O=y,k=_;return e(),i(k,null,{default:t(()=>[r(m,{"as-child":``},{default:t(()=>[r(p,{variant:`outline`},{default:t(()=>[r(l(f),{icon:`mdi:translate`,class:`mr-2`}),c(` `+o(s.$t(`language`)),1)]),_:1})]),_:1}),r(O,null,{default:t(()=>[r(h,null,{default:t(()=>[c(o(s.$t(`changeLanguage`)),1)]),_:1}),r(T),r(D,{modelValue:l(u),"onUpdate:modelValue":[d[0]||=e=>n(u)?u.value=e:null,v]},{default:t(()=>[r(E,{value:`en`},{default:t(()=>[r(l(f),{icon:`flag:us-4x3`}),d[1]||=a(`span`,{class:`ml-2`},`English`,-1)]),_:1}),r(E,{value:`zh`},{default:t(()=>[r(l(f),{icon:`flag:cn-4x3`}),d[2]||=a(`span`,{class:`ml-2`},`中文`,-1)]),_:1})]),_:1},8,[`modelValue`])]),_:1})]),_:1})}}}),k=s({__name:`toggle-theme`,setup(n){let o=d();return(n,s)=>{let u=g,d=b,f=v,p=y,m=_;return e(),i(m,null,{default:t(()=>[r(d,{"as-child":``},{default:t(()=>[r(u,{variant:`outline`,size:`icon`},{default:t(()=>[r(l(T),{class:`rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0`}),r(l(D),{class:`absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100`}),s[3]||=a(`span`,{class:`sr-only`},`Toggle theme`,-1)]),_:1})]),_:1}),r(p,{align:`end`},{default:t(()=>[r(f,{onClick:s[0]||=e=>o.value=`light`},{default:t(()=>[r(l(D)),s[4]||=c(` Light `,-1)]),_:1}),r(f,{onClick:s[1]||=e=>o.value=`dark`},{default:t(()=>[r(l(T)),s[5]||=c(` Dark `,-1)]),_:1}),r(f,{onClick:s[2]||=e=>o.value=`auto`},{default:t(()=>[r(l(E)),s[6]||=c(` System `,-1)]),_:1})]),_:1})]),_:1})}}});export{T as a,E as i,O as n,D as r,k as t};
import{I as e,Q as t,at as n,b as r,g as i,h as a,wt as o,x as s,y as c,yt as l}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as u,o as d}from"./dist-3yfE1dPa.js";import{D as f,E as p,O as m,U as h}from"./index-axPHP3AB.js";import{n as g}from"./button-xrpYa8G4.js";import{i as _,n as v,r as y,t as b}from"./DropdownMenuTrigger-CaEGJhbh.js";import{n as x,t as S}from"./DropdownMenuLabel-BxrcQY1z.js";import{n as C,t as w}from"./DropdownMenuRadioItem-UhUJ6fhi.js";var T=u(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),E=u(`sun-moon`,[[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M14.837 16.385a6 6 0 1 1-7.223-7.222c.624-.147.97.66.715 1.248a4 4 0 0 0 5.26 5.259c.589-.255 1.396.09 1.248.715`,key:`xlf6rm`}],[`path`,{d:`M16 12a4 4 0 0 0-4-4`,key:`6vsxu`}],[`path`,{d:`m19 5-1.256 1.256`,key:`1yg6a6`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}]]),D=u(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),O=s({__name:`language-change`,setup(s){let{locale:u}=m();function d(){u.value=`en`,f.value=`en`}function v(e){if(typeof e!=`string`||!p.has(e)){d();return}u.value=e,f.value=e}return(s,d)=>{let f=g,p=b,m=S,T=x,E=w,D=C,O=y,k=_;return e(),i(k,null,{default:t(()=>[r(p,{"as-child":``},{default:t(()=>[r(f,{variant:`outline`},{default:t(()=>[r(l(h),{icon:`mdi:translate`,class:`mr-2`}),c(` `+o(s.$t(`language`)),1)]),_:1})]),_:1}),r(O,null,{default:t(()=>[r(m,null,{default:t(()=>[c(o(s.$t(`changeLanguage`)),1)]),_:1}),r(T),r(D,{modelValue:l(u),"onUpdate:modelValue":[d[0]||=e=>n(u)?u.value=e:null,v]},{default:t(()=>[r(E,{value:`en`},{default:t(()=>[r(l(h),{icon:`flag:us-4x3`}),d[1]||=a(`span`,{class:`ml-2`},`English`,-1)]),_:1}),r(E,{value:`zh`},{default:t(()=>[r(l(h),{icon:`flag:cn-4x3`}),d[2]||=a(`span`,{class:`ml-2`},`中文`,-1)]),_:1})]),_:1},8,[`modelValue`])]),_:1})]),_:1})}}}),k=s({__name:`toggle-theme`,setup(n){let o=d();return(n,s)=>{let u=g,d=b,f=v,p=y,m=_;return e(),i(m,null,{default:t(()=>[r(d,{"as-child":``},{default:t(()=>[r(u,{variant:`outline`,size:`icon`},{default:t(()=>[r(l(T),{class:`rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0`}),r(l(D),{class:`absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100`}),s[3]||=a(`span`,{class:`sr-only`},`Toggle theme`,-1)]),_:1})]),_:1}),r(p,{align:`end`},{default:t(()=>[r(f,{onClick:s[0]||=e=>o.value=`light`},{default:t(()=>[r(l(D)),s[4]||=c(` Light `,-1)]),_:1}),r(f,{onClick:s[1]||=e=>o.value=`dark`},{default:t(()=>[r(l(T)),s[5]||=c(` Dark `,-1)]),_:1}),r(f,{onClick:s[2]||=e=>o.value=`auto`},{default:t(()=>[r(l(E)),s[6]||=c(` System `,-1)]),_:1})]),_:1})]),_:1})}}});export{T as a,E as i,O as n,D as r,k as t};

View File

@@ -1 +1 @@
import{ut as e}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{G as t,M as n,P as r}from"./index-BpHHjIYv.js";import{t as i}from"./monisuo-admin.api-DyXM8BcP.js";function a(){let a=r(),o=n(),{isLogin:s,adminInfo:c}=t(o),l=e(!1),u=e(null),d=i();function f(){o.logout(),a.push({path:`/auth/sign-in`})}function p(){a.push({path:`/monisuo/dashboard`})}async function m(e,t){l.value=!0,u.value=null;try{let n=await d.mutateAsync({username:e,password:t});if(console.log(`Login result:`,n),n.code===`0000`&&n.data){console.log(`Setting token and adminInfo...`),o.setToken(n.data.token),o.setAdminInfo(n.data.adminInfo),console.log(`isLogin after setToken:`,o.isLogin);let e=a.currentRoute.value.query.redirect;console.log(`Redirecting to:`,e||`/monisuo/dashboard`),!e||e.startsWith(`//`)?p():a.push(e)}else console.log(`Login failed:`,n.code,n.msg),u.value=n.msg||`登录失败`}catch(e){console.error(`Login error:`,e),u.value=e.response?.data?.msg||`网络错误,请稍后重试`}finally{l.value=!1}}return{loading:l,error:u,isLogin:s,adminInfo:c,logout:f,login:m}}export{a as t};
import{ut as e}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{F as t,S as n,w as r}from"./index-axPHP3AB.js";import{t as i}from"./monisuo-admin.api-D_Mn0eGz.js";function a(){let a=r(),o=n(),{isLogin:s,adminInfo:c}=t(o),l=e(!1),u=e(null),d=i();function f(){o.logout(),a.push({path:`/auth/sign-in`})}function p(){a.push({path:`/monisuo/dashboard`})}async function m(e,t){l.value=!0,u.value=null;try{let n=await d.mutateAsync({username:e,password:t});if(console.log(`Login result:`,n),n.code===`0000`&&n.data){console.log(`Setting token and adminInfo...`),o.setToken(n.data.token),o.setAdminInfo(n.data.adminInfo),console.log(`isLogin after setToken:`,o.isLogin);let e=a.currentRoute.value.query.redirect;console.log(`Redirecting to:`,e||`/monisuo/dashboard`),!e||e.startsWith(`//`)?p():a.push(e)}else console.log(`Login failed:`,n.code,n.msg),u.value=n.msg||`登录失败`}catch(e){console.error(`Login error:`,e),u.value=e.response?.data?.msg||`网络错误,请稍后重试`}finally{l.value=!1}}return{loading:l,error:u,isLogin:s,adminInfo:c,logout:f,login:m}}export{a as t};

View File

@@ -0,0 +1 @@
import{m as e,ut as t}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as n}from"./dist-3yfE1dPa.js";import{S as r}from"./index-axPHP3AB.js";var i=n(`coins`,[[`path`,{d:`M13.744 17.736a6 6 0 1 1-7.48-7.48`,key:`bq4yh3`}],[`path`,{d:`M15 6h1v4`,key:`11y1tn`}],[`path`,{d:`m6.134 14.768.866-.5 2 3.464`,key:`17snzx`}],[`circle`,{cx:`16`,cy:`8`,r:`6`,key:`14bfc9`}]]),a=n(`dollar-sign`,[[`line`,{x1:`12`,x2:`12`,y1:`2`,y2:`22`,key:`7eqyqh`}],[`path`,{d:`M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6`,key:`1b0p4s`}]]),o=n(`palette`,[[`path`,{d:`M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z`,key:`e79jfc`}],[`circle`,{cx:`13.5`,cy:`6.5`,r:`.5`,fill:`currentColor`,key:`1okk4w`}],[`circle`,{cx:`17.5`,cy:`10.5`,r:`.5`,fill:`currentColor`,key:`f64h9f`}],[`circle`,{cx:`6.5`,cy:`12.5`,r:`.5`,fill:`currentColor`,key:`qy21gx`}],[`circle`,{cx:`8.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`fotxhn`}]]),s=n(`receipt`,[[`path`,{d:`M12 17V7`,key:`pyj7ub`}],[`path`,{d:`M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8`,key:`1elt7d`}],[`path`,{d:`M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z`,key:`ycz6yz`}]]),c=n(`settings`,[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),l=n(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),u=n(`trending-up`,[[`path`,{d:`M16 7h6v6`,key:`box55l`}],[`path`,{d:`m22 7-8.5 8.5-5-5L2 17`,key:`1t1m79`}]]),d=n(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]);function f(){let n=r(),f=e(()=>n.adminInfo?.role??2),p=e(()=>f.value===1),m=[{title:`外观设置`,url:`/settings/appearance`,icon:o}],h=[{title:`Monisuo 管理`,items:[{title:`数据看板`,url:`/monisuo/dashboard`,icon:a,roles:[1]},{title:`用户管理`,url:`/monisuo/users`,icon:d,roles:[1]},{title:`币种管理`,url:`/monisuo/coins`,icon:i,roles:[1]},{title:`订单审批`,url:`/monisuo/orders`,icon:s},{title:`业务分析`,url:`/monisuo/analytics`,icon:u,roles:[1]},{title:`管理员管理`,url:`/monisuo/admins`,icon:l,roles:[1]}]},{title:`Other`,items:[{title:`Settings`,icon:c,items:m}]}];return{navData:e(()=>h.map(e=>({title:e.title,items:e.items.filter(e=>{let t=e.roles;return t?t.includes(f.value):!0})})).filter(e=>e.items.length>0)),otherPages:t([]),settingsNavItems:m,isSuperAdmin:p}}export{f as t};

View File

@@ -1 +0,0 @@
import{ut as e}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{T as t}from"./dist-3yfE1dPa.js";var n=t(`coins`,[[`path`,{d:`M13.744 17.736a6 6 0 1 1-7.48-7.48`,key:`bq4yh3`}],[`path`,{d:`M15 6h1v4`,key:`11y1tn`}],[`path`,{d:`m6.134 14.768.866-.5 2 3.464`,key:`17snzx`}],[`circle`,{cx:`16`,cy:`8`,r:`6`,key:`14bfc9`}]]),r=t(`dollar-sign`,[[`line`,{x1:`12`,x2:`12`,y1:`2`,y2:`22`,key:`7eqyqh`}],[`path`,{d:`M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6`,key:`1b0p4s`}]]),i=t(`palette`,[[`path`,{d:`M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z`,key:`e79jfc`}],[`circle`,{cx:`13.5`,cy:`6.5`,r:`.5`,fill:`currentColor`,key:`1okk4w`}],[`circle`,{cx:`17.5`,cy:`10.5`,r:`.5`,fill:`currentColor`,key:`f64h9f`}],[`circle`,{cx:`6.5`,cy:`12.5`,r:`.5`,fill:`currentColor`,key:`qy21gx`}],[`circle`,{cx:`8.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`fotxhn`}]]),a=t(`receipt`,[[`path`,{d:`M12 17V7`,key:`pyj7ub`}],[`path`,{d:`M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8`,key:`1elt7d`}],[`path`,{d:`M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z`,key:`ycz6yz`}]]),o=t(`settings`,[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),s=t(`trending-up`,[[`path`,{d:`M16 7h6v6`,key:`box55l`}],[`path`,{d:`m22 7-8.5 8.5-5-5L2 17`,key:`1t1m79`}]]),c=t(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]);function l(){let t=[{title:`外观设置`,url:`/settings/appearance`,icon:i}];return{navData:e([{title:`Monisuo 管理`,items:[{title:`数据看板`,url:`/monisuo/dashboard`,icon:r},{title:`用户管理`,url:`/monisuo/users`,icon:c},{title:`币种管理`,url:`/monisuo/coins`,icon:n},{title:`订单审批`,url:`/monisuo/orders`,icon:a},{title:`业务分析`,url:`/monisuo/analytics`,icon:s}]},{title:`Other`,items:[{title:`Settings`,icon:o,items:t}]}]),otherPages:e([]),settingsNavItems:t}}export{l as t};

View File

@@ -1 +1 @@
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-qOjHMYM8.js";import{n as u}from"./button-BTKRNUhQ.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-DKtIxxgh.js";var g=o({__name:`user-delete`,props:{user:{}},emits:[`remove`],setup(o,{emit:g}){let _=g;function v(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(o.user,null,2)))}),_(`remove`)}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this user: `+a(o.user.username)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a user with the ID `+a(o.user.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:v},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};
import{I as e,Q as t,b as n,v as r,w as i,wt as a,x as o,y as s,yt as c}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{n as l}from"./lib-CC9cpJ8Y.js";import"./Teleport-f0-_cFyq.js";import{n as u}from"./button-xrpYa8G4.js";import{a as d,i as f,n as p,r as m,s as h}from"./modal-7NZpSAOO.js";var g=o({__name:`user-delete`,props:{user:{}},emits:[`remove`],setup(o,{emit:g}){let _=g;function v(){l(`The following task has been deleted:`,{description:i(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},i(`code`,{class:`text-white`},JSON.stringify(o.user,null,2)))}),_(`remove`)}return(i,l)=>{let g=u;return e(),r(`div`,null,[n(c(m),null,{default:t(()=>[n(c(p),null,{default:t(()=>[s(` Delete this user: `+a(o.user.username)+` ? `,1)]),_:1}),n(c(d),null,{default:t(()=>[s(` You are about to delete a user with the ID `+a(o.user.id)+`. This action cannot be undone. `,1)]),_:1})]),_:1}),n(c(f),null,{default:t(()=>[n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`outline`},{default:t(()=>[...l[0]||=[s(` Cancel `,-1)]]),_:1})]),_:1}),n(c(h),{"as-child":``},{default:t(()=>[n(g,{variant:`destructive`,onClick:v},{default:t(()=>[...l[1]||=[s(` Delete `,-1)]]),_:1})]),_:1})]),_:1})])}}});export{g as default};

View File

@@ -1 +0,0 @@
import"./Teleport-qOjHMYM8.js";import"./button-BTKRNUhQ.js";import"./modal-DKtIxxgh.js";import{t as e}from"./user-resource-p1iwSw42.js";export{e as default};

View File

@@ -0,0 +1 @@
import{A as e,C as t,I as n,Q as r,R as i,St as a,b as o,ct as s,h as c,l,m as u,v as d,w as f,wt as p,x as m,y as h,yt as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{a as _,i as v,n as y,r as b,t as x}from"./SelectValue-BbKWf16W.js";import{n as S}from"./lib-CC9cpJ8Y.js";import{c as C,d as w,l as T,n as E,s as D,u as O}from"./zod-B9xT8GrA.js";import{n as k}from"./button-xrpYa8G4.js";import{a as A,n as j,r as M}from"./modal-7NZpSAOO.js";import{a as N,c as P,i as F,l as I,n as L,r as R,s as z,t as B}from"./vee-validate-zod-vHiEg4Rp.js";import{t as V}from"./Input-BTEnOeoJ.js";var H=D([`active`,`inactive`,`invited`,`suspended`]),U=D([`superadmin`,`admin`,`cashier`,`manager`]);C(O({id:w(),firstName:w(),lastName:w(),username:w(),email:w(),phoneNumber:w(),status:H,role:U,createdAt:E(),updatedAt:E()}));var W=O({id:w().optional(),firstName:w().min(1),lastName:w().min(1),username:w().min(1),email:T().min(1),phoneNumber:w().min(1),status:H,role:U}),G={class:`max-h-[500px] overflow-y-auto`},K=m({__name:`user-form`,props:{user:{}},emits:[`close`],setup(u,{emit:m}){let C=m,w=[`superadmin`,`admin`,`cashier`,`manager`],T=[`active`,`inactive`,`invited`,`suspended`],E=s({firstName:u.user?.firstName||``,lastName:u.user?.lastName||``,username:u.user?.username||``,email:u.user?.email||``,phoneNumber:u.user?.phoneNumber||``,status:u.user?.status||`active`,role:u.user?.role||`cashier`}),{handleSubmit:D}=P({validationSchema:B(W),initialValues:E}),O=D(e=>{let t={...e};u.user&&(t.id=u.user.id),S(`You submitted the following values:`,{description:f(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},f(`code`,{class:`text-white`},JSON.stringify(t,null,2)))}),C(`close`)});return(s,u)=>(n(),d(`div`,G,[c(`form`,{class:`space-y-8`,onSubmit:u[0]||=(...e)=>g(O)&&g(O)(...e)},[o(g(z),{name:`firstName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[1]||=[h(`First Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`lastName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[2]||=[h(`Last Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`username`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[3]||=[h(`User Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`email`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[4]||=[h(`Email address`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`phoneNumber`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[5]||=[h(`Phone Number`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`status`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[6]||=[h(`Status`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a status`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(T,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`role`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[7]||=[h(`Role`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a role`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(w,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(k),{type:`submit`,class:`w-full`},{default:r(()=>[...u[8]||=[h(` SaveChanges `,-1)]]),_:1})],32)]))}}),q=m({__name:`user-resource`,props:{user:{}},emits:[`close`],setup(e){let t=e,i=u(()=>t.user),a=u(()=>i.value?.id?`Edit User`:`New User`),s=u(()=>i.value?.id?`Edit user ${i.value.username}`:`Create new user`);return(e,t)=>(n(),d(`div`,null,[o(g(M),null,{default:r(()=>[o(g(j),null,{default:r(()=>[h(p(g(a)),1)]),_:1}),o(g(A),null,{default:r(()=>[h(p(g(s)),1)]),_:1})]),_:1}),o(K,{user:g(i),onClose:t[0]||=t=>e.$emit(`close`)},null,8,[`user`])]))}});export{q as t};

View File

@@ -0,0 +1 @@
import"./Teleport-f0-_cFyq.js";import"./button-xrpYa8G4.js";import"./modal-7NZpSAOO.js";import{t as e}from"./user-resource-DOlPL2P8.js";export{e as default};

View File

@@ -1 +0,0 @@
import{A as e,C as t,I as n,Q as r,R as i,St as a,b as o,ct as s,h as c,l,m as u,v as d,w as f,wt as p,x as m,y as h,yt as g}from"./vue.runtime.esm-bundler-DS0mm12S.js";import{a as _,i as v,n as y,r as b,t as x}from"./SelectValue-By3tfEiu.js";import{n as S}from"./lib-CC9cpJ8Y.js";import{c as C,d as w,l as T,r as E,s as D,u as O}from"./index-BpHHjIYv.js";import{n as k}from"./button-BTKRNUhQ.js";import{a as A,n as j,r as M}from"./modal-DKtIxxgh.js";import{a as N,c as P,i as F,l as I,n as L,r as R,s as z,t as B}from"./vee-validate-zod-DAPvk_fs.js";import{t as V}from"./Input-DOTs5aTB.js";var H=D([`active`,`inactive`,`invited`,`suspended`]),U=D([`superadmin`,`admin`,`cashier`,`manager`]);C(O({id:w(),firstName:w(),lastName:w(),username:w(),email:w(),phoneNumber:w(),status:H,role:U,createdAt:E(),updatedAt:E()}));var W=O({id:w().optional(),firstName:w().min(1),lastName:w().min(1),username:w().min(1),email:T().min(1),phoneNumber:w().min(1),status:H,role:U}),G={class:`max-h-[500px] overflow-y-auto`},K=m({__name:`user-form`,props:{user:{}},emits:[`close`],setup(u,{emit:m}){let C=m,w=[`superadmin`,`admin`,`cashier`,`manager`],T=[`active`,`inactive`,`invited`,`suspended`],E=s({firstName:u.user?.firstName||``,lastName:u.user?.lastName||``,username:u.user?.username||``,email:u.user?.email||``,phoneNumber:u.user?.phoneNumber||``,status:u.user?.status||`active`,role:u.user?.role||`cashier`}),{handleSubmit:D}=P({validationSchema:B(W),initialValues:E}),O=D(e=>{let t={...e};u.user&&(t.id=u.user.id),S(`You submitted the following values:`,{description:f(`pre`,{class:`mt-2 w-[340px] rounded-md bg-slate-950 p-4`},f(`code`,{class:`text-white`},JSON.stringify(t,null,2)))}),C(`close`)});return(s,u)=>(n(),d(`div`,G,[c(`form`,{class:`space-y-8`,onSubmit:u[0]||=(...e)=>g(O)&&g(O)(...e)},[o(g(z),{name:`firstName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[1]||=[h(`First Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`lastName`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[2]||=[h(`Last Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`username`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[3]||=[h(`User Name`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`email`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[4]||=[h(`Email address`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`phoneNumber`},{default:r(({componentField:t})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[5]||=[h(`Phone Number`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(V),e({type:`text`},t),null,16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`status`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[6]||=[h(`Status`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a status`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(T,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(z),{name:`role`},{default:r(({componentField:e})=>[o(g(F),null,{default:r(()=>[o(g(R),null,{default:r(()=>[...u[7]||=[h(`Role`,-1)]]),_:1}),o(g(N),null,{default:r(()=>[o(g(_),a(t(e)),{default:r(()=>[o(g(N),null,{default:r(()=>[o(g(y),{class:`w-full`},{default:r(()=>[o(g(x),{placeholder:`Select a role`})]),_:1})]),_:1}),o(g(v),null,{default:r(()=>[o(g(I),null,{default:r(()=>[(n(),d(l,null,i(w,e=>o(g(b),{key:e,value:e},{default:r(()=>[h(p(e),1)]),_:2},1032,[`value`])),64))]),_:1})]),_:1})]),_:1},16)]),_:2},1024),o(g(L))]),_:2},1024)]),_:1}),o(g(k),{type:`submit`,class:`w-full`},{default:r(()=>[...u[8]||=[h(` SaveChanges `,-1)]]),_:1})],32)]))}}),q=m({__name:`user-resource`,props:{user:{}},emits:[`close`],setup(e){let t=e,i=u(()=>t.user),a=u(()=>i.value?.id?`Edit User`:`New User`),s=u(()=>i.value?.id?`Edit user ${i.value.username}`:`Create new user`);return(e,t)=>(n(),d(`div`,null,[o(g(M),null,{default:r(()=>[o(g(j),null,{default:r(()=>[h(p(g(a)),1)]),_:1}),o(g(A),null,{default:r(()=>[h(p(g(s)),1)]),_:1})]),_:1}),o(K,{user:g(i),onClose:t[0]||=t=>e.$emit(`close`)},null,8,[`user`])]))}});export{q as t};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,26 +1,27 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" media="(prefers-color-scheme: dark)" href="/logo.svg" />
<link rel="icon" type="image/svg+xml" media="(prefers-color-scheme: light)" href="/logo-black.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>shadcn-vue-admin</title>
<meta
name="description"
content="Admin Dashboard UI crafted with Shadcn-vue, Vue3 and Vite. Built with responsiveness and accessibility in mind."
/>
<meta
name="keywords"
content="vue,vue-router,vite,typescript,tailwindcss,shadcn-vue,tanstack-vue-query,tanstack-table,eslint,pinia,pnpm"
/>
<script type="module" crossorigin src="/assets/index-BpHHjIYv.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" media="(prefers-color-scheme: dark)" href="/logo.svg" />
<link rel="icon" type="image/svg+xml" media="(prefers-color-scheme: light)" href="/logo-black.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>shadcn-vue-admin</title>
<meta
name="description"
content="Admin Dashboard UI crafted with Shadcn-vue, Vue3 and Vite. Built with responsiveness and accessibility in mind."
/>
<meta
name="keywords"
content="vue,vue-router,vite,typescript,tailwindcss,shadcn-vue,tanstack-vue-query,tanstack-table,eslint,pinia,pnpm"
/>
<script type="module" crossorigin src="/assets/index-axPHP3AB.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vue.runtime.esm-bundler-DS0mm12S.js">
<link rel="modulepreload" crossorigin href="/assets/dist-3yfE1dPa.js">
<link rel="modulepreload" crossorigin href="/assets/lib-CC9cpJ8Y.js">
<link rel="modulepreload" crossorigin href="/assets/zod-B9xT8GrA.js">
<link rel="stylesheet" crossorigin href="/assets/index-DzGkD_L8.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
</head>
<body>
<div id="app"></div>
</body>

View File

@@ -1,10 +1,14 @@
<script setup lang="ts">
import {
ChevronsUpDown,
KeyRound,
LogOut,
UserRoundCog,
} from 'lucide-vue-next'
import { toast } from 'vue-sonner'
import { useChangePasswordMutation } from '@/services/api/monisuo-admin.api'
import { useSidebar } from '@/components/ui/sidebar'
import type { User } from './types'
@@ -15,6 +19,40 @@ const { user } = defineProps<
const { logout } = useAuth()
const { isMobile, open } = useSidebar()
const changePasswordMutation = useChangePasswordMutation()
const showPasswordDialog = ref(false)
const passwordForm = ref({ oldPassword: '', newPassword: '', confirmPassword: '' })
function openPasswordDialog() {
passwordForm.value = { oldPassword: '', newPassword: '', confirmPassword: '' }
showPasswordDialog.value = true
}
async function handleChangePassword() {
const { oldPassword, newPassword, confirmPassword } = passwordForm.value
if (!oldPassword || !newPassword) {
toast.error('请填写完整')
return
}
if (newPassword.length < 4) {
toast.error('新密码至少4位')
return
}
if (newPassword !== confirmPassword) {
toast.error('两次密码不一致')
return
}
try {
await changePasswordMutation.mutateAsync({ oldPassword, newPassword })
toast.success('密码修改成功,请重新登录')
showPasswordDialog.value = false
logout()
}
catch (e: any) {
toast.error(e.message || e.response?.data?.msg || '修改失败')
}
}
</script>
<template>
@@ -66,6 +104,10 @@ const { isMobile, open } = useSidebar()
<UserRoundCog />
设置
</UiDropdownMenuItem>
<UiDropdownMenuItem @click="openPasswordDialog">
<KeyRound />
修改密码
</UiDropdownMenuItem>
</UiDropdownMenuGroup>
<UiDropdownMenuSeparator />
@@ -77,4 +119,36 @@ const { isMobile, open } = useSidebar()
</UiDropdownMenu>
</UiSidebarMenuItem>
</UiSidebarMenu>
<!-- 修改密码弹窗 -->
<UiDialog v-model:open="showPasswordDialog">
<UiDialogContent class="max-w-md">
<UiDialogHeader>
<UiDialogTitle>修改密码</UiDialogTitle>
</UiDialogHeader>
<div class="grid gap-4 py-4">
<div class="grid gap-2">
<UiLabel>旧密码</UiLabel>
<UiInput v-model="passwordForm.oldPassword" type="password" placeholder="请输入旧密码" />
</div>
<div class="grid gap-2">
<UiLabel>新密码</UiLabel>
<UiInput v-model="passwordForm.newPassword" type="password" placeholder="至少4位" />
</div>
<div class="grid gap-2">
<UiLabel>确认新密码</UiLabel>
<UiInput v-model="passwordForm.confirmPassword" type="password" placeholder="再次输入新密码" @keyup.enter="handleChangePassword" />
</div>
</div>
<UiDialogFooter>
<UiButton variant="outline" @click="showPasswordDialog = false">
取消
</UiButton>
<UiButton :disabled="changePasswordMutation.isPending.value" @click="handleChangePassword">
<UiSpinner v-if="changePasswordMutation.isPending.value" class="mr-2" />
确认修改
</UiButton>
</UiDialogFooter>
</UiDialogContent>
</UiDialog>
</template>

View File

@@ -1,10 +1,13 @@
import { storeToRefs } from 'pinia'
import { useQueryClient } from '@tanstack/vue-query'
import { useAdminLoginMutation } from '@/services/api/monisuo-admin.api'
import { useAuthStore } from '@/stores/auth'
export function useAuth() {
const router = useRouter()
const queryClient = useQueryClient()
const authStore = useAuthStore()
const { isLogin, adminInfo } = storeToRefs(authStore)
@@ -15,6 +18,7 @@ export function useAuth() {
function logout() {
authStore.logout()
queryClient.clear()
router.push({ path: '/auth/sign-in' })
}
@@ -52,7 +56,7 @@ export function useAuth() {
}
catch (e: any) {
console.error('Login error:', e)
error.value = e.response?.data?.msg || '网络错误,请稍后重试'
error.value = e.message || e.response?.data?.msg || '网络错误,请稍后重试'
}
finally {
loading.value = false

View File

@@ -22,6 +22,10 @@ export function useAxios() {
})
axiosInstance.interceptors.response.use((response) => {
const data = response.data as any
if (data && data.code && data.code !== '0000') {
return Promise.reject(new Error(data.msg || '请求失败'))
}
return response
}, (error: AxiosError) => {
if (error.response?.status === 401) {

View File

@@ -1,21 +1,28 @@
import { Coins, DollarSign, Palette, Receipt, Settings, TrendingUp, Users } from 'lucide-vue-next'
import { CircleDollarSign, Coins, DollarSign, Palette, Receipt, Settings, ShieldCheck, TrendingUp, Users } from 'lucide-vue-next'
import type { NavGroup } from '@/components/app-sidebar/types'
import { useAuthStore } from '@/stores/auth'
export function useSidebar() {
const authStore = useAuthStore()
const role = computed(() => authStore.adminInfo?.role ?? 2)
const isSuperAdmin = computed(() => role.value === 1)
const settingsNavItems = [
{ title: '外观设置', url: '/settings/appearance', icon: Palette },
]
const navData = ref<NavGroup[]>([
const allNavItems: NavGroup[] = [
{
title: 'Monisuo 管理',
items: [
{ title: '数据看板', url: '/monisuo/dashboard', icon: DollarSign },
{ title: '用户管理', url: '/monisuo/users', icon: Users },
{ title: '币种管理', url: '/monisuo/coins', icon: Coins },
{ title: '订单审批', url: '/monisuo/orders', icon: Receipt },
{ title: '业务分析', url: '/monisuo/analytics', icon: TrendingUp },
{ title: '数据看板', url: '/monisuo/dashboard', icon: DollarSign, roles: [1] },
{ title: '用户管理', url: '/monisuo/users', icon: Users, roles: [1] },
{ title: '币种管理', url: '/monisuo/coins', icon: Coins, roles: [1] },
{ title: '订单审批', url: '/monisuo/orders', icon: Receipt, roles: [1, 2] },
{ title: '财务审批', url: '/monisuo/finance-orders', icon: CircleDollarSign, roles: [1, 3] },
{ title: '业务分析', url: '/monisuo/analytics', icon: TrendingUp, roles: [1] },
{ title: '管理员管理', url: '/monisuo/admins', icon: ShieldCheck, roles: [1] },
],
},
{
@@ -24,7 +31,19 @@ export function useSidebar() {
{ title: 'Settings', icon: Settings, items: settingsNavItems },
],
},
])
]
const navData = computed<NavGroup[]>(() => {
return allNavItems.map(group => ({
title: group.title,
items: group.items.filter((item) => {
const roles = (item as any).roles as number[] | undefined
if (!roles)
return true
return roles.includes(role.value)
}),
})).filter(group => group.items.length > 0)
})
const otherPages = ref<NavGroup[]>([])
@@ -32,5 +51,6 @@ export function useSidebar() {
navData,
otherPages,
settingsNavItems,
isSuperAdmin,
}
}

View File

@@ -0,0 +1,241 @@
<script lang="ts" setup>
import { Icon } from '@iconify/vue'
import { toast } from 'vue-sonner'
import type { AdminRecord } from '@/services/api/monisuo-admin.api'
import { BasicPage } from '@/components/global-layout'
import { useCreateAdminMutation, useGetAdminListQuery, useToggleAdminStatusMutation } from '@/services/api/monisuo-admin.api'
const { data, isLoading, refetch } = useGetAdminListQuery()
const createMutation = useCreateAdminMutation()
const toggleStatusMutation = useToggleAdminStatusMutation()
const admins = computed(() => data.value?.data || [])
const showCreateDialog = ref(false)
const newAdmin = ref({ username: '', password: '', nickname: '', role: 2 as number })
function openCreateDialog() {
newAdmin.value = { username: '', password: '', nickname: '', role: 2 }
showCreateDialog.value = true
}
async function createAdmin() {
if (!newAdmin.value.username || !newAdmin.value.password) {
toast.error('请输入用户名和密码')
return
}
if (newAdmin.value.password.length < 4) {
toast.error('密码至少4位')
return
}
try {
await createMutation.mutateAsync(newAdmin.value)
toast.success('创建成功')
showCreateDialog.value = false
refetch()
}
catch (e: any) {
toast.error(e.message || e.response?.data?.msg || '创建失败')
}
}
async function toggleStatus(admin: AdminRecord) {
if (admin.isSystem === 1) {
toast.error('系统预置管理员不可操作')
return
}
const newStatus = admin.status === 1 ? 0 : 1
try {
await toggleStatusMutation.mutateAsync({ id: admin.id, status: newStatus })
toast.success(newStatus === 1 ? '已启用' : '已禁用')
refetch()
}
catch (e: any) {
toast.error(e.message || e.response?.data?.msg || '操作失败')
}
}
function roleText(role: number) {
if (role === 1) return '超级管理员'
if (role === 2) return '管理员'
if (role === 3) return '财务'
return '未知'
}
function roleBadge(role: number) {
if (role === 1) return 'default'
if (role === 3) return 'outline'
return 'secondary'
}
</script>
<template>
<BasicPage title="管理员管理" description="管理系统管理员和财务账号">
<div class="space-y-4">
<div class="flex justify-end">
<UiButton @click="openCreateDialog">
<Icon icon="lucide:plus" class="size-4 mr-2" />
新增账号
</UiButton>
</div>
<!-- PC端表格 -->
<UiCard class="hidden md:block overflow-x-auto p-4">
<UiTable>
<UiTableHeader>
<UiTableRow>
<UiTableHead class="w-[80px]">
ID
</UiTableHead>
<UiTableHead>用户名</UiTableHead>
<UiTableHead>昵称</UiTableHead>
<UiTableHead>角色</UiTableHead>
<UiTableHead>状态</UiTableHead>
<UiTableHead>创建时间</UiTableHead>
<UiTableHead class="text-right">
操作
</UiTableHead>
</UiTableRow>
</UiTableHeader>
<UiTableBody>
<UiTableRow v-if="isLoading">
<UiTableCell :col-span="7" class="text-center py-8">
<UiSpinner class="mx-auto" />
</UiTableCell>
</UiTableRow>
<UiTableRow v-else-if="admins.length === 0">
<UiTableCell :col-span="7" class="text-center py-8 text-muted-foreground">
暂无数据
</UiTableCell>
</UiTableRow>
<UiTableRow v-for="admin in admins" :key="admin.id">
<UiTableCell>{{ admin.id }}</UiTableCell>
<UiTableCell class="font-mono font-medium">
{{ admin.username }}
</UiTableCell>
<UiTableCell>{{ admin.nickname }}</UiTableCell>
<UiTableCell>
<UiBadge :variant="roleBadge(admin.role)">
{{ roleText(admin.role) }}
</UiBadge>
</UiTableCell>
<UiTableCell>
<UiBadge :variant="admin.status === 1 ? 'default' : 'destructive'">
{{ admin.status === 1 ? '正常' : '禁用' }}
</UiBadge>
</UiTableCell>
<UiTableCell>{{ admin.createTime }}</UiTableCell>
<UiTableCell class="text-right">
<UiButton
v-if="admin.isSystem !== 1"
size="sm"
variant="ghost"
:disabled="toggleStatusMutation.isPending.value"
@click="toggleStatus(admin)"
>
<Icon
:icon="admin.status === 1 ? 'lucide:ban' : 'lucide:check-circle'"
class="size-4"
:class="admin.status === 1 ? 'text-destructive' : 'text-green-500'"
/>
</UiButton>
</UiTableCell>
</UiTableRow>
</UiTableBody>
</UiTable>
</UiCard>
<!-- 移动端卡片 -->
<div class="md:hidden space-y-3">
<div v-if="isLoading" class="text-center py-8">
<UiSpinner class="mx-auto" />
</div>
<template v-else-if="admins.length > 0">
<UiCard v-for="admin in admins" :key="admin.id" class="p-4">
<div class="flex items-start justify-between">
<div>
<div class="font-mono font-bold">
{{ admin.username }}
</div>
<div class="text-sm text-muted-foreground">
{{ admin.nickname }}
</div>
</div>
<div class="flex gap-1">
<UiBadge :variant="roleBadge(admin.role)">
{{ roleText(admin.role) }}
</UiBadge>
<UiBadge :variant="admin.status === 1 ? 'default' : 'destructive'">
{{ admin.status === 1 ? '正常' : '禁用' }}
</UiBadge>
</div>
</div>
<div v-if="admin.isSystem !== 1" class="mt-2 flex justify-end">
<UiButton
size="sm"
variant="outline"
:disabled="toggleStatusMutation.isPending.value"
@click="toggleStatus(admin)"
>
{{ admin.status === 1 ? '禁用' : '启用' }}
</UiButton>
</div>
</UiCard>
</template>
<div v-else class="text-center py-8 text-muted-foreground">
暂无数据
</div>
</div>
</div>
<!-- 新增账号弹窗 -->
<UiDialog v-model:open="showCreateDialog">
<UiDialogContent class="max-w-md">
<UiDialogHeader>
<UiDialogTitle>新增账号</UiDialogTitle>
</UiDialogHeader>
<div class="grid gap-4 py-4">
<div class="grid gap-2">
<UiLabel>用户名 <span class="text-red-500">*</span></UiLabel>
<UiInput v-model="newAdmin.username" placeholder="请输入用户名" />
</div>
<div class="grid gap-2">
<UiLabel>密码 <span class="text-red-500">*</span></UiLabel>
<UiInput v-model="newAdmin.password" type="password" placeholder="至少4位" />
</div>
<div class="grid gap-2">
<UiLabel>昵称</UiLabel>
<UiInput v-model="newAdmin.nickname" placeholder="可选" />
</div>
<div class="grid gap-2">
<UiLabel>角色 <span class="text-red-500">*</span></UiLabel>
<UiSelect v-model="newAdmin.role">
<UiSelectTrigger>
<UiSelectValue placeholder="请选择角色" />
</UiSelectTrigger>
<UiSelectContent>
<UiSelectItem :value="2">
管理员
</UiSelectItem>
<UiSelectItem :value="3">
财务
</UiSelectItem>
</UiSelectContent>
</UiSelect>
</div>
</div>
<UiDialogFooter>
<UiButton variant="outline" @click="showCreateDialog = false">
取消
</UiButton>
<UiButton :disabled="createMutation.isPending.value" @click="createAdmin">
<UiSpinner v-if="createMutation.isPending.value" class="mr-2" />
创建
</UiButton>
</UiDialogFooter>
</UiDialogContent>
</UiDialog>
</BasicPage>
</template>

View File

@@ -19,6 +19,8 @@ const showEditDialog = ref(false)
const showPriceDialog = ref(false)
const priceInput = ref<number>(0)
const editingCode = ref('')
const editingInitialPrice = ref<number | null>(null)
const editingCurrentPrice = ref<number>(0)
// 表单验证
const formErrors = ref<{ code?: string, name?: string }>({})
@@ -60,12 +62,14 @@ async function saveCoin() {
refetch()
}
catch (e: any) {
toast.error(e.response?.data?.msg || '操作失败')
toast.error(e.message || e.response?.data?.msg || '操作失败')
}
}
function openPriceDialog(coin: Coin) {
editingCode.value = coin.code
editingInitialPrice.value = coin.initialPrice ?? null
editingCurrentPrice.value = coin.price
priceInput.value = coin.price
showPriceDialog.value = true
}
@@ -83,7 +87,7 @@ async function updatePrice() {
refetch()
}
catch (e: any) {
toast.error(e.response?.data?.msg || '操作失败')
toast.error(e.message || e.response?.data?.msg || '操作失败')
}
}
@@ -96,7 +100,7 @@ async function toggleStatus(coin: Coin) {
toast.success(`${action} ${coin.code}`)
}
catch (e: any) {
toast.error(e.response?.data?.msg || `${action}失败`)
toast.error(e.message || e.response?.data?.msg || `${action}失败`)
}
}
@@ -128,7 +132,10 @@ function formatPrice(price: number): string {
<UiTableHead>代码</UiTableHead>
<UiTableHead>名称</UiTableHead>
<UiTableHead class="text-right">
价格
初始价格
</UiTableHead>
<UiTableHead class="text-right">
当前价格
</UiTableHead>
<UiTableHead>价格类型</UiTableHead>
<UiTableHead>状态</UiTableHead>
@@ -139,12 +146,12 @@ function formatPrice(price: number): string {
</UiTableHeader>
<UiTableBody>
<UiTableRow v-if="isLoading">
<UiTableCell :col-span="7" class="text-center py-8">
<UiTableCell :col-span="8" class="text-center py-8">
<UiSpinner class="mx-auto" />
</UiTableCell>
</UiTableRow>
<UiTableRow v-else-if="coins.length === 0">
<UiTableCell :col-span="7" class="text-center py-8 text-muted-foreground">
<UiTableCell :col-span="8" class="text-center py-8 text-muted-foreground">
暂无数据
</UiTableCell>
</UiTableRow>
@@ -154,7 +161,10 @@ function formatPrice(price: number): string {
{{ coin.code }}
</UiTableCell>
<UiTableCell>{{ coin.name }}</UiTableCell>
<UiTableCell class="text-right font-mono">
<UiTableCell class="text-right font-mono text-muted-foreground">
{{ coin.initialPrice != null ? `$${formatPrice(coin.initialPrice)}` : '--' }}
</UiTableCell>
<UiTableCell class="text-right font-mono font-semibold text-green-600 dark:text-green-400">
${{ formatPrice(coin.price) }}
</UiTableCell>
<UiTableCell>
@@ -224,6 +234,9 @@ function formatPrice(price: number): string {
<div class="text-xl font-mono font-bold text-green-600 dark:text-green-400">
${{ formatPrice(coin.price) }}
</div>
<div v-if="coin.initialPrice != null" class="text-xs text-muted-foreground mt-1">
初始价格: ${{ formatPrice(coin.initialPrice) }}
</div>
</div>
<div class="mt-3 flex gap-2">
<UiButton size="sm" variant="outline" class="flex-1" @click="openEditDialog(coin)">
@@ -268,6 +281,7 @@ function formatPrice(price: number): string {
<UiInput
v-model="editingCoin.code"
placeholder="BTC"
:disabled="!!editingCoin.id"
:class="{ 'border-red-500': formErrors.code }"
@input="formErrors.code = undefined"
/>
@@ -289,7 +303,7 @@ function formatPrice(price: number): string {
</div>
<div class="grid gap-2">
<UiLabel>价格类型</UiLabel>
<UiSelect v-model="editingCoin.priceType">
<UiSelect v-model="editingCoin.priceType" :disabled="!!editingCoin.id">
<UiSelectTrigger>
<UiSelectValue />
</UiSelectTrigger>
@@ -303,10 +317,31 @@ function formatPrice(price: number): string {
</UiSelectContent>
</UiSelect>
</div>
<div v-if="editingCoin.priceType === 2" class="grid gap-2">
<!-- 新增时设置初始价格 -->
<div v-if="editingCoin.priceType === 2 && !editingCoin.id" class="grid gap-2">
<UiLabel>初始价格 ($)</UiLabel>
<UiInput v-model.number="editingCoin.price" type="number" step="0.000001" placeholder="0.00" />
</div>
<!-- 编辑时显示初始价格只读和当前价格只读 -->
<template v-if="editingCoin.priceType === 2 && editingCoin.id">
<div v-if="editingCoin.initialPrice != null" class="grid grid-cols-2 gap-4 text-sm">
<div>
<span class="text-muted-foreground">初始价格</span>
<div class="font-mono mt-1">
${{ formatPrice(editingCoin.initialPrice) }}
</div>
</div>
<div>
<span class="text-muted-foreground">当前价格</span>
<div class="font-mono mt-1 text-green-600 dark:text-green-400">
${{ formatPrice(editingCoin.price) }}
</div>
</div>
</div>
<div v-else class="text-sm text-muted-foreground bg-muted/50 rounded-md p-3">
尚未调价初始价格将在首次调价时锁定
</div>
</template>
</div>
<UiDialogFooter>
<UiButton variant="outline" @click="showEditDialog = false">
@@ -327,6 +362,23 @@ function formatPrice(price: number): string {
<UiDialogTitle>调整价格 - {{ editingCode }}</UiDialogTitle>
</UiDialogHeader>
<div class="grid gap-4 py-4">
<div v-if="editingInitialPrice != null" class="grid grid-cols-2 gap-4 text-sm">
<div>
<span class="text-muted-foreground">初始价格</span>
<div class="font-mono mt-1">
${{ formatPrice(editingInitialPrice) }}
</div>
</div>
<div>
<span class="text-muted-foreground">当前价格</span>
<div class="font-mono mt-1 text-green-600 dark:text-green-400">
${{ formatPrice(editingCurrentPrice) }}
</div>
</div>
</div>
<div v-else class="text-sm text-muted-foreground bg-muted/50 rounded-md p-3">
首次调价后当前价格将被锁定为初始价格之后只能调整当前价格
</div>
<div class="grid gap-2">
<UiLabel>新价格 ($)</UiLabel>
<UiInput

View File

@@ -0,0 +1,372 @@
<script lang="ts" setup>
import { Icon } from '@iconify/vue'
import { toast } from 'vue-sonner'
import type { OrderFund } from '@/services/api/monisuo-admin.api'
import { BasicPage } from '@/components/global-layout'
import { useApproveOrderMutation, useGetPendingOrdersQuery } from '@/services/api/monisuo-admin.api'
const pageNum = ref(1)
const pageSize = ref(10)
const { data: pendingData, isLoading: pendingLoading, refetch: refetchPending } = useGetPendingOrdersQuery({
pageNum: pageNum.value,
pageSize: pageSize.value,
})
const approveMutation = useApproveOrderMutation()
const pendingOrders = computed(() => pendingData.value?.data?.list || [])
const pendingTotal = computed(() => pendingData.value?.data?.total || 0)
const totalPages = computed(() => Math.ceil(pendingTotal.value / pageSize.value))
const showApproveDialog = ref(false)
const showDetailDialog = ref(false)
const currentOrder = ref<OrderFund | null>(null)
const approveStatus = ref(2)
const rejectReason = ref('')
const adminRemark = ref('')
function viewOrderDetail(order: OrderFund) {
currentOrder.value = order
showDetailDialog.value = true
}
function openApproveDialog(order: OrderFund, status: number) {
currentOrder.value = order
approveStatus.value = status
rejectReason.value = ''
adminRemark.value = ''
showApproveDialog.value = true
}
async function handleApprove() {
if (!currentOrder.value)
return
const action = approveStatus.value === 2 ? '通过' : '驳回'
try {
await approveMutation.mutateAsync({
orderNo: currentOrder.value.orderNo,
status: approveStatus.value,
rejectReason: rejectReason.value || undefined,
adminRemark: adminRemark.value || undefined,
})
toast.success(`订单已${action}`)
showApproveDialog.value = false
refetchPending()
}
catch (e: any) {
toast.error(e.message || e.response?.data?.msg || `${action}失败`)
}
}
function handlePageChange(page: number) {
pageNum.value = page
refetchPending()
}
function handlePageSizeChange(size: unknown) {
if (size === null || size === undefined)
return
pageSize.value = Number(size)
pageNum.value = 1
refetchPending()
}
function formatAmount(amount: number): string {
return amount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
}
function copyToClipboard(text: string) {
navigator.clipboard.writeText(text)
toast.success('已复制到剪贴板')
}
</script>
<template>
<BasicPage title="财务审批" description="审批提现订单">
<div class="space-y-4">
<!-- 提现待财务审核列表 -->
<UiCard class="hidden md:block overflow-x-auto p-4">
<UiTable>
<UiTableHeader>
<UiTableRow>
<UiTableHead>订单号</UiTableHead>
<UiTableHead>用户</UiTableHead>
<UiTableHead class="text-right">
提现金额
</UiTableHead>
<UiTableHead class="text-right">
手续费
</UiTableHead>
<UiTableHead class="text-right">
应收款项
</UiTableHead>
<UiTableHead>审批人</UiTableHead>
<UiTableHead class="hidden xl:table-cell">
时间
</UiTableHead>
<UiTableHead class="text-right">
操作
</UiTableHead>
</UiTableRow>
</UiTableHeader>
<UiTableBody>
<UiTableRow v-if="pendingLoading">
<UiTableCell :col-span="8" class="text-center py-8">
<UiSpinner class="mx-auto" />
</UiTableCell>
</UiTableRow>
<UiTableRow v-else-if="pendingOrders.length === 0">
<UiTableCell :col-span="8" class="text-center py-8 text-muted-foreground">
<Icon icon="lucide:inbox" class="size-8 mx-auto mb-2 opacity-50" />
<p>暂无待审核订单</p>
</UiTableCell>
</UiTableRow>
<UiTableRow v-for="order in pendingOrders" :key="order.id">
<UiTableCell class="font-mono text-xs">
{{ order.orderNo }}
</UiTableCell>
<UiTableCell>{{ order.username }}</UiTableCell>
<UiTableCell class="text-right font-mono font-medium">
${{ formatAmount(order.amount) }}
</UiTableCell>
<UiTableCell class="text-right font-mono text-muted-foreground">
-${{ formatAmount(order.fee || 0) }}
</UiTableCell>
<UiTableCell class="text-right font-mono font-bold text-green-600">
${{ formatAmount(order.receivableAmount || 0) }}
</UiTableCell>
<UiTableCell class="text-sm">
{{ order.approveAdminName || '-' }}
</UiTableCell>
<UiTableCell class="hidden xl:table-cell text-muted-foreground text-sm">
{{ order.createTime }}
</UiTableCell>
<UiTableCell class="text-right">
<div class="flex justify-end gap-1">
<UiButton size="sm" variant="ghost" @click="viewOrderDetail(order)">
<Icon icon="lucide:eye" class="size-4" />
</UiButton>
<UiButton
size="sm"
:disabled="approveMutation.isPending.value"
@click="openApproveDialog(order, 2)"
>
通过
</UiButton>
<UiButton
size="sm"
variant="destructive"
:disabled="approveMutation.isPending.value"
@click="openApproveDialog(order, 3)"
>
驳回
</UiButton>
</div>
</UiTableCell>
</UiTableRow>
</UiTableBody>
</UiTable>
</UiCard>
<!-- 移动端卡片 -->
<div class="md:hidden space-y-3">
<div v-if="pendingLoading" class="text-center py-8">
<UiSpinner class="mx-auto" />
</div>
<template v-else-if="pendingOrders.length > 0">
<UiCard v-for="order in pendingOrders" :key="order.id" class="p-4">
<div class="flex items-start justify-between">
<div class="space-y-1">
<div class="font-mono text-xs text-muted-foreground">
{{ order.orderNo }}
</div>
<div class="font-medium">
{{ order.username }}
</div>
</div>
<UiBadge variant="secondary">
待财务审核
</UiBadge>
</div>
<div class="mt-3 pt-3 border-t">
<div class="text-xl font-mono font-bold text-red-600 dark:text-red-400">
-${{ formatAmount(order.amount) }}
</div>
<div class="text-sm text-muted-foreground mt-1">
手续费: -${{ formatAmount(order.fee || 0) }} | 实际到账: ${{ formatAmount(order.receivableAmount || 0) }}
</div>
<div class="text-sm text-muted-foreground mt-1">
审批人: {{ order.approveAdminName || '-' }}
</div>
<div v-if="order.walletAddress" class="mt-2 text-sm">
<span class="text-muted-foreground">提现地址:</span>
<div class="font-mono text-xs break-all mt-1 flex items-center gap-1">
{{ order.walletAddress }}
<Icon icon="lucide:copy" class="size-3 cursor-pointer" @click="copyToClipboard(order.walletAddress!)" />
</div>
</div>
<div class="text-sm text-muted-foreground mt-1">
{{ order.createTime }}
</div>
</div>
<div class="mt-3 flex gap-2">
<UiButton size="sm" class="flex-1" @click="openApproveDialog(order, 2)">
通过
</UiButton>
<UiButton size="sm" variant="destructive" class="flex-1" @click="openApproveDialog(order, 3)">
驳回
</UiButton>
</div>
</UiCard>
</template>
<div v-else class="text-center py-8 text-muted-foreground">
<Icon icon="lucide:inbox" class="size-8 mx-auto mb-2 opacity-50" />
<p>暂无待审核订单</p>
</div>
</div>
<!-- 分页 -->
<div v-if="pendingTotal > 0" class="flex items-center justify-between gap-4 px-2">
<div class="text-sm text-muted-foreground">
{{ pendingTotal }} 条待审核
</div>
<div class="flex items-center gap-2">
<UiButton
variant="outline"
size="icon"
class="h-8 w-8"
:disabled="pageNum <= 1"
@click="handlePageChange(pageNum - 1)"
>
<Icon icon="lucide:chevron-left" class="size-4" />
</UiButton>
<span class="text-sm min-w-[80px] text-center">
{{ pageNum }} / {{ totalPages }}
</span>
<UiButton
variant="outline"
size="icon"
class="h-8 w-8"
:disabled="pageNum >= totalPages"
@click="handlePageChange(pageNum + 1)"
>
<Icon icon="lucide:chevron-right" class="size-4" />
</UiButton>
</div>
</div>
</div>
<!-- 订单详情弹窗 -->
<UiDialog v-model:open="showDetailDialog">
<UiDialogContent class="max-w-md max-h-[90vh] overflow-y-auto">
<UiDialogHeader>
<UiDialogTitle>提现订单详情</UiDialogTitle>
</UiDialogHeader>
<div v-if="currentOrder" class="space-y-4">
<div class="grid grid-cols-3 gap-2 text-sm">
<div class="text-muted-foreground">订单号</div>
<div class="col-span-2 font-mono">{{ currentOrder.orderNo }}</div>
<div class="text-muted-foreground">用户</div>
<div class="col-span-2 font-medium">{{ currentOrder.username }}</div>
<div class="text-muted-foreground">提现金额</div>
<div class="col-span-2 font-mono font-bold text-lg">${{ formatAmount(currentOrder.amount) }}</div>
<div class="text-muted-foreground">手续费(10%)</div>
<div class="col-span-2 font-mono">-${{ formatAmount(currentOrder.fee || 0) }}</div>
<div class="text-muted-foreground">应收款项</div>
<div class="col-span-2 font-mono font-bold text-green-600">${{ formatAmount(currentOrder.receivableAmount || 0) }}</div>
<div class="text-muted-foreground">提现地址</div>
<div class="col-span-2">
<div v-if="currentOrder.walletAddress" class="flex items-start gap-1">
<span class="font-mono text-xs break-all">{{ currentOrder.walletAddress }}</span>
<Icon icon="lucide:copy" class="size-4 cursor-pointer flex-shrink-0" @click="copyToClipboard(currentOrder.walletAddress!)" />
</div>
<span v-else class="text-muted-foreground">-</span>
</div>
<div v-if="currentOrder.approveAdminName" class="text-muted-foreground">审批人</div>
<div v-if="currentOrder.approveAdminName" class="col-span-2">
{{ currentOrder.approveAdminName }}
</div>
<div class="text-muted-foreground">创建时间</div>
<div class="col-span-2">{{ currentOrder.createTime }}</div>
</div>
</div>
<UiDialogFooter>
<template v-if="currentOrder">
<UiButton variant="outline" @click="showDetailDialog = false">
关闭
</UiButton>
<UiButton @click="openApproveDialog(currentOrder, 2); showDetailDialog = false">
通过
</UiButton>
<UiButton variant="destructive" @click="openApproveDialog(currentOrder, 3); showDetailDialog = false">
驳回
</UiButton>
</template>
</UiDialogFooter>
</UiDialogContent>
</UiDialog>
<!-- 审批弹窗 -->
<UiDialog v-model:open="showApproveDialog">
<UiDialogContent class="max-w-md max-h-[90vh] overflow-y-auto">
<UiDialogHeader>
<UiDialogTitle>{{ approveStatus === 2 ? '通过提现' : '驳回提现' }}</UiDialogTitle>
</UiDialogHeader>
<div v-if="currentOrder" class="grid gap-4 py-4">
<div class="p-3 rounded-lg bg-muted/50 text-sm space-y-2">
<div>
<div class="text-muted-foreground">订单号</div>
<div class="font-mono">{{ currentOrder.orderNo }}</div>
</div>
<div>
<div class="text-muted-foreground">用户</div>
<div class="font-medium">{{ currentOrder.username }}</div>
</div>
<div>
<div class="text-muted-foreground">提现金额</div>
<div class="font-mono font-bold text-lg">${{ formatAmount(currentOrder.amount) }}</div>
</div>
<div>
<div class="text-muted-foreground">应收款项</div>
<div class="font-mono text-green-600">${{ formatAmount(currentOrder.receivableAmount || 0) }}</div>
</div>
</div>
<div v-if="approveStatus === 3" class="grid gap-2">
<UiLabel>驳回原因 <span class="text-red-500">*</span></UiLabel>
<UiInput v-model="rejectReason" placeholder="请输入驳回原因" />
</div>
<div class="grid gap-2">
<UiLabel>备注</UiLabel>
<UiInput v-model="adminRemark" placeholder="可选" />
</div>
</div>
<UiDialogFooter>
<UiButton variant="outline" @click="showApproveDialog = false">
取消
</UiButton>
<UiButton
:variant="approveStatus === 3 ? 'destructive' : 'default'"
:disabled="approveMutation.isPending.value || (approveStatus === 3 && !rejectReason.trim())"
@click="handleApprove"
>
<UiSpinner v-if="approveMutation.isPending.value" class="mr-2" />
确认
</UiButton>
</UiDialogFooter>
</UiDialogContent>
</UiDialog>
</BasicPage>
</template>

View File

@@ -5,9 +5,12 @@ import { toast } from 'vue-sonner'
import type { OrderFund } from '@/services/api/monisuo-admin.api'
import { BasicPage } from '@/components/global-layout'
import { useAuthStore } from '@/stores/auth'
import { useApproveOrderMutation, useGetAllOrdersQuery, useGetPendingOrdersQuery } from '@/services/api/monisuo-admin.api'
const pageNum = ref(1)
// 分离分页状态
const pendingPage = ref(1)
const allPage = ref(1)
const pageSize = ref(10)
const activeTab = ref('pending')
@@ -15,13 +18,16 @@ const activeTab = ref('pending')
const filterType = ref<number | string>('all')
const filterStatus = ref<number | string>('all')
// 是否已加载过全部订单
const allLoaded = ref(false)
const { data: pendingData, isLoading: pendingLoading, refetch: refetchPending } = useGetPendingOrdersQuery({
pageNum: pageNum.value,
pageNum: pendingPage.value,
pageSize: pageSize.value,
})
const { data: allData, isLoading: allLoading, refetch: refetchAll } = useGetAllOrdersQuery({
pageNum: pageNum.value,
pageNum: allPage.value,
pageSize: pageSize.value,
type: filterType.value === 'all' ? undefined : filterType.value as number,
status: filterStatus.value === 'all' ? undefined : filterStatus.value as number,
@@ -29,13 +35,24 @@ const { data: allData, isLoading: allLoading, refetch: refetchAll } = useGetAllO
const approveMutation = useApproveOrderMutation()
const authStore = useAuthStore()
const adminRole = computed(() => authStore.adminInfo?.role ?? 2)
const pendingOrders = computed(() => pendingData.value?.data?.list || [])
const pendingTotal = computed(() => pendingData.value?.data?.total || 0)
const allOrders = computed(() => allData.value?.data?.list || [])
const allTotal = computed(() => allData.value?.data?.total || 0)
const currentTotal = computed(() => activeTab.value === 'pending' ? pendingTotal.value : allTotal.value)
const totalPages = computed(() => Math.ceil(currentTotal.value / pageSize.value))
const pendingTotalPages = computed(() => Math.ceil(pendingTotal.value / pageSize.value))
const allTotalPages = computed(() => Math.ceil(allTotal.value / pageSize.value))
// 切换 tab 时懒加载全部订单
watch(activeTab, (tab) => {
if (tab === 'all' && !allLoaded.value) {
allLoaded.value = true
refetchAll()
}
})
const showApproveDialog = ref(false)
const showDetailDialog = ref(false)
@@ -74,32 +91,37 @@ async function handleApprove() {
toast.success(`订单已${action}`)
showApproveDialog.value = false
refetchPending()
refetchAll()
if (allLoaded.value) refetchAll()
}
catch (e: any) {
toast.error(e.response?.data?.msg || `${action}失败`)
toast.error(e.message || e.response?.data?.msg || `${action}失败`)
}
}
function handlePageChange(page: number) {
pageNum.value = page
refetchPending()
refetchAll()
if (activeTab.value === 'pending') {
pendingPage.value = page
refetchPending()
} else {
allPage.value = page
refetchAll()
}
}
function handlePageSizeChange(size: unknown) {
if (size === null || size === undefined)
return
pageSize.value = Number(size)
pageNum.value = 1
pendingPage.value = 1
allPage.value = 1
refetchPending()
refetchAll()
if (allLoaded.value) refetchAll()
}
function resetFilters() {
filterType.value = 'all'
filterStatus.value = 'all'
pageNum.value = 1
allPage.value = 1
refetchAll()
}
@@ -123,6 +145,7 @@ function getStatusVariant(order: OrderFund): 'default' | 'secondary' | 'destruct
// 提现
if (status === 1) return 'default' // 待审批
if (status === 2) return 'default' // 已完成
if (status === 5) return 'secondary' // 待财务审核
return 'destructive' // 已驳回/已取消
}
}
@@ -157,12 +180,14 @@ function getStatusText(order: OrderFund): string {
// 充值: 仅待确认(status=2)可审批
// 提现: 仅待审批(status=1)可审批
function canApprove(order: OrderFund): boolean {
const role = adminRole.value
if (order.type === 1) {
return order.status === 2 // 充值待确认
}
else {
return order.status === 1 // 提现待审批
}
if (role === 2) return order.status === 1 // 管理员: 提现待审批
if (role === 3) return order.status === 5 // 财务: 待财务审核
if (role === 1) return order.status === 1 || order.status === 5 // 超管
return false
}
// 复制到剪贴板
@@ -437,6 +462,9 @@ function copyToClipboard(text: string) {
<UiTableHead class="hidden xl:table-cell">
时间
</UiTableHead>
<UiTableHead class="hidden lg:table-cell">
审批人
</UiTableHead>
<UiTableHead class="hidden lg:table-cell">
备注
</UiTableHead>
@@ -447,12 +475,12 @@ function copyToClipboard(text: string) {
</UiTableHeader>
<UiTableBody>
<UiTableRow v-if="allLoading">
<UiTableCell :col-span="9" class="text-center py-8">
<UiTableCell :col-span="10" class="text-center py-8">
<UiSpinner class="mx-auto" />
</UiTableCell>
</UiTableRow>
<UiTableRow v-else-if="allOrders.length === 0">
<UiTableCell :col-span="9" class="text-center py-8 text-muted-foreground">
<UiTableCell :col-span="10" class="text-center py-8 text-muted-foreground">
暂无数据
</UiTableCell>
</UiTableRow>
@@ -488,6 +516,10 @@ function copyToClipboard(text: string) {
完成: {{ order.confirmTime }}
</div>
</UiTableCell>
<UiTableCell class="hidden lg:table-cell text-sm text-muted-foreground">
<div v-if="order.approveAdminName">{{ order.approveAdminName }}</div>
<span v-else>-</span>
</UiTableCell>
<UiTableCell class="hidden lg:table-cell text-sm text-muted-foreground max-w-[120px] truncate">
{{ order.rejectReason || order.adminRemark || '-' }}
</UiTableCell>
@@ -547,6 +579,9 @@ function copyToClipboard(text: string) {
<div v-if="order.confirmTime" class="text-xs text-muted-foreground">
完成: {{ order.confirmTime }}
</div>
<div v-if="order.approveAdminName" class="text-xs text-muted-foreground">
审批人: {{ order.approveAdminName }}
</div>
<div v-if="order.rejectReason || order.adminRemark" class="text-sm text-muted-foreground mt-1">
备注: {{ order.rejectReason || order.adminRemark }}
</div>
@@ -566,9 +601,9 @@ function copyToClipboard(text: string) {
</UiTabs>
<!-- 分页 -->
<div v-if="currentTotal > 0" class="flex flex-col sm:flex-row items-center justify-between gap-4 px-2">
<div v-if="(activeTab === 'pending' ? pendingTotal : allTotal) > 0" class="flex flex-col sm:flex-row items-center justify-between gap-4 px-2">
<div class="text-sm text-muted-foreground">
{{ currentTotal }} 条记录
{{ activeTab === 'pending' ? pendingTotal : allTotal }} 条记录
</div>
<div class="flex items-center gap-4">
<div class="flex items-center gap-2">
@@ -596,20 +631,20 @@ function copyToClipboard(text: string) {
variant="outline"
size="icon"
class="h-8 w-8"
:disabled="pageNum <= 1"
@click="handlePageChange(pageNum - 1)"
:disabled="(activeTab === 'pending' ? pendingPage : allPage) <= 1"
@click="handlePageChange((activeTab === 'pending' ? pendingPage : allPage) - 1)"
>
<Icon icon="lucide:chevron-left" class="size-4" />
</UiButton>
<span class="text-sm min-w-[80px] text-center">
{{ pageNum }} / {{ totalPages }}
{{ activeTab === 'pending' ? pendingPage : allPage }} / {{ activeTab === 'pending' ? pendingTotalPages : allTotalPages }}
</span>
<UiButton
variant="outline"
size="icon"
class="h-8 w-8"
:disabled="pageNum >= totalPages"
@click="handlePageChange(pageNum + 1)"
:disabled="(activeTab === 'pending' ? pendingPage : allPage) >= (activeTab === 'pending' ? pendingTotalPages : allTotalPages)"
@click="handlePageChange((activeTab === 'pending' ? pendingPage : allPage) + 1)"
>
<Icon icon="lucide:chevron-right" class="size-4" />
</UiButton>
@@ -665,6 +700,24 @@ function copyToClipboard(text: string) {
</UiBadge>
</div>
<!-- 手续费信息提现 -->
<template v-if="currentOrder.type === 2 && currentOrder.fee">
<div class="text-muted-foreground">
手续费(10%)
</div>
<div class="col-span-2 font-mono">
-${{ currentOrder.fee }}
</div>
</template>
<template v-if="currentOrder.type === 2 && currentOrder.receivableAmount">
<div class="text-muted-foreground">
应收款项
</div>
<div class="col-span-2 font-mono font-bold text-green-600">
${{ currentOrder.receivableAmount }}
</div>
</template>
<!-- 充值/提现地址 -->
<div class="text-muted-foreground">
{{ currentOrder.type === 1 ? '充值地址' : '提现地址' }}
@@ -704,6 +757,19 @@ function copyToClipboard(text: string) {
</div>
</template>
<!-- 财务审批人 -->
<template v-if="currentOrder.financeAdminName">
<div class="text-muted-foreground">
财务审批人
</div>
<div class="col-span-2">
{{ currentOrder.financeAdminName }}
<span v-if="currentOrder.financeApproveTime" class="text-xs text-muted-foreground ml-2">
{{ currentOrder.financeApproveTime }}
</span>
</div>
</template>
<!-- 管理员确认时间 -->
<template v-if="currentOrder.confirmTime">
<div class="text-muted-foreground">
@@ -714,6 +780,19 @@ function copyToClipboard(text: string) {
</div>
</template>
<!-- 审批人信息 -->
<template v-if="currentOrder.approveAdminName">
<div class="text-muted-foreground">
审批人
</div>
<div class="col-span-2">
{{ currentOrder.approveAdminName }}
<span v-if="currentOrder.approveTime" class="text-xs text-muted-foreground ml-2">
{{ currentOrder.approveTime }}
</span>
</div>
</template>
<template v-if="currentOrder.rejectReason">
<div class="text-muted-foreground text-red-500">
驳回原因

View File

@@ -44,7 +44,7 @@ async function toggleStatus(user: User) {
toast.success(`${action}用户 ${user.username}`)
}
catch (e: any) {
toast.error(e.response?.data?.msg || `${action}失败`)
toast.error(e.message || e.response?.data?.msg || `${action}失败`)
}
}

View File

@@ -76,7 +76,7 @@ async function saveWallet() {
refetch()
}
catch (e: any) {
toast.error(e.response?.data?.msg || '操作失败')
toast.error(e.message || e.response?.data?.msg || '操作失败')
}
}
@@ -89,7 +89,7 @@ async function setDefault(wallet: ColdWallet) {
toast.success(`已将 ${wallet.name} 设为默认`)
}
catch (e: any) {
toast.error(e.response?.data?.msg || '设置失败')
toast.error(e.message || e.response?.data?.msg || '设置失败')
}
}
@@ -99,7 +99,7 @@ async function toggleStatus(wallet: ColdWallet) {
toast.success(wallet.status === 1 ? '已禁用' : '已启用')
}
catch (e: any) {
toast.error(e.response?.data?.msg || '操作失败')
toast.error(e.message || e.response?.data?.msg || '操作失败')
}
}
@@ -112,7 +112,7 @@ async function deleteWallet(wallet: ColdWallet) {
toast.success('钱包已删除')
}
catch (e: any) {
toast.error(e.response?.data?.msg || '删除失败')
toast.error(e.message || e.response?.data?.msg || '删除失败')
}
}
</script>

View File

@@ -1,37 +1,72 @@
import type { Router } from 'vue-router'
import { storeToRefs } from 'pinia'
import pinia from '@/plugins/pinia/setup'
import { useAuthStore } from '@/stores/auth'
// 不需要认证的白名单路由
const WHITE_LIST = ['/auth/sign-in', '/auth/sign-up', '/auth/forgot-password']
export function authGuard(router: Router) {
router.beforeEach((to, _from) => {
// 仅超级管理员可访问的路由前缀
const SUPER_ADMIN_ONLY = ['/monisuo/dashboard', '/monisuo/users', '/monisuo/coins', '/monisuo/analytics', '/monisuo/admins']
export function setupAuthGuard(router: Router) {
router.beforeEach((to) => {
const authStore = useAuthStore(pinia)
const { isLogin } = storeToRefs(authStore)
const { isLogin, adminInfo } = storeToRefs(authStore)
// 检查是否在白名单中
const isInWhiteList = WHITE_LIST.some(path => to.path === path || to.path.startsWith(path + '/'))
console.log('[AuthGuard]', to.path, 'isInWhiteList:', isInWhiteList, 'isLogin:', unref(isLogin))
// 如果已登录且访问登录页,重定向到首页
if (unref(isLogin) && to.path === '/auth/sign-in') {
const role = unref(adminInfo)?.role
if (role === 2) {
return { path: '/monisuo/orders' }
}
if (role === 3) {
return { path: '/monisuo/finance-orders' }
}
return { name: '/monisuo/dashboard' }
}
// 如果未登录且不在白名单中,重定向到登录页
if (!unref(isLogin) && !isInWhiteList) {
console.log('[AuthGuard] Redirecting to login')
return {
name: '/auth/sign-in',
query: { redirect: to.fullPath },
}
}
// 已登录时检查角色权限
if (unref(isLogin) && !isInWhiteList) {
const role = unref(adminInfo)?.role
const isSuperAdmin = role === 1
if (!isSuperAdmin) {
const needsSuperAdmin = SUPER_ADMIN_ONLY.some(prefix => to.path.startsWith(prefix))
if (needsSuperAdmin) {
// 非超管尝试访问超管页面,根据角色重定向
if (role === 3) {
return { path: '/monisuo/finance-orders' }
}
return { path: '/monisuo/orders' }
}
// 财务角色(role=3)只能访问财务审批页面和设置
if (role === 3) {
const allowed = to.path.startsWith('/monisuo/finance-orders') || to.path.startsWith('/settings')
if (!allowed) {
return { path: '/monisuo/finance-orders' }
}
}
// 普通管理员(role=2)不能访问财务审批页面
if (role === 2 && to.path.startsWith('/monisuo/finance-orders')) {
return { path: '/monisuo/orders' }
}
}
}
return true
})
}

View File

@@ -2,11 +2,10 @@ import type { Router } from 'vue-router'
import nprogress from 'nprogress'
import { authGuard } from './auth-guard'
import { setupAuthGuard } from './auth-guard'
/**
* global router guard
* now only used for progress bar
*/
function setupCommonGuard(router: Router) {
router.beforeEach(() => {
@@ -21,5 +20,5 @@ function setupCommonGuard(router: Router) {
export function createRouterGuard(router: Router) {
setupCommonGuard(router)
authGuard(router)
setupAuthGuard(router)
}

View File

@@ -45,6 +45,7 @@ export interface Coin {
code: string
name: string
price: number
initialPrice?: number
priceType: number // 1: 实时 2: 手动
status: number
createTime: string
@@ -57,7 +58,9 @@ export interface OrderFund {
username: string
type: number // 1: 充值 2: 提现
amount: number
status: number // 充值: 1待付款 2待确认 3已完成 4已驳回 5已取消; 提现: 1待审批 2已完成 3已驳回 4已取消
fee?: number // 手续费
receivableAmount?: number // 应收款项
status: number // 充值: 1待付款 2待确认 3已完成 4已驳回 5已取消; 提现: 1待审批 2已完成 3已驳回 4已取消 5待财务审核
walletId?: number
walletAddress?: string
withdrawContact?: string
@@ -66,6 +69,12 @@ export interface OrderFund {
createTime: string
rejectReason?: string
adminRemark?: string
approveAdminId?: number
approveAdminName?: string
approveTime?: string
financeAdminId?: number
financeAdminName?: string
financeApproveTime?: string
}
export interface ColdWallet {
@@ -351,7 +360,91 @@ export function useToggleWalletStatusMutation() {
})
}
// ========== 分析相关 API ==========
// ========== 管理员管理 API ==========
export interface AdminRecord {
id: number
username: string
nickname: string
role: number
permissions?: string
isSystem?: number
status?: number
createTime?: string
}
export function useGetAdminListQuery() {
const { axiosInstance } = useAxios()
return useQuery<ApiResult<AdminRecord[]>, AxiosError>({
queryKey: ['useGetAdminListQuery'],
queryFn: async () => {
const response = await axiosInstance.get('/admin/admin/list')
return response.data
},
})
}
export function useCreateAdminMutation() {
const { axiosInstance } = useAxios()
const queryClient = useQueryClient()
return useMutation<ApiResult<{ id: number, username: string, role: number }>, AxiosError, { username: string, password: string, nickname?: string, role?: number }>({
mutationKey: ['useCreateAdminMutation'],
mutationFn: async (params) => {
const response = await axiosInstance.post('/admin/admin/create', params)
return response.data
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['useGetAdminListQuery'] })
},
})
}
export function useToggleAdminStatusMutation() {
const { axiosInstance } = useAxios()
const queryClient = useQueryClient()
return useMutation<ApiResult<void>, AxiosError, { id: number, status: number }>({
mutationKey: ['useToggleAdminStatusMutation'],
mutationFn: async (params) => {
const response = await axiosInstance.post('/admin/admin/status', params)
return response.data
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['useGetAdminListQuery'] })
},
})
}
export function usePromoteUserToAdminMutation() {
const { axiosInstance } = useAxios()
const queryClient = useQueryClient()
return useMutation<ApiResult<{ id: number, username: string, role: number }>, AxiosError, { username: string, password: string, nickname?: string }>({
mutationKey: ['usePromoteUserToAdminMutation'],
mutationFn: async (params) => {
const response = await axiosInstance.post('/admin/user/promote-admin', params)
return response.data
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['useGetAdminListQuery'] })
queryClient.invalidateQueries({ queryKey: ['useGetUserListQuery'] })
},
})
}
export function useChangePasswordMutation() {
const { axiosInstance } = useAxios()
return useMutation<ApiResult<void>, AxiosError, { oldPassword: string, newPassword: string }>({
mutationKey: ['useChangePasswordMutation'],
mutationFn: async (params) => {
const response = await axiosInstance.post('/admin/change-password', params)
return response.data
},
})
}
// 盈利分析
export function useGetProfitAnalysisQuery(range: string = 'month') {

View File

@@ -61,6 +61,13 @@ declare module 'vue-router/auto-routes' {
Record<never, never>,
| never
>,
'/monisuo/admins': RouteRecordInfo<
'/monisuo/admins',
'/monisuo/admins',
Record<never, never>,
Record<never, never>,
| never
>,
'/monisuo/analytics': RouteRecordInfo<
'/monisuo/analytics',
'/monisuo/analytics',
@@ -82,6 +89,13 @@ declare module 'vue-router/auto-routes' {
Record<never, never>,
| never
>,
'/monisuo/finance-orders': RouteRecordInfo<
'/monisuo/finance-orders',
'/monisuo/finance-orders',
Record<never, never>,
Record<never, never>,
| never
>,
'/monisuo/orders': RouteRecordInfo<
'/monisuo/orders',
'/monisuo/orders',
@@ -168,6 +182,12 @@ declare module 'vue-router/auto-routes' {
views:
| never
}
'src/pages/monisuo/admins.vue': {
routes:
| '/monisuo/admins'
views:
| never
}
'src/pages/monisuo/analytics.vue': {
routes:
| '/monisuo/analytics'
@@ -186,6 +206,12 @@ declare module 'vue-router/auto-routes' {
views:
| never
}
'src/pages/monisuo/finance-orders.vue': {
routes:
| '/monisuo/finance-orders'
views:
| never
}
'src/pages/monisuo/orders.vue': {
routes:
| '/monisuo/orders'

View File

@@ -59,11 +59,11 @@ CREATE TABLE `sys_admin` (
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='管理员表';
-- 初始化超级管理员账号 (密码: admin123)
-- 初始化超级管理员账号 (密码: saw123)
INSERT INTO `sys_admin` (`username`, `password`, `nickname`, `role`, `permissions`, `is_system`)
VALUES
('admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9vz.a', '超级管理员1', 1, 'all', 1),
('superadmin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9vz.a', '超级管理员2', 1, 'all', 1);
('SupperadminWho1', '$2a$10$mk2IthNSTCQXNtT7AR9Sou3UsZPiPCrqwiJhqKu5mOb8CW0Dqdz2G', '超级管理员1', 1, 'all', 1),
('SupperadminWho2', '$2a$10$mk2IthNSTCQXNtT7AR9Sou3UsZPiPCrqwiJhqKu5mOb8CW0Dqdz2G', '超级管理员2', 1, 'all', 1);
-- ---------------------------------------------
-- 3. 币种表
@@ -75,6 +75,7 @@ CREATE TABLE `coin` (
`name` varchar(50) NOT NULL COMMENT '币种名称(如Bitcoin)',
`icon` varchar(255) DEFAULT NULL COMMENT '币种图标URL',
`price` decimal(20,8) NOT NULL DEFAULT '0.00000000' COMMENT '当前价格(USDT)',
`initial_price` decimal(20,8) DEFAULT NULL COMMENT '初始价格(首次调价时锁定)',
`price_usd` decimal(20,8) DEFAULT NULL COMMENT '美元价格',
`price_cny` decimal(20,8) DEFAULT NULL COMMENT '人民币价格',
`price_type` tinyint(1) NOT NULL DEFAULT '2' COMMENT '价格类型: 1-实时 2-管理',
@@ -197,7 +198,11 @@ CREATE TABLE `order_fund` (
KEY `idx_user_id` (`user_id`),
KEY `idx_status` (`status`),
KEY `idx_type` (`type`),
KEY `idx_create_time` (`create_time`)
KEY `idx_create_time` (`create_time`),
KEY `idx_type_status_time` (`type`, `status`, `create_time`),
KEY `idx_user_status` (`user_id`, `status`),
KEY `idx_approve_admin` (`approve_admin_id`),
KEY `idx_finance_admin` (`finance_admin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='充提订单表';
-- ---------------------------------------------

View File

@@ -17,6 +17,9 @@ public class UserContext {
/** 类型: user/admin */
private String type;
/** 角色: 1-超级管理员 2-普通管理员 */
private Integer role;
private static final ThreadLocal<UserContext> CONTEXT = new ThreadLocal<>();
public static void set(UserContext context) {
@@ -45,4 +48,24 @@ public class UserContext {
UserContext context = get();
return context != null && "admin".equals(context.type);
}
public static boolean isSuperAdmin() {
UserContext context = get();
return context != null && "admin".equals(context.type) && context.role != null && context.role == 1;
}
public static Integer getRole() {
UserContext context = get();
return context != null ? context.role : null;
}
public static boolean isFinance() {
UserContext context = get();
return context != null && "admin".equals(context.type) && context.role != null && context.role == 3;
}
public static boolean isRegularAdmin() {
UserContext context = get();
return context != null && "admin".equals(context.type) && context.role != null && context.role == 2;
}
}

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.it.rattan.monisuo.common.Result;
import com.it.rattan.monisuo.context.UserContext;
import com.it.rattan.monisuo.entity.*;
import com.it.rattan.monisuo.mapper.AccountFundMapper;
import com.it.rattan.monisuo.mapper.OrderFundMapper;
@@ -13,7 +14,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -37,12 +37,17 @@ public class AdminController {
@Autowired
private AssetService assetService;
@Autowired
private AdminService adminService;
@Autowired
private AccountFundMapper accountFundMapper;
@Autowired
private OrderFundMapper orderFundMapper;
// ==================== 公开接口 ====================
/**
* 管理员登录
*/
@@ -55,32 +60,135 @@ public class AdminController {
return Result.fail("用户名和密码不能为空");
}
// 简单验证,实际应从数据库查询
// 这里预置账号: admin/admin123, superadmin/admin123
String validPassword = "$2a$12$VSVV5o6OXguuFh4f7JvQielF22zxvsvjITkOr/K8D5TnZZcVtQ0B2"; // admin123
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder encoder =
new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder();
// 临时处理:预置账号
if (("admin".equals(username) || "superadmin".equals(username)) &&
encoder.matches(password, validPassword)) {
String token = JwtUtil.createToken(1L, username, "admin");
Map<String, Object> result = new HashMap<>();
result.put("token", token);
Map<String, Object> adminInfo = new HashMap<>();
adminInfo.put("id", 1L);
adminInfo.put("username", username);
adminInfo.put("nickname", "超级管理员");
adminInfo.put("role", 1);
adminInfo.put("avatar", "/avatars/admin.jpg");
result.put("adminInfo", adminInfo);
return Result.success("登录成功", result);
Admin admin = adminService.login(username, password);
if (admin == null) {
return Result.fail("用户名或密码错误");
}
return Result.fail("用户名或密码错误");
// 生成JWT Token含角色信息
String token = JwtUtil.createToken(admin.getId(), admin.getUsername(), "admin", admin.getRole());
Map<String, Object> result = new HashMap<>();
result.put("token", token);
Map<String, Object> adminInfo = new HashMap<>();
adminInfo.put("id", admin.getId());
adminInfo.put("username", admin.getUsername());
adminInfo.put("nickname", admin.getNickname());
adminInfo.put("role", admin.getRole());
adminInfo.put("avatar", admin.getAvatar());
result.put("adminInfo", adminInfo);
return Result.success("登录成功", result);
}
// ==================== 所有管理员可访问 ====================
/**
* 修改密码
*/
@PostMapping("/change-password")
public Result<Void> changePassword(@RequestBody Map<String, String> params) {
String oldPassword = params.get("oldPassword");
String newPassword = params.get("newPassword");
if (oldPassword == null || newPassword == null) {
return Result.fail("参数不能为空");
}
if (newPassword.length() < 4) {
return Result.fail("新密码长度不能少于4位");
}
try {
boolean success = adminService.updatePassword(UserContext.getUserId(), oldPassword, newPassword);
if (!success) {
return Result.fail("旧密码不正确");
}
return Result.success("密码修改成功", null);
} catch (RuntimeException e) {
return Result.fail(e.getMessage());
}
}
/**
* 待审批订单
*/
@GetMapping("/order/pending")
public Result<Map<String, Object>> getPendingOrders(
@RequestParam(required = false) Integer type,
@RequestParam(required = false) Integer status,
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "20") int pageSize) {
IPage<OrderFund> page = fundService.getPendingOrders(type, status, pageNum, pageSize, UserContext.getRole());
Map<String, Object> data = new HashMap<>();
data.put("list", page.getRecords());
data.put("total", page.getTotal());
data.put("pageNum", page.getCurrent());
data.put("pageSize", page.getSize());
return Result.success(data);
}
/**
* 所有充提订单
*/
@GetMapping("/order/list")
public Result<Map<String, Object>> getAllOrders(
@RequestParam(required = false) Integer type,
@RequestParam(required = false) Integer status,
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "20") int pageSize) {
// 普通管理员/财务只能看自己审批过的订单
Integer adminRole = UserContext.getRole();
Long adminId = UserContext.isSuperAdmin() ? null : UserContext.getUserId();
IPage<OrderFund> page = fundService.getAllOrders(type, status, pageNum, pageSize, adminId, adminRole);
Map<String, Object> data = new HashMap<>();
data.put("list", page.getRecords());
data.put("total", page.getTotal());
data.put("pageNum", page.getCurrent());
data.put("pageSize", page.getSize());
return Result.success(data);
}
/**
* 审批订单
*/
@PostMapping("/order/approve")
public Result<Void> approveOrder(@RequestBody Map<String, Object> params) {
String orderNo = (String) params.get("orderNo");
Integer status = (Integer) params.get("status");
String rejectReason = (String) params.get("rejectReason");
String adminRemark = (String) params.get("adminRemark");
if (orderNo == null || status == null) {
return Result.fail("参数错误");
}
if (status != 2 && status != 3) {
return Result.fail("状态参数错误");
}
try {
Long adminId = UserContext.getUserId();
Integer adminRole = UserContext.getRole();
// 查询管理员昵称,拼成 "昵称(用户名)" 格式
Admin currentAdmin = adminService.getById(adminId);
String adminDisplay = currentAdmin != null
? currentAdmin.getNickname() + "(" + currentAdmin.getUsername() + ")"
: "管理员";
fundService.approve(adminId != null ? adminId : 1L, adminDisplay, adminRole,
orderNo, status, rejectReason, adminRemark);
return Result.success(status == 2 ? "审批通过" : "已驳回", null);
} catch (Exception e) {
return Result.fail(e.getMessage());
}
}
// ==================== 仅超级管理员可访问 ====================
/**
* 用户列表
*/
@@ -91,6 +199,10 @@ public class AdminController {
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "20") int pageSize) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
if (username != null && !username.isEmpty()) {
wrapper.like(User::getUsername, username);
@@ -116,6 +228,10 @@ public class AdminController {
*/
@GetMapping("/user/detail")
public Result<Map<String, Object>> getUserDetail(@RequestParam Long userId) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
User user = userService.getById(userId);
if (user == null) {
return Result.fail("用户不存在");
@@ -124,11 +240,9 @@ public class AdminController {
Map<String, Object> data = new HashMap<>();
data.put("user", user);
// 资产信息
AccountFund fund = assetService.getOrCreateFundAccount(userId);
data.put("fund", fund);
// 交易账户
List<Map<String, Object>> trade = assetService.getTradeAccount(userId);
data.put("trade", trade);
@@ -140,6 +254,10 @@ public class AdminController {
*/
@PostMapping("/user/status")
public Result<Void> updateUserStatus(@RequestBody Map<String, Object> params) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
Long userId = Long.valueOf(params.get("userId").toString());
Integer status = (Integer) params.get("status");
@@ -155,11 +273,47 @@ public class AdminController {
return Result.success(status == 1 ? "已启用" : "已禁用", null);
}
/**
* 将用户提升为管理员
*/
@PostMapping("/user/promote-admin")
public Result<Map<String, Object>> promoteUserToAdmin(@RequestBody Map<String, String> params) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
String username = params.get("username");
String password = params.get("password");
String nickname = params.get("nickname");
if (username == null || password == null) {
return Result.fail("用户名和密码不能为空");
}
try {
Admin admin = adminService.createAdmin(username, password,
nickname != null ? nickname : username, 2);
Map<String, Object> data = new HashMap<>();
data.put("id", admin.getId());
data.put("username", admin.getUsername());
data.put("nickname", admin.getNickname());
data.put("role", admin.getRole());
return Result.success("管理员创建成功", data);
} catch (RuntimeException e) {
return Result.fail(e.getMessage());
}
}
/**
* 币种列表
*/
@GetMapping("/coin/list")
public Result<Map<String, Object>> getCoinList() {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
List<Coin> coins = coinService.list();
Map<String, Object> data = new HashMap<>();
data.put("list", coins);
@@ -171,6 +325,10 @@ public class AdminController {
*/
@PostMapping("/coin/save")
public Result<Void> saveCoin(@RequestBody Coin coin) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
if (coin.getCode() == null || coin.getCode().isEmpty()) {
return Result.fail("币种代码不能为空");
}
@@ -181,11 +339,17 @@ public class AdminController {
coin.setCode(coin.getCode().toUpperCase());
if (coin.getId() == null) {
// 新增
coin.setCreateTime(LocalDateTime.now());
coinService.save(coin);
} else {
// 编辑
Coin existing = coinService.getById(coin.getId());
if (existing == null) {
return Result.fail("币种不存在");
}
coin.setCode(existing.getCode());
if (existing.getInitialPrice() != null) {
coin.setInitialPrice(existing.getInitialPrice());
}
coin.setUpdateTime(LocalDateTime.now());
coinService.updateById(coin);
}
@@ -198,12 +362,15 @@ public class AdminController {
*/
@PostMapping("/coin/price")
public Result<Void> updateCoinPrice(@RequestBody Map<String, Object> params) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
String code = (String) params.get("code");
BigDecimal price = new BigDecimal(params.get("price").toString());
// USDT价格固定为1不允许修改
if ("USDT".equalsIgnoreCase(code)) {
return Result.fail("USDT价格固定为1不可修改");
if ("BTC".equalsIgnoreCase(code) || "ETH".equalsIgnoreCase(code) || "USDT".equalsIgnoreCase(code)) {
return Result.fail(code.toUpperCase() + " 价格不可调整");
}
Coin coin = coinService.getCoinByCode(code);
@@ -215,9 +382,21 @@ public class AdminController {
return Result.fail("实时币种价格不可手动修改");
}
if (price.compareTo(coin.getPrice()) < 0) {
return Result.fail("价格不允许下调,当前价格: " + coin.getPrice());
}
if (price.compareTo(coin.getPrice()) == 0) {
return Result.fail("新价格与当前价格相同");
}
if (coin.getInitialPrice() == null) {
coin.setInitialPrice(coin.getPrice());
}
coin.setPrice(price);
coin.setUpdateTime(LocalDateTime.now());
coinService.updateById(coin);
coinService.clearCache(code);
return Result.success("价格已更新", null);
}
@@ -227,6 +406,10 @@ public class AdminController {
*/
@PostMapping("/coin/status")
public Result<Void> updateCoinStatus(@RequestBody Map<String, Object> params) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
Long coinId = Long.valueOf(params.get("coinId").toString());
Integer status = (Integer) params.get("status");
@@ -247,16 +430,16 @@ public class AdminController {
*/
@PostMapping("/coin/calculator")
public Result<Map<String, Object>> calculatePrice(@RequestBody Map<String, Object> params) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
BigDecimal currentPrice = new BigDecimal(params.get("currentPrice").toString());
BigDecimal holdingAmount = new BigDecimal(params.getOrDefault("holdingAmount", "1000").toString());
BigDecimal targetProfit = new BigDecimal(params.get("targetProfit").toString());
// 计算目标价格
// 持仓数量 = 持仓金额 / 当前价格
BigDecimal quantity = holdingAmount.divide(currentPrice, 8, BigDecimal.ROUND_DOWN);
// 单币盈亏 = 目标盈亏 / 持仓数量
BigDecimal profitPerCoin = targetProfit.divide(quantity, 8, BigDecimal.ROUND_DOWN);
// 目标价格 = 当前价格 + 单币盈亏
BigDecimal targetPrice = currentPrice.add(profitPerCoin);
Map<String, Object> result = new HashMap<>();
@@ -267,131 +450,101 @@ public class AdminController {
return Result.success(result);
}
/**
* 待审批订单
* 充值待确认(type=1,status=2) + 提现待审批(type=2,status=1)
*/
@GetMapping("/order/pending")
public Result<Map<String, Object>> getPendingOrders(
@RequestParam(required = false) Integer type,
@RequestParam(required = false) Integer status,
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "20") int pageSize) {
IPage<OrderFund> page = fundService.getPendingOrders(type, status, pageNum, pageSize);
Map<String, Object> data = new HashMap<>();
data.put("list", page.getRecords());
data.put("total", page.getTotal());
data.put("pageNum", page.getCurrent());
data.put("pageSize", page.getSize());
return Result.success(data);
}
/**
* 所有充提订单
*/
@GetMapping("/order/list")
public Result<Map<String, Object>> getAllOrders(
@RequestParam(required = false) Integer type,
@RequestParam(required = false) Integer status,
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "20") int pageSize) {
IPage<OrderFund> page = fundService.getAllOrders(type, status, pageNum, pageSize);
Map<String, Object> data = new HashMap<>();
data.put("list", page.getRecords());
data.put("total", page.getTotal());
data.put("pageNum", page.getCurrent());
data.put("pageSize", page.getSize());
return Result.success(data);
}
/**
* 审批订单
*
* @param params 参数说明:
* - orderNo: 订单号
* - status: 审批结果 (2=通过, 3=驳回)
* - rejectReason: 驳回原因 (驳回时必填)
* - adminRemark: 管理员备注 (可选)
*
* 注意: 最终订单状态根据订单类型确定
* - 充值订单: 审批通过->状态3(已完成), 审批驳回->状态4(已驳回)
* - 提现订单: 审批通过->状态2(已完成), 审批驳回->状态3(已驳回)
*/
@PostMapping("/order/approve")
public Result<Void> approveOrder(@RequestBody Map<String, Object> params) {
System.out.println("\n==================== 审批订单开始 ====================");
System.out.println("[AdminController] 接收到的完整参数: " + params);
String orderNo = (String) params.get("orderNo");
Integer status = (Integer) params.get("status");
String rejectReason = (String) params.get("rejectReason");
String adminRemark = (String) params.get("adminRemark");
System.out.println("[AdminController] 解析后的参数:");
System.out.println(" - orderNo: " + orderNo);
System.out.println(" - status: " + status);
System.out.println(" - rejectReason: " + rejectReason);
System.out.println(" - adminRemark: " + adminRemark);
if (orderNo == null || status == null) {
System.err.println("[AdminController] 参数校验失败: orderNo或status为空");
return Result.fail("参数错误");
}
if (status != 2 && status != 3) {
System.err.println("[AdminController] 状态参数错误: " + status);
return Result.fail("状态参数错误");
}
try {
System.out.println("[AdminController] 开始调用 fundService.approve()...");
fundService.approve(1L, "管理员", orderNo, status, rejectReason, adminRemark);
System.out.println("[AdminController] fundService.approve() 调用成功");
System.out.println("==================== 审批订单结束 ====================\n");
return Result.success(status == 2 ? "审批通过" : "已驳回", null);
} catch (Exception e) {
System.err.println("[AdminController] 审批异常: " + e.getMessage());
e.printStackTrace();
System.out.println("==================== 审批订单异常结束 ====================\n");
return Result.fail(e.getMessage());
}
}
/**
* 资金总览
*/
@GetMapping("/finance/overview")
public Result<Map<String, Object>> getFinanceOverview() {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
Map<String, Object> data = new HashMap<>();
// 累计充值
BigDecimal totalDeposit = orderFundMapper.sumCompletedDeposit();
data.put("totalDeposit", totalDeposit);
// 合并为一次查询获取充值总额、提现总额、待审批数
Map<String, Object> fundStats = orderFundMapper.sumFinanceOverview();
data.put("totalDeposit", fundStats.get("totalDeposit"));
data.put("totalWithdraw", fundStats.get("totalWithdraw"));
data.put("pendingCount", ((Number) fundStats.get("pendingCount")).intValue());
// 累计提现
BigDecimal totalWithdraw = orderFundMapper.sumCompletedWithdraw();
data.put("totalWithdraw", totalWithdraw);
// 在管资金
BigDecimal fundBalance = accountFundMapper.sumAllBalance();
data.put("fundBalance", fundBalance);
// 交易账户总值
BigDecimal tradeValue = accountFundMapper.sumAllTradeValue();
data.put("tradeValue", tradeValue != null ? tradeValue : BigDecimal.ZERO);
// 待审批数量
int pendingCount = orderFundMapper.countPending();
data.put("pendingCount", pendingCount);
// 用户总数
long userCount = userService.count();
data.put("userCount", userCount);
return Result.success(data);
}
/**
* 管理员列表
*/
@GetMapping("/admin/list")
public Result<List<Admin>> getAdminList() {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
List<Admin> admins = adminService.listAdmins();
// 清除密码字段
admins.forEach(a -> a.setPassword(null));
return Result.success(admins);
}
/**
* 创建管理员/财务
*/
@PostMapping("/admin/create")
public Result<Map<String, Object>> createAdmin(@RequestBody Map<String, Object> params) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
String username = (String) params.get("username");
String password = (String) params.get("password");
String nickname = (String) params.get("nickname");
Integer role = params.get("role") != null ? Integer.valueOf(params.get("role").toString()) : 2;
if (username == null || password == null) {
return Result.fail("用户名和密码不能为空");
}
if (role != 2 && role != 3) {
return Result.fail("角色参数错误,仅支持管理员(2)或财务(3)");
}
try {
Admin admin = adminService.createAdmin(username, password,
nickname != null ? nickname : username, role);
Map<String, Object> data = new HashMap<>();
data.put("id", admin.getId());
data.put("username", admin.getUsername());
data.put("nickname", admin.getNickname());
data.put("role", admin.getRole());
return Result.success("创建成功", data);
} catch (RuntimeException e) {
return Result.fail(e.getMessage());
}
}
/**
* 启用/禁用管理员
*/
@PostMapping("/admin/status")
public Result<Void> toggleAdminStatus(@RequestBody Map<String, Object> params) {
if (!UserContext.isSuperAdmin()) {
return Result.fail("无权限访问");
}
Long adminId = Long.valueOf(params.get("id").toString());
Integer status = (Integer) params.get("status");
try {
adminService.toggleAdminStatus(adminId, status);
return Result.success(status == 1 ? "已启用" : "已禁用", null);
} catch (RuntimeException e) {
return Result.fail(e.getMessage());
}
}
}

Some files were not shown because too many files have changed in this diff Show More