Accept Merge Request #219: (feature/hant -> develop)
Merge Request: 导出逻辑 Created By: @todayswind Accepted By: @todayswind URL: https://g-bcrc3009.coding.net/p/allocatr/d/allocatr/git/merge/219?initial=true
This commit is contained in:
commit
c0c01284b0
|
|
@ -2,26 +2,13 @@
|
||||||
|
|
||||||
namespace app\admin\command;
|
namespace app\admin\command;
|
||||||
|
|
||||||
use app\admin\addresmart\Address;
|
|
||||||
use app\admin\controller\AutoDispatchLogic;
|
|
||||||
use app\admin\controller\orders\DispatchLogic;
|
|
||||||
use app\admin\controller\SendMailLogic;
|
|
||||||
use app\admin\model\Order;
|
|
||||||
use app\admin\model\OrderDispatch;
|
|
||||||
use app\admin\model\OrderReview;
|
|
||||||
use app\admin\model\Worker;
|
|
||||||
use app\admin\model\WorkerItem;
|
|
||||||
use app\admin\controller\AmapTrait;
|
use app\admin\controller\AmapTrait;
|
||||||
use think\Collection;
|
use app\admin\controller\AutoDispatchLogic;
|
||||||
|
use app\admin\model\Order;
|
||||||
use think\console\Command;
|
use think\console\Command;
|
||||||
use think\console\Input;
|
use think\console\Input;
|
||||||
use think\console\Output;
|
use think\console\Output;
|
||||||
use think\Db;
|
use think\Exception;
|
||||||
use think\exception\DbException;
|
|
||||||
use think\Hook;
|
|
||||||
use think\Lang;
|
|
||||||
use think\Model;
|
|
||||||
use function Symfony\Component\Clock\now;
|
|
||||||
|
|
||||||
class Test extends Command
|
class Test extends Command
|
||||||
{
|
{
|
||||||
|
|
@ -35,8 +22,18 @@ class Test extends Command
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
protected function execute(Input $input, Output $output)
|
||||||
{
|
{
|
||||||
$order = Order::where('id',221)->select()[0];
|
// $order = Order::where('id','>=',694)->select();
|
||||||
AutoDispatchLogic::autoDispatch($order);
|
try {
|
||||||
|
$order = Order::get(5126);
|
||||||
|
AutoDispatchLogic::autoDispatch($order,null,true);
|
||||||
|
}catch (Exception $e){
|
||||||
|
$output->writeln('<error>' . $e->getMessage() . '</error>');
|
||||||
|
$output->writeln('<comment>' . $e->getFile() . ':' . $e->getLine() . '</comment>');
|
||||||
|
$output->writeln($e->getTraceAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
dd(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,16 @@ use app\admin\model\OrderLog;
|
||||||
use app\admin\model\orders\Dispatchlog;
|
use app\admin\model\orders\Dispatchlog;
|
||||||
use app\admin\model\Worker;
|
use app\admin\model\Worker;
|
||||||
use app\admin\model\WorkerItem;
|
use app\admin\model\WorkerItem;
|
||||||
|
use app\common\cache\SimpleFileCache;
|
||||||
|
use app\common\cache\ThinkphpCacheAdapter;
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use app\common\Logic\OrderLogic;
|
use app\common\Logic\OrderLogic;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Carbon\Traits\Creator;
|
use Carbon\Traits\Creator;
|
||||||
use fast\Tree;
|
use fast\Tree;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Settings;
|
||||||
|
use think\Cache;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
use think\exception\DbException;
|
use think\exception\DbException;
|
||||||
|
|
@ -28,6 +33,9 @@ use think\Hook;
|
||||||
use think\Loader;
|
use think\Loader;
|
||||||
use think\Model;
|
use think\Model;
|
||||||
use function Symfony\Component\Clock\now;
|
use function Symfony\Component\Clock\now;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单列管理
|
* 订单列管理
|
||||||
|
|
@ -127,12 +135,11 @@ class Order extends Backend
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
public function index()
|
public function index($getArray = false, $page = 0, $input_limit = 0)
|
||||||
{
|
{
|
||||||
$this->request->filter(['strip_tags', 'trim']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
$group = \model('auth_group_access')->where('uid', $this->auth->id)->find()->group_id ?? 0;
|
$group = \model('auth_group_access')->where('uid', $this->auth->id)->find()->group_id ?? 0;
|
||||||
$user = \model('admin')->find($this->auth->id);
|
$user = \model('admin')->find($this->auth->id);
|
||||||
|
|
||||||
$this->assignconfig('permissions', [
|
$this->assignconfig('permissions', [
|
||||||
'add' => $this->auth->check('order/add'),
|
'add' => $this->auth->check('order/add'),
|
||||||
'edit' => $this->auth->check('order/edit'),
|
'edit' => $this->auth->check('order/edit'),
|
||||||
|
|
@ -149,8 +156,7 @@ class Order extends Backend
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
if (false === $this->request->isAjax()) {
|
if (false === $this->request->isAjax() && $getArray == false) {
|
||||||
|
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
//如果发送的来源是 Selectpage,则转发到 Selectpage
|
//如果发送的来源是 Selectpage,则转发到 Selectpage
|
||||||
|
|
@ -177,8 +183,8 @@ class Order extends Backend
|
||||||
->where($where);
|
->where($where);
|
||||||
$filter = (array)json_decode(input()['filter'] ?? '', true);
|
$filter = (array)json_decode(input()['filter'] ?? '', true);
|
||||||
|
|
||||||
if(isset($filter['audit_time'])){
|
if (isset($filter['audit_time'])) {
|
||||||
$build->where('status',\app\admin\model\Order::STATUS_FINISHED);
|
$build->where('status', \app\admin\model\Order::STATUS_FINISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
$admin_filter = $filter['user.nickname'] ?? false;
|
$admin_filter = $filter['user.nickname'] ?? false;
|
||||||
|
|
@ -199,13 +205,13 @@ class Order extends Backend
|
||||||
$build->whereIn('item_id', $item_ids);
|
$build->whereIn('item_id', $item_ids);
|
||||||
}
|
}
|
||||||
if (!is_null($is_timeout)) {
|
if (!is_null($is_timeout)) {
|
||||||
$build->where('is_overtime',$is_timeout);
|
$build->where('is_overtime', $is_timeout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($group == 2 ) { // 录单员
|
if ($group == 2) { // 录单员
|
||||||
$build->where('admin_id',$user->id);
|
$build->where('admin_id', $user->id);
|
||||||
}elseif ($group == 6){ // 派单员
|
} elseif ($group == 6) { // 派单员
|
||||||
// 生成 SQL 语句
|
// 生成 SQL 语句
|
||||||
$ids = $user->area_ids ?? '';
|
$ids = $user->area_ids ?? '';
|
||||||
if ($ids == '') {
|
if ($ids == '') {
|
||||||
|
|
@ -221,7 +227,7 @@ class Order extends Backend
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$list = $build
|
$build
|
||||||
->with(['user' => function ($q) {
|
->with(['user' => function ($q) {
|
||||||
$q->field('id,nickname');
|
$q->field('id,nickname');
|
||||||
}, 'area' => function ($q) {
|
}, 'area' => function ($q) {
|
||||||
|
|
@ -236,26 +242,32 @@ class Order extends Backend
|
||||||
}
|
}
|
||||||
]]
|
]]
|
||||||
)
|
)
|
||||||
->order($sort, $order)
|
->order($sort, $order);
|
||||||
->paginate($limit);
|
if ($getArray) {
|
||||||
|
$list = $build->paginate([
|
||||||
|
'list_rows' => $input_limit,
|
||||||
|
'page' => $page
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$list = $build->paginate($limit);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($list as $item) {
|
foreach ($list as $item) {
|
||||||
$item->aftersale_btn = false;
|
$item->aftersale_btn = false;
|
||||||
if ($item->aftersale_id == 0 && $this->auth->check('aftersales/aftersale/add') && $item->status == \app\admin\model\Order::STATUS_FINISHED) { //$item->status == \app\admin\model\Order::STATUS_FINISHED &&
|
if ($item->aftersale_id == 0 && $this->auth->check('aftersales/aftersale/add') && $item->status == \app\admin\model\Order::STATUS_FINISHED) { //$item->status == \app\admin\model\Order::STATUS_FINISHED &&
|
||||||
$item->aftersale_btn = true;
|
$item->aftersale_btn = true;
|
||||||
}
|
}
|
||||||
if (isset($item->getRelation('source')->parent->title)){
|
if (isset($item->getRelation('source')->parent->title)) {
|
||||||
$item->source_total_name = '【' . $item->getRelation('source')->parent->title . '】' . ($item->getRelation('source')->title??'');
|
$item->source_total_name = '【' . $item->getRelation('source')->parent->title . '】' . ($item->getRelation('source')->title ?? '');
|
||||||
}else{
|
} else {
|
||||||
$item->source_total_name = ($item->getRelation('source')->title??'');
|
$item->source_total_name = ($item->getRelation('source')->title ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($item->status <60){
|
if ($item->status < 60) {
|
||||||
$item->audit_time = null;
|
$item->audit_time = null;
|
||||||
}
|
}
|
||||||
unset($item->source);
|
unset($item->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +319,7 @@ class Order extends Backend
|
||||||
|
|
||||||
$sources = array_column($sources, null, 'id');
|
$sources = array_column($sources, null, 'id');
|
||||||
|
|
||||||
if (!in_array($sources[$params['source']]['pid'],[3,8])&& empty($params['customer'])){
|
if (!in_array($sources[$params['source']]['pid'], [3, 8]) && empty($params['customer'])) {
|
||||||
$this->error('请输入客户名称');
|
$this->error('请输入客户名称');
|
||||||
}
|
}
|
||||||
$params['source_shop'] = $sources[$params['source']]['title'] ?? null;
|
$params['source_shop'] = $sources[$params['source']]['title'] ?? null;
|
||||||
|
|
@ -328,23 +340,23 @@ class Order extends Backend
|
||||||
$params['order_no'] = $this->generateOrderNumber();
|
$params['order_no'] = $this->generateOrderNumber();
|
||||||
$params['create_time'] = date('Y-m-d H:i:s');
|
$params['create_time'] = date('Y-m-d H:i:s');
|
||||||
$params['update_time'] = date('Y-m-d H:i:s');
|
$params['update_time'] = date('Y-m-d H:i:s');
|
||||||
$params['receive_type'] = $params['receive_type']?: 1;
|
$params['receive_type'] = $params['receive_type'] ?: 1;
|
||||||
$params['audit_time'] = date('Y-m-d H:i:s');
|
$params['audit_time'] = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
$result = $this->model->allowField(true)->save($params);
|
$result = $this->model->allowField(true)->save($params);
|
||||||
$auth = clone $this->auth;
|
$auth = clone $this->auth;
|
||||||
$order = \app\admin\model\Order::where('id',$this->model->id)->with(['source' => [
|
$order = \app\admin\model\Order::where('id', $this->model->id)->with(['source' => [
|
||||||
'parent' => function ($q) {
|
'parent' => function ($q) {
|
||||||
$q->field('id,title');
|
$q->field('id,title');
|
||||||
}
|
}
|
||||||
]]
|
]]
|
||||||
)->find();
|
)->find();
|
||||||
// dd($order);
|
// dd($order);
|
||||||
if (isset($order->getRelation('source')->parent->title)){
|
if (isset($order->getRelation('source')->parent->title)) {
|
||||||
$order->source_total_name = '【' . $order->getRelation('source')->parent->title . '】' .
|
$order->source_total_name = '【' . $order->getRelation('source')->parent->title . '】' .
|
||||||
($order->getRelation('source')->title??'');
|
($order->getRelation('source')->title ?? '');
|
||||||
}else{
|
} else {
|
||||||
$order->source_total_name = ($order->getRelation('source')->title??'');
|
$order->source_total_name = ($order->getRelation('source')->title ?? '');
|
||||||
}
|
}
|
||||||
unset($order->source);
|
unset($order->source);
|
||||||
//日志
|
//日志
|
||||||
|
|
@ -426,11 +438,11 @@ class Order extends Backend
|
||||||
// $params['create_time'] = date('Y-m-d H:i:s');
|
// $params['create_time'] = date('Y-m-d H:i:s');
|
||||||
$params['update_time'] = date('Y-m-d H:i:s');
|
$params['update_time'] = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
$params['receive_type'] = $params['receive_type']?: 1;
|
$params['receive_type'] = $params['receive_type'] ?: 1;
|
||||||
|
|
||||||
if($order->receive_type != $params['receive_type']){
|
if ($order->receive_type != $params['receive_type']) {
|
||||||
//修改派单表
|
//修改派单表
|
||||||
OrderDispatch::where('order_id',$order->id)->whereBetween('status',[0,30])->update(['is_receipt' => $params['receive_type']== 1? 1:0]);
|
OrderDispatch::where('order_id', $order->id)->whereBetween('status', [0, 30])->update(['is_receipt' => $params['receive_type'] == 1 ? 1 : 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新订单信息
|
// 更新订单信息
|
||||||
|
|
@ -571,11 +583,11 @@ class Order extends Backend
|
||||||
|
|
||||||
$dispatch_admin = AuthGroupAccess::where('group_id', 6)
|
$dispatch_admin = AuthGroupAccess::where('group_id', 6)
|
||||||
->column('uid');
|
->column('uid');
|
||||||
$res = array_values(array_intersect($res,$dispatch_admin));
|
$res = array_values(array_intersect($res, $dispatch_admin));
|
||||||
|
|
||||||
$message = $params['detail'] ?? '';
|
$message = $params['detail'] ?? '';
|
||||||
$abnormals = model('abnormal')->where('type', 3)
|
$abnormals = model('abnormal')->where('type', 3)
|
||||||
->where('id',$params['abnormal_id'])->find();
|
->where('id', $params['abnormal_id'])->find();
|
||||||
|
|
||||||
$insert = [];
|
$insert = [];
|
||||||
foreach ($res as $re) {
|
foreach ($res as $re) {
|
||||||
|
|
@ -583,7 +595,7 @@ class Order extends Backend
|
||||||
'to_id' => $re,
|
'to_id' => $re,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
'title' => '订单内容变更',
|
'title' => '订单内容变更',
|
||||||
'content' => '【订单内容变更】您有一条订单'.$order->order_no.'信息被修改,异常类型【'.$abnormals->title.'】,备注:【' . $message . '】,请注意查收。'
|
'content' => '【订单内容变更】您有一条订单' . $order->order_no . '信息被修改,异常类型【' . $abnormals->title . '】,备注:【' . $message . '】,请注意查收。'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$build = new Message();
|
$build = new Message();
|
||||||
|
|
@ -630,7 +642,7 @@ class Order extends Backend
|
||||||
'update_time' => now()->format('Y-m-d H:m:s'),
|
'update_time' => now()->format('Y-m-d H:m:s'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$orderDispatch = OrderDispatch::where('order_id',$order->id)->whereBetween('status','>=',0)->find();
|
$orderDispatch = OrderDispatch::where('order_id', $order->id)->whereBetween('status', '>=', 0)->find();
|
||||||
|
|
||||||
if ($params['abnormal_id'] == 2 || $params['abnormal_id'] == 3) {
|
if ($params['abnormal_id'] == 2 || $params['abnormal_id'] == 3) {
|
||||||
|
|
||||||
|
|
@ -732,7 +744,7 @@ class Order extends Backend
|
||||||
|
|
||||||
$result = $order->allowField(true)->save($params);
|
$result = $order->allowField(true)->save($params);
|
||||||
|
|
||||||
$dispatch = OrderDispatch::where('order_id', $order->id)->where('status','>=',0)->find();
|
$dispatch = OrderDispatch::where('order_id', $order->id)->where('status', '>=', 0)->find();
|
||||||
if (!empty($dispatch)) {
|
if (!empty($dispatch)) {
|
||||||
$orderLogic = new OrderLogic();
|
$orderLogic = new OrderLogic();
|
||||||
$orderLogic->cancelOrderDispatch($dispatch, $this->auth, '订单被取消', false);
|
$orderLogic->cancelOrderDispatch($dispatch, $this->auth, '订单被取消', false);
|
||||||
|
|
@ -1087,4 +1099,48 @@ class Order extends Backend
|
||||||
return json($result);
|
return json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function export()
|
||||||
|
{
|
||||||
|
// 表头结构(可从参数获取或手动定义)
|
||||||
|
$columns = json_decode($this->request->get('columns', ''), true);
|
||||||
|
// dd($columns);
|
||||||
|
if (!$columns) {
|
||||||
|
// 用第一页数据自动生成字段
|
||||||
|
$sample = $this->index(true, 1, 1)->getData();
|
||||||
|
if (!isset($sample['rows'][0])) {
|
||||||
|
return json(['code' => 0, 'msg' => '无数据可导出']);
|
||||||
|
}
|
||||||
|
$columns = [];
|
||||||
|
foreach ($sample['rows'][0] as $key => $value) {
|
||||||
|
$columns[] = ['field' => $key, 'title' => $key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数据获取函数:分页获取数据(支持返回 array)
|
||||||
|
$fetchData = function ($page, $limit) {
|
||||||
|
$result = $this->index(true, $page, $limit);
|
||||||
|
$order = new \app\admin\model\Order();
|
||||||
|
foreach ($result->getData()['rows'] as $item){
|
||||||
|
$item->status = $order->getStatusList()[$item->status] ?? '';
|
||||||
|
$item->dispatch_type = $item->dispatch_type == 1 ? '手动派单' : '自动派单';
|
||||||
|
$item->is_overtime = $item->is_overtime ? '超时' : '未超时';
|
||||||
|
$item->receive_type = $item->receive_type == 1 ? '已收定金' : '已收全款';
|
||||||
|
$images = explode(',',$item->images ?? '');
|
||||||
|
$url = '';
|
||||||
|
if ($images){
|
||||||
|
foreach ($images as $img){
|
||||||
|
if($img == '')continue;
|
||||||
|
$url .= cdnurl($img) . ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$item->images = $url;
|
||||||
|
}
|
||||||
|
return $result->getData()['rows'] ?? [];
|
||||||
|
};
|
||||||
|
|
||||||
|
$this->exportExcelByStream($columns, $fetchData, '订单导出_' . date('Ymd_His') . '.xlsx');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@
|
||||||
<div id="toolbar" class="toolbar">
|
<div id="toolbar" class="toolbar">
|
||||||
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
|
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
|
||||||
<a href="javascript:;" class="btn btn-success btn-edit {:$auth->check('order/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-edit"></i> {:__('Edit')}</a>
|
<a href="javascript:;" class="btn btn-success btn-edit {:$auth->check('order/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-edit"></i> {:__('Edit')}</a>
|
||||||
|
<a href="javascript:;" class="btn btn-success btn-export" id="btn-export">
|
||||||
|
<i class="fa fa-download"></i> 导出
|
||||||
|
</a>
|
||||||
<!-- <div class="dropdown btn-group {:$auth->check('order/multi')?'':'hide'}">-->
|
<!-- <div class="dropdown btn-group {:$auth->check('order/multi')?'':'hide'}">-->
|
||||||
<!-- <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>-->
|
<!-- <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>-->
|
||||||
<!-- <ul class="dropdown-menu text-left" role="menu">-->
|
<!-- <ul class="dropdown-menu text-left" role="menu">-->
|
||||||
|
|
|
||||||
109
application/common/cache/SimpleFileCache.php
vendored
Normal file
109
application/common/cache/SimpleFileCache.php
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
namespace app\common\cache;
|
||||||
|
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
|
class SimpleFileCache implements CacheInterface
|
||||||
|
{
|
||||||
|
protected $path;
|
||||||
|
protected $prefix;
|
||||||
|
|
||||||
|
public function __construct($path = null, $prefix = 'spreadsheet_')
|
||||||
|
{
|
||||||
|
$this->path = $path ?? CACHE_PATH;
|
||||||
|
$this->prefix = $prefix;
|
||||||
|
|
||||||
|
if (!is_dir($this->path)) {
|
||||||
|
mkdir($this->path, 0777, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFilePath(string $key): string
|
||||||
|
{
|
||||||
|
return $this->path . DIRECTORY_SEPARATOR . $this->prefix . md5($key) . '.cache';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get($key, $default = null): mixed
|
||||||
|
{
|
||||||
|
$file = $this->getFilePath($key);
|
||||||
|
if (!file_exists($file)) {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
$content = file_get_contents($file);
|
||||||
|
$data = unserialize($content);
|
||||||
|
if ($data['expire'] !== 0 && $data['expire'] < time()) {
|
||||||
|
@unlink($file);
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
return $data['value'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($key, $value, $ttl = null): bool
|
||||||
|
{
|
||||||
|
$file = $this->getFilePath($key);
|
||||||
|
$expire = $ttl instanceof \DateInterval ? (new \DateTime())->add($ttl)->getTimestamp() : ($ttl ? time() + $ttl : 0);
|
||||||
|
$data = [
|
||||||
|
'expire' => $expire,
|
||||||
|
'value' => $value,
|
||||||
|
];
|
||||||
|
return file_put_contents($file, serialize($data)) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($key): bool
|
||||||
|
{
|
||||||
|
$file = $this->getFilePath($key);
|
||||||
|
return file_exists($file) ? unlink($file) : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clear(): bool
|
||||||
|
{
|
||||||
|
$files = glob($this->path . '/' . $this->prefix . '*.cache');
|
||||||
|
foreach ($files as $file) {
|
||||||
|
unlink($file);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMultiple($keys, $default = null): iterable
|
||||||
|
{
|
||||||
|
$results = [];
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$results[$key] = $this->get($key, $default);
|
||||||
|
}
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMultiple($values, $ttl = null): bool
|
||||||
|
{
|
||||||
|
$success = true;
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
if (!$this->set($key, $value, $ttl)) {
|
||||||
|
$success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteMultiple($keys): bool
|
||||||
|
{
|
||||||
|
$success = true;
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (!$this->delete($key)) {
|
||||||
|
$success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function has($key): bool
|
||||||
|
{
|
||||||
|
$file = $this->getFilePath($key);
|
||||||
|
if (!file_exists($file)) return false;
|
||||||
|
$data = unserialize(file_get_contents($file));
|
||||||
|
if ($data['expire'] !== 0 && $data['expire'] < time()) {
|
||||||
|
@unlink($file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
74
application/common/cache/ThinkphpCacheAdapter.php
vendored
Normal file
74
application/common/cache/ThinkphpCacheAdapter.php
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
namespace app\common\cache;
|
||||||
|
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
|
class ThinkphpCacheAdapter implements CacheInterface
|
||||||
|
{
|
||||||
|
protected $cache;
|
||||||
|
|
||||||
|
public function __construct($cache)
|
||||||
|
{
|
||||||
|
$this->cache = $cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get($key, $default = null): mixed
|
||||||
|
{
|
||||||
|
$value = $this->cache->get($key);
|
||||||
|
return $value === false ? $default : $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($key, $value, $ttl = null): bool
|
||||||
|
{
|
||||||
|
if ($ttl === null) {
|
||||||
|
return $this->cache->set($key, $value);
|
||||||
|
}
|
||||||
|
return $this->cache->set($key, $value, $ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($key): bool
|
||||||
|
{
|
||||||
|
return $this->cache->delete($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clear(): bool
|
||||||
|
{
|
||||||
|
return $this->cache->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMultiple($keys, $default = null): iterable
|
||||||
|
{
|
||||||
|
$results = [];
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$results[$key] = $this->get($key, $default);
|
||||||
|
}
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMultiple($values, $ttl = null): bool
|
||||||
|
{
|
||||||
|
$success = true;
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
if (!$this->set($key, $value, $ttl)) {
|
||||||
|
$success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteMultiple($keys): bool
|
||||||
|
{
|
||||||
|
$success = true;
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (!$this->delete($key)) {
|
||||||
|
$success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function has($key): bool
|
||||||
|
{
|
||||||
|
return $this->cache->has($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,9 @@
|
||||||
namespace app\common\controller;
|
namespace app\common\controller;
|
||||||
|
|
||||||
use app\admin\library\Auth;
|
use app\admin\library\Auth;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
use think\Config;
|
use think\Config;
|
||||||
use think\Controller;
|
use think\Controller;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
|
|
@ -762,4 +765,78 @@ class Backend extends Controller
|
||||||
}
|
}
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function exportExcelByStream(array $columns, callable $fetchData, string $filename = '导出.xlsx', int $limit = 1000)
|
||||||
|
{
|
||||||
|
$page = 1;
|
||||||
|
$rowIndex = 2;
|
||||||
|
|
||||||
|
// 创建 Spreadsheet 和 Sheet
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$spreadsheet->removeSheetByIndex(0);
|
||||||
|
$sheet = new Worksheet($spreadsheet, 'Sheet1');
|
||||||
|
$spreadsheet->addSheet($sheet);
|
||||||
|
$spreadsheet->setActiveSheetIndex(0);
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
|
||||||
|
$writer = new Xlsx($spreadsheet);
|
||||||
|
$writer->setPreCalculateFormulas(false);
|
||||||
|
|
||||||
|
// 获取字段映射
|
||||||
|
$titles = array_column($columns, 'title');
|
||||||
|
$fields = array_column($columns, 'field');
|
||||||
|
|
||||||
|
// 写入表头
|
||||||
|
$sheet->fromArray($titles, null, 'A1');
|
||||||
|
|
||||||
|
// 分页写入数据
|
||||||
|
do {
|
||||||
|
$rows = $fetchData($page, $limit);
|
||||||
|
$count = count($rows);
|
||||||
|
if ($count === 0) break;
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$dataRow = [];
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$value = $this->getNestedValue($row->toArray(), $field);
|
||||||
|
if (is_array($value) || is_object($value)) {
|
||||||
|
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
$dataRow[] = $value;
|
||||||
|
}
|
||||||
|
$sheet->fromArray($dataRow, null, 'A' . $rowIndex);
|
||||||
|
$rowIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page++;
|
||||||
|
} while ($count === $limit);
|
||||||
|
|
||||||
|
// 输出为下载流
|
||||||
|
$filename = $filename ?: ('导出_' . date('Ymd_His') . '.xlsx');
|
||||||
|
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||||
|
header('Content-Disposition: attachment;filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: max-age=0');
|
||||||
|
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
|
||||||
|
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||||
|
header('Pragma: public');
|
||||||
|
|
||||||
|
$writer->save('php://output');
|
||||||
|
$spreadsheet->disconnectWorksheets();
|
||||||
|
unset($spreadsheet);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
protected function getNestedValue(array $data, string $path, $default = '')
|
||||||
|
{
|
||||||
|
$segments = explode('.', $path);
|
||||||
|
foreach ($segments as $segment) {
|
||||||
|
if (is_array($data) && array_key_exists($segment, $data)) {
|
||||||
|
$data = $data[$segment];
|
||||||
|
} elseif (is_object($data) && isset($data->{$segment})) {
|
||||||
|
$data = $data->{$segment};
|
||||||
|
} else {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ ${data.receive_type == 1 ? '已收定金' : '已收全款'}
|
||||||
renderDefault: true,
|
renderDefault: true,
|
||||||
searchFormVisible: true,
|
searchFormVisible: true,
|
||||||
search: false,
|
search: false,
|
||||||
|
showExport: false,
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{checkbox: true},
|
{checkbox: true},
|
||||||
|
|
@ -531,6 +532,32 @@ ${data.receive_type == 1 ? '已收定金' : '已收全款'}
|
||||||
clickParent: true
|
clickParent: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#btn-export').on('click', function () {
|
||||||
|
var options = $("#table").bootstrapTable('getOptions');
|
||||||
|
|
||||||
|
// 提取列信息(不含 checkbox)
|
||||||
|
var columns = [];
|
||||||
|
$.each(options.columns[0], function (i, item) {
|
||||||
|
if (item.field && !item.checkbox && !item.visible === false) {
|
||||||
|
columns.push({
|
||||||
|
field: item.field,
|
||||||
|
title: item.title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
columns: JSON.stringify(columns),
|
||||||
|
filter: options.queryParams({}).filter || {},
|
||||||
|
op: options.queryParams({}).op || {},
|
||||||
|
sort: options.sortName,
|
||||||
|
order: options.sortOrder
|
||||||
|
};
|
||||||
|
// console.log($.param(params))
|
||||||
|
var url = '/admin/order/export?' + $.param(params);
|
||||||
|
window.open(url); // 发起文件下载
|
||||||
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
add: function () {
|
add: function () {
|
||||||
$("#mybuttom").on("click", function () {
|
$("#mybuttom").on("click", function () {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user