2025-05-22 17:53:57 +08:00

312 lines
12 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
namespace app\admin\controller\home;
use app\admin\library\Auth;
use app\common\controller\Backend;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use think\db\exception\BindParamException;
use think\Exception;
use think\exception\PDOException;
/**
* 新闻
*
* @icon fa fa-circle-o
*/
class News extends Backend
{
/**
* News模型对象
* @var \app\admin\model\home\News
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\home\News;
$this->view->assign("typeList", $this->model->getTypeList());
$this->view->assign("recommendList", $this->model->getRecommendList());
$this->view->assign("hotList", $this->model->getHotList());
$this->view->assign("fineList", $this->model->getFineList());
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = true;
$this->searchFields = ["id","title","subtitle","source","cate.name","cate.flag"];
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->with(['cate'])
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->getRelation('cate')->visible(['name']);
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
/**
* 导入
*/
public function import()
{
$file = $this->request->request('file');
if (!$file) {
$this->error(__('Parameter %s can not be empty', 'file'));
}
$filePath = ROOT_PATH . DS . 'public' . DS . $file;
if (!is_file($filePath)) {
$this->error(__('No results were found'));
}
//实例化reader
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
$this->error(__('Unknown data format'));
}
if ($ext === 'csv') {
$file = fopen($filePath, 'r');
$filePath = tempnam(sys_get_temp_dir(), 'import_csv');
$fp = fopen($filePath, "w");
$n = 0;
while ($line = fgets($file)) {
$line = rtrim($line, "\n\r\0");
$encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
if ($encoding != 'utf-8') {
$line = mb_convert_encoding($line, 'utf-8', $encoding);
}
if ($n == 0 || preg_match('/^".*"$/', $line)) {
fwrite($fp, $line . "\n");
} else {
fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
}
$n++;
}
fclose($file) || fclose($fp);
$reader = new Csv();
} elseif ($ext === 'xls') {
$reader = new Xls();
} else {
$reader = new Xlsx();
}
//导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
$importHeadType = isset($this->importHeadType) ? $this->importHeadType : 'comment';
$table = $this->model->getQuery()->getTable();
$database = \think\Config::get('database.database');
// $fieldArr = [];
// $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
// foreach ($list as $k => $v) {
// if ($importHeadType == 'comment') {
// $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
// } else {
// $fieldArr[$v['COLUMN_NAME']] = $v['COLUMN_NAME'];
// }
// }
//加载文件
$insert = [];
try {
if (!$PHPExcel = $reader->load($filePath)) {
$this->error(__('Unknown data format'));
}
$currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
$allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
$allRow = $currentSheet->getHighestRow(); //取得一共有多少行
$maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
$fields = []; //遍历得到第一行的字段内容
for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
$fields[] = $val;
}
}
//遍历余下所有行(具体数据)
for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
$values = []; //得到当前行数据
for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
$values[] = is_null($val) ? '' : $val;
}
if(!$values[0] && !$values[0])continue;
$row = [];
$temp = array_combine($fields, $values);
//拼接提交参数
foreach ($temp as $k => $v) {
if(!$k)throw new Exception("异常的格式或存在空列,请检查!");
//保留原始数据
$raw_v = $v;
$v = str_replace('"','',trim(strip_tags(htmlspecialchars_decode($v))));
switch ($k)
{
case "新闻标题":
case "文章标题":
case "标题":
if (!$v)throw new Exception("{$k}项有的行并未填写内容请检查!");
$row['title'] = $v;
break;
case "新闻副标题":
case "文章副标题":
case "副标题":
$row['subtitle'] = $v;
break;
case "发布时间":
case "时间":
$row['release_time'] = $v;
//转换时间2025/5/20 成时间戳
$row['release_time'] = strtotime($row['release_time']);
break;
case "内容" :
case "文章内容" :
// var_dump($v);die;
$row['content'] = $raw_v;
break;
case "新闻类目" :
case "类目" :
case "分类" :
case "分类ID" :
case "分类id" :
//根据name查询分类表id
if($v){
$cate = \app\admin\model\home\NewsCate::where('name',$v)->find();
if ($cate) {
$row['cate_id'] = $cate['id'];
}else{
//创建分类
$cate = \app\admin\model\home\NewsCate::create([
'name' => $v,
'status' => 1,
'weigh' => 0,
]);
$row['cate_id'] = $cate['id'];
}
}else{
//无分类默认第一个
$row['cate_id'] = \app\admin\model\home\NewsCate::where('status',1)->order('weigh desc')->value('id');
}
break;
case "来源" :
$row['source'] = $v; // 来源
break;
case "浏览量" :
case "点击数" :
$row['views'] = $v; // 来源
break;
case "来源复合数据" :
//$v = "来源新华社 发布日期2025-05-20 点击数15";
if (!$v)throw new Exception("{$k}项有的行并未填写内容请检查!");
// 转换编码为 UTF-8
$v = mb_convert_encoding($v, 'UTF-8', 'UTF-8,GBK,GB2312,ASCII');
if (preg_match('/来源:(.+?)[\\s ]+发布日期:(\d{4}-\d{2}-\d{2})[\\s ]+点击数:(\d+)/is', $v, $matches)) {
$source = isset($matches[1]) ? trim(mb_convert_encoding($matches[1], 'UTF-8', 'auto')) : '';
$releaseDate = isset($matches[2]) ? strtotime(trim($matches[2])) : null;
$clicks = isset($matches[3]) ? intval(trim($matches[3])) : 0;
$row['source'] = $source; // 来源
$row['release_time'] = $releaseDate ?: time(); // 默认当前时间
$row['views'] = $clicks; // 点击数
// var_dump($row);die;
} else {
$this->error("来源复合数据格式异常,请检查字段内容: {$v}");
}
break;
}
}
if ($row) {
//查询是否存在一样的,如果存在,忽略
$where = [
'title' => $row['title'],
];
// unset($where['title']);
if(! \app\admin\model\home\News::where($where)->find()){
$row["weigh"] = 0;
$insert[] = $row;
}
}
}
// var_dump($values);die;
} catch (Exception $exception) {
$this->error($exception->getMessage());
}
if (!$insert) {
$this->error(__('No rows were updated'));
}
try {
//$insert倒序插入
$insert = array_reverse($insert);
$this->model->saveAll($insert);
} catch (PDOException $exception) {
$msg = $exception->getMessage();
if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
$msg = "导入失败,包含【{$matches[1]}】的记录已存在";
};
var_dump($exception->getData());
$this->error($msg);
} catch (Exception $e) {
$this->error($e->getMessage());
}
$this->success();
}
}