From e4bf808abc2a69d6545c7ba1d7f3db5e5e26276d Mon Sep 17 00:00:00 2001 From: liapples Date: Thu, 26 Aug 2021 11:17:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=90=86=E5=95=86?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MySQL_change.sql | 25 +++ app/Admin/Controllers/SupplierController.php | 10 ++ .../Controllers/AdvertisingController.php | 3 +- .../Controllers/AgentProductController.php | 160 ++++++++++++------ .../Controllers/SpecialController.php | 21 +-- app/AdminAgent/Controllers/UserController.php | 2 +- .../Renderable/SelectAgentProduct.php | 16 +- app/AdminAgent/routes.php | 1 + .../Api/AgentProductController.php | 22 ++- .../Controllers/Api/ChannelController.php | 5 +- app/Http/Controllers/Api/IndexController.php | 10 +- app/Http/Controllers/Api/LoginController.php | 3 +- app/Http/Controllers/Api/OrderController.php | 27 ++- .../Controllers/Api/SpecialController.php | 9 +- .../Controllers/Api/UserFavController.php | 17 +- app/Models/AgentProduct.php | 29 +++- app/Models/Product.php | 9 +- ready.md | 64 +++++++ resources/lang/zh_CN/agent-product.php | 6 + 19 files changed, 315 insertions(+), 124 deletions(-) diff --git a/MySQL_change.sql b/MySQL_change.sql index 0a3a808..85f0d54 100644 --- a/MySQL_change.sql +++ b/MySQL_change.sql @@ -152,3 +152,28 @@ ALTER TABLE `specials` # 14:15 2021/8/25 ALTER TABLE `messages` DROP COLUMN `is_read`; + +CREATE TABLE `message_reads` ( + `id` INT(10) NOT NULL COMMENT '消息ID,message_id', + `user_id` INT(10) NOT NULL COMMENT '用户ID,user_id', + PRIMARY KEY (`id`, `user_id`) USING BTREE +) +COMMENT='消息已读状态记录,如果含有记录,说明已读,否则未读' +COLLATE='utf8_general_ci' +ENGINE=InnoDB +; + +# 14:34 2021/8/25 +ALTER TABLE `agent_products` + ADD COLUMN `is_rec` TINYINT NOT NULL DEFAULT 0 COMMENT '是否推荐,推荐后在我的下文显示,0:未推荐;1:推荐;' AFTER `verifier`; + +# 16:35 2021/8/25 +ALTER TABLE `agent_products` + ADD COLUMN `type` TINYINT(3) NOT NULL DEFAULT '0' COMMENT '0:单品销售;1:组合销售;' AFTER `is_rec`, + ADD COLUMN `title` VARCHAR(255) NOT NULL COMMENT '标题' COLLATE 'utf8_general_ci' AFTER `type`, + ADD COLUMN `pictures` TEXT NOT NULL COMMENT '产品图片,可能有多张,JSON格式' COLLATE 'utf8_general_ci' AFTER `title`, + ADD COLUMN `know` TEXT NULL DEFAULT NULL COMMENT '旅客须知' COLLATE 'utf8_general_ci' AFTER `pictures`, + ADD COLUMN `content` MEDIUMTEXT NULL DEFAULT NULL COMMENT '产品详情' COLLATE 'utf8_general_ci' AFTER `know`; + +# 11:07 2021/8/26 +DROP TABLE `waterfall_ads`; diff --git a/app/Admin/Controllers/SupplierController.php b/app/Admin/Controllers/SupplierController.php index ae3e08f..a0cb945 100644 --- a/app/Admin/Controllers/SupplierController.php +++ b/app/Admin/Controllers/SupplierController.php @@ -4,7 +4,9 @@ namespace App\Admin\Controllers; use App\Admin\Extensions\Grid\AuditSupplier; use App\Admin\Repositories\Supplier; +use App\Common\ProductStatus; use App\Common\UserStatus; +use App\Models\Product; use Dcat\Admin\Form; use Dcat\Admin\Grid; use Dcat\Admin\Show; @@ -116,6 +118,7 @@ class SupplierController extends AdminController $form->select('status', '状态') ->options(UserStatus::array()) ->default(UserStatus::NORMAL) + ->help('如果禁用供应商将同时下架供应商的所有产品,需要供应商手动上架后才能销售,请谨慎!') ->required(); $form->text('company_name'); $form->image('logo'); @@ -123,6 +126,8 @@ class SupplierController extends AdminController $form->image('license_pic'); $form->text('director'); $form->mobile('contact_phone'); + })->editing(function (Form $form) { + $form->responseValidationMessages('111111111111111111111', 'title格式错误'); })->saving(function (Form $form) { //判断账号是否唯一 if ($form->isCreating()) { @@ -142,6 +147,11 @@ class SupplierController extends AdminController $form->$k = ''; } } + })->saved(function (Form $form) { + //禁用供应商将下架所有供应商的产品 + if ($form->status == UserStatus::DISABLED) { + Product::where('supplier_id', $form->getKey())->update(['status' => ProductStatus::SOLD_OUT]); + } }); } } diff --git a/app/AdminAgent/Controllers/AdvertisingController.php b/app/AdminAgent/Controllers/AdvertisingController.php index b6b504a..b5286d9 100644 --- a/app/AdminAgent/Controllers/AdvertisingController.php +++ b/app/AdminAgent/Controllers/AdvertisingController.php @@ -19,7 +19,8 @@ class AdvertisingController extends AdminController protected function grid() { return Grid::make(new Advertising(), function (Grid $grid) { - $grid->model()->where('agent_id', Admin::user()->id)->orderBy('sort')->orderBy('id', 'DESC'); + $grid->model()->where('agent_id', Admin::user()->id) + ->orderBy('display', 'desc')->orderBy('sort')->orderBy('id', 'DESC'); $grid->column('id')->sortable(); $grid->column('display')->using(admin_trans('advertising.options.display')); diff --git a/app/AdminAgent/Controllers/AgentProductController.php b/app/AdminAgent/Controllers/AgentProductController.php index 0341e4e..854a69a 100644 --- a/app/AdminAgent/Controllers/AgentProductController.php +++ b/app/AdminAgent/Controllers/AgentProductController.php @@ -21,7 +21,6 @@ use Dcat\Admin\Grid; use Dcat\Admin\Show; use Dcat\Admin\Http\Controllers\AdminController; use Dcat\Admin\Widgets\Alert; -use Dcat\Admin\Widgets\Table; class AgentProductController extends AdminController { @@ -37,9 +36,22 @@ class AgentProductController extends AdminController $grid->model()->where('agent_id', $agent_id); $grid->column('id')->sortable(); - $grid->column('product.picture', '产品图片')->image('', 60, 60); - $grid->column('product.title', '产品名称')->limit(15); - $grid->column('product_ids', '产品详情') + $grid->column('picture', '产品图片')->image('', 60, 60); + $grid->column('title', '产品名称')->limit(15); + $grid->column('price'); + $grid->column('original_price'); + $grid->column('sale'); + $grid->column('stock'); + + $channels = Channel::where('agent_id', $agent_id)->pluck('name', 'id')->toArray(); + $grid->column('channel_id', '频道') + ->display(function ($modal) use ($channels) { + $data = array_flip(explode(',', $this->channel_id)); + return join(',',array_intersect_key($channels, $data)); + }) + ->limit(10); + $grid->column('category.name', '分类'); + /*$grid->column('product_ids', '产品详情') ->display('查看') ->modal(function ($modal) { $titles = ['供应商', '产品标题', '产品图片', '原价', '现价', '销量', '库存']; @@ -56,20 +68,8 @@ class AgentProductController extends AdminController $this->product->stock ?? '', ]]; return Table::make($titles, $data); - }); - $grid->column('price'); - $grid->column('original_price'); - $grid->column('sale'); - $grid->column('stock'); + });*/ - $channels = Channel::where('agent_id', $agent_id)->pluck('name', 'id')->toArray(); - $grid->column('channel_id', '频道') - ->display(function ($modal) use ($channels) { - $data = array_flip(explode(',', $this->channel_id)); - return join(',',array_intersect_key($channels, $data)); - }) - ->limit(10); - $grid->column('category.name', '分类'); $grid->column('status') ->using(ProductStatus::array()) ->dot([ @@ -78,7 +78,7 @@ class AgentProductController extends AdminController ProductStatus::REFUSE => 'danger', ProductStatus::SOLD_OUT => 'warning', ], 'primary'); - $grid->column('created_at'); + $grid->column('is_rec')->switch()->help('推荐后将在“我的”页面下方显示'); $grid->column('updated_at'); $grid->filter(function (Grid\Filter $filter) { @@ -125,6 +125,11 @@ class AgentProductController extends AdminController if (Admin::user()->type == AgentType::CLUSTER) { $show->field('guide.name', '地接'); } + $show->field('is_rec')->using(['未推荐', '已推荐']); + $show->field('title'); + $show->field('pictures')->image('', 80, 80); + $show->field('know')->unescape(); + $show->field('content')->unescape(); $show->field('created_at'); $show->field('updated_at'); @@ -150,7 +155,7 @@ class AgentProductController extends AdminController */ protected function form() { - return Form::make(new AgentProduct(['product:id,title']), function (Form $form) { + return Form::make(new AgentProduct(), function (Form $form) { $agent_id = Admin::user()->id; //不允许查看非自己的数据 @@ -159,25 +164,36 @@ class AgentProductController extends AdminController } $form->display('id'); - $form->hidden('product_id'); - $form->selectTable('product_id', '封面产品') - ->help('产品列表显示的是该产品的标题和图片') - ->title('选择产品') - ->dialogWidth('80%;min-width:825px;') - ->from(SelectProduct::make()) - ->model(Product::class) - ->required(); - $form->multipleSelectTable('product_ids', '选择产品') - ->help('可单选或多选组合销售') - ->title('选择产品') - ->dialogWidth('80%;min-width:825px;') - ->from(SelectProduct::make()) - ->model(Product::class) - ->required(); + $form->radio('type') + ->options(['单品销售', '组合销售']) + ->default(0) + ->when(0, function (Form $form) { + /** 单品销售 **/ + $form->selectTable('product_id', '选择产品') + ->help('产品列表显示的是该产品的标题和图片') + ->title('选择产品') + ->dialogWidth('80%;min-width:825px;') + ->from(SelectProduct::make()) + ->model(Product::class); + })->when(1, function (Form $form) { + /** 组合销售 **/ + $form->multipleSelectTable('product_ids', '选择产品') + ->help('可单选或多选组合销售') + ->title('选择产品') + ->dialogWidth('80%;min-width:825px;') + ->from(SelectProduct::make()) + ->model(Product::class); + + /** 自定义内容 **/ + $form->text('title'); + $form->multipleImage('pictures'); + $form->editor('know'); + $form->editor('content'); + }); $form->text('price')->required(); $form->text('original_price')->required(); $form->text('sale')->default(0); - $form->text('stock')->default(9999); + $form->text('stock')->default(8888); $options = Channel::selectOptions(fn($query) => $query->where('agent_id', $agent_id)); $form->multipleSelect('channel_id')->options(array_slice($options, 1)); @@ -194,6 +210,7 @@ class AgentProductController extends AdminController ProductStatus::SOLD_OUT => '下架', ]) ->required(); + $form->switch('is_rec')->help('推荐后将在“我的”页面下方显示'); $form->selectTable('verifier') ->title('选择核销人员') ->dialogWidth('50%;min-width:600px;') //不起作用 @@ -216,26 +233,69 @@ class AgentProductController extends AdminController return $form->response()->error('数据不存在'); } - $agent_id = Admin::user()->id; + //推荐按钮开关 + if ($form->product_id === null && $form->product_ids === null && $form->is_rec !== null) { + $form->model()->is_rec = $form->is_rec ? 1 : 0; + $form->model()->save(); + return $form->response()->success('更新成功'); + } - $product_ids = explode(',', $form->product_ids); - if (empty($product_ids)) { - return $form->response()->error('请选择产品'); + //单品销售 + if ($form->type == 0) { + $form->product_id = (int)$form->product_id; + if (!$form->product_id) { + return $form->response()->error('请选择产品'); + } + $form->product_ids = $form->product_id; + + //将供应商产品写入title,pictures,know,content + $product = Product::find($form->product_id); + if ($product->status != ProductStatus::ON_SALE) { + return $form->response()->error('产品ID '. $form->product_id .' 已下架'); + } else if ($product->stock < $form->stock) { + return $form->response()->error('库存不足,你设置的库存应小于等于' . $form->stock); + } + $form->title = $product->title; + $form->pictures = $product->pictures; + $form->know = $product->know; + $form->content = $product->content; } + //组合销售 + else if ($form->type == 1) { + if (!$form->product_ids) { + return $form->response()->error('请选择产品'); + } + $product_ids = explode(',', $form->product_ids); - //判断供应商产品是否存在或下架 - $not_in_id = Product::query() - ->whereIn('id', $product_ids) - ->where(function ($query) use ($form) { - $query->where('status', '<>', ProductStatus::ON_SALE) - ->orWhere('stock', '<', $form->stock); - }) - ->pluck('id') - ->toArray(); - if ($not_in_id) { - return $form->response()->error('产品ID '. join(',', $not_in_id) .' 库存小于你设置的库存' . $form->stock . ',或不存在、已下架'); + if (count($product_ids) < 2) { + return $form->response()->error('组合销售必须选择两个以上产品,否则请选择单品销售'); + } + $form->product_id = $product_ids[0]; + + $required_fields = ['title', 'pictures', 'know', 'content']; + foreach ($required_fields as $field) { + if (!$form->$field) { + return $form->response()->error('内容输入不完整,标题、产品图片、旅游须知、产品详情必填'); + } + } + + //判断供应商产品是否存在或下架 + $not_in_id = Product::query() + ->whereIn('id', $product_ids) + ->where(function ($query) use ($form) { + $query->where('status', '<>', ProductStatus::ON_SALE) + ->orWhere('stock', '<', $form->stock); + }) + ->pluck('id') + ->toArray(); + if ($not_in_id) { + return $form->response()->error('产品ID ' . join(',', $not_in_id) . ' 库存小于你设置的库存' . $form->stock . ',或不存在、已下架'); + } + } else { + return $form->response()->error('不存在此销售方式'); } + $agent_id = Admin::user()->id; //处理特殊字段 $form->hidden(['agent_id', 'status']); //表单没有的字段,必须加这句才能够重写 $form->agent_id = $agent_id; diff --git a/app/AdminAgent/Controllers/SpecialController.php b/app/AdminAgent/Controllers/SpecialController.php index 68978ec..8894a9c 100644 --- a/app/AdminAgent/Controllers/SpecialController.php +++ b/app/AdminAgent/Controllers/SpecialController.php @@ -31,16 +31,15 @@ class SpecialController extends AdminController $grid->column('agent_product_id', '专题产品') ->display('查看') ->modal(function ($modal) use ($grid) { - $data = AgentProduct::with('product:id,title,pictures') - ->whereIn('id', $this->agent_product_id) - ->get(['id', 'product_id', 'sale', 'stock']); + $data = AgentProduct::whereIn('id', $this->agent_product_id) + ->get(['id', 'product_id', 'sale', 'stock', 'title', 'pictures']); $result = []; $prefix = Storage::disk('public')->url(''); foreach ($data as $k => $v) { $result[] = [ $v->id, - $v->product->title, - '', + $v->title, + '', $v->sale, $v->stock, ]; @@ -78,10 +77,9 @@ class SpecialController extends AdminController $show->field('agent_product_id', '产品') ->unescape() ->as(function ($v) { - $data = AgentProduct::with('product:id,title') - ->whereIn('id', $v) + $data = AgentProduct::whereIn('id', $v) ->orderBy('id')->get(['id', 'product_id']); - return join("
", $data->map(fn($v) => $v->product->title)->toArray()); + return join("
", $data->map(fn($v) => $v->title)->toArray()); }); $show->field('created_at'); $show->field('updated_at'); @@ -111,17 +109,16 @@ class SpecialController extends AdminController ->from(SelectAgentProduct::make()) ->options(function ($v) { if (!$v) return []; - $agent_product = AgentProduct::with('product:id,title') - ->select(['id', 'product_id']) + $agent_product = AgentProduct::select(['id', 'product_id', 'title']) ->whereIn('id', $v) ->orderBy('id')->get(); $result = []; foreach ($agent_product as $v) { - $result[$v->id] = $v->product->title ?? ''; + $result[$v->id] = $v->title ?? ''; } return $result; }) - ->pluck('product.title') + ->pluck('title', 'id') ->value(join(',', $form->model()->agent_product_id ?? [])); })->saving(function (Form $form) { //不允许修改非自己的数据 diff --git a/app/AdminAgent/Controllers/UserController.php b/app/AdminAgent/Controllers/UserController.php index ac410f0..e77faa9 100644 --- a/app/AdminAgent/Controllers/UserController.php +++ b/app/AdminAgent/Controllers/UserController.php @@ -37,7 +37,7 @@ class UserController extends AdminController $grid->column('avatar')->image(60, 60); $grid->column('mobile'); $grid->column('nickname'); - $grid->column('status')->switch(); + $grid->column('status')->switch()->help('禁用后用户将无法登录'); $grid->column('is_verify')->switch(); $grid->column('created_at'); diff --git a/app/AdminAgent/Renderable/SelectAgentProduct.php b/app/AdminAgent/Renderable/SelectAgentProduct.php index b4d480d..527910c 100644 --- a/app/AdminAgent/Renderable/SelectAgentProduct.php +++ b/app/AdminAgent/Renderable/SelectAgentProduct.php @@ -8,7 +8,7 @@ use Dcat\Admin\Grid; use Dcat\Admin\Grid\LazyRenderable; /** - * 选择产品 + * 选择代理商在售产品 * Class SelectProduct * @package App\AdminAgent\Renderable */ @@ -19,19 +19,18 @@ class SelectAgentProduct extends LazyRenderable // 获取外部传递的参数 // $id = $this->id; Admin::translation('agent-product'); - return Grid::make(new AgentProduct(['product.supplier:id,name']), function (Grid $grid) { + return Grid::make(new AgentProduct(), function (Grid $grid) { $grid->disableActions(); $grid->disableBatchDelete(); $grid->disableBatchActions(); $grid->model()->where('stock', '>', 0) ->where(['agent_id' => Admin::user()->id, 'status' => ProductStatus::ON_SALE]); - $grid->quickSearch(['product.title', 'product.supplier.name'])->placeholder('搜索产品名称、供应商'); + $grid->quickSearch(['title'])->placeholder('搜索产品名称'); $grid->column('id'); - $grid->column('product.supplier.name'); - $grid->column('product.title'); - $grid->column('product.picture')->image(60, 60); + $grid->column('title'); + $grid->column('picture')->image(60, 60); $grid->column('sale'); $grid->column('stock'); $grid->column('updated_at'); @@ -39,8 +38,9 @@ class SelectAgentProduct extends LazyRenderable $grid->paginate(15); $grid->filter(function (Grid\Filter $filter) { - $filter->like('product.title')->width(4); - $filter->like('product.supplier.name', '供应商名称')->width(4); + $filter->panel(); + + $filter->like('title')->width(4); }); }); } diff --git a/app/AdminAgent/routes.php b/app/AdminAgent/routes.php index 8f26883..34318d8 100644 --- a/app/AdminAgent/routes.php +++ b/app/AdminAgent/routes.php @@ -28,4 +28,5 @@ Route::group([ $router->resource('agent_info', 'AgentInfoController'); $router->resource('supplier/list', 'SupplierController'); $router->resource('article/list', 'ArticleController'); + $router->resource('setting', 'SettingController'); }); diff --git a/app/Http/Controllers/Api/AgentProductController.php b/app/Http/Controllers/Api/AgentProductController.php index 662f341..40fdc4a 100644 --- a/app/Http/Controllers/Api/AgentProductController.php +++ b/app/Http/Controllers/Api/AgentProductController.php @@ -25,7 +25,7 @@ class AgentProductController extends Controller $where['agent_id'] = $this->agent_id; - $list = AgentProduct::list()->where($where)->simplePaginate(); + $list = AgentProduct::list()->where($where)->orderBy('id', 'DESC')->simplePaginate(); $list = $this->paginatePicAddHost($list); $list = $this->insertAd($list); @@ -39,7 +39,6 @@ class AgentProductController extends Controller // TODO 优惠券查询待优化 $agent_product = AgentProduct::query() - ->with('product:id,title,pictures,know,stock,content') ->with('coupon:tag,agent_product_id') ->with('fav:agent_product_id') ->whereHas('product', function ($query) { @@ -53,9 +52,10 @@ class AgentProductController extends Controller } $prefix = Storage::disk('public')->url(''); - $agent_product->product->pictures = array_map(fn($item) => ($prefix . $item), $agent_product->product->pictures); + $agent_product->pictures = array_map(fn($item) => ($prefix . $item), $agent_product->pictures); $agent_product->is_collect = !is_null($agent_product->fav); //判断是否收藏 + unset($agent_product->fav); //计算折扣 if ($agent_product->price < $agent_product->original_price) { $agent_product->cost = round($agent_product->price / $agent_product->original_price * 10, 1); @@ -70,7 +70,7 @@ class AgentProductController extends Controller // 猜你喜欢 public function guessLike() { - $list = AgentProduct::list()->where('agent_id', $this->agent_id)->simplePaginate(); + $list = AgentProduct::list()->where('agent_id', $this->agent_id)->orderBy('id', 'DESC')->simplePaginate(); $list = $this->paginatePicAddHost($list); $list = $list->toArray(); if (!empty($list['data']) && is_array($list['data'])) { @@ -84,14 +84,18 @@ class AgentProductController extends Controller //【我的】页面下方推荐 public function recommendList() { - //TODO 推荐数据暂时使用产品列表,后期需要通过后台设置获取或根据用户购买过的关键词获取 - return $this->index(); + $list = AgentProduct::list()->where(['agent_id' => $this->agent_id, 'is_rec' => 1]) + ->orderBy('id', 'DESC')->simplePaginate(); + $list = $this->paginatePicAddHost($list); + $list = $this->insertAd($list); + + return $this->success($list); } //人气爆款列表,销量排序 public function hotList() { - $list = AgentProduct::list()->where('agent_id', $this->agent_id)->simplePaginate(); + $list = AgentProduct::list()->where('agent_id', $this->agent_id)->orderBy('id', 'DESC')->simplePaginate(); $list = $this->paginatePicAddHost($list); $list = $this->insertAd($list); @@ -104,9 +108,9 @@ class AgentProductController extends Controller if (!$list->isEmpty()) { $prefix = Storage::disk('public')->url(''); foreach ($list->items() as $k=>&$v) { - $v->product->pictures = array_map(function($item) use ($prefix) { + $v->pictures = array_map(function($item) use ($prefix) { return strpos($item, $prefix) === false ? $prefix . $item : $item; - }, $v->product->pictures); + }, $v->pictures); } } return $list; diff --git a/app/Http/Controllers/Api/ChannelController.php b/app/Http/Controllers/Api/ChannelController.php index f653a67..0a36a2d 100644 --- a/app/Http/Controllers/Api/ChannelController.php +++ b/app/Http/Controllers/Api/ChannelController.php @@ -5,7 +5,6 @@ use App\Http\Controllers\Controller; use App\Models\AgentProduct; use App\Models\Channel; use App\Models\UserChannel; -use Illuminate\Support\Facades\DB; /** * 频道列表 @@ -38,10 +37,8 @@ class ChannelController extends Controller { $channel_id = (int)request()->input('channel_id'); - $list = AgentProduct::where('agent_id', $this->agent_id) + $list = AgentProduct::list()->where('agent_id', $this->agent_id) ->whereRaw("FIND_IN_SET($channel_id, `channel_id`)") - ->with('product:id,title,pictures') - ->select('id', 'sale', 'product_id', 'price', 'original_price') ->orderBy('id', 'DESC') ->simplePaginate(); return $this->success($list); diff --git a/app/Http/Controllers/Api/IndexController.php b/app/Http/Controllers/Api/IndexController.php index f7e5212..567bd90 100644 --- a/app/Http/Controllers/Api/IndexController.php +++ b/app/Http/Controllers/Api/IndexController.php @@ -82,17 +82,15 @@ class IndexController extends Controller } # 人气爆款 - $hots = AgentProduct::with('product:id,title,pictures') //必须查询ID才能正常查询 - ->where('agent_id', $this->agent_id) - ->select('id', 'sale', 'product_id', 'price', 'original_price') //必须查询product_id才能with + $hots = AgentProduct::list()->where('agent_id', $this->agent_id) ->orderBy('sale', 'desc')->orderBy('id', 'desc') ->limit(6)->get(); if (!$hots->isEmpty()) { foreach ($hots as &$v) { - if (!empty($v->product->pictures) && is_array($v->product->pictures)) { - $v->product->pictures = array_map(function($item) use ($img_prefix) { + if (!empty($v->pictures) && is_array($v->pictures)) { + $v->pictures = array_map(function($item) use ($img_prefix) { return strpos($item, $img_prefix) === false ? $img_prefix . $item : $item; - }, $v->product->pictures); + }, $v->pictures); } } } diff --git a/app/Http/Controllers/Api/LoginController.php b/app/Http/Controllers/Api/LoginController.php index f31892b..dd98651 100644 --- a/app/Http/Controllers/Api/LoginController.php +++ b/app/Http/Controllers/Api/LoginController.php @@ -67,8 +67,7 @@ class LoginController extends Controller //TODO 存入初始化数据 user_channel - // TODO 用于测试 - $token_key = md5($userModel->id); + $token_key = md5($userModel->id . env('APP_KEY')); Cache::put($token_key, $userModel->id); // 测试代码结束 $userModel->token = $token_key; diff --git a/app/Http/Controllers/Api/OrderController.php b/app/Http/Controllers/Api/OrderController.php index 6aa66c5..fb00b89 100644 --- a/app/Http/Controllers/Api/OrderController.php +++ b/app/Http/Controllers/Api/OrderController.php @@ -46,8 +46,7 @@ class OrderController extends Controller $where['user_id'] = $this->user_id; $order_list = Order::where($where) - ->with('product:id,title,pictures') - ->select('id', 'agent_product_id', 'product_id', 'picture', 'price', 'num', 'status', 'created_at') + ->select('id', 'agent_product_id', 'product_id', 'title', 'picture', 'price', 'num', 'status', 'created_at') ->orderBy('id', 'DESC') ->simplePaginate(15) ->toArray(); @@ -61,14 +60,14 @@ class OrderController extends Controller $v['picture'] = $prefix . $v['picture']; } - if (strpos($v['product']['picture'], $prefix) === false) { - $v['product']['picture'] = $prefix . $v['product']['picture']; + if (strpos($v['picture'], $prefix) === false) { + $v['picture'] = $prefix . $v['picture']; } - if (!empty($v['product']['pictures']) && is_array($v['product']['pictures'])) { - $v['product']['pictures'] = array_map(function($item) use ($prefix) { + if (!empty($v['pictures']) && is_array($v['pictures'])) { + $v['pictures'] = array_map(function($item) use ($prefix) { return strpos($item, $prefix) === false ? $prefix . $item : $item; - }, $v['product']['pictures']); + }, $v['pictures']); } //10分钟内未付款订单提示付款 @@ -124,9 +123,10 @@ class OrderController extends Controller ->where('id', $formData['id']) ->with('coupon') ->with('product') + ->has('product') ->first(); if (!$ap || !$ap->product) { - $this->error('产品不存在'); + $this->error('产品不存在或已下架'); } if ($ap->stock < $formData['num'] || $ap->product->stock < $formData['num']) { $this->error('对不起,库存不足'); @@ -142,12 +142,9 @@ class OrderController extends Controller DB::beginTransaction(); try { $price = $this->calc($ap->price, $ap->coupon, $formData['num'], $formData['pay_type']); - $title = $ap->product->title; //产品标题 - //代理商产品表增加销量 - // $ap->increment('sale', $formData['num']); TODO 支付成功之后再增加销量 + $title = $ap->title; //产品标题 - //供应商产品表加销量、减库存 - // $ap->product->sale += $formData['num']; TODO 支付成功之后再增加销量 + //供应商产品表减库存 $ap->product->decrement('stock', $formData['num']); //代理商产品表减库存 @@ -163,7 +160,7 @@ class OrderController extends Controller 'name' => $formData['name'], 'mobile' => $formData['mobile'], 'title' => $title, - 'picture' => $ap->product->picture, + 'picture' => $ap->picture, 'agent_product_id' => $ap->id, 'product_id' => $ap->product_id, 'product_ids' => $ap->product->product_ids ?? $ap->product_id, @@ -250,7 +247,7 @@ class OrderController extends Controller } $ap = AgentProduct::query() - ->with('product:id,title,pictures') + ->has('product') ->with('coupon:agent_product_id,type,detail,agent_id,tag,start_at,end_at') ->find($formData['id'], ['id', 'price', 'original_price', 'product_id']); diff --git a/app/Http/Controllers/Api/SpecialController.php b/app/Http/Controllers/Api/SpecialController.php index 73e0def..638e828 100644 --- a/app/Http/Controllers/Api/SpecialController.php +++ b/app/Http/Controllers/Api/SpecialController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\AgentProduct; use App\Models\Special; +use Illuminate\Support\Facades\Storage; class SpecialController extends Controller { @@ -11,14 +12,20 @@ class SpecialController extends Controller public function show() { $id = (int)request()->input('id'); + $prefix = Storage::disk('public')->url(''); + $detail = Special::query() ->select(['id', 'picture', 'updated_at', 'agent_product_id']) ->find($id); + $detail->picture = array_map(fn($v) => $prefix . $v, $detail->picture); $detail->product = AgentProduct::list() ->where('agent_id', $this->agent_id) ->whereIn('id', $detail->agent_product_id) - ->limit(6)->get(); + ->orderBy('id', 'DESC')->limit(6)->get(); + foreach ($detail->product as $k => &$v) { + $v->pictures = array_map(fn($item) => $prefix . $item, $v->pictures); + } unset($detail->agent_product_id); return $this->success($detail); diff --git a/app/Http/Controllers/Api/UserFavController.php b/app/Http/Controllers/Api/UserFavController.php index b900971..c83f33f 100644 --- a/app/Http/Controllers/Api/UserFavController.php +++ b/app/Http/Controllers/Api/UserFavController.php @@ -18,8 +18,7 @@ class UserFavController extends Controller { $list = UserFav::query() ->with([ - 'agentProduct:id,price,original_price', - 'product:id,title,pictures', + 'agentProduct:id,price,original_price,title,pictures', ]) ->where('user_id', $this->user_id) ->select('id', 'agent_product_id', 'product_id', 'created_at') @@ -30,16 +29,14 @@ class UserFavController extends Controller $prefix = Storage::disk('public')->url(''); if ($list['data']) { foreach ($list['data'] as &$v) { - if (!empty($v['product']['pictures'])) { - //单图 - if (strpos($v['product']['picture'], $prefix) === false) { - $v['product']['picture'] = $prefix . $v['product']['picture']; - } - + if (!empty($v['agent_product']['pictures'])) { //多图 - $v['product']['pictures'] = array_map(function ($v) use ($prefix) { + $v['agent_product']['pictures'] = array_map(function ($v) use ($prefix) { return strpos($v, $prefix) === false ? $prefix . $v : $v; - }, $v['product']['pictures']); + }, $v['agent_product']['pictures']); + + //单图 + $v['agent_product']['picture'] = $prefix . $v['agent_product']['picture']; } } } diff --git a/app/Models/AgentProduct.php b/app/Models/AgentProduct.php index 6138030..5957e13 100644 --- a/app/Models/AgentProduct.php +++ b/app/Models/AgentProduct.php @@ -59,6 +59,13 @@ class AgentProduct extends BaseModel } } + public function setPicturesAttribute($value) + { + if (is_array($value)) { + $this->attributes['pictures'] = json_encode(array_filter($value)); + } + } + public function setProductIdsAttribute($value) { if (is_array($value)) { @@ -66,15 +73,29 @@ class AgentProduct extends BaseModel } } + // 获取所有产品图片 + public function getPicturesAttribute($value): array + { + if (is_string($value)) { + $value = $value ? json_decode($value, true) : []; + } + $this->append('picture'); + return $value ?? []; + } + + // 获取第一张产品图片 + public function getPictureAttribute($value): string + { + return $this->pictures[0] ?? ''; + } + //列表查询统一查询条件 public function scopeList($query) { - return $query->with('product:id,title,pictures') - ->whereHas('product', function ($query) { + return $query->whereHas('product', function ($query) { return $query->where('status', ProductStatus::ON_SALE)->where('stock', '>', 0); }) ->where('status', ProductStatus::ON_SALE)->where('stock', '>', 0) - ->select('id', 'sale', 'product_id', 'price', 'original_price') - ->orderBy('id', 'DESC'); + ->select('id', 'sale', 'product_id', 'price', 'original_price', 'title', 'pictures'); } } diff --git a/app/Models/Product.php b/app/Models/Product.php index b4e6a8d..9210efe 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -32,7 +32,14 @@ class Product extends BaseModel return $this->pictures[0] ?? ''; } - public function supplier() + public function setPicturesAttribute($value) + { + if (is_array($value)) { + $this->attributes['pictures'] = json_encode(array_filter($value)); + } + } + + public function supplier() { return $this->belongsTo(Supplier::class); } diff --git a/ready.md b/ready.md index d32c95f..a6887e5 100644 --- a/ready.md +++ b/ready.md @@ -6,8 +6,72 @@ 5、关于我们、注册协议、购买协议等信息; ```sql +# 11:12 2021/8/26 +TRUNCATE `advertisings`; +TRUNCATE `agent_products`; +TRUNCATE `agent_product_items`; +TRUNCATE `articles`; +TRUNCATE `coupons`; +TRUNCATE `messages`; +TRUNCATE `message_reads`; +TRUNCATE `notices`; TRUNCATE `orders`; +TRUNCATE `products`; +TRUNCATE `specials`; TRUNCATE `users`; +TRUNCATE `user_channels`; TRUNCATE `user_favs`; TRUNCATE `user_money_logs`; +TRUNCATE `agents`; +TRUNCATE `suppliers`; +TRUNCATE `guides`; + +INSERT INTO `categories` (`id`, `agent_id`, `pid`, `name`, `sort`, `template`, `deleted_at`) VALUES (1, 0, 0, '酒店', 255, '', NULL); +INSERT INTO `categories` (`id`, `agent_id`, `pid`, `name`, `sort`, `template`, `deleted_at`) VALUES (2, 0, 0, '景点', 255, '', NULL); +INSERT INTO `categories` (`id`, `agent_id`, `pid`, `name`, `sort`, `template`, `deleted_at`) VALUES (3, 0, 0, '国内游', 255, '', NULL); +INSERT INTO `categories` (`id`, `agent_id`, `pid`, `name`, `sort`, `template`, `deleted_at`) VALUES (4, 0, 0, '国际游', 255, '', NULL); +INSERT INTO `categories` (`id`, `agent_id`, `pid`, `name`, `sort`, `template`, `deleted_at`) VALUES (5, 0, 0, '跟团游', 255, '', NULL); + +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (1, 0, 0, '机票酒店', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (2, 0, 0, '旅游度假', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (3, 0, 0, '接送服务', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (4, 0, 0, '其它精选', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (5, 0, 0, '攻略社区', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (6, 0, 1, '多地比价', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (7, 0, 1, '降价提醒', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (8, 0, 1, '团体机票', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (9, 0, 2, '冲浪', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (10, 0, 2, '热气球', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (11, 0, 2, '蹦极', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (12, 0, 2, '滑翔伞', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (13, 0, 2, '主题玩法', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (14, 0, 2, '取景地', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (15, 0, 2, '周边游', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (16, 0, 2, '国内游', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (17, 0, 2, '尾单特卖', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (18, 0, 2, '邮轮', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (19, 0, 2, '汽车·船票', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (20, 0, 2, '定制游', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (21, 0, 2, '家庭游', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (22, 0, 2, '签证·上网', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (23, 0, 2, '自驾·租车', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (24, 0, 2, '旅游·团购', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (25, 0, 3, '接送机', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (26, 0, 3, '接送火车', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (27, 0, 3, '打车', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (28, 0, 3, '按天包车', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (29, 0, 3, '定制包车', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (30, 0, 3, '国内租车', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (31, 0, 3, '境外租车', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (32, 0, 4, '每日签到', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (33, 0, 4, '会员中心', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (34, 0, 4, '任务中心', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (35, 0, 4, '智慧旅游', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (36, 0, 4, '兑换会员', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (37, 0, 4, '旅盟', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (38, 0, 5, '旅游攻略', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (39, 0, 5, '玩法指南', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (40, 0, 5, '有问必答', '/static/images/icon.jpg', 255, NULL); +INSERT INTO `channels` (`id`, `agent_id`, `pid`, `name`, `icon`, `sort`, `deleted_at`) VALUES (41, 0, 5, '热门笔记', '/static/images/icon.jpg', 255, NULL); + ``` \ No newline at end of file diff --git a/resources/lang/zh_CN/agent-product.php b/resources/lang/zh_CN/agent-product.php index c5b61c3..2d914c6 100644 --- a/resources/lang/zh_CN/agent-product.php +++ b/resources/lang/zh_CN/agent-product.php @@ -15,6 +15,12 @@ return [ 'category_id' => '分类', 'status' => '状态', 'verifier' => '核销人员', + 'is_rec' => '是否推荐', + 'title' => '标题', + 'content' => '产品详情', + 'know' => '旅游须知', + 'pictures' => '产品图片', + 'picture' => '产品图片', 'product' => trans('product.fields'), ], 'options' => [