阿里云图生视频工具:I2VGen-XL - image to video - AIBetas

mikel阅读(883)

来源: 阿里云图生视频工具:I2VGen-XL – image to video – AIBetas

2VGen-XL简介

I2VGen-XL项目由阿里云达摩院研发,用于根据输入图像生成高清视频。模型经大规模视频和图像数据混合预训练,并在少量精品数据上微调,具有良好的泛化性。相比现有的视频生成模型,I2VGen-XL在清晰度、质感、语义、时序连续性等方面具有优势。

  • [💡] I2VGen-XL模型的核心部分包含两个阶段,分别解决语义一致性和清晰度的问题,参数量共计约37亿。
  • [👍] I2VGen-XL模型在大规模视频和图像数据混合预训练,并在少量精品数据上微调,具有良好的泛化性。
  • [🎯] 相比现有的视频生成模型,I2VGen-XL在清晰度、质感、语义、时序连续性等方面具有优势。
  • [🎬] I2VGen-XL模型可以直接生成720P分辨率的视频,无水印,适用更多视频平台,减少许多限制。
  • [🔧] I2VGen-XL模型在处理小目标生成、快速运动目标生成以及生成速度等方面存在局限性。
  • [📚] I2VGen-XL模型的训练数据来源广泛,类别分布广,数据来源于开源数据、视频网站以及其他内部数据,具有多分辨率、长宽比等。

2VGen-XL生成效果

图片[1] - 阿里云图生视频工具:I2VGen-XL - image to video - AIBetas
图片[2] - 阿里云图生视频工具:I2VGen-XL - image to video - AIBetas

2VGen-XL模型体验

Demo:https://modelscope.cn/studios/damo/I2VGen-XL-Demo/summary

图片[3] - 阿里云图生视频工具:I2VGen-XL - image to video - AIBetas

2VGen-XL项目

Paper: https://arxiv.org/abs/2306.02018

项目开源地址:https://modelscope.cn/models/damo/Image-to-Video/summary

Github地址:https://www.github.com/camenduru/I2VGen-XL-colab

.NET开源最全的第三方登录整合库 - CollectiveOAuth - 追逐时光者 - 博客园

mikel阅读(309)

来源: .NET开源最全的第三方登录整合库 – CollectiveOAuth – 追逐时光者 – 博客园

前言

我相信很多同学都对接过各种各样的第三方平台的登录授权获取用户信息(如:微信登录、支付宝登录、GitHub登录等等)。今天给大家推荐一个.NET开源最全的第三方登录整合库:CollectiveOAuth。

官方项目介绍

.Net平台(C#) 史上最全的整合第三方登录的开源库 => 环境支持 .NET Framework 4.5 ~ 4.6.2 和 .NetCore 3.1。目前已包含Github、Gitee、钉钉、百度、支付宝、微信、企业微信、腾讯云开发者平台(Coding)、OSChina、微博、QQ、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、酷家乐、Gitlab、美团、饿了么、等第三方平台的授权登录。

项目特点

  • 全:已集成二十多家第三方平台(国内外常用的基本都已包含),仍然还在持续扩展中!
  • 简:API就是奔着最简单去设计的(见后面快速开始),尽量让您用起来没有障碍感!

企业微信扫码授权快速开始

0、企业微信开发对接文档

文档介绍

企业微信扫码授权登录官方文档地址:https://developer.work.weixin.qq.com/document/path/91025,在进行企业微信扫码授权绑定/登录之前需要先自建应用,同时需要开启网页授权登录,具体自建应用的相关操作可以参考博文:https://developer.aliyun.com/article/1136114

管理平台接入

完成了上面企业微信管理后台的相关配置之后,我们就可以按照文档步骤开始操作了

构造二维码

关于构造企业微信扫码绑定/登录二维码一共有两种方式:构造独立窗口登录二维码、构造内嵌登录二维码,下面简单说一下构造独立窗口登录二维码

构造独立窗口登录二维码

构造独立窗口登录二维码,可以在页面放置一个 button 按钮,添加点击事件,在触发点击事件时访问连接https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=CORPID&agentid=AGENTID&redirect_uri=REDIRECT_URI&state=STATE,效果如图:

连接参数说明:

 

1、引入依赖

下载源码,添加Come.CollectiveOAuth类库。

 

2、配置企业微信扫码授权(appsettings.json)中配置

{
  "AppSettings": {
    //企业微信扫码授权
    "CollectiveOAuth_WECHAT_ENTERPRISE_SCAN_ClientId": "xxxxxxxxxxxxxxxxx",
    "CollectiveOAuth_WECHAT_ENTERPRISE_SCAN_AgentId""xxxxxx",
    "CollectiveOAuth_WECHAT_ENTERPRISE_SCAN_ClientSecret""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "CollectiveOAuth_WECHAT_ENTERPRISE_SCAN_RedirectUri""https://yours.domain.com/oauth2/callback?authSource=WECHAT_ENTERPRISE_SCAN"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft""Warning",
      "Microsoft.Hosting.Lifetime""Information"
    }
  },
  "AllowedHosts": "*"
}

构建授权Url方法

        /// <summary>
        /// 构建授权Url方法
        /// </summary>
        /// <param name="authSource"></param>
        /// <returns>RedirectUrl</returns>
        public IActionResult Authorization(string authSource= "WECHAT_ENTERPRISE_SCAN")
        {
            AuthRequestFactory authRequest = new AuthRequestFactory();
            var request = authRequest.getRequest(authSource);
            var authorize = request.authorize(AuthStateUtils.createState());
            Console.WriteLine(authorize);
            return Redirect(authorize);
        }
    public class AuthRequestFactory
    {

        #region 从Webconfig中获取默认配置(可以改造成从数据库中读取)
        public Dictionary<string, ClientConfig> _clientConfigs;

        public Dictionary<string, ClientConfig> ClientConfigs
        {
            get
            {
                if (_clientConfigs == null)
                {
                    var _defaultPrefix = "CollectiveOAuth_";
                    _clientConfigs = new Dictionary<string, ClientConfig>();

                    #region 或者默认授权列表数据
                    var defaultAuthList = typeof(DefaultAuthSourceEnum).ToList().Select(a => a.Name.ToUpper()).ToList();
                    foreach (var authSource in defaultAuthList)
                    {
                        var clientConfig = new ClientConfig();
                        clientConfig.clientId = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_ClientId");
                        clientConfig.clientSecret = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_ClientSecret");
                        clientConfig.redirectUri = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_RedirectUri");
                        clientConfig.alipayPublicKey = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_AlipayPublicKey");
                        clientConfig.unionId = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_UnionId");
                        clientConfig.stackOverflowKey = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_StackOverflowKey");
                        clientConfig.agentId = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_AgentId");
                        clientConfig.scope = AppSettingUtils.GetStrValue($"{_defaultPrefix}{authSource}_Scope");
                        _clientConfigs.Add(authSource, clientConfig);
                    }
                    #endregion
                }
                return _clientConfigs;
            }
        }


        public ClientConfig GetClientConfig(string authSource)
        {
            if (authSource.IsNullOrWhiteSpace())
            {
                return null;
            }

            if (!ClientConfigs.ContainsKey(authSource))
            {
                return null;
            }
            else
            {
                return ClientConfigs[authSource];
            }
        } 
        #endregion

        /**
        * 返回AuthRequest对象
        *
        * @return {@link AuthRequest}
        */
        public IAuthRequest getRequest(string authSource)
        {
            // 获取 CollectiveOAuth 中已存在的
            IAuthRequest authRequest = getDefaultRequest(authSource);
            return authRequest;
        }


        /// <summary>
        /// 获取默认的 Request
        /// </summary>
        /// <param name="authSource"></param>
        /// <returns>{@link AuthRequest}</returns>
        private IAuthRequest getDefaultRequest(string authSource)
        {
            ClientConfig clientConfig = GetClientConfig(authSource);
            IAuthStateCache authStateCache = new DefaultAuthStateCache();

            DefaultAuthSourceEnum authSourceEnum = GlobalAuthUtil.enumFromString<DefaultAuthSourceEnum>(authSource);

            switch (authSourceEnum)
            {

                case DefaultAuthSourceEnum.WECHAT_MP:
                    return new WeChatMpAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.WECHAT_OPEN:
                    return new WeChatOpenAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.WECHAT_ENTERPRISE:
                    return new WeChatEnterpriseAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.WECHAT_ENTERPRISE_SCAN:
                    return new WeChatEnterpriseScanAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.ALIPAY_MP:
                    return new AlipayMpAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.GITEE:
                    return new GiteeAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.GITHUB:
                    return new GithubAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.BAIDU:
                    return new BaiduAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.XIAOMI:
                    return new XiaoMiAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.DINGTALK_SCAN:
                    return new DingTalkScanAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.OSCHINA:
                    return new OschinaAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.CODING:
                    return new CodingAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.LINKEDIN:
                    return new LinkedInAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.WEIBO:
                    return new WeiboAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.QQ:
                    return new QQAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.DOUYIN:
                    return new DouyinAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.GOOGLE:
                    return new GoogleAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.FACEBOOK:
                    return new FackbookAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.MICROSOFT:
                    return new MicrosoftAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.TOUTIAO:
                    return new ToutiaoAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.TEAMBITION:
                    return new TeambitionAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.RENREN:
                    return new RenrenAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.PINTEREST:
                    return new PinterestAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.STACK_OVERFLOW:
                    return new StackOverflowAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.HUAWEI:
                    return new HuaweiAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.KUJIALE:
                    return new KujialeAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.GITLAB:
                    return new GitlabAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.MEITUAN:
                    return new MeituanAuthRequest(clientConfig, authStateCache);

                case DefaultAuthSourceEnum.ELEME:
                    return new ElemeAuthRequest(clientConfig, authStateCache);

                default:
                    return null;
            }
        }
    }

