前后端基本架构和完全excel表的解析及统计图表的生成以及excel表的到出

This commit is contained in:
2026-03-19 01:51:34 +08:00
parent c23b93bb70
commit 2f630695ff
194 changed files with 23354 additions and 174 deletions

View File

@@ -0,0 +1,28 @@
id: selectItemWithEmptyValue
language: Tsx
files:
- src/**/*.tsx
rule:
kind: jsx_opening_element
all:
- has:
kind: identifier
regex: '^SelectItem$'
- has:
kind: jsx_attribute
all:
- has:
kind: property_identifier
regex: '^value$'
- any:
- has:
kind: string
regex: '^""$'
- has:
kind: jsx_expression
has:
kind: string
regex: '^""$'
message: "检测到 SelectItem 组件使用空字符串 value: $MATCH 这是错误用法, 运行时会报错, 请修改, 如果想实现全选建议使用all代替空字符串"
severity: error

39
frontend/.rules/check.sh Normal file
View File

@@ -0,0 +1,39 @@
#!/bin/bash
ast-grep scan -r .rules/SelectItem.yml
ast-grep scan -r .rules/contrast.yml
ast-grep scan -r .rules/supabase-google-sso.yml
ast-grep scan -r .rules/toast-hook.yml
ast-grep scan -r .rules/slot-nesting.yml
ast-grep scan -r .rules/require-button-interaction.yml
useauth_output=$(ast-grep scan -r .rules/useAuth.yml 2>/dev/null)
if [ -z "$useauth_output" ]; then
exit 0
fi
authprovider_output=$(ast-grep scan -r .rules/authProvider.yml 2>/dev/null)
if [ -n "$authprovider_output" ]; then
exit 0
fi
echo "=== ast-grep scan -r .rules/useAuth.yml output ==="
echo "$useauth_output"
echo ""
echo "=== ast-grep scan -r .rules/authProvider.yml output ==="
echo "$authprovider_output"
echo ""
echo "⚠️ Issue detected:"
echo "The code uses useAuth Hook but does not have AuthProvider component wrapping the components."
echo "Please ensure that components using useAuth are wrapped with AuthProvider to provide proper authentication context."
echo ""
echo "Suggested fixes:"
echo "1. Add AuthProvider wrapper in app.tsx or corresponding root component"
echo "2. Ensure all components using useAuth are within AuthProvider scope"

View File

@@ -0,0 +1,103 @@
id: button-outline-text-foreground-contrast
language: tsx
files:
- src/**/*.tsx
message: "Outline button with text-foreground class causes invisible text. The outline variant has a transparent background, making text-foreground color blend with the background and become unreadable. Use text-primary or another contrasting color instead."
rule:
kind: jsx_element
has:
kind: jsx_opening_element
all:
- has:
field: name
regex: "^Button$"
- has:
kind: jsx_attribute
all:
- has:
kind: property_identifier
regex: "^variant$"
- has:
kind: string
has:
kind: string_fragment
regex: "^outline$"
- has:
kind: jsx_attribute
all:
- has:
kind: property_identifier
regex: "^className$"
- has:
kind: string
has:
kind: string_fragment
regex: "(^|\\s)text-foreground(\\s|$)"
---
id: button-default-text-primary-contrast
language: tsx
files:
- src/**/*.tsx
message: "Default button with text-primary class causes poor contrast. The default variant has a primary-colored background, making text-primary color blend with the background and become hard to read. Remove the text-primary class or specify a different variant like 'outline' or 'ghost'."
rule:
kind: jsx_element
has:
kind: jsx_opening_element
all:
- has:
field: name
regex: "^Button$"
- has:
kind: jsx_attribute
all:
- has:
kind: property_identifier
regex: "^className$"
- has:
kind: string
has:
kind: string_fragment
regex: "(^|\\s)text-primary(\\s|$)"
- not:
has:
kind: jsx_attribute
has:
kind: property_identifier
regex: "^variant$"
---
id: button-outline-white-gray-contrast
language: tsx
files:
- src/**/*.tsx
message: "Outline button with white/gray text color has poor contrast. Remove the text color class and use the default button text color."
rule:
kind: jsx_element
has:
kind: jsx_opening_element
all:
- has:
field: name
regex: "^Button$"
- has:
kind: jsx_attribute
all:
- has:
kind: property_identifier
regex: "^variant$"
- has:
kind: string
has:
kind: string_fragment
regex: "^outline$"
- has:
kind: jsx_attribute
all:
- has:
kind: property_identifier
regex: "^className$"
- has:
kind: string
has:
kind: string_fragment
regex: "(^|\\s)text-(white|gray)(-[0-9]+)?(\\s|$)"

