The middle and background management system solution quasar-sika-design-admin makes the world free from hard-to-write codes

quasar-sika-design-admin

English | Simplified Chinese

<h1 align="center">Quasar Sika Design Admin</h1> <div align="center"> An out-of-box UI solution for enterprise applications as a Vue boilerplate. based on <a href="http://www.quasarchs.com/" target="_blank"> Quasar </a> </div>

<div align="center">

License Release

</div>

Project Introduction

  • quasar-sika-design-admin is a set of enterprise-level mid- and back-end management system solutions, Quasar Sika Design Admin is an enterprise-level mid- and back-end front-end/design solution, and mid- and back-end management templates. We adhere to the design values ​​of Ant Design and are committed to On the basis of design specifications and basic components, continue to build upwards, extract typical templates/business components/supporting design resources, and further improve the experience of "users" and "designers" in the process of enterprise-level mid- and back-end product design and development

The original intention of the project

Starting from Sika Design, not only Sika Design, every detail is the ultimate experience vision: open source changes the world, Sika Design Admin makes the world without difficult code to write.

Program features

front end

  • Elegant and beautiful: carefully designed based on the Ant Design system
  • Common design patterns: Open source changes the world, Sika Design makes the world free from hard-to-write code
  • The latest technology stack: developed using front-end cutting-edge technologies such as Quasar&Vue&echarts
  • Responsive: Designed for different screen sizes
  • Theme: Configurable themes to meet diverse brand demands
  • Best Practices: Good engineering practices help you consistently produce high-quality code

rear end

  • Elegant, concise, normative without losing individuality
  • abstract base component
  • Constraint code specification
  • Featured domain-driven design practice [context object context+executor executor]
  • Complete code generator - zero development of new module base functions

organizational structure

- quasar-sika-design-admin
  - quasar-sika-design // 前端-基于vue+quasar构建
  - quasar-sika-design-server // 后端服务-基于springboot+mybatis
    - doc // 文档说明
      - sql // sql脚本
    - quasar-sika-design-server-common // 基础公共模块;包括业务的constant+dto+query以及baseDTO+baseSrvice等等
    - quasar-sika-design-server-core // 核心业务模块;包括业务的service,核心领域实现逻辑等等
    - quasar-sika-design-server-ataaccess // 数据库访问层
    - quasar-sika-design-server-generator // 代码生成器模块【无须开发】
    - quasar-sika-design-server-web // controller层
    - sika-code-cor // 核心公共组件,包括且不限于缓存组件、代码生成器组件、公共组件、数据访问、分布式锁、脚手架规范
      - cache // 缓存组件
      - code-generator // 代码生成器组件
      - common // 公共组件
      - databasse // 数据库访问组件
      - hutool-starter // hutool基础集成
      - lock // 分布式组件
      - standard-footer // 标准脚手架组件

Technical selection

Backend technology

Technology Official website Remark
Spring Framework http://projects.spring.io/spring-framework/ container
spring-boot-dependencies https://spring.io/projects/spring-boot/ No explanation
Apache Shiro http://shiro.apache.org/ security framework
MyBatis http://www.mybatis.org/mybatis-3/zh/index.html ORM framework
MyBatisPlus https://mp.baomidou.com/ ORM Enhancement Framework
Mybatis-plus-boot-starter https://mp.baomidou.com/ ORM Enhancement Framework
Mybatis-Plus-Generator https://baomidou.gitee.io/mybatis-plus-doc/#/generate-code/ ORM Enhancement Framework
Hikari CP https://github.com/brettwooldridge/HikariCP/ database connection pool
ShardingSphere https://shardingsphere.apache.org/ Sub-library and sub-table components
Redis https://redis.io/ Distributed cache database
commons-collections http://commons.apache.org/proper/commons-collections/ Collection Tool Components
Log4J http://logging.apache.org/log4j/1.2/ log component
FastJson https://mvnrepository.com/artifact/com.alibaba/fastjson/ JSON serialization and deserialization components
Lombok https://www.projectlombok.org/ Simplify JAVA code components
Hutool http://hutool.mydoc.io/ Tool components in line with Chinese habits
MapStruct http://mapstruct.org/ Entity Conversion Component

