1
0

16 Коммиты feb64d326b ... 6cca5cb74a

Автор SHA1 Сообщение Дата
  gorden 6cca5cb74a 重启福利账户 2 месяцев назад
  gorden cb45251d42 Merge branch 'master' into dev 2 месяцев назад
  gorden 5f87858da6 Merge branch 'master' of http://39.98.194.76:3000/txct/wanyue_app 2 месяцев назад
  gorden b5d87853ff 重启福利账户 2 месяцев назад
  gorden 32874ca590 红包功能 2 месяцев назад
  gorden b35b8d1d05 红包功能 2 месяцев назад
  gorden f747a759b2 红包 2 месяцев назад
  gorden da676bca66 红包发行 2 месяцев назад
  gorden 9a7459bcde 康养城支付记录凭证 2 месяцев назад
  gorden 0b38057435 券包 2 месяцев назад
  gorden 5e46b7495d 套包订单核销 2 месяцев назад
  gorden 29e01230c7 执行时间 2 месяцев назад
  gorden a9b580b18a 执行时间 2 месяцев назад
  gorden f559b06f5e 执行时间 2 месяцев назад
  gorden 4d33af6705 执行时间 2 месяцев назад
  gorden 2f06815124 执行时间 2 месяцев назад

+ 1 - 0
app/admin/controller/coupon/CouponController.php

@@ -152,6 +152,7 @@ class CouponController extends Curd
                     }
                 }
             }
+            unset($item['detail']);
         }
 
         return $items;

+ 479 - 0
app/admin/controller/coupon/CouponPacketController.php

