<?php namespace Phpcmf\Model;
/**
 * https://www.besyun.com
 * BESCMS
 * 本文件是框架系统文件，二次开发时不可以修改本文件，可以通过继承类方法来重写此文件
 **/


// 数据表（DDL 优先驱动；未实现时按 MySQL 源方言兼容，经 formatCreateSql 转换）
class Table extends \Phpcmf\Model {

    /**
     * MySQL 源方言标识符加反引号（供 formatCreateSql 转换）
     *
     * @param string $id
     * @return string
     */
    protected function _mysql_qi($id) {
        return '`'.str_replace('`', '``', $this->unquote_id((string) $id)).'`';
    }

    /**
     * 执行 MySQL 源 DDL（_query_batch → dr_format_create_sql）
     *
     * @param string $sql
     * @return bool
     */
    protected function _ddl_exec_mysql($sql) {

        $sql = trim((string) $sql);
        if ($sql === '') {
            return false;
        }

        $rt = $this->_query_batch($sql);
        if (!empty($rt['code'])) {
            return true;
        }

        log_message('error', 'DDL compat: '.($rt['msg'] ?? $sql));
        return false;
    }

    /**
     * 修改字段（优先驱动 editField）
     *
     * @param string $table
     * @param string $name
     * @param string $type
     * @param string $info
     * @param string $note
     * @return mixed
     */
    public function edit_field($table, $name, $type, $info, $note) {

        if (method_exists($this->db, 'editField')) {
            return $this->db->editField($table, $name, $type, $info, $note);
        }

        return $this->_edit_field_compat($table, $name, $type, $info, $note);
    }

    /**
     * @param string $table
     * @param string $name
     * @param string $type
     * @param string $info
     * @param string $note
     * @return bool
     */
    protected function _edit_field_compat($table, $name, $type, $info, $note) {

        $table = $this->unquote_id((string) $table);
        $name = $this->unquote_id((string) $name);
        if ($table === '' || $name === '') {
            return false;
        }

        $qi = $this->_mysql_qi($name);
        $sql = 'ALTER TABLE '.$this->_mysql_qi($table).' CHANGE '.$qi.' '.$qi
            .' '.$type.' '.$info;
        $note = (string) $note;
        if ($note !== '') {
            $sql .= " COMMENT '".str_replace("'", "''", $note)."'";
        }

        return $this->_ddl_exec_mysql($sql);
    }

    /**
     * 添加字段（优先驱动 addField）
     *
     * @param string $table
     * @param string $name
     * @param string $type
     * @param string $info
     * @param string $note
     * @return mixed
     */
    public function add_field($table, $name, $type, $info, $note) {

        if (method_exists($this->db, 'addField')) {
            return $this->db->addField($table, $name, $type, $info, $note);
        }

        return $this->_add_field_compat($table, $name, $type, $info, $note);
    }

    /**
     * @param string $table
     * @param string $name
     * @param string $type
     * @param string $info
     * @param string $note
     * @return bool
     */
    protected function _add_field_compat($table, $name, $type, $info, $note) {

        $table = $this->unquote_id((string) $table);
        $name = $this->unquote_id((string) $name);
        if ($table === '' || $name === '') {
            return false;
        }

        $sql = 'ALTER TABLE '.$this->_mysql_qi($table).' ADD '.$this->_mysql_qi($name)
            .' '.$type.' '.$info;
        $note = (string) $note;
        if ($note !== '') {
            $sql .= " COMMENT '".str_replace("'", "''", $note)."'";
        }

        return $this->_ddl_exec_mysql($sql);
    }

    /**
     * 删除字段（优先驱动 dropField）
     *
     * @param string $table
     * @param string $name
     * @return mixed
     */
    public function drop_field($table, $name) {

        if (method_exists($this->db, 'dropField')) {
            return $this->db->dropField($table, $name);
        }

        return $this->_drop_field_compat($table, $name);
    }