Front-end technology

Technology Official website Remark
View https://cn.vuejs.org/ Progressive JavaScript Framework
Quasar http://www.quasarchs.com/ Front-end UI framework based on Vue
Echarts https://echarts.apache.org/zh/index.html/ JavaScript-based open source visual chart library
Lodashi https://www.lodashjs.com/ Consistent, modular, high-performance JavaScript utility library

Overview

Quasar Sika Design_Admin based on Quasar implementation

PC-side example




mobile side example


Server code example

Controller is generated by code generator

package com.quasar.sika.design.server.business.menu.controller;
import java.util.List;
import com.sika.code.result.Result;
import com.sika.code.standard.base.controller.BaseStandardController;
import com.quasar.sika.design.server.business.menu.service.MenuService;
import com.quasar.sika.design.server.business.menu.pojo.dto.MenuDTO;
import com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 菜单权限表 前端控制器
 * </p>
 *
 * @author daiqi
 * @since 2021-01-07 23:35:13
 */
@RestController(value = "menuController")
@RequestMapping("menu")
public class MenuController extends BaseStandardController {
    @Autowired
    private MenuService menuService;

    @RequestMapping(value = "save")
    public Result save(@RequestBody MenuDTO menuDto) {
        return super.success(menuService.save(menuDto));
    }

    @RequestMapping(value = "save_batch")
    public Result saveBatch(@RequestBody List<MenuDTO> menuDtos) {
        return super.success(menuService.saveForBatch(menuDtos));
    }

    @RequestMapping(value = "update_by_id")
    public Result updateById(@RequestBody MenuDTO menuDto) {
        return super.success(menuService.updateById(menuDto));
    }

    @RequestMapping(value = "page")
    public Result page(@RequestBody MenuQuery menuQuery) {
        return super.success(menuService.page(menuQuery));
    }

    @RequestMapping(value = "find")
    public Result find(@RequestBody MenuQuery menuQuery) {
        return super.success(menuService.find(menuQuery));
    }

    @RequestMapping(value = "list")
    public Result list(@RequestBody MenuQuery menuQuery) {
        return super.success(menuService.list(menuQuery));
    }
}

Service is generated by code generator

package com.quasar.sika.design.server.business.menu.service;
import com.quasar.sika.design.server.business.menu.pojo.dto.MenuDTO;
import com.sika.code.standard.base.service.BaseStandardService;
import java.util.List;
/**
 * <p>
 * 菜单权限表 服务类
 * </p>
 *
 * @author daiqi
 * @since 2021-01-07 23:35:09
 */
public interface MenuService extends BaseStandardService<MenuDTO> {

}

ServiceImpl is generated by the code generator

package com.quasar.sika.design.server.business.menu.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.quasar.sika.design.server.business.menu.convert.MenuConvert;
import com.quasar.sika.design.server.business.menu.entity.MenuEntity;
import com.quasar.sika.design.server.business.menu.mapper.MenuMapper;
import com.quasar.sika.design.server.business.menu.pojo.dto.MenuDTO;
import com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery;
import com.quasar.sika.design.server.business.menu.service.MenuService;
import com.quasar.sika.design.server.business.rolemenu.service.RoleMenuService;
import com.sika.code.standard.base.convert.BaseConvert;
import com.sika.code.standard.base.service.impl.BaseStandardServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author daiqi
 * @since 2021-01-07 23:35:10
 */
@Service(value = "menuService")
public class MenuServiceImpl extends BaseStandardServiceImpl<MenuMapper, MenuEntity, MenuDTO> implements MenuService {
    @Autowired
    private MenuMapper menuMapper;

    @Override
    protected BaseConvert<MenuEntity, MenuDTO> convert() {
        return MenuConvert.INSTANCE;
    }
}

Mapper is generated by code generator

package com.quasar.sika.design.server.business.menu.mapper;