API列表

https://gitee.com/rthinking/CollectiveOAuth#api%E5%88%97%E8%A1%A8

 

项目源码地址

更多实用功能特性欢迎前往开源地址查看👀,别忘了给项目一个Star💖。

https://gitee.com/rthinking/CollectiveOAuth

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发效率和质量。坑已挖,欢迎大家踊跃提交PR,自荐(让优秀的项目和框架不被埋没🤞)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

加入DotNetGuide技术交流群

  1. 提供.NET开发者分享自己优质文章的群组和获取更多全面的C#/.NET/.NET Core学习资料、视频、文章、书籍,社区组织,工具和常见面试题资源,帮助大家更好地了解和使用 .NET技术。
  2. 在这个群里,开发者们可以分享自己的项目经验、遇到的问题以及解决方案,倾听他人的意见和建议,共同成长与进步。
  3. 可以结识更多志同道合的开发者,甚至可能与其他开发者合作完成有趣的项目。通过这个群组,我们希望能够搭建一个积极向上、和谐友善的.NET技术交流平台,为广大.NET开发者带来更多的价值。

C# 怎么用OpenCVSharp4实现图片表格识别

mikel阅读(802)

要使用OpenCVSharp4来实现图片表格识别,你可以按照以下步骤进行操作:

安装OpenCVSharp4:首先,你需要安装OpenCVSharp4库。你可以通过NuGet包管理器或者从OpenCVSharp的官方网站下载并安装它。

导入必要的命名空间:在你的C#项目中,导入OpenCVSharp4的命名空间,以便能够使用它的功能。

using OpenCvSharp;
using OpenCvSharp.Extensions;

读取图片:使用OpenCVSharp4加载你要进行表格识别的图片。

Mat image = Cv2.ImRead(“your_image_path.jpg”);

图像预处理:在进行表格识别之前,你可能需要对图像进行一些预处理,以增强表格的检测和识别。这包括灰度化、二值化、去噪等操作,具体取决于你的图像特点。

Mat grayImage = new Mat();
Cv2.CvtColor(image, grayImage, ColorConversionCodes.BGR2GRAY);
Cv2.Threshold(grayImage, grayImage, 0, 255, ThresholdTypes.Binary);

表格检测:使用OpenCVSharp4的功能来检测图像中的表格。这可以通过查找图像中的直线、边缘或者轮廓来实现。

HoughLinesP(grayImage, out LineSegmentPoint[] lines, 1, Math.PI / 180, 100, 100, 10);

表格识别:一旦你检测到了表格的线条,你可以使用这些线条来提取表格中的内容。你可以根据线条的位置来切割图像,然后进一步处理每个表格单元格中的内容。

请注意,图像表格识别是一个复杂的任务,它可能需要一些调试和参数调整,以适应不同的图像和表格样式。你可能还需要使用OCR(光学字符识别)工具来提取单元格中的文本信息。

这只是一个基本的示例,实际的实现可能需要更多的步骤和细节。你可能需要深入研究OpenCVSharp4的文档以获取更多关于表格检测和图像处理的信息。

当你已经完成了表格检测并切割了图像以获取表格单元格的区域后,接下来的步骤通常包括:

单元格内容识别:对于每个切割出的表格单元格区域,你可以使用OCR工具来识别文本内容。Tesseract是一个常用的OCR引擎,你可以将其集成到你的C#项目中。以下是一个使用Tesseract的示例:

using Tesseract;

using (var engine = new TesseractEngine(@”tessdataPath”, “eng”, EngineMode.Default))
{
using (var img = Pix.LoadFromFile(“cell_image.png”))
{
using (var page = engine.Process(img))
{
string text = page.GetText();
// 处理识别出的文本内容
}
}
}

这里,tessdataPath应该是Tesseract数据文件的路径,”eng”表示使用英语语言模型,你可以根据需要选择其他语言模型。

处理识别结果:一旦你获取了每个表格单元格的识别文本,你可以根据需要对文本进行进一步的处理,如数据清理、格式化或存储。

结果输出:最后,你可以将识别出的表格数据输出到所需的格式,如Excel、CSV等,或者将其显示在用户界面中

请注意,表格识别是一个具有挑战性的任务,特别是对于复杂的表格和不同的图像质量。你可能需要调整和优化算法、参数和图像预处理步骤,以确保准确性和性能。另外,对于不同的语言和文本字体,OCR的准确性也可能会有所不同。

最好的方式是根据你的具体需求和数据集进行实验和测试,以找到最适合你的表格识别方法。同时,记得保持代码的可维护性和可扩展性,以便随着项目的发展进行进一步的改进和优化。

C#结合OpenCVSharp4图片相似度识别 - 宣君 - 博客园

mikel阅读(1018)

OpenCVSharp4

来源: C#结合OpenCVSharp4图片相似度识别 – 宣君 – 博客园

OpenCVSharp4图片相似度识别

需求背景:需要计算两个图片的相似度,然后将相似的图片进行归纳

1. 图片相似度算法

由于我是CRUD后端仔,对图像处理没什么概念。因此网上调研了几种相似度算法分析其适用场景。

直方图算法

获取要比较的2个图片的直方图数据,然后再将直方图数据归一化比较,最终得到一个相似指数,通过设定相似指数的边界,以此判断是否相同图片。

平均值哈希算法 aHash

转灰度压缩之后计算均值,最终通过像素比较得出哈希值,速度很快,但敏感度很高,稍有变化就会极大影响判定结果,精准度较差。因此比较适用于缩略图比较,最常用的就是以图搜图

感知哈希算法 pHash

