CRMEB单商户-功能扩展之营业时间段

当前版本 CRMEB-BZ v5.6.0(20250308)

数据库变更

店铺营业时间段

php think migrate:create CreateStoreSaleWeek

public function change()
{
    $table = $this->table('store_sale_week', ['comment' => '店铺营业时间段', 'signed' => false]);
    $table->addColumn('day_of_week', AdapterInterface::PHINX_TYPE_INTEGER, ['length' => MysqlAdapter::INT_TINY, 'comment' => '星期几(0-6,0表示周日)', 'null' => false, 'signed' => false])
        ->addColumn('range_1', AdapterInterface::PHINX_TYPE_CHAR, ['comment' => '时间范围', 'limit' => 23, 'default' => null, 'null' => true])
        ->addColumn('range_2', AdapterInterface::PHINX_TYPE_CHAR, ['comment' => '时间范围', 'limit' => 23, 'default' => null, 'null' => true])
        ->addColumn('range_3', AdapterInterface::PHINX_TYPE_CHAR, ['comment' => '时间范围', 'limit' => 23, 'default' => null, 'null' => true])
        ->addColumn('enabled', AdapterInterface::PHINX_TYPE_INTEGER, ['comment' => '启用状态', 'length' => MysqlAdapter::INT_TINY, 'default' => 1, 'null' => false, 'signed' => false])
        ->addColumn('create_time', 'datetime', ['comment' => '创建时间', 'null' => false, 'default' => 'CURRENT_TIMESTAMP'])
        ->addColumn('update_time', 'datetime', ['comment' => '更新时间', 'null' => true, 'default' => 'CURRENT_TIMESTAMP', 'update' => 'CURRENT_TIMESTAMP'])
        ->addIndex(['day_of_week'], ['unique' => true, 'name' => 'idx_week'])
        ->addIndex(['enabled'], ['name' => 'idx_enabled'])
        ->create();
}

代码变更

1.模型层变更(新增模型)

新增模型类 app/model/EbStoreSaleWeek.php

<?php

namespace app\model;

use think\db\BaseQuery;
use think\db\Query;
use think\Model;

/**
 * eb_store_sale_week 店铺营业时间段
 * @property integer $id 主键(主键)
 * @property integer $day_of_week 星期几(0-6,0表示周日)
 * @property array|null $range_1 时间范围
 * @property array|null $range_2 时间范围
 * @property array|null $range_3 时间范围
 * @property int|bool $enabled 启用状态
 * @property string $create_time 创建时间
 * @property string $update_time 更新时间
 */
class EbStoreSaleWeek extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'eb_store_sale_week';

    /**
     * The primary key associated with the table.
     *
     * @var string
     */
    protected $pk = 'id';

    /**
     * 每天营业时间段的最大数量
     */
    public const RANGE_MAX = 3;

    /**
     * The attributes that are mass assignable.
     * @var array
     */
    protected $type = [
        'range_1' => 'array',
        'range_2' => 'array',
        'range_3' => 'array',
    ];

    /**
     * 星期几
     * @var array
     */
    public const DAY_OF_WEEK_MAP = [
        0 => '周日',
        1 => '周一',
        2 => '周二',
        3 => '周三',
        4 => '周四',
        5 => '周五',
        6 => '周六',
    ];

    /**
     * 获取秒数
     * @param int $timestamp 时间戳
     * @return float|int
     */
    public static function seconds(int $timestamp)
    {
        return (int)date('H', $timestamp) * 3600 + (int)date('i', $timestamp) * 60 + (int)date('s', $timestamp);
    }

    /**
     * 转换时分秒为今日的秒数
     * @param string $time 时间,格式为HH:mm:ss
     * @return int
     */
    public static function conversionTodaySeconds(string $time): int
    {
        $time = explode(':', $time);
        return (int)$time[0] * 3600 + (int)$time[1] * 60 + (int)$time[2];
    }

    /**
     * 校验一个时间戳是否在营业时间段内
     * @param int $timestamp
     * @return bool
     */
    public static function validate(int $timestamp): bool
    {
        // 获取星期几
        $week = date('w', $timestamp);
        /** @var static $model */
        $model = self::queryByDayOfWeek($week)->findOrEmpty();
        if ($model->isEmpty()) {
            return false;
        }
        if (!$model->isEnabled()) {
            return false;
        }

        $seconds = self::seconds($timestamp);
        foreach (range(1, self::RANGE_MAX) as $i) {
            $range = $model->getAttr('range_' . $i);
            if (empty($range)) {
                continue;
            }

            [$start, $end] = $range;
            $start_number = self::conversionTodaySeconds($start);
            $end_number = self::conversionTodaySeconds($end);
            if ($start_number <= $seconds && $seconds <= $end_number) {
                return true;
            }
        }

        return false;
    }

    /**
     * 根据星期几查询
     * @param int $day_of_week
     * @return Query|BaseQuery
     */
    public static function queryByDayOfWeek(int $day_of_week): Query
    {
        $model = new static();

        return $model->db()->where('day_of_week', $day_of_week);
    }

    /**
     * 根据启用状态查询
     * @param bool $enabled
     * @return Query|BaseQuery
     */
    public static function queryByEnabled(bool $enabled = true): Query
    {
        $model = new static();

        return $model->db()->where('enabled', $enabled ? 1 : 0);
    }

    /**
     * 获取启用状态
     * @return bool
     */
    public function isEnabled(): bool
    {
        return (bool)$this->getAttr('enabled');
    }
}

