From 498cd8a49752aa10f9a1a8fa366f8c1ee22cd91a Mon Sep 17 00:00:00 2001 From: gitee-bot Date: Mon, 15 Sep 2025 08:51:34 +0000 Subject: [PATCH] Add README.md --- README.en.md | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 554 insertions(+) create mode 100644 README.en.md create mode 100644 README.md diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..072e6c3 --- /dev/null +++ b/README.en.md @@ -0,0 +1,277 @@ +# Cashier System Frontend (Angular) Product Management Module Architecture Design + +## Overview + +This design document describes the architecture design of the product management module for the cashier system frontend (based on Angular). This module is responsible for operations such as displaying, creating, editing, and deleting products, providing users with an intuitive product management interface. + +## Module Structure + +The product management module consists of the following core components: + +- **Product Interface**: Defines the data model of a product. +- **ProductService**: Provides functions for retrieving, creating, updating, and deleting product data. +- **ProductListComponent**: Displays a list of products and provides navigation to detail and edit pages. +- **ProductFormComponent**: Provides a form interface for creating and editing products. +- **ProductDetailComponent**: Displays detailed information of a single product. +- **Angular Routing Configuration**: Defines routing rules for the product module. + +## Detailed Design + +### 3.1. Product Interface (`product.model.ts`) + +```typescript +export interface Product { + id: number; + name: string; + description: string; + price: number; + category: string; + status: 'active' | 'inactive'; + inventoryCount: number; +} +``` + +### 3.2. ProductService (`product.service.ts`) + +```typescript +@Injectable({ + providedIn: 'root' +}) +export class ProductService { + private apiUrl = '/api/products'; + + constructor(private http: HttpClient) {} + + getProducts(): Observable { + return this.http.get(this.apiUrl); + } + + getProductById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + createProduct(product: Product): Observable { + return this.http.post(this.apiUrl, product); + } + + updateProduct(id: number, product: Product): Observable { + return this.http.put(`${this.apiUrl}/${id}`, product); + } + + deleteProduct(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } +} +``` + +### 3.3. ProductListComponent (`product-list/product-list.component.ts`) + +```typescript +@Component({ + selector: 'app-product-list', + templateUrl: './product-list.component.html', + styleUrls: ['./product-list.component.scss'] +}) +export class ProductListComponent implements OnInit { + products: Product[] = []; + loading = false; + errorMessage: string | null = null; + + constructor(private productService: ProductService, private router: Router) {} + + ngOnInit(): void { + this.loadProducts(); + } + + loadProducts(): void { + this.loading = true; + this.productService.getProducts() + .pipe(finalize(() => this.loading = false)) + .subscribe({ + next: (products) => { + this.products = products; + }, + error: (err) => { + this.errorMessage = 'Failed to load products'; + console.error(err); + } + }); + } + + viewProductDetails(id: number): void { + this.router.navigate(['/products', id]); + } + + editProduct(id: number): void { + this.router.navigate(['/products', id, 'edit']); + } + + deleteProduct(id: number): void { + if (confirm('Are you sure you want to delete this product?')) { + this.productService.deleteProduct(id) + .subscribe({ + next: () => { + this.products = this.products.filter(p => p.id !== id); + }, + error: (err) => { + this.errorMessage = 'Failed to delete product'; + console.error(err); + } + }); + } + } +} +``` + +### 3.4. ProductFormComponent (`product-form/product-form.component.ts`) + +```typescript +@Component({ + selector: 'app-product-form', + templateUrl: './product-form.component.html', + styleUrls: ['./product-form.component.scss'] +}) +export class ProductFormComponent implements OnInit { + productForm: FormGroup; + isEditMode = false; + productId: number | null = null; + + constructor( + private fb: FormBuilder, + private productService: ProductService, + private route: ActivatedRoute, + private router: Router + ) { + this.productForm = this.fb.group({ + name: ['', Validators.required], + description: [''], + price: [0, [Validators.required, Validators.min(0)]], + category: ['', Validators.required], + status: ['active', Validators.required], + inventoryCount: [0, [Validators.required, Validators.min(0)]] + }); + } + + ngOnInit(): void { + this.route.params.subscribe(params => { + if (params['id']) { + this.isEditMode = true; + this.productId = +params['id']; + this.loadProduct(this.productId); + } + }); + } + + loadProduct(id: number): void { + this.productService.getProductById(id) + .subscribe({ + next: (product) => { + this.productForm.patchValue(product); + }, + error: (err) => { + console.error('Failed to load product', err); + } + }); + } + + onSubmit(): void { + if (this.productForm.valid) { + const product = this.productForm.value; + if (this.isEditMode && this.productId) { + this.productService.updateProduct(this.productId, product) + .subscribe({ + next: () => { + this.router.navigate(['/products']); + }, + error: (err) => { + console.error('Failed to update product', err); + } + }); + } else { + this.productService.createProduct(product) + .subscribe({ + next: () => { + this.router.navigate(['/products']); + }, + error: (err) => { + console.error('Failed to create product', err); + } + }); + } + } + } + + onCancel(): void { + this.router.navigate(['/products']); + } +} +``` + +### 3.5. ProductDetailComponent (`product-detail/product-detail.component.ts`) + +```typescript +@Component({ + selector: 'app-product-detail', + templateUrl: './product-detail.component.html', + styleUrls: ['./product-detail.component.scss'] +}) +export class ProductDetailComponent implements OnInit { + product: Product | null = null; + loading = false; + errorMessage: string | null = null; + + constructor( + private productService: ProductService, + private route: ActivatedRoute + ) {} + + ngOnInit(): void { + const productId = +this.route.snapshot.paramMap.get('id')!; + this.loadProduct(productId); + } + + loadProduct(id: number): void { + this.loading = true; + this.productService.getProductById(id) + .pipe(finalize(() => this.loading = false)) + .subscribe({ + next: (product) => { + this.product = product; + }, + error: (err) => { + this.errorMessage = 'Failed to load product details'; + console.error(err); + } + }); + } +} +``` + +### 3.6. Angular Routing Configuration (`products.routes.ts`) + +```typescript +const routes: Routes = [ + { + path: 'products', + component: ProductListComponent + }, + { + path: 'products/:id', + component: ProductDetailComponent + }, + { + path: 'products/:id/edit', + component: ProductFormComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class ProductsRoutingModule {} +``` + +## Summary + +This design document details the architecture design of the product management module for the cashier system frontend (Angular). Through clear module division and component design, it implements the basic CRUD (Create, Read, Update, Delete) functionality for products and provides a good user experience. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..41abc05 --- /dev/null +++ b/README.md @@ -0,0 +1,277 @@ +# 收银台系统前端(Angular)商品管理模块架构设计 + +## 概述 + +本设计文档描述了收银台系统前端(基于 Angular)的商品管理模块架构设计。该模块负责商品的展示、创建、编辑和删除等操作,为用户提供直观的商品管理界面。 + +## 模块结构 + +商品管理模块由以下几个核心部分组成: + +- **Product 接口**:定义商品的数据模型。 +- **ProductService**:提供商品数据的获取、创建、更新和删除功能。 +- **ProductListComponent**:展示商品列表,并提供导航至详情和编辑页面的功能。 +- **ProductFormComponent**:提供创建和编辑商品的表单界面。 +- **ProductDetailComponent**:展示单个商品的详细信息。 +- **Angular 路由配置**:定义商品模块的路由规则。 + +## 详细设计 + +### 3.1. Product 接口 (`product.model.ts`) + +```typescript +export interface Product { + id: number; + name: string; + description: string; + price: number; + category: string; + status: 'active' | 'inactive'; + inventoryCount: number; +} +``` + +### 3.2. ProductService (`product.service.ts`) + +```typescript +@Injectable({ + providedIn: 'root' +}) +export class ProductService { + private apiUrl = '/api/products'; + + constructor(private http: HttpClient) {} + + getProducts(): Observable { + return this.http.get(this.apiUrl); + } + + getProductById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + createProduct(product: Product): Observable { + return this.http.post(this.apiUrl, product); + } + + updateProduct(id: number, product: Product): Observable { + return this.http.put(`${this.apiUrl}/${id}`, product); + } + + deleteProduct(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } +} +``` + +### 3.3. ProductListComponent (`product-list/product-list.component.ts`) + +```typescript +@Component({ + selector: 'app-product-list', + templateUrl: './product-list.component.html', + styleUrls: ['./product-list.component.scss'] +}) +export class ProductListComponent implements OnInit { + products: Product[] = []; + loading = false; + errorMessage: string | null = null; + + constructor(private productService: ProductService, private router: Router) {} + + ngOnInit(): void { + this.loadProducts(); + } + + loadProducts(): void { + this.loading = true; + this.productService.getProducts() + .pipe(finalize(() => this.loading = false)) + .subscribe({ + next: (products) => { + this.products = products; + }, + error: (err) => { + this.errorMessage = 'Failed to load products'; + console.error(err); + } + }); + } + + viewProductDetails(id: number): void { + this.router.navigate(['/products', id]); + } + + editProduct(id: number): void { + this.router.navigate(['/products', id, 'edit']); + } + + deleteProduct(id: number): void { + if (confirm('Are you sure you want to delete this product?')) { + this.productService.deleteProduct(id) + .subscribe({ + next: () => { + this.products = this.products.filter(p => p.id !== id); + }, + error: (err) => { + this.errorMessage = 'Failed to delete product'; + console.error(err); + } + }); + } + } +} +``` + +### 3.4. ProductFormComponent (`product-form/product-form.component.ts`) + +```typescript +@Component({ + selector: 'app-product-form', + templateUrl: './product-form.component.html', + styleUrls: ['./product-form.component.scss'] +}) +export class ProductFormComponent implements OnInit { + productForm: FormGroup; + isEditMode = false; + productId: number | null = null; + + constructor( + private fb: FormBuilder, + private productService: ProductService, + private route: ActivatedRoute, + private router: Router + ) { + this.productForm = this.fb.group({ + name: ['', Validators.required], + description: [''], + price: [0, [Validators.required, Validators.min(0)]], + category: ['', Validators.required], + status: ['active', Validators.required], + inventoryCount: [0, [Validators.required, Validators.min(0)]] + }); + } + + ngOnInit(): void { + this.route.params.subscribe(params => { + if (params['id']) { + this.isEditMode = true; + this.productId = +params['id']; + this.loadProduct(this.productId); + } + }); + } + + loadProduct(id: number): void { + this.productService.getProductById(id) + .subscribe({ + next: (product) => { + this.productForm.patchValue(product); + }, + error: (err) => { + console.error('Failed to load product', err); + } + }); + } + + onSubmit(): void { + if (this.productForm.valid) { + const product = this.productForm.value; + if (this.isEditMode && this.productId) { + this.productService.updateProduct(this.productId, product) + .subscribe({ + next: () => { + this.router.navigate(['/products']); + }, + error: (err) => { + console.error('Failed to update product', err); + } + }); + } else { + this.productService.createProduct(product) + .subscribe({ + next: () => { + this.router.navigate(['/products']); + }, + error: (err) => { + console.error('Failed to create product', err); + } + }); + } + } + } + + onCancel(): void { + this.router.navigate(['/products']); + } +} +``` + +### 3.5. ProductDetailComponent (`product-detail/product-detail.component.ts`) + +```typescript +@Component({ + selector: 'app-product-detail', + templateUrl: './product-detail.component.html', + styleUrls: ['./product-detail.component.scss'] +}) +export class ProductDetailComponent implements OnInit { + product: Product | null = null; + loading = false; + errorMessage: string | null = null; + + constructor( + private productService: ProductService, + private route: ActivatedRoute + ) {} + + ngOnInit(): void { + const productId = +this.route.snapshot.paramMap.get('id')!; + this.loadProduct(productId); + } + + loadProduct(id: number): void { + this.loading = true; + this.productService.getProductById(id) + .pipe(finalize(() => this.loading = false)) + .subscribe({ + next: (product) => { + this.product = product; + }, + error: (err) => { + this.errorMessage = 'Failed to load product details'; + console.error(err); + } + }); + } +} +``` + +### 3.6. Angular 路由配置 (`products.routes.ts`) + +```typescript +const routes: Routes = [ + { + path: 'products', + component: ProductListComponent + }, + { + path: 'products/:id', + component: ProductDetailComponent + }, + { + path: 'products/:id/edit', + component: ProductFormComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class ProductsRoutingModule {} +``` + +## 总结 + +本设计文档详细描述了收银台系统前端(Angular)商品管理模块的架构设计。通过清晰的模块划分和组件设计,实现了商品的增删改查功能,并提供了良好的用户体验。 \ No newline at end of file -- Gitee