在均值哈希基础上加入DCT(离散余弦变化),两次DCT就可以很好的将图像按照频度分开,取左上角高能低频信息做均值哈希,因此,精确度很高,但是速度方面较差一些。相比较aHashpHash更加适合用于缩略图比较,也非常适合比较两个近似图片是否相等。

差异值哈希算法 dHash

灰度压缩之后,比较相邻像素之间差异。假设有10×10的图像,每行10个像素,就会产生9个差异值,一共10行,就一共有9×10=90个差异值。最终生成哈希值即指纹。速度上来说,介于aHashpHash之间,精准度同样也介于aHashpHash之间。

结构相似性算法 SSIM

SSIM(structural similarity),结构相似性,是一种衡量两幅图像相似度的指标。SSIM算法主要用于检测两张相同尺寸的图像的相似度、或者检测图像的失真程度。原论文中,SSIM算法主要通过分别比较两个图像的亮度,对比度,结构,然后对这三个要素加权并用乘积表示。

SSIM算法在设计上考虑了人眼的视觉特性,它能够考虑到图像的结构信息在人的感知上的模糊变化,该模型还引入了一些与感知上的变化有关的感知现象,包含亮度mask和对比mask,结构信息指的是像素之间有着内部的依赖性,尤其是空间上靠近的像素点。这些依赖性携带着目标对象视觉感知上的重要信息。

经过调研对比,这里就选择SSIM算法。

2. 下载OpenCVSharp4

通过NuGet包管理器进行下载。搜索OpenCVSharp4下载。

请注意其描述信息:OpenCV wrapper for .NET. Since this package includes only core managed libraries, another package of native bindings for your OS is required (OpenCvSharp4.runtime.*).

这是说:OpenCV 包只是一个核心库,如需在你的系统上使用,还需要对应的运行时包,这里是Windows系统,因此还需下载 OpenCvSharp4.runtime.win

image


3. 使用

在项目中引入OpenCvSharp

using OpenCvSharp;

由于OpenCVSharp4没有直接提供封装SSIM算法的接口,因此需要自行写这部分代码。完整代码如下

public Scalar Compare_SSIM(string imgFile1, string imgFile2)
{
var image1 = Cv2.ImRead(imgFile1);
var image2Tmp = Cv2.ImRead(imgFile2);
// 将两个图片处理成同样大小,否则会有错误: The operation is neither ‘array op array’ (where arrays have the same size and the same number of channels), nor ‘array op scalar’, nor ‘scalar op array’
var image2 = new Mat();
Cv2.Resize(image2Tmp, image2, new OpenCvSharp.Size(image1.Size().Width, image1.Size().Height));
double C1 = 6.5025, C2 = 58.5225;
var validImage1 = new Mat();
var validImage2 = new Mat();
image1.ConvertTo(validImage1, MatType.CV_32F); //数据类型转换为 float,防止后续计算出现错误
image2.ConvertTo(validImage2, MatType.CV_32F);
Mat image1_1 = validImage1.Mul(validImage1); //图像乘积
Mat image2_2 = validImage2.Mul(validImage2);
Mat image1_2 = validImage1.Mul(validImage2);
Mat gausBlur1 = new Mat(), gausBlur2 = new Mat(), gausBlur12 = new Mat();
Cv2.GaussianBlur(validImage1, gausBlur1, new OpenCvSharp.Size(11, 11), 1.5); //高斯卷积核计算图像均值
Cv2.GaussianBlur(validImage2, gausBlur2, new OpenCvSharp.Size(11, 11), 1.5);
Cv2.GaussianBlur(image1_2, gausBlur12, new OpenCvSharp.Size(11, 11), 1.5);
Mat imageAvgProduct = gausBlur1.Mul(gausBlur2); //均值乘积
Mat u1Squre = gausBlur1.Mul(gausBlur1); //各自均值的平方
Mat u2Squre = gausBlur2.Mul(gausBlur2);
Mat imageConvariance = new Mat(), imageVariance1 = new Mat(), imageVariance2 = new Mat();
Mat squreAvg1 = new Mat(), squreAvg2 = new Mat();
Cv2.GaussianBlur(image1_1, squreAvg1, new OpenCvSharp.Size(11, 11), 1.5); //图像平方的均值
Cv2.GaussianBlur(image2_2, squreAvg2, new OpenCvSharp.Size(11, 11), 1.5);
imageConvariance = gausBlur12 – gausBlur1.Mul(gausBlur2);// 计算协方差
imageVariance1 = squreAvg1 – gausBlur1.Mul(gausBlur1); //计算方差
imageVariance2 = squreAvg2 – gausBlur2.Mul(gausBlur2);
var member = ((2 * gausBlur1.Mul(gausBlur2) + C1).Mul(2 * imageConvariance + C2));
var denominator = ((u1Squre + u2Squre + C1).Mul(imageVariance1 + imageVariance2 + C2));
Mat ssim = new Mat();
Cv2.Divide(member, denominator, ssim);
var sclar = Cv2.Mean(ssim);
return sclar; // 变化率,即差异
}

实际检测效果如下

image

这两幅图的相似度大约是92.21%,基本符合预期

image

这两幅图居然还有约18%的相似度,根据SSIM算法特性,这应该是图片大小的相似。

虽然也是拿来主义,毕竟我不是研究算法的大佬,需要站在巨人肩膀上干活~

做个笔记。

Visual Studio如何使用插件改变主题_visual studio 主题_Liquor999的博客-CSDN博客

mikel阅读(225)

Goodnight Theme

来源: Visual Studio如何使用插件改变主题_visual studio 主题_Liquor999的博客-CSDN博客

Visual Studio自带的主题太过于枯燥,此篇文章将详细讲述如何改变主题。

1.打开Visual Studio,在导航栏选择工具 -> 主题 -> 获取更多主题

此时浏览器会跳转到这个页面。选择一款自己喜欢的主题(可以搜索)点击,这里推荐One Dark Pro主题(本人VS里面有这个主题了,演示的时候使用Goodnight Theme)。

点开之后选择Download下载这个插件。

2.关闭Visual Studio,双击点开.vsix插件**

3.弹出来安装窗口,点击Install,即可成功安装。

安装成功,点击Close即可。

4.打开Visual Studio,在导航栏选择工具 -> 主题 -> Goodnight 就可以使用我们的下载的主题了。

5.效果对比
Goodnight主题效果如下图。

One Dark Pro主题效果如下图。

————————————————
版权声明:本文为CSDN博主「Liquor999」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45959662/article/details/125696277

11个最佳Visual Studio主题合集排行:哪个最好?

mikel阅读(1102)

来源: 11个最佳Visual Studio主题合集排行:哪个最好?

开发者喜欢黑暗模式。当谈到生产力时,我们有意地将ide和代码编辑器的颜色方案从标准的纯白色改为相反的颜色。在某种程度上,我们这样做是为了把眼睛从耀眼的屏幕中拯救出来,减少潜在的压力。

最佳Visual Studio主题有哪些?但并非所有的黑暗主题都是平等的。它不仅仅是将配色方案从白色反转为黑色。随着时间的推移,函数、类、模块和代码部分的突出显示方式也可以决定你的整体生产力。正确的配色方案可以帮助你快速扫描并找出代码中的异常,本文为你介绍最佳Visual Studio主题合集。

什么是 Visual Studio 2019 主题?

主题是可切换的皮肤,可让你为Visual Studio 编辑器配置配色方案和字体。市场目前有 5000 多个可用主题,涵盖 Visual Studio 2019 和Visual Studio Code,每个主题都旨在以可视化方式优化代码的显示方式。这是通过预先配置函数、模块、类和代码部分的颜色来完成的,那么Visual Studio主题哪个最好

快速教程 – 如何安装 Visual Studio 主题

