123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- <?php
- namespace App\Modules\Admin\Services;
- use App\Base\BaseService;
- use App\Exceptions\ClientException;
- use App\Models\Goods\Spec;
- use App\Models\Goods\SpecAttr;
- use Illuminate\Database\Eloquent\Builder;
- use Illuminate\Support\Arr;
- use Illuminate\Support\Facades\DB;
- use Nerd\CartesianProduct\CartesianProduct;
- class SpecService extends BaseService
- {
- public function paginate($params)
- {
- $p = Spec::query()->when($params['name'], function (Builder $query) use ($params) {
- return $query->where("name", 'like', "%{$params['name']}%");
- })->orderByDesc("id")->paginate($params['page_size']);
- return [
- "total" => $p->total(),
- "page_total" => $p->lastPage(),
- "list" => array_map(function (Spec $u) {
- return $u->format(Spec::FORMAT_ATTR);
- }, $p->items()),
- ];
- }
- public function specStore($params)
- {
- $id = $params['id'] ?? 0;
- if ($id) {
- $spec = Spec::find($id);
- } else {
- $spec = new Spec();
- }
- $spec->name = Arr::get($params, 'name');
- $spec->en_name = Arr::get($params, 'en_name');
- $spec->index_weight = Arr::get($params, 'index_weight');
- $spec->category_weight = Arr::get($params, 'category_weight');
- $spec->search_weight = Arr::get($params, 'search_weight');
- $spec->is_custom = (int)Arr::get($params, 'is_custom');
- DB::transaction(function () use ($params, $spec) {
- $spec->save();
- $attr = Arr::get($params, "attr", []);
- $holdIdArr = Arr::pluck($attr, "id");
- SpecAttr::query()->where("spec_id", $spec->id)->whereNotIn("id", $holdIdArr)->delete();
- foreach ($attr as $k => $v) {
- $id = Arr::get($v, "id");
- if ($id) {
- $m = SpecAttr::whereSpecId($spec->id)->find($id);
- if (is_null($m)) {
- logger()->error("无法保存这个属性值:" . $v['name'] ?? "");
- throw new ClientException("无法保存这个属性值:" . $v['name'] ?? "");
- }
- } else {
- $m = new SpecAttr();
- }
- $m->spec_id = $spec->id;
- $m->name = $v['name'] ?? "";
- $m->save();
- }
- });
- return true;
- }
- public function specInfo($data)
- {
- $id = $data['id'];
- $spec = Spec::findOrFail($id);
- return $spec->format(Spec::FORMAT_ATTR);
- }
- public function specDelete($data)
- {
- $id = $data['id'] ?? 0;
- // @TODO kphcdr 判断是否有商品还在使用这个规则,否则无法删除
- $spec = Spec::find($id);
- if ($spec) {
- SpecAttr::where("spec_id", $spec->id)->delete();
- $spec->delete();
- }
- return true;
- }
- /**
- * 生成笛卡尔积表格
- *
- * @param array $specIdArr
- */
- public function cartesian(array $specIdArr)
- {
- $specS = Spec::with("attrs")->whereIn("id", $specIdArr)->where("is_custom", 0)->get();
- if ($specS->isEmpty()) {
- return [];
- }
- $attrS = collect();
- $cartesianProduct = new CartesianProduct();
- foreach ($specS as $spec) {
- /** @var Spec $spec */
- $cartesianProduct->appendSet($spec->attrs->pluck("name")->toArray());
- $attrS = $attrS->merge($spec->attrs);
- }
- $cartesian = $cartesianProduct->compute();
- foreach ($cartesian as $c) {
- if (is_array($c)) {
- $specAttr = array_map(function ($cname) use ($attrS) {
- /** @var SpecAttr $attr */
- $attr = $attrS->where("name", $cname)->first();
- return [
- "id" => $attr->id,
- "name" => $cname,
- "spec_name" => optional($attr->spec)->name,
- ];
- }, $c);
- } else {
- /** @var SpecAttr $attr */
- $attr = $attrS->where("name", $c)->first();
- $specAttr = [[
- "id" => $attr->id,
- "name" => $c,
- "spec_name" => optional($attr->spec)->name,
- ]];
- }
- $return[] = [
- "id" => 0,
- "sn" => "",
- "url_3d" => "",
- "is_use" => 1,
- "spec_attr" => $specAttr,
- ];
- }
- return $return;
- }
- }
|