Zhiqim Manager(知启蒙管理台)是知启蒙框架中最核心的基础组件,大部分后台组件和产品都依赖该组件。因为管理台提供了核心的系统配置、菜单、操作员、部门、角色等权限功能,以及6种皮肤样式可供选择

森中灵 最后提交于3月前 修复切换frame模式时未情况includeUrl
ZmrBootstrap.java11KB
/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_components/zhiqim_manager.htm
 *
 * Zhiqim Manager is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.manager;

import java.lang.management.ManagementFactory;
import java.util.List;

import org.zhiqim.httpd.context.ZmlBootstrap;
import org.zhiqim.kernel.Z;
import org.zhiqim.kernel.config.ItemType;
import org.zhiqim.kernel.model.codes.RSA;
import org.zhiqim.kernel.model.objects.SS;
import org.zhiqim.kernel.schedule.Day;
import org.zhiqim.kernel.schedule.Scheduler;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Bytes;
import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Randoms;
import org.zhiqim.kernel.util.Resources;
import org.zhiqim.kernel.util.Sqls;
import org.zhiqim.kernel.util.Streams;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.manager.dao.ZmrParamDao;
import org.zhiqim.manager.dbo.ZmrAvatar;
import org.zhiqim.manager.dbo.ZmrDept;
import org.zhiqim.manager.dbo.ZmrDeptType;
import org.zhiqim.manager.dbo.ZmrMenu;
import org.zhiqim.manager.dbo.ZmrOperator;
import org.zhiqim.manager.dbo.ZmrRole;
import org.zhiqim.orm.ORM;

/**
 * 初始化引导类
 *
 * @version v1.0.0 @author zouzhigang 2015-5-28 新建与整理
 */
public class ZmrBootstrap extends ZmlBootstrap implements ZmrConstants
{
    private static ZmrPassworder passworder;    //管理台密码器支持配置
    private static String pidName;              //管理台进程名(MAC下获取比较慢,所以在启动时加载)
    
    /*******************************************************************************/
    //初始化
    /*******************************************************************************/
    
    @Override
    protected void initBefore() throws Exception
    {
        context.setAttribute(ZmrBootstrap.class, this);
        pidName = ManagementFactory.getRuntimeMXBean().getName();
        
        String zmrPassworder = context.getTopAttributeString(ZMR_PASSWORDER, ZMR_PASSWORDER_DEFAULT);
        Object instance = Z.cls().newInstance(zmrPassworder);
        Asserts.asserts(instance instanceof ZmrPassworder, "上下文环境[%s]的密码器配置[zmr.passworder]不是ZmrPassworder或子类", context.getContextName());
        
        passworder = (ZmrPassworder)instance;
    }
    
    @Override
    protected void initAfter() throws Exception
    {
        initMenu();
        initAvatar();
        initParam();
        initDept();
        initRole();
        initOperator();
        
        //设置主题默认值
        context.setAttribute(ZMR_THEME_INDEX, ZmrParamDao.getThemeIndex());
        context.setAttribute(ZMR_THEME_MAIN, ZmrParamDao.getThemeMain());
        
        //增加删除日志任务
        Scheduler scheduler = Z.glb().getc(Scheduler.class);
        scheduler.addTask(new Day(new ZmrTask(), 5, 5, 5));
    }
    
    /** 初始化菜单 */
    private void initMenu() throws Exception
    {
        if (ORM.table().count(ZmrMenu.class) > 0)
            return;
        
        String path = context.getAttributeString(ZMR_MENU_SQL);
        if (Validates.isEmpty(path))
            return;
        
        String sqls = context.getResourceString(path);
        if (sqls == null)
            return;
        
        List<String> sqlList = Sqls.toSqlList(sqls);
        if (sqlList.isEmpty())
            return;
        
        ORM.sql().execute(sqlList);
    }
    