    /**
     * @param string $table
     * @param string $name
     * @return bool
     */
    protected function _drop_field_compat($table, $name) {

        $table = $this->unquote_id((string) $table);
        $name = $this->unquote_id((string) $name);
        if ($table === '' || $name === '') {
            return false;
        }

        return $this->_ddl_exec_mysql(
            'ALTER TABLE '.$this->_mysql_qi($table).' DROP '.$this->_mysql_qi($name)
        );
    }

    // 根据配置创建字段（字段类 create_sql 经驱动 sqlAddField 生成）
    public function create_field($table, $config) {

        if (!$config || !$table) {
            return;
        }

        $tablename = $this->dbprefix($table);
        foreach ($config as $field) {

            if ($this->db->fieldExists($field['fieldname'], $tablename)) {
                continue;
            }

            $obj = \Phpcmf\Service::L('field')->get($field['fieldtype']);
            if (!$obj) {
                continue;
            }

            $sql = $obj->create_sql($field['fieldname'], $field['setting']['option'], dr_safe_filename($field['name']));
            if (!$sql) {
                continue;
            }
            // create_sql 为 MySQL 源（含 {tablename}），走兼容执行
            $sql = str_replace('{tablename}', $this->unquote_id($tablename), $sql);
            $this->_ddl_exec_mysql($sql);
        }
    }

    /**
     * 创建表（优先驱动 createTable；未实现时拼 MySQL 源 SQL 经 formatCreateSql 兼容执行）
     *
     * @param string $table  表名（可含前缀）
     * @param array  $fields ['字段名'=>'类型属性'] 或 [0=>'完整列定义']
     * @param array  $indexs ['PRIMARY KEY (`id`)', 'KEY `name` (`name`)', ...]
     * @param string $note   表注释
     * @return array
     */
    public function create_table($table, $fields, $indexs, $note) {

        try {
            if (method_exists($this->db, 'createTable')) {
                $rt = $this->db->createTable($table, $fields, $indexs, $note);
                if ($rt === false) {
                    $error = $this->db->error();
                    return dr_return_data(0, $error['message'] ?? 'createTable failed');
                }
                return dr_return_data(1);
            }
            return $this->_create_table_compat($table, $fields, $indexs, $note);
        } catch (\Throwable $e) {
            log_message('error', 'createTable: '.$e->getMessage());
            return dr_return_data(0, $e->getMessage());
        }
    }

    /**
     * 驱动未实现 createTable 时的兼容建表
     *
     * @param string $table
     * @param array  $fields
     * @param array  $indexs
     * @param string $note
     * @return array
     */
    protected function _create_table_compat($table, $fields, $indexs, $note) {

        $table = $this->unquote_id((string) $table);
        if ($table === '' || !is_array($fields) || !$fields) {
            return dr_return_data(0, 'createTable 参数无效');
        }

        $lines = [];
        foreach ($fields as $name => $def) {
            if (is_int($name)) {
                $lines[] = (string) $def;
            } else {
                $lines[] = $this->_mysql_qi($name).' '.(string) $def;
            }
        }

        if (is_array($indexs)) {
            foreach ($indexs as $idx) {
                $idx = trim((string) $idx);
                if ($idx !== '') {
                    $lines[] = $idx;
                }
            }
        }

        if (!$lines) {
            return dr_return_data(0, 'createTable 无字段定义');
        }

        $sql = 'CREATE TABLE IF NOT EXISTS '.$this->_mysql_qi($table).' (
'.implode(",\n", $lines).'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT=\''
            .str_replace("'", "''", (string) $note).'\'';

        $rt = $this->_query_batch($sql);
        if (empty($rt['code'])) {
            return dr_return_data(0, $rt['msg'] ?? 'createTable compat failed');
        }

        return dr_return_data(1);
    }