使用 Visual Studio 2019 而不是 Visual Studio Code 的好处是,除了拥有与 Azure 服务直接集成的工具之外,还可以跨设备同步设置。这意味着即使你不在常用的工作机器上,你的主题配置也能随心所欲。

安装 Visual Studio 主题的最简单方法是导航到菜单栏中的“扩展”选项,然后选择“管理扩展”。

11个最佳Visual Studio主题合集排行:哪个最好?

下一步是在左侧面板的 Online 下选择 Visual Studio Marketplace。

11个最佳Visual Studio主题合集排行:哪个最好?

完成后,搜索你想要的主题并在搜索结果中选择它。

11个最佳Visual Studio主题合集排行:哪个最好?

下载主题后,关闭 VS2019,它将开始安装主题并创建一个如下所示的提示:

11个最佳Visual Studio主题合集排行:哪个最好?
11个最佳Visual Studio主题合集排行:哪个最好?
11个最佳Visual Studio主题合集排行:哪个最好?
11个最佳Visual Studio主题合集排行:哪个最好?

完成此操作后,再次打开 Visual Studio 2019 并导航到位于“工具”选项卡下的“选项”面板。选择颜色主题选项并选择你要应用的主题。

11个最佳Visual Studio主题合集排行:哪个最好?
11个最佳Visual Studio主题合集排行:哪个最好?

这基本上就是在 Visual Studio 中安装和切换主题的过程。事不宜迟,让我们回顾一下顶级 VS Code 主题。

由于Visual Studio Code 是市场上最受欢迎的代码编辑器之一,Visual Studio 2019 获得了共享市场和社区规模的好处。说到主题,有很多可用的主题。但是你应该选择哪一个呢?这是其他开发人员使用的前 11 个 Visual Studio 主题的列表。

前 11 个 最佳Visual Studio主题合集

1.One Dark Pro

最佳Visual Studio主题有哪些?除了标准的 Visual Studio 暗模式,One Dark Pro也是 Visual Studio 安装最多的主题之一。

它由 binaryify 创建,已下载超过 91,000 次,并将 Atom 的原始标志性 One Dark 主题移植到 Visual Studio 2019 中。

One Dark Pro 的一个特殊功能是突出显示语法支持 Markdown 预览——这在编写文档时可以派上用场。Markdown 并不适合所有人,能够区分不同的样式可以让生活更轻松。

11个最佳Visual Studio主题合集排行:哪个最好?

2. Midnight Spruce Pine

Visual Studio主题哪个最好Midnight Spruce Pine是一个黑暗主题,融合了 Tim Macharia 的 Pine Gap Dark 主题和 VS Code Ayu Mirage 的最佳部分。它在方法的黄色突出显示和变量、函数和类的蓝色主题上运行。这使得基于层次结构及其作用域位置跟踪和扫描代码变得容易。

11个最佳Visual Studio主题合集排行:哪个最好?

3. Atom One Dark Theme

Atom One Dark Theme是另一个 VS Code 主题,它来自Atom的原始 One Dark 主题。它是 One Dark Pro 的替代品,并且基于 250 万次下载证明很受欢迎。

11个最佳Visual Studio主题合集排行:哪个最好?

4.Goodnight Theme

Goodnight Theme是 Visual Studio 的深色主题,针对 C#、JSON、XML 和 Razor 进行了优化。方法以黄色突出显示,而数组以对比鲜明的水绿色突出显示。晚安主题中最重要的值是变量,其中黑色背景之间的对比度通过白色突出显示达到最大。

11个最佳Visual Studio主题合集排行:哪个最好?

5.Midnight Deep

最佳Visual Studio主题有哪些?Midnight Deep是 VS2019 的主题,适用于喜欢具有最大对比度效果的深色主题的开发人员。纯黑色背景确保了这是可能的,并为弱光情况打造了一个梦幻般的主题。如果你是那种喜欢熬夜工作或喜欢在大量人造光下工作的开发人员,Midnight Deep 可能就是适合你的 Visual Studio 主题。

11个最佳Visual Studio主题合集排行:哪个最好?

6. Night Owl

Visual Studio主题哪个最好?Night Owl是一个漂亮的小黑暗主题,不仅仅是反转颜色。Night Owl 的创造者确保将色盲人士和在弱光环境中工作的人士纳入配色方案的考虑中。

11个最佳Visual Studio主题合集排行:哪个最好?

7. Monokai Night

最佳Visual Studio主题合集:Monokai Night是一种因其功能性和美感而被选择的调色板。它最初由 Wimer Hazenberg 于 2006 年创建,并被采纳为 Sublime Text 的原始主题。

如果你是 Sublime Text 用户,那么Monokai Night 会让你熟悉 Visual Studio。

11个最佳Visual Studio主题合集排行:哪个最好?

8.Voyager Theme

Voyager Theme于 2020 年发布,受到 Jetbrains 的启发,包含在带有橙色、绿色、浅黄色和白色调色板的深色背景下突出显示的文本。与非黑色背景的对比度根据代码中类型的重要性而增加。例如,评论是可读的,但除非我们去搜索它们,否则不会跳出来。但是,类具有最大对比度,以便于扫描和跟踪。

11个最佳Visual Studio主题合集排行:哪个最好?

9. Pine Gap Dark

Pine Gap Dark是 VS2019 的主题,其灵感来自Ayu Mirage 的调色板,带有芥末黄色突出显示,使你的标签流行起来。这个主题非常适合 JavaScript、CSS/SCSS、C# 和 JSON,并且是使用 Microsoft 的 Visual Studio颜色主题设计器创建的

11个最佳Visual Studio主题合集排行:哪个最好?

10. MonokaiVS

Visual Studio主题哪个最好?MonokaiVS主题将两个流行的主题融合在一起,形成一个史诗主题。One Monokai 从 Monokai 的 One Dark 主题和颜色原则中汲取了最佳部分,以可视化地优化 Visual Studio 上的代码输出。

11个最佳Visual Studio主题合集排行:哪个最好?

11. Midnight Lights

最佳Visual Studio主题有哪些?如果黑色不是你喜欢的配色方案,Midnight Lights 会用一些不同的东西来营造黑暗模式的氛围。深蓝色背景散发出夜间氛围。它还通过为类和函数提供各种深浅不一的蓝色来营造氛围,同时以最大对比度突出显示新方法和变量。

11个最佳Visual Studio主题合集排行:哪个最好?

最佳Visual Studio主题合集总结

在编码方面,暗模式不仅仅是暗模式。除了使其具有视觉吸引力之外,它还使我们的代码在视觉上更易于跟踪和跟踪。

大多数深色主题都遵循相同的格式——最重要信息的最高对比度。根据主题创建者的偏好,它可能意味着作为突出显示元素的函数和类与变量和数组之间的差异。

Vue在ASP.NET MVC中的进行前后端的交互 - Kaden - 博客园

mikel阅读(280)

来源: Vue在ASP.NET MVC中的进行前后端的交互 – Kaden – 博客园

Preface:

由于最近在研究前端相关的技术,作为前端非常优秀的框架Vue,个人在学习的过程中遇到一些问题,网上相关资料有限,所以在这这里总结一下个人使用Vue的一点经验,以便后来者借鉴!

官方文档:Vue.js

使用Vue在ASP.NET MVC中进行前后端交互
在阅读下面的文章之前你需要先了解一下Vue官方推荐的前后端交互的插件:

1.resource(官方在2.0版本之后取消了对此插件的维护)

2.axios

注:这里使用的都是异步的插件,因为这样才会在你的项目中具有使用意义,当然你也可以用其它的js库,如JQuery、Fetch等等…

Instance:

Controller

