最新版本
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -9,4 +9,5 @@ Thumbs.db
|
||||
/vendor
|
||||
/.settings
|
||||
/.buildpath
|
||||
/.project
|
||||
/.project
|
||||
/runtime
|
||||
@@ -7,6 +7,14 @@ use app\admin\service\AccountService;
|
||||
|
||||
class AccountManagement extends BaseController
|
||||
{
|
||||
/* 查询所有用户 */
|
||||
public function getAllUsers(AccountService $accountService)
|
||||
{
|
||||
$result = $accountService->getAllUsers();
|
||||
return json(['code' => 200, 'message' => '查询成功', 'data' => $result]);
|
||||
}
|
||||
|
||||
/* 注册用户 */
|
||||
public function addAccount(AccountService $accountService)
|
||||
{
|
||||
|
||||
@@ -14,7 +22,7 @@ class AccountManagement extends BaseController
|
||||
$params = $this->request->post();
|
||||
|
||||
# 参数校验
|
||||
if (empty($params['real_name'])) {
|
||||
if (empty($params['username'])) {
|
||||
return json(['code' => 400, 'message' => '缺少必要参数']);
|
||||
}
|
||||
|
||||
@@ -31,4 +39,26 @@ class AccountManagement extends BaseController
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/* 更新用户状态 */
|
||||
public function updateAccountStatus(AccountService $accountService, $id, $status)
|
||||
{
|
||||
try {
|
||||
$result = $accountService->updateAccountStatus($id, $status);
|
||||
return json(['code' => 200, 'message' => '账户状态更新成功', 'data' => $result]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 400, 'message' => $e->getMessage(), 'data' => null]);
|
||||
}
|
||||
}
|
||||
|
||||
/* 删除用户 */
|
||||
public function deleteAccount(AccountService $accountService, $id)
|
||||
{
|
||||
try {
|
||||
$result = $accountService->deleteAccount($id);
|
||||
return json(['code' => 200, 'message' => '账户删除成功', 'data' => $result]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 400, 'message' => $e->getMessage(), 'data' => null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
app/admin/controller/CompanyAndOperators.php
Normal file
89
app/admin/controller/CompanyAndOperators.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\BaseController;
|
||||
use app\common\service\TicketService;
|
||||
use app\admin\service\CompanyOperatorsService;
|
||||
|
||||
class CompanyAndOperators extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取所有运营人员名称
|
||||
*/
|
||||
public function getAllOperators(TicketService $ticketService)
|
||||
{
|
||||
|
||||
$result = $ticketService->getAllOperators();
|
||||
|
||||
return json(['code' => 200, 'msg' => '查询成功', 'data' => $result]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function TestgetAllOperators(TicketService $ticketService)
|
||||
{
|
||||
|
||||
$result = $ticketService->TestgetAllOperators();
|
||||
|
||||
return json(['code' => 200, 'msg' => '查询成功', 'data' => $result]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取我方员工列表
|
||||
*/
|
||||
public function getStaffList(TicketService $ticketService)
|
||||
{
|
||||
$result = $ticketService->getStaffList();
|
||||
return json(['code' => 200, 'msg' => '查询成功', 'data' => $result]);
|
||||
}
|
||||
|
||||
|
||||
/* 删除运营 */
|
||||
public function deleteOperator(CompanyOperatorsService $CompanyOperatorService, $id)
|
||||
{
|
||||
|
||||
$result = $CompanyOperatorService->deleteOperator($id);
|
||||
|
||||
return json(['code' => 200, 'msg' => '删除成功', 'data' => $result]);
|
||||
}
|
||||
|
||||
/* 删除客户单位 */
|
||||
public function deleteCompany(CompanyOperatorsService $CompanyOperatorService, $id)
|
||||
{
|
||||
$result = $CompanyOperatorService->deleteCompany($id);
|
||||
if (!$result) {
|
||||
return json(['code' => 400, 'msg' => '删除失败', 'data' => null]);
|
||||
}
|
||||
return json(['code' => 200, 'msg' => '删除成功']);
|
||||
}
|
||||
|
||||
|
||||
/* 新增公司(客户)单位 */
|
||||
public function addCompany(CompanyOperatorsService $CompanyOperatorService)
|
||||
{
|
||||
$data = $this->request->post();
|
||||
try {
|
||||
$result = $CompanyOperatorService->addCompany($data);
|
||||
return json(['code' => 200, 'msg' => '创建成功', 'data' => $result]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 400, 'msg' => $e->getMessage(), 'data' => null]);
|
||||
}
|
||||
}
|
||||
|
||||
/* 新增运营人员 */
|
||||
public function addOperator(CompanyOperatorsService $CompanyOperatorService)
|
||||
{
|
||||
$data = $this->request->post();
|
||||
try {
|
||||
$result = $CompanyOperatorService->addOperator($data);
|
||||
return json(['code' => 200, 'msg' => '创建成功', 'data' => $result]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 400, 'msg' => $e->getMessage(), 'data' => null]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,8 @@ class Ticket extends BaseController
|
||||
"page" => $this->request->param('page', 1, 'intval'),
|
||||
"limit" => $this->request->param('limit', 20, 'intval'),
|
||||
"status" => $this->request->param('status', null),
|
||||
"operator_name" => $this->request->param('operator_name', null),
|
||||
"operator_id" => $this->request->param('operator_id', null),
|
||||
"user_id" => $this->request->param('user_id', null),
|
||||
"searchKeyword" => $this->request->param('search', null),
|
||||
"sortOrder" => $this->request->param('sort_order', 'desc'),
|
||||
];
|
||||
@@ -69,6 +70,39 @@ class Ticket extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 统计各状态工单数量
|
||||
*/
|
||||
public function getTicketDashboardStats(TicketService $ticketService)
|
||||
{
|
||||
$result = $ticketService->getTicketDashboardStats();
|
||||
return json(['code' => 200, 'msg' => '查询成功', 'data' => $result]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新工单
|
||||
*/
|
||||
public function batchUpdate(TicketService $ticketService)
|
||||
{
|
||||
$adminId = Session::get('user_info.id'); // 获取当前登录管理员ID
|
||||
$data = $this->request->post();
|
||||
|
||||
$ids = $data['ids'] ?? [];
|
||||
if (!is_array($ids) || empty($ids)) {
|
||||
return json(['code' => 400, 'msg' => 'ids 必须是非空数组', 'data' => []]);
|
||||
}
|
||||
|
||||
$allowFields = ['status', 'lock_time'];
|
||||
|
||||
try {
|
||||
$result = $ticketService->batchUpdateTickets($ids, $data, $allowFields, $adminId, true);
|
||||
return json(['code' => 200, 'msg' => '批量更新成功', 'data' => $result]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 400, 'msg' => $e->getMessage(), 'data' => []]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个工单(仅后台可调用)
|
||||
*/
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\BaseController;
|
||||
use app\common\service\TicketService;
|
||||
|
||||
class TicketFilter extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取所有运营人员名称 (下拉筛选用)
|
||||
*/
|
||||
public function getAllOperators(TicketService $ticketService)
|
||||
{
|
||||
|
||||
$result = $ticketService->getAllOperators();
|
||||
|
||||
return json(['code' => 200, 'msg' => '查询成功', 'data' => $result]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取我方员工列表 (下拉选择用)
|
||||
*/
|
||||
public function getStaffList(TicketService $ticketService)
|
||||
{
|
||||
$result = $ticketService->getStaffList();
|
||||
return json(['code' => 200, 'msg' => '查询成功', 'data' => $result]);
|
||||
}
|
||||
}
|
||||
30
app/admin/controller/Utill.php
Normal file
30
app/admin/controller/Utill.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\BaseController;
|
||||
use app\admin\service\UtillService;
|
||||
use think\facade\Session;
|
||||
|
||||
class Utill extends BaseController
|
||||
{
|
||||
/* 获取需要导出的数据
|
||||
$range范围:week,month
|
||||
*/
|
||||
public function getExportData(UtillService $UtillService)
|
||||
{
|
||||
$range = $this->request->post('range');
|
||||
|
||||
try {
|
||||
# session中获取当前登录是否是管理员
|
||||
$isAdmin = Session::get('user_info.role') === 'admin' ? true : false; // 后续用来判断
|
||||
if (!$isAdmin) {
|
||||
return json(['code' => 403, 'msg' => '权限不足', 'data' => []]);
|
||||
}
|
||||
$data = $UtillService->getExportData($range);
|
||||
return json(['code' => 200, 'msg' => '查询成功', 'data' => $data]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 500, 'msg' => '查询失败', 'data' => []]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,30 +2,21 @@
|
||||
|
||||
namespace app\admin\middleware;
|
||||
|
||||
use thans\jwt\facade\JWTAuth;
|
||||
use thans\jwt\exception\TokenExpiredException;
|
||||
use think\facade\Session;
|
||||
|
||||
class Auth
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
try {
|
||||
// 1. 核心:必须先执行 auth(),它会自动从 Header 读取 Bearer Token 并验证
|
||||
// 如果过期或非法,这里会直接抛出异常
|
||||
|
||||
$payload = JWTAuth::auth();
|
||||
// $payload = JWTAuth::getPayload(); 这个是获取数据,进行解码token
|
||||
$request->login_user_id = (int)$payload['user_id'] ?? null;
|
||||
$request->login_role = $payload['role'] ?? null;
|
||||
|
||||
return $next($request);
|
||||
}catch (TokenExpiredException $e){
|
||||
// 捕获token过期异常
|
||||
return json(['code' => 401, 'msg' => '登录已过期,请重新登录'],401);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// 如果报错,返回具体的错误信息,方便我们排查
|
||||
return json(['code' => 400, 'msg' => '权限校验失败:' . $e->getMessage()], 400);
|
||||
if (!Session::has('user_info')) {
|
||||
return json(['code' => 401, 'msg' => '未登录,请先登录']);
|
||||
}
|
||||
|
||||
$user = Session::get('user_info');
|
||||
|
||||
$request->login_user_id = $user['id'] ?? null;
|
||||
$request->login_role = $user['role'] ?? null;
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
<?php
|
||||
|
||||
use think\facade\Route;
|
||||
use app\admin\middleware\Auth;
|
||||
|
||||
Route::get('ticketsfind', 'Ticket/ticketsFind'); // 通用查询方法
|
||||
// Route::group(function () {
|
||||
// // Route::get('ticketsfind', 'Ticket/ticketsFind'); // 通用查询方法
|
||||
// Route::post('addticket', 'Ticket/save'); // 保存工单
|
||||
// Route::put('ticket/:id', 'Ticket/updateTicket'); // 更新工单
|
||||
// Route::delete('ticket/:id', 'Ticket/deleteTicket'); // 删除工单
|
||||
// Route::get('operators', 'Ticket/getAllOperators'); // 根据运营人员查询
|
||||
// Route::get('customers', 'Customers/getList');
|
||||
// Route::post('addcustomername', 'Customers/addCustomer'); //添加客户名称
|
||||
// Route::post('addemployee', 'Customers/addEmployee');
|
||||
// Route::get('getStaffList', 'Ticket/getStaffList');
|
||||
// Route::delete('deleteemployee/:empId', 'Customers/deleteEmployee');
|
||||
// Route::delete('deletecustomer/:customerId', 'Customers/deleteCustomer');
|
||||
// Route::get('getticketstatuscount', 'Ticket/getTicketStatusCount');
|
||||
// })->middleware(Auth::class); // 只有这里需要 Token
|
||||
Route::group(function () {
|
||||
Route::get('ticketsfind', 'Ticket/ticketsFind');
|
||||
Route::post('addticket', 'Ticket/createTicket');
|
||||
Route::put('ticket/:id', 'Ticket/updateTicket');
|
||||
Route::delete('ticket/:id', 'Ticket/deleteTicket');
|
||||
Route::put('tickets/batch-update', 'Ticket/batchUpdate');
|
||||
Route::get('getticketdashboardstats', 'Ticket/getTicketDashboardStats');
|
||||
|
||||
|
||||
Route::get('getUserStaffList', 'CompanyAndOperators/getStaffList');
|
||||
Route::get('operators', 'CompanyAndOperators/getAllOperators');
|
||||
Route::get('getOperatorList', 'CompanyAndOperators/TestgetAllOperators');
|
||||
Route::delete('deleteOperator/:id', 'CompanyAndOperators/deleteOperator');
|
||||
Route::delete('deleteCompany/:id', 'CompanyAndOperators/deleteCompany');
|
||||
Route::post('addCompany', 'CompanyAndOperators/addCompany');
|
||||
Route::post('addOperator', 'CompanyAndOperators/addOperator');
|
||||
|
||||
Route::get('getAllUsers', 'AccountManagement/getAllUsers');
|
||||
Route::post('addAccount', 'AccountManagement/addAccount');
|
||||
Route::put('updateAccountStatus/:id/:status', 'AccountManagement/updateAccountStatus');
|
||||
Route::delete('deleteAccount/:id', 'AccountManagement/deleteAccount');
|
||||
|
||||
Route::post('getExportData', 'Utill/getExportData');
|
||||
})->middleware(Auth::class);
|
||||
|
||||
@@ -6,21 +6,44 @@ use app\common\model\User as UserModel;
|
||||
|
||||
class AccountService
|
||||
{
|
||||
|
||||
/* 查询所有用户 */
|
||||
public function getAllUsers()
|
||||
{
|
||||
$users = UserModel::with('company')->select();
|
||||
return $users->map(function ($user) {
|
||||
return [
|
||||
'id' => $user->id,
|
||||
'company' => [
|
||||
'id' => $user->company_id,
|
||||
'company_name' => $user->company->company_name
|
||||
],
|
||||
'username' => $user->username,
|
||||
'real_name' => $user->real_name,
|
||||
'role' => $user->role,
|
||||
'status' => $user->status,
|
||||
];
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
/* 注册账户 */
|
||||
public function createAccount($data)
|
||||
{
|
||||
if (empty($data['username'])) {
|
||||
$data['username'] = $data['real_name'];
|
||||
{
|
||||
if (empty($data['real_name'])) {
|
||||
$data['real_name'] = $data['username'];
|
||||
}
|
||||
|
||||
# 检查数据库中是否有相同用户名账户
|
||||
$exist = UserModel::where('username', $data['username'])->find();
|
||||
|
||||
if ($exist) {
|
||||
throw new \Exception('用户名已存在');
|
||||
}
|
||||
|
||||
$insertData = [
|
||||
'username' => $data['username'] ?? $data['real_name'],
|
||||
'real_name' => $data['real_name'],
|
||||
'company_id' => $data['company_id'] ?? 0,
|
||||
'username' => $data['username'],
|
||||
'real_name' => $data['real_name'] ?? $data['username'],
|
||||
'password' => password_hash('123456', PASSWORD_DEFAULT),
|
||||
'role' => $data['role'] ?? 'user',
|
||||
'status' => 1,
|
||||
@@ -31,4 +54,32 @@ class AccountService
|
||||
/** @var \think\Model $user */
|
||||
return $user->visible(['id', 'username', 'real_name', 'role', 'status'])->toArray();
|
||||
}
|
||||
|
||||
/* 更新用户状态 */
|
||||
public function updateAccountStatus($id, $status)
|
||||
{
|
||||
$user = UserModel::find($id);
|
||||
if (!$user) {
|
||||
throw new \Exception('用户不存在');
|
||||
}
|
||||
|
||||
$user->status = $status;
|
||||
$user->save();
|
||||
|
||||
return $user->visible(['id', 'username', 'real_name', 'role', 'status'])->toArray();
|
||||
}
|
||||
|
||||
|
||||
/* 删除用户 */
|
||||
public function deleteAccount($id)
|
||||
{
|
||||
$user = UserModel::find($id);
|
||||
if (!$user) {
|
||||
throw new \Exception('用户不存在');
|
||||
}
|
||||
|
||||
$user->delete();
|
||||
|
||||
return ['id' => $id];
|
||||
}
|
||||
}
|
||||
|
||||
46
app/admin/service/CompanyOperatorsService.php
Normal file
46
app/admin/service/CompanyOperatorsService.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service;
|
||||
use app\common\model\CompanyOperators;
|
||||
use app\common\model\Companys;
|
||||
|
||||
|
||||
class CompanyOperatorsService
|
||||
{
|
||||
public function deleteOperator($id)
|
||||
{
|
||||
$result = CompanyOperators::destroy($id);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function deleteCompany($id)
|
||||
{
|
||||
$result = Companys::customDelete($id);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function addCompany($data){
|
||||
|
||||
# 判断该公司名称是否已存在
|
||||
$existingCompany = Companys::where('company_name', $data['company_name'])->find();
|
||||
if ($existingCompany) {
|
||||
throw new \Exception('公司名称已存在');
|
||||
}
|
||||
|
||||
$result = Companys::create($data);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function addOperator($data){
|
||||
|
||||
# 判断运营人员是否存在
|
||||
$existingOperator = CompanyOperators::where('operator_name', $data['operator_name'])->find();
|
||||
if ($existingOperator) {
|
||||
throw new \Exception('运营人员已存在');
|
||||
}
|
||||
$result = CompanyOperators::create($data);
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service;
|
||||
|
||||
use app\common\model\Customers as CustomersModel;
|
||||
use app\common\model\CustomerEmployees;
|
||||
|
||||
class CustomersService
|
||||
{
|
||||
public function selectCustomersWithEmployees()
|
||||
{
|
||||
//with 预载入 ,解决N+1问题
|
||||
$list = CustomersModel::with('employees')->select();
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function addCustomer($companyName)
|
||||
{
|
||||
$id = CustomersModel::create([
|
||||
'company_name' => $companyName
|
||||
]);
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function addEmployee($empName, $Id)
|
||||
{
|
||||
$id = CustomersModel::where('id', $Id)->find()->employees()->save([
|
||||
'employee_name' => $empName
|
||||
]);
|
||||
return $id;
|
||||
}
|
||||
|
||||
|
||||
public function deleteEmployee($empId)
|
||||
{
|
||||
$result = CustomerEmployees::destroy($empId);
|
||||
return $result; // 返回受影响的行数,删除一行就1,没有删除就是0
|
||||
}
|
||||
|
||||
public function deleteCustomer($customerId)
|
||||
{
|
||||
// 删除客户单位会自动删除关联的员工(假设你在模型中设置了级联删除)
|
||||
$result = CustomersModel::destroy($customerId);
|
||||
return $result; // 返回受影响的行数,删除一行就1,没有删除就是0
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
20
app/admin/service/UtillService.php
Normal file
20
app/admin/service/UtillService.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service;
|
||||
|
||||
use app\common\model\Tickets;
|
||||
|
||||
class UtillService
|
||||
{
|
||||
/* 获取需要导出的数据 */
|
||||
public function getExportData($range)
|
||||
{
|
||||
$list = Tickets::with(['ticketStaff', 'ticketOperator'])->whereTime('lock_time', $range)->select();
|
||||
|
||||
foreach ($list as $item) {
|
||||
$item->visible(['id', 'website', 'datanum', 'remark', 'create_time', 'lock_time']);
|
||||
$item->append(['username', 'operator_name'])->hidden(['ticketStaff', 'ticketOperator']);
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
77
app/command/SyncData.php
Normal file
77
app/command/SyncData.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\facade\Db;
|
||||
|
||||
class SyncData extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('syncdata')->setDescription('从宝塔同步并处理数据');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln('开始连接远程数据库...');
|
||||
|
||||
try {
|
||||
// 增加 count 确认远程到底有没有数据
|
||||
$total = Db::connect('remote')->table('tickets')->count();
|
||||
$output->writeln("远程表共有 {$total} 条数据待处理");
|
||||
|
||||
if ($total == 0) {
|
||||
$output->writeln('警告:远程表中没有找到数据,请检查表名或权限。');
|
||||
return 0;
|
||||
}
|
||||
|
||||
// chunk(100) 比较平衡,2 太小了
|
||||
Db::connect('remote')->table('tickets')->chunk(100, function ($remoteRows) use ($output) {
|
||||
$processedData = [];
|
||||
|
||||
foreach ($remoteRows as $row) {
|
||||
$operator = Db::name('company_operators')->where('operator_name', $row['operator'])->find();
|
||||
|
||||
$operator_id = $operator ? $operator['id'] : null;
|
||||
$company_id = $operator ? $operator['company_id'] : null;
|
||||
|
||||
|
||||
$processedData[] = [
|
||||
// 'id' => $row['id'], // 如果想用旧ID就取消注释,否则留空让本地表自增
|
||||
'website' => $row['website_url'],
|
||||
'datanum' => $row['datanum'],
|
||||
'create_time' => !empty($row['create_time']) ? strtotime($row['create_time']) : 0,
|
||||
'update_time' => !empty($row['update_time']) ? strtotime($row['update_time']) : 0,
|
||||
'progress' => $row['progress'],
|
||||
'remark' => $row['remark'] ?? '',
|
||||
'status' => $row['is_completed'],
|
||||
'lock_time' => $row['lock_time'] ?? 0,
|
||||
'operator_id' => $operator_id,
|
||||
'company_id' => $company_id,
|
||||
'user_id' => $row['staff_id'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($processedData)) {
|
||||
// 使用 try-catch 捕获插入时的报错
|
||||
try {
|
||||
Db::name('tickets')->insertAll($processedData);
|
||||
$output->writeln("成功插入一批数据 (" . count($processedData) . " 条)");
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln("本地插入失败: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln("严重错误: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$output->writeln('--- 同步流程结束 ---');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ class CompanyOperators extends Model
|
||||
{
|
||||
protected $table = 'company_operators';
|
||||
|
||||
protected $hidden = ['company_id', 'create_time', 'status'];
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Companys::class, 'company_id', 'id');
|
||||
|
||||
@@ -9,4 +9,20 @@ class Companys extends Model
|
||||
{
|
||||
protected $table = 'companys';
|
||||
|
||||
public function companyoperators()
|
||||
{
|
||||
return $this->hasMany(CompanyOperators::class, 'company_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public static function customDelete($id)
|
||||
{
|
||||
$companyAndOperators = self::with(['companyoperators'])->where('id', $id)->find();
|
||||
if (!$companyAndOperators) {
|
||||
return false;
|
||||
}
|
||||
$companyAndOperators->companyoperators()->delete();
|
||||
$companyAndOperators->delete();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
use app\common\model\CustomerEmployees;
|
||||
|
||||
class Customers extends Model
|
||||
{
|
||||
protected $table = 'customers';
|
||||
|
||||
public function employees()
|
||||
{
|
||||
return $this->hasMany(CustomerEmployees::class, 'customer_id', 'id');
|
||||
}
|
||||
|
||||
/* 模型事件:在删除客户记录之后执行 */
|
||||
public static function onAfterDelete($customer)
|
||||
{
|
||||
// 删除与该客户相关的员工记录
|
||||
$customer->employees()->delete();
|
||||
}
|
||||
|
||||
|
||||
public function getCompanyOfAccount(){
|
||||
return $this->hasMany(User::class,'company_id','id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
use app\common\model\Companys;
|
||||
use app\common\model\Tickets;
|
||||
|
||||
|
||||
|
||||
class User extends Model
|
||||
@@ -13,4 +16,9 @@ class User extends Model
|
||||
return $this->belongsTo(Companys::class,'company_id','id');
|
||||
}
|
||||
|
||||
public function tickets()
|
||||
{
|
||||
return $this->hasMany(Tickets::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace app\common\service;
|
||||
|
||||
use app\common\model\Tickets;
|
||||
use app\common\model\CompanyOperators;
|
||||
use app\common\model\Companys;
|
||||
use app\common\model\User;
|
||||
|
||||
use think\facade\Cache;
|
||||
@@ -26,20 +27,20 @@ class TicketService
|
||||
}
|
||||
|
||||
// 运营人员筛选
|
||||
if (!empty($params['operator_name'])) {
|
||||
$query->where('operator_name', $params['operator_name']);
|
||||
if (!empty($params['operator_id'])) {
|
||||
$query->where('operator_id', $params['operator_id']);
|
||||
}
|
||||
|
||||
// 负责人筛选
|
||||
if (!empty($params['username'])) {
|
||||
$query->where('username', $params['username']);
|
||||
if (!empty($params['user_id'])) {
|
||||
$query->where('user_id', $params['user_id']);
|
||||
}
|
||||
|
||||
// 关键词搜索
|
||||
if (!empty($params['searchKeyword'])) {
|
||||
$query->where(function ($q) use ($params) {
|
||||
$q->where('website', 'like', '%' . $params['searchKeyword'] . '%')
|
||||
->whereOr('operator_name', 'like', '%' . $params['searchKeyword'] . '%');
|
||||
->whereOr('remark', 'like', '%' . $params['searchKeyword'] . '%');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -109,7 +110,6 @@ class TicketService
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 更新工单
|
||||
* @param $id 工单id
|
||||
@@ -170,13 +170,70 @@ class TicketService
|
||||
}
|
||||
|
||||
|
||||
public function TestgetAllOperators()
|
||||
{
|
||||
$operators = Companys::with('companyoperators')->select();
|
||||
return $operators;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取员工列表(下拉筛选用)
|
||||
* 统计各状态工单数量
|
||||
*/
|
||||
public function getTicketDashboardStats()
|
||||
{
|
||||
return [
|
||||
'total' => Tickets::count(),
|
||||
'status_counts' => Tickets::field('status, COUNT(*) as count')
|
||||
->group('status')
|
||||
->select()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新工单(事务内执行)
|
||||
*/
|
||||
public function batchUpdateTickets(array $ids, array $data, array $allowFields, $uid, $isSuper = false)
|
||||
{
|
||||
if (empty($ids)) {
|
||||
throw new \Exception('请选择要更新的工单');
|
||||
}
|
||||
|
||||
$updateData = [];
|
||||
foreach ($allowFields as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$updateData[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($updateData)) {
|
||||
throw new \Exception('没有合法的更新字段');
|
||||
}
|
||||
|
||||
$tickets = Tickets::whereIn('id', $ids)->select();
|
||||
|
||||
if ($tickets->isEmpty()) {
|
||||
throw new \Exception('未找到任何工单');
|
||||
}
|
||||
|
||||
\think\facade\Db::transaction(function () use ($tickets, $updateData, $uid, $isSuper) {
|
||||
foreach ($tickets as $ticket) {
|
||||
if (!$isSuper) {
|
||||
if (!is_null($ticket->user_id) && $ticket->user_id != $uid) {
|
||||
throw new \Exception("工单 #{$ticket->id} 没有权限修改");
|
||||
}
|
||||
}
|
||||
$ticket->save($updateData);
|
||||
}
|
||||
});
|
||||
|
||||
return ['updated_count' => count($tickets)];
|
||||
}
|
||||
|
||||
public function getStaffList()
|
||||
{
|
||||
$map = [
|
||||
'role' => 'user',
|
||||
'role' => ['user', 'admin'],
|
||||
'status' => 1
|
||||
];
|
||||
|
||||
|
||||
24
app/index/controller/ClientTicket.php
Normal file
24
app/index/controller/ClientTicket.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\BaseController;
|
||||
use app\index\service\ClientTicketService;
|
||||
use think\facade\Session;
|
||||
|
||||
class ClientTicket extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取客户关联工单
|
||||
*/
|
||||
public function getClientTickets(ClientTicketService $ClientTicketService)
|
||||
{
|
||||
$clientId = Session::get('user_info.id'); // 获取当前登录客户ID
|
||||
try {
|
||||
$tickets = $ClientTicketService->getClientTickets($clientId);
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => $tickets]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 400, 'msg' => $e->getMessage(), 'data' => null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class Login extends BaseController
|
||||
/*
|
||||
退出登录(已完成)
|
||||
*/
|
||||
protected function logout()
|
||||
public function logout()
|
||||
{
|
||||
Session::clear();
|
||||
return json(['code' => 200, 'message' => '退出成功']);
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?php
|
||||
|
||||
use app\admin\middleware\Auth;
|
||||
use think\facade\Route;
|
||||
|
||||
Route::post('login', 'Login/login'); // 登录
|
||||
Route::post('logout', 'Login/logout'); // 退出登录
|
||||
|
||||
Route::post('api/login', 'Login/login'); // 登录
|
||||
|
||||
Route::group(function () {
|
||||
Route::get('client/tickets', 'ClientTicket/getClientTickets'); // 获取客户关联工单
|
||||
})->middleware(Auth::class);
|
||||
27
app/index/service/ClientTicketService.php
Normal file
27
app/index/service/ClientTicketService.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace app\index\service;
|
||||
|
||||
use app\common\model\User as UserModel;
|
||||
|
||||
|
||||
class ClientTicketService
|
||||
{
|
||||
/* 获取客户关联工单 */
|
||||
public function getClientTickets($clientId)
|
||||
{
|
||||
# 查询当前登录用户所对应的工单
|
||||
|
||||
$tickets = UserModel::with(['tickets'])->find($clientId);
|
||||
|
||||
$newList = [];
|
||||
foreach ($tickets->tickets as $ticket) {
|
||||
if (in_array($ticket->status, [0, 1, 2])) {
|
||||
$ticket->visible(['id', 'website', 'datanum', 'progress', 'status']);
|
||||
$newList[] = $ticket->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
return $newList;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,19 @@ return [
|
||||
// 序列化机制 例如 ['serialize', 'unserialize']
|
||||
'serialize' => [],
|
||||
],
|
||||
// 更多的缓存连接
|
||||
'redis' => [
|
||||
// 驱动方式固定为 redis
|
||||
'type' => 'redis',
|
||||
// 服务器地址 (如果是本地就写 127.0.0.1)
|
||||
'host' => '127.0.0.1',
|
||||
// 端口号,默认 6379
|
||||
'port' => 6379,
|
||||
// 密码,如果没有设置可留空
|
||||
'password' => '',
|
||||
// 缓存前缀,建议设为你的项目简称,防止和其他项目冲突
|
||||
'prefix' => 'tickets_',
|
||||
// 缓存有效期
|
||||
'expire' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -60,4 +60,16 @@ return [
|
||||
|
||||
// 更多的数据库配置信息
|
||||
],
|
||||
// 2. 新增:宝塔远程数据库连接
|
||||
'remote' => [
|
||||
'type' => 'mysql',
|
||||
'hostname' => '127.0.0.1',
|
||||
'database' => '112_5_15_136_255',
|
||||
'username' => '112_5_15_136_255',
|
||||
'password' => 'xz1YX1jswSWzkE4K',
|
||||
'hostport' => '3306',
|
||||
'charset' => 'utf8mb4',
|
||||
'prefix' => '', // 如果有表前缀请填写
|
||||
'break_reconnect' => true, // 远程连接建议开启断线重连
|
||||
],
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user