feat: 初始化进销存数据开放平台项目

初始化完整的前后端项目结构,包含ThinkPHP后端API服务和Next.js前端管理系统,添加基础配置、中间件、模型、路由等核心代码,以及项目文档和静态资源。
This commit is contained in:
cenzuhai
2026-07-08 17:48:00 +08:00
parent 6713e13ea6
commit 3a04eede84
99 changed files with 17002 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
<?php
namespace app\model;
use think\Model;
class AdminUser extends Model
{
protected $name = 'admin_users';
protected $pk = 'id';
protected $autoWriteTimestamp = true;
protected $createTime = 'created_at';
protected $updateTime = false;
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
const ROLE_ADMIN = 'admin';
const ROLE_VIEWER = 'viewer';
public function checkPassword($password)
{
return password_verify($password, $this->getAttr('password_hash') ?? '');
}
public static function getRoles()
{
return [
self::ROLE_ADMIN => '管理员',
self::ROLE_VIEWER => '查看员',
];
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace app\model;
use think\Model;
class ApiKey extends Model
{
protected $name = 'api_keys';
protected $pk = 'id';
protected $autoWriteTimestamp = true;
protected $createTime = 'created_at';
protected $updateTime = false;
// 状态枚举
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
/**
* 关联客户
*/
public function client()
{
return $this->belongsTo(Client::class, 'client_id');
}
/**
* 关联权限
*/
public function permission()
{
return $this->hasOne(Permission::class, 'api_key_id');
}
/**
* 关联日志
*/
public function logs()
{
return $this->hasMany(ApiLog::class, 'api_key_id');
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace app\model;
use think\Model;
class ApiLog extends Model
{
protected $name = 'api_logs';
protected $pk = 'id';
protected $autoWriteTimestamp = true;
protected $createTime = 'created_at';
protected $updateTime = false;
protected $json = ['request_params', 'response_body'];
protected $jsonAssoc = true;
/**
* 关联API密钥
*/
public function apiKey()
{
return $this->belongsTo(ApiKey::class, 'api_key_id');
}
/**
* 关联客户
*/
public function client()
{
return $this->belongsTo(Client::class, 'client_id');
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace app\model;
use think\Model;
class Client extends Model
{
protected $name = 'clients';
protected $pk = 'id';
protected $autoWriteTimestamp = true;
protected $createTime = 'created_at';
protected $updateTime = 'updated_at';
protected $append = ['api_keys'];
// 客户类型枚举
const TYPE_SUPPLIER = 'supplier';
const TYPE_DISTRIBUTOR = 'distributor';
const TYPE_HOSPITAL = 'hospital';
const TYPE_OTHER = 'other';
// 状态枚举
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
/**
* 关联API密钥
*/
public function apiKeys()
{
return $this->hasMany(ApiKey::class, 'client_id');
}
/**
* 获取api_keys字段下划线命名
*/
public function getApiKeysAttr()
{
return $this->apiKeys()->select()->toArray();
}
/**
* 获取客户类型列表
*/
public static function getClientTypes()
{
return [
self::TYPE_SUPPLIER => '供应商',
self::TYPE_DISTRIBUTOR => '分销商',
self::TYPE_HOSPITAL => '医院',
self::TYPE_OTHER => '其他',
];
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace app\model;
use think\Model;
class Permission extends Model
{
protected $name = 'permissions';
protected $pk = 'id';
protected $autoWriteTimestamp = true;
protected $createTime = 'created_at';
protected $updateTime = 'updated_at';
// 权限枚举
const ALLOW_NO = 0;
const ALLOW_YES = 1;
// 数据模式枚举
const MODE_FILTER = 'filter';
const MODE_CUSTOM = 'custom';
const MODE_FULL = 'full';
/**
* 关联API密钥
*/
public function apiKey()
{
return $this->belongsTo(ApiKey::class, 'api_key_id');
}
/**
* 检查是否允许访问接口
*/
public function canAccess($endpoint)
{
if ($this->isFullData()) {
return true;
}
if ($endpoint === 'chuku') {
return $this->allow_chuku == self::ALLOW_YES;
} elseif ($endpoint === 'ruku') {
return $this->allow_ruku == self::ALLOW_YES;
}
return false;
}
/**
* 检查是否允许全量数据
*/
public function isFullData()
{
return $this->allow_full_data == self::ALLOW_YES;
}
}