會員在不同網咖/店鋪消費累積積分,需將各店鋪積分分別記錄於單一 JSON 欄位 integrallog 中。結構如下:
[
{"store_id": 1, "jifen": 15},
{"store_id": 3, "jifen": 8}
]
$yanzhen、$arrstore)。$yanzhen[$key]['store_id'] = $key 會破壞原有結構。$store_id 來源不明)、直接依賴 $_SESSION 難以測試。m('integral')),不利單元測試。<?php
declare(strict_types=1);
class IntegralService
{
private $model;
private $userId;
public function __construct($model, int $userId)
{
$this->model = $model;
$this->userId = $userId;
}
/**
* 增加指定店鋪積分
* @param int $storeId 店鋪 ID
* @param int $points 增加點數(預設 5)
* @return bool
*/
public function addPoints(int $storeId, int $points = 5): bool
{
$record = $this->model->get(['user_id' => $this->userId]);
$logs = $record ? json_decode($record['integrallog'], true) : [];
// 正規化為 store_id => jifen 關聯陣列,方便查找
$map = [];
foreach ($logs as $log) {
if (isset($log['store_id'], $log['jifen'])) {
$map[(int)$log['store_id']] = (int)$log['jifen'];
}
}
if (isset($map[$storeId])) {
$map[$storeId] += $points;
} else {
$map[$storeId] = $points; // 新店鋪初始積分
}
// 轉回索引陣列格式存儲
$newLogs = [];
foreach ($map as $sid => $jf) {
$newLogs[] = ['store_id' => $sid, 'jifen' => $jf];
}
$data = ['integrallog' => json_encode($newLogs, JSON_UNESCAPED_UNICODE)];
if ($record) {
return $this->model->edit($record['id'], $data);
} else {
$data['user_id'] = $this->userId;
return $this->model->add($data);
}
}
}
// 使用範例(控制器中)
// $service = new IntegralService(M('integral'), $_SESSION['user_info']['user_id']);
// $service->addPoints((int)$store_id);
JSON_UNESCAPED_UNICODE 保留中文可讀性。若積分查詢/統計頻繁,建議拆分為獨立資料表 user_integral_log (user_id, store_id, points, created_at),並建立複合索引,效能與擴展性遠優於 JSON 欄位。