Let's talk about this open source project, how to make GitHub popular step by step!

At the beginning of 2010, influenced by foreign saas suppliers such as salesforce and zoho, more and more enterprises began to invest in CRM research and development. In order to find its own brand direction, Wukong team took openerp (odoo) as the benchmark, began to explore on the road of open source, and invested in it for nearly ten years.

First release in 2014

Wukong CRM project started in 2010. For the start-up team, the product R & D iteration and investment are limited, until the first open source CRM version was launched in 2104 V0.0.1 At that time, the open-source market of domestic enterprise management software was not fully mature V0.0.1 The version has the limitation of function and technology, and does not get a large number of users after the product is released.

Continue iteration in 2016

Wukong CRM is not as fast as it thinks in version iteration. Some R & D investment is open source and some R & D investment is secondary development project. After all, for an enterprise, survival is the first element. After 12 iterations in two years, in 2016, Wukong CRM version iterated to V0.4.5 , and after it was released on codecloud and Github, it has been downloaded and experienced by thousands of users. V0.4.5 This version has been completely upgraded and transformed on the basis of the original version, which is a relatively stable version currently used in the market.

But in this age of technological change. node, vue, microservice, Python, AI and other technologies continue to rise, and the technologies provided by Goku CRM open source have been difficult to meet the needs of existing technology lovers. The path of open source is once again hindered in China, and open source projects are temporarily put on hold.

A new challenge in 2019

Continue open source? It's a tough decision. After all, open source projects require a lot of effort. The cost to the enterprise is not a small challenge. But after all, Wukong CRM has devoted many years of efforts on the road of open source, open source is bound to continue!

pull one 's forces together and start afresh! This time, we are facing a major adjustment in technology. Wukong CRM decided to launch the current popular front-end and back-end separation technology. The back-end uses php and JAVA development languages, and the front-end uses the hottest vue architecture. Two kinds of background development language architecture are the only attempt in China. Developers of any technology stack, whether PHP or JAVA, can try to learn.

Make the ultimate open source product in 2019

In April 2019, PHP version released: Based on TP5.0 +Separate CRM system in front and back of Vue + element UI
In June 2019, JAVA version released: front and back end separation CRM system project based on jfinal+vue+ElementUI

Download address: https://gitee.com/wukongcrm

The two products were released in the same year, and after they were released, they got a lot of attention and favor from open source fans. With high-quality source code and high-standard UI design, Wukong CRM not only invested a lot of time and energy in technology, but also upgraded the user experience and UI comprehensively.

In 10 years, Wukong CRM's open-source path still needs to move forward, and will continue to face greater challenges. I believe that this open-source direction has been embedded in Wukong CRM's bone marrow, and Wukong's golden cudgel will become stronger one day.

Main functions of Wukong CRM open source project: Wukong CRM open source version contains more than 100 module applications

JAVA version

Core framework: jfinal3.8
Cache: redis caffeine
Database connection pool: Druid
Tool class: hutool, fastjson, POI OOXML
Scheduled task: jfinal Cron
Project construction tool: maven
Web container: Tomcat, below (default)
Front end MVVM framework: Vue.JS 2.5.x
Route: Vue router 3.x
Data interaction: AxiosUI framework: element UI 2.6.3
Project structure