@@ -0,0 +1,479 @@
+<?php
+
+namespace app\admin\controller\coupon;
+
+use app\admin\service\coupon\CouponDetailService;
+use app\admin\service\coupon\CouponService;
+use app\admin\validate\coupon\CouponValidate;
+use app\admin\validate\device\DeviceValidate;
+use app\controller\Curd;
+use app\model\Coupon;
+use app\model\CouponDetail;
+use app\model\CouponGoods;
+use app\model\CouponPacket;
+use app\model\CouponPacketSequence;
+use app\model\Device;
+use app\model\Member;
+use app\model\SysDept;
+use app\model\SysSerial;
+use support\Db;
+use support\exception\BusinessException;
+use support\Request;
+use support\Response;
+use Tinywan\Jwt\JwtToken;
+
+class CouponPacketController extends Curd
+{
+    public function __construct()
+    {
+        $this->model = new CouponPacket();
+    }
+
+    /**
+     * @Desc 列表
+     * @Author Gorden
+     * @Date 2024/3/28 15:01
+     *
+     * @param Request $request
+     * @return Response
+     * @throws \support\exception\BusinessException
+     */
+    public function select(Request $request): Response
+    {
+        [$where, $format, $limit, $field, $order] = $this->selectInput($request);
+        if (!empty($where['coupon_packet_addtimes'])) {
+            $where['coupon_packet_addtimes'][0] = strtotime($where['coupon_packet_addtimes'][0]);
+            $where['coupon_packet_addtimes'][1] = strtotime($where['coupon_packet_addtimes'][1]);
+        }
+        $order = $request->get('order', 'desc');
+        $field = $field ?? 'coupon_packet_addtimes';
+        $query = $this->doSelect($where, $field, $order);
+        return $this->doFormat($query, $format, $limit);
+    }
+
+    protected function doSelect(array $where, string $field = null, string $order = 'desc')
+    {
+        $model = $this->model->with([
+            'category' => function ($query) {
+                $query->select('category_id', 'category_name');
+            },
+            'user',
+            'dept'
+//            'detail'
+        ]);
+        foreach ($where as $column => $value) {
+            if (is_array($value)) {
+                if ($value[0] === 'like' || $value[0] === 'not like') {
+                    $model = $model->where($column, $value[0], "%$value[1]%");
+                } elseif (in_array($value[0], ['>', '=', '<', '<>'])) {
+                    $model = $model->where($column, $value[0], $value[1]);
+                } elseif ($value[0] == 'in' && !empty($value[1])) {
+                    $valArr = $value[1];
+                    if (is_string($value[1])) {
+                        $valArr = explode(",", trim($value[1]));
+                    }
+                    $model = $model->whereIn($column, $valArr);
+                } elseif ($value[0] == 'not in' && !empty($value[1])) {
+                    $valArr = $value[1];
+                    if (is_string($value[1])) {
+                        $valArr = explode(",", trim($value[1]));
+                    }
+                    $model = $model->whereNotIn($column, $valArr);
+                } elseif ($value[0] == 'null') {
+                    $model = $model->whereNull($column);
+                } elseif ($value[0] == 'not null') {
+                    $model = $model->whereNotNull($column);
+                } elseif ($value[0] !== '' || $value[1] !== '') {
+                    $model = $model->whereBetween($column, $value);
+                }
+            } else {
+                $model = $model->where($column, $value);
+            }
+        }
+        if ($field) {
+            $model = $model->orderBy($field, $order);
+        }
+        return $model;
+    }
+
+    protected function afterQuery($items)
+    {
+        foreach ($items as &$item) {
+            if (empty($item['dept'])) {
+                $item['dept_all'] = [
+                    'dept_id' => 0,
+                    'dept_name' => "所有门店"
+                ];
+            }
+            $item['used_total'] = CouponPacketSequence::where('join_sequence_coupon_packet_id',$item['coupon_packet_id'])
+                ->where('coupon_packet_sequence_status','USED')
+                ->count();
+            $item['unused_total'] = $item->coupon_packet_issue_num - $item['used_total'];
+        }
+
+        return $items;
+    }
+
+    public function selectList()
+    {
+        $coupons = Coupon::where('coupon_status', 'ACTIVED')
+            ->select('coupon_id', 'coupon_name')
+            ->orderBy('coupon_addtimes', 'DESC')
+            ->get()
+            ->toArray();
+
+        return json_success('', $coupons);
+    }
+
+//    public function afterQuery($items)
+//    {
+//        foreach ($items as &$item) {
+//            $item->coupon_begindate = date('Y-m-d H:i:s', $item->coupon_begindate);
+//            $item->coupon_enddate = date('Y-m-d H:i:s', $item->coupon_enddate);
+//        }
+//
+//        return $items;
+//    }
+
+    /**
+     * @Desc 添加优惠券
+     * @Author Gorden
+     * @Date 2024/8/14 15:16
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function insert(Request $request): Response
+    {
+        if ($this->validate && !$this->validateClass->scene('add')->check($request->post())) {
+            return json_fail($this->validateClass->getError());
+        }
+        Db::beginTransaction();
+        try {
+            $data = $this->insertInput($request);
+            $data['join_coupon_packet_user_id'] = JwtToken::getCurrentId();
+            $data['coupon_packet_status'] = 'PENDING';
+            $this->doInsert($data);
+            Db::commit();
+
+            return json_success('success');
+        } catch (BusinessException $customException) {
+            Db::rollBack();
+            dump($customException->getMessage());
+            return json_fail($customException->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            return json_fail('数据写入失败');
+        }
+    }
+
+    /**
+     * @Desc 关联优惠券、产品、规格
+     * @Author Gorden
+     * @Date 2024/8/14 14:32
+     *
+     * @param $goods
+     * @param $couponId
+     * @return void
+     * @throws BusinessException
+     */
+    public function insertCouponGoods($goods, $couponId)
+    {
+        try {
+            foreach ($goods as $good) {
+                CouponGoods::insert([
+                    'join_goods_coupon_id' => $couponId,
+                    'join_coupon_goods_id' => $good['goods_id'],
+                    'join_coupon_goods_sku_id' => $good['sku_id'],
+                    'coupon_goods_json' => '[]',
+                    'coupon_goods_extend_json' => '[]',
+                    'coupon_goods_addtimes' => time()
+                ]);
+            }
+        } catch (\Exception $e) {
+            throw new BusinessException("关联产品失败");
+        }
+    }
+
+    protected function insertInput(Request $request): array
+    {
+        $params = $request->post();
+        $data = $this->inputFilter($params);
+        $data['coupon_packet_id'] = "CP" . date("ymdH") . random_string(6, 'up');
+        $coupons = [];
+        if (!empty($params['coupons'])) {
+            foreach ($params['coupons'] as $coupon) {
+                $coupons[$coupon['id']]['num'] = $coupon['nbr'];
+            }
+        }
+
+        $data['coupon_packet_json'] = json_encode(['coupons' => $coupons]);
+
+        dump($data);
+        return $data;
+    }
+
+    /**
+     * @Desc 修改优惠券
+     * @Author Gorden
+     * @Date 2024/8/14 15:48
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function update(Request $request): Response
+    {
+        Db::beginTransaction();
+        try {
+            [$id, $data] = $this->updateInput($request);
+
+            $this->doUpdate($id, $data);
+
+            Db::commit();
+
+            return json_success('success');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+            dump($e->getMessage());
+            return json_fail('数据更新失败');
+        }
+
+    }
+
+    protected function updateInput(Request $request): array
+    {
+        $params = $request->post();
+        $primary_key = $this->model->getKeyName();
+        $id = $request->post($primary_key);
+        $data = $this->inputFilter($params);
+        $model = $this->model->find($id);
+        $coupons = [];
+        if (!empty($params['coupons'])) {
+            foreach ($params['coupons'] as $coupon) {
+                $coupons[$coupon['id']]['num'] = $coupon['nbr'];
+            }
+        }
+        $packetJson = [];
+        if (!empty($model->coupon_packet_json)) {
+            $packetJson = json_decode($model->coupon_packet_json, true);
+        }
+        $packetJson['coupons'] = $coupons;
+
+        $data['coupon_packet_json'] = json_encode($packetJson);
+
+        unset($data[$primary_key]);
+        return [$id, $data];
+    }
+
+    /**
+     * 优惠券详情
+     */
+    public function info(Request $request): Response
+    {
+        $packetId = $request->get('packet_id', '');
+        if (!$packetId) {
+            return json_fail('参数异常');
+        }
+        $packet = CouponPacket::where('coupon_packet_id', $packetId)->first();
+        if (!$packet) {
+            return json_fail('数据异常');
+        }
+        $coupons = [];
+        if (!empty($packet->coupon_packet_json)) {
+            $packetJson = json_decode($packet->coupon_packet_json, true);
+            if (isset($packetJson['coupons'])) {
+                $couponIds = array_keys($packetJson['coupons']);
+                $couponModel = Coupon::whereIn('coupon_id', $couponIds)
+                    ->select('coupon_id', 'coupon_name','coupon_classify','coupon_value','coupon_minimum_limit','coupon_category')
+                    ->get()
+                    ->toArray();
+                foreach ($couponModel as $coupon) {
+                    foreach ($packetJson['coupons'] as $key => $jsonCoupon) {
+                        if ($coupon['coupon_id'] == $key) {
+                            $coupons[] = [
+                                'id' => $key,
+                                'name' => $coupon['coupon_name'],
+                                'nbr' => $jsonCoupon['num'],
+                                'classify'=>$coupon['coupon_classify'],
+                                'info'=>CouponService::couponClassifyInfo($coupon['coupon_classify'],$coupon['coupon_category'],$coupon['coupon_value'],$coupon['coupon_minimum_limit'])
+                            ];
+                        }
+                    }
+                }
+            }
+        }
+
+        $data = [
+            'coupons' => $coupons
+        ];
+
+        return json_success('', $data);
+    }
+
+    /**
+     * 删除
+     * @param Request $request
+     * @return Response
+     * @throws BusinessException
+     */
+    public function delete(Request $request): Response
+    {
+        $ids = $this->deleteInput($request);
+        Db::beginTransaction();
+        try {
+            if (CouponPacket::whereIn('coupon_packet_id', $ids)->where('coupon_packet_status', '=', 'ACTIVED')->exists()) {
+                throw new BusinessException("有已发行的券包,无法删除");
+            }
+            $this->doDelete($ids);
+            Db::commit();
+            return json_success('success');
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            Db::rollBack();
+            return json_fail('删除失败');
+        }
+    }
+
+    /**
+     * @Desc 红包发行
+     * @Author Gorden
+     * @Date 2024/9/12 13:21
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function packetIssue(Request $request)
+    {
+        $packetId = $request->post('packet_id');
+        if (!$packetId) {
+            return json_fail("参数异常");
+        }
+        $packet = CouponPacket::where('coupon_packet_id', $packetId)
+            ->where('coupon_packet_status', 'PENDING')
+            ->first();
+        if (!$packet) {
+            return json_fail('数据异常');
+        }
+        Db::beginTransaction();
+        try {
+            // 生成红包记录
+            $this->generatePacket($packet);
+
+            $packet->coupon_packet_status = 'ACTIVED';
+            $packet->coupon_packet_issue_datetime = date('Y-m-d H:i:s');
+            $packet->save();
+
+            Db::commit();
+
+            return json_success("success");
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+
+            return json_fail("发行失败");
+        }
+    }
+
+    private function generatePacket(CouponPacket $couponPacket)
+    {
+        try {
+            $length = $couponPacket->coupon_packet_seq_length;
+            $prefixLength = strlen($couponPacket->coupon_packet_seq_prefix);
+            $suffixLength = strlen($couponPacket->coupon_packet_seq_suffix);
+            $seqBegin = $couponPacket->coupon_packet_seq_begin;
+            $realLength = $length - $prefixLength - $suffixLength;
+            $data = [];
+            for ($i = 0; $i < $couponPacket->coupon_packet_issue_num; $i++) {
+                if ($seqBegin > 0) {
+                    $seqBegin = $i === 0 ? $seqBegin : $seqBegin + 1;
+                    $data[] = $couponPacket->coupon_packet_seq_prefix . str_pad($seqBegin, $realLength, $couponPacket->coupon_packet_seq_fill, STR_PAD_LEFT) . $couponPacket->coupon_packet_seq_suffix;
+                } else {
+                    $data[] = $this->generateRandomStr($data, $realLength, $couponPacket->coupon_packet_seq_prefix, $couponPacket->coupon_packet_seq_suffi);
+                }
+            }
+
+            $chunk = collect($data);
+            $chunks = $chunk->chunk(100);
+            foreach ($chunks as $item) {
+                $insertData = [];
+                foreach ($item as $k => $value) {
+                    $insertData[$k] = [
+                        'coupon_packet_sequence_id' => $value,
+                        'join_sequence_coupon_packet_id' => $couponPacket->coupon_packet_id,
+                        'coupon_packet_sequence_status' => 'PENDING',
+                        'coupon_packet_sequence_json' => $couponPacket->coupon_packet_json,
+                        'coupon_packet_sequence_addtimes' => time()
+                    ];
+                }
+                CouponPacketSequence::insert($insertData);
+            }
+        } catch (\Exception $e) {
+            throw new BusinessException("发行失败");
+        }
+    }
+
+    private function generateRandomStr($data, $length, $prefix, $suffix)
+    {
+        $str = $prefix . random_string($length, 'up') . $suffix;
+        if (in_array($str, $data)) {
+            $this->generateRandomStr($data, $length, $prefix, $suffix);
+        }
+
+        return $str;
+    }
+
+    /**
+     * @Desc 红包重新发行
+     * @Author Gorden
+     * @Date 2024/9/12 13:21
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function packetReIssue(Request $request)
+    {
+        $packetId = $request->post('packet_id');
+        if (!$packetId) {
+            return json_fail("参数异常");
+        }
+        if (CouponPacketSequence::where('join_sequence_coupon_packet_id',$packetId)->where('coupon_packet_sequence_status','USED')->exists()){
+            return json_fail('已有领取记录,无法重新发行');
+        }
+        $packet = CouponPacket::where('coupon_packet_id', $packetId)
+            ->where('coupon_packet_status', 'ACTIVED')
+            ->first();
+        if (!$packet) {
+            return json_fail('数据异常');
+        }
+        Db::beginTransaction();
+        try {
+            // 删除旧的记录
+            CouponPacketSequence::where('join_sequence_coupon_packet_id',$packetId)->delete();
+            // 生成红包记录
+            $this->generatePacket($packet);
+
+            $packet->coupon_packet_issue_datetime = date('Y-m-d H:i:s');
+            $packet->save();
+
+            Db::commit();
+
+            return json_success("success");
+        } catch (BusinessException $e) {
+            Db::rollBack();
+            return json_fail($e->getMessage());
+        } catch (\Exception $e) {
+            Db::rollBack();
+
+            return json_fail("发行失败");
+        }
+    }
+}

+ 249 - 0
app/admin/controller/coupon/CouponPacketSequenceController.php

@@ -0,0 +1,249 @@
+<?php
+
+namespace app\admin\controller\coupon;
+
+use app\admin\service\coupon\CouponService;
+use app\admin\service\member\MemberService;
+use app\controller\Curd;
+use app\model\Coupon;
+use app\model\CouponDetail;
+use app\model\CouponGoods;
+use app\model\CouponPacket;
+use app\model\CouponPacketSequence;
+use app\model\SysCategory;
+use app\model\SysDept;
+use support\Request;
+use support\Response;
+
+class CouponPacketSequenceController extends Curd
+{
+    public function __construct()
+    {
+        $this->model = new CouponPacketSequence();
+    }
+
+    public function select(Request $request): Response
+    {
+        [$where, $format, $limit, $field, $order] = $this->selectInput($request);
+//        $where['join_coupon_detail_member_id'] = ['<>', ''];
+        $order = $request->get('order', 'desc');
+        $field = $field ?? 'coupon_packet_sequence_addtimes';
+
+        $couponPacketName = $request->get('coupon_packet_name', '');
+        if (!empty($couponPacketName)) {
+            $packetIds = CouponPacket::where('coupon_packet_name', 'like', '%' . $couponPacketName . '%')->pluck('coupon_packet_id')->toArray();
+            $where['join_sequence_coupon_packet_id'] = ['in', $packetIds];
+        }
+        $addTimes = $request->get('coupon_packet_sequence_addtimes', []);
+        if (!empty($addTimes)) {
+            $addTimes[0] = isset($addTimes[0]) ? strtotime($addTimes[0]) : time();
+            $addTimes[1] = isset($addTimes[1]) ? strtotime($addTimes[1]) : time();
+
+            $where['coupon_packet_sequence_addtimes'] = $addTimes;
+        }
+
+        $query = $this->doSelect($where, $field, $order);
+        return $this->doFormat($query, $format, $limit);
+    }
+
+    protected function doSelect(array $where, string $field = null, string $order = 'desc')
+    {
+        $model = $this->model->with([
+            'packet' => function ($query) {
+                $query->select('coupon_packet_id', 'coupon_packet_name');
+            },
+            'member' => function ($query) {
+                $query->select('member_id', 'member_mobile');
+            },
+            'cert' => function ($query) {
+                $query->select('join_cert_member_id', 'member_cert_name');
+            },
+            'info' => function ($query) {
+                $query->select('join_info_member_id', 'member_info_nickname');
+            }
+        ]);
+        foreach ($where as $column => $value) {
+            if (is_array($value)) {
+                if ($value[0] === 'like' || $value[0] === 'not like') {
+                    $model = $model->where($column, $value[0], "%$value[1]%");
+                } elseif (in_array($value[0], ['>', '=', '<', '<>'])) {
+                    $model = $model->where($column, $value[0], $value[1]);
+                } elseif ($value[0] == 'in' && !empty($value[1])) {
+                    $valArr = $value[1];
+                    if (is_string($value[1])) {
+                        $valArr = explode(",", trim($value[1]));
+                    }
+                    $model = $model->whereIn($column, $valArr);
+                } elseif ($value[0] == 'not in' && !empty($value[1])) {
+                    $valArr = $value[1];
+                    if (is_string($value[1])) {
+                        $valArr = explode(",", trim($value[1]));
+                    }
+                    $model = $model->whereNotIn($column, $valArr);
+                } elseif ($value[0] == 'null') {
+                    $model = $model->whereNull($column);
+                } elseif ($value[0] == 'not null') {
+                    $model = $model->whereNotNull($column);
+                } elseif ($value[0] !== '' || $value[1] !== '') {
+                    $model = $model->whereBetween($column, $value);
+                }
+            } else {
+                $model = $model->where($column, $value);
+            }
+        }
+//        $model = $model->selectRaw('join_detail_coupon_id,join_coupon_detail_member_id,MAX(coupon_detail_addtimes) as coupon_detail_addtimes,COUNT(*) as total');
+//        $model = $model->groupBy('join_coupon_detail_member_id', 'join_detail_coupon_id');
+        if ($field) {
+            $model = $model->orderBy($field, $order);
+        }
+        return $model;
+    }
+
+    public function afterQuery($items)
+    {
+        foreach ($items as &$item) {
+            $mobile = $certName = $nickname = '';
+            if (!empty($item['member']) && !empty($item['member']['member_mobile'])) {
+                $mobile = $item['member']['member_mobile'];
+            }
+            if (!empty($item['cert']) && !empty($item['cert']['member_cert_name'])) {
+                $certName = $item['cert']['member_cert_name'];
+            }
+            if (!empty($item['info']) && !empty($item['info']['member_info_nickname'])) {
+                $nickname = $item['info']['member_info_nickname'];
+            }
+            $item['member_name'] = MemberService::getMemberName($mobile, $certName, $nickname);
+        }
+
+        return $items;
+    }
+
+    /**
+     * @Desc 修改状态
+     * @Author Gorden
+     * @Date 2024/8/22 8:44
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function updateStatus(Request $request)
+    {
+        $detailId = $request->post('coupon_detail_id', '');
+        $status = $request->post('status', '');
+
+        $detail = CouponDetail::where('coupon_detail_id', $detailId)->first();
+        if (!$detail) {
+            return json_fail('数据不存在');
+        }
+        //状态 INIT|PENDING=等待领取|ACTIVED=可用|WAITING=已占用(待完成)|USED=已使用|DISABLED|CANCEL|EXPIRED
+        if (!in_array($status, ['INIT', 'PENDING', 'ACTIVED', 'WAITING', 'USED', 'DISABLED', 'CANCEL', 'EXPIRED'])) {
+            return json_fail("状态异常");
+        }
+        try {
+            CouponDetail::where('coupon_detail_id', $detailId)->update(['coupon_detail_status' => $status]);
+
+            return json_success('success');
+        } catch (\Exception $e) {
+            dump($e->getMessage());
+            return json_fail('数据修改失败');
+        }
+    }
+
+    /**
+     * @Desc 详情
+     * @Author Gorden
+     * @Date 2024/8/22 11:46
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function info(Request $request): Response
+    {
+        $packetSequenceId = $request->get('coupon_packet_sequence_id', '');
+        if (empty($packetSequenceId)) {
+            return json_fail('参数异常');
+        }
+
+        $sequence = CouponPacketSequence::with([
+            'packet' => function ($query) {
+                $query->select('coupon_packet_id', 'coupon_packet_name', 'join_coupon_packet_category_id', 'join_coupon_packet_dept_id', 'coupon_packet_status', 'coupon_packet_issue_num', 'coupon_packet_issue_datetime');
+            }
+        ])->where('coupon_packet_sequence_id', $packetSequenceId)
+            ->first();
+        if(!empty($sequence->packet)){
+            if ($sequence->packet->join_coupon_packet_dept_id == 0){
+                $sequence->packet->dept_name = '所有门店';
+            }else{
+                $sequence->packet->dept_nam = '';
+                $dept = SysDept::where('dept_id',$sequence->packet->join_coupon_packet_dept_id)->select('dept_id','dept_name')->first();
+                if (!empty($dept)){
+                    $sequence->packet->dept_name = $dept->dept_name;
+                }
+            }
+            if (!empty($sequence->packet->join_coupon_packet_category_id)){
+                $category = SysCategory::where('category_id',$sequence->packet->join_coupon_packet_category_id)
+                    ->first();
+                if (!empty($category->category_name)){
+                    $sequence->packet->category_name = $category->category_name;
+                }
+            }
+        }
+
+        return json_success('', $sequence);
+    }
+
+    public function myCouponGrouping(Request $request)
+    {
+        $memberId = $request->get('member_id', '');
+        $goods = $request->get('goods', []);
+        $settlementNow = $request->get('settlement_now', 'N');
+        if ($memberId == '') {
+            return json_fail("参数异常");
+        }
+
+        $goodsIds = array_column($goods, 'goods_id');
+        $couponGoods = CouponGoods::whereIn('join_coupon_goods_id', $goodsIds)->get()->toArray();
+        $couponIds = [];
+        foreach ($couponGoods as $couponGood) {
+            foreach ($goods as $good) {
+                if ($good['sku_id'] = $couponGood['join_coupon_goods_sku_id']) {
+                    $couponIds[] = $couponGood['join_goods_coupon_id'];
+                }
+            }
+        }
+
+        $details = CouponDetail::with([
+            'coupon' => function ($query) {
+                $query->select('coupon_id', 'coupon_name', 'coupon_classify', 'coupon_value', 'coupon_category', 'coupon_minimum_limit');
+            }
+        ])->whereIn('join_detail_coupon_id', $couponIds)
+            ->where('join_coupon_detail_member_id', $memberId);
+        if ($settlementNow == 'Y') {
+            $details = $details->whereIn('coupon_detail.coupon_detail_status', ['ACTIVED', 'WAITING']);
+        } else {
+            $details = $details->where('coupon_detail.coupon_detail_status', 'ACTIVED');
+        }
+        $details = $details->selectRaw('join_detail_coupon_id,join_coupon_detail_member_id,COUNT(*) as count')
+            ->groupBy('join_detail_coupon_id', 'join_coupon_detail_member_id')
+            ->get()
+            ->toArray();
+        $data = [];
+        foreach ($details as $detail) {
+            if (empty($detail['coupon'])) {
+                continue;
+            }
+            $classify = CouponService::couponClassifyInfo($detail['coupon']['coupon_classify'], $detail['coupon']['coupon_category'], $detail['coupon']['coupon_value'], $detail['coupon']['coupon_minimum_limit']);
+            $data[] = [
+                'coupon_id' => $detail['coupon']['coupon_id'],
+                'coupon_name' => $detail['coupon']['coupon_name'],
+                'classify' => $classify,
+                'count' => $detail['count'],
+                'coupon_classify' => $detail['coupon']['coupon_classify'],
+                'coupon_value' => $detail['coupon']['coupon_value'] ?? '',
+                'coupon_minimum_limit' => $detail['coupon']['coupon_minimum_limit'] ?? '',
+            ];
+        }
+
+        return json_success('', $data);
+    }
+}

+ 45 - 15
app/admin/controller/member/AccountController.php

@@ -17,7 +17,7 @@ class AccountController extends Curd
 
     public function my($id)
     {
-        $account = MemberAccount::where('join_account_member_id', $id)->where('member_account_status','ACTIVED')->get()->toArray();
+        $account = MemberAccount::where('join_account_member_id', $id)->get()->toArray();
         if (!$account) {
             // 账户表
             $accountData = [
@@ -39,13 +39,13 @@ class AccountController extends Curd
 
             $account = MemberAccount::where('join_account_member_id', $id)->get()->toArray();
         }
-        if ($account[0]['member_account_classify'] == 'POINTS'){
+        if ($account[0]['member_account_classify'] == 'POINTS') {
             $account = array_reverse($account);
         }
 
-        foreach ($account as &$item){
-            $item['member_account_duedate'] = !empty($item['member_account_duedate']) ? date('Y-m-d H:i:s',$item['member_account_duedate']) : '长期有效';
-            $item['member_account_surplus'] = round($item['member_account_surplus'] + $item['member_account_added'],2);
+        foreach ($account as &$item) {
+            $item['member_account_duedate'] = !empty($item['member_account_duedate']) ? date('Y-m-d H:i:s', $item['member_account_duedate']) : '长期有效';
+            $item['member_account_surplus'] = round($item['member_account_surplus'] + $item['member_account_added'], 2);
         }
 
         return json_success('', $account);
@@ -81,30 +81,60 @@ class AccountController extends Curd
     /**
      * 用户的账户
      */
-    public function selectMemberAccount(Request $request) 
+    public function selectMemberAccount(Request $request)
     {
-        $memberId = $request->get('member_id','');
-        if (!$memberId){
+        $memberId = $request->get('member_id', '');
+        if (!$memberId) {
             return json_fail('参数异常');
         }
-        
+
         $account = MemberAccount::where('join_account_member_id', $memberId)->get()->toArray();
 
         $data = [];
-        foreach ($account as $item){
-            $item['member_account_duedate'] = !empty($item['member_account_duedate']) ? date('Y-m-d H:i:s',$item['member_account_duedate']) : '长期有效';
+        foreach ($account as $item) {
+            $item['member_account_duedate'] = !empty($item['member_account_duedate']) ? date('Y-m-d H:i:s', $item['member_account_duedate']) : '长期有效';
 
-            if ($item['member_account_classify'] == 'POINTS'){
+            if ($item['member_account_classify'] == 'POINTS') {
                 $data['points'] = $item;
-            }elseif ($item['member_account_classify'] == 'CASH'){
+            } elseif ($item['member_account_classify'] == 'CASH') {
                 $data['cash'] = $item;
-            }elseif ($item['member_account_classify'] == 'CARD'){
+            } elseif ($item['member_account_classify'] == 'CARD') {
                 $data['card'][] = $item;
-            }elseif ($item['member_account_classify'] == 'WELFARE'){
+            } elseif ($item['member_account_classify'] == 'WELFARE') {
                 $data['welfare'] = $item;
+            } elseif ($item['member_account_classify'] == 'VIP') {
+                $data['vip'] = $item;
             }
         }
 
         return json_success('', $data);
     }
+
+    /**
+     * @Desc 修改账户状态
+     * @Author Gorden
+     * @Date 2024/9/12 16:28
+     *
+     * @param Request $request
+     * @return \support\Response
+     */
+    public function updateStatus(Request $request)
+    {
+        $accountId = $request->post('account_id');
+        $status = $request->post('status');
+        if (!$accountId || !$status || !in_array($status,['DISABLED','ACTIVED','EXPIRED'])){
+            return json_fail('参数异常');
+        }
+        try {
+            $account = MemberAccount::where('member_account_id',$accountId)->first();
+            $account->member_account_status = $status;
+            $account->save();
+
+            _syslog("修改账户状态",'修改账户状态成功');
+            return json_success('账户状态修改成功');
+        }catch (\Exception $e){
+            _syslog("修改账户状态",'账户状态修改失败');
+            return json_fail('账户状态修改失败');
+        }
+    }
 }

+ 39 - 0
app/admin/controller/order/KangyangCityController.php

@@ -983,6 +983,9 @@ class KangyangCityController extends Curd
                 if (!empty($payDetail->pay_extend_json)) {
                     $payExtendJson = json_decode($payDetail->pay_extend_json, true);
                     $order->cancel_times = $payExtendJson['cancel_times'] ?? '';
+                    if (isset($payExtendJson['ticket'])) {
+                        $payDetail->ticket = str_replace('/thumb', '', getenv("STORAGE_DOMAIN") . $payExtendJson['ticket']);
+                    }
                 }
                 $order->pay_amount_total += $payDetail->pay_amount;
             }
@@ -1108,4 +1111,40 @@ class KangyangCityController extends Curd
 
         return json_success('', $order);
     }
+
+    /**
+     * @Desc 上传支付凭证
+     * @Author Gorden
+     * @Date 2024/9/12 10:14
+     *
+     * @param Request $request
+     * @return Response
+     */
+    public function uploadTicket(Request $request)
+    {
+        $payId = $request->post('pay_id');
+        $url = $request->post('url');
+        if (!$payId || !$url) {
+            return json_fail("参数异常");
+        }
+        $url = str_replace(getenv("STORAGE_DOMAIN"), '', $url);
+        try {
+            $payDetail = PayDetail::where('pay_id', $payId)->first();
+            if (!$payDetail) {
+                return json_fail('数据异常');
+            }
+            $extendJson = [];
+            if (!empty($payDetail->pay_extend_json)) {
+                $extendJson = json_decode($payDetail->pay_extend_json, true);
+            }
+            $extendJson['ticket'] = $url;
+
+            $payDetail->pay_extend_json = json_encode($extendJson);
+            dump($payDetail->save());
+
+            return json_success('success');
+        } catch (\Exception $e) {
+            return json_fail("上传附件失败");
+        }
+    }
 }

