From cc462ccfed31e56bea11bd2389242621aec41479 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 10:47:22 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=E8=A1=8C=E4=B8=9A=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E8=B4=AD=E4=B9=B0=E6=94=B9=E4=B8=BA=E5=B7=A5=E5=85=B7=E8=A1=A8?= =?UTF-8?q?=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MySQL_change.sql | 10 +- .../Controllers/IndustryOrderController.php | 36 +++- .../Controllers/IndustryProductController.php | 18 +- app/AdminAgent/Forms/IndustryProductBuy.php | 200 ++++++++++++++++++ app/AdminAgent/routes.php | 1 + app/Models/IndustryOrder.php | 2 + resources/lang/zh_CN/industry-order.php | 2 + 7 files changed, 258 insertions(+), 11 deletions(-) create mode 100644 app/AdminAgent/Forms/IndustryProductBuy.php diff --git a/MySQL_change.sql b/MySQL_change.sql index 8a2cc04..fd2349e 100644 --- a/MySQL_change.sql +++ b/MySQL_change.sql @@ -304,10 +304,18 @@ ALTER TABLE `industry_orders` ADD COLUMN `paid_money` DECIMAL(20,2) NOT NULL DEFAULT '0.00' COMMENT '已付款金额' AFTER `pay_type`, ADD COLUMN `prepay_price` DECIMAL(8,2) NOT NULL DEFAULT '0.00' COMMENT '下单时产品的订金/定金' AFTER `deleted_at`, ADD COLUMN `prepay_timeout` INT(11) NOT NULL DEFAULT '0' COMMENT '订金/定金支付超时时间,单位:分钟' AFTER `prepay_price`, - ADD COLUMN `single_price` DECIMAL(8,2) NOT NULL DEFAULT '0.00' COMMENT '下单时的单人头交易费' AFTER `prepay_timeout`; + ADD COLUMN `single_price` DECIMAL(8,2) NOT NULL DEFAULT '0.00' COMMENT '下单时的单人头交易费' AFTER `prepay_timeout`, + ADD COLUMN `info` JSON NULL DEFAULT NULL COMMENT '客户信息收集' AFTER `single_price`; + # 17:46 ‎2021/‎10/‎17 ALTER TABLE `products` ADD COLUMN `logitude` DECIMAL(20,14) NOT NULL DEFAULT 0 COMMENT '经度' AFTER `diy_form_id`, ADD COLUMN `latitude` DECIMAL(20,14) NOT NULL DEFAULT 0 COMMENT '纬度' AFTER `logitude`, ADD COLUMN `address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '地址' AFTER `latitude`; + + + +# 10:43 ‎2021/‎10/‎18 +ALTER TABLE `industry_orders` + CHANGE COLUMN `trade_deposit` `trade_deposit` DECIMAL(20,2) NOT NULL DEFAULT '0.00' COMMENT '需要扣除的交易金' AFTER `prepay_timeout`; diff --git a/app/AdminAgent/Controllers/IndustryOrderController.php b/app/AdminAgent/Controllers/IndustryOrderController.php index d659bce..597aee4 100644 --- a/app/AdminAgent/Controllers/IndustryOrderController.php +++ b/app/AdminAgent/Controllers/IndustryOrderController.php @@ -135,7 +135,7 @@ class IndustryOrderController extends AdminController } else { $msg = $pay_config['return_msg'] ?? '获取支付信息失败'; } - Admin::script("Dcat.swal.info('支付失败:$msg', null);"); + Admin::script("Dcat.swal.info('支付:$msg', null);"); } else { Admin::js('@qrcode'); Admin::script(<<input('pid'); - $industry = IndustryProduct::where([ - ['status', '=', ProductStatus::ON_SALE], - ['stock', '>', 0], - ])->find($pid); + $industry = IndustryProduct::with('diyForm.fields') + ->where([ + ['status', '=', ProductStatus::ON_SALE], + ['stock', '>', 0], + ])->find($pid); return Form::make(new IndustryOrder(), function (Form $form) use ($industry) { if (!$industry) { @@ -240,6 +241,19 @@ JS $options = array_filter(PayType::array(), fn($k) => in_array($k, $pay_type), ARRAY_FILTER_USE_KEY); $form->select('pay_type')->options($options)->default(PayType::ONLINE)->required(); + //信息收集表单 TODO 信息收集表单文件上传不了,不能用事务 + if (!empty($industry->diyForm->fields)) { + $form->divider(); + $fields = $industry->diyForm->fields->toArray(); + foreach ($fields as $v) { + if ($v['type'] == 'radio' || $v['type'] == 'checkbox') { + $form->{$v['type']}('info.' . $v['field'])->options($v['options'])->required((bool)$v['required']); + } else { + $form->{$v['type']}('info.' . $v['field'])->required((bool)$v['required']); + } + } + } + $form->divider(); $form->text('', '购买产品')->default($industry->title)->disable(); $form->text('', '单价')->default($industry->price)->disable(); @@ -297,16 +311,20 @@ JS $form->timeout = null; if ($form->pay_type == PayType::DEPOSIT_PAY) { - $form->prepay_price = $industry->deposit; + $form->prepay_price = $industry->deposit * $form->num; } else if ($form->pay_type == PayType::EARNEST_PAY) { - $form->prepay_price = $industry->earnest; + $form->prepay_price = $industry->earnest * $form->num; } else { $form->prepay_price = 0; } + + //产品规格表减库存 + $spec->stock = $spec->stock - $form->num; + $spec->save(); })->saved(function (Form $form) { return $form->response()->success('下单成功,请等待供应商审核订单')->redirect(admin_url('industry_order/list')); })->deleting(function (Form $form) { return $form->response()->error('操作禁止'); }); - } + }*/ } diff --git a/app/AdminAgent/Controllers/IndustryProductController.php b/app/AdminAgent/Controllers/IndustryProductController.php index 4654036..a66771a 100644 --- a/app/AdminAgent/Controllers/IndustryProductController.php +++ b/app/AdminAgent/Controllers/IndustryProductController.php @@ -2,11 +2,15 @@ namespace App\AdminAgent\Controllers; +use App\AdminAgent\Forms\IndustryProductBuy; use App\AdminAgent\Repositories\IndustryProduct; use App\Common\ProductStatus; +use Dcat\Admin\Admin; use Dcat\Admin\Grid; +use Dcat\Admin\Layout\Content; use Dcat\Admin\Show; use Dcat\Admin\Http\Controllers\AdminController; +use Dcat\Admin\Widgets\Card; class IndustryProductController extends AdminController { @@ -41,7 +45,7 @@ class IndustryProductController extends AdminController ->if(fn() => true) ->then(function ($column) { $column->append('查看  '); - $column->append('购买'); + $column->append('购买'); }); $grid->filter(function (Grid\Filter $filter) { @@ -84,4 +88,16 @@ class IndustryProductController extends AdminController $show->field('updated_at'); }); } + + //购买行业产品 + public function buy(Content $content): Content + { + $pid = request()->input('pid'); + if (!$pid) { + Admin::exit('未指定要购买的产品'); + } + return $content + ->title('购买行业产品') + ->body(new Card(new IndustryProductBuy())); + } } diff --git a/app/AdminAgent/Forms/IndustryProductBuy.php b/app/AdminAgent/Forms/IndustryProductBuy.php new file mode 100644 index 0000000..2245526 --- /dev/null +++ b/app/AdminAgent/Forms/IndustryProductBuy.php @@ -0,0 +1,200 @@ +input('pid'); + + $industry = IndustryProduct::where([ + ['status', '=', ProductStatus::ON_SALE], + ['stock', '>', 0], + ])->find($pid); + if (!$industry) { + return $this->response()->error('产品不存在或已下架'); + } + + //最小起购数 + if ($input['num'] < $industry->min_sale) { + return $this->response()->error('购买数量不能小于最低起购数:' . $industry->min_sale); + } + + //产品规格 + $spec = IndustryProductSpec::where([ + ['industry_product_id', '=', $industry->id], + ['stock', '>=', $input['num']], + ])->find($input['industry_product_spec_id']); + if (!$spec) { + return $this->response()->error('产品规格不存在或库存不足'); + } + + //生成订单号 + list($micro, $sec) = explode(' ', microtime()); + $micro = str_pad(floor($micro * 1000000), 6, 0, STR_PAD_LEFT); + $order_no = date('ymdHis', $sec) . $micro . mt_rand(1000, 9999); + + DB::beginTransaction(); + try { + //规格减库存 + $allow_row = IndustryProductSpec::where([ + ['id', '=', $spec->id], + ['stock', '>=', $input['num']], + ])->decrement('stock', $input['num']); + if (!$allow_row) { + throw new \Exception('产品规格库存不足!'); + } + + //产品表减库存 + $industry->stock = $industry->stock - $input['num']; + $industry->save(); + + if ($input['pay_type'] == PayType::DEPOSIT_PAY) { + $prepay_price = $industry->deposit * $input['num']; + } else if ($input['pay_type'] == PayType::EARNEST_PAY) { + $prepay_price = $industry->earnest * $input['num']; + } else { + $prepay_price = 0; + } + + $order = IndustryOrder::create([ + 'agent_id' => Admin::user()->id, + 'supplier_id' => $industry->supplier_id, + 'order_no' => $order_no, + 'industry_product_id' => $industry->id, + 'industry_product_spec_id' => $input['industry_product_spec_id'], + 'num' => $input['num'], + 'price' => $input['num'] * $spec['price'], + 'name' => $input['name'], + 'mobile' => $input['mobile'], + 'title' => $industry->title, + 'picture' => $industry->pictures[0] ?? '', + 'status' => $input['pay_type'] == PayType::OFFLINE ? OrderStatus::OFFLINE_UNPAID : OrderStatus::UNPAID, + 'pay_type' => $input['pay_type'], + 'paid_money' => 0, + 'paid_at' => null, + 'trade_deposit' => $industry->single_deposit * $input['num'], + 'timeout' => null, + 'created_at' => now(), + 'prepay_price' => $prepay_price, + 'single_price' => $industry->single_deposit, + 'info' => json_encode($input['info']), + ]); + + DB::commit(); + return $this->response()->success('购买成功!')->redirect('industry_order/list/' . $order->id); + } catch (\Exception $e) { + DB::rollBack(); + return $this->response()->error($e->getMessage()); + } + } + + /** + * Build a form here. + */ + public function form() + { + //处理图片上传 + $_file = request()->file('_file_'); + if ($_file && $_file->isValid()) { + $this->image(request()->input('upload_column'))->uniqueName()->saveFullUrl(); + return true; + } + + $pid = request()->input('pid'); + $industry = IndustryProduct::with('diyForm.fields') + ->where([ + ['status', '=', ProductStatus::ON_SALE], + ['stock', '>', 0], + ])->find($pid); + + if (!$industry) { + return $this->response()->error('产品不存在或已下架'); + } + Admin::translation('industry-order'); + + $this->selectTable('industry_product_spec_id', '选择产品规格') + ->required() + ->title('选择产品规格') + ->dialogWidth('80%;min-width:825px;') + ->from(SelectIndustryProductSpec::make(['industry_product_id' => $pid])) + ->model(IndustryProductSpec::class); + + //购买人信息 + $this->hidden('pid')->value($industry->id); //pid要跟上面的request中的一样,否则提交出错 + $this->number('num')->min($industry->min_sale)->required()->default($industry->min_sale); + $this->text('name', '您的姓名')->default(Admin::user()->director)->required(); + $this->mobile('mobile', '您的手机号')->default(Admin::user()->contact_phone)->required(); + + //支付信息 + $pay_type = [PayType::ONLINE, PayType::OFFLINE]; + if ((float)$industry->deposit) { //订金支付 + $pay_type = [...$pay_type, PayType::DEPOSIT_PAY]; + } + if ((float)$industry->earnest) { //定金支付 + $pay_type = [...$pay_type, PayType::EARNEST_PAY]; + } + $options = array_filter(PayType::array(), fn($k) => in_array($k, $pay_type), ARRAY_FILTER_USE_KEY); + $this->select('pay_type') + ->options($options)->default(PayType::ONLINE)->required() + ->when(PayType::DEPOSIT_PAY, function () use ($industry) { + $this->display('deposit', '订金')->customFormat(fn() => $industry->deposit); + })->when(PayType::EARNEST_PAY, function () use ($industry) { + $this->display('earnest', '定金')->customFormat(fn() => $industry->earnest); + }); + + //信息收集表单 + if (!empty($industry->diyForm->fields)) { + $this->html(Alert::make(null, '客户信息收集表单')->warning())->width(12); + $fields = $industry->diyForm->fields->toArray(); + foreach ($fields as $v) { + if ($v['type'] == 'radio' || $v['type'] == 'checkbox') { + $this->{$v['type']}('info.' . $v['field'])->options(array_combine($v['options'], $v['options']))->required((bool)$v['required']); + } else if ($v['type'] == 'image') { + $this->image('info.' . $v['field'])->uniqueName()->saveFullUrl()->required((bool)$v['required']); + } else { + $this->{$v['type']}('info.' . $v['field'])->required((bool)$v['required']); + } + } + } + + $this->html(Alert::make(null, '产品信息')->info())->width(12); + $this->text('', '购买产品')->default($industry->title)->disable(); + $this->text('', '单价')->default($industry->price)->disable(); + $this->text('', '库存')->default($industry->stock)->disable(); + $this->text('', '起购数量')->default($industry->min_sale)->disable(); + $this->image('picture', '产品图')->default($industry->pictures)->disable(); + $this->display('', '旅游须知')->default(fn() => preg_replace('/.*?<\/script>/is', '', $industry->know))->disable(); + $this->display('', '产品详情')->default(fn() => preg_replace('/.*?<\/script>/is', '', $industry->content))->disable(); + } + + /** + * The data of the form. + * + * @return array + */ + public function default() + { + return []; + } +} diff --git a/app/AdminAgent/routes.php b/app/AdminAgent/routes.php index 76f104c..f340f54 100644 --- a/app/AdminAgent/routes.php +++ b/app/AdminAgent/routes.php @@ -24,6 +24,7 @@ Route::group([ $router->resource('special/list', 'SpecialController'); $router->resource('industry_product/list', 'IndustryProductController'); + $router->get('industry_product/buy', 'IndustryProductController@buy'); $router->resource('industry_order/list', 'IndustryOrderController'); $router->get('industry_order/qrcode/{verify_code}', 'IndustryOrderController@qrcode'); diff --git a/app/Models/IndustryOrder.php b/app/Models/IndustryOrder.php index 86d243b..e199fdc 100644 --- a/app/Models/IndustryOrder.php +++ b/app/Models/IndustryOrder.php @@ -10,6 +10,8 @@ class IndustryOrder extends BaseModel use HasDateTimeFormatter; use SoftDeletes; + protected $guarded = ['id']; + public function supplier() { return $this->belongsTo(Supplier::class)->withTrashed(); diff --git a/resources/lang/zh_CN/industry-order.php b/resources/lang/zh_CN/industry-order.php index e0c5a73..aa01256 100644 --- a/resources/lang/zh_CN/industry-order.php +++ b/resources/lang/zh_CN/industry-order.php @@ -4,6 +4,8 @@ return [ 'IndustryOrder' => '行业产品订单', 'industry-order' => '行业产品订单', 'industry_order' => '行业产品订单', + 'industry_product' => '行业产品', + 'buy' => '购买', ], 'fields' => [ 'supplier_id' => '供应商ID', From ec098be8fed7ac6c8fa351217af3de96909d57f9 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 10:55:07 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E6=9C=AA=E8=AE=BE=E7=BD=AE=E4=BA=A4?= =?UTF-8?q?=E6=98=93=E9=87=91=E5=8D=95=E4=BB=B7=EF=BC=8C=E5=B0=86=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E7=BD=AE=E4=B8=BA=E6=9C=AA=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/AdminSupplier/Controllers/IndustryProductController.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/AdminSupplier/Controllers/IndustryProductController.php b/app/AdminSupplier/Controllers/IndustryProductController.php index 1281d06..a722a48 100644 --- a/app/AdminSupplier/Controllers/IndustryProductController.php +++ b/app/AdminSupplier/Controllers/IndustryProductController.php @@ -292,6 +292,10 @@ class IndustryProductController extends AdminController if (in_array($form->model()->status, $user_status) && !is_null($form->status) && $form->status == 0) { $form->status = ProductStatus::SOLD_OUT; } + //交易金单价未设置不允许上架,状态改为未审核 + else if ((float)$form->model()->single_deposit <= 0) { + $form->status = ProductStatus::UNAUDITED; + } //非用户可编辑状态不允许修改 else if (!in_array($form->model()->status, $user_status) || !in_array($form->status, $user_status)) { $form->deleteInput('status'); From 21444fb81e71351455be43035706e24095211e00 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 11:07:07 +0800 Subject: [PATCH 03/14] industry_product_id --- app/Http/Controllers/IndustryProductWxpay.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/IndustryProductWxpay.php b/app/Http/Controllers/IndustryProductWxpay.php index 88f77e3..6c5638f 100644 --- a/app/Http/Controllers/IndustryProductWxpay.php +++ b/app/Http/Controllers/IndustryProductWxpay.php @@ -70,7 +70,7 @@ class IndustryProductWxpay try { //增加销量,库存在拍下时已经减了 IndustryProduct::query() - ->where('id', $order->product_id) + ->where('id', $order->industry_product_id) ->increment('sale', $order->num); $old_status = $order->status; @@ -123,7 +123,7 @@ class IndustryProductWxpay $fail('Unknown error 2'); }); } catch (InvalidSignException | Exception $e) { - return 'error' . $e->getFile() . $e->getMessage() . $e->getLine(); + return 'error'; } return $response; From c815a4f3155c38884f1532646a6340f247658703 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 11:11:14 +0800 Subject: [PATCH 04/14] supplier_id --- app/Http/Controllers/IndustryProductWxpay.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/IndustryProductWxpay.php b/app/Http/Controllers/IndustryProductWxpay.php index 6c5638f..61b11d1 100644 --- a/app/Http/Controllers/IndustryProductWxpay.php +++ b/app/Http/Controllers/IndustryProductWxpay.php @@ -96,8 +96,8 @@ class IndustryProductWxpay //资金流水 IndustryPayLog::create([ - 'user_id' => $order->user_id, 'agent_id' => $order->agent_id, + 'supplier_id' => $order->supplier_id, 'money' => $money, 'industry_order_id' => $order->id, 'type' => 1, From 01ca7e338bd9301b68c8e1c3127e9205087d2cc8 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 11:17:16 +0800 Subject: [PATCH 05/14] debug --- app/Http/Controllers/IndustryProductWxpay.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Http/Controllers/IndustryProductWxpay.php b/app/Http/Controllers/IndustryProductWxpay.php index 61b11d1..7c723c7 100644 --- a/app/Http/Controllers/IndustryProductWxpay.php +++ b/app/Http/Controllers/IndustryProductWxpay.php @@ -12,6 +12,7 @@ use EasyWeChat\Factory; use EasyWeChat\Kernel\Exceptions\Exception; use EasyWeChat\Payment\Kernel\Exceptions\InvalidSignException; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; /** * 行业产品微信支付回调 @@ -123,6 +124,7 @@ class IndustryProductWxpay $fail('Unknown error 2'); }); } catch (InvalidSignException | Exception $e) { + LOG::debug('行业产品支付', [$e->getFile(), $e->getLine(), $e->getMessage()]); return 'error'; } From 419345352baed5c190beaf56abb3f2d5ed6905e2 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 11:42:25 +0800 Subject: [PATCH 06/14] =?UTF-8?q?switch=E6=97=A0=E9=9C=80=E5=BF=85?= =?UTF-8?q?=E5=A1=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/AdminSupplier/Controllers/DiyFormController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/AdminSupplier/Controllers/DiyFormController.php b/app/AdminSupplier/Controllers/DiyFormController.php index 1f2a29f..aa39904 100644 --- a/app/AdminSupplier/Controllers/DiyFormController.php +++ b/app/AdminSupplier/Controllers/DiyFormController.php @@ -94,7 +94,7 @@ class DiyFormController extends AdminController $form->text('name')->required(); $form->hasMany('fields', function (Form\NestedForm $form) { $form->text('field', '字段名称')->required(); - $form->switch('required', '是否必填')->default(1)->required(); + $form->switch('required', '是否必填')->default(1); $form->radio2('type', '字段类型') ->required()->default('text') ->options(admin_trans('diy-form.options')) From 51ac463443423d967b1ade8b7b6c7750fb2aee55 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 12:03:10 +0800 Subject: [PATCH 07/14] =?UTF-8?q?=E4=BF=AE=E6=94=B9paid=5Fat=20label?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/AdminAgent/Controllers/IndustryOrderController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/AdminAgent/Controllers/IndustryOrderController.php b/app/AdminAgent/Controllers/IndustryOrderController.php index 597aee4..749445f 100644 --- a/app/AdminAgent/Controllers/IndustryOrderController.php +++ b/app/AdminAgent/Controllers/IndustryOrderController.php @@ -49,7 +49,7 @@ class IndustryOrderController extends AdminController ->display(fn() => '付款') ->if(fn() => $this->status == OrderStatus::PAY_EARNEST) ->display(fn() => '付尾款'); - $grid->column('paid_at', '订单确认时间'); + $grid->column('paid_at'); $grid->column('verify_qrcode', '核销二维码') ->if(fn() => $this->verify_code) ->then(function ($column) { From a82829a8024336c189fd6b08084e4d2ab231adce Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 12:32:02 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=9A=E9=87=91/?= =?UTF-8?q?=E8=AE=A2=E9=87=91=E6=94=AF=E4=BB=98=E4=BB=B7=E6=A0=BC=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/AdminAgent/Controllers/IndustryOrderController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/AdminAgent/Controllers/IndustryOrderController.php b/app/AdminAgent/Controllers/IndustryOrderController.php index 749445f..0eab28c 100644 --- a/app/AdminAgent/Controllers/IndustryOrderController.php +++ b/app/AdminAgent/Controllers/IndustryOrderController.php @@ -185,6 +185,8 @@ JS //计算价格 if ($order->status == OrderStatus::PAY_EARNEST) { $price = $order->price - $order->paid_money; + } elseif (in_array($order->pay_type, [PayType::DEPOSIT_PAY, PayType::EARNEST_PAY])) { + $price = $order->prepay_price; } else { $price = $order->price; } From bdc144e95fe4e6213c799f32e2e50c1d69d7e904 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 13:18:58 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E5=A4=84=E7=90=86=E5=B7=B2=E4=BB=98?= =?UTF-8?q?=E5=AE=9A=E9=87=91/=E8=AE=A2=E9=87=91=E7=9A=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/IndustryOrderController.php | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/AdminAgent/Controllers/IndustryOrderController.php b/app/AdminAgent/Controllers/IndustryOrderController.php index 0eab28c..656a89e 100644 --- a/app/AdminAgent/Controllers/IndustryOrderController.php +++ b/app/AdminAgent/Controllers/IndustryOrderController.php @@ -41,7 +41,7 @@ class IndustryOrderController extends AdminController $grid->column('price'); $grid->column('name', '预留姓名'); $grid->column('mobile', '预留手机'); - $grid->column('title'); + $grid->column('title')->limit(15); $grid->column('picture')->image('', 80, 80); $grid->column('status') ->using(OrderStatus::array()) @@ -137,23 +137,31 @@ class IndustryOrderController extends AdminController } Admin::script("Dcat.swal.info('支付:$msg', null);"); } else { + $status_text = $show->model()->status == OrderStatus::PAY_EARNEST ? + '\'当前状态:'.OrderStatus::array()[$show->model()->status].'\'' + : 'null'; + $back_url = admin_url('industry_order/list'); Admin::js('@qrcode'); Admin::script(<<', $status_text, { type: null, - html: '
', imageWidth: 240, imageHeight: 240, animation: false, - confirmButtonText: '我已支付,刷新页面', + confirmButtonText: '已支付,刷新', + showCancelButton: true, + cancelButtonText: '返回列表', allowOutsideClick: false, allowEscapeKey: false, onOpen: function () { $('#qrcode').qrcode({text:'{$pay_config['code_url']}', width:240, height:240}); - }, - onClose: function() { - window.location.reload(); } +}).then((res) => { + if (res.dismiss === 'cancel') { + window.location.href = '$back_url'; + } else { + window.location.reload(); + } }); JS ); From 56f9b39e489db8576ddde664fe026455c8527a5d Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 13:21:53 +0800 Subject: [PATCH 10/14] where --- app/AdminAgent/Controllers/IndustryOrderController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/AdminAgent/Controllers/IndustryOrderController.php b/app/AdminAgent/Controllers/IndustryOrderController.php index 656a89e..5f356ed 100644 --- a/app/AdminAgent/Controllers/IndustryOrderController.php +++ b/app/AdminAgent/Controllers/IndustryOrderController.php @@ -33,8 +33,10 @@ class IndustryOrderController extends AdminController $grid->disableCreateButton(); $grid->disableActions(); + $grid->model()->where('agent_id', Admin::user()->id); + $grid->column('id')->sortable(); - $grid->column('supplier.company_name', '供应商'); + $grid->column('supplier.company_name', '供应商')->limit(10); $grid->column('supplier.contact_phone', '供应商电话'); $grid->column('order_no')->limit(10); $grid->column('num'); From dd75a819d4dada7ee61017ef0bc3b8fbb1c3fb29 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 13:35:00 +0800 Subject: [PATCH 11/14] =?UTF-8?q?info=20json=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/AdminAgent/Forms/IndustryProductBuy.php | 2 +- app/Models/IndustryOrder.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/AdminAgent/Forms/IndustryProductBuy.php b/app/AdminAgent/Forms/IndustryProductBuy.php index 2245526..2cfd15a 100644 --- a/app/AdminAgent/Forms/IndustryProductBuy.php +++ b/app/AdminAgent/Forms/IndustryProductBuy.php @@ -98,7 +98,7 @@ class IndustryProductBuy extends Form 'created_at' => now(), 'prepay_price' => $prepay_price, 'single_price' => $industry->single_deposit, - 'info' => json_encode($input['info']), + 'info' => $input['info'], ]); DB::commit(); diff --git a/app/Models/IndustryOrder.php b/app/Models/IndustryOrder.php index e199fdc..c0072f1 100644 --- a/app/Models/IndustryOrder.php +++ b/app/Models/IndustryOrder.php @@ -10,6 +10,7 @@ class IndustryOrder extends BaseModel use HasDateTimeFormatter; use SoftDeletes; + protected $casts = ['info' => 'json']; protected $guarded = ['id']; public function supplier() From 1b52701e69b84cd1e8002a900041ce70eb20e565 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 13:52:41 +0800 Subject: [PATCH 12/14] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ready.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ready.md b/ready.md index f24394a..a6a238f 100644 --- a/ready.md +++ b/ready.md @@ -24,9 +24,13 @@ TRUNCATE `demand`; TRUNCATE `demand_bidding`; TRUNCATE `demand_products`; TRUNCATE `deposit_log`; +TRUNCATE `diy_forms`; +TRUNCATE `diy_form_fields`; TRUNCATE `guides`; TRUNCATE `industry_orders`; +TRUNCATE `industry_pay_logs`; TRUNCATE `industry_products`; +TRUNCATE `industry_product_specs`; TRUNCATE `messages`; TRUNCATE `message_reads`; TRUNCATE `mini_program_drafts`; From b202cd1fa62ce135422780da0f5d980c15dd3145 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 13:52:50 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=94=B6=E9=9B=86?= =?UTF-8?q?=E8=A1=A8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/IndustryOrderController.php | 156 +++--------------- app/AdminAgent/Forms/IndustryProductBuy.php | 29 +++- .../Controllers/IndustryOrderController.php | 21 +++ 3 files changed, 63 insertions(+), 143 deletions(-) diff --git a/app/AdminAgent/Controllers/IndustryOrderController.php b/app/AdminAgent/Controllers/IndustryOrderController.php index 5f356ed..96e4ff1 100644 --- a/app/AdminAgent/Controllers/IndustryOrderController.php +++ b/app/AdminAgent/Controllers/IndustryOrderController.php @@ -2,19 +2,15 @@ namespace App\AdminAgent\Controllers; -use App\AdminAgent\Renderable\SelectIndustryProductSpec; use App\AdminAgent\Repositories\IndustryOrder; use App\Common\OrderStatus; use App\Common\PayType; -use App\Common\ProductStatus; use App\Models\AdminSetting; -use App\Models\IndustryProduct; -use App\Models\IndustryProductSpec; use Dcat\Admin\Admin; -use Dcat\Admin\Form; use Dcat\Admin\Grid; use Dcat\Admin\Show; use Dcat\Admin\Http\Controllers\AdminController; +use Dcat\Admin\Widgets\Table; use EasyWeChat\Factory; use EasyWeChat\Kernel\Http\StreamResponse; use Illuminate\Support\Facades\Storage; @@ -43,6 +39,26 @@ class IndustryOrderController extends AdminController $grid->column('price'); $grid->column('name', '预留姓名'); $grid->column('mobile', '预留手机'); + $grid->column('info', '客户信息') + ->display('查看') + ->modal('客户信息', function ($modal) { + $info = $this->info ?? []; + $info = array_map(function($v) { + if (isset($v['value'], $v['type'])) { + if ($v['type'] == 'image') { + if (is_array($v['value'])) { + return array_reduce($v['value'], fn($v2, $v3) => $v2 . '  '); + } else { + return ''; + } + } else { + return is_string($v['value']) ? $v['value'] : join(',', $v['value']); + } + } + return is_string($v) ? $v : json_encode($v); + }, $info); + return Table::make([], $info); + })->xl(); $grid->column('title')->limit(15); $grid->column('picture')->image('', 80, 80); $grid->column('status') @@ -209,134 +225,4 @@ JS 'trade_type' => 'NATIVE', // 请对应换成你的支付方式对应的值类型 ]); } - - /** - * Make a form builder. - * - * @return Form - */ - /*protected function form() - { - $pid = request()->input('pid'); - $industry = IndustryProduct::with('diyForm.fields') - ->where([ - ['status', '=', ProductStatus::ON_SALE], - ['stock', '>', 0], - ])->find($pid); - - return Form::make(new IndustryOrder(), function (Form $form) use ($industry) { - if (!$industry) { - Admin::exit('订单不允许编辑'); - } - - $form->selectTable('industry_product_spec_id', '选择产品规格') - ->required() - ->title('选择产品规格') - ->dialogWidth('80%;min-width:825px;') - ->from(SelectIndustryProductSpec::make(['industry_product_id' => request()->input('pid')])) - ->model(IndustryProductSpec::class); - - $form->hidden('pid')->value($industry->id); //pid要跟上面的request中的一样,否则提交出错 - $form->number('num') - ->min($industry->min_sale)->required() - ->default($industry->min_sale); - $form->text('name')->default(Admin::user()->director)->required(); - $form->mobile('mobile')->default(Admin::user()->contact_phone)->required(); - - $pay_type = [PayType::ONLINE, PayType::OFFLINE]; - if ($industry->deposit) { //订金支付 - $pay_type = [...$pay_type, PayType::DEPOSIT_PAY]; - } - if ($industry->earnest) { //定金支付 - $pay_type = [...$pay_type, PayType::EARNEST_PAY]; - } - $options = array_filter(PayType::array(), fn($k) => in_array($k, $pay_type), ARRAY_FILTER_USE_KEY); - $form->select('pay_type')->options($options)->default(PayType::ONLINE)->required(); - - //信息收集表单 TODO 信息收集表单文件上传不了,不能用事务 - if (!empty($industry->diyForm->fields)) { - $form->divider(); - $fields = $industry->diyForm->fields->toArray(); - foreach ($fields as $v) { - if ($v['type'] == 'radio' || $v['type'] == 'checkbox') { - $form->{$v['type']}('info.' . $v['field'])->options($v['options'])->required((bool)$v['required']); - } else { - $form->{$v['type']}('info.' . $v['field'])->required((bool)$v['required']); - } - } - } - - $form->divider(); - $form->text('', '购买产品')->default($industry->title)->disable(); - $form->text('', '单价')->default($industry->price)->disable(); - $form->text('', '库存')->default($industry->stock)->disable(); - $form->text('', '起购数量')->default($industry->min_sale)->disable(); - $form->image('picture', '产品图')->default($industry->pictures)->disable(); - $form->display('', '旅游须知')->default(fn() => preg_replace('/.*?<\/script>/is', '', $industry->know))->disable(); - $form->display('', '产品详情')->default(fn() => preg_replace('/.*?<\/script>/is', '', $industry->content))->disable(); - })->saving(function (Form $form) use ($industry) { - //禁止编辑 - if ($form->isEditing()) { - return $form->response()->error('操作禁止'); - } - - //判断最小起购数 - if ($form->num < $industry->min_sale) { - return $form->response()->error('购买数量不能小于最低起购数:' . $industry->min_sale); - } - - //判断产品状态和库存 - if (!$industry || $industry->status != ProductStatus::ON_SALE || $industry->stock < $form->num) { - return $form->response()->error('产品已下架或库存不足'); - } - - //生成订单号 - list($micro, $sec) = explode(' ', microtime()); - $micro = str_pad(floor($micro * 1000000), 6, 0, STR_PAD_LEFT); - $order_no = date('ymdHis', $sec) . $micro . mt_rand(1000, 9999); - - //产品规格处理 - $spec = IndustryProductSpec::where('industry_product_id', $form->pid)->find($form->industry_product_spec_id); - if (!$spec) { - return $form->response()->error('您选择的产品规格不存在'); - } - - $form->deleteInput(['pid', 'picture']); - - $form->hidden(['industry_product_id', 'supplier_id', 'agent_id', 'order_no', 'price', 'title', 'picture', 'status', 'pay_type', 'paid_at', 'verify_code', 'trade_deposit', 'timeout']); - - $form->name = $form->name ?? Admin::user()->director; - $form->mobile = $form->mobile ?? Admin::user()->contact_phone; - - $form->industry_product_id = $industry->id; - $form->supplier_id = $industry->supplier_id; - $form->agent_id = Admin::user()->id; - $form->order_no = $order_no; - $form->price = $form->num * $spec->price; - $form->title = $industry->title; - $form->picture = $industry->pictures[0] ?? '' ; - $form->status = $form->pay_type == PayType::OFFLINE ? OrderStatus::OFFLINE_UNPAID : OrderStatus::UNPAID; - $form->paid_at = null; - $form->verify_code = ''; - $form->trade_deposit = $form->num * $industry->single_deposit; - $form->single_price = $industry->single_deposit; - $form->timeout = null; - - if ($form->pay_type == PayType::DEPOSIT_PAY) { - $form->prepay_price = $industry->deposit * $form->num; - } else if ($form->pay_type == PayType::EARNEST_PAY) { - $form->prepay_price = $industry->earnest * $form->num; - } else { - $form->prepay_price = 0; - } - - //产品规格表减库存 - $spec->stock = $spec->stock - $form->num; - $spec->save(); - })->saved(function (Form $form) { - return $form->response()->success('下单成功,请等待供应商审核订单')->redirect(admin_url('industry_order/list')); - })->deleting(function (Form $form) { - return $form->response()->error('操作禁止'); - }); - }*/ } diff --git a/app/AdminAgent/Forms/IndustryProductBuy.php b/app/AdminAgent/Forms/IndustryProductBuy.php index 2cfd15a..b1d9257 100644 --- a/app/AdminAgent/Forms/IndustryProductBuy.php +++ b/app/AdminAgent/Forms/IndustryProductBuy.php @@ -27,7 +27,7 @@ class IndustryProductBuy extends Form { $pid = request()->input('pid'); - $industry = IndustryProduct::where([ + $industry = IndustryProduct::with('diyForm')->where([ ['status', '=', ProductStatus::ON_SALE], ['stock', '>', 0], ])->find($pid); @@ -49,6 +49,19 @@ class IndustryProductBuy extends Form return $this->response()->error('产品规格不存在或库存不足'); } + //信息收集表处理,保留字段类型等信息,便于后台显示 + $order_info = $input['info'] ?? []; + if (!empty($industry->diyForm->fields) && !$industry->diyForm->fields->isEmpty()) { + $fields = array_column($industry->diyForm->fields->toArray(), null, 'field'); + foreach ($fields as &$field) { + if ($field['required'] && !isset($order_info[$field['field']])) { //判断是否必填 + return $this->error($field['field'] . '不能为空'); + } + $field['value'] = $order_info[$field['field']] ?? ''; + } + $order_info = $fields; + } + //生成订单号 list($micro, $sec) = explode(' ', microtime()); $micro = str_pad(floor($micro * 1000000), 6, 0, STR_PAD_LEFT); @@ -57,11 +70,11 @@ class IndustryProductBuy extends Form DB::beginTransaction(); try { //规格减库存 - $allow_row = IndustryProductSpec::where([ + $affect_row = IndustryProductSpec::where([ ['id', '=', $spec->id], ['stock', '>=', $input['num']], ])->decrement('stock', $input['num']); - if (!$allow_row) { + if (!$affect_row) { throw new \Exception('产品规格库存不足!'); } @@ -98,11 +111,11 @@ class IndustryProductBuy extends Form 'created_at' => now(), 'prepay_price' => $prepay_price, 'single_price' => $industry->single_deposit, - 'info' => $input['info'], + 'info' => $order_info, ]); DB::commit(); - return $this->response()->success('购买成功!')->redirect('industry_order/list/' . $order->id); + return $this->response()->success('购买成功,正在前往支付页面')->redirect('industry_order/list/' . $order->id); } catch (\Exception $e) { DB::rollBack(); return $this->response()->error($e->getMessage()); @@ -117,7 +130,7 @@ class IndustryProductBuy extends Form //处理图片上传 $_file = request()->file('_file_'); if ($_file && $_file->isValid()) { - $this->image(request()->input('upload_column'))->uniqueName()->saveFullUrl(); + $this->multipleImage(request()->input('upload_column'))->uniqueName()->saveFullUrl(); return true; } @@ -171,7 +184,7 @@ class IndustryProductBuy extends Form if ($v['type'] == 'radio' || $v['type'] == 'checkbox') { $this->{$v['type']}('info.' . $v['field'])->options(array_combine($v['options'], $v['options']))->required((bool)$v['required']); } else if ($v['type'] == 'image') { - $this->image('info.' . $v['field'])->uniqueName()->saveFullUrl()->required((bool)$v['required']); + $this->multipleImage('info.' . $v['field'])->uniqueName()->saveFullUrl()->required((bool)$v['required']); } else { $this->{$v['type']}('info.' . $v['field'])->required((bool)$v['required']); } @@ -183,7 +196,7 @@ class IndustryProductBuy extends Form $this->text('', '单价')->default($industry->price)->disable(); $this->text('', '库存')->default($industry->stock)->disable(); $this->text('', '起购数量')->default($industry->min_sale)->disable(); - $this->image('picture', '产品图')->default($industry->pictures)->disable(); + $this->multipleImage('pictures', '产品图')->default($industry->pictures)->disable(); $this->display('', '旅游须知')->default(fn() => preg_replace('/.*?<\/script>/is', '', $industry->know))->disable(); $this->display('', '产品详情')->default(fn() => preg_replace('/.*?<\/script>/is', '', $industry->content))->disable(); } diff --git a/app/AdminSupplier/Controllers/IndustryOrderController.php b/app/AdminSupplier/Controllers/IndustryOrderController.php index 98e4308..6438a6c 100644 --- a/app/AdminSupplier/Controllers/IndustryOrderController.php +++ b/app/AdminSupplier/Controllers/IndustryOrderController.php @@ -10,6 +10,7 @@ use Dcat\Admin\Form; use Dcat\Admin\Grid; use Dcat\Admin\Show; use Dcat\Admin\Http\Controllers\AdminController; +use Dcat\Admin\Widgets\Table; class IndustryOrderController extends AdminController { @@ -34,6 +35,26 @@ class IndustryOrderController extends AdminController $grid->column('price'); $grid->column('name'); $grid->column('mobile'); + $grid->column('info', '客户信息') + ->display('查看') + ->modal('客户信息', function ($modal) { + $info = $this->info ?? []; + $info = array_map(function($v) { + if (isset($v['value'], $v['type'])) { + if ($v['type'] == 'image') { + if (is_array($v['value'])) { + return array_reduce($v['value'], fn($v2, $v3) => $v2 . '  '); + } else { + return ''; + } + } else { + return is_string($v['value']) ? $v['value'] : join(',', $v['value']); + } + } + return is_string($v) ? $v : json_encode($v); + }, $info); + return Table::make([], $info); + })->xl(); $grid->column('industry_product_id', '产品ID'); $grid->column('title')->limit(15); $grid->column('picture')->image('', 60, 60); From 1247df8839f2632f770781ccb12dff5328fd3bb5 Mon Sep 17 00:00:00 2001 From: liapples Date: Mon, 18 Oct 2021 14:03:02 +0800 Subject: [PATCH 14/14] limit & label --- app/AdminSupplier/Controllers/IndustryOrderController.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/AdminSupplier/Controllers/IndustryOrderController.php b/app/AdminSupplier/Controllers/IndustryOrderController.php index 6438a6c..9c453d6 100644 --- a/app/AdminSupplier/Controllers/IndustryOrderController.php +++ b/app/AdminSupplier/Controllers/IndustryOrderController.php @@ -29,15 +29,15 @@ class IndustryOrderController extends AdminController $grid->model()->where('supplier_id', Admin::user()->id); $grid->column('id')->sortable(); - $grid->column('agent.company_name', '代理商名称'); - $grid->column('order_no'); + $grid->column('agent.company_name', '代理商名称')->limit(10); + $grid->column('order_no')->limit(10); $grid->column('num'); $grid->column('price'); $grid->column('name'); $grid->column('mobile'); - $grid->column('info', '客户信息') + $grid->column('info', '信息收集') ->display('查看') - ->modal('客户信息', function ($modal) { + ->modal('信息收集', function ($modal) { $info = $this->info ?? []; $info = array_map(function($v) { if (isset($v['value'], $v['type'])) {