完成分配库功能

This commit is contained in:
lilong@dgg.net 2021-03-24 17:10:12 +08:00
parent 1d18249fdb
commit 32823c8486
26 changed files with 870 additions and 91 deletions

View File

@ -43,11 +43,7 @@ class ApiController extends Controller
}
$roles = Role::query()->orderByDesc('id')->get();
foreach ($roles as $role) {
array_push($data, [
'name' => $role->display_name,
'value' => $role->id,
'selected' => $user != null && $user->hasRole($role),
]);
$role->selected = $user != null && $user->hasRole($role);
}
return $this->success('ok', $data);
}
@ -62,13 +58,22 @@ class ApiController extends Controller
}
$departments = Department::query()->orderByDesc('id')->get();
foreach ($departments as $d) {
$d->value = $d->id;
$d->selected = $user != null && $user->department_id == $d->id;
}
$data = recursive($departments);
return $this->success('ok', $data);
}
public function getUser(Request $request)
{
$user_id = $request->input('user_id');
$users = User::query()->get();
foreach ($users as $user){
$user->selected = $user_id == $user->id;
}
return $this->success('ok',$users);
}
/**
* 呼叫接口
* @param Request $request

View File

@ -3,15 +3,18 @@
namespace App\Http\Controllers\Crm;
use App\Http\Controllers\Controller;
use App\Imports\CustomerImport;
use App\Models\CustomerField;
use App\Models\Customer;
use App\Models\CustomerFieldValue;
use App\Models\Department;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\View;
use Maatwebsite\Excel\Facades\Excel;
class AssignmentController extends Controller
{
@ -22,7 +25,6 @@ class AssignmentController extends Controller
*/
public function index(Request $request)
{
$users = User::query()->get();
if ($request->ajax()){
$data = $request->all(['name','contact_name','contact_phone']);
$res = Customer::query()
@ -43,7 +45,12 @@ class AssignmentController extends Controller
->paginate($request->get('limit', 30));
return $this->success('ok',$res->items(),$res->total());
}
return View::make('crm.assignment.index',compact('users'));
$business = collect([]);
$user_ids = Department::query()->where('business_user_id','>',0)->pluck('business_user_id')->toArray();
if (!empty($user_ids)){
$business = User::query()->whereIn('id',$user_ids)->get();
}
return View::make('crm.assignment.index',compact('business'));
}
@ -183,33 +190,79 @@ class AssignmentController extends Controller
public function to(Request $request)
{
$ids = $request->get('ids',[]);
$user = User::where('id',$request->get('user_id'))->first();
$department_id = $request->get('department_id');
$user_ids = User::where('department_id',$request->department_id)->pluck('id')->toArray();
$type = $request->get('type');
DB::beginTransaction();
try{
if ($type=='user'){
DB::table('project')->whereIn('id',$ids)->update([
'owner_user_id' => -3,
'assignment_time' => date('Y-m-d H:i:s'),
'department_id' => $user->department_id,
]);
}elseif ($type=='department'){
DB::table('project')->whereIn('id',$ids)->update([
'owner_user_id' => -2,
'department_id' => $department_id,
'assignment_time' => date('Y-m-d H:i:s'),
]);
$user = User::where('id',$request->get('user_id'))->first();
if ($user == null){
return $this->error('请选择员工');
}
$data = [
'owner_user_id' => $user->id,
'owner_user_nickname' => $user->nickname,
'owner_department_id' => $user->department_id??0,
'assignment_user_id' => $request->user()->id,
'assignment_user_nickname' => $request->user()->nickname,
'status' => 3,
'status_time' => date('Y-m-d H:i:s'),
];
}elseif ($type=='department'){
$department_id = $request->get('department_id');
if (!$department_id){
return $this->error('请选择分配部门');
}
$data = [
'owner_user_id' => 0,
'owner_user_nickname' => null,
'owner_department_id' => $department_id,
'assignment_user_id' => $request->user()->id,
'assignment_user_nickname' => $request->user()->nickname,
'status' => 4,
'status_time' => date('Y-m-d H:i:s'),
];
}elseif ($type=='business'){
$user = User::where('id',$request->get('user_id'))->first();
if ($user == null){
return $this->error('请选择部门经理');
}
$data = [
'owner_user_id' => $user->id,
'owner_user_nickname' => $user->nickname,
'owner_department_id' => $user->department_id??0,
'assignment_user_id' => $request->user()->id,
'assignment_user_nickname' => $request->user()->nickname,
'status' => 2,
'status_time' => date('Y-m-d H:i:s'),
];
}
Customer::query()->whereIn('id',$ids)->update($data);
DB::commit();
return Response::json(['code'=>0,'msg'=>'分配成功']);
return $this->success();
}catch (\Exception $exception){
DB::rollBack();
Log::error('分配异常:'.$exception->getMessage());
return Response::json(['code'=>1,'msg'=>'分配失败']);
return $this->error();
}
}
public function import(Request $request)
{
if ($request->ajax()){
$file = $request->input('upload_file');
if ($file == null){
return $this->error('请先上传文件');
}
$xlsFile = public_path().'/'.$file;
try{
Excel::import(new CustomerImport(), $xlsFile);
return $this->success('导入成功');
}catch (\Exception $exception){
Log::error('导入失败:'.$exception->getMessage());
return $this->error('导入失败');
}
}
return View::make('crm.assignment.import');
}
}

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Crm;
use App\Models\Department;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\View;
@ -27,7 +28,7 @@ class DepartmentController extends Controller
public function store(Request $request)
{
$data = $request->all(['name','parent_id']);
$data = $request->all(['name','parent_id','user_id']);
if ($data['parent_id']){
$parent = Department::query()->where('id',$data['parent_id'])->first();
if ($parent == null){
@ -36,7 +37,13 @@ class DepartmentController extends Controller
$data['level'] = $parent->level + 1;
}
try{
Department::create($data);
$user = User::query()->where('id','=',$data['user_id'])->first();
Department::create([
'name' => $data['name'],
'parent_id' => $data['parent_id'],
'business_user_id' => $user->id??0,
'business_user_nickname' => $user->nickname??null,
]);
return $this->success();
}catch (\Exception $exception){
Log::error('添加部门异常:'.$exception->getMessage());
@ -52,10 +59,15 @@ class DepartmentController extends Controller
public function update(Request $request,$id)
{
$data = $request->all(['name']);
$data = $request->all(['name','user_id']);
$model = Department::findOrFail($id);
try{
$model->update($data);
$user = User::query()->where('id','=',$data['user_id'])->first();
$model->update([
'name' => $data['name'],
'business_user_id' => $user->id??0,
'business_user_nickname' => $user->nickname??null,
]);
return $this->success();
}catch (\Exception $exception){
Log::error('更新部门异常:'.$exception->getMessage());

View File

@ -0,0 +1,28 @@
<?php
namespace App\Imports;
use App\Models\Customer;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Concerns\ToModel;
class CustomerImport implements ToModel
{
public function model(array $row)
{
if (!isset($row[2]) || !preg_match('/\d{7,11}/',$row[2]) ) {
return null;
}
return new Customer([
'uuid' => uuid_generate(),
'name' => $row[0],
'contact_name' => $row[1],
'contact_phone' => $row[2],
'created_user_id' => request()->user()->id,
'created_user_nickname' => request()->user()->nickname,
'owner_user_id' => request()->user()->id,
'owner_user_nickname' => request()->user()->nickname,
'status' => 1,
]);
}
}

View File

@ -9,12 +9,13 @@
"license": "MIT",
"require": {
"php": "^7.2.5|^8.0",
"ext-json": "*",
"fideloper/proxy": "^4.4",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^6.20",
"laravel/tinker": "^2.5",
"spatie/laravel-permission": "^4.0",
"ext-json": "*"
"maatwebsite/excel": "^3.1",
"spatie/laravel-permission": "^4.0"
},
"require-dev": {
"facade/ignition": "^1.16.4",

588
composer.lock generated
View File

@ -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": "faaec6f30b53b0a8fb976c76f1775054",
"content-hash": "98c22c6ca3fb4b7a979a0df0533f23b2",
"packages": [
{
"name": "dnoegel/php-xdg-base-dir",
@ -320,6 +320,62 @@
],
"time": "2020-12-29T14:50:06+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.13.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
"reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=5.2"
},
"require-dev": {
"simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
},
"type": "library",
"autoload": {
"psr-0": {
"HTMLPurifier": "library/"
},
"files": [
"library/HTMLPurifier.composer.php"
],
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-or-later"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "admin@htmlpurifier.org",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"time": "2020-06-29T00:56:53+00:00"
},
{
"name": "fideloper/proxy",
"version": "4.4.1",
@ -1039,6 +1095,320 @@
"description": "Mime-type detection for Flysystem",
"time": "2021-01-18T20:58:21+00:00"
},
{
"name": "maatwebsite/excel",
"version": "3.1.29",
"source": {
"type": "git",
"url": "https://github.com/Maatwebsite/Laravel-Excel.git",
"reference": "1e567e6e19a04fd65b5876d5bc92f4015f09fab4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/1e567e6e19a04fd65b5876d5bc92f4015f09fab4",
"reference": "1e567e6e19a04fd65b5876d5bc92f4015f09fab4",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"illuminate/support": "5.8.*|^6.0|^7.0|^8.0",
"php": "^7.0|^8.0",
"phpoffice/phpspreadsheet": "1.16.*"
},
"require-dev": {
"orchestra/testbench": "^6.0",
"predis/predis": "^1.1"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Maatwebsite\\Excel\\ExcelServiceProvider"
],
"aliases": {
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
}
}
},
"autoload": {
"psr-4": {
"Maatwebsite\\Excel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Patrick Brouwers",
"email": "patrick@maatwebsite.nl"
}
],
"description": "Supercharged Excel exports and imports in Laravel",
"keywords": [
"PHPExcel",
"batch",
"csv",
"excel",
"export",
"import",
"laravel",
"php",
"phpspreadsheet"
],
"time": "2021-03-16T11:56:39+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/c4c5803cc1f93df3d2448478ef79394a5981cc58",
"reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"myclabs/php-enum": "^1.5",
"php": ">= 7.1",
"psr/http-message": "^1.0",
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"ext-zip": "*",
"guzzlehttp/guzzle": ">= 6.3",
"mikey179/vfsstream": "^1.6",
"phpunit/phpunit": ">= 7.5"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "András Kolesár",
"email": "kolesar@kolesar.hu"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"time": "2020-05-30T13:11:16+00:00"
},
{
"name": "markbaker/complex",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "9999f1432fae467bc93c53f357105b4c31bb994c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/9999f1432fae467bc93c53f357105b4c31bb994c",
"reference": "9999f1432fae467bc93c53f357105b4c31bb994c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"phpcompatibility/php-compatibility": "^9.0",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
},
"files": [
"classes/src/functions/abs.php",
"classes/src/functions/acos.php",
"classes/src/functions/acosh.php",
"classes/src/functions/acot.php",
"classes/src/functions/acoth.php",
"classes/src/functions/acsc.php",
"classes/src/functions/acsch.php",
"classes/src/functions/argument.php",
"classes/src/functions/asec.php",
"classes/src/functions/asech.php",
"classes/src/functions/asin.php",
"classes/src/functions/asinh.php",
"classes/src/functions/atan.php",
"classes/src/functions/atanh.php",
"classes/src/functions/conjugate.php",
"classes/src/functions/cos.php",
"classes/src/functions/cosh.php",
"classes/src/functions/cot.php",
"classes/src/functions/coth.php",
"classes/src/functions/csc.php",
"classes/src/functions/csch.php",
"classes/src/functions/exp.php",
"classes/src/functions/inverse.php",
"classes/src/functions/ln.php",
"classes/src/functions/log2.php",
"classes/src/functions/log10.php",
"classes/src/functions/negative.php",
"classes/src/functions/pow.php",
"classes/src/functions/rho.php",
"classes/src/functions/sec.php",
"classes/src/functions/sech.php",
"classes/src/functions/sin.php",
"classes/src/functions/sinh.php",
"classes/src/functions/sqrt.php",
"classes/src/functions/tan.php",
"classes/src/functions/tanh.php",
"classes/src/functions/theta.php",
"classes/src/operations/add.php",
"classes/src/operations/subtract.php",
"classes/src/operations/multiply.php",
"classes/src/operations/divideby.php",
"classes/src/operations/divideinto.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"time": "2020-08-26T10:42:07+00:00"
},
{
"name": "markbaker/matrix",
"version": "2.1.2",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
"reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"phpcompatibility/php-compatibility": "^9.0",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
},
"files": [
"classes/src/Functions/adjoint.php",
"classes/src/Functions/antidiagonal.php",
"classes/src/Functions/cofactors.php",
"classes/src/Functions/determinant.php",
"classes/src/Functions/diagonal.php",
"classes/src/Functions/identity.php",
"classes/src/Functions/inverse.php",
"classes/src/Functions/minors.php",
"classes/src/Functions/trace.php",
"classes/src/Functions/transpose.php",
"classes/src/Operations/add.php",
"classes/src/Operations/directsum.php",
"classes/src/Operations/subtract.php",
"classes/src/Operations/multiply.php",
"classes/src/Operations/divideby.php",
"classes/src/Operations/divideinto.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@demon-angel.eu"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"time": "2021-01-23T16:37:31+00:00"
},
{
"name": "monolog/monolog",
"version": "2.2.0",
@ -1127,6 +1497,58 @@
],
"time": "2020-12-14T13:15:25+00:00"
},
{
"name": "myclabs/php-enum",
"version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/php-enum.git",
"reference": "46cf3d8498b095bd33727b13fd5707263af99421"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/php-enum/zipball/46cf3d8498b095bd33727b13fd5707263af99421",
"reference": "46cf3d8498b095bd33727b13fd5707263af99421",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"php": "^7.3 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "1.*",
"vimeo/psalm": "^4.5.1"
},
"type": "library",
"autoload": {
"psr-4": {
"MyCLabs\\Enum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP Enum contributors",
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
}
],
"description": "PHP Enum implementation",
"homepage": "http://github.com/myclabs/php-enum",
"keywords": [
"enum"
],
"time": "2021-02-15T16:11:48+00:00"
},
{
"name": "nesbot/carbon",
"version": "2.46.0",
@ -1388,6 +1810,109 @@
],
"time": "2018-07-02T15:55:56+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.16.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "76d4323b85129d0c368149c831a07a3e258b2b50"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/76d4323b85129d0c368149c831a07a3e258b2b50",
"reference": "76d4323b85129d0c368149c831a07a3e258b2b50",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"ezyang/htmlpurifier": "^4.13",
"maennchen/zipstream-php": "^2.1",
"markbaker/complex": "^1.5||^2.0",
"markbaker/matrix": "^1.2||^2.0",
"php": "^7.2||^8.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0"
},
"require-dev": {
"dompdf/dompdf": "^0.8.5",
"friendsofphp/php-cs-fixer": "^2.16",
"jpgraph/jpgraph": "^4.0",
"mpdf/mpdf": "^8.0",
"phpcompatibility/php-compatibility": "^9.3",
"phpunit/phpunit": "^8.5||^9.3",
"squizlabs/php_codesniffer": "^3.5",
"tecnickcom/tcpdf": "^6.3"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
"jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
},
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"time": "2020-12-31T18:03:49+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.7.5",
@ -1554,6 +2079,64 @@
],
"time": "2020-06-29T06:28:15+00:00"
},
{
"name": "psr/http-factory",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-factory.git",
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.0.0",
"psr/http-message": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"time": "2019-04-30T12:38:16+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
@ -6513,7 +7096,8 @@
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^7.2.5|^8.0"
"php": "^7.2.5|^8.0",
"ext-json": "*"
},
"platform-dev": []
}

