1
0
forked from erp-dev/erp

feat: running on docker fully, and added rabbitmq/worker container

This commit is contained in:
2025-11-25 15:56:13 +08:00
parent cd6a2370fc
commit d90917e764
34 changed files with 2474 additions and 74 deletions

741
api_backend.md Normal file
View File

@@ -0,0 +1,741 @@
# API Backend Documentation
This document provides comprehensive documentation for all API endpoints in the `/api/backend/` namespace, with special focus on the Customers API which includes employee visibility control features.
## Table of Contents
1. [Authentication](#authentication)
2. [Common Response Format](#common-response-format)
3. [API Endpoints](#api-endpoints)
- [Quick Inputs](#quick-inputs)
- [Products](#products)
- [Warehouses](#warehouses)
- [Product Categories](#product-categories)
- [Suppliers](#suppliers)
- [Employees](#employees)
- [Employee Types](#employee-types)
- [Customers](#customers)
- [Vehicle Types](#vehicle-types)
- [Bank Accounts](#bank-accounts)
- [Device Info](#device-info)
- [Vehicle Transport Records](#vehicle-transport-records)
- [User Profiles](#user-profiles)
4. [Error Handling](#error-handling)
5. [Pagination](#pagination)
## Authentication
All API endpoints in the `/api/backend/` namespace require authentication. Requests must include a valid authentication token or session.
```http
Authorization: Bearer <your_token>
```
Or use session cookies for web-based applications.
## Common Response Format
Most endpoints follow a standard response format:
### Success Response (200 OK, 201 Created)
```json
{
"id": 1,
"field1": "value1",
"field2": "value2",
"created_at": "2025-11-24T10:00:00Z",
"updated_at": "2025-11-24T10:00:00Z"
}
```
### List Response (200 OK)
```json
{
"count": 100,
"next": "http://example.com/api/backend/endpoint/?page=2",
"previous": null,
"results": [
{
"id": 1,
"field1": "value1",
...
}
]
}
```
### Error Response (400, 401, 403, 404, 500)
```json
{
"field_name": ["Error message for this field"],
"non_field_errors": ["General error message"]
}
```
## API Endpoints
### Quick Inputs
**Base URL**: `/api/backend/quick-inputs/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/quick-inputs/` | List | Retrieve all quick input items |
| GET | `/api/backend/quick-inputs/{id}/` | Retrieve | Get a specific quick input item |
| POST | `/api/backend/quick-inputs/` | Create | Create a new quick input item |
| PUT | `/api/backend/quick-inputs/{id}/` | Update | Update a quick input item |
| PATCH | `/api/backend/quick-inputs/{id}/` | Partial Update | Partially update a quick input item |
| DELETE | `/api/backend/quick-inputs/{id}/` | Delete | Delete a quick input item |
**Query Parameters**:
- `group` (optional): Filter items by group
**Request/Response Fields**:
- `id`: Quick input ID
- `name`: Name of the quick input
- `value`: Value of the quick input
- `group`: Group category for the quick input
**Example Response**:
```json
{
"id": 1,
"name": "常用尺寸",
"value": "1.5米",
"group": "尺寸"
}
```
### Products
**Base URL**: `/api/backend/products/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/products/` | List | Retrieve all products |
| GET | `/api/backend/products/{id}/` | Retrieve | Get a specific product |
| POST | `/api/backend/products/` | Create | Create a new product |
| PUT | `/api/backend/products/{id}/` | Update | Update a product |
| PATCH | `/api/backend/products/{id}/` | Partial Update | Partially update a product |
| DELETE | `/api/backend/products/{id}/` | Delete | Delete a product |
**Request/Response Fields**:
- `id`: Product ID
- `name`: Product name
- `category`: Product category (nested object)
- `price`: Product price
- `unit`: Unit of measurement
- `image`: Product image file
- `image_url`: URL of product image (generated)
- `description`: Product description
**Example Response**:
```json
{
"id": 1,
"name": "纯棉印花布",
"price": "25.50",
"unit": 1,
"description": "高品质纯棉印花布料",
"image": "/media/products/cotton_fabric.jpg",
"image_url": "http://example.com/media/products/cotton_fabric.jpg",
"category": {
"id": 3,
"name": "印花布"
},
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Warehouses
**Base URL**: `/api/backend/warehouses/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/warehouses/` | List | Retrieve all warehouses |
| GET | `/api/backend/warehouses/{id}/` | Retrieve | Get a specific warehouse |
| POST | `/api/backend/warehouses/` | Create | Create a new warehouse |
| PUT | `/api/backend/warehouses/{id}/` | Update | Update a warehouse |
| PATCH | `/api/backend/warehouses/{id}/` | Partial Update | Partially update a warehouse |
| DELETE | `/api/backend/warehouses/{id}/` | Delete | Delete a warehouse |
**Request/Response Fields**:
- `id`: Warehouse ID
- `name`: Warehouse name
- `location`: Warehouse location
- `type`: Warehouse type (1: Whole, 2: Scattered)
**Example Response**:
```json
{
"id": 1,
"name": "主仓库",
"location": "园区A区1号",
"type": 1,
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Product Categories
**Base URL**: `/api/backend/product-categories/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/product-categories/` | List | Retrieve all product categories |
| GET | `/api/backend/product-categories/{id}/` | Retrieve | Get a specific product category |
| POST | `/api/backend/product-categories/` | Create | Create a new product category |
| PUT | `/api/backend/product-categories/{id}/` | Update | Update a product category |
| PATCH | `/api/backend/product-categories/{id}/` | Partial Update | Partially update a product category |
| DELETE | `/api/backend/product-categories/{id}/` | Delete | Delete a product category |
**Request/Response Fields**:
- `id`: Category ID
- `name`: Category name
- `description`: Category description
**Example Response**:
```json
{
"id": 1,
"name": "印花布",
"description": "各类印花布料",
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Suppliers
**Base URL**: `/api/backend/suppliers/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/suppliers/` | List | Retrieve all suppliers |
| GET | `/api/backend/suppliers/{id}/` | Retrieve | Get a specific supplier |
| POST | `/api/backend/suppliers/` | Create | Create a new supplier |
| PUT | `/api/backend/suppliers/{id}/` | Update | Update a supplier |
| PATCH | `/api/backend/suppliers/{id}/` | Partial Update | Partially update a supplier |
| DELETE | `/api/backend/suppliers/{id}/` | Delete | Delete a supplier |
**Request/Response Fields**:
- `id`: Supplier ID
- `name`: Supplier name
- `contact`: Contact person
- `mobile`: Mobile phone number
- `email`: Email address
- `address`: Physical address
- `description`: Additional description
**Example Response**:
```json
{
"id": 1,
"name": "华美纺织原料厂",
"contact": "张经理",
"mobile": "13800138001",
"email": "zhang@huamei.com",
"address": "广州市天河区科技园",
"description": "长期合作的优质原料供应商",
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Employees
**Base URL**: `/api/backend/employees/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/employees/` | List | Retrieve all employees |
| GET | `/api/backend/employees/{id}/` | Retrieve | Get a specific employee |
| POST | `/api/backend/employees/` | Create | Create a new employee |
| PUT | `/api/backend/employees/{id}/` | Update | Update an employee |
| PATCH | `/api/backend/employees/{id}/` | Partial Update | Partially update an employee |
| DELETE | `/api/backend/employees/{id}/` | Delete | Delete an employee |
**Request/Response Fields**:
- `id`: Employee ID
- `name`: Employee name
- `position`: Employee position (EmployeeType object)
- `job_type`: Job type (read-only string derived from position)
- `mobile`: Mobile phone number
- `status`: Employee status
- `sys_user`: Associated Django User ID (nullable)
**Example Response**:
```json
{
"id": 1,
"name": "张三",
"position": {
"id": 2,
"title": "打纸工",
"description": "负责打纸工作",
"merchant": 1
},
"job_type": "打纸工",
"mobile": "13800138000",
"status": "在职",
"sys_user": 5,
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Employee Types
**Base URL**: `/api/backend/employee-types/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/employee-types/` | List | Retrieve all employee types |
| GET | `/api/backend/employee-types/{id}/` | Retrieve | Get a specific employee type |
| POST | `/api/backend/employee-types/` | Create | Create a new employee type |
| PUT | `/api/backend/employee-types/{id}/` | Update | Update an employee type |
| PATCH | `/api/backend/employee-types/{id}/` | Partial Update | Partially update an employee type |
| DELETE | `/api/backend/employee-types/{id}/` | Delete | Delete an employee type |
**Request/Response Fields**:
- `id`: Employee type ID
- `title`: Type title
- `description`: Type description
**Example Response**:
```json
{
"id": 1,
"title": "打纸工",
"description": "负责打纸工作",
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Customers
**Base URL**: `/api/backend/customers/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/customers/` | List | Retrieve customers visible to the current employee |
| GET | `/api/backend/customers/{id}/` | Retrieve | Get a specific customer (if visible to current employee) |
| POST | `/api/backend/customers/` | Create | Create a new customer |
| PUT | `/api/backend/customers/{id}/` | Update | Update a customer (if visible to current employee) |
| PATCH | `/api/backend/customers/{id}/` | Partial Update | Partially update a customer (if visible to current employee) |
| DELETE | `/api/backend/customers/{id}/` | Delete | Delete a customer (if visible to current employee) |
#### Customer Visibility System
The Customers API implements a visibility control system that restricts which customers are accessible to each employee. This system works as follows:
**Visibility Rules**:
1. A customer is visible to an employee if:
- The employee created the customer, OR
- The employee is explicitly added to the customer's `visible_employees` list, OR
- The employee is a superuser or has `basic_info.view_all_customers` permission
2. When listing customers, the API automatically filters to only show customers visible to the current employee.
3. When accessing a specific customer (GET, PUT, PATCH, DELETE), the API checks if the customer is visible to the current employee. If not, a 404 Not Found response is returned.
**Request/Response Fields**:
- `id`: Customer ID
- `name`: Customer name
- `mobile`: Mobile phone number
- `email`: Email address
- `contact`: Contact person
- `area`: Geographic area
- `description`: Additional description
- `visible_employees`: List of employee IDs who can view this customer
- `created_by`: ID of the employee who created this customer (auto-set on creation)
**Creating a Customer (POST)**:
```json
{
"name": "Acme Corporation",
"mobile": "13800138000",
"email": "contact@acme.com",
"contact": "John Doe",
"area": "Beijing",
"description": "Regular wholesale customer",
"visible_employees": [1, 2, 3] // Optional: employees who can view this customer
}
```
**Updating a Customer (PUT/PATCH)**:
When updating a customer, the same visibility rules apply:
- The employee must be able to see the customer to update it
- The `visible_employees` field can be updated to add or remove access for other employees
```json
{
"name": "Updated Customer Name",
"visible_employees": [1, 4, 5] // Updated list of employees who can view this customer
}
```
**Example Response**:
```json
{
"id": 1,
"name": "北京服装批发公司",
"mobile": "13800138000",
"email": "beijing@clothing.com",
"contact": "李经理",
"area": "北京朝阳区",
"description": "长期合作的服装批发客户",
"visible_employees": [1, 3, 5],
"created_by": 1,
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
**Security Note**: Customer visibility is enforced at the API level. Attempts to access a customer that isn't visible to the current employee will result in a 404 Not Found response, regardless of whether the customer actually exists in the database.
#### Customer Visibility System
The Customers API implements a visibility control system that restricts which customers are accessible to each employee. This system works as follows:
**Visibility Rules**:
1. A customer is visible to an employee if:
- The employee created the customer, OR
- The employee is explicitly added to the customer's `visible_employees` list, OR
- The employee is a superuser or has `basic_info.view_all_customers` permission
2. When listing customers, the API automatically filters to only show customers visible to the current employee.
3. When accessing a specific customer (GET, PUT, PATCH, DELETE), the API checks if the customer is visible to the current employee. If not, a 404 Not Found response is returned.
**Request/Response Fields**:
- `id`: Customer ID
- `name`: Customer name
- `mobile`: Mobile phone number
- `email`: Email address
- `contact`: Contact person
- `area`: Geographic area
- `description`: Additional description
- `visible_employees`: List of employee IDs who can view this customer
- `created_by`: ID of the employee who created this customer (auto-set on creation)
**Creating a Customer (POST)**:
```json
{
"name": "Acme Corporation",
"mobile": "13800138000",
"email": "contact@acme.com",
"contact": "John Doe",
"area": "Beijing",
"description": "Regular wholesale customer",
"visible_employees": [1, 2, 3] // Optional: employees who can view this customer
}
```
**Updating a Customer (PUT/PATCH)**:
When updating a customer, the same visibility rules apply:
- The employee must be able to see the customer to update it
- The `visible_employees` field can be updated to add or remove access for other employees
```json
{
"name": "Updated Customer Name",
"visible_employees": [1, 4, 5] // Updated list of employees who can view this customer
}
```
**Security Note**: Customer visibility is enforced at the API level. Attempts to access a customer that isn't visible to the current employee will result in a 404 Not Found response, regardless of whether the customer actually exists in the database.
### Vehicle Types
**Base URL**: `/api/backend/vehicle-types/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/vehicle-types/` | List | Retrieve all vehicle types |
| GET | `/api/backend/vehicle-types/{id}/` | Retrieve | Get a specific vehicle type |
| POST | `/api/backend/vehicle-types/` | Create | Create a new vehicle type |
| PUT | `/api/backend/vehicle-types/{id}/` | Update | Update a vehicle type |
| PATCH | `/api/backend/vehicle-types/{id}/` | Partial Update | Partially update a vehicle type |
| DELETE | `/api/backend/vehicle-types/{id}/` | Delete | Delete a vehicle type |
**Request/Response Fields**:
- `id`: Vehicle type ID
- `name`: Type name
- `capacity`: Vehicle capacity
- `description`: Type description
**Example Response**:
```json
{
"id": 1,
"name": "小型货车",
"capacity": "500公斤",
"description": "适合小批量货物运输",
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Bank Accounts
**Base URL**: `/api/backend/bank-accounts/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/bank-accounts/` | List | Retrieve all bank accounts |
| GET | `/api/backend/bank-accounts/{id}/` | Retrieve | Get a specific bank account |
| POST | `/api/backend/bank-accounts/` | Create | Create a new bank account |
| PUT | `/api/backend/bank-accounts/{id}/` | Update | Update a bank account |
| PATCH | `/api/backend/bank-accounts/{id}/` | Partial Update | Partially update a bank account |
| DELETE | `/api/backend/bank-accounts/{id}/` | Delete | Delete a bank account |
**Request/Response Fields**:
- `id`: Account ID
- `bank_name`: Bank name
- `account_number`: Account number
- `account_holder`: Account holder name
- `branch`: Bank branch
- `is_default`: Whether this is the default account
**Example Response**:
```json
{
"id": 1,
"bank_name": "中国工商银行",
"account_number": "6222021234567890",
"account_holder": "张三",
"branch": "广州天河支行",
"is_default": true,
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Device Info
**Base URL**: `/api/backend/device-info/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/device-info/` | List | Retrieve all device information |
| GET | `/api/backend/device-info/{id}/` | Retrieve | Get specific device information |
| POST | `/api/backend/device-info/` | Create | Create new device information |
| PUT | `/api/backend/device-info/{id}/` | Update | Update device information |
| PATCH | `/api/backend/device-info/{id}/` | Partial Update | Partially update device information |
| DELETE | `/api/backend/device-info/{id}/` | Delete | Delete device information |
**Request/Response Fields**:
- `id`: Device ID
- `name`: Device name
- `type`: Device type (ROLLING, PRINTING, etc.)
- `status`: Device status (ACTIVE, MAINTENANCE, etc.)
- `start_working_at`: Date when device started working
- `stop_working_at`: Date when device stopped working
- `is_occupied`: Whether device is currently occupied
- `description`: Additional description
**Example Response**:
```json
{
"id": 1,
"name": "滚筒机A",
"type": "ROLLING",
"status": "ACTIVE",
"start_working_at": "2025-01-15",
"stop_working_at": null,
"is_occupied": true,
"description": "主要生产用滚筒设备",
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### Vehicle Transport Records
**Base URL**: `/api/backend/vehicle-transport-records/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/vehicle-transport-records/` | List | Retrieve all transport records |
| GET | `/api/backend/vehicle-transport-records/{id}/` | Retrieve | Get a specific transport record |
| POST | `/api/backend/vehicle-transport-records/` | Create | Create a new transport record |
| PUT | `/api/backend/vehicle-transport-records/{id}/` | Update | Update a transport record |
| PATCH | `/api/backend/vehicle-transport-records/{id}/` | Partial Update | Partially update a transport record |
| DELETE | `/api/backend/vehicle-transport-records/{id}/` | Delete | Delete a transport record |
**Request/Response Fields**:
- `id`: Record ID
- `vehicle_type`: Vehicle type (nested object)
- `driver_name`: Driver name
- `driver_mobile`: Driver mobile phone
- `transport_date`: Date of transport
- `source`: Source location
- `destination`: Destination location
- `goods_description`: Description of goods being transported
- `quantity`: Quantity of goods
- `status`: Transport status
- `notes`: Additional notes
- `vehicle_type_name`: Read-only derived vehicle type name
**Example Response**:
```json
{
"id": 1,
"vehicle_type": {
"id": 1,
"name": "小型货车",
"capacity": "500公斤",
"description": "适合小批量货物运输"
},
"driver_name": "王师傅",
"driver_mobile": "13900139000",
"transport_date": "2025-11-24",
"source": "广州工厂",
"destination": "深圳客户",
"goods_description": "印花布料",
"quantity": "300公斤",
"status": "COMPLETED",
"notes": "运输顺利",
"vehicle_type_name": "小型货车",
"merchant": 1,
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
### User Profiles
**Base URL**: `/api/backend/user-profiles/`
| Method | URL Pattern | Action | Description |
|--------|-------------|---------|-------------|
| GET | `/api/backend/user-profiles/` | List | Retrieve all user profiles for current merchant |
| GET | `/api/backend/user-profiles/{id}/` | Retrieve | Get a specific user profile |
| POST | `/api/backend/user-profiles/` | Create | Create a new user profile |
| PUT | `/api/backend/user-profiles/{id}/` | Update | Update a user profile |
| PATCH | `/api/backend/user-profiles/{id}/` | Partial Update | Partially update a user profile |
| DELETE | `/api/backend/user-profiles/{id}/` | Delete | Delete a user profile |
**Request/Response Fields**:
- `id`: Profile ID
- `user`: User ID (for writing)
- `user_detail`: User object details (for reading)
- `merchant`: Merchant ID (auto-set to current user's merchant)
- `description`: Profile description
- `created_at`: Creation timestamp
- `updated_at`: Last update timestamp
**Creating a User Profile (POST)**:
```json
{
"user": 123, // User ID
"description": "User profile for system access"
}
```
**Example Response**:
```json
{
"id": 1,
"user": 5,
"user_detail": {
"id": 5,
"username": "testuser",
"email": "test@example.com",
"is_active": true,
"is_superuser": false,
"last_login": "2025-11-24T09:00:00Z"
},
"merchant": 1,
"description": "用户资料描述",
"created_at": "2025-11-24T10:30:00Z",
"updated_at": "2025-11-24T10:30:00Z"
}
```
## Error Handling
All endpoints may return the following error responses:
### 401 Unauthorized
```json
{
"detail": "Authentication credentials were not provided."
}
```
### 403 Forbidden
```json
{
"detail": "You do not have permission to perform this action."
}
```
### 404 Not Found
```json
{
"detail": "Not found."
}
```
### 400 Bad Request
```json
{
"field_name": ["Error message for this field"],
"non_field_errors": ["General error message"]
}
```
### 500 Server Error
```json
{
"detail": "A server error occurred."
}
```
## Pagination
List endpoints support pagination using the LimitOffsetPagination scheme.
**Query Parameters**:
- `limit`: Number of results to return per page
- `offset`: Number of results to skip
**Example**:
```
GET /api/backend/products/?limit=20&offset=40
```
This will return 20 items starting from position 40 (items 41-60).
**Response Format**:
```json
{
"count": 150,
"next": "http://example.com/api/backend/products/?limit=20&offset=60",
"previous": "http://example.com/api/backend/products/?limit=20&offset=20",
"results": [
{
"id": 41,
"name": "Product 41",
...
}
// ... up to 20 items
]
}
```