『贴Builder』
最新文章
热门话题
用户问答
lao人言
「搜索」
PasteSpider
一款更加适合开发人员的微服务(容器)发布管理工具

节省资源

极小的运行资源消耗,还支持一拖多运行,运行内存甚至低至100MB!

安全运行

和业务服务没有层级上的关联,哪怕PasteSpider停止运行也不会影响你的业务服务运行

简单易上手

一键安装,图形操作点点点即可完成操作,附属服务的支持原汁原味,简单易上手

环境隔离

支持拆分多环境运行,工厂,测试两不误,还可以根据环境配置适应不一样的配置信息

适用功能一应俱全

从项目角度进行服务容器管理,支持自动升级,扩容,缩减,状态报表,键值配置,自动路由等

支持Git/Svn代码管理

通过配置支持服务环境级别的自动提交构建,一键提交代码后即可自动发布服务和路由等

PasteBuilder的进阶用法
尘埃 2023-11-01 1413 33 1
PasteBuilder的高级使用,你可以自定义模板,实现自己的代码生成风格!比如作者就不喜欢使用仓储模式,直接改用DB模式!你也可以自定义模板,改成vue前端模式!

PasteBuilder作为代码生成器,他的局限就是需要依赖于ABP vNext的项目模板,可以参考PasteTemplate的项目架构!

今天要说的是PasteBuilder的另一个功能,模板自定义!!!

1.在xxx.Domain的项目中创建文件夹/template/,把模板文件放在这个文件夹下面,比如

index.html:生成后存放于XXX.HttpApi.Host项目中的wwwroot/manage/{model}/index.html
view.html:生成后存放于XXX.HttpApi.Host项目中的wwwroot/manage/{model}/view.html
add.html:生成后存放于XXX.HttpApi.Host项目中的wwwroot/manage/{model}/add.html
edit.html:生成后存放于XXX.HttpApi.Host项目中的wwwroot/manage/{model}/edit.html
vueindex.html:生成后存放于XXX.HttpApi.Host项目中的wwwroot/manage/{model}/index.vue
vueadd.html:生成后存放于XXX.HttpApi.Host项目中的wwwroot/manage/{model}/add.vue
vueview.html:生成后存放于XXX.HttpApi.Host项目中的wwwroot/manage/{model}/view.vue
server.html:生成后存放于XXX.Application项目中的{model}/{table}AppService.cs 作为表对应的主服务文件

注意:要生成前端文件,需要你在XXX.HttpApi.Host项目下,创建文件夹/wwwroot/manage/,否则前端文件是不会创建的!

上面的8个模板文件,内容要如何写呢???

PasteBuilder里面是使用dotliquid实现的,可以查看这个模板的文档

    http://dotliquidmarkup.org/
    https://shopify.github.io/liquid/tags/template/

