gqz / FOP Bean代码生成V2

// ==UserScript==
// @name         FOP Bean代码生成V2
// @namespace    http://tampermonkey.net/
// @version      1.0424.01
// @description  try to take over the world!
// @author       gqz
// @match        https://fop.goodcang.com/portal/alInner/detail?*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=goodcang.com
// @run-at       document-end
// @license      Apache-2.0
// @grant        GM_xmlhttpRequest

// @require https://cdn.bootcdn.net/ajax/libs/jquery/2.2.4/jquery.min.js
// @require https://cdn.bootcdn.net/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js
// @require https://cdn.bootcdn.net/ajax/libs/vue/2.7.9/vue.min.js

// @resource jqueryUiCSS https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css
// @resource jqueryUiThemeCSS https://cdn.bootcdn.net/ajax/libs/jqueryui/1.9.2/themes/base/jquery.ui.theme.min.css
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @grant        GM_setClipboard
// @grant        GM_notification

// ==/UserScript==

(function() {
    'use strict';
//获取token
    var tonken = localStorage.getItem('micro-gosAdmin-Token');
//响应数据变量
    var ReqBeanData = null;
    var RespBeanData = null;
    var checkUrlChange=null;
    var url = window.location.search;

     if(!tonken){
        return;
    }
//封装获取数据
function getData(url,callback){
       GM_xmlhttpRequest({
        method: 'GET',
        url: url,
         headers: {
             'Authorization': tonken
         },
        onload: function(response) {
            callback(JSON.parse(response.responseText))
            //console.log(response.responseText);
        }
    });
}
//请求数据
function getFieldData(){
        const urlParams = new URLSearchParams(window.location.search);
        let icode= urlParams.get('icode') || ''
        console.log('开始请求数据',icode)
        //request
        getData('https://ark-gateway.goodcang.com/gos/api/v1/interface_base/get_interface_detail/'+icode+'?ability=1&customer_app_id=',(data)=>{
             let filed = (JSON.parse(data.data.req_param_json)).object_params;
             if(!filed){
                 $('#reqBtn').hide();
                 return;
             }

             $('#reqBtn').show();
             let format = new Format(filed)
             ReqBeanData = format.format();

        })

         //response
        getData('https://ark-gateway.goodcang.com/gos/api/v1/interface_reqresp/get_detail_resp/'+icode+'?ability=1',(data)=>{
             let dataFiled = (JSON.parse(data.data.RESP)).object_params.filter(item=>item.field_name=='data')
             if(dataFiled.length < 1){ return;}
             let filed = null;
             if(dataFiled[0].field_type == 'object'){
                  filed = dataFiled[0].object_params;
             }
            if(dataFiled[0].field_type == 'array'){
                  filed = dataFiled[0].array_params.object_params;
             }

             if(!filed || filed.length<1){
                      $('#respBtn').hide();
                      return;
              }
             $('#respBtn').show();

             let format = new Format(filed)
             RespBeanData = format.format();

        })
}

function toast(msg){
    $('#toast').html(`<div>${msg}</div>`);
    $("#toast" ).dialog( "open" );
    setTimeout(()=>{
        $( "#toast" ).dialog( "close" );
    },2000)
}

//格式化数据
class Format {
    constructor(data) {
        //this.data = data
        this.fieldGroup = {}
        this.beanGroup = {}
        this.typeMap = {
            "integer":'int',
            "number":'int'
        }
        this.expandData(data)
    }
    format() {
        for (const key in this.fieldGroup) {
            this.beanGroup[key]=[];
            this.fieldGroup[key].forEach(item => {
                this.beanGroup[key].push(item)
            })
        }
        return this.beanGroup
    }

    expandData(data,group='default'){
        if(!(group in this.fieldGroup)){
            this.fieldGroup[group]=[]
        }
        data.forEach(item => {
            let {field_name,field_type,filed_must,field_desc} = item;
            if(item.field_type=='array' && item.array_params!==null && item.array_params.object_params!==null){ //存在子元素
                this.fieldGroup[group].push({field_name,field_type,filed_must,field_desc,true_type:this.formmatName(field_name)})
                item.array_params.object_params && this.expandData(item.array_params.object_params,this.formmatName(field_name))
            }else if(item.field_type=='object' && item.object_params!==null ){ //存在子元素
                field_type = this.formmatName(field_name)
                this.fieldGroup[group].push({field_name,field_type,filed_must,field_desc})
                item.object_params && this.expandData(item.object_params,field_type)
            }else{
                this.fieldGroup[group].push({field_name,field_type,filed_must,field_desc})
            }
        })
    }
    formmatName(name) {
        return  name.split('_').map(item=>{
            let tempItem = item.charAt(0).toUpperCase() + item.slice(1);
            return tempItem == 'List'?'ListItem':tempItem;
        }).join('')
    }
}


 $(function(){

        GM_addStyle(GM_getResourceText("jqueryUiCSS"));
        GM_addStyle(GM_getResourceText("jqueryUiThemeCSS"));
        GM_addStyle('.ui-button .ui-icon{background-image: url(https://cdn.bootcdn.net/ajax/libs/jqueryui/1.13.2/themes/base/images/ui-icons_777777_256x240.png);}');
        GM_addStyle('.ui-widget-header .ui-icon{background-image: url(https://cdn.bootcdn.net/ajax/libs/jqueryui/1.13.2/themes/base/images/ui-icons_777777_256x240.png);}');
        GM_addStyle('.code_box_left{width:150px;border-right: 1px solid #ddd;flex-shrink: 0;}');
        GM_addStyle('.toast > .ui-dialog-titlebar{ display:none;}');
        GM_addStyle('#toast{min-height: 20px !important;}');

        $('body').append('<div  style="display:none;" id="toast"></div>');
        $('body').append(`<div style="height:0px;display:none;display:flex;overflow: hidden;"id="vueApp"title="生成参数"><div class="code_box_left"><div><div>语言</div><div><select style="width:126px;"v-model="default_lang"><option v-for="item in lang" :key="item">{{item}}</option></select></div></div><div style="margin-top:10px;"><div>类名</div><div><input style="width:120px;"v-model="default_class"placeholder="基础类名"></div></div></div><div style="width: calc(100% - 140px);"><div id="copy_box"style="border-bottom: 1px solid rgb(204, 204, 204);text-align: right;padding-right: 20px;line-height: 32px;"@click="copy">复制</div><div style="height: calc(100% - 30px);overflow: auto;"><pre>{{result}}</pre></div></div></div>`)

        var app = new Vue({
            el: '#vueApp',
            data: {
                lang:['PHP','Tyscript'],
                default_lang:"PHP",
                default_class:"default",
                typeMap: {"PHP":{
                    "integer":'int',
                    "number":'string'
                },"Tyscript":{
                    "integer":'number',
                }},
                data:{}
            },
            methods: {
                copy:function(){
                     GM_setClipboard($('#vueApp pre').text(), "text", () => {
                         toast('复制成功');
                      });
                },
                setData:function(data){
                   this.data = data
                },
                formatItemName(key){
                    if(this.default_lang == 'PHP'){
                       return `class ${key == 'default' ? this.default_class : key }{

`;
                    }
                    if(this.default_lang == 'Tyscript'){
                       return `export interface ${key == 'default' ? this.default_class : key }{

`;
                    }
                },
                formatItem(item){
                        let filedMastStr1 =  item.filed_must == "false" ? '?':'';
                        let filedMastStr2 =  item.filed_must == "false" ? ' = null':'' ;
                        let filedMastStr3 =  item.filed_must == "false" ? '|null':'' ;

                        let filedType1 =  this.typeMap[this.default_lang][item.field_type] || item.field_type;
                        let trueType = filedType1;
                        if(filedType1 == 'array'){
                            trueType = (item.true_type || 'string')+'[]'
                        }
                        if(this.default_lang == 'PHP'){
return `    \/** @var ${trueType}${filedMastStr3} ${item.field_desc} *\/
    public ${filedMastStr1}${filedType1} \$${item.field_name}${filedMastStr2};

`                       }
                        if(this.default_lang == 'Tyscript'){
return `    \/** ${item.field_desc} *\/
    ${item.field_name}${filedMastStr1}:${trueType};

`;                      }

                    }
            },
            computed: {
                // 计算属性的 getter
                result: function () {
                    let str = '';
                    for (let key in this.data) {
                         str += this.formatItemName(key);
                         this.data[key].map((item)=>{
                          str += this.formatItem(item);
                         })
                         str += `}

 `
                    }
                    return str
                }
            }
        })

        $("#toast" ).dialog({
            autoOpen: false,
            draggable:false,
            resizable:false,
            dialogClass:"toast",
            position :{ my: "center", at: "top+150", of: window },
            hide:{
              effect:'blind',
              duration:800
            }
        });

         //添加按钮
        var $reqButton = $('<a>').text('生成请求参数');
        var $resqButton = $('<a>').text('生成响应参数');

        setTimeout(function(){
            $('.fbg-group-title .flex-center').append('<ul id="create_code_menu"><li><div>&nbsp;&nbsp;&lt;/&gt;生成代码&nbsp;&nbsp;</div><ul><li id="reqBtn"></li><li id="respBtn"></li></ul></li></ul>');
            $('#create_code_menu > li > ul li').eq(0).append($reqButton);
            $('#create_code_menu > li > ul li').eq(1).append($resqButton);
            $( "#create_code_menu" ).menu({position:{ my: "left top", at: "right top-35"}});
            getFieldData();

            $('.fop-left-tree-menu a').on('click',function(){
                 if(checkUrlChange!==null){
                     clearTimeout(checkUrlChange)
                 }
                checkUrlChange = setTimeout(()=>{
                      checkUrlChange = null;
                      if(url != window.location.search){//网址发生改变重新请求数据
                          url = window.location.search;
                          $('reqStr').html('');
                          $('accordion').html('');
                          getFieldData();
                      }
                  },300)
             })

        },1000)

        var dialogParam={
            height: 600,
            width:800,
            modal: true,
            closeOnEscape : true
        }

        $reqButton.on('click', function() {
            app.setData(ReqBeanData);
            dialogParam.title = $(this).text();
            $("#vueApp" ).dialog(dialogParam);
        });

        $resqButton.on('click', function() {
            app.setData(RespBeanData);
            dialogParam.title = $(this).text();
            $("#vueApp" ).dialog(dialogParam);
        });

    });
})();