import com.quasar.sika.design.server.business.menu.entity.MenuEntity;
import org.springframework.stereotype.Repository;
import com.sika.code.standard.base.basemapper.BaseStandardMapper;

/**
 * <p>
 * 菜单权限表 Mapper 接口
 * </p>
 *
 * @author daiqi
 * @since 2021-01-07 23:35:08
 */
@Repository
public interface MenuMapper extends BaseStandardMapper<MenuEntity> {

}

Xml is generated by code generator

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.quasar.sika.design.server.business.menu.mapper.MenuMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="ResultMap" type="com.quasar.sika.design.server.business.menu.entity.MenuEntity">
        <result column="id" property="id" />
        <result column="create_by" property="createBy" />
        <result column="update_by" property="updateBy" />
        <result column="create_date" property="createDate" />
        <result column="update_date" property="updateDate" />
        <result column="version" property="version" />
        <result column="available" property="available" />
        <result column="is_deleted" property="isDeleted" />
        <result column="remark" property="remark" />
        <result column="menu_name" property="menuName" />
        <result column="parent_id" property="parentId" />
        <result column="order_num" property="orderNum" />
        <result column="url" property="url" />
        <result column="target" property="target" />
        <result column="menu_type" property="menuType" />
        <result column="visible" property="visible" />
        <result column="perms" property="perms" />
        <result column="icon" property="icon" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="columnList">
        id, create_by, update_by, create_date, update_date, version, available, is_deleted, remark, menu_name, parent_id, order_num, url, target, menu_type, visible, perms, icon
    </sql>

    <!-- 根据查询条件获取列表信息 -->
    <select id="listByQuery" resultMap="ResultMap" parameterType="com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery" >
        SELECT <include refid="columnList" />
        FROM sika_menu
        <where>
            is_deleted = 0
            <include refid="query_sql" />
        </where>
    </select>

    <!-- 根据查询条件获取Id列表信息 -->
    <select id="listIdByQuery" resultType="java.lang.Long" parameterType="com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery" >
        SELECT id
        FROM sika_menu
        <where>
            is_deleted = 0
            <include refid="query_sql" />
        </where>
    </select>

    <!-- 根据查询条件获取实体信息 -->
    <select id="findByQuery" resultMap="ResultMap" parameterType="com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery" >
        SELECT <include refid="columnList" />
        FROM sika_menu
        <where>
            is_deleted = 0
            <include refid="query_sql" />
        </where>
        LIMIT 1
    </select>

    <!-- 根据查询条件获取表id -->
    <select id="findIdByQuery" resultType="java.lang.Long" parameterType="com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery" >
        SELECT id
        FROM sika_menu
        <where>
            is_deleted = 0
            <include refid="query_sql" />
        </where>
        LIMIT 1
    </select>

    <!-- 根据查询条件获取分页信息 -->
    <select id="pageByQuery" resultMap="ResultMap" parameterType="com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery" >
        SELECT <include refid="columnList" />
        FROM sika_menu
        <where>
            is_deleted = 0
            <include refid="query_sql" />
        </where>
        <include refid="order_by_sql"/>
    </select>

    <!-- 根据查询条件获取总数量信息 -->
    <select id="totalCountByQuery" resultType="Integer" parameterType="com.quasar.sika.design.server.business.menu.pojo.query.MenuQuery" >
        SELECT count(*)
        FROM sika_menu
        <where>
            is_deleted = 0
            <include refid="query_sql" />
        </where>
    </select>

    <!-- 根据查询条件SQL -->
    <sql id="query_sql" >
        <if test="query.id != null">AND id = #{query.id}</if>
        <if test="query.menuId != null">AND id = #{query.menuId}</if>
        <if test="query.menuName != null">AND menu_name = #{query.menuName}</if>
        <if test="query.parentId != null">AND parent_id = #{query.parentId}</if>
        <if test="query.orderNum != null">AND order_num = #{query.orderNum}</if>
        <if test="query.url != null">AND url = #{query.url}</if>
        <if test="query.target != null">AND target = #{query.target}</if>
        <if test="query.menuType != null">AND menu_type = #{query.menuType}</if>
        <if test="query.visible != null">AND visible = #{query.visible}</if>
        <if test="query.perms != null">AND perms = #{query.perms}</if>
        <if test="query.icon != null">AND icon = #{query.icon}</if>
        <if test="query.ids != null and query.ids.size() > 0">
            AND id in
            <foreach item="item" collection="query.ids" separator="," open="(" close=")" index="">
                #{item}
            </foreach>
        </if>
    </sql>

    <!-- 排序的sql -->
    <sql id="order_by_sql">
        <if test="query.sortColumn != null and query.sortType != null" >
            ORDER BY
            <include refid="order_by_column_sql"/>
            <include refid="order_by_type_sql"/>
        </if>
    </sql>

    <!-- 排序列名的sql -->
    <sql id="order_by_column_sql">
        <choose>
            <when test="query.sortColumn == 'menuId'">
                id
            </when>
            <otherwise>
                id
            </otherwise>
        </choose>
    </sql>

    <!-- 排序类型的sql -->
    <sql id="order_by_type_sql">
        <choose>
            <when test="query.sortType == 'DESC'">
                DESC
            </when>
            <otherwise>
                ASC
            </otherwise>
        </choose>
    </sql>