+ 21 - 14
app/admin/controller/order/PackagesController.php

@@ -227,21 +227,28 @@ class PackagesController extends Curd
 
         Db::beginTransaction();
         try {
-            // 减额度
+            // 减额度 加使用量
             $benefit->member_benefit_used_count = $benefit->member_benefit_used_count + $nbr;
-            // 用完了
-//            if ($benefit->member_benefit_limit_count <= $benefit->member_benefit_used_count) {
-//                $benefit->member_benefit_status = 'DONE';
-//                if (!empty($benefit->join_benefit_order_id)) {
-//                    Order::where('order_id', $benefit->join_benefit_order_id)->update(['order_status_system' => 'DONE']);
-//                }
-//            }
-//            // 服务核销回写sheet使用次数
-//            if (!empty($benefit->join_benefit_goods_id) && !empty($benefit->join_benefit_order_id)) {
-//                OrderSheet::where('join_sheet_goods_id', $benefit->join_benefit_goods_id)
-//                    ->where('join_sheet_order_id', $benefit->join_benefit_order_id)
-//                    ->update(['order_sheet_used_num' => $benefit->member_benefit_used_count]);
-//            }
+            // 此权益用完了
+            if ($benefit->member_benefit_limit_count <= $benefit->member_benefit_used_count) {
+                // 套包和套包里的产品是否用完了
+                $result = OrderService::checkPackageBenefit($benefit);
+                $benefit->member_benefit_status = 'DONE';
+                if (!empty($benefit->join_benefit_order_id) && $result['order'] === true) {
+                    Order::where('order_id', $benefit->join_benefit_order_id)->update([
+                        'order_is_complete' => 'Y',
+                        'order_status_system' => 'DONE'
+                    ]);
+                }
+                // sheet
+                if (!empty($benefit->join_benefit_order_id) && $result['sheet'] === true) {
+                    $sheet = OrderSheet::where('join_sheet_goods_id', $benefit->join_benefit_package_id)
+                        ->where('join_sheet_order_id', $benefit->join_benefit_order_id)
+                        ->first();
+                    $sheet->order_sheet_used_num = $sheet->order_sheet_num;
+                    $sheet->save();
+                }
+            }
 
             $benefit->save();
             // 记录核销

+ 25 - 6
app/admin/controller/order/PayDetailController.php

@@ -53,11 +53,11 @@ class PayDetailController extends Curd
         //     $where['pay_category'] = 'RECHARGE';
         //     $where['pay_prepayid'] = ['in','WXPAY,ALIPAY'];
         // }
-        $query = $this->doSelect($where, $field, $order);
+        $query = $this->doSelect($where, $field, $order,$request->get());
         return $this->doFormat($query, $format, $limit);
     }
 