    /**
     * 删除表（优先驱动 dropTable；未实现时走兼容 SQL）
     *
     * @param string $table
     * @param bool   $ifExists
     * @return array
     */
    public function drop_table($table, $ifExists = true) {

        try {
            if (method_exists($this->db, 'dropTable')) {
                $rt = $this->db->dropTable($table, $ifExists);
            } else {
                $rt = $this->_drop_table_compat($table, $ifExists);
            }
            if ($rt === false) {
                $error = $this->db->error();
                return dr_return_data(0, $error['message'] ?? 'dropTable failed');
            }
            return dr_return_data(1);
        } catch (\Throwable $e) {
            log_message('error', 'dropTable: '.$e->getMessage());
            return dr_return_data(0, $e->getMessage());
        }
    }

    /**
     * 驱动未实现 dropTable 时的兼容删除
     *
     * @param string $table
     * @param bool   $ifExists
     * @return bool
     */
    protected function _drop_table_compat($table, $ifExists = true) {

        $table = $this->unquote_id((string) $table);
        if ($table === '') {
            return false;
        }

        if ($ifExists && method_exists($this->db, 'tableExists') && !$this->db->tableExists($table)) {
            return true;
        }

        $sql = ($ifExists ? 'DROP TABLE IF EXISTS ' : 'DROP TABLE ').$this->_mysql_qi($table);
        if ($this->_ddl_exec_mysql($sql)) {
            return true;
        }

        // IF EXISTS 不被支持时退化
        if ($ifExists) {
            return $this->_ddl_exec_mysql('DROP TABLE '.$this->_mysql_qi($table));
        }

        return false;
    }

    /**
     * 按 Schema 安装表结构与种子数据（Config/Install.php）
     *
     * @param array $schema ['tables'=>[name=>['fields','indexes','comment','drop']], 'seeds'=>[['table','data']]]
     * @return array
     */
    public function install_schema(array $schema) {

        $tables = isset($schema['tables']) && is_array($schema['tables']) ? $schema['tables'] : [];
        $seeds = isset($schema['seeds']) && is_array($schema['seeds']) ? $schema['seeds'] : [];

        foreach ($tables as $name => $def) {
            if (!$name || !is_array($def) || empty($def['fields'])) {
                continue;
            }
            $table = $this->dbprefix($name);
            if (!empty($def['drop'])) {
                $rt = $this->drop_table($table, true);
                if (!$rt['code']) {
                    return $rt;
                }
            }
            $rt = $this->create_table(
                $table,
                $def['fields'],
                isset($def['indexes']) ? $def['indexes'] : [],
                isset($def['comment']) ? $def['comment'] : ''
            );
            if (!$rt['code']) {
                return dr_return_data(0, dr_lang('创建表失败（%s）：%s', $table, $rt['msg']));
            }
        }

        foreach ($seeds as $seed) {
            if (empty($seed['table']) || empty($seed['data']) || !is_array($seed['data'])) {
                continue;
            }
            $rt = \Phpcmf\Service::M()->table($seed['table'])->replace($seed['data']);
            if (is_array($rt) && isset($rt['code']) && !$rt['code']) {
                return dr_return_data(0, dr_lang('写入初始数据失败（%s）：%s', $seed['table'], $rt['msg']));
            }
        }

        return dr_return_data(1, '', ['tables' => dr_count($tables), 'seeds' => dr_count($seeds)]);
    }

    /**
     * 获取建表 SQL（优先驱动 createTableSql）
     *
     * @param string $table
     * @return array [createSql, fieldFragments, table]
     */
    public function create_table_sql($table) {

        if (method_exists($this->db, 'createTableSql')) {
            $create = $this->db->createTableSql($table);
        } else {
            $create = $this->_create_table_sql_compat($table);
        }

        if (!$create) {
            return ['', [], $table];
        }

        $char = '`';
        if (isset($this->db->escapeChar) && is_string($this->db->escapeChar) && $this->db->escapeChar !== '') {
            $char = $this->db->escapeChar;
        }
        $quote = preg_quote($char, '/');

        $arr = explode(PHP_EOL, $create);
        $sql = [];
        foreach ($arr as $t) {
            if (preg_match('/'.$quote.'(.+)'.$quote.'/U', $t, $mt)
                && strpos($t, ' KEY ') === false
                && strpos($t, $char.$this->dbprefix()) === false
            ) {
                $sql[$mt[1]] = trim($t, ',');
            }
        }

        return [$create, $sql, $table];
    }