</mapper>

Context [domain context object]

package com.quasar.sika.design.server.common.auth.context;

import com.quasar.sika.design.server.common.auth.executor.AuthRegisterRequestExecutor;
import com.quasar.sika.design.server.common.auth.pojo.request.AuthRegisterRequest;
import com.quasar.sika.design.server.common.captcha.pojo.request.CaptchaCheckRequest;
import com.quasar.sika.design.server.common.mail.context.CheckMailCodeContext;
import com.quasar.sika.design.server.common.mail.pojo.request.CheckMailRequest;
import com.quasar.sika.design.server.common.shiro.util.SHA256Util;
import com.sika.code.standard.base.pojo.context.BaseStandardContext;
import com.sika.code.standard.base.pojo.executor.BaseStandardExecutor;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @author daiqi
 * @create 2021-01-09 18:02
 */
@Data
@Accessors(chain = true)
public class AuthRegisterContext extends BaseStandardContext {
    private AuthRegisterRequest registerRequest;
    private CheckMailRequest checkMailRequest;
    protected CaptchaCheckRequest captchaCheckRequest;
    private CheckMailCodeContext checkMailCodeContext;
    private Boolean bindOauthUser;

    @Override
    public void initCustomer() {
        checkMailCodeContext = new CheckMailCodeContext().setRequest(checkMailRequest);
        registerRequest.setPassword(SHA256Util.sha256(registerRequest));
    }

    @Override
    protected Class<? extends BaseStandardExecutor> buildExecutorClass() {
        return AuthRegisterRequestExecutor.class;
    }
}

Executor domain executor object [by domain]

package com.quasar.sika.design.server.common.auth.executor;

import cn.hutool.core.util.BooleanUtil;
import com.quasar.sika.design.server.common.auth.context.AuthRegisterContext;
import com.quasar.sika.design.server.common.auth.domain.AuthDomain;
import com.quasar.sika.design.server.common.auth.pojo.request.AuthLoginRequest;
import com.quasar.sika.design.server.common.auth.pojo.request.AuthRegisterRequest;
import com.quasar.sika.design.server.common.auth.pojo.response.AuthResponse;
import com.sika.code.basic.pojo.dto.ServiceResult;
import com.sika.code.exception.BusinessException;
import com.sika.code.standard.base.pojo.executor.BaseStandardExecutor;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @author daiqi
 * @create 2021-01-09 18:02
 */
@Data
@Accessors(chain = true)
public class AuthRegisterRequestExecutor extends BaseStandardExecutor<AuthRegisterContext> implements AuthDomain {
    @Override
    protected void executeBefore() {
        verify();
    }