-    protected function doSelect(array $where, string $field = null, string $order = 'desc')
+    protected function doSelect(array $where, string $field = null, string $order = 'desc',$params=[])
     {
         $model = $this->model->with(['member', 'cert', 'memberAccount']);
         foreach ($where as $column => $value) {
@@ -89,10 +89,25 @@ class PayDetailController extends Curd
                 $model = $model->where($column, $value);
             }
         }
-        $model = $model->where(function ($query) {
-            $query->whereIn('pay_prepayid', ['ALIPAY', 'WXPAY','OFFLINE_WXPAY','OFFLINE_ALIPAY','MONEY'])
-                ->orWhere('pay_prepayid', 'like', '%CASH%');
-        });
+        if (empty($params['type'])){
+            $model = $model->where(function ($query) {
+                $query->whereIn('pay_prepayid', ['ALIPAY', 'WXPAY','OFFLINE_WXPAY','OFFLINE_ALIPAY','MONEY'])
+                    ->orWhere('pay_prepayid', 'like', '%CASH%')
+                    ->orWhere('pay_prepayid', 'like', '%WELFARE%');
+            });
+        }else{
+            if ($params['type'] == 'NORMAL'){
+                $model = $model->where(function ($query) {
+                    $query->whereIn('pay_prepayid', ['ALIPAY', 'WXPAY','OFFLINE_WXPAY','OFFLINE_ALIPAY','MONEY'])
+                        ->orWhere('pay_prepayid', 'like', '%CASH%');
+                });
+            }else{
+                $model = $model->where(function ($query) {
+                    $query->orWhere('pay_prepayid', 'like', '%WELFARE%');
+                });
+            }
+        }
+
 
         if ($field) {
             $model = $model->orderBy($field, $order);
@@ -168,6 +183,10 @@ class PayDetailController extends Curd
             if (count($prepayId) > 1) {
                 $item->pay_prepayid = $prepayId[1];
             }
+            $item->type = 'NORMAL';
+            if (isset($prepayId[1]) && $prepayId[1] == 'WELFARE'){
+                $item->type = 'WELFARE';
+            }
             $memberAccount = [];
             if (!empty($item->memberAccount)) {
                 foreach ($item->memberAccount as $account) {

+ 63 - 1
app/admin/controller/order/WholeController.php

@@ -275,6 +275,8 @@ class WholeController extends Curd
                     $item['payWay'] = '账户余额';
                 } else if (!empty($payWay[1]) && $payWay[1] == 'WELFARE') {
                     $item['payWay'] = '福利账户';
+                } else if (!empty($payWay[1]) && $payWay[1] == 'VIP') {
+                    $item['payWay'] = 'VIP账户';
                 } else if (!empty($payWay[1]) && $payWay[1] == 'QRCODE') {
                     $item['payWay'] = '付款码';
                 } else if (!empty($payWay[0]) && $payWay[0] == 'OFFLINE') {
@@ -883,6 +885,35 @@ class WholeController extends Curd
                     $order->order_status_system = $systemStatus;
                     $order->order_status_payment = 'SUCCESS';
                 }
+            }  else if ($params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
+                    $order->order_status_system = $systemStatus;
+                    $order->order_status_payment = 'SUCCESS';
+                }
             } else if ($params['pay_category'] == 'WELFARE') {  // 福利账户
                 $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
                     ->where('member_account_classify', 'WELFARE')
@@ -1117,6 +1148,8 @@ class WholeController extends Curd
                 $payData['pay_prepayid'] = $params['join_order_member_id'] . '-CASH';
             } else if ($params['pay_category'] == 'WELFARE') {
                 $payData['pay_prepayid'] = $params['join_order_member_id'] . '-WELFARE';
+            }  else if ($params['pay_category'] == 'VIP') {
+                $payData['pay_prepayid'] = $params['join_order_member_id'] . '-VIP';
             } else if ($params['pay_category'] == 'CARD') {
                 $payData['pay_prepayid'] = $params['card_nbr'];
             } else if ($params['pay_category'] == 'OFFLINE') {
@@ -1913,7 +1946,7 @@ class WholeController extends Curd
                 }
             }
             // 余额、福利、储值卡 验证短信