复制代码
 1 using Demo.Models;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Mvc;
 7 
 8 namespace Demo.Controllers
 9 {
10     //[RoutePrefix("api/Goods")]
11     public class GoodsController : Controller
12     {
13         List<GoodsEntity> goosdList = new List<GoodsEntity>
14         {
15             new GoodsEntity(){ ID=001,Name="水",Type=1,Price=3},
16             new GoodsEntity(){ ID=002,Name="牛奶",Type=1,Price=10},
17             new GoodsEntity(){ ID=003,Name="面包",Type=2,Price=15}
18         };
19 
20         // GET: Goods
21         public ActionResult Index()
22         {
23             return View();
24         }
25 
26         public ActionResult Check()
27         {
28             return View();
29         }
30 
31         [HttpGet]
32         public JsonResult GetGoodsType()
33         {
34             List<int> goodsType = new List<int>();
35             foreach (var item in goosdList)
36             {
37                 if (!goodsType.Contains(item.Type))
38                 {
39                     goodsType.Add(item.Type);
40                 }
41             }
42             return Json(goodsType, JsonRequestBehavior.AllowGet);
43         }
44 
45         [HttpGet]
46         public JsonResult GetAllGoods()
47         {
48             return Json(goosdList, JsonRequestBehavior.AllowGet);
49         }
50 
51         [HttpPost]
52         public JsonResult GetGoods(int id)
53         {
54             var entity = goosdList.Where(g => g.ID == id).FirstOrDefault();
55             if (entity != null)
56             {
57                 return Json(new ReturnJsonInfo(500, "success!", entity));
58             }
59             return Json(new ReturnJsonInfo(400, "error!", null));
60         }
61 
62         [HttpPost]
63         public JsonResult UpdateGoods(GoodsEntity entity)
64         {
65             if (entity!=null)
66             {
67                 var goodsEntiy = goosdList.FirstOrDefault(g => g.ID == entity.ID);
68                 if (goodsEntiy!=null)
69                 {
70                     goodsEntiy = entity;
71                     return Json(new ReturnJsonInfo(500, "success!", goosdList));
72                 }
73                 goosdList.Add(entity);
74                 return Json(new ReturnJsonInfo(500, "success!", goosdList));
75             }
76             return Json(new ReturnJsonInfo(400, "error!",null));
77         }
78 
79         [HttpPost]
80         public JsonResult DelectGoods(int id)
81         {
82             var entity = goosdList.Where(g => g.ID == id).FirstOrDefault();
83             if (entity != null)
84             {
85                 goosdList.Remove(entity);
86                 return Json(new ReturnJsonInfo(500, "success!", goosdList));
87             }
88             return Json(new ReturnJsonInfo(400, "error!",null));
89         }
90 
91     }
92 }
复制代码

在上面的控制器中加载了一些示例数据,并且都是以json的格式返回前端,这样前端就可以直接使用这些数据。

注:控制器返回至前端的json中,上面使用 “ReturnJsonInfo” 对象序列化进行返回, “ReturnJsonInfo” 代码如下。

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 namespace Demo.Models
 7 {
 8     public class ReturnJsonInfo
 9     {
10         public int Code { get; set; }
11         public string Message { get; set; }
12         public object Entity { get; set; }
13         public ReturnJsonInfo(int code, string message,object obj)
14         {
15             this.Code = code;
16             this.Message = message;
17             this.Entity = obj;
18         }
19     }
20 }
复制代码

 

View

1.前端采用resource插件

 

复制代码
  1 @{
  2     ViewBag.Title = "Goods IndexPage";
  3 }
  4                  <script type="text/javascript" src="~/Resources/Scripts/vue.js"></script>
  5                  <script type="text/javascript" src="~/Resources/Scripts/vue-resource.js"></script>
  6 <h2>Index</h2>
  7                <div id="demo">
  8                       <table>
  9                           <tr>
 10                               <td><label>编号:</label></td>
 11                               <td><input type="text" v-model="newGoods.id" /></td>
 12 
 13                               <td><label>名称:</label></td>
 14                               <td><input type="text" v-model="newGoods.name" /></td>
 15 
 16                               <td><label>类型:</label></td>
 17                               <td><input type="text" v-model="newGoods.type" /></td>
 18 
 19                               <td><label>售价:</label></td>
 20                               <td><input type="text" v-model="newGoods.price" /></td>
 21 
 22                               <td><input type="submit" value="查询" v-on:click="GetGoods(newGoods.id)" /></td>
 23                           </tr>
 24                       </table>
 25                               <table v-show="goodsList.length">
 26                                   <tr>
 27                                       <td>编号</td>
 28                                       <td>名称</td>
 29                                       <td>类型</td>
 30                                       <td>售价</td>
 31                                   </tr>
 32                                   <tr v-for="item in goodsList">
 33                                       <td>{{item.ID}}</td>
 34                                       <td>{{item.Name}}</td>
 35                                       <td>{{item.Type}}</td>
 36                                       <td>{{item.Price}}</td>
 37                                   </tr>
 38                               </table>
 39                </div> 
 40 <script type="text/javascript">
 41     var view = new Vue(
 42         {
 43             el: "#demo",
 44             data: {
 45                 goodsList: [],
 46                 newGoods: {id:'',name:'',type:'',price:''}
 47             },              
 48             created: function () {
 49                 this.InIt();
 50             },
 51             methods: {
 52                 InIt: function () {
 53                     //初始化
 54                     this.GetAllGoods();
 55                 },
 56                 GetAllGoods: function () {
 57                     var _self = this;               
 58                     _self.$http.get("../Goods/GetAllGoods").then(
 59                         // Lambda写法
 60                         (response) => {
 61                             //successCallback
 62                             for (var i = 0; i < response.data.length; i++) {
 63                                 _self.goodsList.push(response.data[i]);                                   
 64                             }                                     
 65                         } ,
 66                         (response) => {
 67                                    //errorCallback   
 68                         }
 69                     );
 70                 },
 71                 GetGoods: function (_id) {
 72                     var _self = this;
 73                     _self.goodsList = [];
 74                     if (_id.length > 0) {
 75                         _self.$http.post("../Goods/GetGoods", { id: _id }).then(
 76                             // 传统写法
 77                             function (response) {
 78                                 //successCallback                                    
 79                                 if (response.data.Code == 500) {
 80                                     _self.goodsList.push(response.data.Entity);
 81                                 }
 82                                 else {
 83                                     alert(response.data.Message);
 84                                 }
 85                             },
 86                             function (response) {
 87                                 //errorCallback
 88                             }
 89                         )
 90                             .catch(function (response) {
 91                                 console.log(response);
 92                             });
 93                     }
 94                     else {
 95                         _self.GetAllGoods();
 96                     }
 97             }
 98             }
 99         }
100     );              
101 </script>
复制代码

 

2.前端采用axios插件

