<?php
/**
 * ===========================================================================
 * Veitool 快捷开发框架系统
 * Author: Niaho 26843818@qq.com
 * Copyright (c)2020-2024 www.veitool.com All rights reserved.
 * Licensed: 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
 * ---------------------------------------------------------------------------
 */
namespace addons\vtool\controller;

use think\facade\Db;
use think\Exception;
use app\admin\controller\AdminBase;
use addons\vtool\tool\Build;
use addons\vtool\model\BuildModule as MD;

/**
 * 插件内的主控制器
 */
class Index extends AdminBase
{
    /**
     * 构建记录
     * @param  string  $do  异步数据
     * @return mixed
     */
    public function index(string $do='')
    {
        if($do == 'json'){
            $where = [];
            $d = $this->request->get('','','strip_sql');
            $kw = $d['kw'] ?? '';
            $fds = ['title','name','controller'];
            $field = isset($d['fields']) && isset($fds[$d['fields']]) ? $d['fields'] : -1;
            $sotime = $d['sotime'] ?? '';
            $type  = $d['type'] ?? '';
            $state = $d['state'] ?? '';
            $limit = isset($d['limit']) ? intval($d['limit']) : 10;
            if($kw!=''){
                if($field>-1){
                    $where[] = $field>1 ? [$fds[$field],'LIKE', '%'.$kw.'%'] : [$fds[$field],'=',$kw];
                }else{
                    $where[] = [implode('|',$fds),'LIKE', '%'.$kw.'%'];
                }
            }
            if(strpos($sotime,' - ')!==false){
                $t = explode(' - ',$sotime);
                $where[] = ['addtime','>=',strtotime($t[0]." 00:00:00")];
                $where[] = ['addtime','<=',strtotime($t[1]." 23:59:59")];
            }
            if($type) $where[] = ['type','=',$type];
            if(is_numeric($state)) $where[] = ['state','=',$state];
            return $this->returnMsg(MD::where($where)->order(['id'=>'desc'])->field('*')->paginate($limit)); // ->withoutField('table_fields')
        }elseif($do == 'table'){
            return $this->fetch($do);
        }elseif($do == 'tableInfo'){
            $db = new \tool\MysqlBackup;
            $rs = $db->dataList();
            $data = [];
            foreach ($rs as $v){
                $data[] = ['name'=>$v['name'], 'value'=>$v['name']];
            }
            return $this->returnMsg($data);
        }elseif($do == 'tableSQL'){
            $table = $this->request->get('table');
            $rs = array_map('array_change_key_case', Db::query("SHOW CREATE TABLE `$table`"));
            return $this->returnMsg($rs[0]['create table'] ?? '');
        }
        $this->assign([
            'limit'=>10
        ]);
        return $this->fetch();
    }

    /**
     * 模块添加
     * @return json
     */
    public function add()
    {
        $d = $this->only(['@token'=>'','name/*/{2,30}/模块标识/1,2,3/','title/h/请输入模块名称','controller/*/{2,30}/请输入控制器名称/1,2/','table/?/{2,30}/数据表名/1,2/_','appdir/*/{2,30}/应用目录/1,2,3/@_','subdir/?/{2,30}/子目录/1,2,3/_','table_engine','table_charset','table_size/d','form_type/d','excelout/d','excelup/d','type/d','do_build/d','menu_pid/d','dict_load/d','open_size/*/{5,30}/弹窗尺寸/1,2/,%','table_fields']);
        //检查模块
        if($rs = MD::where("name = '$d[name]' OR `table` = '$d[table]' OR (controller = '$d[controller]' AND appdir = '$d[appdir]' AND subdir = '$d[subdir]')")->find()){
            if($rs['name'] == $d['name']) return $this->returnMsg('模块标识已经存在');
            if($rs['table'] == $d['table']) return $this->returnMsg('数据表已经存在');
            return $this->returnMsg('控制器路由已经存在');
        }
        //创建信息
        $d['note'] = '';
        $d["addtime"] = time();
        $d['add'] = $this->manUser['username'];
        if(MD::insert($d)){
            return $this->returnMsg("添加成功", 1);
        }else{
            return $this->returnMsg('添加失败');
        }
    }