View File

@ -18,6 +18,8 @@ class Department extends Migration
$table->string('name')->comment('部门名称');
$table->tinyInteger('level')->default(1)->comment('部门级别,最高级从1开始');
$table->unsignedBigInteger('parent_id')->default(0)->comment('上级部门ID');
$table->unsignedBigInteger('business_user_id')->default(0)->comment('部门经理用户ID');
$table->string('business_user_nickname')->nullable()->comment('部门经理用户昵称');
$table->timestamps();
});
}

View File

@ -17,7 +17,7 @@ class Node extends Migration
$table->bigIncrements('id');
$table->string('name')->comment('节点名称');
$table->tinyInteger('sort')->default(10)->comment('排序');
$table->tinyInteger('type')->default(0)->comment('默认00表示公共1客户跟进2订单生产3财务付款');
$table->tinyInteger('type')->default(1)->comment('默认11表示公共2客户跟进3订单生产4财务付款');
$table->timestamps();
});
}

View File

@ -21,17 +21,20 @@ class Customer extends Migration
$table->string('contact_phone')->nullable()->comment('联系电话');
$table->unsignedBigInteger('created_user_id')->default(0)->comment('创建人ID');
$table->string('created_user_nickname')->nullable()->comment('创建人姓名');
$table->unsignedBigInteger('node_id')->nullable()->comment('当前节点ID');
$table->unsignedBigInteger('node_id')->default(0)->comment('当前节点ID');
$table->string('node_name')->nullable()->comment('当前节点名称');
$table->unsignedBigInteger('follow_user_id')->default(0)->comment('最近跟进人ID');
$table->string('follow_user_nickname')->nullable()->comment('最近跟进人姓名');
$table->timestamp('next_follow_time')->nullable()->comment('下次跟进时间');
$table->unsignedBigInteger('owner_user_id')->default(0)->comment('当前所属用户ID');
$table->string('owner_user_nickname')->default(0)->comment('当前所属用户名称');
$table->string('owner_user_nickname')->nullable()->comment('当前所属用户名称');
$table->unsignedBigInteger('owner_department_id')->default(0)->comment('当前所属用户部门ID');
$table->unsignedBigInteger('assignment_user_id')->default(0)->comment('分配人ID');
$table->string('assignment_user_nickname')->nullable()->comment('分配人名称');
$table->tinyInteger('status')->default(1)->comment('资源所在库1待分配库录入库2经理库3个人库4部门库5公海库');
$table->dateTime('status_time')->nullable()->comment('进入当前库的时间');
$table->text('remark')->nullable()->comment('客户跟进备注');
$table->dateTime('remove_time')->nullable()->comment('剔除到公海库的时间');
$table->tinyInteger('is_end')->default(0)->comment('是否成单0未成单1成单');
$table->timestamp('end_time')->nullable()->comment('成单时间');
$table->timestamps();