复制代码
  1 @{
  2     Layout = null;
  3 }
  4 
  5 <!DOCTYPE html>
  6 
  7 <html>
  8 <head>
  9     <meta name="viewport" content="width=device-width" />
 10     <title>Check</title>
 11     <script type="text/javascript" src="~/Resources/Scripts/vue.js"></script>
 12     <script type="text/javascript" src="~/Resources/Scripts/axios.min.js"></script>
 13 </head>
 14 <body>
 15     <div id="demo">
 16         <div>
 17             <table>
 18                 <tr>
 19                     <td><label>编号:</label></td>
 20                     <td><input type="text" v-model="newGoods.id" /></td>
 21 
 22                     <td><label>名称:</label></td>
 23                     <td><input type="text" v-model="newGoods.name" /></td>
 24 
 25                     <td><label>类型:</label></td>
 26                     <td>
 27                         <select v-model="newGoods.type">
 28                             <option value="">---ALL---</option>
 29                             <option v-for="type in goodsType" v-bind:value="type">{{type}}</option>
 30                         </select>
 31                     </td>
 32 
 33                     <td><label>售价:</label></td>
 34                     <td><input type="text" v-model="newGoods.price" /></td>
 35 
 36                     <td>
 37                         <input type="submit" value="查询" v-on:click="GetGoods(newGoods.id)" />
 38                         <input type="submit" value="更新" v-on:click="UpdateGoods(newGoods.id,newGoods.name,newGoods.type,newGoods.price)" />
 39                         <input type="submit" value="删除" v-on:click="DelectGoods(newGoods.id)" />
 40                     </td>
 41                 </tr>
 42             </table>
 43         </div>
 44         <div>
 45             <table v-show="goodsList.length">
 46                 <tr>
 47                     <td>行号</td>
 48                     <td>编号</td>
 49                     <td>名称</td>
 50                     <td>类型</td>
 51                     <td>售价</td>
 52                 </tr>
 53                 <tr v-for="(item,index) in goodsList">
 54                     <td>{{index+1}}</td>
 55                     <td>{{item.ID}}</td>
 56                     <td>{{item.Name}}</td>
 57                     <td>{{item.Type}}</td>
 58                     <td>{{item.Price}}</td>
 59                 </tr>
 60             </table>
 61         </div>
 62     </div>
 63 
 64     
 65     <script type="text/javascript">
 66         var vm = new Vue({
 67             el: "#demo",
 68             data: {
 69                 goodsType:[],
 70                 goodsList: [],
 71                 newGoods: { id: '', name: '', type: '', price: '' }
 72             },
 73             mounted() {
 74                 this.GetGoodsType();
 75                 this.GetAllGoods();
 76             },
 77             methods:
 78             {
 79                 GetGoodsType: function () {
 80                     axios.get("../Goods/GetGoodsType").then(
 81                         (response) => {
 82                             this.goodsType = [];
 83                             for (var i = 0; i < response.data.length; i++) {
 84                                 this.goodsType.push(response.data[i]);
 85                             }
 86                         },
 87                         (response) => {
 88                             alert(response.status);
 89                         }
 90                     )
 91                         .catch(function (response) {
 92                             console.log(response);
 93                         });
 94                 } ,
 95                 GetAllGoods: function () {
 96                     axios.get('../Goods/GetAllGoods').then(
 97                         function (response) {                               
 98                             vm.goodsList = [];  
 99                             for (var i = 0; i < response.data.length; i++) {      
100                                 vm.goodsList.push(response.data[i]);
101                             }
102                             //vm.goodsList.splice(response.data.length);
103                         },
104                         function (response) {
105                             alert(response.status);
106                         }
107                     )
108                         .catch(
109                         function (error) {
110                             alert(error);
111                         }
112                         )
113                 },
114                 GetGoods: function (_id) {
115                     if (_id.length > 0) {
116                         axios.post("../Goods/GetGoods", { id: _id }).then(                                   
117                             (response) => {        
118                                 this.goodsList = [];
119                                 if (response.data.Code == 500) {
120                                     this.goodsList.push(response.data.Entity);   
121                                 }
122                                 else {
123                                     alert(response.data.Message);
124                                 }
125                                  
126                             },
127                             (response) => {       
128                                 alert(response.status);
129                             }
130                         )
131                             .catch(function (response) {
132                                 console.log(response);
133                             });
134                     }
135                     else {
136                         this.GetAllGoods();
137                     }
138                 },
139                 UpdateGoods: function (_id,_name,_type,_price) {
140                     axios.post("../Goods/UpdateGoods", { entity: { ID: _id, Name: _name, Type: _type, Price: _price } }).then(                              
141                         (response) => {
142                             this.goodsList = [];
143                             if (response.data.Code == 500) { 
144                                 for (var i = 0; i < response.data.Entity.length; i++) {
145                                     this.goodsList.push(response.data.Entity[i]);
146                                 }
147                             }
148                             else {
149                                 alert(response.data.Message);
150                             }
151                         },
152                         (response) => {
153                             alert(response.status);
154                         }
155                     )
156                         .catch(function (response) {
157                             console.log(response);
158                         });
159                 },
160                 DelectGoods: function (_id) {
161                     axios.post("../Goods/DelectGoods", { id: _id }).then(
162                         (response) => {
163                             this.goodsList = [];
164                             if (response.data.Code == 500) {
165                                 for (var i = 0; i < response.data.Entity.length; i++) {
166                                     this.goodsList.push(response.data.Entity[i]);
167                                 }
168                             }
169                             else {
170                                 alert(response.data.Message);
171                             }
172 
173                         },
174                         (response) => {
175                             alert(response.status);
176                         }
177                     )
178                         .catch(function (response) {
179                             console.log(response);
180                         });
181                 } 
182             },
183 
184         });
185     </script>
186 </body>
187 </html>
复制代码

在上面的视图中,前端都是用数组进行填充的,值得注意的是vue在数组监听这一块做得并不是特别友好。但也提供了一些非常友好的api。

如果你也采用上述方式更新view,请参阅vue官方提供的关于操作数组方法

 

Perorations:

在上面的Demo中,采用的是ASP.NET MVC模板。在写View部分的时候感觉确实比较方便,不需要再去写获取元素的代码,只需要把数据绑定至元素上,关注数据的变动就可以了。

当然你也可以选择Razor语法,只不过那样看起来并不是很友善。

 

以上是个人在写这个Demo之后的一些总结。如有描述不当,请@作者修改,谢谢!

C#加Vue MVC+Vue快速开发_c# vue_太阳的后裔的博客-CSDN博客

mikel阅读(261)

来源: C#加Vue MVC+Vue快速开发_c# vue_太阳的后裔的博客-CSDN博客

首先创建项目

创建后大概的样子

1.配置Startup.cs

1.添加服务器端缓存
2.使用服务器端缓存
3.修改启动项为Home控制器下的Home视图

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Supply_System
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCaching();//1.添加服务器端缓存
services.AddControllersWithViews();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(“/Home/Error”);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseResponseCaching();//2.使用服务器端缓存

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: “default”,
pattern: “{controller=Home}/{action=Home}/{id?}”);//3.修改启动项为Home控制器下的Home视图
});
}
}
}

2.在Models文件夹下添加两个实体类

1.SupplyDemandsViewModel
2.TypeViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Supply_System.Models
{
public class SupplyDemandsViewModel
{
public int Id { get; set; }
public string SupplyDemandTitle { get; set; }
public string SupplyDemandDetail { get; set; }
public string CreateTime { get; set; }
public int CreateUserId { get; set; }
public int TypeId { get; set; }
public string TypeName { get; set; }
public bool IsRecommend { get; set; }
public bool IsDel { get; set; }
public static List<SupplyDemandsViewModel> ListAll()
{
List<SupplyDemandsViewModel> supplyDemands = new List<SupplyDemandsViewModel>();
for (int i = 0; i < 8; i++)
{
bool IsRecommend = false;
if (i > 4)
{
IsRecommend = true;
}
supplyDemands.Add(new SupplyDemandsViewModel
{
Id = 1,
SupplyDemandTitle = “v-if”,
SupplyDemandDetail = “”,
CreateTime = DateTime.Now.ToString(“yyyy-MM-dd HH:mm:ss”),
CreateUserId = 1,
TypeId = 1,
TypeName = “Vue控件”,
IsRecommend = IsRecommend,
IsDel = false
});
}
for (int i = 0; i < 8; i++)
{
bool IsRecommend = false;
if (i > 4)
{
IsRecommend = true;
}
supplyDemands.Add(new SupplyDemandsViewModel
{
Id = 1,
SupplyDemandTitle = “vm”,
SupplyDemandDetail = “”,
CreateTime = DateTime.Now.ToString(“yyyy-MM-dd HH:mm:ss”),
CreateUserId = 1,
TypeId = 2,
TypeName = “Vue语法”,
IsRecommend = IsRecommend,
IsDel = false
});
}
for (int i = 0; i < 8; i++)
{
bool IsRecommend = false;
if (i > 4)
{
IsRecommend = true;
}
supplyDemands.Add(new SupplyDemandsViewModel
{
Id = 1,
SupplyDemandTitle = “商城”,
SupplyDemandDetail = “”,
CreateTime = DateTime.Now.ToString(“yyyy-MM-dd HH:mm:ss”),
CreateUserId = 1,
TypeId = 3,
TypeName = “Vue实战”,
IsRecommend = IsRecommend,
IsDel = false
});
}
return supplyDemands;
}
}

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Supply_System.Models
{
public class TypeViewModel
{
public int Id { get; set; }
public string TypeName { get; set; }
public string Url { get; set; }
public static List<TypeViewModel> ListAll()
{
List<TypeViewModel> navViewNodels = new List<TypeViewModel>();
navViewNodels.Add(new TypeViewModel
{
Id = 1,
TypeName = “Vue控件”,
Url = “”
});
navViewNodels.Add(new TypeViewModel
{
Id = 2,
TypeName = “Vue语法”,
Url = “”
});
navViewNodels.Add(new TypeViewModel
{
Id = 3,
TypeName = “Vue实战”,
Url = “”
});
return navViewNodels;
}
}
}

3.修改HomeController控制器

1.添加浏览器端缓存
2.加载栏目数据
3.加载栏目对应的内容数据

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Supply_System.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace Supply_System.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;

public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}