├──  LICENSE
├──  README.md
├──  build                        //  to configure
│      ├──  build.js
│      ├──  check-versions.js
│      ├──  logo.png
│      ├──  utils.js
│      ├──  vue-loader.conf.js
│      ├──  webpack.base.conf.js
│      ├──  webpack.dev.conf.js
│      └──  webpack.prod.conf.js
├──  config
│      ├──  dev.env.js
│      ├──  index.js
│      └──  prod.env.js
├──  favicon.ico
├──  index.html                      //  Entry html file
├──  package-lock.json
├──  package.json                     //  Define the various modules required for the project, as well as configuration information
├──  src
│      ├──  App.vue                   //  Page entry
│      ├──  api                        //  api interface
│      │      ├──  businessIntelligence    //  business intelligence 
│      │      ├──  common.js                   //  public
│      │      ├──  customermanagement        //  customer management
│      │      ├──  login.js                   //  Sign in
│      │      ├──  oamanagement                    //to work in an office
│      │      ├──  personCenter
│      │      └──  systemManagement
│      ├──  assets                            //  Pictures and icons
│      │      ├──  401_images
│      │      ├──  404_images
│      │      ├──  iconfont
│      │      └──  img
│      ├──  components                         //  Custom components
│      │      ├──  CreateCom                     //  newly build
│      │      │      ├──  CrmRelative.vue              //  Associated customer management list
│      │      │      ├──  CrmRelativeCell.vue
│      │      │      ├──  CrmRelativeTable.vue
│      │      │      ├──  XhBusinessStatus.vue        //  Opportunity status
│      │      │      ├──  XhCustomerAddress.vue  //  Map location under new customer
│      │      │      ├──  XhDate.vue                        //  Time selection
│      │      │      ├──  XhDateTime.vue
│      │      │      ├──  XhFiles.vue                        //  enclosure
│      │      │      ├──  XhInput.vue                      //  Single line input box
│      │      │      ├──  XhMultipleSelect.vue        //  Multiple choice
│      │      │      ├──  XhProduct.vue                  //  Product Association
│      │      │      ├──  XhProuctCate.vue              //  Product category
│      │      │      ├──  XhReceivablesPlan.vue      //  Collection plan
│      │      │      ├──  XhSelect.vue                        //  Single choice
│      │      │      ├──  XhStrucUserCell.vue            //  Employee Department selection box
│      │      │      ├──  XhStructure.vue                    //  Department selection
│      │      │      ├──  XhStructureCell.vue
│      │      │      ├──  XhTextarea.vue                      //  Multiline input box
│      │      │      ├──  XhUser.vue                            //  Employee selection
│      │      │      ├──  XhUserCell.vue
│      │      │      ├──  arrayMixin.js                            //  Public logic
│      │      │      ├──  index.js
│      │      │      ├──  objMixin.js
│      │      │      └──  stringMixin.js
│      │      ├──  CreateSections.vue                          //  Container layout
│      │      ├──  CreateView.vue
│      │      ├──  DetailCell.vue
│      │      ├──  EditImage.vue                                    //  Edit picture
│      │      ├──  Examine                                          //  Approval display and operation
│      │      ├──  MapView.vue                                      //  Map preview location
│      │      ├──  SlideView.vue
│      │      ├──  emoji.vue                                              //  expression
│      │      ├──  flexbox                                                  //  flex
│      │      │      ├──  flexbox-item.vue
│      │      │      ├──  flexbox.vue
│      │      │      └──  index.js
│      │      ├──  relatedBusiness.vue                              //  Related customer content
│      │      ├──  reminder.vue
│      │      ├──  selectEmployee                                    //  Select employees
│      │      └──  vuePictureViewer                                  //  File Preview
│      ├──  directives                                            //  Custom instruction
│      │      ├──  empty
│      │      ├──  photo
│      ├──  filters                                          //  filter
│      ├──  main.js                                         //  Program entry
│      ├──  permission.js                                                    //  Routing processing
│      ├──  route Load more

The copy code judges whether the user has access right through the permission annotation in the interceptor