2. 控制器变更

新增控制器 app/adminapi/controller/SaleWeek.php

<?php
declare (strict_types=1);

namespace app\adminapi\controller;

use app\model\EbStoreSaleWeek;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use app\Request;
use think\Response;
use think\response\Json;
use Throwable;

/**
 * 店铺营业时间段
 * Class SaleWeek
 * @package app\adminapi\controller
 */
class SaleWeek extends AuthController
{
    /**
     * 店铺营业时间段
     * @return Response|Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function index(): Json
    {
        $model = new EbStoreSaleWeek();
        $query = $model->db()->order('day_of_week', 'asc');

        return response_json()->success('ok', [
            'list' => $query->select()->toArray(),
            'count' => $query->count(),
        ]);
    }

    /**
     * 保存新建的资源
     * @method POST
     * @param Request $request
     * @return Response|Json
     */
    public function save(Request $request): Json
    {
        $id = $request->post('id/d');
        try {
            $model = new EbStoreSaleWeek();
            $data = $request->post(false);
            unset($data[$model->getPk()]);
            if ($id) {
                $model = EbStoreSaleWeek::findOrFail($id);
                $model->save($data);
            } else {
                $model = EbStoreSaleWeek::create($data);
            }

            return response_json()->success('ok', $model->toArray());
        } catch (Throwable $throwable) {
            return response_json()->fail($throwable->getMessage());
        }
    }

    /**
     * 删除指定资源
     * @method DELETE
     * @param string|int $id
     * @return Response|Json
     */
    public function delete($id): Json
    {
        $ids = is_array($id) ? $id : explode('_', $id);
        EbStoreSaleWeek::destroy($ids);
        return response_json()->success('ok');
    }
}

3.路由变更

app/adminapi/route/setting.php 的路由分组内,增加

/**
 * 店铺外卖营业时间段
 * @author david
 * @date 2025年4月25日 13:16:50
 */
Route::get('sale_week', 'SaleWeek/index')->option(['real_name' => '店铺外卖营业时间段列表']);
Route::post('sale_week', 'SaleWeek/save')->option(['real_name' => '店铺外卖营业时间段创建或更新']);
Route::delete('sale_week/:id', 'SaleWeek/delete')->option(['real_name' => '店铺外卖营业时间段删除']);

4.服务层变更

变更 \app\services\order\StoreOrderServices::getOrderConfirmData 方法

新增以下代码逻辑,可以校验特定类型的订单,也可以校验所有类型的订单

// 校验外卖营业时间段
if (1 == $shipping_type) {
    if (!EbStoreSaleWeek::validate(time())) {
        throw new ApiException('当前不在营业时间范围');
    }
}
最后修改:2025 年 04 月 25 日 03 : 41 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论