-            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE'])) {
+            if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE','VIP'])) {
                 $code = $params['sms_code'];
                 if (!$code) {
                     throw new BusinessException('验证码错误,请重新输入');
@@ -2000,6 +2033,35 @@ class WholeController extends Curd
                     $params['order_status_system'] = $systemStatus;
                     $params['order_status_payment'] = 'SUCCESS';
                 }
+            } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'VIP') {    // 余额支付
+                $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
+                    ->where('member_account_classify', 'VIP')
+                    ->where('member_account_status', 'ACTIVED')
+                    ->first();
+                if (!$account) {
+                    throw new BusinessException('账户异常');
+                }
+                $amount = $account->member_account_surplus + $account->member_account_added;
+                if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    throw new BusinessException('账户余额不足');
+                }
+                if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
+                    $qrcodePayAmount = $params['order_amount_pay'] - $amount;
+                    $params['order_amount_pay'] = $amount;
+                }
+                if ($params['order_amount_pay'] > $account->member_account_surplus) {
+                    $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
+                    $account->member_account_surplus = 0;
+                    $account->member_account_added = $cut;
+                } else {
+                    $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
+                }
+                $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
+                $account->save();
+                if ($params['pay_constitute'] == 'N') {
+                    $params['order_status_system'] = $systemStatus;
+                    $params['order_status_payment'] = 'SUCCESS';
+                }
             } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'WELFARE') {  // 福利账户
                 $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
                     ->where('member_account_classify', 'WELFARE')

+ 12 - 12
app/admin/service/member/MemberService.php

@@ -1015,18 +1015,18 @@ class MemberService
                 MemberInfo::where('join_info_member_id', $params['member_id'])->update($infoData);
             }
             // 福利账户