@Override
public void intercept(Invocation invocation) {
    //TODO permission function background interception
    Permissions permissions=invocation.getMethod().getAnnotation(Permissions.class);
    if(permissions!=null&&permissions.value().length>0){
        JSONObject jsonObject= Aop.get(AdminRoleService.class).auth(BaseUtil.getUserId());
        //Assembly should have authority list
        List<String> arr=queryAuth(jsonObject, "");
        boolean isRelease=false;
        for (String key : permissions.value()) {
            if(!isRelease){
                if(arr.contains(key)){
                    isRelease=true;
                }
            }
        }
        if(!isRelease){
            invocation.getController().renderJson(R.error("No access"));
            return;
        }
    }
    invocation.invoke();

}The copied code checks the data through AOP and annotation. It doesn't need to judge whether the parameters are empty one by one. If the data is empty, it will directly return to the user-defined paging data receiving, automatically process the paging parameters and data objects, and add the parameter basepagerequest to the controller method, T is the object type, and then the parameters will automatically assemble the component page parameters and the defined object classes. The following is the implementation code:

public class PageParaGetter extends ParaGetter<BasePageRequest> {
    public PageParaGetter(String parameterName, String defaultValue) {
        super(parameterName, defaultValue);
    }
    @Override
    protected BasePageRequest to(String s) {
        return null;
    }
@Override
@SuppressWarnings("unchecked")
public BasePageRequest get(Action action, Controller controller) {
    Parameter[] parameters=action.getMethod().getParameters();
    Class clazz=null;
    for (Parameter parameter:parameters){
        if(BasePageRequest.class.isAssignableFrom(parameter.getType())){
            Type parameterizedType=parameter.getParameterizedType();
            if (parameterizedType instanceof ParameterizedType) {
                Type[] params = ((ParameterizedType) parameterizedType).getActualTypeArguments();
                clazz= TypeUtils.getClass(params[0]);
            }
            break;
        }
    }
    boolean isJson=controller.getHeader("Content-Type")!=null&&controller.getHeader("Content-Type").toLowerCase().contains("application/json");
    return isJson?new BasePageRequest(controller.getRawData(),clazz):new BasePageRequest(controller.getKv(),clazz);
}
}

Copy code and customize json factory to realize personalized analysis and return of data, such as converting data to hump rule when returning data, customizing the return format of some type of object, etc. You can customize the error handling template. In case of errors or other exceptions, you can give the user a clear prompt to prevent the user from seeing some useless error information and other functional files that can be uploaded outside the project directory, so as to avoid the loss of files after repacking the project

@Override
public void configConstant(Constants me) {
    me.setDevMode(prop.getBoolean("jfinal.devMode", true));
    me.setInjectDependency(true);
    //Set which directory to upload files to
    me.setBaseUploadPath(BaseConstant.UPLOAD_PATH);
    me.setBaseDownloadPath(BaseConstant.UPLOAD_PATH);
  //Custom json factory
    me.setJsonFactory(new ErpJsonFactory());
    //Limit upload 100M
    me.setMaxPostSize(104857600);
}

The replication code is designed by project layering, with clear division of responsibilities, reduced code coupling, handler - > capture the url of specified rules or rest assured interceptor - > surround AOP interception, verify access rights, data rights, parameters, etc., which can be configured on the global, single route, single controller, single method, etc., and can be implemented by customization and logarithm According to the processing, router - > distributes the data of different rules, different URLs enter different routes and controllercontroller - > assembles the parameters, passes the data to the service for processing, and then the render returns the service - > processes the business code, and transfers the data to Db processing or caching Db - > operates the database Render - > returns the data returned by the service in the controller and writes the SQL to the xx.sql In the file, if the SQL file changes, you don't need to recompile and package it. You can directly change the SQL in the SQL file. The following is the code for automatically scanning the SQL file under the specified path:

private void getSqlTemplate(String path, ActiveRecordPlugin arp) {
    File file = new File(path);
    if (file.exists()) {
        File[] files = file.listFiles();
        if (files != null && files.length > 0) {
            for (File childFile : files) {
                if (childFile.isDirectory()) {
                    getSqlTemplate(childFile.getAbsolutePath(), arp);
                } else {
                    if (childFile.getName().toLowerCase().endsWith(".sql")) {
                        arp.addSqlTemplate(childFile.getAbsolutePath().replace(PathKit.getRootClassPath(), "").replace("\\", "/"));
                    }
                }
            }
        }
    }
}

