Initial commit

This commit is contained in:
易焱
2021-04-18 18:51:51 +08:00
commit ec705f2fa8
3240 changed files with 623103 additions and 0 deletions
@@ -0,0 +1,525 @@
<?php
namespace Admin\Model;
use Think\Model;
class TableFieldModel extends Model{
//自动验证
//array(验证字段,验证规则,错误提示,[验证条件,附加规则,验证时间])
protected $_validate = array(
array('table_id', 'require', '请选择数据表!'),
array('formtype', 'require', '字段类型不能为空!'),
array('field', 'require', '字段名称必须填写!'),
array('field', 'isFieldUnique', '该字段名称已经存在!', 0, 'callback', 1),
array('name', 'require', '字段别名必须填写!'),
array('field', '/^[a-z_0-9]+$/i', '字段名只支持英文或数字!', 0, 'regex', 3),
);
/**
* 验证字段名是否已经存在
* @param type $fieldName
* @return boolean false已经存在,true不存在
*/
public function isFieldUnique($fieldName) {
if (empty($fieldName)) {
return true;
}
if ($this->where(array('table_id' =>I("table_id"), 'field' => $fieldName))->count()){
return false;
}
return true;
}
/**
* 根据模型ID,返回表名
* @param type $table_id
* @param type $table_id
* @return string
*/
protected function getTbName($table_id, $issystem = 1) {
//表名获取
$table_name = M("table")->where(array("table_id"=>$table_id))->getField("table_name");
$table_name="cms_".$table_name;
//完整表名获取 判断主表 还是副表
$table_name = $issystem ? $table_name : $table_name . "_data";
return $table_name;
}
//增加
public function data_add(){
$data=$this->create();
//数据表id
$table_id = $data['table_id'];
$fieldtype = $data['fieldtype'];
//完整表名获取 判断主表 还是副表
$table_name = $this->getTbName($table_id, $data['issystem']);
if (!$this->table_exists($table_name)) {
$this->error = '数据表不存在!';
return false;
}
//检查字段是否存在
if ($this->field_exists($table_name, $data['field'])) {
$this->error = '该字段已经存在!';
return false;
}
//增加字段
$field = array(
'tablename' => C("DB_PREFIX") . $table_name,
'fieldname' => $data['field'],
'fieldlen' => $data['fieldlen'],
'defaultvalue' => $data['defaultvalue'],
);
if ($this->addFieldSql($fieldtype, $field)) {
//更新htmlcode
$TableModel=new \Admin\Model\TableModel();
$data['htmlcode']=$TableModel->createFieldHtmlCode($data);
$data['memberhtmlcode']=$TableModel->createMemberFieldHtmlCode($data);
//
$fieldid = $this->add($data);
if ($fieldid) {
return $fieldid;
} else {
$this->error = '字段信息入库失败!';
//回滚
$this->execute("ALTER TABLE `{$field['tablename']}` DROP `{$field['fieldname']}`");
return false;
}
} else {
$this->error = '数据库字段添加失败!';
return false;
}
}
//修改
public function data_editor(){
$data=$this->create();
if (!$data['field_id']) {
$this->error = '缺少字段id';
return false;
} else {
$field_id = $field_id ? $field_id : (int) $data['field_id'];
}
//重置htmlcode
$TableModel=new \Admin\Model\TableModel();
$data['htmlcode']=htmlspecialchars_decode($data['htmlcode']);
$data['htmlcode']=$TableModel->createFieldHtmlCode($data);
//投稿的
$data['memberhtmlcode']=htmlspecialchars_decode($data['memberhtmlcode']);
$data['memberhtmlcode']=$TableModel->createMemberFieldHtmlCode($data);
//原字段信息
$info = $this->where(array("field_id" => $field_id))->find();
if (empty($info)){
$this->error = '该字段不存在!';
return false;
}
//字段主表副表不能修改
unset($data['issystem']);
//字段类型
if (empty($data['formtype'])) {
$data['formtype'] = $info['formtype'];
}
//模型id
$table_id = $info['table_id'];
$field_type = $data['fieldtype'];
//完整表名获取 判断主表 还是副表
$tablename = $this->getTbName($table_id, $info['issystem']);
if (!$this->table_exists($tablename)) {
$this->error = '数据表不存在!';
return false;
}
if (false !== $this->save($data)) {
//如果字段名变更
if ($data['field'] && $info['field']) {
//检查字段是否存在,只有当字段名改变才检测
if ($data['field'] != $info['field'] && $this->field_exists($tablename, $data['field'])) {
$this->error = '该字段已经存在!';
//回滚
$this->where(array("field_id" => $field_id))->save($info);
return false;
}
$field = array(
'tablename' => C("DB_PREFIX") . $tablename,
'newfilename' => $data['field'],
'oldfilename' => $info['field'],
'fieldlen' => $data['fieldlen'],
'defaultvalue' => $data['defaultvalue'],
);
if (false === $this->editFieldSql($field_type, $field)) {
$this->error = '数据库字段结构更改失败!';
//回滚
$this->where(array("field_id" => $field_id))->save($info);
return false;
}
//根据table_id查询model表,并更新modeltemp
$model=M("model")->where(array("table_id"=>$table_id))->select();
$ModelModel=new \Admin\Model\ModelModel();
foreach($model as $v){
$ModelModel->updateModelTemp($v["modelid"]);
}
}
} else {
$this->error = '数据库更新失败!';
return false;
}
//
//
return $data;
}
//删除字段
public function data_delete($field_id,$systemfield) {
//原字段信息
$info = $this->where(array("field_id" => $field_id))->find();
if (empty($info)) {
$this->error = '该字段不存在!';
return false;
}
//模型id
$table_id = $info['table_id'];
//完整表名获取 判断主表 还是副表
$tablename = $this->getTbName($table_id, $info['issystem']);
if (!$this->table_exists($tablename)) {
$this->error = '数据表不存在!';
return false;
}
//判断是否允许删除
if (in_array($info['field'],$systemfield)){
$this->error = '系统字段不允许被删除!';
return false;
}
if ($this->deleteFieldSql($info['field'], C("DB_PREFIX") . $tablename)) {
$this->where(array("field_id" => $field_id, "table_id" => $table_id))->delete();
//根据table_id查询model表,并更新modeltemp
$model=M("model")->where(array("table_id"=>$table_id))->select();
$ModelModel=new \Admin\Model\ModelModel();
foreach($model as $v){
$ModelModel->updateModelTemp($v["modelid"]);
}
} else {
$this->error = '数据库表字段删除失败!';
return false;
}
return true;
}
/**
* 根据字段类型,删除对应的字段到相应表里面
* @param type $filename 字段名称
* @param type $tablename 完整表名
*/
protected function deleteFieldSql($filename, $tablename) {
//不带表前缀的表名
$noprefixTablename = str_replace(C("DB_PREFIX"), '', $tablename);
if (empty($tablename) || empty($filename)) {
$this->error = '表名或者字段名不能为空!';
return false;
}
if (false === $this->table_exists($noprefixTablename)) {
$this->error = '该表不存在!';
return false;
}
$sql = "ALTER TABLE `{$tablename}` DROP `{$filename}`;";
if (false === $this->execute($sql)) {
$this->error = '字段删除失败!';
return false;
}
return true;
}
/**
* 根据字段类型,增加对应的字段到相应表里面
* @param type $field_type 字段类型
* @param type $field 相关配置
* $field = array(
* 'tablename' 表名(完整表名)
* 'fieldname' 字段名
* 'maxlength' 最大长度
* 'minlength' 最小值
* 'defaultvalue' 默认值
* 'minnumber' 是否正整数 和整数 1为正整数,-1是为整数
* 'decimaldigits' 小数位数
* )
*/
protected function addFieldSql($field_type, $field) {
//表名
$tablename = $field['tablename'];
//字段名
$fieldname = $field['fieldname'];
//长度
$fieldlen = $field['fieldlen'];
switch ($field_type) {
case "varchar":
if (!$fieldlen) {
$fieldlen = 255;
}
$fieldlen = min($fieldlen, 255);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` VARCHAR( {$fieldlen} ) DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "tinyint":
if (!$fieldlen) {
$fieldlen = 3;
}
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TINYINT( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "smallint":
$minnumber = intval($minnumber);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` SMALLINT( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "mediumint":
$minnumber = intval($minnumber);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` INT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "int":
$minnumber = intval($minnumber);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` INT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "mediumtext":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` MEDIUMTEXT";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "text":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TEXT";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "date":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DATE DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "datetime":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "timestamp":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "double":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DOUBLE NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "float":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` FLOAT( {$fieldlen} ) NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "bigint":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` BIGINT( {$fieldlen} ) NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "longtext":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` LONGTEXT";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "char":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` CHAR( {$fieldlen} ) DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
default:
return false;
break;
}
return true;
}
/**
* 执行数据库表结构更改
* @param type $field_type 字段类型
* @param type $field 相关配置
* $field = array(
* 'tablename' 表名(完整表名)
* 'newfilename' 新字段名
* 'oldfilename' 原字段名
* 'maxlength' 最大长度
* 'minlength' 最小值
* 'defaultvalue' 默认值
* 'minnumber' 是否正整数 和整数 1为正整数,-1是为整数
* 'decimaldigits' 小数位数
* )
*/
protected function editFieldSql($field_type, $field) {
//表名
$tablename = $field['tablename'];
//原字段名
$oldfilename = $field['oldfilename'];
//新字段名
$newfilename = $field['newfilename'] ? $field['newfilename'] : $oldfilename;
//长度
$fieldlen = $field['fieldlen'];
if (empty($tablename) || empty($newfilename)) {
$this->error = '表名或者字段名不能为空!';
return false;
}
switch ($field_type) {
case 'varchar':
//最大值
if (!$fieldlen) {
$fieldlen = 255;
}
$fieldlen = min($fieldlen, 255);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` VARCHAR( {$fieldlen} ) DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'tinyint':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` TINYINT( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'smallint':
$minnumber = intval($minnumber);
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` SMALLINT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT '{$defaultvalue}' DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'mediumint':
$minnumber = intval($minnumber);
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` MEDIUMINT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT '{$defaultvalue}' DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'int':
$minnumber = intval($minnumber);
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` INT ( {$fieldlen} ) NOT NULL DEFAULT '{$defaultvalue}' DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'mediumtext':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` MEDIUMTEXT";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'text':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` TEXT";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'date':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` DATE DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'datetime':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'timestamp':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "double":
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` DOUBLE NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "float":
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` FLOAT(" . $minnumber . ") NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "bigint":
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` BIGINT NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "longtext":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` LONGTEXT";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "char":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` CHAR(" . $fieldlen . ") DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
default:
$this->error = "字段类型" . $field_type . "不存在相应信息!";
return false;
break;
}
return true;
}
}