View File

@ -17,7 +17,7 @@ class CustomerFieldValue extends Migration
$table->bigIncrements('id');
$table->unsignedBigInteger('customer_id')->comment('客户ID');
$table->unsignedBigInteger('customer_field_id')->comment('客户字段ID');
$table->string('data')->nullable()->comment('项目对应表单字段的值');
$table->text('data')->nullable()->comment('项目对应表单字段的值');
$table->timestamps();
});
}

BIN
public/template/import.xlsx Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
18908221080
13512293513
13512293514
13512293515
13512293516
13512293517
13512293517
1 18908221080
2 13512293513
3 13512293514
4 13512293515
5 13512293516
6 13512293517
7 13512293517

View File

@ -2,6 +2,9 @@
{{csrf_field()}}
<div class="layui-row">
<div class="layui-col-md6">
<div class="layui-form-item">
<h2>基础信息</h2>
</div>
<div class="layui-form-item">
<label for="" class="layui-form-label">客户名称</label>
<div class="layui-input-inline" style="width: 400px">
@ -22,6 +25,9 @@
</div>
</div>
<div class="layui-col-md6">
<div class="layui-form-item">
<h2>扩展信息</h2>
</div>
@foreach($fields as $d)
<div class="layui-form-item">
<label for="" class="layui-form-label">{{$d->field_label}}</label>
@ -90,7 +96,7 @@
<button type="button" class="layui-btn layui-btn-sm uploadPics" data-ul="ul_{{$d->field_key}}" data-input="input_{{$d->field_key}}" ><i class="layui-icon">&#xe67c;</i>多图上传</button>
<div class="layui-upload-list" >
<ul class="layui-upload-box layui-clear" id="ul_{{$d->field_key}}">
@if(isset($data[$d->id]) && strpos($data[$d->id],','))
@if(isset($data[$d->id]))
@foreach(explode(',',$data[$d->id]) as $v)
<li><img src="{{ $v }}" /><p onclick="removePics(this,'ul_{{$d->field_key}}','input_{{$d->field_key}}')">删除</p></li>
@endforeach