    /** 初始化参数 */
    private void initParam() throws Exception
    {
        ZmrParamDao.addGroupIfNotExists(ZMR_NAME, 0, ItemType.PUBLIC, "管理台参数");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_THEME_INDEX,             "00_default",                  1,  ItemType.PROTECTED, "首页主题(在首页主题中修改)");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_THEME_MAIN,              "00_default",                  2,  ItemType.PROTECTED, "主页主题(在主页主题中修改)");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_THEME_FRAME,             "false",                       3,  ItemType.PUBLIC,    "主题是否使用iframe风格");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_HAS_MANAGE_LOGIN,        "false",                       4,  ItemType.PUBLIC,    "是否使用管理页登录退出功能");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_HAS_VERIFICATION_CODE,   "false",                       5,  ItemType.PUBLIC,    "是否需要验证码");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_HAS_REMEMBER_CODE,       "true",                        6,  ItemType.PUBLIC,    "是否显示记住账号");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_HAS_REMEMBER_PASS,       "false",                       7,  ItemType.PUBLIC,    "是否显示记住密码");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_CHK_CLOSE_SUPER_ADMIN,   "true",                        8,  ItemType.PUBLIC,    "是否任务检查需要关闭超级管理员");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_REMAIN_LOG_DAY,          "180",                         9,  ItemType.PUBLIC,    "保留操作员日志天数");
        
        if (!ZmrParamDao.hasParam(ZMR_NAME, ZMR_PUBLIC_KEY) || !ZmrParamDao.hasParam(ZMR_NAME, ZMR_PRIVATE_KEY))
        {//密钥没成对
            SS keys = RSA.buildKeyPair();
            
            ZmrParamDao.replaceParam(ZMR_NAME, ZMR_PUBLIC_KEY,              keys.key(),                       10, ItemType.PRIVATE,   "随机生成的公钥");
            ZmrParamDao.replaceParam(ZMR_NAME, ZMR_PRIVATE_KEY,             keys.value(),                     11, ItemType.PRIVATE,   "随机生成的私钥");
        }
        
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_MAIN_URL,                "",                            12, ItemType.PUBLIC,    "指定登录之后的主页地址,为空取标准主页地址");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_CDN_PATH,                "",                            13, ItemType.PUBLIC,    "如果CDN路径不为空,JS文件优先取CDN路径");
        ZmrParamDao.addParamIfNotExists(ZMR_NAME, ZMR_OPERATOR_DEPT_ALL_RULE,  "true",                        14, ItemType.PUBLIC,    "操作员权限是否继承上级部门权限");
    }

    /** 初始化头像 */
    private void initAvatar() throws Exception
    {
        if (ORM.table().count(ZmrAvatar.class) > 0)
            return;
        
        long avatarId = _ID_13_;
        List<String> avatarNameList = Resources.getResourceNameList(ZmrBootstrap.class, AVATAR_PREFIX);
        for (String avatarName : avatarNameList)
        {
            byte[] data = Streams.getBytesClassPath(ZmrBootstrap.class, AVATAR_PREFIX + avatarName);
            
            byte[]  bytes50 = Bytes.resizePNG(data, 50, 50);
            byte[]  bytes100 = Bytes.resizePNG(data, 100, 100);
            byte[]  bytes150 = Bytes.resizePNG(data, 150, 150);
            
            ZmrAvatar avatar = new ZmrAvatar();
            avatar.setAvatarId(avatarId++);
            avatar.setAvatarType(0);
            avatar.setAvatarTime(System.currentTimeMillis());
            avatar.setAvatar50(bytes50);
            avatar.setAvatar100(bytes100);
            avatar.setAvatar150(bytes150);
            
            ORM.table().insert(avatar);
        }
    }
    
    /** 初始化部门 */
    private void initDept() throws Exception
    {
        if (ORM.table().count(ZmrDept.class) > 0)
            return;
        
        //初始化部门类型
        ZmrDeptType type = new ZmrDeptType();
        type.setDeptType(_ID_13_);
        type.setDeptTypeName("通用");
        type.setDeptTypeValid(true);
        type.setDeptTypeSeq(0);
        type.setDeptTypeSys(true);
        
        ORM.table().insert(type);
        
        //初始化根部门
        ZmrDept dept = new ZmrDept();
        dept.setParentId(0);
        dept.setDeptId(_ID_13_);
        dept.setDeptName("湖南知启蒙科技创业中心");
        dept.setDeptValid(true);
        dept.setDeptLevel(0);
        dept.setDeptType(_ID_13_);
        dept.setDeptParentAll("0");
        
        ORM.table().insert(dept);
    }
    
    /** 初始化管理员角色 */
    private void initRole() throws Exception
    {
        if (ORM.table().count(ZmrRole.class) > 0)
            return;
        
        ZmrRole role = new ZmrRole();
        role.setRoleId(_ID_13_);
        role.setRoleName("管理员");
        role.setRoleValid(true);
        role.setRoleSys(true);
        role.setRoleSeq(0);
        
        ORM.table().insert(role);
    }
    
    /** 初始操作员,使用操作员独立数据库 */
    private void initOperator() throws Exception
    {
        int count = ORM.table().count(ZmrOperator.class);
        if (count > 0)
            return;
        
        //初始化系统管理员账号
        ZmrOperator zhiqim = new ZmrOperator();
        zhiqim.setOperatorCode(Z_NAME);
        zhiqim.setOperatorPassSalt(Randoms.lettersDigitsSecure(64));
        zhiqim.setOperatorPass(passworder.encode(Z_NAME, ZMR_PASSWORD, zhiqim.getOperatorPassSalt()));
        zhiqim.setOperatorValid(true);
        zhiqim.setOperatorType(0);
        zhiqim.setOperatorName("系统管理员");
        zhiqim.setOperatorAvatar(_ID_13_);
        zhiqim.setOperatorCreated(Sqls.nowTimestamp());
        zhiqim.setOperatorModified(zhiqim.getOperatorCreated());
        
        ORM.table().insert(zhiqim);
        
        //初始化系统账号
        ZmrOperator system = new ZmrOperator();
        system.setOperatorCode(SYSTEM_OPERATOR_CODE);
        system.setOperatorPassSalt(Randoms.lettersDigits(64));
        system.setOperatorPass(passworder.encode(SYSTEM_OPERATOR_CODE, Randoms.letters(4) + Randoms.symbol(1) + Randoms.digits(3), system.getOperatorPassSalt()));
        system.setOperatorValid(true);
        system.setOperatorType(2);
        system.setOperatorName(SYSTEM_OPERATOR_CODE);
        system.setOperatorAvatar(_ID_13_ + Ints.toInt(Randoms.digits(1)));
        system.setOperatorCreated(zhiqim.getOperatorCreated());
        system.setOperatorModified(zhiqim.getOperatorCreated());
        
        ORM.table().insert(system);
    }
    
    /*******************************************************************************/
    //获取管理台密码器&进程名
    /*******************************************************************************/
    
    /** 获取密码器 */
    public static ZmrPassworder getPassworder()
    {
        return passworder;
    }
    
    /** 获取进程名 */
    public static String getPidName()
    {
        return pidName;
    }
}