-//            if (!empty($params['member_classify']) && $params['member_classify'] == 'EMPLOY' && !MemberAccount::where('member_account_nbr',$memberId.'-WELFARE')->exists()){
-//                $welfareData = [
-//                    'join_account_member_id'=>$memberId,
-//                    'member_account_classify'=>'WELFARE',
-//                    'member_account_status'=>'ACTIVED',
-//                    'member_account_category'=>'NORMAL',
-//                    'member_account_nbr'=>$memberId.'-WELFARE',
-//                    'member_account_name'=>'福利账户',
-//                    'member_account_addtimes'=>time()
-//                ];
-//                MemberAccount::insert($welfareData);
-//            }
+            if (!empty($params['member_classify']) && $params['member_classify'] == 'EMPLOY' && !MemberAccount::where('member_account_nbr',$memberId.'-WELFARE')->exists()){
+                $welfareData = [
+                    'join_account_member_id'=>$memberId,
+                    'member_account_classify'=>'WELFARE',
+                    'member_account_status'=>'ACTIVED',
+                    'member_account_category'=>'NORMAL',
+                    'member_account_nbr'=>$memberId.'-WELFARE',
+                    'member_account_name'=>'福利账户',
+                    'member_account_addtimes'=>time()
+                ];
+                MemberAccount::insert($welfareData);
+            }
 
             Db::commit();
         } catch (\Exception $e) {

+ 34 - 0
app/admin/service/order/OrderService.php

@@ -7,6 +7,7 @@ use app\model\CouponGoods;
 use app\model\GoodsRunning;
 use app\model\GoodsSku;
 use app\model\Member;
+use app\model\MemberBenefit;
 use app\model\Order;
 use app\model\OrderSheet;
 use app\model\PayDetail;
@@ -844,6 +845,39 @@ class OrderService
         }
     }
 
