整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

快来尝鲜一款基于naive-ui开发的后台管理框架

快来尝鲜一款基于naive-ui开发的后台管理框架

各们广大的前端小伙伴们,大家好,作为 vue-admin-work系列的衍生版,vue-amdin-work-p 版本现在正式和大家见面了。

vue-admin-work-p采用当时流行的开发技术栈:

vite2 + vue3 + typescript + naive-ui

css处理上采用了

sass + tailwindcss

无论是在项目结构上还是代码编写上都和其它版本有很大的不同。

适合人群

  • 有一定的编程经验或者说之前对计算机软件了解过,如果是有前端编程经验那会更好地入手。
  • 之前只写静态页面,在前后分离这样的大趋势下,想提升自己
  • 之前从事后端,想学习一下前端
  • 创业公司或者中小型公司想要快速搭建自己的前端后台管理系统
  • ……

总之,你只要想学,这个框架总能帮助到你。

演示地址: http://qingqingxuan.gitee.io/vue-admin-work/p/

冰山一角

济资助是帮助学生支付大学学费的任何形式的资助,如佩尔助学金或以成绩为基础的奖学金。美国留学经济费用较高,最好了解大学能提供的财政资助,顺顺进行了下文整理,请看介绍(有点多哦~)。

  前言:许多家庭对大学学费的价码感到震惊。学费价格虽然可能是一笔巨额数字,但大学财政援助可以使高等教育负担得起。

事实上,根据Sallie Mae/Ipsos的调查,收入和储蓄只是家庭用于支付学生大学费用的资源中的一小部分。调查发现,在2018-2019年期间,对于一个普通家庭来说,奖学金和助学金覆盖了其31%的大学费用。奖学金和助学金是两种不需要偿还的大学经济资助方式。

  由于支付大学学费的复杂性,顺利通过奖助学金获取程序似乎颇具挑战性。以下是一些常见的经济援助问题的答案。

什么是大学经济资助?它是如何运作的?

  大学助学金帮助学生和他们的家庭支付高等教育费用,如学费和杂费、食宿费、书本费和交通费。

总共有几种类型的财政援助:

  · 补助金-Grants.

  · 奖学金-Scholarships.

  · 勤工俭学-Work-study.

  · 联邦或私人贷款-Federal or private loans.

  不同类型的援助是通过各种渠道提供的,如联邦和州机构、大学、高中、基金会和公司等。学生获得的资助取决于联邦、州和高等教育机构的指导方针。

  请记住,联邦财政资助的运作方式是,学生必须首先通过回答一系列用来确定他们支付大学费用能力的问题来申请资助。

  然后,根据申请情况给予资助,学生可以选择接受或拒绝资助。所提供的援助的种类决定了它是否必须得到偿还。有时,存在一些其他奖学金或私人资助,学生还需要完成额外的一些申请。

我怎样申请经济资助?

  第一步是提交联邦政府助学金免费申请,即FAFSA。这一申请被许多国家机构和学院和大学用来确定大学资助。

  FAFSA可以通过教育部的网站免费获得。家长们最早可于10月1日开始填写下一学年的申请表格。FAFSA的最后提交期限是6月30日。但这个最后期限只针对联邦财政援助。许多利用FAFSA来决定援助的学校会将最后期限提前。

  一些学校——主要是私立大学——使用一种叫做“大学奖学金服务简况(CSS Profile)”的补充表格来决定如何发放他们自己的助学金。该表单的信息项目比FAFSA更详细,而且完成起来很耗时。

  CSS简况的初始提交费用为25美元;每个额外的申请报告需要额外的16美元。需要使用CSS的学校列表可以在大学理事会(College Board)的网站上找到,该组织负责管理和维护这一申请。

  只有大约250所大学要求CSS配置文件。一般来说,更多的精英大学需要CSS文件。“记住,CSS文件将比FAFSA更深入地挖掘你家庭的财务状况。”

  例如,CSS中考虑了一些FAFSA中排除的资产。举几个不同的例子,它计算家庭住宅、小型企业或祖父母资助的529计划的价值。