    /**
     * 驱动未实现 createTableSql：先试 SHOW CREATE TABLE，再按字段元数据拼装
     *
     * @param string $table
     * @return string
     */
    protected function _create_table_sql_compat($table) {

        $table = $this->unquote_id((string) $table);
        if ($table === '') {
            return '';
        }

        try {
            $query = $this->db->query('SHOW CREATE TABLE '.$this->_mysql_qi($table));
            $row = $query ? $query->getRowArray() : null;
            if ($row) {
                foreach ($row as $k => $v) {
                    if (stripos((string) $k, 'create') !== false && $v) {
                        return str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', (string) $v);
                    }
                }
            }
        } catch (\Throwable $e) {
            // 非 MySQL 忽略
        }

        if (!method_exists($this->db, 'getFieldData')) {
            return '';
        }

        $fds = $this->db->getFieldData($table);
        if (!$fds) {
            return '';
        }

        $lines = [];
        $pk = [];
        foreach ($fds as $f) {
            $name = isset($f->name) ? $f->name : '';
            if ($name === '') {
                continue;
            }
            $type = isset($f->type) ? $f->type : 'TEXT';
            if (!empty($f->max_length) && !preg_match('/\(/', $type)
                && !preg_match('/(TEXT|BLOB|DATE|TIME|INT|FLOAT|DOUBLE|REAL|BOOL)/i', $type)
            ) {
                $type .= '('.$f->max_length.')';
            }
            $null = (isset($f->nullable) ? $f->nullable : true) ? 'NULL' : 'NOT NULL';
            $def = '';
            if (isset($f->default) && $f->default !== null) {
                $def = " DEFAULT '".str_replace("'", "''", (string) $f->default)."'";
            }
            $extra = '';
            if (!empty($f->primary_key)) {
                $pk[] = $this->_mysql_qi($name);
            }
            if (!empty($f->auto_increment)) {
                $extra = ' AUTO_INCREMENT';
            }
            $lines[] = $this->_mysql_qi($name).' '.$type.' '.$null.$def.$extra;
        }
        if ($pk) {
            $lines[] = 'PRIMARY KEY ('.implode(',', $pk).')';
        }

        return 'CREATE TABLE IF NOT EXISTS '.$this->_mysql_qi($table).' (
'.implode(",\n", $lines).'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci';
    }

    /**
     * 从表结构导出规范化 Schema（fields / indexes / comment）
     * 供 Dever 导出 Config/Content.php、Form.php 等使用
     */
    public function create_table_schema($table) {

        list($create) = $this->create_table_sql($table);
        if (!$create) {
            return [
                'comment' => '',
                'fields' => [],
                'indexes' => [],
            ];
        }

        $comment = '';
        if (preg_match("/COMMENT='([^']*)'/", $create, $cm)) {
            $comment = $cm[1];
        } elseif (preg_match('/COMMENT="([^"]*)"/', $create, $cm)) {
            $comment = $cm[1];
        }

        $inner = $create;
        if (preg_match('/\((.*)\)\s*ENGINE/is', $create, $m)) {
            $inner = $m[1];
        }

        $fields = [];
        $indexes = [];
        $parts = preg_split("/,\s*\n/", trim($inner));
        if (dr_count($parts) < 2) {
            $parts = [];
            $buf = '';
            $depth = 0;
            $len = strlen($inner);
            for ($i = 0; $i < $len; $i++) {
                $ch = $inner[$i];
                if ($ch === '(') {
                    $depth++;
                    $buf .= $ch;
                } elseif ($ch === ')') {
                    $depth = max(0, $depth - 1);
                    $buf .= $ch;
                } elseif ($ch === ',' && $depth === 0) {
                    $parts[] = trim($buf);
                    $buf = '';
                } else {
                    $buf .= $ch;
                }
            }
            if (trim($buf) !== '') {
                $parts[] = trim($buf);
            }
        }

        foreach ($parts as $line) {
            $line = trim($line);
            $line = rtrim($line, ',');
            if ($line === '') {
                continue;
            }
            if (preg_match('/^(PRIMARY KEY|UNIQUE KEY|KEY|FULLTEXT KEY)\s/i', $line)) {
                $indexes[] = $line;
                continue;
            }
            if (preg_match('/^`([^`]+)`\s+(.+)$/s', $line, $fm)) {
                $fields[$fm[1]] = trim($fm[2]);
            }
        }

        return [
            'comment' => $comment,
            'fields' => $fields,
            'indexes' => $indexes,
        ];
    }

