From 1cf64baf95720678b3ec4b12bcded0aa7437a1df Mon Sep 17 00:00:00 2001 From: hant Date: Sun, 18 May 2025 18:41:05 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=90=E8=90=A5=E8=A1=A5=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/supplement/Orders.php | 241 ++++++++++++++++++ .../admin/lang/zh-cn/supplement/orders.php | 27 ++ application/admin/model/supplement/Orders.php | 51 ++++ .../admin/validate/supplement/Orders.php | 27 ++ .../admin/view/supplement/orders/add.html | 98 +++++++ .../admin/view/supplement/orders/edit.html | 98 +++++++ .../admin/view/supplement/orders/index.html | 46 ++++ public/assets/js/backend/order.js | 2 +- public/assets/js/backend/supplement/orders.js | 134 ++++++++++ 9 files changed, 723 insertions(+), 1 deletion(-) create mode 100644 application/admin/controller/supplement/Orders.php create mode 100644 application/admin/lang/zh-cn/supplement/orders.php create mode 100644 application/admin/model/supplement/Orders.php create mode 100644 application/admin/validate/supplement/Orders.php create mode 100644 application/admin/view/supplement/orders/add.html create mode 100644 application/admin/view/supplement/orders/edit.html create mode 100644 application/admin/view/supplement/orders/index.html create mode 100644 public/assets/js/backend/supplement/orders.js diff --git a/application/admin/controller/supplement/Orders.php b/application/admin/controller/supplement/Orders.php new file mode 100644 index 0000000..2ce30b1 --- /dev/null +++ b/application/admin/controller/supplement/Orders.php @@ -0,0 +1,241 @@ +model = new \app\admin\model\supplement\Orders; + + + $sources = Db::name('source') + ->where('status', 1) + ->field(['id', 'title', 'key_word', 'pid']) + ->order('pid', 'asc') + ->order('sort', 'desc') + ->select(); + $this->sources = $sources; + $filtered = array_filter($sources, function ($item) { + return $item['pid'] == 0; + }); + + $pid_map = array_column($filtered, null, 'id'); + $res = []; + foreach ($sources as $item) { + if ($item['pid'] != 0 && isset($pid_map[$item['pid']])) { + $res [] = [ + ...$item, 'ptitle' => $pid_map[$item['pid']]['title'] + ]; + } + } + + $items = Db::name('item') + ->where('status', 1) + ->field(['id', 'title', 'key_word', 'pid']) + ->order('pid', 'asc') + ->order('sort', 'desc') + ->select(); + $tree = $this->buildTree($items); + $formattedTree = $this->formatTree($tree); + + $this->items = $items; + $this->itemsformattedTree = $formattedTree; + + + $this->view->assign("sources", $res); + $this->view->assign("items", $formattedTree); + + + $this->view->assign("statusList", $this->model->getStatusList()); + } + + public function index() + { + //设置过滤方法 + $this->request->filter(['strip_tags', 'trim']); + if (false === $this->request->isAjax()) { + return $this->view->fetch(); + } + //如果发送的来源是 Selectpage,则转发到 Selectpage + if ($this->request->request('keyField')) { + return $this->selectpage(); + } + [$where, $sort, $order, $offset, $limit] = $this->buildparams(); + + + $list = $this->model + ->where($where) + ->with(['user' => function ($q) { + $q->field('id,nickname'); + }, + 'area' => function ($q) { + $q->field('id,area_code,merge_name'); + }, + ]) + ->order($sort, $order) + ->paginate($limit); + $result = ['total' => $list->total(), 'rows' => $list->items()]; + return json($result); + } + + + /** + * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法 + * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑 + * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改 + */ + + + public function add() + { + if (false === $this->request->isPost()) { + return $this->view->fetch(); + } + $params = $this->request->post('row/a'); + if (empty($params)) { + $this->error(__('Parameter %s can not be empty', '')); + } + $params = $this->preExcludeFields($params); + + if ($this->dataLimit && $this->dataLimitFieldAutoFill) { + $params[$this->dataLimitField] = $this->auth->id; + } + $result = false; + Db::startTrans(); + try { + //是否采用模型验证 + if ($this->modelValidate) { + $name = str_replace("\\model\\", "\\validate\\", get_class($this->model)); + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate; + $this->model->validateFailException()->validate($validate); + } + + $sources = $this->sources; + $sources = array_column($sources, 'title', 'id'); + $params['source_name'] = $sources[$params['source']] ?? null; + $params['source_id'] = $params['source']; + + $params['item_name'] = $this->findElementByValue($this->itemsformattedTree, $params['item_id'] ?? null); + + + $params['admin_id'] = ($params['admin_id'] ?? -1) == -1 ? $this->auth->id : $params['admin_id']; + if (empty($params['admin_id'])) { + $params['admin_id'] = $this->auth->id; + } + $params['status'] = 0; + $params['created_at'] = date('Y-m-d H:i:s'); + $params['updated_at'] = date('Y-m-d H:i:s'); +// dd($params); + $result = $this->model->allowField(true)->save($params); + Db::commit(); + } catch (ValidateException | PDOException | Exception $e) { + Db::rollback(); + $this->error($e->getMessage()); + } + if ($result === false) { + $this->error(__('No rows were inserted')); + } + $this->success(); + } + + + function findElementByValue($data, $targetValue, $path = []) + { + foreach ($data as $item) { + // 将当前节点的 label 添加到路径中 + $newPath = array_merge($path, [$item['label']]); + + // 如果找到目标值,返回路径 + if ($item['value'] == $targetValue) { + return implode(' / ', $newPath); + } + + // 如果当前节点有 children,递归搜索 + if (isset($item['children']) && is_array($item['children'])) { + $result = $this->findElementByValue($item['children'], $targetValue, $newPath); + if ($result) { + return $result; + } + } + } + return null; // 如果找不到返回 null + } + + public function edit($ids = null) + { + if (!$ids) { + if (request()->isPost()) { + $ids = input('id'); + if (!$ids) { + $this->error('缺少订单ID'); + } + } else { + $this->error('缺少订单ID'); + } + } + + // 获取当前ID对应的订单信息 + $order = $this->model->get($ids); + if (!$order) { + $this->error('订单不存在'); + } + + // 判断是否为POST请求,进行更新操作 + if (request()->isPost()) { + // 获取表单提交的数据 + $params = input('post.row/a'); + + $sources = $this->sources; + $sources = array_column($sources, 'title', 'id'); + $params['source_name'] = $sources[$params['source']] ?? null; + $params['source_id'] = $params['source']; + + $params['item_name'] = $this->findElementByValue($this->itemsformattedTree, $params['item_id'] ?? null); + + unset($params['source']); + + $params['admin_id'] = ($params['admin_id'] ?? -1) == -1 ? $this->auth->id : $params['admin_id']; + if (empty($params['admin_id'])) { + $params['admin_id'] = $this->auth->id; + } + $params['updated_at'] = date('Y-m-d H:i:s'); + // 更新订单信息 + $order->save($params); + + // 返回成功信息 + $this->success('更新成功', 'index'); + } + $area = new \app\admin\model\Area(); + $area_name = $area->getNameByCode($order->area_id); + $order->area_name = str_replace(',', '/', $area_name); + + // 将订单数据传递到视图 + $this->assign('row', $order); + // 渲染编辑页面 + return $this->fetch(); + } + + +} diff --git a/application/admin/lang/zh-cn/supplement/orders.php b/application/admin/lang/zh-cn/supplement/orders.php new file mode 100644 index 0000000..5e4d602 --- /dev/null +++ b/application/admin/lang/zh-cn/supplement/orders.php @@ -0,0 +1,27 @@ + 'ID', + 'Area_id' => '区域 ID', + 'Area_name' => '地址', + 'Source_id' => '所属店铺 ID', + 'Source_name' => '所属店铺 ID', + 'Platform_order_no' => '平台订单编号', + 'Item_id' => '服务类型 ID', + 'Item_name' => '服务类型 ID', + 'Buyer_account' => '刷手账号', + 'Amount' => '支付金额', + 'Commission' => '刷单佣金', + 'Screenshots' => '截图 JSON(下单图、评价图等)', + 'Status' => '订单状态', + 'Status 0' => '待发货', + 'Set status to 0' => '设为待发货', + 'Status 1' => '待评价', + 'Set status to 1' => '设为待评价', + 'Status 2' => '评价超时', + 'Set status to 2' => '设为评价超时', + 'Admin_id' => '运营人员 ID', + 'Remark' => '备注信息', + 'Created_at' => '创建时间', + 'Updated_at' => '最后更新时间' +]; diff --git a/application/admin/model/supplement/Orders.php b/application/admin/model/supplement/Orders.php new file mode 100644 index 0000000..0a026df --- /dev/null +++ b/application/admin/model/supplement/Orders.php @@ -0,0 +1,51 @@ + __('Status 0'), '1' => __('Status 1'), '2' => __('Status 2'), '3' => '被驳回']; + } + + + public function getStatusTextAttr($value, $data) + { + $value = $value ?: ($data['status'] ?? ''); + $list = $this->getStatusList(); + return $list[$value] ?? ''; + } + + public function area(){ + return $this->belongsTo(Area::class,'area_id','area_code'); + } + public function user(){ + return $this->belongsTo(Admin::class,'admin_id'); + } + +} diff --git a/application/admin/validate/supplement/Orders.php b/application/admin/validate/supplement/Orders.php new file mode 100644 index 0000000..d233386 --- /dev/null +++ b/application/admin/validate/supplement/Orders.php @@ -0,0 +1,27 @@ + [], + 'edit' => [], + ]; + +} diff --git a/application/admin/view/supplement/orders/add.html b/application/admin/view/supplement/orders/add.html new file mode 100644 index 0000000..91573b3 --- /dev/null +++ b/application/admin/view/supplement/orders/add.html @@ -0,0 +1,98 @@ +
+ + +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+ + +
+ +
+
    +
    +
    + +
    + +
    + +
    + {foreach name="statusList" item="vo"} + + {/foreach} +
    + +
    +
    +
    + +
    + +
    +
    + +
    + + + \ No newline at end of file diff --git a/application/admin/view/supplement/orders/edit.html b/application/admin/view/supplement/orders/edit.html new file mode 100644 index 0000000..db21061 --- /dev/null +++ b/application/admin/view/supplement/orders/edit.html @@ -0,0 +1,98 @@ +
    + + +
    + +
    + +
    +
    + +
    + +
    + + +
    +
    + +
    + +
    + +
    +
    +
    + +
    + + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + +
    + + +
    + +
    +
      +
      +
      + +
      + +
      + +
      + {foreach name="statusList" item="vo"} + + {/foreach} +
      + +
      +
      +
      + +
      + +
      +
      + +
      + + + \ No newline at end of file diff --git a/application/admin/view/supplement/orders/index.html b/application/admin/view/supplement/orders/index.html new file mode 100644 index 0000000..d2440c1 --- /dev/null +++ b/application/admin/view/supplement/orders/index.html @@ -0,0 +1,46 @@ +
      + +
      + {:build_heading(null,FALSE)} + +
      + + +
      +
      +
      +
      +
      + + {:__('Add')} + {:__('Edit')} + {:__('Delete')} + + + + + +
      + +
      +
      +
      + +
      +
      +
      diff --git a/public/assets/js/backend/order.js b/public/assets/js/backend/order.js index 3fb9310..d1a9594 100644 --- a/public/assets/js/backend/order.js +++ b/public/assets/js/backend/order.js @@ -110,7 +110,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'cascader'], function {field: 'order_no', title: __('Order_no'), operate: 'LIKE'}, {field: 'customer', title: __('Customer'), operate: 'LIKE'}, {field: 'tel', title: __('Tel'), operate: 'LIKE'}, - {field: 'area.merge_name', title: __('Area_id')}, + {field: 'area.merge_name', title: __('Area_id'),searchable:false}, { field: 'address', title: __('Address'), diff --git a/public/assets/js/backend/supplement/orders.js b/public/assets/js/backend/supplement/orders.js new file mode 100644 index 0000000..bb9290d --- /dev/null +++ b/public/assets/js/backend/supplement/orders.js @@ -0,0 +1,134 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form','cascader'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'supplement/orders/index' + location.search, + add_url: 'supplement/orders/add', + edit_url: 'supplement/orders/edit', + del_url: 'supplement/orders/del', + multi_url: 'supplement/orders/multi', + import_url: 'supplement/orders/import', + table: 'supplement_orders', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + pk: 'id', + sortName: 'id', + fixedColumns: true, + fixedRightNumber: 1, + columns: [ + [ + {checkbox: true}, + {field: 'id', title: __('Id')}, + {field: 'user.nickname', title: '创建人'}, + {field: 'area.merge_name', title: '地区',searchable:false}, + {field: 'item_name', title: __('Item_name')}, + {field: 'source_name', title: __('Source_name')}, + {field: 'platform_order_no', title: __('Platform_order_no'), operate: 'LIKE'}, + {field: 'buyer_account', title: __('Buyer_account'), operate: 'LIKE'}, + {field: 'amount', title: __('Amount'), operate:'BETWEEN'}, + {field: 'commission', title: __('Commission'), operate:'BETWEEN'}, + {field: 'screenshots', title: '图片', operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'status', title: __('Status'), searchList: {"0":__('Status 0'),"1":__('Status 1'),"2":__('Status 2')}, formatter: Table.api.formatter.status}, + {field: 'created_at', title: __('Created_at'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, + {field: 'updated_at', title: __('Updated_at'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ] + ] + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + add: function () { + Controller.api.bindevent(); + Controller.api.map(); + }, + edit: function () { + Controller.api.bindevent(); + Controller.api.map(); + }, + api: { + bindevent: function () { + Form.api.bindevent($("form[role=form]")); + }, + map:function () { + $("#c-city").on("cp:updated", function () { + var citypicker = $(this).data("citypicker"); + var code = citypicker.getCode("district") || citypicker.getCode("city") || citypicker.getCode("province"); + + $("#area_id").val(code); + $("#area_name").val(citypicker.getVal()); + }); + // $("#area_map").data("callback", function (res) { + // Form.api.target($('#c-address')); + // }); + $(document).on('click', "#area_map", function (e) { + const data = $("#c-city").val(); + if (!data){ + Toastr.error('请先选择区域'); + return false; + } + + var that = this; + var callback = $(that).data('callback'); + var input_id = $(that).data("input-id") ? $(that).data("input-id") : ""; + var lat_id = $(that).data("lat-id") ? $(that).data("lat-id") : ""; + var lng_id = $(that).data("lng-id") ? $(that).data("lng-id") : ""; + var zoom_id = $(that).data("zoom-id") ? $(that).data("zoom-id") : ""; + var lat = lat_id ? $("#" + lat_id).val() : ''; + var lng = lng_id ? $("#" + lng_id).val() : ''; + var city_code = $("#c-city").val(); + var zoom = zoom_id ? $("#" + zoom_id).val() : ''; + var url = "/addons/address/index/select?a=1"; + url += (lat && lng) ? 'lat=' + lat + '&lng=' + lng + + (input_id ? "&address=" + $("#" + input_id).val() : "") + +(zoom ? "&zoom=" + zoom : "") : '' + ; + if (city_code){ + url += city_code ? "&city_code=" + city_code : ""; + } + // console.log(url); + Fast.api.open(url, '位置选择', { + callback: function (res) { + input_id && $("#" + input_id).val(res.address).trigger("change"); + lat_id && $("#" + lat_id).val(res.lat).trigger("change"); + lng_id && $("#" + lng_id).val(res.lng).trigger("change"); + zoom_id && $("#" + zoom_id).val(res.zoom).trigger("change"); + + try { + //执行回调函数 + if (typeof callback === 'function') { + callback.call(that, res); + } + } catch (e) { + + } + } + }); + + }); + + var _data = items; + + $('#item_id').zdCascader({ + data: _data, + onChange: function ($this, data, allPathData) { + // console.log(data,allPathData); + $('#item_id_value').val(data.value); + } + }); + $('#item_id').val($('#item_id').data('value')).focus(); + } + } + }; + return Controller; +});