209 lines
6.7 KiB
PHP
209 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace app\support;
|
|
|
|
use support\think\Db;
|
|
|
|
class ExpressCompanyService
|
|
{
|
|
public function __construct()
|
|
{
|
|
$this->ensureTable();
|
|
$this->bootstrapDefaults();
|
|
}
|
|
|
|
public function list(bool $enabledOnly = false): array
|
|
{
|
|
$query = Db::name('express_companies')
|
|
->order('is_default', 'desc')
|
|
->order('sort_order', 'asc')
|
|
->order('id', 'asc');
|
|
|
|
if ($enabledOnly) {
|
|
$query->where('status', 'enabled');
|
|
}
|
|
|
|
return array_map(fn (array $item) => $this->format($item), $query->select()->toArray());
|
|
}
|
|
|
|
public function save(array $payload, int $id = 0): int
|
|
{
|
|
$now = date('Y-m-d H:i:s');
|
|
$companyName = trim((string)($payload['company_name'] ?? ''));
|
|
$companyCode = trim((string)($payload['company_code'] ?? ''));
|
|
$status = trim((string)($payload['status'] ?? 'enabled'));
|
|
$isDefault = !empty($payload['is_default']);
|
|
|
|
if ($companyName === '') {
|
|
throw new \RuntimeException('快递公司名称不能为空');
|
|
}
|
|
if (!in_array($status, ['enabled', 'disabled'], true)) {
|
|
throw new \RuntimeException('快递公司状态无效');
|
|
}
|
|
if ($isDefault && $status !== 'enabled') {
|
|
throw new \RuntimeException('默认快递公司必须保持启用');
|
|
}
|
|
if ($companyCode === '') {
|
|
$companyCode = $this->generateCompanyCode($companyName);
|
|
}
|
|
|
|
$existsByName = Db::name('express_companies')
|
|
->where('company_name', $companyName)
|
|
->when($id > 0, fn ($query) => $query->where('id', '<>', $id))
|
|
->find();
|
|
if ($existsByName) {
|
|
throw new \RuntimeException('快递公司名称已存在');
|
|
}
|
|
|
|
$existsByCode = Db::name('express_companies')
|
|
->where('company_code', $companyCode)
|
|
->when($id > 0, fn ($query) => $query->where('id', '<>', $id))
|
|
->find();
|
|
if ($existsByCode) {
|
|
throw new \RuntimeException('快递公司编码已存在');
|
|
}
|
|
|
|
$data = [
|
|
'company_name' => $companyName,
|
|
'company_code' => $companyCode,
|
|
'status' => $status,
|
|
'is_default' => $isDefault ? 1 : 0,
|
|
'sort_order' => (int)($payload['sort_order'] ?? 0),
|
|
'remark' => trim((string)($payload['remark'] ?? '')),
|
|
'updated_at' => $now,
|
|
];
|
|
|
|
Db::startTrans();
|
|
try {
|
|
if ($isDefault) {
|
|
Db::name('express_companies')->update([
|
|
'is_default' => 0,
|
|
'updated_at' => $now,
|
|
]);
|
|
}
|
|
|
|
if ($id > 0) {
|
|
Db::name('express_companies')->where('id', $id)->update($data);
|
|
$companyId = $id;
|
|
} else {
|
|
$data['created_at'] = $now;
|
|
$companyId = (int)Db::name('express_companies')->insertGetId($data);
|
|
}
|
|
|
|
$this->ensureEnabledDefault($now);
|
|
Db::commit();
|
|
} catch (\Throwable $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
|
|
return $companyId;
|
|
}
|
|
|
|
public function defaultName(): string
|
|
{
|
|
$row = Db::name('express_companies')
|
|
->where('status', 'enabled')
|
|
->where('is_default', 1)
|
|
->find();
|
|
|
|
if (!$row) {
|
|
$row = Db::name('express_companies')
|
|
->where('status', 'enabled')
|
|
->order('sort_order', 'asc')
|
|
->order('id', 'asc')
|
|
->find();
|
|
}
|
|
|
|
return trim((string)($row['company_name'] ?? ''));
|
|
}
|
|
|
|
private function format(array $item): array
|
|
{
|
|
$status = (string)($item['status'] ?? 'enabled');
|
|
|
|
return [
|
|
'id' => (int)$item['id'],
|
|
'company_name' => (string)$item['company_name'],
|
|
'company_code' => (string)$item['company_code'],
|
|
'status' => $status,
|
|
'status_text' => $status === 'enabled' ? '启用中' : '已停用',
|
|
'is_default' => (bool)$item['is_default'],
|
|
'sort_order' => (int)$item['sort_order'],
|
|
'remark' => (string)($item['remark'] ?? ''),
|
|
'created_at' => (string)($item['created_at'] ?? ''),
|
|
'updated_at' => (string)($item['updated_at'] ?? ''),
|
|
];
|
|
}
|
|
|
|
private function bootstrapDefaults(): void
|
|
{
|
|
$now = date('Y-m-d H:i:s');
|
|
$exists = Db::name('express_companies')->where('company_name', '顺丰速运')->find();
|
|
if (!$exists) {
|
|
Db::name('express_companies')->insert([
|
|
'company_name' => '顺丰速运',
|
|
'company_code' => 'sf_express',
|
|
'status' => 'enabled',
|
|
'is_default' => 1,
|
|
'sort_order' => 1,
|
|
'remark' => '系统默认快递公司',
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
}
|
|
|
|
$this->ensureEnabledDefault($now);
|
|
}
|
|
|
|
private function ensureEnabledDefault(string $now): void
|
|
{
|
|
$default = Db::name('express_companies')
|
|
->where('status', 'enabled')
|
|
->where('is_default', 1)
|
|
->find();
|
|
if ($default) {
|
|
return;
|
|
}
|
|
|
|
$firstEnabled = Db::name('express_companies')
|
|
->where('status', 'enabled')
|
|
->order('sort_order', 'asc')
|
|
->order('id', 'asc')
|
|
->find();
|
|
if ($firstEnabled) {
|
|
Db::name('express_companies')->where('id', $firstEnabled['id'])->update([
|
|
'is_default' => 1,
|
|
'updated_at' => $now,
|
|
]);
|
|
}
|
|
}
|
|
|
|
private function generateCompanyCode(string $companyName): string
|
|
{
|
|
return 'express_' . substr(hash('sha256', $companyName), 0, 12);
|
|
}
|
|
|
|
private function ensureTable(): void
|
|
{
|
|
Db::execute(<<<'SQL'
|
|
CREATE TABLE IF NOT EXISTS express_companies (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
company_name VARCHAR(64) NOT NULL DEFAULT '',
|
|
company_code VARCHAR(64) NOT NULL DEFAULT '',
|
|
status VARCHAR(32) NOT NULL DEFAULT 'enabled',
|
|
is_default TINYINT(1) NOT NULL DEFAULT 0,
|
|
sort_order INT NOT NULL DEFAULT 0,
|
|
remark VARCHAR(255) NOT NULL DEFAULT '',
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uk_express_companies_name (company_name),
|
|
UNIQUE KEY uk_express_companies_code (company_code),
|
|
KEY idx_express_companies_status (status),
|
|
KEY idx_express_companies_default (is_default)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='快递公司字典'
|
|
SQL);
|
|
}
|
|
}
|