    /**
     * 表完整字段信息（优先驱动 showFullColunms）
     *
     * @param string $table
     * @return array
     */
    public function show_full_colunms($table) {

        if (method_exists($this->db, 'showFullColunms')) {
            return $this->db->showFullColunms($table);
        }

        return $this->_show_full_colunms_compat($table);
    }

    /**
     * @param string $table
     * @return array
     */
    protected function _show_full_colunms_compat($table) {

        $table = $this->unquote_id((string) $table);
        if ($table === '') {
            return [];
        }

        try {
            $query = $this->db->query('SHOW FULL COLUMNS FROM '.$this->_mysql_qi($table));
            if ($query) {
                $rows = $query->getResultArray();
                if ($rows) {
                    return $rows;
                }
            }
        } catch (\Throwable $e) {
            // 非 MySQL
        }

        if (!method_exists($this->db, 'getFieldData')) {
            return [];
        }

        $out = [];
        foreach ($this->db->getFieldData($table) as $f) {
            $out[] = [
                'Field' => isset($f->name) ? $f->name : '',
                'Type' => isset($f->type) ? $f->type : '',
                'Collation' => null,
                'Null' => (isset($f->nullable) && !$f->nullable) ? 'NO' : 'YES',
                'Key' => !empty($f->primary_key) ? 'PRI' : '',
                'Default' => isset($f->default) ? $f->default : null,
                'Extra' => !empty($f->auto_increment) ? 'auto_increment' : '',
                'Privileges' => '',
                'Comment' => '',
            ];
        }

        return $out;
    }

    /**
     * 全部表状态（优先驱动 showTableStatus）
     *
     * @return array
     */
    public function show_table_status() {

        if (method_exists($this->db, 'showTableStatus')) {
            return $this->db->showTableStatus();
        }

        return $this->_show_table_status_compat();
    }

    /**
     * @return array
     */
    protected function _show_table_status_compat() {

        try {
            $query = $this->db->query('SHOW TABLE STATUS');
            if ($query) {
                $rows = $query->getResultArray();
                if ($rows) {
                    return $rows;
                }
            }
        } catch (\Throwable $e) {
            // 非 MySQL
        }

        $out = [];
        if (method_exists($this->db, 'listTables')) {
            foreach ($this->db->listTables() as $name) {
                $out[] = [
                    'Name' => $name,
                    'Engine' => '',
                    'Version' => '',
                    'Row_format' => '',
                    'Rows' => 0,
                    'Avg_row_length' => 0,
                    'Data_length' => 0,
                    'Max_data_length' => 0,
                    'Index_length' => 0,
                    'Data_free' => 0,
                    'Auto_increment' => null,
                    'Create_time' => null,
                    'Update_time' => null,
                    'Check_time' => null,
                    'Collation' => '',
                    'Checksum' => null,
                    'Create_options' => '',
                    'Comment' => '',
                ];
            }
        }

        return $out;
    }

    /**
     * 修复表（优先驱动；兼容执行 MySQL REPAIR TABLE，失败则视为跳过成功）
     *
     * @param string $table
     * @return mixed
     */
    public function repair_table($table) {

        if (method_exists($this->db, 'repairTable')) {
            return $this->db->repairTable($table);
        }

        return $this->_maintenance_table_compat('REPAIR TABLE', $table);
    }