有哪些不同类型的经济援助?

  有两种类型的援助:基于需求的援助和基于优秀的援助。

  例如,根据FAFSA的计算,以联邦需求为基础的资助是由家庭支付大学学费的能力决定的。

  另一方面,奖学金可以由机构、学院或私人组织颁发给具有特殊才能或运动或学术能力的学生。这些奖励的授予不基于经济需要。

  大学生可能有资格获得联邦、州或教育机构的资助。机构援助是由学院提供的财政援助,因学院而异,因为每个学院都使用自己的政策和公式来决定如何发放财政援助。

  根据教育部的说法,大多数学生有资格获得某种形式的联邦学生资助。对于联邦财政援助,有三种类型的资金:贷款、补助金和勤工俭学。

  ●联邦学生贷款。这些是来自政府的固定利率贷款。每个学年的利率在7月1日确定,并且该利率在贷款期限内是有担保的。学生贷款的主要项目是直接贷款。根据该计划,如果本科生是受抚养人,他们可以直接借到补贴贷款或非补贴贷款,总额最高可达3.1万美元。被划为独立人士的本科生最多可以借到5.75万美元。

  ●联邦补助金。这笔联邦资金不需要偿还。最著名的高等教育补助金是佩尔补助金。获得Pell的资格是基于家庭的预期家庭贡献(EFC),并根据FAFSA计算。大多数家庭收入低于5万美元的家庭通常有资格获得一定数额的Pell。2019-2020学年的最高佩尔补助金为6195美元。例如,EFC为0的家庭将有资格获得完全的Pell资助。

  ●勤工助学。这个项目提供兼职工作,通常是在校园里进行的一些工作,以帮助学生支付与大学有关的费用。并非所有学生都有资格参加联邦勤工俭学。学生需要通过FAFSA获得资格,并证明他们有经济上的需要。在勤工俭学制度下,学生每小时至少赚7.25美元,这是联邦最低工资。根据《美国如何支付大学学费报告》(How America Pays for college report),在2018-2019年间,联邦政府用于支付大学学费的勤工俭学平均费用为1808美元。

  当涉及到州援助时,大多数州将其援助限制在州内居民。北科罗拉多大学(University of Northern Colorado)经济援助主任马蒂?索梅洛(Marty Somero)表示:“总的来说,学生必须是该州的居民,并留在该州就读高等教育,才能获得助学金。”

  大学援助专家说,虽然FAFSA应该在学生的雷达范围内,使他们有资格获得联邦和州基金的以需求为基础的援助,但上大学的学生可以更进一步,利用潜在成绩基础使援助最大化。这是因为奖学金是缩小出勤成本和基于需求的经济援助之间差距的一种方式。

  但并不是所有的学校都颁发奖学金。有些学校只在特殊情况下才提供奖学金。在一项年度调查中,向《美国新闻与世界报道》提交数据的上榜学校中,2018-2019年获得奖学金的全日制学生平均比例为15%。一些学校,比如佛蒙特州的明德学院和马萨诸塞州的阿默斯特学院,都有不颁发奖学金的政策。

关于经济援助的最后期限,我应该知道些什么?

  专家建议,要注意最后期限。满足大学财政资助的最后期限是很重要的,因为不同的学校有不同的申请截止期限。

  例如,佛罗里达大学(University of Florida)将其财政援助的最后期限定在12月15日,这比许多其他学校提前了。事实上,学校网站鼓励学生在截止日期前申请。根据佛罗里达大学学生金融事务办公室的网站,“在12月15日前申请,以确保联邦处理器有时间进行分析并将你的FAFSA结果发送到我们的办公室。”

  还有其他学校推迟了截止日期。例如,北科罗拉多大学将最后期限定在3月1日。

  Somero说:“学生想要知道他们每一所申请学校的截止日期。例如,在北卡罗来纳大学,如果错过一天的最后期限,学生可能会损失5000至6000美元的免费援助,而不是家长贷款或其他类型的学生贷款。所以最后期限很重要,学校之间可能有所不同。所以学生们想要确保他们在优先期限之前提交申请。”

  但家长和学生应该注意和考虑的不仅仅是制度上的最后期限。

  艾奥瓦州格林内尔学院(Grinnell College)负责入学和助学金的副校长助理布拉德·林德伯格(Brad Lindberg)说:“有些州对州助学金资格有较早的最后期限,如果申请晚了,有些学校可能无法提供同样慷慨的助学金。对截止日期和申请要求进行组织是任何申请过程的第一步。