+    /**
+     * @Desc
+     * @Author Gorden
+     * @Date 2024/9/11 11:11
+     *
+     * @param MemberBenefit $benefit
+     * @return false[]|true[]
+     */
+    public static function checkPackageBenefit(MemberBenefit $benefit)
+    {
+        $result = ['sheet' => true, 'order' => true];
+        // 除此权益外,套包的其他权益是否用完了  where('join_benefit_package_id', $benefit->join_benefit_package_id)
+        $benefits = MemberBenefit::where('join_benefit_order_id', $benefit->join_benefit_order_id)
+            ->where('member_benefit_id', '<>', $benefit->member_benefit_id)
+            ->get()
+            ->toArray();
+        foreach ($benefits as $benefitItem) {
+            if ($benefitItem['join_benefit_package_id'] == $benefit->join_benefit_package_id) {
+                if ($benefitItem['member_benefit_limit_count'] > $benefitItem['member_benefit_used_count']) {
+                    return ['sheet' => false, 'order' => false];
+                }
+            }
+        }
+        foreach ($benefits as $benefitItem) {
+            if ($benefitItem['member_benefit_limit_count'] > $benefitItem['member_benefit_used_count']) {
+                $result['order'] = false;
+                return $result;
+            }
+        }
+
+        return $result;
+    }
+
 
     public static $couponClassify = [
         'wipe' => '抹零',

+ 44 - 0
app/model/CouponPacket.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace app\model;
+
+use DateTimeInterface;
+use support\Model;
+
+class CouponPacket extends Model
+{
+    protected $table = 'coupon_packet';
+
+    protected $primaryKey = 'coupon_packet_id';
+
+    protected $keyType = 'string';
+
+    protected $dateFormat = 'U';
+
+    const CREATED_AT = 'coupon_packet_addtimes';
+
+    const UPDATED_AT = null;
+
+    public function serializeDate(DateTimeInterface $date)
+    {
+        return $date->format('Y-m-d H:i:s');
+    }
+
+    public function detail()
+    {
+        return $this->hasMany(CouponDetail::class,'join_detail_coupon_id','coupon_id');
+    }
+
+    public function dept()
+    {
+        return $this->hasOne(SysDept::class,'dept_id','join_coupon_packet_dept_id')->select('dept_id','dept_name');
+    }
+
+    public function category(){
+        return $this->hasOne(SysCategory::class,'category_id','join_coupon_packet_category_id')->select('category_id','category_name');
+    }
+
+    public function user(){
+        return $this->hasOne(SysUser::class,'user_id','join_coupon_packet_user_id')->select('user_id','user_name');
+    }
+}

+ 74 - 0
app/model/CouponPacketSequence.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace app\model;
+
+use DateTimeInterface;
+use support\Model;
+
+class CouponPacketSequence extends Model
+{
+    protected $table = 'coupon_packet_sequence';
+
+    protected $primaryKey = 'coupon_packet_sequence_id';
+
+    protected $keyType = 'string';
+
+    protected $dateFormat = 'U';
+
+    const CREATED_AT = 'coupon_packet_sequence_addtimes';
+
+    const UPDATED_AT = null;
+
+    public function serializeDate(DateTimeInterface $date)
+    {
+        return $date->format('Y-m-d H:i:s');
+    }
+
+    /**
+     * @Desc 关联券包
+     * @Author Gorden
+     * @Date 2024/9/12 14:33
+     *
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function packet()
+    {
+        return $this->hasOne(CouponPacket::class,'coupon_packet_id','join_sequence_coupon_packet_id');
+    }
+
+    /**
+     * @Desc 关联会员
+     * @Author Gorden
+     * @Date 2024/3/30 13:08
+     *
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function member()
+    {
+        return $this->hasOne(Member::class, 'member_id', 'join_coupon_packet_sequence_member_id');
+    }
+
+    /**
+     * @Desc 关联实名
+     * @Author Gorden
+     * @Date 2024/8/21 13:50
+     *
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function cert()
+    {
+        return $this->hasOne(MemberCert::class, 'join_cert_member_id', 'join_coupon_packet_sequence_member_id');
+    }
+
+    /**
+     * @Desc 关联详情
+     * @Author Gorden
+     * @Date 2024/8/21 13:51
+     *
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function info()
+    {
+        return $this->hasOne(MemberInfo::class, 'join_info_member_id', 'join_coupon_packet_sequence_member_id');
+    }
+}

+ 59 - 36
route/admin.php

@@ -2,7 +2,7 @@
 
 use Webman\Route;
 
-Route::options('[{path:.+}]', function (){
+Route::options('[{path:.+}]', function () {
     return response('');
 });
 
@@ -55,7 +55,7 @@ Route::group('/admin', function () {
             Route::get('/selectAll', [\app\admin\controller\goods\EntityGoodsController::class, 'selectAll']);
             Route::get('/selectAllByGoodsName', [\app\admin\controller\goods\EntityGoodsController::class, 'selectAllByGoodsName']);
             Route::get('/selectAllByCategoryForRuleAddComponent', [\app\admin\controller\goods\EntityGoodsController::class, 'selectAllByCategoryForRuleAddComponent']);
-            Route::get('/getPremises', [\app\admin\controller\goods\EntityGoodsController::class, 'selectPremisesByGoodsId']);   
+            Route::get('/getPremises', [\app\admin\controller\goods\EntityGoodsController::class, 'selectPremisesByGoodsId']);
             Route::get('/list', [\app\admin\controller\goods\EntityGoodsController::class, 'select']);
             Route::get('/info', [\app\admin\controller\goods\EntityGoodsController::class, 'info']);
             Route::post('/add', [\app\admin\controller\goods\EntityGoodsController::class, 'insert']);
@@ -108,23 +108,23 @@ Route::group('/admin', function () {
         ]);
     });
     /* 财务管理 */
-    Route::group('/finance',function (){
-        Route::group('/writeOff',function (){
-            Route::get('/list',[\app\admin\controller\finance\WriteOffController::class,'list']);
-            Route::get('/statistics',[\app\admin\controller\finance\WriteOffController::class,'statistics']);
+    Route::group('/finance', function () {
+        Route::group('/writeOff', function () {
+            Route::get('/list', [\app\admin\controller\finance\WriteOffController::class, 'list']);
+            Route::get('/statistics', [\app\admin\controller\finance\WriteOffController::class, 'statistics']);
         });
-        Route::group('/goodsSales',function (){
-            Route::get('/statistics',[\app\admin\controller\finance\GoodsSalesController::class,'statistics']);
-            Route::get('/list',[\app\admin\controller\finance\GoodsSalesController::class,'list']);
+        Route::group('/goodsSales', function () {
+            Route::get('/statistics', [\app\admin\controller\finance\GoodsSalesController::class, 'statistics']);
+            Route::get('/list', [\app\admin\controller\finance\GoodsSalesController::class, 'list']);
         });
-        Route::group('/memberAccount',function (){
-            Route::get('/list',[\app\admin\controller\finance\MemberAccountController::class,'list']);
+        Route::group('/memberAccount', function () {
+            Route::get('/list', [\app\admin\controller\finance\MemberAccountController::class, 'list']);
         });
-        Route::group('/premisesMember',function (){
-            Route::get('/list',[\app\admin\controller\finance\PremisesMemberController::class,'list']);
+        Route::group('/premisesMember', function () {
+            Route::get('/list', [\app\admin\controller\finance\PremisesMemberController::class, 'list']);
         });
-        Route::group('/incomeAndExpend',function (){
-            Route::get('/list',[\app\admin\controller\finance\IncomeAndExpendController::class,'list']);
+        Route::group('/incomeAndExpend', function () {
+            Route::get('/list', [\app\admin\controller\finance\IncomeAndExpendController::class, 'list']);
         });
     });
     /* 系统管理中心 */
@@ -138,7 +138,7 @@ Route::group('/admin', function () {
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
-        
+
         /* 绿通医院 */
         Route::group('/greenChannel', function () {
             Route::get('/list', [\app\admin\controller\sys_manage\GreenChannelController::class, 'select']);
@@ -183,7 +183,7 @@ Route::group('/admin', function () {
             Route::delete('/delete', [\app\admin\controller\sys_manage\RestaurantController::class, 'delete']);
             Route::get('/getPrinterByPremiseName', [\app\admin\controller\sys_manage\RestaurantController::class, 'getPrinterByPremiseName']);
             Route::get('/getByUser', [\app\admin\controller\sys_manage\RestaurantController::class, 'getByUser']);
-            
+
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -212,9 +212,9 @@ Route::group('/admin', function () {
             Route::post('/updateStatus/{id:\w+}', [\app\admin\controller\sys_manage\UserController::class, 'updateStatus']);
             Route::post('/updatePassword/{id:\w+}', [\app\admin\controller\sys_manage\UserController::class, 'updatePassword']);
             Route::delete('/delete', [\app\admin\controller\sys_manage\UserController::class, 'delUser']);
-            Route::post('/correlationMember',[\app\admin\controller\sys_manage\UserController::class,'correlationMember']);
-            Route::get('/selectDoctorList',[\app\admin\controller\sys_manage\UserController::class,'selectDoctorList']);
-            Route::get('/selectSalesmanList',[\app\admin\controller\sys_manage\UserController::class,'selectSalesmanList']);
+            Route::post('/correlationMember', [\app\admin\controller\sys_manage\UserController::class, 'correlationMember']);
+            Route::get('/selectDoctorList', [\app\admin\controller\sys_manage\UserController::class, 'selectDoctorList']);
+            Route::get('/selectSalesmanList', [\app\admin\controller\sys_manage\UserController::class, 'selectSalesmanList']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -610,7 +610,7 @@ Route::group('/admin', function () {
     /* 营销团队管理 */
     Route::group('/market', function () {
         /* 团队管理 */
-        Route::group('/team', function (){
+        Route::group('/team', function () {
             Route::get('/list', [\app\admin\controller\consultant\TeamController::class, 'select']);
             Route::post('/add', [\app\admin\controller\consultant\TeamController::class, 'addDept']);
             Route::post('/update', [\app\admin\controller\consultant\TeamController::class, 'updateDept']);
@@ -619,7 +619,7 @@ Route::group('/admin', function () {
             Route::get('/check', [\app\admin\controller\consultant\TeamController::class, 'checkDept']);
         });
         /* 员工管理 */
-        Route::group('/consultant', function (){
+        Route::group('/consultant', function () {
             Route::get('/list', [\app\admin\controller\consultant\IndexController::class, 'select']);
             Route::post('/add', [\app\admin\controller\consultant\IndexController::class, 'addConsultant']);
             Route::post('/update', [\app\admin\controller\consultant\IndexController::class, 'updateConsultant']);
@@ -627,7 +627,7 @@ Route::group('/admin', function () {
             Route::get('/user', [\app\admin\controller\consultant\IndexController::class, 'getUserList']);
         });
         /* 客户管理 */
-        Route::group('/custom', function (){
+        Route::group('/custom', function () {
             Route::get('/config', [\app\admin\controller\consultant\CustomController::class, 'getOptionConfig']);
             Route::post('/add', [\app\admin\controller\consultant\CustomController::class, 'addCustom']);
             Route::post('/update', [\app\admin\controller\consultant\CustomController::class, 'updateCustom']);
@@ -666,13 +666,14 @@ Route::group('/admin', function () {
         Route::group('/account', function () {
             Route::get('/my/{id:\w+}', [\app\admin\controller\member\AccountController::class, 'my']);
             Route::post('/incomeExpend', [\app\admin\controller\member\AccountController::class, 'incomeExpend']);
+            Route::post('/updateStatus', [\app\admin\controller\member\AccountController::class, 'updateStatus']);
             Route::get('/selectMemberAccount', [\app\admin\controller\member\AccountController::class, 'selectMemberAccount']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
-        Route::group('/writeOff',function(){
-            Route::get('/list',[\app\admin\controller\member\WriteOffController::class,'list']);
-            Route::post('/remark',[\app\admin\controller\member\WriteOffController::class,'remark']);
+        Route::group('/writeOff', function () {
+            Route::get('/list', [\app\admin\controller\member\WriteOffController::class, 'list']);
+            Route::post('/remark', [\app\admin\controller\member\WriteOffController::class, 'remark']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -884,7 +885,27 @@ Route::group('/admin', function () {
             Route::get('/list', [\app\admin\controller\coupon\CouponDetailController::class, 'select']);
             Route::get('/info', [\app\admin\controller\coupon\CouponDetailController::class, 'info']);
             Route::post('/updateStatus', [\app\admin\controller\coupon\CouponDetailController::class, 'updateStatus']);
-            Route::get('/myCouponGrouping',[\app\admin\controller\coupon\CouponDetailController::class,'myCouponGrouping']);
+            Route::get('/myCouponGrouping', [\app\admin\controller\coupon\CouponDetailController::class, 'myCouponGrouping']);
+        })->middleware([
+            \app\middleware\AdminAuthCheck::class
+        ]);
+        /* 券包 */
+        Route::group('/packet', function () {
+            Route::get('/list', [\app\admin\controller\coupon\CouponPacketController::class, 'select']);
+            Route::post('/add', [\app\admin\controller\coupon\CouponPacketController::class, 'insert']);
+            Route::post('/update', [\app\admin\controller\coupon\CouponPacketController::class, 'update']);
+            Route::get('/info', [\app\admin\controller\coupon\CouponPacketController::class, 'info']);
+            Route::delete('/delete', [\app\admin\controller\coupon\CouponPacketController::class, 'delete']);
+            Route::post('/packetIssue',[\app\admin\controller\coupon\CouponPacketController::class,'packetIssue']);
+            Route::post('/packetReIssue',[\app\admin\controller\coupon\CouponPacketController::class,'packetReIssue']);
+        })->middleware([
+            \app\middleware\AdminAuthCheck::class
+        ]);
+
+        Route::group('/packetSequence', function () {
+            Route::get('/list', [\app\admin\controller\coupon\CouponPacketSequenceController::class, 'select']);
+            Route::get('/info', [\app\admin\controller\coupon\CouponPacketSequenceController::class, 'info']);
+            Route::post('/updateStatus', [\app\admin\controller\coupon\CouponPacketSequenceController::class, 'updateStatus']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -917,7 +938,7 @@ Route::group('/admin', function () {
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
-        Route::group('/statistics',function (){
+        Route::group('/statistics', function () {
             Route::get('/order', [\app\admin\controller\order\StatisticsController::class, 'order']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
@@ -948,6 +969,7 @@ Route::group('/admin', function () {
             Route::post('/pay', [\app\admin\controller\order\KangyangCityController::class, 'pay']);
             Route::get('/sheet', [\app\admin\controller\order\KangyangCityController::class, 'sheet']);
             Route::get('/getPaidOrder', [\app\admin\controller\order\KangyangCityController::class, 'getPaidOrder']);
+            Route::post('/uploadTicket', [\app\admin\controller\order\KangyangCityController::class, 'uploadTicket']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -960,6 +982,7 @@ Route::group('/admin', function () {
         // 套包订单
         Route::group('/packages', function () {
             Route::get('/list', [\app\admin\controller\order\PackagesController::class, 'select']);
+            Route::post('/writeOff', [\app\admin\controller\order\PackagesController::class, 'writeOff']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -985,9 +1008,9 @@ Route::group('/admin', function () {
             Route::post('/confirm/{id:[0-9a-zA-Z]+}', [\app\admin\controller\order\AppointmentController::class, 'confirm']);
             Route::get('/getTimes', [\app\admin\controller\order\AppointmentController::class, 'getTimes']);
             Route::get('/my', [\app\admin\controller\order\AppointmentController::class, 'myAppointments']);
-            Route::post('/arrival',[\app\admin\controller\order\AppointmentController::class, 'arrival']);
-            Route::post('/done',[\app\admin\controller\order\AppointmentController::class, 'done']);
-            Route::post('/cancelApply',[\app\admin\controller\order\AppointmentController::class, 'cancelApply']);
+            Route::post('/arrival', [\app\admin\controller\order\AppointmentController::class, 'arrival']);
+            Route::post('/done', [\app\admin\controller\order\AppointmentController::class, 'done']);
+            Route::post('/cancelApply', [\app\admin\controller\order\AppointmentController::class, 'cancelApply']);
 
         })->middleware([
             \app\middleware\AdminAuthCheck::class
@@ -996,7 +1019,7 @@ Route::group('/admin', function () {
         Route::group('/refund', function () {
             Route::get('/list', [\app\admin\controller\order\RefundController::class, 'select']);
             Route::get('/sheet', [\app\admin\controller\order\RefundController::class, 'sheet']);
-            Route::post('/customRefund',[\app\admin\controller\order\RefundController::class,'customRefund']);
+            Route::post('/customRefund', [\app\admin\controller\order\RefundController::class, 'customRefund']);
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
@@ -1004,9 +1027,9 @@ Route::group('/admin', function () {
         Route::group('/payDetail', function () {
             Route::get('/list', [\app\admin\controller\order\PayDetailController::class, 'select']);
             Route::get('/welfareList', [\app\admin\controller\order\PayDetailController::class, 'selectWelfare']);
-            Route::get('/goodsOrder',[\app\admin\controller\order\PayDetailController::class,'goodsOrder']);
-            Route::post('/insertRecharge',[\app\admin\controller\order\PayDetailController::class,'insertRecharge']);
-            Route::post('/insertRechargeWelfare',[\app\admin\controller\order\PayDetailController::class,'insertRechargeWelfare']);
+            Route::get('/goodsOrder', [\app\admin\controller\order\PayDetailController::class, 'goodsOrder']);
+            Route::post('/insertRecharge', [\app\admin\controller\order\PayDetailController::class, 'insertRecharge']);
+            Route::post('/insertRechargeWelfare', [\app\admin\controller\order\PayDetailController::class, 'insertRechargeWelfare']);
 //            Route::get('/info', [\app\admin\controller\order\AppointmentController::class, 'info']);
         });
     });
@@ -1036,7 +1059,7 @@ Route::group('/admin', function () {
         })->middleware([
             \app\middleware\AdminAuthCheck::class
         ]);
-        
+
         /* 评价管理 */
         Route::group('/evaluate', function () {
             Route::get('/list', [\app\admin\controller\client\EvaluateController::class, 'select']);