|
@@ -0,0 +1,172 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+declare(strict_types=1);
|
|
|
|
|
+
|
|
|
|
|
+namespace SixShop\Eav\Service;
|
|
|
|
|
+
|
|
|
|
|
+use SixShop\Eav\Model\EavAttributeModel;
|
|
|
|
|
+use SixShop\Eav\Model\EavEntityTypeModel;
|
|
|
|
|
+use SixShop\Eav\Model\EavValueModel;
|
|
|
|
|
+use think\facade\Log;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * EAV 值服务类
|
|
|
|
|
+ * 提供通用的 EAV 属性值操作方法
|
|
|
|
|
+ */
|
|
|
|
|
+class EavValueService
|
|
|
|
|
+{
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 保存 EAV 属性值
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param int $entityId 实体ID
|
|
|
|
|
+ * @param string $entityTypeCode 实体类型编码(如:order, goods, category)
|
|
|
|
|
+ * @param string $attributeCode 属性编码(如:reissue, color, size)
|
|
|
|
|
+ * @param mixed $value 属性值
|
|
|
|
|
+ * @return bool 是否保存成功
|
|
|
|
|
+ */
|
|
|
|
|
+ public function saveAttributeValue(int $entityId, string $entityTypeCode, string $attributeCode, mixed $value): bool
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ // 获取实体类型 ID
|
|
|
|
|
+ $entityType = EavEntityTypeModel::where('entity_type_code', $entityTypeCode)->find();
|
|
|
|
|
+ if (!$entityType) {
|
|
|
|
|
+ Log::warning("实体类型不存在: {$entityTypeCode}");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取属性 ID
|
|
|
|
|
+ $attribute = EavAttributeModel::where([
|
|
|
|
|
+ 'entity_type_id' => $entityType->id,
|
|
|
|
|
+ 'attribute_code' => $attributeCode
|
|
|
|
|
+ ])->find();
|
|
|
|
|
+ if (!$attribute) {
|
|
|
|
|
+ Log::warning("属性不存在: {$attributeCode} (entity_type: {$entityTypeCode})");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否已存在
|
|
|
|
|
+ $existValue = EavValueModel::where([
|
|
|
|
|
+ 'entity_id' => $entityId,
|
|
|
|
|
+ 'entity_type_id' => $entityType->id,
|
|
|
|
|
+ 'attribute_id' => $attribute->id
|
|
|
|
|
+ ])->find();
|
|
|
|
|
+
|
|
|
|
|
+ // 根据属性的 backend_type 确定存储字段
|
|
|
|
|
+ $saveData = [
|
|
|
|
|
+ 'entity_id' => $entityId,
|
|
|
|
|
+ 'entity_type_id' => $entityType->id,
|
|
|
|
|
+ 'attribute_id' => $attribute->id,
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ switch ($attribute->backend_type) {
|
|
|
|
|
+ case 'int':
|
|
|
|
|
+ case 'boolean':
|
|
|
|
|
+ $saveData['value_int'] = intval($value);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'decimal':
|
|
|
|
|
+ $saveData['value_decimal'] = floatval($value);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'text':
|
|
|
|
|
+ $saveData['value_text'] = strval($value);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'datetime':
|
|
|
|
|
+ $saveData['value_datetime'] = strval($value);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'varchar':
|
|
|
|
|
+ default:
|
|
|
|
|
+ $saveData['value_varchar'] = strval($value);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($existValue) {
|
|
|
|
|
+ // 更新
|
|
|
|
|
+ EavValueModel::where('id', $existValue->id)->update($saveData);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 新增
|
|
|
|
|
+ EavValueModel::create($saveData);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取 EAV 属性值
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param int $entityId 实体ID
|
|
|
|
|
+ * @param string $entityTypeCode 实体类型编码
|
|
|
|
|
+ * @param string $attributeCode 属性编码
|
|
|
|
|
+ * @return mixed 属性值,不存在返回 null
|
|
|
|
|
+ */
|
|
|
|
|
+ public function getAttributeValue(int $entityId, string $entityTypeCode, string $attributeCode): mixed
|
|
|
|
|
+ {
|
|
|
|
|
+ // 获取实体类型 ID
|
|
|
|
|
+ $entityType = EavEntityTypeModel::where('entity_type_code', $entityTypeCode)->find();
|
|
|
|
|
+ if (!$entityType) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取属性 ID
|
|
|
|
|
+ $attribute = EavAttributeModel::where([
|
|
|
|
|
+ 'entity_type_id' => $entityType->id,
|
|
|
|
|
+ 'attribute_code' => $attributeCode
|
|
|
|
|
+ ])->find();
|
|
|
|
|
+ if (!$attribute) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询属性值
|
|
|
|
|
+ $value = EavValueModel::where([
|
|
|
|
|
+ 'entity_id' => $entityId,
|
|
|
|
|
+ 'entity_type_id' => $entityType->id,
|
|
|
|
|
+ 'attribute_id' => $attribute->id
|
|
|
|
|
+ ])->find();
|
|
|
|
|
+
|
|
|
|
|
+ if (!$value) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 根据 backend_type 返回对应的值
|
|
|
|
|
+ return match ($attribute->backend_type) {
|
|
|
|
|
+ 'int', 'boolean' => $value->value_int,
|
|
|
|
|
+ 'decimal' => $value->value_decimal,
|
|
|
|
|
+ 'text' => $value->value_text,
|
|
|
|
|
+ 'datetime' => $value->value_datetime,
|
|
|
|
|
+ default => $value->value_varchar,
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 删除 EAV 属性值
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param int $entityId 实体ID
|
|
|
|
|
+ * @param string $entityTypeCode 实体类型编码
|
|
|
|
|
+ * @param string $attributeCode 属性编码
|
|
|
|
|
+ * @return bool 是否删除成功
|
|
|
|
|
+ */
|
|
|
|
|
+ public function deleteAttributeValue(int $entityId, string $entityTypeCode, string $attributeCode): bool
|
|
|
|
|
+ {
|
|
|
|
|
+ // 获取实体类型 ID
|
|
|
|
|
+ $entityType = EavEntityTypeModel::where('entity_type_code', $entityTypeCode)->find();
|
|
|
|
|
+ if (!$entityType) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取属性 ID
|
|
|
|
|
+ $attribute = EavAttributeModel::where([
|
|
|
|
|
+ 'entity_type_id' => $entityType->id,
|
|
|
|
|
+ 'attribute_code' => $attributeCode
|
|
|
|
|
+ ])->find();
|
|
|
|
|
+ if (!$attribute) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 删除属性值
|
|
|
|
|
+ EavValueModel::where([
|
|
|
|
|
+ 'entity_id' => $entityId,
|
|
|
|
|
+ 'entity_type_id' => $entityType->id,
|
|
|
|
|
+ 'attribute_id' => $attribute->id
|
|
|
|
|
+ ])->delete();
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|