Files
orico-official-website/app/admin/controller/v1/ProductPurchaseLink.php

340 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace app\admin\controller\v1;
use app\admin\model\v1\ProductModel;
use app\admin\model\v1\ProductPurchaseLinkModel;
use app\admin\model\v1\ProductPurchaseLinkPlatformModel;
use app\admin\validate\v1\ProductPurchaseLinkValidate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\facade\Db;
class ProductPurchaseLink
{
/**
* 获取购买平台
*/
public function platforms()
{
$platforms = ProductPurchaseLinkPlatformModel::withoutField([
'language_id',
'desc',
'sort',
'created_at'
])
->language(request()->lang_id)
->order(['sort' => 'asc', 'id' => 'desc'])
->select();
return success('获取成功', $platforms);
}
/**
* 购买链接分布数据
*/
public function index()
{
$params = request()->param([
'name' => '',
'spu' => '',
'page/d' => 1,
'size/d' => 10
]);
$links = ProductModel::alias('pd')
->field([
'pd.id',
'pd.spu',
'pd.name',
'CASE WHEN pd.is_show = 0 THEN "已下架" WHEN pd.is_show = 1 THEN "已上架" END' => 'is_show',
'pf.id' => 'platform_id',
'pf.platform' => 'platform_name',
'min(pl.id)' => 'link_id',
'pl.link'
])
->leftJoin('product_purchase_link pl', 'pl.product_id = pd.id')
->leftJoin('product_purchase_platform pf', 'pf.id = pl.platform_id')
->where(function ($query) use ($params) {
$query->where('pd.is_show', '=', 1);
if (!empty($params['name'])) {
$query->where('pd.name', 'like', '%' . $params['name'] . '%');
}
if (!empty($params['spu'])) {
$query->where('pd.spu', 'like', '%' . $params['spu'] . '%');
}
})
->where('pd.language_id', '=', request()->lang_id)
->group('pd.id')
->order(['pl.sort' => 'asc', 'pl.id' => 'desc', 'pd.id' => 'desc'])
->paginate([
'list_rows' => $params['size'],
'page' => $params['page'],
]);
if ($links->isEmpty()) {
return success('获取成功', []);
}
$others = ProductPurchaseLinkModel::alias('pl')
->field([
'pl.product_id',
'pl.platform_id',
'pf.platform' => 'platform_name',
'pl.id' => 'link_id',
'pl.link'
])
->join('product_purchase_platform pf', 'pf.id = pl.platform_id')
->where('pl.language_id', '=', request()->lang_id)
->where('pl.product_id', 'in', array_column($links->items(), 'id'))
->where('pl.id', 'not in', array_column($links->items(), 'link_id'))
->select();
if (!$others->isEmpty()) {
$others_map = [];
$others_arr = $others->toArray();
foreach ($others_arr as $other) {
$product_id = $other['product_id'];
unset($other['product_id']);
$others_map[$product_id][] = $other;
}
$links->each(function ($item) use ($others_map) {
if (!empty($others_map[$item['id']])) {
$item['rowspan'] = $others_map[$item['id']];
}
return $item;
});
}
return success('获取成功', $links);
}
/**
* 导入
*/
public function import()
{
$file = request()->file('file');
if ($file->getSize() > 20 * 1024 * 1024) {
return error('上传文件不能超过20M');
}
$reader = IOFactory::createReader('Xlsx');
// 读取文件
$spreadsheet = $reader->load($file->getRealPath());
// 获取活动sheet
$sheet = $spreadsheet->getActiveSheet();
// 获取行数
$rows = $sheet->getHighestRow();
// 从表格获取数据
$xlsx_data = [];
for ($i=2; $i <= $rows; $i++) {
$xlsx_data[$i] = [
'spu' => $sheet->getCell('A' . $i)->getValue(),
'platform' => $sheet->getCell('B' . $i)->getValue(),
'link' => $sheet->getCell('C' . $i)->getValue(),
];
}
$platforms_name = array_unique(array_column($xlsx_data, 'platform'));
$platforms_map = ProductPurchaseLinkPlatformModel::language(request()->lang_id)
->where('platform', 'in', $platforms_name)
->column('id', 'platform');
$data = [];
$errors = [];
$chunks = array_chunk($xlsx_data, 500, true);
// 分组验证每行,并组装数据
foreach ($chunks as $chunk) {
$spus = array_unique(array_column($chunk, 'spu'));
$products_map = ProductModel::language(request()->lang_id)
->where('spu', 'in', $spus)
->column('id', 'spu');
$items = [];
foreach ($chunk as $r => $it) {
if (empty($platforms_map[$it['platform']])) {
$errors[] = sprintf("第%d行平台名称错误", $r);
continue;
}
if (empty($products_map[$it['spu']])) {
$errors[] = sprintf("第%d行型号不存在", $r);
continue;
}
$items[] = [
'language_id' => request()->lang_id,
'product_id' => $products_map[$it['spu']],
'platform_id' => $platforms_map[$it['platform']],
'link' => $it['link'],
'sort' => 0,
];
}
if (!empty($items)) {
$data[] = $items;
}
}
// 组装sql并执行
if (!empty($data)) {
$link_model = new ProductPurchaseLinkModel();
$sql = sprintf(
'REPLACE INTO %s (id, language_id, product_id, platform_id, link, sort) VALUES ',
$link_model->getTable(),
);
foreach ($data as $items) {
$products_id = array_unique(array_column($items, 'product_id'));
$links = $link_model->field([
'id',
'product_id',
'platform_id'
])
->where('product_id', 'in', $products_id)
->select();
$links_map = [];
if (!$links->isEmpty()) {
foreach ($links as $link) {
$links_map[$link['product_id'] . '_' . $link['platform_id']] = $link['id'];
}
}
foreach ($items as $item) {
$item['id'] = null;
if (!empty($links_map[$item['product_id'] . '_' . $item['platform_id']])) {
$item['id'] = $links_map[$item['product_id'] . '_' . $item['platform_id']];
}
$sql .= sprintf(
'(%d, %d, %d, %d, "%s", %d),',
$item['id'],
$item['language_id'],
$item['product_id'],
$item['platform_id'],
$item['link'],
$item['sort']
);
}
}
Db::execute(rtrim($sql, ','));
}
if (!empty($errors)) {
return error(implode(";\n", $errors));
}
return success('导入成功');
}
/**
* 导出
*/
public function export()
{
$schema = [
'spu' => '型号',
'platform' => '平台',
'link' => '链接'
];
// 获取导出数据
$data = $this->getExportLinkData();
// 获取Spreadsheet对象
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 写入表头
$title = array_values($schema);
$title_col = 'A';
foreach ($title as $value) {
// 单元格内容写入
$sheet->setCellValue($title_col . '1', $value);
$title_col++;
}
// 写入数据
$row = 2;
$keys = array_keys($schema);
foreach ($data as $item) {
$data_col = 'A';
foreach ($keys as $key) {
$sheet->setCellValue($data_col . $row, $item[$key] ?? '');
$data_col++;
}
$row++;
}
flush();
ob_flush();
$filename = date('YmdHms');
header('Access-Control-Expose-Headers: Content-Disposition');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; Charset=UTF-8');
header('Content-Disposition: attachment;filename=' . $filename . '.xlsx');
header('Cache-Control: max-age=0');
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
}
private function getExportLinkData()
{
$params = request()->param([
'name' => '',
'spu' => ''
]);
return ProductModel::alias('pd')
->field([
'pd.spu',
'pf.platform',
'pl.link'
])
->leftJoin('product_purchase_link pl', 'pl.product_id = pd.id')
->leftJoin('product_purchase_platform pf', 'pf.id = pl.platform_id')
->where(function ($query) use ($params) {
$query->where('pd.is_show', '=', 1);
if (!empty($params['name'])) {
$query->where('pd.name', 'like', '%' . $params['name'] . '%');
}
if (!empty($params['spu'])) {
$query->where('pd.spu', 'like', '%' . $params['spu'] . '%');
}
})
->where('pd.language_id', '=', request()->lang_id)
->order(['pl.sort' => 'asc', 'pl.id' => 'desc', 'pd.id' => 'desc'])
->select();
}
/**
* 更新购买链接
*/
public function update()
{
$id = request()->param('id');
$put = request()->put([
'link',
'platform_id'
]);
$data = [
'id' => $id,
'link' => $put['link'],
'platform_id' => $put['platform_id']
];
$validate = new ProductPurchaseLinkValidate;
if (!$validate->scene('update')->check($data)) {
return error($validate->getError());
}
$link = ProductPurchaseLinkModel::bypk($data['id'])->find();
if (empty($link)) {
return error('请确认操作对象是否存在');
}
if (!$link->save($data)) {
return error('操作失败');
}
return success('操作成功');
}
}