首页
网络资源
技术分享
云资源
分享你我
行动起来,活在当下
累计撰写
107
篇文章
累计创建
13
个标签
累计收到
0
条评论
栏目
首页
网络资源
技术分享
云资源
目 录
CONTENT
最新文章
OpenWrt实现双线接入实现负载均衡带宽叠加(测速也可以查看叠加是否成功)
<p>一、</p><p>添加两个 WAN 口,并把双线插入对应的WAN口</p><p><br/></p><p>添加WAN-1</p><p> 这里如果是用拨号上网的选择 "PPOE" 协议,然后输入宽带密码和帐号</p><p><img src="https://www.javalc.com/zb_users/upload/2021/12/202112111830304972536.png" alt="image.png" width="621" height="500" border="0" vspace="0" style="width: 621px; height: 500px;"/></p><!--autointro--><!--84-->
2021-12-11
36
0
0
技术分享
mysql bat一键安装(可手动可自动加载sql文件初始化库)
<p>简单点的:</p><pre class="brush:bash;toolbar:false">@echo off if %~dp0 == %cd%\ ( echo 请使用管理员身份执行脚本,按下回车键终止此次安装! set /p in= exit ) echo mysql5.*压缩版一键安装脚本... echo 即将开始安装... set /p password=请设置密码: if not defined password ( echo 您没有输入密码,按下回车键终止此次安装! set /p in= exit ) echo === 检查服务是否存在 SC QUERY MySQL > NUL IF ERRORLEVEL 1060 GOTO NOTEXIST GOTO EXIST :NOTEXIST ECHO 不存在MySQL服务 GOTO END :EXIST echo === 服务存在 net stop MySQL echo === 服务停止完成 sc delete MySQL If errorlevel 1 ( echo ===删除服务出错了。按下回车退出 set /p in= exit ) Else ( echo ===删除服务成功 ) GOTO END :END rem 将当前路径存储起来 set mysqlPath=%~dp0 rem 进入当前路径 cd /d %mysqlPath% rem 将配置文件名存储起来 set ini=my.ini rem 创建data文件夹 mkdir data echo ************************************************************ echo * * echo * MYSQL 系统环境变量设置 * echo * * echo ************************************************************ echo. echo === 准备设置环境变量: PATH=%%MYSQL_HOME%%bin echo. set /P EN=请确认后按 回车键 开始设置! echo. echo. rem ::如果有的话,先删除MYSQL_HOME wmic ENVIRONMENT where "name='MYSQL_HOME'" delete rem ::创建MYSQL_HOME wmic ENVIRONMENT create name="MYSQL_HOME",username="<system>",VariableValue="%mysqlPath%" ::在环境变量path中,剔除掉变量MYSQL_HOME中的字符,回显剩下的字符串 set newPath=%Path%;%%MYSQL_HOME%%\bin echo === 环境变量: PATH=%newPath% ::将返回显的字符重新赋值到path中 wmic ENVIRONMENT where "name='Path' and username='<system>'" set VariableValue="%newPath%" rem 向my.ini文件输出内容 echo [Client] >> %ini% echo. echo port = 3306 >> %ini% echo. echo [mysqld] >> %ini% echo. echo port = 3306 >> %ini% echo. echo basedir=%mysqlPath% >> %ini% echo. echo datadir=%mysqlPath%\data >> %ini% echo. echo max_connections=200 >> %ini% echo. echo character-set-server=utf8 >> %ini% echo. echo default-storage-engine=InnoDB >> %ini% echo. echo sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES >> %ini% echo. echo skip-grant-tables >> %ini% echo default_authentication_plugin=mysql_native_password >> %ini% echo. echo. echo [mysql] >> %ini% echo. echo default-character-set=utf8 >> %ini% rem 进入bin目录 cd /d %mysqlPath%\bin rem 执行mysql安装命令 start /b /wait mysqld -install rem 执行mysql初始化命令 start /b /wait mysqld --initialize --console rem 启动mysql服务 start /b /wait net start mysql rem 设置root用户密码 start /b /wait mysql -uroot -pnon -e "update mysql.user set authentication_string=PASSWORD('%password%') where user='root' and host='localhost';" rem 刷新权限 start /b /wait mysql -uroot -pnon -e "flush privileges;" rem 停止mysql服务 start /b /wait net stop mysql rem 启动mysql服务 start /b /wait net start mysql echo === 初始化数据库 set /p dataBaseName=请设置数据库名称: if not defined dataBaseName ( echo 您没有输入数据库名称,按下回车键终止此次安装! set /p in= exit ) set MYSQL_CMD= mysql -uroot -pnon rem echo %MYSQL_CMD% rem 停止mysql服务 start /b /wait net stop mysql rem 启动mysql服务 start /b /wait net start mysql echo === 创建数据库====数据库:%dataBaseName% start /b /wait %MYSQL_CMD% -e "CREATE DATABASE IF NOT EXISTS %dataBaseName% DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;"; set /p sqlfile=请输入执行sql的文件名称包括后缀: if not defined sqlfile ( echo 请没有输入执行sql的文件名称包括后缀,按下回车键终止此次安装! set /p in= exit ) echo === 执行sql脚本 echo. echo === 执行sql脚本---%sqlfile% echo. start /b /wait %MYSQL_CMD% -D%dataBaseName% < %mysqlPath%%sqlfile% @echo on echo === 执行sql脚本---setSql.sql echo. start /b /wait %MYSQL_CMD% -D%dataBaseName% < %mysqlPath%setSql.sql @echo off rem 停止mysql服务 start /b /wait net stop mysql rem 进入根目录 cd /d %mysqlPath% rem 清空my.ini文件 CD. > %ini% rem 向my.ini文件输出内容 echo [Client] >> %ini% echo. echo port = 3306 >> %ini% echo. echo [mysqld] >> %ini% echo. echo port = 3306 >> %ini% echo. echo basedir=%mysqlPath% >> %ini% echo. echo datadir=%mysqlPath%\data >> %ini% echo. echo max_connections=200 >> %ini% echo. echo character-set-server=utf8 >> %ini% echo. echo default-storage-engine=InnoDB >> %ini% echo. echo sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES >> %ini% echo default_authentication_plugin=mysql_native_password >> %ini% echo. echo. echo [mysql] >> %ini% echo. echo default-character-set=utf8 >> %ini% rem 启动mysql服务 start /b /wait net start mysql echo 安装完成 pause >nul</pre><!--autointro--><!--83-->
2021-12-03
4
0
0
技术分享
C# HttpWebRequest 多网卡指定IP下载
<pre class="brush:c#;toolbar:false">/// <summary> /// 获取指定网卡IP /// </summary> /// <param name="servicePoint"></param> /// <param name="remoteEndPoint"></param> /// <param name="retryCount"></param> /// <returns></returns> public IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount) { if (!string.IsNullOrWhiteSpace(_configuration.IP)) { IPAddress address = IPAddress.Parse(_configuration.IP); return new IPEndPoint(address, 0); } return new IPEndPoint(IPAddress.Any, 0); } public static void Main() { HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://MyServer"); request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); }</pre><!--autointro--><!--82-->
2021-11-29
2
0
0
技术分享
vue3 + ts+vite+electron使用tinymce富文本框
<p>新建TEditor.vue组件</p><pre class="brush:js;toolbar:false"># index.vue <template> <div class="tinymce-box"> <Editor v-model="contentValue" :init="initOptions" :disabled="disabled" @onClick="onClick" /> </div> </template> <script lang="ts"> //引入tinymce编辑器 import Editor from '@tinymce/tinymce-vue'; // 引入富文本编辑器主题的js和css // import 'tinymce/skins/content/default/content.css' //引入方式引入node_modules里的tinymce相关文件文件 import tinymce from 'tinymce/tinymce'; //tinymce默认hidden,不引入则不显示编辑器 import 'tinymce/themes/silver'; //编辑器主题,不引入则报错 import 'tinymce/icons/default'; //引入编辑器图标icon,不引入则不显示对应图标 // 引入编辑器插件 import 'tinymce/plugins/advlist'; //高级列表 import 'tinymce/plugins/anchor'; //锚点 import 'tinymce/plugins/autolink'; //自动链接 import 'tinymce/plugins/autoresize'; //编辑器高度自适应,注:plugins里引入此插件时,Init里设置的height将失效 import 'tinymce/plugins/autosave'; //自动存稿 import 'tinymce/plugins/charmap'; //特殊字符 import 'tinymce/plugins/code'; //编辑源码 import 'tinymce/plugins/codesample'; //代码示例 import 'tinymce/plugins/directionality'; //文字方向 import 'tinymce/plugins/emoticons'; //表情 import 'tinymce/plugins/fullpage'; //文档属性 import 'tinymce/plugins/fullscreen'; //全屏 import 'tinymce/plugins/help'; //帮助 import 'tinymce/plugins/hr'; //水平分割线 import 'tinymce/plugins/image'; //插入编辑图片 import 'tinymce/plugins/importcss'; //引入css import 'tinymce/plugins/insertdatetime'; //插入日期时间 import 'tinymce/plugins/link'; //超链接 import 'tinymce/plugins/lists'; //列表插件 import 'tinymce/plugins/media'; //插入编辑媒体 import 'tinymce/plugins/nonbreaking'; //插入不间断空格 import 'tinymce/plugins/pagebreak'; //插入分页符 import 'tinymce/plugins/paste'; //粘贴插件 import 'tinymce/plugins/preview'; //预览 import 'tinymce/plugins/print'; //打印 import 'tinymce/plugins/quickbars'; //快速工具栏 import 'tinymce/plugins/save'; //保存 import 'tinymce/plugins/searchreplace'; //查找替换 // import 'tinymce/plugins/spellchecker' //拼写检查,暂未加入汉化,不建议使用 import 'tinymce/plugins/tabfocus'; //切入切出,按tab键切出编辑器,切入页面其他输入框中 import 'tinymce/plugins/table'; //表格 import 'tinymce/plugins/template'; //内容模板 import 'tinymce/plugins/textcolor'; //文字颜色 import 'tinymce/plugins/textpattern'; //快速排版 import 'tinymce/plugins/toc'; //目录生成器 import 'tinymce/plugins/visualblocks'; //显示元素范围 import 'tinymce/plugins/visualchars'; //显示不可见字符 import 'tinymce/plugins/wordcount'; //字数统计 // import '../../public/tinymce/axupimgs' //多图上传 import { defineComponent, reactive, toRefs, watch, ref, onMounted } from 'vue'; export default defineComponent({ components: { Editor, }, props: { value: { type: String, default: '', }, disabled: { type: Boolean, default: false, }, plugins: { type: [String, Array], default: 'print preview searchreplace autolink directionality emoticons visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ', }, toolbar: { type: [String, Array], default: 'fullscreen undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \ styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs', }, }, setup(props, { expose, emit }) { const state = reactive({ contentValue: props.value, }); const initOptions = ref({ emoticons_database_url: './/tinymce/emoticons/js/emojis.js', //更改表情插件路径 language_url: './/tinymce/langs/zh_CN.js', //引入语言包文件 language: 'zh_CN', //语言类型 skin_url: './/tinymce/skins/ui/oxide', //皮肤:浅色 // skin_url: '/tinymce/skins/ui/oxide-dark',//皮肤:暗色 plugins: props.plugins, //插件配置 toolbar: props.toolbar, //工具栏配置,设为false则隐藏 // menubar: 'file edit', //菜单栏配置,设为false则隐藏,不配置则默认显示全部菜单,也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单” fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //字体大小 font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;', height: 300, //注:引入autoresize插件时,此属性失效 min_heigth: 200, placeholder: '在这里输入文字...', branding: false, //tiny技术支持信息是否显示 resize: false, //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号 // statusbar: false, //最下方的元素路径和字数统计那一栏是否显示 elementpath: false, //元素路径是否显示 // content_style: 'img {max-width:100%;}', //直接自定义可编辑区域的css样式 content_css: './/tinymce/tinycontent.css', //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入 // images_upload_url: '/demo/upimg.php', //后端处理程序的url // images_upload_base_path: '/demo', //相对基本路径--关于图片上传建议查看--http://tinymce.ax-z.cn/general/upload-images.php // 此处为图片上传处理函数,这个直接用了base64的图片形式上传图片, // 如需ajax上传可参考https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_handler images_upload_handler: (blobInfo: any, success: any, failure: any) => { const img = 'data:image/jpeg;base64,' + blobInfo.base64(); success(img); }, }); const methods = reactive({ onClick(e: any) { emit('onClick', e, tinymce); }, // 可以添加一些自己的自定义事件,如清空内容 clear() { state.contentValue = ''; }, }); onMounted(() => { tinymce.init({}); }); watch( () => props.value, (newValue) => { state.contentValue = newValue; } ); watch( () => state.contentValue, (newValue) => { emit('input', newValue); } ); expose({ ...toRefs(state) }); return { initOptions, ...toRefs(state), ...toRefs(methods), }; }, }); </script> <style lang="scss"> .tinymce-box { z-index: 2; } </style></pre><!--autointro--><!--81-->
2021-11-21
3
0
0
技术分享
VUE3 语法糖(script setup)+ts 使用
<p>VUE3官方网站:<a href="https://v3.cn.vuejs.org/guide/introduction.html" target="_blank" rel="noopener">点击访问</a><br/></p><p>VUE3的生命周期和VUE2的区别:<a href="https://v3.cn.vuejs.org/guide/composition-api-lifecycle-hooks.html" target="_self" rel="noopener">点击访问</a><br/></p><p>下面通过两组件和一个辅助文件说明:<br/></p><!--autointro--><!--80-->
2021-11-21
5
0
0
技术分享
WPF绘制测速仪表
<pre class="brush:c#;toolbar:false"> #region 公共参数 // 原点位置 Point Opos = new Point(200, 200); //总角度 double angle = 360; // 角度 //取模 private static int num = 0; //刻度值0~100 private int externalNum = 0; //最大刻度 private int MaxScale = 51; //最小刻度 private int MinScale = 0; //实际会绘制角度 double drawAngle = 280.00; //圆的半径 double radius = 200; // 圆半径 #endregion public delegate void ExecuteMethodDelegate(); public MainWindow() { InitializeComponent(); } private Dictionary<string, Line> dicLine = new Dictionary<string, Line>(); private int _num = 0; /// <summary> /// 画表盘的刻度 /// </summary> private void ExternalScale() { this.radius = MainCanvas.Width / 2; double min = MinScale; double max = MaxScale; double step = drawAngle / (max - min); for (int i = 0; i < max - min; i++) { double angle1 = WrapAngle(i * step) + 90 + (360 - drawAngle) / 2; angle1 = ConvertDegreesToRadians(angle1); #region 绘制外圈线 { Line lineScale = new Line { X1 = (radius) * Math.Cos(angle1), Y1 = (radius) * Math.Sin(angle1), X2 = (radius - 15) * Math.Cos(angle1), Y2 = (radius - 15) * Math.Sin(angle1), Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)), StrokeThickness = 8 }; lineScale.Name = "line_" + _num; Canvas.SetLeft(lineScale, Opos.X); Canvas.SetTop(lineScale, Opos.Y); MainCanvas.Children.Add(lineScale); dicLine.Add("line_" + _num, lineScale); _num += 2; } #endregion #region 绘制内圈点和数值 { Action<int, double, double> action = (t1, t2, t3) => { Ellipse ellipse = new Ellipse { Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)), StrokeThickness = t1, Fill = new SolidColorBrush(Color.FromRgb(227, 227, 226)) }; ellipse.SetValue(Canvas.LeftProperty, t2 - 5); ellipse.SetValue(Canvas.TopProperty, t3 - 5); MainCanvas.Children.Add(ellipse); }; //double _step = externalNum >= 60 ? step - 0.28 : externalNum > 40 ? step - 0.149 : step;//刻度进行微调 double x1 = (radius - 45) * Math.Cos(angle1) + radius; double y1 = (radius - 52) * Math.Sin(angle1) + radius; if (num % 5 == 0) { //if (externalNum == 50) //{ // action(7, x1, y1); //} //else //{ action(8, x1, y1); //} //添加刻度值 TextBlock txtScale = new TextBlock(); txtScale.Text = Convert.ToString(externalNum); txtScale.FontSize = 10; if (externalNum == 50) { Canvas.SetLeft(txtScale, ((radius - 65) * Math.Cos(angle1)) + radius - 6.6); Canvas.SetTop(txtScale, ((radius - 65) * Math.Sin(angle1)) + radius - 8); } else { Canvas.SetLeft(txtScale, ((radius - 65) * Math.Cos(angle1)) + radius - 6.6); Canvas.SetTop(txtScale, ((radius - 65) * Math.Sin(angle1)) + radius - 8); } MainCanvas.Children.Add(txtScale); externalNum = externalNum + 10; num = 0; } else { action(4, x1, y1); } num++; } #endregion } RotationAngle(0);//指针归零位 DrawOCircle(); } /// <summary> /// 圆形表心圆 /// </summary> private void DrawOCircle() { Ellipse ellipseO = new Ellipse(); ellipseO.Width = 5; ellipseO.Height = 5; ellipseO.Fill = Brushes.Black; Canvas.SetLeft(ellipseO, Opos.X - 2.5); Canvas.SetTop(ellipseO, Opos.Y - 2.5); //if (MainCanvas.Children.Contains(ellipseO)) // MainCanvas.Children.Remove(ellipseO); MainCanvas.Children.Add(ellipseO); } /// <summary> /// 计算指针旋转角度 /// </summary> /// <param name="degrees"></param> /// <param name="maxNum"></param> /// <param name="minNum"></param> private void RotationAngle(double degrees) { double maxNum = 100; double minNum = 0; //表盘最小值 0 //表盘最大值 100 double span = maxNum - minNum; double v = maxNum / span; var row = drawAngle / MaxScale * (degrees - MinScale) * v / 2 - 142; this.PointerCanvas.RenderTransform = SetAngleXY(row, Opos.X, Opos.Y); DispatcherHelper.UpdateUI(); } /// <summary> /// 角度360度进制 /// </summary> /// <param name="angle"></param> /// <returns></returns> private double WrapAngle(double angle) { return angle % 360; } /// <summary> /// 将角度转为弧度 /// </summary> /// <param name="degrees"></param> /// <returns></returns> private double ConvertDegreesToRadians(double degrees) { double radians = (Math.PI / 180) * degrees; return radians; } /// <summary> /// 设置旋转角度和位置 /// </summary> /// <param name="Angle">角度</param> /// <param name="CenterX">X轴偏移位置</param> /// <param name="CenterY">X轴偏移位置</param> /// <returns></returns> public TransformGroup SetAngleXY(double Angle, double CenterX, double CenterY) { TransformGroup tfGroup = new TransformGroup(); RotateTransform rt = new RotateTransform(); rt.Angle = Angle; rt.CenterX = CenterX; rt.CenterY = CenterY; tfGroup.Children.Add(rt); return tfGroup; } private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { try { ExecuteMethodDelegate scale = ExternalScale; this.Dispatcher.BeginInvoke(scale); //scale?.BeginInvoke(null,null); } catch (Exception exception) { Console.WriteLine(exception); throw exception; } } public delegate void RotationAngleDelegate(double i); private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { double PreviousValue = 0, NextValue = 0; double[] arr = new double[] { 0, 1, 1.5, 2.5, 3.5, 7, 8.9, 9, 9.19, 9.23, 9.56, 9.58, 9.88, 9.99, 10.0, 10.12, 11, 12, 12.5, 15, 15.1, 15.23, 15.26, 15.27, 15.28, 15.5, 15.7, 15.9, 15.9, 16.12, 16.4, 16.8, 12.5 }; //数值移动 foreach (var item in arr) { PreviousValue = NextValue; NextValue = item; if (NextValue >= PreviousValue)//下一个值大于上一个值 { for (int i = 0; i < item; i += 2) { dicLine.TryGetValue("line_" + i, out Line line); if (line != null) { line.Stroke = Brushes.Red; } } } else { for (int i = Convert.ToInt32(NextValue) + 2; i <= PreviousValue; i += 2) { dicLine.TryGetValue("line_" + i, out Line line); if (line != null) { line.Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)); } } } RotationAngleDelegate rotationAngle = RotationAngle; this.Dispatcher.Invoke(rotationAngle, item); Thread.Sleep(200); Console.WriteLine($"i的值:{item}"); } } private void ResetBtn_OnClick(object sender, RoutedEventArgs e) { RotationAngleDelegate rotationAngle = RotationAngle; rotationAngle.Invoke(0); foreach (var item in dicLine) { item.Value.Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)); } }</pre><!--autointro--><!--79-->
2021-10-18
3
0
0
技术分享
WPF 绘制仪表
<pre class="brush:c#;toolbar:false"> private int angleNext = 0; private int angelCurrent = 0; private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) { RotateTransform rt = new RotateTransform(); rt.CenterX = 200; rt.CenterY = 200; Canvas canvas = (Canvas)sender; if (dictionary.Count <= 0) { foreach (var item in canvas.Children) { if ("System.Windows.Shapes.Line".Equals(item.ToString(), StringComparison.CurrentCultureIgnoreCase)) { var data = (Line)item; dictionary.Add(data.Name, data); } else if ("System.Windows.Controls.TextBlock".Equals(item.ToString(), StringComparison.CurrentCultureIgnoreCase)) { } else if ("System.Windows.Controls.Path".Equals(item.ToString(), StringComparison.CurrentCultureIgnoreCase)) { ((Path)item).RenderTransform = rt; } } } //this.indicatorPin.RenderTransform = rt; angelCurrent = angleNext; Random random = new Random(); angleNext = random.Next(100); double timeAnimation = Math.Abs(angelCurrent - angleNext) * 8; DoubleAnimation da = new DoubleAnimation(angelCurrent, angleNext, new Duration(TimeSpan.FromMilliseconds(timeAnimation))); da.AccelerationRatio = 1; rt.BeginAnimation(RotateTransform.AngleProperty, da); this.currentValueTxtBlock.Text = string.Format("当前值:{0}度", angleNext); } private int lineNum = 0; /// <summary> /// 画表盘的刻度(外圈) /// </summary> private void ExternalScale() { for (double i = 0; i <= 180; i += 9) { //添加刻度线 Line lineScale = new Line(); var x1= 200 - 200 * Math.Cos(i * Math.PI / 180); var y1= 200 - 200 * Math.Sin(i * Math.PI / 180); lineScale.X1 = x1; lineScale.Y1 = y1; lineScale.Stroke = new SolidColorBrush(Color.FromRgb(128, 128, 129)); lineScale.StrokeThickness = 10; lineScale.Width = 420; lineScale.Height = 400; lineScale.Name = "line" + lineNum; var x2= 200 - 182 * Math.Cos(i * Math.PI / 180); var y2= 200 - 182 * Math.Sin(i * Math.PI / 180); lineScale.X2 = x2; lineScale.Y2 = y2; this.gaugeCanvas.Children.Add(lineScale); lineNum = lineNum + 5; } this.DrawScale(); } private int externalNum = 0; /// <summary> /// 画表盘的刻度(内圈) /// </summary> private void DrawScale() { for (double i = 0; i <= 180; i += 6) { Ellipse ellipse = new Ellipse(); if (Convert.ToInt32(i) % 18 == 0) { ellipse.Width = 10; ellipse.Height = 10; ellipse.Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)); ellipse.StrokeThickness = 1; ellipse.Fill = new SolidColorBrush(Color.FromRgb(227, 227, 226)); ellipse.SetValue(Canvas.LeftProperty, 200 - 160 * Math.Cos(i * Math.PI / 180)); ellipse.SetValue(Canvas.TopProperty, 200 - 160 * Math.Sin(i * Math.PI / 180) - 4.5); //添加刻度值 TextBlock txtScale = new TextBlock(); txtScale.Text = Convert.ToString(externalNum); txtScale.FontSize = 10; if (i <= 90) //对坐标值进行一定的修正 { Canvas.SetLeft(txtScale, 200 - 145 * Math.Cos(i * Math.PI / 180)); } else { Canvas.SetLeft(txtScale, 190 - 145 * Math.Cos(i * Math.PI / 180)); } Canvas.SetTop(txtScale, 200 - 145 * Math.Sin(i * Math.PI / 180)); this.gaugeCanvas.Children.Add(txtScale); externalNum = externalNum + 10; } else { ellipse.Width = 7; ellipse.Height = 7; if (i <= 90) { ellipse.SetValue(Canvas.LeftProperty, 200 - 158 * Math.Cos(i * Math.PI / 180)); ellipse.SetValue(Canvas.TopProperty, 200 - 158 * Math.Sin(i * Math.PI / 180) - 4.5); } else if (i > 160) { ellipse.SetValue(Canvas.LeftProperty, 200 - 162 * Math.Cos(i * Math.PI / 180)); ellipse.SetValue(Canvas.TopProperty, 200 - 162 * Math.Sin(i * Math.PI / 180) - 4.5); } else { ellipse.SetValue(Canvas.LeftProperty, 200 - 160 * Math.Cos(i * Math.PI / 180)); ellipse.SetValue(Canvas.TopProperty, 200 - 160 * Math.Sin(i * Math.PI / 180) - 4.5); } ellipse.Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)); ellipse.StrokeThickness = 1; ellipse.Fill = new SolidColorBrush(Color.FromRgb(227, 227, 226)); } this.gaugeCanvas.Children.Add(ellipse); } this.DrawPointer(); } /// <summary> /// 画指针 /// </summary> private void DrawPointer() { PathFigure pathFigure = new PathFigure() { StartPoint = new Point(200.00, 195.00), IsClosed = true }; PathSegmentCollection pathSegmentCollection = new PathSegmentCollection(); LineSegment lineSegment = new LineSegment(new Point(20, 200), true); pathSegmentCollection.Add(lineSegment); LineSegment lineSegment1 = new LineSegment(new Point(200, 205), true); pathSegmentCollection.Add(lineSegment1); pathFigure.Segments = pathSegmentCollection; PathFigureCollection myPathFigureCollection = new PathFigureCollection(); myPathFigureCollection.Add(pathFigure); PathGeometry pathGeometry = new PathGeometry(); pathGeometry.Figures = myPathFigureCollection; //this.indicatorPin.Data = pathGeometry; Path path = new Path(); path.Name = "indicatorPin"; path.Fill = new SolidColorBrush(Color.FromRgb(239, 191, 79)); path.Data = pathGeometry; this.gaugeCanvas.Children.Add(path); }</pre><!--autointro--><!--78-->
2021-10-14
2
0
0
技术分享
VUE 打包后继续使用代理
<p>vue.config.js的 devServer 节点配置如下:</p><pre class="brush:js;toolbar:false">devServer: { port: 9011, // 端口号 https: false, // https:{type:Boolean} open: "Google Chrome", //配置自动启动浏览器 openPage: "/", //指定打开浏览器时要导航到的页面 proxy: proxyConfig.proxyList },</pre><!--autointro--><!--77-->
2021-09-16
8
0
0
技术分享
同一台服务器 nginx配置https以及http自动跳转https
<p>创建新的配置文件 javalc.conf</p><pre class="brush:c#;toolbar:false">server { listen 80; server_name www.javalc.com; rewrite ^(.*)$ https://$server_name$1 permanent; } server { listen 443 ssl; server_name www.javalc.com; ssl on; ssl_certificate /cert/6003766_www.javalc.com.pem; ssl_certificate_key /cert/6003766_www.javalc.com.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; client_max_body_size 100M; server_name_in_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / { root /home/nginx-host/web; index index.html index.htm; } }</pre><!--autointro--><!--76-->
2021-09-01
4
0
0
技术分享
VUE3 使用 openlayers v6.6.1 绘制台风路径、台风圈
<p>ts代码:</p><pre class="brush:js;toolbar:false">import { Feature, Overlay } from 'ol'; import { Point, Polygon, LineString, Circle as GeomCircle } from 'ol/geom'; import { Vector as LayerVector } from 'ol/layer'; import { Style, Stroke, Circle, Fill } from 'ol/style'; import { Vector } from 'ol/source'; import { WKT } from 'ol/format'; import { fromLonLat } from 'ol/proj'; import d from '../assets/201929'; export default class Typhoon { _map: any; _speed: Number = 200; _forcColorDict: any = { 中国: '#ec5d72', 中国香港: '#ec7cfe', 中国台湾: '#ecaa65', 日本: '#56f66e', 美国: '#53dbfe', 韩国: '#72a4ac', 欧洲: '#4c54a6', }; _typhoonList: any = []; _typhoonData: any = {}; _nameOverlays: any = {}; _typhoonPlayFlag: any = {}; _typhoonPlayIndex: any = {}; _warnLines: any = null; _typhoonLayers: any = {}; _forecastFeatures: any = {}; _typhoonCircle: any = []; wktformat:any = new WKT(); constructor(map: any) { this._map = map; } init = () => { // 添加警戒线 this.addWarnLine(); // 添加地图事件 this.addMapEvent(); this.showTyphoon(d.data[0]); // 获取台风数据 // $.get('../../data/201929.json', (res) => { // _typhoonList = res; // showTyphoon(_typhoonList[0]); // }); }; addWarnLine = () => { const warnLineData = [ { color: 'blue', weight: 1, opacity: 0.8, dashArray: [0, 0], points: [ [105, 0], [113, 4.5], [119, 11], [119, 18], [127, 22], [127, 34], ], }, { color: 'green', weight: 1, opacity: 0.8, dashArray: [10, 5], points: [ [105, 0], [120, 0], [132, 15], [132, 34], ], }, ]; const features = []; for (var i = 0; i < warnLineData.length; i++) { const d = warnLineData[i]; const geometry = new LineString(d.points); geometry.transform('EPSG:4326', this._map.getView().getProjection()); const feature = new Feature({ geometry: geometry, attr: d, }); features.push(feature); } const source = new Vector({ features: features, }); this._warnLines = new LayerVector({ source: source, style: this.warnLineStyle, opacity: 0.8, }); this._map.addLayer(this._warnLines); }; // 警戒线样式设置 warnLineStyle = (feat: any) => { const attr = feat.get('attr'); return new Style({ stroke: new Stroke({ color: attr.color, width: attr.weight, lineDash: attr.dashArray, }), }); }; // 添加地图事件 addMapEvent = () => { // 鼠标移动事件 this._map.on('pointermove', (evt: any) => { const pixel = evt.pixel; const dom = this._map.getTargetElement(); if (this._map.hasFeatureAtPixel(pixel)) { dom.style.cursor = 'pointer'; const features = this._map.getFeaturesAtPixel(pixel); const feature = features[0]; // console.log(feature.get('attr')); } else { dom.style.cursor = 'default'; } }); this._map.on('click', (evt: any) => { const pixel = evt.pixel; if (this._map.hasFeatureAtPixel(pixel)) { const features = this._map.getFeaturesAtPixel(pixel); const feature = features[0]; const attr = feature.get('attr'); this._typhoonPlayIndex[attr.tfbh] = attr.index; this.showForecast(attr.tfbh, attr); } }); }; // 展示台风 showTyphoon = (typhoonData: any) => { const tfbh = typhoonData.tfbh; this._typhoonData[tfbh] = typhoonData; // 1. 添加台风名称 this.addNameOverlay(typhoonData); // 2. 创建展示图层 this.addTyphoonLayer(tfbh); // 3.开始播放 this.playTyphoon(tfbh); }; // 移除台风 removeTyphoon = (tfbh: any) => { // 删除台风名称 this._map.removeOverlay(this._nameOverlays[tfbh]); // 删除展示图层 this._map.removeLayer(this._typhoonLayers[tfbh].layer); // 消除定时器 clearInterval(this._typhoonPlayFlag[tfbh]); }; // 添加台风名称 addNameOverlay = (typhoonData: any) => { const nameDom = document.createElement('div'); nameDom.setAttribute('class', 'typhoon-name'); nameDom.innerHTML = typhoonData.name; const pointStart = typhoonData.points[0]; // const position = fromLonLat([ // pointStart.longitude, // pointStart.latitude, // ]); const nameOverlay = new Overlay({ element: nameDom, position: [pointStart.longitude, pointStart.latitude], positioning: 'center-left', offset: [15, 0], }); this._map.addOverlay(nameOverlay); this._nameOverlays[typhoonData.tfbh] = nameOverlay; this._typhoonCircle[typhoonData.tfbh]=this.drawTyphoonCircle(pointStart.longitude, pointStart.latitude);//台风圈 }; /** * 绘制台风圈 */ drawTyphoonCircle = (x: any, y: any) => { /** 台风配置 */ var Configs = { // CIRCLE_CENTER_X:104.21390114106414, // CIRCLE_CENTER_Y:35.847595169932646, CIRCLE_CENTER_X: x, CIRCLE_CENTER_Y: y, CIRCLE_R: { "SE": 0.5, "NE": 0.3, "NW": 0.2, "SW": 0.5 } }; /** 台风算法 */ var wkt = "POLYGON(("; var wkt0 = "", _interval = 6; for (var i = 0; i < 360 / _interval; i++) { var _r = 0; var _ang = i * _interval; if (_ang > 0 && _ang <= 90) { _r = Configs.CIRCLE_R.NE; } else if (_ang > 90 && _ang <= 180) { _r = Configs.CIRCLE_R.NW; } else if (_ang > 180 && _ang <= 270) { _r = Configs.CIRCLE_R.SW; } else { _r = Configs.CIRCLE_R.SE; } var x = Configs.CIRCLE_CENTER_X + _r * Math.cos(_ang * 3.14 / 180); var y = Configs.CIRCLE_CENTER_Y + _r * Math.sin(_ang * 3.14 / 180); wkt = wkt + "" + x + " " + y + ", "; if (i === 0) { wkt0 = "" + x + " " + y + ""; } } wkt = wkt + wkt0 + "))"; var features = new Array(); features.push(this.wktformat.readFeature(wkt)); features.push(this.wktformat.readFeature("POINT(" + Configs.CIRCLE_CENTER_X + " " + Configs.CIRCLE_CENTER_Y + ")")); var styleFunc = (feature: any, resolution: any) => { return new Style({ fill: new Fill({ color: 'rgba(255, 0, 0, 0.2)' }), stroke: new Stroke({ color: '#ffcc33', width: 2 }), image: new Circle({ radius: 4, fill: new Fill({ color: '#ff0000' }) }) }); }; var layerVector = new LayerVector({ source: new Vector({ features: features, }), style: styleFunc }); this._map.addLayer(layerVector); return layerVector; }; /** * 删除台风圈 * @param tfbh 分组名称 */ removeTyphoonCircle = (tfbh: any)=>{ // const source = this._typhoonCircle[tfbh].getSource(); // source.removeFeature(this._typhoonCircle[tfbh]); this._typhoonCircle[tfbh].getSource().clear(); this._map.removeLayer(this._typhoonCircle[tfbh]); } // 根据编号添加台风图层 addTyphoonLayer = (tfbh: any) => { const source = new Vector({ features: [], }); const layer = new LayerVector({ source: source, style: this.typhoonStyle, }); this._map.addLayer(layer); this._typhoonLayers[tfbh] = { source: source, layer: layer, }; this._forecastFeatures[tfbh] = []; }; // 播放台风 playTyphoon = (tfbh: any) => { let index = 0; const typhoonData = this._typhoonData[tfbh]; this.play(index, tfbh); this._typhoonPlayFlag[tfbh] = setInterval(() => { index++; if (index === typhoonData.points.length) { clearInterval(this._typhoonPlayFlag[tfbh]); } else { this.play(index, tfbh); } }, 200); }; // 播放单个点 play = (index: any, tfbh: any) => { // 删除预报 this.removeForecast(tfbh); this.removeTyphoonCircle(tfbh); this._map.removeLayer(this._typhoonCircle[tfbh]); this._typhoonPlayIndex[tfbh] = index; const points = this._typhoonData[tfbh].points; const point = points[index]; point.type = 'live'; point.index = index; point.tfbh = tfbh; if (index > 0) { const prePoint = points[index - 1]; point.start = [prePoint.longitude, prePoint.latitude]; } point.end = [point.longitude, point.latitude]; //const position = fromLonLat(point.end); const position = point.end; //点的数据设置 const feature = new Feature({ geometry: new Point(position), attr: point, }); this._typhoonLayers[tfbh].source.addFeature(feature); this._typhoonCircle[tfbh]=this.drawTyphoonCircle(point.longitude, point.latitude);//台风圈 // console.log("输出数据", this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry()); // this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry().setCoordinates(feature); // debugger; console.log("分类保存的台风圈"); // 最后一个实况点,展示预报路径 if (index === this._typhoonData[tfbh].points.length - 1) { this.showForecast(tfbh, point); } }; // 删除预报数据 removeForecast = (tfbh: any) => { const source = this._typhoonLayers[tfbh].source; for (var i = 0; i < this._forecastFeatures[tfbh].length; i++) { const f = this._forecastFeatures[tfbh][i]; source.removeFeature(f); } this._forecastFeatures[tfbh] = []; }; // 展示预报数据 showForecast = (tfbh: any, livePoint: any) => { const source = this._typhoonLayers[tfbh].source; // 1. 删除预报数据 this.removeForecast(tfbh); // 2. 添加预报 const forecast = livePoint.forecast; const features = []; for (var i = 0; i < forecast.length; i++) { const f = forecast[i]; for (var j = 0; j < f.points.length; j++) { const point = f.points[j]; const prePoint = f.points[j - 1]; point.sets = f.sets; point.type = 'forc'; point.index = j; point.start = j === 0 ? [livePoint.longitude, livePoint.latitude] : [prePoint.longitude, prePoint.latitude]; point.end = [point.longitude, point.latitude]; //const coords = fromLonLat(point.end); const coords = point.end; const feature = new Feature({ geometry: new Point(coords), attr: point, }); features.push(feature); } } source.addFeatures(features); this._forecastFeatures[tfbh] = features; }; // 根据风速获取点的颜色 getPointColor = (speed: any) => { let _color = ''; if (speed >= 10.8 && speed < 17.2) { _color = 'rgba(153, 255, 153, .9)'; } else if (speed >= 17.2 && speed < 24.5) { _color = 'rgba(102, 204, 255, .9)'; } else if (speed >= 24.5 && speed < 32.7) { _color = 'rgba(255, 255, 102, .9)'; } else if (speed >= 32.7 && speed < 41.5) { _color = 'rgba(253, 139, 0, .9)'; } else if (speed >= 41.5 && speed < 50.1) { _color = 'rgba(255, 51, 0, .9)'; } else { _color = 'rgba(255, 0, 255, .9)'; } return _color; }; // 台风展示样式 typhoonStyle = (feat: any) => { const attr = feat.get('attr'); const speed = 12; //attr.speed; const type = attr.type; const index = attr.index; const color = this.getPointColor(speed); let styles = []; // 点的样式 const radius = type === 'live' ? 4 : 3; const pointStyle = new Style({ image: new Circle({ radius: radius, fill: new Fill({ color: color, }), stroke: new Stroke({ color: 'rgba(0, 0, 0, 0.6)', width: 1, }), }), }); styles.push(pointStyle); if (type === 'live' && index === this._typhoonPlayIndex[attr.tfbh]) { const center = feat.get('geometry').getCoordinates(); const fillStyle = new Fill({ color: 'rgba(0, 0, 0, 0.2)', }); // 7级风圈的样式 if (attr.radius7 > 0) { const geometry: any = this.getCircleGeometry(center, attr.radius7_quad); const style = new Style({ geometry: geometry, stroke: new Stroke({ color: '#00bab2', width: 1, }), fill: fillStyle, }); styles.push(style); } // 10级风圈的样式 if (attr.radius10 > 0) { const geometry: any = this.getCircleGeometry( center, attr.radius10_quad ); const style = new Style({ geometry: geometry, stroke: new Stroke({ color: '#ffff00', width: 1, }), fill: fillStyle, }); styles.push(style); } // 12级风圈的样式 if (attr.radius12 > 0) { const geometry: any = this.getCircleGeometry( center, attr.radius12_quad ); const style = new Style({ geometry: geometry, stroke: new Stroke({ color: '#da7341', width: 1, }), fill: fillStyle, }); styles.push(style); } } // 线的样式 const start = attr.start; const end = attr.end; const lineColor = this.getLineColor(type, attr.sets); const lineDash = type === 'live' ? [0] : [8]; const lineWidth = type === 'live' ? 2 : 1; if (start && start.length > 0) { const coords = [start, end]; const geometry = new LineString(coords); geometry.transform('EPSG:4326', this._map.getView().getProjection()); const lineStyle = new Style({ geometry: geometry, stroke: new Stroke({ color: lineColor, width: lineWidth, lineDash: lineDash, }), }); styles.push(lineStyle); } return styles; }; // 获取线的颜色 getLineColor = (type: any, sets: any) => { if (type === 'live') { return 'rgba(0, 0, 0, .6)'; } else { let color = this._forcColorDict[sets]; if (!color) color = 'rgba(0, 0, 0, .3)'; return color; } }; getCircleGeometry = (center: any, radiusData: any) => { if (typeof radiusData === 'number') { return new GeomCircle(center, radiusData * 1000); } else { if (radiusData['ne']) { let _coords = []; let _angInterval = 6; let _pointNums = 360 / (_angInterval * 4); let quadrant: any = { // 逆时针算角度 '0': 'ne', '1': 'nw', '2': 'sw', '3': 'se', }; for (let i = 0; i < 4; i++) { let _r = parseFloat(radiusData[quadrant[i]]) * 1000; // 单位是km if (!_r) _r = 0; for (let j = i * _pointNums; j <= (i + 1) * _pointNums; j++) { let _ang = _angInterval * j; let x = center[0] + _r * Math.cos((_ang * Math.PI) / 180); let y = center[1] + _r * Math.sin((_ang * Math.PI) / 180); _coords.push([x, y]); } } return new Polygon([_coords]); } else { return null; } } }; }</pre><!--autointro--><!--75-->
2021-08-30
3
0
0
技术分享
1
2
3
4
5
...
11