    /**
     * 优化表
     *
     * @param string $table
     * @return mixed
     */
    public function optimize_table($table) {

        if (method_exists($this->db, 'optimizeTable')) {
            return $this->db->optimizeTable($table);
        }

        return $this->_maintenance_table_compat('OPTIMIZE TABLE', $table);
    }

    /**
     * 刷新表
     *
     * @param string $table
     * @return mixed
     */
    public function flush_table($table) {

        if (method_exists($this->db, 'flushTable')) {
            return $this->db->flushTable($table);
        }

        return $this->_maintenance_table_compat('FLUSH TABLE', $table);
    }

    /**
     * 检查表
     *
     * @param string $table
     * @return array
     */
    public function check_table($table) {

        if (method_exists($this->db, 'checkTable')) {
            return $this->db->checkTable($table);
        }

        $table = $this->unquote_id((string) $table);
        if ($table === '') {
            return [];
        }

        try {
            $query = $this->db->query('CHECK TABLE '.$this->_mysql_qi($table));
            $row = $query ? $query->getRowArray() : null;
            if ($row) {
                return $row;
            }
        } catch (\Throwable $e) {
            // 非 MySQL：返回通过状态，避免后台报错
        }

        return ['Msg_text' => 'OK', 'Msg_type' => 'status'];
    }

    /**
     * MySQL 维护类语句兼容（不支持的库跳过并返回 true）
     *
     * @param string $verb REPAIR TABLE / OPTIMIZE TABLE / FLUSH TABLE
     * @param string $table
     * @return bool
     */
    protected function _maintenance_table_compat($verb, $table) {

        $table = $this->unquote_id((string) $table);
        if ($table === '') {
            return false;
        }

        try {
            $rt = $this->db->query($verb.' '.$this->_mysql_qi($table));
            if ($rt !== false) {
                return $rt;
            }
        } catch (\Throwable $e) {
            // ignore
        }

        return true;
    }

    /**
     * 修改表默认字符集（优先驱动 setTableCharset）
     *
     * @param string $table
     * @param string $charset
     * @param string $collate
     * @return mixed
     */
    public function set_table_charset($table, $charset = 'utf8mb4', $collate = 'utf8mb4_unicode_ci') {

        if (method_exists($this->db, 'setTableCharset')) {
            return $this->db->setTableCharset($table, $charset, $collate);
        }

        return $this->_set_table_charset_compat($table, $charset, $collate);
    }

    /**
     * @param string $table
     * @param string $charset
     * @param string $collate
     * @return bool
     */
    protected function _set_table_charset_compat($table, $charset = 'utf8mb4', $collate = 'utf8mb4_unicode_ci') {

        $table = $this->unquote_id((string) $table);
        if ($table === '') {
            return false;
        }

        $charset = preg_replace('/[^a-z0-9_]/i', '', (string) $charset);
        $collate = preg_replace('/[^a-z0-9_]/i', '', (string) $collate);
        $sql = 'ALTER TABLE '.$this->_mysql_qi($table).' DEFAULT CHARSET='.$charset.' COLLATE '.$collate;

        if ($this->_ddl_exec_mysql($sql)) {
            return true;
        }

        // 不支持字符集的库视为跳过
        return true;
    }

    /**
     * 创建索引（优先驱动；否则 MySQL CREATE INDEX 经 formatCreateSql）
     *
     * @param string       $table
     * @param string       $name
     * @param string|array $columns
     * @return mixed
     */
    public function add_index($table, $name, $columns) {

        $table = $this->unquote_id((string) $table);
        $name = $this->unquote_id((string) $name);
        if ($table === '' || $name === '') {
            return false;
        }

        if (is_array($columns)) {
            $cols = [];
            foreach ($columns as $c) {
                $cols[] = $this->_mysql_qi($c);
            }
            $colsql = implode(', ', $cols);
        } else {
            $colsql = (string) $columns;
            if (!$this->has_id_quotes($colsql)) {
                $parts = array_map('trim', explode(',', $colsql));
                $tmp = [];
                foreach ($parts as $p) {
                    $p !== '' && $tmp[] = $this->_mysql_qi($p);
                }
                $colsql = implode(', ', $tmp);
            }
        }

        if (method_exists($this->db, 'addIndex')) {
            return $this->db->addIndex($table, $name, $columns);
        }

        return $this->_ddl_exec_mysql(
            'CREATE INDEX '.$this->_mysql_qi($name).' ON '.$this->_mysql_qi($table).'('.$colsql.')'
        );
    }

