dzadsod/src/update/update.class.php

637 lines
28 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
defined('IN_MET') or exit('No permission');
//更新文件的模板
load::sys_class('admin');
load::sys_func('file');
//不继承APP
class update extends admin{
//应用信息
private $app;
//应用NO
private $appno;
//应用文件名
private $m_name;
//应用新版本号
private $newver;
//当前版本号
private $oldver;
//安装锁信息,应用入口信息
private $appinfo = [];
//应用数据库
private $sqlk;
private $fixed_name;
# 初始化
public function __construct() {
global $_M;
parent::__construct();
//安装锁信息,应用入口信息
$this->appinfo = [
'url' => '',
'c' => 'dzadsod',
'a' => 'dodzadsod',
'lang' => $_M['lang'],
'time' => date('Y-m-d H:i:s',time())
];
$this->sqlk = $_M['table']['cloud_config'];
}
//需要传递值
public function set($app) {
global $_M;
$this->app = $app;
$this->appno = $app['no'];
$this->m_name = $app['m_name'];
$this->newver = $app['ver'];
$this->oldver = $app['oldver'];
return $this;
}
//修改数据库版本
public function start() {
global $_M;
if(file_exists(INS_LOCK_FILE)){
switch ($this->newver) {
case 1.1:
//更新数据库
self::inssql();
//更新版本内容
self::update_1_1();
break;
case 1.2:
//更新版本内容
self::update_1_2();
break;
case 1.3:
//更新版本内容
self::update_1_3();
break;
default:
break;
}
//更新版本号
self::upver();
}else{
//创建数据表
self::inssql();
//默认系统表处理
self::systable();
//默认数据
self::default_config();
//创建栏目 [前端页面时才需要API也不需要]
// self::column();
//安装锁
self::install_lock();
}
}
/*
+ 应用新安装操作
+-------------------------------------------------------------------------------------------
+ up1.1 : 更新版本
+-------------------------------------------------------------------------------------------
+ default_config : 默认的应用配置信息方法
+-------------------------------------------------------------------------------------------
+ systable : 当前应用版本针对数据库表的信息
+-------------------------------------------------------------------------------------------
*/
// 1.1 版本
public function update_1_1() {
global $_M;
//执行SQL其他操作
$tview = self::tview();
foreach ($tview as $key => $val){
$tname[] = $key;
$table_name = self::split_table_name($key);
$table[] = $table_name;
DB::query($val);
}
//记录表名
add_table(arrayto_string($table,'|'));
$filetable = PATH_ALL_APP.$this->m_name.'/config/table';
//先获取之前已经存在的简短表名
if(file_exists($filetable)) {
$tnamestr = file_get_contents($filetable);
$tname = array_merge($tname,stringto_array($tnamestr,','));
}else{
//创建
makefile($filetable);
}
//写入
file_put_contents($filetable,arrayto_string($tname,','));
}
// 1.2 版本
public function update_1_2() {
global $_M;
//执行SQL其他操作
$tables = self::table_field();
$table = $tname = [];
foreach ($tables as $key => $val) {
$tname[] = $key;
$table_name = self::split_table_name($key);
$table[] = $table_name;
if($val) DB::query("CREATE TABLE `{$_M['config']['tablepre']}{$table_name}` ( {$val} ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8");
}
//记录表名
add_table(arrayto_string($table,'|'));
$filetable = PATH_ALL_APP.$this->m_name.'/config/table';
//先获取之前已经存在的简短表名
if(file_exists($filetable)) {
$tnamestr = file_get_contents($filetable);
$tname = array_merge($tname,stringto_array($tnamestr,','));
}else{
//创建
makefile($filetable);
}
//写入
file_put_contents($filetable,arrayto_string($tname,','));
}
// 1.3 版本
public function update_1_3() {
global $_M;
//执行SQL其他操作
$tview = self::tview();
foreach ($tview as $key => $val){
$tname[] = $key;
$table_name = self::split_table_name($key);
$table[] = $table_name;
DB::query($val);
}
//记录表名
add_table(arrayto_string($table,'|'));
$filetable = PATH_ALL_APP.$this->m_name.'/config/table';
//先获取之前已经存在的简短表名
if(file_exists($filetable)) {
$tnamestr = file_get_contents($filetable);
$tname = array_merge($tname,stringto_array($tnamestr,','));
}else{
//创建
makefile($filetable);
}
//写入
file_put_contents($filetable,arrayto_string($tname,','));
}
/*
+ 应用新安装操作
+-------------------------------------------------------------------------------------------
+ table_field : 当前应用数据创建依据
+-------------------------------------------------------------------------------------------
+ default_config : 默认的应用配置信息方法
+-------------------------------------------------------------------------------------------
+ systable : 当前应用版本针对数据库表的信息
+-------------------------------------------------------------------------------------------
*/
//数据库创建
protected function table_field() {
global $_M;
// 场所资料库
$zdytable['village'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`v_name` varchar(255) NOT NULL COMMENT '场所名称',
`v_type` varchar(255) NOT NULL COMMENT '分类',
`v_province` varchar(255) NOT NULL COMMENT '省',
`v_city` varchar(255) NOT NULL COMMENT '市',
`v_district` varchar(255) NOT NULL COMMENT '区',
`v_address` varchar(255) NOT NULL COMMENT '详细地址',
`v_lxname` varchar(150) NOT NULL COMMENT '相关联系人',
`v_tel` text COMMENT '联系电话',
`v_price` decimal(10,2) DEFAULT NULL COMMENT '场所均价',
`v_psize` int(11) COMMENT '居住人口规模',
`v_text` text COMMENT '备注',
`v_updatetime` datetime DEFAULT NULL,
`v_addtime` datetime DEFAULT NULL,
UNIQUE KEY `vname` (`v_name`),
PRIMARY KEY (`id`)";
// 公司资料库
// 公司地址填写采用选择城市联动的方式填写,方便后期数据查询处理筛选
$zdytable['customer'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`c_allname` varchar(255) NOT NULL COMMENT '公司全称名称',
`c_name` varchar(255) NOT NULL COMMENT '公司简称名称',
`c_province` varchar(255) NOT NULL COMMENT '省',
`c_city` varchar(255) NOT NULL COMMENT '市',
`c_district` varchar(255) NOT NULL COMMENT '区',
`c_address` varchar(255) NOT NULL COMMENT '详细地址',
`c_lxname` varchar(150) NOT NULL COMMENT '相关联系人',
`c_tel` text COMMENT '联系电话',
`c_text` text COMMENT '备注',
`c_updatetime` datetime DEFAULT NULL,
`c_addtime` datetime DEFAULT NULL,
UNIQUE KEY `cname` (`c_name`),
PRIMARY KEY (`id`)";
//公司负责人联系方式
//负责人姓名,电话,职位分类,备注
// w_tel 可做成标签,总之要满足多个录入的要求
$zdytable['workers'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`w_jid` int(11) NOT NULL COMMENT '职务id',
`w_name` varchar(150) NOT NULL COMMENT '姓名',
`w_tel` text COMMENT '联系电话',
`w_text` text COMMENT '备注',
`w_updatetime` datetime DEFAULT NULL,
`w_addtime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)";
// 同一个广告位置 不可重复
$zdytable['elevator'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`e_vid` int(11) COMMENT '场所ID',
`e_number` varchar(100) NOT NULL COMMENT '广告位编号,用于后期各表操作',
`e_bno` int(11) NOT NULL COMMENT '道闸方位',
`e_aps` int(11) NOT NULL COMMENT '广告位置',
`e_size` varchar(255) NOT NULL COMMENT '广告位尺寸大小',
`e_enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用 0 不启用1 为启用',
`e_label` text COMMENT '自主标签',
`e_text` text COMMENT '备注',
UNIQUE KEY `elidno` (`e_vid`,`e_bno`,`e_aps`),
UNIQUE KEY `enumber` (`e_number`),
PRIMARY KEY (`id`)";
// 合同资料库
// h_cid h_wid 采用联动菜单方式
// h_noticeday 可做成tab 标签形式满足多个通知天数
$zdytable['contract'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`h_number` varchar(100) NOT NULL COMMENT '合同编号,用于后期各表操作',
`h_signtime` varchar(255) COMMENT '签订日期',
`h_cid` int(11) COMMENT '签定公司',
`h_wid` varchar(255) COMMENT '签定相关公司人员',
`h_tprice` decimal(10,2) DEFAULT NULL COMMENT '总价格',
`h_starttime` varchar(255) COMMENT '广告开始时间',
`h_endtime` varchar(255) COMMENT '广告结束时间',
`h_noticeday` varchar(255) COMMENT '提前通知天数',
`h_text` text COMMENT '备注',
`h_updatetime` datetime DEFAULT NULL COMMENT '修改时间',
`h_addtime` datetime DEFAULT NULL COMMENT '录入时间',
UNIQUE KEY `elidno` (`h_number`),
PRIMARY KEY (`id`)";
// 广告投放计划单 //将合同的进度状态调整到投放计划内
$zdytable['launch'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`l_title` varchar(255) COMMENT '投放计划标题',
`l_hnumber` varchar(100) NOT NULL COMMENT '合同编号',
`l_enumber` text COMMENT '排期成功的广告位编号',
`l_selectenum` text COMMENT '选择的广告位编号',
`l_schedule` int(11) COMMENT '投放进度',
`l_starttime` varchar(255) COMMENT '广告开始时间',
`l_endtime` varchar(255) COMMENT '广告结束时间',
`l_enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '广告排期状态 0预选1正常 2预排',
`l_type` varchar(255) NOT NULL COMMENT '分类',
`l_text` text COMMENT '备注',
`l_updatetime` datetime DEFAULT NULL COMMENT '修改时间',
`l_addtime` datetime DEFAULT NULL COMMENT '录入时间',
PRIMARY KEY (`id`)";
// 广告时间段排期表,广告位编号,合同编号,开始时间,结束时间,状态
// 排期的缓存表
$zdytable['schedule'] = "
`id` char(36) NOT NULL COMMENT 'uuid',
`s_lid` int(11) COMMENT '广告投放ID',
`s_enumber` varchar(100) NOT NULL COMMENT '广告位编号',
`s_hnumber` varchar(100) NOT NULL COMMENT '合同编号',
`s_starttime` varchar(255) COMMENT '广告开始时间',
`s_endtime` varchar(255) COMMENT '广告结束时间',
UNIQUE KEY `slidse` (`s_lid`,`s_enumber`),
PRIMARY KEY (`id`)
";
// 参数配置
$zdytable['para'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`p_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '参数分类 0广告位置,1职位,2合同状态,3道闸方位',
`p_order` int(11) DEFAULT '0' COMMENT '排序',
`p_name` varchar(255) COMMENT '名称',
`p_value` int(11) COMMENT '参数值,必须为数字',
`p_text` varchar(255) COMMENT '备注',
UNIQUE KEY `ptypevalue` (`p_type`,`p_value`),
PRIMARY KEY (`id`)";
// 有序表,处理分割字段
$zdytable['sequence'] = " `seq` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`seq`)";
// 公司资料库
// 公司地址填写采用选择城市联动的方式填写,方便后期数据查询处理筛选
$zdytable['welog'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`openid` varchar(45) NOT NULL COMMENT '微信用户ID',
`text` text COMMENT '核心内容',
`content` text COMMENT '微信模板信息',
`returntext` text COMMENT '返回信息',
`state` tinyint(1) COMMENT '记录状态',
`exetime` varchar(255) COMMENT '处理时间',
`addtime` varchar(255) COMMENT '录入时间',
PRIMARY KEY (`id`)";
//前台巡查人员的验证密钥密码
$zdytable['keylist'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`k_passkey` varchar(45) NOT NULL COMMENT '密钥密码',
`k_basekey` text COMMENT '明密',
`k_wid` varchar(255) COMMENT '相关联系人',
`k_state` tinyint(1) COMMENT '密钥状态',
`k_text` text COMMENT '备注',
`k_addtime` varchar(255) COMMENT '新增时间',
`k_updatetime` varchar(255) COMMENT '修改时间',
PRIMARY KEY (`id`)";
/**
* 1、增加新表
* name 配置名称
* id 添加信息自动增加,
* value 配置名称值
* lang 语言[后台]
**/
$zdytable['cloud_config'] = " `id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`m_name` varchar(50) NOT NULL,
`value` text,
`lang` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_lang` (`name`,`m_name`,`lang`)";
//执行
return $zdytable;
}
//mysql 触发器
protected function trigger() {
global $_M;
//新增schedule 表的更新触发器
$table_name = self::split_table_name('schedule',true);
$launch_name = self::split_table_name('launch',true);
//更新触发器并没有排除两个时间字段为空的排查
$array[] = " CREATE TRIGGER `add` BEFORE INSERT ON `{$table_name}` FOR EACH ROW
BEGIN
IF
EXISTS (
SELECT
`id`
FROM
`{$table_name}`
WHERE
NOT ( s_endtime < new.s_starttime OR s_starttime > new.s_endtime ) AND s_enumber = new.s_enumber)
OR
EXISTS (
SELECT
`id`
FROM
`{$launch_name}`
WHERE
NOT ( l_endtime < new.s_starttime OR l_starttime > new.s_endtime ) AND find_in_set( new.s_enumber, l_enumber ) AND id != new.s_lid )
THEN
SIGNAL SQLSTATE 'SC001' SET MESSAGE_TEXT = '排期时间区间重复';
END IF;
END; ";
// 加入为空排查其他字段就无法实现更新
$array[] = " CREATE TRIGGER `up` BEFORE UPDATE ON `{$table_name}` FOR EACH ROW
BEGIN
IF
EXISTS (
SELECT
`id`
FROM
`{$table_name}`
WHERE
NOT ( s_endtime < new.s_starttime OR s_starttime > new.s_endtime ) AND s_enumber = new.s_enumber AND id != new.id )
OR
EXISTS (
SELECT
`id`
FROM
`{$launch_name}`
WHERE
NOT ( l_endtime < new.s_starttime OR l_starttime > new.s_endtime ) AND find_in_set( new.s_enumber, l_enumber ) AND id != new.s_lid )
THEN
SIGNAL SQLSTATE 'SC002' SET MESSAGE_TEXT = '排期时间区间重复';
END IF;
END; ";
return $array;
}
//mysql 视图
protected function tview() {
global $_M;
//查询到期合同以及根据设置的到期天数提醒
$sequence = self::split_table_name('sequence',true);
$contract = self::split_table_name('contract',true);
$noticeday = self::split_table_name('noticeday',true);
$array['noticeday'] = " CREATE VIEW {$noticeday} AS
SELECT
ct.*,
substring_index( substring_index( ct.h_noticeday, ',', sq.seq ), ',',- ( 1 ) ) AS noticeday,
DATE_SUB(ct.h_endtime,INTERVAL substring_index( substring_index( ct.h_noticeday, ',', sq.seq ), ',',- ( 1 ) ) DAY) AS endtime,
sq.seq
FROM
{$sequence} AS sq INNER JOIN {$contract} AS ct
ON sq.seq <= ( ( 1 + length( ct.h_noticeday ) ) - length( REPLACE ( ct.h_noticeday, ',', '' ) ) ) ";
//查询微信关注用户,排除非关注的用户
$weuser = self::split_table_name('weuser',true);
$nwechat_user = self::split_table_name('nwechat_user',true);
$array['weuser'] = " CREATE VIEW {$weuser} AS
SELECT * FROM {$nwechat_user} WHERE subscribe = 1 ";
// 广告位排期统计,计算广告位的空闲,到期,投放中
$elevator = self::split_table_name('elevator',true);
$launch = self::split_table_name('launch',true);
$countela = self::split_table_name('countela',true);
$array['countela'] = " CREATE VIEW {$countela} AS
SELECT
e.id,
e.e_vid,
e.e_number,
e.e_bno,
e.e_aps,
e.e_enable,
l.id AS l_id,
l.l_title,
l.l_hnumber,
l.l_schedule,
l.l_starttime,
l.l_endtime,
l.l_enable,
l.l_type
FROM
{$elevator} AS e
LEFT JOIN {$launch} AS l ON find_in_set( e.e_number, l.l_enumber ) ";
return $array;
}
//默认配置
protected function default_config() {
global $_M;
//正常升级
$config = [
'tem_ida','tem_idb','tem_idc','openid'
];
$lang = $_M['lang'];
foreach ($config as $key => $val){
DB::query("INSERT INTO {$this->sqlk} (name,lang,m_name,value) VALUES ('{$key}','{$lang}','{$this->m_name}','{$val}') ON DUPLICATE KEY UPDATE value='{$val}' ");
}
}
//系统表
protected function systable() {
global $_M;
//访问入口固定为app/index.php?n=XXX&c=XXX&a=XXX
//定时处理入口
// $field = "no='{$this->appno}',m_name='{$this->m_name}',filename='timing.php',m_module='web',m_class='timing',m_action='@\$_GET[a]'";
// self::addsql('ifcolumn_addfile',$field);
}
/*
+ 公用安装升级方法
+-------------------------------------------------------------------------------------------
+ inssql : 应用数据表创建
+-------------------------------------------------------------------------------------------
+ upver : 修改应用版本号
+-------------------------------------------------------------------------------------------
+ install_lock : 创建安装锁
+-------------------------------------------------------------------------------------------
*/
//应用数据表创建
protected function inssql() {
global $_M;
$tables = self::table_field();
$table = $tname = [];
foreach ($tables as $key => $val) {
$tname[] = $key;
$table_name = self::split_table_name($key);
$table[] = $table_name;
if($val) DB::query("CREATE TABLE `{$_M['config']['tablepre']}{$table_name}` ( {$val} ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8");
}
//建立触发器
$trigger = self::trigger();
foreach ($trigger as $val){
DB::query($val);
}
//执行SQL其他操作
$tview = self::tview();
foreach ($tview as $key => $val){
$tname[] = $key;
$table_name = self::split_table_name($key);
$table[] = $table_name;
DB::query($val);
}
//记录表名
add_table(arrayto_string($table,'|'));
$filetable = PATH_ALL_APP.$this->m_name.'/config/table';
//先获取之前已经存在的简短表名
if(file_exists($filetable)) {
$tnamestr = file_get_contents($filetable);
$tname = array_merge($tname,stringto_array($tnamestr,','));
}else{
//创建
makefile($filetable);
}
//写入
file_put_contents($filetable,arrayto_string(array_unique($tname),','));
}
//修改版本号
protected function upver() {
global $_M;
DB::query("UPDATE {$_M['table']['applist']} SET ver='{$this->newver}' WHERE no='{$this->appno}' AND m_name='{$this->m_name}' ");
}
//创建安装锁
protected function install_lock() {
global $_M;
if(!file_exists(INS_LOCK_FILE)) makefile(INS_LOCK_FILE);
file_put_contents(INS_LOCK_FILE, json_encode($this->appinfo,JSON_UNESCAPED_UNICODE) );
}
/*
+ 公用SQL方法
+-------------------------------------------------------------------------------------------
+ sqlone : 单条查询方法
+-------------------------------------------------------------------------------------------
+ sqlall : 批量查询方法
+-------------------------------------------------------------------------------------------
+ addsql : 入库方法
+-------------------------------------------------------------------------------------------
+ split_table_name : 拼接完整数据库名
+-------------------------------------------------------------------------------------------
*/
//公共查询方法
private function sqlone($tname,$where = '') {
global $_M;
$table = $_M['table'][$tname];
if(!$where) $where = "no='{$this->appno}'";
return DB::get_one("select * from {$table} where {$where}");
}
//公共查询方法
private function sqlall($tname,$where = '') {
global $_M;
$table = $_M['table'][$tname];
if(!$where) $where = "no='{$this->appno}'";
return DB::get_all("select * from {$table} where {$where}");
}
//公共写入方法
private function addsql($tname,$field = '') {
global $_M;
$table = $_M['table'][$tname];
DB::query("INSERT INTO {$table} SET {$field}");
}
//拼接完整数据库名
private function split_table_name($name,$all = false) {
global $_M;
//公用表
$global_table = ['cloud_config','nwechat_user'];
$tablename = in_array($name, $global_table)?$name:$this->m_name.'_'.$name;
return $all?$_M['config']['tablepre'].$tablename:$tablename;
}
/*
+ 前端入口的创建。
+-------------------------------------------------------------------------------------------
+ column : 创建栏目信息 //目前的方法不适合最新版本 后期等待更正
+-------------------------------------------------------------------------------------------
*/
//创建前台入口API形式
protected function column_api() {
global $_M;
$file = self::sqlall('ifcolumn_addfile');
$dir = PATH_WEB.$this->fixed_name;
if(makedir($dir)){
if(getdirpower($dir) == false) modifydirpower($dir,0777);
}
foreach ($file as $val) {
$dirfile = $dir.'/'.$val['filename'];
$action = strstr($val['m_action'],'@$_')?$val['m_action']:"'{$val['m_action']}'";
$phpstr = "<?php".PHP_EOL
. "define('M_NAME', '{$val['m_name']}');".PHP_EOL
. "define('M_MODULE', '{$val['m_module']}');".PHP_EOL
. "define('M_CLASS', '{$val['m_class']}');".PHP_EOL
. "define('M_ACTION', {$action});".PHP_EOL
. "require_once '../app/app/entrance.php';".PHP_EOL
. "?>";
file_put_contents($dirfile, $phpstr);
}
}
//创建栏目信息
protected function column() {
global $_M;
$name = array('cn'=>'加盟店','en'=>'Join store query','tc'=>'加盟店');
foreach (array('cn','en','tc') as $k => $v) {
DB::query("INSERT INTO {$_M['table']['column']} SET name='{$name[$v]}',foldername='{$this->fixed_name}',module='{$this->appno}',no_order='100',if_in='1',classtype='1',out_url='{$_M['url']['site']}{$this->fixed_name}',isshow='1',lang='{$v}',nav='1'");
}
}
}