Files
orico-official-website-old/app/admin/controller/ProductPurchaseLinks.php
2024-10-29 14:04:59 +08:00

322 lines
12 KiB
PHP
Executable File

<?php
namespace app\admin\controller;
use PHPExcel;
use think\Db;
use think\Loader;
use think\Validate;
Loader::import('phpexcel.Classes.PHPExcel', EXTEND_PATH);
Loader::import('phpexcel.Classes.PHPExcel.IOFactory.PHPExcel_IOFactory');
class ProductPurchaseLinks extends BaseController
{
/**
* 列表
*/
public function index()
{
$list = Db::name('product_purchase_links')->alias('links')
->field([
'links.id',
'links.product_id',
'product.name',
'product.brand_id' => 'spu',
'links.platform_id',
'links.link',
'product.is_show'
])
->join('product', 'product.id=links.product_id')
->where(function ($query) {
$query->where('product.is_show', '=', 0)
->where('links.country_code', '=', $this->country_code);
if (request()->has('skeyword')) {
$query->where(function ($q) {
$keyword = request()->get('skeyword');
$q->where('product.brand_id', 'like', '%' . $keyword . '%')
->whereOr('product.name', 'like', '%' . $keyword . '%');
});
}
})
->order('links.id', 'sort')
->group('links.product_id')
->paginate(10);
$data = [];
foreach ($list as $val) {
if (empty($data[$val['spu']])) {
$val['rowspan'] = 1;
$data[$val['spu']] = $val;
}
}
if (!$list->isEmpty()) {
$others = Db::name('product_purchase_links')->alias('links')
->field([
'links.id',
'product.name',
'product.brand_id' => 'spu',
'links.platform_id',
'links.link',
'product.is_show'
])
->join('product', 'product.id=links.product_id')
->where('links.country_code', '=', $this->country_code)
->where('links.id', 'not in', array_column($list->items(), 'id'))
->where('links.product_id', 'in', array_column($list->items(), 'product_id'))
->select();
foreach ($others as $val) {
if (!empty($data[$val['spu']]) && $data[$val['spu']]['id'] != $val['id']) {
if (empty($data[$val['spu']]['children'])) {
$data[$val['spu']]['children'] = [];
}
$data[$val['spu']]['children'][] = $val;
$data[$val['spu']]['rowspan'] = count($data[$val['spu']]['children']) + 1;
}
}
}
$this->assign('list', $data);
$this->assign('page', $list->render());
$platforms = Db::name('product_purchase_link_platforms')
->field(['id', 'platform'])
->where('id', '>', 0)
->where('country_code', '=', $this->country_code)
->select();
$this->assign('platforms', $platforms);
return $this->fetch();
}
/**
* 更新
*/
public function update()
{
$post = request()->post();
if (empty($post['id'])) {
return $this->error('请确认操作数据');
}
$id = $post['id'];
unset($post['id']);
// 验证链接
if (!empty($post['link'])) {
$validate = new Validate([
'link' => 'url|max:255'
], [
'link.url' => '连接地址格式错误',
'link.max' => '连接址不能超过255个字符'
]);
if (!$validate->check($post)) {
return $this->error($validate->getError());
}
}
// 验证平台
if (!empty($post['platform_id'])) {
$proid = Db::name('product_purchase_links')->where('id', '=', $id)->value('product_id');
$exists = Db::name('product_purchase_links')
->where('product_id', '=', $proid)
->where('platform_id', '=', $post['platform_id'])
->value('id');
if ($exists) {
$platform = Db::name('product_purchase_link_platforms')
->where('id', '=', $post['platform_id'])
->value('platform');
return $this->error(sprintf('该型号已存在【%s】链接', $platform));
}
}
$ret = Db::name('product_purchase_links')->where('id', '=', $id)->update($post);
if (!$ret) {
return $this->error('操作失败');
}
return $this->success('操作成功');
}
/**
* 导入
*/
public function import()
{
ini_set('max_execution_time', '0');
$file = request()->file('file');
if ($file->getSize() > 20 * 1024 * 1024) {
return $this->error('上传文件不能超过20M');
}
// 创建读取器
$reader = \PHPExcel_IOFactory::createReader('Excel2007');
// 加载表格
$spreadsheet = $reader->load($file->getRealPath());
// 读取sheet
$sheet = $spreadsheet->getSheet(0);
$rows = $sheet->getHighestRow(); //总行数
$xlsx = [];
for($i = 2; $i <= $rows; $i++) {
// $xlsx[行号] = 数据
$xlsx[$i] = [
'spu' => $sheet->getCellByColumnAndRow(0, $i)->getValue(),
'platform' => $sheet->getCellByColumnAndRow(1, $i)->getValue(),
'link' => $sheet->getCellByColumnAndRow(2, $i)->getValue(),
];
}
// 错误提示
$errors = [];
// 验证成功数据
$valid_data = [];
// 购买平台数据
$platforms = Db::name('product_purchase_link_platforms')
->where('id', '>', 0)
->where('country_code', '=', $this->country_code)
->column('id', 'platform');
$xlsx_chunks = array_chunk($xlsx, 500, true);
// 分批次验证 spu
foreach ($xlsx_chunks as $x) {
$spus = array_column($x, 'spu');
$products = Db::name('product')
->where('brand_id', 'in', $spus)
->where('country_code', '=', $this->country_code)
->column('id', 'brand_id');
if (empty($products)) {
$errors[] = sprintf('第%s行, 型号不存在', implode(',', array_keys($x)));
continue;
}
$items = [];
foreach ($x as $k => $v) {
if (empty($products[$v['spu']])) {
$errors[] = sprintf('第%s行, 型号不存在', $k);
continue;
}
if (empty($platforms[$v['platform']])) {
$errors[] = sprintf("第%s行, 平台名称错误", $k);
continue;
}
if (
!empty($v['link']) &&
!\think\helper\Str::startsWith($v['link'], 'http://') &&
!\think\helper\Str::startsWith($v['link'], 'https://')
) {
$errors[] = sprintf("第%s行, 链接地址格式错误", $k);
continue;
}
$items[] = [
'product_id' => $products[$v['spu']],
'platform_id' => $platforms[$v['platform']],
'link' => $v['link'],
'country_code' => $this->country_code,
];
}
if (!empty($items)) {
$valid_data[] = $items;
}
}
if (!empty($valid_data)) {
// 组装 SQL
$sql = 'REPLACE INTO `cod_product_purchase_links`(`id`, `product_id`, `platform_id`, `link`, `country_code`) VALUES ';
foreach ($valid_data as $val) {
$proids = array_column($val, 'product_id');
$links = Db::name('product_purchase_links')
->field(['id', 'product_id', 'platform_id'])
->where('product_id', 'in', $proids)
->where('country_code', '=', $this->country_code)
->select();
if (!empty($links)) {
$links_mapping = [];
foreach ($links as $l) {
$links_mapping[$l['product_id'] . "_" . $l['platform_id']] = $l['id'];
}
}
foreach ($val as $v) {
$id = null;
if (!empty($links_mapping[$v['product_id'] . '_' . $v['platform_id']])) {
$id = $links_mapping[$v['product_id'] . '_' . $v['platform_id']];
}
$sql .= sprintf('(%d, %d, %d, "%s", "%s"),', $id, $v['product_id'], $v['platform_id'], $v['link'], $v['country_code']);
}
}
Db::execute(\think\helper\Str::substr($sql, 0, \think\helper\Str::length($sql) - 1));
}
if (!empty($errors)) {
return $this->error(implode(";\n", $errors));
}
return $this->success('导入成功');
}
/**
* 导出
*/
public function export()
{
$data = Db::name('product_purchase_links')->alias('links')
->field([
'product.brand_id' => 'spu',
'platforms.platform',
'links.link'
])
->join('product_purchase_link_platforms platforms', 'platforms.id=links.platform_id')
->join('product', 'product.id=links.product_id')
->where(function($query) {
$query->where('product.is_show', '=', 0)->where('links.country_code', '=', $this->country_code);
if (request()->has('skeyword')) {
$query->where(function ($q) {
$keyword = request()->get('skeyword');
$q->where('product.brand_id', 'like', '%' . $keyword . '%')
->whereOr('product.name', 'like', '%' . $keyword . '%');
});
}
})
->select();
$excel = new \PHPExcel();
$excel->getProperties()->setCreator("Call of Duty")
->setLastModifiedBy("Call of Duty")
->setTitle("Office 2007 XLSX Cod Document")
->setSubject("Office 2007 XLSX Cod Document")
->setDescription("Cod document for Office 2007 XLSX, generated using PHP classes.")
->setKeywords("office 2007 openxml php")
->setCategory("Cod result file");
$excel->createSheet();
$excel->getActiveSheet()->setCellValueByColumnAndRow(0, 1, '型号');
$excel->getActiveSheet()->setCellValueByColumnAndRow(1, 1, '平台');
$excel->getActiveSheet()->setCellValueByColumnAndRow(2, 1, '链接');
foreach ($data as $i => $v) {
$excel->getActiveSheet()->setCellValueByColumnAndRow(0, $i + 2, $v['spu']);
$excel->getActiveSheet()->setCellValueByColumnAndRow(1, $i + 2, $v['platform']);
$excel->getActiveSheet()->setCellValueByColumnAndRow(2, $i + 2, $v['link']);
}
ob_end_clean();
$writer = \PHPExcel_IOFactory::createWriter($excel, 'Excel2007');
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream"); //文件流
header("Content-Type: application/download"); //下载文件
header('Content-Disposition: attachment;filename="' . date('YmdHis') . '-' . $this->country_code . '.xlsx"');
header("Content-Transfer-Encoding: binary");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); //上一次修改时间
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache"); //不缓存页面
$writer->save('php://output');
exit;
}
}