学校如何发放助学金?

  大学财政援助官员说,虽然学校发放资助的方式有很多相似之处,但在处理申请和发放资助方面,每个学校都有自己独特的流程。有些学校提供的助学金比其他学校多,就像有些学校收取的学费比其他学校高一样。

  “每个学院和大学在分配援助的方式上都是独一无二的。俄亥俄代顿大学(university of Dayton)招生和财政援助主任罗布?德克尔(Rob Durkle)表示:“与各个学院和大学合作,是了解援助在特定学校如何发挥作用的最佳方式。”

  杜克尔鼓励学生家长询问每所学校的奖助学金发放方法。例如,一些学校声称,他们已经完全满足了学生出勤费的财政需求,但这些一揽子计划可能包括贷款。包括罗德岛的布朗大学(Brown University)和新泽西州的普林斯顿大学(Princeton University)在内的少数几所大学,不管一个家庭的年收入如何,都提供不提供贷款的助学金。

  德克尔说,在代顿大学,学校每年都会提高学生的经济资助,以应对学费的上涨。从本质上讲,学生大一的学费与大四的学费是一样的。

我何时会收到经济资助来信?

  助学金通常会在早春的时候寄到学生的邮箱里,通常是在大学录取通知书发出之后,或者是在同一时间。索梅洛说:“从12月到4月,学生陆续可以收到自己的奖助学金获取结果了,具体时间取决于学校。”

如何申请助学金?

  上诉裁决的过程被称为职业判断审查。

  然而,学生们可能不知道上诉裁决是有可能的。根据Barnes & Noble College Insights在2019年对College Ave学生贷款的调查,大约有三分之一的学生事后会向经济资助办公室寻求更多的资助。

  但据奥索里尼说,“你需要的不仅仅是阐述出‘我需要更多的钱’而来申请助学金。”奥索里尼说,申请上诉家庭需要一个合理的理由,让学校重新检查学生的财务状况。

  TEAK Fellowship是一家为来自纽约市低收入家庭的学生提供服务的非营利组织。该组织的大学指导主任丹?布莱德尼克(Dan Blednick)说,要想在上诉中获得成功,申请者需要证明,自他们提交申请以来,他们的财务状况确实发生了重大变化。

  大学援助专家说,一个家庭通常会被要求提交一封信,概述影响他们支付能力发生变化的特殊情况。这类特殊情况可能是父母最近失业、离婚、家庭人员去世、医疗费用花费或年迈父母所需的护理费用等。

  “我建议学生联系学校经济资助办公室里负责你的案子的某个人,”Blednick说,他建议提供反映额外资金需求的文件。

  他说,比如,如果最近家庭收入下降了,一些学校可能会考虑在有足够证明文件的基础上修改他们的财务计划。他补充称,在某些情况下,一些学校可能会提供与同行机构相当的奖励。“如果所有这些措施都失败了,家长可以询问家长加贷款的可行性,增加学生联邦贷款的可能性,或者调查私人贷款选项。”

本来在Swagger的基础上,前后端开发人员在开发生产期间,可以借此进行更加便捷的沟通交流。可是总有些时候,遇到一些难缠的,又不讲道理,偏偏觉得将Swagger文档地址丢给客户会不够正式!死活要一份word文档。

可是这个时候,如果接口数量上百个,甚至更多,一个一个手动输入word,那将是一笔耗时的工作。但却有什么办法可以解决呢?

对了,利用Swagge生成的Json文件转换为word文档不就可以了吗?

思路

1. 获取Swagger接口文档的Json文件

2. 解析Json文件数据填充到Html的表格中

3.根据生成的html转work文档

开始

一、根据Swagger版本获取Json数据

1.通过Swagger源码文件可以看到

可以拿到swagger生成的文档数据,所以我们可以新建一个控制器SwaggerController.cs,

        private readonly SwaggerGenerator _swaggerGenerator;
        public SwaggerController(SwaggerGenerator swaggerGenerator)
        {
            _swaggerGenerator=swaggerGenerator;
        }
        /// <summary>
        /// 导出文件
        /// </summary>
        /// <param name="type">文件类型</param>
        /// <param name="version">版本号V1</param>
        /// <returns></returns>
        [HttpGet]
        public FileResult ExportWord(string type,string version)
        {
            string contenttype=string.Empty;

            var model=_swaggerGenerator.GetSwagger(version); //1. 根据指定版本获取指定版本的json对象。
        }