View File

@ -42,7 +42,6 @@
$("#"+elem_ul+" li").each(function (index,elem) {
pic_urls.push($(elem).find("img").attr("src"))
})
console.log(pic_urls)
$("#"+elem_input).val(pic_urls.join(','));
}
$(".uploadPics").each(function (index,elem) {

View File

@ -18,6 +18,10 @@
model: { label: { type: 'text' } },
radio: true,
clickClose: true,
prop: {
name: 'name',
value: 'id',
},
tree: {
show: true,
showLine: false,

View File

@ -11,10 +11,13 @@
url: '{{route('api.getRoleByUserId',['user_id'=>$user_id??null])}}',
dataType: 'json',
success: function (res) {
var role_ids = []
var demo1 = xmSelect.render({
el: '#xm-select-role',
name: 'role_ids',
prop: {
name: 'name',
value: 'id',
},
data: res.data,
})

View File

@ -0,0 +1,30 @@
<div id="xm-select-user" class="xm-select-user"></div>
<script>
layui.use(['jquery','form', 'layer'], function () {
var $ = layui.jquery;
var form = layui.form;
var layer = layui.layer;
// 一般来说,权限数据是异步传递过来的
$.ajax({
method: 'post',
url: '{{route('api.getUser',['user_id'=>$user_id??0])}}',
dataType: 'json',
success: function (res) {
var demo1 = xmSelect.render({
el: '#xm-select-user',
name: 'user_id',
filterable: true,
radio: true,
clickClose: true,
model: { label: { type: 'text' } },
prop: {
name: 'nickname',
value: 'id',
},
data: res.data,
})
}
});
});
</script>

View File

@ -2,9 +2,6 @@
@section('content')
<div class="layui-card">
<div class="layui-card-header layuiadmin-card-header-auto">
<h2>更新</h2>
</div>
<div class="layui-card-body">
<form action="{{route('crm.assignment.update',['id'=>$model->id])}}" method="post" class="layui-form">
@include('common.customer_edit',['model'=>$model,'fields'=>$fields,'data'=>$data])

View File

@ -0,0 +1,60 @@
@extends('base')
@section('content')
<div class="layui-card">
<div class="layui-card-body">
<form action="{{route('crm.assignment.import')}}" method="post" class="layui-form">
<div class="layui-form-item">
<label for="" class="layui-form-label">文件</label>
<div class="layui-input-block">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="uploadBtn">
<i class="layui-icon">&#xe67c;</i>点击选择
</button>
<span id="filename"></span>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="hidden" name="upload_file">
<button type="button" class="layui-btn layui-btn-sm layui-disabled" disabled id="importBtn" lay-submit lay-filter="go-close-refresh">确认导入</button>
</div>
</div>
</form>
</div>
</div>
@endsection
@section('script')
<script>
layui.use(['layer','table','form','laydate','upload'],function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var table = layui.table;
var laydate = layui.laydate;
var upload = layui.upload;
upload.render({
elem: '#uploadBtn'
,url: '{{route('api.upload')}}'
,auto: true
,multiple: false
,accept: 'file'
,exts: 'xlsx|xls'
,done: function(res){
layer.msg(res.msg,{icon:res.code==0?1:2,time:2000},function() {
if (res.code==0){
$('input[name="upload_file"]').val(res.data.url)
$("#filename").text(res.data.url)
$("#importBtn").removeClass("layui-disabled")
$("#importBtn").removeAttr("disabled")
}
})
}
,error: function(){
layer.msg('上传文件异常',{icon:2});
}
});
})
</script>
@endsection

View File

@ -13,7 +13,7 @@
@endcan
@can('crm.assignment.import')
<button type="button" id="import_project" class="layui-btn layui-btn-sm">导入</button>
<a href="" class="layui-btn layui-btn-sm layui-btn-warm">模板下载</a>
<a href="/template/import.xlsx" class="layui-btn layui-btn-sm layui-btn-warm">模板下载</a>
@endcan
<button type="button" lay-submit lay-filter="search" class="layui-btn layui-btn-sm" >搜索</button>
</div>
@ -42,16 +42,29 @@
<form class="layui-form" action="{{route("crm.assignment.to")}}">
<div class="layui-form-item">
<div class="layui-inline">
<label for="" class="layui-form-label">用户</label>
<label for="" class="layui-form-label">员工</label>
<div class="layui-input-block" style="width: 275px">
<select name="user_id" lay-verify="required">
@include('common.get_user')
</div>
</div>
<input type="hidden" name="type" value="user">
<button type="button" class="layui-btn layui-btn-sm" lay-submit lay-filter="assignment_to" >分配</button>
</div>
</form>
<form class="layui-form" action="{{route("crm.assignment.to")}}">
<div class="layui-form-item">
<div class="layui-inline">
<label for="" class="layui-form-label">经理:</label>
<div class="layui-input-block" style="width: 275px">
<select name="user_id" >
<option value=""></option>
@foreach($users as $d)
@foreach($business as $d)
<option value="{{$d->id}}">{{$d->nickname}}</option>
@endforeach
</select>
</div>
</div>
<input type="hidden" name="type" value="business">
<button type="button" class="layui-btn layui-btn-sm" lay-submit lay-filter="assignment_to" >分配</button>
</div>
</form>
@ -63,6 +76,7 @@
@include('common.get_department_by_user_id')
</div>
</div>
<input type="hidden" name="type" value="department">
<button type="button" class="layui-btn layui-btn-sm" lay-submit lay-filter="assignment_to" >分配</button>
</div>
</form>
@ -79,25 +93,6 @@
</script>
</div>
</div>
<script type="text/html" id="import-html">
<div style="padding:20px">
<div class="layui-form">
<div class="layui-form-item">
<label for="" class="layui-form-label">文件</label>
<div class="layui-input-block">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="uploadBtn">
<i class="layui-icon">&#xe67c;</i>点击选择
</button>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn layui-btn-sm" id="importBtn">确认导入</button>
</div>
</div>
</div>
</script>
@endsection
@section('script')
@ -153,31 +148,12 @@
//导入
$("#import_project").click(function() {
layer.open({
type : 1,
title : '导入项目仅允许xls、xlsx格式',
type : 2,
title : '导入客户仅允许xls、xlsx格式',
shadeClose : true,
area : ['500px','auto'],
content : $("#import-html").html()
area : ['600px','400px'],
content : "{{route('crm.assignment.import')}}"
})
upload.render({
elem: '#uploadBtn'
,url: '{{route('crm.assignment.import')}}'
,auto: false
,multiple: false
,accept: 'file'
,exts: 'xlsx|xls'
,bindAction: '#importBtn'
,done: function(res){
layer.msg(res.msg,{},function() {
if (res.code==0){
layer.closeAll();
dataTable.reload({
page:{curr:1}
})
}
})
}
});
})
//分配
@ -197,7 +173,7 @@
layer.confirm('确认分配吗?', function (index) {
layer.close(index);
let load = layer.load();
$.post(data.form.action, {ids:ids,user_id:data.field.user_id}, function (res) {
$.post(data.form.action, {ids:ids,user_id:data.field.user_id,type:data.field.type,department_id:data.field.department_id}, function (res) {
layer.close(load);
let code = res.code
layer.msg(res.msg, {time: 2000, icon: code == 0 ? 1 : 2}, function () {

View File

@ -5,6 +5,13 @@
<input type="hidden" name="parent_id" value="{{$parent_id??0}}">
<input class="layui-input" type="text" name="name" lay-verify="required" value="{{$model->name??''}}" placeholder="请输入名称">
</div>
</div>
<div class="layui-form-item">
<label for="" class="layui-form-label">人员</label>
<div class="layui-input-block">
@include('common.get_user',['user_id'=>$model->business_user_id??0])
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">

View File

@ -56,6 +56,7 @@
cols: [[ //表头
{field: 'id', title: 'ID', sort: true, width: 80}
, {field: 'name', title: '名称'}
, {field: 'business_user_nickname', title: '部门经理'}
, {field: 'created_at', title: '创建时间'}
, {field: 'updated_at', title: '更新时间'}
, {fixed: 'right',title:'操作', width: 260, align: 'center', toolbar: '#options'}

View File

@ -20,5 +20,6 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
Route::post('/api/get_permission_by_role_id','ApiController@getPermissionByRoleId')->name('api.getPermissionByRoleId');
Route::post('/api/get_role_by_user_id','ApiController@getRoleByUserId')->name('api.getRoleByUserId');
Route::post('/api/get_department_by_user_id','ApiController@getDepartmentByUserId')->name('api.getDepartmentByUserId');
Route::post('/api/get_user','ApiController@getUser')->name('api.getUser');
Route::post('/api/call','ApiController@call')->name('api.call');
Route::post('/api/upload','ApiController@upload')->name('api.upload');

View File

@ -242,7 +242,7 @@ Route::group(['prefix'=>'crm','namespace'=>'Crm','middleware'=>['auth','permissi
//分配
Route::post('assignment/to','AssignmentController@to')->name('crm.assignment.to')->middleware('permission:crm.assignment.to');
//导入
Route::post('assignment/import','AssignmentController@import')->name('crm.assignment.import')->middleware('permission:crm.assignment.import');
Route::match(['get','post'],'assignment/import','AssignmentController@import')->name('crm.assignment.import')->middleware('permission:crm.assignment.import');
//添加
Route::get('assignment/create','AssignmentController@create')->name('crm.assignment.create')->middleware('permission:crm.assignment.create');
Route::post('assignment/store','AssignmentController@store')->name('crm.assignment.store')->middleware('permission:crm.assignment.create');