public IActionResult Index()
{
return View();
}
[ResponseCache(Duration = 600)]/*1.浏览器端缓存*/
public IActionResult Home()
{
return View();
}
[ResponseCache(Duration = 600)]
public IActionResult GetNavs()/*2.加载栏目数据*/
{
return new JsonResult(TypeViewModel.ListAll());
}
[ResponseCache(Duration = 600)]
public IActionResult GetSuppys ()/*3.加载栏目对应的内容数据*/
{
return new JsonResult(SupplyDemandsViewModel.ListAll());
}

public IActionResult Privacy()
{
return View();
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

4.修改_Layout.cshtml视图

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″ />
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />
<title>@ViewData[“Title”] – Supply_System</title>
<link rel=”stylesheet” href=”~/lib/bootstrap/dist/css/bootstrap.min.css” />
<link rel=”stylesheet” href=”~/css/site.css” />
<script src=”~/lib/Vue/vue.min.js”></script>
</head>
<body>
<header>
<nav class=”navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3″>
<div id=”navs” class=”container”>
<a class=”navbar-brand” asp-area=”” asp-controller=”Home” asp-action=”Home”>主页</a>
<button class=”navbar-toggler” type=”button” data-toggle=”collapse” data-target=”.navbar-collapse” aria-controls=”navbarSupportedContent”
aria-expanded=”false” aria-label=”Toggle navigation”>
<span class=”navbar-toggler-icon”></span>
</button>
<div class=”navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse”>
<ul class=”navbar-nav flex-grow-1″>
<li class=”nav-item” v-for=”nav in navs”>
<a class=”nav-link text-dark” asp-area=”” asp-controller=”Home” asp-action=”Index”>{{nav.typeName}}</a>
</li>
@*<li class=”nav-item”>
<a class=”nav-link text-dark” asp-area=”” asp-controller=”Home” asp-action=”Index”>Vue控件</a>
</li>
<li class=”nav-item”>
<a class=”nav-link text-dark” asp-area=”” asp-controller=”Home” asp-action=”Privacy”>Vue语法</a>
</li>
<li class=”nav-item”>
<a class=”nav-link text-dark” asp-area=”” asp-controller=”Home” asp-action=”Privacy”>Vue实战</a>
</li>*@
</ul>
</div>
</div>
</nav>
</header>
<div class=”container”>
<main role=”main” class=”pb-3″>
@RenderBody()
</main>
</div>

<footer class=”border-top footer text-muted”>
<div class=”container”>
&copy; 2021 – Supply_System – <a asp-area=”” asp-controller=”Home” asp-action=”Privacy”>Privacy</a>
</div>
</footer>
<script src=”~/lib/JQuery/dist/JQuery.min.js”></script>
<script src=”~/lib/bootstrap/dist/js/bootstrap.bundle.min.js”></script>
<script src=”~/js/site.js” asp-append-version=”true”></script>
@RenderSection(“Scripts”, required: false)
</body>
</html>
<script>
var vm = new Vue({
el: “#navs”,
data: {
navs:[]
},
mounted() {
this.getNavs();
},
methods: {
getNavs() {
var that = this;
$.get(“/Home/GetNavs”, {}, function (res) {
that.navs = res;
console.log(res)
})
}
}
});
</script>

5.修改Home.cshtml视图

@{
ViewData[“Title”] = “Home Page”;
}
<script src=”~/lib/Vue/vue.min.js”></script>
<style>
ul {
list-style: none;
margin: 10px;
float: left;
}

ul li {
font-size: 18px;
}
/* ul li {
float: left;
}*/
</style>
<div id=”HomePage”>
<div style=”margin-left:50px;”>
<p>请输入关键字</p>
<input type=”text” v-model=”searchText” placeholder=”请输入需要搜索的关键字” />
@*<button @@click=”search()”>搜索</button>*@@*click前面添加两个@@符号是因为C#定义一个@会转换为后端语言*@
<button v-on:click=”search()”>搜索</button>
</div>
<div v-show=”showSearch==false”>
<ul>
<li><h3>推荐信息</h3></li>
<li v-for=”supply in getSupplyByRecommend”>{{supply.supplyDemandTitle}}</li>
</ul>
</div>
<div v-show=”showSearch==false” v-for=”type in types”>
<ul>
<li><h3>{{type.typeName}}</h3></li>
@*字段首字母要小写*@
<li v-for=”supply in getSupplysByTypeId(type.id)”>{{supply.supplyDemandTitle}}</li>

</ul>
</div>
<div v-show=”showSearch==true”>
<p style=”margin-left:50px;”>搜索内容</p><button v-on:click=”backAll()”>返回</button>
<ul v-if=”searchRes.length > 0″>
<li v-for=”supply in searchRes”>
{{supply.supplyDemandTitle}}
</li>
</ul>
<div v-else>
您搜索的内容尚不存在
</div>
</div>

@*<div>
<ul>
<li>Vue控件</li>
<li>v-if</li>
<li>v-show</li>
<li>v-text</li>
<li>v-model</li>
<li>v-for</li>
<li>v-bind</li>
</ul>
</div>
<div>
<ul>
<li>Vue语法</li>
<li>vm</li>
<li>data</li>
<li>methods</li>
</ul>
</div>
<div>
<ul>
<li>Vue实战</li>
<li>商城</li>
<li>官网</li>
<li>后台管理</li>
</ul>
</div>*@
</div>
<script src=”~/lib/jQuery/dist/jQuery.min.js”></script>
<script>
var vmHome = new Vue({
el: “#HomePage”,
data: {//定义变量
types: [],
supplys: [],
searchText: null,
searchRes: [],
showSearch: false
},
mounted() {
this.getNavs();
this.getSupplys();
},
methods: {
getNavs() {
var that = this;
$.get(“/Home/GetNavs”, {}, function (res) {
that.types = res;
console.log(res)
})
},
getSupplys() {
var that = this;
$.get(“/Home/GetSuppys”, {}, function (res) {
that.supplys = res;
console.log(res)
})
}
//,
//getSupplysByTypeId(typeId) {
// return this.supplys.filter(m => m.typeId == typeId);
//}
, search() {
console.log(this.searchText);
if (this.searchText == null) {
alert(“您尚未输入内容!”);
} else {
this.searchRes = this.supplys.filter(m => m.supplyDemandTitle.includes(this.searchText));
this.showSearch = true;
}

},
backAll() {
this.showSearch = false;
this.searchText = null;
}
},
computed: {/*computed下定义的是属性,不能直接定义方法,但是可以在其属性下定义方法*/
getSupplyByRecommend(){
return this.supplys.filter(m=>m.isRecommend==true);
},
getSupplysByTypeId() {
//无法像methods中那样直接定义方法,该处的getSupplysByTypeId()是一个属性,所以也不能传参,但是可以在该属性下定义一个方法
return function (typeId) {
return this.supplys.filter(m => m.typeId == typeId);
}
}
}
})
</script>

————————————————
版权声明:本文为CSDN博主「太阳的后裔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43942765/article/details/121938973

asp.net mvc 引入vue+ElementUi_asp.net mvc vue_K-superhero的博客-CSDN博客

mikel阅读(289)

来源: asp.net mvc 引入vue+ElementUi_asp.net mvc vue_K-superhero的博客-CSDN博客

ASP.NET mvc 引入vue+ElementUi
右键项目名——管理NuGet程序包

在浏览里搜素 vue element

分别安装

会发现在Content文件夹 script文件夹下会有相关的文件

在项目中引用vue的js文件、element的css和js文件,下面两种方式都可以
1.使用link标签、script标签引入

<script src=”~/Scripts/vue.js”></script>
<link rel=”stylesheet” href=”~/Content/ElementUI/element-ui.css” />
<script src=”~/Scripts/ElementUI/element-ui.js”></script>
1
2
2.在App_start文件下的bundleConfig.cs写下如下代码

bundles.Add(new ScriptBundle(“~/bundles/vue”).Include(
“~/Scripts/vue.js”));
bundles.Add(new ScriptBundle(“~/bundles/element”).Include(
“~/Scripts/ElementUI/element-ui.js”));
bundles.Add(new StyleBundle(“~/Content/elementcss”).Include(
“~/Content/ElementUI/element-ui.css”));
1
2
3
4
5
然后再html中引入

@Scripts.Render(“~/bundles/vue”)
@Scripts.Render(“~/bundles/element”)
@Styles.Render(“~/Content/elementcss”)
1
2
接下来就可以成功使用了
要注意的地方就是:如果没有vue实例就显示不了elementui的样式例如:

<el-button type=”primary”>Login</el-button>
如果想显示el-button的样式,你应该写一个vue实例。

<script>
var vm = new Vue({
el: “#app”,
data: {
msg: ‘我是vue’
}
})
</script>
————————————————
版权声明:本文为CSDN博主「K-superhero」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44106924/article/details/108567321

白嫖一个属于你的私有大模型 - yejg1212 - 博客园

mikel阅读(302)

来源: 白嫖一个属于你的私有大模型 – yejg1212 – 博客园

最近国内的大模型可谓是遍地开花,你瞧瞧:

这么火,我也想搞一个试试,于是就有了这篇文章!对,你没看错,就是白嫖。

毕竟人家清华都开源了,哈哈哈hoho~~

先把开源地址贴一下,老铁们可以自行去瞧一瞧:

https://github.com/THUDM/ChatGLM-6B
https://huggingface.co/THUDM/chatglm-6b

ChatGLM-6B 是一个开源的、支持中英双语问答的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。
结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。
ChatGLM-6B 使用了和 ChatGLM 相同的技术,针对中文问答和对话进行了优化。
经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答。

最重要的一点,人家遵循Apache-2.0协议。

下面开干吧!

准备机器

毕竟是要搭建可以跑起来的环境,机器肯定是必不可少的。好在阿里云有白嫖的使用机器。

  1. 进去阿里云免费试用活动页面 https://free.aliyun.com/
  2. 申请试用PAI-DSW资源,点击页面上的【立即试用】就可以了。(我因为已经试用了,所以显示的是“已试用”)
  3. 参考试用教程创建PAI平台示例。或者接着往下看
  4. 在阿里云页面搜索PAI,点击立即开通,然后进入到PAI控制台。

    开通的时候,有些可选的资源(比如NAS存储等),我因为没有,所以都没选。

  5. 进入控制台后,选择创建DSW实例

创建的时候,资源选择GPU资源,然后选择 支持资源包抵扣的那款 ecs.gn6v-c8g1.2xlarge

如果资源组下拉框是空白的,那么你需要在 上图左侧【工作空间详情】菜单,配置一下计算资源。

配置的按钮在工作空间详情页面右边【资源管理】,选择public-cluster 即可

镜像选择pytorch1.12,点击创建完成,机器就白嫖好了。

下载大模型

前面实例创建完之后,点击【打开】,会进入到机器的web控制台(Data Science Workshop)。

在这里,可以在Terminal里面操作了。

  1. 先执行安装git相关命令

    sudo apt-get update

    sudo apt-get install git-lfs

  2. 下载模型仓库(因为模型比较大,所以下载下来再执行方便些)

    git clone git@hf.co:THUDM/chatglm-6b

  3. 下载模型运行代码

    git clone https://github.com/THUDM/ChatGLM-6B.git

部署启动

部署前修改源码

因为我们已经把模型下载下来了,部署前,需要把代码中的模型路径改成你自己的。

比如我们的模型下载在/mnt/workspace/chatglm-6b,我们就需要把 ChatGLM-6B 下的两个文件路径都改一下:

  • cli_demo.py:命令行交互界面
  • web_demo.py:Web图形交互界面

启动

进入到ChatGLM-6B目录,执行启动命令即可

python web_demo.py

命令执行成功,会提示。就表示启动成功了。

Running on local URL: http://127.0.0.1:7860

To create a public link, set share=True in launch().

如果想外网访问,就还需要改一点源码。在web_demo.py文件最末尾,设置share=True

修改前:demo.queue().launch(share=False, inbrowser=True)

修改后:demo.queue().launch(share=True, inbrowser=True)

改完后,保存,再次启动,会打印出Running on public URL:XXXX,通过这个链接即可打开体验。

启动中如果遇到缺少一些module,可通过【pip install xxx】进行安装,安装完之后再执行启动命令

使用效果

使用效果的话,只能说还有相当长的路需要走。

答的是有板有眼的!但是,实际上…

我把完整的代码贴在下面,大家可自行体验评论:

import java.util.concurrent.Thread;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors.newSingleThreadExecutor();
import java.util.concurrent.Future;
public class TwoThreads交替打印String {
    public static void main(String[] args) {
        int numThreads = 2;
        String str = "Hello, World!";
        int index = 0;
        ExecutorService executor = Executors.newSingleThreadExecutor();
        List<Future<void>> futures = new ArrayList<>();
        for (int i = 0; i < numThreads; i++) {
            int size = str.length();
            int start = index * size + i;
            int end = start + size;
            int buffer = start * size + size;
            // 打印前一个线程的输出
            futures.add(executor.submit(() -> {
                Thread thread = new Thread(new MyThread(str, buffer));
                thread.start();
            }));
            // 打印当前线程的输出
            futures.add(executor.submit(() -> {
                Thread thread = new Thread(new MyThread(str, buffer));
                thread.start();
            }));
            // 等待当前线程完成
            thread.join();
            // 打印下一个线程的输出
            futures.add(executor.submit(() -> {
                Thread thread = new Thread(new MyThread(str, buffer));
                thread.start();
            }));
            index += size;
        }
        // 打印所有线程的输出
        for (Future<void> future : futures) {
            future.get();
        }
        executor.shutdown();
    }
    private static class MyThread implements Runnable {
        private final String str;
        private final int buffer;
        public MyThread(String str, int buffer) {
            this.str = str;
            this.buffer = buffer;
        }
        @Override
        public void run() {
            for (int i = 0; i < buffer; i++) {
                System.out.print(str.charAt(i) + " ");
            }
        }
    }
}