Quasar Sika Design Admin

An out-of-box UI solution for enterprise applications as a Vue boilerplate. based on Quasar

  • Preview: quasar.admin.sikacode.com/
  • Github
  • Gitee
  • Communication QQ group: 327424532
  • Wechat official account: Sikacode open source community
  • Home page: To be perfected
  • Documentation: To be completed
  • Update log: To be improved
  • Common Problems: To be improved

Project introduction

  • Quasar – Sika – Design-Admin is a set of enterprise level middle back end management system solution,Quasar Sika Design Admin is an enterprise level middle back end front-end/design solution, middle back end management template, we uphold the design values of Ant Design, On the basis of design specifications and basic components, we continue to build up, extract typical templates/business components/supporting design resources, and further improve the experience of “users” and “designers” in the design and development process of enterprise-level background products

Project purpose

From Sika Design and beyond, every detail is the ultimate experience vision: Open source changes the world, Sika Design Admin makes the world without hard code.

Project characteristics

The front end

  • Elegant and beautiful: Carefully designed based on Ant Design system
  • Common Design patterns: Open source changes the world, Sika Design makes the world easy to write code
  • Latest technology stack: Using Quasar&Vue& Echarts and other cutting-edge technology development
  • Responsive: Designed for different screen sizes
  • Theme: configurable theme to meet diversified brand demands
  • Best Practices: Good engineering practices help you consistently produce high-quality code

The back-end

  • Elegant, concise, standard without losing personality
  • Abstract base component
  • Constraint code specification
  • Characteristic Domain-driven design practices context+ Executor
  • Complete code generator – new module base function zero development

The structure of the organization

- Quasar -sika-design-admin - Quasar -sika- Design // Front-end - Build based on VUE + QUASar - Quasar - Sika -design-server // Backend service - based on Springboot +mybatis -doc // documentation - SQL // SQL script - Quasar-sika-design-server-common // basic public module; Including constant+ DTO+ Query and baseDTO+baseSrvice, etc. - Quasar-sika-design-server-core // core business module; Including business services, Core domain implementation logic etc. - Quasar - Sika - Design -server- ataAccess // database access layer - Quasar - Sika - Design -server- Generator // code generator module Quasar-sika-design-server-web // Controller layer -Sika-code-cor // Core common Components, Includes but is not limited to cache components, code generator components, common components, data access, distributed locks, scaffolding specifications - cache // Cache components - code-generator // Code generator components - common // Common components - databasse // Database access component - Hutool -starter // Hutool basic integration - Lock // distributed component - standard-footer // standard scaffolding componentCopy the code

Technology selection

The back-end technology

technology

website

note

Spring Framework

The projects. Spring. IO/spring – fram…

The container

spring-boot-dependencies

Spring. IO/projects/sp…

Don’t explain

Apache Shiro

shiro.apache.org/

Security framework

MyBatis

www.mybatis.org/mybatis-3/z…

ORM framework

MyBatisPlus

mp.baomidou.com/

ORM enhancement framework

Mybatis-plus-boot-starter

mp.baomidou.com/

ORM enhancement framework

Mybatis-Plus-Generator

Baomidou. Gitee. IO/mybatis – plu…

ORM enhancement framework

HikariCP

Github.com/brettwooldr…

Database connection pool

ShardingSphere

shardingsphere.apache.org/

Sub-library sub-table components

Redis

redis.io/

Distributed cache database

commons-collections

Commons.apache.org/proper/comm…

Collection tools component

Log4J

logging.apache.org/log4j/1.2/

The logging component

FastJson

Mvnrepository.com/artifact/co…

JSON serialization and deserialization components

Lombok

www.projectlombok.org/

Simplified JAVA code components

Hutool

hutool.mydoc.io/

Tool components in line with the habits of the people

MapStruct

mapstruct.org/

Entity transformation component

The front-end technology

technology

website

note

Vue

cn.vuejs.org/

Progressive JavaScript framework

Quasar

www.quasarchs.com/

Front-end UI framework based on Vue

Echarts

