初始化

This commit is contained in:
2026-08-08 18:28:49 +08:00
parent 9bef4420e0
commit f082037a6e
854 changed files with 217171 additions and 11 deletions
+192
View File
@@ -0,0 +1,192 @@
<?php
namespace app\models;
use core\base\Model;
/**
* 系统配置模型
*/
class SysConfig extends Model
{
protected $table = 'sys_config';
// 获取配置
public function getConfig()
{
return $this->where(['id = :id'], [':id' => 1])->fetch();
}
// 更新配置
public function updateConfig($data)
{
return $this->where(['id = :id'], [':id' => 1])->update($data);
}
/**
* 获取代码前缀规则
* 格式: ['成品' => 'CP', '电芯' => 'DX', 'PCBA' => 'XLB']
*/
public function getCodePrefixRules()
{
$config = $this->getConfig();
$raw = $config['code_prefix_rules'] ?? '';
if (empty($raw)) {
// 返回默认规则
$rules = $this->getDefaultCodePrefixRules();
} else {
$rules = json_decode($raw, true);
if (!is_array($rules)) {
$rules = $this->getDefaultCodePrefixRules();
}
}
// 产品类型别名对齐:确保同义类型能匹配到同一前缀规则
// 例如配置表中使用「电池」,而前缀规则可能使用旧名「电芯」
$aliases = [
'电池' => '电芯',
'电芯' => '电池',
'底壳' => '外壳',
'外壳' => '底壳',
'半成品' => '半成',
'半成' => '半成品',
];
foreach ($aliases as $from => $to) {
if (!isset($rules[$from]) && isset($rules[$to])) {
$rules[$from] = $rules[$to];
}
}
return $rules;
}
/**
* 获取默认代码前缀规则
*/
public function getDefaultCodePrefixRules()
{
return [
'成品' => 'CP',
'电池' => 'dc',
'PCBA' => 'xlb',
'半成品' => '',
'外壳' => '',
'包装' => '',
'配件' => '',
];
}
/**
* 根据产品类型获取代码前缀
* @param string $productType 产品类型(如:成品、电芯、PCBA)
* @return string 前缀,无规则返回空字符串
*/
public function getPrefixByType($productType)
{
$rules = $this->getCodePrefixRules();
$prefix = $rules[$productType] ?? '';
// 原则:所有工位序列号都受前缀管控。配置了该类型但前缀为空时,
// 自动回退为「产品类型名拼音首字母」,避免无前缀类型被放行或卡死。
if ($prefix === '' && isset($rules[$productType])) {
$prefix = $this->pinyinInitials($productType);
}
return $prefix;
}
/**
* 取得字符串的拼音首字母(中文取首字拼音首字母,英文/数字原样保留)。
* 兼容「外壳」「包装」「半成品」「配件」等常见类型,英文部分(如 PCBA)原样输出。
* @param string $str
* @return string
*/
public function pinyinInitials($str)
{
$str = trim($str);
if ($str === '') return '';
// 常见产品类型精确映射(避免多音字/误判)
$map = [
'外壳' => 'WK',
'底壳' => 'WK',
'包装' => 'BZ',
'半成品' => 'BCP',
'半成' => 'BCP',
'配件' => 'PJ',
'成品' => 'CP',
'电池' => 'DC',
'电芯' => 'DC',
'PCBA' => 'XLB',
];
if (isset($map[$str])) return $map[$str];
$first = mb_substr($str, 0, 1, 'UTF-8');
// 英文字母/数字:直接原样(大写)
if (preg_match('/^[A-Za-z0-9]$/', $first)) {
return strtoupper($first) . (mb_strlen($str, 'UTF-8') > 1 ? strtoupper(mb_substr($str, 1, 1, 'UTF-8')) : '');
}
// 中文:取首字拼音首字母
return $this->chineseInitial($first);
}
/**
* 单汉字 → 拼音首字母(GB2312 区位区间法,覆盖常用汉字)
*/
private function chineseInitial($char)
{
$py = 'A';
try {
$gbk = iconv('UTF-8', 'GB2312//IGNORE', $char);
} catch (\Throwable $e) {
$gbk = '';
}
if ($gbk === '' || strlen($gbk) < 2) {
return $py; // 生僻字/无法转换时回退
}
$hi = ord($gbk[0]);
$lo = ord($gbk[1]);
$code = $hi * 256 + $lo;
// GB2312 拼音首字母分区(常用字)
$ranges = [
[0xB0A1, 0xB0C4, 'A'], [0xB0C5, 0xB2C0, 'B'], [0xB2C1, 0xB4ED, 'C'],
[0xB4EE, 0xB6E9, 'D'], [0xB6EA, 0xB7A1, 'E'], [0xB7A2, 0xB8C0, 'F'],
[0xB8C1, 0xB9FD, 'G'], [0xB9FE, 0xBBF6, 'H'], [0xBBF7, 0xBFA5, 'J'],
[0xBFA6, 0xC0AB, 'K'], [0xC0AC, 0xC2E7, 'L'], [0xC2E8, 0xC4C2, 'M'],
[0xC4C3, 0xC5B5, 'N'], [0xC5B6, 0xC5BD, 'O'], [0xC5BE, 0xC6DA, 'P'],
[0xC6DB, 0xC8BA, 'Q'], [0xC8BB, 0xC8F5, 'R'], [0xC8F6, 0xCBF0, 'S'],
[0xCBF1, 0xCDDA, 'T'], [0xCDDB, 0xCEF3, 'W'], [0xCEF4, 0xD1B8, 'X'],
[0xD1B9, 0xD4D0, 'Y'], [0xD4D1, 0xD7F9, 'Z'],
];
foreach ($ranges as $r) {
if ($code >= $r[0] && $code <= $r[1]) { $py = $r[2]; break; }
}
return $py;
}
/**
* 获取所有已配置的非空前缀规则(用于验证)
* @return array [前缀 => 产品类型名]
*/
public function getActivePrefixMap()
{
$rules = $this->getCodePrefixRules();
$active = [];
foreach ($rules as $type => $prefix) {
if (!empty($prefix)) {
$active[$prefix] = $type;
}
}
return $active;
}
/**
* 更新代码前缀规则(JSON 存储)
* @param array $rules ['成品' => 'CP', '电池' => 'dc', ...]
*/
public function updateCodePrefixRules($rules)
{
$json = json_encode($rules, JSON_UNESCAPED_UNICODE);
// 使用原生 PDO 直写,避免 Model::update 链式调用在二次写入时的潜在问题
$pdo = \core\db\Db::pdo();
$table = $this->getTable();
$stmt = $pdo->prepare("UPDATE {$table} SET code_prefix_rules = :v WHERE id = 1");
$stmt->execute([':v' => $json]);
return true;
}
}