重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
angular-primeng by seikaikyo/dash-skills
npx skills add https://github.com/seikaikyo/dash-skills --skill angular-primengsrc/app/
├── core/ # 核心模块(单例服务)
│ ├── auth/ # 认证相关
│ ├── guards/ # 路由守卫
│ ├── interceptors/ # HTTP 拦截器
│ ├── models/ # 数据模型
│ └── services/ # 共享服务
├── shared/ # 共享模块
│ ├── components/ # 可复用组件
│ ├── directives/ # 自定义指令
│ ├── pipes/ # 数据管道
│ └── utils/ # 工具函数
├── features/ # 功能模块
│ ├── dashboard/
│ ├── production/
│ └── settings/
└── layout/ # 布局模块
import { ApplicationConfig } from '@angular/core';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { providePrimeNG } from 'primeng/config';
import Aura from '@primeng/themes/aura';
export const appConfig: ApplicationConfig = {
providers: [
provideAnimationsAsync(),
providePrimeNG({
theme: {
preset: Aura,
options: {
darkModeSelector: '.dark-mode',
cssLayer: {
name: 'primeng',
order: 'tailwind-base, primeng, tailwind-utilities'
}
}
},
ripple: true
})
]
};
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 用途 | 组件 | 示例 |
|---|---|---|
| 表单/详情侧边栏 | <p-drawer> | 编辑工单、新增客户 |
| 确认对话框 | <p-dialog> | 删除确认、警告消息 |
| 数据表格 | <p-table> | 工单列表、报表 |
| 按钮 | <p-button> | 所有按钮操作 |
| 文本输入 | <input pInputText> | 搭配 ngModel |
| 下拉菜单 | <p-select> | 状态选择、分类 |
| 日期选择 | <p-datepicker> | 日期范围筛选 |
| 标签/徽章 | <p-tag> | 状态标示 |
| Toast 通知 | <p-toast> | 操作反馈 |
| 加载遮罩 | <p-blockui> | 异步操作 |
// 推荐:使用 Signals
import { signal, computed, effect } from '@angular/core';
@Component({...})
export class WorkOrderListComponent {
// 状态
workOrders = signal<WorkOrder[]>([]);
selectedId = signal<string | null>(null);
isLoading = signal(false);
// 计算属性
selectedOrder = computed(() =>
this.workOrders().find(o => o.id === this.selectedId())
);
pendingCount = computed(() =>
this.workOrders().filter(o => o.status === 'pending').length
);
// 副作用
constructor() {
effect(() => {
console.log('选中的工单:', this.selectedOrder());
});
}
}
@Injectable({ providedIn: 'root' })
export class WorkOrderService {
private apiUrl = environment.apiUrl + '/work-orders';
constructor(private http: HttpClient) {}
// 列表查询(支持筛选)
getList(params?: WorkOrderQueryParams): Observable<ApiResponse<WorkOrder[]>> {
return this.http.get<ApiResponse<WorkOrder[]>>(this.apiUrl, { params });
}
// 单笔查询
getById(id: string): Observable<ApiResponse<WorkOrder>> {
return this.http.get<ApiResponse<WorkOrder>>(`${this.apiUrl}/${id}`);
}
// 新增
create(data: CreateWorkOrderDto): Observable<ApiResponse<WorkOrder>> {
return this.http.post<ApiResponse<WorkOrder>>(this.apiUrl, data);
}
// 更新
update(id: string, data: UpdateWorkOrderDto): Observable<ApiResponse<WorkOrder>> {
return this.http.put<ApiResponse<WorkOrder>>(`${this.apiUrl}/${id}`, data);
}
// 删除
delete(id: string): Observable<ApiResponse<void>> {
return this.http.delete<ApiResponse<void>>(`${this.apiUrl}/${id}`);
}
}
// 统一响应格式
interface ApiResponse<T> {
success: boolean;
data?: T;
error?: {
code: string;
message: string;
};
}
// 分页响应
interface PaginatedResponse<T> extends ApiResponse<T[]> {
pagination: {
total: number;
page: number;
limit: number;
};
}
// 推荐:Reactive Forms + PrimeNG
@Component({
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div class="field">
<label for="orderNumber">工单编号</label>
<input pInputText id="orderNumber" formControlName="orderNumber" />
<small *ngIf="form.get('orderNumber')?.errors?.['required']" class="p-error">
必填字段
</small>
</div>
<div class="field">
<label for="customer">客户</label>
<p-select
id="customer"
formControlName="customerId"
[options]="customers()"
optionLabel="name"
optionValue="id"
placeholder="选择客户"
/>
</div>
<div class="field">
<label for="dueDate">交期</label>
<p-datepicker
id="dueDate"
formControlName="dueDate"
dateFormat="yy-mm-dd"
/>
</div>
<p-button type="submit" label="保存" [loading]="isSubmitting()" />
</form>
`
})
export class WorkOrderFormComponent {
form = new FormGroup({
orderNumber: new FormControl('', Validators.required),
customerId: new FormControl('', Validators.required),
dueDate: new FormControl<Date | null>(null)
});
customers = signal<Customer[]>([]);
isSubmitting = signal(false);
}
@Component({
template: `
<p-table
[value]="workOrders()"
[paginator]="true"
[rows]="20"
[rowsPerPageOptions]="[10, 20, 50]"
[loading]="isLoading()"
[globalFilterFields]="['orderNumber', 'customerName']"
styleClass="p-datatable-sm"
>
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="orderNumber">
工单编号 <p-sortIcon field="orderNumber" />
</th>
<th pSortableColumn="status">状态</th>
<th>操作</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-order>
<tr>
<td>{{ order.orderNumber }}</td>
<td>
<p-tag [value]="order.status" [severity]="getStatusSeverity(order.status)" />
</td>
<td>
<p-button icon="pi pi-pencil" [text]="true" (click)="edit(order)" />
<p-button icon="pi pi-trash" [text]="true" severity="danger" (click)="confirmDelete(order)" />
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="3" class="text-center">无数据</td>
</tr>
</ng-template>
</p-table>
`
})
export class WorkOrderTableComponent {
workOrders = signal<WorkOrder[]>([]);
isLoading = signal(false);
getStatusSeverity(status: string): 'success' | 'info' | 'warn' | 'danger' {
const map: Record<string, 'success' | 'info' | 'warn' | 'danger'> = {
completed: 'success',
in_progress: 'info',
pending: 'warn',
cancelled: 'danger'
};
return map[status] || 'info';
}
}
@Component({
template: `
<p-drawer
[(visible)]="drawerVisible"
[header]="isEditMode() ? '编辑工单' : '新增工单'"
position="right"
[style]="{ width: '500px' }"
(onHide)="onClose()"
>
<app-work-order-form
[workOrder]="selectedOrder()"
(save)="onSave($event)"
(cancel)="drawerVisible = false"
/>
</p-drawer>
`
})
export class WorkOrderListComponent {
drawerVisible = false;
selectedOrder = signal<WorkOrder | null>(null);
isEditMode = computed(() => this.selectedOrder() !== null);
openCreate() {
this.selectedOrder.set(null);
this.drawerVisible = true;
}
openEdit(order: WorkOrder) {
this.selectedOrder.set(order);
this.drawerVisible = true;
}
}
// HTTP 拦截器
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private messageService: MessageService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
let message = '发生错误,请稍后再试';
if (error.status === 401) {
message = '请重新登录';
} else if (error.status === 403) {
message = '权限不足';
} else if (error.status === 404) {
message = '数据不存在';
} else if (error.status === 503) {
message = '服务暂时无法使用';
} else if (error.error?.error?.message) {
message = error.error.error.message;
}
this.messageService.add({
severity: 'error',
summary: '错误',
detail: message
});
return throwError(() => error);
})
);
}
}
<p-scroller>Weekly Installs
51
Repository
GitHub Stars
1
First Seen
Feb 6, 2026
Security Audits
Installed on
opencode50
github-copilot49
gemini-cli49
codex48
amp47
kimi-cli47
json-render生成式UI框架:AI驱动、多平台JSON渲染,安全构建动态界面
648 周安装