<?php

namespace app\admin\controller\Gen;

use app\BaseController;
use app\common\model\Banner\Banner as ModelBanner;
use app\Request;
use app\exception\ErrorMsg;
use think\facade\Db;
use app\common\exception\Tool;
use app\admin\controller\Gen\GenApi\GenModel\Model as GenModel;
use app\admin\controller\Gen\GenApi\GenController\Admin as GenAdminController;
use app\admin\controller\Gen\GenApi\GenController\Api as GenApiController;

class Gen extends BaseController
{
    private $address = 'D:\phpstudy_pro\WWW\Aerwen\houde_web\houde_web_back';


    public function index(Request $request)
    {
    }

    //一键删除表
    public function deleteTable()
    {
        try {
            Db::execute("drop table gen_table,gen_table_column");
            return [
                'code' => 0,
                'msg' => '一键删除表成功!'
            ];
        } catch (\Throwable $th) {
            throw  $th;
        }
    }

    //一键生成表
    public function createTable()
    {
        try {
            Db::execute("
            CREATE TABLE `gen_table`  (
                `tableId` int(0) NOT NULL AUTO_INCREMENT COMMENT '编号',
                `tableName` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '表名称',
                `tableComment` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '表描述',
                `className` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '实体类名称',
                `tplCategory` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'crud' COMMENT '使用的模板（crud单表操作 tree树表操作）',
                `moduleName` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '生成模块名',
                `businessName` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '生成业务名',
                `functionName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '生成功能名',
                `functionAuthor` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '生成功能作者',
                `genType` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '生成代码方式（0zip压缩包 1自定义路径）',
                `genPath` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '/' COMMENT '生成路径（不填默认项目路径）',
                `options` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '其它生成选项',
                `remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
                `create_time` datetime(0) NULL DEFAULT NULL,
                `create_user_guid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                `update_time` datetime(0) NULL DEFAULT NULL,
                `update_user_guid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                `delete_time` datetime(0) NULL DEFAULT NULL,
                `delete_user_guid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                PRIMARY KEY (`tableId`) USING BTREE
              ) ENGINE = InnoDB AUTO_INCREMENT = 79 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '生成表' ROW_FORMAT = DYNAMIC;
              ");

            Db::execute("
            CREATE TABLE `gen_table_column`  (
                `columnId` int(0) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '编号',
                `tableName` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表名',
                `tableId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '归属表编号',
                `columnName` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列名称',
                `columnComment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列描述',
                `columnType` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列类型',
                `isPk` tinyint(1) NULL DEFAULT NULL COMMENT '是否主键（1是）',
                `isIncrement` tinyint(1) NULL DEFAULT NULL COMMENT '是否自增（1是）',
                `isRequired` tinyint(1) NULL DEFAULT NULL COMMENT '是否必填（1是）',
                `isInsert` tinyint(1) NULL DEFAULT NULL COMMENT '是否为插入字段（1是）',
                `isEdit` tinyint(1) NULL DEFAULT NULL COMMENT '是否编辑字段（1是）',
                `isList` tinyint(1) NULL DEFAULT NULL COMMENT '是否列表字段（1是）',
                `isQuery` tinyint(0) NULL DEFAULT NULL COMMENT '是否查询字段（1是）',
                `isSort` tinyint(0) NULL DEFAULT NULL COMMENT '是否排序字段（1是）',
                `queryType` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'EQ' COMMENT '查询方式（等于、不等于、大于、小于、范围）',
                `htmlType` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '显示类型（文本框、文本域、下拉框、复选框、单选框、日期控件）',
                `dictType` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型',
                `sort` int(0) NULL DEFAULT NULL COMMENT '排序',
                `isInit` tinyint(1) NULL DEFAULT 0 COMMENT '是否初始化字段（1是）',
                `create_time` datetime(0) NULL DEFAULT NULL,
                `create_user_guid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                `update_time` datetime(0) NULL DEFAULT NULL,
                `update_user_guid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                `delete_time` datetime(0) NULL DEFAULT NULL,
                `delete_user_guid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
                PRIMARY KEY (`columnId`) USING BTREE
              ) ENGINE = InnoDB AUTO_INCREMENT = 534 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '生成表字段' ROW_FORMAT = DYNAMIC;
              ");

            return [
                'code' => 0,
                'msg' => '一键生成表成功!'
            ];
        } catch (\Throwable $th) {
            throw  $th;
        }
    }

    // 获取所有表名称
    public function getTatbleList(Request $request)
    {
        $data_base_name_arr = Db::query("select database()");
        $tableName = $request->param('tableName');

        // $select = Db::getTables();
        $select = Db::query("show tables");
        $selecJs = [];

        $data_base_name = $data_base_name_arr[0]['database()'];

        foreach ($select as $key => $value) {
            array_push($selecJs, ['name' => $value["Tables_in_{$data_base_name}"]]);
        }

        $arr = [];
        if ($tableName) {
            foreach ($selecJs as $key => $value) {
                if (strstr($value["name"], $tableName)) {
                    // return 1;
                    array_push($arr, $value);
                }
            }
        }
        if (count($arr) > 0) {
            $selecJs = $arr;
        }

        $count = count($selecJs);
        return [
            'code' => 200,
            'data' => [
                'pageIndex' => 1,
                'pageSize' => 10,
                'result' => $selecJs,
                'totalNum' => $count,
                'totalPage' => 1,
            ],
            'msg' => 'SUCCESS'
        ];
    }

    // 获取生成表列表
    public function getGenTableList(Request $request)
    {
        $tableName = $request->param('tableName');
        $search = [];
        if ($tableName) {
            $search['tableName'] = $tableName;
        }

        $select = Db::name('gen_table')
            ->where($search)
            ->order('tableId', 'desc');

        $count = $select->count();
        $select = self::pageWrapper($select)->select();

        return [
            'code' => 0,
            'data' => $select,
            'count' => $count,
            'msg' => 'ok'
        ];
    }

    // 获取生成表详情
    public function getGenTableDetail(Request $request)
    {
        $tableId = $request->param('tableId');

        $select = Db::name('gen_table')
            ->where('tableId', $tableId)
            ->find();

        $columns = Db::name('gen_table_column')
            ->where('tableId', $tableId)
            ->select()->toArray();

        $select['options'] = json_decode($select['options']);
        foreach ($columns as $key => $value) {
            $columns[$key]['isEdit']  =  $this->intToBool($value['isEdit']);
            $columns[$key]['isPk']  =  $this->intToBool($value['isPk']);
            $columns[$key]['isIncrement']  =  $this->intToBool($value['isIncrement']);
            $columns[$key]['isRequired']  =  $this->intToBool($value['isRequired']);
            $columns[$key]['isInsert']  =  $this->intToBool($value['isInsert']);
            $columns[$key]['isList']  =  $this->intToBool($value['isList']);
            $columns[$key]['isQuery']  =  $this->intToBool($value['isQuery']);
            $columns[$key]['isSort']  =  $this->intToBool($value['isSort']);
            $columns[$key]['isInit']  =  $this->intToBool($value['isInit']);
        }

        return [
            'code' => 0,
            'data' => $select,
            'columns' => $columns,
            'msg' => 'ok'
        ];
    }

    // 删除生成表
    public function delTable(Request $request)
    {
        $params = $request->param();

        $gen = Db::name('gen_table')->where([
            'tableId' => $params['tableId']
        ]);
        $id = $gen->find()['tableId'];
        // return $gen->find()['tableId'];
        $gen->delete();

        $gen_column = Db::name('gen_table_column')->where('tableId', $id);
        $gen_column->delete();

        return [
            'code' => 200,
            'msg' => "删除成功"
        ];
    }

    // 导入表
    public function importTable(Request $request)
    {
        $tables = $request->param('tables');

        // 初始化表数据
        $tableInfo = Db::query("SHOW TABLE STATUS where Name = '$tables[0]'")[0];
        $tabledata = $this->initTable($tableInfo);
        // return $tabledata;
        $id = Db::name('gen_table')->strict()->insertGetId($tabledata);

        // 初始化字段数据
        $fields = Db::getFields($tables[0]);

        foreach ($fields as $value) {
            // return $value;
            $fieldsdata = $this->initFields($tables[0], $id, $value);
            $fieldid = Db::name('gen_table_column')->strict()->insertGetId($fieldsdata);
        }

        return [
            'code' => 200,
            'msg' => '导入成功'
        ];
    }

    /**
     * 编辑生成
     */
    public function updateGenTable(Request $request)
    {
        $params = $request->param();
        // return $params['options'];

        $options = [
            "ParentMenuId" => $params['ParentMenuId'],
            "SortType" => $params['SortType'],
            "SortField" => $params['SortField'],
            "CheckedBtn" => $params['CheckedBtn'],
            "ColNum" => $params['ColNum'],
        ];

        $model = Db::name('gen_table')->where([
            'tableId' => $params['tableId']
        ])->update([
            'tableName' => $params['tableName'],
            'tableComment' => $params['tableComment'],
            'className' => $params['className'],
            'tplCategory' => $params['tplCategory'],
            'moduleName' => $params['moduleName'],
            'isSort' => $params['isSort'],
            'businessName' => $params['businessName'],
            'functionName' => $params['functionName'],
            'functionAuthor' => $params['functionAuthor'],
            'genType' => $params['genType'],
            'genPath' => $params['genPath'],
            'options' => json_encode($options),
            'remark' => $params['remark'],
        ]);
        // if (!$model) {
        //     throwErrorMsg("生成表不存在", 1);
        // }
        // $model->save($params);

        $model2 = Db::name('gen_table_column')->where([
            'tableId' => $params['tableId']
        ])->select();
        if (!$model2) {
            throwErrorMsg("生成表字段不存在", 1);
        }
        // return $model2;
        foreach ($model2 as $key => $item1) {
            // return $item1;
            foreach ($params['columns'] as $key => $item2) {
                if ($item1['columnId'] == $item2['columnId']) {
                    // return $item2;
                    // return var_dump($item2);
                    $item = Db::name('gen_table_column')->where([
                        'columnId' => $item2['columnId']
                    ])->update($item2);
                }
            }
        }

        return [
            'code' => 200,
            'msg' => '编辑成功'
        ];
    }

    // 生成代码入口
    public function genCode(Request $request)
    {
        $tableId = $request->param('tableId');

        $table = Db::name('gen_table')
            ->where('tableId', $tableId)
            ->find();

        $columns = Db::name('gen_table_column')
            ->where('tableId', $tableId)
            ->select()->toArray();

        $table['options'] = json_decode($table['options']);
        foreach ($columns as $key => $value) {
            $columns[$key]['isEdit']  =  $this->intToBool($value['isEdit']);
            $columns[$key]['isPk']  =  $this->intToBool($value['isPk']);
            $columns[$key]['isIncrement']  =  $this->intToBool($value['isIncrement']);
            $columns[$key]['isRequired']  =  $this->intToBool($value['isRequired']);
            $columns[$key]['isInsert']  =  $this->intToBool($value['isInsert']);
            $columns[$key]['isList']  =  $this->intToBool($value['isList']);
            $columns[$key]['isQuery']  =  $this->intToBool($value['isQuery']);
            $columns[$key]['isSort']  =  $this->intToBool($value['isSort']);
            $columns[$key]['isInit']  =  $this->intToBool($value['isInit']);
        }

        // return $table;

        try {
            (new GenModel($columns, $table))->createNewModel();
            (new GenAdminController($columns, $table))->createAdminController();
            if ($table['tplCategory'] == "web_static") {
                $this->createJsWebStaticIndex($columns, $table);
                $this->createJsApi($columns, $table);
            } else if ($table['tplCategory'] == "crud") {
                $this->createJsVue($columns, $table);
                $this->createJsAdd($columns, $table);
                $this->createJsEdit($columns, $table);
                $this->createJsDetail($columns, $table);
                $this->createJsApi($columns, $table);
            }
        } catch (\Throwable $th) {
            throw $th;
        }

        return [
            'code' => 200,
            'msg' => '生成成功'
        ];
    }

    // 生成Api代码入口
    public function codeGeneratorApi(Request $request)
    {
        $tableId = $request->param('tableId');

        $table = Db::name('gen_table')
            ->where('tableId', $tableId)
            ->find();

        $columns = Db::name('gen_table_column')
            ->where('tableId', $tableId)
            ->select()->toArray();

        $table['options'] = json_decode($table['options']);
        foreach ($columns as $key => $value) {
            $columns[$key]['isEdit']  =  $this->intToBool($value['isEdit']);
            $columns[$key]['isPk']  =  $this->intToBool($value['isPk']);
            $columns[$key]['isIncrement']  =  $this->intToBool($value['isIncrement']);
            $columns[$key]['isRequired']  =  $this->intToBool($value['isRequired']);
            $columns[$key]['isInsert']  =  $this->intToBool($value['isInsert']);
            $columns[$key]['isList']  =  $this->intToBool($value['isList']);
            $columns[$key]['isQuery']  =  $this->intToBool($value['isQuery']);
            $columns[$key]['isSort']  =  $this->intToBool($value['isSort']);
            $columns[$key]['isInit']  =  $this->intToBool($value['isInit']);
        }

        (new GenApiController($columns, $table))->createApiController();

        return [
            'code' => 200,
            'msg' => '生成成功'
        ];
    }

    // 初始化表数据
    private function initTable($tableInfo)
    {
        $options = [
            "ParentMenuId" => 0,
            "SortType" => "desc",
            "SortField" => $tableInfo['Name'] . "_update_time",
            "CheckedBtn" => [1, 2, 3, 5],
            "ColNum" => 0,
        ];

        $tabledata = [
            // 'tplCategory' => $tableInfo['tplCategory'],
            'tableName' => $tableInfo['Name'],
            'tableComment' => $tableInfo['Comment'],
            'className' => Tool::camelize($tableInfo['Name'], true),
            'businessName' => $tableInfo['Name'],
            'moduleName' => Tool::camelize($tableInfo['Name'], true),
            'functionName' => $tableInfo['Comment'],
            'functionAuthor' => 'admin',
            'genType' => 1,
            'isSort' => 0,
            'genPath' => $this->address, // 自定义路径
            'options' => json_encode($options),
            'create_time'   =>  date('Y-m-d H:i:s'),
        ];
        return $tabledata;
    }

    // 初始化字段数据
    private function initFields($tableName, $id, $value)
    {
        // 初始字段
        $inputDtoNoFieldArr = [
            $tableName . "_" . "id",
            $tableName . "_" . "guid",
            $tableName . "_" . "create_time",
            $tableName . "_" . "create_user_guid",
            $tableName . "_" . "update_time",
            $tableName . "_" . "update_user_guid",
            $tableName . "_" . "delete_time",
            $tableName . "_" . "delete_user_guid"
        ];
        // 查询字段
        $ListFieldArr = [
            $tableName . "_" . "create_time",
            $tableName . "_" . "create_user_guid",
            $tableName . "_" . "update_time",
            $tableName . "_" . "update_user_guid",
            $tableName . "_" . "delete_time",
            $tableName . "_" . "delete_user_guid"
        ];
        // 图片字段
        $imageFiledArr = [
            $tableName . "_" . "icon",
            $tableName . "_" . "img",
            $tableName . "_" . "image",
            $tableName . "_" . "url",
            $tableName . "_" . "pic",
            $tableName . "_" . "photo",
            $tableName . "_" . "avatar"
        ];
        // 下拉框字段
        $selectFiledArr = [
            $tableName . "_" . "status",
            $tableName . "_" . "type",
            $tableName . "_" . "state",
            $tableName . "_" . "sex",
            $tableName . "_" . "gender"
        ];
        // 类型判断
        $type = $this->FieldsType($value['type']);
        $queryType = '';

        if (in_array($value["name"], $inputDtoNoFieldArr)) $isInsert = false;
        else $isInsert = true;

        if (in_array($value["name"], $inputDtoNoFieldArr)) $isInit = true;
        else $isInit = false;

        if ($value["primary"] || $value["autoinc"] || in_array($value["name"], $inputDtoNoFieldArr)) $isEdit = false;
        else $isEdit = true;

        if (in_array($value["name"], $ListFieldArr)) $isList = false;
        else $isList = true;

        //时间类型初始化between范围查询
        if ($value['type'] == "datetime") {
            $queryType = "BETWEEN";
        }

        $fieldData = [
            'tableName' => $tableName,
            'tableId' => $id,
            'columnName' => $value["name"],
            'columnComment' => $value["comment"],
            'columnType' => $type,
            'isPk' => $value["primary"],
            'isIncrement' => $value["autoinc"],
            'isRequired' => $value["notnull"],
            'isInsert' => $isInsert,
            'isEdit' => $isEdit,
            'isList' => $isList,
            'isQuery' => false,
            'htmlType' => $this->FieldsHtmlType($value["name"], $tableName),
            'queryType' => $queryType,
            'isInit' => $isInit,
            'create_time'   =>  date('Y-m-d H:i:s'),
        ];

        return $fieldData;
        // return 6;
    }

    //生成模型
    private function createNewModel($fields, $table)
    {
        $root = base_path(); //根地址
        $model_path_name = $table['className'];

        //模型路径并创建
        $is_multiple = false;
        $multiple_name = '';

        $model_path = str_replace('/', DIRECTORY_SEPARATOR, $root . "common/model/" . $table['moduleName']);
        if (true !== $res = $this->mkdir($model_path)) {
            return $res;
        }

        $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/admin/model.tpl');
        $gen_path = str_replace('/', DIRECTORY_SEPARATOR, $root . "common/model/" . $table['moduleName'] . '/' . $model_path_name . ".php"); //生成的模型地址\

        $fieldArr = '';
        foreach ($fields as $value) {
            $fieldArr .=  '
            ' . '"' . $value['columnName'] . '"'  . " => " . '"' . $value['columnType'] . '",' . "
            ";
        }

        $checked_btn_arr = $table['options']->CheckedBtn; //其他选项 4：导出 6：导入
        $init_fields = []; //初始化(业务字段) 例: user_name => 用户名称
        foreach ($fields as $key => $val) {
            if (!$val['isInit']) $init_fields[$val['columnName']] =  $val['columnComment'];
        }

        //模型的示例代码
        $tem_f = fopen($temp_path, "r");
        $temp_str = fread($tem_f, filesize($temp_path));
        self::getImportExcelTempStr($fields, $table, $init_fields, 'imp_mod');
        $temp_str = str_replace(
            [
                '{$className}',
                '{$moduleName}',
                '{$businessName}',
                '{$fields}',
                '{$multiple_name}',
                '{$exportExcelContent}',
                '{$importExcelContent}',
                '{$importExcelInitContent}',
                '{$importExcelField}'
            ],
            [
                $table['className'],
                $table['moduleName'],
                $table['businessName'],
                $fieldArr,
                $multiple_name,
                in_array('4', $checked_btn_arr) ? self::getExportExcelTempStr($fields, $table, $init_fields, 'export_mod') : null,
                in_array('6', $checked_btn_arr) ? self::getImportExcelTempStr($fields, $table, $init_fields, 'imp_mod') : null,
                in_array('6', $checked_btn_arr) ? self::getImportExcelTempStr($fields, $table, $init_fields, 'imp_init') : null,
                in_array('6', $checked_btn_arr) ? self::getImportExcelTempStr($fields, $table, $init_fields, 'imp_fie') : null,
            ],
            $temp_str
        );
        // return $temp_str;
        $gen_model = fopen($gen_path, 'w');
        fwrite($gen_model, $temp_str);
        return true;
    }

    //生成后台控制器
    private function createAdminController($fields, $table)
    {
        $root = base_path(); //根地址
        $module_name = $table['moduleName']; //模块名
        $class_name = $table['className']; //实体类名

        //控制器模块构建
        $con_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}admin/controller/{$module_name}");
        if (true !== $res = $this->mkdir($con_path)) return $res;
        //模板路径构建

        if ($table['tplCategory'] == "crud") {
            $temp_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}resources/view/admin/controller.tpl");
        } else if ($table['tplCategory'] == "web_static") {
            $temp_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}resources/view/business/webController.tpl");
        }

        //控制器生成后的路径构建
        $gen_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}admin/controller/{$module_name}/{$class_name}.php");


        $function_name = $table['functionName']; //功能名
        $business_name = $table['businessName']; //业务名
        $checked_btn_arr = $table['options']->CheckedBtn; //其他选项 4：导出 6：导入
        $query_fields = []; //查询列表可显字段
        $order_field = "'{$table['options']->SortField}'"; //排序字段
        $order_mode = "'{$table['options']->SortType}'"; //排序方式
        $edit_allow_fields  = ["{$business_name}_update_user_guid"]; //编辑允许字段
        $add_allow_fields = ["{$business_name}_guid", "{$business_name}_create_user_guid", "{$business_name}_update_user_guid"]; //新增允许字段
        $where_content_arr = []; //列表查询条件
        $init_fields = []; //初始化(业务字段)
        $is_img_upload = false;
        $isSort = $table['isSort']; // 排序处理
        $add_require_fields = []; //新增必填字段
        $edit_require_fields = []; //编辑必填字段
        foreach ($fields as $key => $val) {
            $column_name = $val['columnName'];
            if (!$val['isInit']) $init_fields[$column_name] =  $val['columnComment'];
            if ($val['isList']) $query_fields[] =  $column_name;

            if ($val['isEdit'] && !in_array($column_name, $edit_allow_fields)) {
                $edit_allow_fields[] =  $column_name;
                if ($val['isRequired']) $edit_require_fields[] =  $column_name;
            }
            if ($val['isInsert'] && !in_array($column_name, $add_allow_fields)) {
                $add_allow_fields[] =  $column_name;
                if ($val['isRequired']) $add_require_fields[] =  $column_name;
            }
            if ($val['isQuery']) $where_content_arr[] = [$column_name, $val['queryType']];
            if ($val['htmlType'] == 'imageUpload') $is_img_upload = true;
            if ($val['htmlType'] == 'fileUpload') $is_file_upload = true;
        }

        if ($isSort) {
        }

        //打开模板文件资源(只读)
        $temp_res_r = fopen($temp_path, "r");
        //获取模板内容
        $temp_res_str = fread($temp_res_r, filesize($temp_path));
        //模板内容替换
        $temp_str = str_replace(
            [
                '{$moduleName}',
                '{$className}',
                '{$functionName}',
                '{$businessName}',
                '{$queryFields}',
                '{$orderField}',
                '{$orderMode}',
                '{$editAllowFields}',
                '{$addAllowFields}',
                '{$whereContent}',
                '{$exportExcelContent}',
                '{$importExcelContent}',
                '{$downloadTempContent}',
                '{$editRequireFields}',
                '{$addRequireFields}',
            ],
            [
                $module_name,
                $class_name,
                $function_name,
                $business_name,
                self::toFormTempStr($query_fields, $init_fields),
                $order_field ?? "'{$business_name}_update_time'",
                $order_mode ?? "'desc'",
                self::toFormTempStr($edit_allow_fields, $init_fields),
                self::toFormTempStr($add_allow_fields, $init_fields),
                self::toFormTempStr($where_content_arr, $init_fields, 3),
                in_array('4', $checked_btn_arr) ? self::getExportExcelTempStr($fields, $table, $init_fields, 'export_con') : null,
                in_array('6', $checked_btn_arr) ? self::getImportExcelTempStr($fields, $table, $init_fields, 'imp_con') : null,
                in_array('6', $checked_btn_arr) ? self::getExportExcelTempStr($fields, $table, $init_fields, 'temp') : null,
                self::toFormTempStr($edit_require_fields, $init_fields, 2),
                self::toFormTempStr($add_require_fields, $init_fields, 2),

            ],
            $temp_res_str
        );
        //渲染(写入)文件
        $gen_con = fopen($gen_path, 'w');
        fwrite($gen_con, $temp_str);
        return true;
    }

    //生成前台控制器
    private function createApiController($fields, $table)
    {
        $root = base_path(); //根地址
        $module_name = $table['moduleName']; //模块名
        $class_name = $table['className']; //实体类名
        $function_name = $table['functionName']; //功能名
        $business_name = $table['businessName']; //业务名

        //控制器模块构建
        $con_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}api/controller/{$module_name}");
        if (true !== $res = $this->mkdir($con_path)) return $res;
        //模板路径构建
        if ($table['tplCategory'] == "crud") {
            $temp_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}resources/view/api/controller.tpl");
        } else if ($table['tplCategory'] == "web_static") {
            $temp_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}resources/view/business/webApiController.tpl");
        }

        //控制器生成后的路径构建
        $gen_path = str_replace('/', DIRECTORY_SEPARATOR, "{$root}api/controller/{$module_name}/{$class_name}.php");

        $query_fields = []; //查询列表可显字段
        $order_field = "'{$table['options']->SortField}'"; //排序字段
        $order_mode = "'{$table['options']->SortType}'"; //排序方式
        $edit_allow_fields  = ["{$business_name}_update_user_guid"]; //编辑允许字段
        $add_allow_fields = ["{$business_name}_guid", "{$business_name}_create_user_guid", "{$business_name}_update_user_guid"]; //新增允许字段
        $where_content_arr = []; //列表查询条件
        $init_fields = []; //初始化(业务字段)
        $add_require_fields = []; //新增必填字段
        $edit_require_fields = []; //编辑必填字段
        foreach ($fields as $key => $val) {
            $column_name = $val['columnName'];
            if (!$val['isInit']) $init_fields[$column_name] =  $val['columnComment'];
            if ($val['isList']) $query_fields[] =  $column_name;
            if ($val['isEdit'] && !in_array($column_name, $edit_allow_fields)) {
                $edit_allow_fields[] =  $column_name;
                if ($val['isRequired']) $edit_require_fields[] =  $column_name;
            }
            if ($val['isInsert'] && !in_array($column_name, $add_allow_fields)) {
                $add_allow_fields[] =  $column_name;
                if ($val['isRequired']) $add_require_fields[] =  $column_name;
            }
            if ($val['isQuery']) $where_content_arr[] = [$column_name, $val['queryType']];
        }

        //打开模板文件资源(只读)
        $temp_res_r = fopen($temp_path, "r");
        //获取模板内容
        $temp_res_str = fread($temp_res_r, filesize($temp_path));
        //模板内容替换
        $temp_str = str_replace(
            [
                '{$moduleName}',
                '{$className}',
                '{$functionName}',
                '{$businessName}',
                '{$queryFields}',
                '{$orderField}',
                '{$orderMode}',
                '{$editAllowFields}',
                '{$addAllowFields}',
                '{$whereContent}',
                '{$imgUploadContent}',
                '{$fileUpload}',
                '{$imgUrlPrefixPadding}',
                '{$editRequireFields}',
                '{$addRequireFields}',
            ],
            [
                $module_name,
                $class_name,
                $function_name,
                $business_name,
                self::toFormTempStr($query_fields, $init_fields),
                $order_field ?? "'{$business_name}_update_time'",
                $order_mode ?? "'desc'",
                self::toFormTempStr($edit_allow_fields, $init_fields),
                self::toFormTempStr($add_allow_fields, $init_fields),
                self::toFormTempStr($where_content_arr, $init_fields, 3),
                self::toFormTempStr($edit_require_fields, $init_fields, 2),
                self::toFormTempStr($add_require_fields, $init_fields, 2),
            ],
            $temp_res_str
        );
        //渲染(写入)文件
        $gen_con = fopen($gen_path, 'w');
        fwrite($gen_con, $temp_str);
        return true;
    }

    // Js版本 1.30

    //生成JsVue页面
    private function createJsVue($fields, $table)
    {
        $root = base_path(); //根地址

        // return $table;
        $vue_path = $table['genPath'] . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR . "pages\index" . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . $table['businessName'];
        $vue_compoment_path = $vue_path . DIRECTORY_SEPARATOR . "components";
        if (true !== $res = $this->mkdir($vue_path)) {
            return $res;
        }
        if (true !== $res = $this->mkdir($vue_compoment_path)) {
            return $res;
        }

        // return $fields;
        $columnsArr = "
             {
               fixed: true,
               type: 'selection'
             },";

        $btn = '';
        $btnFunName = '';
        $btnFun = '';
        $imgTemplate = '';
        $search = '';
        $dictFun = '';
        $dict = '';
        $dictScope = '';
        $query = '';
        $sortTemplate = '';
        $sortTemplateFun = '';
        $switchTemplate = '';
        $switchTemplateFun = '';

        $isSort = $table['isSort']; // 排序处理
        foreach ($fields as $value) {
            $columnName = $value['columnName'];
            $className = $table['className'];

            if ($isSort == 1) {
                
                $sortTemplate = "
                <!-- 排序 -->
                <template #{$table['options']->SortField}='scope'>
                  <el-input-number :disabled='loading' v-model='scope.row.{$table['options']->SortField}' :min='1' controls-position='right'
                    @change='handleEditOrder(scope.row)'></el-input-number>
                </template>    
                ";

                $sortTemplateFun = "
                //排序
                const loading = ref(false)
                async function handleEditOrder(data) {
                    loading.value = true
                    const { code } = await edit{$className}(data);
                    if (code == 0) {
                        loading.value = false
                        tableRef.value.reload()
                    }
                }
                ";
            }
        }

        $btn_arr = $table['options']->CheckedBtn; // 勾选按钮
        // return $btn_arr;
        foreach ($btn_arr as $key => $item) {
            switch ($item) {
                case 6:
                    $btn .= '
                       <!-- 导入 -->
                       <el-upload
                           class="upload-demo"
                           :action="importExcel"
                           :headers="headers"
                           :on-success="handleExcelSuccess"
                           :on-progress="uploadLoading" 
                           :on-error="closeUploadLoading"
                           style="margin-left: 10px"
                           :show-file-list="false"
                       >
                           <el-button type="primary">导入</el-button>
                       </el-upload>
   
                       <!-- 下载导入模板 -->
                       <el-button icon="ElIconDownload" @click="downloadTemplate()"
                           >下载导入模板</el-button>
                       ';

                    $btnFunName .= ', downloadTemplate , importExcel ';

                    $btnFun .= '
                    // 导入方法
                    let loadingImoprt = null;
                    const uploadLoading = () => {
                      loadingImoprt = ElLoading.service({
                        lock: true,
                        text: "正在导入中...",
                        background: "rgba(255, 255, 255, 0.7)",
                      });
                    };
                    const closeUploadLoading = () => loadingImoprt.close();
                       const handleExcelSuccess = (value) => {
                        if (value.code == 0) {
                            ElMessageBox.alert(value.msg, "导入信息", {
                              dangerouslyUseHTMLString: true,
                              confirmButtonText: "确定",
                            });
                          } else {
                            ElMessage.error(value.msg);
                          }
                           closeUploadLoading();
                           tableRef.value.reload();
                         };
                       
                       ';
                    break;
                case 4:
                    $btn .= '
                           <!-- 导出 -->
                           <el-button icon="ElIconDocument" @click="exportExcel(params)">导出</el-button>
                           ';

                    $btnFunName .= ' , exportExcel';
                    break;
            }
        }

        foreach ($fields as $value) {
            if ($value['isList'] == true) {
                if ($value['isInit'] == false) {
                    $columnsArr .=  '
              ' . '{
               prop: "' . $value['columnName'] . '",
               '  .
                        "label: '" . $value['columnComment'] . "',
               " .
                        "width: '150'
               },";
                }
            }

            if ($value['isQuery'] == true) {
                $query .=  $value['columnName'] . ': "",
                ';
            }

            if ($value['isQuery'] == true) {
                if ($value['htmlType'] == "input") {
                    $search .= '
                       <el-form-item label="' . $value['columnComment'] . '">' . '
                       ' . "   <el-input v-model='params." . $value['columnName'] . "' " . "placeholder=" . "'请输入" . $value['columnComment'] . "'></el-input>
                       </el-form-item>";
                }
                if ($value['htmlType'] == "select") {
                    $search .= '
                       <el-form-item label="' . $value['columnComment'] . '">' . '
                       ' . '   <el-select v-model="params.' . $value['columnName'] . '"' . ' clearable placeholder="' . '请选择"' . '>
                               <el-option
           v-for="item in ' . $value['dictType'] . '"' . '
           ' . ':key="item.dictionary_guid" ' . ':label="item.dictionary_name"
           :value="item.dictionary_value"
           ></el-option>
                           </el-select>
                       </el-form-item>';
                }
            }

            if ($value['dictType'] != null) {
                $dictFun = ", getDictionary";

                $dictScope .= "
                <template #{$value['columnName']}='scope'>
                    <dict-tag :options='{$value['dictType']}' :value='scope.row.{$value['columnName']}' />
                </template>
                ";

                $dict .= "
                   // 字典获取
                   const " . $value['dictType'] . " = ref([]);" . '
                   ' . "async function get_" . $value['dictType'] . "() {
                     await getDictionary({ dictionary_value: '" . $value['dictType'] . "'}).then((res) => {" . '
                       ' . $value['dictType'] . ".value = res
                     })
                   }" . '
                   ' .
                    "get_" . $value['dictType'] . "()";
            }

            if ($value['htmlType'] == 'imageUpload') {
                $imgTemplate .= "
                   <template #" . $value['columnName'] . '="scope">' . '
                   ' . '<el-image v-if="scope.row.' . $value['columnName'] . '"' . ' 
                           :src="scope.row.' . $value['columnName'] . '.split(' . "','" . ')[0]"' . ' lazy
                           :preview-src-list="scope.row.' . $value['columnName'] . ".split(',')" . '"' .
                    ' :preview-teleported="true" :hide-on-click-modal="true" fit="contain" class="el-avatar"
                    ></el-image>
                       <template v-else>暂无图片</template>
                   </template>';
            }

            if ($value['htmlType'] == 'switch') {
                $switchTemplate = "
                <el-switch
                    :disabled=scope.row.{$value['columnName']}_bool
                    v-model=scope.row.{$value['columnName']}
                    class=mt-2
                    inline-prompt
                    :inactive-value=1
                    :active-value=2
                    style='--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949'
                    @click=handleEditShow(scope.row)
                />
                ";

                $switchTemplateFun = "
                // 展示切换
                async function handleEditShow(data) {
                    if(data.{$value['columnName']} === 1) return;
                  
                    loading.value = true
                    const { code } = await edit{$table['className']}(data);
                    if (code == 0) {
                      loading.value = false
                      tableRef.value.reload()
                    }
                  }
                ";
            }
        }



        $columnsArr .= "
             {
               label: '操作',
               prop: 'chaoz',
               width: '250',
               fixed: 'right'
             }";


        // //模型的示例代码
        $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/jsVue/index.tpl');
        $gen_path = $vue_path . DIRECTORY_SEPARATOR . "index.vue"; //生成Js的index.vue的地址
        $tem_f = fopen($temp_path, "r");
        $temp_str = fread($tem_f, filesize($temp_path));
        $temp_str = str_replace(
            [
                '${functionName}',
                '${moduleName}',
                '${search}',
                '${className}',
                '${btn}',
                '${imgTemplate}',
                '${dictFun}',
                '${cloumns}',
                '${businessName}',
                '${dict}',
                '${btnFunName}',
                '${btnFun}',
                '${query}',
                '${dictScope}',
                '${sortTemplate}',
                '${sortTemplateFun}',
                '${switchTemplate}',
                '${switchTemplateFun}',
            ],
            [
                $table['functionName'],
                $table['moduleName'],
                $search,
                $table['className'],
                $btn,
                $imgTemplate,
                $dictFun,
                $columnsArr,
                $table['businessName'],
                $dict,
                $btnFunName,
                $btnFun,
                $query,
                $dictScope,
                $sortTemplate,
                $sortTemplateFun,
                $switchTemplate,
                $switchTemplateFun,
            ],
            $temp_str
        );
        // return $temp_str;
        $gen_model = fopen($gen_path, 'w');
        fwrite($gen_model, $temp_str);
        return true;
    }

    //生成JsWebStaticIndex页面
    private function createJsWebStaticIndex($fields, $table)
    {
        $root = base_path(); //根地址
        $vue_path = $table['genPath'] . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR . "pages\index" . DIRECTORY_SEPARATOR . $table['businessName'];
        if (true !== $res = $this->mkdir($vue_path)) {
            return $res;
        }

        $rulesArr = "";
        $col = "";
        $mapParm = '';
        $mapFun = '';
        $mapOpen = '';
        $mapOpenFun = 'getContent()';

        $col = $this->getCol($fields);

        foreach ($fields as $value) {
            if ($value['isInit'] == false) {
                if ($value['isRequired'] == true) {
                    if ($value['isInsert'] == true) {
                        $rulesArr .=
                            $value['columnName'] . ": [
                                   {
                                   required: true,
                                   message: '" . $value['columnComment'] . "不能为空'
                                   }
                               ],
                               ";
                    }
                }
            }

            if ($value['htmlType'] == "map") {
                $mapParm = "const locationList = ref({})";

                $mapFun = "
                    // 地址处理
                    if (!locationList.value.address) {
                        ElMessage.error('请选择{$value['columnName']}');
                        return
                    }
                    let locationData = locationList.value
                    formData.{$value['columnName']} = locationData.address
                    formData.longitude = locationData.longitude
                    formData.latitude = locationData.latitude
                    ";

                $mapOpen = "
                if (formData.value.longitude) {
                    locationList.value.address = formData.value.{$value['columnName']};
                    locationList.value.longitude = formData.value.longitude;
                    locationList.value.latitude = formData.value.latitude;
                  }
                ";

                $mapOpenFun = "
                let mapCb = function(){
                    getContent()
                  }";
            }
        }

        $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/business/webIndex.tpl');
        $gen_path = $vue_path . DIRECTORY_SEPARATOR . "index.vue"; //生成Js的index.vue的地址
        $tem_f = fopen($temp_path, "r");
        $temp_str = fread($tem_f, filesize($temp_path));
        $temp_str = str_replace(
            [
                '${functionName}',
                '${className}',
                '${rules}',
                '${businessName}',
                '${col}',
                '${mapParm}',
                '${mapFun}',
                '${mapOpen}',
                '${mapOpenFun}',
            ],
            [
                $table['functionName'],
                $table['className'],
                $rulesArr,
                $table['businessName'],
                $col,
                $mapParm,
                $mapFun,
                $mapOpen,
                $mapOpenFun
            ],
            $temp_str
        );
        $gen_model = fopen($gen_path, 'w');
        fwrite($gen_model, $temp_str);
        return true;
    }

    //生成JsAdd添加页面
    private function createJsAdd($fields, $table)
    {
        $root = base_path(); //根地址
        $vue_compoment_path = $table['genPath'] . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR . "pages\index" . DIRECTORY_SEPARATOR . $table['businessName'] . DIRECTORY_SEPARATOR . "components";

        $rulesArr = "";
        $col = "";
        $dictFunName = '';
        $dictFunName2 = '';
        $dictFun = '';
        $mapParm = '';
        $mapFun = '';

        $col = $this->getCol($fields);

        foreach ($fields as $value) {
            if ($value['isInit'] == false) {
                if ($value['isRequired'] == true) {
                    if ($value['isInsert'] == true) {
                        $rulesArr .=
                            $value['columnName'] . ": [
                               {
                               required: true,
                               message: '" . $value['columnComment'] . "不能为空'
                               }
                           ],
                           ";
                    }
                }
            }

            if ($value['dictType'] != null) {
                $dictFunName = ", getDictionary";
                $dictFunName2 .= "get_" . $value['dictType'] . "()" . '
                   ';

                $dictFun .= "
                   // 字典获取
                   const " . $value['dictType'] . " = ref([]);" . '
                   ' . "async function get_" . $value['dictType'] . "() {
                     await getDictionary({ dictionary_value: '" . $value['dictType'] . "'}).then((res) => {" . '
                       ' . $value['dictType'] . ".value = res
                     })
                   }";
            }

            if ($value['htmlType'] == "map") {
                $mapParm = "const locationList = ref({})";

                $mapFun = "
                // 地址处理
                if (!locationList.value.address) {
                    ElMessage.error('请选择{$value['columnName']}');
                    return
                }
                let locationData = locationList.value
                formData.{$value['columnName']} = locationData.address
                formData.longitude = locationData.longitude
                formData.latitude = locationData.latitude
                ";
            }
        }

        $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/jsVue/add.tpl');
        $gen_path = $vue_compoment_path . DIRECTORY_SEPARATOR . "Add" . $table['className'] . 'Dialog' . ".vue"; //生成Js的index.vue的地址
        $tem_f = fopen($temp_path, "r");
        $temp_str = fread($tem_f, filesize($temp_path));
        $temp_str = str_replace(
            [
                '${functionName}',
                '${className}',
                '${rules}',
                '${businessName}',
                '${dictFunName}',
                '${dictFunName2}',
                '${dictFun}',
                '${col}',
                '${mapParm}',
                '${mapFun}',
            ],
            [
                $table['functionName'],
                $table['className'],
                $rulesArr,
                $table['businessName'],
                $dictFunName,
                $dictFunName2,
                $dictFun,
                $col,
                $mapParm,
                $mapFun,
            ],
            $temp_str
        );
        $gen_model = fopen($gen_path, 'w');
        fwrite($gen_model, $temp_str);
        return true;
    }

    //生成JsEdit编辑页面
    private function createJsEdit($fields, $table)
    {
        $root = base_path(); //根地址

        $vue_compoment_path = $table['genPath'] . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR . "pages\index" . DIRECTORY_SEPARATOR . $table['businessName'] . DIRECTORY_SEPARATOR . "components";

        // return $fields;
        $rulesArr = "";
        $dictFunName = '';
        $dictFunName2 = '';
        $dictFun = '';
        $col = '';
        $mapParm = '';
        $mapFun = '';
        $mapOpen = '';

        $col = $this->getCol($fields);

        foreach ($fields as $value) {
            if ($value['isInit'] == false) {
                if ($value['isRequired'] == true) {
                    if ($value['isEdit'] == true) {
                        $rulesArr .=
                            $value['columnName'] . ": [
                               {
                               required: true,
                               message: '" . $value['columnComment'] . "不能为空'
                               }
                           ],
                           ";
                    }
                }
            }

            if ($value['dictType'] != null) {
                $dictFunName = ", getDictionary";
                $dictFunName2 .= "get_" . $value['dictType'] . "()" . '
                   ';

                $dictFun .= "
                   // 字典获取
                   const " . $value['dictType'] . " = ref([]);" . '
                   ' . "async function get_" . $value['dictType'] . "() {
                     await getDictionary({ dictionary_value: '" . $value['dictType'] . "'}).then((res) => {" . '
                       ' . $value['dictType'] . ".value = res
                     })
                   }";
            }

            if ($value['htmlType'] == "map") {
                $mapParm = "const locationList = ref({})";

                $mapFun = "
                // 地址处理
                let locationData = locationList.value
                formData.value.{$value['columnName']} = locationData.address
                formData.value.longitude = locationData.longitude
                formData.value.latitude = locationData.latitude
                ";

                $mapOpen = "
                if (formData.value.longitude) {
                    locationList.value.address = formData.value.{$value['columnName']};
                    locationList.value.longitude = formData.value.longitude;
                    locationList.value.latitude = formData.value.latitude;
                  }
                ";
            }
        }
        // return $rulesArr;

        $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/jsVue/edit.tpl');
        $gen_path = $vue_compoment_path . DIRECTORY_SEPARATOR . "Edit" . $table['className'] . 'Dialog' . ".vue"; //生成Js的index.vue的地址
        $tem_f = fopen($temp_path, "r");
        $temp_str = fread($tem_f, filesize($temp_path));
        $temp_str = str_replace(
            [
                '${functionName}',
                '${className}',
                '${rules}',
                '${businessName}',
                '${dictFunName}',
                '${dictFunName2}',
                '${dictFun}',
                '${col}',
                '${mapParm}',
                '${mapFun}',
                '${mapOpen}',
            ],
            [
                $table['functionName'],
                $table['className'],
                $rulesArr,
                $table['businessName'],
                $dictFunName,
                $dictFunName2,
                $dictFun,
                $col,
                $mapParm,
                $mapFun,
                $mapOpen,
            ],
            $temp_str
        );
        // return $temp_str;
        $gen_model = fopen($gen_path, 'w');
        fwrite($gen_model, $temp_str);
        return true;
    }

    //生成JsDetail详情页面
    private function createJsDetail($fields, $table)
    {
        $root = base_path(); //根地址

        $vue_compoment_path = $table['genPath'] . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR . "pages\index" . DIRECTORY_SEPARATOR . $table['businessName'] . DIRECTORY_SEPARATOR . "components";

        $dictFunName = '';
        $dictFunName2 = '';
        $dictFun = '';
        $col = '';
        $mapParm = '';
        $mapOpen = '';

        $col = $this->getCol($fields);

        foreach ($fields as $key => $value) {
            if ($value['dictType'] != null) {
                $dictFunName = "import { getDictionary } from '~/service/{$table['businessName']}';";
                $dictFunName2 .= "get_" . $value['dictType'] . "()" . '
                   ';

                $dictFun .= "
                   // 字典获取
                   const " . $value['dictType'] . " = ref([]);" . '
                   ' . "async function get_" . $value['dictType'] . "() {
                     await getDictionary({ dictionary_value: '" . $value['dictType'] . "'}).then((res) => {" . '
                       ' . $value['dictType'] . ".value = res
                     })
                   }";
            }
            if ($value['htmlType'] == "map") {
                $mapParm = "const locationList = ref({})";

                $mapOpen = "
                if (formData.value.longitude) {
                    locationList.value.address = formData.value.{$value['columnName']};
                    locationList.value.longitude = formData.value.longitude;
                    locationList.value.latitude = formData.value.latitude;
                  }
                ";
            }
        }

        $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/jsVue/detail.tpl');
        $gen_path = $vue_compoment_path . DIRECTORY_SEPARATOR . "Detail" . $table['className'] . 'Dialog' . ".vue"; //生成的index.vue的地址
        $tem_f = fopen($temp_path, "r");
        $temp_str = fread($tem_f, filesize($temp_path));
        $temp_str = str_replace(
            [
                '${functionName}',
                '${className}',
                '${businessName}',
                '${dictFunName}',
                '${dictFunName2}',
                '${dictFun}',
                '${col}',
                '${mapParm}',
                '${mapOpen}',
            ],
            [
                $table['functionName'],
                $table['className'],
                $table['businessName'],
                $dictFunName,
                $dictFunName2,
                $dictFun,
                $col,
                $mapParm,
                $mapOpen,
            ],
            $temp_str
        );
        // return $temp_str;
        $gen_model = fopen($gen_path, 'w');
        fwrite($gen_model, $temp_str);
        return true;
    }

    //生成Api页面
    private function createJsApi($fields, $table)
    {
        $root = base_path(); //根地址

        $vue_api_path = $table['genPath'] . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR . "service";

        // return $fields;

        $urlStr = "";
        $listArr = "";
        $imageFun = "";
        $fileFun = "";
        $dictFun = "";

        $excelFun = "";

        $btn_arr = $table['options']->CheckedBtn; // 勾选按钮
        // return $btn_arr;

        foreach ($btn_arr as $key => $item) {
            switch ($item) {
                case 6:
                    $excelFun .= '
                       /**
                        * 下载' . $table['tableComment'] . '模板
                        * @param {Object} data
                        * @return {Promise} api
                        */
                       export function downloadTemplate(data) {
                           downloadFile(createApiUrl(' . "'" . $table['moduleName'] . "." . $table['className'] . "/downloadTemplate'), data);
                       }" . '
                       
                       /**
                        * 导入' . $table['tableComment'] . '
                        * @param {Object} data
                        * @return {Promise} api
                        */
                       export const importExcel = createApiUrl(' . "'" . $table['moduleName'] . "." . $table['className'] . "/importExcel');
                       ";
                    break;
                case 4:
                    $excelFun .= '
                       /**
                       * 导出' . $table['tableComment'] . '
                       * @param {Object} data
                       * @return {Promise} api
                       */
                       export function exportExcel(data) {
                           downloadFile(createApiUrl(' . "'" . $table['moduleName'] . "." . $table['className'] . "/exportExcel'), data);
                       }
                       ";
                    break;
            }
        }

        foreach ($fields as $value) {
            if ($value['isList'] == true) {
                if ($value['isInit'] == false) {
                    $listArr .=
                        $value['columnName'] . ":" . self::FieldsJsType($value['columnType']) . ",
                           ";

                    if ($value['htmlType'] == 'imageUpload' || $value['htmlType'] == 'fileUpload') {
                        $urlStr = 'url: "",';
                    }
                }

                if ($value['dictType'] != null) {
                    $dictFun = "
                       /**
                        * 获取字典值
                        * @param {Object} data
                        * @return {Promise} api
                        */
                       export function getDictionary(data) {
                         return api.post('Dictionary.Dictionary/getDictionary', data, {
                         });
                       }
                       ";
                }
                // if ($value['htmlType'] == 'imageUpload') {
                //     $imageFun = "
                //        /**
                //         * 上传图片
                //         */
                //         export const upload" . $table['className'] . "Img = createApiUrl('" . $table['className'] . "." . $table['className'] . "/upload" . $table['className'] . "Img');
                //        ";
                // }
                // if ($value['htmlType'] == 'fileUpload') {
                //     $fileFun = "
                //        /**
                //         * 上传文件
                //         */
                //         export const upload" . $table['className'] . "File = createApiUrl('" . $table['className'] . "." . $table['className'] . "/upload" . $table['className'] . "File');
                //        ";
                // }
            }
        }

        if ($table['tplCategory'] == "web_static") $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/business/webApi.tpl');
        else if ($table['tplCategory'] == "crud") $temp_path = str_replace('/', DIRECTORY_SEPARATOR, $root . 'resources/view/jsVue/api.tpl');
        $gen_path = $vue_api_path . DIRECTORY_SEPARATOR . $table['businessName'] . ".js"; //生成的api的地址
        $tem_f = fopen($temp_path, "r");
        $temp_str = fread($tem_f, filesize($temp_path));
        $temp_str = str_replace(
            [
                '${moduleName}',
                '${functionName}',
                '${className}',
                '${businessName}',
                '${list}',
                '${imageFun}',
                '${fileFun}',
                '${dictFun}',
                '${excelFun}',
                '${urlStr}',
            ],
            [
                $table['moduleName'],
                $table['functionName'],
                $table['className'],
                $table['businessName'],
                $listArr,
                $imageFun,
                $fileFun,
                $dictFun,
                $excelFun,
                $urlStr,
            ],
            $temp_str
        );
        // return $temp_str;
        $gen_model = fopen($gen_path, 'w');
        fwrite($gen_model, $temp_str);
        return true;
    }



    //创建文件夹
    public function mkdir($path)
    {
        if (!is_dir($path)) {
            if (false === @mkdir($path, 0777, true) && !is_dir($path)) {
                throwErrorMsg('创建文件夹失败:' . $path);
            }
        }
        return true;
    }

    //判断字段类型
    private function FieldsType($type)
    {
        // return $type;
        switch ($type) {
            case strstr($type, 'int'):
                return "int";
                break;
            case strstr($type, 'double'):
                return "double";
                break;
            case strstr($type, 'varchar'):
                return "string";
                break;
            case strstr($type, 'text'):
                return "string";
                break;
            case strstr($type, 'datetime'):
                return "datetime";
                break;

            default:
                $type;
        }
    }

    //判断Js字段类型
    private function FieldsJsType($type)
    {
        switch ($type) {
            case strstr($type, 'int'):
                return "number";
                break;
            case strstr($type, 'decimal'):
                return "number";
                break;
            case strstr($type, 'datetime'):
                return "Date";
                break;

            default:
                $type;
        }
        return $type;
    }

    //判断Js默认值字段类型
    private function FieldsJsDefaultValue($type)
    {
        switch ($type) {
            case strstr($type, 'string'):
                return '""';
                break;
            case strstr($type, 'int'):
                return "0";
                break;
            case strstr($type, 'decimal'):
                return "0";
                break;
            case strstr($type, 'datetime'):
                return 'null';
                break;

            default:
                $type;
        }
        return "";
    }

    //判断HTML类型
    private function FieldsHtmlType($name, $tableName)
    {
        // 图片字段
        $imageFiledArr = [
            $tableName . "_" . "icon",
            $tableName . "_" . "img",
            $tableName . "_" . "image",
            $tableName . "_" . "url",
            $tableName . "_" . "pic",
            $tableName . "_" . "photo",
            $tableName . "_" . "avatar"
        ];
        // 下拉框字段
        $selectFiledArr = [
            $tableName . "_" . "status",
            $tableName . "_" . "type",
            $tableName . "_" . "state",
            $tableName . "_" . "sex",
            $tableName . "_" . "gender"
        ];
        // 时间字段
        $timeFiledArr = [
            $tableName . "_" . "datetime",
            $tableName . "_" . "time",
            $tableName . "_" . "date",
            $tableName . "_" . "timestamp"
        ];


        $htmlType = 'input';

        if (in_array($name, $imageFiledArr)) {
            $htmlType = "imageUpload";
        } else if (in_array($name, $timeFiledArr)) {
            $htmlType = "datetime";
        } else if (strstr($name, 'content')) {
            $htmlType = "editor";
        } else if (in_array($name, $selectFiledArr)) {
            $htmlType = "select";
        }

        return $htmlType;
    }

    public function intToBool($value)
    {
        return (bool)$value;
    }


    public function getCol($fields)
    {
        $col = '';

        foreach ($fields as $value) {
            if ($value['isList'] == true) {
                if ($value['isInit'] == false) {
                    if ($value['htmlType'] == "input") {
                        $col .= '
                           <el-col :span="12">
                               <el-form-item :label-width="labelWidth" label="' . $value['columnComment'] . '" prop="' . $value['columnName'] . '">' . '
                               ' . "   <el-input v-model='formData." . $value['columnName'] . "' " . 'type="text" ' . "placeholder=" . "'请输入" . $value['columnComment'] . "'></el-input>
                               </el-form-item>
                           </el-col>";
                    }
                    if ($value['htmlType'] == "textarea") {
                        $col .= '
                           <el-col :span="24">
                               <el-form-item :label-width="labelWidth" label="' . $value['columnComment'] . '" prop="' . $value['columnName'] . '">' . '
                               ' . "   <el-input v-model='formData." . $value['columnName'] . "' " . 'type="textarea" :rows="5" ' . "placeholder=" . "'请输入" . $value['columnComment'] . "'></el-input>
                               </el-form-item>
                           </el-col>";
                    }
                    if ($value['htmlType'] == "select") {
                        $col .= '
                           <el-col :span="12">
                               <el-form-item label="' . $value['columnComment'] . '" prop="' . $value['columnName'] . '">' . '
                               ' . '<el-select v-model="formData.' . $value['columnName'] . '"' . ' clearable placeholder="' . '请选择"' . '>
                                       <el-option
                                           v-for="item in ' . $value['dictType'] . '"' . '
                                           ' . ':key="item.dictionary_guid" ' . ':label="item.dictionary_name"
                                           :value="item.dictionary_value"
                                           ></el-option>
                                   </el-select>
                               </el-form-item>
                           </el-col>';
                    }
                    if ($value['htmlType'] == "datetime") {
                        $col .= '
                           <el-col :span="12">
                               <el-form-item
                                   :label-width="labelWidth"
                                   label="' . $value['columnComment'] . '"' .
                            ' prop="' . $value['columnName'] . '"
                               >
                                   <el-date-picker
                                   v-model="formData.' . $value['columnName'] . '"' . '
                                   type="datetime"
                                   value-format="YYYY-MM-DD HH:mm"
                                   placeholder="' . $value['columnComment'] . '"
                                   />
                               </el-form-item>
                           </el-col>';
                    }
                    if ($value['htmlType'] == "imageUpload") {

                        $col .= "
                        <el-col :span='12'>
                            <el-form-item :label-width='labelWidth' label='{$value['columnComment']}' prop='{$value['columnName']}'>
                                <UploadImage ref='uploadRef' v-model='formData.{$value['columnName']}' :data=uoloadData :limit='1' :fileSize='5'
                                    :drag='true' :isShowTip='false' />
                            </el-form-item>
                        </el-col>
                        ";
                    }
                    if ($value['htmlType'] == "fileUpload") {

                        $col .= "
                        <el-col :span='12'>
                            <el-form-item :label-width='labelWidth' label='{$value['columnComment']}' prop='{$value['columnName']}'>
                                <UploadFile v-model='formData.{$value['columnName']}' :data=uoloadData />
                            </el-form-item>
                        </el-col>
                        ";
                    }
                    if ($value['htmlType'] == "editor") {
                        $col .= '
                           <el-col :span="24">
                               <el-form-item :label-width="labelWidth" label="' . $value['columnComment'] . '" prop="' . $value['columnName'] . '">' . '
                               ' . "   <RichText v-model='formData." . $value['columnName'] . "' :min-height='196'></RichText>
                               </el-form-item>
                           </el-col>";
                    }
                    if ($value['htmlType'] == "inputNumber") {
                        $col .= '
                           <el-col :span="12">
                               <el-form-item :label-width="labelWidth" label="' . $value['columnComment'] . '" prop="' . $value['columnName'] . '">' . '
                               ' . "   <el-input-number v-model='formData." . $value['columnName'] . "' controls-position='right' :min='1'></el-input-number>
                               </el-form-item>
                           </el-col>";
                    }
                    if ($value['htmlType'] == "map") {
                        $col .= "
                        <el-col :span='24'>
                        <el-form-item :label-width='labelWidth' label='{$value['columnComment']}' prop='{$value['columnName']}'>
                          <Map v-model='locationList' style='margin-top: 20px;'></Map>
                        </el-form-item>
                      </el-col>
                      ";
                    }
                    if ($value['htmlType'] == "switch") {
                        $col .= "
                        <el-col :span='12'>
                               <el-form-item :label-width='labelWidth' label='{$value['columnComment']}' prop='{$value['columnName']}'>
                                <el-switch
                                    v-model='formData.{$value['columnName']}'
                                    class='mt-2'
                                    inline-prompt
                                    :inactive-value=1
                                    :active-value=2
                                    style='--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949'
                                />
                            </el-form-item>
                        </el-col>
                      ";
                    }
                    if ($value['htmlType'] == "rate") {
                        $col .= "
                        <el-col :span='12'>
                               <el-form-item :label-width='labelWidth' label='{$value['columnComment']}' prop='{$value['columnName']}'>
                                 <el-rate style='padding-top: 6px!important;' v-model='formData.{$value['columnName']}' allow-half />
                            </el-form-item>
                        </el-col>
                      ";
                    }
                }
            }
        }

        return $col;
    }


    /**
     * 数组转换为模板字符串
     * @param array $arr 数组
     * @param array $service_fields 业务字段
     * @param int $type 模板字符类型 1:一维数组格式 2:验证器格式 3:列表条件查询 4:关联数组格式 
     */
    public static function toFormTempStr(array $arr, array $service_fields, int $type = 1)
    {
        $str = "";
        switch ($type) {
            case 1:
                $str = str_replace('##', "'", "[\n##" . implode("##,\n##", $arr) . "##\n]");
                break;
            case 2:
                foreach ($service_fields as $key => &$val) {
                    foreach ($arr as $key1 => &$val1) {
                        if ($key == $val1) {
                            $val1 .= "|{$val}";
                        }
                    }
                }
                $str = str_replace('##', "'", "[\n##" . implode("##=>'require',\n##", $arr) . "##=>##require##\n]");
                break;
            case 3:
                $str .= "\$con = Tool::getOptionalQuery(";
                foreach ($arr as $key => $val) {
                    if ($val[1]) {
                        $str .= self::getListConditionalQuery($val[0], $val[1]);
                    }
                };
                $str .= ");";
                break;
            case 4:
                foreach ($arr as $key => $val) {
                    $str .= "'{$key}' => '{$val}',\n";
                }
                $str = "[\n$str],";
                break;
            default:
                break;
        }
        return $str;
    }

    /**
     * 获取列表条件表达式查询对应模板字符串
     * @param string $column_name 字段名
     * @param string $ope 运算符
     */
    private static function getListConditionalQuery(string $column_name, string $ope): string
    {
        return [
            'LIKE' => self::geJsimpleExpTempStr($column_name, 'LIKE'),
            'BETWEEN' => self::geJsimpleExpTempStr($column_name, 'BETWEEN'),
            'EQ' => self::geJsimpleExpTempStr($column_name, '='),
            'LT' => self::geJsimpleExpTempStr($column_name, '<'),
            'LTE' => self::geJsimpleExpTempStr($column_name, '<='),
            'GTE' => self::geJsimpleExpTempStr($column_name, '>='),
            'GT' => self::geJsimpleExpTempStr($column_name, '>'),
            'NE' => self::geJsimpleExpTempStr($column_name, '!='),
        ][$ope];
    }

    /**
     * 获取简易表达式对应模板字符串
     * @param string $column_name 字段名
     * @param string $ope 运算符
     */
    private static function geJsimpleExpTempStr(string $column_name, string $ope): string
    {
        return "['{$column_name}','{$ope}'],";
    }

    /**
     * 获取导出模板字符串
     * @param array $fields 字段信息
     * @param array $table 表信息
     * @param array $init_fields 业务字段
     * @param string $type 导出类型: export_con：导出-控制器 | export_mod：导出-模型层 | temp : 下载模板
     */
    private static function getExportExcelTempStr(array $fields, array $table, array $init_fields, string $type): string
    {
        $module_name = $table['moduleName']; //模块名 例:News
        $function_name = $table['functionName']; //功能名 例:新闻
        $business_name = $table['businessName']; //业务名 例:news
        $class_name = $table['className']; //类名 例:News
        $init_fields_arr = [];
        $init_fields_text = [];
        $data_str = '';

        $img_field = false;
        foreach ($fields as $key => $val) {
            if ($val['htmlType'] == 'imageUpload') $img_field = $val['columnName'];
        }

        foreach ($init_fields as $key => $val) {
            $init_fields_arr[] = $key;
            $init_fields_text[] = $val;

            if ($key == $img_field) {
                $data_str .= "Excel::ExportImgFiled(\$val['$img_field']),\n";
            } else {
                $data_str .= "\$val['{$key}'],\n";
            }
        }
        $data_str = "[\n{$data_str}]"; //导出数据模板字段
        $init_fields_arr_str = self::toFormTempStr($init_fields_arr, $init_fields); //字段名(模板字符串)
        $init_fields_text_str = self::toFormTempStr($init_fields_text, $init_fields); //字段注释(模板字符串)
        switch ($type) {
            case 'export_con':
                $order_field = "'{$table['options']->SortField}'"; //排序字段
                $order_mode = "'{$table['options']->SortType}'"; //排序方式
                $order_field ?? $order_field = "'{$business_name}_update_time'";
                $order_mode ?? $order_mode = "'desc'";
                return "/**\n* 导出Excel\n*/
                    public function exportExcel(Request \$request)
                    {
                        \$params = \$request->param();
                        \$select = Model{$class_name}::field({$init_fields_arr_str})
                            ->order({$order_field}, $order_mode )
                            ->select();
                        return Model{$class_name}::exportExcel(\$select);
                    }";
            case 'export_mod':
                return "/**\n* 导出Excel\n*/
                public static function exportExcel(\$select)
                {
                    \$data = [{$init_fields_text_str}];
                    foreach (\$select as \$key => \$val) {
                        \$data[] = {$data_str};
                    }
                    \$excel = (new Excel())->exporTsheet(\$data);
                    \$excel->save('{$function_name}.xlsx');
                }";
            case 'temp':
                return "/**\n* 下载导入模板\n*/
                public function downloadTemplate(Request \$request)
                {
                    \$params = \$request->param();
                    \$data = array_values(Model{$class_name}::EXCELFIELD);
                    \$excel = (new Excel())->exporTsheet(\$data);
                    \$excel->save('{$function_name}导入模板.xlsx');
                }";
            default:
                break;
        }
    }

    /**
     * 获取有关文件上传的模板字符串
     * @param array $table 表信息
     * @param string $type 类型  img图片上传 file文件上传
     * @param string $is_multiple 是否为多应用类型 false => 单应用 true =>多应用 
     */
    private static function getFileUploadTempStr(array $table, string $type): string
    {
        $class_name = $table['className']; //类名 例:News

        return   [
            'img' =>
            "/**\n* 上传图片\n*/
        public function upload{$class_name}Img(Request \$request)
        {
            \$upload = new UploadFile('uploads', 'file');
            \$path = \$upload->putFile('{$table['className']}Img');

            return [
                'code' => 0,
                'data' => '/uploads/' . \$path,
                'msg' => '上传成功！'
            ];
        }",
            'file' =>
            "/**\n* 上传文件\n*/
            public function uploadFile(Request \$request): array
            {
                \$upload = new UploadFile('uploads', 'file');
                \$path = \$upload->putFile('{$table['className']}File');
                \$FileUrl = Env::get('自行替换.FileUrl');
                return [
                    'code' => 0,
                    'data' => \$path,
                    'url' => \$FileUrl,
                    'msg' => '上传成功！'
                ];
            }"
        ][$type];
    }

    /**
     * 获取导入模板字符串
     * @param array $fields 字段信息
     * @param array $table 表信息
     * @param array $init_fields 业务字段
     * @param string $type 导出类型: imp_con：导入-控制器 | imp_mod：导入-模型层 | imp_init : 导入初始化 | imp_fie : 导入/下载模板表头
     */
    private static function getImportExcelTempStr(array $fields, array $table, array $init_fields, string $type): string
    {
        $module_name = $table['moduleName']; //模块名 例:News
        $function_name = $table['functionName']; //功能名 例:新闻
        $business_name = $table['businessName']; //业务名 例:news
        $class_name = $table['className']; //类名 例:News

        $fields_val_allocation_str = ""; //字段值分配
        $add_fields_str = ""; //新增允许字段模板字符串
        foreach ($init_fields as $field => $name) {
            $fields_val_allocation_str .= "\${$field} = \$value['{$field}'];";
            $add_fields_str .= "'{$field}' => \${$field},\n";
        };
        $add_fields_str = "[\n$add_fields_str]";

        $init_fields_str = self::toFormTempStr($init_fields, $init_fields, 4);
        $init_fields_str = substr($init_fields_str, 0, strlen($init_fields_str) - 1);
        switch ($type) {
            case "imp_con":
                return "/**\n* 导入excel\n*/
                public function importExcel(Request \$request)
                {
                    \$file = new UploadFile('uploads', 'fileExt:xlsx');
                    \$file->putFile('{$business_name}');
               
                    \$msg = Model{$class_name}::importExcel(\$file);
                    return [
                        'code' => 0,
                        'msg' => \$msg
                    ];
                }";
            case "imp_mod":
                return "/**\n* 导入excel\n*/
                public static function importExcel(\$file)
                {
                    \$msg = [];

                    Db::startTrans();
                    try {
                        \$excel = new Excel(\$file);
                        \$data = \$excel->parseExcel(
                            Tool::getExcelRule(self::EXCELFIELD), 
                        [
                            'titleLine' => [1]
                        ]);
                        if (!\$data)  throwErrorMsg('excel无数据', 1);
                        \$msg = [];
                        foreach (\$data as \$line => \$value) {
                            try {
                                \$model = self::importExcelInit(\$value);
                                \$msg[] = \"{\$line} <span style='color:#27af49'>新增成功!</span><br>\";
                            } catch (\Throwable \$th) {
                                \$msg[] = \"{\$line} <span style='color:red'>{\$th->getMessage()}</span><br>\";
                            }
                        }
                        Db::commit();
                        return implode(', ', \$msg);
                    } catch (\Throwable \$th) {
                        Db::rollback();
                        throw \$th;
                    }
                }";
            case "imp_init":
                return "/**\n* 导入excel初始化\n*/
                public static function importExcelInit(\$value)
                {
                    {$fields_val_allocation_str}
                    return self::create({$add_fields_str});
                }";
            case "imp_fie":
                return "
                // excel导入/下载模板表头
                public const EXCELFIELD = {$init_fields_str};
                ";
        };
    }
}
