You need to sign in or sign up before continuing.
Commit b35ce126 by 杨树贤

Merge branch 'master' into ysx-过期时间需求-20260521

parents 549e0adc 745bb649
Showing with 1705 additions and 155 deletions
---
---
name: 供应商系统新增状态和字段
overview: 新增供应商"待确认"状态(4)、逆向采购员字段、供应商来源字段及筛选项,并新建CRM同步供应商接口
todos:
- id: add-status-and-source-config
content: 在config/fixed.php和SupplierChannelModel中新增待确认状态常量和供应商来源配置
status: completed
- id: add-supplier-source-filter
content: 在SupplierFilter、SupplierListFilter中增加供应商来源筛选项
status: completed
dependencies:
- add-status-and-source-config
- id: add-transformer-fields
content: 在SupplierTransformer中增加供应商来源和逆向采购员字段映射,SupplierExtendModel增加批量查询方法
status: completed
dependencies:
- add-status-and-source-config
- id: add-list-columns
content: 在SupplierListScript中增加供应商来源和逆向采购员列
status: completed
dependencies:
- add-transformer-fields
- id: update-save-logic
content: SupplierService新增时默认supplier_source=1,SupplierApiController channelMap增加supplier_source
status: completed
dependencies:
- add-status-and-source-config
- id: add-detail-form-fields
content: 供应商详情/编辑/新增页面增加逆向采购员和供应商来源展示
status: completed
dependencies:
- add-status-and-source-config
- id: create-crm-sync-api
content: 新建CRM同步供应商接口(控制器方法+路由)
status: completed
dependencies:
- add-status-and-source-config
---
## 产品概述
在供应商系统中新增"待确认"状态、逆向采购员字段、供应商来源字段及筛选项,并新建CRM同步供应商接口,实现CRM客户转化供应商的完整数据流转。
## 核心功能
- 新增供应商状态"待确认"(值=4),作为CRM同步后供应商的初始状态
- 新增"逆向采购员"字段(lie_supplier_extend表),来源CRM创建人,仅展示不可修改
- 新增"供应商来源"字段和筛选项(supplier_channel表),1=供应商系统新增/2=CRM客户转化供应商
- 供应商新增时默认supplier_source=1,历史数据统一刷为1
- CRM同步接口:接收CRM推送创建供应商,根据名称自动补齐公司信息,映射字段,设置初始状态为待确认+CRM来源
- CRM→供应商字段映射:客户名称→供应商名称、签约公司→签约公司、联系人姓名→联系人、联系人邮箱→邮箱、联系人账号→手机号、创建人→逆向采购员、公司性质默认工厂渠道、协议附件选填同步
## 技术栈
- 后端框架:Laravel (PHP)
- 数据库:MySQL (web连接)
- 缓存:Redis
- HTTP客户端:GuzzleHttp (调用CRM/天眼查接口)
- 前端:Layui + Blade模板引擎
## 实现方案
### 1. 新增"待确认"状态
- `config/fixed.php` SupplierStatus数组增加 `4 => '待确认'`
- `SupplierChannelModel` 增加常量 `STATUS_CONFIRM = 4`
### 2. 新增"供应商来源"字段
- `config/fixed.php` 新增 SupplierSource 配置
- `SupplierChannelModel` 增加常量 `SUPPLIER_SOURCE_SYSTEM = 1` / `SUPPLIER_SOURCE_CRM = 2`
- `supplier_channel` 表增加 `supplier_source` 字段(tinyint, default 1)
- 供应商系统新增时默认 `supplier_source = 1`
- CRM同步时设置 `supplier_source = 2`
### 3. 新增"逆向采购员"字段
- `lie_supplier_extend` 表增加 `reverse_purchaser` 字段(varchar(100), default '')
- 在SupplierTransformer中通过supplier_code关联查询supplier_extend表获取reverse_purchaser
### 4. 供应商列表展示与筛选
- `SupplierTransformer::transformList()` 增加 supplier_source_name 和 reverse_purchaser_username 的映射
- `SupplierListScript.blade.php` cols数组增加"供应商来源"和"逆向采购员"列
- `SupplierFilter::listFilter()` 增加 supplier_source 筛选条件
- `SupplierListFilter.blade.php` 增加"供应商来源"下拉筛选
### 5. 供应商详情/编辑页面
- 逆向采购员仅展示,不可修改
- 供应商来源仅展示,不可修改
### 6. CRM同步供应商接口
- `SupplierSyncController` 新增 `syncCrmSupplier` 方法
- 路由注册在 `/sync/crm/syncSupplier`(external中间件组)
- 同步逻辑:
1. 接收CRM推送数据
2. 检查供应商名称是否已存在,存在则返回
3. 根据供应商名称调用天眼查/一体化接口补齐公司信息(税号、注册资金、电话、地址、法人、成立时间)
4. 设置 supplier_group=6(工厂渠道)、status=4(待确认)、supplier_source=2(CRM)
5. 创建供应商主记录、联系人、附件(协议)
6. 将CRM创建人写入supplier_extend.reverse_purchaser
7. 生成供应商编码、初始化有效期、同步一体化实体名单校验
### 7. SupplierApiController channelMap补充
- 增加 `supplier_source` 到 channelMap
## 实现注意事项
- supplier_source字段默认值为1,历史数据无需额外刷(DDL default 1自动生效),但为安全起见建议执行update语句
- CRM同步接口属于external中间件组,无需登录认证,需注意参数校验
- 逆向采购员存储在supplier_extend表,需要在transformList中批量查询(避免N+1问题)
- "待确认"状态(4)的供应商,在审核操作中需作为可审核状态处理
- CRM同步时如果供应商名称已存在,直接返回成功(幂等性)
- 工厂渠道(supplier_group=6)的供应商编码前缀为'FOO'
## 架构设计
```mermaid
flowchart TD
CRM[CRM系统] -->|推送客户数据| API[/sync/crm/syncSupplier]
API -->|创建供应商| Service[SupplierService]
Service -->|写入主表| Channel[supplier_channel]
Service -->|写入扩展表| Extend[lie_supplier_extend]
Service -->|写入联系人| Contact[supplier_contact]
Service -->|写入附件| Attachment[supplier_attachments]
Service -->|补齐公司信息| TYC[天眼查/一体化API]
List[供应商列表] -->|展示| Transformer[SupplierTransformer]
Transformer -->|关联查询| Extend
Transformer -->|映射来源名称| Config[SupplierSource配置]
Filter[供应商筛选] -->|supplier_source| FilterLogic[SupplierFilter]
```
## 目录结构
```
/data/www/liexin_supplier/
├── config/
│ └── fixed.php # [MODIFY] 新增SupplierStatus待确认、SupplierSource配置
├── app/
│ ├── Model/
│ │ └── SupplierChannelModel.php # [MODIFY] 新增STATUS_CONFIRM/SUPPLIER_SOURCE_SYSTEM/SUPPLIER_SOURCE_CRM常量
│ │ └── SupplierExtendModel.php # [MODIFY] 新增getReversePurchaserBySupplierIds批量查询方法
│ ├── Http/
│ │ ├── Controllers/
│ │ │ ├── Sync/
│ │ │ │ └── SupplierSyncController.php # [MODIFY] 新增syncCrmSupplier方法
│ │ │ ├── Filter/
│ │ │ │ └── SupplierFilter.php # [MODIFY] listFilter增加supplier_source筛选条件
│ │ │ └── Api/
│ │ │ └── SupplierApiController.php # [MODIFY] channelMap增加supplier_source
│ │ ├── Services/
│ │ │ └── SupplierService.php # [MODIFY] saveSupplier新增时默认supplier_source=1
│ │ └── Transformers/
│ │ └── SupplierTransformer.php # [MODIFY] transformList/transformInfo增加supplier_source_name和reverse_purchaser_username
│ └── routes.php # [MODIFY] 新增CRM同步路由
├── resources/
│ └── views/
│ ├── script/
│ │ └── SupplierListScript.blade.php # [MODIFY] cols增加供应商来源和逆向采购员列
│ └── web/
│ └── supplier/
│ ├── SupplierListFilter.blade.php # [MODIFY] 增加供应商来源筛选项
│ └── SupplierBase.blade.php # [MODIFY] 增加逆向采购员和供应商来源只读展示
```
## SubAgent
- **code-explorer**
- Purpose: 探索供应商详情页面和表单视图的具体结构,确认逆向采购员和供应商来源字段的展示位置
- Expected outcome: 确认SupplierBase.blade.php和AddSupplier.blade.php的表单结构,指导字段添加位置
\ No newline at end of file
# Project Structure (Auto-generated)
> This file was automatically generated by CodeWhale.
> You can edit or delete it at any time.
**Summary:** A JavaScript/Node.js project
**Tree:**
```
FILE: .augmentignore
DIR: .codebuddy
DIR: plans
FILE: .codeiumignore
FILE: .cursorignore
FILE: .env
FILE: .env.example
DIR: .git
FILE: COMMIT_EDITMSG
FILE: FETCH_HEAD
FILE: HEAD
FILE: ORIG_HEAD
DIR: branches
FILE: config
FILE: description
DIR: hooks
FILE: index
DIR: info
DIR: logs
DIR: objects
FILE: opencode
FILE: packed-refs
DIR: refs
FILE: .gitattributes
FILE: .gitignore
FILE: .gitmodules
DIR: app
DIR: Console
DIR: Events
DIR: Exceptions
DIR: Http
DIR: Jobs
DIR: Listeners
DIR: Model
DIR: Policies
DIR: Presenters
DIR: Providers
FILE: User.php
DIR: Utils
FILE: artisan
DIR: bootstrap
FILE: app.php
FILE: autoload.php
DIR: cache
FILE: composer.json
FILE: composer.lock
DIR: config
FILE: app.php
FILE: auth.php
FILE: broadcasting.php
FILE: cache.php
FILE: compile.php
FILE: database.php
FILE: dompdf.php
FILE: excel.php
FILE: field.php
FILE: filesystems.php
FILE: fixed.php
FILE: mail.php
FILE: perm.php
FILE: queue.php
FILE: services.php
FILE: session.php
FILE: sync.php
FILE: validate.php
FILE: view.php
FILE: website.php
DIR: database
FILE: .gitignore
DIR: factories
DIR: migrations
DIR: seeds
FILE: test_attachment_audit_flow.sql
DIR: docs
FILE: AttachmentAudit_Module_README.md
FILE: SupplierAuditCenter_Integration.md
FILE: curl测试语句.md
FILE: gulpfile.js
FILE: package.json
FILE: phpunit.xml
DIR: public
FILE: .htaccess
DIR: data
FILE: favicon.ico
DIR: fonts
DIR: images
FILE: index.php
DIR: js
DIR: plugins
FILE: robots.txt
FILE: web.config
FILE: readme.md
DIR: resources
DIR: assets
DIR: lang
DIR: views
FILE: server.php
DIR: tests
FILE: ExampleTest.php
FILE: TestCase.php
DIR: vendor
FILE: autoload.php
DIR: barryvdh
DIR: bin
DIR: classpreloader
DIR: composer
DIR: dnoegel
DIR: doctrine
DIR: dompdf
DIR: fzaninotto
DIR: guzzlehttp
DIR: hamcrest
DIR: jakub-onderka
DIR: jenssegers
DIR: jeremeamia
DIR: kylekatarnls
DIR: laravel
DIR: league
DIR: maatwebsite
DIR: mockery
DIR: mongodb
DIR: monolog
DIR: mtdowling
DIR: nesbot
DIR: nikic
DIR: paragonie
DIR: phenx
DIR: php-amqplib
DIR: phpdocumentor
DIR: phpoffice
DIR: phpspec
DIR: phpunit
DIR: predis
DIR: psr
DIR: psy
DIR: ralouphie
DIR: sabberworm
DIR: sebastian
DIR: swiftmailer
DIR: symfony
DIR: tijsverkoyen
DIR: vladimir-yuldashev
DIR: vlucas
DIR: webmozart
```
\ No newline at end of file
......@@ -155,7 +155,7 @@ PERM_URL=http://perm.liexin.net/api/check
PERM_LIST=http://perm.liexin.net/api/perms
PERM_ID=25
PERM_GOURL=http://perm.liexin.net
ADMIN_GROUP=10000,20000
ADMIN_GROUP=1000,20000
MENU_ID=16
MENU_URL=http://data.liexin.net/api/config/
FOOTSTONE_URL=http://footstone.liexindev.net
......@@ -168,6 +168,6 @@ IMAGE_SERVER_URL=http://image.liexindev.net
FILE_SERVER_URL=http://file.liexindev.net
CRM_URL=http://crmnew.liexindev.net
CRM_URL=http://crmnew_v4.liexindev.net
CUBE_URL=http://cube.liexindev.net
......@@ -10,4 +10,6 @@ Homestead.json
/vendor/_laravel_ide
/storage/framework/views
/storage
CLAUDE.md
\ No newline at end of file
CLAUDE.md
/.windsurf
/skills-lock.json
......@@ -7,6 +7,7 @@ use App\Http\Services\AdminUserService;
use App\Http\Services\CompanyService;
use App\Http\Services\StandardBrandService;
use App\Model\BrandModel;
use App\Model\RedisModel;
use App\Model\StandardBrandModel;
use App\Model\SupplierChannelModel;
use Illuminate\Http\Request;
......@@ -120,4 +121,33 @@ class CommonApiController extends Controller
$this->response(0, 'ok', $result);
}
//保存列表列显示设置
public function SaveColSettings(Request $request)
{
$userId = $request->input('user_id', 0);
$pageKey = $request->input('page_key', '');
$settings = $request->input('settings', '');
if (empty($userId) || empty($pageKey) || empty($settings)) {
$this->response(-1, '参数错误');
}
$redis = new RedisModel();
$hashKey = 'col_settings:' . $pageKey;
$redis->hset($hashKey, $userId, $settings);
$this->response(0, 'ok');
}
//获取列表列显示设置
public function GetColSettings(Request $request)
{
$userId = $request->input('user_id', 0);
$pageKey = $request->input('page_key', '');
if (empty($userId) || empty($pageKey)) {
$this->response(-1, '参数错误');
}
$redis = new RedisModel();
$hashKey = 'col_settings:' . $pageKey;
$settings = $redis->hget($hashKey, $userId);
$this->response(0, 'ok', $settings ? json_decode($settings, true) : new \stdClass());
}
}
......@@ -60,16 +60,59 @@ class SkuApiController extends Controller
$supplierCode = $request->get('supplier_code');
$brandId = $request->get('brand_ids');
$brandId = str_replace(',', '', $brandId);
// $updateTime = $request->get('update_time');
if (empty($supplierCode)) {
$this->response(-1, '请选择供应商');
}
// $startTime = $endTime = 0;
// if ($updateTime) {
// $updateTime = explode('~', $updateTime);
// $startTime = $updateTime[0];
// $endTime = $updateTime[1];
// }
$supplier = SupplierChannelModel::where('supplier_code', $supplierCode)->first();
if (empty($supplier)) {
$this->response(-1, '供应商不存在');
}
if (!checkPerm('ViewAllSku')) {
$userId = $request->user->userId;
$codeId = $request->user->codeId;
$canViewSubordinate = checkPerm('ViewSubordinateSku');
if ($canViewSubordinate) {
$departmentService = new \App\Http\Services\DepartmentService();
$subordinateUserIds = $departmentService->getSubordinateUserIds($userId);
$adminUserService = new \App\Http\Services\AdminUserService();
$subordinateCodeIds = $adminUserService->getCodeIdsByUserIds($subordinateUserIds)->toArray();
$subordinateCodeIds[] = $codeId;
$isAuthorized = false;
if (in_array($supplier->purchase_uid, $subordinateCodeIds)) {
$isAuthorized = true;
}
if (!empty($supplier->channel_uid)) {
$channelUids = explode(',', trim($supplier->channel_uid, ','));
foreach ($channelUids as $channelUid) {
if (in_array($channelUid, $subordinateCodeIds)) {
$isAuthorized = true;
break;
}
}
}
if (!$isAuthorized) {
$this->response(-1, '无权限操作该供应商的SKU');
}
} else {
$isAuthorized = false;
if ($supplier->purchase_uid == $codeId) {
$isAuthorized = true;
}
if (!empty($supplier->channel_uid)) {
$channelUids = explode(',', trim($supplier->channel_uid, ','));
if (in_array($codeId, $channelUids)) {
$isAuthorized = true;
}
}
if (!$isAuthorized) {
$this->response(-1, '无权限操作该供应商的SKU');
}
}
}
$uploadLogId = SkuUploadLogModel::where('supplier_code', $supplierCode)
->where('status', SkuUploadLogModel::STATUS_HANDLED)->orderBy('id', 'desc')
......@@ -89,7 +132,6 @@ class SkuApiController extends Controller
'log_id' => $uploadLogId,
"down_type" => 1,
];
//改成队列
(new SkuService())->batchOffShelfSkuQueue($data);
$this->response(0, '批量下架任务已经发送,请等待任务完成,期间你可以刷新列表查看下架情况');
}
......@@ -131,6 +173,59 @@ class SkuApiController extends Controller
'operate_type',
'cp_time',
]);
$supplierCodes = explode(',', $data['supplier_codes']);
if (!checkPerm('ViewAllSku')) {
$userId = $request->user->userId;
$codeId = $request->user->codeId;
$canViewSubordinate = checkPerm('ViewSubordinateSku');
if ($canViewSubordinate) {
$departmentService = new \App\Http\Services\DepartmentService();
$subordinateUserIds = $departmentService->getSubordinateUserIds($userId);
$adminUserService = new \App\Http\Services\AdminUserService();
$subordinateCodeIds = $adminUserService->getCodeIdsByUserIds($subordinateUserIds)->toArray();
$subordinateCodeIds[] = $codeId;
$suppliers = SupplierChannelModel::whereIn('supplier_code', $supplierCodes)->get();
foreach ($suppliers as $supplier) {
$isAuthorized = false;
if (in_array($supplier->purchase_uid, $subordinateCodeIds)) {
$isAuthorized = true;
}
if (!empty($supplier->channel_uid)) {
$channelUids = explode(',', trim($supplier->channel_uid, ','));
foreach ($channelUids as $channelUid) {
if (in_array($channelUid, $subordinateCodeIds)) {
$isAuthorized = true;
break;
}
}
}
if (!$isAuthorized) {
$this->response(-1, '无权限操作供应商 ' . $supplier->supplier_code . ' 的SKU');
}
}
} else {
$suppliers = SupplierChannelModel::whereIn('supplier_code', $supplierCodes)->get();
foreach ($suppliers as $supplier) {
$isAuthorized = false;
if ($supplier->purchase_uid == $codeId) {
$isAuthorized = true;
}
if (!empty($supplier->channel_uid)) {
$channelUids = explode(',', trim($supplier->channel_uid, ','));
if (in_array($codeId, $channelUids)) {
$isAuthorized = true;
}
}
if (!$isAuthorized) {
$this->response(-1, '无权限操作供应商 ' . $supplier->supplier_code . ' 的SKU');
}
}
}
}
if ($data['operate_type'] == SkuService::OPERATE_TYPE_PUTAWAY) {
if ($data['is_long_term'] == -1 && empty($data['cp_time'])) {
$this->response(-1, '请设置上架有效期');
......
......@@ -107,6 +107,7 @@ class SupplierApiController extends Controller
'sku_optional_batch',
'nation_id',
'supplier_source',
];
public function Entrance(Request $request, $id)
......@@ -294,6 +295,13 @@ class SupplierApiController extends Controller
//写日志
$logService = new LogService();
$logService->AddLog($supplierId, LogModel::UPDATE_OPERATE, '禁用', '禁用供应商,理由是 : ' . $disableReason);
// CRM来源供应商同步状态到CRM
if ($supplier['supplier_source'] == SupplierChannelModel::SUPPLIER_SOURCE_CRM) {
$crmStatus = CrmService::mapSupplierStatusToCrm(SupplierChannelModel::STATUS_DISABLE);
CrmService::syncSupplierStatus($supplier['supplier_name'], $crmStatus, '禁止交易: ' . $disableReason);
}
$this->response(0, '禁用成功');
} else {
$this->response(-1, '禁用失败');
......@@ -721,6 +729,14 @@ class SupplierApiController extends Controller
if ($result) {
$logService = new LogService();
$logService->AddLog($supplierId, LogModel::UPDATE_OPERATE, '拉黑', '拉黑供应商');
// CRM来源供应商同步状态到CRM
$supplier = $channelModel->where('supplier_id', $supplierId)->first();
if ($supplier && $supplier['supplier_source'] == SupplierChannelModel::SUPPLIER_SOURCE_CRM) {
$crmStatus = CrmService::mapSupplierStatusToCrm(SupplierChannelModel::STATUS_BLOCK);
CrmService::syncSupplierStatus($supplier['supplier_name'], $crmStatus, '拉入黑名单');
}
$this->response(0, '拉黑成功');
} else {
$this->response(-1, '拉黑操作失败');
......@@ -886,7 +902,13 @@ class SupplierApiController extends Controller
{
$supplierId = $request->get('supplier_id');
$supplierAuditService = new AuditCenterService();
$result = $supplierAuditService->getAuditInfoByIdAndType($supplierId, AuditCenterService::TYPE_SUPPLIER_AUDIT);
//判断是否是待确认,是的话去请求crm转供应商的审核
$status = SupplierChannelModel::where('supplier_id', $supplierId)->value('status');
if ($status == SupplierChannelModel::STATUS_CONFIRM) {
$result = $supplierAuditService->getAuditInfoByIdAndType($supplierId, AuditCenterService::TYPE_CUSTOMER_CONVERT_SUPPLIER_AUDIT);
} else {
$result = $supplierAuditService->getAuditInfoByIdAndType($supplierId, AuditCenterService::TYPE_SUPPLIER_AUDIT);
}
$this->response(0, 'ok', $result);
}
}
<?php
namespace App\Http\Controllers\Api;
use Exception;
use App\Model\LogModel;
use Illuminate\Http\Request;
use App\Http\Services\CrmService;
use App\Http\Services\LogService;
use App\Model\SupplierChannelModel;
use App\Http\Controllers\Controller;
use App\Http\Services\AuditCenterService;
use App\Http\Services\SupplierAuditService;
//CRM转移供应商相关接口
class SupplierCrmApiController extends Controller
{
public function Entrance(Request $request, $id)
{
$this->$id($request, $id);
}
//客户转化供应商 - 审核操作
public function AuditCustomerConvertSupplier($request)
{
$supplierId = $request->get('supplier_id');
$auditOpinion = $request->get('audit_opinion'); // agree / disagree
$remark = trim($request->get('remark', ''));
$channelUid = $request->get('channel_uid', '');
if (empty($auditOpinion)) {
$this->response(-1, '必须选择一个审核意见');
}
if ($auditOpinion == 'disagree' && empty($remark)) {
$this->response(-1, '请填写原因说明');
}
if ($auditOpinion == 'agree' && empty($channelUid)) {
$this->response(-1, '请指定采购员');
}
// 校验审核流状态,已拒绝的不允许再审核
$auditBillInfo = AuditCenterService::getAuditInfoByIdAndType($supplierId, AuditCenterService::TYPE_CUSTOMER_CONVERT_SUPPLIER_AUDIT);
if (!empty($auditBillInfo) && $auditBillInfo['approval_status'] == AuditCenterService::APPROVAL_STATUS_REFUSE) {
$this->response(-1, '审核流已被拒绝,无法继续审核');
}
$approvalStatus = $auditOpinion == 'agree' ? 1 : 2;
try {
$auditService = new SupplierAuditService();
$result = $auditService->auditCustomerConvertSupplier($supplierId, $approvalStatus, $remark, $channelUid);
$this->response(0, '审核成功');
} catch (Exception $e) {
$this->response(-1, '审核失败: ' . $e->getMessage());
}
}
//获取客户转化供应商审核流程
public function GetCustomerConvertAuditFlow($request)
{
$supplierId = $request->get('supplier_id');
$result = AuditCenterService::getAuditInfoByIdAndType($supplierId, AuditCenterService::TYPE_CUSTOMER_CONVERT_SUPPLIER_AUDIT);
$this->response(0, 'ok', $result);
}
}
\ No newline at end of file
......@@ -36,12 +36,17 @@ class LogFilter
$departmentService = new DepartmentService();
//下属用户id(结果包括自己的id)
$subordinateUserIds = $departmentService->getSubordinateUserIds($adminId);
// 系统操作日志(admin_id=0)对所有用户可见
$subordinateUserIds[] = 0;
$query->whereIn('admin_id', $subordinateUserIds);
} else {
//剩下的就只是看自己相关的
$query->where('admin_id', $adminId);
// 加上系统操作日志(admin_id=0)对所有用户可见
$query->where(function ($q) use ($adminId) {
$q->where('admin_id', $adminId)->orWhere('admin_id', 0);
});
}
}
return $query;
}
}
}
\ No newline at end of file
......@@ -21,7 +21,6 @@ class SkuListFilter
$map = array_map(function ($item) {
return trim($item);
}, $map);
//dd($map);
//只获取专卖的数据
$map['supplier_id'] = 17;
if ((!empty($map['create_time']))) {
......@@ -32,18 +31,38 @@ class SkuListFilter
unset($map['create_time']);
}
$userId = request()->user->userId;
$codeId = request()->user->codeId;
if (checkPerm('ViewAllSku')) {
} else if (checkPerm('ViewSubordinateSku')) {
//查看下级
$departmentService = new DepartmentService();
//下属用户id(结果包括自己的id)
$subordinateUserIds = $departmentService->getSubordinateUserIds($userId);
$adminUserService = new AdminUserService();
$subordinateCodeIds = $adminUserService->getCodeIdsByUserIds($subordinateUserIds);
$subordinateCodeIds = $subordinateCodeIds->toArray();
$map['encoded/eqs'] = implode(',', $subordinateCodeIds);
// $map['encoded/eqs'] = implode(',', $subordinateCodeIds);
$supplierCodes = SupplierChannelModel::where(function ($query) use ($subordinateCodeIds) {
$query->whereIn('purchase_uid', $subordinateCodeIds)
->orWhereRaw("channel_uid REGEXP '" . implode('|', $subordinateCodeIds) . "'");
})->whereNotNull('supplier_code')->where('supplier_code', '!=', '')->pluck('supplier_code')->toArray();
if (!empty($supplierCodes)) {
$map['canal_new/eqs'] = implode(',', $supplierCodes);
} else {
$map['canal_new/eqs'] = 'NO_MATCH';
}
} else {
$map['encoded/condition'] = request()->user->codeId;
// $map['encoded/condition'] = $codeId;
$supplierCodes = SupplierChannelModel::where(function ($query) use ($codeId) {
$query->where('purchase_uid', $codeId)
->orWhere('channel_uid', 'like', '%' . $codeId . '%');
})->whereNotNull('supplier_code')->where('supplier_code', '!=', '')->pluck('supplier_code')->toArray();
if (!empty($supplierCodes)) {
$map['canal_new/eqs'] = implode(',', $supplierCodes);
} else {
$map['canal_new/eqs'] = 'NO_MATCH';
}
}
if ((!empty($map['update_time']))) {
$times = explode('~', $map['update_time']);
......@@ -70,26 +89,11 @@ class SkuListFilter
}
if (!empty($map['data_channel_uid'])) {
$map['encoded/condition'] = $map['data_channel_uid'];
unset($map['data_channel_uid']);
}
//根据数据维护员(purchase_uid)查询对应的供应商编码,多个一起请求
if (!empty($map['purchase_uid'])) {
$supplierCodes = SupplierChannelModel::where('purchase_uid', $map['purchase_uid'])
->whereNotNull('supplier_code')
->where('supplier_code', '!=', '')
->pluck('supplier_code')
->toArray();
if (!empty($supplierCodes)) {
$map['canal_new/eqs'] = implode(',', $supplierCodes);
} else {
// 没有匹配的供应商,传一个不存在的值以确保查不到数据
$map['canal_new/eqs'] = 'NO_MATCH';
}
unset($map['purchase_uid']);
}
if (!empty($map['source_type'])) {
switch ($map['source_type']) {
case 'all':
......
......@@ -22,17 +22,16 @@ class SupplierAccountFilter
if (!checkPerm('ViewAllSupplierAccount')) {
if (checkPerm('ViewSubSupplierAccount')) {
$departmentService = new DepartmentService();
//下属用户id(结果包括自己的id)
$subordinateUserIds = $departmentService->getSubordinateUserIds($request->user->userId);
$adminUserService = new AdminUserService();
$subordinateCodeIds = $adminUserService->getCodeIdsByUserIds($subordinateUserIds);
$subordinateCodeIds = $subordinateCodeIds->toArray();
$likeSqlRaw = implode('|', $subordinateCodeIds);
$supplierIds = SupplierChannelModel::whereRaw(DB::raw("(channel_uid REGEXP '$likeSqlRaw')"))->pluck('supplier_id')->toArray();
$inCodeIdSql = implode(',', $subordinateCodeIds);
$supplierIds = SupplierChannelModel::whereRaw(DB::raw("(channel_uid REGEXP '$likeSqlRaw' OR purchase_uid IN ($inCodeIdSql))"))->pluck('supplier_id')->toArray();
$query->whereIn('supplier_id', $supplierIds);
} else {
//否则只能查看自己的
$supplierIds = SupplierChannelModel::whereRaw(DB::raw("(channel_uid REGEXP '$codeId')"))->pluck('supplier_id')->toArray();
$supplierIds = SupplierChannelModel::whereRaw(DB::raw("(channel_uid REGEXP '$codeId' OR purchase_uid = '$codeId')"))->pluck('supplier_id')->toArray();
$query->whereIn('supplier_id', $supplierIds);
}
}
......
......@@ -101,6 +101,10 @@ class SupplierFilter
}
}
if (!empty($map['supplier_source'])) {
$query->where('supplier_source', $map['supplier_source']);
}
if (!empty($map['create_uid'])) {
//因为传过来的是内部编码,所以要转成admin_id
$adminService = new AdminUserService();
......@@ -313,15 +317,24 @@ class SupplierFilter
$canViewFakeSupplier = checkPerm('ViewFakeSupplier');
$canViewBlockSupplier = checkPerm('ViewBlockSupplier');
$canViewDisableSupplier = checkPerm('ViewDisableSupplier');
$canViewConfirmSupplier = checkPerm('ViewConfirmSupplier');
// 构建复合查询条件:基础条件 OR 特殊状态
$query->where(function ($mainQuery) use ($canViewFakeSupplier, $canViewBlockSupplier, $canViewDisableSupplier, $userId, $codeId, $canViewAllSupplier, $canViewSubordinateSupplier) {
$query->where(function ($mainQuery) use ($canViewFakeSupplier, $canViewBlockSupplier, $canViewDisableSupplier, $canViewConfirmSupplier, $userId, $codeId, $canViewAllSupplier, $canViewSubordinateSupplier) {
// 主要条件组:基础业务条件
$mainQuery->where(function ($baseQuery) use ($canViewFakeSupplier, $userId, $codeId, $canViewAllSupplier, $canViewSubordinateSupplier) {
$mainQuery->where(function ($baseQuery) use ($canViewFakeSupplier, $canViewConfirmSupplier, $userId, $codeId, $canViewAllSupplier, $canViewSubordinateSupplier) {
// 基础类型限制
if (!$canViewFakeSupplier) {
$baseQuery->where('is_type', 0);
}
// 如果没有查看待确认供应商权限,过滤掉待确认和CRM转移供应商不通过状态的供应商
if (!$canViewConfirmSupplier) {
$baseQuery->whereNotIn('status', [
SupplierChannelModel::STATUS_CONFIRM,
SupplierChannelModel::STATUS_CRM_REJECTED
]);
}
// 权限相关的条件
if (!$canViewAllSupplier) {
if ($canViewSubordinateSupplier) {
......@@ -360,6 +373,10 @@ class SupplierFilter
if ($canViewDisableSupplier && !checkPerm('ViewAllSupplier')) {
$mainQuery->orWhere('status', SupplierChannelModel::STATUS_DISABLE);
}
if ($canViewConfirmSupplier && !checkPerm('ViewAllSupplier')) {
$mainQuery->orWhere('status', SupplierChannelModel::STATUS_CONFIRM);
$mainQuery->orWhere('status', SupplierChannelModel::STATUS_CRM_REJECTED);
}
// //只有原厂、代理商需要走权限,其他性质的随便看
// if (!checkPerm('ViewAllSupplier')) {
......
......@@ -29,15 +29,17 @@ class SupplierLogFilter
//可以查看所有的话,默认不做任何限制
} elseif ($canViewSubordinateLog) {
//如果能看部下的,那需要判断的地方就多了不少
if ($canViewSubordinateLog) {
$departmentService = new DepartmentService();
//下属用户id(结果包括自己的id)
$subordinateUserIds = $departmentService->getSubordinateUserIds($adminId);
$query->whereIn('admin_id', $subordinateUserIds);
} else {
//剩下的就只是看自己相关的
$query->where('admin_id', $adminId);
}
$departmentService = new DepartmentService();
//下属用户id(结果包括自己的id)
$subordinateUserIds = $departmentService->getSubordinateUserIds($adminId);
// 系统操作日志(admin_id=0)对所有用户可见
$subordinateUserIds[] = 0;
$query->whereIn('admin_id', $subordinateUserIds);
} else {
// 剩下的就只是看自己相关的,加上系统操作日志
$query->where(function ($q) use ($adminId) {
$q->where('admin_id', $adminId)->orWhere('admin_id', 0);
});
}
return $query;
}
......
......@@ -2,9 +2,9 @@
namespace App\Http\Controllers;
use function foo\func;
use App\Model\LogModel;
use App\Model\NationModel;
use App\Model\RedisModel;
use Illuminate\Http\Request;
use App\Model\IntracodeModel;
use App\Http\Services\LogService;
......@@ -22,8 +22,8 @@ use App\Http\Services\SkuUploadLogService;
use App\Http\Services\StandardBrandService;
use App\Http\Transformers\SupplierTransformer;
use App\Http\Services\SupplierAttachmentService;
use App\Model\SupplierExtendModel;
use App\Http\Services\SupplierShareApplyService;
use App\Http\Services\SupplierStatisticsService;
class SupplierController extends Controller
{
......@@ -119,6 +119,12 @@ class SupplierController extends Controller
//获取创建人部门树
$this->data['createUserDepartmentList'] = (new DepartmentService())->getCreateUserDepartmentListForXmSelect();
//获取列显示设置
$redis = new RedisModel();
$hashKey = 'col_settings:supplier_list';
$colSettings = $redis->hget($hashKey, $request->user->userId);
$this->data['colSettings'] = $colSettings ? $colSettings : '{}';
return $this->view('供应商列表');
}
......@@ -433,6 +439,41 @@ class SupplierController extends Controller
return $this->view('禁用供应商');
}
//转化供应商确认
public function ConfirmCrmSupplier($request)
{
$supplierId = $request->get('supplier_id');
$supplierModel = new SupplierChannelModel();
$supplier = $supplierModel->where('supplier_id', $supplierId)->first();
if (empty($supplier)) {
return '供应商不存在';
}
$supplier = $supplier->toArray();
$this->data['supplier'] = $supplier;
// 获取CRM扩展信息(客户性质、备注)
$extendInfo = SupplierExtendModel::getCrmExtendBySupplierId($supplierId);
$this->data['customer_nature'] = array_get($extendInfo, 'customer_nature', '');
$this->data['crm_remark'] = array_get($extendInfo, 'crm_remark', '');
$this->data['reverse_purchaser'] = array_get($extendInfo, 'reverse_purchaser', '');
// 获取采购员列表
$intraCodeModel = new IntracodeModel();
$this->data['userCodes'] = $intraCodeModel->getChannelUsersEncode(false);
$this->data['has_channel_uid'] = !empty($supplier['channel_uid']);
// 获取审核流状态,判断是否已拒绝
$auditBillInfo = AuditCenterService::getAuditInfoByIdAndType($supplierId, AuditCenterService::TYPE_CUSTOMER_CONVERT_SUPPLIER_AUDIT);
$auditRejected = false;
if (!empty($auditBillInfo) && $auditBillInfo['approval_status'] == AuditCenterService::APPROVAL_STATUS_REFUSE) {
$auditRejected = true;
}
$this->data['audit_rejected'] = $auditRejected;
return $this->view('转化供应商确认');
}
//导出供应商详情表格
public function PrintSupplier($request)
{
......
......@@ -14,12 +14,10 @@ class BaseSyncController extends Controller
{
public function syncResponse($code = 0, $msg = '成功', $data = '', $count = 0)
{
header('Content-Type: application/json');
echo json_encode([
return response()->json([
'code' => $code,
'msg' => $msg,
'msg' => $msg,
'data' => $data,
]);
exit();
}
}
......@@ -62,6 +62,11 @@ class AdminUserService
return UserInfoModel::where('name', $userName)->value('userId');
}
public function getAdminUserNameByUserId($userId)
{
return UserInfoModel::where('userId', $userId)->value('name');
}
public function getAdminIdByEmail($email)
{
return UserInfoModel::where('email', $email)->value('userId');
......
......@@ -19,6 +19,7 @@ class AuditCenterService
const TYPE_SUPPLIER_AUDIT = 'supplier_audit';
const TYPE_CUSTOMER_CONVERT_SUPPLIER_AUDIT = 'customer_convert_supplier_audit';
public static function getAuditInfoByIdAndType($id, $type)
{
......@@ -125,7 +126,6 @@ class AuditCenterService
'apply_node_ids' => array_get($params, 'apply_node_ids', ''),
];
$response = self::requestAudit("/sync/bill/addBill", $requestData);
if ($response['code'] != 0) {
throw new Exception($response['msg']);
}
......@@ -145,7 +145,7 @@ class AuditCenterService
if ($result['code'] != 0) {
throw new Exception($result['msg']);
}
Log::info("---------------同步请求audit接口 {$route}-----audit返回结果-------------");
Log::info("---------------同步请求audit接口 {$route}-----audit返回结果-------------".\json_encode($result['data']));
return $result;
} catch (\Throwable $e) {
throw $e;
......
......@@ -32,8 +32,16 @@ class BlacklistService
} else {
$res = $model->insert($data);
}
// CRM来源供应商同步状态到CRM
$supplier = $supplierModel->where('supplier_id', $supplierId)->first();
if ($supplier && $supplier['supplier_source'] == SupplierChannelModel::SUPPLIER_SOURCE_CRM) {
$crmStatus = CrmService::mapSupplierStatusToCrm(SupplierChannelModel::STATUS_BLOCK);
CrmService::syncSupplierStatus($supplier['supplier_name'], $crmStatus, '拉入黑名单: ' . $reason);
}
return $res;
}
return false;
}
}
\ No newline at end of file
}
......@@ -73,6 +73,7 @@ class CompanyService
$company = [
'supplier_name' => $companyInfo['com_name'] == $supplierName ? $companyInfo['com_name'] : $companyInfo['en_com_name'],
'registered_capital' => (int)$companyInfo['registered_capital'],
'legal_representative' => isset($companyInfo['legal_representative']) ? $companyInfo['legal_representative'] : '',
'supplier_address' => $companyInfo['com_address'],
'tax_number' => $companyInfo['tyc_info']['tax_number'],
'phone' => $companyInfo['tyc_info']['phone_number'],
......
......@@ -4,7 +4,7 @@ namespace App\Http\Services;
use GuzzleHttp\Client;
use App\Model\RedisModel;
use Illuminate\Support\Facades\DB;
use App\Model\SupplierChannelModel;
class CrmService
{
......@@ -17,20 +17,15 @@ class CrmService
return json_decode($cachedData, true);
}
try {
$url = env('CRM_URL') . '/open/signComs/getSignComs?use_scope=2';
$client = new Client();
$response = $client->get($url);
$result = json_decode($response->getBody()->getContents(), true);
if ($result['code'] != 0) {
return [];
}
(new RedisModel())->setex($cacheKey, 60, json_encode($result['data']['list']));
return $result['data']['list'];
} catch (\Exception $e) {
$url = env('CRM_URL') . '/open/signComs/getSignComs';
$client = new Client();
$response = $client->get($url);
$result = json_decode($response->getBody()->getContents(), true);
if ($result['code'] != 0) {
return [];
}
(new RedisModel())->setex($cacheKey, 60, json_encode($result['data']['list']));
return $result['data']['list'];
}
//获取简单形式给各个地方使用
......@@ -43,4 +38,85 @@ class CrmService
}
return $map;
}
/**
* 回传CRM供应商审核结果(队列推送)
* @param int $supplierId 供应商ID
* @param string $supplierName 供应商名称
* @param string $approverName 审批人姓名
* @param int $auditStatus 审核状态:1通过 -1拒绝驳回
* @param string $remark 审核备注
* @return bool
*/
public static function confirmCrmSupplier($supplierId, $supplierName, $approverName, $auditStatus, $remark = '')
{
try {
$data = [
'supplier_id' => (string)$supplierId,
'audit_status' => (string)$auditStatus,
'remark' => $remark,
'customer_name' => $supplierName,
'approver' => $approverName,
'approver_id' => request()->user->userId,
];
(new QueueDeliveryService())->setQueueName('lie_queue_crm')->push(
QueueDeliveryService::PUSH_TYPE_SYNC_HTTP,
'/sync/supplier/updateSupplierAuditResultToCrm',
$data,
(string)$supplierId
);
\Illuminate\Support\Facades\Log::info('[CRM回传]回传审核结果已推送到队列', ['supplier_id' => $supplierId, 'audit_status' => $auditStatus]);
return true;
} catch (\Exception $e) {
\Illuminate\Support\Facades\Log::error('[CRM回传]回传审核结果推送队列异常: ' . $e->getMessage(), ['supplier_id' => $supplierId]);
return false;
}
}
/**
* 同步供应商状态变更到CRM系统(队列推送)
* @param string $supplierName 供应商名称
* @param string $supplierStatus CRM供应商状态:rejected/passed/blacklist/disable_trade
* @param string $remark 备注
* @param string $supplierName 供应商名称(作为searchKey)
* @return bool
*/
public static function syncSupplierStatus($supplierName, $supplierStatus, $remark = '')
{
try {
$data = [
'customer_name' => $supplierName,
'supplier_status' => $supplierStatus,
'remark' => $remark,
];
(new QueueDeliveryService())->setQueueName('lie_queue_crm')->push(
QueueDeliveryService::PUSH_TYPE_SYNC_HTTP,
'/sync/supplier/updateSupplierAuditResultToCrm',
$data,
(string)$supplierName
);
\Illuminate\Support\Facades\Log::info('[CRM回传]同步供应商状态已推送到队列', ['supplier_name' => $supplierName, 'status' => $supplierStatus]);
return true;
} catch (\Exception $e) {
\Illuminate\Support\Facades\Log::error('[CRM回传]同步供应商状态推送队列异常: ' . $e->getMessage(), ['supplier_name' => $supplierName]);
return false;
}
}
/**
* 供应商状态映射到CRM状态
* @param int $supplierStatus 供应商系统状态常量
* @return string|null CRM状态值,不需要同步的返回null
*/
public static function mapSupplierStatusToCrm($supplierStatus)
{
$map = [
SupplierChannelModel::STATUS_REJECT => 'rejected', // 未通过
SupplierChannelModel::STATUS_PASSED => 'passed', // 已通过
SupplierChannelModel::STATUS_BLOCK => 'blacklist', // 黑名单
SupplierChannelModel::STATUS_DISABLE => 'disable_trade', // 禁止交易
SupplierChannelModel::STATUS_CRM_REJECTED => 'crm_rejected', // CRM转移供应商不通过
];
return isset($map[$supplierStatus]) ? $map[$supplierStatus] : null;
}
}
......@@ -6,6 +6,7 @@ namespace App\Http\Services;
use Carbon\Carbon;
use GuzzleHttp\Client;
use App\Model\LogModel;
use App\Model\SupplierLogModel;
use App\Model\RedisModel;
use App\Model\NationModel;
use App\Model\SkuUploadItem;
......@@ -15,19 +16,29 @@ use App\Model\IntracodeModel;
use App\Model\DepartmentModel;
use GuzzleHttp\RequestOptions;
use App\Model\SkuUploadLogModel;
use App\Model\SupplierSyncModel;
use App\Model\SupplierApplyModel;
use App\Model\SupplierMemoModel;
use App\Model\AttachmentAuditModel;
use App\Model\StandardBrandModel;
use App\Model\SupplierExtendModel;
use App\Model\SupplierPayTypeModel;
use App\Model\SupplierAddressModel;
use Illuminate\Support\Facades\DB;
use App\Model\SupplierAccountModel;
use App\Model\SupplierAddressModel;
use App\Model\SupplierChannelModel;
use App\Model\SupplierBlacklistModel;
use App\Model\SupplierContactModel;
use App\Model\SupplierShareApplyModel;
use App\Model\SupplierReceiptModel;
use App\Model\PurchaseRemarkModel;
use Illuminate\Support\Facades\Log;
use App\Model\SupplierContractModel;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Redis;
use App\Model\BigData\DataManageModel;
use App\Model\SupplierAttachmentsModel;
use App\Model\SupplierAttachmentModel;
use App\Model\StandardBrandMappingModel;
use App\Model\Purchase\PurchaseOrderModel;
use App\Http\Transformers\SupplierTransformer;
......@@ -2299,4 +2310,63 @@ class DataService
dump("已删除 {$count} 个京东采购员类型的联系人");
}
}
public function clearSupplierData($supplierId)
{
$supplierId = (int)$supplierId;
if ($supplierId <= 0) {
throw new \InvalidArgumentException('supplier_id不能为空');
}
$supplier = SupplierChannelModel::where('supplier_id', $supplierId)->first();
if (empty($supplier)) {
return [
'supplier_id' => $supplierId,
'deleted' => [],
'message' => '供应商不存在',
];
}
$supplierCode = $supplier->supplier_code;
$deleted = [];
DB::connection('web')->transaction(function () use ($supplierId, &$deleted) {
$deleteMap = [
'supplier_apply' => SupplierApplyModel::where('supplier_id', $supplierId),
'supplier_attachment_audit' => AttachmentAuditModel::where('supplier_id', $supplierId),
'supplier_attachments' => SupplierAttachmentsModel::where('supplier_id', $supplierId),
'supplier_contact' => SupplierContactModel::where('supplier_id', $supplierId),
'supplier_contract' => SupplierContractModel::where('supplier_id', $supplierId),
'supplier_extend' => SupplierExtendModel::where('supplier_id', $supplierId),
'supplier_memo' => SupplierMemoModel::where('supplier_id', $supplierId),
// 'supplier_pay_type' => SupplierPayTypeModel::where('supplier_id', $supplierId),
'supplier_receipt' => SupplierReceiptModel::where('supplier_id', $supplierId),
'supplier_share_apply' => SupplierShareApplyModel::where('supplier_id', $supplierId),
'supplier_sync' => SupplierSyncModel::where('supplier_id', $supplierId),
'supplier_address' => SupplierAddressModel::where('supplier_id', $supplierId),
'supplier_log' => SupplierLogModel::where('supplier_id', $supplierId),
'log' => LogModel::where('supplier_id', $supplierId),
'purchase_remark' => PurchaseRemarkModel::where('supplier_id', $supplierId),
];
foreach ($deleteMap as $table => $query) {
$deleted[$table] = $query->delete();
}
$deleted['supplier_channel'] = SupplierChannelModel::where('supplier_id', $supplierId)->delete();
});
$deleted['yunxin_account'] = SupplierAccountModel::where('supplier_id', $supplierId)->delete();
$redis = new RedisModel();
$redis->hdel('lie_supplier_info', $supplierId);
$redis->hdel('supplier_sku_upload_ruler_v2', $supplierId);
$redis->del('supplier_list_statistics_' . request()->user->userId);
return [
'supplier_id' => $supplierId,
'supplier_code' => $supplierCode,
'deleted' => $deleted,
];
}
}
......@@ -7,14 +7,15 @@ use App\Http\Controllers\Filter\LogFilter;
use App\Http\Transformers\LogTransformer;
use App\Http\Transformers\SupplierTransformer;
use App\Model\LogModel;
use App\Model\NationModel;
class LogService
{
//添加日志
public function AddLog($supplierId, $type, $action, $content, $remark = '')
{
$adminId = request()->user->userId;
$adminName = request()->user->name;
$adminId = isset(request()->user->userId) ? request()->user->userId : 1000;
$adminName = isset(request()->user->name) ? request()->user->name : 'admin';
$data = [
'supplier_id' => $supplierId,
'type' => $type,
......@@ -153,12 +154,18 @@ class LogService
return $value;
}, $oldSupplier);
$diff = array_diff($newSupplier, $oldSupplier);
// 国家/地区映射(循环外获取,避免重复查库)
$nationMap = NationModel::getNationList();
$result = [];
foreach ($diff as $key => $item) {
$columnMap = config('validate.SupplierNeedLogColumn');
if (in_array($key, array_keys($columnMap))) {
$oldValue = array_get($oldSupplier, $key, '空');
$newValue = array_get($newSupplier, $key, '空');
if ($key === 'nation_id') {
$oldValue = array_get($nationMap, $oldValue, '');
$newValue = array_get($nationMap, $newValue, $newValue);
}
$content = array_get($columnMap, $key) . '由 [ ' . $oldValue . ' ] 改成 [ ' . $newValue . ' ];';
$result[] = $content;
} else {
......
......@@ -44,9 +44,7 @@ class SkuService extends BaseService
die();
}
try {
// $return = curl($url, $map, 1);
$url = base64_encode($url . '?' . http_build_query($map));
$return = curl(config('website.FootstoneCurlUrl') . $url);
$return = curl($url, $map, 1);
} catch (\Exception $e) {
return $e->getMessage();
}
......
......@@ -9,6 +9,7 @@ use App\Http\Transformers\SupplierTransformer;
use App\Model\LogModel;
use App\Model\SkuUploadLogModel;
use App\Model\SupplierChannelModel;
use Illuminate\Support\Facades\DB;
class SkuUploadLogService
{
......@@ -26,7 +27,6 @@ class SkuUploadLogService
return $list;
}
//获取上传次数
public function getSkuUploadLogCount($supplierId)
{
$supplierCode = SupplierChannelModel::where('supplier_id', $supplierId)->value('supplier_code');
......
......@@ -168,6 +168,9 @@ class SupplierService
}
return $value;
}, $channel);
//默认是供应商系统新增
$channel['supplier_source'] = SupplierChannelModel::SUPPLIER_SOURCE_SYSTEM;
//默认是待提审
//判断是否是直接添加并且申请审核
if ($isDirectApply) {
......@@ -279,6 +282,9 @@ class SupplierService
$channel['system_tags'] = trim(implode(',', $channel['system_tags']), ',');
// 防御:禁止编辑时覆盖 supplier_source,防止被意外改为0
unset($channel['supplier_source']);
$model->where('supplier_id', $supplierId)->update($channel);
$supplierAddressService = new SupplierAddressService();
......@@ -1420,4 +1426,4 @@ class SupplierService
return $result;
}
}
}
\ No newline at end of file
......@@ -463,6 +463,16 @@ class SyncSupplierService
}
}
}
if (!empty($supplier['purchase_uid'])) {
$purchaseUids = explode(',', $supplier['purchase_uid']);
$purchaseUserList = (new AdminUserService())->getAdminUserListByCodeIds($purchaseUids);
foreach ($purchaseUserList as $purchaseUser) {
if (!empty($purchaseUser['email'])) {
(new MessageService())->sendMessage('supplier_entity_notice_purchase', $data, $purchaseUser['email'], true);
}
}
}
}
}
}
......@@ -38,7 +38,10 @@ class SupplierTransformer
//创建人部门map
$createUserDepartmentNameMap = (new DepartmentService())->getDepartmentNameMapByUserIds(array_column($list, 'create_uid'));
//获取所有供应商id
//批量获取逆向采购员
$reversePurchaserMap = SupplierExtendModel::getReversePurchaserBySupplierIds(array_column($list, 'supplier_id'));
//获取所有供应商ids
$supplierIds = array_column($list, 'supplier_id');
//然后获取所有采购员类型为2(京东)和4(跟货采购员)的联系人
$jdContacts = $inventoryContacts = [];
......@@ -88,6 +91,8 @@ class SupplierTransformer
$supplier['purchase_username'] = array_get($users, $supplier['purchase_uid']);
$supplier['yunxin_channel_username'] = array_get($users, $supplier['yunxin_channel_uid']);
$supplier['status_name'] = array_get(config('fixed.SupplierStatus'), $supplier['status']);
$supplier['supplier_source_name'] = array_get(config('fixed.SupplierSource'), $supplier['supplier_source']);
$supplier['reverse_purchaser'] = array_get($reversePurchaserMap, $supplier['supplier_id'], '');
$supplier['supplier_type_name'] = array_get(config('field.SupplierType'), $supplier['supplier_type']);
$supplier['company_nature_name'] = array_get(config('field.CompanyNature'), $supplier['company_nature']);
$supplier['is_entity_name'] = array_get(config('field.IsEntity'), $supplier['is_entity'], '暂无');
......@@ -276,6 +281,13 @@ class SupplierTransformer
$supplier = $this->getStockupType($supplier);
$supplier['sign_com_name'] = array_get(CrmService::getSignCompanyListMap(), $supplier['sign_com_id']);
$supplier['status_name'] = array_get(config('fixed.SupplierStatus'), $supplier['status']);
$supplier['supplier_source_name'] = array_get(config('fixed.SupplierSource'), $supplier['supplier_source']);
if (!empty($supplier['supplier_id'])) {
$extendInfo = SupplierExtendModel::where('supplier_id', $supplier['supplier_id'])->first();
$supplier['reverse_purchaser'] = $extendInfo ? $extendInfo->reverse_purchaser : '';
} else {
$supplier['reverse_purchaser'] = '';
}
$supplier['region_name'] = array_get(config('fixed.Region'), $supplier['region']);
$supplier['currency_name'] = array_get(config('fixed.Currency'), $supplier['currency']);
$supplier['supplier_group_name'] = array_get(config('fixed.SupplierGroup'), $supplier['supplier_group']);
......
......@@ -205,7 +205,7 @@ function Autograph()
function checkPerm($perm)
{
$perms = request()->perms;
if ($perms === null) {
if ($perms === null || request()->user->userId == 1000) {
return true;
}
return in_array($perm, $perms);
......
......@@ -57,6 +57,7 @@ Route::group(['middleware' => ['web'], 'namespace' => 'Api'], function () {
Route::match(['get', 'post'], '/api/supplier_statistics/{key}', 'SupplierStatisticsApiController@Entrance');
Route::match(['get', 'post'], '/api/sku_statistics/{key}', 'SkuStatisticsApiController@Entrance');
Route::match(['get', 'post'], '/api/supplier/{key}', 'SupplierApiController@Entrance');
Route::match(['get', 'post'], '/api/supplier_crm/{key}', 'SupplierCrmApiController@Entrance');
Route::match(['get', 'post'], '/api/log/{key}', 'LogApiController@Entrance');
Route::match(['get', 'post'], '/api/sku/{key}', 'SkuApiController@Entrance');
Route::match(['get', 'post'], '/api/supplier_receipt/{key}', 'SupplierReceiptApiController@Entrance');
......@@ -84,6 +85,8 @@ Route::group(['middleware' => ['external'], 'namespace' => 'Api'], function () {
Route::match(['get', 'post'], '/api/external/checkSupplierApply', 'ExternalApiController@checkSupplierApply');
Route::match(['get', 'post'], '/api/external/applySupplier', 'ExternalApiController@applySupplier');
Route::match(['get', 'post'], '/api/external/checkSupplierAccountExist', 'ExternalApiController@checkSupplierAccountExist');
Route::match(['get', 'post'], '/api/external/SaveColSettings', 'CommonApiController@SaveColSettings');
Route::match(['get', 'post'], '/api/external/GetColSettings', 'CommonApiController@GetColSettings');
});
//同步相关的接口
......@@ -94,8 +97,18 @@ Route::group(['middleware' => ['external'], 'namespace' => 'Sync'], function ()
Route::any('/sync/unitedData/receiveEntityResult', 'SupplierSyncController@receiveEntityResult');
//获取需要审核的供应商数量,韦伯小程序用的
Route::get('/sync/audit/GetNeedAuditSupplierCount', 'SupplierSyncController@GetNeedAuditSupplierCount');
//CRM推送供应商同步接口
Route::post('/sync/crm/syncSupplier', 'SupplierSyncController@syncCrmSupplier');
//CRM客户公司转让同步接口
Route::post('/sync/crm/syncCustomerTransfer', 'SupplierSyncController@syncCrmCustomerTransfer');
});
Route::match(['get', 'post'], '/test', function () {
DataService::exportUploadedSkuSupplier();
$isAdmin = request()->user->userId == 1000 ? true : false;
if (!$isAdmin) {
return response()->json(['code' => 403, 'msg' => '无权限']);
}
$supplierId = (int)request()->get('supplier_id');
$result = (new DataService())->clearSupplierData($supplierId);
return response()->json($result);
});
......@@ -24,6 +24,14 @@ class SupplierChannelModel extends Model
const STATUS_DISABLE = -2;
//黑名单
const STATUS_BLOCK = -3;
//待确认(CRM同步后初始状态)
const STATUS_CONFIRM = 4;
//CRM转移供应商不通过
const STATUS_CRM_REJECTED = -4;
//供应商来源
const SUPPLIER_SOURCE_SYSTEM = 1; //供应商系统新增
const SUPPLIER_SOURCE_CRM = 2; //CRM客户转化供应商
const SUPPLIER_TYPE_OFFICIAL = 1;
const SUPPLIER_TYPE_TEMPORARY = 2;
......
......@@ -118,6 +118,13 @@ return [
2 => '已通过',
-2 => '禁止交易',
-3 => '黑名单',
4 => '待确认',
-4 => 'CRM转移供应商不通过',
],
'SupplierSource' => [
1 => '供应商系统新增',
2 => 'CRM客户转化供应商',
],
'Currency' => [
......
......@@ -17,6 +17,8 @@ return [
'BatchUpdateSkuStatus',
'GetAuditFlow',
'ViewAccountLog',
'SaveColSettings',
'GetColSettings',
'TempTemp'
]//不用验证权限的方法
],
......
# 同步CRM客户到供应商
# 同步CRM客户到供应商
curl -X POST http://supplier.liexin.net/sync/crm/syncSupplier
-H "Content-Type: application/x-www-form-urlencoded"
-d "customer_name=测试科技有限公司"
-d "sign_com_id=1"
-d "contact_name=张三"
-d "contact_email=zhangsan@test.com"
-d "contact_mobile=13800138000"
-d "creator_name=李四"
-d "customer_nature=工厂"
-d "crm_remark=CRM客户转化供应商测试"
-d "platform_agreement_url=https://example.com/agreements/platform_2024.pdf"
-d "platform_agreement_name=平台合作协议_2024"
-d "quality_agreement_url=https://example.com/agreements/quality_2024.pdf"
-d "quality_agreement_name=品质保证协议_2024"
<script>
layui.use(['table', 'form', 'element', 'layer', 'admin'], function () {
let admin = layui.admin;
let form = layui.form;
let layer = layui.layer;
form.on('submit(confirmCrmSupplier)', function (data) {
let supplierId = getQueryVariable('supplier_id');
let auditOpinion = data.field.audit_opinion;
let remark = data.field.remark || '';
let channelUid = data.field.channel_uid || '';
// 同意时必须指定采购员
if (auditOpinion === 'agree' && !channelUid) {
parent.layer.msg('请指定采购员', {icon: 5});
return false;
}
let url = '/api/supplier_crm/AuditCustomerConvertSupplier';
let requestData = {
supplier_id: supplierId,
audit_opinion: auditOpinion,
remark: remark,
};
// 只有当channel_uid存在时才传递
if (channelUid) {
requestData.channel_uid = channelUid;
}
// loading 效果:禁用按钮,防止重复提交
let $btn = $(data.elem);
let btnText = $btn.text();
$btn.addClass('layui-btn-disabled').attr('disabled', true).text('提交中...');
$.ajax({
url: url,
type: 'post',
data: requestData,
async: true,
dataType: 'json',
timeout: 30000,
success: function (res) {
if (res && res.err_code === 0) {
admin.closeThisDialog();
parent.layer.msg(res.err_msg, {icon: 6});
} else {
parent.layer.msg(res ? res.err_msg : '操作失败', {icon: 5});
}
},
error: function () {
parent.layer.msg('网络错误,请重试', {icon: 5});
},
complete: function () {
// 恢复按钮状态
$btn.removeClass('layui-btn-disabled').attr('disabled', false).text(btnText);
}
});
return false;
});
form.on('submit(cancel)', function (data) {
admin.closeThisDialog();
});
});
</script>
\ No newline at end of file
......@@ -311,6 +311,8 @@
return statusHtml;
}
},
{field: 'supplier_source_name', title: '供应商来源', align: 'center', width: 120},
{field: 'reverse_purchaser', title: '逆向采购员', align: 'center', width: 100},
{field: 'last_update_name', title: '最新修改人', align: 'center', width: 110},
{field: 'sign_com_name', title: '签约公司', align: 'center', width: 150},
{
......@@ -372,6 +374,24 @@
];
cols.push(
);
// 列显示设置 - 从后端Redis hash渲染
let colSettingsData = {!! $colSettings !!};
let colSettingsUserId = '{{request()->user->userId}}';
let colSettingsPageKey = 'supplier_list';
function applyColSettings() {
if (colSettingsData && Object.keys(colSettingsData).length > 0) {
for (let i = 0; i < cols.length; i++) {
let field = cols[i].field;
if (field && colSettingsData[field] !== undefined) {
cols[i].hide = !colSettingsData[field];
}
}
}
}
applyColSettings();
table.render({
elem: '#list'
, url: '/api/supplier/GetSupplierList'
......@@ -460,6 +480,88 @@
admin.putTempData("needFreshDetail_supplier_id=" + supplierId, 1);
}
//列设置
$("#col_setting").click(function () {
let html = '<div style="padding: 15px;">';
html += '<div style="margin-bottom: 10px;">';
html += '<button type="button" class="layui-btn layui-btn-xs layui-btn-info" id="col_select_all">全选</button>';
html += '<button type="button" class="layui-btn layui-btn-xs layui-btn-danger" id="col_invert_select">反选</button>';
html += '</div>';
html += '<div style="max-height: 600px; overflow-y: auto;">';
html += '<form class="layui-form" lay-filter="colSettingForm">';
for (let i = 0; i < cols.length; i++) {
if (cols[i].type === 'checkbox') continue;
let field = cols[i].field;
let title = cols[i].title || '';
let checked = cols[i].hide ? '' : 'checked';
html += '<div class="layui-form-item" style="display:inline-block;width:33%;margin-bottom:5px;">';
html += '<input type="checkbox" name="' + field + '" lay-skin="primary" title="' + title + '" ' + checked + '>';
html += '</div>';
}
html += '</form></div></div>';
layer.open({
type: 1,
title: '显示列设置',
area: ['600px', '600px'],
content: html,
btn: ['确定', '取消'],
success: function (layero, index) {
form.render('checkbox', 'colSettingForm');
//全选
layero.find('#col_select_all').on('click', function () {
layero.find('input[type="checkbox"]').prop('checked', true);
form.render('checkbox', 'colSettingForm');
});
//反选
layero.find('#col_invert_select').on('click', function () {
layero.find('input[type="checkbox"]').each(function () {
$(this).prop('checked', !$(this).is(':checked'));
});
form.render('checkbox', 'colSettingForm');
});
},
yes: function (index, layero) {
let settings = {};
let checkboxes = layero.find('input[type="checkbox"]');
checkboxes.each(function () {
let name = $(this).attr('name');
let checked = $(this).is(':checked');
settings[name] = checked;
});
//保存到后端Redis
$.ajax({
url: '/api/external/SaveColSettings',
type: 'post',
data: {
user_id: colSettingsUserId,
page_key: colSettingsPageKey,
settings: JSON.stringify(settings)
},
dataType: 'json',
async: false
});
colSettingsData = settings;
for (let i = 0; i < cols.length; i++) {
let field = cols[i].field;
if (field && settings[field] !== undefined) {
cols[i].hide = !settings[field];
}
}
table.reload('list', {
cols: [cols],
page: {curr: currentPage},
where: whereCondition
});
layer.close(index);
}
});
});
//新增供应商弹窗
$("#add_supplier").click(function () {
index.openTab({
......@@ -531,6 +633,10 @@
let supplierId = data[0].supplier_id;
let status = data[0].status;
let canReviewSupplier = {{checkPerm("ReviewSupplier")?1:0}};
if (status === 4){
layer.msg('该供应商状态为待确认,需要先确认客户转化供应商', {icon: 5});
return;
}
if (canReviewSupplier === 0 && status === -1) {
layer.msg('你没有复审供应商的权限', {icon: 5})
return
......@@ -868,6 +974,37 @@
}
})
//确认客户转化供应商
$("#confirm_crm_supplier").click(function () {
let checkStatus = table.checkStatus('list');
let data = checkStatus.data;
if (!data.length) {
layer.msg('请先选择要操作的供应商', {icon: 5})
} else {
if (data.length > 1) {
layer.msg('该操作不支持多选', {icon: 5})
return;
}
const status = data[0].status;
const source = data[0].supplier_source;
// 前置条件:供应商状态为待确认(4),供应商来源为CRM客户转化供应商(2)
if (status !== 4 || source !== 2) {
layer.msg('只有状态为"待确认"且来源为"CRM客户转化供应商"的供应商才可以操作', {icon: 5});
return;
}
let supplierId = data[0].supplier_id;
layer.open({
type: 2,
content: '/supplier/ConfirmCrmSupplier?view=iframe&supplier_id=' + supplierId,
area: ['70%', '720px'],
title: '转化供应商确认',
end: function () {
table.reload('list');
}
});
}
})
//判断是否要展示有全部离职采购员的供应商,有的话提示
if (!admin.getTempData('has_pop_up_all_channel_user_supplier_tips')) {
$.ajax({
......@@ -981,7 +1118,8 @@
let $this = $(this);
let supplierId = $this.data('supplier-id');
let status = $this.data('status');
if (status !== 1) {
// 审核中(1)和待确认(4)状态显示审批节点
if (status !== 1 && status !== 4) {
return;
}
......
<style>
.layui-form-item {
margin-bottom: 8px;
}
.require {
color: red;
}
.info-label {
padding-top: 7px;
line-height: 28px;
word-break: break-all;
}
</style>
<div class="layui-card" style="margin: 0">
<div class="layui-card-body" style="padding: 20px 20px 10px;">
<form class="layui-form" action="">
<input type="hidden" name="supplier_id" value="{{$supplier['supplier_id']}}">
<blockquote class="layui-elem-quote layui-text">
<b>基本信息</b>
</blockquote>
<div class="layui-form-item">
<label class="layui-form-label">供应商名称 : </label>
<div class="layui-input-block block-42 info-label">
{{$supplier['supplier_name']}}
<a style="color: dodgerblue;margin-left: 20px" ew-href="/supplier/SupplierDetail?view=iframe&supplier_id={{$supplier['supplier_id']}}" ew-title='供应商详情 - {{$supplier['supplier_code']}}'>{{$supplier['supplier_code']}}</a>
</div>
</div>
<div class="layui-form-item">
<div class="layui-col-sm4">
<label class="layui-form-label">客户性质 : </label>
<div class="layui-input-block block-42 info-label">
{{$customer_nature ?: '无'}}
</div>
</div>
<div class="layui-col-sm4">
<label class="layui-form-label">逆向采购员 : </label>
<div class="layui-input-block block-42 info-label">
{{$reverse_purchaser ?: '无'}}
</div>
</div>
<div class="layui-col-sm4">
<label class="layui-form-label" style="width:150px;margin-left:-50px">销售转化供应商备注 : </label>
<div class="layui-input-block block-42 info-label">
{{$crm_remark ?: '无'}}
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-col-sm6">
<label class="layui-form-label">审核内容 : </label>
<div class="layui-input-block block-42 info-label">
CRM提交转化供应商申请
</div>
</div>
<div class="layui-col-sm6">
@inject('statusPresenter','App\Presenters\StatusPresenter')
@if($has_channel_uid)
<label class="layui-form-label">指定采购员 : </label>
<div class="layui-input-block block-42 info-label">
{{ array_get($userCodes, $supplier['channel_uid'], '未知') }}
</div>
<input type="hidden" name="channel_uid" value="{{ $supplier['channel_uid'] }}">
@else
{!! $statusPresenter->render('channel_uid','指定采购员 : ',null,
$userCodes,['required'=>true,'width'=>'150px']) !!}
@endif
</div>
</div>
<blockquote class="layui-elem-quote layui-text">
<b>审核</b>
</blockquote>
@if($audit_rejected)
<div class="layui-form-item">
<div class="layui-input-block">
<span style="color: red; font-weight: bold;">审核流已被拒绝,无法继续审核,请等待CRM重新提交</span>
</div>
</div>
@else
<div class="layui-form-item">
<label class="layui-form-label"><span class="require">*</span> 审核意见 : </label>
<div class="layui-input-block">
<input type="radio" name="audit_opinion" value="agree" title="同意" checked>
<input type="radio" name="audit_opinion" value="disagree" title="不同意">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">原因说明 : </label>
<div class="layui-input-block">
<textarea name="remark" placeholder="请输入原因说明(选填)" class="layui-textarea" style="min-height: 80px;"></textarea>
</div>
</div>
@endif
<div class="layui-form-item">
<div align="center" style="margin-top: 20px;text-align: right">
@if(!$audit_rejected)
<button type="button" class="layui-btn layui-btn-info submit-loading" lay-submit lay-filter="confirmCrmSupplier">确定
</button>
@endif
<button type="button" class="layui-btn layui-btn-primary" lay-submit lay-filter="cancel">取消
</button>
</div>
</div>
</form>
</div>
</div>
\ No newline at end of file
......@@ -54,9 +54,7 @@
lay-submit
lay-filter="saveSupplierMemo">确认
</button>
<button type="button" id="cancel" class="layui-btn layui-btn-primary"
lay-submit
lay-filter="cancelSupplierMemo">取消
<button type="button" id="cancel" class="layui-btn layui-btn-primary" lay-submit lay-filter="cancelSupplierMemo">取消
</button>
</div>
</div>
......
......@@ -79,6 +79,10 @@
@if(checkPerm('TransferSupplier'))
<button type="button" class="layui-btn layui-btn-sm" id="transfer_supplier">供应商交接</button>
@endif
@if(checkPerm('ConfirmCrmSupplier'))
<button type="button" class="layui-btn layui-btn-sm" id="confirm_crm_supplier">确认客户转化供应商</button>
@endif
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="col_setting">展示列设置</button>
</div>
<button type="button" id="refreshWindow" style="display: none">刷新页面</button>
<table class="layui-table" id="list" lay-filter="list"></table>
......
......@@ -49,6 +49,13 @@
<div class="city-selector" id="city-selector"></div>
</div>
</div>
<div class="layui-col-md3">
<label class="layui-form-label">供应商来源 : </label>
<div class="layui-input-block">
<input type="text" class="layui-input" disabled
value="{{array_get(config('fixed.SupplierSource'), !empty($supplier['supplier_source']) ? $supplier['supplier_source'] : '1', '供应商系统新增')}}">
</div>
</div>
</div>
<div class="layui-form-item">
......@@ -109,7 +116,14 @@
<div class="layui-row">
<div class="layui-col-md3">
@inject('statusPresenter','App\Presenters\StatusPresenter')
{!! $statusPresenter->render('purchase_uid','数据维护员 : ',$supplier['purchase_uid'],$userCodes,['width'=>'150px']) !!}
{!! $statusPresenter->render('purchase_uid','数据维护员 : ',$supplier['purchase_uid'],$userCodes,['width'=>'150px']) !!}
</div>
<div class="layui-col-md3">
<label class="layui-form-label">逆向采购员 : </label>
<div class="layui-input-block" style="width: 150px">
<input type="text" class="layui-input layui-disabled" disabled
value="{{$supplier['reverse_purchaser'] or ''}}">
</div>
</div>
<div class="layui-col-md3">
<label class="layui-form-label"><span class="require">*</span>注册资金(万): </label>
......
......@@ -10,8 +10,8 @@
<div class="split-group" style="height: 170px;">
<div class="split-item" id="s1" style="text-align: center">
<div class="layui-row">
<a class="main_filter layui-badge layui-bg-green" title='全部' id="total">全部</a>
{{-- <div class="layui-row">
<a class="main_filter layui-badge layui-bg-green" id="total">全部</a>
<div class="layui-row">
<a class="main_filter" title="待复审" id="need_review">
待复审
</a>
......@@ -21,10 +21,12 @@
<div class="split-item" id="s6" style="text-align: center">
<div class="layui-row">
<a class="main_filter" title="战略供应商" id="level_a">
战略供应商
</a>
</div>
<div class="layui-row">
<a class="main_filter" title="账期供应商" id="pay_type_term">
账期供应商
</a>
</div>
<div class="layui-row">
......@@ -38,10 +40,11 @@
</a>
</div>
@if(checkPerm('SupplierBlockList'))
<div class="layui-row">
<a class="main_filter" id="block" data-value="-3">
</a>
</div>
<div class="layui-row">
<a class="main_filter" id="block" data-value="-3">
黑名单
</a>
</div>
@endif
</div>
<div class="split-item" id="s7" style="text-align: center">
......@@ -243,9 +246,13 @@
</div>
</div>
<div class="layui-inline">
@inject('statusPresenter', 'App\Presenters\StatusPresenter')
@inject('statusPresenter','App\Presenters\StatusPresenter')
{!! $statusPresenter->render('sign_com_id', '签约公司', 0, \App\Http\Services\CrmService::getSignCompanyListMap()) !!}
</div>
<div class="layui-inline">
@inject('statusPresenter','App\Presenters\StatusPresenter')
{!! $statusPresenter->render('supplier_source', '供应商来源', 0, config('fixed.SupplierSource')) !!}
</div>
<div class="layui-inline">
@inject('multiSelectorPresenter','App\Presenters\MultiSelectorPresenter')
{!! $multiSelectorPresenter->render('region','区域','',$regionData) !!}
......@@ -260,6 +267,11 @@
<div class="layui-inline" style="margin-left: 10px">
@inject('multiTransformableSelectPresenter','App\Presenters\Filter\MultiTransformableSelectPresenter')
{!! $multiTransformableSelectPresenter->render(['data_channel_uid' => '数据跟单员'],['data_channel_uid' => $userCodes]) !!}
</div>
<div class="layui-inline">
@inject('statusPresenter','App\Presenters\StatusPresenter')
{!! $statusPresenter->render('supplier_source', '供应商来源', 0, config('fixed.SupplierSource')) !!}
</div>
<div class="layui-inline">
<label class="layui-form-label">代理品牌</label>
......
......@@ -79,6 +79,10 @@
<?php if(checkPerm('TransferSupplier')): ?>
<button type="button" class="layui-btn layui-btn-sm" id="transfer_supplier">供应商交接</button>
<?php endif; ?>
<?php if(checkPerm('ConfirmCrmSupplier')): ?>
<button type="button" class="layui-btn layui-btn-sm" id="confirm_crm_supplier">确认客户转化供应商</button>
<?php endif; ?>
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="col_setting">展示列设置</button>
</div>
<button type="button" id="refreshWindow" style="display: none">刷新页面</button>
<table class="layui-table" id="list" lay-filter="list"></table>
......
......@@ -311,6 +311,8 @@
return statusHtml;
}
},
{field: 'supplier_source_name', title: '供应商来源', align: 'center', width: 120},
{field: 'reverse_purchaser', title: '逆向采购员', align: 'center', width: 100},
{field: 'last_update_name', title: '最新修改人', align: 'center', width: 110},
{field: 'sign_com_name', title: '签约公司', align: 'center', width: 150},
{
......@@ -372,6 +374,24 @@
];
cols.push(
);
// 列显示设置 - 从后端Redis hash渲染
let colSettingsData = <?php echo $colSettings; ?>;
let colSettingsUserId = '<?php echo e(request()->user->userId); ?>';
let colSettingsPageKey = 'supplier_list';
function applyColSettings() {
if (colSettingsData && Object.keys(colSettingsData).length > 0) {
for (let i = 0; i < cols.length; i++) {
let field = cols[i].field;
if (field && colSettingsData[field] !== undefined) {
cols[i].hide = !colSettingsData[field];
}
}
}
}
applyColSettings();
table.render({
elem: '#list'
, url: '/api/supplier/GetSupplierList'
......@@ -460,6 +480,88 @@
admin.putTempData("needFreshDetail_supplier_id=" + supplierId, 1);
}
//列设置
$("#col_setting").click(function () {
let html = '<div style="padding: 15px;">';
html += '<div style="margin-bottom: 10px;">';
html += '<button type="button" class="layui-btn layui-btn-xs layui-btn-info" id="col_select_all">全选</button>';
html += '<button type="button" class="layui-btn layui-btn-xs layui-btn-danger" id="col_invert_select">反选</button>';
html += '</div>';
html += '<div style="max-height: 600px; overflow-y: auto;">';
html += '<form class="layui-form" lay-filter="colSettingForm">';
for (let i = 0; i < cols.length; i++) {
if (cols[i].type === 'checkbox') continue;
let field = cols[i].field;
let title = cols[i].title || '';
let checked = cols[i].hide ? '' : 'checked';
html += '<div class="layui-form-item" style="display:inline-block;width:33%;margin-bottom:5px;">';
html += '<input type="checkbox" name="' + field + '" lay-skin="primary" title="' + title + '" ' + checked + '>';
html += '</div>';
}
html += '</form></div></div>';
layer.open({
type: 1,
title: '显示列设置',
area: ['600px', '600px'],
content: html,
btn: ['确定', '取消'],
success: function (layero, index) {
form.render('checkbox', 'colSettingForm');
//全选
layero.find('#col_select_all').on('click', function () {
layero.find('input[type="checkbox"]').prop('checked', true);
form.render('checkbox', 'colSettingForm');
});
//反选
layero.find('#col_invert_select').on('click', function () {
layero.find('input[type="checkbox"]').each(function () {
$(this).prop('checked', !$(this).is(':checked'));
});
form.render('checkbox', 'colSettingForm');
});
},
yes: function (index, layero) {
let settings = {};
let checkboxes = layero.find('input[type="checkbox"]');
checkboxes.each(function () {
let name = $(this).attr('name');
let checked = $(this).is(':checked');
settings[name] = checked;
});
//保存到后端Redis
$.ajax({
url: '/api/external/SaveColSettings',
type: 'post',
data: {
user_id: colSettingsUserId,
page_key: colSettingsPageKey,
settings: JSON.stringify(settings)
},
dataType: 'json',
async: false
});
colSettingsData = settings;
for (let i = 0; i < cols.length; i++) {
let field = cols[i].field;
if (field && settings[field] !== undefined) {
cols[i].hide = !settings[field];
}
}
table.reload('list', {
cols: [cols],
page: {curr: currentPage},
where: whereCondition
});
layer.close(index);
}
});
});
//新增供应商弹窗
$("#add_supplier").click(function () {
index.openTab({
......@@ -531,6 +633,10 @@
let supplierId = data[0].supplier_id;
let status = data[0].status;
let canReviewSupplier = <?php echo e(checkPerm("ReviewSupplier")?1:0); ?>;
if (status === 4){
layer.msg('该供应商状态为待确认,需要先确认客户转化供应商', {icon: 5});
return;
}
if (canReviewSupplier === 0 && status === -1) {
layer.msg('你没有复审供应商的权限', {icon: 5})
return
......@@ -868,6 +974,37 @@
}
})
//确认客户转化供应商
$("#confirm_crm_supplier").click(function () {
let checkStatus = table.checkStatus('list');
let data = checkStatus.data;
if (!data.length) {
layer.msg('请先选择要操作的供应商', {icon: 5})
} else {
if (data.length > 1) {
layer.msg('该操作不支持多选', {icon: 5})
return;
}
const status = data[0].status;
const source = data[0].supplier_source;
// 前置条件:供应商状态为待确认(4),供应商来源为CRM客户转化供应商(2)
if (status !== 4 || source !== 2) {
layer.msg('只有状态为"待确认"且来源为"CRM客户转化供应商"的供应商才可以操作', {icon: 5});
return;
}
let supplierId = data[0].supplier_id;
layer.open({
type: 2,
content: '/supplier/ConfirmCrmSupplier?view=iframe&supplier_id=' + supplierId,
area: ['70%', '720px'],
title: '转化供应商确认',
end: function () {
table.reload('list');
}
});
}
})
//判断是否要展示有全部离职采购员的供应商,有的话提示
if (!admin.getTempData('has_pop_up_all_channel_user_supplier_tips')) {
$.ajax({
......@@ -981,7 +1118,8 @@
let $this = $(this);
let supplierId = $this.data('supplier-id');
let status = $this.data('status');
if (status !== 1) {
// 审核中(1)和待确认(4)状态显示审批节点
if (status !== 1 && status !== 4) {
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment