lungosoft / document
用于具有标题和行结构的文档,验证行和标题信息,在数据库中保存数据。
Requires
- php: >=7.0.0
- illuminate/contracts: ^5.5
- illuminate/database: ^5.5
- illuminate/support: ^5.5
Requires (Dev)
- mockery/mockery: ^1.2
- phpunit/phpunit: 7
This package is not auto-updated.
Last update: 2024-10-02 20:36:48 UTC
README
简介
一个文档是指具有两个表,一个是标题表,一个是行表,行与标题之间是1对N的关系,外键在行表中,也就是说,一个标题对应多个行。
它提供了一个机制来处理打开、关闭和部分关闭(仅限于行)的状态,允许仅在打开状态下进行编辑。
它帮助我们通过外键关联两个文档。一个文档将其某些行与另一个文档的行关联起来,这是一个1对1的关系。
在上面的图中,我们可以看到一个示例,其中有两个文档及其关系
这种结构有什么好处?
它帮助我们以安全的方式执行文档的CRUD操作,并减少创建、编辑和删除文档时对文档状态的验证。有时,需要创建一个更大、更严格的文档链,我们通过一个控制这些更改及其状态更改的类来减少CRUD操作。
为什么会有数据冗余?
如前所述,有时需要一个更长、更复杂的文档行。一个例子是ERP类型的企业应用程序,它可以控制采购、存储和发票的文档。
数据冗余帮助我们简化查询并使其更快(减少获取信息的JOIN操作数量)。
因此,我们必须有效地控制数据重复。
数量控制
我们可以在编辑文档时控制数量,也就是说,假设我们创建了一个“采购订单”文档,并通过一个“入库”文档输入一个数量,该数量小于“采购订单”文档中指定的数量,我们可以编辑“采购订单”文档的数量,只要该数量不超过“入库”文档的数量。
表列
所有表都必须强制有一个状态(status)。对于行,除了状态(status)之外,还有一个数量(quantity)列。文档的状态是'打开'、'关闭'和'部分关闭'。前面提到的值(status、quantity、打开、关闭和部分关闭)是默认值,但可以通过修改文档属性进行更改。
要求
- 创建模型:创建Eloquent模型
- 批量赋值:在模型中启用批量赋值。
- 一对多关系:标题必须有
lines
方法,与行模型相关联。
class Order extends Model
{
protected $fillable = ['customer', 'status'];
public function lines()
{
return $this->hasMany(OrderDetail::class);
}
}
安装
composer install "lungosoft/document"
使用
文档
需要创建一个继承自Document
的文档类,并重写两个属性,一个用于标题类($headerClass
),另一个用于行类($lineClass
)。
<?php
namespace App\Repositories;
use Lungo\Doc\Document;
class SaleOrderRepository extends Document
{
protected $headerClass = '\\Lungo\\Doc\\Test\\Testeable\\HeaderModel';
protected $lineClass = '\\Lungo\\Doc\\Test\\Testeable\\LineModel';
}
现在我们可以使用它们的方法
Route::post('/saleorder', function (Request $request) {
//validate saleorder data
$saleOrder = \App\Repositories\SaleOrderRepository();
//use methods
});
当然,可以创建所需的任何类。
方法
create($headers, $lines, $fk):
帮助创建一个具有标题、行和与其外键相关联的文档。
editHeader($id, $header):
仅当行和标题的状态为'打开'时,编辑文档标题。
editLine($id, $lineId, $header):
仅当行和标题的状态为'打开'时,编辑指定的文档行。
destroyHeader($id):
仅在文档标题及其行具有 '开放' 状态时,删除文档标题。
destroyLine($id, $lineId):
仅在行和标题具有 '开放' 状态时,删除指定的文档行。
canEdit($model, $lineId = 0):
如果模型可编辑,则返回 true 或 false。如果没有指定行,则检查标题和所有行是否处于 '开放' 状态;如果指定了行,则检查标题和指定的行是否处于 '开放' 状态。
getModels($id, $lineId, $callback):
如果可以编辑文档,则返回标题和行模型(如果指定,则返回 0)。如果可以编辑文档,则回调函数被调用,返回两个值:标题模型和行模型;如果没有指定行,则行返回 null。
getModel($id, $header = true):
获取标题或行的 Eloquent 模型,如果第二个参数指定为 false,则返回行,否则返回标题。
getModelLineByFK($value, $fk):
根据特定的字段(fk)和值(value)从行中获取一个模型行数组。通常用于根据外键(fk)获取行中包含产品(value)的行,但也可以用于模型行的任何字段。
属性
可以更改属性以使用我们喜欢的列名和状态。
$headerColumnStatus:
表 header 的状态列名。默认状态。
$headerCloseStatus:
表 header 的文档关闭状态名称。默认为 '关闭'。
$headerDestroyedStatus:
表 header 的文档删除状态名称。默认为 '取消'。
$headerOpenStatus:
表 header 的文档开放状态名称。默认为 '开放'。
$lineColumnStatus:
表 línea 的状态列名。默认状态。
$lineCloseStatus:
表 línea 的文档关闭状态名称。默认为 '关闭'。
$linePartiallyCloseStatus:
表 línea 的部分开放文档状态名称。默认为 '部分开放'。
$lineDestroyedStatus:
表 línea 的文档删除状态名称。默认为 '取消'。
$lineOpenStatus:
表 línea 的文档开放状态名称。默认为 '开放'。
$lineQuantityColumn:
表 línea 的数量列名。默认为 'quantity'。
DocumentManager
DocumentManager 是文档管理器,通过传递两个相互关联的文档类型类进行实例化。
示例
创建文档
Route::post('/saleorder', function (Request $request) {
//validate saleorder data
if ($request->has(['header', 'lines'])) {
$saleOrder = \App\Repositories\SaleOrderRepository();
$saleOrder->create($request->header, $request->lines, 'sale_order_id');
} else {
//throw an error, 400 status or do a redirect....
}
});
编辑文档标题
Route::post('/saleorder/{id}', function (Request $request, $id) {
//validate saleorder data
if ($request->has(['header'])) {
$saleOrder = \App\Repositories\SaleOrderRepository();
if ($saleOrder->editHeader($id, $request->header)) {
return response('OK', 200);
} else {
return response('OK', 400);
}
} else {
//throw an error, 400 status or do a redirect....
}
});