PHP backend framework:

ThinkPHP 5.0.2
Front end MVVM framework: Vue.JS 2.5.x
Route: Vue router 3.x
Data interaction: AxiosUI
Framework: element UI 2.6.3
name of a fictitious monkey with supernatural powers crm9.0 Operating environment requirements of PHP5.6 Above Wukong CRM9.0(PHP) version application deployment
directory structure

├ - application directory (settable)
↘├ - admin system setting directory
 │  │  ├─ config.php       Module profile
 │  │  ├─ common.php       Module function file
 The controller controller directory
 Model model catalog
  - validate validator directory
 View view directory
 The lang language pack
 │├ - bi business intelligence module catalog
 │  │  ├─ config.php       Module profile
 │  │  ├─ common.php       Module function file
 The controller controller directory
 Model model catalog
  - validate validator directory
 View view directory
 The lang language pack
 ├ - common common module directory
 │├ - adapter authentication permission class directory
 List of behavior s (hooks)
The controller public controller directory
 The lang language pack
​
The crm customer management catalog
 │  │  ├─ config.php       Module profile
 │  │  ├─ common.php       Module function file
 The controller controller directory
 Model model catalog
  - validate validator directory
 View view directory
 The lang language pack
 │ ├ - lang language pack
 ‐├├ - oa office directory
 │  │  ├─ config.php       Module profile
 │  │  ├─ common.php       Module function file
 The controller controller directory
 Model model catalog
  - validate validator directory
 View view directory
 The lang language pack
 Project management catalog
 │  │  ├─ config.php       Module profile
 │  │  ├─ common.php       Module function file
 The controller controller directory
 Model model catalog
  - validate validator directory
 View view directory
 The lang language pack
 │  ├─ command.php         Command line tools profile
 │  ├─ common.php          Apply common (function) files
 │  ├─ tags.php            Application behavior extension definition file
 ├ - config configuration directory (definable)
│  ├─ config.php          Apply (public) profile
 │  ├─ database.php        Database profile
 │  ├─route_admin.php     System settings routing file
 │  ├─route_bi.php        Business intelligence routing file
 │  ├─route_crm.php       Customer management routing file
 │  ├─route_oa.php        Office routing file
 │  ├─route_work.php      Project management routing file
 │  └─ version.php         Version information file
 ├ - extend extension library directory (definable)
├ - public web deployment directory (external access directory)
├ - sql installation and update sql directory
 │├ - static static resource storage directory (css,js,image)
└ -. uploads upload file directory
 ├ - runtime directory of runtime application (writable and settable)
├ - static front-end VUE packaging directory=
├ - vendor third party Library Directory (Composer)
├ - thinkphp framework system directory
 │ ├ - lang language pack directory
 ‐├ - library framework core class library directory
  - think think library package directory
 Training system training directory
 List of tpl system templates
 The rewriting of apache with htaccess
 │  ├─. travis.yml         Ci definition file
 │  ├─ base.php            Basic definition document
 │  ├─ composer.json       Composer definition file
 │  ├─ console.php         Console entry file
 │  ├─ convention.php      Conventions profile
 │  ├─ helper.php          Assistant function file (optional)
│  ├─ LICENSE.txt         Authorization documents
 │  ├─ phpunit.xml         Unit test profile
 │  ├─ README.md           Readme file
 │  └─ start.php           Framework guidance file
 ├─ composer.json          Composer definition file
 ├─ LICENSE.txt            Authorization documents
 ├─ README.md              Readme file
 ├ - think command line entry file
 ├─ index.php              Application Portal file
 ├─ index.html             Screenshot of front-end display entry file copying code system






Tags: Operation & Maintenance Vue PHP SQL JSON

Posted on Tue, 19 May 2020 05:37:34 -0400 by JNettles