550 lines
22 KiB
PHP
550 lines
22 KiB
PHP
<?php
|
||
namespace app\api\controller\v1;
|
||
|
||
use app\api\model\Question as QuestionModel;
|
||
use app\api\validate\Question as QuestionValidate;
|
||
use Egulias\EmailValidator\EmailValidator;
|
||
use Egulias\EmailValidator\Validation\DNSCheckValidation;
|
||
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
|
||
use Egulias\EmailValidator\Validation\RFCValidation;
|
||
use PHPMailer\PHPMailer\PHPMailer;
|
||
use PHPMailer\PHPMailer\SMTP;
|
||
use PHPMailer\PHPMailer\Exception;
|
||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||
use PhpOffice\PhpSpreadsheet\Reader\Csv;
|
||
use PhpOffice\PhpSpreadsheet\Reader\Xls;
|
||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
|
||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
||
use think\db\exception\PDOException;
|
||
use think\facade\Env;
|
||
|
||
/**
|
||
* 用户反馈类
|
||
* Class Question
|
||
* @package app\api\controller
|
||
*/
|
||
class Question extends Base
|
||
{
|
||
public function initialize()
|
||
{
|
||
parent::initialize();
|
||
$this->validate = new QuestionValidate();
|
||
$this->model = new QuestionModel();
|
||
}
|
||
|
||
/**
|
||
* 列表
|
||
* @return \think\response\Json
|
||
*/
|
||
public function index()
|
||
{
|
||
$inputData = $this->request->param();
|
||
$inputData['platform_id'] = $this->platformId;
|
||
|
||
|
||
if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
|
||
$this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
|
||
unset($inputData['language_id']);
|
||
}
|
||
if (isset($inputData['is_done']) && $inputData['is_done'] != '') {
|
||
$this->focus['is_done'] = $inputData['is_done'];
|
||
}
|
||
|
||
if (isset($inputData['product_model']) && $inputData['product_model'] != '') {
|
||
$this->simple['product_model'] = $inputData['product_model'];
|
||
}
|
||
|
||
if (isset($inputData['create_time']) && $inputData['create_time'] != '') {
|
||
$this->orderby['create_time'] = $inputData['create_time'];
|
||
}
|
||
|
||
|
||
if (!$this->commonValidate(__FUNCTION__,$inputData)) {
|
||
return $this->msg(-1,$this->validate->getError());
|
||
}
|
||
if (!empty($this->focus)) {
|
||
if (!$this->commonValidate(__FUNCTION__,$this->focus)) {
|
||
return $this->msg(-1,$this->validate->getError());
|
||
}
|
||
}
|
||
|
||
if (!empty($this->simple)) {
|
||
if (!$this->commonValidate(__FUNCTION__,$this->simple)) {
|
||
return $this->msg(-1,$this->validate->getError());
|
||
}
|
||
}
|
||
|
||
if (!empty($this->orderby)) {
|
||
if (!$this->commonValidate(__FUNCTION__,$this->orderby)) {
|
||
return $this->msg(-1,$this->validate->getError());
|
||
}
|
||
}
|
||
//字段过滤
|
||
$this->field = ['id','platform_id','language_id','site_id','country_id','name','phone','email','order_sn','product_model','os','sort','is_done','create_time'];
|
||
$result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->orderby,$this->field);
|
||
return $this->msg(200,'获取列表成功',$result);
|
||
}
|
||
|
||
/**
|
||
* 已解决
|
||
*/
|
||
public function isDone()
|
||
{
|
||
$inputData = $this->request->param();
|
||
$inputData['platform_id'] = $this->platformId;
|
||
|
||
if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
|
||
$this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
|
||
unset($inputData['language_id']);
|
||
}
|
||
if (!$this->commonValidate(__FUNCTION__,$inputData)) {
|
||
return $this->msg(-1,$this->validate->getError());
|
||
}
|
||
$result = $this->model->isDone($inputData);
|
||
if ($result) {
|
||
return $this->msg(200,'更改成功');
|
||
} else {
|
||
return $this->msg(504,'更改失败');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Excel导出,
|
||
* @param array $data
|
||
* @param string $fileName
|
||
* @param array $options
|
||
* @return bool
|
||
*/
|
||
public function export($data = [], $fileName = '', $options = [])
|
||
{
|
||
try {
|
||
if (empty($data)) {
|
||
return false;
|
||
}
|
||
|
||
set_time_limit(0);
|
||
$objSpreadsheet = new Spreadsheet();
|
||
/* 设置默认文字居左,上下居中 */
|
||
$styleArray = [
|
||
'alignment' => [
|
||
'horizontal' => Alignment::HORIZONTAL_LEFT,
|
||
'vertical' => Alignment::VERTICAL_CENTER,
|
||
],
|
||
];
|
||
$objSpreadsheet->getDefaultStyle()->applyFromArray($styleArray);
|
||
/* 设置Excel Sheet */
|
||
$activeSheet = $objSpreadsheet->setActiveSheetIndex(0);
|
||
|
||
/* 打印设置 */
|
||
if (isset($options['print']) && $options['print']) {
|
||
/* 设置打印为A4效果 */
|
||
$activeSheet->getPageSetup()->setPaperSize(PageSetup:: PAPERSIZE_A4);
|
||
/* 设置打印时边距 */
|
||
$pValue = 1 / 2.54;
|
||
$activeSheet->getPageMargins()->setTop($pValue / 2);
|
||
$activeSheet->getPageMargins()->setBottom($pValue * 2);
|
||
$activeSheet->getPageMargins()->setLeft($pValue / 2);
|
||
$activeSheet->getPageMargins()->setRight($pValue / 2);
|
||
}
|
||
|
||
$row = 2;
|
||
$col = 0;
|
||
/* 行数据处理 */
|
||
foreach ($data as $sKey => $sItem) {
|
||
/* 默认文本格式 */
|
||
$pDataType = DataType::TYPE_STRING;
|
||
|
||
/* 设置单元格格式 */
|
||
if (isset($options['format']) && !empty($options['format'])) {
|
||
$colRow = Coordinate::coordinateFromString($sKey);
|
||
|
||
/* 存在该列格式并且有特殊格式 */
|
||
if (isset($options['format'][$colRow[0]]) &&
|
||
NumberFormat::FORMAT_GENERAL != $options['format'][$colRow[0]]) {
|
||
$activeSheet->getStyle($sKey)->getNumberFormat()
|
||
->setFormatCode($options['format'][$colRow[0]]);
|
||
|
||
if (false !== strpos($options['format'][$colRow[0]], '0.00') &&
|
||
is_numeric(str_replace(['¥', ','], '', $sItem))) {
|
||
/* 数字格式转换为数字单元格 */
|
||
$pDataType = DataType::TYPE_NUMERIC;
|
||
$sItem = str_replace(['¥', ','], '', $sItem);
|
||
}
|
||
} elseif (is_int($sItem)) {
|
||
$pDataType = DataType::TYPE_NUMERIC;
|
||
}
|
||
}
|
||
|
||
if ($col < count($options['alignCenter'])) {
|
||
$activeSheet->getColumnDimension($options['alignCenter'][$col])->setAutoSize(true);
|
||
}
|
||
$activeSheet->getRowDimension($row)->setRowHeight(65);
|
||
$activeSheet->setCellValueExplicit($sKey, $sItem, $pDataType);
|
||
$row++;
|
||
$col++;
|
||
/* 存在:形式的合并行列,列入A1:B2,则对应合并 */
|
||
if (false !== strstr($sKey, ":")) {
|
||
$options['mergeCells'][$sKey] = $sKey;
|
||
}
|
||
|
||
if (is_image(Env::get('root_path').'public'.$sItem) && file_exists(Env::get('root_path').'public'.$sItem)) {
|
||
$activeSheet->setCellValueExplicit($sKey, '', $pDataType);
|
||
$drawing = new Drawing();
|
||
$drawing->setName('Logo');
|
||
$drawing->setDescription('Logo');
|
||
$drawing->setPath(Env::get('root_path').'public'.$sItem);
|
||
$drawing->setResizeProportional(false);
|
||
$drawing->setHeight(50);
|
||
$drawing->setCoordinates($sKey);
|
||
$drawing->setOffsetX(12);
|
||
$drawing->setOffsetY(12);
|
||
$drawing->getShadow()->setVisible(true);
|
||
// $drawing->getShadow()->setDirection(45);
|
||
$drawing->setWorksheet($objSpreadsheet->getActiveSheet());
|
||
}
|
||
}
|
||
|
||
unset($data);
|
||
|
||
/* 设置锁定行 */
|
||
if (isset($options['freezePane']) && !empty($options['freezePane'])) {
|
||
$activeSheet->freezePane($options['freezePane']);
|
||
unset($options['freezePane']);
|
||
}
|
||
|
||
/* 设置宽度 */
|
||
if (isset($options['setWidth']) && !empty($options['setWidth'])) {
|
||
foreach ($options['setWidth'] as $swKey => $swItem) {
|
||
$activeSheet->getColumnDimension($swKey)->setWidth($swItem);
|
||
}
|
||
|
||
unset($options['setWidth']);
|
||
}
|
||
|
||
/* 设置背景色 */
|
||
if (isset($options['setARGB']) && !empty($options['setARGB'])) {
|
||
foreach ($options['setARGB'] as $sItem) {
|
||
$activeSheet->getStyle($sItem)
|
||
->getFill()->setFillType(Fill::FILL_SOLID)
|
||
->getStartColor()->setARGB(Color::COLOR_YELLOW);
|
||
}
|
||
|
||
unset($options['setARGB']);
|
||
}
|
||
|
||
/* 设置公式 */
|
||
if (isset($options['formula']) && !empty($options['formula'])) {
|
||
foreach ($options['formula'] as $fKey => $fItem) {
|
||
$activeSheet->setCellValue($fKey, $fItem);
|
||
}
|
||
|
||
unset($options['formula']);
|
||
}
|
||
|
||
/* 合并行列处理 */
|
||
if (isset($options['mergeCells']) && !empty($options['mergeCells'])) {
|
||
$activeSheet->setMergeCells($options['mergeCells']);
|
||
unset($options['mergeCells']);
|
||
}
|
||
|
||
/* 设置居中 */
|
||
if (isset($options['alignCenter']) && !empty($options['alignCenter'])) {
|
||
$styleArray = [
|
||
'alignment' => [
|
||
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||
'vertical' => Alignment::VERTICAL_CENTER,
|
||
],
|
||
];
|
||
|
||
foreach ($options['alignCenter'] as $acItem) {
|
||
$activeSheet->getStyle($acItem)->applyFromArray($styleArray);
|
||
}
|
||
|
||
unset($options['alignCenter']);
|
||
}
|
||
|
||
/* 设置加粗 */
|
||
if (isset($options['bold']) && !empty($options['bold'])) {
|
||
foreach ($options['bold'] as $bItem) {
|
||
$activeSheet->getStyle($bItem)->getFont()->setBold(true);
|
||
}
|
||
|
||
unset($options['bold']);
|
||
}
|
||
|
||
/* 设置单元格边框,整个表格设置即可,必须在数据填充后才可以获取到最大行列 */
|
||
if (isset($options['setBorder']) && $options['setBorder']) {
|
||
$border = [
|
||
'borders' => [
|
||
'allBorders' => [
|
||
'borderStyle' => Border::BORDER_THIN, // 设置border样式
|
||
'color' => ['argb' => 'FF000000'], // 设置border颜色
|
||
],
|
||
],
|
||
];
|
||
$setBorder = 'A1:' . $activeSheet->getHighestColumn() . $activeSheet->getHighestRow();
|
||
$activeSheet->getStyle($setBorder)->applyFromArray($border);
|
||
unset($options['setBorder']);
|
||
}
|
||
|
||
$fileName = !empty($fileName) ? $fileName : (date('YmdHis') . '.xlsx');
|
||
|
||
if (!isset($options['savePath'])) {
|
||
/* 直接导出Excel,无需保存到本地,输出07Excel文件 */
|
||
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||
header(
|
||
"Content-Disposition:attachment;filename=" . iconv(
|
||
"utf-8", "GB2312//TRANSLIT", $fileName
|
||
)
|
||
);
|
||
header('Cache-Control: max-age=0');//禁止缓存
|
||
$savePath = 'php://output';
|
||
} else {
|
||
$savePath = $options['savePath'];
|
||
}
|
||
|
||
ob_clean();
|
||
ob_start();
|
||
$objWriter = IOFactory::createWriter($objSpreadsheet, 'Xlsx');
|
||
$objWriter->save($savePath);
|
||
/* 释放内存 */
|
||
$objSpreadsheet->disconnectWorksheets();
|
||
unset($objSpreadsheet);
|
||
ob_end_flush();
|
||
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 导入
|
||
*/
|
||
public function import()
|
||
{
|
||
$file = $this->request->request('file');
|
||
if (!$file) {
|
||
return $this->msg(504,'Parameter %s can not be empty');
|
||
}
|
||
$filePath = Env::get('root_path') . '/public/' . $file;
|
||
if (!is_file($filePath)) {
|
||
return $this->msg(504,'No results were found');
|
||
}
|
||
//实例化reader
|
||
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
|
||
if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
|
||
return $this->msg(504,'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 = 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)) {
|
||
return $this->msg(504,'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;
|
||
}
|
||
$row = [];
|
||
$temp = array_combine($fields, $values);
|
||
foreach ($temp as $k => $v) {
|
||
if (isset($fieldArr[$k]) && $k !== '') {
|
||
$row[$fieldArr[$k]] = $v;
|
||
}
|
||
}
|
||
if ($row) {
|
||
$insert[] = $row;
|
||
}
|
||
}
|
||
} catch (Exception $exception) {
|
||
return $this->msg(504,$exception->getMessage());
|
||
}
|
||
if (!$insert) {
|
||
return $this->msg(504,'No rows were updated');
|
||
}
|
||
|
||
try {
|
||
//是否包含admin_id字段
|
||
$has_admin_id = false;
|
||
foreach ($fieldArr as $name => $key) {
|
||
if ($key == 'admin_id') {
|
||
$has_admin_id = true;
|
||
break;
|
||
}
|
||
}
|
||
if ($has_admin_id) {
|
||
$auth = Auth::instance();
|
||
foreach ($insert as &$val) {
|
||
if (!isset($val['admin_id']) || empty($val['admin_id'])) {
|
||
$val['admin_id'] = $auth->isLogin() ? $auth->id : 0;
|
||
}
|
||
}
|
||
}
|
||
$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]}】的记录已存在";
|
||
};
|
||
return $this->msg(504,$msg);
|
||
} catch (\Exception $e) {
|
||
return $this->msg(504,$e->getMessage());
|
||
}
|
||
|
||
return $this->msg(200,'导入成功!!');
|
||
}
|
||
|
||
// /**
|
||
// * 发送邮件
|
||
// */
|
||
// public function sendEmail()
|
||
// {
|
||
// $translate = [
|
||
// 'language_id' => '所属站点',
|
||
// 'country_id' => '国家/地区',
|
||
// 'name' => '客户名称',
|
||
// 'email' => '客户邮箱',
|
||
// 'order_sn' => '订单号',
|
||
// 'product_model' => '产品型号',
|
||
// 'os' => '操作系统',
|
||
// 'desc' => '问题详情',
|
||
// 'question_attachment' => '反馈附件',
|
||
// 'create_time' => '反馈时间'
|
||
// ];
|
||
//
|
||
// $data = $this->request->param();
|
||
// $data['create_time'] = date('Y-m-d H:i:s',time());
|
||
// $mail = new PHPMailer();
|
||
// $mail->CharSet = "UTF8";
|
||
// $mail->SMTPDebug = 0; //Enable verbose debug output
|
||
// $mail->isSMTP(); //Send using SMTP
|
||
// $mail->Host = Env::get('EMAIL.MAIL_HOST'); //Set the SMTP server to send through
|
||
// $mail->SMTPAuth = true; //Enable SMTP authentication
|
||
// $mail->Username = Env::get('EMAIL.MAIL_USERNAME'); //SMTP username
|
||
// $mail->Password = Env::get('EMAIL.MAIL_PASSWORD'); //SMTP password
|
||
// $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
|
||
// $mail->Port = Env::get('EMAIL.MAIL_PORT'); //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
|
||
//
|
||
// //Recipients
|
||
// $mail->setFrom(Env::get('EMAIL.MAIL_FROM_ADDRESS'), Env::get('EMAIL.MAIL_FROM_ADDRESS'));
|
||
// $mail->addAddress('yulinzhihou@163.com', 'yulinzhihou'); //Add a recipient
|
||
//
|
||
// //Content
|
||
// $mail->isHTML(true); //Set email format to HTML
|
||
// $mail->Subject = '尤达官网用户问题反馈'.$data['name'].date('Y-m-d H:i:s');
|
||
// $body = '';
|
||
// $body .= <<<EOF
|
||
//<style>
|
||
// table,tr,td,th {
|
||
// border: 1px solid #ccc;
|
||
// border-collapse: collapse;
|
||
// text-align: justify;
|
||
// }
|
||
// .item1 {
|
||
// width: 20%;
|
||
// }
|
||
//</style>
|
||
//<table>
|
||
//EOF;
|
||
// foreach ($data as $key => $value) {
|
||
// if (is_array($value)) {
|
||
// foreach ($value as $item) {
|
||
// $body .= '<tr><td class="item1">'.$translate[$key].'</td>'.'<td><a href='.$item['attach'].'>点击查看附件</a></td></tr>';
|
||
// }
|
||
// } else {
|
||
// $body .= '<tr><td class="item1">'.$translate[$key].'</td>'.'<td>'.$value.'</td></tr>';
|
||
// }
|
||
// }
|
||
// $body .= '</table>';
|
||
// $mail->Body = $body;
|
||
// $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
|
||
// $result = $mail->send();
|
||
// dd($result);
|
||
//
|
||
// }
|
||
//
|
||
//
|
||
// public function validateEmail()
|
||
// {
|
||
// $inputData = $this->request->param();
|
||
// $validator = new EmailValidator();
|
||
// $multipleValidations = new MultipleValidationWithAnd([
|
||
// new RFCValidation(),
|
||
// new DNSCheckValidation()
|
||
// ]);
|
||
// //ietf.org has MX records signaling a server with email capabilites
|
||
// $result = $validator->isValid($inputData['email'], $multipleValidations); //true
|
||
// if ($result) {
|
||
// return $this->msg(200,'邮箱有效');
|
||
// } else {
|
||
// return $this->msg(504,'邮箱无效');
|
||
// }
|
||
// }
|
||
}
|