    // 表结构缓存
    public function cache($siteid = SITE_ID, $module = null) {

        $cache = [];
        $paytable = []; // 付款表名 支持模块和表单 后期淘汰
        // 生成模块表结构
        if (dr_is_use_module()) {
            $obj = \Phpcmf\Service::M('module', 'cms');
            if (method_exists($obj, 'paytable')) {
                list($cache, $paytable) = $obj->paytable($cache, $paytable, $module, $siteid);
            }
        }

        // 网站表单
        if (dr_is_app('form') && $this->is_table_exists($siteid.'_form')) {
            $obj = \Phpcmf\Service::M('form', 'form');
            if (method_exists($obj, 'paytable')) {
                list($cache, $paytable) = $obj->paytable($cache, $paytable, $siteid);
            }
        }

        // 会员表
        $table = $this->dbprefix('member');
        $cache[$table] = $this->db->getFieldNames($table);

        // 会员附表
        $table = $this->dbprefix('member_data');
        $cache[$table] = $this->db->getFieldNames($table);

        // 缓存表结构
        \Phpcmf\Service::L('cache')->set_file('table-'.$siteid, $cache);

        // 缓存的字段类型
        //$type = ['Select', 'Checkbox', 'Radio', 'Pay', 'Pays', 'File', 'Files', 'Image', 'Images', 'Ftable'];
        $cache = [];
        $field = $this->db->table('field')->where('disabled', 0)->orderBy('id ASC')->get()->getResultArray();
        if ($field) {
            foreach ($field as $f) {
                $f['setting'] = dr_string2array($f['setting']);
                $cache[$f['id']] = $f;
            }
        }
        \Phpcmf\Service::L('cache')->set_file('table-field', $cache);

        // 缓存付款表
        \Phpcmf\Service::L('cache')->set_file('table-pay-'.$siteid, $paytable);
        /*
         * $paytable字段主键为 自定义字段rname-rid
         * */
    }

    // 获取字段结构
    public function get_field($table) {
        return $this->db->getFieldNames($this->dbprefix($table));
    }

    // 获取缓存的字段结构
    public function get_cache_field($table) {

        $tableinfo = \Phpcmf\Service::L('cache')->get('table-'.SITE_ID);
        if (!$tableinfo) {
            // 没有表结构缓存时返回空
            return [];
        }

        return isset($tableinfo[$this->dbprefix($table)]) ? $tableinfo[$this->dbprefix($table)] : [];
    }

    // 执行批量sql
    public function _query($sql, $replace = []) {
        return $this->_query_batch($sql, $replace);
    }

    // 网站表单--------------------------------------------------------------------

    // 创建
    public function create_form($data) {
        if (dr_is_app('form')) {
            \Phpcmf\Service::M('form', 'form')->create_form($data);
        }
    }

    // 删除表单
    public function delete_form($data) {
        if (dr_is_app('form')) {
            \Phpcmf\Service::M('form', 'form')->delete_form_table($data);
        }
    }

    // 模块表单--------------------------------------------------------------------

    // 创建
    public function create_module_form($data) {
        if (dr_is_app('mform')) {
            \Phpcmf\Service::M('mform', 'mform')->create_module_form($data);
        }
    }

    // 删除模块表单
    public function delete_module_form($data) {
        if (dr_is_app('mform')) {
            \Phpcmf\Service::M('mform', 'mform')->delete_module_form($data);
        }
    }

    // 项目--------------------------------------------------------------------

    // 创建项目
    public function create_site($siteid) {



    }

}
