1、管理员账号权限为空,示例如下:

解决:
1、用另一个有权的的账号分配;
2、或者找开发从数据库添加:表名:model_has_roles,如下插入一条数据:

2、采购模块关联删除数据
1、通过订单号:
php artisan test — filter=”test_batch_delete_by_supply_serial_code$”
2、通过订单创建时间:
php artisan test –filter=”test_batch_delete_supply_order_data_by_date$”
示例图片:

代码资料:如本地没有则新建到本地文件项目里面:
<?php
namespace Tests\Unit;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;
class DeleteSupplyOrderDataTest extends TestCase
{
public function test_delete_supply_order_data(array $orderIds = [], bool $dryRun = true, bool $deleteOrders = false, string $source = ''){
if (empty($orderIds)) {
$this->outputInfo("没有找到需要删除的订单");
return;
}
$orderIdsStr = implode(',', $orderIds);
$this->outputInfo("找到 " . count($orderIds) . " 个订单,ID: {$orderIdsStr}");
if ($dryRun) {
$this->outputInfo("【预览模式】以下为将要删除的数据:");
$this->showAffectedData($orderIds, $deleteOrders);
return;
}
$this->outputWarning("警告:此操作将永久删除相关数据,无法恢复!");
if ($deleteOrders) {
$this->outputWarning("⚠️ 将删除采购订单主表数据!");
}
try {
DB::beginTransaction();
$this->outputInfo("开始删除数据...");
// 执行删除操作
$this->deleteSupplyOrderData($orderIds, $deleteOrders);
DB::commit();
$this->outputSuccess("删除操作完成!");
$logMessage = "删除采购订单数据命令执行成功,删除订单ID: {$orderIdsStr}";
if (!empty($source)) {
$logMessage .= " (来源: {$source})";
}
Log::info($logMessage);
} catch (\Exception $e) {
DB::rollBack();
$this->outputError("操作失败:" . $e->getMessage());
Log::error("删除采购订单数据命令执行失败:" . $e->getMessage());
}
}
/**
* 通过日期获取订单ID并删除数据
* @param string $date 删除该日期之后的数据,格式:YYYY-MM-DD
* @param bool $dryRun 是否预览模式,只显示不实际删除
* @param bool $deleteOrders 是否删除采购订单主表数据
*/
public function test_delete_supply_order_data_by_date($date = '2025-10-01', $dryRun = true, $deleteOrders = false){
$startDate = $date . ' 00:00:00';
$this->outputInfo("开始查询 {$startDate} 之后创建的订单...");
// 查询需要删除的订单ID
$orderIds = DB::table('supply_orders')
->where('created_at', '>=', $startDate)
->pluck('id')
->toArray();
$this->test_delete_supply_order_data($orderIds, $dryRun, $deleteOrders, "日期: {$startDate}");
}
/**
* 通过订单编号获取订单ID并删除数据
*
* @param string|array $serialCodes 订单编号或编号数组
* @param bool $dryRun 是否预览模式,只显示不实际删除
* @param bool $deleteOrders 是否删除采购订单主表数据
*/
public function test_delete_supply_order_data_by_serial_code($serialCodes = [], $dryRun = true, $deleteOrders = false){
// 支持字符串或数组格式的订单编号
if (is_string($serialCodes)) {
$serialCodes = [$serialCodes];
}
if (empty($serialCodes)) {
// 如果没有提供订单编号,使用默认的测试数据
$serialCodes = ['PO20250001', 'PO20250002', 'PO20250003'];
$this->outputInfo("使用默认测试订单编号: " . implode(', ', $serialCodes));
}
$this->outputInfo("开始查询订单编号为 [" . implode(', ', $serialCodes) . "] 的订单...");
// 查询需要删除的订单ID
$orderIds = DB::table('supply_orders')
->whereIn('serial_code', $serialCodes)
->pluck('id')
->toArray();
$this->test_delete_supply_order_data($orderIds, $dryRun, $deleteOrders, "订单编号: " . implode(', ', $serialCodes));
}
/**
* 通过订单ID直接删除数据
*
* @param string|array $orderIds 订单ID或ID数组
* @param bool $dryRun 是否预览模式,只显示不实际删除
* @param bool $deleteOrders 是否删除采购订单主表数据
*/
public function test_delete_supply_order_data_by_ids($orderIds = [], $dryRun = true, $deleteOrders = false){
// 支持字符串或数组格式的订单ID
if (is_string($orderIds)) {
$orderIds = array_map('intval', explode(',', $orderIds));
}
if (empty($orderIds)) {
// 如果没有提供订单ID,使用默认的测试数据
$orderIds = [174, 175];
$this->outputInfo("使用默认测试订单ID: " . implode(', ', $orderIds));
}
$this->outputInfo("开始处理订单ID: [" . implode(', ', $orderIds) . "]");
$this->test_delete_supply_order_data($orderIds, $dryRun, $deleteOrders, "订单ID: " . implode(', ', $orderIds));
}
/**
* 显示受影响的数据(预览模式)
*/
private function showAffectedData(array $orderIds, bool $deleteOrders = false){
$orderIdsStr = implode(',', $orderIds);
$this->outputInfo("将要删除的数据表(按删除顺序):");
// 按照删除顺序显示
$tables = [
'invoice_received' => "SELECT COUNT(*) as count FROM invoice_received WHERE id IN (SELECT bill_id FROM invoice_received_items WHERE supply_order_id IN ({$orderIdsStr}) GROUP BY bill_id)",'invoice_received_items' => "SELECT COUNT(*) as count FROM invoice_received_items WHERE supply_order_id IN ({$orderIdsStr})",'payments' => "SELECT COUNT(*) as count FROM payments WHERE id IN (SELECT bill_id FROM payment_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1) GROUP BY bill_id)",
'payment_items' => "SELECT COUNT(*) as count FROM payment_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1)",'supply_acccheck' => "SELECT COUNT(*) as count FROM supply_acccheck WHERE id IN (SELECT bill_id FROM supply_acccheck_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1) GROUP BY bill_id)",
'supply_acccheck_items' => "SELECT COUNT(*) as count FROM supply_acccheck_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1)",'finance_stockin_details' => "SELECT COUNT(*) as count FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1",'supply_stockin_items' => "SELECT COUNT(*) as count FROM supply_stockin_items WHERE order_id IN ({$orderIdsStr})",
'supply_stockin' => "SELECT COUNT(*) as count FROM supply_stockin WHERE ori_bill_id IN ({$orderIdsStr})",
'to_stockin_lists' => "SELECT COUNT(*) as count FROM to_stockin_lists WHERE ori_bill_type = 'App/Models/SupplyOrder' AND ori_bill_id IN ({$orderIdsStr})", 'qc_tasks' => "SELECT COUNT(*) as count FROM qc_tasks WHERE scope = 'caigoulailiao' AND ori_bill_id IN ({$orderIdsStr})",'supply_incoming_materials' => "SELECT COUNT(*) as count FROM supply_incoming_materials WHERE id IN (SELECT bill_id FROM supply_incoming_material_items WHERE ori_bill_id IN ({$orderIdsStr}) GROUP BY bill_id)",'supply_incoming_material_items' => "SELECT COUNT(*) as count FROM supply_incoming_material_items WHERE ori_bill_id IN ({$orderIdsStr})",'supply_order_items' => "SELECT COUNT(*) as count FROM supply_order_items WHERE order_id IN ({$orderIdsStr})",'supply_orders' => "SELECT COUNT(*) as count FROM supply_orders WHERE id IN ({$orderIdsStr})",];
// 如果启用删除订单主表,添加采购订单表的统计
if (!$deleteOrders) {
// 如果不删除订单主表,则移除采购订单主表和明细表的统计
unset($tables['supply_order_items']);
unset($tables['supply_orders']);
}
$order = 1;
foreach ($tables as $tableName => $sql) {
try {
$count = DB::select($sql)[0]->count ?? 0;
$this->outputLine(" {$order}. 表 {$tableName}: {$count} 条记录");
$order++;
} catch (\Exception $e) {
$this->outputError(" 查询表 {$tableName} 失败: " . $e->getMessage());
}
}
}
/**
* 执行删除操作(按照指定顺序)
*/
private function deleteSupplyOrderData(array $orderIds, bool $deleteOrders = false){
$orderIdsStr = implode(',', $orderIds);
$step = 1;
$this->outputInfo("{$step}. 删除采购发票主表...");
DB::statement("DELETE FROM invoice_received WHERE id IN (SELECT bill_id FROM invoice_received_items WHERE supply_order_id IN ({$orderIdsStr}) GROUP BY bill_id)");
$step++;
$this->outputInfo("{$step}. 删除采购发票明细...");
DB::statement("DELETE FROM invoice_received_items WHERE supply_order_id IN ({$orderIdsStr})");
$step++;
$this->outputInfo("{$step}. 删除付款主表...");
DB::statement("DELETE FROM payments WHERE id IN (SELECT bill_id FROM payment_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1) GROUP BY bill_id)");
$step++;
$this->outputInfo("{$step}. 删除付款明细...");
DB::statement("DELETE FROM payment_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1)");
$step++;
$this->outputInfo("{$step}. 删除采购对账主表...");
DB::statement("DELETE FROM supply_acccheck WHERE id IN (SELECT bill_id FROM supply_acccheck_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1) GROUP BY bill_id)");
$step++;
$this->outputInfo("{$step}. 删除采购对账明细...");
DB::statement("DELETE FROM supply_acccheck_items WHERE finance_stockin_id IN (SELECT id FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1)");
$step++;
$this->outputInfo("{$step}. 删除财务入库明细...");
DB::statement("DELETE FROM finance_stockin_details WHERE order_id IN ({$orderIdsStr}) AND order_type_key = 1");
$step++;
$this->outputInfo("{$step}. 删除采购入库明细...");
DB::statement("DELETE FROM supply_stockin_items WHERE order_id IN ({$orderIdsStr})");
$step++;
$this->outputInfo("{$step}. 删除采购入库主表...");
DB::statement("DELETE FROM supply_stockin WHERE ori_bill_id IN ({$orderIdsStr})");
$step++;
$this->outputInfo("{$step}. 删除待入库列表...");
DB::statement("DELETE FROM to_stockin_lists WHERE ori_bill_type = 'App/Models/SupplyOrder' AND ori_bill_id IN ({$orderIdsStr})");
$step++;
$this->outputInfo("{$step}. 删除采购来料质检任务...");
DB::statement("DELETE FROM qc_tasks WHERE scope = 'caigoulailiao' AND ori_bill_id IN ({$orderIdsStr})");
$step++;
$this->outputInfo("{$step}. 删除采购来料主表...");
DB::statement("DELETE FROM supply_incoming_materials WHERE id IN (SELECT bill_id FROM supply_incoming_material_items WHERE ori_bill_id IN ({$orderIdsStr}) GROUP BY bill_id)");
$step++;
$this->outputInfo("{$step}. 删除采购来料明细...");
DB::statement("DELETE FROM supply_incoming_material_items WHERE ori_bill_id IN ({$orderIdsStr})");
$step++;
// 最后删除采购订单表数据(如果启用)
if ($deleteOrders) {
$this->outputInfo("{$step}. 删除采购订单明细表...");
DB::statement("DELETE FROM supply_order_items WHERE order_id IN ({$orderIdsStr})");
$step++;
$this->outputInfo("{$step}. 删除采购订单主表...");
DB::statement("DELETE FROM supply_orders WHERE id IN ({$orderIdsStr})");
$step++;
}
$this->outputSuccess("所有操作完成!共执行 {$step} 个步骤");
}
/**
* 批量删除测试 - 通过日期
*/
public function test_batch_delete_supply_order_data_by_date(){
// 可以通过环境变量设置日期和数量
$startDate = $_ENV['DELETE_SUPPLY_START_DATE'] ?? '2025-08-01';
// 是否预览模式,只显示不实际删除
$dryRun = $_ENV['DELETE_SUPPLY_DRY_RUN'] ?? false;
// 是否删除订单表数据(默认 false)
$deleteOrders = $_ENV['DELETE_SUPPLY_ORDERS'] ?? true;
$this->test_delete_supply_order_data_by_date($startDate, $dryRun, $deleteOrders);
}
/**
* 批量删除测试 - 通过订单编号
*/
public function test_batch_delete_by_supply_serial_code(){
// 是否预览模式,只显示不实际删除
$dryRun = $_ENV['DELETE_SUPPLY_DRY_RUN'] ?? false;
// 是否删除订单表数据(默认 false)
$deleteOrders = $_ENV['DELETE_SUPPLY_ORDERS'] ?? false;
$serialCodes = 'SO251001001,SO251002001,SO251001002,SO251002002,SO251001003,SO251002003';
// 将逗号分隔的订单编号转换为数组
$serialCodeArray = [];
if (!empty($serialCodes)) {
$serialCodeArray = array_map('trim', explode(',', $serialCodes));
}
$this->test_delete_supply_order_data_by_serial_code($serialCodeArray, $dryRun, $deleteOrders);
}
/**
* 批量删除测试 - 通过订单ID
*/
public function test_batch_delete_by_supply_ids(){
// 可以通过环境变量设置订单ID和删除选项
$orderIds = $_ENV['DELETE_SUPPLY_ORDER_IDS'] ?? '';
$dryRun = ($_ENV['DELETE_SUPPLY_DRY_RUN'] ?? 'true') === 'false';
$deleteOrders = ($_ENV['DELETE_SUPPLY_ORDERS'] ?? 'false') === 'true';
$this->test_delete_supply_order_data_by_ids($orderIds, $dryRun, $deleteOrders);
}
/**
* 输出信息(白色)
*/
private function outputInfo(string $message){
echo "\033[0;37m[INFO] " . $message . "\033[0m" . PHP_EOL;
}
/**
* 输出成功信息(绿色)
*/
private function outputSuccess(string $message){
echo "\033[0;32m[SUCCESS] " . $message . "\033[0m" . PHP_EOL;
}
/**
* 输出警告信息(黄色)
*/
private function outputWarning(string $message){
echo "\033[1;33m[WARNING] " . $message . "\033[0m" . PHP_EOL;
}
/**
* 输出错误信息(红色)
*/
private function outputError(string $message){
echo "\033[0;31m[ERROR] " . $message . "\033[0m" . PHP_EOL;
}
/**
* 输出普通行
*/
private function outputLine(string $message){
echo $message . PHP_EOL;
}
}
3、审批流中流程节点(判断条件)怎么设置?
条件表达式的编写:
1.支持字段: 仅支持业务单据主表中已存在的字段,如“客户档案”表中的id,name,company_id…
2.支持的比较、算术运算符+,-*,/,%,=,!=,>,<,>=,<=
3.支持的逻辑运算符:与 and ,或 or
4.支持使用括号()将条件分组
5.php内置函数支持:php_is_nu11,php_is_numeric ,分别对应php中的 is_null,is_numeric函数。涉及到代码安全,根据实际需求开放。
网关条件表达式编写示例:
(id >20 and name ==’test’)or parent id ==1
此表达式指:单据id大于20日name等于test'或者parent id 等于1’时 满足条件


发表回复
要发表评论,您必须先登录。