View File

@@ -0,0 +1,56 @@
id: require-button-interaction
language: Tsx
files:
- src/**/*.tsx
- src/**/*.jsx
rule:
kind: jsx_opening_element
all:
# 必须是 <Button> 组件
- has:
kind: identifier
regex: '^Button$'
# 没有 onClick
- not:
has:
kind: jsx_attribute
has:
kind: property_identifier
regex: '^onClick$'
# 没有 asChild
- not:
has:
kind: jsx_attribute
has:
kind: property_identifier
regex: '^asChild$'
# 没有 type="submit" 或 type="reset"
- not:
has:
kind: jsx_attribute
all:
- has:
kind: property_identifier
regex: '^type$'
- any:
- has:
kind: string
regex: '^"(submit|reset)"$'
- has:
kind: jsx_expression
has:
kind: string
regex: '^"(submit|reset)"$'
# 不在 *Trigger 组件内部(如 DialogTrigger、SheetTrigger
- not:
inside:
stopBy: end
kind: jsx_element
has:
kind: jsx_opening_element
has:
kind: identifier
regex: 'Trigger$'
message: '<Button> 必须是可点击的:请添加 onClick、type="submit"、type="reset"、asChild 属性,或将其包裹在 *Trigger 组件中'
severity: error

View File

@@ -0,0 +1,52 @@
---
id: radix-trigger-formcontrol-nesting
language: tsx
files:
- src/**/*.tsx
message: |
❌ 检测到危险的 Slot 嵌套Radix UI Trigger (asChild) 内包裹 FormControl
问题代码:
<PopoverTrigger asChild>
<FormControl> ← 会导致点击事件失效
<Button>...</Button>
</FormControl>
</PopoverTrigger>
正确写法:
<PopoverTrigger asChild>
<Button>...</Button> ← 直接使用 Button
</PopoverTrigger>
原因FormControl 和 Trigger 都使用 Radix UI 的 Slot 机制,双层嵌套会导致:
- ref 传递链断裂
- 点击事件丢失
- 内部组件无法交互
FormControl 只应该用于原生表单控件Input, Textarea, Select不要用于触发器按钮。
severity: error
rule:
kind: jsx_element
all:
# 开始标签需要满足的条件
- has:
kind: jsx_opening_element
all:
# 匹配所有 Radix UI 的 Trigger 组件
- has:
field: name
regex: "^(Popover|Dialog|DropdownMenu|AlertDialog|HoverCard|Menubar|NavigationMenu|ContextMenu|Tooltip)Trigger$"
# 必须有 asChild 属性
- has:
kind: jsx_attribute
has:
kind: property_identifier
regex: "^asChild$"
# 直接子元素包含 FormControl
- has:
kind: jsx_element
has:
kind: jsx_opening_element
has:
field: name
regex: "^FormControl$"

View File

@@ -0,0 +1,20 @@
id: supabase-google-sso
language: Tsx
files:
- src/**/*.tsx
rule:
pattern: |
$AUTH.signInWithOAuth({ provider: 'google', $$$ })
message: |
Replace `signInWithOAuth` with `signInWithSSO` for Google authentication (Supabase).
Refactor to:
```typescript
const { data, error } = await supabase.auth.signInWithSSO({
domain: 'miaoda-gg.com',
options: { redirectTo: window.location.origin },
});
if (data?.url) window.open(data.url, '_self');
```
Ensure `window.open` uses `_self` target.
severity: warning

View File

@@ -0,0 +1,10 @@
#!/bin/bash
OUTPUT=$(npx vite build --minify false --logLevel error --outDir /workspace/.dist 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
echo "$OUTPUT"
fi
exit $EXIT_CODE

View File

@@ -0,0 +1,11 @@
id: use-toast-import
message: Use 'import { toast } from "sonner"' instead of "@/hooks/use-toast"
severity: error
language: Tsx
note: |
The new shadcn/ui pattern uses sonner for toast notifications.
Replace: import { toast } from "@/hooks/use-toast"
With: import { toast } from "sonner"
rule:
pattern: import { $$$IMPORTS } from "@/hooks/use-toast"