|
|
@@ -20,7 +20,7 @@ class Purchasecontent extends Backend
|
|
|
protected const RECIPIENT_AUTH_GROUP_ROOT_ID = 10;
|
|
|
|
|
|
/** 表结构已就绪缓存键(避免每次请求重复 SHOW COLUMNS / 探表) */
|
|
|
- protected const SCHEMA_CACHE_KEY = 'purchase_content_schema_v2';
|
|
|
+ protected const SCHEMA_CACHE_KEY = 'purchase_content_schema_v3';
|
|
|
|
|
|
/** 可选接收人列表缓存秒数 */
|
|
|
protected const RECIPIENT_LIST_CACHE_TTL = 300;
|
|
|
@@ -41,36 +41,64 @@ class Purchasecontent extends Backend
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /** 首次访问时建表/迁移,完成后写入缓存 */
|
|
|
+ /**
|
|
|
+ * 首次访问时建表/迁移;仅当两表均存在才写缓存,避免建表失败后永久跳过。
|
|
|
+ */
|
|
|
protected function ensurePurchaseContentSchemaOnce(): void
|
|
|
{
|
|
|
$this->ensurePurchaseContentTables();
|
|
|
- $this->ensurePurchaseContentDatetimeColumns();
|
|
|
- Cache::set(self::SCHEMA_CACHE_KEY, 1);
|
|
|
+ if ($this->purchaseContentTablesReady()) {
|
|
|
+ $this->ensurePurchaseContentDatetimeColumns();
|
|
|
+ Cache::set(self::SCHEMA_CACHE_KEY, 1, 86400);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- protected function ensurePurchaseContentTables(): void
|
|
|
+ protected function purchaseContentTablesReady(): bool
|
|
|
{
|
|
|
try {
|
|
|
Db::query('SELECT 1 FROM `purchase_content` LIMIT 1');
|
|
|
Db::query('SELECT 1 FROM `purchase_content_recipient` LIMIT 1');
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function ensurePurchaseContentTables(): void
|
|
|
+ {
|
|
|
+ if ($this->purchaseContentTablesReady()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 内联建表(不依赖 sql 文件拆分),与 ProcuremenSchema 一致
|
|
|
+ try {
|
|
|
+ Db::execute("CREATE TABLE IF NOT EXISTS `purchase_content` (
|
|
|
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
|
|
+ `creator_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建人',
|
|
|
+ `sender_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '投递人',
|
|
|
+ `subject` varchar(255) NOT NULL DEFAULT '' COMMENT '主题',
|
|
|
+ `content` mediumtext COMMENT '内容',
|
|
|
+ `createtime` datetime DEFAULT NULL COMMENT '投递时间',
|
|
|
+ `updatetime` datetime DEFAULT NULL COMMENT '更新时间',
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
+ KEY `idx_creator` (`creator_id`),
|
|
|
+ KEY `idx_sender` (`sender_id`),
|
|
|
+ KEY `idx_ct` (`createtime`)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='协助采购通知公告'");
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ Db::execute("CREATE TABLE IF NOT EXISTS `purchase_content_recipient` (
|
|
|
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
|
|
+ `content_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '公告ID',
|
|
|
+ `admin_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '接收人',
|
|
|
+ `read_time` datetime DEFAULT NULL COMMENT '首次阅读时间',
|
|
|
+ `createtime` datetime DEFAULT NULL COMMENT '创建时间',
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
+ UNIQUE KEY `uk_content_admin` (`content_id`,`admin_id`),
|
|
|
+ KEY `idx_admin` (`admin_id`)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知公告接收人'");
|
|
|
} catch (\Throwable $e) {
|
|
|
- $sqlFile = APP_PATH . 'extra' . DS . 'purchase_content_install.sql';
|
|
|
- if (is_file($sqlFile)) {
|
|
|
- $sql = file_get_contents($sqlFile);
|
|
|
- if (is_string($sql) && $sql !== '') {
|
|
|
- foreach (preg_split('/;\s*[\r\n]+/', $sql) as $stmt) {
|
|
|
- $stmt = trim($stmt);
|
|
|
- if ($stmt === '' || stripos($stmt, 'CREATE TABLE') === false) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- try {
|
|
|
- Db::execute($stmt);
|
|
|
- } catch (\Throwable $ignore) {
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|