    protected void verify() {
        // 图片验证码校验
        captchaService().checkCaptchaVerifyCode(context.getCaptchaCheckRequest());
        // 邮箱验证码校验
        executorManager().execute(context.getCheckMailCodeContext());
        // 校验用户名
        AuthRegisterRequest registerRequest = context.getRegisterRequest();
        authService().checkRegisterUsername(registerRequest);
        // 校验邮箱
        authService().checkRegisterEmail(registerRequest);
        // 校验手机号
        authService().checkRegisterPhone(registerRequest);
    }

    @Override
    protected ServiceResult doExecute() {
        AuthRegisterRequest registerRequest = context.getRegisterRequest();
        boolean saveSuccess = userService().save(registerRequest);
        if (BooleanUtil.isFalse(saveSuccess)) {
            throw new BusinessException("保存失败,请校验注册参数");
        }
        return ServiceResult.newInstanceOfSucResult(AuthResponse.success(registerRequest));
    }

    @Override
    protected void executeAfter() {
        // 自动登录
        AuthRegisterRequest registerRequest = context.getRegisterRequest();
        AuthLoginRequest request = new AuthLoginRequest(registerRequest.getUsername(), registerRequest.getPassword());
        request.setEncryptedPassword(true);
        if (BooleanUtil.isTrue(context.getBindOauthUser())) {
            authService().bindOauthUser(request);
        } else {
            authService().login(request);
        }
        // 移除缓存
        captchaService().removeCaptchaVerifyCode(context.getCaptchaCheckRequest());
        mailService().removeMailCode(context.getCheckMailRequest());
    }
}

Front-end environment and dependencies

  • node
  • yarn
  • webpack
  • sling
  • @vue/cli ~3
  • Quasar - Quasar Of Vue implementation

Please note that we strongly recommend using the Yarn package management tool for this project, so that the exact same dependency version (yarn.lock) is loaded by the demo site of this project. Since we do not have mandatory version control for dependencies, when using non-yarn package management to import, there may be problems caused by the introduction of a new version of the library that Pro depends on has been upgraded. The author may have problems using this project as the base project due to the time issue that cannot be checked in time.

Project download and run

  • Pull project code
git clone https://github.com/dq-open-cloud/quasar-sika-design.git
cd quasar-sika-design
  • Install dependencies
yarn install
  • Running in development mode
quasar dev
  • Compile the project
quasar build
  • Lints and fixes files
yarn run lint

Documentation to be improved

Startup steps

  • Find QuasarSikaDesignServerApplication to run directly
  • The front-end quasar-dev can start and run

other instructions

  • About Issue Feedback (Important! Important! Important!) Please read this content before opening an Issue : Issue / PR Writing Suggestions

  • The quasar-cli used by the project , please make sure that the quasar-cli you are using is a new version, and you have studied the official documentation of cli

  • Turn off Eslint (not recommended) Remove package.jsonthe eslintConfigentire node code in , and change vue.config.jsthe lintOnSavevaluefalse

  • For production environment, please use releaseversion code, any problems with master code need to be solved by yourself

  • MysqlThe environment provided by the backend Redisbelongs to the online testing environment. Please do not add or delete fields at will during the internal testing phase.

Browser Compatible

  • Chrome for Android >= 87
  • Firefox for Android >= 83
  • Android >= 81
  • Chrome >= 77
  • Edge >= 84
  • Firefox >= 74
  • iOS >= 10.3
  • Opera> = 68
  • Safari >= 11
<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" /></br>IE / Edge <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" /></br>Firefox <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" /></br>Chrome <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" /></br>Safari <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" /></br>Opera
IE10, Edge last 2 versions last 2 versions last 2 versions last 2 versions

Contributors

This project exists thanks to all the people who contribute. <a href="https://github.com/vueComponent/ant-design-vue-pro/graphs/contributors"><img src="https://opencollective.com/ant-design-pro-vue/contributors.svg?width=890&button=false" /></a>

Customize the configuration

See Configuring quasar.conf.js.

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324135198&siteId=291194637