| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 | <?phpnamespace App\Services;use Illuminate\Support\Facades\Storage;class LotteryImageService{    /**     * 生成开奖记录图片     * @param array $records 开奖记录数组     * @return string 图片的访问URL     * @throws \Exception     */    public function generate(array $records): string    {        // ========= 1. 生成HTML内容 =========        $html = $this->buildHtml($records);        // ========= 2. 保存HTML到临时文件 =========        $htmlPath = storage_path('app/lottery_temp.html');        file_put_contents($htmlPath, $html);        // ========= 3. 输出图片路径 =========        $fileName = 'lottery_' . time() . '.png';        $outputPath = storage_path('app/public/lottery/' . $fileName);        if (!is_dir(dirname($outputPath))) {            mkdir(dirname($outputPath), 0755, true);        }        // ========= 4. 调用 wkhtmltoimage =========        // --quality 100 提高图片质量,可选        $cmd = sprintf(            'wkhtmltoimage --quality 100 %s %s',            escapeshellarg($htmlPath),            escapeshellarg($outputPath)        );        exec($cmd, $output, $code);        if ($code !== 0 || !file_exists($outputPath)) {            throw new \Exception('图片生成失败,请检查是否已安装 wkhtmltoimage 并可在命令行执行');        }        // ========= 5. 返回访问URL =========        return Storage::url('lottery/' . $fileName);    }    /**     * 生成HTML内容     */    protected function buildHtml($records): string    {               $rows = '';        foreach ($records as $row) {            $rows .= '<tr>';            $rows .= '<td>' . htmlspecialchars($row['issue_no']) . '期</td>';            $rows .= '<td>';            foreach ($row['winning_numbers'] as $i => $num) {                $color = match ($i) {                    0 => '#FF8A8A',                    1 => '#8AB8FF',                    2 => '#FFDF80',                    default => '#000',                };                $rows .= "<span style='color: {$color};'>{$num}</span>";                if ($i < count($row['winning_numbers']) - 1) $rows .= ' + ';            }            $rows .= ' = ' . array_sum($row['winning_numbers']) . '</td>';            $rows .= '<td>' . $row['combo'] . '</td>';            $rows .= '<td>'.$row['extreme'].'</td>';            $rows .= '<td>'.$row['tail'].'</td>';            $rows .= '</tr>';        }        $time = now()->format('Y-m-d H:i:s');        return <<<HTML<!DOCTYPE html><html><head><meta charset="UTF-8"><title>加拿大28开奖记录</title><style>body {    font-family: "Microsoft YaHei", Arial, sans-serif;    /* background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); */    /* background:  #667eea 0%; */    margin: 0;    padding: 5px;    min-height: 100vh;}.container {    max-width: 800px;    margin: 0 auto;    background: white;    border-radius: 15px;    box-shadow: 0 10px 30px rgba(0,0,0,0.3);    overflow: hidden;}.header {    /* background: linear-gradient(45deg, #e74c3c, #c0392b); */    background:  #e74c3c;    color: white;    padding: 20px;    text-align: center;}.header h1 {    margin: 0;    font-size: 28px;    text-shadow: 2px 2px 4px rgba(0,0,0,0.3);}.results-table {    width: 100%;    border-collapse: collapse;}.results-table th {    background: #34495e;    color: white;    padding: 15px 10px;    text-align: center;}.results-table td {    padding: 12px 10px;    text-align: center;    border-bottom: 1px solid #e0e0e0;    font-weight: 900;}.footer {    background: #ecf0f1;    padding: 15px;    text-align: center;    color: #7f8c8d;    font-size: 12px;}</style></head><body><div class="container">    <div class="header">        <h1>加拿大28开奖记录</h1>        <div class="subtitle">最近开奖记录</div>    </div>    <table class="results-table">        <thead>            <tr>                <th>回合</th>                <th>结果</th>                <th>组合</th>                <th>极值</th>                <th>尾数</th>            </tr>        </thead>        <tbody>            {$rows}        </tbody>    </table>    <div class="footer">        生成时间: {$time} | 数据仅供参考    </div></div></body></html>HTML;    }}
 |