Browse Source

feat:add new files

igb 4 months ago
parent
commit
caf2695a74

+ 16 - 8
app/Helpers/SiteCache.php

@@ -4,6 +4,8 @@ namespace App\Helpers;
 
 use Illuminate\Support\Facades\Cache;
 use App\Models\DistAdminDistributor;
+use App\Models\DistAppearance;
+use App\Models\DistAppearancePublishList;
 
 class SiteCache
 {
@@ -14,20 +16,26 @@ class SiteCache
      * @param int $seconds 缓存时间(秒)
      * @return Dist|null
      */
-    public static function getDist(?string $domain = null, int $seconds = 600): ?string
+    public static function getDist(?string $domain = null, int $seconds = 300): ?string
     {
         if (is_null($domain)) {
             return null; // 如果未传入域名,返回 null
         }
 
         return Cache::tags([$domain, 'dist'])->remember("dist_{$domain}", $seconds, function () use ($domain) {
-            $dist= DistAdminDistributor::where('custom_domain', $domain)
-                ->orWhere('secondary_domain', $domain)
-                ->first();
-            //dd($dist);  // 调试缓存的数据
+            $dist= DistAdminDistributor::findByDomain($domain);
+
+            if($dist['appearance_id'])
+            {
+                $dist['appearance'] = DistAppearance::getTemplateById($dist['appearance_id']);
+                $dist['publishList'] = DistAppearancePublishList::findByDistAndAppearance($dist['id'], $dist['appearance_id']);
+
+            }
+
+
+
             // 序列化存储
             return serialize($dist);
-
         });
     }
 
@@ -54,7 +62,7 @@ class SiteCache
      * @param int $seconds 缓存时间(秒)
      * @return Product|null
      */
-    public static function getProduct(?string $domain = null, ?int $productId = null, int $seconds = 600): ?Product
+    public static function getProduct(?string $domain = null, ?int $productId = null, int $seconds = 300): ?Product
     {
         if (is_null($domain) || is_null($productId)) {
             return null; // 如果未传入 domain 或 productId,返回 null
@@ -89,7 +97,7 @@ class SiteCache
      * @param int $seconds 缓存时间(秒)
      * @return Article|null
      */
-    public static function getArticle(?string $domain = null, ?int $articleId = null, int $seconds = 600): ?Article
+    public static function getArticle(?string $domain = null, ?int $articleId = null, int $seconds = 300): ?Article
     {
         if (is_null($domain) || is_null($articleId)) {
             return null; // 如果未传入 domain 或 articleId,返回 null

+ 63 - 0
app/Helpers/helpers.php

@@ -22,3 +22,66 @@ if (!function_exists('getHost')) {
         return request()->getHost();
     }
 }
+
+if (!function_exists('formatDirectory')) {
+    /**
+     * 格式化目录名
+     *
+     * @param string $directory 目录名
+     * @return string
+     */
+    function formatDirectory($directory) {
+        // 如果目录名为空,返回空字符串
+        if (empty($directory)) {
+            return '';
+        }
+
+        // 移除前面的斜杠
+        $directory = ltrim($directory, '/');
+
+        // 确保最后添加一个斜杠
+        $directory = rtrim($directory, '/') . '/';
+
+        return $directory;
+    }
+}
+
+if (!function_exists('formatAndCreateAbsoluteDirectory')) {
+    /**
+     * 格式化绝对路径,移除文件部分并创建目录
+     *
+     * @param string $path 完整的路径(可能包含文件)
+     * @param int $permissions 新建目录的权限(默认为 0755)
+     * @return string 格式化后的绝对路径
+     */
+    function formatAndCreateAbsoluteDirectory($path, $permissions = 0755) {
+        // 如果路径为空,返回空字符串
+        if (empty($path)) {
+            return '';
+        }
+
+        // 确保路径是绝对路径(以 / 开头)
+        if ($path[0] !== '/') {
+            throw new Exception("The path must be an absolute path starting with '/'. Provided: {$path}");
+        }
+
+        // 检查是否包含文件部分
+        if (preg_match('/\/[^\/]+\.[^\/]+$/', $path)) {
+            // 如果路径中包含文件名,则移除
+            $path = dirname($path);
+        }
+
+        // 确保路径以斜杠结尾
+        $path = rtrim($path, '/') . '/';
+
+        // 检查目录是否存在,如果不存在则创建
+        if (!is_dir($path)) {
+            if (!mkdir($path, $permissions, true)) { // true 表示递归创建中间目录
+                throw new Exception("Failed to create directory: {$path}");
+            }
+        }
+
+        return $path;
+    }
+}
+

+ 25 - 19
app/Http/Middleware/LoadDistData.php

@@ -6,7 +6,8 @@ use Closure;
 use Illuminate\Http\Request;
 use Symfony\Component\HttpFoundation\Response;
 use App\Helpers\SiteCache;
-use Liquid\Liquid;
+use App\Services\TemplateUpdater;
+use App\Services\LiquidRenderer;
 /**
  * Class LoadDistData 用中间件来获取distm网店信息
  */
@@ -24,35 +25,40 @@ class LoadDistData
         // 获取请求的域名
         $domain = getHost();
 
-        // 先检查 custom_domain,如果没有找到,再检查 secondary_domain
-        $dist=SiteCache::getDist($domain);
-
-        // 如果缓存的结果是字符串,反序列化为对象
-        if ($dist) {
-            $dist = unserialize($dist);
-        }
-
-        //dd($dist);
-//// 如果是数组或对象,直接转换为对象
-//        if (is_array($dist)) {
-//            $dist = (object) $dist; // 将数组转换为对象
-//        } elseif (is_string($dist)) {
-//            // 处理字符串情况,假设字符串是 JSON 格式,可以尝试解析
-//            $dist = json_decode($dist);
-//        }
+        // 从缓存中获取站点配置并反序列化
+        $dist = SiteCache::getDist($domain);
+        $dist = $dist ? unserialize($dist) : null;
 
         // 如果找不到匹配的数据,直接返回404响应
         if (!$dist) {
             abort(404, 'site not found.');
         }
 
-        // 全局共享  数据
-        app()->instance('dist', $dist);
+        // 检查模板是否需要更新
+        if (  !$dist->publishList->template_local_code ||
+            $dist->publishList->template_update_code !== $dist->publishList->template_local_code) {
+
+            // dd('update template');
+            // 更新模板
+            TemplateUpdater::updateTemplates($dist);
 
+            // 清除缓存并重新获取
+            SiteCache::clearDistCache($domain);
+            $dist = SiteCache::getDist($domain);
+            $dist = $dist ? unserialize($dist) : null;
 
+            if (!$dist) {
+                abort(404, 'site not found.');
+            }
+        }
+
+
+        // 全局共享  数据
+        app()->instance('dist', $dist);
         // 将找到的 dist 数据添加到请求中,方便后续使用
         $request->attributes->set('dist', $dist);
 
+
         //保存到共享地方供其它地方用
 
         return $next($request);

+ 42 - 0
app/Models/DistAdminDistributor.php

@@ -11,4 +11,46 @@ class DistAdminDistributor extends Model
 
     protected $table = 'dist_admin_distributor';
 
+
+    // 关联关系:一个 Distributor 可能有多个 AppearancePublish
+    public function appearancePublishes()
+    {
+        return $this->hasMany(DistAppearancePublishList::class, 'dist_id', 'id');
+    }
+
+    /**
+     * 关联到 DistAppearance
+     */
+    public function appearance()
+    {
+        return $this->belongsTo(DistAppearance::class, 'appearance_id', 'id');
+    }
+
+    /**
+     * 根据域名查找 Distributor 并加载关联数据
+     *
+     * @param string $domain
+     * @return self|null
+     */
+    public static function findByDomainWithAppearances(string $domain)
+    {
+        return self::with('appearancePublishes') // 预加载关联数据
+        ->where('custom_domain', $domain)
+            ->orWhere('secondary_domain', $domain)
+            ->first();
+    }
+
+    /**
+     * 根据域名查找 Distributor(不加载关联数据)
+     *
+     * @param string $domain
+     * @return self|null
+     */
+    public static function findByDomain(string $domain)
+    {
+        return self::where('custom_domain', $domain)
+            ->orWhere('secondary_domain', $domain)
+            ->first(); // 只查找当前模型数据
+    }
+
 }

+ 17 - 13
app/Models/DistAppearance.php

@@ -5,22 +5,26 @@ namespace App\Models;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 
-class DistAppearance extends Model implements Sortable
+class DistAppearance extends Model
 {
-	use HasDateTimeFormatter;
-    use SortableTrait;
+    use HasFactory;
 
     protected $table = 'dist_appearance';
 
-    protected $casts = [
-        'created_at' => 'datetime:Y-m-d H:i:s',
-        'updated_at' => 'datetime:Y-m-d H:i:s',
-    ];
-
-    // 可选:你可以在这里自定义排序配置
-    public $sortable = [
-        'order_column_name' => 'order',  // 排序字段
-        'sort_when_creating' => true,    // 创建时自动排序
-    ];
+    // 与 DistAppearancePublishList 的反向关联
+    public function publishLists()
+    {
+        return $this->hasMany(DistAppearancePublishList::class, 'appearance_id', 'id');
+    }
 
+    /**
+     * 根据 ID 返回对应模板信息
+     *
+     * @param int $id
+     * @return self|null
+     */
+    public static function getTemplateById(int $id)
+    {
+        return self::find($id); // 根据主键 ID 查找记录
+    }
 }

+ 43 - 0
app/Models/DistAppearancePublishList.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class DistAppearancePublishList extends Model
+{
+    use HasFactory;
+
+    protected $table = 'dist_appearance_publish_list';
+
+    // 如果主键字段不是 'id',可以指定
+    protected $primaryKey = 'id';
+
+
+    // 反向关联:每个 AppearancePublish 属于一个 Distributor
+    public function distributor()
+    {
+        return $this->belongsTo(DistAdminDistributor::class, 'dist_id', 'id');
+    }
+
+    // 新增:与 DistAppearance 的关联
+    public function appearance()
+    {
+        return $this->belongsTo(DistAppearance::class, 'appearance_id', 'id');
+    }
+
+    /**
+     * 根据 dist_id 和 appearance_id 查找唯一记录
+     *
+     * @param int $dist_id
+     * @param int $appearance_id
+     * @return self|null
+     */
+    public static function findByDistAndAppearance(int $dist_id, int $appearance_id)
+    {
+        return self::where('dist_id', $dist_id)
+            ->where('appearance_id', $appearance_id)
+            ->first(); // 返回唯一记录或 null
+    }
+}

+ 1 - 1
app/Models/DistAppearanceTemplate.php

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
 
 class DistAppearanceTemplate extends Model
 {
-	use HasDateTimeFormatter;
+
     protected $table = 'dist_appearance_template';
 
 }

+ 10 - 0
app/Services/LiquidRenderer.php

@@ -77,6 +77,16 @@ class LiquidRenderer
         return $template;
     }
 
+    public static function getBaseTemplatePath(): string
+    {
+        // 确保路径已经初始化
+        if (self::$baseTemplatePath === null) {
+            self::initializeBaseTemplatePath();
+        }
+
+        return self::$baseTemplatePath;
+    }
+
     // 设置 Liquid 渲染的全局配置
     private static function initializeLiquidSettings(): void
     {

+ 81 - 0
app/Services/TemplateUpdater.php

@@ -0,0 +1,81 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\DistAppearancePublishList;
+use App\Models\DistAppearanceTemplate;
+use Illuminate\Support\Facades\Storage;
+
+class TemplateUpdater
+{
+    protected static ?string $baseTemplatePath = null;
+    /**
+     * 更新模板文件并更新数据库记录
+     *
+     * @param int $dist_id
+     * @param int $appearance_id
+     * @return string
+     */
+    public static function updateTemplates($dist): string
+    {
+
+
+        if(!$dist->appearance_id)
+        {
+            return "No appearance found for dist_id: $dist->id.";
+        }
+
+        // 使用默认值的函数封装,避免重复逻辑
+        $template_dist_id = $dist->id ?? trim(config('liquid.template_dist_id'));
+        $template_name = $dist->appearance->title ?? trim(config('liquid.template_name'));
+
+        if (self::$baseTemplatePath === null) {
+            self::$baseTemplatePath = rtrim(config('liquid.template_path'), '/') . '/' .
+                trim($template_dist_id). '/' .
+                ltrim($template_name, '/');
+        }
+
+        // 查询 dist_appearance_publish_list 表的记录
+        $publishList = DistAppearancePublishList::where('dist_id', $dist->id)
+            ->where('appearance_id', $dist->appearance_id)
+            ->first();
+
+
+        // 获取 template_update_code
+        $updateCode = $publishList->template_update_code;
+
+        // 查询 dist_appearance_template 表,获取与该 dist_id 和 appearance_id 对应的所有模板文件
+        $templates = DistAppearanceTemplate::where('dist_id', $dist->id)
+            ->where('appearance_id', $dist->appearance_id)
+            ->get();
+
+
+        if ($templates->isEmpty()) {
+            return "No templates found in dist_appearance_template for dist_id: $dist->id, appearance_id: $dist->appearance_id.";
+        }
+
+        // 循环处理每个模板文件
+        foreach ($templates as $template) {
+            // 如果文件名和路径不存在,生成默认值
+            //$fileName = $template->file_name ?: "template_{$dist_id}_{$appearance_id}_{$template->id}.txt";
+            $filePath = self::$baseTemplatePath.'/'.formatDirectory($template->file_path).$template->file_name;
+
+
+            // 写入文件内容
+            formatAndCreateAbsoluteDirectory($filePath);
+            //// 强制转换内容为 UTF-8 编码
+            $contentUtf8 = mb_convert_encoding($template->content, 'UTF-8', 'auto');
+
+
+            // 写入文件内容,带 BOM
+            file_put_contents($filePath, $contentUtf8);
+
+        }
+
+        // 更新 dist_appearance_publish_list 的 template_local_code
+        $publishList->template_local_code = $updateCode;
+        $publishList->save();
+
+        return "Templates updated successfully for dist_id: $dist->id and appearance_id: $dist->appearance_id.";
+    }
+}