using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.CompilerServices;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
Test test;
private void Form2_Load(object sender, EventArgs e)
{
test=new Test();
label1.DataBindings.Add("Text", test, "Str");
label2.DataBindings.Add("Text", test, "Str");
label3.DataBindings.Add("Text", test, "Str");
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
test.Str = textBox1.Text;
}
}
//要使用绑定数据功能,需要模型支持INotifyPropertyChanged接口
public class Test : INotifyPropertyChanged
{
string _str;
public string Str
{
get
{
return _str;
}
set
{
_str = value;
FireStrChanged();
}
}
//必须实现INotifyPropertyChanged接口的此事件
public event PropertyChangedEventHandler PropertyChanged;
//要在.net4.0使用CallerMemberName特性,需要加上后面一段代码
public void FireStrChanged([CallerMemberName] string propertyName="")
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
public class CallerMemberNameAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
public class CallerFilePathAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
public class CallerLineNumberAttribute : Attribute
{
}
}
————————————————
版权声明:本文为CSDN博主「naruto2017」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/szy759590387/article/details/89516163
Author: Robin
laravel-admin form
protected function form()
{
$form = new Form(new InfusionTicket());
$form->select('clinic_id', "诊所信息")->options(Clinic::all()->pluck('name', 'id'))->required();
$form->date('date', __('Date'))->default(date('Y-m-d'))->required();
$form->select('inject', __('Inject'))->options(['静脉输液'=>'静脉输液',"肌肉(皮下)注射"=>"肌肉(皮下)注射","抽血"=>"抽血"])->required();
$form->number('ticket', __('Ticket'))->required();
$form->select('time_index', __('时间'))->options(InfusionTicketController::$timeArray)->required();
$form->hidden('time');
$form->saving(function ($form){
$timeIndex = $form->time_index;
Log::debug('数据');
Log::debug($timeIndex);
$time = InfusionTicketController::$timeArray[$timeIndex];
Log::debug($time);
$form->time= $time;
});
//保存后回调
$form->saved(function ($form){
Log::debug("执行创建");
$model = $form->model();
$clinicId = $model->clinic_id;
$inject = $model->inject=='静脉输液'?'jmsy':'default';
$date = $model->date;
$dateFormat = Carbon::parse($date)->format('Y-m-d');
$timeIndex = $model->time_index;
$ticket = $model->ticket;
Redis::select(2);
$key = 'infusion-tickets:'.$clinicId.':'.$inject.':'.$dateFormat.':'.$timeIndex;
Log::info($key);
Redis::set($key,$ticket);
});
return $form;
在form表单中设置time为不可见(一定要设置time 不然无法保存time信息)
上述代码在保存时 添加time信息
在保存后 把对应信息 存储在redis中
protected function detail($id)
{
$show = new Show(InfusionTicket::findOrFail($id));
$show->panel()->tools(function ( \Encore\Admin\Show\Tools $tools) {
$tools->disableEdit();
});
$show->clinic('诊所信息', function ($clinic) {
$clinic->setResource('/admin/clinics/');
$clinic->field('name',__('Name'));
});
$show->field('date', __('Date'));
$show->field('inject', __('Inject'));
$show->field('ticket', __('Ticket'));
$show->field('time', __('Time'));
return $show;
}
详情页面 屏蔽“编辑”按钮
public static function boot()
{
parent::boot(); // TODO: Change the autogenerated stub
static:: deleted(function (InfusionTicket $model) {
Log::debug("模型删除");
$clinicId = $model->clinic_id;
$inject = $model->inject=='静脉输液'?'jmsy':'default';
$date = $model->date;
$dateFormat = Carbon::parse($date)->format('Y-m-d');
$timeIndex = $model->time_index;
Redis::select(2);
$key = 'infusion-tickets:'.$clinicId.':'.$inject.':'.$dateFormat.':'.$timeIndex;
Log::info($key);
Redis::del($key);
});
}
在数据模型中 增加删除回调 删除redis值

C#是微软公司发布的一种由C和C++衍生出来的面向对象的编程语言、运行于.NET Framework和.NET Core(完全开源,跨平台)之上的高级程序设计语言。并定于在微软职业开发者论坛(PDC)上登台亮相。
C#是微软公司研究员Anders Hejlsberg的最新成果。C#看起来与Java有着惊人的相似;它包括了诸如单一继承、接口、与Java几乎同样的语法和编译成中间代码再运行的过程。但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对象模型)是直接集成的,而且它是微软公司 .NET windows网络框架的主角。
C#是由C和C++衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言。它在继承C和C++强大功能的同时去掉了一些它们的复杂特性(例如没有宏以及不允许多重继承)。C#综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言。
C#是面向对象的编程语言。它使得程序员可以快速地编写各种基于MICROSOFT .NET平台的应用程序,MICROSOFT .NET提供了一系列的工具和服务来最大程度地开发利用计算与通讯领域。C#使得C++程序员可以高效的开发程序,且因可调用由 C/C++ 编写的本机原生函数,而绝不损失C/C++原有的强大的功能。因为这种继承关系,C#与C/C++具有极大的相似性,熟悉类似语言的开发者可以很快的转向C#
国内的可集群 任务调度
程序内部分为两部分
admin 管理控制台
executor 调度执行器
通过管理控制台 向系统提交任务 和绑定到对应的执行器
执行器在安排的时间内执行任务
windows 下 SC 命令
windows 下可以通过 sc 命令添加服务
sc create gogs start= auto binPath= ""C:\gogs\gogs.exe" web --config "C:\gogs\conf\app.ini""
sc create nginx start= auto binPath= ""C:\nginx\nginx.exe" -p "C:\nginx"" DisplayName= nginx-server
Elastic job
分布式调度应用
elasticjob-lite-core 分布式调度应用核心代码
基于ZooKeeper 作为调度中心
启动 mongodb
还原 mongorestore
linux下安装mongoDB
sudo apt install mongodb-server
执行本地连接
mongo
本地配置文件
/etc/mongodb.conf
重要配置项
bind_ip //绑定主机
port //服务端口
auth //是否需要账号密码登录
配置需要登录前需要先添加用户
在admin表下添加user
use admin;
db.createUser({user:"admin", pwd:"密码",roles:[{role:"userAdminAnyDatabase",db:"admin"},{role:"readWriteAnyDatabase",db:"admin"}]});
连接后先授权
use admin;
db.auth('robin','RobinLuo123');
// 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母)
String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
"(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
//假设18位身份证号码:41000119910101123X 410001 19910101 123X
//^开头
//[1-9] 第一位1-9中的一个 4
//\\d{5} 五位数字 10001(前六位省市县地区)
//(18|19|20) 19(现阶段可能取值范围18xx-20xx年)
//\\d{2} 91(年份)
//((0[1-9])|(10|11|12)) 01(月份)
//(([0-2][1-9])|10|20|30|31)01(日期)
//\\d{3} 三位数字 123(第十七位奇数代表男,偶数代表女)
//[0-9Xx] 0123456789Xx其中的一个 X(第十八位为校验值)
//$结尾
//假设15位身份证号码:410001910101123 410001 910101 123
//^开头
//[1-9] 第一位1-9中的一个 4
//\\d{5} 五位数字 10001(前六位省市县地区)
//\\d{2} 91(年份)
//((0[1-9])|(10|11|12)) 01(月份)
//(([0-2][1-9])|10|20|30|31)01(日期)
//\\d{3} 三位数字 123(第十五位奇数代表男,偶数代表女),15位身份证不含X
//$结尾
boolean matches = IDNumber.matches(regularExpression);
//判断第18位校验值
if (matches) {
if (IDNumber.length() == 18) {
try {
char[] charArray = IDNumber.toCharArray();
//前十七位加权因子
int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
//这是除以11后,可能产生的11位余数对应的验证码
String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
int sum = 0;
for (int i = 0; i < idCardWi.length; i++) {
int current = Integer.parseInt(String.valueOf(charArray[i]));
int count = current * idCardWi[i];
sum += count;
}
char idCardLast = charArray[17];
int idCardMod = sum % 11;
if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
return true;
} else {
return false;
}
} catch (Exception e) {
logger.error("身份证校验异常,{}", e.getMessage());
return false;
}
}
}
return matches;
spring AOP
切面语法
execution
execution是一种使用频率比较高比较主要的一种切点指示符,用来匹配方法签名,方法签名使用全限定名,包括访问修饰符(public/private/protected)、返回类型,包名、类名、方法名、参数,其中返回类型,包名,类名,方法,参数是必须的,如下面代码片段所示:
@Pointcut("execution(public String org.baeldung.dao.FooDao.findById(Long))")
上面的代码片段里的表达式精确地匹配到FooDao类里的findById(Long)方法,但是这看起来不是很灵活。假设我们要匹配FooDao类的所有方法,这些方法可能会有不同的方法名,不同的返回值,不同的参数列表,为了达到这种效果,我们可以使用通配符。如下代码片段所示:
@Pointcut("execution(* org.baeldung.dao.FooDao.*(..))")
第一个通配符匹配所有返回值类型,第二个匹配这个类里的所有方法,()括号表示参数列表,括号里的用两个点号表示匹配任意个参数,包括0个
within
使用within切点批示符可以达到上面例子一样的效果,within用来限定连接点属于某个确定类型的类。如下面代码的效果与上面的例子是一样的:
@Pointcut("within(org.baeldung.dao.FooDao)")
我们也可以使用within指示符来匹配某个包下面所有类的方法(包括子包下面的所有类方法),如下代码所示:
@Pointcut("within(org.baeldung..*)")
this 和 target
this用来匹配的连接点所属的对象引用是某个特定类型的实例,target用来匹配的连接点所属目标对象必须是指定类型的实例;那么这两个有什么区别呢?原来AspectJ在实现代理时有两种方式:
1、如果当前对象引用的类型没有实现自接口时,spring aop使用生成一个基于CGLIB的代理类实现切面编程
2、如果当前对象引用实现了某个接口时,Spring aop使用JDK的动态代理机制来实现切面编程
this指示符就是用来匹配基于CGLIB的代理类,通俗的来讲就是,如果当前要代理的类对象没有实现某个接口的话,则使用this;target指示符用于基于JDK动态代理的代理类,通俗的来讲就是如果当前要代理的目标对象有实现了某个接口的话,则使用target.
比如在上面这段代码示例中,spring aop将使用jdk的动态代理来实现切面编程,在编写匹配这类型的目标对象的连接点表达式时要使用target指示符, 如下所示:
@Pointcut("target(org.baeldung.dao.BarDao)")
如果FooDao类没有实现任何接口,或者在spring aop配置属性:proxyTargetClass设为true时,Spring Aop会使用基于CGLIB的动态字节码技为目标对象生成一个子类将为代理类,这时应该使用this指示器
@Pointcut("this(org.baeldung.dao.FooDao)")
参数
参数指示符是一对括号所括的内容,用来匹配指定方法参数:
@Pointcut("execution(* *..find*(Long))")
这个切点匹配所有以find开头的方法,并且只一个Long类的参数。如果我们想要匹配一个有任意个参数,但是第一个参数必须是Long类的,我们这可使用下面这个切点表达式:
@Pointcut("execution(* *..find*(Long,..))")
@Target
@Pointcut("@target(org.springframework.stereotype.Repository)")
@args
@Pointcut("@args(org.baeldung.aop.annotations.Entity)")
public void methodsAcceptingEntities() {}
@within
这个指示器,指定匹配必须包括某个注解的的类里的所有连接点:
@Pointcut("@within(org.springframework.stereotype.Repository)")
上面的切点跟以下这个切点是等效的:
@Pointcut("within(@org.springframework.stereotype.Repository *)")
@annotation
这个指示器匹配那些有指定注解的连接点,比如,我们可以新建一个这样的注解@Loggable:
@Pointcut("@annotation(org.baeldung.aop.annotations.Loggable)")
public void loggableMethods() {}
我们可以使用@Loggable注解标记哪些方法执行需要输出日志:
@Before("loggableMethods()")
public void logMethod(JoinPoint jp) {
String methodName = jp.getSignature().getName();
logger.info("Executing method: " + methodName);
}
&&、||、!
可以使用&&、||、!、三种运算符来组合切点表达式,表示与或非的关系。
@target @within 区别
@target要求对象的运行时类型与被注解的类型是同一个类型
@within要求对象的运行时类型是被注解的类型的子类
nginx tcpip 代理
nginx stream 能提供基于tcpip的代理功能
stream {
upstream redis {
server 192.168.0.14:6379;
}
server {
listen 6379;
proxy_pass redis;
}
}
定义stram模块 开始配置tcpip转发规则
定义的upstream redis 是一个只能内网访问的redis
server 模块表示对外的配置信息 上文就是把开通本机6379端口 代理redis服务器