Files

586 lines
25 KiB
PHP

<?php
namespace app\admin\controller\order;
use app\common\controller\Backend;
use think\Db;
/**
* 订单
*
* @icon fa fa-circle-o
*/
class Order extends Backend
{
/**
* Order模型对象
* @var \app\admin\model\order\Order
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\order\Order;
$this->courseModel = new \app\admin\model\course\Course;
}
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
$itemName = input('item_name','');
//如果发送的来源是Selectpage,则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$model = $this->model->where($where);
if($itemName){
$model = $model->where(function ($query) use ($itemName) {
$query->where(function ($query) use ($itemName) {
$query->whereExists(function ($query) use ($itemName) {
$itemTableName = (new \app\admin\model\order\Item())->getQuery()->getTable();
$query->table($itemTableName)->where($itemTableName . '.order_no=order.order_no')
->where('item_name', 'like', "%{$itemName}%");
});
});
});
}
$list = $model
->with(['user','item','item.detail'])
->order($sort, $order)
->paginate($limit);
$rows = $list->toArray();
if(!empty($rows['data'])){
foreach ($rows['data'] as &$item){
$item['source'] = strtolower($item['source']);
foreach ($item['item'] as &$goods){
$goods['detail'] = json_decode($goods['snapshoot'],true);
// if($item['order_type'] == 'vipcard'){
// $goods['detail'] = json_decode($goods['snapshoot'],true);
// }else{
// $goods['detail'] = $this->courseModel->structrue($goods['detail'],'decode');
// }
}
}
}
$result = array("total" => $rows['total'], "rows" => $rows['data']);
return $this->success("获取成功",$result);
}
/**
* 获取详情
* @param $id
* @return mixed
*/
public function detail($orderNo = null){
if($orderNo==null){
$orderNo = input('order_no');
}
$row = $this->model
->with(['log','user','item','item.detail'])
->where([
'order_no'=>$orderNo
])
->find();
$row->getRelation('user')->visible(\app\admin\model\User::$listShowField);
if (!$row) {
$this->error(__('No Results were found'));
}
$row = $row->toArray();
$row['log'] = array_reverse($row['log']);
foreach ($row['item'] as $key => $goods){
$row['item'][$key]['detail'] = json_decode($goods['snapshoot'],true);
// if($row['order_type'] == 'vipcard' || $row['order_type'] == 'exercises'){
// $row['item'][$key]['detail'] = json_decode($goods['snapshoot'],true);
// }else{
// $row['item'][$key]['detail'] = $this->courseModel->structrue($goods['detail'],'decode');
// }
// $row->getRelation('user')->visible(\app\admin\model\User::$listShowField);
}
$row['source'] = strtolower($row['source']);
if($row['source'] == 'channels' && \app\common\library\Platform::getSystemType() == 'single' && \app\admin\library\project\App::isInstall('channels')){
//获取视频号订单信息
$row['channels'] = (new \app\admin\model\app\channels\Order())->getOrderDetail($orderNo);
}
// 实物商品获取收货信息和物流信息
if($row['order_type'] == 'physical'){
// 收货信息
$row['address'] = \app\common\model\app\physical\OrderAddress::getByOrderId($row['id']);
// 物流信息
$expressModel = \app\common\model\app\physical\OrderExpress::where([
'order_id' => $row['id'],
'uniacid' => UNIACID
])->find();
if($expressModel){
// 更新物流信息(5分钟缓存)
$this->updateExpressInfo($expressModel);
// 重新获取物流信息
$expressModel = \app\common\model\app\physical\OrderExpress::where([
'order_id' => $row['id'],
'uniacid' => UNIACID
])->find();
$row['express'] = $expressModel->toArray();
// 获取物流轨迹
$row['express']['logs'] = $expressModel->getLogs();
}
}
return $this->success("获取成功",$row);
}
/**
* 编辑
*
* @param $ids
* @return string
* @throws DbException
* @throws \think\Exception
*/
public function edit($orderNo = null)
{
if($orderNo==null){
$orderNo = input('order_no');
}
$row = $this->model
->where([
'order_no'=>$orderNo
])
->find();
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
$params = $this->preExcludeFields($params);
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validateFailException()->validate($validate);
}
$result = $row->allowField(true)->save($params);
Db::commit();
} catch (ValidateException|PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if (false === $result) {
$this->error(__('No rows were updated'));
}
$this->success("提交成功");
}
/**
* 获取辅助参数
* @return mixed
*/
public function getAttr(){
$attr = [];
$attr["payTypeList"] = $this->model->getPayTypeList();
$attr["sourceList"] = $this->model->getSourceList();
$attr["sendTypeList"] = $this->model->getSendTypeList();
$attr["statusList"] = $this->model->getStatusList();
$attr["typeList"] = $this->model->getTypeList();
$attr["virtualPayList"] = $this->model->getVirtualPayList();
return $this->success("获取成功",$attr);
}
/**
* 关闭订单
* @return void
*/
public function closeOrder($ids){
$ids = $ids ?: $this->request->post("ids");
if (empty($ids)) {
$this->error(__('Parameter %s can not be empty', 'ids'));
}
$pk = $this->model->getPk();
$list = $this->model->where($pk, 'in', $ids)->select();
$count = 0;
Db::startTrans();
try {
foreach ($list as $item) {
if($item['status'] == \app\common\constant\order\Status::STATUS_CLOSE){
continue;
}
$this->model->where([
'id'=>$item['id']
])->update([
'status'=>\app\common\constant\order\Status::STATUS_CLOSE
]);
$orderNo = $item['order_no'];
//作废分佣金记录
\think\Hook::exec('app\\common\\behavior\\app\\agent\\Commission','cancelOrder',$orderNo);
\app\common\model\order\Log::set($item['id'],"管理员关闭订单");
$count++;
}
Db::commit();
} catch (PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($count) {
$this->success("已成功变更{$count}条数据");
}
$this->error(__('未变更任何数据'));
}
protected $exportIndex = 0;
/**
* 导出订单
* @return void
*/
public function export(){
set_time_limit(0);
ini_set('memory_limit', '512M');
$this->relationSearch = true;
$this->request->filter(['strip_tags', 'trim']);
$itemName = input('item_name','');
list($where, $sort, $order, $offset, $limit, $page, $alias, $bind, $originWhere) = $this->buildparams();
$excelTitle = '订单列表【'.date('Y-m-d H:i',time()).'】';
$objPHPExcel = new \PHPExcel();
$objPHPExcel->getProperties()
->setTitle($excelTitle);
$objPHPExcel->getActiveSheet()->setCellValue('A1', '订单号');
$objPHPExcel->getActiveSheet()->setCellValue('B1', '商品名称');
$objPHPExcel->getActiveSheet()->setCellValue('C1', '单价');
$objPHPExcel->getActiveSheet()->setCellValue('D1', '数量');
$objPHPExcel->getActiveSheet()->setCellValue('E1', '实收金额');
$objPHPExcel->getActiveSheet()->setCellValue('F1', '状态');
$objPHPExcel->getActiveSheet()->setCellValue('G1', '用户名');
$objPHPExcel->getActiveSheet()->setCellValue('H1', '手机号');
$objPHPExcel->getActiveSheet()->setCellValue('I1', '订单类型');
$objPHPExcel->getActiveSheet()->setCellValue('J1', '来源');
$objPHPExcel->getActiveSheet()->setCellValue('K1', '评级');
$objPHPExcel->getActiveSheet()->setCellValue('L1', '买家留言');
$objPHPExcel->getActiveSheet()->setCellValue('M1', '商家备注');
$objPHPExcel->getActiveSheet()->setCellValue('N1', '收货人');
$objPHPExcel->getActiveSheet()->setCellValue('O1', '收货手机');
$objPHPExcel->getActiveSheet()->setCellValue('P1', '收货地址');
$objPHPExcel->getActiveSheet()->setCellValue('Q1', '快递公司');
$objPHPExcel->getActiveSheet()->setCellValue('R1', '快递单号');
$objPHPExcel->getActiveSheet()->setCellValue('S1', '视频号信息');
$objPHPExcel->getActiveSheet()->setCellValue('T1', '下单时间');
$objPHPExcel->getActiveSheet()->setCellValue('U1', '付款时间');
$statusList = $this->model->getStatusList();
$typeList = $this->model->getTypeList();
$sourceList = $this->model->getSourceList();
$isChannelsInstalled = \app\admin\library\project\App::isInstall('channels');
$systemType = \app\common\library\Platform::getSystemType();
$orderWhere = [];
$userWhere = [];
if(!empty($originWhere)){
foreach ($originWhere as $w) {
if(is_array($w) && isset($w[0])){
$field = $w[0];
if(strpos($field, 'user.') === 0){
$userField = substr($field, 5);
$userWhere[] = [$userField, $w[1], $w[2]];
}else{
$orderWhere[] = $w;
}
}else{
$orderWhere[] = $w;
}
}
}
if(!empty($userWhere)){
$userQuery = \app\admin\model\User::where(function($query) use ($userWhere) {
foreach ($userWhere as $w) {
if(is_array($w)){
call_user_func_array([$query, 'where'], $w);
}
}
});
$userIds = $userQuery->column('id');
if(empty($userIds)){
$userIds = [0];
}
$orderWhere[] = ['user_id', 'in', $userIds];
}
$query = $this->model->where(function($query) use ($orderWhere) {
foreach ($orderWhere as $w) {
if(is_array($w)){
call_user_func_array([$query, 'where'], $w);
}
}
});
if($itemName){
$query = $query->where(function ($query) use ($itemName) {
$query->where(function ($query) use ($itemName) {
$query->whereExists(function ($query) use ($itemName) {
$itemTableName = (new \app\admin\model\order\Item())->getQuery()->getTable();
$query->table($itemTableName)->where($itemTableName . '.order_no=order.order_no')
->where('item_name', 'like', "%{$itemName}%");
});
});
});
}
$query->chunk(100, function($list) use ($objPHPExcel, $statusList, $typeList, $sourceList, $isChannelsInstalled, $systemType) {
if(!$list) return;
$userIds = [];
$orderNos = [];
$orderIds = [];
$physicalOrderIds = [];
$channelsOrderNos = [];
foreach ($list as $item) {
$userIds[] = $item['user_id'];
$orderNos[] = $item['order_no'];
$orderIds[] = $item['id'];
if($item['order_type'] == 'physical'){
$physicalOrderIds[] = $item['id'];
}
if(strtolower($item['source']) == 'channels'){
$channelsOrderNos[] = $item['order_no'];
}
}
$userIds = array_unique($userIds);
$userList = \app\admin\model\User::where('id', 'in', $userIds)->field('id,username,mobile')->select();
$userMap = [];
foreach ($userList as $u) {
$userMap[$u['id']] = $u;
}
$itemList = \app\admin\model\order\Item::where('order_no', 'in', $orderNos)->select();
$itemMap = [];
foreach ($itemList as $goods) {
$detail = json_decode($goods['snapshoot'], true);
$goods['detail_name'] = $detail['name'] ?? $goods['item_name'] ?? '-';
$itemMap[$goods['order_no']][] = $goods;
}
$addressMap = [];
if(!empty($physicalOrderIds)){
$addressList = \app\common\model\app\physical\OrderAddress::where('order_id', 'in', $physicalOrderIds)->select();
foreach ($addressList as $addr) {
$addressMap[$addr['order_id']] = $addr;
}
}
$expressMap = [];
if(!empty($physicalOrderIds)){
$expressList = \app\common\model\app\physical\OrderExpress::where('order_id', 'in', $physicalOrderIds)->select();
foreach ($expressList as $exp) {
$expressMap[$exp['order_id']] = $exp;
}
}
$channelsMap = [];
$storeMap = [];
if(!empty($channelsOrderNos) && $isChannelsInstalled && $systemType == 'single'){
$channelsList = \app\admin\model\app\channels\Order::where('order_id', 'in', $channelsOrderNos)->with(['member','store'])->select();
if($channelsList){
if(is_array($channelsList) === false){
$channelsList = $channelsList->toArray();
}
foreach ($channelsList as $ch) {
$channelsMap[$ch['order_id']] = $ch;
if(isset($ch['store_id']) && $ch['store_id'] && !isset($storeMap[$ch['store_id']])){
$storeMap[$ch['store_id']] = $ch['store'] ?? null;
}
}
}
}
foreach ($list as $item){
$itemNames = [];
$unitPrices = [];
$counts = [];
if(!empty($itemMap[$item['order_no']])){
foreach ($itemMap[$item['order_no']] as $goods){
$itemNames[] = $goods['detail_name'];
$unitPrices[] = $goods['unit_price'];
$counts[] = $goods['count'];
}
}
$userInfo = isset($userMap[$item['user_id']]) ? $userMap[$item['user_id']] : null;
$consignee = '-';
$consigneeMobile = '-';
$consigneeAddress = '-';
$expressName = '-';
$expressNo = '-';
if($item['order_type'] == 'physical'){
if(isset($addressMap[$item['id']])){
$addr = $addressMap[$item['id']];
$consignee = $addr['consignee'] ?: '-';
$consigneeMobile = $addr['mobile'] ?: '-';
$consigneeAddress = ($addr['province_name'] ?? '') . ($addr['city_name'] ?? '') . ($addr['district_name'] ?? '') . ($addr['address'] ?? '');
if(!$consigneeAddress) $consigneeAddress = '-';
}
if(isset($expressMap[$item['id']])){
$exp = $expressMap[$item['id']];
$expressName = $exp['express_name'] ?: '-';
$expressNo = $exp['express_no'] ?: '-';
}
}
$channelsInfo = '-';
if(strtolower($item['source']) == 'channels' && isset($channelsMap[$item['order_no']])){
$ch = $channelsMap[$item['order_no']];
$parts = [];
if(!empty($ch['mobile'])){
$parts[] = '联系电话:' . $ch['mobile'];
}
$orderSceneList = (new \app\admin\model\app\channels\Order())->getOrderScene();
if(isset($ch['order_scene']) && isset($orderSceneList[$ch['order_scene']])){
$parts[] = '下单场景:' . $orderSceneList[$ch['order_scene']];
}
if(isset($storeMap[$ch['store_id']]) && $storeMap[$ch['store_id']]){
$parts[] = '所属店铺:' . ($storeMap[$ch['store_id']]['nickname'] ?? $storeMap[$ch['store_id']]['username'] ?? '-');
}
$channelsInfo = !empty($parts) ? implode("\t", $parts) : '-';
}
$objPHPExcel->getActiveSheet()->setCellValue('A'.(2 + $this->exportIndex), $item['order_no']);
$objPHPExcel->getActiveSheet()->setCellValue('B'.(2 + $this->exportIndex), implode("\n", $itemNames));
$objPHPExcel->getActiveSheet()->setCellValue('C'.(2 + $this->exportIndex), implode("\n", $unitPrices));
$objPHPExcel->getActiveSheet()->setCellValue('D'.(2 + $this->exportIndex), implode("\n", $counts));
$objPHPExcel->getActiveSheet()->setCellValue('E'.(2 + $this->exportIndex), $item['real_price']);
$objPHPExcel->getActiveSheet()->setCellValue('F'.(2 + $this->exportIndex), isset($statusList[$item['status']]) ? $statusList[$item['status']] : $item['status']);
$objPHPExcel->getActiveSheet()->setCellValue('G'.(2 + $this->exportIndex), $userInfo ? $userInfo['username'] : '-');
$objPHPExcel->getActiveSheet()->setCellValue('H'.(2 + $this->exportIndex), $userInfo ? $userInfo['mobile'] : '-');
$objPHPExcel->getActiveSheet()->setCellValue('I'.(2 + $this->exportIndex), isset($typeList[$item['order_type']]) ? $typeList[$item['order_type']] : $item['order_type']);
$objPHPExcel->getActiveSheet()->setCellValue('J'.(2 + $this->exportIndex), isset($sourceList[$item['source']]) ? $sourceList[$item['source']] : $item['source']);
$objPHPExcel->getActiveSheet()->setCellValue('K'.(2 + $this->exportIndex), $item['star'] ?: '-');
$objPHPExcel->getActiveSheet()->setCellValue('L'.(2 + $this->exportIndex), $item['buyer_remark'] ?: '-');
$objPHPExcel->getActiveSheet()->setCellValue('M'.(2 + $this->exportIndex), $item['merch_remark'] ?: '-');
$objPHPExcel->getActiveSheet()->setCellValue('N'.(2 + $this->exportIndex), $consignee);
$objPHPExcel->getActiveSheet()->setCellValue('O'.(2 + $this->exportIndex), $consigneeMobile);
$objPHPExcel->getActiveSheet()->setCellValue('P'.(2 + $this->exportIndex), $consigneeAddress);
$objPHPExcel->getActiveSheet()->setCellValue('Q'.(2 + $this->exportIndex), $expressName);
$objPHPExcel->getActiveSheet()->setCellValueExplicit('R'.(2 + $this->exportIndex), $expressNo, \PHPExcel_Cell_DataType::TYPE_STRING);
$objPHPExcel->getActiveSheet()->setCellValue('S'.(2 + $this->exportIndex), $channelsInfo);
$objPHPExcel->getActiveSheet()->setCellValue('T'.(2 + $this->exportIndex), $item['createtime'] ? date('Y-m-d H:i:s', $item['createtime']) : '-');
$objPHPExcel->getActiveSheet()->setCellValue('U'.(2 + $this->exportIndex), $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '-');
$this->exportIndex++;
}
});
$objPHPExcel->getActiveSheet()->getStyle('A1:U1')->getFont()->setBold(true)->getColor()->setARGB(\PHPExcel_Style_Color::COLOR_BLACK);
$objPHPExcel->getActiveSheet()->getStyle('A1:U1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getActiveSheet()->getStyle('A1:U1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('D9FFC125');
$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(22);
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30);
$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(10);
$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(8);
$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12);
$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12);
$objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(15);
$objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(15);
$objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12);
$objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(10);
$objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(8);
$objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(20);
$objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(20);
$objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(12);
$objPHPExcel->getActiveSheet()->getColumnDimension('O')->setWidth(15);
$objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(30);
$objPHPExcel->getActiveSheet()->getColumnDimension('Q')->setWidth(15);
$objPHPExcel->getActiveSheet()->getColumnDimension('R')->setWidth(20);
$objPHPExcel->getActiveSheet()->getColumnDimension('S')->setWidth(30);
$objPHPExcel->getActiveSheet()->getColumnDimension('T')->setWidth(18);
$objPHPExcel->getActiveSheet()->getColumnDimension('U')->setWidth(18);
$objPHPExcel->setActiveSheetIndex(0);
ob_end_clean();
header('pragma:public');
header("Content-Disposition:attachment;filename={$excelTitle}.xlsx");
header('Cache-Control: max-age=0');
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
exit;
}
/**
* 更新物流信息
*
* @param \think\Model $expressModel 发货单模型
* @return void
*/
private function updateExpressInfo($expressModel)
{
try {
// 获取阿里云配置
$aliyunConfig = [
'appcode' => 'd6beec8b9be945bfa3c07b9c712f6bce',
'appkey' => '203944259',
'appsecret' => 'R8rx9QLNZlRKxHtvgjBlocFI8f0hq12J'
];
$expressLib = new \app\common\library\app\physical\express\Express('aliyun', $aliyunConfig);
$expressLib->updateExpress($expressModel);
} catch (\Exception $e) {
\think\Log::error('updateExpressInfo.Exception: ' . $e->getMessage());
}
}
}