代码运行的时候,会把一个TapClassModel信息推送到模板文件中,模板文件里面接收这个信息,然后基于这个信息实现模板代码,对象信息为

    /// <summary>
    /// 对象信息 字段信息
    /// </summary>
    public class TapClassModel : Drop
    {
        /// <summary>
        /// 命名空间,项目名称
        /// </summary>
        public string Namespace { get; set; }

        /// <summary>
        /// 模型名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 首字母小写
        /// </summary>
        public string lowerName { get {
                return CommonHelper.FirstCharToLower(Name);
            } 
        }
        
        /// <summary>
        /// 模型中文名称
        /// </summary>
        public string CnName { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 文件夹名称
        /// </summary>
        public string DirName { get; set; }

        /// <summary>
        /// 附带的属性
        /// </summary>
        public List<ClassProperty> ClassPropertys { get; set; }

        /// <summary>
        /// uint long int
        /// </summary>
        public string EntityType { get; set; } = "int";

        /// <summary>
        /// 显示的注释 注释summary里面的内容
        /// </summary>
        public string DisplayStr { get; set; }

        /// <summary>
        /// 作废,使用CnName替代
        /// </summary>
        public string DisplayShort { get; set; }

        /// <summary>
        /// 是否是读写分离模式
        /// </summary>
        public bool IsWriteReadModel { get; set; } = false;

    }

    /// <summary>
    /// 对象属性 字段的属性
    /// </summary>
    public class ClassProperty : Drop
    {
        /// <summary>
        /// 属性类型 可能带了Dto
        /// </summary>
        public string PropertyType { get; set; }

        /// <summary>
        /// 上面这个的基类,不带Dto,干净的个体
        /// </summary>
        public string PropertyBase { get; set; }

        /// <summary>
        /// 属性名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 首字母小写
        /// </summary>
        public string lowerName
        {
            get
            {
                return CommonHelper.FirstCharToLower(Name);
            }
        }

        /// <summary>
        /// 属性中文名称
        /// </summary>
        public string CnName { get; set; }

        /// <summary>
        /// 是否必填
        /// </summary>
        public bool Required { get; set; } = false;

        /// <summary>
        /// 最大长度 -1表示不启用MaxLength
        /// </summary>
        public int MaxLength { get; set; } = -1;

        /// <summary>
        /// 默认值
        /// </summary>
        public string DefaultValue { get; set; } = "";

        /// <summary>
        /// 属性特性
        /// </summary>
        public List<ClassAttribute> ClassAttributes { get; set; }

        /// <summary>
        /// 是否是其他的模型
        /// </summary>
        public bool boolOtherModel { get; set; }

        /// <summary>
        /// 注释是啥
        /// </summary>
        public string PropertyDisplayStr { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        public string DisplayStr { get { return PropertyDisplayStr; } }

        /// <summary>
        /// 是否是枚举类型
        /// </summary>
        public bool IsEnumClass { get; set; } = false;
    }

    /// <summary>
    /// 属性特性
    /// </summary>
    public class ClassAttribute:Drop
    {
        /// <summary>
        /// 属性名称
        /// </summary>
        public string Name { get; set; }
        
        /// <summary>
        /// 属性值
        /// </summary>
        public string Value { get; set; }

        /// <summary>
        /// 属性组合字符串
        /// </summary>
        public string NameValue { get; set; }
    }

比如你可以在index.html的模板文件中这样写

{% Namespace %}

这样最后生成的代码在对应的模块中的index.html应该可以看到输出了你当前项目的命名空间!

具体的代码如何写,你可以参考PasteSpider里面的Nginx路由代码,他们使用的模板技术是一样的,以下是Nginx路由模板!

# --- -- - https模式 - -- ---
{% for item in services -%}
	{% assign findapp=false -%}
	{% for model in item.models -%}
		{% for app in model.apps -%}
			{% assign findapp=true -%}
		{% endfor -%}
	{% endfor -%}
	{% if findapp == true %}
	   upstream {{ Code }}ser{{item.Code}} {
		{% for model in item.models -%}
		  {% for app in model.apps -%}
			server {{ app.Address }}:{{ app.listen_ports }} weight=10;
		  {% endfor -%}
		{% endfor -%}
		}
	{% endif -%}
{% endfor -%}
server {
	#listen 80;	
	listen 443 ssl; # managed by Certbot
    server_name {{ Host }};
    ssl_certificate /etc/letsencrypt/live/{{ Host }}/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/{{ Host }}/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
	{% for item in services -%}
	location /api/{{ item.Code }} {
		proxy_pass http://{{ Code }}ser{{ item.Code }}/;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
	{% endfor -%}
	location / {
		root /spider/static/soft/web/;
		index index.html index.htm;
	}
}

如果你在使用过程中遇到问题,可以在QQ群中找到帮助! QQ群:296245685

以下是/template/server.html的一个范本

using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace {{ Namespace }}.{{ DirName }}
{
    /// <summary>
    ///
    ///</summary>
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]
    public class {{ Name }}AppService : IUserAppService
    {

        private readonly I{{ Namespace }}DbContext _dbContext;

        /// <summary>
        ///
        ///</summary>
        ///<param name="dbContext"></param>
        public {{ Name }}AppService(I{{ Namespace }}DbContext dbContext):base()
        {
            _dbContext = dbContext;
        }

        /// <summary>
        /// 按页获取
        ///</summary>
        ///<param name="page">页码</param>
        ///<param name="size">页大小</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PagedResultDto<{{ Name }}ListDto>> GetListAsync(int page = 1, int size = 20)
        {

            var query = _dbContext.{{ Name }}.Where(t => 1 == 1).OrderByDescending(xy => xy.Id);
            var _pagedto = new PagedResultDto<{{ Name }}ListDto>();
            if (page == 1)
            {
                _pagedto.TotalCount = await query.CountAsync();
            }
            var userList = await query.Page(page, size).ToListAsync();
            var temList = ObjectMapper.Map<List<{{ Name }}>, List<{{ Name }}ListDto>>(userList);
            _pagedto.Items = temList;
            return _pagedto;
        }

        /// <summary>
        /// 根据ID获取单项
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public {{ Name }}Dto GetByIdAsync(int id)
        {
            var query = _dbContext.{{ Name }}.Where(t => t.Id == id).AsNoTracking().FirstOrDefault();
            if (query == null || query == default)
            {
                throw new {{ Namespace }}Exception("没有找到这样的信息", 404);
            }
            var temList = ObjectMapper.Map<{{ Name }}, {{ Name }}Dto>(query);
            return temList;
        }

        /// <summary>
        /// 根据ID获取待更新单项信息
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public {{ Name }}UpdateDto GetInfoForUpdateAsync(int id)
        {
            var query = _dbContext.{{ Name }}.Where(t => t.Id == id).AsNoTracking().FirstOrDefault();
            if (query == null || query == default)
            {
                throw new {{ Namespace }}Exception("没有找到这样的信息", 404);
            }
            var temList = ObjectMapper.Map<{{ Name }}, {{ Name }}UpdateDto>(query);
            return temList;
        }


        /// <summary>
        /// 添加一个
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<{{ Name }}Dto> CreateItemAsync({{ Name }}AddDto input)
        {
            var _userid = base.CurrentUserId();
            var newu = ObjectMapper.Map<{{ Name }}AddDto, {{ Name }}>(input);
            //添加自定义
            _dbContext.Add(newu);
            {% for item in ClassPropertys -%}
                {% if item.Name == "create_time" -%}
                    newu.create_time = DateTime.Now().ToUnixTimeSeconds();
                {% endif -%}
                {% if item.Name == "CreateDate" -%}
                    newu.CreateDate = DateTime.Now();
                {% endif -%}
                {% if item.Name == "CreateUserId" -%}
                    newu.CreateUserId = _userid;
                {% endif -%}
            {% endfor -%}
            await _dbContext.SaveChangesAsync();
            var backinfo = ObjectMapper.Map<{{ Name }}, {{ Name }}Dto>(newu);
            return backinfo;
        }
        /// <summary>
        /// 更新一个
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<{{ Name }}Dto> UpdateItemAsync({{ Name }}UpdateDto input)
        {
            var info = await _dbContext.{{ Name }}.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
            if (info == null || info == default)
            {
                throw new UserFriendlyException("需要查询的信息不存在", "404");
            }
            ObjectMapper.Map<{{ Name }}UpdateDto, {{ Name }}>(input, info);
            await _dbContext.SaveChangesAsync();
            var backinfo = ObjectMapper.Map<{{ Name }}, {{ Name }}Dto>(info);
            return backinfo;
        }
    }
}

如果需要自己编写模板,可以实际开发的表中,然后把对应的表名等按照实际情况替换即可,然后在特定的地方加上for循环或者if判断即可!

index.html的范本

<!--inherits RazorEngine.Templating.TemplateBase<CodeBuilder.Models.TemplateModels.DtoFileModel>-->
<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
        content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <link rel="stylesheet" type="text/css" href="../static/h-ui/css/H-ui.min.css" />
    <link rel="stylesheet" type="text/css" href="../static/h-ui.admin/css/H-ui.admin.css" />
    <link rel="stylesheet" type="text/css" href="../lib/Hui-iconfont/1.0.8/iconfont.css" />
    <link rel="stylesheet" type="text/css" href="../static/h-ui.admin/skin/default/skin.css" id="skin" />
    <link rel="stylesheet" type="text/css" href="../static/h-ui.admin/css/style.css" />
    <title>{{ Name }}</title>
</head>

<body>
    <div class="page-container">
        <div class="searcharea">
            <div class="st">
                <div class="sn">{{ cn_name }}</div>
                <div class="idesc">{{ Description }}</div>
            </div>
            <form id="formsearch">
                <div class="searchbox">
                    <!--<div class="timearea" style="display:flex;border:1px solid #888;border-radius: 4px;">
                        <select name="timetype" style="width:120px;border:none;outline:none;text-align: center;">
                            <option value="empty">订单时间</option>
                            <option value="bdate">动账日期</option>
                            <option value="cdate">消耗日期</option>
                            <option value="odate">到期日期</option>
                        </select>
                        <input type="text" name="daterange" readonly datas="" datae="" value=""
                            style="position:relative;flex:1;outline:none;border:none;border-radius: 4px; text-align: center;"
                            id="picker_date_range">
                    </div>-->
                    <input type="text" class="inputword" name="word" placeholder="输入关键字查询" value="">
                    <input type="button" class="btnsearch" onclick="_readpagedata(1);" value="查询">
                </div>
            </form>
            <a class="btn btn-success radius r" style="line-height:1.6em;margin-top:3px"
                href="javascript:location.replace(location.href);" title="刷新"><i class="Hui-iconfont"></i></a>
        </div>
        <div class="suminfo">
            <span class="idesc"></span>
        </div>
        <div class="mt-20">
            <table class="table table-border table-bordered table-bg table-hover table-sort table-responsive">
                <thead>
                    <tr class="text-c">
                        {% for ione in ClassPropertys -%}
                        <th>{{ ione.cn_name }}</th>
                        {% endfor -%}
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                </tbody>
            </table>
        </div>
        <div id="pagenumarea" class="pagenumarea"></div>
        <script type="text/html" id="templateitem">
            <% list.forEach(item=>{ %>
            <tr>
                {% for ione in ClassPropertys -%}
                <td><%:=item.{{ ione.lower_name }}%></td>
                {% endfor -%}
                <td><a title="编辑" href="javascript:;" onclick="_showedit('编辑','view.html','<%:=item.id%>','80%','80%')" class="ml-5" style="text-decoration:none"><i class="Hui-iconfont"></i></a></td>
            </tr>
            <% }) %>
        </script>
    </div>

    <!--_footer 作为公共模版分离出去-->
    <script type="text/javascript" src="../lib/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript" src="../lib/layer/2.4/layer.js"></script>
    <script type="text/javascript" src="../static/h-ui/js/H-ui.min.js"></script>
    <script type="text/javascript" src="../lib/jquery.contextmenu/jquery.contextmenu.r2.js"></script>
    <script type="text/javascript" src="../static/h-ui.admin/js/H-ui.admin.js"></script>
    <!--/_footer 作为公共模版分离出去-->
    <!--请在下方写此页面业务相关的脚本-->
    <!-- <script type="text/javascript" src="../lib/My97DatePicker/4.8/WdatePicker.js"></script> -->
    <!--<script type="text/javascript" src="../lib/pickerdaterange/dateRange.js"></script>
    <link rel="stylesheet" href="../lib/pickerdaterange/dateRange.css">-->

    <script type="text/javascript" src="../lib/api.js"></script>
    <link href="../lib/page.min.css" rel="stylesheet" />
    <script type="text/javascript" src="../lib/page.min.js"></script>
    <script type="text/javascript" src="../lib/template.js"></script>

    <script>

        var pageobject = null;
        var isedit = true;
        var _datalist = null;
        var extendSum = null
        $(window).ready(function () {

            _readpagedata(1);

            $(".inputword").keyup(function (event) {
                if (event.keyCode == 13) {
                    _readpagedata(1);
                }
            });
            //var dateRange = new pickerDateRange('picker_date_range', {
            //    isTodayValid: false,
            //    defaultText: '  至  ',
            //    inputTrigger: 'input_trigger_demo3',
            //    success: function (obj) {
            //        $("#picker_date_range").attr('datas', obj.startDate);
            //        $("#picker_date_range").attr('datae', obj.endDate);
            //    },
            //    clear: function () {
            //    }
            //});

        });

        function _readpagedata(page) {
            if (page == 1) {
                $("#pagenumarea").empty();
            }
            var _info = $("#formsearch").parseForm();
            _info.page = page;
            _info.size = 20;
            //if (_info.daterange) {
            //    if (_info.daterange.length > 0) {
            //        _info.sdate = $("[name=daterange]").attr('datas') + " 00:00:00";
            //        _info.edate = $("[name=daterange]").attr('datae') + " 00:00:00";
            //    }
            //}
            // _apiget('/api/app/{{ lowerName }}',true,function(code,obj){
            _apipost("/api/app/{{ lowerName }}/list", true, JSON.stringify(_info), function (code, obj) {
                if (code == 200 && obj.items != null && obj.items.length > 0) {
                    var datas = obj.items;
                    _showpagedata(datas, extendSum);
                    if (pageobject == null || page == 1) {
                        pageobject = new Page({
                            el: '#pagenumarea',
                            nums: obj.totalCount,//总数
                            counts: 20,//每页大小
                            defaultPage: 1,
                            showHeadFoot: false, // 显示首页尾页
                            head: '首', // 更改首页文字
                            foot: '尾', // 更改尾页文字
                            jumpToOrder: true, // 跳转到指定页
                            showNowAndAll: true, // 当前页/共几页
                            prev: "上一页",
                            next: "下一页",
                            clickEvent: function (currectPage, _this) {
                                _readpagedata(currectPage);
                            }
                        });
                    }
                }
            });
        }

        function _showpagedata(datas,total) {
            _datalist = datas;
            var _ahtml=$("#templateitem").html();
            var _heml=template(_ahtml,{list:datas, extend: total});
            $("table").find("tbody").html(_heml);
        }
    </script>
</body>
</html>

view.html的范本

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <link rel="Bookmark" href="/favicon.ico">
    <link rel="Shortcut Icon" href="/favicon.ico" />
    <!--[if lt IE 9]>
    <script type="text/javascript" src="../lib/html5shiv.js"></script>
    <script type="text/javascript" src="../lib/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="../static/h-ui/css/H-ui.min.css" />
    <link rel="stylesheet" type="text/css" href="../static/h-ui.admin/css/H-ui.admin.css" />
    <link rel="stylesheet" type="text/css" href="../lib/Hui-iconfont/1.0.8/iconfont.css" />
    <link rel="stylesheet" type="text/css" href="../static/h-ui.admin/skin/default/skin.css" id="skin" />
    <link rel="stylesheet" type="text/css" href="../static/h-ui.admin/css/style.css" />
    <!--[if IE 6]>
    <script type="text/javascript" src="../lib/DD_belatedPNG_0.0.8a-min.js" ></script>
    <script>DD_belatedPNG.fix('*');</script>
    <![endif]-->
    <!--/meta 作为公共模版分离出去-->
    <title>{{ cn_name }}</title>
</head>

<body>
    <div class="newarticle">
        <form class="form newform" id="form-article-add">

            <div class="row cl" style="display:none;">
                <label class="form-label"><span class="c-red">*</span>ID标识:</label>
                <div class="formControls">
                    <input type="number" class="input-number" value="0" placeholder="" name="id" readonly>
                </div>
            </div>

            {% for ione in ClassPropertys -%}
            <div class="row cl">
                <label class="form-label">{{ ione.cn_name }}:</label>
                <div class="formControls">
                    {% if ione.property_base == "int" || ione.property_base == "long" -%}
                    <input type="number" class="input-number" value="" placeholder="{{ ione.display_str }}" name="{{ ione.lower_name }}">
                    {% elseif ione.property_base == "bit" || ione.property_base == "bool" -%}
                    <input type="checkbox" class="input-checkbox mui-switch-anim mui-switch" name="{{ ione.lower_name }}">
                    {% else -%}
                    <input type="text" class="input-text" value="{{ ione.default_value }}" placeholder="{{ ione.display_str }}" name="{{ ione.lower_name }}" {% if ione.required -%} required {% endif -%} {% if ione.max_length > 0 -%} maxlength="{{ ione.max_length }}"{% endif -%}>
                    {% endif -%}
                </div>
            </div>
            {% endfor -%}

            <div class="row cl">
                <div class="rowbtn">
                    <input onClick="_funcAdd();" class="formbtnsubmit btn-primary" type="button" value="保存">
                </div>
            </div>
        </form>
    </div>

    <!--_footer 作为公共模版分离出去-->
    <script type="text/javascript" src="../lib/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript" src="../lib/layer/2.4/layer.js"></script>
    <script type="text/javascript" src="../static/h-ui/js/H-ui.min.js"></script>
    <script type="text/javascript" src="../static/h-ui.admin/js/H-ui.admin.js"></script>
    <!--/_footer /作为公共模版分离出去-->
    <!--请在下方写此页面业务相关的脚本-->
    <script src="../lib/api.js"></script>


    <script type="text/javascript">var iseditemodel = false;
        $(function () {
            //获取参数中的ID
            var _id = 0;
            var uidstr = _apigetquery("id");
            if (uidstr != null) {
                _id = parseInt(uidstr);
                iseditemodel = true;
                if (_id == 0) {
                    iseditemodel = false;
                }
            } else {
                iseditemodel = false;
            }
            if (iseditemodel) {
                $(".styleadd").hide();
                _loaditem(_id);
            } else {
                $(".styleedit").hide();
            }
        });

        function _loaditem(userid) {
            //读取角色列表
            _apiget("/api/app/{{ lower_name }}/" + userid + "/infoForUpdate", true, function (code, obj) {
                if (code == 200) {
                    _bindelement(obj);
                }
            });
        }

        function _funcAdd() {
            if (!_beforeValidity("#form-article-add")) {
                return;
            }
            var dataobj = $("#form-article-add").parseForm();
            if (iseditemodel) {
                _apipost("/api/app/{{ lower_name }}/updateItem", false, JSON.stringify(dataobj), function (code, obj) {
                    if (code == 200) {
                        layer.msg("更新成功", { time: 1500 }, function () {
                            var index = parent.layer.getFrameIndex(window.name); //获取窗口索引
                            parent.layer.close(index);  // 关闭layer
                        });
                    }
                });
            } else {
                _apipost("/api/app/{{ lower_name }}/item", false, JSON.stringify(dataobj), function (code, obj) {
                    if (code == 200) {
                        layer.msg("新增成功", { time: 1500 }, function () {
                            var index = parent.layer.getFrameIndex(window.name); //获取窗口索引
                            parent.layer.close(index);  // 关闭layer
                        });
                    }
                });
            }
        }</script>
    <!--/请在上方写此页面业务相关的脚本-->
</body>

</html>


评论列表
提枪灭婊

有没有vue的模板?

尘埃
33 1413 1
快捷注册
最新动态
  • 1.****.2 正在查看 PasteSpider之占位符,宏,对象属性遍历的说明 !
  • 173.****.191 正在查看 免费SSL证书,自动续期配置,配合PasteSpider的路由策略,用得飞起 !
  • 14.****.171 正在查看 PasteSpider之占位符,宏,对象属性遍历的说明 !
  • 107.****.121 正在查看 PasteSpider之占位符,宏,对象属性遍历的说明 !
  • 29.****.9 正在查看 PasteSpider中如何同步文件到服务器包含PasteSpiderFile的下载 !
  • 86.****.117 正在查看 在centos7中安装docker !
  • 77.****.33 正在查看 PasteSpider支持Ubuntu(podman)啦! !
  • 59.****.150 正在查看 使用PasteSpider部署CoreShop商城 !
  • 30.****.12 正在查看 Redis的安装 !
  • 96.****.136 正在查看 使用PasteSpider实现CI/CD持续部署,类似Jenkins的功能,让你的2G服务器也可以飞起 !
  • 41.****.222 正在查看 PasteSpider之私有仓库的创建和使用 !
欢迎加入QQ讨论群 296245685 更新记录 [PasteSpider]介绍 @2022-2023 PasteCode.cn 版权所有 ICP证 闽ICP备2021013869号-2