Echarts.apache.org/zh/index.ht…

Open source visual chart library based on JavaScript

Lodashi

www.lodashjs.com/

A consistent, modular, high-performance JavaScript utility library

Overview

Quasar Sika Design_Admin Based on the Quasar implementation

PC sample

The mobile end sample

Server-side code examples

The Controller is generated by the 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> ** @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)); }}Copy the code

The Service is generated by the 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> ** @author daiqi * @since 2021-01-07 23:35:09 */ Public Interface MenuService extends BaseStandardService<MenuDTO> { }Copy the code

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> ** @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; }}Copy the code

The Mapper is generated by the 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> ** @author daiqi * @since 2021-01-07 23:35:08 */ @repository public interface MenuMapper extends BaseStandardMapper<MenuEntity> { }Copy the code

The Xml is generated by the code generator

<? The 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"> <! , general query mapping results - - > < resultMap id = "resultMap" type = "com. Quasar. Sika. Design. The server business. The menu. The entity. The MenuEntity" > < the 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> <! <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> <! <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 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>Copy the code

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; }}Copy the code

Executor Domain Executor objects

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 () {/ / image authentication code check captchaService () checkCaptchaVerifyCode (context) getCaptchaCheckRequest ()); / / email verification code check executorManager (). The execute (context) getCheckMailCodeContext ()); / / check username AuthRegisterRequest registerRequest = context. GetRegisterRequest (); authService().checkRegisterUsername(registerRequest); // Check the mailbox authService().checkregisterEmail (registerRequest); // Check phone number authService().checkRegisterPhone(registerRequest); } @Override protected ServiceResult doExecute() { AuthRegisterRequest registerRequest = context.getRegisterRequest(); boolean saveSuccess = userService().save(registerRequest); If (BooleanUtil. IsFalse (saveSuccess)) {throw new BusinessException(" Save failed, please validate register parameter "); } return ServiceResult.newInstanceOfSucResult(AuthResponse.success(registerRequest)); } @ Override protected void executeAfter () {/ / automatic login 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); } / / remove the cache captchaService (.) removeCaptchaVerifyCode (context) getCaptchaCheckRequest ()); mailService().removeMailCode(context.getCheckMailRequest()); }}Copy the code

Front-end environment and dependencies

  • node
  • yarn
  • webpack
  • eslint
  • @vue/cli ~3
  • Quasar – Quasar Of Vue implementation

Please note that we strongly recommend that this project use the Yarn package management tool so that the exact same dependency version (yarn.lock) is loaded at the project demo site. Because we do not enforce version control on dependencies, non-YARN package management may cause problems when the new version of the library Pro depends on has been upgraded. The author may be unable to timely check due to time problems, which may cause problems when you adopt this project as the base project.

Project download and run

  • Pull the project code

Git clone github.com/dq-open-clo… cd quasar-sika-design

  • Install dependencies

yarn install

  • Run in development mode

quasar dev

  • Compile the project

quasar build

  • Lints and fixes files

yarn run lint

Documentation to be improved

The launch step

  • Find QuasarSikaDesignServerApplication run directly
  • Quasar-dev can be started and run

Other instructions

  • Feedback about Issue (important! Important! Important!) Please open**Issue**Before, read this:Issue/PR writing suggestions
  • The project uses Quasar -CLI. Make sure you use a new version of quasar -CLI and have studied the official CLI documentation
  • Disable Eslint (not recommended) Removepackage.jsoneslintConfigThe entire node code,vue.config.jsUnder thelintOnSaveTo valuefalse
  • For the production environment, please use**release**Version code, any problems with the master code need to be resolved by you
  • Provided by the backendMysqlandRedisThe environment belongs to the online test environment, please do not add or delete fields at will during the internal test stage

Browser compatibility

  • Chrome for Android >= 87
  • Firefox for Android >= 83
  • Android >= 81
  • Chrome >= 77
  • Edge >= 84
  • Firefox >= 74
  • IOS > = 10.3
  • Opera >= 68
  • Safari >= 11