2. 在Startup.cs文件中,利用net core的ioc容器,注入SwaggerGenerator实例化,这样在后面的调用中可以直接使用这个方法

            services.AddScoped<SwaggerGenerator>(); //注入SwaggerGenerator,后面可以直接使用这个方法

二、文件数据填充到Html的表格中

根据上面获取的model文件数据,这个时候,我们利用Razor文件,结合html的table模板,将数据遍历填充到页面中,生成完整的页面

Html模板

@using Swashbuckle.AspNetCore.Swagger;
<!DOCTYPE html>
<html>
<head>
    <title>Swagger API文档代码文件</title>
    <style type='text/css'>

        table, table td, table th {
            border: 1px solid #000000;
            border-collapse: collapse;
        }

        table {
            table-layout: fixed;
            word-break: break-all;
        }

        tr {
            height: 20px;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div style='width:1000px; margin: 0 auto'>
        <span><i>Word接口文档</i></span>
        <h1 align="center">@Model.Info.Title</h1>
        <h1 align="center">接口文档 @Model.Info.Version</h1>
        <h4>联系方式</h4>
        <span>作者:@Model.Info.Contact.Name</span>
        <br>
        <a href="mailto:@Model.Info.Contact.Email" rel="noopener noreferrer" class="link">Send email to Xunit.Core</a>
        <br>
        <a href="@Model.Info.Contact.Url" target="_blank" rel="noopener noreferrer" class="link">@Model.Info.Contact.Name - Website</a>
        <br>
        <h3>接口描述</h3>
        <span>@Model.Info.Description</span>
        <br>
        <table border='1' cellspacing='0' cellpadding='0' style="table-layout: fixed; word-break: break-all;border: 1px solid #000000;border-collapse: collapse;" width='100%'>
            <tr style="border: 1px solid #000000;border-collapse: collapse;">
                <td align="center" style="background-color: rgb(84, 127, 177);">说明</td>
                <td></td>
            </tr>
            <tr style="border: 1px solid #000000;border-collapse: collapse;">
                <td align="center" style="background-color: rgb(84, 127, 177);">类型</td>
                <td></td>
            </tr>

        </table>
        @foreach (var item in Model.Paths)
        {
            if (item.Value.Operations !=null)
            {
                foreach (var operation in item.Value.Operations)
                {
                    <h3>@operation.Value.Summary</h3>
                    <table border='1' cellspacing='0' cellpadding='0' width='100%' style="table-layout: fixed; word-break: break-all;border: 1px solid #000000;border-collapse: collapse;">
                        <tr style="background-color: rgb(84, 127, 177);" align="center">
                            <td colspan='5'></td>
                        </tr>
                     
                        <tr style="border: 1px solid #000000;border-collapse: collapse;">
                            <td style="border: 1px solid #000000;border-collapse: collapse;">URL</td>
                            <td colspan='4'>@item.Key</td>
                        </tr>
                        <tr style="border: 1px solid #000000;border-collapse: collapse;">
                            <td style="border: 1px solid #000000;border-collapse: collapse;">请求方式</td>
                            <td colspan='4'>
                                @operation.Key
                            </td>
                        </tr>
                       
                        @if (operation.Value.Parameters !=null && operation.Value.Parameters.Count > 0)
                        {
                            <tr style="background-color: rgb(84, 127, 177);" align='center'>
                                <td style="border: 1px solid #000000;border-collapse: collapse;">参数名</td>
                                <td style="border: 1px solid #000000;border-collapse: collapse;">参数类型</td>
                                <td style="border: 1px solid #000000;border-collapse: collapse;">是否必填</td>
                                <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='2'>说明</td>
                            </tr>
                            @foreach (var param in operation.Value.Parameters)
                            {
                                <tr align='center' style="border: 1px solid #000000;border-collapse: collapse;">
                                    <td style="border: 1px solid #000000;border-collapse: collapse;">@param.Name</td>
                                    <td style="border: 1px solid #000000;border-collapse: collapse;">@param.In</td>
                                    <td style="border: 1px solid #000000;border-collapse: collapse;">@param.Required</td>
                                    <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='2'>@param.Description</td>
                                </tr>
                            }
                        }

                        <tr style="background-color: rgb(84, 127, 177);" align='center'>
                            <td style="border: 1px solid #000000;border-collapse: collapse;">状态码</td>
                            <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'>说明</td>
                        </tr>
                        @if (operation.Value.Responses !=null && operation.Value.Responses.Count > 0)
                        {
                            foreach (var response in operation.Value.Responses)
                            {
                                <tr align='center' style="border: 1px solid #000000;border-collapse: collapse;">
                                    <td style="border: 1px solid #000000;border-collapse: collapse;">@response.Key</td>
                                    <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'>@response.Value.Description</td>
                                </tr>

                            }
                        }
                        <tr style="background-color: rgb(84, 127, 177);">
                            <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='5'>示例</td>
                        </tr>
                        <tr style="height: 40px;" style="border: 1px solid #000000;border-collapse: collapse;">
                            <td style="background-color: rgb(84, 127, 177);">请求参数</td>
                            <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'></td>
                        </tr>
                        <tr style="height: 40px;" style="border: 1px solid #000000;border-collapse: collapse;">
                            <td style="background-color: rgb(84, 127, 177);">返回值</td>
                            <td style="border: 1px solid #000000;border-collapse: collapse;" colspan='4'></td>
                        </tr>
                    </table>
                    <br>
                }

            }
            
        }
    </div>
</body>
</html>

将数据遍历到静态页面中,

        /// <summary>
        /// 将数据遍历静态页面中
        /// </summary>
        /// <param name="templatePath">静态页面地址</param>
        /// <param name="model">获取到的文件数据</param>
        /// <returns></returns>
        public static string GeneritorSwaggerHtml(string templatePath, OpenApiDocument model)
        {
            var template=System.IO.File.ReadAllText(templatePath);
            var result=Engine.Razor.RunCompile(template, "i3yuan", typeof(OpenApiDocument), model);
            return result;
        }

三、根据生成的html转work文档

        /// <summary>
        /// 静态页面转文件
        /// </summary>
        /// <param name="html">静态页面html</param>
        /// <param name="type">文件类型</param>
        /// <param name="contenttype">上下文类型</param>
        /// <returns></returns>
        public Stream SwaggerConversHtml(string html, string type, out string contenttype)
        {
            string fileName=Guid.NewGuid().ToString() + type;
            //文件存放路径
            string webRootPath=_hostingEnvironment.WebRootPath;
            string path=webRootPath + @"\Files\TempFiles\";
            var addrUrl=path + $"{fileName}";
            FileStream fileStream=null;
            var provider=new FileExtensionContentTypeProvider();
            contenttype=provider.Mappings[type];
            try
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                var data=Encoding.Default.GetBytes(html);
                var stream=ByteHelper.BytesToStream(data);
                //创建Document实例
                Document document=new Document();
                //加载HTML文档
                document.LoadFromStream(stream, FileFormat.Html, XHTMLValidationType.None);
                //保存为Word
                document.SaveToFile(addrUrl, FileFormat.Docx);

                document.Close();
                fileStream=File.Open(addrUrl, FileMode.OpenOrCreate);
                var filedata=ByteHelper.StreamToBytes(fileStream);
                var outdata=ByteHelper.BytesToStream(filedata);

                return outdata;
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (fileStream !=null)
                    fileStream.Close();
                if (File.Exists(addrUrl))
                    File.Delete(addrUrl);//删掉文件
            }
        }
    public class ByteHelper
    {
        public static byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes=new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始 
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }

        /// 将 byte[] 转成 Stream
        public static Stream BytesToStream(byte[] bytes)
        {
            Stream stream=new MemoryStream(bytes);
            return stream;
        }
    }

四、最终效果

将html转换为word后,我们就可以看到带有 .doc 的效果了!差不多是如下效果

总结

1. 到这基本就结束了,通过简易的几个接口的方式,展示了如何通过将Swagger接口文档生成word文档。可以根据自己的html模板生成各式的word样式文档说明。

2.写这篇番外主要是因为之前介绍了关于如何使用Swagger生成在线文档,但实际工作中,可能也会遇到这种要各种正式word文档的客户,所以在此分享一些想法和思路,同时希望大家不吝指教。