    /**
     * 模块编辑
     * @param  string  $do  快编操作
     * @return json
     */
    public function edit(string $do='')
    {

        $d = $this->only($do ? ['@token'=>'','id/d/参数错误222','av','af'] : ['@token'=>'','id/d/参数错误212','name/*/{2,30}/模块标识/1,2,3/','title/h/请输入模块名称','controller/*/{2,30}/请输入控制器名称/1,2/','table/?/{2,30}/数据表名/1,2/_','appdir/*/{2,30}/应用目录/1,2,3/@_','subdir/?/{2,30}/子目录/1,2,3/_','table_engine','table_charset','table_size/d','form_type/d','excelout/d','excelup/d','type/d','do_build/d','menu_pid/d','dict_load/d','open_size/*/{5,30}/弹窗尺寸/1,2/,%','action']);
        $id = $d['id'];
        $Myobj = MD::one("id = $id");

        if(!$Myobj) return $this->returnMsg("数据不存在");
        if($do=='up'){
            $value = $d['av'];
            $field = $d['af'];
            if(!in_array($field,['table_fields','state'])) return $this->returnMsg("参数错误32132");
            return $this->returnMsg($Myobj->save(['edit'=>$this->manUser['username'], 'edittime'=>time(), $field=>$value]) ? "设置成功" : '设置失败', 1);
        }else{
            //检查模块
            if($rs = MD::where("id <> '$id' AND (name = '$d[name]' OR `table` = '$d[table]' OR (controller = '$d[controller]' AND appdir = '$d[appdir]' AND subdir = '$d[subdir]'))")->find()){
                if($rs['name'] == $d['name']) return $this->returnMsg('模块标识已经存在');
                if($rs['table'] == $d['table']) return $this->returnMsg('数据表已经存在');
                return $this->returnMsg('控制器路由已经存在');
            }

            $d["edittime"] = time();
            $d['edit'] = $this->manUser['username'];
            $action = $d['action']; unset($d['action']);
            if($Myobj->save($d)){
                if($action == 'build'){ //生成代码
                    if(!$Myobj->state) return $this->returnMsg('模块已被停用，数据已保存，构建未执行');
                    $rs = $Myobj->toArray();
                    if(!$rs['table_fields'] || $rs['table_fields'] == '[]') return $this->returnMsg('请先配置好数据表字段');
                    unset($rs['addtime'],$rs['edittime'],$rs['runtime'],$rs['times'],$rs['add'],$rs['edit'],$rs['run'],$rs['note']);
                    $d = $this->only(['uid/d','token','repeat/d','reback/d']);
                    $d = array_merge($rs,$d);

                    try{
                        $d['version'] = VT_VERSION;
                        //删除相关菜单
                        if($d['do_build'] > 1) \tool\Menus::delete($d['name']);
                        //获取模板后缀
                        $d['suffix'] = config('view.view_suffix');
                        //开始远程构建

                        Build::build(strtolower($d['name']), $d);


                        //记录操作
                        $Myobj->times ++;
                        $Myobj->runtime = time();
                        $Myobj->run = $this->manUser['username'];
                        $note = '标识:'.$d['name'].' 控制器:'.$d['controller'].' 目录:'.$d['appdir'].($d['subdir'] ? ' / '.$d['subdir'] : '').(in_array($d['do_build'],[1,3]) ? ' 创建表:'.$d['table'].'/'.$d['table_engine'].'/'.$d['table_charset'] : '').(in_array($d['do_build'],[2,3]) ? ' 建菜单' : '').' 用户:'.$this->manUser['username'];
                        $Myobj->note = $Myobj->note . '<li><a>'.date('Y-m-d H:i:s', time()).' #</a> <a>'.$note.' 执行生成</a></li>';
                        $Myobj->save();
                    }catch(Exception $e){
                        return $this->returnMsg($e->getMessage(),$e->getCode());
                    }
                    return $this->returnMsg('生成成功',1);
                }
                return $this->returnMsg("编辑成功", 1);
            }else{
                return $this->returnMsg("编辑失败");
            }
        }
    }

    /**
     * 模块删除
     * @return json
     */
    public function del()
    {
        $id = $this->only(['@token'=>'','id'])['id'];
        $id = is_array($id) ? implode(',',$id) : $id;
        if(!$id) return $this->returnMsg('参数错误');
        $rs = MD::where("id IN($id)")->column('name');
        if(MD::del("id IN($id)")){
            /* 删除记录文件 */
            foreach ($rs as $v){
                @rmdirs(ADDON_PATH . '/vtool/data/' . $v);
            }/**/
            return $this->returnMsg("删除成功", 1);
        }else{
            return $this->returnMsg("删除失败");
        }
    }

    /**
     * 模块卸载
     * @return json
     */
    public function uninstall()
    {
        $d = $this->only(['@token'=>'','name/*/{2,30}/模块标识/1,2,3/']);
        try{
            $Myobj = MD::one("name = '".$d['name']."'");
            if(!$Myobj) return $this->returnMsg("数据不存在");
            if(!$Myobj->state) return $this->returnMsg('模块已被停用，不能执行卸载');
            //执行卸载
            Build::uninstall(strtolower($d['name']));
            //记录操作
            $Myobj->note = $Myobj->note . '<li><a>'.date('Y-m-d H:i:s', time()).' #</a> <a>'.$this->manUser['username'].' 执行卸载</a></li>';
            $Myobj->save();
            return $this->returnMsg('卸载成功', 1);
        }catch(Exception $e){
            return $this->returnMsg($e->getMessage(),$e->getCode());
        }
    }

}