Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c6e43170f | |||
| a0d5a766a1 | |||
| 403ac7a271 | |||
| 433b2dd915 | |||
| bed833f790 | |||
| 5570e025b4 | |||
| 67139e4161 | |||
| 9f96d4da3f | |||
| 736df0ebdf | |||
| 4c9853f72a | |||
| 90dca83487 | |||
| 35f80aab1a | |||
| b35e536c79 | |||
| facf0b4c10 | |||
| 1221e42917 | |||
| 4dc708e133 | |||
| 5bcca5cb12 | |||
| 9b36bbf227 | |||
| 502740e106 | |||
| 52eac05d43 | |||
| fec079ef58 | |||
| 134ced1a31 | |||
| 472f8e39a7 | |||
| 90aebf9956 | |||
| edee50aaf9 | |||
| 615e9745a0 | |||
| fd4fa0fbf3 | |||
| 8003ef49d1 | |||
| fddcbc2df8 | |||
| f60b365361 | |||
| ded377a758 | |||
| 4537df63c2 | |||
| d76fec4624 | |||
| 62d86c634c | |||
| 9fc890f8cd | |||
| 6289b545f5 | |||
| 376411dd79 | |||
| 83ff52c1a0 | |||
| db7f5d568c | |||
| bcf39b6037 | |||
| 9d050f4211 | |||
| 034b278b40 | |||
| ebcabb23df | |||
| 4acb89e56a | |||
| d16bddcc32 | |||
| 6434c8769e | |||
| c796d01703 | |||
| ab6a8806af | |||
| 9f8a241e35 | |||
| 8f699d5ca9 | |||
| e6f68a9946 | |||
| 7ac6201925 | |||
| 358cb64fe4 | |||
| aede027ae2 | |||
| dbe5e2e96f | |||
| 91c313f2ca | |||
| f99b2a84ca | |||
| 909f169aae | |||
| cdd6d78995 | |||
| 133cd0a801 | |||
| 8cdf9e9e39 | |||
| e21f41701a | |||
| 9f77b93b25 | |||
| 70fa843970 | |||
| 0050ef6829 | |||
| ba7c00e942 | |||
| 460de92912 | |||
| c85f07cff4 | |||
| 638be73988 | |||
| cab55847e4 | |||
| 07f9280327 | |||
| a3da2cfc23 | |||
| 521cfec00a | |||
| ac982b0957 | |||
| d9e2c89c0e | |||
| 81445a7096 | |||
| 1413a93d6d | |||
| 65f0be0a5d | |||
| b65f8090cf | |||
| 5c1304e239 |
@@ -4,7 +4,6 @@ namespace app\admin\controller;
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\model\Corp;
|
||||
use app\common\model\User;
|
||||
use app\common\service\OssService;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\common\service\InvItemService;
|
||||
use support\Request;
|
||||
@@ -41,8 +40,8 @@ class InvItemController extends BaseController
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
@@ -51,89 +50,6 @@ class InvItemController extends BaseController
|
||||
$data['company_name'] = Corp::where('id', $data['company_id'])->value('name');
|
||||
if (isset($data['manage_user_id']))
|
||||
$data['manage_user_name'] = User::where('id', $data['manage_user_id'])->value('name');
|
||||
if (!empty($data['qr_code']))
|
||||
$data['qr_code_pull'] = (new OssService)->generatePrivateUrl($data['qr_code']);;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成物品二维码
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function generateQrCode(Request $request)
|
||||
{
|
||||
try {
|
||||
$id = $request->post('id');
|
||||
$num = $request->post('num');
|
||||
if (!$id) {
|
||||
return $this->error('物品ID不能为空');
|
||||
}
|
||||
|
||||
$item = \app\common\model\InvItem::find($id);
|
||||
if (!$item) {
|
||||
return $this->error('物品不存在');
|
||||
}
|
||||
|
||||
// 获取应用访问地址
|
||||
$appUrl = 'https://'.$request->host();
|
||||
|
||||
$qrCodeService = new \app\common\service\QrCodeService();
|
||||
$content = $qrCodeService->generateItemQrCode($id, $appUrl);
|
||||
$fileName = 'qr_item_' . $id . '_' . time() . '.png';
|
||||
|
||||
$result = $qrCodeService->generateAndUploadQrCode($id, $content, $fileName);
|
||||
|
||||
// 更新物品记录
|
||||
$item->qr_code = $result['path'];
|
||||
//$item->qr_code_num = !empty($num)?$num:0;
|
||||
$item->qr_code_url = $result['url'];
|
||||
$item->save();
|
||||
|
||||
return $this->success([
|
||||
'qr_code_url' => $result['url'],
|
||||
'content' => $content,
|
||||
], '二维码生成成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除物品二维码
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function deleteQrCode(Request $request)
|
||||
{
|
||||
try {
|
||||
$id = $request->post('id');
|
||||
if (!$id) {
|
||||
return $this->error('物品ID不能为空');
|
||||
}
|
||||
|
||||
$item = \app\common\model\InvItem::find($id);
|
||||
if (!$item) {
|
||||
return $this->error('物品不存在');
|
||||
}
|
||||
|
||||
// 删除 OSS 文件
|
||||
if ($item->qr_code) {
|
||||
$qrCodeService = new \app\common\service\QrCodeService();
|
||||
$qrCodeService->deleteQrCode($item->qr_code);
|
||||
}
|
||||
|
||||
// 清空物品记录中的二维码字段
|
||||
$item->qr_code = '';
|
||||
//$item->qr_code_num = 0;
|
||||
$item->qr_code_url = '';
|
||||
$item->save();
|
||||
|
||||
return $this->success([], '二维码删除成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,8 @@
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\model\InvRequisitionApprove;
|
||||
use app\common\model\InvRequisitionAttachment;
|
||||
use app\common\model\InvRequisitionItem;
|
||||
use app\common\service\OssService;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\admin\service\InvRequisitionService;
|
||||
use app\common\service\InvRequisitionService;
|
||||
use support\Request;
|
||||
|
||||
class InvRequisitionController extends BaseController
|
||||
@@ -21,160 +17,18 @@ class InvRequisitionController extends BaseController
|
||||
$this->service = new InvRequisitionService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function approve(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $this->service->serviceApprove($request);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回分页数据及总数
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
try {
|
||||
$applicant_id = $request->get('applicant_id');
|
||||
$uid = $request->user->uid;
|
||||
$raw = $this->service->serviceList($request);
|
||||
$data = $this->formatindex($raw,$applicant_id,$uid);
|
||||
// $data = $this->transformData($raw, method_exists($this, 'indexFormat')
|
||||
// ? [$this, 'indexFormat']
|
||||
// : null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function formatindex($p,$applicant_id,$uid){
|
||||
$records = $p->getCollection()
|
||||
->map(fn($item) => $this->indexFormat($item, $applicant_id,$uid))
|
||||
->toArray();
|
||||
|
||||
return [
|
||||
'records' => $records,
|
||||
'total' => $p->total(),
|
||||
'current' => $p->currentPage(),
|
||||
'size' => $p->perPage(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function indexFormat($data, $applicant_id, $uid)
|
||||
{
|
||||
if (isset($data['id'])){
|
||||
//$data['approve'] = InvRequisitionApprove::where('requisition_id', $data['id'])->get();
|
||||
$data = $data->toArray();
|
||||
}
|
||||
if (isset($data['created_at'])){
|
||||
$data['created_at'] = is_int($data['created_at'])?$data['created_at']:strtotime($data['created_at']);
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
}
|
||||
if (isset($data['updated_at'])){
|
||||
$data['updated_at'] = is_int($data['updated_at'])?$data['updated_at']:strtotime($data['updated_at']);
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
}
|
||||
if (isset($data['id'])){
|
||||
$data['item'] = InvRequisitionItem::where('requisition_id', $data['id'])->get();
|
||||
}
|
||||
|
||||
if($applicant_id != 'self' && isset($data['id'])){ //不是查询自己数据时查询是否已审核
|
||||
$approve = InvRequisitionApprove::where('requisition_id', $data['id'])
|
||||
->where('approver_id', $uid)
|
||||
->first();
|
||||
$data['action'] = $approve['action']??3;//查询人审核状态:0待审核 1通过 2驳回 3非审核人
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function showFormat($data)
|
||||
{
|
||||
if (isset($data['id'])){
|
||||
$data['approve'] = InvRequisitionApprove::where('requisition_id', $data['id'])->orderBy('id')->get()->toArray();
|
||||
|
||||
$approve_id = 0;
|
||||
foreach ($data['approve'] as $key => $value) {
|
||||
if (isset($value['created_at'])){
|
||||
$value['created_at'] = is_int($value['created_at'])?$value['created_at']:strtotime($value['created_at']);
|
||||
$data['approve'][$key]['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
|
||||
}
|
||||
if (isset($value['updated_at'])){
|
||||
$value['updated_at'] = is_int($value['updated_at'])?$value['updated_at']:strtotime($value['updated_at']);
|
||||
$data['approve'][$key]['updated_at'] = date('Y-m-d H:i:s', $value['updated_at']);
|
||||
}
|
||||
$data['approve'][$key]['action_at'] = date('Y-m-d H:i:s', $data['approve'][$key]['action_at']);
|
||||
$approve_id = $value['id'];
|
||||
}
|
||||
$data['approve_id'] = $approve_id;
|
||||
}
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
if (isset($data['id'])){
|
||||
$data['item'] = InvRequisitionItem::where('requisition_id', $data['id'])->get();
|
||||
$data['attachment'] = InvRequisitionAttachment::where('requisition_id', $data['id'])->get();
|
||||
$oss = new OssService();
|
||||
foreach ($data['attachment'] as $key => $value) {
|
||||
$data['attachment'][$key]['file_path_pull'] = $oss->generatePrivateUrl($value['file_path']);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员代领
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function proxyClaim(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $this->service->proxyClaim($request, $request->post());
|
||||
return $this->success($data, '代领成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码/代领记录查询
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function qrClaims(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $this->service->qrClaimsList($request);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\common\service\InvRequisitionReturnService;
|
||||
use support\Request;
|
||||
|
||||
class InvRequisitionReturnController extends BaseController
|
||||
{
|
||||
use CrudControllerTrait;
|
||||
|
||||
protected $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->service = new InvRequisitionReturnService();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 列表页数据格式化
|
||||
// *
|
||||
// * @param array $data
|
||||
// * @return array
|
||||
// */
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
|
||||
public function returnConfirm(Request $request){
|
||||
try {
|
||||
// 处理申请逻辑
|
||||
$result = $this->service->serviceReturnConfirm($request);
|
||||
|
||||
return $this->success($result, '申请提交成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\service\InvStockLogService;
|
||||
use support\Request;
|
||||
|
||||
class InvStockLogController extends BaseController
|
||||
{
|
||||
protected $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->service = new InvStockLogService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 库存变化记录列表
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function list(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $this->service->getList($request->get());
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,39 +398,21 @@ class BrandSeriesService
|
||||
*/
|
||||
public function crawlKeywordCreate(Request $request)
|
||||
{
|
||||
$brand_id = $request->input('brand_id');
|
||||
$brand_name = $request->input('brand_name');
|
||||
$brand_code = $request->input('brand_code');
|
||||
$series_id = $request->input('series_id');
|
||||
$brand_id = $request->input('brand_id');
|
||||
$series_name = $request->input('series_name');
|
||||
$models = $request->input('models');
|
||||
|
||||
if(empty($brand_id) && empty($brand_name)){
|
||||
if(empty($brand_id)){
|
||||
throw new \Exception("请选择品牌");
|
||||
}
|
||||
if(empty($series_id) && empty($series_name)){
|
||||
throw new \Exception("请选择车系");
|
||||
}
|
||||
|
||||
// 获取品牌信息
|
||||
if (empty($brand_id)) {
|
||||
$brand = Brand::where('id', $brand_id)->where('brand_name', $brand_name)->first();
|
||||
if (empty($brand)) { //如果没有该车系则创建
|
||||
$brandService = new \app\admin\service\BrandService();
|
||||
$brandData = [
|
||||
'brand_code' => $brandService->generateUniqueCode(),
|
||||
'brand_name' => $brand_name,
|
||||
];
|
||||
$brand = CrudUtil::create(Brand::class, $brandData);
|
||||
}
|
||||
$brand_id = $brand->id;
|
||||
}else{
|
||||
$brand = Brand::where('id', $brand_id)->first();
|
||||
}
|
||||
|
||||
if (empty($series_id)) {
|
||||
$series = BrandSeries::where('brand_id', $brand_id)->where('series_name', $series_name)->first();
|
||||
if (empty($series)) { //如果没有该车系则创建
|
||||
if (empty($brandseries)) { //如果没有该车系则创建
|
||||
$seriesService = new \app\admin\service\BrandSeriesService();
|
||||
$seriesData = [
|
||||
'brand_id' => $brand_id,
|
||||
@@ -443,6 +425,8 @@ class BrandSeriesService
|
||||
}else{
|
||||
$series = BrandSeries::where('id', $series_id)->first();
|
||||
}
|
||||
// 获取品牌信息
|
||||
$brand = Brand::where('id', $series->brand_id)->first();
|
||||
|
||||
// 保存车型数据
|
||||
$createdCount = 0;
|
||||
@@ -497,91 +481,6 @@ class BrandSeriesService
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 抓取
|
||||
*/
|
||||
public function crawl(Request $request): array
|
||||
{
|
||||
$keyword = $request->get('keyword');
|
||||
if(filter_var($keyword, FILTER_VALIDATE_URL)){
|
||||
return $this->crawlUrl($request);
|
||||
}else{
|
||||
return $this->crawlKeyword($request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 抓取车型数据(通过接口)
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function crawlUrl(Request $request): array
|
||||
{
|
||||
//$url = $request->get('url');
|
||||
$url = $request->get('keyword');
|
||||
|
||||
// 执行抓取
|
||||
$crawlService = new CrawlService();
|
||||
|
||||
//懂车帝提取车系id
|
||||
$seriesId = $this->get_series_from_url($url); //懂车帝车系id
|
||||
|
||||
if (empty($seriesId)) {
|
||||
throw new \Exception('抓取失败,未找到该系列车型');
|
||||
}
|
||||
|
||||
$brandSerieses = [];
|
||||
//抓取品牌与系列
|
||||
$brandSeries = $crawlService->crawlBrandSeries($seriesId);
|
||||
$brandSerieses[] = ['brand' => $brandSeries['brand'], 'series' => $brandSeries['series']];
|
||||
|
||||
$result = [];
|
||||
try {
|
||||
foreach ($brandSerieses as $brandSeries) {
|
||||
$item = [];
|
||||
// 验证品牌是否存在
|
||||
$brand = Brand::where('brand_name', $brandSeries['brand'])->first();
|
||||
// 获取品牌信息
|
||||
$series = BrandSeries::where('series_name', $brandSeries['series'])->first();
|
||||
$item['brand'] = ['brand_name' => $brandSeries['brand'], 'exists' => $brand ? 1 : 0];
|
||||
if ($brand) {
|
||||
$item['brand']['id'] = $brand['id'];
|
||||
}
|
||||
$item['series'] = ['series_name' => $brandSeries['series'], 'exists' => $series ? 1 : 0];
|
||||
if ($series) {
|
||||
$item['series']['id'] = $series['id'];
|
||||
if (empty($item['brand']['id'])) {
|
||||
$item['brand']['id'] = $series['brand_id'];
|
||||
}
|
||||
}
|
||||
|
||||
//获取车型数据
|
||||
$item['model'] = [];
|
||||
if (count($brandSerieses)<2) {
|
||||
$item['model'] = $this->crawlSeriesModel($seriesId);
|
||||
}
|
||||
$result[] = $item;
|
||||
}
|
||||
|
||||
return ['is_series' => (count($brandSerieses)<2)?1:0, 'data' => $result];
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function get_series_from_url($url) {
|
||||
// 使用正则表达式匹配 "https://www.dongchedi.com/auto/series/{数字}"
|
||||
$pattern = '/^https:\/\/www\.dongchedi\.com\/auto\/series\/(\d+)$/';
|
||||
if (preg_match($pattern, $url, $matches)) {
|
||||
// 提取数字部分作为 series ID
|
||||
$series_id = $matches[1];
|
||||
return $series_id; // 返回系列ID
|
||||
} else {
|
||||
throw new \Exception("URL格式不匹配");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取车系下车型数据
|
||||
* @return array
|
||||
|
||||
@@ -151,37 +151,4 @@ class BrandService
|
||||
$msg .= (!empty($fail))?',失败' . $fail . '条':'';
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一的7位颜色编码
|
||||
* 格式:C + (O/I) + 5位字母数字组合
|
||||
*
|
||||
* @param int $type 类型
|
||||
* @return string 7位唯一编码
|
||||
*/
|
||||
public function generateUniqueCode()
|
||||
{
|
||||
$chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$maxAttempts = 10; // 防止无限循环
|
||||
|
||||
for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
|
||||
// 生成后5位随机字符
|
||||
$suffix = '';
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$suffix .= $chars[rand(0, strlen($chars) - 1)];
|
||||
}
|
||||
|
||||
$code = $suffix;
|
||||
|
||||
// 检查是否已存在
|
||||
$existing = Brand::where('brand_code', $code)->first();
|
||||
if (!$existing) {
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果1000次尝试后仍然重复,使用时间戳确保唯一性
|
||||
$timestamp = substr(time(), -6);
|
||||
return $suffix . $timestamp;
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service;
|
||||
|
||||
use app\common\validate\InvRequisitionValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InvRequisition;
|
||||
use support\Request;
|
||||
|
||||
class InvRequisitionService
|
||||
{
|
||||
|
||||
use CrudServiceTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = InvRequisition::class;
|
||||
|
||||
/**
|
||||
* 验证器
|
||||
*/
|
||||
protected $validator = InvRequisitionValidate::class;
|
||||
|
||||
/**
|
||||
* 获取验证器
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造 CrudUtil 查询配置
|
||||
*/
|
||||
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
|
||||
{
|
||||
$p = $request->all();
|
||||
|
||||
$config = [];
|
||||
$config['model'] = $this->modelClass;
|
||||
switch ($scene) {
|
||||
case 'default':
|
||||
//$config['where']['status'] = 1;
|
||||
$config['order']['id'] = 'desc';
|
||||
break;
|
||||
case 'index':
|
||||
if(isset($p['status']) && $p['status']){
|
||||
$config['where']['status'] = $p['status'];
|
||||
}
|
||||
if (isset($p['applicant_id']) && $p['applicant_id'] == 'self') { //自己的领用申请
|
||||
$config['where']['applicant_id'] = $request->user->uid;
|
||||
} elseif (isset($p['applicant_id']) && $p['applicant_id']) { //指定人员的申请
|
||||
$config['where']['applicant_id'] = $p['applicant_id'];
|
||||
} else { //审批人对应的记录
|
||||
$config['where']['approval.approver_id'] = $request->user->uid;
|
||||
$config['where']['approval.action'] = 0;
|
||||
}
|
||||
if(isset($p['phase']) && $p['phase'] == 'approve'){//借用审批中
|
||||
$config['where']['status'] = ['in',[10,11,13]];
|
||||
}elseif(isset($p['phase']) && $p['phase'] == 'repaid'){//已全部归还
|
||||
$config['where']['status'] = 17;
|
||||
}elseif(isset($p['phase']) && $p['phase'] == 'unreturned'){ //未归还
|
||||
$config['where']['status'] = ['in',[12,14,15,16,18]];
|
||||
}
|
||||
$config['order']['id'] = 'desc';
|
||||
break;
|
||||
case 'show':
|
||||
$config['where']['id'] = $p['id'];
|
||||
//$config['where']['status'] = 1;
|
||||
break;
|
||||
case 'store':
|
||||
break;
|
||||
case 'update':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'destroy':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 审批
|
||||
* @param Request $request
|
||||
* @return mixed|string[]|null
|
||||
*/
|
||||
public function serviceApprove(Request $request)
|
||||
{
|
||||
$param = $request->all();
|
||||
$attachment = $param['attachment']??[];
|
||||
//$appro = new \app\common\utils\approval\service\ApprovalFlowService();
|
||||
$appro = new \app\common\service\InvRequisitionApproveService();
|
||||
//requisition_id:申请id
|
||||
//approve_id:审核步骤id
|
||||
//action:审批动作:1通过 2驳回
|
||||
//comment:审批意见
|
||||
return $appro->approve($param['requisition_id'], $param['approve_id'], $request->user->uid, $param['action'], $param['comment'], $attachment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员代领
|
||||
* 调用 common 服务层方法
|
||||
*/
|
||||
public function proxyClaim(Request $request, array $data): array
|
||||
{
|
||||
return (new \app\common\service\InvRequisitionService())->proxyClaim($request, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码/代领记录查询
|
||||
* 调用 common 服务层方法
|
||||
*/
|
||||
public function qrClaimsList(Request $request): array
|
||||
{
|
||||
return (new \app\common\service\InvRequisitionService())->qrClaimsList($request);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ namespace app\common\controller;
|
||||
|
||||
use app\common\service\AuthService;
|
||||
use app\common\validate\UserValidate;
|
||||
use Exception;
|
||||
use support\Request;
|
||||
|
||||
class AuthController extends BaseController
|
||||
@@ -32,7 +31,7 @@ class AuthController extends BaseController
|
||||
public function feishuScope(Request $request)
|
||||
{
|
||||
try {
|
||||
$is_mob = $request->get('is_mob', 0);
|
||||
$is_mob = $request->get('is_mob',0);
|
||||
$result = (new AuthService())->feishuAuthorize($request->corp_abbr, $request->system_code, $is_mob);
|
||||
return $this->success($result);
|
||||
} catch (\Throwable $e) {
|
||||
@@ -114,19 +113,4 @@ class AuthController extends BaseController
|
||||
// (new AuthService())->blockToken($token, $systemCode);
|
||||
// return $this->success([], '已强制停用该token');
|
||||
// }
|
||||
|
||||
|
||||
public function getJsApi(Request $request)
|
||||
{
|
||||
try {
|
||||
$url = $request->get('url');
|
||||
if(empty($url)){
|
||||
throw new Exception("url不能为空");
|
||||
}
|
||||
$result = (new AuthService())->getJsApiConfig($request->corp_abbr, $request->system_code,$url);
|
||||
return $this->success($result);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,42 +101,6 @@ class BrandSeriesController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* URL抓取品牌、车系、车型
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function crawlUrl(Request $request){
|
||||
try {
|
||||
$result = $this->service->crawlUrl($request);
|
||||
if($result){
|
||||
return $this->success($result,'抓取成功');
|
||||
}else{
|
||||
return $this->error('抓取任务失败');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 抓取品牌、车系、车型
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function crawl(Request $request){
|
||||
try {
|
||||
$result = $this->service->crawl($request);
|
||||
if($result){
|
||||
return $this->success($result,'抓取成功');
|
||||
}else{
|
||||
return $this->error('抓取任务失败');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存抓取的系列车型
|
||||
* @param Request $request
|
||||
|
||||
@@ -2,14 +2,8 @@
|
||||
namespace app\common\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\model\InvItem;
|
||||
use app\common\model\InvRequisitionItem;
|
||||
use app\common\model\InvRequisitionItemReturn;
|
||||
use app\common\model\InvRequisitionItemReturnAttachment;
|
||||
use app\common\service\OssService;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\common\service\InvRequisitionItemReturnService;
|
||||
use support\Request;
|
||||
|
||||
class InvRequisitionItemReturnController extends BaseController
|
||||
{
|
||||
@@ -22,160 +16,18 @@ class InvRequisitionItemReturnController extends BaseController
|
||||
$this->service = new InvRequisitionItemReturnService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回分页数据及总数
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
try {
|
||||
//$request->setGet('$request');
|
||||
$raw = $this->service->serviceList($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'indexFormat')
|
||||
? [$this, 'indexFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if(isset($data['id'])){
|
||||
$data['return_item'] = InvRequisitionItemReturn::where('return_id', $data['id'])->get();
|
||||
foreach ($data['return_item'] as $key => $value) {
|
||||
$data['return_item'][$key]['item'] = InvItem::where('id', $value['item_id'])->get();
|
||||
}
|
||||
}
|
||||
if (isset($data['return_at']))
|
||||
$data['return_at'] = date('Y-m-d H:i:s', $data['return_at']);
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param int|string $id 资源 ID
|
||||
* @return mixed 返回资源详情数据
|
||||
*/
|
||||
public function show(Request $request)
|
||||
{
|
||||
try {
|
||||
$raw = $this->service->serviceShow($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'showFormat')
|
||||
? [$this, 'showFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function showFormat($data)
|
||||
{
|
||||
foreach ($data['item_return'] as $key => $item){
|
||||
$data['item_return'][$key]['requisition_item'] = InvRequisitionItem::where('id', $item['requisition_item_id'])->first();
|
||||
}
|
||||
if (isset($data['return_at']))
|
||||
$data['return_at'] = date('Y-m-d H:i:s', $data['return_at']);
|
||||
if (isset($data['id'])){
|
||||
//归还附件
|
||||
$data['return_attachment'] = InvRequisitionItemReturnAttachment::where('return_id', $data['id'])->get();
|
||||
$ossservice = new OssService();
|
||||
foreach ($data['return_attachment'] as $item){
|
||||
$item['file_path_pull'] = $ossservice->generatePrivateUrl($item['file_path']);
|
||||
|
||||
}
|
||||
|
||||
//归还审核附件
|
||||
$data['return_approve_attachment'] = InvRequisitionItemReturnAttachment::where('return_id', $data['id'])->get();
|
||||
foreach ($data['return_approve_attachment'] as $item){
|
||||
$item['file_path_pull'] = $ossservice->generatePrivateUrl($item['file_path']);
|
||||
}
|
||||
}
|
||||
/*if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);*/
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回更新成功的数据或信息
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'update');
|
||||
$res = $this->service->serviceUpdate($request, $data);
|
||||
return $this->success([], '更新成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物品归还确认
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function returnItemConfirm(Request $request)
|
||||
{
|
||||
try {
|
||||
// 验证申请数据
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm');
|
||||
// 处理申请逻辑
|
||||
$result = $this->service->serviceReturnItemConfirm($request, $data, 'returnConfirm');
|
||||
|
||||
return $this->success($result, '申请提交成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物品归还确认
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function returnConfirm(Request $request)
|
||||
{
|
||||
try {
|
||||
// 验证申请数据
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm');
|
||||
|
||||
// 处理申请逻辑
|
||||
$result = $this->service->serviceReturnConfirm($request, $data, 'returnConfirm');
|
||||
|
||||
return $this->success($result, '申请提交成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\controller;
|
||||
|
||||
use app\common\traits\ResponseTrait;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use app\common\utils\SystemAuth;
|
||||
use app\common\utils\Jwt;
|
||||
use app\common\model\User;
|
||||
use app\common\model\Systems;
|
||||
use support\Redis;
|
||||
|
||||
class SystemController
|
||||
{
|
||||
use ResponseTrait;
|
||||
|
||||
protected $noNeedLogin = ['auth'];
|
||||
|
||||
protected $noNeedHeaderData = ['auth'];
|
||||
/**
|
||||
* 系统间认证接口
|
||||
* POST /api/system/auth
|
||||
*/
|
||||
public function auth(Request $request): Response
|
||||
{
|
||||
$userId = $request->post('user_id');
|
||||
$timestamp = (int)$request->post('timestamp');
|
||||
$signature = $request->post('signature');
|
||||
$systemCode = $request->post('system_code');
|
||||
|
||||
// 参数验证
|
||||
if (empty($userId) || empty($timestamp) || empty($signature)) {
|
||||
return $this->error('参数不完整', 400);
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
$secret = config('system_auth.shared_secret');
|
||||
$expire = config('system_auth.signature_expire', 600);
|
||||
|
||||
// 验证时间戳(10分钟有效期)
|
||||
if (!SystemAuth::verifyTimestamp($timestamp, $expire)) {
|
||||
return $this->error('请求已过期', 401);
|
||||
}
|
||||
|
||||
// 验证签名
|
||||
if (!SystemAuth::verifySignature($userId, $timestamp, $signature, $secret)) {
|
||||
return $this->error('签名验证失败', 401);
|
||||
}
|
||||
|
||||
// 查找用户
|
||||
$user = User::find($userId);
|
||||
if (!$user) {
|
||||
return $this->error('用户不存在', 404);
|
||||
}
|
||||
|
||||
// 验证系统(如果提供了 system_code)
|
||||
$system = null;
|
||||
if ($systemCode) {
|
||||
$system = Systems::where('code', $systemCode)->first();
|
||||
if (!$system) {
|
||||
return $this->error('系统不存在', 404);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 corp_abbr(优先从请求参数获取,否则通过用户 corp_id 查询)
|
||||
$corpAbbr = $request->post('corp_abbr');
|
||||
if (!$corpAbbr && $user->corp_id) {
|
||||
$corp = \app\common\model\Corp::find($user->corp_id);
|
||||
$corpAbbr = $corp ? $corp->abbr : '';
|
||||
}
|
||||
|
||||
// 构建 JWT payload
|
||||
$payload = $this->buildJwtPayload($user, $system);
|
||||
|
||||
// 生成 access_token
|
||||
$jwt = new Jwt();
|
||||
$token = $jwt->generateToken($payload);
|
||||
|
||||
// 生成 refresh_token
|
||||
$refreshToken = $this->generateRefreshToken($user->id, $systemCode ?? '');
|
||||
|
||||
// 获取 home_url
|
||||
$homeUrl = $system ? $this->getHome($system->id, $payload) : '';
|
||||
|
||||
// 记录 token 到 Redis 和 MySQL
|
||||
$this->recordUserToken($user->id, $token, $systemCode ?? '');
|
||||
|
||||
// 构建用户信息(去除敏感信息)
|
||||
$userInfo = [
|
||||
'id' => $user->id,
|
||||
'sn' => $user->sn ?? '',
|
||||
'name' => $user->name ?? '',
|
||||
'avatar' => $user->avatar ?? '',
|
||||
'phone' => $user->phone ?? '',
|
||||
'email' => $user->email ?? '',
|
||||
'sex' => $user->sex ?? '',
|
||||
'position' => $user->position ?? '',
|
||||
'status' => $user->status ?? 1,
|
||||
'corp_id' => $user->corp_id,
|
||||
];
|
||||
|
||||
return $this->success([
|
||||
'access_token' => $token,
|
||||
'refresh_token' => $refreshToken,
|
||||
'expires_in' => config('jwt.jwt_expiration'),
|
||||
'system_code' => $systemCode ?? '',
|
||||
'corp_abbr' => $corpAbbr ?? '',
|
||||
'login_type' => 'system',
|
||||
'home_url' => $homeUrl,
|
||||
'user_info' => $userInfo,
|
||||
], '认证成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 JWT payload
|
||||
*/
|
||||
private function buildJwtPayload(User $user, ?Systems $system): array
|
||||
{
|
||||
$now = time();
|
||||
$exp = $now + config('jwt.jwt_expiration');
|
||||
$system_ids = $user->systems ? $user->systems->pluck('id')->toArray() : [];
|
||||
$role_ids = $user->roles ? $user->roles->pluck('id')->toArray() : [];
|
||||
$payload = [
|
||||
'sub' => 'user_' . $user->id,
|
||||
'aud' => $system->code,
|
||||
'iat' => $now,
|
||||
'exp' => $exp,
|
||||
'nbf' => $now,
|
||||
'typ' => 'access',
|
||||
'uid' => $user->id,
|
||||
'uname' => $user->name,
|
||||
'role_ids' => $role_ids,
|
||||
'system_ids' => $system_ids,
|
||||
// 'user_id' => $user->id,
|
||||
// 'sn' => $user->sn ?? '',
|
||||
// 'name' => $user->name ?? '',
|
||||
];
|
||||
|
||||
if ($system) {
|
||||
$payload['system_code'] = $system->code;
|
||||
$payload['system_id'] = $system->id;
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 refresh_token
|
||||
*/
|
||||
private function generateRefreshToken(int $userId, string $systemCode): string
|
||||
{
|
||||
$refreshToken = bin2hex(random_bytes(32));
|
||||
|
||||
// 存储到 Redis
|
||||
$key = "refresh_token:{$refreshToken}";
|
||||
$expire = config('jwt.jwt_refresh_token_expiration');
|
||||
Redis::setex($key, $expire, json_encode([
|
||||
'user_id' => $userId,
|
||||
'system_code' => $systemCode,
|
||||
]));
|
||||
|
||||
return $refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户首页地址
|
||||
*/
|
||||
private function getHome(int $systemId, array $payload): string
|
||||
{
|
||||
// 简单实现,可以根据实际需求调整
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录用户token到 Redis 和 MySQL
|
||||
*/
|
||||
private function recordUserToken(int $userId, string $token, string $systemCode): void
|
||||
{
|
||||
$request = request();
|
||||
$ip = $request ? $request->getRealIp() : '';
|
||||
$ua = $request ? $request->header('user-agent', '') : '';
|
||||
$now = time();
|
||||
$expireAt = $now + config('jwt.jwt_expiration');
|
||||
|
||||
// Redis Set 用户token集合
|
||||
Redis::sAdd("user_tokens:{$userId}:{$systemCode}", $token);
|
||||
Redis::expire("user_tokens:{$userId}:{$systemCode}", config('jwt.jwt_expiration'));
|
||||
|
||||
// Redis Hash token元信息
|
||||
$meta = [
|
||||
'system_code' => $systemCode,
|
||||
'login_ip' => $ip,
|
||||
'user_agent' => $ua,
|
||||
'login_time' => $now,
|
||||
'expired_at' => $expireAt,
|
||||
];
|
||||
Redis::hMSet("user_token_meta:{$token}", $meta);
|
||||
Redis::expire("user_token_meta:{$token}", config('jwt.jwt_expiration'));
|
||||
|
||||
// MySQL 持久化
|
||||
\app\common\model\UserTokenLog::create([
|
||||
'user_id' => $userId,
|
||||
'token' => $token,
|
||||
'system_code' => $systemCode,
|
||||
'login_ip' => $ip,
|
||||
'user_agent' => $ua,
|
||||
'expired_at' => $expireAt,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -40,9 +40,8 @@ class InvItem extends Model
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'company_id', 'item_code', 'item_name',
|
||||
'category_id', 'spec_model', 'unit', 'is_consumable', 'allow_qr_claim', 'qr_code', 'qr_code_num', 'qr_code_url',
|
||||
'stock_qty', 'manage_user_id', 'location', 'remark',
|
||||
protected $fillable = ['id', 'company_id', 'item_code', 'item_name',
|
||||
'category_id', 'spec_model', 'unit', 'is_consumable', 'stock_qty', 'manage_user_id', 'location', 'remark',
|
||||
'sort', 'status',
|
||||
'created_at', 'updated_at'];
|
||||
|
||||
|
||||
@@ -40,42 +40,19 @@ class InvRequisition extends Model
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'order_no', 'applicant_company_id', 'dept_id', 'applicant_id', 'applicant_name', 'leader_id', 'manager_id', 'borrow_reason', 'use_start_date', 'use_end_date', 'status', 'claim_type', 'qr_claim_time', 'proxy_claim_user_id', 'proxy_claim_user_name', 'is_returned', 'remark', 'created_at', 'updated_at'];
|
||||
protected $fillable = ['id', 'order_no', 'applicant_company_id', 'dept_id', 'applicant_id', 'applicant_name', 'leader_id', 'manager_id', 'borrow_reason', 'use_start_date', 'use_end_date', 'status', 'is_returned', 'remark', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
// 领取方式常量
|
||||
const CLAIM_TYPE_NORMAL = 1; // 正常申请
|
||||
const CLAIM_TYPE_QR = 2; // 扫码领取
|
||||
const CLAIM_TYPE_PROXY = 3; // 管理员代领
|
||||
|
||||
/**
|
||||
* 领取方式文本
|
||||
*/
|
||||
public static function getClaimTypeText($type)
|
||||
{
|
||||
return [
|
||||
self::CLAIM_TYPE_NORMAL => '正常申请',
|
||||
self::CLAIM_TYPE_QR => '扫码领取',
|
||||
self::CLAIM_TYPE_PROXY => '管理员代领',
|
||||
][$type] ?? '未知';
|
||||
}
|
||||
const STATUS_DRAFT = 0; // 草稿
|
||||
const STATUS_LEADER = 10; // 待直属上级审批
|
||||
const STATUS_MANAGE = 20; // 待管理员审批
|
||||
const STATUS_APPROVED = 30; // 已通过
|
||||
const STATUS_REJECTEDT = 40; // 已驳回
|
||||
const STATUS_CANCELED = 50; // 已取消
|
||||
|
||||
public function approval()
|
||||
{
|
||||
return $this->hasMany('app\common\model\InvRequisitionApprove',
|
||||
'requisition_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 领用明细关联
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany('app\common\model\InvRequisitionItem',
|
||||
'requisition_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -46,10 +46,4 @@ class InvRequisitionApprove extends Model
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
public function requisition()
|
||||
{
|
||||
return $this->belongsTo('app\common\model\InvRequisition',
|
||||
'requisition_id','id');
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
class InvRequisitionApproveAttachment extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'mysql';
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'inv_requisition_approve_attachment';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = true;
|
||||
|
||||
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'requisition_id', 'approve_id', 'file_name', 'file_path', 'file_size', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -46,12 +46,4 @@ class InvRequisitionItem extends Model
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 关联领用申请主表
|
||||
*/
|
||||
public function requisition()
|
||||
{
|
||||
return $this->belongsTo('app\common\model\InvRequisition', 'requisition_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class InvRequisitionItemReturn extends Model
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'return_id', 'requisition_id', 'requisition_item_id', 'item_id', 'apply_user_id', 'apply_user_name', 'return_qty', 'status', 'handler_id', 'handler_name', 'return_status', 'apply_remark', 'handle_remark', 'return_at', 'created_at', 'updated_at'];
|
||||
protected $fillable = ['id', 'requisition_id', 'requisition_item_id', 'item_id', 'apply_user_id', 'apply_user_name', 'return_qty', 'status', 'handler_id', 'handler_name', 'return_status', 'apply_remark', 'handle_remark', 'return_at', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
class InvRequisitionReturnApproveAttachment extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'mysql';
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'inv_requisition_return_approve_attachment';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = true;
|
||||
|
||||
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = [];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
/**
|
||||
* 物品库存变化记录模型
|
||||
*/
|
||||
class InvStockLog extends Model
|
||||
{
|
||||
protected $table = 'inv_stock_log';
|
||||
|
||||
protected $fillable = [
|
||||
'company_id',
|
||||
'item_id',
|
||||
'item_name_snap',
|
||||
'change_type',
|
||||
'change_qty',
|
||||
'before_qty',
|
||||
'after_qty',
|
||||
'biz_type',
|
||||
'biz_no',
|
||||
'operator_id',
|
||||
'operator_name',
|
||||
'remark',
|
||||
'updated_at',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = true;
|
||||
|
||||
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
public const CHANGE_TYPE_IN = 1; // 入库
|
||||
public const CHANGE_TYPE_OUT_CLAIM = 2; // 出库(领用)
|
||||
public const CHANGE_TYPE_OUT_LOSS = 3; // 出库(损耗)
|
||||
public const CHANGE_TYPE_IN_RETURN = 4; // 入库(归还)
|
||||
|
||||
public const BIZ_TYPE_PURCHASE = 1; // 采购入库
|
||||
public const BIZ_TYPE_QR_CLAIM = 2; // 扫码领取
|
||||
public const BIZ_TYPE_PROXY_CLAIM = 3; // 管理员代领
|
||||
public const BIZ_TYPE_NORMAL_CLAIM = 4; // 正常领用(审批后)
|
||||
public const BIZ_TYPE_RETURN = 5; // 归还入库
|
||||
public const BIZ_TYPE_LOSS = 6; // 损耗出库
|
||||
|
||||
/**
|
||||
* 变动类型文本
|
||||
*/
|
||||
public static function getChangeTypeText($type)
|
||||
{
|
||||
return [
|
||||
self::CHANGE_TYPE_IN => '入库',
|
||||
self::CHANGE_TYPE_OUT_CLAIM => '出库(领用)',
|
||||
self::CHANGE_TYPE_OUT_LOSS => '出库(损耗)',
|
||||
self::CHANGE_TYPE_IN_RETURN => '入库(归还)',
|
||||
][$type] ?? '未知';
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务类型文本
|
||||
*/
|
||||
public static function getBizTypeText($type)
|
||||
{
|
||||
return [
|
||||
self::BIZ_TYPE_PURCHASE => '采购入库',
|
||||
self::BIZ_TYPE_QR_CLAIM => '扫码领取',
|
||||
self::BIZ_TYPE_PROXY_CLAIM => '管理员代领',
|
||||
self::BIZ_TYPE_NORMAL_CLAIM => '正常领用',
|
||||
self::BIZ_TYPE_RETURN => '归还入库',
|
||||
self::BIZ_TYPE_LOSS => '损耗出库',
|
||||
][$type] ?? '未知';
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联物品
|
||||
*/
|
||||
public function item()
|
||||
{
|
||||
return $this->belongsTo(InvItem::class, 'item_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -86,20 +86,4 @@ class AuthService
|
||||
{
|
||||
(new AuthLogic())->blockToken($token, $systemCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取jsapi配置
|
||||
* @param string $corpAbbr
|
||||
* @param string $systemCcode
|
||||
* @param string $url 当前页面完整 URL(不包含 # 后面的内容)
|
||||
* @return array
|
||||
*/
|
||||
public function getJsApiConfig(string $corpAbbr, string $systemCcode, string $url)
|
||||
{
|
||||
$logic = new AuthLogic();
|
||||
$certificate = $logic->feishuAppInfo($corpAbbr, $systemCcode);
|
||||
$feishu = new Feishu($certificate['app_id'], $certificate['app_secret'], $certificate['abbr']);
|
||||
$jsApi = $feishu->getJsApiConfig($url);
|
||||
return $jsApi;
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,9 @@
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\logic\InvItemLogic;
|
||||
use app\common\model\User;
|
||||
use app\common\validate\InvItemValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InvItem;
|
||||
use support\Redis;
|
||||
use support\Request;
|
||||
use support\exception\BusinessException;
|
||||
|
||||
@@ -113,55 +111,12 @@ class InvItemService
|
||||
$data['category_id'] = 0;
|
||||
$data['spec_model'] = '';
|
||||
$data['unit'] = '件';
|
||||
$data['is_consumable'] = 0;
|
||||
$data['stock_qty'] = $data['stock_qty']??1;
|
||||
$data['location'] = '';
|
||||
|
||||
Redis::set('inv_store_u_stock', $request->user->uid, 'EX', 30);
|
||||
|
||||
return $data;
|
||||
}
|
||||
public function afterServiceStore($res)
|
||||
{
|
||||
$uid = redis::get('inv_store_u_stock');
|
||||
$name = $uid ? User::where('id', $uid)->value('name') : '';
|
||||
Redis::del('inv_store_u_stock');
|
||||
// 记录库存变化日志
|
||||
$this->recordStockLog([
|
||||
'item_id' => $res['id'],
|
||||
'item_name_snap' => $res['item_name'],
|
||||
'change_qty' => $res['stock_qty'],
|
||||
'before_qty' => 0,
|
||||
'after_qty' => $res['stock_qty'],
|
||||
'biz_type' => 1,
|
||||
'biz_no' => '',
|
||||
'operator_id' => $uid,
|
||||
'operator_name' => $name,
|
||||
'remark' => '初始数量',
|
||||
], $res['stock_qty']);
|
||||
}
|
||||
|
||||
public function beforeServiceUpdate($data, Request $request)
|
||||
{
|
||||
$uid = $request->user->uid;
|
||||
$name = $uid ? User::where('id', $uid)->value('name') : '';
|
||||
$item = InvItem::where('id', $data['id'])->first();
|
||||
$change_qty = $data['stock_qty'] - $item['stock_qty'];
|
||||
// 记录库存变化日志
|
||||
$this->recordStockLog([
|
||||
'item_id' => $data['id'],
|
||||
'item_name_snap' => $data['item_name'],
|
||||
'change_qty' => $change_qty,
|
||||
'before_qty' => $item['stock_qty'],
|
||||
'after_qty' => $data['stock_qty'],
|
||||
'biz_type' => 1,
|
||||
'biz_no' => '',
|
||||
'operator_id' => $uid,
|
||||
'operator_name' => $name,
|
||||
'remark' => '管理员修改数量',
|
||||
], $change_qty);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变动物品库存数量
|
||||
@@ -169,29 +124,16 @@ class InvItemService
|
||||
* @param int $itemId 物品ID
|
||||
* @param int $changeQty 变动数量:>0 入库,<0 出库
|
||||
* @param bool $allowNegative 是否允许库存变成负数,默认不允许
|
||||
* @param array $options 额外选项(用于记录日志)
|
||||
* - change_type: 变动类型
|
||||
* - biz_type: 业务类型
|
||||
* - biz_no: 单据号
|
||||
* - operator_id: 操作人ID
|
||||
* - operator_name: 操作人姓名
|
||||
* - remark: 备注
|
||||
*
|
||||
* @return InvItem 最新的物品记录
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function changeStock(int $itemId, int $changeQty, bool $allowNegative = false, array $options = []): InvItem
|
||||
public function changeStock(int $itemId, int $changeQty, bool $allowNegative = false): InvItem
|
||||
{
|
||||
if ($changeQty === 0) {
|
||||
throw new BusinessException('库存变动数量不能为 0');
|
||||
}
|
||||
|
||||
// 获取变动前的库存(用于日志)
|
||||
$itemBefore = InvItem::query()->find($itemId);
|
||||
if (!$itemBefore) {
|
||||
throw new BusinessException('物品不存在');
|
||||
}
|
||||
$beforeQty = $itemBefore->stock_qty;
|
||||
|
||||
$now = time();
|
||||
|
||||
// 构建查询
|
||||
@@ -212,102 +154,39 @@ class InvItemService
|
||||
// 更新不到行:
|
||||
// 1) 物品不存在
|
||||
// 2) 或者库存不足(不允许负数时)
|
||||
$exists = InvItem::query()->where('id', $itemId)->exists();
|
||||
if (! $exists) {
|
||||
throw new BusinessException('物品不存在');
|
||||
}
|
||||
throw new BusinessException('库存不足,无法完成库存变动');
|
||||
}
|
||||
|
||||
// 再查一次最新数据返回(在外层事务中也会保持一致)
|
||||
/** @var InvItem $item */
|
||||
$item = InvItem::query()->find($itemId);
|
||||
|
||||
// 记录库存变化日志
|
||||
$this->recordStockLog([
|
||||
'item_id' => $itemId,
|
||||
'item_name_snap' => $item->item_name,
|
||||
'change_qty' => $changeQty,
|
||||
'before_qty' => $beforeQty,
|
||||
'after_qty' => $item->stock_qty,
|
||||
'change_type' => $options['change_type'] ?? null,
|
||||
'biz_type' => $options['biz_type'] ?? null,
|
||||
'biz_no' => $options['biz_no'] ?? null,
|
||||
'operator_id' => $options['operator_id'] ?? null,
|
||||
'operator_name' => $options['operator_name'] ?? null,
|
||||
'remark' => $options['remark'] ?? null,
|
||||
], $changeQty);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 出库(减库存,默认不允许负数)
|
||||
*
|
||||
* @param int $itemId 物品ID
|
||||
* @param int $qty 出库数量
|
||||
* @param bool $allowNegative 是否允许负数
|
||||
* @param array $options 日志选项(同 changeStock)
|
||||
* @return InvItem
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function stockOut(int $itemId, int $qty, bool $allowNegative = false, array $options = []): InvItem
|
||||
public function stockOut(int $itemId, int $qty, bool $allowNegative = false): InvItem
|
||||
{
|
||||
if ($qty <= 0) {
|
||||
throw new BusinessException('出库数量必须大于 0');
|
||||
}
|
||||
// 确定变动类型:2-出库(领用)或 3-出库(损耗)
|
||||
$changeType = $options['change_type'] ?? \app\common\model\InvStockLog::CHANGE_TYPE_OUT_CLAIM;
|
||||
|
||||
return $this->changeStock($itemId, -$qty, $allowNegative, array_merge($options, [
|
||||
'change_type' => $changeType,
|
||||
'remark' => $options['remark'] ?? '领用出库',
|
||||
]));
|
||||
return $this->changeStock($itemId, -$qty, $allowNegative);
|
||||
}
|
||||
|
||||
/**
|
||||
* 入库(加库存)
|
||||
*
|
||||
* @param int $itemId 物品ID
|
||||
* @param int $qty 入库数量
|
||||
* @param array $options 日志选项(同 changeStock)
|
||||
* @return InvItem
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function stockIn(int $itemId, int $qty, array $options = []): InvItem
|
||||
public function stockIn(int $itemId, int $qty): InvItem
|
||||
{
|
||||
if ($qty <= 0) {
|
||||
throw new BusinessException('入库数量必须大于 0');
|
||||
}
|
||||
// 确定变动类型:1-入库 或 4-入库(归还)
|
||||
$changeType = $options['change_type'] ?? \app\common\model\InvStockLog::CHANGE_TYPE_IN;
|
||||
|
||||
return $this->changeStock($itemId, $qty, true, array_merge($options, [
|
||||
'change_type' => $changeType,
|
||||
'remark' => $options['remark'] ?? '入库',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录库存变化日志
|
||||
*
|
||||
* @param array $logData
|
||||
* @param int $changeQty 变动数量
|
||||
* @return void
|
||||
*/
|
||||
private function recordStockLog(array $logData, int $changeQty): void
|
||||
{
|
||||
try {
|
||||
// 根据变动数量确定变动类型(如果未指定)
|
||||
if (!isset($logData['change_type'])) {
|
||||
if ($changeQty > 0) {
|
||||
$logData['change_type'] = \app\common\model\InvStockLog::CHANGE_TYPE_IN;
|
||||
} else {
|
||||
$logData['change_type'] = \app\common\model\InvStockLog::CHANGE_TYPE_OUT_CLAIM;
|
||||
}
|
||||
}
|
||||
|
||||
(new InvStockLogService())->record($logData);
|
||||
} catch (\Throwable $e) {
|
||||
// 日志记录失败不影响主业务,仅记录错误
|
||||
error_log('库存日志记录失败: ' . $e->getMessage());
|
||||
}
|
||||
return $this->changeStock($itemId, $qty, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\model\InvItem;
|
||||
use app\common\model\User;
|
||||
use app\common\validate\InvRequisitionApproveValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InvRequisitionApprove;
|
||||
use support\Db;
|
||||
use support\exception\BusinessException;
|
||||
|
||||
class InvRequisitionApproveService
|
||||
{
|
||||
@@ -33,239 +29,5 @@ class InvRequisitionApproveService
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $flowType
|
||||
* @param string $bizType
|
||||
* @param string $bizId
|
||||
* @param array $formData ['manage_user_id'=>23]//物品管理员
|
||||
* @param int $initiatorId //申请人id
|
||||
* @return array
|
||||
*/
|
||||
public function start(string $flowType, string $bizType, string $bizId, array $formData, int $initiatorId): array
|
||||
{
|
||||
return Db::transaction(function () use ($flowType, $bizType, $bizId, $formData, $initiatorId) {
|
||||
$flow = Db::table('approval_flows')->where('type', $flowType)->where('is_active', 1)->first();
|
||||
if (!$flow) throw new BusinessException("审批流程未找到或已停用: {$flowType}");
|
||||
|
||||
$steps = json_decode($flow->steps, true);
|
||||
if (!is_array($steps) || empty($steps)) throw new BusinessException("流程步骤配置错误");
|
||||
|
||||
// 找首个有效步骤索引(考虑条件)
|
||||
$firstIndex = $this->getNextStepIndex($steps, $formData, -1);
|
||||
if ($firstIndex === null) throw new BusinessException("未找到可执行的审批步骤");
|
||||
$firstStep = $steps[$firstIndex];
|
||||
|
||||
//$now = date('Y-m-d H:i:s');
|
||||
$now = time();
|
||||
|
||||
|
||||
$service = new \app\common\utils\approval\service\ApprovalFlowService();
|
||||
|
||||
// 解析首步审批人(支持 role_id 或 roles.name)
|
||||
$instance = (object)[
|
||||
'initiator_id' => $initiatorId,
|
||||
'form_data'=>json_encode($formData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
||||
];
|
||||
$approverIds = $service->StetApprovers($firstStep, $instance, true);
|
||||
|
||||
if(empty($approverIds)){
|
||||
throw new BusinessException('未解析到任何审批人');
|
||||
}
|
||||
$uid = array_shift($approverIds);
|
||||
$approver = User::where('id', $uid)->first();
|
||||
|
||||
$approveId = Db::table('inv_requisition_approve')->insertGetId([
|
||||
'requisition_id' => $bizId, //申请单ID
|
||||
'node_type' => $bizType,
|
||||
'approver_id' => $approver->id,
|
||||
'approver_name' => $approver->name,
|
||||
'action' => 0,
|
||||
'comment' => '',
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
// foreach ($approverIds as $uid) {
|
||||
// $this->insertApprovalRecord($instance, $firstIndex, $uid);
|
||||
// }
|
||||
|
||||
return ['instance_id' => $approveId];
|
||||
});
|
||||
}
|
||||
|
||||
/** 执行审批 */
|
||||
public function approve(int $requisitionId, int $approverId, int $uid, string $action, string $comment = '', array $attachment = [])
|
||||
{
|
||||
if (!in_array($action, ['1','2'], true)) { //审批动作:1通过 2驳回
|
||||
throw new BusinessException("无效的审批操作");
|
||||
}
|
||||
|
||||
return Db::transaction(function () use ($requisitionId, $approverId, $uid, $action, $comment, $attachment) {
|
||||
// $instance = Db::table('approval_instances')->where('id', $instanceId)->lockForUpdate()->first();
|
||||
$requisition = Db::table('inv_requisition')->where('id', $requisitionId)->lockForUpdate()->first();
|
||||
if (!$requisition) throw new BusinessException("审批实例未找到");
|
||||
if ($requisition->status !== 10 && $requisition->status !== 11) {
|
||||
return ['status' => 'noop', 'msg' => '实例未处理'];
|
||||
}
|
||||
|
||||
//审批流程
|
||||
$flow = Db::table('approval_flows')->where('type', 'inv_requisition')->first();
|
||||
if (!$flow) throw new BusinessException("审批流程定义未找到");
|
||||
|
||||
$steps = json_decode($flow->steps, true);
|
||||
//$idx = (int)$requisition->current_step;
|
||||
//$step = $steps[$idx] ?? null;
|
||||
//if (!$step) throw new BusinessException("当前步骤配置错误");
|
||||
|
||||
// 找到该用户在本步的 pending 记录(加锁)
|
||||
$pendingRecord = Db::table('inv_requisition_approve')
|
||||
->where('requisition_id', $requisitionId)
|
||||
->where('id', $approverId)
|
||||
->where('action', 0)
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
if (!$pendingRecord) {
|
||||
// 已处理过?
|
||||
$anyRecord = Db::table('inv_requisition_approve')
|
||||
->where('requisition_id', $requisitionId)
|
||||
->where('id', $approverId)
|
||||
->first();
|
||||
if ($anyRecord && $anyRecord->action > 0) {
|
||||
return ['status' => 'noop', 'msg' => '已处理'];
|
||||
}
|
||||
// 步骤已推进
|
||||
// if ((int)$requisition->current_step !== $idx) {
|
||||
// return ['status' => 'noop', 'msg' => '非当前审批'];
|
||||
// }
|
||||
return ['status' => 'noop', 'msg' => '无待处理记录'];
|
||||
} else if ($pendingRecord->approver_id != $uid) { //检查当前用户是否为审核人
|
||||
return ['status' => 'noop', 'msg' => '无审核权限'];
|
||||
}
|
||||
|
||||
$now = time();
|
||||
|
||||
// 1) 更新当前人的审批记录
|
||||
Db::table('inv_requisition_approve')->where('id', $pendingRecord->id)->update([
|
||||
'action' => $action,
|
||||
'comment' => $comment,
|
||||
'action_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
foreach ($attachment as $attac) {
|
||||
Db::table('inv_requisition_approve_attachment')->insertGetId([
|
||||
'requisition_id' => $requisitionId,
|
||||
'approve_id' => $approverId,
|
||||
'file_name' => $attac['original_name'],
|
||||
'file_path' => $attac['file_path'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
// 2) 已通过步骤与总步数相等则结束审核流程
|
||||
$pass = Db::table('inv_requisition_approve')
|
||||
->where('requisition_id', $requisitionId)
|
||||
->where('action', 1)
|
||||
->count();
|
||||
if($action == 1){
|
||||
if(count($steps) == $pass){
|
||||
//判断是否都是消耗品,是否需要归还
|
||||
$requisitionItem = Db::table('inv_requisition_item')
|
||||
->where('requisition_id', $requisition->id)
|
||||
->where('is_consumable_snap', 0)
|
||||
->get();
|
||||
if($requisitionItem){
|
||||
Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>12]);
|
||||
}else{
|
||||
Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>19]);
|
||||
}
|
||||
|
||||
//更改库存
|
||||
$requisitionItem = Db::table('inv_requisition_item')
|
||||
->where('requisition_id', $requisition->id)
|
||||
->get();
|
||||
foreach ($requisitionItem as $item) {
|
||||
//$invItem = InvItem::where('id', $item->item_id)->first();
|
||||
(new InvItemService())->stockOut($item->item_id,$item->approved_qty);
|
||||
}
|
||||
|
||||
// $requisition->status = 12;
|
||||
// $requisition->save();
|
||||
return ['status' => 'complete', 'msg' => '已通过'];
|
||||
}
|
||||
}
|
||||
|
||||
// 3) 拒绝 => 结束
|
||||
if($action == 2){
|
||||
Db::table('inv_requisition_approve')->where('id', $pendingRecord->id)->update([
|
||||
'action' => $action,
|
||||
'comment' => $comment,
|
||||
'approved_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
//if(count($steps) == $pass){
|
||||
Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>13]);
|
||||
return ['status' => 'complete', 'msg' => '拒绝'];
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// 4) 通过 => 进入下一步
|
||||
Db::table('inv_requisition')->where('id', $requisitionId)->update(['status'=>11]);
|
||||
$requisitionItem = Db::table('inv_requisition_item')->where('requisition_id', $requisitionId)->first();
|
||||
$item_id = Db::table('inv_item')->where('id', $requisitionItem->item_id)->first();
|
||||
$formData = ['manage_user_id'=>$item_id->manage_user_id];
|
||||
|
||||
$nextIndex = $pass;
|
||||
$nextStep = $steps[$nextIndex];
|
||||
$service = new \app\common\utils\approval\service\ApprovalFlowService();
|
||||
|
||||
$instance = (object)[
|
||||
'initiator_id' => $requisition->applicant_id, //申请人id
|
||||
'form_data'=>json_encode($formData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
||||
];
|
||||
$approverIds = $service->StetApprovers($nextStep, $instance, true);
|
||||
// if($approverIds == "manage_user_id"){ //物品管理人审核步骤查询管理人
|
||||
// $requisitionItem = Db::table('inv_requisition_item')->where('id', $requisitionId)->first();
|
||||
// $invItem = Db::table('inv_requisition_item')->where('id', $requisitionItem->item_id)->first();
|
||||
//
|
||||
// if(empty($invItem)){
|
||||
// return ['status' => 'noop', 'msg' => '未查询到物品管理人'];
|
||||
// }
|
||||
// $approverIds = [$invItem->manage_user_id];
|
||||
// }
|
||||
|
||||
$approver = User::where('id', array_pop($approverIds))->first();
|
||||
Db::table('inv_requisition_approve')->insertGetId([
|
||||
'requisition_id' => $requisitionId, //申请单ID
|
||||
'node_type' => $nextStep['approvers'][0]['value'],
|
||||
'approver_id' => $approver->id,
|
||||
'approver_name' => $approver->name,
|
||||
'action' => 0,
|
||||
'comment' => '',
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);;
|
||||
return ['status' => 'complete', 'msg' => '已通过'];
|
||||
});
|
||||
}
|
||||
|
||||
// public function insertApprovalRecord()
|
||||
// {
|
||||
// }
|
||||
|
||||
|
||||
/** 获取下一个有效步骤索引 */
|
||||
private function getNextStepIndex(array $steps, array $formData, int $currentStepIndex): ?int
|
||||
{
|
||||
for ($i = $currentStepIndex + 1; $i < count($steps); $i++) {
|
||||
$s = $steps[$i];
|
||||
if (empty($s['condition'])) {
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,19 +2,16 @@
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\model\InvItem;
|
||||
use app\common\model\InvRequisition;
|
||||
use app\common\model\InvRequisitionItem;
|
||||
use app\common\model\InvRequisitionReturn;
|
||||
use app\common\model\InvStockLog;
|
||||
use app\common\model\User;
|
||||
use app\common\service\UserService;
|
||||
use app\common\validate\InvRequisitionItemReturnValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InvRequisitionItemReturn;
|
||||
use support\Request;
|
||||
use support\Db;
|
||||
use support\exception\BusinessException;
|
||||
use app\common\service\UserService;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use app\common\model\InvRequisitionItemReturnAttachment;
|
||||
use function Symfony\Component\String\u;
|
||||
@@ -122,16 +119,14 @@ class InvRequisitionItemReturnService
|
||||
$data['applicant_id'] = $user['user']['id'];
|
||||
$data['applicant_name'] = $user['user']['name'];
|
||||
|
||||
//$reqItemId = $data['requisition_id'];
|
||||
$reqItemId = $data['requisition_id'];
|
||||
$arr = [];
|
||||
foreach ($reqItemsArr as $reqItem) {
|
||||
$reqItemId = $reqItem['id'];
|
||||
|
||||
// 检查是否有对应的新申请项数据
|
||||
if (!isset($newReqItems[$reqItemId])) {
|
||||
continue;
|
||||
}
|
||||
$item = InvItem::where('id', $reqItem['item_id'])->first();
|
||||
$manage = User::where('id',$item['manage_user_id'])->first();
|
||||
|
||||
$arr[] = [
|
||||
'requisition_id' => $data['requisition_id'],
|
||||
@@ -140,15 +135,11 @@ class InvRequisitionItemReturnService
|
||||
'apply_user_id' => $user['user']['id'],
|
||||
'apply_user_name' => $user['user']['name'],
|
||||
'return_qty' => $newReqItems[$reqItemId]['return_qty'] ?: '1',
|
||||
'apply_remark' => $data['apply_remark'] ?? '',
|
||||
'handler_id' => $item['manage_user_id'] ?? 0,
|
||||
'handler_name' => $manage['name'] ?? '',
|
||||
'apply_remark' => $newReqItems[$reqItemId]['apply_remark'] ?? '',
|
||||
//'attachment' => $newReqItems[$reqItemId]['attachment'],
|
||||
//'return_at' => time(),
|
||||
'return_at' => $data['return_at'],
|
||||
];
|
||||
$data['handler_id'] = $item['manage_user_id'] ?? 0;
|
||||
$data['handler_name'] = $manage['name'] ?? '';
|
||||
}
|
||||
$data['items'] =$arr;
|
||||
|
||||
@@ -184,18 +175,10 @@ class InvRequisitionItemReturnService
|
||||
$created = [];
|
||||
foreach ($items as $item) {
|
||||
//$created = $this->logicCreate($item, $dl);
|
||||
$item['return_id'] = $res->id;
|
||||
$item['requisition_id'] = $data['requisition_id'];
|
||||
$item['return_at'] = $data['return_at'];
|
||||
$item['apply_remark'] = $data['apply_remark'];
|
||||
$created = $this->logicCreate($item);
|
||||
}
|
||||
$this->processRequisitionItemReturnAttachment($res, $attachment);
|
||||
InvRequisition::where('id',$request->post('requisition_id'))->update(
|
||||
['status' => 14] //审批状态:10默认、11审批中、12已审批(待归还)、13拒绝、14申请归还、15归还审核中、16部分归还、17已全部归还、18已拒绝、19已审批(无需归还)
|
||||
);
|
||||
$this->postProcess('Store', $created);
|
||||
return $res;
|
||||
return $this->postProcess('Store', $created);
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
throw new BusinessException("创建物品申请失败:" . $e->getMessage().$e->getTraceAsString());
|
||||
@@ -233,72 +216,9 @@ class InvRequisitionItemReturnService
|
||||
// ]
|
||||
// ]
|
||||
// ];
|
||||
|
||||
try {
|
||||
$approved = InvRequisitionItemReturn::where('return_id',$data['id'])
|
||||
->where('status','>',0)
|
||||
->count();
|
||||
if ($approved > 0) {
|
||||
throw new BusinessException('已审核禁止编辑');
|
||||
}
|
||||
|
||||
// 获取所有申请项ID
|
||||
$reqItemIds = array_column($data['items'], 'requisition_item_id');
|
||||
|
||||
// 参数校验
|
||||
if (empty($reqItemIds)) {
|
||||
throw new BusinessException('未提供有效的申请项ID');
|
||||
}
|
||||
|
||||
// 将申请项按 ID 重组为关联数组
|
||||
$newReqItems = $this->groupArrayByKey($data['items'], 'requisition_item_id');
|
||||
|
||||
$data['return_at'] = is_int($data['return_at']) ? $data['return_at']: strtotime($data['return_at']);
|
||||
|
||||
// 获取申请项明细
|
||||
$reqItemsArr = InvRequisitionItem::whereIn('id', $reqItemIds)->get()->toArray();
|
||||
|
||||
// 检查是否获取到有效数据
|
||||
if (empty($reqItemsArr)) {
|
||||
throw new BusinessException('未找到对应的申请项');
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
$userService = new UserService();
|
||||
$user = $userService->getUserInfo($request->user->uid, '');
|
||||
$data['applicant_id'] = $user['user']['id'];
|
||||
$data['applicant_name'] = $user['user']['name'];
|
||||
|
||||
//$reqItemId = $data['requisition_id'];
|
||||
$arr = [];
|
||||
foreach ($reqItemsArr as $reqItem) {
|
||||
$reqItemId = $reqItem['id'];
|
||||
// 检查是否有对应的新申请项数据
|
||||
if (!isset($newReqItems[$reqItemId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arr[] = [
|
||||
'requisition_id' => $data['requisition_id'],
|
||||
'requisition_item_id' => $reqItem['id'],
|
||||
'item_id' => $reqItem['item_id'],
|
||||
'apply_user_id' => $user['user']['id'],
|
||||
'apply_user_name' => $user['user']['name'],
|
||||
'return_qty' => $newReqItems[$reqItemId]['return_qty'] ?: '1',
|
||||
'apply_remark' => $data['apply_remark'] ?? '',
|
||||
//'attachment' => $newReqItems[$reqItemId]['attachment'],
|
||||
//'return_at' => time(),
|
||||
'return_at' => $data['return_at'],
|
||||
];
|
||||
}
|
||||
$data['items'] =$arr;
|
||||
|
||||
return $data;
|
||||
} catch (BusinessException $e) {
|
||||
throw $e;
|
||||
} catch (\Throwable $th) {
|
||||
throw new BusinessException('创建物品归还申请失败:' . $th->getMessage());
|
||||
}
|
||||
|
||||
$data['return_at'] = time();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,37 +234,20 @@ class InvRequisitionItemReturnService
|
||||
// 关联表增加事务处理
|
||||
return Db::transaction(function () use ($request, $data) {
|
||||
$data = $this->preProcess('Update', $data, $request);
|
||||
//$config = $this->buildQueryConfig($request, 'update');
|
||||
$config = $this->buildQueryConfig($request, 'update');
|
||||
|
||||
$attachment = $data['attachment'];
|
||||
unset($data['attachment']);
|
||||
$items = $data['items'];
|
||||
unset($data['items']);
|
||||
|
||||
|
||||
$config = [];
|
||||
$config['model'] = InvRequisitionReturn::class;
|
||||
$config['where']['id'] = $request->post('id');
|
||||
$returnService = new InvRequisitionReturnService();
|
||||
$returnService->logicUpdateBy($config, $data);
|
||||
|
||||
InvRequisitionItemReturn::where('return_id',$data['id'])->delete();
|
||||
foreach ($items as $item) {
|
||||
$item['return_id'] = $data['id'];
|
||||
$item['requisition_id'] = $data['requisition_id'];
|
||||
$item['return_at'] = $data['return_at'];
|
||||
$item['apply_remark'] = $data['apply_remark'];
|
||||
$created = $this->logicCreate($item);
|
||||
//$this->logicUpdateBy($config, $data);
|
||||
}
|
||||
$this->logicUpdateBy($config, $data);
|
||||
// 获取更新后的完整记录
|
||||
$updated = $returnService->logicShow($config);
|
||||
$updated = $this->logicShow($config);
|
||||
// 处理附件更新
|
||||
$this->processRequisitionItemReturnAttachment($updated, $attachment, true);
|
||||
return $this->postProcess('Update', $updated);
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
throw new BusinessException("更新物品归还申请失败:" . $e->getMessage().$e->getLine().$e->getFile().$e->getTraceAsString());
|
||||
throw new BusinessException("更新物品归还申请失败:" . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,13 +295,11 @@ class InvRequisitionItemReturnService
|
||||
* @return array|bool
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function serviceReturnItemConfirm(Request $request, array $data, string $scene = 'returnConfirm')
|
||||
public function serviceReturnConfirm(Request $request, array $data, string $scene = 'returnConfirm')
|
||||
{
|
||||
try {
|
||||
$attachment = $request->post('attachment') ?? [];
|
||||
unset($data['attachment']);
|
||||
// 归还确认是业务顶层方法,这里统一使用事务
|
||||
return Db::transaction(function () use ($request, $data, $scene, $attachment) {
|
||||
return Db::transaction(function () use ($request, $data, $scene) {
|
||||
|
||||
// 1. 当前操作人信息
|
||||
$userInfo = (new UserService())->getUserInfo($request->user->uid, '');
|
||||
@@ -440,23 +341,10 @@ class InvRequisitionItemReturnService
|
||||
|
||||
// 4. 更新归还记录(状态 + 审核人 + 备注等)
|
||||
$updateResult = $this->logicUpdateBy($config, $data);
|
||||
$resultItem = $this->logicShow($config);
|
||||
InvRequisitionReturn::where('id',$resultItem['return_id'])->update(['status' => $data['status']]);
|
||||
foreach ($attachment as $attac) {
|
||||
Db::table('inv_requisition_return_approve_attachment')->insertGetId([
|
||||
'requisition_id' => $resultItem['requisition_id'],
|
||||
'return_id' => $resultItem['return_id'],
|
||||
'file_name' => $attac['original_name'],
|
||||
'file_path' => $attac['file_path'],
|
||||
'created_at' => time(),
|
||||
]);
|
||||
}
|
||||
if ($updateResult === 0) {
|
||||
throw new BusinessException('更新归还申请失败,可能记录不存在或已被处理');
|
||||
}
|
||||
|
||||
//InvRequisitionReturn::where('return_id', $data['id'])->update(['status' => $status]);
|
||||
|
||||
// 5. 若是拒绝,直接返回(不改库存、不改已归还数量)
|
||||
if ($status === 2) {
|
||||
// 拒绝:这里你返回 true 或者返回更新后的记录都可以
|
||||
@@ -517,7 +405,6 @@ class InvRequisitionItemReturnService
|
||||
// 全部非耗材都已归还
|
||||
$affected = InvRequisition::where('id', $requisitionId)->update([
|
||||
'is_returned' => 1,
|
||||
'status' => 17,
|
||||
'updated_at' => time(),
|
||||
]);
|
||||
|
||||
@@ -525,12 +412,6 @@ class InvRequisitionItemReturnService
|
||||
if ($affected === 0) {
|
||||
throw new BusinessException('更新领用单状态失败,可能记录不存在');
|
||||
}
|
||||
}else{
|
||||
// 非耗材未全部归还
|
||||
$affected = InvRequisition::where('id', $requisitionId)->update([
|
||||
'status' => 16,
|
||||
'updated_at' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
// 7. 返回处理结果(保持你原来的 postProcess 习惯)
|
||||
@@ -544,179 +425,6 @@ class InvRequisitionItemReturnService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物品领用归还确认
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data
|
||||
* @param string $scene
|
||||
* @return array|bool
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function serviceReturnConfirm(Request $request, array $data, string $scene = 'returnConfirm')
|
||||
{
|
||||
try {
|
||||
if(empty($data['return_id'])) {
|
||||
$data['return_id'] = $data['requisition_item_return_id'];
|
||||
}
|
||||
$attachment = $request->post('attachment') ?? [];
|
||||
unset($data['attachment']);
|
||||
// 归还确认是业务顶层方法,这里统一使用事务
|
||||
return Db::transaction(function () use ($request, $data, $scene, $attachment) {
|
||||
|
||||
// 1. 当前操作人信息
|
||||
$userInfo = (new UserService())->getUserInfo($request->user->uid, '');
|
||||
if (empty($userInfo['user']['id']) || empty($userInfo['user']['name'])) {
|
||||
throw new BusinessException('无法获取当前用户信息');
|
||||
}
|
||||
|
||||
$handlerId = (int)$userInfo['user']['id'];
|
||||
$handlerName = (string)$userInfo['user']['name'];
|
||||
|
||||
$data['handler_id'] = $handlerId;
|
||||
$data['handler_name'] = $handlerName;
|
||||
|
||||
// 确认状态:1=通过,2=拒绝
|
||||
$status = isset($data['status']) ? (int)$data['status'] : null;
|
||||
if (!in_array($status, [1, 2], true)) {
|
||||
throw new BusinessException('非法的归还处理状态');
|
||||
}
|
||||
|
||||
// 2. 构建查询配置,定位到这条归还记录
|
||||
$returnService = new InvRequisitionReturnService();
|
||||
$return = InvRequisitionReturn::where('id', $data['return_id'])->first();
|
||||
if (!$return) {
|
||||
throw new BusinessException('未找到对应的领用归还记录');
|
||||
}
|
||||
$requisitionId = (int)$return->requisition_id;
|
||||
$existingStatus = (int)($return->status ?? 0);
|
||||
if (in_array($existingStatus, [1, 2], true)) {
|
||||
throw new BusinessException('该归还申请已经被处理过了');
|
||||
}
|
||||
$return->status = $status;
|
||||
$return->save();
|
||||
if($status == 1){
|
||||
//更改库存
|
||||
$returnItem = Db::table('inv_requisition_item_return')
|
||||
->where('return_id', $return->id)
|
||||
->get();
|
||||
foreach ($returnItem as $item) {
|
||||
//$invItem = InvItem::where('id', $item->item_id)->first();
|
||||
(new InvItemService())->stockIn($item->item_id,$item->return_qty,['change_type'=>InvStockLog::CHANGE_TYPE_IN_RETURN,
|
||||
'biz_type'=>InvStockLog::BIZ_TYPE_RETURN,]);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存归还审核附件
|
||||
foreach ($attachment as $attac) {
|
||||
Db::table('inv_requisition_return_approve_attachment')->insertGetId([
|
||||
'requisition_id' => $requisitionId,
|
||||
'return_id' => $data['return_id'],
|
||||
'file_name' => $attac['original_name'],
|
||||
'file_path' => $attac['file_path'],
|
||||
'created_at' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
//查询归还明细
|
||||
$itemReturns = InvRequisitionItemReturn::where('return_id', $data['return_id'])->get();
|
||||
foreach ($itemReturns as $itemReturn) {
|
||||
$itemReturn->status = $status;
|
||||
$itemReturn->handle_remark = $data['handle_remark'];
|
||||
$itemReturn->save();
|
||||
|
||||
// 5. 若是拒绝,直接跳出(不改库存、不改已归还数量)
|
||||
if ($status === 2) {
|
||||
// 拒绝:这里你返回 true 或者返回更新后的记录都可以
|
||||
continue;
|
||||
}
|
||||
|
||||
// 6. 审核通过:继续处理领用明细 & 库存 & 领用单状态
|
||||
// 注意:requisition_item_id、item_id、return_qty 等字段在本次确认流程中不会被修改,
|
||||
// 所以可以直接使用 $existingRecord 中的值(都是只读字段)
|
||||
$requisitionItemId = (int)$itemReturn->requisition_item_id;
|
||||
$itemId = (int)$itemReturn->item_id;
|
||||
$returnQty = (int)$itemReturn->return_qty;
|
||||
|
||||
if ($requisitionItemId <= 0 || $itemId <= 0 || $returnQty <= 0 || $requisitionId <= 0) {
|
||||
throw new BusinessException('归还申请记录缺少必要字段,无法处理');
|
||||
}
|
||||
|
||||
// 6.2 处理领用明细
|
||||
/** @var \app\model\InvRequisitionItem|null $item */
|
||||
$item = InvRequisitionItem::find($requisitionItemId);
|
||||
if (!$item) {
|
||||
throw new BusinessException('未找到对应的领用明细记录');
|
||||
}
|
||||
|
||||
$approvedQty = (int)($item->approved_qty ?? 0);
|
||||
$returnedQty = (int)($item->returned_qty ?? 0);
|
||||
|
||||
if ($approvedQty <= 0) {
|
||||
throw new BusinessException('该物品尚未审批出库,无法归还');
|
||||
}
|
||||
|
||||
if ($returnedQty + $returnQty > $approvedQty) {
|
||||
throw new BusinessException('归还数量超过已借数量,无法确认');
|
||||
}
|
||||
|
||||
$item->returned_qty = $returnedQty + $returnQty;
|
||||
if ($item->returned_qty >= $approvedQty) {
|
||||
$item->is_finished = 1;
|
||||
}
|
||||
$item->updated_at = time();
|
||||
|
||||
if ($item->save() === false) {
|
||||
throw new BusinessException('更新领用明细失败');
|
||||
}
|
||||
|
||||
// 6.3 处理库存(入库)
|
||||
(new InvItemService())->stockIn($itemId, $returnQty);
|
||||
}
|
||||
// 5. 若是拒绝,直接返回(不修改领用申请状态)
|
||||
if ($status === 2) {
|
||||
// 拒绝:这里你返回 true 或者返回更新后的记录都可以
|
||||
return $return;
|
||||
}
|
||||
|
||||
// 6.3 检查整张单是否已全部归还(只看非耗材)
|
||||
$notFinishedCount = InvRequisitionItem::query()
|
||||
->where('requisition_id', $requisitionId)
|
||||
->where('is_consumable_snap', 0)
|
||||
->where('is_finished', 0)
|
||||
->count();
|
||||
if ($notFinishedCount === 0) {
|
||||
// 全部非耗材都已归还
|
||||
$affected = InvRequisition::where('id', $requisitionId)->update([
|
||||
'is_returned' => 1,
|
||||
'status' => 17,
|
||||
'updated_at' => time(),
|
||||
]);
|
||||
|
||||
// Eloquent::update 返回的是影响行数,0 表示未更新到任何行
|
||||
if ($affected === 0) {
|
||||
throw new BusinessException('更新领用单状态失败,可能记录不存在');
|
||||
}
|
||||
}else{
|
||||
// 非耗材未全部归还
|
||||
$affected = InvRequisition::where('id', $requisitionId)->update([
|
||||
'status' => 16,
|
||||
'updated_at' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
// 7. 返回处理结果(保持你原来的 postProcess 习惯)
|
||||
//return $this->postProcess(ucfirst($scene), $existingRecord);
|
||||
return $return;
|
||||
});
|
||||
|
||||
} catch (BusinessException $e) {
|
||||
throw $e;
|
||||
} catch (\Throwable $e) {
|
||||
throw new BusinessException("确认归还物品失败:" . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询配置
|
||||
*
|
||||
@@ -735,18 +443,13 @@ class InvRequisitionItemReturnService
|
||||
$config['where']['id'] = $p['requisition_item_return_id'];
|
||||
break;
|
||||
case 'index':
|
||||
// if(isset($p['status']) && $p['status']!=''){
|
||||
// $config['where']['status'] = $p['status'];
|
||||
// }
|
||||
// if(isset($p['handler_id']) && $p['handler_id']=='self'){
|
||||
// $config['where']['applicant_id'] = $request->user->uid;
|
||||
// }else{
|
||||
// $config['where']['handler_id'] = $request->user->uid;
|
||||
// }
|
||||
// $config['order']['id'] = 'desc';
|
||||
$config['where']['status'] = 1;
|
||||
$config['order']['sort'] = 'desc';
|
||||
$config['order']['id'] = 'desc';
|
||||
break;
|
||||
case 'show':
|
||||
$config['where']['id'] = $p['id'];
|
||||
$config['where']['status'] = 1;
|
||||
break;
|
||||
case 'store':
|
||||
break;
|
||||
@@ -761,22 +464,6 @@ class InvRequisitionItemReturnService
|
||||
return $config;
|
||||
}
|
||||
|
||||
/** 分页列表 */
|
||||
public function serviceList(Request $request, string $scene = 'index')
|
||||
{
|
||||
$InvRequisitionReturn = new InvRequisitionReturnService();
|
||||
return $InvRequisitionReturn->serviceList($request, $scene);
|
||||
}
|
||||
|
||||
/** 查看单条 */
|
||||
public function serviceShow(Request $request, string $scene = 'show')
|
||||
{
|
||||
$id = $request->get('id');
|
||||
$return = InvRequisitionReturn::where('id', $id)->first();
|
||||
$return['item_return'] = InvRequisitionItemReturn::where('return_id', $return['id'])->orderBy('id', 'desc')->get();
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成申请单号
|
||||
*
|
||||
|
||||
@@ -5,8 +5,6 @@ namespace app\common\service;
|
||||
use app\common\validate\InvRequisitionReturnValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InvRequisitionReturn;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
|
||||
class InvRequisitionReturnService
|
||||
{
|
||||
@@ -30,64 +28,4 @@ class InvRequisitionReturnService
|
||||
{
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
public function serviceReturnConfirm(Request$request)
|
||||
{
|
||||
$status = $request->post('status');
|
||||
if(in_array($status,[1,2])){
|
||||
throw new BusinessException("状态不正确");
|
||||
}
|
||||
$requisitionReturn = InvRequisitionReturn::where(['id' => $request['id']])->first();
|
||||
if (!$requisitionReturn && $requisitionReturn->handler_id == $request->user->uid) {
|
||||
$requisitionReturn->status = $status;
|
||||
return $requisitionReturn->save();
|
||||
}else{
|
||||
throw new BusinessException("审核示例不正确或非物品管理员");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建查询配置
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $scene
|
||||
* @return array
|
||||
*/
|
||||
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
|
||||
{
|
||||
$p = $request->all();
|
||||
|
||||
$config = [];
|
||||
$config['model'] = $this->modelClass;
|
||||
switch ($scene) {
|
||||
case 'returnConfirm':
|
||||
$config['where']['id'] = $p['requisition_item_return_id'];
|
||||
break;
|
||||
case 'index':
|
||||
if(isset($p['status']) && $p['status']!=''){
|
||||
$config['where']['status'] = $p['status'];
|
||||
}
|
||||
if (isset($p['handler_id']) && $p['handler_id'] == 'self') {
|
||||
$config['where']['applicant_id'] = $request->user->uid;
|
||||
} else {
|
||||
$config['where']['handler_id'] = $request->user->uid;
|
||||
}
|
||||
$config['order']['id'] = 'desc';
|
||||
break;
|
||||
case 'show':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'store':
|
||||
break;
|
||||
case 'update':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'destroy':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\model\InvItem;
|
||||
use app\common\model\InvStockLog;
|
||||
use app\common\validate\InvRequisitionValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InvRequisition;
|
||||
@@ -53,44 +52,7 @@ class InvRequisitionService
|
||||
$config['order']['id'] = 'desc';
|
||||
break;
|
||||
case 'index':
|
||||
if(isset($p['status']) && $p['status']){
|
||||
$config['where']['status'] = $p['status'];
|
||||
}
|
||||
if (isset($p['applicant_id']) && $p['applicant_id'] == 'self') { //自己的领用申请
|
||||
$config['where']['applicant_id'] = $request->user->uid;
|
||||
} elseif (isset($p['applicant_id']) && $p['applicant_id']) { //指定人员的申请
|
||||
$config['where']['applicant_id'] = $p['applicant_id'];
|
||||
}
|
||||
/* else { //审批人对应的记录
|
||||
$config['with'] = ['approval'];
|
||||
$config['where']['approval.approver_id'] = $request->user->uid;
|
||||
//$config['where']['approval.action'] = 0;
|
||||
}*/
|
||||
if(isset($p['phase']) && $p['phase'] == 'approve'){//借用审批中
|
||||
$config['where']['status'] = ['in',[10,11]];
|
||||
if(isset($p['scene']) && $p['scene'] == 'approval'){
|
||||
$config['with'] = ['approval'];
|
||||
$config['where']['approval.action'] = 0;
|
||||
}
|
||||
}elseif(isset($p['phase']) && $p['phase'] == 'repaid'){//已全部归还
|
||||
$config['where']['status'] = 17;
|
||||
}elseif(isset($p['phase']) && $p['phase'] == 'unreturned'){ //未归还
|
||||
$config['where']['status'] = ['in',[11,12,13,14,15,16,18,19]];
|
||||
}
|
||||
//审核列表
|
||||
elseif(isset($p['phase']) && $p['phase'] == 'pending'){ //待审核
|
||||
$config['where']['status'] = ['in',[10,11]];
|
||||
$config['with'] = ['approval'];
|
||||
$config['where']['approval.approver_id'] = $request->user->uid;
|
||||
$config['where']['approval.action'] = 0;
|
||||
}elseif(isset($p['phase']) && $p['phase'] == 'approved'){ //已通过
|
||||
$config['where']['status'] = ['in',[11,12,14,15,16,17,18,19]];
|
||||
$config['with'] = ['approval'];
|
||||
$config['where']['approval.approver_id'] = $request->user->uid;
|
||||
$config['where']['approval.action'] = [">",0];
|
||||
}elseif(isset($p['phase']) && $p['phase'] == 'refuse'){ //拒绝,未通过
|
||||
$config['where']['status'] = ['in',[13]];
|
||||
}
|
||||
$config['where']['applicant_id'] = $request->user->uid;
|
||||
$config['order']['id'] = 'desc';
|
||||
break;
|
||||
case 'show':
|
||||
@@ -128,7 +90,7 @@ class InvRequisitionService
|
||||
$data['applicant_id'] = (int)$user['user']['id'];
|
||||
$data['applicant_name'] = (string)$user['user']['name'];
|
||||
$data['leader_id'] = $user['user']['report_to'];
|
||||
$data['status'] = 10;
|
||||
$data['status'] = InvRequisition::STATUS_LEADER;
|
||||
|
||||
//查询物品管理人是否是一个
|
||||
if(count($data['items'])>=2){
|
||||
@@ -138,7 +100,7 @@ class InvRequisitionService
|
||||
}
|
||||
$manage_user = array_unique($manage_user);
|
||||
if(count($manage_user)>1){
|
||||
throw new BusinessException("物品管理员不是同一人");
|
||||
throw new BusinessException("审批实例未找到");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +139,7 @@ class InvRequisitionService
|
||||
return $res;
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
throw new BusinessException("创建物品申请失败:".$e->getMessage());
|
||||
throw new BusinessException("创建物品申请失败:" . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,12 +149,11 @@ class InvRequisitionService
|
||||
public function startApproval($requisition)
|
||||
{
|
||||
// 启动审批
|
||||
//$appro = new \app\common\utils\approval\service\ApprovalFlowService();
|
||||
$appro = new \app\common\service\InvRequisitionApproveService();
|
||||
$appro = new \app\common\utils\approval\service\ApprovalFlowService();
|
||||
$formData = [
|
||||
'manage_user_id' => $requisition['manage_user_id'],
|
||||
];
|
||||
return $appro->start('inv_requisition', 'inv_requisition', $requisition['id'], $formData, $requisition['applicant_id']);
|
||||
$appro->start('inv_requisition', 'inv_requisition', $requisition['id'], $formData, $requisition['applicant_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,14 +210,13 @@ class InvRequisitionService
|
||||
}
|
||||
|
||||
foreach ($items as $item) {
|
||||
$invitem = InvItem::where('id',$item)->first();
|
||||
$itemData = [
|
||||
'requisition_id' => $created->id,
|
||||
'item_id' => $item['item_id'],
|
||||
'item_name_snap' => $item['item_name_snap'], // 修改:使用 snap 字段
|
||||
'spec_model_snap' => $item['spec_model_snap']??'', // 修改:使用 snap 字段
|
||||
'unit_snap' => $item['unit_snap']??'', // 修改:使用 snap 字段
|
||||
'is_consumable_snap' => $item['is_consumable_snap']?? ($invitem['is_consumable_snap']??0), // 修改:使用 snap 字段
|
||||
'is_consumable_snap' => $item['is_consumable_snap']?? 0, // 修改:使用 snap 字段
|
||||
'request_qty' => (int) $item['request_qty'] ?? 1, // 动态获取数量,转为整型
|
||||
'approved_qty' => (int) $item['request_qty'] ?? 1, // 初始审批数量等于申请数量
|
||||
'remark' => $item['remark'] ?? ''
|
||||
@@ -319,311 +279,4 @@ class InvRequisitionService
|
||||
{
|
||||
return 'RQ' . date('Ymd') . strtoupper(substr(uniqid(), -6));
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码领取物品
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function qrClaim(Request $request, array $data): array
|
||||
{
|
||||
return Db::transaction(function () use ($request, $data) {
|
||||
$itemId = (int)($data['item_id'] ?? 0);
|
||||
$qty = (int)($data['qty'] ?? 1);
|
||||
|
||||
if ($itemId <= 0) {
|
||||
throw new BusinessException('物品ID无效');
|
||||
}
|
||||
if ($qty <= 0) {
|
||||
throw new BusinessException('领取数量必须大于0');
|
||||
}
|
||||
|
||||
// 获取物品信息
|
||||
$item = InvItem::find($itemId);
|
||||
if (!$item) {
|
||||
throw new BusinessException('物品不存在');
|
||||
}
|
||||
|
||||
// 检查是否允许扫码领取
|
||||
if (!$item->allow_qr_claim) {
|
||||
throw new BusinessException('该物品不允许扫码领取');
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
$user = (new UserService())->getUserInfo($request->user->uid, '');
|
||||
$applicantId = (int)$user['user']['id'];
|
||||
$applicantName = (string)$user['user']['name'];
|
||||
|
||||
// 检查扫码领取数量限制
|
||||
if ($item->qr_code_num > 0) {
|
||||
// 查询该用户已扫码领取该物品的数量
|
||||
$claimedQty = InvRequisitionItem::whereHas('requisition', function ($q) use ($applicantId) {
|
||||
$q->where('applicant_id', $applicantId)
|
||||
->where('claim_type', InvRequisition::CLAIM_TYPE_QR);
|
||||
})->where('item_id', $itemId)
|
||||
->sum('approved_qty');
|
||||
|
||||
if (($claimedQty + $qty) > $item->qr_code_num) {
|
||||
throw new BusinessException("扫码领取数量超限,每人最多可领取 {$item->qr_code_num} {$item->unit},已领取 {$claimedQty} {$item->unit}");
|
||||
}
|
||||
}
|
||||
|
||||
// 检查库存
|
||||
if ($item->stock_qty < $qty) {
|
||||
throw new BusinessException('库存不足,当前库存: ' . $item->stock_qty);
|
||||
}
|
||||
|
||||
// 创建领用申请记录(直接完成)
|
||||
$requisition = InvRequisition::create([
|
||||
'order_no' => $this->generateOrderNo(),
|
||||
'applicant_company_id' => $user['user']['company_id'] ?? 0,
|
||||
'dept_id' => $user['user']['dept_id'] ?? 0,
|
||||
'applicant_id' => $applicantId,
|
||||
'applicant_name' => $applicantName,
|
||||
'leader_id' => $user['user']['report_to'] ?? 0,
|
||||
'manager_id' => $item->manage_user_id,
|
||||
'borrow_reason' => '扫码领取',
|
||||
'use_start_date' => date('Y-m-d', time()),
|
||||
'use_end_date' => date('Y-m-d', time()),
|
||||
'status' => 19, // 已审批(无需归还)
|
||||
'claim_type' => InvRequisition::CLAIM_TYPE_QR,
|
||||
'qr_claim_time' => time(),
|
||||
'remark' => $data['remark'] ?? '扫码领取',
|
||||
]);
|
||||
|
||||
// 创建领用明细
|
||||
InvRequisitionItem::create([
|
||||
'requisition_id' => $requisition->id,
|
||||
'item_id' => $itemId,
|
||||
'item_name_snap' => $item->item_name,
|
||||
'spec_model_snap' => $item->spec_model,
|
||||
'unit_snap' => $item->unit,
|
||||
'is_consumable_snap' => $item->is_consumable,
|
||||
'request_qty' => $qty,
|
||||
'approved_qty' => $qty,
|
||||
'remark' => '扫码领取',
|
||||
]);
|
||||
|
||||
// 扣减库存
|
||||
(new InvItemService())->stockOut($itemId, $qty, false, [
|
||||
'biz_type' => InvStockLog::BIZ_TYPE_QR_CLAIM,
|
||||
'biz_no' => $requisition->order_no,
|
||||
'operator_id' => $applicantId,
|
||||
'operator_name' => $applicantName,
|
||||
'remark' => '扫码领取',
|
||||
]);
|
||||
|
||||
return $requisition->toArray();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员代领(支持多人)
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function proxyClaim(Request $request, array $data): array
|
||||
{
|
||||
return Db::transaction(function () use ($request, $data) {
|
||||
$itemId = (int)($data['item_id'] ?? 0);
|
||||
$qty = (int)($data['qty'] ?? 1);
|
||||
$targetUserIds = $data['target_user_id'];
|
||||
|
||||
if ($itemId <= 0) {
|
||||
throw new BusinessException('物品ID无效');
|
||||
}
|
||||
if ($qty <= 0) {
|
||||
throw new BusinessException('领取数量必须大于0');
|
||||
}
|
||||
if (empty($targetUserIds)) {
|
||||
throw new BusinessException('请选择代领用户');
|
||||
}
|
||||
|
||||
// 获取物品信息
|
||||
$item = InvItem::find($itemId);
|
||||
if (!$item) {
|
||||
throw new BusinessException('物品不存在');
|
||||
}
|
||||
|
||||
$targetUserIds = explode(',', $targetUserIds);
|
||||
|
||||
// 获取操作人(管理员)信息
|
||||
$proxyUser = (new UserService())->getUserInfo($request->user->uid, '');
|
||||
$proxyUserId = (int)$proxyUser['user']['id'];
|
||||
$proxyUserName = (string)$proxyUser['user']['name'];
|
||||
|
||||
// 验证操作人是否是物品管理员
|
||||
if ($item->manage_user_id != $proxyUserId) {
|
||||
throw new BusinessException('您不是该物品的管理员,无权代领');
|
||||
}
|
||||
|
||||
// 计算总需求量
|
||||
$totalQty = $qty * count($targetUserIds);
|
||||
|
||||
// 检查库存
|
||||
if ($item->stock_qty < $totalQty) {
|
||||
throw new BusinessException('库存不足,当前库存: ' . $item->stock_qty . ',需要: ' . $totalQty);
|
||||
}
|
||||
|
||||
$createdRequisitions = [];
|
||||
$remark = $data['remark'] ?? '管理员代领';
|
||||
|
||||
// 为每个目标用户创建领用记录
|
||||
foreach ($targetUserIds as $targetUserId) {
|
||||
$targetUserId = (int)$targetUserId;
|
||||
if ($targetUserId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取目标用户信息
|
||||
$targetUser = (new UserService())->getUserInfo($targetUserId, '');
|
||||
if (!$targetUser['user']) {
|
||||
throw new BusinessException('用户ID ' . $targetUserId . ' 不存在');
|
||||
}
|
||||
|
||||
// 创建领用申请记录(直接完成)
|
||||
$requisition = InvRequisition::create([
|
||||
'order_no' => $this->generateOrderNo(),
|
||||
'applicant_company_id' => $targetUser['user']['company_id'] ?? 0,
|
||||
'dept_id' => $targetUser['user']['dept_id'] ?? 0,
|
||||
'applicant_id' => $targetUserId,
|
||||
'applicant_name' => $targetUser['user']['name'],
|
||||
'leader_id' => $targetUser['user']['report_to'] ?? 0,
|
||||
'manager_id' => $item->manage_user_id,
|
||||
'borrow_reason' => $data['borrow_reason'] ?? '管理员代领',
|
||||
'use_start_date' => date('Y-m-d', time()),
|
||||
'use_end_date' => date('Y-m-d', time()),
|
||||
'status' => 19, // 已审批(无需归还)
|
||||
'claim_type' => InvRequisition::CLAIM_TYPE_PROXY,
|
||||
'proxy_claim_user_id' => $proxyUserId,
|
||||
'proxy_claim_user_name' => $proxyUserName,
|
||||
'remark' => $remark,
|
||||
]);
|
||||
|
||||
// 创建领用明细
|
||||
InvRequisitionItem::create([
|
||||
'requisition_id' => $requisition->id,
|
||||
'item_id' => $itemId,
|
||||
'item_name_snap' => $item->item_name,
|
||||
'spec_model_snap' => $item->spec_model,
|
||||
'unit_snap' => $item->unit,
|
||||
'is_consumable_snap' => $item->is_consumable,
|
||||
'request_qty' => $qty,
|
||||
'approved_qty' => $qty,
|
||||
'remark' => $remark,
|
||||
]);
|
||||
|
||||
$createdRequisitions[] = $requisition->toArray();
|
||||
}
|
||||
|
||||
// 一次性扣减总库存
|
||||
(new InvItemService())->stockOut($itemId, $totalQty, false, [
|
||||
'biz_type' => InvStockLog::BIZ_TYPE_PROXY_CLAIM,
|
||||
'biz_no' => 'PROXY_' . time(),
|
||||
'operator_id' => $proxyUserId,
|
||||
'operator_name' => $proxyUserName,
|
||||
'remark' => '管理员代领(' . count($targetUserIds) . '人×' . $qty . ')',
|
||||
]);
|
||||
|
||||
return [
|
||||
'created_count' => count($createdRequisitions),
|
||||
'requisitions' => $createdRequisitions,
|
||||
'total_qty' => $totalQty,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询扫码/代领记录列表
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function qrClaimsList(Request $request): array
|
||||
{
|
||||
$query = InvRequisition::query()->with(['items']);
|
||||
|
||||
// 只查询扫码领取和代领记录
|
||||
$query->whereIn('claim_type', [
|
||||
InvRequisition::CLAIM_TYPE_QR,
|
||||
InvRequisition::CLAIM_TYPE_PROXY
|
||||
]);
|
||||
|
||||
// 按申请人筛选(移动端"我的记录"功能)
|
||||
if ($request->get('applicant_id') === 'self') {
|
||||
$query->where('applicant_id', $request->user->uid);
|
||||
} elseif (!empty($request->get('applicant_id'))) {
|
||||
$query->where('applicant_id', $request->get('applicant_id'));
|
||||
}
|
||||
|
||||
// 按领取方式筛选
|
||||
if (!empty($request->get('claim_type'))) {
|
||||
$query->where('claim_type', $request->get('claim_type'));
|
||||
}
|
||||
|
||||
// 按代领操作人筛选
|
||||
if (!empty($request->get('proxy_user_id'))) {
|
||||
$query->where('proxy_claim_user_id', $request->get('proxy_user_id'));
|
||||
}
|
||||
|
||||
// 按物品ID筛选
|
||||
if (!empty($request->get('item_id'))) {
|
||||
$query->whereHas('items', function ($q) use ($request) {
|
||||
$q->where('item_id', $request->get('item_id'));
|
||||
});
|
||||
}
|
||||
|
||||
// 时间范围筛选
|
||||
if (!empty($request->get('start_time'))) {
|
||||
$query->where('created_at', '>=', strtotime($request->get('start_time')));
|
||||
}
|
||||
if (!empty($request->get('end_time'))) {
|
||||
$query->where('created_at', '<=', strtotime($request->get('end_time')));
|
||||
}
|
||||
|
||||
// 排序
|
||||
$query->orderBy('id', 'desc');
|
||||
|
||||
// 分页
|
||||
$perPage = $request->get('size', 20);
|
||||
$page = $request->get('current', 1);
|
||||
|
||||
$result = $query->paginate($perPage, ['*'], 'page', $page);
|
||||
|
||||
return [
|
||||
'records' => $result->getCollection()->map(function ($req) {
|
||||
return [
|
||||
'id' => $req->id,
|
||||
'order_no' => $req->order_no,
|
||||
'applicant_id' => $req->applicant_id,
|
||||
'applicant_name' => $req->applicant_name,
|
||||
'claim_type' => $req->claim_type,
|
||||
'claim_type_text' => InvRequisition::getClaimTypeText($req->claim_type),
|
||||
'qr_claim_time' => $req->qr_claim_time ? date('Y-m-d H:i:s', $req->qr_claim_time) : null,
|
||||
'proxy_claim_user_id' => $req->proxy_claim_user_id,
|
||||
'proxy_claim_user_name' => $req->proxy_claim_user_name,
|
||||
'status' => $req->status,
|
||||
'borrow_reason' => $req->borrow_reason,
|
||||
'remark' => $req->remark,
|
||||
'created_at' => $req->created_at ? $req->created_at->format('Y-m-d H:i:s') : null,
|
||||
'items' => $req->items->map(function ($item) {
|
||||
return [
|
||||
'item_id' => $item->item_id,
|
||||
'item_name_snap' => $item->item_name_snap,
|
||||
'approved_qty' => $item->approved_qty,
|
||||
];
|
||||
})->toArray(),
|
||||
];
|
||||
})->toArray(),
|
||||
'total' => $result->total(),
|
||||
'current' => $result->currentPage(),
|
||||
'size' => $result->perPage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\model\InvStockLog;
|
||||
use support\exception\BusinessException;
|
||||
|
||||
/**
|
||||
* 物品库存变化记录服务
|
||||
*/
|
||||
class InvStockLogService
|
||||
{
|
||||
/**
|
||||
* 记录库存变化
|
||||
*
|
||||
* @param array $data 日志数据
|
||||
* @return InvStockLog
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function record(array $data): InvStockLog
|
||||
{
|
||||
$required = ['item_id', 'change_type', 'change_qty', 'before_qty', 'after_qty'];
|
||||
foreach ($required as $field) {
|
||||
if (!isset($data[$field])) {
|
||||
throw new BusinessException("库存日志缺少必需字段: {$field}");
|
||||
}
|
||||
}
|
||||
|
||||
return InvStockLog::create([
|
||||
'company_id' => $data['company_id'] ?? 0,
|
||||
'item_id' => $data['item_id'],
|
||||
'item_name_snap' => $data['item_name_snap'] ?? null,
|
||||
'change_type' => $data['change_type'],
|
||||
'change_qty' => $data['change_qty'],
|
||||
'before_qty' => $data['before_qty'],
|
||||
'after_qty' => $data['after_qty'],
|
||||
'biz_type' => $data['biz_type'] ?? null,
|
||||
'biz_no' => $data['biz_no'] ?? null,
|
||||
'operator_id' => $data['operator_id'] ?? null,
|
||||
'operator_name' => $data['operator_name'] ?? null,
|
||||
'remark' => $data['remark'] ?? null,
|
||||
'updated_at' => time(),
|
||||
'created_at' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询库存变化记录列表
|
||||
*
|
||||
* @param array $params 查询参数
|
||||
* @return array
|
||||
*/
|
||||
public function getList(array $params): array
|
||||
{
|
||||
$query = InvStockLog::query()->with(['item']);
|
||||
|
||||
// 物品ID筛选
|
||||
if (!empty($params['item_id'])) {
|
||||
$query->where('item_id', $params['item_id']);
|
||||
}
|
||||
|
||||
// 变动类型筛选
|
||||
if (!empty($params['change_type'])) {
|
||||
$query->where('change_type', $params['change_type']);
|
||||
}
|
||||
|
||||
// 业务类型筛选
|
||||
if (!empty($params['biz_type'])) {
|
||||
$query->where('biz_type', $params['biz_type']);
|
||||
}
|
||||
|
||||
// 单据号筛选
|
||||
if (!empty($params['biz_no'])) {
|
||||
$query->where('biz_no', 'like', '%' . $params['biz_no'] . '%');
|
||||
}
|
||||
|
||||
// 时间范围筛选
|
||||
if (!empty($params['start_time'])) {
|
||||
$query->where('created_at', '>=', strtotime($params['start_time']));
|
||||
}
|
||||
if (!empty($params['end_time'])) {
|
||||
$query->where('created_at', '<=', strtotime($params['end_time']));
|
||||
}
|
||||
|
||||
// 排序
|
||||
$query->orderBy('id', 'desc');
|
||||
|
||||
// 分页
|
||||
$perPage = $params['size'] ?? 20;
|
||||
$page = $params['current'] ?? 1;
|
||||
|
||||
$result = $query->paginate($perPage, ['*'], 'page', $page);
|
||||
|
||||
return [
|
||||
'records' => $result->getCollection()->map(function ($log) {
|
||||
return [
|
||||
'id' => $log->id,
|
||||
'item_id' => $log->item_id,
|
||||
'item_name' => $log->item_name_snap,
|
||||
'change_type' => $log->change_type,
|
||||
'change_type_text' => InvStockLog::getChangeTypeText($log->change_type),
|
||||
'change_qty' => $log->change_qty,
|
||||
'before_qty' => $log->before_qty,
|
||||
'after_qty' => $log->after_qty,
|
||||
'biz_type' => $log->biz_type,
|
||||
'biz_type_text' => $log->biz_type ? InvStockLog::getBizTypeText($log->biz_type) : null,
|
||||
'biz_no' => $log->biz_no,
|
||||
'operator_id' => $log->operator_id,
|
||||
'operator_name' => $log->operator_name,
|
||||
'remark' => $log->remark,
|
||||
'created_at' => date('Y-m-d H:i:s', is_int($log->created_at)?$log->created_at:strtotime($log->created_at)),
|
||||
];
|
||||
})->toArray(),
|
||||
'total' => $result->total(),
|
||||
'current' => $result->currentPage(),
|
||||
'size' => $result->perPage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use support\exception\BusinessException;
|
||||
|
||||
/**
|
||||
* 二维码生成服务
|
||||
*/
|
||||
class QrCodeService
|
||||
{
|
||||
/**
|
||||
* 生成物品二维码
|
||||
*
|
||||
* @param int $itemId 物品ID
|
||||
* @param string $appUrl 应用访问地址
|
||||
* @return string 二维码内容URL
|
||||
*/
|
||||
public function generateItemQrCode(int $itemId, string $appUrl): string
|
||||
{
|
||||
//return rtrim($appUrl, '/') . '/mobile/inv/claim/' . $itemId;
|
||||
return "https://mweb-fdesk.hnxinyouhe.com/pages/scan/external-scan?id=" . $itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码图片并上传到 OSS
|
||||
*
|
||||
* @param int $itemId 物品ID
|
||||
* @param string $content 二维码内容
|
||||
* @param string $fileName 文件名
|
||||
* @return array 返回OSS路径和完整URL
|
||||
* @throws BusinessException
|
||||
*/
|
||||
public function generateAndUploadQrCode(int $itemId, string $content, string $fileName): array
|
||||
{
|
||||
// 使用 endroid/qr-code 库生成二维码
|
||||
// 如果未安装,使用 API 方式生成
|
||||
|
||||
$tempPath = $this->generateQrCodeImage($content, $fileName);
|
||||
|
||||
if (!$tempPath) {
|
||||
throw new BusinessException('二维码生成失败');
|
||||
}
|
||||
|
||||
try {
|
||||
// 上传到 OSS
|
||||
$ossService = new OssService();
|
||||
$ossPath = 'qr/' . $fileName;
|
||||
$ossUrl = $ossService->uploadImage($tempPath, $ossPath);
|
||||
|
||||
// 删除临时文件
|
||||
if (file_exists($tempPath)) {
|
||||
unlink($tempPath);
|
||||
}
|
||||
|
||||
return [
|
||||
'path' => $ossPath,
|
||||
'url' => $ossUrl,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
// 删除临时文件
|
||||
if (file_exists($tempPath)) {
|
||||
unlink($tempPath);
|
||||
}
|
||||
throw new BusinessException('二维码上传失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码图片(使用 QR Server API 或本地库)
|
||||
*
|
||||
* @param string $content 二维码内容
|
||||
* @param string $fileName 文件名
|
||||
* @return string 临时文件路径,失败返回 false
|
||||
*/
|
||||
private function generateQrCodeImage(string $content, string $fileName)
|
||||
{
|
||||
$tempDir = runtime_path() . '/qr_temp/';
|
||||
if (!is_dir($tempDir)) {
|
||||
mkdir($tempDir, 0755, true);
|
||||
}
|
||||
|
||||
$tempPath = $tempDir . $fileName;
|
||||
|
||||
// 方式1: 使用 endroid/qr-code 库(推荐)
|
||||
if (class_exists('\Endroid\QrCode\QrCode')) {
|
||||
return $this->generateWithEndroid($content, $tempPath);
|
||||
}
|
||||
|
||||
// 方式2: 使用在线 API(备用方案)
|
||||
return $this->generateWithApi($content, $tempPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 endroid/qr-code 生成二维码
|
||||
*/
|
||||
private function generateWithEndroid(string $content, string $tempPath): string
|
||||
{
|
||||
try {
|
||||
// 5.x 版本使用静态工厂方法
|
||||
if (method_exists(\Endroid\QrCode\QrCode::class, 'create')) {
|
||||
$qrCode = \Endroid\QrCode\QrCode::create($content)
|
||||
->setSize(300)
|
||||
->setMargin(10);
|
||||
} else {
|
||||
// 4.x 及以下版本
|
||||
$qrCode = new \Endroid\QrCode\QrCode($content);
|
||||
if (method_exists($qrCode, 'setSize')) {
|
||||
$qrCode->setSize(300);
|
||||
}
|
||||
if (method_exists($qrCode, 'setMargin')) {
|
||||
$qrCode->setMargin(10);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 Writer
|
||||
if (class_exists('\Endroid\QrCode\Writer\PngWriter')) {
|
||||
$writer = new \Endroid\QrCode\Writer\PngWriter();
|
||||
} else {
|
||||
// 旧版本可能使用不同的命名空间
|
||||
$writer = new \Endroid\QrCode\Writer();
|
||||
}
|
||||
|
||||
$result = $writer->write($qrCode);
|
||||
|
||||
// 保存文件
|
||||
if (method_exists($result, 'getString')) {
|
||||
file_put_contents($tempPath, $result->getString());
|
||||
} else {
|
||||
// 更旧版本可能直接返回字符串
|
||||
file_put_contents($tempPath, $result);
|
||||
}
|
||||
|
||||
return $tempPath;
|
||||
} catch (\Throwable $e) {
|
||||
// 如果 endroid 库使用失败,回退到在线 API
|
||||
error_log('endroid/qr-code 生成失败: ' . $e->getMessage() . ',使用在线 API 备用方案');
|
||||
return $this->generateWithApi($content, $tempPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用在线 API 生成二维码(备用方案)
|
||||
*/
|
||||
private function generateWithApi(string $content, string $tempPath): string
|
||||
{
|
||||
$apiUrl = 'https://api.qrserver.com/v1/create-qr-code/?';
|
||||
$params = [
|
||||
'size' => '300x300',
|
||||
'data' => $content,
|
||||
'margin' => '10',
|
||||
];
|
||||
|
||||
$url = $apiUrl . http_build_query($params);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
$imageData = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode !== 200 || !$imageData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file_put_contents($tempPath, $imageData);
|
||||
return $tempPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 OSS 上的二维码文件
|
||||
*
|
||||
* @param string $ossPath OSS路径
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteQrCode(string $ossPath): bool
|
||||
{
|
||||
try {
|
||||
$ossService = new OssService();
|
||||
return $ossService->deleteFile($ossPath);
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,101 +225,4 @@ class Feishu
|
||||
// ];
|
||||
// return $this->requestResult($url);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取 JSAPI 配置(签名)
|
||||
* @param string $url 当前页面完整 URL(不包含 # 后面的内容)
|
||||
* @return array
|
||||
*/
|
||||
public function getJsApiConfig($url)
|
||||
{
|
||||
// 1. 获取 tenant_access_token
|
||||
//$accessToken = $this->getTenantAccessToken();
|
||||
$accessToken = $this->tenantAccessToken();
|
||||
|
||||
// 2. 获取 jsapi_ticket
|
||||
$ticket = $this->getJsapiTicket($accessToken);
|
||||
|
||||
// 3. 生成签名参数
|
||||
$timestamp = (int) round(microtime(true) * 1000);
|
||||
$nonceStr = $this->generateNonceStr();
|
||||
|
||||
// 4. 生成签名
|
||||
$signature = $this->generateSignature($ticket, $nonceStr, $timestamp, $url);
|
||||
|
||||
return [
|
||||
'appId' => $this->appId,
|
||||
'timestamp' => $timestamp,
|
||||
'nonceStr' => $nonceStr,
|
||||
'signature' => $signature,
|
||||
'url' => $url
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 jsapi_ticket
|
||||
* @param string $accessToken
|
||||
* @return string
|
||||
*/
|
||||
private function getJsapiTicket($accessToken)
|
||||
{
|
||||
// 检查缓存
|
||||
$cachedTicket = Cache::get($this->abbr.'-feishu:jsapi_ticket');
|
||||
// $cachedTicket = $this->getCachedData('feishu:jsapi_ticket');
|
||||
if ($cachedTicket) {
|
||||
return $cachedTicket;
|
||||
}
|
||||
|
||||
// 使用 requestResult 方法发起请求,而不是 httpGet
|
||||
$this->options["headers"] = [
|
||||
"Authorization" => "Bearer " . $accessToken,
|
||||
"Content-Type" => "application/json; charset=utf-8"
|
||||
];
|
||||
|
||||
$result = $this->requestResult('jssdk/ticket/get', 'GET');
|
||||
|
||||
if (!$result) {
|
||||
throw new BusinessException('获取 jsapi_ticket 失败: ' . $this->error());
|
||||
}
|
||||
|
||||
$ticket = $result['data']['ticket'];
|
||||
$expire = $result['data']['expire_in'] - 300; // 提前5分钟过期
|
||||
|
||||
// 缓存 ticket
|
||||
Cache::set($this->abbr.'-feishu:jsapi_ticket', $ticket, $expire);
|
||||
// $this->setCachedData('feishu:jsapi_ticket', $ticket, $expire);
|
||||
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
* @param string $ticket
|
||||
* @param string $nonceStr
|
||||
* @param int $timestamp
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
private function generateSignature($ticket, $nonceStr, $timestamp, $url)
|
||||
{
|
||||
// 拼接待签名字符串(注意顺序)
|
||||
$signStr = "jsapi_ticket={$ticket}&noncestr={$nonceStr}×tamp={$timestamp}&url={$url}";
|
||||
|
||||
return sha1($signStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机字符串
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
private function generateNonceStr($length = 16)
|
||||
{
|
||||
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
$str = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\utils;
|
||||
|
||||
class SystemAuth
|
||||
{
|
||||
/**
|
||||
* 生成签名
|
||||
* @param string $userId 用户ID
|
||||
* @param int $timestamp Unix时间戳
|
||||
* @param string $secret 共享密钥
|
||||
* @return string
|
||||
*/
|
||||
public static function generateSignature(string $userId, int $timestamp, string $secret): string
|
||||
{
|
||||
$data = $userId . $timestamp;
|
||||
return hash_hmac('md5', $data, $secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证签名
|
||||
* @param string $userId 用户ID
|
||||
* @param int $timestamp Unix时间戳
|
||||
* @param string $receivedSignature 接收到的签名
|
||||
* @param string $secret 共享密钥
|
||||
* @return bool
|
||||
*/
|
||||
public static function verifySignature(string $userId, int $timestamp, string $receivedSignature, string $secret): bool
|
||||
{
|
||||
$expectedSignature = self::generateSignature($userId, $timestamp, $secret);
|
||||
return hash_equals($expectedSignature, $receivedSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证时间戳是否在有效期内
|
||||
* @param int $timestamp Unix时间戳
|
||||
* @param int $maxSeconds 有效期(秒)
|
||||
* @return bool
|
||||
*/
|
||||
public static function verifyTimestamp(int $timestamp, int $maxSeconds = 600): bool
|
||||
{
|
||||
$now = time();
|
||||
$diff = abs($now - $timestamp);
|
||||
return $diff <= $maxSeconds;
|
||||
}
|
||||
}
|
||||
@@ -403,8 +403,4 @@ trait ApprovalResolverTrait
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
public function StetApprovers(array $step, object $instance, bool $avoidSelf = true){
|
||||
return$this->resolveApprovers($step, $instance, $avoidSelf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,22 @@ class InvItemValidate extends Validate
|
||||
{
|
||||
// 规则
|
||||
protected $rule = [
|
||||
|
||||
];
|
||||
|
||||
// 提示
|
||||
protected $message = [
|
||||
|
||||
];
|
||||
|
||||
// 场景
|
||||
protected $scene = [
|
||||
'update' => [
|
||||
'store' => [
|
||||
|
||||
],
|
||||
|
||||
'qrCode' => [
|
||||
],
|
||||
'update' => [
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,6 @@ class InvRequisitionValidate extends Validate
|
||||
'items' => 'require|array',
|
||||
'items.*.item_id' => 'require|number',
|
||||
'items.*.request_qty' => 'require|number|gt:0',
|
||||
// 扫码领取规则
|
||||
'item_id' => 'require|integer|gt:0',
|
||||
'qty' => 'require|integer|gt:0',
|
||||
// 管理员代领规则
|
||||
'target_user_id' => 'integer|gt:0',
|
||||
'target_user_ids' => 'array',
|
||||
'target_user_ids.*' => 'integer|gt:0',
|
||||
];
|
||||
|
||||
// 提示
|
||||
@@ -39,52 +32,24 @@ class InvRequisitionValidate extends Validate
|
||||
'items.*.request_qty.require' => '申请数量不能为空',
|
||||
'items.*.request_qty.number' => '申请数量格式错误',
|
||||
'items.*.request_qty.gt' => '申请数量必须大于0',
|
||||
'item_id.require' => '物品ID不能为空',
|
||||
'item_id.integer' => '物品ID必须为整数',
|
||||
'item_id.gt' => '物品ID必须大于0',
|
||||
'qty.require' => '领取数量不能为空',
|
||||
'qty.integer' => '领取数量必须为整数',
|
||||
'qty.gt' => '领取数量必须大于0',
|
||||
'target_user_id.require' => '代领用户不能为空',
|
||||
];
|
||||
|
||||
// 场景
|
||||
protected $scene = [
|
||||
'store' => [
|
||||
'applicant_id',
|
||||
'borrow_reason',
|
||||
'use_start_date',
|
||||
'use_end_date',
|
||||
'items'
|
||||
|
||||
],
|
||||
|
||||
'update' => [
|
||||
'applicant_id',
|
||||
'borrow_reason',
|
||||
'use_start_date',
|
||||
'use_end_date',
|
||||
'items'
|
||||
|
||||
],
|
||||
|
||||
|
||||
'apply' => [
|
||||
'applicant_id',
|
||||
'borrow_reason',
|
||||
'use_start_date',
|
||||
'use_end_date',
|
||||
'items'
|
||||
],
|
||||
|
||||
'qrClaim' => [
|
||||
'item_id',
|
||||
'qty',
|
||||
],
|
||||
|
||||
'proxyClaim' => [
|
||||
'item_id',
|
||||
'qty',
|
||||
'target_user_id',
|
||||
'target_user_ids',
|
||||
'borrow_reason',
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -73,26 +73,26 @@ class IndexController
|
||||
{
|
||||
$options = [
|
||||
'controller' => [
|
||||
'module' => 'common',
|
||||
'name' => 'usedcar_crawl_results_images'
|
||||
'module' => 'mobile',
|
||||
'name' => 'inv_requisition_return'
|
||||
],
|
||||
'model' => [
|
||||
'module' => 'common',
|
||||
'name' => 'usedcar_crawl_results_images'
|
||||
'name' => 'inv_requisition_return'
|
||||
],
|
||||
'service' => [
|
||||
'module' => 'common',
|
||||
'name' => 'usedcar_crawl_results_images'
|
||||
'name' => 'inv_requisition_return'
|
||||
],
|
||||
'logic' => [
|
||||
'module' => 'common',
|
||||
'name' => 'usedcar_crawl_results_images'
|
||||
'name' => 'inv_requisition_return'
|
||||
],
|
||||
'validate' => [
|
||||
'module' => 'common',
|
||||
'name' => 'usedcar_crawl_results_images'
|
||||
'name' => 'inv_requisition_return'
|
||||
],
|
||||
'table' => 'usedcar_crawl_results_images'
|
||||
'table' => 'inv_requisition_return'
|
||||
];
|
||||
|
||||
$result = (new Generate($options))->doGenerate();
|
||||
|
||||
@@ -120,7 +120,7 @@ class CustomerService
|
||||
if($corpId == 1){
|
||||
$query->whereIn('channel_id', [1,2,3,4,5,6,7,8]);
|
||||
} elseif($corpId == 3) {
|
||||
$query->whereIn('channel_id', [9,10,11,16,17]);
|
||||
$query->whereIn('channel_id', [9,10,11]);
|
||||
} else{
|
||||
$query->whereIn('channel_id', [0]);
|
||||
}
|
||||
|
||||
@@ -60,14 +60,10 @@ class StockOrdersService extends \app\common\service\StockOrdersService
|
||||
->pluck('user_id')
|
||||
->toArray();
|
||||
$config['where']['salesperson_id'] = ['in',$report];
|
||||
$config['where']['approval_status'] = ['>=',1];
|
||||
}else{ //内勤没有负责的组时
|
||||
$config['where']['salesperson_id'] = $request->user->uid;
|
||||
}
|
||||
} elseif (in_array(1,$roles_id)) { //超管可以看所有的
|
||||
//$config['where']['approval_status'] = ['>=',1];
|
||||
$config['orWhere'][] = ['approval_status','>=',1];
|
||||
$config['orWhere'][] = ['salesperson_id','=',$request->user->uid];
|
||||
unset($config['where']['salesperson_id']);
|
||||
}else{
|
||||
$config['where']['salesperson_id'] = $request->user->uid;
|
||||
|
||||
@@ -79,11 +79,6 @@ class FbLeadHeaderMapper
|
||||
// '阶段' => 'lead_status', // 或 extra_data
|
||||
// '所有者' => 'owner', // 建议 extra_data
|
||||
// '标签' => 'tags', // 建议 extra_data
|
||||
|
||||
// ===== Google 表格(大写表头)兼容(防御式)=====
|
||||
'FULL_NAME' => 'full_name',
|
||||
'EMAIL' => 'email',
|
||||
'PHONE_NUMBER' => 'phone',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,8 +4,6 @@ namespace app\mobile\controller;
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\model\Corp;
|
||||
use app\common\model\InvItem;
|
||||
use app\common\model\InvRequisitionApprove;
|
||||
use app\common\model\InvRequisitionApproveAttachment;
|
||||
use app\common\model\InvRequisitionAttachment;
|
||||
use app\common\model\InvRequisitionItem;
|
||||
use app\common\service\OssService;
|
||||
@@ -45,78 +43,24 @@ class InvRequisitionController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回分页数据及总数
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
try {
|
||||
$param = $request->all();
|
||||
$applicant_id = $request->get('applicant_id');
|
||||
$raw = $this->service->serviceList($request);
|
||||
$uid = $request->user->uid;
|
||||
$data = $this->formatindex($raw,$applicant_id,$uid,$param);
|
||||
// $data = $this->transformData($raw, method_exists($this, 'indexFormat')
|
||||
// ? [$this, 'indexFormat']
|
||||
// : null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function formatindex($p,$applicant_id,$uid,$param){
|
||||
$records = $p->getCollection()
|
||||
->map(fn($item) => $this->indexFormat($item, $applicant_id,$uid))
|
||||
->toArray();
|
||||
|
||||
if(isset($param['phase']) && $param['phase'] == 'pending'){
|
||||
foreach ($records as $key => $record) {
|
||||
if($record['action']==1 || $record['action']==2)
|
||||
unset($records[$key]);
|
||||
}
|
||||
$records = array_values($records);
|
||||
}
|
||||
|
||||
return [
|
||||
'records' => $records,
|
||||
'total' => $p->total(),
|
||||
'current' => $p->currentPage(),
|
||||
'size' => $p->perPage(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function indexFormat($data, $applicant_id, $uid)
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if(isset($data['id']) && is_object($data)){
|
||||
$data = $data->toArray();
|
||||
}
|
||||
if (isset($data['created_at'])){
|
||||
$data['created_at'] = is_int($data['created_at'])?$data['created_at']:strtotime($data['created_at']);
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
}
|
||||
if (isset($data['updated_at'])){
|
||||
$data['updated_at'] = is_int($data['updated_at'])?$data['updated_at']:strtotime($data['updated_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
}
|
||||
if (isset($data['id'])){
|
||||
$data['item'] = InvRequisitionItem::where('requisition_id', $data['id'])->get();
|
||||
}
|
||||
|
||||
if($applicant_id != 'self' && isset($data['id'])){ //不是查询自己数据时查询是否已审核
|
||||
$approve = InvRequisitionApprove::where('requisition_id', $data['id'])
|
||||
->where('approver_id', $uid)
|
||||
->first();
|
||||
$data['action'] = $approve['action']??3;//查询人审核状态:0待审核 1通过 2驳回 3非审核人
|
||||
foreach ($data['item'] as $key => $item){
|
||||
$corpId = InvItem::where('id', $item->item_id)->value('company_id');
|
||||
$item['company_name'] = Corp::where('id', $corpId)->value('name');
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
@@ -129,20 +73,6 @@ class InvRequisitionController extends BaseController
|
||||
*/
|
||||
protected function showFormat($data)
|
||||
{
|
||||
$oss = new OssService();
|
||||
if (isset($data['id'])){
|
||||
$data['approve'] = InvRequisitionApprove::where('requisition_id', $data['id'])->get()->toArray();
|
||||
foreach ($data['approve'] as $key => $item){
|
||||
$attachment = InvRequisitionApproveAttachment::where('approve_id', $item['id'])->get();
|
||||
foreach ($attachment as $k => $v){
|
||||
$attachment[$k] = $v->toArray();
|
||||
$attachment[$k]['file_path_pull'] = $oss->generatePrivateUrl($v['file_path']);
|
||||
}
|
||||
$data['approve'][$key]['attachment'] = $attachment;
|
||||
}
|
||||
$approve_id = !empty($data['approve'])?array_pop($data['approve'])['id']:null;
|
||||
$data['approve_id'] = $approve_id;
|
||||
}
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
@@ -150,44 +80,11 @@ class InvRequisitionController extends BaseController
|
||||
if (isset($data['id'])){
|
||||
$data['item'] = InvRequisitionItem::where('requisition_id', $data['id'])->get();
|
||||
$data['attachment'] = InvRequisitionAttachment::where('requisition_id', $data['id'])->get();
|
||||
$oss = new OssService();
|
||||
foreach ($data['attachment'] as $key => $value) {
|
||||
$data['attachment'][$key]['file_path_pull'] = $oss->generatePrivateUrl($value['file_path']);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码领取物品
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function qrClaim(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $this->service->qrClaim($request, $request->post());
|
||||
return $this->success($data, '领取成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的扫码/代领记录
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function myQrClaims(Request $request)
|
||||
{
|
||||
try {
|
||||
// 只查询当前用户的扫码记录,通过设置 applicant_id=self 实现
|
||||
$request->setGet('applicant_id','self');
|
||||
$data = $this->service->qrClaimsList($request);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,6 @@
|
||||
namespace app\mobile\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\model\Corp;
|
||||
use app\common\model\InvItem;
|
||||
use app\common\model\InvRequisitionItem;
|
||||
use app\common\model\InvRequisitionItemReturn;
|
||||
use app\common\model\InvRequisitionItemReturnAttachment;
|
||||
use app\common\service\OssService;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\common\service\InvRequisitionItemReturnService;
|
||||
use support\Request;
|
||||
@@ -23,143 +17,24 @@ class InvRequisitionItemReturnController extends BaseController
|
||||
$this->service = new InvRequisitionItemReturnService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回分页数据及总数
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
try {
|
||||
//$request->setGet('$request');
|
||||
$raw = $this->service->serviceList($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'indexFormat')
|
||||
? [$this, 'indexFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if(isset($data['id'])){
|
||||
$data['return_item'] = InvRequisitionItemReturn::where('return_id', $data['id'])->get();
|
||||
foreach ($data['return_item'] as $key => $value) {
|
||||
$data['return_item'][$key]['item'] = InvItem::where('id', $value['item_id'])->get();
|
||||
}
|
||||
}
|
||||
if (isset($data['return_at']))
|
||||
$data['return_at'] = date('Y-m-d H:i:s', $data['return_at']);
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param int|string $id 资源 ID
|
||||
* @return mixed 返回资源详情数据
|
||||
*/
|
||||
public function show(Request $request)
|
||||
{
|
||||
try {
|
||||
$raw = $this->service->serviceShow($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'showFormat')
|
||||
? [$this, 'showFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function showFormat($data)
|
||||
{
|
||||
foreach ($data['item_return'] as $key => $item){
|
||||
$data['item_return'][$key]['requisition_item'] = InvRequisitionItem::where('id', $item['requisition_item_id'])->first();
|
||||
}
|
||||
if (isset($data['return_at']))
|
||||
$data['return_at'] = date('Y-m-d H:i:s', $data['return_at']);
|
||||
if (isset($data['id'])){
|
||||
$data['return_attachment'] = InvRequisitionItemReturnAttachment::where('return_id', $data['id'])->get();
|
||||
$ossservice = new OssService();
|
||||
foreach ($data['return_attachment'] as $item){
|
||||
$item['file_path_pull'] = $ossservice->generatePrivateUrl($item['file_path']);
|
||||
|
||||
}
|
||||
|
||||
//归还审核附件
|
||||
$data['return_approve_attachment'] = InvRequisitionItemReturnAttachment::where('return_id', $data['id'])->get();
|
||||
foreach ($data['return_approve_attachment'] as $item){
|
||||
$item['file_path_pull'] = $ossservice->generatePrivateUrl($item['file_path']);
|
||||
}
|
||||
}
|
||||
/*if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);*/
|
||||
return $data;
|
||||
}
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回更新成功的数据或信息
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'update');
|
||||
$res = $this->service->serviceUpdate($request, $data);
|
||||
return $this->success([], '更新成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物品归还确认
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function returnItemConfirm(Request $request)
|
||||
{
|
||||
try {
|
||||
// 验证申请数据
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm');
|
||||
// 处理申请逻辑
|
||||
$result = $this->service->serviceReturnItemConfirm($request, $data, 'returnConfirm');
|
||||
|
||||
return $this->success($result, '申请提交成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物品归还确认
|
||||
* 物品兑换确认
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
@@ -169,9 +44,10 @@ class InvRequisitionItemReturnController extends BaseController
|
||||
try {
|
||||
// 验证申请数据
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'returnConfirm');
|
||||
|
||||
// 处理申请逻辑
|
||||
$result = $this->service->serviceReturnConfirm($request, $data, 'returnConfirm');
|
||||
|
||||
|
||||
return $this->success($result, '申请提交成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
namespace app\mobile\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\model\InvRequisitionItem;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\common\service\InvRequisitionReturnService;
|
||||
|
||||
@@ -23,15 +22,12 @@ class InvRequisitionReturnController extends BaseController
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if (isset($data['id'])) {
|
||||
$data['item'] = InvRequisitionItem::where('requisition_id', $data['id'])->get();
|
||||
}
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
return $data;
|
||||
}
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
}
|
||||
+1
-2
@@ -49,8 +49,7 @@
|
||||
"mpdf/mpdf": "^8.2",
|
||||
"jaeger/querylist": "^4.4",
|
||||
"zoujingli/ip2region": "^3.0",
|
||||
"webman/log": "^2.1",
|
||||
"endroid/qr-code": "^6.0"
|
||||
"webman/log": "^2.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
|
||||
Generated
+1
-154
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "28a80d57e5dbc1da167b66780b6dfd00",
|
||||
"content-hash": "bf987c3cd5510fc0637d6b64d460dde1",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aliyuncs/oss-sdk-php",
|
||||
@@ -51,55 +51,6 @@
|
||||
},
|
||||
"time": "2024-10-28T10:41:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"version": "v3.0.3",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/bacon/bacon-qr-code/v3.0.3/bacon-bacon-qr-code-v3.0.3.zip",
|
||||
"reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dasprid/enum": "^1.0.3",
|
||||
"ext-iconv": "*",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phly/keep-a-changelog": "^2.12",
|
||||
"phpunit/phpunit": "^10.5.11 || ^11.0.4",
|
||||
"spatie/phpunit-snapshot-assertions": "^5.1.5",
|
||||
"spatie/pixelmatch-php": "^1.2.0",
|
||||
"squizlabs/php_codesniffer": "^3.9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-imagick": "to generate QR code images"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BaconQrCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"BSD-2-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Scholzen 'DASPRiD'",
|
||||
"email": "mail@dasprids.de",
|
||||
"homepage": "https://dasprids.de/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "BaconQrCode is a QR code generator for PHP.",
|
||||
"homepage": "https://github.com/Bacon/BaconQrCode",
|
||||
"support": {
|
||||
"issues": "https://github.com/Bacon/BaconQrCode/issues",
|
||||
"source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.3"
|
||||
},
|
||||
"time": "2025-11-19T17:15:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.14.1",
|
||||
@@ -308,50 +259,6 @@
|
||||
],
|
||||
"time": "2024-11-12T16:29:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dasprid/enum",
|
||||
"version": "1.0.7",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/dasprid/enum/1.0.7/dasprid-enum-1.0.7.zip",
|
||||
"reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1 <9.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
|
||||
"squizlabs/php_codesniffer": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DASPRiD\\Enum\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"BSD-2-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Scholzen 'DASPRiD'",
|
||||
"email": "mail@dasprids.de",
|
||||
"homepage": "https://dasprids.de/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "PHP 7.1 enum implementation",
|
||||
"keywords": [
|
||||
"enum",
|
||||
"map"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/DASPRiD/Enum/issues",
|
||||
"source": "https://github.com/DASPRiD/Enum/tree/1.0.7"
|
||||
},
|
||||
"time": "2025-09-16T12:23:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "2.1.0",
|
||||
@@ -442,66 +349,6 @@
|
||||
],
|
||||
"time": "2025-08-10T19:31:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "endroid/qr-code",
|
||||
"version": "6.0.9",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://mirrors.cloud.tencent.com/repository/composer/endroid/qr-code/6.0.9/endroid-qr-code-6.0.9.zip",
|
||||
"reference": "21e888e8597440b2205e2e5c484b6c8e556bcd1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"bacon/bacon-qr-code": "^3.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"endroid/quality": "dev-main",
|
||||
"ext-gd": "*",
|
||||
"khanamiryan/qrcode-detector-decoder": "^2.0.2",
|
||||
"setasign/fpdf": "^1.8.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "Enables you to write PNG images",
|
||||
"khanamiryan/qrcode-detector-decoder": "Enables you to use the image validator",
|
||||
"roave/security-advisories": "Makes sure package versions with known security issues are not installed",
|
||||
"setasign/fpdf": "Enables you to use the PDF writer"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Endroid\\QrCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jeroen van den Enden",
|
||||
"email": "info@endroid.nl"
|
||||
}
|
||||
],
|
||||
"description": "Endroid QR Code",
|
||||
"homepage": "https://github.com/endroid/qr-code",
|
||||
"keywords": [
|
||||
"code",
|
||||
"endroid",
|
||||
"php",
|
||||
"qr",
|
||||
"qrcode"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/endroid/qr-code/issues",
|
||||
"source": "https://github.com/endroid/qr-code/tree/6.0.9"
|
||||
},
|
||||
"time": "2025-07-13T19:59:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.11.1",
|
||||
|
||||
@@ -34,7 +34,7 @@ return [
|
||||
// 合塑社媒
|
||||
'fb_hesu_shemei' => [
|
||||
'watch_dir' => 'excel/fb_hesu_shemei',
|
||||
'enter_user_id' => 17,
|
||||
'enter_user_id' => 186,
|
||||
'channel_id' => 6,
|
||||
'sales_user_ids' => [
|
||||
22, 23, 34, 44, 49, 71, 72, 73, 96, 104, 125, 135, 142, 155, 187
|
||||
|
||||
+6
-58
@@ -29,11 +29,6 @@ use Webman\Route;
|
||||
Route::any('/c', [app\controller\IndexController::class, 'createResource']);
|
||||
Route::any('/perm', [app\controller\IndexController::class, 'perm']);
|
||||
|
||||
// 系统间认证接口
|
||||
Route::group('/api/system', function () {
|
||||
Route::any('/auth', [app\common\controller\SystemController::class, 'auth']);
|
||||
});
|
||||
|
||||
// 飞书
|
||||
Route::any('/feishu/event', [app\common\controller\NotifyController::class, 'feishuEvent']);
|
||||
// 飞书回调
|
||||
@@ -56,7 +51,7 @@ Route::group('/common', function () {
|
||||
Route::any('/register', [app\common\controller\AuthController::class, 'register']);
|
||||
Route::any('/feishu/scope', [app\common\controller\AuthController::class, 'feishuScope']);
|
||||
Route::any('/refresh/token', [app\common\controller\AuthController::class, 'refresh']);
|
||||
Route::any('/feishu/jsapi', [app\common\controller\AuthController::class, 'getJsApi']);
|
||||
|
||||
|
||||
// // 调试
|
||||
Route::any('/feishu/auth', [app\common\controller\AuthController::class, 'feishuAuth']);
|
||||
@@ -121,8 +116,6 @@ Route::group('/common', function () {
|
||||
Route::any('/crawlModelCreate', [app\common\controller\BrandSeriesController::class, 'crawlModelCreate']);
|
||||
Route::any('/crawlKeyword', [app\common\controller\BrandSeriesController::class, 'crawlKeyword']);
|
||||
Route::any('/crawlKeywordCreate', [app\common\controller\BrandSeriesController::class, 'crawlKeywordCreate']);
|
||||
Route::any('/crawlUrl', [app\common\controller\BrandSeriesController::class, 'crawlUrl']);
|
||||
Route::any('/crawl', [app\common\controller\BrandSeriesController::class, 'crawl']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -531,37 +524,6 @@ Route::group('/admin', function () {
|
||||
Route::any('/item/update', [app\admin\controller\InvItemController::class, 'update']);
|
||||
Route::any('/item/show', [app\admin\controller\InvItemController::class, 'show']);
|
||||
Route::any('/item/destroy', [app\admin\controller\InvItemController::class, 'destroy']);
|
||||
Route::any('/item/qr-code', [app\admin\controller\InvItemController::class, 'generateQrCode']);
|
||||
Route::any('/item/qr-code/delete', [app\admin\controller\InvItemController::class, 'deleteQrCode']);
|
||||
|
||||
Route::group('/requisition', function () {
|
||||
Route::any('/list', [app\admin\controller\InvRequisitionController::class, 'index']);
|
||||
Route::any('/show', [app\admin\controller\InvRequisitionController::class, 'show']);
|
||||
Route::any('/approve', [app\admin\controller\InvRequisitionController::class, 'approve']);
|
||||
});
|
||||
|
||||
// 物品归还
|
||||
Route::group('/requisition/return', function () {
|
||||
Route::any('/store', [app\common\controller\InvRequisitionItemReturnController::class, 'store']);
|
||||
Route::any('/update', [app\common\controller\InvRequisitionItemReturnController::class, 'update']);
|
||||
Route::any('/list', [app\common\controller\InvRequisitionItemReturnController::class, 'index']);
|
||||
Route::any('/show', [app\common\controller\InvRequisitionItemReturnController::class, 'show']);
|
||||
Route::any('/confirm', [app\common\controller\InvRequisitionItemReturnController::class, 'returnConfirm']);
|
||||
// Route::any('/confirmItem', [app\common\controller\InvRequisitionItemReturnController::class, 'returnItemConfirm']);
|
||||
});
|
||||
});
|
||||
|
||||
// 库存变化记录
|
||||
Route::group('/stock-log', function () {
|
||||
Route::any('/list', [app\admin\controller\InvStockLogController::class, 'list']);
|
||||
});
|
||||
|
||||
Route::group('/requisition', function () {
|
||||
// Route::any('/list', [app\admin\controller\InvRequisitionController::class, 'index']);
|
||||
// Route::any('/show', [app\admin\controller\InvRequisitionController::class, 'show']);
|
||||
// Route::any('/approve', [app\admin\controller\InvRequisitionController::class, 'approve']);
|
||||
Route::any('/proxy-claim', [app\admin\controller\InvRequisitionController::class, 'proxyClaim']);
|
||||
Route::any('/qr-claims', [app\admin\controller\InvRequisitionController::class, 'qrClaims']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -694,28 +656,14 @@ Route::group('/mobile', function () {
|
||||
Route::any('/item/preset', [app\mobile\controller\InvItemController::class, 'preset']);
|
||||
|
||||
// 物品领用申请
|
||||
// Route::any('/requisition/list', [app\mobile\controller\InvRequisitionController::class, 'index']);
|
||||
// Route::any('/requisition/show', [app\mobile\controller\InvRequisitionController::class, 'show']);
|
||||
Route::any('/requisition/list', [app\mobile\controller\InvRequisitionController::class, 'index']);
|
||||
Route::any('/requisition/show', [app\mobile\controller\InvRequisitionController::class, 'show']);
|
||||
Route::any('/requisition/apply', [app\mobile\controller\InvRequisitionController::class, 'apply']);
|
||||
Route::any('/requisition/update', [app\mobile\controller\InvRequisitionController::class, 'update']);
|
||||
|
||||
|
||||
Route::group('/requisition', function () {
|
||||
Route::any('/list', [app\mobile\controller\InvRequisitionController::class, 'index']);
|
||||
Route::any('/show', [app\mobile\controller\InvRequisitionController::class, 'show']);
|
||||
// Route::any('/approve', [app\mobile\controller\InvRequisitionController::class, 'approve']);
|
||||
Route::any('/qr-claim', [app\mobile\controller\InvRequisitionController::class, 'qrClaim']);
|
||||
Route::any('/my-qr-claims', [app\mobile\controller\InvRequisitionController::class, 'myQrClaims']);
|
||||
});
|
||||
|
||||
// 物品归还
|
||||
Route::group('/requisition/return', function () {
|
||||
Route::any('/store', [app\mobile\controller\InvRequisitionItemReturnController::class, 'store']);
|
||||
Route::any('/update', [app\mobile\controller\InvRequisitionItemReturnController::class, 'update']);
|
||||
Route::any('/list', [app\mobile\controller\InvRequisitionItemReturnController::class, 'index']);
|
||||
Route::any('/show', [app\mobile\controller\InvRequisitionItemReturnController::class, 'show']);
|
||||
Route::any('/confirm', [app\mobile\controller\InvRequisitionItemReturnController::class, 'returnConfirm']);
|
||||
// Route::any('/confirmItem', [app\mobile\controller\InvRequisitionItemReturnController::class, 'returnItemConfirm']);
|
||||
});
|
||||
Route::any('/requisition/item/return', [app\mobile\controller\InvRequisitionItemReturnController::class, 'store']);
|
||||
Route::any('/requisition/item/return/update', [app\mobile\controller\InvRequisitionItemReturnController::class, 'update']);
|
||||
Route::any('/requisition/item/return/confirm', [app\mobile\controller\InvRequisitionItemReturnController::class, 'returnConfirm']);
|
||||
});
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
// 共享密钥(双方约定同一个字符串)
|
||||
'shared_secret' => env('SYSTEM_AUTH_SHARED_SECRET', 'your-shared-secret-string'),
|
||||
|
||||
// 签名有效期(秒),默认10分钟
|
||||
'signature_expire' => 600,
|
||||
|
||||
// Token 有效期(秒)
|
||||
'token_expire' => 86400,
|
||||
];
|
||||
Reference in New Issue
Block a user